-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathnapi-rs.ts
More file actions
81 lines (77 loc) · 2.4 KB
/
napi-rs.ts
File metadata and controls
81 lines (77 loc) · 2.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import assert from "node:assert/strict";
import fs from "node:fs";
import path from "node:path";
import { spawn } from "bufout";
import { getBlockComment } from "./banner.js";
const PACKAGE_ROOT = path.join(import.meta.dirname, "..");
type TypeScriptDeclarationsOptions = {
/**
* Path to the directory containing the Cargo.toml file.
*/
createPath: string;
/**
* Path to the output directory where the TypeScript declarations will be copied into.
*/
outputPath: string;
/**
* File name of the generated TypeScript declarations (including .d.ts).
*/
outputFilename: string;
};
export async function generateTypeScriptDeclarations({
createPath,
outputPath,
outputFilename,
}: TypeScriptDeclarationsOptions) {
// Using a temporary directory to avoid polluting crate with any other side-effects for generating TypeScript declarations
const tempPath = fs.realpathSync(
fs.mkdtempSync(path.join(PACKAGE_ROOT, "dts-tmp-"))
);
const finalOutputPath = path.join(outputPath, outputFilename);
try {
// Write a dummy package.json file to avoid errors from napi-rs
await fs.promises.writeFile(
path.join(tempPath, "package.json"),
"{}",
"utf8"
);
// Call into napi.rs to generate TypeScript declarations
const napiCliPath = new URL(
import.meta.resolve("@napi-rs/cli/scripts/index.js")
).pathname;
await spawn(
// TODO: Resolve the CLI path (not using npx because we don't want to npx to mess up the cwd)
napiCliPath,
[
"build",
"--dts",
outputFilename,
"--cargo-cwd",
// This doesn't understand absolute paths
path.relative(tempPath, createPath),
],
{
outputMode: "buffered",
cwd: tempPath,
}
);
// Override the banner
const tempOutputPath = path.join(tempPath, outputFilename);
assert(
fs.existsSync(tempOutputPath),
`Expected napi.rs to emit ${tempOutputPath}`
);
const contents = await fs.promises.readFile(tempOutputPath, "utf8");
const patchedContents = contents.replace(
"/* auto-generated by NAPI-RS */",
getBlockComment()
);
// Copy out the generated TypeScript declarations
await fs.promises.writeFile(finalOutputPath, patchedContents, {
encoding: "utf8",
});
return finalOutputPath;
} finally {
await fs.promises.rm(tempPath, { recursive: true, force: true });
}
}