gencow 0.1.199 → 0.1.201
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/add-memory.mjs +21 -0
- package/lib/cloud-targets.mjs +11 -4
- package/lib/codegen-command.mjs +15 -6
- package/lib/db-command.mjs +1 -1
- package/lib/deploy-bundle-staging.mjs +23 -6
- package/lib/deploy-codegen-preflight.mjs +122 -0
- package/lib/deploy-package-runtime.mjs +50 -39
- package/lib/deploy-project-metadata.mjs +32 -3
- package/lib/deploy-runtime.mjs +1 -1
- package/lib/deploy-static-fullstack-runtime.mjs +3 -0
- package/lib/install-features.mjs +2 -0
- package/lib/static-deploy-command.mjs +3 -21
- package/package.json +3 -3
- package/runtime/server.mjs +204 -51
- package/server/index.js.map +7 -0
- package/templateFeature/memory/manifest.json +1 -0
- package/templates/ai-chat/schema.ts +2 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { dirname, relative, resolve } from "path";
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
3
|
+
|
|
4
|
+
import { patchSchemaEntrySource } from "./add-rag.mjs";
|
|
5
|
+
|
|
6
|
+
export async function patchMemoryProjectWiring(deps) {
|
|
7
|
+
const cwd = deps.cwdImpl();
|
|
8
|
+
const exists = deps.existsSyncImpl ?? existsSync;
|
|
9
|
+
const projectConfig = await deps.loadConfig();
|
|
10
|
+
const functionsDir = projectConfig?.rootDir || "gencow";
|
|
11
|
+
const schemaPath = resolve(cwd, functionsDir, "schema.ts");
|
|
12
|
+
|
|
13
|
+
if (!exists(dirname(schemaPath))) mkdirSync(dirname(schemaPath), { recursive: true });
|
|
14
|
+
|
|
15
|
+
const schemaSource = exists(schemaPath) ? readFileSync(schemaPath, "utf-8") : "";
|
|
16
|
+
const nextSchemaSource = patchSchemaEntrySource(schemaSource, "./schema-memory");
|
|
17
|
+
if (nextSchemaSource !== schemaSource) {
|
|
18
|
+
writeFileSync(schemaPath, nextSchemaSource);
|
|
19
|
+
deps.logImpl(` ${deps.GREEN}✓${deps.RESET} ${relative(cwd, schemaPath)} — exported schema-memory`);
|
|
20
|
+
}
|
|
21
|
+
}
|
package/lib/cloud-targets.mjs
CHANGED
|
@@ -15,17 +15,21 @@ export function readProjectAppTargets(cwd = process.cwd()) {
|
|
|
15
15
|
}
|
|
16
16
|
const gencowJsonPath = resolveProjectMetadataPath(projectDir, resolve);
|
|
17
17
|
if (!existsSync(gencowJsonPath)) {
|
|
18
|
-
return { appId: null, prodApp: null };
|
|
18
|
+
return { appId: null, invalid: false, prodApp: null };
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
try {
|
|
22
22
|
const gencowJson = JSON.parse(readFileSync(gencowJsonPath, "utf8"));
|
|
23
|
+
if (!gencowJson || typeof gencowJson !== "object" || Array.isArray(gencowJson)) {
|
|
24
|
+
return { appId: null, invalid: true, prodApp: null };
|
|
25
|
+
}
|
|
23
26
|
return {
|
|
24
27
|
appId: gencowJson.appId || gencowJson.appName || null,
|
|
28
|
+
invalid: false,
|
|
25
29
|
prodApp: gencowJson.prodApp || null,
|
|
26
30
|
};
|
|
27
31
|
} catch {
|
|
28
|
-
return { appId: null, prodApp: null };
|
|
32
|
+
return { appId: null, invalid: true, prodApp: null };
|
|
29
33
|
}
|
|
30
34
|
}
|
|
31
35
|
|
|
@@ -52,15 +56,18 @@ export function resolveCloudAppTarget(restArgs, options = {}) {
|
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
const projectTargets = readProjectAppTargets(cwd);
|
|
59
|
+
if (projectTargets.invalid) {
|
|
60
|
+
return { error: "MIGRATION_PROJECT_CONFIG_INVALID" };
|
|
61
|
+
}
|
|
55
62
|
if (!appId) {
|
|
56
63
|
appId = envTarget === "prod" ? projectTargets.prodApp : projectTargets.appId;
|
|
57
64
|
}
|
|
58
65
|
|
|
59
66
|
if (envTarget === "prod") {
|
|
60
|
-
if (!projectTargets.prodApp) {
|
|
67
|
+
if (!projectTargets.prodApp && !explicitApp) {
|
|
61
68
|
return { error: missingProdMessage };
|
|
62
69
|
}
|
|
63
|
-
if (explicitApp && appId !== projectTargets.prodApp) {
|
|
70
|
+
if (explicitApp && projectTargets.prodApp && appId !== projectTargets.prodApp) {
|
|
64
71
|
return { error: missingProdMessage };
|
|
65
72
|
}
|
|
66
73
|
}
|
package/lib/codegen-command.mjs
CHANGED
|
@@ -5,7 +5,11 @@ import {
|
|
|
5
5
|
formatAuthSchemaConflictMessage,
|
|
6
6
|
} from "./auth-schema-provenance-guard.mjs";
|
|
7
7
|
import { loadToolingRuntime } from "./tooling-runtime.mjs";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
getCliInvocationSelection,
|
|
10
|
+
resolveProjectSelection,
|
|
11
|
+
selectCodegenClient,
|
|
12
|
+
} from "./project-context.mjs";
|
|
9
13
|
|
|
10
14
|
export { formatAuthSchemaConflictMessage } from "./auth-schema-provenance-guard.mjs";
|
|
11
15
|
|
|
@@ -187,19 +191,20 @@ export async function runCodegenWithReporting({
|
|
|
187
191
|
outDir = resolveCodegenArtifactsDir(cwd),
|
|
188
192
|
publishDir = resolveCodegenPublishDir(cwd, config),
|
|
189
193
|
resolvePathImpl = resolve,
|
|
190
|
-
serverPublishDir
|
|
194
|
+
serverPublishDir,
|
|
191
195
|
successImpl,
|
|
192
196
|
}) {
|
|
193
197
|
const bundled = await (loadCodegenBundleImpl ?? loadCodegenBundleDefault)();
|
|
194
198
|
|
|
195
199
|
const codegenResolved = resolveCodegenConfig(config);
|
|
200
|
+
const effectiveServerPublishDir = serverPublishDir ?? resolveCodegenServerPublishDir(cwd, config);
|
|
196
201
|
const result = await bundled.runCodegen({
|
|
197
202
|
projectRoot: cwd,
|
|
198
203
|
rootDir: resolveBackendRootDir(config),
|
|
199
204
|
schema: config.schema,
|
|
200
205
|
outDir,
|
|
201
206
|
finalOutDir: publishDir,
|
|
202
|
-
serverPublishDir
|
|
207
|
+
serverPublishDir,
|
|
203
208
|
cloudFeatures: config.cloudFeatures,
|
|
204
209
|
authSchema: codegenResolved.authSchema
|
|
205
210
|
? { emitRelations: codegenResolved.authSchemaEmitRelations }
|
|
@@ -213,7 +218,7 @@ export async function runCodegenWithReporting({
|
|
|
213
218
|
cwd,
|
|
214
219
|
publishDir,
|
|
215
220
|
resolvePathImpl,
|
|
216
|
-
serverPublishDir,
|
|
221
|
+
serverPublishDir: effectiveServerPublishDir,
|
|
217
222
|
successImpl,
|
|
218
223
|
});
|
|
219
224
|
logCodegenDiagnostics(logImpl, result.diagnostics, diagnosticsColors);
|
|
@@ -288,7 +293,12 @@ export function createCodegenCommand(deps) {
|
|
|
288
293
|
}
|
|
289
294
|
const declaredCodegenClients = getDeclaredCodegenClients(config);
|
|
290
295
|
const explicitSelection = explicitTarget ?? getCliInvocationSelection()?.target ?? null;
|
|
291
|
-
if (
|
|
296
|
+
if (
|
|
297
|
+
Array.isArray(config?.clients) &&
|
|
298
|
+
config.clients.length > 0 &&
|
|
299
|
+
declaredCodegenClients.length === 0 &&
|
|
300
|
+
!outdir
|
|
301
|
+
) {
|
|
292
302
|
deps.errorImpl(
|
|
293
303
|
"No declared codegen client found. Add clients[*].codegen.outDir or pass --outdir for a one-off output.",
|
|
294
304
|
);
|
|
@@ -336,7 +346,6 @@ export function createCodegenCommand(deps) {
|
|
|
336
346
|
outDir: artifactsDir,
|
|
337
347
|
publishDir,
|
|
338
348
|
resolvePathImpl: deps.resolvePathImpl,
|
|
339
|
-
serverPublishDir,
|
|
340
349
|
successImpl: deps.successImpl,
|
|
341
350
|
});
|
|
342
351
|
deps.successImpl("Codegen completed successfully.");
|
package/lib/db-command.mjs
CHANGED
|
@@ -36,7 +36,7 @@ export function resolveDbCloudTarget(args, gencowJson = null) {
|
|
|
36
36
|
platformUrl = gencowJson.platformUrl || null;
|
|
37
37
|
if (isProd) {
|
|
38
38
|
const prodApp = gencowJson.prodApp || null;
|
|
39
|
-
const appId = prodApp
|
|
39
|
+
const appId = prodApp ? (!explicitAppId || explicitAppId === prodApp ? prodApp : null) : explicitAppId;
|
|
40
40
|
return { appId, isProd, platformUrl };
|
|
41
41
|
}
|
|
42
42
|
return { appId: explicitAppId || gencowJson.appId || gencowJson.appName || null, isProd, platformUrl };
|
|
@@ -17,6 +17,8 @@ export async function writeCanonicalDeployBundle({
|
|
|
17
17
|
backendRoot,
|
|
18
18
|
dependencyAuditManifest,
|
|
19
19
|
existsSyncImpl,
|
|
20
|
+
generatedServerPublishDir,
|
|
21
|
+
generatedServerRelativeDir,
|
|
20
22
|
cpSyncImpl,
|
|
21
23
|
generatorVersion,
|
|
22
24
|
lockfileSelection,
|
|
@@ -43,12 +45,13 @@ export async function writeCanonicalDeployBundle({
|
|
|
43
45
|
canonicalBackendDir: bundleBackendRoot,
|
|
44
46
|
})
|
|
45
47
|
: null;
|
|
46
|
-
const canonicalBundleProjectConfig =
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
const canonicalBundleProjectConfig =
|
|
49
|
+
hasSelectedProjectConfigFile && projectConfig
|
|
50
|
+
? canonicalizeBundleProjectConfig(projectConfig, {
|
|
51
|
+
backendDir: backendRoot,
|
|
52
|
+
canonicalBackendDir: bundleBackendRoot,
|
|
53
|
+
})
|
|
54
|
+
: null;
|
|
52
55
|
const envExcludes = buildBackendEnvExcludePatterns(
|
|
53
56
|
canonicalBundleProjectConfig ?? canonicalManifestConfig ?? { rootDir: `./${bundleBackendRoot}` },
|
|
54
57
|
);
|
|
@@ -58,6 +61,20 @@ export async function writeCanonicalDeployBundle({
|
|
|
58
61
|
rmSyncImpl(bundleStagingDir, { recursive: true, force: true });
|
|
59
62
|
mkdirSyncImpl(bundleStagingDir, { recursive: true });
|
|
60
63
|
cpSyncImpl(sourceBackendDir, resolvePathImpl(bundleStagingDir, bundleBackendRoot), { recursive: true });
|
|
64
|
+
if (
|
|
65
|
+
generatedServerPublishDir &&
|
|
66
|
+
generatedServerRelativeDir &&
|
|
67
|
+
existsSyncImpl(generatedServerPublishDir)
|
|
68
|
+
) {
|
|
69
|
+
const generatedServerTarget = resolvePathImpl(
|
|
70
|
+
bundleStagingDir,
|
|
71
|
+
bundleBackendRoot,
|
|
72
|
+
generatedServerRelativeDir,
|
|
73
|
+
);
|
|
74
|
+
rmSyncImpl(generatedServerTarget, { recursive: true, force: true });
|
|
75
|
+
mkdirSyncImpl(dirname(generatedServerTarget), { recursive: true });
|
|
76
|
+
cpSyncImpl(generatedServerPublishDir, generatedServerTarget, { recursive: true });
|
|
77
|
+
}
|
|
61
78
|
|
|
62
79
|
if (canonicalBundleProjectConfig) {
|
|
63
80
|
writeCanonicalBundleProjectConfig({
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { isAbsolute, relative, sep } from "path";
|
|
2
|
+
|
|
3
|
+
import { resolveCodegenServerPublishDir, runCodegenWithReporting } from "./codegen-command.mjs";
|
|
4
|
+
|
|
5
|
+
const GENERATED_AUTH_SCHEMA_IMPORT =
|
|
6
|
+
/(?:export\s+\*\s+from|import)\s*["'][^"']*generated\/schema-auth\.gen["']/u;
|
|
7
|
+
|
|
8
|
+
export function resolveConfiguredBackendRoot(projectConfig) {
|
|
9
|
+
const pathValue = projectConfig?.rootDir ?? projectConfig?.functionsDir ?? "gencow";
|
|
10
|
+
if (typeof pathValue !== "string") return "gencow";
|
|
11
|
+
const normalized = pathValue
|
|
12
|
+
.trim()
|
|
13
|
+
.replace(/^\.\/+/, "")
|
|
14
|
+
.replace(/[\\/]+$/, "");
|
|
15
|
+
return normalized || "gencow";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function loadDeployMigrationGenerationContext({
|
|
19
|
+
buildEnvImpl,
|
|
20
|
+
cwd,
|
|
21
|
+
errorImpl,
|
|
22
|
+
existsSyncImpl,
|
|
23
|
+
infoImpl,
|
|
24
|
+
loadConfigImpl,
|
|
25
|
+
loadProjectConfigForDeployImpl,
|
|
26
|
+
readFileSyncImpl,
|
|
27
|
+
resolvePathImpl,
|
|
28
|
+
statSyncImpl,
|
|
29
|
+
warnImpl,
|
|
30
|
+
}) {
|
|
31
|
+
if (!loadConfigImpl || !buildEnvImpl) {
|
|
32
|
+
warnImpl("Deploy packaging is using legacy migration generation without a Gencow schema contract.");
|
|
33
|
+
return { config: null, genEnv: null };
|
|
34
|
+
}
|
|
35
|
+
const config = await loadProjectConfigForDeployImpl({
|
|
36
|
+
cwd,
|
|
37
|
+
existsSyncImpl,
|
|
38
|
+
readFileSyncImpl,
|
|
39
|
+
resolvePathImpl,
|
|
40
|
+
statSyncImpl,
|
|
41
|
+
warnImpl,
|
|
42
|
+
errorImpl,
|
|
43
|
+
loadConfigImpl,
|
|
44
|
+
throwOnInvalid: true,
|
|
45
|
+
});
|
|
46
|
+
const genEnv = buildEnvImpl(config, { cwd, existsSyncImpl, readFileSyncImpl, resolvePathImpl });
|
|
47
|
+
infoImpl("Using Gencow-derived schema contract for deploy packaging.");
|
|
48
|
+
return { config, genEnv };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export async function prepareDeployCodegenArtifacts({
|
|
52
|
+
backendRoot,
|
|
53
|
+
config,
|
|
54
|
+
cwd,
|
|
55
|
+
diagnosticsColors,
|
|
56
|
+
errorImpl,
|
|
57
|
+
existsSyncImpl,
|
|
58
|
+
infoImpl,
|
|
59
|
+
logImpl,
|
|
60
|
+
readFileSyncImpl,
|
|
61
|
+
relativePathImpl = relative,
|
|
62
|
+
resolvePathImpl,
|
|
63
|
+
rmSyncImpl,
|
|
64
|
+
runCodegenForDeployImpl = runCodegenWithReporting,
|
|
65
|
+
successImpl,
|
|
66
|
+
}) {
|
|
67
|
+
const authSchemaPath = resolvePathImpl(cwd, backendRoot, "schema-auth.ts");
|
|
68
|
+
const serverPublishDir = resolveCodegenServerPublishDir(cwd, config);
|
|
69
|
+
const authSchemaGeneratedPath = resolvePathImpl(serverPublishDir, "schema-auth.gen.ts");
|
|
70
|
+
const hasGeneratedAuthSchemaDependency =
|
|
71
|
+
existsSyncImpl(authSchemaPath) &&
|
|
72
|
+
GENERATED_AUTH_SCHEMA_IMPORT.test(readFileSyncImpl(authSchemaPath, "utf8"));
|
|
73
|
+
const shouldGenerate =
|
|
74
|
+
config.codegen !== undefined ||
|
|
75
|
+
(hasGeneratedAuthSchemaDependency && !existsSyncImpl(authSchemaGeneratedPath));
|
|
76
|
+
if (!shouldGenerate) return null;
|
|
77
|
+
|
|
78
|
+
const backendRootDir = resolvePathImpl(cwd, backendRoot);
|
|
79
|
+
const serverPublishRelativeDir = relativePathImpl(backendRootDir, serverPublishDir);
|
|
80
|
+
if (
|
|
81
|
+
!serverPublishRelativeDir ||
|
|
82
|
+
serverPublishRelativeDir === "." ||
|
|
83
|
+
isAbsolute(serverPublishRelativeDir) ||
|
|
84
|
+
serverPublishRelativeDir === ".." ||
|
|
85
|
+
serverPublishRelativeDir.startsWith(`..${sep}`)
|
|
86
|
+
) {
|
|
87
|
+
errorImpl("Deploy codegen server output must be inside the configured backend root.");
|
|
88
|
+
infoImpl("Code: CODEGEN_SERVER_OUTPUT_OUTSIDE_BACKEND");
|
|
89
|
+
throw new Error("CODEGEN_SERVER_OUTPUT_OUTSIDE_BACKEND");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
infoImpl("Generating required auth schema for deploy packaging...");
|
|
93
|
+
const deployCodegenDir = resolvePathImpl(cwd, ".gencow", "deploy-codegen");
|
|
94
|
+
const deployCodegenClientDir = resolvePathImpl(cwd, ".gencow", "deploy-codegen-client");
|
|
95
|
+
const deployCodegenServerDir = resolvePathImpl(cwd, ".gencow", "deploy-codegen-server");
|
|
96
|
+
const cleanup = () => {
|
|
97
|
+
rmSyncImpl(deployCodegenDir, { recursive: true, force: true });
|
|
98
|
+
rmSyncImpl(deployCodegenClientDir, { recursive: true, force: true });
|
|
99
|
+
rmSyncImpl(deployCodegenServerDir, { recursive: true, force: true });
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
await runCodegenForDeployImpl({
|
|
104
|
+
config,
|
|
105
|
+
cwd,
|
|
106
|
+
diagnosticsColors,
|
|
107
|
+
logImpl,
|
|
108
|
+
outDir: deployCodegenDir,
|
|
109
|
+
publishDir: deployCodegenClientDir,
|
|
110
|
+
serverPublishDir: deployCodegenServerDir,
|
|
111
|
+
successImpl,
|
|
112
|
+
});
|
|
113
|
+
} catch {
|
|
114
|
+
cleanup();
|
|
115
|
+
errorImpl("Deploy codegen generation failed.");
|
|
116
|
+
infoImpl("Code: CODEGEN_GENERATION_FAILED");
|
|
117
|
+
throw new Error("CODEGEN_GENERATION_FAILED");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
successImpl("Required auth schema generated for deploy packaging");
|
|
121
|
+
return { cleanup, serverPublishDir: deployCodegenServerDir, serverPublishRelativeDir };
|
|
122
|
+
}
|
|
@@ -5,6 +5,11 @@ import { fetchAppDiagnosticLogsViaRest, normalizeDiagnosticLogLines } from "./ap
|
|
|
5
5
|
import { resolveCreatedAppResponse } from "./app-create-response.mjs";
|
|
6
6
|
import { resolveConfiguredAuditorImplementation } from "./auditor-mode.mjs";
|
|
7
7
|
import { writeProjectMetadata } from "./deploy-project-metadata.mjs";
|
|
8
|
+
import {
|
|
9
|
+
loadDeployMigrationGenerationContext,
|
|
10
|
+
prepareDeployCodegenArtifacts,
|
|
11
|
+
resolveConfiguredBackendRoot,
|
|
12
|
+
} from "./deploy-codegen-preflight.mjs";
|
|
8
13
|
import {
|
|
9
14
|
SUPPORTED_DRIZZLE_KIT_GENERATOR_VERSION,
|
|
10
15
|
buildMigrationGenerationError,
|
|
@@ -40,18 +45,6 @@ async function loadProjectConfigDefault(options) {
|
|
|
40
45
|
const { loadConfig } = await import("./cli-project-runtime.mjs");
|
|
41
46
|
return loadConfig(options);
|
|
42
47
|
}
|
|
43
|
-
function normalizeBackendRootDir(pathValue) {
|
|
44
|
-
if (typeof pathValue !== "string") return "gencow";
|
|
45
|
-
const normalized = pathValue
|
|
46
|
-
.trim()
|
|
47
|
-
.replace(/^\.\/+/, "")
|
|
48
|
-
.replace(/[\\/]+$/, "");
|
|
49
|
-
return normalized || "gencow";
|
|
50
|
-
}
|
|
51
|
-
function resolveConfiguredBackendRoot(projectConfig) {
|
|
52
|
-
return normalizeBackendRootDir(projectConfig?.rootDir ?? projectConfig?.functionsDir ?? "gencow");
|
|
53
|
-
}
|
|
54
|
-
|
|
55
48
|
export function isExplicitEmptyBackendApi(source) {
|
|
56
49
|
return /\bdefineApi\s*\(\s*\{\s*procedures\s*:\s*\{\s*\}\s*,?\s*\}\s*\)\s*;?\s*$/u.test(source);
|
|
57
50
|
}
|
|
@@ -148,8 +141,14 @@ export function createDeployPackageRuntime({
|
|
|
148
141
|
updateEnvLocalUrlImpl,
|
|
149
142
|
loadInternalBundleImpl,
|
|
150
143
|
loadDeployAuditorImpl,
|
|
144
|
+
runCodegenForDeployImpl,
|
|
151
145
|
} = {}) {
|
|
152
146
|
let migrationProjectConfig = null;
|
|
147
|
+
let preparedDeployCodegenArtifacts = null;
|
|
148
|
+
function cleanupPreparedDeploySource() {
|
|
149
|
+
preparedDeployCodegenArtifacts?.cleanup?.();
|
|
150
|
+
preparedDeployCodegenArtifacts = null;
|
|
151
|
+
}
|
|
153
152
|
async function loadAnalyzerBundleForDeployAudit() {
|
|
154
153
|
try {
|
|
155
154
|
const bundled = await (loadInternalBundleImpl ?? loadInternalToolingDefault)();
|
|
@@ -176,35 +175,43 @@ export function createDeployPackageRuntime({
|
|
|
176
175
|
}
|
|
177
176
|
}
|
|
178
177
|
async function loadMigrationGenerationContext(cwd) {
|
|
179
|
-
|
|
180
|
-
|
|
178
|
+
const context = await loadDeployMigrationGenerationContext({
|
|
179
|
+
buildEnvImpl,
|
|
180
|
+
cwd,
|
|
181
|
+
errorImpl,
|
|
182
|
+
existsSyncImpl,
|
|
183
|
+
infoImpl: (message) => infoImpl(`${DIM}${message}${RESET}`),
|
|
184
|
+
loadConfigImpl,
|
|
185
|
+
loadProjectConfigForDeployImpl: loadProjectConfigForDeploy,
|
|
186
|
+
readFileSyncImpl,
|
|
187
|
+
resolvePathImpl,
|
|
188
|
+
statSyncImpl,
|
|
189
|
+
warnImpl,
|
|
190
|
+
});
|
|
191
|
+
migrationProjectConfig = context.config;
|
|
192
|
+
return context;
|
|
193
|
+
}
|
|
194
|
+
async function runMigrationGenerate() {
|
|
195
|
+
const cwd = cwdImpl();
|
|
196
|
+
cleanupPreparedDeploySource();
|
|
197
|
+
const { config, genEnv } = await loadMigrationGenerationContext(cwd);
|
|
198
|
+
if (config) {
|
|
199
|
+
preparedDeployCodegenArtifacts = await prepareDeployCodegenArtifacts({
|
|
200
|
+
backendRoot: resolveConfiguredBackendRoot(config),
|
|
201
|
+
config,
|
|
181
202
|
cwd,
|
|
182
|
-
|
|
183
|
-
readFileSyncImpl,
|
|
184
|
-
resolvePathImpl,
|
|
185
|
-
statSyncImpl,
|
|
186
|
-
warnImpl,
|
|
203
|
+
diagnosticsColors: { CYAN, DIM, RED, RESET, YELLOW },
|
|
187
204
|
errorImpl,
|
|
188
|
-
loadConfigImpl,
|
|
189
|
-
throwOnInvalid: true,
|
|
190
|
-
});
|
|
191
|
-
migrationProjectConfig = config;
|
|
192
|
-
const genEnv = buildEnvImpl(config, {
|
|
193
|
-
cwd,
|
|
194
205
|
existsSyncImpl,
|
|
206
|
+
infoImpl,
|
|
207
|
+
logImpl,
|
|
195
208
|
readFileSyncImpl,
|
|
196
209
|
resolvePathImpl,
|
|
210
|
+
rmSyncImpl,
|
|
211
|
+
runCodegenForDeployImpl,
|
|
212
|
+
successImpl,
|
|
197
213
|
});
|
|
198
|
-
infoImpl(`${DIM}Using Gencow-derived schema contract for deploy packaging.${RESET}`);
|
|
199
|
-
return { config, genEnv };
|
|
200
214
|
}
|
|
201
|
-
migrationProjectConfig = null;
|
|
202
|
-
warnImpl("Deploy packaging is using legacy migration generation without a Gencow schema contract.");
|
|
203
|
-
return { config: null, genEnv: null };
|
|
204
|
-
}
|
|
205
|
-
async function runMigrationGenerate() {
|
|
206
|
-
const cwd = cwdImpl();
|
|
207
|
-
const { genEnv } = await loadMigrationGenerationContext(cwd);
|
|
208
215
|
if (
|
|
209
216
|
!hasProjectDatabaseSchemaSource({
|
|
210
217
|
cwd,
|
|
@@ -249,6 +256,7 @@ export function createDeployPackageRuntime({
|
|
|
249
256
|
logImpl(`${DIM} ok Migrations up-to-date — no new schema changes detected${RESET}`);
|
|
250
257
|
return SUPPORTED_DRIZZLE_KIT_GENERATOR_VERSION;
|
|
251
258
|
}
|
|
259
|
+
cleanupPreparedDeploySource();
|
|
252
260
|
throw buildMigrationGenerationError(caught);
|
|
253
261
|
}
|
|
254
262
|
}
|
|
@@ -370,7 +378,6 @@ export function createDeployPackageRuntime({
|
|
|
370
378
|
? preparedGeneratorVersion || SUPPORTED_DRIZZLE_KIT_GENERATOR_VERSION
|
|
371
379
|
: await prepareDeployProjectSource({ existingBundleMode });
|
|
372
380
|
logImpl("");
|
|
373
|
-
|
|
374
381
|
infoImpl("Packaging project...");
|
|
375
382
|
const tmpBundle = resolvePathImpl(cwd, ".gencow", "deploy-bundle.tar.gz");
|
|
376
383
|
mkdirSyncImpl(dirname(tmpBundle), { recursive: true });
|
|
@@ -386,15 +393,12 @@ export function createDeployPackageRuntime({
|
|
|
386
393
|
throwOnInvalid: false,
|
|
387
394
|
});
|
|
388
395
|
const backendRoot = resolveConfiguredBackendRoot(projectConfig);
|
|
389
|
-
|
|
390
396
|
if (!existsSyncImpl(resolvePathImpl(cwd, backendRoot))) {
|
|
391
397
|
errorImpl(`${backendRoot}/ directory not found. Run from Gencow project root.`);
|
|
392
398
|
exitImpl(1);
|
|
393
399
|
return null;
|
|
394
400
|
}
|
|
395
|
-
|
|
396
401
|
const entryPoint = resolvePathImpl(cwd, backendRoot, "index.ts");
|
|
397
|
-
|
|
398
402
|
await runWorkflowShadowingAudit({ cwd, projectConfig, backendRoot });
|
|
399
403
|
|
|
400
404
|
let dependencyAuditManifest = null;
|
|
@@ -461,6 +465,8 @@ export function createDeployPackageRuntime({
|
|
|
461
465
|
existsSyncImpl,
|
|
462
466
|
cpSyncImpl,
|
|
463
467
|
generatorVersion,
|
|
468
|
+
generatedServerPublishDir: preparedDeployCodegenArtifacts?.serverPublishDir,
|
|
469
|
+
generatedServerRelativeDir: preparedDeployCodegenArtifacts?.serverPublishRelativeDir,
|
|
464
470
|
lockfileSelection,
|
|
465
471
|
migrationProjectConfig,
|
|
466
472
|
mkdirSyncImpl,
|
|
@@ -478,8 +484,10 @@ export function createDeployPackageRuntime({
|
|
|
478
484
|
} catch (caught) {
|
|
479
485
|
errorImpl(`Packaging failed: ${caught.message}`);
|
|
480
486
|
exitImpl(1);
|
|
487
|
+
cleanupPreparedDeploySource();
|
|
481
488
|
return null;
|
|
482
489
|
}
|
|
490
|
+
cleanupPreparedDeploySource();
|
|
483
491
|
|
|
484
492
|
const bundleBuffer = readFileSyncImpl(tmpBundle);
|
|
485
493
|
const bundleSize = statSyncImpl(tmpBundle).size;
|
|
@@ -518,7 +526,7 @@ export function createDeployPackageRuntime({
|
|
|
518
526
|
return { bundleBuffer, bundleSize, deployClaim, tmpBundle };
|
|
519
527
|
}
|
|
520
528
|
|
|
521
|
-
async function createCloudAppIfNeeded({ creds, appId, displayName, gencowJsonPath }) {
|
|
529
|
+
async function createCloudAppIfNeeded({ creds, appId, displayName, envTarget = "dev", gencowJsonPath }) {
|
|
522
530
|
if (appId) return appId;
|
|
523
531
|
|
|
524
532
|
infoImpl("Creating app (auto-generating ID)...");
|
|
@@ -544,6 +552,7 @@ export function createDeployPackageRuntime({
|
|
|
544
552
|
writeProjectMetadata({
|
|
545
553
|
appId: nextAppId,
|
|
546
554
|
displayName,
|
|
555
|
+
envTarget,
|
|
547
556
|
platformUrl: creds.platformUrl,
|
|
548
557
|
gencowJsonPath,
|
|
549
558
|
writeFileSyncImpl,
|
|
@@ -667,6 +676,7 @@ export function createDeployPackageRuntime({
|
|
|
667
676
|
creds,
|
|
668
677
|
appId: null,
|
|
669
678
|
displayName,
|
|
679
|
+
envTarget,
|
|
670
680
|
gencowJsonPath,
|
|
671
681
|
});
|
|
672
682
|
if (activeDeployClaim) {
|
|
@@ -782,6 +792,7 @@ export function createDeployPackageRuntime({
|
|
|
782
792
|
runMigrationGenerate,
|
|
783
793
|
preflightBackendCapability,
|
|
784
794
|
prepareDeployProjectSource,
|
|
795
|
+
cleanupPreparedDeploySource,
|
|
785
796
|
packageDeployProject,
|
|
786
797
|
createCloudAppIfNeeded,
|
|
787
798
|
deployBundleWithRetry,
|
|
@@ -1,8 +1,35 @@
|
|
|
1
|
-
import { writeFileSync } from "fs";
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
2
|
+
|
|
3
|
+
function readExistingProjectMetadata(gencowJsonPath) {
|
|
4
|
+
if (!existsSync(gencowJsonPath)) return {};
|
|
5
|
+
try {
|
|
6
|
+
const parsed = JSON.parse(readFileSync(gencowJsonPath, "utf8"));
|
|
7
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) return parsed;
|
|
8
|
+
} catch {
|
|
9
|
+
// Fall through to the stable fail-closed diagnostic below.
|
|
10
|
+
}
|
|
11
|
+
throw new Error("MIGRATION_PROJECT_CONFIG_INVALID");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function buildProjectMetadata({
|
|
15
|
+
appId,
|
|
16
|
+
displayName,
|
|
17
|
+
envTarget = "dev",
|
|
18
|
+
existingMetadata,
|
|
19
|
+
platformUrl,
|
|
20
|
+
}) {
|
|
21
|
+
return {
|
|
22
|
+
...existingMetadata,
|
|
23
|
+
displayName,
|
|
24
|
+
platformUrl,
|
|
25
|
+
...(envTarget === "prod" ? { prodApp: appId } : { appId }),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
2
28
|
|
|
3
29
|
export function writeProjectMetadata({
|
|
4
30
|
appId,
|
|
5
31
|
displayName,
|
|
32
|
+
envTarget = "dev",
|
|
6
33
|
platformUrl,
|
|
7
34
|
gencowJsonPath,
|
|
8
35
|
writeFileSyncImpl = writeFileSync,
|
|
@@ -10,11 +37,13 @@ export function writeProjectMetadata({
|
|
|
10
37
|
writeFileSyncImpl(
|
|
11
38
|
gencowJsonPath,
|
|
12
39
|
JSON.stringify(
|
|
13
|
-
{
|
|
40
|
+
buildProjectMetadata({
|
|
14
41
|
appId,
|
|
15
42
|
displayName,
|
|
43
|
+
envTarget,
|
|
44
|
+
existingMetadata: readExistingProjectMetadata(gencowJsonPath),
|
|
16
45
|
platformUrl,
|
|
17
|
-
},
|
|
46
|
+
}),
|
|
18
47
|
null,
|
|
19
48
|
2,
|
|
20
49
|
),
|
package/lib/deploy-runtime.mjs
CHANGED
|
@@ -124,7 +124,7 @@ export function readDeployProjectContext({
|
|
|
124
124
|
|
|
125
125
|
if (existsSyncImpl(gencowJsonPath)) {
|
|
126
126
|
const gencowJson = JSON.parse(readFileSyncImpl(gencowJsonPath, "utf8"));
|
|
127
|
-
if (!appId) appId = gencowJson.appId || gencowJson.appName;
|
|
127
|
+
if (!appId) appId = gencowJson.appId || gencowJson.appName || null;
|
|
128
128
|
if (typeof gencowJson.displayName === "string" && gencowJson.displayName.trim()) {
|
|
129
129
|
fallbackDisplayName = gencowJson.displayName.trim();
|
|
130
130
|
}
|
|
@@ -114,6 +114,7 @@ export async function deployBackendPackage({
|
|
|
114
114
|
creds,
|
|
115
115
|
appId,
|
|
116
116
|
displayName,
|
|
117
|
+
envTarget,
|
|
117
118
|
gencowJsonPath,
|
|
118
119
|
});
|
|
119
120
|
if (!activeAppId) return null;
|
|
@@ -158,6 +159,7 @@ export async function deployBackendPackage({
|
|
|
158
159
|
/* ignore */
|
|
159
160
|
}
|
|
160
161
|
}
|
|
162
|
+
activePackageRuntime.cleanupPreparedDeploySource?.();
|
|
161
163
|
}
|
|
162
164
|
|
|
163
165
|
if (!deployed) return null;
|
|
@@ -169,6 +171,7 @@ export async function deployBackendPackage({
|
|
|
169
171
|
writeProjectMetadata({
|
|
170
172
|
appId: deployed.appId,
|
|
171
173
|
displayName,
|
|
174
|
+
envTarget,
|
|
172
175
|
platformUrl: creds.platformUrl,
|
|
173
176
|
gencowJsonPath,
|
|
174
177
|
writeFileSyncImpl,
|
package/lib/install-features.mjs
CHANGED
|
@@ -8,10 +8,12 @@ import {
|
|
|
8
8
|
logEnvFileOperationWithType,
|
|
9
9
|
} from "./backend-env-resolver.mjs";
|
|
10
10
|
import { installGoogleSsoAuthConfig } from "./add-sso.mjs";
|
|
11
|
+
import { patchMemoryProjectWiring } from "./add-memory.mjs";
|
|
11
12
|
import { patchRagProjectWiring } from "./add-rag.mjs";
|
|
12
13
|
import { patchTossPaymentsProjectWiring } from "./add-tosspayments.mjs";
|
|
13
14
|
|
|
14
15
|
export const SETUP_HOOKS = {
|
|
16
|
+
"memory-wiring": patchMemoryProjectWiring,
|
|
15
17
|
"rag-wiring": patchRagProjectWiring,
|
|
16
18
|
"sso-auth-config": installGoogleSsoAuthConfig,
|
|
17
19
|
"tosspayments-wiring": patchTossPaymentsProjectWiring,
|
|
@@ -18,6 +18,7 @@ import { buildDeployClaimFromArchive } from "./deploy-package-claim.mjs";
|
|
|
18
18
|
import { buildStaticArtifactManifest } from "./static-artifact-manifest.mjs";
|
|
19
19
|
import { getCliInvocationSelection } from "./project-context.mjs";
|
|
20
20
|
import { pollAcceptedDeploymentOperation } from "./deployment-operation-poll.mjs";
|
|
21
|
+
import { writeProjectMetadata } from "./deploy-project-metadata.mjs";
|
|
21
22
|
|
|
22
23
|
export function resolveStaticDeployDir({
|
|
23
24
|
staticDirArg,
|
|
@@ -153,27 +154,6 @@ async function confirmStaticApiReferenceProceed(createInterfaceImpl) {
|
|
|
153
154
|
});
|
|
154
155
|
}
|
|
155
156
|
|
|
156
|
-
function writeProjectMetadata({
|
|
157
|
-
appId,
|
|
158
|
-
displayName,
|
|
159
|
-
platformUrl,
|
|
160
|
-
gencowJsonPath,
|
|
161
|
-
writeFileSyncImpl = writeFileSync,
|
|
162
|
-
}) {
|
|
163
|
-
writeFileSyncImpl(
|
|
164
|
-
gencowJsonPath,
|
|
165
|
-
JSON.stringify(
|
|
166
|
-
{
|
|
167
|
-
appId,
|
|
168
|
-
displayName,
|
|
169
|
-
platformUrl,
|
|
170
|
-
},
|
|
171
|
-
null,
|
|
172
|
-
2,
|
|
173
|
-
),
|
|
174
|
-
);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
157
|
export function createStaticDeployRuntime({
|
|
178
158
|
buildDeployClaimFromArchiveImpl = buildDeployClaimFromArchive,
|
|
179
159
|
cliVersion = "0.0.0",
|
|
@@ -303,6 +283,7 @@ export function createStaticDeployRuntime({
|
|
|
303
283
|
writeProjectMetadata({
|
|
304
284
|
appId,
|
|
305
285
|
displayName,
|
|
286
|
+
envTarget: opts.envTarget || "dev",
|
|
306
287
|
platformUrl: creds.platformUrl,
|
|
307
288
|
gencowJsonPath,
|
|
308
289
|
writeFileSyncImpl,
|
|
@@ -505,6 +486,7 @@ export function createStaticDeployRuntime({
|
|
|
505
486
|
writeProjectMetadata({
|
|
506
487
|
appId,
|
|
507
488
|
displayName,
|
|
489
|
+
envTarget: opts.envTarget || "dev",
|
|
508
490
|
platformUrl: creds.platformUrl,
|
|
509
491
|
gencowJsonPath,
|
|
510
492
|
writeFileSyncImpl,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gencow",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.201",
|
|
4
4
|
"description": "Gencow — AI Backend Engine",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -33,9 +33,9 @@
|
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/node": "^25.9.5",
|
|
35
35
|
"better-auth": "^1.6.23",
|
|
36
|
-
"@gencow/client": "0.2.6",
|
|
37
36
|
"@gencow/core": "0.1.42",
|
|
38
|
-
"@gencow/react": "0.2.6"
|
|
37
|
+
"@gencow/react": "0.2.6",
|
|
38
|
+
"@gencow/client": "0.2.6"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"prebuild": "pnpm --filter @gencow/migration-contract run build && pnpm --filter @gencow/server run build",
|