gencow 0.1.260 → 0.1.261
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/lib/cli-command-runner.mjs +12 -0
- package/lib/deploy-codegen-failure.mjs +21 -4
- package/package.json +4 -4
- package/runtime/server.mjs +132 -137
- package/runtime/tooling.mjs +242 -65
- package/scripts/codegen-named-import-check.ts +224 -0
- package/scripts/tooling-codegen-runtime.ts +26 -2
|
@@ -86,6 +86,11 @@ const SAFE_LOCAL_ERROR_CODES = new Map([
|
|
|
86
86
|
message: "Deploy stopped before upload: a backend source file could not be loaded.",
|
|
87
87
|
stage: "codegen",
|
|
88
88
|
action: (caught) => {
|
|
89
|
+
if (safeMissingExportName(caught)) {
|
|
90
|
+
const name = safeMissingExportName(caught);
|
|
91
|
+
const where = safeSourceLocation(caught) ? "at the location above " : "";
|
|
92
|
+
return `Retryable: yes, after the import of "${name}" ${where}names an export its module does not have — use an exported name, or export it from that module, then run \`npx gencow@latest codegen\` to confirm it passes, then rerun your deploy command.`;
|
|
93
|
+
}
|
|
89
94
|
const cause =
|
|
90
95
|
"the top-level code that throws during module load, or an import path that does not resolve (check the path and that the imported package is installed)";
|
|
91
96
|
if (safeSourceLocation(caught)) {
|
|
@@ -169,6 +174,13 @@ function safeDisplayDir(caught) {
|
|
|
169
174
|
}
|
|
170
175
|
const SAFE_SOURCE_LOCATION_PATH = /^(?![/\\])(?!.*(?:^|\/)\.\.(?:\/|$))[^\u0000-\u001f\u007f]{1,240}$/u;
|
|
171
176
|
|
|
177
|
+
const SAFE_IMPORT_NAME = /^[A-Za-z_$][\w$]{0,127}$/u;
|
|
178
|
+
|
|
179
|
+
function safeMissingExportName(caught) {
|
|
180
|
+
const { missingExport } = caught;
|
|
181
|
+
return typeof missingExport === "string" && SAFE_IMPORT_NAME.test(missingExport) ? missingExport : null;
|
|
182
|
+
}
|
|
183
|
+
|
|
172
184
|
function safeSourceLocation(caught) {
|
|
173
185
|
const { sourceFile, line, column } = caught;
|
|
174
186
|
if (typeof sourceFile !== "string" || !SAFE_SOURCE_LOCATION_PATH.test(sourceFile)) return null;
|
|
@@ -36,13 +36,24 @@ function toProjectRelativePath(rawPath, cwd, processCwd) {
|
|
|
36
36
|
// esbuild prints one diagnostic per line (`<file>:<line>:<col>: ERROR: <text>`) and the
|
|
37
37
|
// Bun loader prints `Could not resolve`/`Cannot find module` for an import path that does
|
|
38
38
|
// not exist. Those are load failures: the source is well-formed, its import is not.
|
|
39
|
+
// `No matching export` is an import of a name its module does not export (esbuild, or the
|
|
40
|
+
// named-import check in codegen-named-import-check.ts); the module itself is well-formed.
|
|
39
41
|
const DIAGNOSTIC_LINE_PATTERN = /ERROR: |Could not resolve "|Cannot find (?:module|package)\b/u;
|
|
40
|
-
const UNRESOLVED_MODULE_PATTERN = /Could not resolve "|Cannot find (?:module|package)\b/u;
|
|
42
|
+
const UNRESOLVED_MODULE_PATTERN = /Could not resolve "|Cannot find (?:module|package)\b|No matching export in "/u;
|
|
43
|
+
const MISSING_EXPORT_PATTERN = /No matching export in "[^"\n]*" for import "([A-Za-z_$][\w$]{0,127})"/u;
|
|
41
44
|
|
|
42
45
|
// The first diagnostic decides the class, matching how the first location is reported.
|
|
46
|
+
function firstDiagnosticLine(message) {
|
|
47
|
+
return message.split("\n").find((line) => DIAGNOSTIC_LINE_PATTERN.test(line)) ?? message;
|
|
48
|
+
}
|
|
49
|
+
|
|
43
50
|
function isUnresolvedModuleFailure(message) {
|
|
44
|
-
|
|
45
|
-
|
|
51
|
+
return UNRESOLVED_MODULE_PATTERN.test(firstDiagnosticLine(message));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Returns the imported name of a missing-export diagnostic (identifier only), or null.
|
|
55
|
+
function findMissingExportName(message) {
|
|
56
|
+
return MISSING_EXPORT_PATTERN.exec(firstDiagnosticLine(message))?.[1] ?? null;
|
|
46
57
|
}
|
|
47
58
|
|
|
48
59
|
// Returns the first project-relative source location found in a raw message, or null.
|
|
@@ -67,7 +78,12 @@ export function classifyDeployCodegenFailure(error, { cwd, backendRoot = "gencow
|
|
|
67
78
|
const location = findProjectSourceLocation(message, { cwd, processCwd });
|
|
68
79
|
const backendLocation = location && location.sourceFile.startsWith(`${backendRoot}/`) ? location : null;
|
|
69
80
|
if (isUnresolvedModuleFailure(message)) {
|
|
70
|
-
|
|
81
|
+
const missingExport = findMissingExportName(message);
|
|
82
|
+
return {
|
|
83
|
+
code: CODEGEN_FAILURE_CODES.SOURCE_LOAD_FAILED,
|
|
84
|
+
...(backendLocation ?? {}),
|
|
85
|
+
...(missingExport ? { missingExport } : {}),
|
|
86
|
+
};
|
|
71
87
|
}
|
|
72
88
|
if (location) {
|
|
73
89
|
return {
|
|
@@ -140,6 +156,7 @@ export function createDeployCodegenFailure(classification, { correlationId } = {
|
|
|
140
156
|
error.line = classification.line;
|
|
141
157
|
if (classification.column !== undefined) error.column = classification.column;
|
|
142
158
|
}
|
|
159
|
+
if (classification.missingExport !== undefined) error.missingExport = classification.missingExport;
|
|
143
160
|
// Local reference only (no Platform request exists for a codegen failure).
|
|
144
161
|
if (correlationId !== undefined) error.correlationId = correlationId;
|
|
145
162
|
return error;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gencow",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.261",
|
|
4
4
|
"description": "Gencow — AI Backend Engine",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -40,11 +40,11 @@
|
|
|
40
40
|
"ai": "^6.0.314",
|
|
41
41
|
"better-auth": "1.7.11",
|
|
42
42
|
"postgres": "^3.4.9",
|
|
43
|
-
"@gencow/client": "0.2.8",
|
|
44
43
|
"@gencow/react": "0.2.8",
|
|
44
|
+
"@gencow/client": "0.2.8",
|
|
45
|
+
"@gencow/server": "0.1.3",
|
|
45
46
|
"@gencow/core": "0.1.47",
|
|
46
|
-
"@gencow/shared": "0.0.0"
|
|
47
|
-
"@gencow/server": "0.1.3"
|
|
47
|
+
"@gencow/shared": "0.0.0"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"build": "node scripts/bundle-core.mjs && node scripts/bundle-shared.mjs && node scripts/bundle-server.mjs",
|