testeranto 0.110.0 → 0.112.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/dist/common/PM/main.js +279 -87
- package/dist/common/run.js +4 -239
- package/dist/common/tsconfig.common.tsbuildinfo +1 -1
- package/dist/module/PM/main.js +280 -88
- package/dist/module/ReportClient.js +46 -46
- package/dist/module/run.js +4 -239
- package/dist/module/tsconfig.module.tsbuildinfo +1 -1
- package/dist/prebuild/ReportClient.js +1060 -60
- package/dist/prebuild/run.mjs +297 -334
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/PM/main.d.ts +16 -9
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/types/utils.d.ts +6 -0
- package/package.json +1 -1
- package/src/PM/main.ts +406 -112
- package/src/ReportClient.tsx +80 -70
- package/src/run.ts +5 -369
- package/src/utils.ts +10 -0
- package/tsc.log +8 -6
package/dist/prebuild/run.mjs
CHANGED
|
@@ -2,20 +2,17 @@ import { createRequire } from 'module';const require = createRequire(import.meta
|
|
|
2
2
|
|
|
3
3
|
// src/run.ts
|
|
4
4
|
import ansiC2 from "ansi-colors";
|
|
5
|
-
import { watch } from "fs";
|
|
6
|
-
import path3 from "path";
|
|
7
|
-
import crypto from "node:crypto";
|
|
8
|
-
import fs2 from "fs";
|
|
9
|
-
import tsc from "tsc-prog";
|
|
10
|
-
import { ESLint } from "eslint";
|
|
11
|
-
import ts from "typescript";
|
|
12
5
|
import readline from "readline";
|
|
13
6
|
|
|
14
7
|
// src/PM/main.ts
|
|
15
|
-
import
|
|
8
|
+
import ts from "typescript";
|
|
9
|
+
import fs, { watch } from "fs";
|
|
16
10
|
import path2 from "path";
|
|
17
11
|
import puppeteer from "puppeteer-core";
|
|
18
12
|
import ansiC from "ansi-colors";
|
|
13
|
+
import crypto from "node:crypto";
|
|
14
|
+
import { ESLint } from "eslint";
|
|
15
|
+
import tsc from "tsc-prog";
|
|
19
16
|
|
|
20
17
|
// src/utils.ts
|
|
21
18
|
import path from "path";
|
|
@@ -27,14 +24,6 @@ var tscPather = (entryPoint, platform) => {
|
|
|
27
24
|
`type_errors.txt`
|
|
28
25
|
);
|
|
29
26
|
};
|
|
30
|
-
var tscExitCodePather = (entryPoint, platform) => {
|
|
31
|
-
return path.join(
|
|
32
|
-
"./docs/",
|
|
33
|
-
platform,
|
|
34
|
-
entryPoint.split(".").slice(0, -1).join("."),
|
|
35
|
-
`type_errors.txt`
|
|
36
|
-
);
|
|
37
|
-
};
|
|
38
27
|
var lintPather = (entryPoint, platform) => {
|
|
39
28
|
return path.join(
|
|
40
29
|
"./docs/",
|
|
@@ -43,33 +32,59 @@ var lintPather = (entryPoint, platform) => {
|
|
|
43
32
|
`lint_errors.json`
|
|
44
33
|
);
|
|
45
34
|
};
|
|
46
|
-
var lintExitCodePather = (entryPoint, platform) => {
|
|
47
|
-
return path.join(
|
|
48
|
-
"./docs/",
|
|
49
|
-
platform,
|
|
50
|
-
entryPoint.split(".").slice(0, -1).join("."),
|
|
51
|
-
`lint_errors.txt`
|
|
52
|
-
);
|
|
53
|
-
};
|
|
54
|
-
var bddExitCodePather = (entryPoint, platform) => {
|
|
55
|
-
return path.join(
|
|
56
|
-
"./docs/",
|
|
57
|
-
platform,
|
|
58
|
-
entryPoint.split(".").slice(0, -1).join("."),
|
|
59
|
-
`bdd_errors.txt`
|
|
60
|
-
);
|
|
61
|
-
};
|
|
62
35
|
|
|
63
36
|
// src/PM/index.ts
|
|
64
37
|
var PM = class {
|
|
65
38
|
};
|
|
66
39
|
|
|
67
40
|
// src/PM/main.ts
|
|
41
|
+
var eslint = new ESLint();
|
|
42
|
+
var formatter = await eslint.loadFormatter(
|
|
43
|
+
"./node_modules/testeranto/dist/prebuild/esbuildConfigs/eslint-formatter-testeranto.mjs"
|
|
44
|
+
);
|
|
45
|
+
var changes = {};
|
|
46
|
+
var fileHashes = {};
|
|
68
47
|
var fileStreams3 = [];
|
|
69
48
|
var fPaths = [];
|
|
70
49
|
var files = {};
|
|
71
50
|
var recorders = {};
|
|
72
51
|
var screenshots = {};
|
|
52
|
+
async function fileHash(filePath, algorithm = "md5") {
|
|
53
|
+
return new Promise((resolve, reject) => {
|
|
54
|
+
const hash = crypto.createHash(algorithm);
|
|
55
|
+
const fileStream = fs.createReadStream(filePath);
|
|
56
|
+
fileStream.on("data", (data) => {
|
|
57
|
+
hash.update(data);
|
|
58
|
+
});
|
|
59
|
+
fileStream.on("end", () => {
|
|
60
|
+
const fileHash2 = hash.digest("hex");
|
|
61
|
+
resolve(fileHash2);
|
|
62
|
+
});
|
|
63
|
+
fileStream.on("error", (error) => {
|
|
64
|
+
reject(`Error reading file: ${error.message}`);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
var getRunnables = (tests, payload = {
|
|
69
|
+
nodeEntryPoints: {},
|
|
70
|
+
webEntryPoints: {}
|
|
71
|
+
}) => {
|
|
72
|
+
return tests.reduce((pt, cv, cndx, cry) => {
|
|
73
|
+
if (cv[1] === "node") {
|
|
74
|
+
pt.nodeEntryPoints[cv[0]] = path2.resolve(
|
|
75
|
+
`./docs/node/${cv[0].split(".").slice(0, -1).concat("mjs").join(".")}`
|
|
76
|
+
);
|
|
77
|
+
} else if (cv[1] === "web") {
|
|
78
|
+
pt.webEntryPoints[cv[0]] = path2.resolve(
|
|
79
|
+
`./docs/web/${cv[0].split(".").slice(0, -1).concat("mjs").join(".")}`
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
if (cv[3].length) {
|
|
83
|
+
getRunnables(cv[3], payload);
|
|
84
|
+
}
|
|
85
|
+
return pt;
|
|
86
|
+
}, payload);
|
|
87
|
+
};
|
|
73
88
|
var statusMessagePretty = (failures, test) => {
|
|
74
89
|
if (failures === 0) {
|
|
75
90
|
console.log(ansiC.green(ansiC.inverse(`> ${test} completed successfully`)));
|
|
@@ -86,6 +101,15 @@ async function writeFileAndCreateDir(filePath, data) {
|
|
|
86
101
|
console.error(`Error writing file: ${error}`);
|
|
87
102
|
}
|
|
88
103
|
}
|
|
104
|
+
var filesHash = async (files2, algorithm = "md5") => {
|
|
105
|
+
return new Promise((resolve, reject) => {
|
|
106
|
+
resolve(
|
|
107
|
+
files2.reduce(async (mm, f) => {
|
|
108
|
+
return await mm + await fileHash(f);
|
|
109
|
+
}, Promise.resolve(""))
|
|
110
|
+
);
|
|
111
|
+
});
|
|
112
|
+
};
|
|
89
113
|
function isValidUrl(string) {
|
|
90
114
|
try {
|
|
91
115
|
new URL(string);
|
|
@@ -99,27 +123,137 @@ var PM_Main = class extends PM {
|
|
|
99
123
|
super();
|
|
100
124
|
this.shutdownMode = false;
|
|
101
125
|
this.bigBoard = {};
|
|
126
|
+
this.stop = () => {
|
|
127
|
+
console.log(ansiC.inverse("Testeranto-Run is shutting down gracefully..."));
|
|
128
|
+
this.mode = "PROD";
|
|
129
|
+
this.nodeMetafileWatcher.close();
|
|
130
|
+
this.webMetafileWatcher.close();
|
|
131
|
+
this.checkForShutdown();
|
|
132
|
+
};
|
|
133
|
+
this.tscCheck = async ({
|
|
134
|
+
entrypoint,
|
|
135
|
+
addableFiles,
|
|
136
|
+
platform
|
|
137
|
+
}) => {
|
|
138
|
+
console.log(ansiC.green(ansiC.inverse(`tsc < ${entrypoint}`)));
|
|
139
|
+
this.bigBoard[entrypoint].typeErrors = "?";
|
|
140
|
+
const program = tsc.createProgramFromConfig({
|
|
141
|
+
basePath: process.cwd(),
|
|
142
|
+
// always required, used for relative paths
|
|
143
|
+
configFilePath: "tsconfig.json",
|
|
144
|
+
// config to inherit from (optional)
|
|
145
|
+
compilerOptions: {
|
|
146
|
+
rootDir: "src",
|
|
147
|
+
outDir: tscPather(entrypoint, platform),
|
|
148
|
+
// declaration: true,
|
|
149
|
+
// skipLibCheck: true,
|
|
150
|
+
noEmit: true
|
|
151
|
+
},
|
|
152
|
+
include: addableFiles
|
|
153
|
+
//["src/**/*"],
|
|
154
|
+
// exclude: ["**/*.test.ts", "**/*.spec.ts"],
|
|
155
|
+
});
|
|
156
|
+
const tscPath = tscPather(entrypoint, platform);
|
|
157
|
+
let allDiagnostics = program.getSemanticDiagnostics();
|
|
158
|
+
const d = [];
|
|
159
|
+
allDiagnostics.forEach((diagnostic) => {
|
|
160
|
+
if (diagnostic.file) {
|
|
161
|
+
let { line, character } = ts.getLineAndCharacterOfPosition(
|
|
162
|
+
diagnostic.file,
|
|
163
|
+
diagnostic.start
|
|
164
|
+
);
|
|
165
|
+
let message = ts.flattenDiagnosticMessageText(
|
|
166
|
+
diagnostic.messageText,
|
|
167
|
+
"\n"
|
|
168
|
+
);
|
|
169
|
+
d.push(
|
|
170
|
+
`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`
|
|
171
|
+
);
|
|
172
|
+
} else {
|
|
173
|
+
d.push(ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"));
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
fs.writeFileSync(tscPath, d.join("\n"));
|
|
177
|
+
this.bigBoard[entrypoint].typeErrors = d.length;
|
|
178
|
+
if (this.shutdownMode) {
|
|
179
|
+
this.checkForShutdown();
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
this.eslintCheck = async (entrypoint, platform, addableFiles) => {
|
|
183
|
+
this.bigBoard[entrypoint].staticErrors = "?";
|
|
184
|
+
console.log(ansiC.green(ansiC.inverse(`eslint < ${entrypoint}`)));
|
|
185
|
+
const results = (await eslint.lintFiles(addableFiles)).filter((r) => r.messages.length).filter((r) => {
|
|
186
|
+
return r.messages[0].ruleId !== null;
|
|
187
|
+
}).map((r) => {
|
|
188
|
+
delete r.source;
|
|
189
|
+
return r;
|
|
190
|
+
});
|
|
191
|
+
fs.writeFileSync(
|
|
192
|
+
lintPather(entrypoint, platform),
|
|
193
|
+
await formatter.format(results)
|
|
194
|
+
);
|
|
195
|
+
this.bigBoard[entrypoint].staticErrors = results.length;
|
|
196
|
+
if (this.shutdownMode) {
|
|
197
|
+
this.checkForShutdown();
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
this.makePrompt = async (entryPoint, addableFiles, platform) => {
|
|
201
|
+
this.bigBoard[entryPoint].prompt = "?";
|
|
202
|
+
const promptPath = path2.join(
|
|
203
|
+
"./docs/",
|
|
204
|
+
platform,
|
|
205
|
+
entryPoint.split(".").slice(0, -1).join("."),
|
|
206
|
+
`prompt.txt`
|
|
207
|
+
);
|
|
208
|
+
const testPaths = path2.join(
|
|
209
|
+
"./docs/",
|
|
210
|
+
platform,
|
|
211
|
+
entryPoint.split(".").slice(0, -1).join("."),
|
|
212
|
+
`tests.json`
|
|
213
|
+
);
|
|
214
|
+
const featuresPath = path2.join(
|
|
215
|
+
"./docs/",
|
|
216
|
+
platform,
|
|
217
|
+
entryPoint.split(".").slice(0, -1).join("."),
|
|
218
|
+
`featurePrompt.txt`
|
|
219
|
+
);
|
|
220
|
+
fs.writeFileSync(
|
|
221
|
+
promptPath,
|
|
222
|
+
`
|
|
223
|
+
${addableFiles.map((x) => {
|
|
224
|
+
return `/add ${x}`;
|
|
225
|
+
}).join("\n")}
|
|
226
|
+
|
|
227
|
+
/read ${lintPather(entryPoint, platform)}
|
|
228
|
+
/read ${tscPather(entryPoint, platform)}
|
|
229
|
+
/read ${testPaths}
|
|
230
|
+
|
|
231
|
+
/load ${featuresPath}
|
|
232
|
+
|
|
233
|
+
/code Fix the failing tests described in ${testPaths}. Correct any type signature errors described in the files ${tscPather(
|
|
234
|
+
entryPoint,
|
|
235
|
+
platform
|
|
236
|
+
)}. Implement any method which throws "Function not implemented. Resolve the lint errors described in ${lintPather(
|
|
237
|
+
entryPoint,
|
|
238
|
+
platform
|
|
239
|
+
)}"
|
|
240
|
+
`
|
|
241
|
+
);
|
|
242
|
+
this.bigBoard[entryPoint].prompt = `aider --model deepseek/deepseek-chat --load docs/${platform}/${entryPoint.split(".").slice(0, -1).join(".")}/prompt.txt`;
|
|
243
|
+
if (this.shutdownMode) {
|
|
244
|
+
this.checkForShutdown();
|
|
245
|
+
}
|
|
246
|
+
};
|
|
102
247
|
this.checkForShutdown = () => {
|
|
103
|
-
const anyRunning = Object.values(this.bigBoard).filter((x) => x.
|
|
248
|
+
const anyRunning = Object.values(this.bigBoard).filter((x) => x.prompt === "?").length + Object.values(this.bigBoard).filter((x) => x.runTimeError === "?").length + Object.values(this.bigBoard).filter((x) => x.staticErrors === "?").length + Object.values(this.bigBoard).filter((x) => x.typeErrors === "?").length > 0;
|
|
104
249
|
if (anyRunning) {
|
|
250
|
+
console.log(ansiC.inverse("Shutting down. Please wait"));
|
|
105
251
|
} else {
|
|
106
252
|
this.browser.disconnect().then(() => {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const lintErrors = fs.readFileSync(lintExitCodePather(t[0], t[1])).toString();
|
|
112
|
-
const typeErrors = fs.readFileSync(tscExitCodePather(t[0], t[1])).toString();
|
|
113
|
-
mm[t[0]] = {
|
|
114
|
-
bddErrors,
|
|
115
|
-
lintErrors,
|
|
116
|
-
typeErrors
|
|
117
|
-
};
|
|
118
|
-
return mm;
|
|
119
|
-
}, {})
|
|
120
|
-
};
|
|
121
|
-
const s = JSON.stringify(final, null, 2);
|
|
122
|
-
fs.writeFileSync("docs/summary.json", s);
|
|
253
|
+
fs.writeFileSync(
|
|
254
|
+
"docs/summary.json",
|
|
255
|
+
JSON.stringify(this.bigBoard, null, 2)
|
|
256
|
+
);
|
|
123
257
|
console.log(ansiC.inverse("Goodbye"));
|
|
124
258
|
process.exit();
|
|
125
259
|
});
|
|
@@ -206,7 +340,6 @@ var PM_Main = class extends PM {
|
|
|
206
340
|
this.launchWebSideCar = async (src, dest, testConfig) => {
|
|
207
341
|
const d = dest + ".mjs";
|
|
208
342
|
console.log(ansiC.green(ansiC.inverse(`launchWebSideCar ${src}`)));
|
|
209
|
-
const destFolder = dest.replace(".mjs", "");
|
|
210
343
|
const fileStreams2 = [];
|
|
211
344
|
const doneFileStream2 = [];
|
|
212
345
|
return new Promise((res, rej) => {
|
|
@@ -608,7 +741,6 @@ var PM_Main = class extends PM {
|
|
|
608
741
|
}).join("\n")
|
|
609
742
|
);
|
|
610
743
|
});
|
|
611
|
-
this.writeBigBoard();
|
|
612
744
|
};
|
|
613
745
|
this.receiveExitCode = (srcTest, failures) => {
|
|
614
746
|
this.bigBoard[srcTest].runTimeError = failures;
|
|
@@ -616,16 +748,20 @@ var PM_Main = class extends PM {
|
|
|
616
748
|
};
|
|
617
749
|
this.writeBigBoard = () => {
|
|
618
750
|
fs.writeFileSync(
|
|
619
|
-
"./docs/
|
|
751
|
+
"./docs/summary.json",
|
|
620
752
|
JSON.stringify(this.bigBoard, null, 2)
|
|
621
753
|
);
|
|
622
754
|
};
|
|
755
|
+
this.mode = configs.devMode ? "DEV" : "PROD";
|
|
623
756
|
this.server = {};
|
|
624
757
|
this.configs = configs;
|
|
625
758
|
this.ports = {};
|
|
626
759
|
this.configs.tests.forEach(([t]) => {
|
|
627
760
|
this.bigBoard[t] = {
|
|
628
|
-
|
|
761
|
+
runTimeError: "?",
|
|
762
|
+
typeErrors: "?",
|
|
763
|
+
staticErrors: "?",
|
|
764
|
+
prompt: "?"
|
|
629
765
|
};
|
|
630
766
|
});
|
|
631
767
|
this.configs.ports.forEach((element) => {
|
|
@@ -638,8 +774,8 @@ var PM_Main = class extends PM {
|
|
|
638
774
|
);
|
|
639
775
|
await page?.waitForSelector(sel);
|
|
640
776
|
};
|
|
641
|
-
globalThis["screencastStop"] = async (
|
|
642
|
-
return recorders[
|
|
777
|
+
globalThis["screencastStop"] = async (path3) => {
|
|
778
|
+
return recorders[path3].stop();
|
|
643
779
|
};
|
|
644
780
|
globalThis["closePage"] = async (pageKey) => {
|
|
645
781
|
const page = (await this.browser.pages()).find(
|
|
@@ -858,260 +994,44 @@ var PM_Main = class extends PM {
|
|
|
858
994
|
throw new Error("Method not implemented.");
|
|
859
995
|
}
|
|
860
996
|
////////////////////////////////////////////////////////////////////////////////
|
|
861
|
-
async
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
if (process.stdin.isTTY)
|
|
880
|
-
process.stdin.setRawMode(true);
|
|
881
|
-
process.stdin.on("keypress", (str, key) => {
|
|
882
|
-
if (key.name === "x") {
|
|
883
|
-
console.log(ansiC2.inverse("Shutting down forcefully..."));
|
|
884
|
-
process.exit(-1);
|
|
885
|
-
}
|
|
886
|
-
});
|
|
887
|
-
async function fileHash(filePath, algorithm = "md5") {
|
|
888
|
-
return new Promise((resolve, reject) => {
|
|
889
|
-
const hash = crypto.createHash(algorithm);
|
|
890
|
-
const fileStream = fs2.createReadStream(filePath);
|
|
891
|
-
fileStream.on("data", (data) => {
|
|
892
|
-
hash.update(data);
|
|
893
|
-
});
|
|
894
|
-
fileStream.on("end", () => {
|
|
895
|
-
const fileHash2 = hash.digest("hex");
|
|
896
|
-
resolve(fileHash2);
|
|
897
|
-
});
|
|
898
|
-
fileStream.on("error", (error) => {
|
|
899
|
-
reject(`Error reading file: ${error.message}`);
|
|
900
|
-
});
|
|
901
|
-
});
|
|
902
|
-
}
|
|
903
|
-
async function filesHash(files2, algorithm = "md5") {
|
|
904
|
-
return new Promise((resolve, reject) => {
|
|
905
|
-
resolve(
|
|
906
|
-
files2.reduce(async (mm, f) => {
|
|
907
|
-
return await mm + await fileHash(f);
|
|
908
|
-
}, Promise.resolve(""))
|
|
909
|
-
);
|
|
910
|
-
});
|
|
911
|
-
}
|
|
912
|
-
var getRunnables = (tests, payload = {
|
|
913
|
-
nodeEntryPoints: {},
|
|
914
|
-
webEntryPoints: {}
|
|
915
|
-
}) => {
|
|
916
|
-
return tests.reduce((pt, cv, cndx, cry) => {
|
|
917
|
-
if (cv[1] === "node") {
|
|
918
|
-
pt.nodeEntryPoints[cv[0]] = path3.resolve(
|
|
919
|
-
`./docs/node/${cv[0].split(".").slice(0, -1).concat("mjs").join(".")}`
|
|
920
|
-
);
|
|
921
|
-
} else if (cv[1] === "web") {
|
|
922
|
-
pt.webEntryPoints[cv[0]] = path3.resolve(
|
|
923
|
-
`./docs/web/${cv[0].split(".").slice(0, -1).concat("mjs").join(".")}`
|
|
924
|
-
);
|
|
925
|
-
}
|
|
926
|
-
if (cv[3].length) {
|
|
927
|
-
getRunnables(cv[3], payload);
|
|
928
|
-
}
|
|
929
|
-
return pt;
|
|
930
|
-
}, payload);
|
|
931
|
-
};
|
|
932
|
-
var changes = {};
|
|
933
|
-
var tscCheck = async ({
|
|
934
|
-
entrypoint,
|
|
935
|
-
addableFiles,
|
|
936
|
-
platform
|
|
937
|
-
}) => {
|
|
938
|
-
console.log(ansiC2.green(ansiC2.inverse(`tsc < ${entrypoint}`)));
|
|
939
|
-
const program = tsc.createProgramFromConfig({
|
|
940
|
-
basePath: process.cwd(),
|
|
941
|
-
// always required, used for relative paths
|
|
942
|
-
configFilePath: "tsconfig.json",
|
|
943
|
-
// config to inherit from (optional)
|
|
944
|
-
compilerOptions: {
|
|
945
|
-
rootDir: "src",
|
|
946
|
-
outDir: tscPather(entrypoint, platform),
|
|
947
|
-
// declaration: true,
|
|
948
|
-
// skipLibCheck: true,
|
|
949
|
-
noEmit: true
|
|
950
|
-
},
|
|
951
|
-
include: addableFiles
|
|
952
|
-
//["src/**/*"],
|
|
953
|
-
// exclude: ["**/*.test.ts", "**/*.spec.ts"],
|
|
954
|
-
});
|
|
955
|
-
const tscPath = tscPather(entrypoint, platform);
|
|
956
|
-
let allDiagnostics = program.getSemanticDiagnostics();
|
|
957
|
-
const d = [];
|
|
958
|
-
allDiagnostics.forEach((diagnostic) => {
|
|
959
|
-
if (diagnostic.file) {
|
|
960
|
-
let { line, character } = ts.getLineAndCharacterOfPosition(
|
|
961
|
-
diagnostic.file,
|
|
962
|
-
diagnostic.start
|
|
963
|
-
);
|
|
964
|
-
let message = ts.flattenDiagnosticMessageText(
|
|
965
|
-
diagnostic.messageText,
|
|
966
|
-
"\n"
|
|
967
|
-
);
|
|
968
|
-
d.push(
|
|
969
|
-
`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`
|
|
970
|
-
);
|
|
971
|
-
} else {
|
|
972
|
-
d.push(ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"));
|
|
973
|
-
}
|
|
974
|
-
});
|
|
975
|
-
fs2.writeFileSync(tscPath, d.join("\n"));
|
|
976
|
-
fs2.writeFileSync(
|
|
977
|
-
tscExitCodePather(entrypoint, platform),
|
|
978
|
-
d.length.toString()
|
|
979
|
-
);
|
|
980
|
-
};
|
|
981
|
-
var eslint = new ESLint();
|
|
982
|
-
var formatter = await eslint.loadFormatter(
|
|
983
|
-
"./node_modules/testeranto/dist/prebuild/esbuildConfigs/eslint-formatter-testeranto.mjs"
|
|
984
|
-
);
|
|
985
|
-
var eslintCheck = async (entrypoint, platform, addableFiles) => {
|
|
986
|
-
console.log(ansiC2.green(ansiC2.inverse(`eslint < ${entrypoint}`)));
|
|
987
|
-
const results = (await eslint.lintFiles(addableFiles)).filter((r) => r.messages.length).filter((r) => {
|
|
988
|
-
return r.messages[0].ruleId !== null;
|
|
989
|
-
}).map((r) => {
|
|
990
|
-
delete r.source;
|
|
991
|
-
return r;
|
|
992
|
-
});
|
|
993
|
-
fs2.writeFileSync(
|
|
994
|
-
lintPather(entrypoint, platform),
|
|
995
|
-
await formatter.format(results)
|
|
996
|
-
);
|
|
997
|
-
fs2.writeFileSync(
|
|
998
|
-
lintExitCodePather(entrypoint, platform),
|
|
999
|
-
results.length.toString()
|
|
1000
|
-
);
|
|
1001
|
-
};
|
|
1002
|
-
var makePrompt = async (entryPoint, addableFiles, platform) => {
|
|
1003
|
-
const promptPath = path3.join(
|
|
1004
|
-
"./docs/",
|
|
1005
|
-
platform,
|
|
1006
|
-
entryPoint.split(".").slice(0, -1).join("."),
|
|
1007
|
-
`prompt.txt`
|
|
1008
|
-
);
|
|
1009
|
-
const testPaths = path3.join(
|
|
1010
|
-
"./docs/",
|
|
1011
|
-
platform,
|
|
1012
|
-
entryPoint.split(".").slice(0, -1).join("."),
|
|
1013
|
-
`tests.json`
|
|
1014
|
-
);
|
|
1015
|
-
const featuresPath = path3.join(
|
|
1016
|
-
"./docs/",
|
|
1017
|
-
platform,
|
|
1018
|
-
entryPoint.split(".").slice(0, -1).join("."),
|
|
1019
|
-
`featurePrompt.txt`
|
|
1020
|
-
);
|
|
1021
|
-
fs2.writeFileSync(
|
|
1022
|
-
promptPath,
|
|
1023
|
-
`
|
|
1024
|
-
${addableFiles.map((x) => {
|
|
1025
|
-
return `/add ${x}`;
|
|
1026
|
-
}).join("\n")}
|
|
1027
|
-
|
|
1028
|
-
/read ${lintPather(entryPoint, platform)}
|
|
1029
|
-
/read ${tscPather(entryPoint, platform)}
|
|
1030
|
-
/read ${testPaths}
|
|
1031
|
-
|
|
1032
|
-
/load ${featuresPath}
|
|
1033
|
-
|
|
1034
|
-
/code Fix the failing tests described in ${testPaths}. Correct any type signature errors described in the files ${tscPather(
|
|
1035
|
-
entryPoint,
|
|
1036
|
-
platform
|
|
1037
|
-
)}. Implement any method which throws "Function not implemented. Resolve the lint errors described in ${lintPather(
|
|
1038
|
-
entryPoint,
|
|
1039
|
-
platform
|
|
1040
|
-
)}"
|
|
1041
|
-
`
|
|
1042
|
-
);
|
|
1043
|
-
};
|
|
1044
|
-
var metafileOutputs = async (platform) => {
|
|
1045
|
-
const metafile = JSON.parse(
|
|
1046
|
-
fs2.readFileSync(`docs/${platform}/metafile.json`).toString()
|
|
1047
|
-
).metafile;
|
|
1048
|
-
if (!metafile)
|
|
1049
|
-
return;
|
|
1050
|
-
const outputs = metafile.outputs;
|
|
1051
|
-
Object.keys(outputs).forEach(async (k) => {
|
|
1052
|
-
const addableFiles = Object.keys(outputs[k].inputs).filter((i) => {
|
|
1053
|
-
if (!fs2.existsSync(i))
|
|
1054
|
-
return false;
|
|
1055
|
-
if (i.startsWith("node_modules"))
|
|
1056
|
-
return false;
|
|
1057
|
-
return true;
|
|
1058
|
-
});
|
|
1059
|
-
const f = `${k.split(".").slice(0, -1).join(".")}/`;
|
|
1060
|
-
if (!fs2.existsSync(f)) {
|
|
1061
|
-
fs2.mkdirSync(f);
|
|
1062
|
-
}
|
|
1063
|
-
const entrypoint = outputs[k].entryPoint;
|
|
1064
|
-
if (entrypoint) {
|
|
1065
|
-
const changeDigest = await filesHash(addableFiles);
|
|
1066
|
-
if (changeDigest === changes[entrypoint]) {
|
|
1067
|
-
} else {
|
|
1068
|
-
changes[entrypoint] = changeDigest;
|
|
1069
|
-
tscCheck({ platform, addableFiles, entrypoint });
|
|
1070
|
-
eslintCheck(entrypoint, platform, addableFiles);
|
|
1071
|
-
makePrompt(entrypoint, addableFiles, platform);
|
|
997
|
+
async metafileOutputs(platform) {
|
|
998
|
+
const metafile = JSON.parse(
|
|
999
|
+
fs.readFileSync(`docs/${platform}/metafile.json`).toString()
|
|
1000
|
+
).metafile;
|
|
1001
|
+
if (!metafile)
|
|
1002
|
+
return;
|
|
1003
|
+
const outputs = metafile.outputs;
|
|
1004
|
+
Object.keys(outputs).forEach(async (k) => {
|
|
1005
|
+
const addableFiles = Object.keys(outputs[k].inputs).filter((i) => {
|
|
1006
|
+
if (!fs.existsSync(i))
|
|
1007
|
+
return false;
|
|
1008
|
+
if (i.startsWith("node_modules"))
|
|
1009
|
+
return false;
|
|
1010
|
+
return true;
|
|
1011
|
+
});
|
|
1012
|
+
const f = `${k.split(".").slice(0, -1).join(".")}/`;
|
|
1013
|
+
if (!fs.existsSync(f)) {
|
|
1014
|
+
fs.mkdirSync(f);
|
|
1072
1015
|
}
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
nodeMetafileWatcher.close();
|
|
1093
|
-
webMetafileWatcher.close();
|
|
1094
|
-
pm.shutDown();
|
|
1095
|
-
}
|
|
1096
|
-
});
|
|
1097
|
-
metafileOutputs("node");
|
|
1098
|
-
const nodeMetafileWatcher = watch(
|
|
1099
|
-
"docs/node/metafile.json",
|
|
1100
|
-
async (e, filename) => {
|
|
1101
|
-
console.log(ansiC2.green(ansiC2.inverse(`< ${e} ${filename} (node)`)));
|
|
1102
|
-
metafileOutputs("node");
|
|
1103
|
-
}
|
|
1104
|
-
);
|
|
1105
|
-
metafileOutputs("web");
|
|
1106
|
-
const webMetafileWatcher = watch(
|
|
1107
|
-
"docs/web/metafile.json",
|
|
1108
|
-
async (e, filename) => {
|
|
1109
|
-
console.log(ansiC2.green(ansiC2.inverse(`< ${e} ${filename} (web)`)));
|
|
1110
|
-
metafileOutputs("web");
|
|
1111
|
-
}
|
|
1112
|
-
);
|
|
1113
|
-
await pm.startPuppeteer(
|
|
1114
|
-
{
|
|
1016
|
+
const entrypoint = outputs[k].entryPoint;
|
|
1017
|
+
if (entrypoint) {
|
|
1018
|
+
const changeDigest = await filesHash(addableFiles);
|
|
1019
|
+
if (changeDigest === changes[entrypoint]) {
|
|
1020
|
+
} else {
|
|
1021
|
+
changes[entrypoint] = changeDigest;
|
|
1022
|
+
this.tscCheck({
|
|
1023
|
+
platform,
|
|
1024
|
+
addableFiles,
|
|
1025
|
+
entrypoint: "./" + entrypoint
|
|
1026
|
+
});
|
|
1027
|
+
this.eslintCheck("./" + entrypoint, platform, addableFiles);
|
|
1028
|
+
this.makePrompt("./" + entrypoint, addableFiles, platform);
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
});
|
|
1032
|
+
}
|
|
1033
|
+
async start() {
|
|
1034
|
+
this.browser = await puppeteer.launch({
|
|
1115
1035
|
slowMo: 1,
|
|
1116
1036
|
// timeout: 1,
|
|
1117
1037
|
waitForInitialPage: false,
|
|
@@ -1153,38 +1073,81 @@ import(process.cwd() + "/" + process.argv[2]).then(async (module) => {
|
|
|
1153
1073
|
// "--disk-cache-size=1",
|
|
1154
1074
|
// "--start-maximized",
|
|
1155
1075
|
]
|
|
1156
|
-
}
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1076
|
+
});
|
|
1077
|
+
const { nodeEntryPoints, webEntryPoints } = getRunnables(
|
|
1078
|
+
this.configs.tests
|
|
1079
|
+
);
|
|
1080
|
+
Object.entries(nodeEntryPoints).forEach(
|
|
1081
|
+
([k, outputFile]) => {
|
|
1082
|
+
this.launchNode(k, outputFile);
|
|
1083
|
+
try {
|
|
1084
|
+
watch(outputFile, async (e, filename) => {
|
|
1085
|
+
const hash = await fileHash(outputFile);
|
|
1086
|
+
if (fileHashes[k] !== hash) {
|
|
1087
|
+
fileHashes[k] = hash;
|
|
1088
|
+
console.log(ansiC.green(ansiC.inverse(`< ${e} ${filename}`)));
|
|
1089
|
+
this.launchNode(k, outputFile);
|
|
1090
|
+
}
|
|
1091
|
+
});
|
|
1092
|
+
} catch (e) {
|
|
1093
|
+
console.error(e);
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
);
|
|
1097
|
+
Object.entries(webEntryPoints).forEach(
|
|
1098
|
+
([k, outputFile]) => {
|
|
1099
|
+
this.launchWeb(k, outputFile);
|
|
1164
1100
|
watch(outputFile, async (e, filename) => {
|
|
1165
1101
|
const hash = await fileHash(outputFile);
|
|
1166
1102
|
if (fileHashes[k] !== hash) {
|
|
1167
1103
|
fileHashes[k] = hash;
|
|
1168
|
-
console.log(
|
|
1169
|
-
|
|
1104
|
+
console.log(ansiC.green(ansiC.inverse(`< ${e} ${filename}`)));
|
|
1105
|
+
this.launchWeb(k, outputFile);
|
|
1170
1106
|
}
|
|
1171
1107
|
});
|
|
1172
|
-
} catch (e) {
|
|
1173
|
-
console.error(e);
|
|
1174
1108
|
}
|
|
1109
|
+
);
|
|
1110
|
+
this.metafileOutputs("node");
|
|
1111
|
+
this.nodeMetafileWatcher = watch(
|
|
1112
|
+
"docs/node/metafile.json",
|
|
1113
|
+
async (e, filename) => {
|
|
1114
|
+
console.log(ansiC.green(ansiC.inverse(`< ${e} ${filename} (node)`)));
|
|
1115
|
+
this.metafileOutputs("node");
|
|
1116
|
+
}
|
|
1117
|
+
);
|
|
1118
|
+
this.metafileOutputs("web");
|
|
1119
|
+
this.webMetafileWatcher = watch(
|
|
1120
|
+
"docs/web/metafile.json",
|
|
1121
|
+
async (e, filename) => {
|
|
1122
|
+
console.log(ansiC.green(ansiC.inverse(`< ${e} ${filename} (web)`)));
|
|
1123
|
+
this.metafileOutputs("web");
|
|
1124
|
+
}
|
|
1125
|
+
);
|
|
1126
|
+
}
|
|
1127
|
+
};
|
|
1128
|
+
|
|
1129
|
+
// src/run.ts
|
|
1130
|
+
readline.emitKeypressEvents(process.stdin);
|
|
1131
|
+
if (process.stdin.isTTY)
|
|
1132
|
+
process.stdin.setRawMode(true);
|
|
1133
|
+
console.log(ansiC2.inverse("Press 'x' to shutdown forcefully."));
|
|
1134
|
+
process.stdin.on("keypress", (str, key) => {
|
|
1135
|
+
if (key.name === "x") {
|
|
1136
|
+
console.log(ansiC2.inverse("Shutting down forcefully..."));
|
|
1137
|
+
process.exit(-1);
|
|
1138
|
+
}
|
|
1139
|
+
});
|
|
1140
|
+
import(process.cwd() + "/" + process.argv[2]).then(async (module) => {
|
|
1141
|
+
const rawConfig = module.default;
|
|
1142
|
+
const config = {
|
|
1143
|
+
...rawConfig,
|
|
1144
|
+
buildDir: process.cwd() + "/" + rawConfig.outdir
|
|
1145
|
+
};
|
|
1146
|
+
const pm = new PM_Main(config);
|
|
1147
|
+
pm.start();
|
|
1148
|
+
process.stdin.on("keypress", (str, key) => {
|
|
1149
|
+
if (key.name === "q") {
|
|
1150
|
+
pm.stop();
|
|
1175
1151
|
}
|
|
1176
|
-
);
|
|
1177
|
-
Object.entries(webEntryPoints).forEach(
|
|
1178
|
-
([k, outputFile]) => {
|
|
1179
|
-
pm.launchWeb(k, outputFile);
|
|
1180
|
-
watch(outputFile, async (e, filename) => {
|
|
1181
|
-
const hash = await fileHash(outputFile);
|
|
1182
|
-
if (fileHashes[k] !== hash) {
|
|
1183
|
-
fileHashes[k] = hash;
|
|
1184
|
-
console.log(ansiC2.green(ansiC2.inverse(`< ${e} ${filename}`)));
|
|
1185
|
-
pm.launchWeb(k, outputFile);
|
|
1186
|
-
}
|
|
1187
|
-
});
|
|
1188
|
-
}
|
|
1189
|
-
);
|
|
1152
|
+
});
|
|
1190
1153
|
});
|