-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathindex.ts
More file actions
150 lines (134 loc) · 3.83 KB
/
index.ts
File metadata and controls
150 lines (134 loc) · 3.83 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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
import { basename, resolve } from 'node:path';
import { prepareBinding } from './bindings.ts';
import { ensureDir, writeFileSafe } from './fs.ts';
import { type WasmGenerateResult, wasmGenerate, wasmInit } from './rs.ts';
const DID_FILE_EXTENSION = '.did';
/**
* Options for controlling the generated output files.
*/
export type GenerateOutputOptions = {
/**
* If `true`, overwrite existing files. If `false`, abort on collisions.
*
* @default false
*/
force?: boolean;
/**
* Options for controlling the generated actor files.
*/
actor?:
| {
/**
* If `true`, skips generating the actor file (`<service-name>.ts`).
*
* @default false
*/
disabled: true;
}
| {
disabled?: false;
/**
* If `true`, generates a `<service-name>.d.ts` file that contains the same types of the `<service-name>.ts` file.
* Useful to add to LLMs' contexts' to give knowledge about what types are available in the service.
*
* Has no effect if `disabled` is `true`.
*
* @default false
*/
interfaceFile?: boolean;
};
};
/**
* Options for the {@link generate} function.
*/
export type GenerateOptions = {
/**
* The path to the `.did` file.
*/
didFile: string;
/**
* The path to the directory where the bindings will be generated.
*/
outDir: string;
/**
* Options for controlling the generated output files.
*/
output?: GenerateOutputOptions;
};
/**
* Generates the bindings for a `.did` file.
*
* For an explanation of the generated files, see the [Bindings Structure](https://js.icp.build/bindgen/latest/structure) docs page.
*
* @param options - The options for the generate function.
*
* @example
*
* Suppose we have a `.did` file in `./canisters/hello_world.did` and we want to generate bindings in `./src/bindings`.
*
* ```ts
* await generate({
* didFile: './canisters/hello_world.did',
* outDir: './src/bindings',
* });
* ```
*/
export async function generate(options: GenerateOptions) {
await wasmInit();
const {
didFile,
outDir,
output = {
force: false,
actor: {
disabled: false,
interfaceFile: false,
},
},
} = options;
const force = Boolean(output.force); // ensure force is a boolean
const didFilePath = resolve(didFile);
const outputFileName = basename(didFile, DID_FILE_EXTENSION);
await ensureDir(outDir);
await ensureDir(resolve(outDir, 'declarations'));
const result = wasmGenerate(didFilePath, outputFileName);
await writeBindings({
bindings: result,
outDir,
outputFileName,
output,
force,
});
}
type WriteBindingsOptions = {
bindings: WasmGenerateResult;
outDir: string;
outputFileName: string;
output: GenerateOutputOptions;
force: boolean;
};
async function writeBindings({
bindings,
outDir,
outputFileName,
output,
force,
}: WriteBindingsOptions) {
const declarationsTsFile = resolve(outDir, 'declarations', `${outputFileName}.did.d.ts`);
const declarationsJsFile = resolve(outDir, 'declarations', `${outputFileName}.did.js`);
const declarationsTs = prepareBinding(bindings.declarations_ts);
const declarationsJs = prepareBinding(bindings.declarations_js);
await writeFileSafe(declarationsTsFile, declarationsTs, force);
await writeFileSafe(declarationsJsFile, declarationsJs, force);
if (output.actor?.disabled) {
return;
}
const serviceTsFile = resolve(outDir, `${outputFileName}.ts`);
const serviceTs = prepareBinding(bindings.service_ts);
await writeFileSafe(serviceTsFile, serviceTs, force);
if (output.actor?.interfaceFile) {
const interfaceTsFile = resolve(outDir, `${outputFileName}.d.ts`);
const interfaceTs = prepareBinding(bindings.interface_ts);
await writeFileSafe(interfaceTsFile, interfaceTs, force);
}
}