Skip to content

v0.1.11

Choose a tag to compare

@github-actions github-actions released this 28 Aug 12:51
· 37 commits to main since this release

Derive the native TypeScript surface from the Rust

The hand-written interface describing the .node binary was a second
description of the same thing, and nothing on this side noticed when the
first one changed: a pub fn could gain a parameter, stop being async
or change its return with the declaration still claiming otherwise.

napi-derive can emit the declarations itself. Its type-def feature
writes one JSON line per #[napi] item while cargo compiles;
scripts/build-napi-types.mjs collects them and
scripts/generate-napi-types.mjs turns them into
src/native/generated.ts. build:napi regenerates it, and the
TypeScript side consumes it instead of restating it.

Three things the generation had to handle:

  • type-def APPENDS to its output file, so a parallel cargo build
    interleaves the writes and definitions go missing, silently, leaving
    the generated file short. Crates are built one at a time, and a crate
    that emits nothing fails the script rather than producing a partial
    surface.
  • A Rust doc example holding a cron expression (0 */5 * * *) closes
    the generated comment early. Every */ is escaped except the one
    that legitimately closes the block — escaping that one breaks the
    file just as thoroughly.
  • The driver is Node rather than bash, because build:napi also runs
    on the Windows prebuild runner: a Git Bash mktemp path is not
    something the native proc-macro can write to, and the type-def file
    would come back empty with nothing to explain why.

The generated file is a .ts holding only ambient declarations rather
than a .d.ts, so tsc carries it into dist/native/ and the
reference from the emitted declarations still resolves for consumers.

It had already drifted here: layoutName and firstDiskNode were
declared | null, but napi-rs maps Option<T> on an #[napi(object)]
to an ABSENT field. The value is undefined, so the === null
invariant guard in Templates never fired and the case it exists to
catch would have reached #resolveTemplateFile as undefined instead.
Generating the types surfaced it as a compile error.

Create the GitHub release from the publish workflow

A published version arrived with no notes: npm showed a number, GitHub showed
nothing, and the only way to learn what changed was to read a diff. The commit
messages already carry the reasoning, so the release is built from the commits
the tag contains rather than written twice.

Skips a pure version bump, leaves an existing release alone, and does nothing
when the run was not built from a tag. The job takes contents:write for this;
the workflow default stays read.


Changes since v0.1.10.