gencow 0.1.192 → 0.1.194
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/bin/gencow.mjs +8 -10
- package/lib/app-command.mjs +70 -41
- package/lib/cli-artifact-guard.mjs +1 -0
- package/lib/cli-command-runner.mjs +27 -0
- package/lib/deploy-runtime.mjs +6 -6
- package/lib/platform-client.mjs +14 -5
- package/lib/static-command.mjs +14 -7
- package/lib/template-marketplace-command.mjs +12 -8
- package/package.json +3 -3
- package/runtime/server.mjs +361467 -98944
- package/scripts/bundle-server.mjs +7 -1
- package/server/index.js.map +0 -7
package/bin/gencow.mjs
CHANGED
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
updateEnvLocalUrl,
|
|
39
39
|
} from "../lib/cli-project-runtime.mjs";
|
|
40
40
|
import { createCodegenCommand } from "../lib/codegen-command.mjs";
|
|
41
|
+
import { runCliCommand } from "../lib/cli-command-runner.mjs";
|
|
41
42
|
import { createDoctorCommand } from "../lib/doctor-command.mjs";
|
|
42
43
|
import { maybeCheckCliVersion } from "../lib/cli-version-check.mjs";
|
|
43
44
|
import { updateComponentReadme } from "../lib/component-readme.mjs";
|
|
@@ -579,13 +580,10 @@ maybeCheckCliVersion({
|
|
|
579
580
|
warnImpl: warn,
|
|
580
581
|
});
|
|
581
582
|
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
commands.help();
|
|
590
|
-
process.exit(1);
|
|
591
|
-
}
|
|
583
|
+
process.exitCode = await runCliCommand({
|
|
584
|
+
args,
|
|
585
|
+
command: cmd,
|
|
586
|
+
commands,
|
|
587
|
+
errorImpl: error,
|
|
588
|
+
helpImpl: commands.help,
|
|
589
|
+
});
|
package/lib/app-command.mjs
CHANGED
|
@@ -24,6 +24,14 @@ import { updateEnvLocalUrl } from "./cli-project-runtime.mjs";
|
|
|
24
24
|
// Covers the 60s runtime-observer restart grace plus multiple 5s reconciliation scans.
|
|
25
25
|
const DEFAULT_DELETE_POLL_ATTEMPTS = 75;
|
|
26
26
|
const DELETE_POLL_INTERVAL_MS = 1_000;
|
|
27
|
+
const DEFAULT_APP_CREATE_TIMEOUT_MS = 60_000;
|
|
28
|
+
|
|
29
|
+
function resolveAppCreateTimeoutMs(value) {
|
|
30
|
+
const parsed = Number(value);
|
|
31
|
+
return Number.isSafeInteger(parsed) && parsed >= 100 && parsed <= 600_000
|
|
32
|
+
? parsed
|
|
33
|
+
: DEFAULT_APP_CREATE_TIMEOUT_MS;
|
|
34
|
+
}
|
|
27
35
|
|
|
28
36
|
function appResponseStatus(response) {
|
|
29
37
|
return Number.isSafeInteger(response?.status) ? `HTTP ${response.status}` : "unknown HTTP status";
|
|
@@ -74,11 +82,15 @@ export function addDeployAppToConfigSource(src, appName) {
|
|
|
74
82
|
if (src.includes("deploy:")) return src;
|
|
75
83
|
|
|
76
84
|
const deployBlock = ` deploy: {\n app: "${appName}",\n },\n`;
|
|
77
|
-
const
|
|
78
|
-
|
|
85
|
+
const insertBeforeClosingObject = (pattern) => {
|
|
86
|
+
const match = src.match(pattern);
|
|
87
|
+
if (!match || match.index == null) return null;
|
|
88
|
+
const prefix = src.slice(0, match.index).trimEnd();
|
|
89
|
+
const separator = prefix.endsWith(",") || prefix.endsWith("{") ? "\n" : ",\n";
|
|
90
|
+
return `${prefix}${separator}${deployBlock}${src.slice(match.index)}`;
|
|
91
|
+
};
|
|
79
92
|
|
|
80
|
-
|
|
81
|
-
return objectExportSource;
|
|
93
|
+
return insertBeforeClosingObject(/\}\s*\)\s*;?\s*$/u) ?? insertBeforeClosingObject(/\}\s*;?\s*$/u) ?? src;
|
|
82
94
|
}
|
|
83
95
|
|
|
84
96
|
export { resolveCreatedAppId };
|
|
@@ -101,23 +113,52 @@ async function confirmDelete(name) {
|
|
|
101
113
|
}
|
|
102
114
|
|
|
103
115
|
export function createAppCommand({
|
|
116
|
+
appCreateTimeoutMs = resolveAppCreateTimeoutMs(process.env.GENCOW_APP_CREATE_TIMEOUT_MS),
|
|
117
|
+
clearTimeoutImpl = clearTimeout,
|
|
118
|
+
confirmDeleteImpl = confirmDelete,
|
|
119
|
+
createAbortControllerImpl = () => new AbortController(),
|
|
104
120
|
cwdImpl = () => process.cwd(),
|
|
105
121
|
loadConfig,
|
|
106
122
|
errorImpl = error,
|
|
107
123
|
infoImpl = info,
|
|
108
124
|
loadCredsImpl = loadCreds,
|
|
109
125
|
logImpl = log,
|
|
110
|
-
processRef = process,
|
|
111
126
|
requireCredsImpl = requireCreds,
|
|
112
127
|
rpcMutationImpl = rpcMutation,
|
|
113
128
|
rpcQueryImpl = rpcQuery,
|
|
114
129
|
saveCredsImpl = saveCreds,
|
|
130
|
+
setTimeoutImpl = setTimeout,
|
|
115
131
|
sleepImpl = (ms) => new Promise((resolvePromise) => setTimeout(resolvePromise, ms)),
|
|
116
132
|
deletePollAttempts = DEFAULT_DELETE_POLL_ATTEMPTS,
|
|
117
133
|
successImpl = success,
|
|
118
134
|
updateEnvLocalUrlImpl = updateEnvLocalUrl,
|
|
119
135
|
warnImpl = warn,
|
|
120
136
|
}) {
|
|
137
|
+
const boundedAppCreateTimeoutMs = resolveAppCreateTimeoutMs(appCreateTimeoutMs);
|
|
138
|
+
|
|
139
|
+
async function requestAppCreate(creds, name) {
|
|
140
|
+
const controller = createAbortControllerImpl();
|
|
141
|
+
const timeoutError = new Error(
|
|
142
|
+
`App creation request timed out after ${boundedAppCreateTimeoutMs}ms. Please try again.`,
|
|
143
|
+
);
|
|
144
|
+
let timeoutHandle;
|
|
145
|
+
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
146
|
+
timeoutHandle = setTimeoutImpl(() => {
|
|
147
|
+
controller.abort(timeoutError);
|
|
148
|
+
reject(timeoutError);
|
|
149
|
+
}, boundedAppCreateTimeoutMs);
|
|
150
|
+
});
|
|
151
|
+
try {
|
|
152
|
+
const request = (async () => {
|
|
153
|
+
const response = await rpcMutationImpl(creds, "apps.create", { name }, { signal: controller.signal });
|
|
154
|
+
return { response, data: await readJsonObjectResponse(response) };
|
|
155
|
+
})();
|
|
156
|
+
return await Promise.race([request, timeoutPromise]);
|
|
157
|
+
} finally {
|
|
158
|
+
clearTimeoutImpl(timeoutHandle);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
121
162
|
return async function app(subcmd, ...rest) {
|
|
122
163
|
if (subcmd === "--help" || subcmd === "-h" || rest.includes("--help") || rest.includes("-h")) {
|
|
123
164
|
logImpl(`\n${BOLD}${CYAN}gencow app${RESET} — App management\n`);
|
|
@@ -127,10 +168,10 @@ export function createAppCommand({
|
|
|
127
168
|
logImpl(` ${CYAN}create${RESET} Create a new app`);
|
|
128
169
|
logImpl(` ${CYAN}delete${RESET} Delete an app (confirmation required)`);
|
|
129
170
|
logImpl(` ${CYAN}status${RESET} Show app status\n`);
|
|
130
|
-
return;
|
|
171
|
+
return 0;
|
|
131
172
|
}
|
|
132
173
|
|
|
133
|
-
const creds = requireCredsImpl();
|
|
174
|
+
const creds = requireCredsImpl({ throwOnMissing: true });
|
|
134
175
|
|
|
135
176
|
if (!subcmd || subcmd === "list") {
|
|
136
177
|
logImpl(`\n${BOLD}${CYAN}Your Apps${RESET}\n`);
|
|
@@ -138,18 +179,16 @@ export function createAppCommand({
|
|
|
138
179
|
const body = await res.json().catch(() => null);
|
|
139
180
|
if (!res.ok) {
|
|
140
181
|
errorImpl(appResponseError(body, invalidAppResponse("app list", res, "error")));
|
|
141
|
-
|
|
142
|
-
return;
|
|
182
|
+
return 1;
|
|
143
183
|
}
|
|
144
184
|
const apps = parseAppListResponse(body);
|
|
145
185
|
if (!apps) {
|
|
146
186
|
errorImpl(invalidAppResponse("app list", res, "success"));
|
|
147
|
-
|
|
148
|
-
return;
|
|
187
|
+
return 1;
|
|
149
188
|
}
|
|
150
189
|
if (!apps.length) {
|
|
151
190
|
infoImpl("No apps yet. Run: gencow app create <name>");
|
|
152
|
-
return;
|
|
191
|
+
return 0;
|
|
153
192
|
}
|
|
154
193
|
|
|
155
194
|
logImpl(` ${"NAME".padEnd(22)} ${"STATUS".padEnd(12)} ${"URL".padEnd(38)} DEPLOYED`);
|
|
@@ -163,29 +202,26 @@ export function createAppCommand({
|
|
|
163
202
|
);
|
|
164
203
|
}
|
|
165
204
|
logImpl("");
|
|
166
|
-
return;
|
|
205
|
+
return 0;
|
|
167
206
|
}
|
|
168
207
|
|
|
169
208
|
if (subcmd === "create") {
|
|
170
209
|
const name = rest[0];
|
|
171
210
|
if (!name) {
|
|
172
211
|
errorImpl("Usage: gencow app create <name>");
|
|
173
|
-
|
|
212
|
+
return 1;
|
|
174
213
|
}
|
|
175
214
|
|
|
176
215
|
logImpl(`\n${BOLD}${CYAN}Gencow App Create${RESET}\n`);
|
|
177
216
|
infoImpl(`Creating app "${name}"...`);
|
|
178
|
-
const res = await
|
|
179
|
-
const data = await readJsonObjectResponse(res);
|
|
217
|
+
const { response: res, data } = await requestAppCreate(creds, name);
|
|
180
218
|
if (!res.ok) {
|
|
181
219
|
errorImpl(appResponseError(data, invalidAppResponse("app create", res, "error")));
|
|
182
|
-
|
|
183
|
-
return;
|
|
220
|
+
return 1;
|
|
184
221
|
}
|
|
185
222
|
if (!data) {
|
|
186
223
|
errorImpl(invalidAppResponse("app create", res, "success"));
|
|
187
|
-
|
|
188
|
-
return;
|
|
224
|
+
return 1;
|
|
189
225
|
}
|
|
190
226
|
|
|
191
227
|
let createdApp;
|
|
@@ -193,8 +229,7 @@ export function createAppCommand({
|
|
|
193
229
|
createdApp = resolveCreatedAppResponse(data, { platformUrl: creds.platformUrl });
|
|
194
230
|
} catch (caught) {
|
|
195
231
|
errorImpl(caught.message);
|
|
196
|
-
|
|
197
|
-
return;
|
|
232
|
+
return 1;
|
|
198
233
|
}
|
|
199
234
|
const { appId, appUrl } = createdApp;
|
|
200
235
|
|
|
@@ -255,7 +290,7 @@ ${dashboardLine}
|
|
|
255
290
|
|
|
256
291
|
${DIM}pnpm gencow dev — watch & auto-deploy to cloud + live logs${RESET}
|
|
257
292
|
`);
|
|
258
|
-
return;
|
|
293
|
+
return 0;
|
|
259
294
|
}
|
|
260
295
|
|
|
261
296
|
if (subcmd === "delete") {
|
|
@@ -266,15 +301,14 @@ ${dashboardLine}
|
|
|
266
301
|
const name = rest.find((value) => !value.startsWith("-")) || loadCredsImpl()?.currentApp;
|
|
267
302
|
if (!name || unsupportedOption) {
|
|
268
303
|
errorImpl("Usage: gencow app delete <name> [--force]");
|
|
269
|
-
|
|
270
|
-
return;
|
|
304
|
+
return 1;
|
|
271
305
|
}
|
|
272
306
|
|
|
273
307
|
if (!force) {
|
|
274
|
-
const confirmed = await
|
|
308
|
+
const confirmed = await confirmDeleteImpl(name);
|
|
275
309
|
if (!confirmed) {
|
|
276
310
|
warnImpl("Cancelled — name did not match.");
|
|
277
|
-
|
|
311
|
+
return 0;
|
|
278
312
|
}
|
|
279
313
|
}
|
|
280
314
|
|
|
@@ -300,8 +334,7 @@ ${dashboardLine}
|
|
|
300
334
|
invalidAppResponse("app delete", delRes, delRes.ok ? "success" : "error"),
|
|
301
335
|
),
|
|
302
336
|
);
|
|
303
|
-
|
|
304
|
-
return;
|
|
337
|
+
return 1;
|
|
305
338
|
}
|
|
306
339
|
|
|
307
340
|
const currentCreds = loadCredsImpl();
|
|
@@ -310,15 +343,14 @@ ${dashboardLine}
|
|
|
310
343
|
}
|
|
311
344
|
|
|
312
345
|
successImpl(`App "${name}" deleted`);
|
|
313
|
-
return;
|
|
346
|
+
return 0;
|
|
314
347
|
}
|
|
315
348
|
|
|
316
349
|
if (subcmd === "status") {
|
|
317
350
|
const name = rest[0] || loadCredsImpl()?.currentApp;
|
|
318
351
|
if (!name) {
|
|
319
352
|
errorImpl("Usage: gencow app status <name>");
|
|
320
|
-
|
|
321
|
-
return;
|
|
353
|
+
return 1;
|
|
322
354
|
}
|
|
323
355
|
const res = await rpcQueryImpl(creds, "apps.get", { name });
|
|
324
356
|
const decoded = await readJsonValueResponse(res);
|
|
@@ -329,24 +361,20 @@ ${dashboardLine}
|
|
|
329
361
|
? appNotFoundDiagnostic()
|
|
330
362
|
: appResponseError(body, invalidAppResponse("app status", res, "error")),
|
|
331
363
|
);
|
|
332
|
-
|
|
333
|
-
return;
|
|
364
|
+
return 1;
|
|
334
365
|
}
|
|
335
366
|
if (!decoded.parsed) {
|
|
336
367
|
errorImpl(invalidAppResponse("app status", res, "success"));
|
|
337
|
-
|
|
338
|
-
return;
|
|
368
|
+
return 1;
|
|
339
369
|
}
|
|
340
370
|
const lookup = parseAppLookupResponse(body, name);
|
|
341
371
|
if (lookup.kind === "not_found") {
|
|
342
372
|
errorImpl(appNotFoundDiagnostic());
|
|
343
|
-
|
|
344
|
-
return;
|
|
373
|
+
return 1;
|
|
345
374
|
}
|
|
346
375
|
if (lookup.kind === "invalid_response") {
|
|
347
376
|
errorImpl(invalidAppResponse("app status", res, "success"));
|
|
348
|
-
|
|
349
|
-
return;
|
|
377
|
+
return 1;
|
|
350
378
|
}
|
|
351
379
|
const data = lookup.app;
|
|
352
380
|
logImpl(`\n ${BOLD}${data.name}${RESET}`);
|
|
@@ -373,10 +401,11 @@ ${dashboardLine}
|
|
|
373
401
|
);
|
|
374
402
|
}
|
|
375
403
|
logImpl("");
|
|
376
|
-
return;
|
|
404
|
+
return 0;
|
|
377
405
|
}
|
|
378
406
|
|
|
379
407
|
errorImpl(`Unknown app subcommand: ${subcmd}`);
|
|
380
408
|
logImpl(` Usage: gencow app [list|create|delete|status]`);
|
|
409
|
+
return 1;
|
|
381
410
|
};
|
|
382
411
|
}
|
|
@@ -110,6 +110,7 @@ export function validateServerRuntimeBundle(source, options = {}) {
|
|
|
110
110
|
String.raw`(?:resolve|join|new\s+URL)\([^;\n]{0,640}(?:${repositorySourcePath}|["'](?:platform|server|route-gateway)["']\s*,\s*["']src["'])`,
|
|
111
111
|
"iu",
|
|
112
112
|
),
|
|
113
|
+
/resolve\([^;\n]{0,320}\bfunctionsPath\b[^;\n]{0,320}["']\.\.\/src\/platform-api-surface\.ts["']/iu,
|
|
113
114
|
];
|
|
114
115
|
const errors = repositorySourceImportPatterns.some((pattern) => pattern.test(source))
|
|
115
116
|
? [
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
function commandErrorMessage(caught) {
|
|
2
|
+
if (caught instanceof Error && caught.message) return caught.message;
|
|
3
|
+
return String(caught);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
function normalizeCommandExitCode(exitCode) {
|
|
7
|
+
if (exitCode === undefined || exitCode === 0) return 0;
|
|
8
|
+
if (exitCode === 1) return 1;
|
|
9
|
+
throw new Error("CLI command returned an invalid exit code");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function runCliCommand({ args, command, commands, errorImpl, helpImpl }) {
|
|
13
|
+
const handler = Object.hasOwn(commands, command) ? commands[command] : undefined;
|
|
14
|
+
if (typeof handler !== "function") {
|
|
15
|
+
errorImpl(`Unknown command: ${command}`);
|
|
16
|
+
helpImpl();
|
|
17
|
+
return 1;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
const exitCode = await Reflect.apply(handler, commands, args);
|
|
22
|
+
return normalizeCommandExitCode(exitCode);
|
|
23
|
+
} catch (caught) {
|
|
24
|
+
errorImpl(commandErrorMessage(caught));
|
|
25
|
+
return 1;
|
|
26
|
+
}
|
|
27
|
+
}
|
package/lib/deploy-runtime.mjs
CHANGED
|
@@ -468,10 +468,7 @@ export function createDeployCommand({
|
|
|
468
468
|
const declaredStaticClients = Array.isArray(workspaceConfig?.clients)
|
|
469
469
|
? workspaceConfig.clients.filter((client) => client?.static?.dir)
|
|
470
470
|
: [];
|
|
471
|
-
const clientSelection = selectClient(
|
|
472
|
-
declaredStaticClients,
|
|
473
|
-
cliSelection?.client ?? null,
|
|
474
|
-
);
|
|
471
|
+
const clientSelection = selectClient(declaredStaticClients, cliSelection?.client ?? null);
|
|
475
472
|
if (clientSelection.error) {
|
|
476
473
|
errorImpl(clientSelection.error);
|
|
477
474
|
exitImpl(1);
|
|
@@ -541,7 +538,9 @@ export function createDeployCommand({
|
|
|
541
538
|
resolvePathImpl,
|
|
542
539
|
}) || displayName;
|
|
543
540
|
const backendDeployRuntime =
|
|
544
|
-
backendProjectRoot === cwd
|
|
541
|
+
backendProjectRoot === cwd
|
|
542
|
+
? deployPackageRuntime
|
|
543
|
+
: createDeployPackageRuntimeForCwd(() => backendProjectRoot);
|
|
545
544
|
|
|
546
545
|
if (parsed.existingBundleMode && !appId) {
|
|
547
546
|
errorImpl("--existing-bundle requires an existing app target.");
|
|
@@ -607,7 +606,7 @@ export function createDeployCommand({
|
|
|
607
606
|
}
|
|
608
607
|
|
|
609
608
|
if (parsed.staticDeploy) {
|
|
610
|
-
|
|
609
|
+
await runStaticDeployFlow({
|
|
611
610
|
appId,
|
|
612
611
|
backendRoot: backendProjectRoot,
|
|
613
612
|
creds,
|
|
@@ -659,6 +658,7 @@ export function createDeployCommand({
|
|
|
659
658
|
})
|
|
660
659
|
: undefined,
|
|
661
660
|
});
|
|
661
|
+
return 0;
|
|
662
662
|
}
|
|
663
663
|
|
|
664
664
|
logImpl(`\n${BOLD}${CYAN}Gencow Deploy${RESET}\n`);
|
package/lib/platform-client.mjs
CHANGED
|
@@ -42,9 +42,15 @@ export function resolveCredsFromSources({ env = process.env, loadCredsImpl = loa
|
|
|
42
42
|
return creds;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
export function formatPlatformCredentialsRequiredMessage({ isCi = Boolean(process.env.CI) } = {}) {
|
|
46
|
+
return isCi
|
|
47
|
+
? "CI environment detected but no credentials found. Set GENCOW_TOKEN in your CI/CD settings."
|
|
48
|
+
: "Not logged in. Run: gencow login";
|
|
49
|
+
}
|
|
50
|
+
|
|
45
51
|
export class PlatformCredentialsRequiredError extends Error {
|
|
46
|
-
constructor() {
|
|
47
|
-
super(
|
|
52
|
+
constructor(message = "Platform credentials are required") {
|
|
53
|
+
super(message);
|
|
48
54
|
this.name = "PlatformCredentialsRequiredError";
|
|
49
55
|
}
|
|
50
56
|
}
|
|
@@ -52,7 +58,9 @@ export class PlatformCredentialsRequiredError extends Error {
|
|
|
52
58
|
export function requireCreds({ throwOnMissing = false } = {}) {
|
|
53
59
|
const creds = resolveCredsFromSources();
|
|
54
60
|
if (!creds?.apiKey) {
|
|
55
|
-
if (throwOnMissing)
|
|
61
|
+
if (throwOnMissing) {
|
|
62
|
+
throw new PlatformCredentialsRequiredError(formatPlatformCredentialsRequiredMessage());
|
|
63
|
+
}
|
|
56
64
|
if (process.env.CI) {
|
|
57
65
|
error("CI environment detected but no credentials found.");
|
|
58
66
|
info(`Set ${CYAN}GENCOW_TOKEN${RESET} secret in your CI/CD settings.`);
|
|
@@ -86,10 +94,11 @@ export async function rpcQuery(creds, queryName, args = {}) {
|
|
|
86
94
|
});
|
|
87
95
|
}
|
|
88
96
|
|
|
89
|
-
export async function rpcMutation(creds, mutationName, args = {}) {
|
|
97
|
+
export async function rpcMutation(creds, mutationName, args = {}, requestOptions = {}) {
|
|
90
98
|
return platformFetch(creds, "/api/mutation", {
|
|
99
|
+
...requestOptions,
|
|
91
100
|
method: "POST",
|
|
92
|
-
headers: { "Content-Type": "application/json" },
|
|
101
|
+
headers: { ...requestOptions.headers, "Content-Type": "application/json" },
|
|
93
102
|
body: JSON.stringify({ name: mutationName, args }),
|
|
94
103
|
});
|
|
95
104
|
}
|
package/lib/static-command.mjs
CHANGED
|
@@ -66,11 +66,13 @@ export function readStaticProjectContext(options = {}) {
|
|
|
66
66
|
projectRoot = selection.projectDir;
|
|
67
67
|
} else {
|
|
68
68
|
const staticBackend = detectStaticDeployBackendImpl({ cwd, existsSyncImpl, resolvePathImpl });
|
|
69
|
-
projectRoot =
|
|
69
|
+
projectRoot =
|
|
70
|
+
staticBackend.detectedBackend && staticBackend.backendRoot ? staticBackend.backendRoot : cwd;
|
|
70
71
|
}
|
|
71
72
|
} catch {
|
|
72
73
|
const staticBackend = detectStaticDeployBackendImpl({ cwd, existsSyncImpl, resolvePathImpl });
|
|
73
|
-
projectRoot =
|
|
74
|
+
projectRoot =
|
|
75
|
+
staticBackend.detectedBackend && staticBackend.backendRoot ? staticBackend.backendRoot : cwd;
|
|
74
76
|
}
|
|
75
77
|
const gencowJsonPath = resolveProjectMetadataPath(projectRoot, resolvePathImpl);
|
|
76
78
|
let appId = explicitAppId;
|
|
@@ -201,15 +203,19 @@ export function createStaticCommand(options = {}) {
|
|
|
201
203
|
|
|
202
204
|
const parsed = parseStaticArgs(staticArgs);
|
|
203
205
|
const creds = requireCredsImpl();
|
|
204
|
-
const {
|
|
206
|
+
const {
|
|
207
|
+
appId,
|
|
208
|
+
displayName: initialDisplayName,
|
|
209
|
+
gencowJsonPath,
|
|
210
|
+
prodAppId,
|
|
211
|
+
projectRoot,
|
|
212
|
+
} = readStaticProjectContextImpl({
|
|
205
213
|
cwd: cwdImpl(),
|
|
206
214
|
explicitAppId: parsed.appId,
|
|
207
215
|
});
|
|
208
216
|
const processEnv = process.env;
|
|
209
217
|
const cliSelection = getCliInvocationSelection();
|
|
210
|
-
const config = loadConfigImpl
|
|
211
|
-
? await loadConfigImpl({ cwd: projectRoot, processEnv })
|
|
212
|
-
: null;
|
|
218
|
+
const config = loadConfigImpl ? await loadConfigImpl({ cwd: projectRoot, processEnv }) : null;
|
|
213
219
|
const displayName = config
|
|
214
220
|
? readProjectDisplayNameImpl({
|
|
215
221
|
config,
|
|
@@ -289,7 +295,7 @@ export function createStaticCommand(options = {}) {
|
|
|
289
295
|
);
|
|
290
296
|
}
|
|
291
297
|
|
|
292
|
-
|
|
298
|
+
await runStaticDeployRuntimeImpl({
|
|
293
299
|
creds,
|
|
294
300
|
appId: deployTarget,
|
|
295
301
|
displayName,
|
|
@@ -302,5 +308,6 @@ export function createStaticCommand(options = {}) {
|
|
|
302
308
|
releaseSourceRoot: projectRoot,
|
|
303
309
|
},
|
|
304
310
|
});
|
|
311
|
+
return 0;
|
|
305
312
|
};
|
|
306
313
|
}
|
|
@@ -53,7 +53,13 @@ async function createSourceBundle({ cwd, staticOutputDir, mkdirSyncImpl = mkdirS
|
|
|
53
53
|
return out;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
async function createStaticBundle({
|
|
56
|
+
async function createStaticBundle({
|
|
57
|
+
cwd,
|
|
58
|
+
outputDir,
|
|
59
|
+
mkdirSyncImpl = mkdirSync,
|
|
60
|
+
resolvePathImpl = resolve,
|
|
61
|
+
tarCreateImpl,
|
|
62
|
+
}) {
|
|
57
63
|
const out = resolve(cwd, ".gencow", "template-static.tar.gz");
|
|
58
64
|
mkdirSyncImpl(resolve(cwd, ".gencow"), { recursive: true });
|
|
59
65
|
await createTarGzipArchive({
|
|
@@ -65,12 +71,7 @@ async function createStaticBundle({ cwd, outputDir, mkdirSyncImpl = mkdirSync, r
|
|
|
65
71
|
return out;
|
|
66
72
|
}
|
|
67
73
|
|
|
68
|
-
async function extractTemplateArchive({
|
|
69
|
-
archive,
|
|
70
|
-
targetDir,
|
|
71
|
-
mkdirSyncImpl = mkdirSync,
|
|
72
|
-
tarExtractImpl,
|
|
73
|
-
}) {
|
|
74
|
+
async function extractTemplateArchive({ archive, targetDir, mkdirSyncImpl = mkdirSync, tarExtractImpl }) {
|
|
74
75
|
mkdirSyncImpl(targetDir, { recursive: true });
|
|
75
76
|
const extractImpl = tarExtractImpl ?? (await import("tar")).extract;
|
|
76
77
|
await extractImpl({ file: archive, cwd: targetDir });
|
|
@@ -230,7 +231,10 @@ export function createTemplateMarketplaceCommand({
|
|
|
230
231
|
if (subcommand === "publish") return publish(options);
|
|
231
232
|
if (subcommand === "list") return list();
|
|
232
233
|
if (subcommand === "info") return infoCommand(options._[0]);
|
|
233
|
-
if (subcommand === "download")
|
|
234
|
+
if (subcommand === "download") {
|
|
235
|
+
await download(options._[0], options);
|
|
236
|
+
return 0;
|
|
237
|
+
}
|
|
234
238
|
if (subcommand === "clone") {
|
|
235
239
|
const slug = options._[0];
|
|
236
240
|
const dir = options._[1] || slug;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gencow",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.194",
|
|
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/react": "0.2.6",
|
|
37
36
|
"@gencow/core": "0.1.42",
|
|
38
|
-
"@gencow/client": "0.2.6"
|
|
37
|
+
"@gencow/client": "0.2.6",
|
|
38
|
+
"@gencow/react": "0.2.6"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
|
41
41
|
"prebuild": "pnpm --filter @gencow/migration-contract run build && pnpm --filter @gencow/server run build",
|