@noodleseed/one 0.10.0 → 0.11.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/cli.d.ts.map +1 -1
- package/dist/cli.js +16 -4
- package/dist/cli.js.map +1 -1
- package/dist/commands/archive-ops.d.ts +3 -0
- package/dist/commands/archive-ops.d.ts.map +1 -0
- package/dist/commands/archive-ops.js +168 -0
- package/dist/commands/archive-ops.js.map +1 -0
- package/dist/commands/org-admin.d.ts +17 -0
- package/dist/commands/org-admin.d.ts.map +1 -0
- package/dist/commands/org-admin.js +241 -0
- package/dist/commands/org-admin.js.map +1 -0
- package/dist/commands/policy-ops.d.ts.map +1 -1
- package/dist/commands/policy-ops.js +94 -1
- package/dist/commands/policy-ops.js.map +1 -1
- package/dist/commands/session.d.ts +1 -15
- package/dist/commands/session.d.ts.map +1 -1
- package/dist/commands/session.js +15 -170
- package/dist/commands/session.js.map +1 -1
- package/dist/commands/shared.d.ts.map +1 -1
- package/dist/commands/shared.js +13 -5
- package/dist/commands/shared.js.map +1 -1
- package/dist/commands/update-ops.d.ts +29 -0
- package/dist/commands/update-ops.d.ts.map +1 -0
- package/dist/commands/update-ops.js +315 -0
- package/dist/commands/update-ops.js.map +1 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/update-binary.d.ts +38 -0
- package/dist/update-binary.d.ts.map +1 -0
- package/dist/update-binary.js +144 -0
- package/dist/update-binary.js.map +1 -0
- package/dist/update-check.d.ts +40 -0
- package/dist/update-check.d.ts.map +1 -0
- package/dist/update-check.js +212 -0
- package/dist/update-check.js.map +1 -0
- package/dist/update-render.d.ts +17 -0
- package/dist/update-render.d.ts.map +1 -0
- package/dist/update-render.js +39 -0
- package/dist/update-render.js.map +1 -0
- package/dist/update.d.ts +10 -9
- package/dist/update.d.ts.map +1 -1
- package/dist/update.js +21 -89
- package/dist/update.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/curated/command-groups.d.ts.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/curated/command-groups.js +13 -1
- package/node_modules/@noodle-borg/agent-kit/dist/curated/command-groups.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/generated/surface.d.ts.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/generated/surface.js +2 -0
- package/node_modules/@noodle-borg/agent-kit/dist/generated/surface.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
- package/node_modules/@noodle-borg/service/dist/archive-sweeper.d.ts +43 -0
- package/node_modules/@noodle-borg/service/dist/archive-sweeper.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/archive-sweeper.js +122 -0
- package/node_modules/@noodle-borg/service/dist/archive-sweeper.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/commercial-plans.d.ts +11 -0
- package/node_modules/@noodle-borg/service/dist/commercial-plans.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/commercial-plans.js +119 -0
- package/node_modules/@noodle-borg/service/dist/commercial-plans.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/deployment-versioning.d.ts +2 -0
- package/node_modules/@noodle-borg/service/dist/deployment-versioning.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/deployment-versioning.js +1 -1
- package/node_modules/@noodle-borg/service/dist/deployment-versioning.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/index.d.ts +3 -1
- package/node_modules/@noodle-borg/service/dist/index.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/index.js +2 -0
- package/node_modules/@noodle-borg/service/dist/index.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/options.d.ts +9 -0
- package/node_modules/@noodle-borg/service/dist/options.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/registry-state.d.ts +25 -0
- package/node_modules/@noodle-borg/service/dist/registry-state.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/registry-state.js +119 -0
- package/node_modules/@noodle-borg/service/dist/registry-state.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/registry.d.ts +7 -6
- package/node_modules/@noodle-borg/service/dist/registry.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/registry.js +44 -44
- package/node_modules/@noodle-borg/service/dist/registry.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/archive.d.ts +16 -0
- package/node_modules/@noodle-borg/service/dist/routes/archive.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/archive.js +83 -0
- package/node_modules/@noodle-borg/service/dist/routes/archive.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.d.ts +1 -18
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.js +18 -260
- package/node_modules/@noodle-borg/service/dist/routes/control-plane.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/deployments.d.ts +17 -0
- package/node_modules/@noodle-borg/service/dist/routes/deployments.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/deployments.js +88 -0
- package/node_modules/@noodle-borg/service/dist/routes/deployments.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/org-admin.d.ts +40 -0
- package/node_modules/@noodle-borg/service/dist/routes/org-admin.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/org-admin.js +353 -0
- package/node_modules/@noodle-borg/service/dist/routes/org-admin.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/paths.d.ts +15 -0
- package/node_modules/@noodle-borg/service/dist/routes/paths.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/paths.js +47 -0
- package/node_modules/@noodle-borg/service/dist/routes/paths.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/plans.d.ts +20 -0
- package/node_modules/@noodle-borg/service/dist/routes/plans.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/plans.js +159 -0
- package/node_modules/@noodle-borg/service/dist/routes/plans.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/policies.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/policies.js +7 -0
- package/node_modules/@noodle-borg/service/dist/routes/policies.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/rollback.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/rollback.js +19 -1
- package/node_modules/@noodle-borg/service/dist/routes/rollback.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/service.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/service.js +107 -4
- package/node_modules/@noodle-borg/service/dist/service.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/control-plane.d.ts +14 -0
- package/node_modules/@noodle-borg/service/dist/store/control-plane.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/control-plane.js +38 -0
- package/node_modules/@noodle-borg/service/dist/store/control-plane.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/json-file.d.ts +25 -0
- package/node_modules/@noodle-borg/service/dist/store/json-file.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/store/json-file.js +163 -0
- package/node_modules/@noodle-borg/service/dist/store/json-file.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-control-plane.d.ts +14 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-control-plane.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-control-plane.js +16 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-control-plane.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-rows.d.ts +60 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-rows.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-rows.js +101 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-rows.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-schema.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-schema.js +8 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-schema.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres.d.ts +20 -6
- package/node_modules/@noodle-borg/service/dist/store/postgres.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres.js +74 -122
- package/node_modules/@noodle-borg/service/dist/store/postgres.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/records.d.ts +35 -0
- package/node_modules/@noodle-borg/service/dist/store/records.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/store/records.js +87 -0
- package/node_modules/@noodle-borg/service/dist/store/records.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/store/validate.d.ts +19 -0
- package/node_modules/@noodle-borg/service/dist/store/validate.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/store/validate.js +61 -0
- package/node_modules/@noodle-borg/service/dist/store/validate.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/store.d.ts +68 -44
- package/node_modules/@noodle-borg/service/dist/store.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store.js +48 -213
- package/node_modules/@noodle-borg/service/dist/store.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Row shapes + row↔record mapping for the relational store (extracted verbatim from `postgres.ts`
|
|
3
|
+
* to keep that file under the size gate). Pure mapping/validation — no SQL here.
|
|
4
|
+
*/
|
|
5
|
+
import type { HostedPackagedAsset } from '@noodle-borg/compiler';
|
|
6
|
+
import type { SecretBox } from '@noodle-borg/runtime';
|
|
7
|
+
import type { ConfigScope, ConfigValueMetadata, DeployRecord, ManagedConfigKind, SecretEnvelope } from '../store.js';
|
|
8
|
+
import type { PostgresStoreOptions } from './postgres.js';
|
|
9
|
+
/** The on-disk-equivalent row shape. `created_at` comes back as a `Date`; `secrets` is parsed `jsonb`. */
|
|
10
|
+
export interface DeployRow {
|
|
11
|
+
readonly deployment_id: string;
|
|
12
|
+
readonly org_slug: string;
|
|
13
|
+
readonly app_slug: string;
|
|
14
|
+
readonly environment: string;
|
|
15
|
+
readonly server_version: string | null;
|
|
16
|
+
readonly deployment_version: string | number;
|
|
17
|
+
readonly active: boolean;
|
|
18
|
+
readonly server_name: string;
|
|
19
|
+
readonly created_at: Date;
|
|
20
|
+
readonly created_by_subject: string | null;
|
|
21
|
+
readonly created_by_email: string | null;
|
|
22
|
+
readonly access_mode: string | null;
|
|
23
|
+
readonly server_auth: unknown | null;
|
|
24
|
+
readonly caller_key_hash: string | null;
|
|
25
|
+
readonly manifest: string;
|
|
26
|
+
readonly connectors: string | null;
|
|
27
|
+
readonly hosted_assets: readonly HostedPackagedAsset[] | null;
|
|
28
|
+
readonly secrets: SecretEnvelope;
|
|
29
|
+
readonly schema_version: number;
|
|
30
|
+
/** App soft-delete stamp (ADR 0117); `NULL` for live records. */
|
|
31
|
+
readonly archived_at: Date | null;
|
|
32
|
+
}
|
|
33
|
+
export interface ConfigRow {
|
|
34
|
+
readonly kind: ManagedConfigKind;
|
|
35
|
+
readonly scope_level: string;
|
|
36
|
+
readonly org_slug: string;
|
|
37
|
+
readonly app_slug: string;
|
|
38
|
+
readonly environment: string;
|
|
39
|
+
readonly name: string;
|
|
40
|
+
readonly secret_value: SecretEnvelope | null;
|
|
41
|
+
readonly variable_value: string | null;
|
|
42
|
+
readonly updated_at: Date;
|
|
43
|
+
readonly updated_by_subject: string | null;
|
|
44
|
+
readonly updated_by_email: string | null;
|
|
45
|
+
}
|
|
46
|
+
export declare function rowToRecord(row: DeployRow): DeployRecord;
|
|
47
|
+
export declare function configRowToMetadata(row: ConfigRow): ConfigValueMetadata;
|
|
48
|
+
export declare function isTenantAuthConfig(value: unknown): value is NonNullable<DeployRecord['serverAuth']>;
|
|
49
|
+
export declare function validateConfigKind(kind: ManagedConfigKind): ManagedConfigKind;
|
|
50
|
+
export declare function scopeParts(scope: ConfigScope): {
|
|
51
|
+
readonly level: ConfigScope['level'];
|
|
52
|
+
readonly org: string;
|
|
53
|
+
readonly app: string;
|
|
54
|
+
readonly env: string;
|
|
55
|
+
};
|
|
56
|
+
export declare function rowToScope(row: ConfigRow): ConfigScope;
|
|
57
|
+
export declare function sealConfigSecret(value: string, secretBox: SecretBox | undefined): Promise<SecretEnvelope>;
|
|
58
|
+
export declare function openConfigSecret(envelope: SecretEnvelope | null, secretBox: SecretBox | undefined): Promise<string>;
|
|
59
|
+
export declare function isPostgresStoreOptions(value: SecretBox | PostgresStoreOptions | undefined): value is PostgresStoreOptions;
|
|
60
|
+
//# sourceMappingURL=postgres-rows.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-rows.d.ts","sourceRoot":"","sources":["../../src/store/postgres-rows.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
export function rowToRecord(row) {
|
|
2
|
+
return {
|
|
3
|
+
schemaVersion: row.schema_version,
|
|
4
|
+
deploymentId: row.deployment_id,
|
|
5
|
+
orgSlug: row.org_slug,
|
|
6
|
+
appSlug: row.app_slug,
|
|
7
|
+
environment: row.environment,
|
|
8
|
+
...(row.server_version !== null ? { serverVersion: row.server_version } : {}),
|
|
9
|
+
// `Date.now()` ms timestamps fit JS's safe-integer range, so the bigint string coerces losslessly.
|
|
10
|
+
deploymentVersion: Number(row.deployment_version),
|
|
11
|
+
active: row.active,
|
|
12
|
+
serverName: row.server_name,
|
|
13
|
+
// timestamptz → the canonical ISO-8601 string the rest of the system uses.
|
|
14
|
+
createdAt: new Date(row.created_at).toISOString(),
|
|
15
|
+
...(row.created_by_subject !== null ? { createdBySubject: row.created_by_subject } : {}),
|
|
16
|
+
...(row.created_by_email !== null ? { createdByEmail: row.created_by_email } : {}),
|
|
17
|
+
...(row.access_mode === 'owner-only' ||
|
|
18
|
+
row.access_mode === 'org-members' ||
|
|
19
|
+
row.access_mode === 'public' ||
|
|
20
|
+
row.access_mode === 'mixed' ||
|
|
21
|
+
row.access_mode === 'authenticated' ||
|
|
22
|
+
row.access_mode === 'customers'
|
|
23
|
+
? { accessMode: row.access_mode }
|
|
24
|
+
: {}),
|
|
25
|
+
...(isTenantAuthConfig(row.server_auth) ? { serverAuth: row.server_auth } : {}),
|
|
26
|
+
manifest: row.manifest,
|
|
27
|
+
...(row.connectors !== null ? { connectors: row.connectors } : {}),
|
|
28
|
+
...(row.hosted_assets !== null ? { hostedAssets: row.hosted_assets } : {}),
|
|
29
|
+
secrets: row.secrets,
|
|
30
|
+
...(row.archived_at !== null && row.archived_at !== undefined
|
|
31
|
+
? { archivedAt: new Date(row.archived_at).toISOString() }
|
|
32
|
+
: {}),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export function configRowToMetadata(row) {
|
|
36
|
+
return {
|
|
37
|
+
kind: validateConfigKind(row.kind),
|
|
38
|
+
scope: rowToScope(row),
|
|
39
|
+
name: row.name,
|
|
40
|
+
updatedAt: new Date(row.updated_at).toISOString(),
|
|
41
|
+
...(row.updated_by_subject !== null ? { updatedBySubject: row.updated_by_subject } : {}),
|
|
42
|
+
...(row.updated_by_email !== null ? { updatedByEmail: row.updated_by_email } : {}),
|
|
43
|
+
...(row.kind === 'variable' && row.variable_value !== null
|
|
44
|
+
? { value: row.variable_value }
|
|
45
|
+
: {}),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export function isTenantAuthConfig(value) {
|
|
49
|
+
if (typeof value !== 'object' || value === null)
|
|
50
|
+
return false;
|
|
51
|
+
const auth = value;
|
|
52
|
+
if (auth.kind === 'bridge')
|
|
53
|
+
return typeof auth.provider === 'string';
|
|
54
|
+
return typeof auth.issuer === 'string' && typeof auth.audience === 'string';
|
|
55
|
+
}
|
|
56
|
+
export function validateConfigKind(kind) {
|
|
57
|
+
if (kind !== 'secret' && kind !== 'variable')
|
|
58
|
+
throw new Error(`invalid config kind: ${kind}`);
|
|
59
|
+
return kind;
|
|
60
|
+
}
|
|
61
|
+
export function scopeParts(scope) {
|
|
62
|
+
if (scope.level === 'org')
|
|
63
|
+
return { level: 'org', org: scope.org, app: '', env: '' };
|
|
64
|
+
if (scope.level === 'app')
|
|
65
|
+
return { level: 'app', org: scope.org, app: scope.app, env: '' };
|
|
66
|
+
return { level: 'env', org: scope.org, app: scope.app, env: scope.env };
|
|
67
|
+
}
|
|
68
|
+
export function rowToScope(row) {
|
|
69
|
+
if (row.scope_level === 'org')
|
|
70
|
+
return { level: 'org', org: row.org_slug };
|
|
71
|
+
if (row.scope_level === 'app')
|
|
72
|
+
return { level: 'app', org: row.org_slug, app: row.app_slug };
|
|
73
|
+
if (row.scope_level === 'env') {
|
|
74
|
+
return { level: 'env', org: row.org_slug, app: row.app_slug, env: row.environment };
|
|
75
|
+
}
|
|
76
|
+
throw new Error(`invalid config scope_level: ${row.scope_level}`);
|
|
77
|
+
}
|
|
78
|
+
export async function sealConfigSecret(value, secretBox) {
|
|
79
|
+
if (secretBox === undefined) {
|
|
80
|
+
throw new Error('durable secret config requires a secret master-key custodian');
|
|
81
|
+
}
|
|
82
|
+
return { enc: 'aes-256-gcm', sealed: await secretBox.seal(value) };
|
|
83
|
+
}
|
|
84
|
+
export async function openConfigSecret(envelope, secretBox) {
|
|
85
|
+
if (envelope === null)
|
|
86
|
+
throw new Error('secret config row has no encrypted value');
|
|
87
|
+
if (envelope.enc === 'none') {
|
|
88
|
+
const value = envelope.values.value;
|
|
89
|
+
if (typeof value !== 'string')
|
|
90
|
+
throw new Error('legacy secret config row has no value');
|
|
91
|
+
return value;
|
|
92
|
+
}
|
|
93
|
+
if (secretBox === undefined) {
|
|
94
|
+
throw new Error('cannot resolve encrypted config without a secret master-key custodian');
|
|
95
|
+
}
|
|
96
|
+
return secretBox.open(envelope.sealed);
|
|
97
|
+
}
|
|
98
|
+
export function isPostgresStoreOptions(value) {
|
|
99
|
+
return typeof value === 'object' && value !== null && ('secretBox' in value || 'now' in value);
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=postgres-rows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-rows.js","sourceRoot":"","sources":["../../src/store/postgres-rows.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres-schema.d.ts","sourceRoot":"","sources":["../../src/store/postgres-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAG/B;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"postgres-schema.d.ts","sourceRoot":"","sources":["../../src/store/postgres-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAG/B;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAkMpE"}
|
|
@@ -117,6 +117,14 @@ export async function ensureArtifactSchema(pool) {
|
|
|
117
117
|
// `deployment_version` holds `Date.now()` (a 13-digit ms timestamp), which overflows a 32-bit `int`.
|
|
118
118
|
// Widen in place (idempotent; no data loss) so existing `int` columns become `bigint`.
|
|
119
119
|
await pool.query(`ALTER TABLE deploy_records ALTER COLUMN deployment_version TYPE bigint`);
|
|
120
|
+
// App soft-delete stamp (ADR 0117): additive + idempotent so existing alpha tables gain the column
|
|
121
|
+
// on next boot. NULL = live; the partial index keeps sweeper scans cheap.
|
|
122
|
+
await pool.query(`ALTER TABLE deploy_records ADD COLUMN IF NOT EXISTS archived_at timestamptz`);
|
|
123
|
+
await pool.query(`
|
|
124
|
+
CREATE INDEX IF NOT EXISTS deploy_records_archived_sweep
|
|
125
|
+
ON deploy_records(archived_at)
|
|
126
|
+
WHERE archived_at IS NOT NULL
|
|
127
|
+
`);
|
|
120
128
|
await pool.query(`DROP INDEX IF EXISTS deploy_records_one_active_env`);
|
|
121
129
|
await pool.query(`
|
|
122
130
|
CREATE UNIQUE INDEX IF NOT EXISTS deploy_records_one_active_legacy_env
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres-schema.js","sourceRoot":"","sources":["../../src/store/postgres-schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAEtE;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAU;IACnD,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;KAMd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;KASd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;KAUd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;KAQd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;KAYd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;KAGd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;KAQd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;KASd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;KAuBd,CAAC,CAAC;IACL,mGAAmG;IACnG,gDAAgD;IAChD,MAAM,IAAI,CAAC,KAAK,CACd,oGAAoG,CACrG,CAAC;IACF,MAAM,IAAI,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAC;IAC1F,MAAM,IAAI,CAAC,KAAK,CAAC,yEAAyE,CAAC,CAAC;IAC5F,kGAAkG;IAClG,8FAA8F;IAC9F,MAAM,IAAI,CAAC,KAAK,CAAC,yEAAyE,CAAC,CAAC;IAC5F,MAAM,IAAI,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAC;IAC1F,qGAAqG;IACrG,uFAAuF;IACvF,MAAM,IAAI,CAAC,KAAK,CAAC,wEAAwE,CAAC,CAAC;IAC3F,MAAM,IAAI,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACvE,MAAM,IAAI,CAAC,KAAK,CAAC;;;;KAId,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;KAId,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;KAGd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;KAGd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;KAed,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;KAgBd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC,+EAA+E,CAAC,CAAC;IAClG,MAAM,IAAI,CAAC,KAAK,CACd,+FAA+F,CAChG,CAAC;IACF,MAAM,IAAI,CAAC,KAAK,CACd,+FAA+F,CAChG,CAAC;IACF,MAAM,IAAI,CAAC,KAAK,CACd,kGAAkG,CACnG,CAAC;IACF,MAAM,IAAI,CAAC,KAAK,CAAC,8EAA8E,CAAC,CAAC;IACjG,MAAM,IAAI,CAAC,KAAK,CAAC;;;;KAId,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;KAId,CAAC,CAAC;IACL,MAAM,uBAAuB,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC"}
|
|
1
|
+
{"version":3,"file":"postgres-schema.js","sourceRoot":"","sources":["../../src/store/postgres-schema.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAEtE;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAU;IACnD,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;KAMd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;KASd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;KAUd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;KAQd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;KAYd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;KAGd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;KAQd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;KASd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;KAuBd,CAAC,CAAC;IACL,mGAAmG;IACnG,gDAAgD;IAChD,MAAM,IAAI,CAAC,KAAK,CACd,oGAAoG,CACrG,CAAC;IACF,MAAM,IAAI,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAC;IAC1F,MAAM,IAAI,CAAC,KAAK,CAAC,yEAAyE,CAAC,CAAC;IAC5F,kGAAkG;IAClG,8FAA8F;IAC9F,MAAM,IAAI,CAAC,KAAK,CAAC,yEAAyE,CAAC,CAAC;IAC5F,MAAM,IAAI,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAC;IAC1F,qGAAqG;IACrG,uFAAuF;IACvF,MAAM,IAAI,CAAC,KAAK,CAAC,wEAAwE,CAAC,CAAC;IAC3F,mGAAmG;IACnG,0EAA0E;IAC1E,MAAM,IAAI,CAAC,KAAK,CAAC,6EAA6E,CAAC,CAAC;IAChG,MAAM,IAAI,CAAC,KAAK,CAAC;;;;KAId,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACvE,MAAM,IAAI,CAAC,KAAK,CAAC;;;;KAId,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;KAId,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;KAGd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;KAGd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;KAed,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;KAgBd,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC,+EAA+E,CAAC,CAAC;IAClG,MAAM,IAAI,CAAC,KAAK,CACd,+FAA+F,CAChG,CAAC;IACF,MAAM,IAAI,CAAC,KAAK,CACd,+FAA+F,CAChG,CAAC;IACF,MAAM,IAAI,CAAC,KAAK,CACd,kGAAkG,CACnG,CAAC;IACF,MAAM,IAAI,CAAC,KAAK,CAAC,8EAA8E,CAAC,CAAC;IACjG,MAAM,IAAI,CAAC,KAAK,CAAC;;;;KAId,CAAC,CAAC;IACL,MAAM,IAAI,CAAC,KAAK,CAAC;;;;KAId,CAAC,CAAC;IACL,MAAM,uBAAuB,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -3,7 +3,7 @@ import type { SecretBox } from '@noodle-borg/runtime';
|
|
|
3
3
|
import type { AccessMode } from '@noodle-borg/transport-http';
|
|
4
4
|
import type { Pool } from 'pg';
|
|
5
5
|
import type { PolicyAssignment, PolicyAssignmentInput, PolicyAssignmentStore, PolicyDeleteInput, PolicyListFilter } from '../policy.js';
|
|
6
|
-
import type { ArtifactStore, ConfigScope, ConfigStore, ConfigValueMetadata, ControlPlaneStore, DeploymentActivationResult, DeploymentSummary, DeployRecord, ManagedConfigKind, OrgDomainRecord, OrgInvitationRecord, OrgMemberRecord, OrgRecord, OrgRole, SignupAllowlistKind, SignupAllowlistRecord, TenantRef } from '../store.js';
|
|
6
|
+
import type { AppArchiveResult, AppRestoreResult, ArtifactStore, ConfigScope, ConfigStore, ConfigValueMetadata, ControlPlaneStore, DeploymentActivationResult, DeploymentListFilter, DeploymentSummary, DeployRecord, ManagedConfigKind, OrgDomainRecord, OrgInvitationRecord, OrgMemberRecord, OrgRecord, OrgRole, SignupAllowlistKind, SignupAllowlistRecord, TenantRef } from '../store.js';
|
|
7
7
|
/**
|
|
8
8
|
* Relational {@link ArtifactStore} backend ([ADR 0035](../../../../docs/decisions/0035-relational-artifact-store.md)).
|
|
9
9
|
* One row per deployment in a `deploy_records` table; a shared, networked, strongly-consistent store
|
|
@@ -42,11 +42,11 @@ export declare class PostgresArtifactStore implements ArtifactStore, ControlPlan
|
|
|
42
42
|
updateActiveAccess(ref: TenantRef, accessMode: AccessMode, serverVersion?: string): Promise<DeployRecord | undefined>;
|
|
43
43
|
activateDeployment(ref: TenantRef, deploymentId: string): Promise<DeploymentActivationResult | undefined>;
|
|
44
44
|
loadAll(): Promise<readonly DeployRecord[]>;
|
|
45
|
-
listDeployments(filter:
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
listDeployments(filter: DeploymentListFilter): Promise<readonly DeploymentSummary[]>;
|
|
46
|
+
getAppArchivedAt(org: string, app: string): Promise<string | undefined>;
|
|
47
|
+
archiveApp(org: string, app: string, at: string): Promise<AppArchiveResult | undefined>;
|
|
48
|
+
restoreApp(org: string, app: string): Promise<AppRestoreResult | undefined>;
|
|
49
|
+
sweepArchived(before: string): Promise<readonly DeployRecord[]>;
|
|
50
50
|
setConfigValue(input: {
|
|
51
51
|
readonly kind: ManagedConfigKind;
|
|
52
52
|
readonly scope: ConfigScope;
|
|
@@ -62,6 +62,10 @@ export declare class PostgresArtifactStore implements ArtifactStore, ControlPlan
|
|
|
62
62
|
slug: string;
|
|
63
63
|
displayName?: string;
|
|
64
64
|
}): Promise<OrgRecord>;
|
|
65
|
+
updateOrg(input: {
|
|
66
|
+
slug: string;
|
|
67
|
+
displayName: string;
|
|
68
|
+
}): Promise<OrgRecord | undefined>;
|
|
65
69
|
listOrgs(): Promise<readonly OrgRecord[]>;
|
|
66
70
|
listOrgsForSubject(subject: string): Promise<readonly OrgRecord[]>;
|
|
67
71
|
addOrgMember(input: {
|
|
@@ -74,6 +78,11 @@ export declare class PostgresArtifactStore implements ArtifactStore, ControlPlan
|
|
|
74
78
|
org: string;
|
|
75
79
|
subject: string;
|
|
76
80
|
}): Promise<boolean>;
|
|
81
|
+
updateOrgMemberRole(input: {
|
|
82
|
+
org: string;
|
|
83
|
+
subject: string;
|
|
84
|
+
role: OrgRole;
|
|
85
|
+
}): Promise<OrgMemberRecord | undefined>;
|
|
77
86
|
getOrgMember(input: {
|
|
78
87
|
org: string;
|
|
79
88
|
subject: string;
|
|
@@ -124,5 +133,10 @@ export declare class PostgresArtifactStore implements ArtifactStore, ControlPlan
|
|
|
124
133
|
consumeOrgInvitation(input: {
|
|
125
134
|
tokenHash: string;
|
|
126
135
|
}): Promise<OrgInvitationRecord | undefined>;
|
|
136
|
+
listOrgInvitations(org: string): Promise<readonly OrgInvitationRecord[]>;
|
|
137
|
+
revokeOrgInvitation(input: {
|
|
138
|
+
org: string;
|
|
139
|
+
email: string;
|
|
140
|
+
}): Promise<number>;
|
|
127
141
|
}
|
|
128
142
|
//# sourceMappingURL=postgres.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../src/store/postgres.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../src/store/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,gBAAgB,EAA0B,MAAM,qBAAqB,CAAC;AACpF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE/B,OAAO,KAAK,EACV,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EACjB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,EACb,WAAW,EACX,WAAW,EACX,mBAAmB,EACnB,iBAAiB,EACjB,0BAA0B,EAC1B,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,eAAe,EACf,SAAS,EACT,OAAO,EACP,mBAAmB,EACnB,qBAAqB,EACrB,SAAS,EACV,MAAM,aAAa,CAAC;AAuDrB;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;IAC/B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED,qBAAa,qBACX,YAAW,aAAa,EAAE,iBAAiB,EAAE,WAAW,EAAE,qBAAqB;;gBAMnE,IAAI,EAAE,IAAI,EAAE,kBAAkB,CAAC,EAAE,SAAS,GAAG,oBAAoB;IAW7E;;;;OAIG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAInC,mBAAmB,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAI5E,sBAAsB,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAI3E,qBAAqB,CAAC,MAAM,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,gBAAgB,EAAE,CAAC;IAItF,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IAItE,2BAA2B,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,SAAS,gBAAgB,EAAE,CAAC;IAI5F,2BAA2B,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,gBAAgB,EAAE,CAAC;IAIvE,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAkG3C,GAAG,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAS5D,iBAAiB,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAapE,wBAAwB,CAC5B,GAAG,EAAE,SAAS,EACd,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAoB9B,kBAAkB,CACtB,GAAG,EAAE,SAAS,EACd,UAAU,EAAE,UAAU,EACtB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAY9B,kBAAkB,CACtB,GAAG,EAAE,SAAS,EACd,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,0BAA0B,GAAG,SAAS,CAAC;IAiE5C,OAAO,IAAI,OAAO,CAAC,SAAS,YAAY,EAAE,CAAC;IAK3C,eAAe,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC;IAuBpF,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAcvE,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IAoBvF,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC;IAkB3E,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,YAAY,EAAE,CAAC;IAU/D,cAAc,CAAC,KAAK,EAAE;QAC1B,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;QACjC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;QAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;QACnC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;KAClC,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAsC1B,iBAAiB,CACrB,IAAI,EAAE,iBAAiB,EACvB,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC;IAkBb,gBAAgB,CACpB,IAAI,EAAE,iBAAiB,EACvB,KAAK,EAAE,WAAW,GACjB,OAAO,CAAC,SAAS,mBAAmB,EAAE,CAAC;IAYpC,mBAAmB,CACvB,IAAI,EAAE,iBAAiB,EACvB,KAAK,EAAE,WAAW,GACjB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAsB5B,SAAS,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,CAAC;IAI5E,SAAS,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAIvF,QAAQ,IAAI,OAAO,CAAC,SAAS,SAAS,EAAE,CAAC;IAIzC,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,SAAS,EAAE,CAAC;IAIlE,YAAY,CAAC,KAAK,EAAE;QACxB,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,OAAO,CAAC;KACf,GAAG,OAAO,CAAC,eAAe,CAAC;IAItB,eAAe,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAI1E,mBAAmB,CAAC,KAAK,EAAE;QAC/B,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,EAAE,OAAO,CAAC;KACf,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAIlC,YAAY,CAAC,KAAK,EAAE;QACxB,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAIlC,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC;IAIhE,WAAW,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAItE,wBAAwB,CAAC,KAAK,EAAE;QACpC,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,eAAe,CAAC;IAMtB,yBAAyB,CAAC,KAAK,EAAE;QACrC,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,OAAO,CAAC;KACnB,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC;IAIlC,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC;IAIhE,oBAAoB,CAAC,KAAK,EAAE;QAChC,GAAG,EAAE,MAAM,CAAC;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,OAAO,CAAC;IAMd,WAAW,CAAC,KAAK,EAAE;QACvB,IAAI,EAAE,mBAAmB,CAAC;QAC1B,KAAK,EAAE,MAAM,CAAC;QACd,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAI5B,mBAAmB,IAAI,OAAO,CAAC,SAAS,qBAAqB,EAAE,CAAC;IAIhE,eAAe,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAI5E,mBAAmB,CAAC,KAAK,EAAE;QAC/B,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,OAAO,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,gBAAgB,EAAE,MAAM,CAAC;QACzB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,SAAS,EAAE,IAAI,CAAC;KACjB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAI1B,gBAAgB,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC;IAIxF,oBAAoB,CAAC,KAAK,EAAE;QAChC,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC;IAItC,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,mBAAmB,EAAE,CAAC;IAIxE,mBAAmB,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CAGlF"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { normalizeServerVersion } from '@noodle-borg/module';
|
|
2
2
|
import { defaultActiveRecord } from '../deployment-versioning.js';
|
|
3
3
|
import { DEPLOYMENT_ID_PATTERN, scopeChain, validateConfigName, validateConfigScope, validateSlug, validateTenantRef, } from '../store.js';
|
|
4
|
-
import { addOrgMemberRow, allowSignupRow, consumeOrgInvitationRow, createOrgDomainChallengeRow, createOrgInvitationRow, createOrgRow, getOrgInvitationRow, getOrgMemberRow, hasVerifiedOrgDomainMembership, isOrgMemberRow, isSignupAllowedByRows, listOrgDomainRows, listOrgMemberRows, listOrgRows, listOrgRowsForSubject, listSignupAllowlistRows, markOrgDomainVerificationRow, removeOrgMemberRow, } from './postgres-control-plane.js';
|
|
4
|
+
import { addOrgMemberRow, allowSignupRow, consumeOrgInvitationRow, createOrgDomainChallengeRow, createOrgInvitationRow, createOrgRow, getOrgInvitationRow, getOrgMemberRow, hasVerifiedOrgDomainMembership, isOrgMemberRow, isSignupAllowedByRows, listOrgDomainRows, listOrgInvitationRows, listOrgMemberRows, listOrgRows, listOrgRowsForSubject, listSignupAllowlistRows, markOrgDomainVerificationRow, removeOrgMemberRow, revokeOrgInvitationRows, updateOrgMemberRoleRow, updateOrgRow, } from './postgres-control-plane.js';
|
|
5
5
|
import { deletePolicyAssignmentRow, getPolicyAssignmentRow, listActivePolicyAssignmentRows, listPolicyAssignmentHistoryRows, listPolicyAssignmentRows, putPolicyAssignmentRow, } from './postgres-policy.js';
|
|
6
|
+
import { configRowToMetadata, isPostgresStoreOptions, openConfigSecret, rowToRecord, scopeParts, sealConfigSecret, validateConfigKind, } from './postgres-rows.js';
|
|
6
7
|
import { ensureArtifactSchema } from './postgres-schema.js';
|
|
8
|
+
import { deploymentSummary, validateDeploymentListFilter } from './records.js';
|
|
7
9
|
export class PostgresArtifactStore {
|
|
8
10
|
#pool;
|
|
9
11
|
#secretBox;
|
|
@@ -73,8 +75,8 @@ export class PostgresArtifactStore {
|
|
|
73
75
|
await client.query(`INSERT INTO deploy_records
|
|
74
76
|
(deployment_id, org_slug, app_slug, environment, server_version, deployment_version, active, server_name,
|
|
75
77
|
created_at, created_by_subject, created_by_email, access_mode, server_auth, caller_key_hash,
|
|
76
|
-
manifest, connectors, hosted_assets, secrets, schema_version)
|
|
77
|
-
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13::jsonb, $14, $15, $16, $17::jsonb, $18::jsonb, $19)
|
|
78
|
+
manifest, connectors, hosted_assets, secrets, schema_version, archived_at)
|
|
79
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13::jsonb, $14, $15, $16, $17::jsonb, $18::jsonb, $19, $20::timestamptz)
|
|
78
80
|
ON CONFLICT (deployment_id) DO UPDATE SET
|
|
79
81
|
org_slug = EXCLUDED.org_slug,
|
|
80
82
|
app_slug = EXCLUDED.app_slug,
|
|
@@ -93,7 +95,8 @@ export class PostgresArtifactStore {
|
|
|
93
95
|
connectors = EXCLUDED.connectors,
|
|
94
96
|
hosted_assets = EXCLUDED.hosted_assets,
|
|
95
97
|
secrets = EXCLUDED.secrets,
|
|
96
|
-
schema_version = EXCLUDED.schema_version
|
|
98
|
+
schema_version = EXCLUDED.schema_version,
|
|
99
|
+
archived_at = EXCLUDED.archived_at`, [
|
|
97
100
|
record.deploymentId,
|
|
98
101
|
record.orgSlug,
|
|
99
102
|
record.appSlug,
|
|
@@ -116,6 +119,7 @@ export class PostgresArtifactStore {
|
|
|
116
119
|
: null,
|
|
117
120
|
JSON.stringify(record.secrets),
|
|
118
121
|
record.schemaVersion,
|
|
122
|
+
record.archivedAt ?? null,
|
|
119
123
|
]);
|
|
120
124
|
await client.query('COMMIT');
|
|
121
125
|
}
|
|
@@ -137,6 +141,7 @@ export class PostgresArtifactStore {
|
|
|
137
141
|
const { rows } = await this.#pool.query(`SELECT *
|
|
138
142
|
FROM deploy_records
|
|
139
143
|
WHERE org_slug = $1 AND app_slug = $2 AND environment = $3 AND active = true
|
|
144
|
+
AND archived_at IS NULL
|
|
140
145
|
ORDER BY deployment_version DESC`, [safe.org, safe.app, safe.env]);
|
|
141
146
|
return defaultActiveRecord(rows.map(rowToRecord), safe);
|
|
142
147
|
}
|
|
@@ -150,6 +155,7 @@ export class PostgresArtifactStore {
|
|
|
150
155
|
AND environment = $3
|
|
151
156
|
AND server_version = $4
|
|
152
157
|
AND active = true
|
|
158
|
+
AND archived_at IS NULL
|
|
153
159
|
ORDER BY deployment_version DESC
|
|
154
160
|
LIMIT 1`, [safe.org, safe.app, safe.env, safeVersion]);
|
|
155
161
|
const row = rows[0];
|
|
@@ -229,25 +235,70 @@ export class PostgresArtifactStore {
|
|
|
229
235
|
return rows.map(rowToRecord);
|
|
230
236
|
}
|
|
231
237
|
async listDeployments(filter) {
|
|
232
|
-
const
|
|
233
|
-
const app = filter.app !== undefined ? validateSlug('app', filter.app) : undefined;
|
|
234
|
-
const env = filter.env !== undefined ? validateSlug('env', filter.env) : undefined;
|
|
238
|
+
const safe = validateDeploymentListFilter(filter);
|
|
235
239
|
const clauses = ['org_slug = $1'];
|
|
236
|
-
const values = [org];
|
|
237
|
-
if (app !== undefined) {
|
|
238
|
-
values.push(app);
|
|
240
|
+
const values = [safe.org];
|
|
241
|
+
if (safe.app !== undefined) {
|
|
242
|
+
values.push(safe.app);
|
|
239
243
|
clauses.push(`app_slug = $${values.length}`);
|
|
240
244
|
}
|
|
241
|
-
if (env !== undefined) {
|
|
242
|
-
values.push(env);
|
|
245
|
+
if (safe.env !== undefined) {
|
|
246
|
+
values.push(safe.env);
|
|
243
247
|
clauses.push(`environment = $${values.length}`);
|
|
244
248
|
}
|
|
249
|
+
if (safe.includeArchived !== true)
|
|
250
|
+
clauses.push('archived_at IS NULL');
|
|
245
251
|
const { rows } = await this.#pool.query(`SELECT *
|
|
246
252
|
FROM deploy_records
|
|
247
253
|
WHERE ${clauses.join(' AND ')}
|
|
248
254
|
ORDER BY deployment_version DESC`, values);
|
|
249
255
|
return rows.map((row) => deploymentSummary(rowToRecord(row)));
|
|
250
256
|
}
|
|
257
|
+
async getAppArchivedAt(org, app) {
|
|
258
|
+
const { rows } = await this.#pool.query(`SELECT count(*)::int AS total, count(archived_at)::int AS archived, max(archived_at) AS latest
|
|
259
|
+
FROM deploy_records
|
|
260
|
+
WHERE org_slug = $1 AND app_slug = $2`, [validateSlug('org', org), validateSlug('app', app)]);
|
|
261
|
+
const row = rows[0];
|
|
262
|
+
if (row === undefined || row.total === 0 || row.archived !== row.total || row.latest === null) {
|
|
263
|
+
return undefined;
|
|
264
|
+
}
|
|
265
|
+
return new Date(row.latest).toISOString();
|
|
266
|
+
}
|
|
267
|
+
async archiveApp(org, app, at) {
|
|
268
|
+
const safeOrg = validateSlug('org', org);
|
|
269
|
+
const safeApp = validateSlug('app', app);
|
|
270
|
+
const { rowCount } = await this.#pool.query(`UPDATE deploy_records
|
|
271
|
+
SET archived_at = $3::timestamptz
|
|
272
|
+
WHERE org_slug = $1 AND app_slug = $2 AND archived_at IS NULL`, [safeOrg, safeApp, at]);
|
|
273
|
+
const archivedDeployments = rowCount ?? 0;
|
|
274
|
+
if (archivedDeployments > 0) {
|
|
275
|
+
return { archivedAt: at, archivedDeployments, alreadyArchived: false };
|
|
276
|
+
}
|
|
277
|
+
// Nothing stamped: either the app is already fully archived (no-op, original stamp preserved so
|
|
278
|
+
// the retention clock never resets — ADR 0117 §5) or it has no records at all.
|
|
279
|
+
const existing = await this.getAppArchivedAt(safeOrg, safeApp);
|
|
280
|
+
if (existing === undefined)
|
|
281
|
+
return undefined;
|
|
282
|
+
return { archivedAt: existing, archivedDeployments: 0, alreadyArchived: true };
|
|
283
|
+
}
|
|
284
|
+
async restoreApp(org, app) {
|
|
285
|
+
const safeOrg = validateSlug('org', org);
|
|
286
|
+
const safeApp = validateSlug('app', app);
|
|
287
|
+
const { rowCount } = await this.#pool.query(`UPDATE deploy_records
|
|
288
|
+
SET archived_at = NULL
|
|
289
|
+
WHERE org_slug = $1 AND app_slug = $2 AND archived_at IS NOT NULL`, [safeOrg, safeApp]);
|
|
290
|
+
const restoredDeployments = rowCount ?? 0;
|
|
291
|
+
if (restoredDeployments > 0)
|
|
292
|
+
return { restoredDeployments };
|
|
293
|
+
const { rows } = await this.#pool.query(`SELECT count(*)::int AS total FROM deploy_records WHERE org_slug = $1 AND app_slug = $2`, [safeOrg, safeApp]);
|
|
294
|
+
return (rows[0]?.total ?? 0) > 0 ? { restoredDeployments: 0 } : undefined;
|
|
295
|
+
}
|
|
296
|
+
async sweepArchived(before) {
|
|
297
|
+
const { rows } = await this.#pool.query(`DELETE FROM deploy_records
|
|
298
|
+
WHERE archived_at IS NOT NULL AND archived_at < $1::timestamptz
|
|
299
|
+
RETURNING *`, [before]);
|
|
300
|
+
return rows.map(rowToRecord);
|
|
301
|
+
}
|
|
251
302
|
async setConfigValue(input) {
|
|
252
303
|
const kind = validateConfigKind(input.kind);
|
|
253
304
|
const scope = validateConfigScope(input.scope);
|
|
@@ -324,6 +375,9 @@ export class PostgresArtifactStore {
|
|
|
324
375
|
async createOrg(input) {
|
|
325
376
|
return createOrgRow(this.#pool, input);
|
|
326
377
|
}
|
|
378
|
+
async updateOrg(input) {
|
|
379
|
+
return updateOrgRow(this.#pool, input);
|
|
380
|
+
}
|
|
327
381
|
async listOrgs() {
|
|
328
382
|
return listOrgRows(this.#pool);
|
|
329
383
|
}
|
|
@@ -336,6 +390,9 @@ export class PostgresArtifactStore {
|
|
|
336
390
|
async removeOrgMember(input) {
|
|
337
391
|
return removeOrgMemberRow(this.#pool, input);
|
|
338
392
|
}
|
|
393
|
+
async updateOrgMemberRole(input) {
|
|
394
|
+
return updateOrgMemberRoleRow(this.#pool, input);
|
|
395
|
+
}
|
|
339
396
|
async getOrgMember(input) {
|
|
340
397
|
return getOrgMemberRow(this.#pool, input);
|
|
341
398
|
}
|
|
@@ -381,116 +438,11 @@ export class PostgresArtifactStore {
|
|
|
381
438
|
async consumeOrgInvitation(input) {
|
|
382
439
|
return consumeOrgInvitationRow(this.#pool, this.#now, input);
|
|
383
440
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
orgSlug: row.org_slug,
|
|
390
|
-
appSlug: row.app_slug,
|
|
391
|
-
environment: row.environment,
|
|
392
|
-
...(row.server_version !== null ? { serverVersion: row.server_version } : {}),
|
|
393
|
-
// `Date.now()` ms timestamps fit JS's safe-integer range, so the bigint string coerces losslessly.
|
|
394
|
-
deploymentVersion: Number(row.deployment_version),
|
|
395
|
-
active: row.active,
|
|
396
|
-
serverName: row.server_name,
|
|
397
|
-
// timestamptz → the canonical ISO-8601 string the rest of the system uses.
|
|
398
|
-
createdAt: new Date(row.created_at).toISOString(),
|
|
399
|
-
...(row.created_by_subject !== null ? { createdBySubject: row.created_by_subject } : {}),
|
|
400
|
-
...(row.created_by_email !== null ? { createdByEmail: row.created_by_email } : {}),
|
|
401
|
-
...(row.access_mode === 'owner-only' ||
|
|
402
|
-
row.access_mode === 'org-members' ||
|
|
403
|
-
row.access_mode === 'public' ||
|
|
404
|
-
row.access_mode === 'mixed' ||
|
|
405
|
-
row.access_mode === 'authenticated' ||
|
|
406
|
-
row.access_mode === 'customers'
|
|
407
|
-
? { accessMode: row.access_mode }
|
|
408
|
-
: {}),
|
|
409
|
-
...(isTenantAuthConfig(row.server_auth) ? { serverAuth: row.server_auth } : {}),
|
|
410
|
-
manifest: row.manifest,
|
|
411
|
-
...(row.connectors !== null ? { connectors: row.connectors } : {}),
|
|
412
|
-
...(row.hosted_assets !== null ? { hostedAssets: row.hosted_assets } : {}),
|
|
413
|
-
secrets: row.secrets,
|
|
414
|
-
};
|
|
415
|
-
}
|
|
416
|
-
function configRowToMetadata(row) {
|
|
417
|
-
return {
|
|
418
|
-
kind: validateConfigKind(row.kind),
|
|
419
|
-
scope: rowToScope(row),
|
|
420
|
-
name: row.name,
|
|
421
|
-
updatedAt: new Date(row.updated_at).toISOString(),
|
|
422
|
-
...(row.updated_by_subject !== null ? { updatedBySubject: row.updated_by_subject } : {}),
|
|
423
|
-
...(row.updated_by_email !== null ? { updatedByEmail: row.updated_by_email } : {}),
|
|
424
|
-
...(row.kind === 'variable' && row.variable_value !== null
|
|
425
|
-
? { value: row.variable_value }
|
|
426
|
-
: {}),
|
|
427
|
-
};
|
|
428
|
-
}
|
|
429
|
-
function isTenantAuthConfig(value) {
|
|
430
|
-
if (typeof value !== 'object' || value === null)
|
|
431
|
-
return false;
|
|
432
|
-
const auth = value;
|
|
433
|
-
if (auth.kind === 'bridge')
|
|
434
|
-
return typeof auth.provider === 'string';
|
|
435
|
-
return typeof auth.issuer === 'string' && typeof auth.audience === 'string';
|
|
436
|
-
}
|
|
437
|
-
function validateConfigKind(kind) {
|
|
438
|
-
if (kind !== 'secret' && kind !== 'variable')
|
|
439
|
-
throw new Error(`invalid config kind: ${kind}`);
|
|
440
|
-
return kind;
|
|
441
|
-
}
|
|
442
|
-
function scopeParts(scope) {
|
|
443
|
-
if (scope.level === 'org')
|
|
444
|
-
return { level: 'org', org: scope.org, app: '', env: '' };
|
|
445
|
-
if (scope.level === 'app')
|
|
446
|
-
return { level: 'app', org: scope.org, app: scope.app, env: '' };
|
|
447
|
-
return { level: 'env', org: scope.org, app: scope.app, env: scope.env };
|
|
448
|
-
}
|
|
449
|
-
function rowToScope(row) {
|
|
450
|
-
if (row.scope_level === 'org')
|
|
451
|
-
return { level: 'org', org: row.org_slug };
|
|
452
|
-
if (row.scope_level === 'app')
|
|
453
|
-
return { level: 'app', org: row.org_slug, app: row.app_slug };
|
|
454
|
-
if (row.scope_level === 'env') {
|
|
455
|
-
return { level: 'env', org: row.org_slug, app: row.app_slug, env: row.environment };
|
|
456
|
-
}
|
|
457
|
-
throw new Error(`invalid config scope_level: ${row.scope_level}`);
|
|
458
|
-
}
|
|
459
|
-
async function sealConfigSecret(value, secretBox) {
|
|
460
|
-
if (secretBox === undefined) {
|
|
461
|
-
throw new Error('durable secret config requires a secret master-key custodian');
|
|
441
|
+
async listOrgInvitations(org) {
|
|
442
|
+
return listOrgInvitationRows(this.#pool, org);
|
|
443
|
+
}
|
|
444
|
+
async revokeOrgInvitation(input) {
|
|
445
|
+
return revokeOrgInvitationRows(this.#pool, input);
|
|
462
446
|
}
|
|
463
|
-
return { enc: 'aes-256-gcm', sealed: await secretBox.seal(value) };
|
|
464
|
-
}
|
|
465
|
-
async function openConfigSecret(envelope, secretBox) {
|
|
466
|
-
if (envelope === null)
|
|
467
|
-
throw new Error('secret config row has no encrypted value');
|
|
468
|
-
if (envelope.enc === 'none') {
|
|
469
|
-
const value = envelope.values.value;
|
|
470
|
-
if (typeof value !== 'string')
|
|
471
|
-
throw new Error('legacy secret config row has no value');
|
|
472
|
-
return value;
|
|
473
|
-
}
|
|
474
|
-
if (secretBox === undefined) {
|
|
475
|
-
throw new Error('cannot resolve encrypted config without a secret master-key custodian');
|
|
476
|
-
}
|
|
477
|
-
return secretBox.open(envelope.sealed);
|
|
478
|
-
}
|
|
479
|
-
function isPostgresStoreOptions(value) {
|
|
480
|
-
return typeof value === 'object' && value !== null && ('secretBox' in value || 'now' in value);
|
|
481
|
-
}
|
|
482
|
-
function deploymentSummary(record) {
|
|
483
|
-
return {
|
|
484
|
-
deploymentId: record.deploymentId,
|
|
485
|
-
orgSlug: record.orgSlug,
|
|
486
|
-
appSlug: record.appSlug,
|
|
487
|
-
environment: record.environment,
|
|
488
|
-
...(record.serverVersion !== undefined ? { serverVersion: record.serverVersion } : {}),
|
|
489
|
-
active: record.active,
|
|
490
|
-
serverName: record.serverName,
|
|
491
|
-
createdAt: record.createdAt,
|
|
492
|
-
...(record.createdByEmail !== undefined ? { createdByEmail: record.createdByEmail } : {}),
|
|
493
|
-
accessMode: record.accessMode ?? 'owner-only',
|
|
494
|
-
};
|
|
495
447
|
}
|
|
496
448
|
//# sourceMappingURL=postgres.js.map
|