testeranto 0.94.0 → 0.100.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.
Files changed (103) hide show
  1. package/bundle.js +4 -7
  2. package/dist/common/src/PM/main.js +160 -42
  3. package/dist/common/src/PM/node.js +20 -5
  4. package/dist/common/src/PM/web.js +19 -4
  5. package/dist/common/src/SubPackages/react/jsx/node.js +1 -6
  6. package/dist/common/src/cli.js +439 -0
  7. package/dist/common/src/cli2.js +144 -0
  8. package/dist/common/src/esbuildConfigs/inputFilesPlugin.js +18 -6
  9. package/dist/common/src/esbuildConfigs/node.js +1 -4
  10. package/dist/common/src/esbuildConfigs/web.js +1 -1
  11. package/dist/common/src/lib/abstractBase.js +14 -91
  12. package/dist/common/src/lib/types.js +1 -0
  13. package/dist/common/tsconfig.common.tsbuildinfo +1 -1
  14. package/dist/module/src/PM/main.js +160 -42
  15. package/dist/module/src/PM/node.js +20 -5
  16. package/dist/module/src/PM/web.js +19 -4
  17. package/dist/module/src/SubPackages/react/jsx/node.js +1 -6
  18. package/dist/module/src/cli.js +411 -0
  19. package/dist/module/src/cli2.js +116 -0
  20. package/dist/module/src/esbuildConfigs/inputFilesPlugin.js +18 -6
  21. package/dist/module/src/esbuildConfigs/node.js +1 -4
  22. package/dist/module/src/esbuildConfigs/web.js +1 -1
  23. package/dist/module/src/lib/abstractBase.js +14 -91
  24. package/dist/module/src/lib/types.js +1 -0
  25. package/dist/module/tsconfig.module.tsbuildinfo +1 -1
  26. package/dist/prebuild/cli.mjs +1491 -0
  27. package/dist/prebuild/{run-tests.mjs → cli2.mjs} +203 -156
  28. package/dist/types/src/Node.d.ts +2 -2
  29. package/dist/types/src/PM/index.d.ts +10 -2
  30. package/dist/types/src/PM/main.d.ts +13 -7
  31. package/dist/types/src/PM/node.d.ts +9 -2
  32. package/dist/types/src/PM/web.d.ts +9 -3
  33. package/dist/types/src/SubPackages/puppeteer.d.ts +1 -1
  34. package/dist/types/src/SubPackages/react/component/node.d.ts +1 -1
  35. package/dist/types/src/SubPackages/react/component/web.d.ts +1 -1
  36. package/dist/types/src/SubPackages/react/jsx/node.d.ts +3 -3
  37. package/dist/types/src/SubPackages/react/jsx/web.d.ts +2 -2
  38. package/dist/types/src/SubPackages/react-dom/component/node.d.ts +2 -2
  39. package/dist/types/src/SubPackages/react-dom/component/web.d.ts +1 -1
  40. package/dist/types/src/SubPackages/react-dom/jsx/node.d.ts +1 -1
  41. package/dist/types/src/SubPackages/react-dom/jsx/web.d.ts +2 -2
  42. package/dist/types/src/SubPackages/react-test-renderer/MemoExoticComponent/node.d.ts +2 -2
  43. package/dist/types/src/SubPackages/react-test-renderer/component/node.d.ts +2 -2
  44. package/dist/types/src/SubPackages/react-test-renderer/component/web.d.ts +2 -2
  45. package/dist/types/src/SubPackages/react-test-renderer/fc/node.d.ts +2 -2
  46. package/dist/types/src/SubPackages/react-test-renderer/fc/web.d.ts +2 -2
  47. package/dist/types/src/SubPackages/react-test-renderer/jsx/node.d.ts +3 -2
  48. package/dist/types/src/SubPackages/react-test-renderer/jsx/web.d.ts +2 -2
  49. package/dist/types/src/SubPackages/react-test-renderer/jsx-promised/node.d.ts +2 -2
  50. package/dist/types/src/SubPackages/react-test-renderer/jsx-promised/web.d.ts +2 -2
  51. package/dist/types/src/Types.d.ts +60 -21
  52. package/dist/types/src/Web.d.ts +2 -2
  53. package/dist/types/src/lib/index.d.ts +1 -1
  54. package/dist/types/src/lib/types.d.ts +2 -30
  55. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  56. package/package.json +11 -8
  57. package/src/PM/index.ts +12 -8
  58. package/src/PM/main.ts +218 -62
  59. package/src/PM/node.ts +42 -7
  60. package/src/PM/web.ts +33 -5
  61. package/src/SubPackages/react/jsx/node.ts +16 -5
  62. package/src/SubPackages/react-test-renderer/jsx/node.ts +16 -1
  63. package/src/Types.ts +362 -114
  64. package/src/cli.ts +535 -0
  65. package/src/cli2.ts +157 -0
  66. package/src/esbuildConfigs/inputFilesPlugin.ts +27 -6
  67. package/src/esbuildConfigs/node.ts +4 -7
  68. package/src/esbuildConfigs/web.ts +4 -3
  69. package/src/lib/abstractBase.ts +58 -115
  70. package/src/lib/types.ts +3 -177
  71. package/dist/common/src/Aider.js +0 -143
  72. package/dist/common/src/Project.js +0 -227
  73. package/dist/common/src/Puppeteer.js +0 -111
  74. package/dist/common/src/build-tests.js +0 -39
  75. package/dist/common/src/esbuildConfigs/features.js +0 -14
  76. package/dist/common/src/esbuildConfigs/report.js +0 -14
  77. package/dist/common/src/esbuildConfigs/tests.js +0 -13
  78. package/dist/common/src/run-tests.js +0 -39
  79. package/dist/module/src/Aider.js +0 -136
  80. package/dist/module/src/Project.js +0 -220
  81. package/dist/module/src/Puppeteer.js +0 -106
  82. package/dist/module/src/build-tests.js +0 -11
  83. package/dist/module/src/esbuildConfigs/features.js +0 -12
  84. package/dist/module/src/esbuildConfigs/report.js +0 -14
  85. package/dist/module/src/esbuildConfigs/tests.js +0 -11
  86. package/dist/module/src/run-tests.js +0 -11
  87. package/dist/prebuild/build-tests.mjs +0 -553
  88. package/dist/types/src/Aider.d.ts +0 -1
  89. package/dist/types/src/Project.d.ts +0 -12
  90. package/dist/types/src/Puppeteer.d.ts +0 -2
  91. package/dist/types/src/esbuildConfigs/features.d.ts +0 -4
  92. package/dist/types/src/esbuildConfigs/report.d.ts +0 -0
  93. package/dist/types/src/esbuildConfigs/tests.d.ts +0 -4
  94. package/src/Aider.ts +0 -168
  95. package/src/Project.ts +0 -292
  96. package/src/Puppeteer.ts +0 -143
  97. package/src/build-tests.ts +0 -12
  98. package/src/esbuildConfigs/features.ts +0 -17
  99. package/src/esbuildConfigs/report.ts +0 -15
  100. package/src/esbuildConfigs/tests.ts +0 -14
  101. package/src/run-tests.ts +0 -12
  102. /package/dist/types/src/{build-tests.d.ts → cli.d.ts} +0 -0
  103. /package/dist/types/src/{run-tests.d.ts → cli2.d.ts} +0 -0
