@ic-reactor/vite-plugin 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -2
- package/dist/index.cjs +187 -63
- package/dist/index.d.cts +13 -2
- package/dist/index.d.ts +13 -2
- package/dist/index.js +187 -63
- package/llms.txt +8 -1
- package/package.json +6 -5
- package/src/env.ts +64 -16
- package/src/index.ts +310 -59
- package/src/index.test.ts +0 -349
package/README.md
CHANGED
|
@@ -69,9 +69,26 @@ icReactor({
|
|
|
69
69
|
clientManagerPath: "../../clients",
|
|
70
70
|
target: "react",
|
|
71
71
|
injectEnvironment: true,
|
|
72
|
+
failOnError: true,
|
|
72
73
|
})
|
|
73
74
|
```
|
|
74
75
|
|
|
76
|
+
Relative paths — `didFile`, `outDir` — resolve against Vite's resolved
|
|
77
|
+
`config.root`, not the directory vite was started from. If you set
|
|
78
|
+
`root: "frontend"`, write the paths as the project itself sees them.
|
|
79
|
+
|
|
80
|
+
Note `--config` alone does **not** change the root: `vite build --config
|
|
81
|
+
apps/web/vite.config.ts` still leaves `root` at the directory vite was started
|
|
82
|
+
from, so app-relative paths resolve against the monorepo root. Set `root` in the
|
|
83
|
+
config file, or pass it positionally (`vite build apps/web --config …`), for
|
|
84
|
+
those paths to mean what the app expects.
|
|
85
|
+
|
|
86
|
+
`failOnError` decides what a failed canister does to the run. It defaults to
|
|
87
|
+
`true` under `vite build` and `false` under `vite dev`: a build that quietly
|
|
88
|
+
ships the bindings left over from the last successful run is worse than no
|
|
89
|
+
build at all, while a dev server has to survive the broken intermediate states
|
|
90
|
+
of a `.did` file being edited.
|
|
91
|
+
|
|
75
92
|
### Per-canister options
|
|
76
93
|
|
|
77
94
|
- `name`
|
|
@@ -112,7 +129,10 @@ Set the `ICP_ENVIRONMENT` environment variable to target a non-default network
|
|
|
112
129
|
(defaults to `"local"`).
|
|
113
130
|
|
|
114
131
|
If environment detection fails, the plugin still falls back to proxying `/api`
|
|
115
|
-
to `http://127.0.0.1:4943`, but it will not inject canister metadata.
|
|
132
|
+
to `http://127.0.0.1:4943`, but it will not inject canister metadata. It warns
|
|
133
|
+
when that happens with canisters configured, because the failure is otherwise
|
|
134
|
+
indistinguishable from success until the app breaks on an undefined canister
|
|
135
|
+
id. Run with `DEBUG=ic-reactor` to see the `icp` output behind the warning.
|
|
116
136
|
|
|
117
137
|
## File Regeneration
|
|
118
138
|
|
|
@@ -121,7 +141,11 @@ the managed `index.generated.ts` implementation. The user-facing `index.ts`
|
|
|
121
141
|
entry is created once, then preserved unless it still matches the default
|
|
122
142
|
wrapper or a legacy generated scaffold that can be migrated automatically.
|
|
123
143
|
When a watched `.did` file changes, the plugin sends a full browser reload so
|
|
124
|
-
the new declarations are picked up.
|
|
144
|
+
the new declarations are picked up. Regeneration is serialized per canister —
|
|
145
|
+
saves that land while a run is in flight collapse into a single rerun — so two
|
|
146
|
+
rapid saves cannot interleave inside the pipeline's delete-then-write sequence.
|
|
147
|
+
A regeneration that fails is reported to the terminal and to the browser error
|
|
148
|
+
overlay rather than leaving the page on stale bindings.
|
|
125
149
|
|
|
126
150
|
## When To Use It
|
|
127
151
|
|
package/dist/index.cjs
CHANGED
|
@@ -39,44 +39,59 @@ var import_codegen = require("@ic-reactor/codegen");
|
|
|
39
39
|
// src/env.ts
|
|
40
40
|
var import_child_process = require("child_process");
|
|
41
41
|
function getIcEnvironmentInfo(canisterNames) {
|
|
42
|
-
const
|
|
42
|
+
const networkName = process.env.ICP_ENVIRONMENT || "local";
|
|
43
|
+
const diagnostics = [];
|
|
43
44
|
try {
|
|
44
45
|
const networkStatus = JSON.parse(
|
|
45
|
-
(0, import_child_process.execFileSync)("icp", ["network", "status", "-e",
|
|
46
|
+
(0, import_child_process.execFileSync)("icp", ["network", "status", "-e", networkName, "--json"], {
|
|
46
47
|
encoding: "utf-8",
|
|
47
|
-
|
|
48
|
-
//
|
|
48
|
+
// stderr is piped rather than ignored so a failure can explain itself.
|
|
49
|
+
// Piping still keeps it off the terminal — it only reaches the user if
|
|
50
|
+
// the caller decides to print the diagnostics we collect below.
|
|
51
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
49
52
|
})
|
|
50
53
|
);
|
|
51
54
|
const rootKey = networkStatus.root_key;
|
|
52
55
|
const proxyTarget = networkStatus.api_url || networkStatus.gateway_url || (networkStatus.port ? `http://127.0.0.1:${networkStatus.port}` : void 0);
|
|
53
56
|
if (!proxyTarget) {
|
|
54
|
-
|
|
57
|
+
diagnostics.push(
|
|
58
|
+
`\`icp network status -e ${networkName}\` reported no api_url, gateway_url or port`
|
|
59
|
+
);
|
|
60
|
+
return { environment: null, diagnostics };
|
|
55
61
|
}
|
|
56
62
|
const canisterIds = {};
|
|
57
63
|
for (const name of canisterNames) {
|
|
58
64
|
try {
|
|
59
65
|
const canisterId = (0, import_child_process.execFileSync)(
|
|
60
66
|
"icp",
|
|
61
|
-
["canister", "status", name, "-e",
|
|
62
|
-
{ encoding: "utf-8", stdio: ["ignore", "pipe", "
|
|
67
|
+
["canister", "status", name, "-e", networkName, "-i"],
|
|
68
|
+
{ encoding: "utf-8", stdio: ["ignore", "pipe", "pipe"] }
|
|
63
69
|
).trim();
|
|
64
70
|
if (canisterId) {
|
|
65
71
|
canisterIds[name] = canisterId;
|
|
66
72
|
}
|
|
67
|
-
} catch {
|
|
73
|
+
} catch (error) {
|
|
74
|
+
diagnostics.push(
|
|
75
|
+
`\`icp canister status ${name} -e ${networkName}\` failed: ${describeExecError(error)}`
|
|
76
|
+
);
|
|
68
77
|
}
|
|
69
78
|
}
|
|
70
|
-
const internetIdentityProvider = !canisterIds.internet_identity && isLocalhostGateway(proxyTarget) &&
|
|
79
|
+
const internetIdentityProvider = !canisterIds.internet_identity && isLocalhostGateway(proxyTarget) && networkName !== "ic" ? localInternetIdentityProvider(proxyTarget) : void 0;
|
|
71
80
|
return {
|
|
72
|
-
environment
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
81
|
+
environment: {
|
|
82
|
+
environment: networkName,
|
|
83
|
+
rootKey,
|
|
84
|
+
proxyTarget,
|
|
85
|
+
canisterIds,
|
|
86
|
+
internetIdentityProvider
|
|
87
|
+
},
|
|
88
|
+
diagnostics
|
|
77
89
|
};
|
|
78
90
|
} catch (error) {
|
|
79
|
-
|
|
91
|
+
diagnostics.push(
|
|
92
|
+
`\`icp network status -e ${networkName}\` failed: ${describeExecError(error)}`
|
|
93
|
+
);
|
|
94
|
+
return { environment: null, diagnostics };
|
|
80
95
|
}
|
|
81
96
|
}
|
|
82
97
|
function buildIcEnvCookie(canisterIds, rootKey, internetIdentityProvider) {
|
|
@@ -89,6 +104,15 @@ function buildIcEnvCookie(canisterIds, rootKey, internetIdentityProvider) {
|
|
|
89
104
|
}
|
|
90
105
|
return encodeURIComponent(parts.join("&"));
|
|
91
106
|
}
|
|
107
|
+
function describeExecError(error) {
|
|
108
|
+
const stderr = error?.stderr;
|
|
109
|
+
const text = typeof stderr === "string" ? stderr : stderr?.toString("utf-8");
|
|
110
|
+
const trimmed = text?.trim();
|
|
111
|
+
if (trimmed) {
|
|
112
|
+
return trimmed;
|
|
113
|
+
}
|
|
114
|
+
return error instanceof Error ? error.message : String(error);
|
|
115
|
+
}
|
|
92
116
|
function isLocalhostGateway(proxyTarget) {
|
|
93
117
|
try {
|
|
94
118
|
const { hostname } = new URL(proxyTarget);
|
|
@@ -104,40 +128,103 @@ function localInternetIdentityProvider(proxyTarget) {
|
|
|
104
128
|
}
|
|
105
129
|
|
|
106
130
|
// src/index.ts
|
|
131
|
+
var PLUGIN_NAME = "ic-reactor-plugin";
|
|
132
|
+
var DEFAULT_LOCAL_REPLICA = "http://127.0.0.1:4943";
|
|
107
133
|
function icReactor(options) {
|
|
108
134
|
const {
|
|
109
135
|
canisters,
|
|
110
136
|
outDir = "src/declarations",
|
|
111
137
|
clientManagerPath = "../../clients",
|
|
112
138
|
target = "react",
|
|
113
|
-
injectEnvironment = true
|
|
139
|
+
injectEnvironment = true,
|
|
140
|
+
failOnError
|
|
114
141
|
} = options;
|
|
115
142
|
const globalConfig = {
|
|
116
143
|
outDir,
|
|
117
144
|
clientManagerPath,
|
|
118
145
|
target
|
|
119
146
|
};
|
|
120
|
-
|
|
147
|
+
let projectRoot = process.cwd();
|
|
148
|
+
let command = "build";
|
|
149
|
+
let devServer = null;
|
|
121
150
|
const resolveDidPath = (didFile) => import_node_path.default.normalize(
|
|
122
151
|
import_node_path.default.isAbsolute(didFile) ? didFile : import_node_path.default.resolve(projectRoot, didFile)
|
|
123
152
|
);
|
|
124
153
|
const configuredCanisterIds = Object.fromEntries(
|
|
125
154
|
canisters.filter((canister) => !!canister.canisterId).map((canister) => [canister.name, canister.canisterId])
|
|
126
155
|
);
|
|
156
|
+
let pendingFailure = null;
|
|
157
|
+
const reportFailure = (server, message, cause) => {
|
|
158
|
+
console.error(`[ic-reactor] ${message}`);
|
|
159
|
+
const err = {
|
|
160
|
+
message: `[ic-reactor] ${message}`,
|
|
161
|
+
stack: cause instanceof Error && cause.stack ? cause.stack : "",
|
|
162
|
+
plugin: PLUGIN_NAME
|
|
163
|
+
};
|
|
164
|
+
pendingFailure = { message: err.message, stack: err.stack };
|
|
165
|
+
server?.ws.send({ type: "error", err });
|
|
166
|
+
};
|
|
167
|
+
const inFlight = /* @__PURE__ */ new Map();
|
|
168
|
+
const rerunQueued = /* @__PURE__ */ new Set();
|
|
169
|
+
const regenerate = (canisterConfig, server) => {
|
|
170
|
+
const { name } = canisterConfig;
|
|
171
|
+
const running = inFlight.get(name);
|
|
172
|
+
if (running) {
|
|
173
|
+
rerunQueued.add(name);
|
|
174
|
+
return running;
|
|
175
|
+
}
|
|
176
|
+
const run = (0, import_codegen.runCanisterPipeline)({
|
|
177
|
+
canisterConfig,
|
|
178
|
+
projectRoot,
|
|
179
|
+
globalConfig
|
|
180
|
+
}).then((result) => {
|
|
181
|
+
if (result.success) {
|
|
182
|
+
pendingFailure = null;
|
|
183
|
+
server.ws.send({ type: "full-reload" });
|
|
184
|
+
} else {
|
|
185
|
+
reportFailure(
|
|
186
|
+
server,
|
|
187
|
+
`Regeneration failed for ${name}: ${result.error ?? "unknown error"}`
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
}).catch((error) => {
|
|
191
|
+
reportFailure(
|
|
192
|
+
server,
|
|
193
|
+
`Regeneration failed for ${name}: ${describeError(error)}`,
|
|
194
|
+
error
|
|
195
|
+
);
|
|
196
|
+
}).finally(() => {
|
|
197
|
+
inFlight.delete(name);
|
|
198
|
+
if (rerunQueued.delete(name)) {
|
|
199
|
+
void regenerate(canisterConfig, server);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
inFlight.set(name, run);
|
|
203
|
+
return run;
|
|
204
|
+
};
|
|
127
205
|
const plugin = {
|
|
128
|
-
name:
|
|
206
|
+
name: PLUGIN_NAME,
|
|
129
207
|
enforce: "pre",
|
|
130
208
|
// Run before other plugins
|
|
131
|
-
config(_config, { command }) {
|
|
132
|
-
|
|
209
|
+
config(_config, { command: viteCommand }) {
|
|
210
|
+
command = viteCommand;
|
|
211
|
+
if (viteCommand !== "serve" || !injectEnvironment) {
|
|
133
212
|
return {};
|
|
134
213
|
}
|
|
135
214
|
const canisterNames = canisters.map((c) => c.name).filter((n) => !!n);
|
|
136
215
|
if (!canisterNames.includes("internet_identity")) {
|
|
137
216
|
canisterNames.push("internet_identity");
|
|
138
217
|
}
|
|
139
|
-
const icEnv = getIcEnvironmentInfo(canisterNames);
|
|
218
|
+
const { environment: icEnv, diagnostics } = getIcEnvironmentInfo(canisterNames);
|
|
140
219
|
if (!icEnv) {
|
|
220
|
+
if (canisters.length > 0) {
|
|
221
|
+
console.warn(
|
|
222
|
+
`[ic-reactor] Could not detect the local IC environment, falling back to ${DEFAULT_LOCAL_REPLICA}. Canister IDs and the root key will not be injected \u2014 is the local replica running? Re-run with DEBUG=ic-reactor to see the \`icp\` output.`
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
for (const diagnostic of diagnostics) {
|
|
226
|
+
debugLog(diagnostic);
|
|
227
|
+
}
|
|
141
228
|
const envOnlyCookie = canisters.length === 0 ? buildIcEnvCookie(
|
|
142
229
|
{},
|
|
143
230
|
void 0,
|
|
@@ -150,13 +237,26 @@ function icReactor(options) {
|
|
|
150
237
|
} : void 0,
|
|
151
238
|
proxy: {
|
|
152
239
|
"/api": {
|
|
153
|
-
target:
|
|
240
|
+
target: DEFAULT_LOCAL_REPLICA,
|
|
154
241
|
changeOrigin: true
|
|
155
242
|
}
|
|
156
243
|
}
|
|
157
244
|
}
|
|
158
245
|
};
|
|
159
246
|
}
|
|
247
|
+
const missingCanisterIds = canisters.map((canister) => canister.name).filter((name) => !!name).filter(
|
|
248
|
+
(name) => !icEnv.canisterIds[name] && !configuredCanisterIds[name]
|
|
249
|
+
);
|
|
250
|
+
if (missingCanisterIds.length > 0) {
|
|
251
|
+
const names = missingCanisterIds.map((name) => `"${name}"`).join(", ");
|
|
252
|
+
const it = missingCanisterIds.length === 1 ? "it" : "them";
|
|
253
|
+
console.warn(
|
|
254
|
+
`[ic-reactor] The local replica is running, but no canister ID could be resolved for ${names}. Deploy ${it} (\`icp deploy\`) \u2014 until then the injected ic_env carries no PUBLIC_CANISTER_ID for ${it} and the app will see an undefined canister id. Re-run with DEBUG=ic-reactor to see the \`icp\` output.`
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
for (const diagnostic of diagnostics) {
|
|
258
|
+
debugLog(diagnostic);
|
|
259
|
+
}
|
|
160
260
|
const cookieValue = buildIcEnvCookie(
|
|
161
261
|
{
|
|
162
262
|
...icEnv.canisterIds,
|
|
@@ -179,7 +279,19 @@ function icReactor(options) {
|
|
|
179
279
|
}
|
|
180
280
|
};
|
|
181
281
|
},
|
|
282
|
+
configResolved(config) {
|
|
283
|
+
projectRoot = config.root;
|
|
284
|
+
command = config.command;
|
|
285
|
+
},
|
|
182
286
|
configureServer(server) {
|
|
287
|
+
devServer = server;
|
|
288
|
+
server.ws.on?.("connection", () => {
|
|
289
|
+
if (!pendingFailure) return;
|
|
290
|
+
server.ws.send({
|
|
291
|
+
type: "error",
|
|
292
|
+
err: { ...pendingFailure, plugin: PLUGIN_NAME }
|
|
293
|
+
});
|
|
294
|
+
});
|
|
183
295
|
const didFiles = canisters.map((c) => resolveDidPath(c.didFile));
|
|
184
296
|
server.watcher.add(didFiles);
|
|
185
297
|
},
|
|
@@ -187,55 +299,67 @@ function icReactor(options) {
|
|
|
187
299
|
console.log(
|
|
188
300
|
`[ic-reactor] Generating canister bindings for ${canisters.length} canisters...`
|
|
189
301
|
);
|
|
190
|
-
await Promise.allSettled(
|
|
191
|
-
canisters.map(
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
canisterConfig,
|
|
195
|
-
projectRoot,
|
|
196
|
-
globalConfig
|
|
197
|
-
});
|
|
198
|
-
if (!result.success) {
|
|
199
|
-
console.error(
|
|
200
|
-
`[ic-reactor] Failed to generate ${canisterConfig.name}: ${result.error}`
|
|
201
|
-
);
|
|
202
|
-
}
|
|
203
|
-
} catch (err) {
|
|
204
|
-
console.error(
|
|
205
|
-
`[ic-reactor] Error generating ${canisterConfig.name}:`,
|
|
206
|
-
err
|
|
207
|
-
);
|
|
208
|
-
}
|
|
209
|
-
})
|
|
210
|
-
);
|
|
211
|
-
},
|
|
212
|
-
handleHotUpdate({ file, server }) {
|
|
213
|
-
if (file.endsWith(".did")) {
|
|
214
|
-
const affectedCanister = canisters.find((c) => {
|
|
215
|
-
const configPath = resolveDidPath(c.didFile);
|
|
216
|
-
return configPath === import_node_path.default.normalize(file);
|
|
217
|
-
});
|
|
218
|
-
if (affectedCanister) {
|
|
219
|
-
console.log(
|
|
220
|
-
`[ic-reactor] .did file changed: ${affectedCanister.name}. Regenerating...`
|
|
221
|
-
);
|
|
222
|
-
(0, import_codegen.runCanisterPipeline)({
|
|
223
|
-
canisterConfig: affectedCanister,
|
|
302
|
+
const outcomes = await Promise.allSettled(
|
|
303
|
+
canisters.map(
|
|
304
|
+
(canisterConfig) => (0, import_codegen.runCanisterPipeline)({
|
|
305
|
+
canisterConfig,
|
|
224
306
|
projectRoot,
|
|
225
307
|
globalConfig
|
|
226
|
-
})
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
});
|
|
308
|
+
})
|
|
309
|
+
)
|
|
310
|
+
);
|
|
311
|
+
const failures = outcomes.flatMap((outcome, index) => {
|
|
312
|
+
const name = canisters[index]?.name ?? `canister #${index}`;
|
|
313
|
+
if (outcome.status === "rejected") {
|
|
314
|
+
return [`${name}: ${describeError(outcome.reason)}`];
|
|
233
315
|
}
|
|
316
|
+
if (!outcome.value.success) {
|
|
317
|
+
return [`${name}: ${outcome.value.error ?? "unknown error"}`];
|
|
318
|
+
}
|
|
319
|
+
return [];
|
|
320
|
+
});
|
|
321
|
+
if (failures.length === 0) {
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
const message = `Failed to generate ${failures.length} of ${canisters.length} canisters:
|
|
325
|
+
` + failures.map((failure) => ` - ${failure}`).join("\n");
|
|
326
|
+
if (failOnError ?? command === "build") {
|
|
327
|
+
this.error(`[ic-reactor] ${message}`);
|
|
234
328
|
}
|
|
329
|
+
reportFailure(devServer, message);
|
|
330
|
+
},
|
|
331
|
+
handleHotUpdate({ file, server }) {
|
|
332
|
+
if (!file.endsWith(".did")) {
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
const changedPath = import_node_path.default.normalize(file);
|
|
336
|
+
const affectedCanister = canisters.find(
|
|
337
|
+
// Check if changed file matches configured didFile
|
|
338
|
+
(canister) => resolveDidPath(canister.didFile) === changedPath
|
|
339
|
+
);
|
|
340
|
+
if (!affectedCanister) {
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
console.log(
|
|
344
|
+
`[ic-reactor] .did file changed: ${affectedCanister.name}. Regenerating...`
|
|
345
|
+
);
|
|
346
|
+
return regenerate(affectedCanister, server);
|
|
235
347
|
}
|
|
236
348
|
};
|
|
237
349
|
return plugin;
|
|
238
350
|
}
|
|
351
|
+
function describeError(error) {
|
|
352
|
+
return error instanceof Error ? error.message : String(error);
|
|
353
|
+
}
|
|
354
|
+
function debugLog(message) {
|
|
355
|
+
const enabled = (process.env.DEBUG ?? "").split(",").some((entry) => {
|
|
356
|
+
const scope = entry.trim();
|
|
357
|
+
return scope === "*" || scope === "ic-reactor" || scope.startsWith("ic-reactor:");
|
|
358
|
+
});
|
|
359
|
+
if (enabled) {
|
|
360
|
+
console.debug(`[ic-reactor:debug] ${message}`);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
239
363
|
// Annotate the CommonJS export names for ESM import in node:
|
|
240
364
|
0 && (module.exports = {
|
|
241
365
|
icReactor
|
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
1
2
|
import { CanisterConfig, CodegenTarget } from '@ic-reactor/codegen';
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -16,7 +17,7 @@ interface IcReactorPluginOptions {
|
|
|
16
17
|
*/
|
|
17
18
|
canisters: CanisterConfig[];
|
|
18
19
|
/**
|
|
19
|
-
* Default output directory (relative to project root).
|
|
20
|
+
* Default output directory (relative to the Vite project root).
|
|
20
21
|
* Default: "src/declarations"
|
|
21
22
|
*/
|
|
22
23
|
outDir?: string;
|
|
@@ -35,7 +36,17 @@ interface IcReactorPluginOptions {
|
|
|
35
36
|
* Default: true
|
|
36
37
|
*/
|
|
37
38
|
injectEnvironment?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Abort the Vite run when a canister fails to generate.
|
|
41
|
+
*
|
|
42
|
+
* Default: `true` under `vite build`, `false` under `vite dev`. A build that
|
|
43
|
+
* silently ships the bindings left over from the last successful run is worse
|
|
44
|
+
* than no build at all, while a dev server has to survive the broken
|
|
45
|
+
* intermediate states of a `.did` file being edited — there the failure is
|
|
46
|
+
* reported to the terminal and the browser error overlay instead.
|
|
47
|
+
*/
|
|
48
|
+
failOnError?: boolean;
|
|
38
49
|
}
|
|
39
|
-
declare function icReactor(options: IcReactorPluginOptions):
|
|
50
|
+
declare function icReactor(options: IcReactorPluginOptions): Plugin;
|
|
40
51
|
|
|
41
52
|
export { type IcReactorPluginOptions, icReactor };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
1
2
|
import { CanisterConfig, CodegenTarget } from '@ic-reactor/codegen';
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -16,7 +17,7 @@ interface IcReactorPluginOptions {
|
|
|
16
17
|
*/
|
|
17
18
|
canisters: CanisterConfig[];
|
|
18
19
|
/**
|
|
19
|
-
* Default output directory (relative to project root).
|
|
20
|
+
* Default output directory (relative to the Vite project root).
|
|
20
21
|
* Default: "src/declarations"
|
|
21
22
|
*/
|
|
22
23
|
outDir?: string;
|
|
@@ -35,7 +36,17 @@ interface IcReactorPluginOptions {
|
|
|
35
36
|
* Default: true
|
|
36
37
|
*/
|
|
37
38
|
injectEnvironment?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Abort the Vite run when a canister fails to generate.
|
|
41
|
+
*
|
|
42
|
+
* Default: `true` under `vite build`, `false` under `vite dev`. A build that
|
|
43
|
+
* silently ships the bindings left over from the last successful run is worse
|
|
44
|
+
* than no build at all, while a dev server has to survive the broken
|
|
45
|
+
* intermediate states of a `.did` file being edited — there the failure is
|
|
46
|
+
* reported to the terminal and the browser error overlay instead.
|
|
47
|
+
*/
|
|
48
|
+
failOnError?: boolean;
|
|
38
49
|
}
|
|
39
|
-
declare function icReactor(options: IcReactorPluginOptions):
|
|
50
|
+
declare function icReactor(options: IcReactorPluginOptions): Plugin;
|
|
40
51
|
|
|
41
52
|
export { type IcReactorPluginOptions, icReactor };
|