@sdeverywhere/plugin-check 0.3.1 → 0.3.2
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 +24 -3
- package/dist/index.cjs +208 -43
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -0
- package/dist/index.js +203 -42
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/template-bundle/tsconfig.json +1 -1
- package/template-report/src/env.d.ts +0 -1
- package/template-report/src/index.ts +7 -3
- package/template-report/tsconfig.json +1 -1
- package/template-tests/src/index.ts +5 -2
- package/template-tests/tsconfig.json +1 -1
- package/template-tests/src/env.d.ts +0 -5
package/README.md
CHANGED
|
@@ -1,11 +1,32 @@
|
|
|
1
1
|
# @sdeverywhere/plugin-check
|
|
2
2
|
|
|
3
|
-
This package provides a plugin that runs model checks and comparison tests for a
|
|
4
|
-
|
|
3
|
+
This package provides a plugin that runs model checks and comparison tests for a given System Dynamics model generated by [SDEverywhere](https://github.com/climateinteractive/SDEverywhere).
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
The best way to get started with SDEverywhere is to follow the [Quick Start](https://github.com/climateinteractive/SDEverywhere#quick-start) instructions.
|
|
8
|
+
If you follow those instructions, the `@sdeverywhere/plugin-check` package will be added to your project automatically, in which case you can skip the next section and jump straight to the ["Usage"](#usage) section below.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
# npm
|
|
14
|
+
npm install --save-dev @sdeverywhere/plugin-check
|
|
15
|
+
|
|
16
|
+
# pnpm
|
|
17
|
+
pnpm add -D @sdeverywhere/plugin-check
|
|
18
|
+
|
|
19
|
+
# yarn
|
|
20
|
+
yarn add -D @sdeverywhere/plugin-check
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
_TODO: This section needs to be fleshed out. In the meantime, you can refer to the API documentation below for the options used to configure this plugin._
|
|
5
26
|
|
|
6
27
|
## Documentation
|
|
7
28
|
|
|
8
|
-
|
|
29
|
+
API documentation (for plugin configuration options) is available in the [`docs`](./docs/index.md) directory.
|
|
9
30
|
|
|
10
31
|
## License
|
|
11
32
|
|
package/dist/index.cjs
CHANGED
|
@@ -17,6 +17,10 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
17
|
return to;
|
|
18
18
|
};
|
|
19
19
|
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
20
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
21
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
22
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
23
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
20
24
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
21
25
|
mod
|
|
22
26
|
));
|
|
@@ -29,6 +33,10 @@ __export(src_exports, {
|
|
|
29
33
|
});
|
|
30
34
|
module.exports = __toCommonJS(src_exports);
|
|
31
35
|
|
|
36
|
+
// ../../node_modules/.pnpm/tsup@7.2.0_typescript@5.2.2/node_modules/tsup/assets/cjs_shims.js
|
|
37
|
+
var getImportMetaUrl = () => typeof document === "undefined" ? new URL("file:" + __filename).href : document.currentScript && document.currentScript.src || new URL("main.js", document.baseURI).href;
|
|
38
|
+
var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
39
|
+
|
|
32
40
|
// src/plugin.ts
|
|
33
41
|
var import_fs2 = require("fs");
|
|
34
42
|
var import_promises = require("fs/promises");
|
|
@@ -177,9 +185,8 @@ function sdeNameForVensimVarName(varName) {
|
|
|
177
185
|
}
|
|
178
186
|
|
|
179
187
|
// src/vite-config-for-bundle.ts
|
|
180
|
-
var
|
|
181
|
-
var
|
|
182
|
-
var __dirname = (0, import_path.dirname)(__filename);
|
|
188
|
+
var __filename2 = (0, import_url.fileURLToPath)(importMetaUrl);
|
|
189
|
+
var __dirname = (0, import_path.dirname)(__filename2);
|
|
183
190
|
function injectModelSpec(prepDir, modelSpec) {
|
|
184
191
|
const inputSpecs = modelSpec.inputs.map((i) => {
|
|
185
192
|
const varId = sdeNameForVensimVarName(i.varName);
|
|
@@ -228,20 +235,58 @@ export const dataSizeInBytes = ${dataSizeInBytes};
|
|
|
228
235
|
}
|
|
229
236
|
};
|
|
230
237
|
}
|
|
238
|
+
function overrideViteResolvePlugin(viteConfig) {
|
|
239
|
+
const resolvePlugin = viteConfig.plugins.find((p) => p.name === "vite:resolve");
|
|
240
|
+
if (resolvePlugin === void 0) {
|
|
241
|
+
throw new Error("Failed to locate the built-in vite:resolve plugin");
|
|
242
|
+
}
|
|
243
|
+
const originalResolveId = resolvePlugin.resolveId;
|
|
244
|
+
resolvePlugin.resolveId = async function resolveId(id, importer, options) {
|
|
245
|
+
if (id.startsWith("./implementation") && importer.includes("threads/dist-esm")) {
|
|
246
|
+
const idFileName = id.replace("./", "");
|
|
247
|
+
const importerFileName = (0, import_path.basename)(importer);
|
|
248
|
+
const resolvedId = importer.replace(importerFileName, `${idFileName}.js`);
|
|
249
|
+
return {
|
|
250
|
+
id: resolvedId,
|
|
251
|
+
moduleSideEffects: false
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
return originalResolveId.call(this, id, importer, options);
|
|
255
|
+
};
|
|
256
|
+
}
|
|
231
257
|
async function createViteConfigForBundle(prepDir, modelSpec) {
|
|
232
258
|
const root = (0, import_path.resolve)(__dirname, "..", "template-bundle");
|
|
233
259
|
const outDir = (0, import_path.relative)(root, prepDir);
|
|
234
260
|
const modelWorkerPath = (0, import_path.join)(prepDir, "staged", "model", "worker.js?raw");
|
|
235
261
|
return {
|
|
262
|
+
// Don't use an external config file
|
|
236
263
|
configFile: false,
|
|
264
|
+
// Use the root directory configured above
|
|
237
265
|
root,
|
|
266
|
+
// Don't clear the screen in dev mode so that we can see builder output
|
|
238
267
|
clearScreen: false,
|
|
268
|
+
// TODO: Disable vite output by default?
|
|
269
|
+
// logLevel: 'silent',
|
|
270
|
+
// Configure path aliases
|
|
239
271
|
resolve: {
|
|
240
272
|
alias: [
|
|
273
|
+
// Inject the configured model worker
|
|
241
274
|
{
|
|
242
275
|
find: "@_model_worker_",
|
|
243
276
|
replacement: modelWorkerPath
|
|
244
277
|
},
|
|
278
|
+
// XXX: Prevent Vite from using the `browser` section of `threads/package.json`
|
|
279
|
+
// since we want to force the use of the general module (under dist-esm) that chooses
|
|
280
|
+
// the correct implementation (Web Worker vs worker_threads) at runtime. Currently
|
|
281
|
+
// Vite's library mode is browser focused and generally chooses the right imports,
|
|
282
|
+
// except in the case of the threads package where we want to use the generic
|
|
283
|
+
// `implementation.js` that chooses between Web Worker and worker_threads at runtime.
|
|
284
|
+
// Note that we could in theory set `resolve.browserField` to false, but that would
|
|
285
|
+
// make Vite not use the browser field for all other packages, and there is not
|
|
286
|
+
// currently a way to tell Vite to use the browser field on a case-by-case basis.
|
|
287
|
+
// So for now we need this workaround here to make it resolve to `dist-esm`, and then
|
|
288
|
+
// a second workaround in `overrideViteResolvePlugin` to prevent the resolver from
|
|
289
|
+
// using the browser field when resolving the threads package.
|
|
245
290
|
{
|
|
246
291
|
find: "threads",
|
|
247
292
|
replacement: "threads",
|
|
@@ -258,18 +303,40 @@ async function createViteConfigForBundle(prepDir, modelSpec) {
|
|
|
258
303
|
]
|
|
259
304
|
},
|
|
260
305
|
plugins: [
|
|
261
|
-
|
|
306
|
+
// Use a virtual module plugin to inject the model spec values
|
|
307
|
+
injectModelSpec(prepDir, modelSpec),
|
|
308
|
+
// XXX: Install a wrapper around the built-in `vite:resolve` plugin so that we can
|
|
309
|
+
// override the default resolver behavior that tries to resolve the `browser` section
|
|
310
|
+
// of the `package.json` for the threads package.
|
|
311
|
+
{
|
|
312
|
+
name: "vite-plugin-override-resolve",
|
|
313
|
+
configResolved(viteConfig) {
|
|
314
|
+
overrideViteResolvePlugin(viteConfig);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
262
317
|
],
|
|
263
318
|
build: {
|
|
319
|
+
// Write output files to the configured directory (instead of the default `dist`);
|
|
320
|
+
// note that this must be relative to the project `root`
|
|
264
321
|
outDir,
|
|
265
322
|
emptyOutDir: false,
|
|
323
|
+
// Uncomment for debugging purposes
|
|
324
|
+
// minify: false,
|
|
266
325
|
lib: {
|
|
267
326
|
entry: "./src/index.ts",
|
|
268
327
|
formats: ["es"],
|
|
269
328
|
fileName: () => "check-bundle.js"
|
|
270
329
|
},
|
|
271
330
|
rollupOptions: {
|
|
331
|
+
// Don't transform Node imports used by threads.js
|
|
272
332
|
external: ["events", "os", "path", "url"],
|
|
333
|
+
// XXX: Insert custom code at the top of the generated bundle that defines
|
|
334
|
+
// the special `__non_webpack_require__` function that is used by threads.js
|
|
335
|
+
// in its Node implementation. This import ensures that threads.js uses
|
|
336
|
+
// the native `worker_threads` implementation when using the bundle in a
|
|
337
|
+
// Node environment. When importing the bundle for use in the browser,
|
|
338
|
+
// Vite will transform this import into an empty module due to the empty
|
|
339
|
+
// polyfill that is configured in `vite-config-for-report.ts`.
|
|
273
340
|
output: {
|
|
274
341
|
banner: `
|
|
275
342
|
import * as worker_threads from 'worker_threads'
|
|
@@ -292,18 +359,16 @@ let __non_webpack_require__ = () => {
|
|
|
292
359
|
var import_path2 = require("path");
|
|
293
360
|
var import_url2 = require("url");
|
|
294
361
|
var import_plugin_replace = __toESM(require("@rollup/plugin-replace"), 1);
|
|
295
|
-
var
|
|
296
|
-
var
|
|
297
|
-
var __dirname2 = (0, import_path2.dirname)(__filename2);
|
|
362
|
+
var __filename3 = (0, import_url2.fileURLToPath)(importMetaUrl);
|
|
363
|
+
var __dirname2 = (0, import_path2.dirname)(__filename3);
|
|
298
364
|
function createViteConfigForReport(options, projDir, prepDir, currentBundleName, currentBundlePath, testConfigPath, suiteSummary) {
|
|
299
|
-
var _a;
|
|
300
365
|
const root = (0, import_path2.resolve)(__dirname2, "..", "template-report");
|
|
301
366
|
const templateSrcDir = (0, import_path2.resolve)(root, "src");
|
|
302
367
|
const relProjDir = (0, import_path2.relative)(templateSrcDir, projDir);
|
|
303
368
|
const relProjDirPath = relProjDir.replaceAll("\\", "/");
|
|
304
369
|
const baselinesPath = `${relProjDirPath}/baselines/*.js`;
|
|
305
370
|
let reportPath;
|
|
306
|
-
if (options
|
|
371
|
+
if (options?.reportPath) {
|
|
307
372
|
reportPath = options.reportPath;
|
|
308
373
|
} else {
|
|
309
374
|
reportPath = (0, import_path2.join)(prepDir, "check-report");
|
|
@@ -323,57 +388,113 @@ function createViteConfigForReport(options, projDir, prepDir, currentBundleName,
|
|
|
323
388
|
};
|
|
324
389
|
};
|
|
325
390
|
return {
|
|
391
|
+
// Don't use an external config file
|
|
326
392
|
configFile: false,
|
|
393
|
+
// Use the root directory configured above
|
|
327
394
|
root,
|
|
395
|
+
// Use `.` as the base directory (instead of the default `/`); this controls
|
|
396
|
+
// how the path to the js/css files are generated in `index.html`
|
|
328
397
|
base: "",
|
|
398
|
+
// Use a custom cache directory under `prepDir`, as otherwise Vite will use
|
|
399
|
+
// `packages/plugin-check/template-report/node_modules/.vite`, and we want to
|
|
400
|
+
// avoid generating files in `template-report` (which should be read-only)
|
|
329
401
|
cacheDir: (0, import_path2.join)(prepDir, ".vite-check-report"),
|
|
402
|
+
// Load static files from `static` (instead of the default `public`)
|
|
403
|
+
// publicDir: 'static',
|
|
404
|
+
// Don't clear the screen in dev mode so that we can see builder output
|
|
330
405
|
clearScreen: false,
|
|
406
|
+
// TODO
|
|
407
|
+
// logLevel: 'silent',
|
|
331
408
|
optimizeDeps: {
|
|
409
|
+
// Prevent Vite from examining other html files when scanning entrypoints
|
|
410
|
+
// for dependency optimization
|
|
332
411
|
entries: ["index.html"],
|
|
412
|
+
// XXX: When plugin-check is installed via pnpm, the Vite dev server seems
|
|
413
|
+
// to have no trouble resolving other dependencies using the optimizeDeps
|
|
414
|
+
// mechanism. However, this fails when the package is installed via yarn
|
|
415
|
+
// or npm (probably due to the fact that the `template-report` directory
|
|
416
|
+
// is located under the top-level `node_modules` directory); in the browser,
|
|
417
|
+
// there will be "import not found" errors for the packages referenced below.
|
|
418
|
+
// As a terrible workaround, explicitly include the direct dependencies so
|
|
419
|
+
// that Vite optimizes them; this works for pnpm, yarn, and npm. We should
|
|
420
|
+
// find a less fragile solution.
|
|
333
421
|
include: [
|
|
334
|
-
|
|
335
|
-
"
|
|
336
|
-
"
|
|
337
|
-
"
|
|
338
|
-
"
|
|
339
|
-
|
|
340
|
-
"
|
|
422
|
+
// from check-core
|
|
423
|
+
"@sdeverywhere/check-core > assert-never",
|
|
424
|
+
"@sdeverywhere/check-core > ajv",
|
|
425
|
+
"@sdeverywhere/check-core > neverthrow",
|
|
426
|
+
"@sdeverywhere/check-core > yaml",
|
|
427
|
+
// from check-ui-shell
|
|
428
|
+
"@sdeverywhere/check-ui-shell > fontfaceobserver",
|
|
429
|
+
"@sdeverywhere/check-ui-shell > copy-text-to-clipboard",
|
|
430
|
+
"@sdeverywhere/check-ui-shell > chart.js"
|
|
341
431
|
],
|
|
342
432
|
exclude: [
|
|
343
|
-
|
|
344
|
-
|
|
433
|
+
// XXX: The threads.js implementation references `tiny-worker` as an optional
|
|
434
|
+
// dependency, but it doesn't get used at runtime, so we can just exclude it
|
|
435
|
+
// so that Vite doesn't complain in dev mode
|
|
436
|
+
"tiny-worker"
|
|
437
|
+
// XXX: Similarly, chart.js treats `moment` as an optional dependency, but we
|
|
438
|
+
// don't use it at runtime; we need to exclude it here, otherwise Vite will
|
|
439
|
+
// complain about missing dependencies in dev mode
|
|
440
|
+
// 'moment'
|
|
345
441
|
]
|
|
346
442
|
},
|
|
443
|
+
// Configure path aliases
|
|
347
444
|
resolve: {
|
|
348
445
|
alias: [
|
|
349
|
-
|
|
446
|
+
// Use the configured "baseline" bundle if defined, otherwise use the "empty" bundle
|
|
447
|
+
// (which will cause comparison tests to be skipped)
|
|
448
|
+
alias("@_baseline_bundle_", options?.baseline ? options.baseline.path : "/src/empty-bundle.ts"),
|
|
449
|
+
// Use the configured "current" bundle
|
|
350
450
|
alias("@_current_bundle_", currentBundlePath),
|
|
451
|
+
// Use the configured test config file
|
|
351
452
|
alias("@_test_config_", testConfigPath),
|
|
453
|
+
// Make the overlay use the `messages.html` file that is written to the prep directory
|
|
352
454
|
alias("@_prep_", prepDir),
|
|
455
|
+
// XXX: Include no-op polyfills for these modules that are used in the Node-specific
|
|
456
|
+
// implementation of threads.js; this allows us to use one bundle that works in both
|
|
457
|
+
// Node and browser environments
|
|
353
458
|
noopPolyfillAlias("events"),
|
|
459
|
+
noopPolyfillAlias("fs"),
|
|
354
460
|
noopPolyfillAlias("os"),
|
|
355
461
|
noopPolyfillAlias("path"),
|
|
356
|
-
noopPolyfillAlias("url")
|
|
462
|
+
noopPolyfillAlias("url"),
|
|
463
|
+
noopPolyfillAlias("worker_threads")
|
|
357
464
|
]
|
|
358
465
|
},
|
|
466
|
+
// Inject special values into the generated JS
|
|
359
467
|
define: {
|
|
468
|
+
// Inject the summary JSON into the build
|
|
360
469
|
__SUITE_SUMMARY_JSON__: JSON.stringify(suiteSummaryJson),
|
|
361
|
-
|
|
470
|
+
// Inject the baseline branch name
|
|
471
|
+
__BASELINE_NAME__: JSON.stringify(options?.baseline?.name || ""),
|
|
472
|
+
// Inject the current branch name
|
|
362
473
|
__CURRENT_NAME__: JSON.stringify(currentBundleName)
|
|
363
474
|
},
|
|
364
475
|
plugins: [
|
|
476
|
+
// Inject special values into the generated JS
|
|
477
|
+
// TODO: We currently have to use `@rollup/plugin-replace` instead of Vite's
|
|
478
|
+
// built-in `define` feature because the latter does not seem to run before
|
|
479
|
+
// the glob handler (which requires the glob to be injected as a literal)
|
|
365
480
|
(0, import_plugin_replace.default)({
|
|
366
481
|
preventAssignment: true,
|
|
482
|
+
delimiters: ["", ""],
|
|
367
483
|
values: {
|
|
368
|
-
|
|
484
|
+
// Inject the path for baseline bundles
|
|
485
|
+
"./__BASELINE_BUNDLES_PATH__": baselinesPath
|
|
369
486
|
}
|
|
370
487
|
})
|
|
371
488
|
],
|
|
372
489
|
build: {
|
|
490
|
+
// Write output files to the configured directory (instead of the default `dist`);
|
|
491
|
+
// note that this must be relative to the project `root`
|
|
373
492
|
outDir,
|
|
493
|
+
// Write js/css files to `public` (instead of the default `<outDir>/assets`)
|
|
374
494
|
assetsDir: "",
|
|
375
495
|
rollupOptions: {
|
|
376
496
|
output: {
|
|
497
|
+
// XXX: Prevent vite from creating a separate `vendor.js` file
|
|
377
498
|
manualChunks: void 0
|
|
378
499
|
},
|
|
379
500
|
onwarn: (warning, warn) => {
|
|
@@ -384,8 +505,14 @@ function createViteConfigForReport(options, projDir, prepDir, currentBundleName,
|
|
|
384
505
|
}
|
|
385
506
|
},
|
|
386
507
|
server: {
|
|
387
|
-
|
|
508
|
+
// Run the dev server at `localhost:8081` by default
|
|
509
|
+
port: options?.serverPort || 8081,
|
|
510
|
+
// Open the app in the browser by default
|
|
388
511
|
open: "/index.html",
|
|
512
|
+
// XXX: Add a small delay, otherwise on macOS we sometimes get multiple
|
|
513
|
+
// change events when a file is saved just once. That is a relatively
|
|
514
|
+
// harmless issue except that it causes redundant messages in the console
|
|
515
|
+
// and can cause extra churn when refreshing the app.
|
|
389
516
|
watch: {
|
|
390
517
|
awaitWriteFinish: {
|
|
391
518
|
stabilityThreshold: 100
|
|
@@ -398,9 +525,9 @@ function createViteConfigForReport(options, projDir, prepDir, currentBundleName,
|
|
|
398
525
|
// src/vite-config-for-tests.ts
|
|
399
526
|
var import_path3 = require("path");
|
|
400
527
|
var import_url3 = require("url");
|
|
401
|
-
var
|
|
402
|
-
var
|
|
403
|
-
var __dirname3 = (0, import_path3.dirname)(
|
|
528
|
+
var import_plugin_replace2 = __toESM(require("@rollup/plugin-replace"), 1);
|
|
529
|
+
var __filename4 = (0, import_url3.fileURLToPath)(importMetaUrl);
|
|
530
|
+
var __dirname3 = (0, import_path3.dirname)(__filename4);
|
|
404
531
|
function createViteConfigForTests(projDir, prepDir, mode) {
|
|
405
532
|
const root = (0, import_path3.resolve)(__dirname3, "..", "template-tests");
|
|
406
533
|
const templateSrcDir = (0, import_path3.resolve)(root, "src");
|
|
@@ -409,13 +536,31 @@ function createViteConfigForTests(projDir, prepDir, mode) {
|
|
|
409
536
|
const yamlPath = `${relProjDirPath}/**/*.check.yaml`;
|
|
410
537
|
const outDir = (0, import_path3.relative)(root, prepDir);
|
|
411
538
|
return {
|
|
539
|
+
// Don't use an external config file
|
|
412
540
|
configFile: false,
|
|
541
|
+
// Use the root directory configured above
|
|
413
542
|
root,
|
|
543
|
+
// Don't clear the screen in dev mode so that we can see builder output
|
|
414
544
|
clearScreen: false,
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
545
|
+
// TODO: Disable vite output by default?
|
|
546
|
+
// logLevel: 'silent',
|
|
547
|
+
plugins: [
|
|
548
|
+
// Inject special values into the generated JS
|
|
549
|
+
// TODO: We currently have to use `@rollup/plugin-replace` instead of Vite's
|
|
550
|
+
// built-in `define` feature because the latter does not seem to run before
|
|
551
|
+
// the glob handler (which requires the glob to be injected as a literal)
|
|
552
|
+
(0, import_plugin_replace2.default)({
|
|
553
|
+
preventAssignment: true,
|
|
554
|
+
delimiters: ["", ""],
|
|
555
|
+
values: {
|
|
556
|
+
// Inject the glob pattern for matching check yaml files
|
|
557
|
+
"./__YAML_PATH__": yamlPath
|
|
558
|
+
}
|
|
559
|
+
})
|
|
560
|
+
],
|
|
418
561
|
build: {
|
|
562
|
+
// Write output files to the configured directory (instead of the default `dist`);
|
|
563
|
+
// note that this must be relative to the project `root`
|
|
419
564
|
outDir,
|
|
420
565
|
emptyOutDir: false,
|
|
421
566
|
lib: {
|
|
@@ -423,14 +568,24 @@ function createViteConfigForTests(projDir, prepDir, mode) {
|
|
|
423
568
|
formats: ["es"],
|
|
424
569
|
fileName: () => "check-tests.js"
|
|
425
570
|
},
|
|
571
|
+
// Enable watch mode if requested
|
|
426
572
|
watch: mode === "watch" && {},
|
|
427
|
-
rollupOptions: {
|
|
573
|
+
rollupOptions: {
|
|
574
|
+
// Prevent dependencies from being included in packaged library
|
|
575
|
+
// TODO: For now we include check-core in the packaged library so that its
|
|
576
|
+
// dependencies are correctly resolved at runtime. Ideally this would only
|
|
577
|
+
// include a couple functions that are used for defining tests, but Vite 2.x
|
|
578
|
+
// does not implement tree shaking for ES libraries, which means the generated
|
|
579
|
+
// library is much larger than it needs to be. Once we upgrade to Vite 3.x,
|
|
580
|
+
// the generated library should be smaller; see related fix:
|
|
581
|
+
// https://github.com/vitejs/vite/pull/8737
|
|
582
|
+
// external: Object.keys(pkg.dependencies)
|
|
583
|
+
}
|
|
428
584
|
}
|
|
429
585
|
};
|
|
430
586
|
}
|
|
431
587
|
|
|
432
588
|
// src/plugin.ts
|
|
433
|
-
var import_meta4 = {};
|
|
434
589
|
function checkPlugin(options) {
|
|
435
590
|
return new CheckPlugin(options);
|
|
436
591
|
}
|
|
@@ -440,8 +595,7 @@ var CheckPlugin = class {
|
|
|
440
595
|
this.firstBuild = true;
|
|
441
596
|
}
|
|
442
597
|
async watch(config) {
|
|
443
|
-
|
|
444
|
-
if (((_a = this.options) == null ? void 0 : _a.testConfigPath) === void 0) {
|
|
598
|
+
if (this.options?.testConfigPath === void 0) {
|
|
445
599
|
await this.genTestConfig(config, "watch");
|
|
446
600
|
}
|
|
447
601
|
const testOptions = this.resolveTestOptions(config);
|
|
@@ -450,8 +604,12 @@ var CheckPlugin = class {
|
|
|
450
604
|
await server.listen();
|
|
451
605
|
const baselinesDir = "baselines";
|
|
452
606
|
const watcher = import_chokidar.default.watch(baselinesDir, {
|
|
607
|
+
// Watch paths are resolved relative to the project root directory
|
|
453
608
|
cwd: config.rootDir,
|
|
609
|
+
// Don't send initial "file added" events
|
|
454
610
|
ignoreInitial: true,
|
|
611
|
+
// XXX: Include a delay, otherwise on macOS we sometimes get multiple
|
|
612
|
+
// change events when a file is saved just once
|
|
455
613
|
awaitWriteFinish: {
|
|
456
614
|
stabilityThreshold: 200
|
|
457
615
|
}
|
|
@@ -459,18 +617,22 @@ var CheckPlugin = class {
|
|
|
459
617
|
watcher.on("add", () => server.restart());
|
|
460
618
|
watcher.on("unlink", () => server.restart());
|
|
461
619
|
}
|
|
620
|
+
// TODO: Note that this plugin runs as a `postBuild` step because it currently
|
|
621
|
+
// needs to run after other plugins, and those plugins need to run after the
|
|
622
|
+
// staged files are copied to their final destination(s). We should probably
|
|
623
|
+
// make it configurable so that it can either be run as a `postGenerate` or a
|
|
624
|
+
// `postBuild` step.
|
|
462
625
|
async postBuild(context, modelSpec) {
|
|
463
|
-
var _a, _b;
|
|
464
626
|
const firstBuild = this.firstBuild;
|
|
465
627
|
this.firstBuild = false;
|
|
466
|
-
if (
|
|
628
|
+
if (this.options?.current === void 0) {
|
|
467
629
|
if (context.config.mode === "development") {
|
|
468
630
|
await this.copyPreviousBundle(context.config);
|
|
469
631
|
}
|
|
470
632
|
context.log("info", "Generating model check bundle...");
|
|
471
633
|
await this.genCurrentBundle(context.config, modelSpec);
|
|
472
634
|
}
|
|
473
|
-
if (
|
|
635
|
+
if (this.options?.testConfigPath === void 0) {
|
|
474
636
|
if (context.config.mode === "production" || firstBuild) {
|
|
475
637
|
context.log("info", "Generating model check test configuration...");
|
|
476
638
|
await this.genTestConfig(context.config, "build");
|
|
@@ -506,14 +668,13 @@ var CheckPlugin = class {
|
|
|
506
668
|
await (0, import_vite.build)(viteConfig);
|
|
507
669
|
}
|
|
508
670
|
async runChecks(context, testOptions) {
|
|
509
|
-
var _a;
|
|
510
671
|
context.log("info", "Running model checks...");
|
|
511
672
|
const moduleR = await import(relativeToSourcePath(testOptions.currentBundlePath));
|
|
512
673
|
const bundleR = moduleR.createBundle();
|
|
513
674
|
const bundleNameR = testOptions.currentBundleName;
|
|
514
675
|
let bundleL;
|
|
515
676
|
let bundleNameL;
|
|
516
|
-
if (
|
|
677
|
+
if (this.options?.baseline) {
|
|
517
678
|
const moduleL = await import(relativeToSourcePath(this.options.baseline.path));
|
|
518
679
|
const rawBundleL = moduleL.createBundle();
|
|
519
680
|
if (rawBundleL.version === bundleR.version) {
|
|
@@ -528,17 +689,21 @@ var CheckPlugin = class {
|
|
|
528
689
|
};
|
|
529
690
|
const configOptions = await testConfigModule.getConfigOptions(bundleL, bundleR, configInitOptions);
|
|
530
691
|
const checkConfig = await (0, import_check_core2.createConfig)(configOptions);
|
|
531
|
-
const result = await runTestSuite(
|
|
692
|
+
const result = await runTestSuite(
|
|
693
|
+
context,
|
|
694
|
+
checkConfig,
|
|
695
|
+
/*verbose=*/
|
|
696
|
+
false
|
|
697
|
+
);
|
|
532
698
|
context.log("info", "Building model check report");
|
|
533
699
|
const viteConfig = this.createViteConfigForReport(context.config, testOptions, result.suiteSummary);
|
|
534
700
|
await (0, import_vite.build)(viteConfig);
|
|
535
701
|
return result.allChecksPassed;
|
|
536
702
|
}
|
|
537
703
|
resolveTestOptions(config) {
|
|
538
|
-
var _a, _b;
|
|
539
704
|
let currentBundleName;
|
|
540
705
|
let currentBundlePath;
|
|
541
|
-
if (
|
|
706
|
+
if (this.options?.current === void 0) {
|
|
542
707
|
currentBundleName = "current";
|
|
543
708
|
currentBundlePath = (0, import_path4.join)(config.prepDir, "check-bundle.js");
|
|
544
709
|
} else {
|
|
@@ -546,7 +711,7 @@ var CheckPlugin = class {
|
|
|
546
711
|
currentBundlePath = this.options.current.path;
|
|
547
712
|
}
|
|
548
713
|
let testConfigPath;
|
|
549
|
-
if (
|
|
714
|
+
if (this.options?.testConfigPath === void 0) {
|
|
550
715
|
testConfigPath = (0, import_path4.join)(config.prepDir, "check-tests.js");
|
|
551
716
|
} else {
|
|
552
717
|
testConfigPath = this.options.testConfigPath;
|
|
@@ -570,7 +735,7 @@ var CheckPlugin = class {
|
|
|
570
735
|
}
|
|
571
736
|
};
|
|
572
737
|
function relativeToSourcePath(filePath) {
|
|
573
|
-
const srcDir = (0, import_path4.dirname)((0, import_url4.fileURLToPath)(
|
|
738
|
+
const srcDir = (0, import_path4.dirname)((0, import_url4.fileURLToPath)(importMetaUrl));
|
|
574
739
|
const relPath = (0, import_path4.relative)(srcDir, filePath);
|
|
575
740
|
return relPath.replaceAll("\\", "/");
|
|
576
741
|
}
|