@@ -0,0 +1,1491 @@
1
+ import { createRequire } from 'module';const require = createRequire(import.meta.url);
2
+
3
+ // src/cli.ts
4
+ import { spawn as spawn2 } from "child_process";
5
+ import fs3 from "fs";
6
+ import path5 from "path";
7
+ import readline from "readline";
8
+ import { glob } from "glob";
9
+ import { debounceWatch } from "@bscotch/debounce-watch";
10
+ import esbuild from "esbuild";
11
+
12
+ // src/esbuildConfigs/index.ts
13
+ var esbuildConfigs_default = (config) => {
14
+ return {
15
+ // packages: "external",
16
+ target: "esnext",
17
+ format: "esm",
18
+ splitting: true,
19
+ outExtension: { ".js": ".mjs" },
20
+ outbase: config.outbase,
21
+ jsx: "transform",
22
+ bundle: true,
23
+ minify: config.minify === true,
24
+ write: true,
25
+ loader: {
26
+ ".js": "jsx",
27
+ ".png": "binary",
28
+ ".jpg": "binary"
29
+ }
30
+ };
31
+ };
32
+
33
+ // src/esbuildConfigs/inputFilesPlugin.ts
34
+ import fs from "fs";
35
+ import path from "path";
36
+ import { spawn } from "child_process";
37
+ var otherInputs = {};
38
+ var register = (entrypoint, sources) => {
39
+ if (!otherInputs[entrypoint]) {
40
+ otherInputs[entrypoint] = /* @__PURE__ */ new Set();
41
+ }
42
+ sources.forEach((s) => otherInputs[entrypoint].add(s));
43
+ };
44
+ function tree(meta, key) {
45
+ const outputKey = Object.keys(meta.outputs).find((k) => {
46
+ return meta.outputs[k].entryPoint === key;
47
+ });
48
+ if (!outputKey) {
49
+ console.error("No outputkey found");
50
+ process.exit(-1);
51
+ }
52
+ return Object.keys(meta.outputs[outputKey].inputs).filter(
53
+ (k) => k.startsWith("src")
54
+ );
55
+ }
56
+ var inputFilesPlugin_default = (platform, entryPoints) => {
57
+ return {
58
+ register,
59
+ inputFilesPluginFactory: {
60
+ name: "metafileWriter",
61
+ setup(build) {
62
+ build.onEnd((result) => {
63
+ fs.writeFileSync(
64
+ `docs/${platform}/metafile.json`,
65
+ JSON.stringify(result, null, 2)
66
+ );
67
+ if (result.errors.length === 0) {
68
+ entryPoints.forEach((entryPoint) => {
69
+ const filePath = path.join(
70
+ "./docs/",
71
+ platform,
72
+ entryPoint.split(".").slice(0, -1).join("."),
73
+ `inputFiles.json`
74
+ );
75
+ const dirName = path.dirname(filePath);
76
+ if (!fs.existsSync(dirName)) {
77
+ fs.mkdirSync(dirName, { recursive: true });
78
+ }
79
+ const promptPath = path.join(
80
+ "./docs/",
81
+ platform,
82
+ entryPoint.split(".").slice(0, -1).join("."),
83
+ `prompt.txt`
84
+ );
85
+ const testPaths = path.join(
86
+ "./docs/",
87
+ platform,
88
+ entryPoint.split(".").slice(0, -1).join("."),
89
+ `tests.json`
90
+ );
91
+ const featuresPath = path.join(
92
+ "./docs/",
93
+ platform,
94
+ entryPoint.split(".").slice(0, -1).join("."),
95
+ `featurePrompt.txt`
96
+ );
97
+ const stderrPath = path.join(
98
+ "./docs/",
99
+ platform,
100
+ entryPoint.split(".").slice(0, -1).join("."),
101
+ `stderr.log`
102
+ );
103
+ const stdoutPath = path.join(
104
+ "./docs/",
105
+ platform,
106
+ entryPoint.split(".").slice(0, -1).join("."),
107
+ `stdout.log`
108
+ );
109
+ if (result.metafile) {
110
+ const addableFiles = tree(
111
+ result.metafile,
112
+ entryPoint.split("/").slice(1).join("/")
113
+ ).map((y) => {
114
+ if (otherInputs[y]) {
115
+ return Array.from(otherInputs[y]);
116
+ }
117
+ return y;
118
+ }).flat();
119
+ const typeErrorFiles = addableFiles.map(
120
+ (t) => `docs/types/${t}.type_errors.txt`
121
+ );
122
+ const lintPath = path.join(
123
+ "./docs/",
124
+ platform,
125
+ entryPoint.split(".").slice(0, -1).join("."),
126
+ `lint_errors.txt`
127
+ );
128
+ fs.writeFileSync(
129
+ promptPath,
130
+ `
131
+ ${addableFiles.map((x) => {
132
+ return `/add ${x}`;
133
+ }).join("\n")}
134
+
135
+ ${typeErrorFiles.map((x) => {
136
+ return `/read ${x}`;
137
+ }).join("\n")}
138
+
139
+ /read ${lintPath}
140
+ /read ${testPaths}
141
+ /read ${stdoutPath}
142
+ /read ${stderrPath}
143
+
144
+ /load ${featuresPath}
145
+
146
+ /code Fix the failing tests described in ${testPaths}. Correct any type signature errors described in the files [${typeErrorFiles.join(
147
+ ", "
148
+ )}]. Implement any method which throws "Function not implemented. Resolve the lint errors described in ${lintPath}"
149
+ `
150
+ );
151
+ const logContent = [];
152
+ const tsc = spawn("eslint", addableFiles);
153
+ tsc.stdout.on("data", (data) => {
154
+ const lines = data.toString().split("\n");
155
+ logContent.push(...lines);
156
+ });
157
+ tsc.stderr.on("data", (data) => {
158
+ console.error(`stderr: ${data}`);
159
+ process.exit(-1);
160
+ });
161
+ tsc.on("close", (code) => {
162
+ fs.writeFileSync(lintPath, logContent.join("\n"));
163
+ });
164
+ }
165
+ });
166
+ }
167
+ });
168
+ }
169
+ }
170
+ };
171
+ };
172
+
173
+ // src/esbuildConfigs/featuresPlugin.ts
174
+ import path2 from "path";
175
+ var featuresPlugin_default = {
176
+ name: "feature-markdown",
177
+ setup(build) {
178
+ build.onResolve({ filter: /\.md$/ }, (args) => {
179
+ if (args.resolveDir === "")
180
+ return;
181
+ return {
182
+ path: path2.isAbsolute(args.path) ? args.path : path2.join(args.resolveDir, args.path),
183
+ namespace: "feature-markdown"
184
+ };
185
+ });
186
+ build.onLoad(
187
+ { filter: /.*/, namespace: "feature-markdown" },
188
+ async (args) => {
189
+ return {
190
+ contents: `file://${args.path}`,
191
+ loader: "text"
192
+ // contents: JSON.stringify({ path: args.path }),
193
+ // loader: "json",
194
+ // contents: JSON.stringify({
195
+ // // html: markdownHTML,
196
+ // raw: markdownContent,
197
+ // filename: args.path, //path.basename(args.path),
198
+ // }),
199
+ // loader: "json",
200
+ };
201
+ }
202
+ );
203
+ }
204
+ };
205
+
206
+ // src/esbuildConfigs/node.ts
207
+ var node_default = (config, entryPoints) => {
208
+ const { inputFilesPluginFactory, register: register2 } = inputFilesPlugin_default(
209
+ "node",
210
+ entryPoints
211
+ );
212
+ return {
213
+ ...esbuildConfigs_default(config),
214
+ splitting: true,
215
+ outdir: config.outdir + "/node",
216
+ // inject: [`./node_modules/testeranto/dist/cjs-shim.js`],
217
+ metafile: true,
218
+ supported: {
219
+ "dynamic-import": true
220
+ },
221
+ define: {
222
+ "process.env.FLUENTFFMPEG_COV": "0"
223
+ },
224
+ absWorkingDir: process.cwd(),
225
+ banner: {
226
+ js: `import { createRequire } from 'module';const require = createRequire(import.meta.url);`
227
+ },
228
+ platform: "node",
229
+ external: [
230
+ // "testeranto.json",
231
+ // "features.test.js",
232
+ "react",
233
+ // "events",
234
+ // "ganache"
235
+ ...config.externals
236
+ ],
237
+ entryPoints: [...entryPoints],
238
+ plugins: [
239
+ featuresPlugin_default,
240
+ ...config.nodePlugins.map((p) => p(register2, entryPoints)) || [],
241
+ inputFilesPluginFactory,
242
+ // inputFilesPlugin("node", entryPoints),
243
+ {
244
+ name: "rebuild-notify",
245
+ setup(build) {
246
+ build.onEnd((result) => {
247
+ console.log(
248
+ `> node build ended with ${result.errors.length} errors`
249
+ );
250
+ if (result.errors.length > 0) {
251
+ console.log(result);
252
+ }
253
+ });
254
+ }
255
+ }
256
+ ]
257
+ };
258
+ };
259
+
260
+ // src/esbuildConfigs/web.ts
261
+ import path3 from "path";
262
+ var web_default = (config, entryPoints) => {
263
+ const { inputFilesPluginFactory, register: register2 } = inputFilesPlugin_default(
264
+ "web",
265
+ entryPoints
266
+ );
267
+ return {
268
+ ...esbuildConfigs_default(config),
269
+ // inject: ["./node_modules/testeranto/dist/cjs-shim.js"],
270
+ // banner: {
271
+ // js: `import { createRequire } from 'module';const require = createRequire(import.meta.url);`,
272
+ // },
273
+ // splitting: true,
274
+ outdir: config.outdir + "/web",
275
+ alias: {
276
+ react: path3.resolve("./node_modules/react")
277
+ },
278
+ metafile: true,
279
+ external: [
280
+ // "testeranto.json",
281
+ // "features.test.ts",
282
+ // "url",
283
+ // "react",
284
+ "path",
285
+ "fs",
286
+ "stream",
287
+ "http",
288
+ "constants",
289
+ "net",
290
+ "assert",
291
+ "tls",
292
+ "os",
293
+ "child_process",
294
+ "readline",
295
+ "zlib",
296
+ "crypto",
297
+ "https",
298
+ "util",
299
+ "process",
300
+ "dns"
301
+ ],
302
+ platform: "browser",
303
+ entryPoints: [...entryPoints],
304
+ plugins: [
305
+ featuresPlugin_default,
306
+ // markdownPlugin({}),
307
+ ...config.nodePlugins.map((p) => p(register2, entryPoints)) || [],
308
+ inputFilesPluginFactory,
309
+ {
310
+ name: "rebuild-notify",
311
+ setup(build) {
312
+ build.onEnd((result) => {
313
+ console.log(
314
+ `> web build ended with ${result.errors.length} errors`
315
+ );
316
+ if (result.errors.length > 0) {
317
+ console.log(result);
318
+ }
319
+ });
320
+ }
321
+ }
322
+ ]
323
+ };
324
+ };
325
+
326
+ // src/web.html.ts
327
+ var web_html_default = (jsfilePath, htmlFilePath) => `
328
+ <!DOCTYPE html>
329
+ <html lang="en">
330
+
331
+ <head>
332
+ <script type="module" src="${jsfilePath}"></script>
333
+
334
+ </head>
335
+
336
+ <body>
337
+ <h1>${htmlFilePath}</h1>
338
+ <div id="root">
339
+
340
+ </div>
341
+ </body>
342
+
343
+ <footer></footer>
344
+
345
+ </html>
346
+ `;
347
+
348
+ // src/PM/main.ts
349
+ import fs2 from "fs";
350
+ import path4 from "path";
351
+ import puppeteer from "puppeteer-core";
352
+ import crypto from "crypto";
353
+
354
+ // src/PM/index.ts
355
+ var PM = class {
356
+ };
357
+
358
+ // src/PM/main.ts
359
+ var fileStreams3 = [];
360
+ var fPaths = [];
361
+ var files = {};
362
+ var recorders = {};
363
+ var screenshots = {};
364
+ var red = "\x1B[31m";
365
+ var green = "\x1B[32m";
366
+ var reset = "\x1B[0m";
367
+ var statusMessagePretty = (failures, test) => {
368
+ if (failures === 0) {
369
+ console.log(green + `${test} completed successfully` + reset);
370
+ } else {
371
+ console.log(red + `${test} failed ${failures} times` + reset);
372
+ }
373
+ };
374
+ var PM_Main = class extends PM {
375
+ constructor(configs) {
376
+ super();
377
+ this.shutdownMode = false;
378
+ this.checkForShutdown = () => {
379
+ const anyRunning = Object.values(this.registry).filter((x) => x === false).length > 0;
380
+ if (anyRunning) {
381
+ } else {
382
+ this.browser.disconnect().then(() => {
383
+ console.log("Goodbye");
384
+ process.exit();
385
+ });
386
+ }
387
+ };
388
+ this.register = (src) => {
389
+ this.registry[src] = false;
390
+ };
391
+ this.deregister = (src) => {
392
+ this.registry[src] = true;
393
+ if (this.shutdownMode) {
394
+ this.checkForShutdown();
395
+ }
396
+ };
397
+ this.launchNode = async (src, dest) => {
398
+ console.log("! node", src);
399
+ this.register(src);
400
+ const destFolder = dest.replace(".mjs", "");
401
+ let argz = "";
402
+ const testConfig = this.configs.tests.find((t) => {
403
+ return t[0] === src;
404
+ });
405
+ if (!testConfig) {
406
+ console.error("missing test config");
407
+ process.exit(-1);
408
+ }
409
+ const testConfigResource = testConfig[2];
410
+ let portsToUse = [];
411
+ if (testConfigResource.ports === 0) {
412
+ argz = JSON.stringify({
413
+ scheduled: true,
414
+ name: src,
415
+ ports: portsToUse,
416
+ fs: destFolder,
417
+ browserWSEndpoint: this.browser.wsEndpoint()
418
+ });
419
+ } else if (testConfigResource.ports > 0) {
420
+ const openPorts = Object.entries(this.ports).filter(
421
+ ([portnumber, portopen]) => portopen
422
+ );
423
+ if (openPorts.length >= testConfigResource.ports) {
424
+ for (let i = 0; i < testConfigResource.ports; i++) {
425
+ portsToUse.push(openPorts[i][0]);
426
+ this.ports[openPorts[i][0]] = false;
427
+ }
428
+ argz = JSON.stringify({
429
+ scheduled: true,
430
+ name: src,
431
+ // ports: [3333],
432
+ ports: portsToUse,
433
+ fs: destFolder,
434
+ browserWSEndpoint: this.browser.wsEndpoint()
435
+ });
436
+ } else {
437
+ this.queue.push(src);
438
+ return;
439
+ }
440
+ } else {
441
+ console.error("negative port makes no sense", src);
442
+ process.exit(-1);
443
+ }
444
+ const builtfile = dest;
445
+ const webSideCares = [];
446
+ this.server[builtfile] = await import(`${builtfile}?cacheBust=${Date.now()}`).then((module) => {
447
+ return module.default.then((defaultModule) => {
448
+ defaultModule.receiveTestResourceConfig(argz).then(async ({ features, failed }) => {
449
+ this.receiveFeatures(features, destFolder, src);
450
+ statusMessagePretty(failed, src);
451
+ }).catch((e) => {
452
+ console.log(`${src} errored with`, e);
453
+ }).finally(() => {
454
+ webSideCares.forEach((webSideCar) => webSideCar.close());
455
+ this.deregister(src);
456
+ });
457
+ });
458
+ });
459
+ for (let i = 0; i <= portsToUse.length; i++) {
460
+ if (portsToUse[i]) {
461
+ this.ports[portsToUse[i]] = "true";
462
+ }
463
+ }
464
+ };
465
+ this.launchWebSideCar = async (src, dest, testConfig) => {
466
+ const d = dest + ".mjs";
467
+ console.log("launchWebSideCar", src, dest, d);
468
+ const destFolder = dest.replace(".mjs", "");
469
+ const fileStreams2 = [];
470
+ const doneFileStream2 = [];
471
+ return new Promise((res, rej) => {
472
+ this.browser.newPage().then((page) => {
473
+ page.exposeFunction(
474
+ "custom-screenshot",
475
+ async (ssOpts, testName) => {
476
+ const p = ssOpts.path;
477
+ const dir = path4.dirname(p);
478
+ fs2.mkdirSync(dir, {
479
+ recursive: true
480
+ });
481
+ files[testName].add(ssOpts.path);
482
+ const sPromise = page.screenshot({
483
+ ...ssOpts,
484
+ path: p
485
+ });
486
+ if (!screenshots[testName]) {
487
+ screenshots[testName] = [];
488
+ }
489
+ screenshots[testName].push(sPromise);
490
+ await sPromise;
491
+ return sPromise;
492
+ }
493
+ );
494
+ page.exposeFunction(
495
+ "writeFileSync",
496
+ (fp, contents, testName) => {
497
+ const dir = path4.dirname(fp);
498
+ fs2.mkdirSync(dir, {
499
+ recursive: true
500
+ });
501
+ const p = new Promise(async (res2, rej2) => {
502
+ fs2.writeFileSync(fp, contents);
503
+ res2(fp);
504
+ });
505
+ doneFileStream2.push(p);
506
+ if (!files[testName]) {
507
+ files[testName] = /* @__PURE__ */ new Set();
508
+ }
509
+ files[testName].add(fp);
510
+ return p;
511
+ }
512
+ );
513
+ page.exposeFunction("existsSync", (fp, contents) => {
514
+ return fs2.existsSync(fp);
515
+ });
516
+ page.exposeFunction("mkdirSync", (fp) => {
517
+ if (!fs2.existsSync(fp)) {
518
+ return fs2.mkdirSync(fp, {
519
+ recursive: true
520
+ });
521
+ }
522
+ return false;
523
+ });
524
+ page.exposeFunction(
525
+ "createWriteStream",
526
+ (fp, testName) => {
527
+ const f = fs2.createWriteStream(fp);
528
+ files[testName].add(fp);
529
+ const p = new Promise((res2, rej2) => {
530
+ res2(fp);
531
+ });
532
+ doneFileStream2.push(p);
533
+ f.on("close", async () => {
534
+ await p;
535
+ });
536
+ fileStreams2.push(f);
537
+ return {
538
+ ...JSON.parse(JSON.stringify(f)),
539
+ uid: fileStreams2.length - 1
540
+ };
541
+ }
542
+ );
543
+ page.exposeFunction(
544
+ "write",
545
+ async (uid, contents) => {
546
+ return fileStreams2[uid].write(contents);
547
+ }
548
+ );
549
+ page.exposeFunction("end", async (uid) => {
550
+ return fileStreams2[uid].end();
551
+ });
552
+ return page;
553
+ }).then(async (page) => {
554
+ await page.goto(`file://${`${dest}.html`}`, {});
555
+ res(page);
556
+ });
557
+ });
558
+ };
559
+ this.launchNodeSideCar = async (src, dest, testConfig) => {
560
+ const d = dest + ".mjs";
561
+ console.log("launchNodeSideCar", src, dest, d);
562
+ const destFolder = dest.replace(".mjs", "");
563
+ let argz = "";
564
+ const testConfigResource = testConfig[2];
565
+ let portsToUse = [];
566
+ if (testConfigResource.ports === 0) {
567
+ argz = JSON.stringify({
568
+ scheduled: true,
569
+ name: src,
570
+ ports: portsToUse,
571
+ fs: destFolder,
572
+ browserWSEndpoint: this.browser.wsEndpoint()
573
+ });
574
+ } else if (testConfigResource.ports > 0) {
575
+ const openPorts = Object.entries(this.ports).filter(
576
+ ([portnumber, portopen]) => portopen
577
+ );
578
+ if (openPorts.length >= testConfigResource.ports) {
579
+ for (let i = 0; i < testConfigResource.ports; i++) {
580
+ portsToUse.push(openPorts[i][0]);
581
+ this.ports[openPorts[i][0]] = false;
582
+ }
583
+ argz = JSON.stringify({
584
+ scheduled: true,
585
+ name: src,
586
+ // ports: [3333],
587
+ ports: portsToUse,
588
+ fs: ".",
589
+ browserWSEndpoint: this.browser.wsEndpoint()
590
+ });
591
+ } else {
592
+ this.queue.push(src);
593
+ return;
594
+ }
595
+ } else {
596
+ console.error("negative port makes no sense", src);
597
+ process.exit(-1);
598
+ }
599
+ const builtfile = dest + ".mjs";
600
+ this.server[builtfile] = await import(`${builtfile}?cacheBust=${Date.now()}`).then((module) => {
601
+ return module.default.then((defaultModule) => {
602
+ const s = new defaultModule();
603
+ s.receiveTestResourceConfig(argz);
604
+ });
605
+ });
606
+ for (let i = 0; i <= portsToUse.length; i++) {
607
+ if (portsToUse[i]) {
608
+ this.ports[portsToUse[i]] = "true";
609
+ }
610
+ }
611
+ };
612
+ this.launchWeb = (t, dest) => {
613
+ console.log("! web", t);
614
+ this.register(t);
615
+ const destFolder = dest.replace(".mjs", "");
616
+ const webArgz = JSON.stringify({
617
+ name: dest,
618
+ ports: [].toString(),
619
+ fs: destFolder,
620
+ browserWSEndpoint: this.browser.wsEndpoint()
621
+ });
622
+ const d = `${dest}?cacheBust=${Date.now()}`;
623
+ const evaluation = `
624
+ console.log("importing ${d}");
625
+ import('${d}').then(async (x) => {
626
+ console.log("imported", (await x.default));
627
+ try {
628
+ return await (await x.default).receiveTestResourceConfig(${webArgz})
629
+ } catch (e) {
630
+ console.log("fail", e)
631
+ }
632
+ })`;
633
+ const fileStreams2 = [];
634
+ const doneFileStream2 = [];
635
+ const stdoutStream = fs2.createWriteStream(`${destFolder}/stdout.log`);
636
+ const stderrStream = fs2.createWriteStream(`${destFolder}/stderr.log`);
637
+ this.browser.newPage().then((page) => {
638
+ page.exposeFunction(
639
+ "screencast",
640
+ async (ssOpts, testName) => {
641
+ const p = ssOpts.path;
642
+ const dir = path4.dirname(p);
643
+ fs2.mkdirSync(dir, {
644
+ recursive: true
645
+ });
646
+ if (!files[testName]) {
647
+ files[testName] = /* @__PURE__ */ new Set();
648
+ }
649
+ files[testName].add(ssOpts.path);
650
+ const sPromise = page.screenshot({
651
+ ...ssOpts,
652
+ path: p
653
+ });
654
+ if (!screenshots[testName]) {
655
+ screenshots[testName] = [];
656
+ }
657
+ screenshots[testName].push(sPromise);
658
+ await sPromise;
659
+ return sPromise;
660
+ }
661
+ );
662
+ page.exposeFunction(
663
+ "customScreenShot",
664
+ async (ssOpts, testName) => {
665
+ const p = ssOpts.path;
666
+ const dir = path4.dirname(p);
667
+ fs2.mkdirSync(dir, {
668
+ recursive: true
669
+ });
670
+ if (!files[testName]) {
671
+ files[testName] = /* @__PURE__ */ new Set();
672
+ }
673
+ files[testName].add(ssOpts.path);
674
+ const sPromise = page.screenshot({
675
+ ...ssOpts,
676
+ path: p
677
+ });
678
+ if (!screenshots[testName]) {
679
+ screenshots[testName] = [];
680
+ }
681
+ screenshots[testName].push(sPromise);
682
+ await sPromise;
683
+ return sPromise;
684
+ }
685
+ );
686
+ page.exposeFunction(
687
+ "writeFileSync",
688
+ (fp, contents, testName) => {
689
+ return globalThis["writeFileSync"](fp, contents, testName);
690
+ }
691
+ );
692
+ page.exposeFunction("existsSync", (fp, contents) => {
693
+ return fs2.existsSync(fp);
694
+ });
695
+ page.exposeFunction("mkdirSync", (fp) => {
696
+ if (!fs2.existsSync(fp)) {
697
+ return fs2.mkdirSync(fp, {
698
+ recursive: true
699
+ });
700
+ }
701
+ return false;
702
+ });
703
+ page.exposeFunction(
704
+ "createWriteStream",
705
+ (fp, testName) => {
706
+ const f = fs2.createWriteStream(fp);
707
+ if (!files[testName]) {
708
+ files[testName] = /* @__PURE__ */ new Set();
709
+ }
710
+ files[testName].add(fp);
711
+ const p = new Promise((res, rej) => {
712
+ res(fp);
713
+ });
714
+ doneFileStream2.push(p);
715
+ f.on("close", async () => {
716
+ await p;
717
+ });
718
+ fileStreams2.push(f);
719
+ return {
720
+ ...JSON.parse(JSON.stringify(f)),
721
+ uid: fileStreams2.length - 1
722
+ };
723
+ }
724
+ );
725
+ page.exposeFunction("write", async (uid, contents) => {
726
+ return fileStreams2[uid].write(contents);
727
+ });
728
+ page.exposeFunction("end", async (uid) => {
729
+ return fileStreams2[uid].end();
730
+ });
731
+ page.exposeFunction("page", () => {
732
+ return page.mainFrame()._id;
733
+ });
734
+ page.exposeFunction("click", (sel) => {
735
+ return page.click(sel);
736
+ });
737
+ page.exposeFunction("focusOn", (sel) => {
738
+ return page.focus(sel);
739
+ });
740
+ page.exposeFunction(
741
+ "typeInto",
742
+ async (value) => await page.keyboard.type(value)
743
+ );
744
+ page.exposeFunction(
745
+ "getValue",
746
+ (selector) => page.$eval(selector, (input) => input.getAttribute("value"))
747
+ );
748
+ page.exposeFunction(
749
+ "getAttribute",
750
+ async (selector, attribute) => {
751
+ const attributeValue = await page.$eval(selector, (input) => {
752
+ return input.getAttribute(attribute);
753
+ });
754
+ return attributeValue;
755
+ }
756
+ );
757
+ page.exposeFunction("isDisabled", async (selector) => {
758
+ const attributeValue = await page.$eval(
759
+ selector,
760
+ (input) => {
761
+ return input.disabled;
762
+ }
763
+ );
764
+ return attributeValue;
765
+ });
766
+ page.exposeFunction("$", async (selector) => {
767
+ const x = page.$(selector);
768
+ const y = await x;
769
+ return y;
770
+ });
771
+ return page;
772
+ }).then(async (page) => {
773
+ const close = () => {
774
+ if (!files[t]) {
775
+ files[t] = /* @__PURE__ */ new Set();
776
+ }
777
+ fs2.writeFileSync(
778
+ destFolder + "/manifest.json",
779
+ JSON.stringify(Array.from(files[t]))
780
+ );
781
+ delete files[t];
782
+ Promise.all(screenshots[t] || []).then(() => {
783
+ delete screenshots[t];
784
+ page.close();
785
+ this.deregister(t);
786
+ stderrStream.close();
787
+ stdoutStream.close();
788
+ });
789
+ };
790
+ page.on("pageerror", (err) => {
791
+ console.debug(`Error from ${t}: [${err.name}] `);
792
+ stderrStream.write(err.name);
793
+ if (err.cause) {
794
+ console.debug(`Error from ${t} cause: [${err.cause}] `);
795
+ stderrStream.write(err.cause);
796
+ }
797
+ if (err.stack) {
798
+ console.debug(`Error from stack ${t}: [${err.stack}] `);
799
+ stderrStream.write(err.stack);
800
+ }
801
+ console.debug(`Error from message ${t}: [${err.message}] `);
802
+ stderrStream.write(err.message);
803
+ });
804
+ page.on("console", (log) => {
805
+ stdoutStream.write(log.text());
806
+ stdoutStream.write(JSON.stringify(log.location()));
807
+ stdoutStream.write(JSON.stringify(log.stackTrace()));
808
+ });
809
+ await page.goto(`file://${`${destFolder}.html`}`, {});
810
+ await page.evaluate(evaluation).then(async ({ failed, features }) => {
811
+ this.receiveFeatures(features, destFolder, t);
812
+ statusMessagePretty(failed, t);
813
+ }).catch((e) => {
814
+ console.log(`${t} errored with`, e);
815
+ }).finally(() => {
816
+ close();
817
+ });
818
+ return page;
819
+ });
820
+ };
821
+ this.receiveFeatures = (features, destFolder, srcTest) => {
822
+ const featureDestination = path4.resolve(
823
+ process.cwd(),
824
+ "docs",
825
+ "features",
826
+ "strings",
827
+ srcTest.split(".").slice(0, -1).join(".") + ".features.txt"
828
+ );
829
+ features.reduce(async (mm, featureStringKey) => {
830
+ const accum = await mm;
831
+ const isUrl = isValidUrl(featureStringKey);
832
+ if (isUrl) {
833
+ const u = new URL(featureStringKey);
834
+ if (u.protocol === "file:") {
835
+ const newPath = `${process.cwd()}/docs/features/internal/${path4.relative(
836
+ process.cwd(),
837
+ u.pathname
838
+ )}`;
839
+ await fs2.promises.mkdir(path4.dirname(newPath), { recursive: true });
840
+ try {
841
+ await fs2.unlinkSync(newPath);
842
+ } catch (error) {
843
+ if (error.code !== "ENOENT") {
844
+ }
845
+ }
846
+ fs2.symlink(u.pathname, newPath, (err) => {
847
+ if (err) {
848
+ } else {
849
+ }
850
+ });
851
+ accum.files.push(newPath);
852
+ } else if (u.protocol === "http:" || u.protocol === "https:") {
853
+ const newPath = `${process.cwd()}/docs/features/external${u.hostname}${u.pathname}`;
854
+ const body = await this.configs.featureIngestor(featureStringKey);
855
+ writeFileAndCreateDir(newPath, body);
856
+ accum.files.push(newPath);
857
+ }
858
+ } else {
859
+ await fs2.promises.mkdir(path4.dirname(featureDestination), {
860
+ recursive: true
861
+ });
862
+ accum.strings.push(featureStringKey);
863
+ }
864
+ return accum;
865
+ }, Promise.resolve({ files: [], strings: [] })).then(({ files: files2, strings }) => {
866
+ fs2.writeFileSync(
867
+ `${destFolder}/featurePrompt.txt`,
868
+ files2.map((f) => {
869
+ return `/read ${f}`;
870
+ }).join("\n")
871
+ );
872
+ });
873
+ };
874
+ this.server = {};
875
+ this.configs = configs;
876
+ this.ports = {};
877
+ this.registry = {};
878
+ this.configs.ports.forEach((element) => {
879
+ this.ports[element] = "true";
880
+ });
881
+ globalThis["waitForSelector"] = async (pageKey, sel) => {
882
+ console.log("waitForSelector", pageKey, sel);
883
+ const page = (await this.browser.pages()).find(
884
+ (p) => p.mainFrame()._id === pageKey
885
+ );
886
+ await page?.waitForSelector(sel);
887
+ };
888
+ globalThis["screencastStop"] = async (path6) => {
889
+ return recorders[path6].stop();
890
+ };
891
+ globalThis["closePage"] = async (pageKey) => {
892
+ const page = (await this.browser.pages()).find(
893
+ (p) => p.mainFrame()._id === pageKey
894
+ );
895
+ return page.close();
896
+ };
897
+ globalThis["goto"] = async (pageKey, url) => {
898
+ const page = (await this.browser.pages()).find(
899
+ (p) => p.mainFrame()._id === pageKey
900
+ );
901
+ await page?.goto(url);
902
+ return;
903
+ };
904
+ globalThis["newPage"] = () => {
905
+ return this.browser.newPage();
906
+ };
907
+ globalThis["pages"] = () => {
908
+ return this.browser.pages();
909
+ };
910
+ globalThis["mkdirSync"] = (fp) => {
911
+ if (!fs2.existsSync(fp)) {
912
+ return fs2.mkdirSync(fp, {
913
+ recursive: true
914
+ });
915
+ }
916
+ return false;
917
+ };
918
+ globalThis["writeFileSync"] = (filepath, contents, testName) => {
919
+ const dir = path4.dirname(filepath);
920
+ fs2.mkdirSync(dir, {
921
+ recursive: true
922
+ });
923
+ if (!files[testName]) {
924
+ files[testName] = /* @__PURE__ */ new Set();
925
+ }
926
+ files[testName].add(filepath);
927
+ return fs2.writeFileSync(filepath, contents);
928
+ };
929
+ globalThis["createWriteStream"] = (filepath, testName) => {
930
+ const f = fs2.createWriteStream(filepath);
931
+ fileStreams3.push(f);
932
+ if (!files[testName]) {
933
+ files[testName] = /* @__PURE__ */ new Set();
934
+ }
935
+ files[testName].add(filepath);
936
+ return {
937
+ ...JSON.parse(JSON.stringify(f)),
938
+ uid: fileStreams3.length - 1
939
+ };
940
+ };
941
+ globalThis["write"] = (uid, contents) => {
942
+ fileStreams3[uid].write(contents);
943
+ };
944
+ globalThis["end"] = (uid) => {
945
+ fileStreams3[uid].end();
946
+ };
947
+ globalThis["customScreenShot"] = async (opts, pageKey, testName) => {
948
+ const page = (await this.browser.pages()).find(
949
+ (p2) => p2.mainFrame()._id === pageKey
950
+ );
951
+ const p = opts.path;
952
+ const dir = path4.dirname(p);
953
+ fs2.mkdirSync(dir, {
954
+ recursive: true
955
+ });
956
+ if (!files[opts.path]) {
957
+ files[opts.path] = /* @__PURE__ */ new Set();
958
+ }
959
+ files[opts.path].add(opts.path);
960
+ const sPromise = page.screenshot({
961
+ ...opts,
962
+ path: p
963
+ });
964
+ if (!screenshots[opts.path]) {
965
+ screenshots[opts.path] = [];
966
+ }
967
+ screenshots[opts.path].push(sPromise);
968
+ await sPromise;
969
+ return sPromise;
970
+ };
971
+ globalThis["screencast"] = async (opts, pageKey) => {
972
+ const page = (await this.browser.pages()).find(
973
+ (p2) => p2.mainFrame()._id === pageKey
974
+ );
975
+ const p = opts.path;
976
+ const dir = path4.dirname(p);
977
+ fs2.mkdirSync(dir, {
978
+ recursive: true
979
+ });
980
+ const recorder = await page?.screencast({
981
+ ...opts,
982
+ path: p
983
+ });
984
+ recorders[opts.path] = recorder;
985
+ return opts.path;
986
+ };
987
+ }
988
+ customclose() {
989
+ throw new Error("Method not implemented.");
990
+ }
991
+ waitForSelector(p, s) {
992
+ throw new Error("Method not implemented.");
993
+ }
994
+ closePage(p) {
995
+ throw new Error("Method not implemented.");
996
+ }
997
+ newPage() {
998
+ throw new Error("Method not implemented.");
999
+ }
1000
+ goto(p, url) {
1001
+ throw new Error("Method not implemented.");
1002
+ }
1003
+ $(selector) {
1004
+ throw new Error("Method not implemented.");
1005
+ }
1006
+ screencast(opts) {
1007
+ throw new Error("Method not implemented.");
1008
+ }
1009
+ customScreenShot(opts, cdpPage) {
1010
+ throw new Error("Method not implemented.");
1011
+ }
1012
+ end(accessObject) {
1013
+ throw new Error("Method not implemented.");
1014
+ }
1015
+ existsSync(destFolder) {
1016
+ return fs2.existsSync(destFolder);
1017
+ }
1018
+ async mkdirSync(fp) {
1019
+ if (!fs2.existsSync(fp)) {
1020
+ return fs2.mkdirSync(fp, {
1021
+ recursive: true
1022
+ });
1023
+ }
1024
+ return false;
1025
+ }
1026
+ writeFileSync(fp, contents) {
1027
+ fs2.writeFileSync(fp, contents);
1028
+ }
1029
+ createWriteStream(filepath) {
1030
+ return fs2.createWriteStream(filepath);
1031
+ }
1032
+ testArtiFactoryfileWriter(tLog, callback) {
1033
+ return (fPath, value) => {
1034
+ callback(
1035
+ new Promise((res, rej) => {
1036
+ tLog("testArtiFactory =>", fPath);
1037
+ const cleanPath = path4.resolve(fPath);
1038
+ fPaths.push(cleanPath.replace(process.cwd(), ``));
1039
+ const targetDir = cleanPath.split("/").slice(0, -1).join("/");
1040
+ fs2.mkdir(targetDir, { recursive: true }, async (error) => {
1041
+ if (error) {
1042
+ console.error(`\u2757\uFE0FtestArtiFactory failed`, targetDir, error);
1043
+ }
1044
+ fs2.writeFileSync(
1045
+ path4.resolve(
1046
+ targetDir.split("/").slice(0, -1).join("/"),
1047
+ "manifest"
1048
+ ),
1049
+ fPaths.join(`
1050
+ `),
1051
+ {
1052
+ encoding: "utf-8"
1053
+ }
1054
+ );
1055
+ if (Buffer.isBuffer(value)) {
1056
+ fs2.writeFileSync(fPath, value, "binary");
1057
+ res();
1058
+ } else if (`string` === typeof value) {
1059
+ fs2.writeFileSync(fPath, value.toString(), {
1060
+ encoding: "utf-8"
1061
+ });
1062
+ res();
1063
+ } else {
1064
+ const pipeStream = value;
1065
+ const myFile = fs2.createWriteStream(fPath);
1066
+ pipeStream.pipe(myFile);
1067
+ pipeStream.on("close", () => {
1068
+ myFile.close();
1069
+ res();
1070
+ });
1071
+ }
1072
+ });
1073
+ })
1074
+ );
1075
+ };
1076
+ }
1077
+ write(accessObject, contents) {
1078
+ throw new Error("Method not implemented.");
1079
+ }
1080
+ page() {
1081
+ throw new Error("Method not implemented.");
1082
+ }
1083
+ click(selector) {
1084
+ throw new Error("Method not implemented.");
1085
+ }
1086
+ focusOn(selector) {
1087
+ throw new Error("Method not implemented.");
1088
+ }
1089
+ typeInto(value) {
1090
+ throw new Error("Method not implemented.");
1091
+ }
1092
+ getValue(value) {
1093
+ throw new Error("Method not implemented.");
1094
+ }
1095
+ getAttribute(selector, attribute) {
1096
+ throw new Error("Method not implemented.");
1097
+ }
1098
+ isDisabled(selector) {
1099
+ throw new Error("Method not implemented.");
1100
+ }
1101
+ screencastStop(s) {
1102
+ throw new Error("Method not implemented.");
1103
+ }
1104
+ ////////////////////////////////////////////////////////////////////////////////
1105
+ async startPuppeteer(options, destfolder) {
1106
+ this.browser = await puppeteer.launch(options);
1107
+ }
1108
+ ////////////////////////////////////////////////////////////////////////////////
1109
+ shutDown() {
1110
+ console.log("shutting down...");
1111
+ this.shutdownMode = true;
1112
+ this.checkForShutdown();
1113
+ }
1114
+ };
1115
+ async function writeFileAndCreateDir(filePath, data) {
1116
+ const dirPath = path4.dirname(filePath);
1117
+ try {
1118
+ await fs2.promises.mkdir(dirPath, { recursive: true });
1119
+ await fs2.appendFileSync(filePath, data);
1120
+ } catch (error) {
1121
+ console.error(`Error writing file: ${error}`);
1122
+ }
1123
+ }
1124
+ function isValidUrl(string) {
1125
+ try {
1126
+ new URL(string);
1127
+ return true;
1128
+ } catch (err) {
1129
+ return false;
1130
+ }
1131
+ }
1132
+
1133
+ // src/cli.ts
1134
+ readline.emitKeypressEvents(process.stdin);
1135
+ if (process.stdin.isTTY)
1136
+ process.stdin.setRawMode(true);
1137
+ function parseTsErrors(logContent) {
1138
+ fs3.writeFileSync("docs/types/log.txt", logContent.join("\n"));
1139
+ try {
1140
+ const regex = /(^src(.*?))\(\d*,\d*\): error/gm;
1141
+ const brokenFilesToLines = {};
1142
+ for (let i = 0; i < logContent.length - 1; i++) {
1143
+ let m;
1144
+ while ((m = regex.exec(logContent[i])) !== null) {
1145
+ if (m.index === regex.lastIndex) {
1146
+ regex.lastIndex++;
1147
+ }
1148
+ if (!brokenFilesToLines[m[1]]) {
1149
+ brokenFilesToLines[m[1]] = /* @__PURE__ */ new Set();
1150
+ }
1151
+ brokenFilesToLines[m[1]].add(i);
1152
+ }
1153
+ }
1154
+ const final = Object.keys(brokenFilesToLines).reduce((mm, lm, ndx) => {
1155
+ mm[lm] = Array.from(brokenFilesToLines[lm]).map((l, ndx3) => {
1156
+ const a = Array.from(brokenFilesToLines[lm]);
1157
+ return Object.keys(a).reduce((mm2, lm2, ndx2) => {
1158
+ const acc = [];
1159
+ let j = a[lm2] + 1;
1160
+ let working = true;
1161
+ while (j < logContent.length - 1 && working) {
1162
+ if (!logContent[j].match(regex) && working && !logContent[j].match(/^..\/(.*?)\(\d*,\d*\)/)) {
1163
+ acc.push(logContent[j]);
1164
+ } else {
1165
+ working = false;
1166
+ }
1167
+ j++;
1168
+ }
1169
+ mm2[lm] = [logContent[l], ...acc];
1170
+ return mm2;
1171
+ }, {})[lm];
1172
+ });
1173
+ return mm;
1174
+ }, {});
1175
+ Object.keys(final).forEach((k) => {
1176
+ fs3.mkdirSync(`./docs/types/${k.split("/").slice(0, -1).join("/")}`, {
1177
+ recursive: true
1178
+ });
1179
+ fs3.writeFileSync(
1180
+ `./docs/types/${k}.type_errors.txt`,
1181
+ final[k].flat().flat().join("\r\n")
1182
+ );
1183
+ });
1184
+ } catch (error) {
1185
+ console.error("Error reading or parsing the log file:", error);
1186
+ process.exit(1);
1187
+ }
1188
+ }
1189
+ function parseLintErrors(logContent) {
1190
+ fs3.writeFileSync("docs/eslint/log.txt", logContent.join("\n"));
1191
+ try {
1192
+ const regex = new RegExp(`^${process.cwd()}/(.*?)`, "gm");
1193
+ const brokenFilesToLines = {};
1194
+ for (let i = 0; i < logContent.length - 1; i++) {
1195
+ let m;
1196
+ while ((m = regex.exec(logContent[i])) !== null) {
1197
+ if (m.index === regex.lastIndex) {
1198
+ regex.lastIndex++;
1199
+ }
1200
+ if (!brokenFilesToLines[m[1]]) {
1201
+ brokenFilesToLines[m[1]] = /* @__PURE__ */ new Set();
1202
+ }
1203
+ brokenFilesToLines[m[1]].add(i);
1204
+ }
1205
+ }
1206
+ const final = Object.keys(brokenFilesToLines).reduce((mm, lm, ndx) => {
1207
+ mm[lm] = Array.from(brokenFilesToLines[lm]).map((l, ndx3) => {
1208
+ const a = Array.from(brokenFilesToLines[lm]);
1209
+ return Object.keys(a).reduce((mm2, lm2, ndx2) => {
1210
+ const acc = [];
1211
+ let j = a[lm2] + 1;
1212
+ let working = true;
1213
+ while (j < logContent.length - 1 && working) {
1214
+ if (!logContent[j].match(regex) && working) {
1215
+ acc.push(logContent[j]);
1216
+ } else {
1217
+ working = false;
1218
+ }
1219
+ j++;
1220
+ }
1221
+ mm2[lm] = [logContent[l], ...acc];
1222
+ return mm2;
1223
+ }, {})[lm];
1224
+ });
1225
+ return mm;
1226
+ }, {});
1227
+ Object.keys(final).forEach((k) => {
1228
+ fs3.mkdirSync(`./docs/eslint/${k.split("/").slice(0, -1).join("/")}`, {
1229
+ recursive: true
1230
+ });
1231
+ fs3.writeFileSync(
1232
+ `./docs/eslint/${k}.lint_errors.txt`,
1233
+ final[k].flat().flat().join("\r\n")
1234
+ );
1235
+ });
1236
+ } catch (error) {
1237
+ console.error("Error reading or parsing the log file:", error);
1238
+ process.exit(1);
1239
+ }
1240
+ }
1241
+ var typecheck = () => {
1242
+ const logContent = [];
1243
+ fs3.rmSync("docs/types", { force: true, recursive: true });
1244
+ fs3.mkdirSync("docs/types");
1245
+ const tsc = spawn2("tsc", ["-noEmit"]);
1246
+ tsc.stdout.on("data", (data) => {
1247
+ const lines = data.toString().split("\n");
1248
+ logContent.push(...lines);
1249
+ });
1250
+ tsc.stderr.on("data", (data) => {
1251
+ console.error(`stderr: ${data}`);
1252
+ process.exit(-1);
1253
+ });
1254
+ tsc.on("close", (code) => {
1255
+ parseTsErrors(logContent);
1256
+ });
1257
+ };
1258
+ var eslint = () => {
1259
+ const logContent = [];
1260
+ fs3.rmSync("docs/eslint", { force: true, recursive: true });
1261
+ fs3.mkdirSync("docs/eslint");
1262
+ const tsc = spawn2("eslint", ["./src"]);
1263
+ tsc.stdout.on("data", (data) => {
1264
+ const lines = data.toString().split("\n");
1265
+ logContent.push(...lines);
1266
+ });
1267
+ tsc.stderr.on("data", (data) => {
1268
+ console.error(`stderr: ${data}`);
1269
+ process.exit(-1);
1270
+ });
1271
+ tsc.on("close", (code) => {
1272
+ parseLintErrors(logContent);
1273
+ });
1274
+ };
1275
+ var getRunnables = (tests, payload = {
1276
+ nodeEntryPoints: {},
1277
+ webEntryPoints: {}
1278
+ }) => {
1279
+ return tests.reduce((pt, cv, cndx, cry) => {
1280
+ if (cv[1] === "node") {
1281
+ pt.nodeEntryPoints[cv[0]] = path5.resolve(
1282
+ `./docs/node/${cv[0].split(".").slice(0, -1).concat("mjs").join(".")}`
1283
+ );
1284
+ } else if (cv[1] === "web") {
1285
+ pt.webEntryPoints[cv[0]] = path5.resolve(
1286
+ `./docs/web/${cv[0].split(".").slice(0, -1).concat("mjs").join(".")}`
1287
+ );
1288
+ }
1289
+ if (cv[3].length) {
1290
+ getRunnables(cv[3], payload);
1291
+ }
1292
+ return pt;
1293
+ }, payload);
1294
+ };
1295
+ import(process.cwd() + "/" + process.argv[2]).then(async (module) => {
1296
+ const rawConfig = module.default;
1297
+ const getSecondaryEndpointsPoints = (runtime) => {
1298
+ const meta = (ts, st) => {
1299
+ ts.forEach((t) => {
1300
+ if (t[1] === runtime) {
1301
+ st.add(t[0]);
1302
+ }
1303
+ if (Array.isArray(t[3])) {
1304
+ meta(t[3], st);
1305
+ }
1306
+ });
1307
+ return st;
1308
+ };
1309
+ return Array.from(meta(config.tests, /* @__PURE__ */ new Set()));
1310
+ };
1311
+ const config = {
1312
+ ...rawConfig,
1313
+ buildDir: process.cwd() + "/" + rawConfig.outdir
1314
+ };
1315
+ let nodeDone = false;
1316
+ let webDone = false;
1317
+ let mode = config.devMode ? "DEV" : "PROD";
1318
+ let status = "build";
1319
+ let pm = new PM_Main(config);
1320
+ const fileHashes = {};
1321
+ const { nodeEntryPoints, webEntryPoints } = getRunnables(config.tests);
1322
+ const onNodeDone = () => {
1323
+ nodeDone = true;
1324
+ onDone();
1325
+ };
1326
+ const onWebDone = () => {
1327
+ webDone = true;
1328
+ onDone();
1329
+ };
1330
+ const onDone = async () => {
1331
+ if (nodeDone && webDone) {
1332
+ status = "built";
1333
+ }
1334
+ if (nodeDone && webDone && status === "built") {
1335
+ }
1336
+ if (nodeDone && webDone && mode === "PROD") {
1337
+ console.log("Testeranto-EsBuild is all done. Goodbye!");
1338
+ process.exit();
1339
+ } else {
1340
+ if (mode === "PROD") {
1341
+ console.log("waiting for tests to finish");
1342
+ console.log(
1343
+ JSON.stringify(
1344
+ {
1345
+ nodeDone,
1346
+ webDone,
1347
+ mode
1348
+ },
1349
+ null,
1350
+ 2
1351
+ )
1352
+ );
1353
+ } else {
1354
+ console.log("waiting for tests to change");
1355
+ }
1356
+ console.log("press 'q' to quit");
1357
+ if (config.devMode) {
1358
+ console.log("ready and watching for changes...");
1359
+ } else {
1360
+ pm.shutDown();
1361
+ }
1362
+ }
1363
+ };
1364
+ console.log(
1365
+ `Press 'q' to shutdown gracefully. Press 'x' to shutdown forcefully.`
1366
+ );
1367
+ process.stdin.on("keypress", (str, key) => {
1368
+ if (key.name === "q") {
1369
+ console.log("Testeranto-EsBuild is shutting down...");
1370
+ mode = "PROD";
1371
+ onDone();
1372
+ }
1373
+ });
1374
+ fs3.writeFileSync(
1375
+ `${config.outdir}/testeranto.json`,
1376
+ JSON.stringify(config, null, 2)
1377
+ );
1378
+ Promise.resolve(
1379
+ Promise.all(
1380
+ [...getSecondaryEndpointsPoints("web")].map(async (sourceFilePath) => {
1381
+ const sourceFileSplit = sourceFilePath.split("/");
1382
+ const sourceDir = sourceFileSplit.slice(0, -1);
1383
+ const sourceFileName = sourceFileSplit[sourceFileSplit.length - 1];
1384
+ const sourceFileNameMinusJs = sourceFileName.split(".").slice(0, -1).join(".");
1385
+ const htmlFilePath = path5.normalize(
1386
+ `${process.cwd()}/${config.outdir}/web/${sourceDir.join(
1387
+ "/"
1388
+ )}/${sourceFileNameMinusJs}.html`
1389
+ );
1390
+ const jsfilePath = `./${sourceFileNameMinusJs}.mjs`;
1391
+ return fs3.promises.mkdir(path5.dirname(htmlFilePath), { recursive: true }).then(
1392
+ (x) => fs3.writeFileSync(
1393
+ htmlFilePath,
1394
+ web_html_default(jsfilePath, htmlFilePath)
1395
+ )
1396
+ );
1397
+ })
1398
+ )
1399
+ );
1400
+ glob(`./${config.outdir}/chunk-*.mjs`, {
1401
+ ignore: "node_modules/**"
1402
+ }).then((chunks) => {
1403
+ chunks.forEach((chunk) => {
1404
+ fs3.unlinkSync(chunk);
1405
+ });
1406
+ });
1407
+ debounceWatch(
1408
+ (events) => {
1409
+ typecheck();
1410
+ eslint();
1411
+ },
1412
+ "./src",
1413
+ {
1414
+ onlyFileExtensions: ["ts", "tsx", "mts"],
1415
+ debounceWaitSeconds: 0.2,
1416
+ allowOverlappingRuns: false
1417
+ }
1418
+ );
1419
+ await pm.startPuppeteer(
1420
+ {
1421
+ slowMo: 1,
1422
+ // timeout: 1,
1423
+ waitForInitialPage: false,
1424
+ executablePath: (
1425
+ // process.env.CHROMIUM_PATH || "/opt/homebrew/bin/chromium",
1426
+ "/opt/homebrew/bin/chromium"
1427
+ ),
1428
+ headless: true,
1429
+ dumpio: true,
1430
+ // timeout: 0,
1431
+ devtools: true,
1432
+ args: [
1433
+ "--auto-open-devtools-for-tabs",
1434
+ `--remote-debugging-port=3234`,
1435
+ // "--disable-features=IsolateOrigins,site-per-process",
1436
+ "--disable-site-isolation-trials",
1437
+ "--allow-insecure-localhost",
1438
+ "--allow-file-access-from-files",
1439
+ "--allow-running-insecure-content",
1440
+ "--disable-dev-shm-usage",
1441
+ "--disable-extensions",
1442
+ "--disable-gpu",
1443
+ "--disable-setuid-sandbox",
1444
+ "--disable-site-isolation-trials",
1445
+ "--disable-web-security",
1446
+ "--no-first-run",
1447
+ "--no-sandbox",
1448
+ "--no-startup-window",
1449
+ // "--no-zygote",
1450
+ "--reduce-security-for-testing",
1451
+ "--remote-allow-origins=*",
1452
+ "--unsafely-treat-insecure-origin-as-secure=*"
1453
+ // "--disable-features=IsolateOrigins",
1454
+ // "--remote-allow-origins=ws://localhost:3234",
1455
+ // "--single-process",
1456
+ // "--unsafely-treat-insecure-origin-as-secure",
1457
+ // "--unsafely-treat-insecure-origin-as-secure=ws://192.168.0.101:3234",
1458
+ // "--disk-cache-dir=/dev/null",
1459
+ // "--disk-cache-size=1",
1460
+ // "--start-maximized",
1461
+ ]
1462
+ },
1463
+ "."
1464
+ );
1465
+ await Promise.all([
1466
+ esbuild.context(node_default(config, Object.keys(nodeEntryPoints))).then(async (nodeContext) => {
1467
+ if (config.devMode) {
1468
+ await nodeContext.watch().then((v) => {
1469
+ onNodeDone();
1470
+ });
1471
+ } else {
1472
+ nodeContext.rebuild().then((v) => {
1473
+ onNodeDone();
1474
+ });
1475
+ }
1476
+ return nodeContext;
1477
+ }),
1478
+ esbuild.context(web_default(config, Object.keys(webEntryPoints))).then(async (webContext) => {
1479
+ if (config.devMode) {
1480
+ await webContext.watch().then((v) => {
1481
+ onWebDone();
1482
+ });
1483
+ } else {
1484
+ webContext.rebuild().then((v) => {
1485
+ onWebDone();
1486
+ });
1487
+ }
1488
+ return webContext;
1489
+ })
1490
+ ]);
1491
+ });