gencow 0.1.185 → 0.1.187
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 +5 -4
- package/lib/app-command.mjs +50 -10
- package/lib/app-response-contract.mjs +49 -0
- package/lib/backup-command.mjs +1 -1
- package/lib/db-command.mjs +4 -4
- package/lib/deploy-auditor.mjs +1 -1
- package/lib/deploy-command.mjs +1 -1
- package/lib/deploy-dependency-compat.mjs +2 -2
- package/lib/deploy-failure-diagnostic.mjs +95 -0
- package/lib/deploy-package-runtime.mjs +17 -9
- package/lib/deploy-runtime.mjs +18 -7
- package/lib/http-response-json.mjs +9 -0
- package/lib/init-command.mjs +1 -1
- package/lib/readme-codegen.mjs +25 -21
- package/lib/static-command.mjs +8 -3
- package/lib/static-deploy-command.mjs +13 -7
- package/package.json +1 -1
- package/runtime/server.mjs +61 -32
- package/runtime/server.mjs.map +2 -2
- package/templates/SECURITY.md +3 -3
- package/templates/ai-chat/README.md +2 -2
- package/templates/ai-chat/prompt.md +5 -5
- package/templates/fullstack/README.md +1 -1
- package/templates/fullstack/prompt.md +3 -3
- package/templates/task-app/prompt.md +1 -1
package/lib/static-command.mjs
CHANGED
|
@@ -4,6 +4,7 @@ import { resolve } from "path";
|
|
|
4
4
|
import { readProjectDisplayName } from "./cli-project-runtime.mjs";
|
|
5
5
|
import { BOLD, CYAN, DIM, RESET, error, info, log, success } from "./output.mjs";
|
|
6
6
|
import { platformFetch } from "./platform-client.mjs";
|
|
7
|
+
import { readJsonObjectResponse } from "./http-response-json.mjs";
|
|
7
8
|
import { detectStaticDeployBackend, preflightStaticDeployArtifact } from "./static-deploy-command.mjs";
|
|
8
9
|
|
|
9
10
|
export function parseStaticArgs(staticArgs) {
|
|
@@ -92,12 +93,16 @@ async function ensureStaticProductionTarget({
|
|
|
92
93
|
});
|
|
93
94
|
|
|
94
95
|
if (!createProdRes.ok) {
|
|
95
|
-
const errData = await createProdRes
|
|
96
|
-
errorImpl(`Prod app creation failed: ${errData
|
|
96
|
+
const errData = await readJsonObjectResponse(createProdRes);
|
|
97
|
+
errorImpl(`Prod app creation failed: ${errData?.error || createProdRes.statusText}`);
|
|
97
98
|
return null;
|
|
98
99
|
}
|
|
99
100
|
|
|
100
|
-
const createProdData = await createProdRes
|
|
101
|
+
const createProdData = await readJsonObjectResponse(createProdRes);
|
|
102
|
+
if (!createProdData) {
|
|
103
|
+
errorImpl("Prod app creation failed: server returned an invalid JSON response");
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
101
106
|
const nextProdAppId = createProdData.prodApp;
|
|
102
107
|
const gencowJson = existsSync(gencowJsonPath) ? JSON.parse(readFileSyncImpl(gencowJsonPath, "utf8")) : {};
|
|
103
108
|
gencowJson.prodApp = nextProdAppId;
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
import { relative, resolve } from "path";
|
|
12
12
|
import { BOLD, CYAN, DIM, RESET, YELLOW, error, info, log, success, warn } from "./output.mjs";
|
|
13
13
|
import { resolveCreatedAppResponse } from "./app-create-response.mjs";
|
|
14
|
+
import { readJsonObjectResponse } from "./http-response-json.mjs";
|
|
14
15
|
import { platformFetch, rpcMutation } from "./platform-client.mjs";
|
|
15
16
|
import { createTarGzipArchive } from "./tar-archive.mjs";
|
|
16
17
|
import { buildDeployClaimFromArchive } from "./deploy-package-claim.mjs";
|
|
@@ -259,7 +260,7 @@ export function createStaticDeployRuntime({
|
|
|
259
260
|
logImpl("");
|
|
260
261
|
warnImpl("Static hosting has no API server — these will return 404.");
|
|
261
262
|
infoImpl(
|
|
262
|
-
`💡 If you need a backend: ${CYAN}VITE_API_URL=https://{backend}.{domain}
|
|
263
|
+
`💡 If you need a backend: ${CYAN}VITE_API_URL=https://{backend}.{domain} bun run build${RESET} then deploy`,
|
|
263
264
|
);
|
|
264
265
|
infoImpl(`💡 If using a separate backend: set ${CYAN}VITE_API_URL${RESET} env var before building.`);
|
|
265
266
|
logImpl("");
|
|
@@ -309,12 +310,12 @@ export function createStaticDeployRuntime({
|
|
|
309
310
|
infoImpl("Creating app (auto-generating ID)...");
|
|
310
311
|
const createRes = await rpcMutationImpl(creds, "apps.create", { name: displayName });
|
|
311
312
|
if (!createRes.ok) {
|
|
312
|
-
const createErr = await createRes
|
|
313
|
-
errorImpl(`App creation failed: ${createErr
|
|
313
|
+
const createErr = await readJsonObjectResponse(createRes);
|
|
314
|
+
errorImpl(`App creation failed: ${createErr?.error || createRes.statusText}`);
|
|
314
315
|
exitImpl(1);
|
|
315
316
|
return;
|
|
316
317
|
}
|
|
317
|
-
const createData = await createRes
|
|
318
|
+
const createData = await readJsonObjectResponse(createRes);
|
|
318
319
|
try {
|
|
319
320
|
appId = resolveCreatedAppResponse(createData, { platformUrl: creds.platformUrl }).appId;
|
|
320
321
|
} catch (caught) {
|
|
@@ -368,13 +369,18 @@ export function createStaticDeployRuntime({
|
|
|
368
369
|
}
|
|
369
370
|
|
|
370
371
|
if (!deployRes.ok) {
|
|
371
|
-
const errData = await deployRes
|
|
372
|
-
errorImpl(`Static deploy failed: ${errData
|
|
372
|
+
const errData = await readJsonObjectResponse(deployRes);
|
|
373
|
+
errorImpl(`Static deploy failed: ${errData?.error || deployRes.statusText}`);
|
|
373
374
|
exitImpl(1);
|
|
374
375
|
return;
|
|
375
376
|
}
|
|
376
377
|
|
|
377
|
-
const data = await deployRes
|
|
378
|
+
const data = await readJsonObjectResponse(deployRes);
|
|
379
|
+
if (!data) {
|
|
380
|
+
errorImpl("Static deploy failed: server returned an invalid JSON response");
|
|
381
|
+
exitImpl(1);
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
378
384
|
logImpl("");
|
|
379
385
|
successImpl("Static deploy complete!");
|
|
380
386
|
infoImpl(`App ID: ${appId}`);
|
package/package.json
CHANGED
package/runtime/server.mjs
CHANGED
|
@@ -74629,8 +74629,10 @@ var init_server_deployment_control_plane_bootstrap = __esm({
|
|
|
74629
74629
|
deployment_id INTEGER NOT NULL REFERENCES deployments(id),
|
|
74630
74630
|
bundle_manifest_sha256 TEXT,
|
|
74631
74631
|
compatibility_class TEXT NOT NULL DEFAULT 'none'
|
|
74632
|
-
|
|
74632
|
+
CONSTRAINT app_schema_revisions_compatibility_check
|
|
74633
|
+
CHECK (compatibility_class IN ('none', 'expand_compatible', 'versioned_v1', 'manual_breaking')),
|
|
74633
74634
|
state TEXT NOT NULL DEFAULT 'planned'
|
|
74635
|
+
CONSTRAINT app_schema_revisions_state_check
|
|
74634
74636
|
CHECK (state IN (
|
|
74635
74637
|
'not_required', 'planned', 'preflight_passed', 'applying',
|
|
74636
74638
|
'applied', 'failed', 'outcome_uncertain', 'recovery_required'
|
|
@@ -74645,6 +74647,56 @@ var init_server_deployment_control_plane_bootstrap = __esm({
|
|
|
74645
74647
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
74646
74648
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
74647
74649
|
)`,
|
|
74650
|
+
`DO $deployment_schema_revision_compatibility$
|
|
74651
|
+
DECLARE
|
|
74652
|
+
compatibility_constraint_count INTEGER;
|
|
74653
|
+
canonical_constraint_count INTEGER;
|
|
74654
|
+
BEGIN
|
|
74655
|
+
SELECT
|
|
74656
|
+
COUNT(*),
|
|
74657
|
+
COUNT(*) FILTER (
|
|
74658
|
+
WHERE conname = 'app_schema_revisions_compatibility_check'
|
|
74659
|
+
AND convalidated
|
|
74660
|
+
AND POSITION('versioned_v1' IN pg_get_constraintdef(oid)) > 0
|
|
74661
|
+
)
|
|
74662
|
+
INTO compatibility_constraint_count, canonical_constraint_count
|
|
74663
|
+
FROM pg_constraint
|
|
74664
|
+
WHERE conrelid = 'app_schema_revisions'::regclass
|
|
74665
|
+
AND conname IN (
|
|
74666
|
+
'app_schema_revisions_compatibility_check',
|
|
74667
|
+
'app_schema_revisions_compatibility_class_check'
|
|
74668
|
+
);
|
|
74669
|
+
|
|
74670
|
+
IF compatibility_constraint_count <> 1 OR canonical_constraint_count <> 1 THEN
|
|
74671
|
+
ALTER TABLE app_schema_revisions
|
|
74672
|
+
DROP CONSTRAINT IF EXISTS app_schema_revisions_compatibility_check;
|
|
74673
|
+
ALTER TABLE app_schema_revisions
|
|
74674
|
+
DROP CONSTRAINT IF EXISTS app_schema_revisions_compatibility_class_check;
|
|
74675
|
+
ALTER TABLE app_schema_revisions
|
|
74676
|
+
ADD CONSTRAINT app_schema_revisions_compatibility_check
|
|
74677
|
+
CHECK (compatibility_class IN ('none', 'expand_compatible', 'versioned_v1', 'manual_breaking'));
|
|
74678
|
+
END IF;
|
|
74679
|
+
|
|
74680
|
+
SELECT
|
|
74681
|
+
COUNT(*),
|
|
74682
|
+
COUNT(*) FILTER (
|
|
74683
|
+
WHERE conname = 'app_schema_revisions_compatibility_check'
|
|
74684
|
+
AND convalidated
|
|
74685
|
+
AND POSITION('versioned_v1' IN pg_get_constraintdef(oid)) > 0
|
|
74686
|
+
)
|
|
74687
|
+
INTO compatibility_constraint_count, canonical_constraint_count
|
|
74688
|
+
FROM pg_constraint
|
|
74689
|
+
WHERE conrelid = 'app_schema_revisions'::regclass
|
|
74690
|
+
AND conname IN (
|
|
74691
|
+
'app_schema_revisions_compatibility_check',
|
|
74692
|
+
'app_schema_revisions_compatibility_class_check'
|
|
74693
|
+
);
|
|
74694
|
+
|
|
74695
|
+
IF compatibility_constraint_count <> 1 OR canonical_constraint_count <> 1 THEN
|
|
74696
|
+
RAISE EXCEPTION 'app_schema_revisions compatibility constraint did not converge';
|
|
74697
|
+
END IF;
|
|
74698
|
+
END
|
|
74699
|
+
$deployment_schema_revision_compatibility$`,
|
|
74648
74700
|
`CREATE UNIQUE INDEX IF NOT EXISTS app_schema_revisions_deployment_unique
|
|
74649
74701
|
ON app_schema_revisions (deployment_id)`,
|
|
74650
74702
|
`CREATE INDEX IF NOT EXISTS app_schema_revisions_app_state_idx
|
|
@@ -74867,42 +74919,19 @@ var init_server_deployment_control_plane_bootstrap = __esm({
|
|
|
74867
74919
|
});
|
|
74868
74920
|
|
|
74869
74921
|
// ../server/dist/server-static-backend-pointer-bootstrap.js
|
|
74870
|
-
async function
|
|
74871
|
-
await params.rawSql(`ALTER TABLE apps ADD COLUMN IF NOT EXISTS current_static_deployment_id INTEGER`);
|
|
74872
|
-
await params.rawSql(DEPLOYMENT_AUTHORITY_REMEDIATION_SCHEMA_SQL);
|
|
74873
|
-
await params.rawSql(DEPLOYMENT_AUTHORITY_REMEDIATION_SECURITY_SQL);
|
|
74922
|
+
async function reconcileStaticBackendDeploymentAuthorityRuntime(params) {
|
|
74874
74923
|
await params.rawSql(STATIC_DEPLOYMENT_POINTER_BACKFILL_SQL);
|
|
74875
|
-
await params.rawSql(UNSAFE_BACKEND_POINTER_REMEDIATION_SQL);
|
|
74876
|
-
await params.rawSql(BACKEND_AUTHORITY_REMEDIATION_STATUS_SQL);
|
|
74877
74924
|
await params.rawSql(BACKEND_AUTHORITY_REMEDIATION_RESOLUTION_SQL);
|
|
74878
74925
|
await params.rawSql(BACKEND_DEPLOYMENT_POINTER_REPAIR_SQL);
|
|
74879
74926
|
await params.rawSql(STATIC_ONLY_BACKEND_AUTHORITY_REMEDIATION_RESOLUTION_SQL);
|
|
74880
74927
|
await params.rawSql(STATIC_ONLY_BACKEND_AUTHORITY_STATUS_CLEAR_SQL);
|
|
74881
74928
|
await params.rawSql(STATIC_ONLY_BACKEND_POINTER_CLEAR_SQL);
|
|
74929
|
+
await params.rawSql(BACKEND_AUTHORITY_REMEDIATION_STATUS_SQL);
|
|
74882
74930
|
}
|
|
74883
|
-
var
|
|
74931
|
+
var STATIC_DEPLOYMENT_POINTER_BACKFILL_SQL, EXACT_BACKEND_AUTHORITY_CTE, UNSAFE_BACKEND_POINTER_REMEDIATION_SQL, BACKEND_AUTHORITY_REMEDIATION_STATUS_SQL, BACKEND_DEPLOYMENT_POINTER_REPAIR_SQL, BACKEND_AUTHORITY_REMEDIATION_RESOLUTION_SQL, STATIC_ONLY_BACKEND_AUTHORITY_REMEDIATION_RESOLUTION_SQL, STATIC_ONLY_BACKEND_AUTHORITY_STATUS_CLEAR_SQL, STATIC_ONLY_BACKEND_POINTER_CLEAR_SQL;
|
|
74884
74932
|
var init_server_static_backend_pointer_bootstrap = __esm({
|
|
74885
74933
|
"../server/dist/server-static-backend-pointer-bootstrap.js"() {
|
|
74886
74934
|
"use strict";
|
|
74887
|
-
DEPLOYMENT_AUTHORITY_REMEDIATION_SCHEMA_SQL = `
|
|
74888
|
-
CREATE TABLE IF NOT EXISTS app_deployment_authority_remediations (
|
|
74889
|
-
app_id INTEGER PRIMARY KEY REFERENCES apps(id) ON DELETE CASCADE,
|
|
74890
|
-
state TEXT NOT NULL DEFAULT 'pending'
|
|
74891
|
-
CONSTRAINT app_deployment_authority_remediations_state_check
|
|
74892
|
-
CHECK (state IN ('pending', 'resolved')),
|
|
74893
|
-
reason_code TEXT NOT NULL
|
|
74894
|
-
CONSTRAINT app_deployment_authority_remediations_reason_check
|
|
74895
|
-
CHECK (reason_code IN ('backend_pointer_unverified')),
|
|
74896
|
-
observed_current_deployment_id INTEGER,
|
|
74897
|
-
resolution_deployment_id INTEGER,
|
|
74898
|
-
detected_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
74899
|
-
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
74900
|
-
resolved_at TIMESTAMPTZ
|
|
74901
|
-
)
|
|
74902
|
-
`;
|
|
74903
|
-
DEPLOYMENT_AUTHORITY_REMEDIATION_SECURITY_SQL = `
|
|
74904
|
-
REVOKE ALL ON TABLE app_deployment_authority_remediations FROM PUBLIC
|
|
74905
|
-
`;
|
|
74906
74935
|
STATIC_DEPLOYMENT_POINTER_BACKFILL_SQL = `
|
|
74907
74936
|
UPDATE apps AS app
|
|
74908
74937
|
SET current_static_deployment_id = (
|
|
@@ -74920,10 +74949,6 @@ WHERE app.current_static_deployment_id IS NULL
|
|
|
74920
74949
|
exact_backend_authority AS (
|
|
74921
74950
|
SELECT app.id AS app_id, activation.deployment_id
|
|
74922
74951
|
FROM apps AS app
|
|
74923
|
-
JOIN deployments AS current_deployment
|
|
74924
|
-
ON current_deployment.id = app.current_deploy_id
|
|
74925
|
-
AND current_deployment.app_id = app.id
|
|
74926
|
-
AND current_deployment.env = 'static'
|
|
74927
74952
|
JOIN app_runtime_desired_state AS desired
|
|
74928
74953
|
ON desired.app_id = app.id
|
|
74929
74954
|
AND desired.authority_mode = 'enforce'
|
|
@@ -75023,6 +75048,10 @@ SET current_deploy_id = exact.deployment_id,
|
|
|
75023
75048
|
END
|
|
75024
75049
|
FROM exact_backend_authority AS exact
|
|
75025
75050
|
WHERE exact.app_id = app.id
|
|
75051
|
+
AND (
|
|
75052
|
+
app.current_deploy_id IS DISTINCT FROM exact.deployment_id
|
|
75053
|
+
OR app.status_reason = 'backend_deployment_authority_remediation_required'
|
|
75054
|
+
)
|
|
75026
75055
|
`;
|
|
75027
75056
|
BACKEND_AUTHORITY_REMEDIATION_RESOLUTION_SQL = `
|
|
75028
75057
|
WITH ${EXACT_BACKEND_AUTHORITY_CTE}
|
|
@@ -75813,7 +75842,6 @@ async function ensurePlatformSchemaUpgrade(params) {
|
|
|
75813
75842
|
await params.rawSql(`ALTER TABLE deployments ADD COLUMN IF NOT EXISTS env TEXT DEFAULT 'dev'`);
|
|
75814
75843
|
await ensureDeploymentRuntimeMetadataSchema(params.rawSql);
|
|
75815
75844
|
await ensureDeploymentControlPlaneSchema({ rawSql: params.rawSql });
|
|
75816
|
-
await ensureStaticBackendDeploymentAuthoritySchema({ rawSql: params.rawSql });
|
|
75817
75845
|
await params.rawSql(`CREATE TABLE IF NOT EXISTS db_backups (
|
|
75818
75846
|
id SERIAL PRIMARY KEY,
|
|
75819
75847
|
app_id INTEGER NOT NULL,
|
|
@@ -76187,6 +76215,7 @@ async function ensurePlatformSchemaUpgrade(params) {
|
|
|
76187
76215
|
if (params.strict)
|
|
76188
76216
|
throw error51;
|
|
76189
76217
|
}
|
|
76218
|
+
await reconcileStaticBackendDeploymentAuthorityRuntime({ rawSql: params.rawSql });
|
|
76190
76219
|
await ensurePlatformRlsPolicies({
|
|
76191
76220
|
rawSql: params.rawSql,
|
|
76192
76221
|
isPlatform: params.isPlatform,
|