@ankhorage/contracts 19.2.2 → 19.4.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/CHANGELOG.md +12 -0
- package/dist/infra/isInfraEnvironmentSpec.d.ts.map +1 -1
- package/dist/infra/isInfraEnvironmentSpec.js +19 -1
- package/dist/infra/isInfraEnvironmentSpec.js.map +1 -1
- package/dist/infra/isInfraWorkloadSpec.js +2 -1
- package/dist/infra/isInfraWorkloadSpec.js.map +1 -1
- package/dist/types/infraManifest.d.ts +8 -0
- package/dist/types/infraManifest.d.ts.map +1 -1
- package/dist/types/infraManifest.js.map +1 -1
- package/dist/types/infraWorkload.d.ts +2 -0
- package/dist/types/infraWorkload.d.ts.map +1 -1
- package/dist/types/infraWorkload.js.map +1 -1
- package/package.json +1 -1
- package/src/infra/isInfraEnvironmentSpec.ts +19 -1
- package/src/infra/isInfraWorkloadSpec.ts +2 -1
- package/src/infra-workload-persistence.test.ts +30 -0
- package/src/infra.test.ts +0 -33
- package/src/infraNetworking.test.ts +52 -0
- package/src/infraServices.test.ts +50 -0
- package/src/types/infraManifest.ts +9 -0
- package/src/types/infraWorkload.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @ankhorage/contracts
|
|
2
2
|
|
|
3
|
+
## 19.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 59277a2: Add portable image-seeded initialization for persistent workload volumes.
|
|
8
|
+
|
|
9
|
+
## 19.3.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 03da0f5: Add runtime-neutral ACME HTTP-01 TLS intent to Infra networking, including validation that automatic TLS uses a matching HTTPS public origin and domain.
|
|
14
|
+
|
|
3
15
|
## 19.2.2
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isInfraEnvironmentSpec.d.ts","sourceRoot":"","sources":["../../src/infra/isInfraEnvironmentSpec.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAA0B,MAAM,wBAAwB,CAAC;AAU3F,8FAA8F;AAC9F,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,oBAAoB,
|
|
1
|
+
{"version":3,"file":"isInfraEnvironmentSpec.d.ts","sourceRoot":"","sources":["../../src/infra/isInfraEnvironmentSpec.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAA0B,MAAM,wBAAwB,CAAC;AAU3F,8FAA8F;AAC9F,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,oBAAoB,CAOpF"}
|
|
@@ -9,7 +9,10 @@ import { isInfraShape } from './isInfraShape';
|
|
|
9
9
|
import { isInfraWorkloadSpec } from './isInfraWorkloadSpec';
|
|
10
10
|
/*** Validate sibling capabilities and their required relationships within one environment. */
|
|
11
11
|
export function isInfraEnvironmentSpec(value) {
|
|
12
|
-
return (isEnvironmentShape(value) &&
|
|
12
|
+
return (isEnvironmentShape(value) &&
|
|
13
|
+
hasServiceDependencies(value) &&
|
|
14
|
+
hasNetworkingRelationships(value) &&
|
|
15
|
+
hasUniquePublishedPorts(value));
|
|
13
16
|
}
|
|
14
17
|
/*** Check all environment field shapes before inspecting canonical dependency metadata. */
|
|
15
18
|
function isEnvironmentShape(value) {
|
|
@@ -37,6 +40,11 @@ function isEnvironmentShape(value) {
|
|
|
37
40
|
isInfraShape(networking, {
|
|
38
41
|
domain: infraFields.optionalText,
|
|
39
42
|
publicBaseUrl: (publicBaseUrl) => publicBaseUrl === undefined || isPublicHttpOrigin(publicBaseUrl),
|
|
43
|
+
tls: (tls) => tls === undefined ||
|
|
44
|
+
isInfraShape(tls, {
|
|
45
|
+
mode: (mode) => mode === 'acme-http-01',
|
|
46
|
+
contactEmail: isNonEmptyString,
|
|
47
|
+
}),
|
|
40
48
|
}),
|
|
41
49
|
workloads: (workloads) => workloads === undefined || isWorkloads(workloads),
|
|
42
50
|
});
|
|
@@ -53,6 +61,16 @@ function isPublicHttpOrigin(value) {
|
|
|
53
61
|
return false;
|
|
54
62
|
}
|
|
55
63
|
}
|
|
64
|
+
/*** Automatic TLS requires one matching HTTPS origin and public DNS hostname. */
|
|
65
|
+
function hasNetworkingRelationships(value) {
|
|
66
|
+
const { networking } = value;
|
|
67
|
+
if (networking?.tls === undefined)
|
|
68
|
+
return true;
|
|
69
|
+
if (networking.domain === undefined || networking.publicBaseUrl === undefined)
|
|
70
|
+
return false;
|
|
71
|
+
const url = new URL(networking.publicBaseUrl);
|
|
72
|
+
return url.protocol === 'https:' && url.hostname === networking.domain;
|
|
73
|
+
}
|
|
56
74
|
/*** Validate portable, unique Cerbos policy files without host paths or traversal. */
|
|
57
75
|
function isPolicyFiles(value) {
|
|
58
76
|
return (Array.isArray(value) &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isInfraEnvironmentSpec.js","sourceRoot":"","sources":["../../src/infra/isInfraEnvironmentSpec.ts"],"names":[],"mappings":"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","sourcesContent":["import { isRecord } from '@ankhorage/utility/object';\nimport { isNonEmptyString } from '@ankhorage/utility/string';\n\nimport type { InfraEnvironmentSpec, InfraObjectStorageSpec } from '../types/infraManifest';\nimport type { InfraShape } from '../types/infraValidation';\nimport { INFRA_ADAPTER_CATALOG } from './constants';\nimport { infraFields } from './infraFields';\nimport { isInfraAuthSpec } from './isInfraAuthSpec';\nimport { isInfraCredentialRef } from './isInfraCredentialRef';\nimport { isInfraDeploymentSpec } from './isInfraDeploymentSpec';\nimport { isInfraShape } from './isInfraShape';\nimport { isInfraWorkloadSpec } from './isInfraWorkloadSpec';\n\n/*** Validate sibling capabilities and their required relationships within one environment. */\nexport function isInfraEnvironmentSpec(value: unknown): value is InfraEnvironmentSpec {\n return (\n isEnvironmentShape(value) && hasServiceDependencies(value) && hasUniquePublishedPorts(value)\n );\n}\n\n/*** Check all environment field shapes before inspecting canonical dependency metadata. */\nfunction isEnvironmentShape(value: unknown): value is InfraEnvironmentSpec {\n return isInfraShape(value, {\n deployment: isInfraDeploymentSpec,\n database: (database) =>\n database === undefined ||\n isInfraShape(database, {\n provider: (provider) => provider === 'supabase',\n tier: (tier) => tier === undefined || tier === 'dev' || tier === 'prod',\n }),\n objectStorage: (storage) => storage === undefined || isObjectStorage(storage),\n auth: (auth) => auth === undefined || isInfraAuthSpec(auth),\n authz: (authz) =>\n authz === undefined ||\n isInfraShape(authz, {\n provider: (provider) => provider === 'cerbos',\n kind: (kind) => kind === 'ABAC' || kind === 'RBAC',\n policies: (policies) => policies === undefined || isPolicyFiles(policies),\n }),\n secretStore: (store) =>\n store === undefined ||\n isInfraShape(store, {\n provider: (provider) => provider === 'supabase-vault',\n schema: infraFields.optionalText,\n }),\n networking: (networking) =>\n networking === undefined ||\n isInfraShape(networking, {\n domain: infraFields.optionalText,\n publicBaseUrl: (publicBaseUrl) =>\n publicBaseUrl === undefined || isPublicHttpOrigin(publicBaseUrl),\n }),\n workloads: (workloads) => workloads === undefined || isWorkloads(workloads),\n } satisfies InfraShape<InfraEnvironmentSpec>);\n}\n\n/*** Public workload configuration uses one canonical absolute HTTP(S) origin without path state. */\nfunction isPublicHttpOrigin(value: unknown): boolean {\n if (!isNonEmptyString(value)) return false;\n try {\n const url = new URL(value);\n return (url.protocol === 'http:' || url.protocol === 'https:') && url.origin === value;\n } catch {\n return false;\n }\n}\n\n/*** Validate portable, unique Cerbos policy files without host paths or traversal. */\nfunction isPolicyFiles(value: unknown): boolean {\n return (\n Array.isArray(value) &&\n value.every((policy) =>\n isInfraShape(policy, {\n path: (path) =>\n isNonEmptyString(path) && !path.startsWith('/') && !path.split('/').includes('..'),\n content: isNonEmptyString,\n }),\n ) &&\n new Set(value.map((policy) => (isRecord(policy) ? policy.path : undefined))).size ===\n value.length\n );\n}\n\n/*** Object storage can vary independently from database/auth; there is no implicit auto provider. */\nfunction isObjectStorage(value: unknown): boolean {\n if (!isRecord(value)) return false;\n const common = {\n provider: (provider: unknown) => provider === value.provider,\n buckets: infraFields.optionalStrings,\n };\n if (value.provider === 'supabase') return isInfraShape(value, common);\n return isInfraShape(value, {\n ...common,\n provider: (provider) => provider === 'r2',\n accountId: infraFields.optionalText,\n credentials: (credentials) => credentials === undefined || isInfraCredentialRef(credentials),\n } satisfies InfraShape<Extract<InfraObjectStorageSpec, { readonly provider: 'r2' }>>);\n}\n\n/*** Duplicate desired workload identities cannot be reconciled safely. */\nfunction isWorkloads(value: unknown): boolean {\n return (\n Array.isArray(value) &&\n value.every(isInfraWorkloadSpec) &&\n new Set(value.map((workload) => workload.id)).size === value.length\n );\n}\n\n/*** Prevent two workloads in one environment from claiming the same external listener. */\nfunction hasUniquePublishedPorts(value: InfraEnvironmentSpec): boolean {\n const ports = (value.workloads ?? []).flatMap((workload) =>\n (workload.ports ?? []).flatMap(({ publishedPort }) =>\n publishedPort === undefined ? [] : [publishedPort],\n ),\n );\n return new Set(ports).size === ports.length;\n}\n\n/*** Check catalog dependencies against selected sibling capabilities and runtime capabilities. */\nfunction hasServiceDependencies(value: InfraEnvironmentSpec): boolean {\n const selections = [\n value.database,\n value.auth,\n value.authz,\n value.objectStorage,\n value.secretStore,\n ];\n const runtime = Object.values(INFRA_ADAPTER_CATALOG).find(\n (entry) => entry.id === value.deployment.runtime.provider,\n );\n const capabilities = new Set<string>([\n 'compute',\n ...(runtime?.capabilities ?? []),\n ...Object.entries(value)\n .filter(([, selection]) => selection !== undefined)\n .map(([capability]) => capability),\n ]);\n return Object.values(INFRA_ADAPTER_CATALOG)\n .filter((entry) => selections.some((selection) => selection?.provider === entry.id))\n .every((entry) => entry.dependencies.every((dependency) => capabilities.has(dependency)));\n}\n"]}
|
|
1
|
+
{"version":3,"file":"isInfraEnvironmentSpec.js","sourceRoot":"","sources":["../../src/infra/isInfraEnvironmentSpec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAI7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,8FAA8F;AAC9F,MAAM,UAAU,sBAAsB,CAAC,KAAc;IACnD,OAAO,CACL,kBAAkB,CAAC,KAAK,CAAC;QACzB,sBAAsB,CAAC,KAAK,CAAC;QAC7B,0BAA0B,CAAC,KAAK,CAAC;QACjC,uBAAuB,CAAC,KAAK,CAAC,CAC/B,CAAC;AACJ,CAAC;AAED,2FAA2F;AAC3F,SAAS,kBAAkB,CAAC,KAAc;IACxC,OAAO,YAAY,CAAC,KAAK,EAAE;QACzB,UAAU,EAAE,qBAAqB;QACjC,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE,CACrB,QAAQ,KAAK,SAAS;YACtB,YAAY,CAAC,QAAQ,EAAE;gBACrB,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,UAAU;gBAC/C,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,MAAM;aACxE,CAAC;QACJ,aAAa,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,SAAS,IAAI,eAAe,CAAC,OAAO,CAAC;QAC7E,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,IAAI,eAAe,CAAC,IAAI,CAAC;QAC3D,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CACf,KAAK,KAAK,SAAS;YACnB,YAAY,CAAC,KAAK,EAAE;gBAClB,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,QAAQ;gBAC7C,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,MAAM;gBAClD,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,SAAS,IAAI,aAAa,CAAC,QAAQ,CAAC;aAC1E,CAAC;QACJ,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,CACrB,KAAK,KAAK,SAAS;YACnB,YAAY,CAAC,KAAK,EAAE;gBAClB,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,gBAAgB;gBACrD,MAAM,EAAE,WAAW,CAAC,YAAY;aACjC,CAAC;QACJ,UAAU,EAAE,CAAC,UAAU,EAAE,EAAE,CACzB,UAAU,KAAK,SAAS;YACxB,YAAY,CAAC,UAAU,EAAE;gBACvB,MAAM,EAAE,WAAW,CAAC,YAAY;gBAChC,aAAa,EAAE,CAAC,aAAa,EAAE,EAAE,CAC/B,aAAa,KAAK,SAAS,IAAI,kBAAkB,CAAC,aAAa,CAAC;gBAClE,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,CACX,GAAG,KAAK,SAAS;oBACjB,YAAY,CAAC,GAAG,EAAE;wBAChB,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,cAAc;wBACvC,YAAY,EAAE,gBAAgB;qBAC/B,CAAC;aACL,CAAC;QACJ,SAAS,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,SAAS,IAAI,WAAW,CAAC,SAAS,CAAC;KACjC,CAAC,CAAC;AAChD,CAAC;AAED,oGAAoG;AACpG,SAAS,kBAAkB,CAAC,KAAc;IACxC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,CAAC;IACzF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,iFAAiF;AACjF,SAAS,0BAA0B,CAAC,KAA2B;IAC7D,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;IAC7B,IAAI,UAAU,EAAE,GAAG,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC/C,IAAI,UAAU,CAAC,MAAM,KAAK,SAAS,IAAI,UAAU,CAAC,aAAa,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC5F,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAC9C,OAAO,GAAG,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,KAAK,UAAU,CAAC,MAAM,CAAC;AACzE,CAAC;AAED,sFAAsF;AACtF,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,CACL,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACpB,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CACrB,YAAY,CAAC,MAAM,EAAE;YACnB,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CACb,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;YACpF,OAAO,EAAE,gBAAgB;SAC1B,CAAC,CACH;QACD,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI;YAC/E,KAAK,CAAC,MAAM,CACf,CAAC;AACJ,CAAC;AAED,qGAAqG;AACrG,SAAS,eAAe,CAAC,KAAc;IACrC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,MAAM,MAAM,GAAG;QACb,QAAQ,EAAE,CAAC,QAAiB,EAAE,EAAE,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ;QAC5D,OAAO,EAAE,WAAW,CAAC,eAAe;KACrC,CAAC;IACF,IAAI,KAAK,CAAC,QAAQ,KAAK,UAAU;QAAE,OAAO,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACtE,OAAO,YAAY,CAAC,KAAK,EAAE;QACzB,GAAG,MAAM;QACT,QAAQ,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,KAAK,IAAI;QACzC,SAAS,EAAE,WAAW,CAAC,YAAY;QACnC,WAAW,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,WAAW,KAAK,SAAS,IAAI,oBAAoB,CAAC,WAAW,CAAC;KACV,CAAC,CAAC;AACxF,CAAC;AAED,0EAA0E;AAC1E,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,CACL,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACpB,KAAK,CAAC,KAAK,CAAC,mBAAmB,CAAC;QAChC,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,CACpE,CAAC;AACJ,CAAC;AAED,0FAA0F;AAC1F,SAAS,uBAAuB,CAAC,KAA2B;IAC1D,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CACzD,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,aAAa,EAAE,EAAE,EAAE,CACnD,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CACnD,CACF,CAAC;IACF,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,MAAM,CAAC;AAC9C,CAAC;AAED,kGAAkG;AAClG,SAAS,sBAAsB,CAAC,KAA2B;IACzD,MAAM,UAAU,GAAG;QACjB,KAAK,CAAC,QAAQ;QACd,KAAK,CAAC,IAAI;QACV,KAAK,CAAC,KAAK;QACX,KAAK,CAAC,aAAa;QACnB,KAAK,CAAC,WAAW;KAClB,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,IAAI,CACvD,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAC1D,CAAC;IACF,MAAM,YAAY,GAAG,IAAI,GAAG,CAAS;QACnC,SAAS;QACT,GAAG,CAAC,OAAO,EAAE,YAAY,IAAI,EAAE,CAAC;QAChC,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;aACrB,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC,SAAS,KAAK,SAAS,CAAC;aAClD,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC;KACrC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,MAAM,CAAC,qBAAqB,CAAC;SACxC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,QAAQ,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC;SACnF,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AAC9F,CAAC","sourcesContent":["import { isRecord } from '@ankhorage/utility/object';\nimport { isNonEmptyString } from '@ankhorage/utility/string';\n\nimport type { InfraEnvironmentSpec, InfraObjectStorageSpec } from '../types/infraManifest';\nimport type { InfraShape } from '../types/infraValidation';\nimport { INFRA_ADAPTER_CATALOG } from './constants';\nimport { infraFields } from './infraFields';\nimport { isInfraAuthSpec } from './isInfraAuthSpec';\nimport { isInfraCredentialRef } from './isInfraCredentialRef';\nimport { isInfraDeploymentSpec } from './isInfraDeploymentSpec';\nimport { isInfraShape } from './isInfraShape';\nimport { isInfraWorkloadSpec } from './isInfraWorkloadSpec';\n\n/*** Validate sibling capabilities and their required relationships within one environment. */\nexport function isInfraEnvironmentSpec(value: unknown): value is InfraEnvironmentSpec {\n return (\n isEnvironmentShape(value) &&\n hasServiceDependencies(value) &&\n hasNetworkingRelationships(value) &&\n hasUniquePublishedPorts(value)\n );\n}\n\n/*** Check all environment field shapes before inspecting canonical dependency metadata. */\nfunction isEnvironmentShape(value: unknown): value is InfraEnvironmentSpec {\n return isInfraShape(value, {\n deployment: isInfraDeploymentSpec,\n database: (database) =>\n database === undefined ||\n isInfraShape(database, {\n provider: (provider) => provider === 'supabase',\n tier: (tier) => tier === undefined || tier === 'dev' || tier === 'prod',\n }),\n objectStorage: (storage) => storage === undefined || isObjectStorage(storage),\n auth: (auth) => auth === undefined || isInfraAuthSpec(auth),\n authz: (authz) =>\n authz === undefined ||\n isInfraShape(authz, {\n provider: (provider) => provider === 'cerbos',\n kind: (kind) => kind === 'ABAC' || kind === 'RBAC',\n policies: (policies) => policies === undefined || isPolicyFiles(policies),\n }),\n secretStore: (store) =>\n store === undefined ||\n isInfraShape(store, {\n provider: (provider) => provider === 'supabase-vault',\n schema: infraFields.optionalText,\n }),\n networking: (networking) =>\n networking === undefined ||\n isInfraShape(networking, {\n domain: infraFields.optionalText,\n publicBaseUrl: (publicBaseUrl) =>\n publicBaseUrl === undefined || isPublicHttpOrigin(publicBaseUrl),\n tls: (tls) =>\n tls === undefined ||\n isInfraShape(tls, {\n mode: (mode) => mode === 'acme-http-01',\n contactEmail: isNonEmptyString,\n }),\n }),\n workloads: (workloads) => workloads === undefined || isWorkloads(workloads),\n } satisfies InfraShape<InfraEnvironmentSpec>);\n}\n\n/*** Public workload configuration uses one canonical absolute HTTP(S) origin without path state. */\nfunction isPublicHttpOrigin(value: unknown): boolean {\n if (!isNonEmptyString(value)) return false;\n try {\n const url = new URL(value);\n return (url.protocol === 'http:' || url.protocol === 'https:') && url.origin === value;\n } catch {\n return false;\n }\n}\n\n/*** Automatic TLS requires one matching HTTPS origin and public DNS hostname. */\nfunction hasNetworkingRelationships(value: InfraEnvironmentSpec): boolean {\n const { networking } = value;\n if (networking?.tls === undefined) return true;\n if (networking.domain === undefined || networking.publicBaseUrl === undefined) return false;\n const url = new URL(networking.publicBaseUrl);\n return url.protocol === 'https:' && url.hostname === networking.domain;\n}\n\n/*** Validate portable, unique Cerbos policy files without host paths or traversal. */\nfunction isPolicyFiles(value: unknown): boolean {\n return (\n Array.isArray(value) &&\n value.every((policy) =>\n isInfraShape(policy, {\n path: (path) =>\n isNonEmptyString(path) && !path.startsWith('/') && !path.split('/').includes('..'),\n content: isNonEmptyString,\n }),\n ) &&\n new Set(value.map((policy) => (isRecord(policy) ? policy.path : undefined))).size ===\n value.length\n );\n}\n\n/*** Object storage can vary independently from database/auth; there is no implicit auto provider. */\nfunction isObjectStorage(value: unknown): boolean {\n if (!isRecord(value)) return false;\n const common = {\n provider: (provider: unknown) => provider === value.provider,\n buckets: infraFields.optionalStrings,\n };\n if (value.provider === 'supabase') return isInfraShape(value, common);\n return isInfraShape(value, {\n ...common,\n provider: (provider) => provider === 'r2',\n accountId: infraFields.optionalText,\n credentials: (credentials) => credentials === undefined || isInfraCredentialRef(credentials),\n } satisfies InfraShape<Extract<InfraObjectStorageSpec, { readonly provider: 'r2' }>>);\n}\n\n/*** Duplicate desired workload identities cannot be reconciled safely. */\nfunction isWorkloads(value: unknown): boolean {\n return (\n Array.isArray(value) &&\n value.every(isInfraWorkloadSpec) &&\n new Set(value.map((workload) => workload.id)).size === value.length\n );\n}\n\n/*** Prevent two workloads in one environment from claiming the same external listener. */\nfunction hasUniquePublishedPorts(value: InfraEnvironmentSpec): boolean {\n const ports = (value.workloads ?? []).flatMap((workload) =>\n (workload.ports ?? []).flatMap(({ publishedPort }) =>\n publishedPort === undefined ? [] : [publishedPort],\n ),\n );\n return new Set(ports).size === ports.length;\n}\n\n/*** Check catalog dependencies against selected sibling capabilities and runtime capabilities. */\nfunction hasServiceDependencies(value: InfraEnvironmentSpec): boolean {\n const selections = [\n value.database,\n value.auth,\n value.authz,\n value.objectStorage,\n value.secretStore,\n ];\n const runtime = Object.values(INFRA_ADAPTER_CATALOG).find(\n (entry) => entry.id === value.deployment.runtime.provider,\n );\n const capabilities = new Set<string>([\n 'compute',\n ...(runtime?.capabilities ?? []),\n ...Object.entries(value)\n .filter(([, selection]) => selection !== undefined)\n .map(([capability]) => capability),\n ]);\n return Object.values(INFRA_ADAPTER_CATALOG)\n .filter((entry) => selections.some((selection) => selection?.provider === entry.id))\n .every((entry) => entry.dependencies.every((dependency) => capabilities.has(dependency)));\n}\n"]}
|
|
@@ -66,12 +66,13 @@ function hasValidPublishedPorts(workload) {
|
|
|
66
66
|
function isFile(value) {
|
|
67
67
|
return isInfraShape(value, { path: isAbsoluteWorkloadPath, content: isInfraWorkloadValue });
|
|
68
68
|
}
|
|
69
|
-
/*** Persistence has explicit ownership-local identity and
|
|
69
|
+
/*** Persistence has explicit ownership-local identity, optional initialization and retention policy. */
|
|
70
70
|
function isVolume(value) {
|
|
71
71
|
return isInfraShape(value, {
|
|
72
72
|
id: isNonEmptyString,
|
|
73
73
|
mountPath: isAbsoluteWorkloadPath,
|
|
74
74
|
sizeGiB: infraFields.positiveInteger,
|
|
75
|
+
seed: (seed) => seed === undefined || seed === 'image',
|
|
75
76
|
retention: (retention) => retention === 'retain' || retention === 'delete-on-destroy',
|
|
76
77
|
});
|
|
77
78
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isInfraWorkloadSpec.js","sourceRoot":"","sources":["../../src/infra/isInfraWorkloadSpec.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"isInfraWorkloadSpec.js","sourceRoot":"","sources":["../../src/infra/isInfraWorkloadSpec.ts"],"names":[],"mappings":"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","sourcesContent":["import { isStringArray } from '@ankhorage/utility/array';\nimport { isRecord } from '@ankhorage/utility/object';\nimport { isNonEmptyString } from '@ankhorage/utility/string';\n\nimport type { InfraShape } from '../types/infraValidation';\nimport type { InfraWorkloadSpec } from '../types/infraWorkload';\nimport { infraFields } from './infraFields';\nimport { isInfraShape } from './isInfraShape';\nimport { isInfraWorkloadHealth } from './isInfraWorkloadHealth';\nimport { isInfraWorkloadValue } from './isInfraWorkloadValue';\n\n/*** Validate the portable desired workload; runtime-specific fields and plaintext secret objects fail. */\nexport function isInfraWorkloadSpec(value: unknown): value is InfraWorkloadSpec {\n if (\n !isInfraShape(value, {\n id: isNonEmptyString,\n artifact: (artifact) =>\n isInfraShape(artifact, { kind: (kind) => kind === 'image', image: isNonEmptyString }),\n command: infraFields.optionalStrings,\n args: (args) => args === undefined || isStringArray(args),\n ports: (ports) =>\n ports === undefined ||\n (Array.isArray(ports) && ports.every(isPort) && hasUniqueField(ports, 'name')),\n environment: (environment) =>\n environment === undefined ||\n (isRecord(environment) && Object.values(environment).every(isInfraWorkloadValue)),\n files: (files) =>\n files === undefined ||\n (Array.isArray(files) && files.every(isFile) && hasUniqueField(files, 'path')),\n health: (health) => health === undefined || isInfraWorkloadHealth(health),\n resources: (resources) =>\n resources === undefined ||\n isInfraShape(resources, {\n cpuMillis: infraFields.optionalPositiveInteger,\n memoryMiB: infraFields.optionalPositiveInteger,\n }),\n persistence: (volumes) =>\n volumes === undefined ||\n (Array.isArray(volumes) &&\n volumes.every(isVolume) &&\n hasUniqueField(volumes, 'id') &&\n hasUniqueField(volumes, 'mountPath')),\n exposure: (exposure) =>\n exposure === undefined || exposure === 'internal' || exposure === 'public',\n replicas: infraFields.optionalNonnegativeInteger,\n dependsOn: infraFields.optionalStrings,\n } satisfies InfraShape<InfraWorkloadSpec>)\n ) {\n return false;\n }\n return hasValidPublishedPorts(value);\n}\n\n/*** Named transport ports stay independent from runtime resource types. */\nfunction isPort(value: unknown): boolean {\n return isInfraShape(value, {\n name: isNonEmptyString,\n port: infraFields.port,\n protocol: (protocol) => protocol === undefined || protocol === 'tcp' || protocol === 'udp',\n publishedPort: infraFields.optionalPort,\n });\n}\n\n/*** Require fixed external listeners to belong to one public workload replica. */\nfunction hasValidPublishedPorts(workload: unknown): boolean {\n if (!isRecord(workload)) return false;\n const ports = Array.isArray(workload.ports) ? workload.ports : [];\n const published = ports.flatMap((port) => {\n if (!isRecord(port) || typeof port.publishedPort !== 'number') return [];\n return [port.publishedPort];\n });\n return (\n new Set(published).size === published.length &&\n (published.length === 0 ||\n (workload.exposure === 'public' &&\n (workload.replicas === undefined ||\n (typeof workload.replicas === 'number' && workload.replicas <= 1))))\n );\n}\n\n/*** Portable files model policy/config materialization without host filesystem access. */\nfunction isFile(value: unknown): boolean {\n return isInfraShape(value, { path: isAbsoluteWorkloadPath, content: isInfraWorkloadValue });\n}\n\n/*** Persistence has explicit ownership-local identity, optional initialization and retention policy. */\nfunction isVolume(value: unknown): boolean {\n return isInfraShape(value, {\n id: isNonEmptyString,\n mountPath: isAbsoluteWorkloadPath,\n sizeGiB: infraFields.positiveInteger,\n seed: (seed) => seed === undefined || seed === 'image',\n retention: (retention) => retention === 'retain' || retention === 'delete-on-destroy',\n });\n}\n\n/*** Workload paths are absolute container paths, never relative host traversal. */\nfunction isAbsoluteWorkloadPath(value: unknown): boolean {\n return (\n typeof value === 'string' &&\n value.startsWith('/') &&\n value.length > 1 &&\n !value.split('/').includes('..')\n );\n}\n\n/*** Duplicate workload-local identities would make runtime projection ambiguous. */\nfunction hasUniqueField(values: readonly unknown[], field: string): boolean {\n const ids = values.map((value) => (isRecord(value) ? Reflect.get(value, field) : undefined));\n return new Set(ids).size === ids.length;\n}\n"]}
|
|
@@ -129,11 +129,19 @@ export type InfraSecretStoreSpec = {
|
|
|
129
129
|
readonly provider: P;
|
|
130
130
|
} & InfraSecretStoreConfigMap[P];
|
|
131
131
|
}[InfraProviderFor<'secretStore'>];
|
|
132
|
+
export interface InfraNetworkingTlsSpec {
|
|
133
|
+
/** First production slice: runtime-managed ACME using the HTTP-01 challenge. */
|
|
134
|
+
readonly mode: 'acme-http-01';
|
|
135
|
+
/** ACME registration and expiry-notification contact. */
|
|
136
|
+
readonly contactEmail: string;
|
|
137
|
+
}
|
|
132
138
|
export interface InfraNetworkingSpec {
|
|
133
139
|
/** Public DNS name intent, not automatic DNS/CDN vendor provisioning. */
|
|
134
140
|
readonly domain?: string;
|
|
135
141
|
/** Absolute HTTP(S) origin used by workloads that must know their external URL at startup. */
|
|
136
142
|
readonly publicBaseUrl?: string;
|
|
143
|
+
/** Runtime-neutral automatic TLS intent; the selected runtime owns concrete ingress configuration. */
|
|
144
|
+
readonly tls?: InfraNetworkingTlsSpec;
|
|
137
145
|
}
|
|
138
146
|
export interface InfraEnvironmentSpec {
|
|
139
147
|
readonly deployment: InfraDeploymentSpec;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"infraManifest.d.ts","sourceRoot":"","sources":["../../src/types/infraManifest.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"infraManifest.d.ts","sourceRoot":"","sources":["../../src/types/infraManifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,2BAA2B,EAAE,MAAM,oBAAoB,CAAC;AAC7F,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC3F,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,MAAM,MAAM,cAAc,GAAG,MAAM,OAAO,qBAAqB,CAAC;AAChE,MAAM,MAAM,eAAe,GACzB,CAAC,OAAO,qBAAqB,CAAC,CAAC,cAAc,CAAC,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AACzE,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,eAAe,IAAI;KACvD,CAAC,IAAI,cAAc,GAAG,CAAC,SAAS,CAAC,OAAO,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,GACtF,CAAC,GACD,KAAK;CACV,CAAC,cAAc,CAAC,CAAC;AAClB,MAAM,MAAM,sBAAsB,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;AACjE,MAAM,MAAM,sBAAsB,GAAG,MAAM,OAAO,2BAA2B,CAAC;AAE9E,kGAAkG;AAClG,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACvD,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,WAAW,CAAC,EAAE,8BAA8B,CAAC;QACtD,QAAQ,CAAC,GAAG,CAAC,EAAE;YACb,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;YACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;YACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,8BAA8B,CAAC;SACvD,CAAC;KACH,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;QACtC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,QAAQ,CAAC,GAAG,EAAE;QACZ,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE;YAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;KAC3E,CAAC;IACF,QAAQ,CAAC,gBAAgB,EAAE;QAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9D;AAED,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,sBAAsB,GAAG,sBAAsB,IAAI;KAC5F,CAAC,IAAI,CAAC,GAAG;QAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAA;KAAE,GAAG,qBAAqB,CAAC,CAAC,CAAC;CAC9D,CAAC,CAAC,CAAC,CAAC;AACL,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,sBAAsB,GAAG,sBAAsB,IAAI;KAC5F,CAAC,IAAI,CAAC,GAAG;QAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAA;KAAE,GAAG,qBAAqB,CAAC,CAAC,CAAC;CAC9D,CAAC,CAAC,CAAC,CAAC;AAEL,yFAAyF;AACzF,MAAM,MAAM,mBAAmB,GAAG;KAC/B,CAAC,IAAI,sBAAsB,GAAG;QAC7B,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC,OAAO,2BAA2B,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QACzF,QAAQ,CAAC,OAAO,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC;KAC5C;CACF,CAAC,sBAAsB,CAAC,CAAC;AAE1B,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,QAAQ,EAAE;QAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,GAAG,MAAM,CAAA;KAAE,CAAC;CACvD;AACD,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,QAAQ,EAAE;QAAE,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,CAAC;IAC5D,QAAQ,CAAC,EAAE,EAAE;QACX,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,8BAA8B,CAAC;KACvD,CAAC;CACH;AACD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE;QACjB,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC;QAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC;QAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;QACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,cAAc,CAAC;QACjC,QAAQ,CAAC,KAAK,CAAC,EAAE,eAAe,CAAC;QACjC,QAAQ,CAAC,OAAO,CAAC,EAAE,eAAe,CAAC;KACpC,CAAC;CACH;AACD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE;QACf,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;QAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAC;KACrD,CAAC;CACH;AACD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AACD,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,gBAAgB,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACzD;AAED,MAAM,MAAM,iBAAiB,GAAG;KAC7B,CAAC,IAAI,gBAAgB,CAAC,UAAU,CAAC,GAAG;QAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAA;KAAE,GAAG,sBAAsB,CAAC,CAAC,CAAC;CAC1F,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC;AAChC,MAAM,MAAM,sBAAsB,GAAG;KAClC,CAAC,IAAI,gBAAgB,CAAC,eAAe,CAAC,GAAG;QACxC,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;KACtB,GAAG,2BAA2B,CAAC,CAAC,CAAC;CACnC,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC,CAAC;AACrC,MAAM,MAAM,aAAa,GAAG;KACzB,CAAC,IAAI,gBAAgB,CAAC,MAAM,CAAC,GAAG;QAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAA;KAAE,GAAG,kBAAkB,CAAC,CAAC,CAAC;CAClF,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC;AAC5B,MAAM,MAAM,cAAc,GAAG;KAC1B,CAAC,IAAI,gBAAgB,CAAC,OAAO,CAAC,GAAG;QAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAA;KAAE,GAAG,mBAAmB,CAAC,CAAC,CAAC;CACpF,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;AAC7B,MAAM,MAAM,oBAAoB,GAAG;KAChC,CAAC,IAAI,gBAAgB,CAAC,aAAa,CAAC,GAAG;QAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAA;KAAE,GAAG,yBAAyB,CAAC,CAAC,CAAC;CAChG,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC,CAAC;AAEnC,MAAM,WAAW,sBAAsB;IACrC,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,yDAAyD;IACzD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,mBAAmB;IAClC,yEAAyE;IACzE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,8FAA8F;IAC9F,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,sGAAsG;IACtG,QAAQ,CAAC,GAAG,CAAC,EAAE,sBAAsB,CAAC;CACvC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,UAAU,EAAE,mBAAmB,CAAC;IACzC,QAAQ,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IACtC,QAAQ,CAAC,aAAa,CAAC,EAAE,sBAAsB,CAAC;IAChD,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,WAAW,CAAC,EAAE,oBAAoB,CAAC;IAC5C,QAAQ,CAAC,UAAU,CAAC,EAAE,mBAAmB,CAAC;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;CACnD;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAC7B,MAAM,CAAC,OAAO,EAAE,oBAAoB,CAAC,GACnC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,OAAO,CAAC,EAAE,oBAAoB,CAAC,CAAC,CAC5E,CAAC;IACF,QAAQ,CAAC,IAAI,CAAC,EAAE,iBAAiB,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAC5D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"infraManifest.js","sourceRoot":"","sources":["../../src/types/infraManifest.ts"],"names":[],"mappings":"","sourcesContent":["import type { AuthFlowConfig, AuthOAuthConfig } from '../auth';\nimport type { ApiDefinitionList } from '../data';\nimport type { AppEnvironmentId } from '../environments';\nimport type { INFRA_ADAPTER_CATALOG, INFRA_RUNTIME_COMPATIBILITY } from '../infra/constants';\nimport type { AuthProfileSpec, AuthScope, AuthSignInSpec, AuthSignUpSpec } from '../types';\nimport type { InfraControlPlaneCredentialRef } from './infraSecrets';\nimport type { InfraWorkloadSpec } from './infraWorkload';\n\nexport type InfraAdapterId = keyof typeof INFRA_ADAPTER_CATALOG;\nexport type InfraCapability =\n (typeof INFRA_ADAPTER_CATALOG)[InfraAdapterId]['capabilities'][number];\nexport type InfraProviderFor<C extends InfraCapability> = {\n [P in InfraAdapterId]: C extends (typeof INFRA_ADAPTER_CATALOG)[P]['capabilities'][number]\n ? P\n : never;\n}[InfraAdapterId];\nexport type InfraComputeProviderId = InfraProviderFor<'compute'>;\nexport type InfraRuntimeProviderId = keyof typeof INFRA_RUNTIME_COMPATIBILITY;\n\n/** Non-secret provider configuration; credentials are resolved only at the execution boundary. */\nexport interface InfraComputeConfigMap {\n readonly local: { readonly workingDirectory?: string };\n readonly hetzner: {\n readonly location: string;\n readonly serverType?: string;\n readonly image?: string;\n readonly credentials?: InfraControlPlaneCredentialRef;\n readonly ssh?: {\n readonly user?: string;\n readonly port?: number;\n readonly credentials?: InfraControlPlaneCredentialRef;\n };\n };\n}\n\nexport interface InfraRuntimeConfigMap {\n readonly minikube: {\n readonly profile?: string;\n readonly driver?: 'docker' | 'podman';\n readonly cpus?: number;\n readonly memoryMiB?: number;\n };\n readonly k3s: {\n readonly version?: string;\n readonly topology?: { readonly servers: number; readonly agents: number };\n };\n readonly 'docker-compose': { readonly projectName?: string };\n}\n\nexport type InfraComputeSelection<P extends InfraComputeProviderId = InfraComputeProviderId> = {\n [K in P]: { readonly provider: K } & InfraComputeConfigMap[K];\n}[P];\nexport type InfraRuntimeSelection<P extends InfraRuntimeProviderId = InfraRuntimeProviderId> = {\n [K in P]: { readonly provider: K } & InfraRuntimeConfigMap[K];\n}[P];\n\n/** A discriminated union derived from the runtime catalog, never a Cartesian product. */\nexport type InfraDeploymentSpec = {\n [R in InfraRuntimeProviderId]: {\n readonly compute: InfraComputeSelection<(typeof INFRA_RUNTIME_COMPATIBILITY)[R][number]>;\n readonly runtime: InfraRuntimeSelection<R>;\n };\n}[InfraRuntimeProviderId];\n\nexport interface InfraDatabaseConfigMap {\n readonly supabase: { readonly tier?: 'dev' | 'prod' };\n}\nexport interface InfraObjectStorageConfigMap {\n readonly supabase: { readonly buckets?: readonly string[] };\n readonly r2: {\n readonly buckets?: readonly string[];\n readonly accountId?: string;\n readonly credentials?: InfraControlPlaneCredentialRef;\n };\n}\nexport interface InfraAuthConfigMap {\n readonly supabase: {\n readonly scope?: AuthScope;\n readonly flow?: AuthFlowConfig;\n readonly signIn?: AuthSignInSpec;\n readonly signUp?: AuthSignUpSpec;\n readonly oauth?: AuthOAuthConfig;\n readonly profile?: AuthProfileSpec;\n };\n}\nexport interface InfraAuthzConfigMap {\n readonly cerbos: {\n readonly kind: 'RBAC' | 'ABAC';\n readonly policies?: readonly InfraAuthzPolicyFile[];\n };\n}\nexport interface InfraAuthzPolicyFile {\n readonly path: string;\n readonly content: string;\n}\nexport interface InfraSecretStoreConfigMap {\n readonly 'supabase-vault': { readonly schema?: string };\n}\n\nexport type InfraDatabaseSpec = {\n [P in InfraProviderFor<'database'>]: { readonly provider: P } & InfraDatabaseConfigMap[P];\n}[InfraProviderFor<'database'>];\nexport type InfraObjectStorageSpec = {\n [P in InfraProviderFor<'objectStorage'>]: {\n readonly provider: P;\n } & InfraObjectStorageConfigMap[P];\n}[InfraProviderFor<'objectStorage'>];\nexport type InfraAuthSpec = {\n [P in InfraProviderFor<'auth'>]: { readonly provider: P } & InfraAuthConfigMap[P];\n}[InfraProviderFor<'auth'>];\nexport type InfraAuthzSpec = {\n [P in InfraProviderFor<'authz'>]: { readonly provider: P } & InfraAuthzConfigMap[P];\n}[InfraProviderFor<'authz'>];\nexport type InfraSecretStoreSpec = {\n [P in InfraProviderFor<'secretStore'>]: { readonly provider: P } & InfraSecretStoreConfigMap[P];\n}[InfraProviderFor<'secretStore'>];\n\nexport interface InfraNetworkingSpec {\n /** Public DNS name intent, not automatic DNS/CDN vendor provisioning. */\n readonly domain?: string;\n /** Absolute HTTP(S) origin used by workloads that must know their external URL at startup. */\n readonly publicBaseUrl?: string;\n}\n\nexport interface InfraEnvironmentSpec {\n readonly deployment: InfraDeploymentSpec;\n readonly database?: InfraDatabaseSpec;\n readonly objectStorage?: InfraObjectStorageSpec;\n readonly auth?: InfraAuthSpec;\n readonly authz?: InfraAuthzSpec;\n readonly secretStore?: InfraSecretStoreSpec;\n readonly networking?: InfraNetworkingSpec;\n readonly workloads?: readonly InfraWorkloadSpec[];\n}\n\nexport interface InfraManifest {\n readonly environments: Readonly<\n Record<'local', InfraEnvironmentSpec> &\n Partial<Record<Exclude<AppEnvironmentId, 'local'>, InfraEnvironmentSpec>>\n >;\n readonly apis?: ApiDefinitionList;\n readonly modules: readonly string[];\n readonly modulesConfig?: Readonly<Record<string, unknown>>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"infraManifest.js","sourceRoot":"","sources":["../../src/types/infraManifest.ts"],"names":[],"mappings":"","sourcesContent":["import type { AuthFlowConfig, AuthOAuthConfig } from '../auth';\nimport type { ApiDefinitionList } from '../data';\nimport type { AppEnvironmentId } from '../environments';\nimport type { INFRA_ADAPTER_CATALOG, INFRA_RUNTIME_COMPATIBILITY } from '../infra/constants';\nimport type { AuthProfileSpec, AuthScope, AuthSignInSpec, AuthSignUpSpec } from '../types';\nimport type { InfraControlPlaneCredentialRef } from './infraSecrets';\nimport type { InfraWorkloadSpec } from './infraWorkload';\n\nexport type InfraAdapterId = keyof typeof INFRA_ADAPTER_CATALOG;\nexport type InfraCapability =\n (typeof INFRA_ADAPTER_CATALOG)[InfraAdapterId]['capabilities'][number];\nexport type InfraProviderFor<C extends InfraCapability> = {\n [P in InfraAdapterId]: C extends (typeof INFRA_ADAPTER_CATALOG)[P]['capabilities'][number]\n ? P\n : never;\n}[InfraAdapterId];\nexport type InfraComputeProviderId = InfraProviderFor<'compute'>;\nexport type InfraRuntimeProviderId = keyof typeof INFRA_RUNTIME_COMPATIBILITY;\n\n/** Non-secret provider configuration; credentials are resolved only at the execution boundary. */\nexport interface InfraComputeConfigMap {\n readonly local: { readonly workingDirectory?: string };\n readonly hetzner: {\n readonly location: string;\n readonly serverType?: string;\n readonly image?: string;\n readonly credentials?: InfraControlPlaneCredentialRef;\n readonly ssh?: {\n readonly user?: string;\n readonly port?: number;\n readonly credentials?: InfraControlPlaneCredentialRef;\n };\n };\n}\n\nexport interface InfraRuntimeConfigMap {\n readonly minikube: {\n readonly profile?: string;\n readonly driver?: 'docker' | 'podman';\n readonly cpus?: number;\n readonly memoryMiB?: number;\n };\n readonly k3s: {\n readonly version?: string;\n readonly topology?: { readonly servers: number; readonly agents: number };\n };\n readonly 'docker-compose': { readonly projectName?: string };\n}\n\nexport type InfraComputeSelection<P extends InfraComputeProviderId = InfraComputeProviderId> = {\n [K in P]: { readonly provider: K } & InfraComputeConfigMap[K];\n}[P];\nexport type InfraRuntimeSelection<P extends InfraRuntimeProviderId = InfraRuntimeProviderId> = {\n [K in P]: { readonly provider: K } & InfraRuntimeConfigMap[K];\n}[P];\n\n/** A discriminated union derived from the runtime catalog, never a Cartesian product. */\nexport type InfraDeploymentSpec = {\n [R in InfraRuntimeProviderId]: {\n readonly compute: InfraComputeSelection<(typeof INFRA_RUNTIME_COMPATIBILITY)[R][number]>;\n readonly runtime: InfraRuntimeSelection<R>;\n };\n}[InfraRuntimeProviderId];\n\nexport interface InfraDatabaseConfigMap {\n readonly supabase: { readonly tier?: 'dev' | 'prod' };\n}\nexport interface InfraObjectStorageConfigMap {\n readonly supabase: { readonly buckets?: readonly string[] };\n readonly r2: {\n readonly buckets?: readonly string[];\n readonly accountId?: string;\n readonly credentials?: InfraControlPlaneCredentialRef;\n };\n}\nexport interface InfraAuthConfigMap {\n readonly supabase: {\n readonly scope?: AuthScope;\n readonly flow?: AuthFlowConfig;\n readonly signIn?: AuthSignInSpec;\n readonly signUp?: AuthSignUpSpec;\n readonly oauth?: AuthOAuthConfig;\n readonly profile?: AuthProfileSpec;\n };\n}\nexport interface InfraAuthzConfigMap {\n readonly cerbos: {\n readonly kind: 'RBAC' | 'ABAC';\n readonly policies?: readonly InfraAuthzPolicyFile[];\n };\n}\nexport interface InfraAuthzPolicyFile {\n readonly path: string;\n readonly content: string;\n}\nexport interface InfraSecretStoreConfigMap {\n readonly 'supabase-vault': { readonly schema?: string };\n}\n\nexport type InfraDatabaseSpec = {\n [P in InfraProviderFor<'database'>]: { readonly provider: P } & InfraDatabaseConfigMap[P];\n}[InfraProviderFor<'database'>];\nexport type InfraObjectStorageSpec = {\n [P in InfraProviderFor<'objectStorage'>]: {\n readonly provider: P;\n } & InfraObjectStorageConfigMap[P];\n}[InfraProviderFor<'objectStorage'>];\nexport type InfraAuthSpec = {\n [P in InfraProviderFor<'auth'>]: { readonly provider: P } & InfraAuthConfigMap[P];\n}[InfraProviderFor<'auth'>];\nexport type InfraAuthzSpec = {\n [P in InfraProviderFor<'authz'>]: { readonly provider: P } & InfraAuthzConfigMap[P];\n}[InfraProviderFor<'authz'>];\nexport type InfraSecretStoreSpec = {\n [P in InfraProviderFor<'secretStore'>]: { readonly provider: P } & InfraSecretStoreConfigMap[P];\n}[InfraProviderFor<'secretStore'>];\n\nexport interface InfraNetworkingTlsSpec {\n /** First production slice: runtime-managed ACME using the HTTP-01 challenge. */\n readonly mode: 'acme-http-01';\n /** ACME registration and expiry-notification contact. */\n readonly contactEmail: string;\n}\n\nexport interface InfraNetworkingSpec {\n /** Public DNS name intent, not automatic DNS/CDN vendor provisioning. */\n readonly domain?: string;\n /** Absolute HTTP(S) origin used by workloads that must know their external URL at startup. */\n readonly publicBaseUrl?: string;\n /** Runtime-neutral automatic TLS intent; the selected runtime owns concrete ingress configuration. */\n readonly tls?: InfraNetworkingTlsSpec;\n}\n\nexport interface InfraEnvironmentSpec {\n readonly deployment: InfraDeploymentSpec;\n readonly database?: InfraDatabaseSpec;\n readonly objectStorage?: InfraObjectStorageSpec;\n readonly auth?: InfraAuthSpec;\n readonly authz?: InfraAuthzSpec;\n readonly secretStore?: InfraSecretStoreSpec;\n readonly networking?: InfraNetworkingSpec;\n readonly workloads?: readonly InfraWorkloadSpec[];\n}\n\nexport interface InfraManifest {\n readonly environments: Readonly<\n Record<'local', InfraEnvironmentSpec> &\n Partial<Record<Exclude<AppEnvironmentId, 'local'>, InfraEnvironmentSpec>>\n >;\n readonly apis?: ApiDefinitionList;\n readonly modules: readonly string[];\n readonly modulesConfig?: Readonly<Record<string, unknown>>;\n}\n"]}
|
|
@@ -54,6 +54,8 @@ export interface InfraWorkloadVolumeSpec {
|
|
|
54
54
|
readonly id: string;
|
|
55
55
|
readonly mountPath: string;
|
|
56
56
|
readonly sizeGiB: number;
|
|
57
|
+
/** Seed a newly created empty volume from the image contents at mountPath before workload start. */
|
|
58
|
+
readonly seed?: 'image';
|
|
57
59
|
/** Persistence survives down and is retained by default on destroy. */
|
|
58
60
|
readonly retention: 'retain' | 'delete-on-destroy';
|
|
59
61
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"infraWorkload.d.ts","sourceRoot":"","sources":["../../src/types/infraWorkload.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"infraWorkload.d.ts","sourceRoot":"","sources":["../../src/types/infraWorkload.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"infraWorkload.js","sourceRoot":"","sources":["../../src/types/infraWorkload.ts"],"names":[],"mappings":"","sourcesContent":["import type { InfraControlPlaneCredentialRef, InfraSecretReference } from './infraSecrets';\n\nexport interface InfraWorkloadArtifact {\n readonly kind: 'image';\n /** Prebuilt image, optionally pinned by digest. No registry/build provider requirement. */\n readonly image: string;\n}\n\nexport type InfraWorkloadScalarValue =\n | { readonly kind: 'literal'; readonly value: string }\n | { readonly kind: 'secret'; readonly reference: InfraSecretReference }\n | {\n readonly kind: 'credential';\n readonly reference: InfraControlPlaneCredentialRef;\n readonly key: string;\n }\n | { readonly kind: 'output'; readonly resourceId: string; readonly output: string };\n\nexport type InfraWorkloadValue =\n | InfraWorkloadScalarValue\n | {\n readonly kind: 'template';\n /** Ordered scalar segments materialized into one value only at the runtime boundary. */\n readonly segments: readonly InfraWorkloadScalarValue[];\n };\n\nexport interface InfraWorkloadPort {\n readonly name: string;\n readonly port: number;\n readonly protocol?: 'tcp' | 'udp';\n /** Exact external listener port requested for a public single-replica workload. */\n readonly publishedPort?: number;\n}\n\nexport type InfraWorkloadHealthSpec = {\n readonly intervalSeconds?: number;\n readonly timeoutSeconds?: number;\n readonly failureThreshold?: number;\n} & (\n | { readonly kind: 'http'; readonly port: number; readonly path: string }\n | { readonly kind: 'tcp'; readonly port: number }\n | { readonly kind: 'command'; readonly command: readonly string[] }\n);\n\nexport interface InfraWorkloadResourceSpec {\n readonly cpuMillis?: number;\n readonly memoryMiB?: number;\n}\n\nexport interface InfraWorkloadVolumeSpec {\n readonly id: string;\n readonly mountPath: string;\n readonly sizeGiB: number;\n /** Persistence survives down and is retained by default on destroy. */\n readonly retention: 'retain' | 'delete-on-destroy';\n}\n\n/** Portable config/policy files; secret values are materialized by the runtime. */\nexport interface InfraWorkloadFileSpec {\n readonly path: string;\n readonly content: InfraWorkloadValue;\n}\n\nexport interface InfraWorkloadSpec {\n readonly id: string;\n readonly artifact: InfraWorkloadArtifact;\n readonly command?: readonly string[];\n readonly args?: readonly string[];\n readonly ports?: readonly InfraWorkloadPort[];\n readonly environment?: Readonly<Record<string, InfraWorkloadValue>>;\n readonly files?: readonly InfraWorkloadFileSpec[];\n readonly health?: InfraWorkloadHealthSpec;\n readonly resources?: InfraWorkloadResourceSpec;\n readonly persistence?: readonly InfraWorkloadVolumeSpec[];\n readonly exposure?: 'internal' | 'public';\n readonly replicas?: number;\n /** IDs in the composed desired-state graph; the orchestrator validates missing/cyclic edges. */\n readonly dependsOn?: readonly string[];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"infraWorkload.js","sourceRoot":"","sources":["../../src/types/infraWorkload.ts"],"names":[],"mappings":"","sourcesContent":["import type { InfraControlPlaneCredentialRef, InfraSecretReference } from './infraSecrets';\n\nexport interface InfraWorkloadArtifact {\n readonly kind: 'image';\n /** Prebuilt image, optionally pinned by digest. No registry/build provider requirement. */\n readonly image: string;\n}\n\nexport type InfraWorkloadScalarValue =\n | { readonly kind: 'literal'; readonly value: string }\n | { readonly kind: 'secret'; readonly reference: InfraSecretReference }\n | {\n readonly kind: 'credential';\n readonly reference: InfraControlPlaneCredentialRef;\n readonly key: string;\n }\n | { readonly kind: 'output'; readonly resourceId: string; readonly output: string };\n\nexport type InfraWorkloadValue =\n | InfraWorkloadScalarValue\n | {\n readonly kind: 'template';\n /** Ordered scalar segments materialized into one value only at the runtime boundary. */\n readonly segments: readonly InfraWorkloadScalarValue[];\n };\n\nexport interface InfraWorkloadPort {\n readonly name: string;\n readonly port: number;\n readonly protocol?: 'tcp' | 'udp';\n /** Exact external listener port requested for a public single-replica workload. */\n readonly publishedPort?: number;\n}\n\nexport type InfraWorkloadHealthSpec = {\n readonly intervalSeconds?: number;\n readonly timeoutSeconds?: number;\n readonly failureThreshold?: number;\n} & (\n | { readonly kind: 'http'; readonly port: number; readonly path: string }\n | { readonly kind: 'tcp'; readonly port: number }\n | { readonly kind: 'command'; readonly command: readonly string[] }\n);\n\nexport interface InfraWorkloadResourceSpec {\n readonly cpuMillis?: number;\n readonly memoryMiB?: number;\n}\n\nexport interface InfraWorkloadVolumeSpec {\n readonly id: string;\n readonly mountPath: string;\n readonly sizeGiB: number;\n /** Seed a newly created empty volume from the image contents at mountPath before workload start. */\n readonly seed?: 'image';\n /** Persistence survives down and is retained by default on destroy. */\n readonly retention: 'retain' | 'delete-on-destroy';\n}\n\n/** Portable config/policy files; secret values are materialized by the runtime. */\nexport interface InfraWorkloadFileSpec {\n readonly path: string;\n readonly content: InfraWorkloadValue;\n}\n\nexport interface InfraWorkloadSpec {\n readonly id: string;\n readonly artifact: InfraWorkloadArtifact;\n readonly command?: readonly string[];\n readonly args?: readonly string[];\n readonly ports?: readonly InfraWorkloadPort[];\n readonly environment?: Readonly<Record<string, InfraWorkloadValue>>;\n readonly files?: readonly InfraWorkloadFileSpec[];\n readonly health?: InfraWorkloadHealthSpec;\n readonly resources?: InfraWorkloadResourceSpec;\n readonly persistence?: readonly InfraWorkloadVolumeSpec[];\n readonly exposure?: 'internal' | 'public';\n readonly replicas?: number;\n /** IDs in the composed desired-state graph; the orchestrator validates missing/cyclic edges. */\n readonly dependsOn?: readonly string[];\n}\n"]}
|
package/package.json
CHANGED
|
@@ -14,7 +14,10 @@ import { isInfraWorkloadSpec } from './isInfraWorkloadSpec';
|
|
|
14
14
|
/*** Validate sibling capabilities and their required relationships within one environment. */
|
|
15
15
|
export function isInfraEnvironmentSpec(value: unknown): value is InfraEnvironmentSpec {
|
|
16
16
|
return (
|
|
17
|
-
isEnvironmentShape(value) &&
|
|
17
|
+
isEnvironmentShape(value) &&
|
|
18
|
+
hasServiceDependencies(value) &&
|
|
19
|
+
hasNetworkingRelationships(value) &&
|
|
20
|
+
hasUniquePublishedPorts(value)
|
|
18
21
|
);
|
|
19
22
|
}
|
|
20
23
|
|
|
@@ -49,6 +52,12 @@ function isEnvironmentShape(value: unknown): value is InfraEnvironmentSpec {
|
|
|
49
52
|
domain: infraFields.optionalText,
|
|
50
53
|
publicBaseUrl: (publicBaseUrl) =>
|
|
51
54
|
publicBaseUrl === undefined || isPublicHttpOrigin(publicBaseUrl),
|
|
55
|
+
tls: (tls) =>
|
|
56
|
+
tls === undefined ||
|
|
57
|
+
isInfraShape(tls, {
|
|
58
|
+
mode: (mode) => mode === 'acme-http-01',
|
|
59
|
+
contactEmail: isNonEmptyString,
|
|
60
|
+
}),
|
|
52
61
|
}),
|
|
53
62
|
workloads: (workloads) => workloads === undefined || isWorkloads(workloads),
|
|
54
63
|
} satisfies InfraShape<InfraEnvironmentSpec>);
|
|
@@ -65,6 +74,15 @@ function isPublicHttpOrigin(value: unknown): boolean {
|
|
|
65
74
|
}
|
|
66
75
|
}
|
|
67
76
|
|
|
77
|
+
/*** Automatic TLS requires one matching HTTPS origin and public DNS hostname. */
|
|
78
|
+
function hasNetworkingRelationships(value: InfraEnvironmentSpec): boolean {
|
|
79
|
+
const { networking } = value;
|
|
80
|
+
if (networking?.tls === undefined) return true;
|
|
81
|
+
if (networking.domain === undefined || networking.publicBaseUrl === undefined) return false;
|
|
82
|
+
const url = new URL(networking.publicBaseUrl);
|
|
83
|
+
return url.protocol === 'https:' && url.hostname === networking.domain;
|
|
84
|
+
}
|
|
85
|
+
|
|
68
86
|
/*** Validate portable, unique Cerbos policy files without host paths or traversal. */
|
|
69
87
|
function isPolicyFiles(value: unknown): boolean {
|
|
70
88
|
return (
|
|
@@ -83,12 +83,13 @@ function isFile(value: unknown): boolean {
|
|
|
83
83
|
return isInfraShape(value, { path: isAbsoluteWorkloadPath, content: isInfraWorkloadValue });
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
/*** Persistence has explicit ownership-local identity and
|
|
86
|
+
/*** Persistence has explicit ownership-local identity, optional initialization and retention policy. */
|
|
87
87
|
function isVolume(value: unknown): boolean {
|
|
88
88
|
return isInfraShape(value, {
|
|
89
89
|
id: isNonEmptyString,
|
|
90
90
|
mountPath: isAbsoluteWorkloadPath,
|
|
91
91
|
sizeGiB: infraFields.positiveInteger,
|
|
92
|
+
seed: (seed) => seed === undefined || seed === 'image',
|
|
92
93
|
retention: (retention) => retention === 'retain' || retention === 'delete-on-destroy',
|
|
93
94
|
});
|
|
94
95
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { expect, it } from 'bun:test';
|
|
2
|
+
|
|
3
|
+
import { isInfraWorkloadSpec } from './infra';
|
|
4
|
+
|
|
5
|
+
const workload = {
|
|
6
|
+
id: 'database',
|
|
7
|
+
artifact: { kind: 'image', image: 'example/database:1' },
|
|
8
|
+
persistence: [
|
|
9
|
+
{
|
|
10
|
+
id: 'config',
|
|
11
|
+
mountPath: '/etc/database-custom',
|
|
12
|
+
sizeGiB: 1,
|
|
13
|
+
seed: 'image',
|
|
14
|
+
retention: 'retain',
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
} as const;
|
|
18
|
+
|
|
19
|
+
it('accepts image-seeded persistence initialization', () => {
|
|
20
|
+
expect(isInfraWorkloadSpec(workload)).toBe(true);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('rejects unsupported persistence initialization modes', () => {
|
|
24
|
+
expect(
|
|
25
|
+
isInfraWorkloadSpec({
|
|
26
|
+
...workload,
|
|
27
|
+
persistence: [{ ...workload.persistence[0], seed: 'empty' }],
|
|
28
|
+
}),
|
|
29
|
+
).toBe(false);
|
|
30
|
+
});
|
package/src/infra.test.ts
CHANGED
|
@@ -140,39 +140,6 @@ describe('runtime topology configuration', () => {
|
|
|
140
140
|
});
|
|
141
141
|
});
|
|
142
142
|
|
|
143
|
-
describe('sibling service configuration', () => {
|
|
144
|
-
it('accepts Supabase auth, Cerbos and independent R2 storage', () => {
|
|
145
|
-
expect(isInfraEnvironmentSpec(production)).toBe(true);
|
|
146
|
-
expect(isInfraEnvironmentSpec({ ...production, objectStorage: { provider: 'supabase' } })).toBe(
|
|
147
|
-
true,
|
|
148
|
-
);
|
|
149
|
-
expect(isInfraEnvironmentSpec({ ...local, auth: { provider: 'supabase' } })).toBe(true);
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
it.each([
|
|
153
|
-
{ database: { provider: 'postgres' } },
|
|
154
|
-
{ database: { provider: 'supabase', tier: 'enterprise' } },
|
|
155
|
-
{ objectStorage: { provider: 'auto' } },
|
|
156
|
-
{ objectStorage: { provider: 's3' } },
|
|
157
|
-
{ objectStorage: { provider: 'supabase', buckets: [1] } },
|
|
158
|
-
{ objectStorage: { provider: 'supabase', accountId: 'r2-account' } },
|
|
159
|
-
{ auth: { provider: 'custom' } },
|
|
160
|
-
{ auth: { provider: 'supabase', scope: 'unknown' } },
|
|
161
|
-
{ auth: { provider: 'supabase', authorization: { kind: 'ABAC', engine: 'cerbos' } } },
|
|
162
|
-
{ authz: { provider: 'native', kind: 'RBAC' } },
|
|
163
|
-
{ authz: { engine: 'cerbos', kind: 'ABAC' } },
|
|
164
|
-
{ authz: { provider: 'cerbos', kind: 'unknown' } },
|
|
165
|
-
{ secretStore: { provider: 'unknown' } },
|
|
166
|
-
{ secretStore: { provider: 'supabase-vault' } },
|
|
167
|
-
{ networking: { domain: 'example.ch', cdn: true } },
|
|
168
|
-
{ networking: { publicBaseUrl: 'ftp://api.example.ch' } },
|
|
169
|
-
{ networking: { publicBaseUrl: 'https://api.example.ch/auth/v1' } },
|
|
170
|
-
{ networking: { publicBaseUrl: 'https://api.example.ch/' } },
|
|
171
|
-
])('rejects unsupported service selection: %j', (selection) => {
|
|
172
|
-
expect(isInfraEnvironmentSpec({ ...local, ...selection })).toBe(false);
|
|
173
|
-
});
|
|
174
|
-
});
|
|
175
|
-
|
|
176
143
|
describe('Cerbos policy configuration', () => {
|
|
177
144
|
it('accepts portable policy files', () => {
|
|
178
145
|
expect(
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test';
|
|
2
|
+
|
|
3
|
+
import { type InfraEnvironmentSpec, isInfraEnvironmentSpec } from './infra';
|
|
4
|
+
|
|
5
|
+
const local = {
|
|
6
|
+
deployment: { compute: { provider: 'local' }, runtime: { provider: 'minikube' } },
|
|
7
|
+
} as const satisfies InfraEnvironmentSpec;
|
|
8
|
+
|
|
9
|
+
describe('Infra networking configuration', () => {
|
|
10
|
+
it('accepts matching HTTPS ACME intent', () => {
|
|
11
|
+
expect(
|
|
12
|
+
isInfraEnvironmentSpec({
|
|
13
|
+
...local,
|
|
14
|
+
networking: {
|
|
15
|
+
domain: 'api.example.ch',
|
|
16
|
+
publicBaseUrl: 'https://api.example.ch',
|
|
17
|
+
tls: { mode: 'acme-http-01', contactEmail: 'infra@example.ch' },
|
|
18
|
+
},
|
|
19
|
+
}),
|
|
20
|
+
).toBe(true);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it.each([
|
|
24
|
+
{ domain: 'example.ch', cdn: true },
|
|
25
|
+
{ publicBaseUrl: 'ftp://api.example.ch' },
|
|
26
|
+
{ publicBaseUrl: 'https://api.example.ch/auth/v1' },
|
|
27
|
+
{ publicBaseUrl: 'https://api.example.ch/' },
|
|
28
|
+
{ tls: { mode: 'acme-http-01', contactEmail: 'infra@example.ch' } },
|
|
29
|
+
{
|
|
30
|
+
domain: 'api.example.ch',
|
|
31
|
+
publicBaseUrl: 'http://api.example.ch',
|
|
32
|
+
tls: { mode: 'acme-http-01', contactEmail: 'infra@example.ch' },
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
domain: 'api.example.ch',
|
|
36
|
+
publicBaseUrl: 'https://other.example.ch',
|
|
37
|
+
tls: { mode: 'acme-http-01', contactEmail: 'infra@example.ch' },
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
domain: 'api.example.ch',
|
|
41
|
+
publicBaseUrl: 'https://api.example.ch',
|
|
42
|
+
tls: { mode: 'manual', contactEmail: 'infra@example.ch' },
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
domain: 'api.example.ch',
|
|
46
|
+
publicBaseUrl: 'https://api.example.ch',
|
|
47
|
+
tls: { mode: 'acme-http-01', contactEmail: '' },
|
|
48
|
+
},
|
|
49
|
+
])('rejects malformed networking intent: %j', (networking) => {
|
|
50
|
+
expect(isInfraEnvironmentSpec({ ...local, networking })).toBe(false);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { describe, expect, it } from 'bun:test';
|
|
2
|
+
|
|
3
|
+
import { type InfraEnvironmentSpec, isInfraEnvironmentSpec } from './infra';
|
|
4
|
+
|
|
5
|
+
const local = {
|
|
6
|
+
deployment: { compute: { provider: 'local' }, runtime: { provider: 'minikube' } },
|
|
7
|
+
} as const satisfies InfraEnvironmentSpec;
|
|
8
|
+
const production = {
|
|
9
|
+
deployment: {
|
|
10
|
+
compute: { provider: 'hetzner', location: 'nbg1' },
|
|
11
|
+
runtime: { provider: 'k3s', topology: { servers: 1, agents: 0 } },
|
|
12
|
+
},
|
|
13
|
+
database: { provider: 'supabase' },
|
|
14
|
+
auth: { provider: 'supabase' },
|
|
15
|
+
objectStorage: { provider: 'r2', buckets: ['media'] },
|
|
16
|
+
authz: { provider: 'cerbos', kind: 'ABAC' },
|
|
17
|
+
secretStore: { provider: 'supabase-vault' },
|
|
18
|
+
networking: { domain: 'api.example.ch', publicBaseUrl: 'https://api.example.ch' },
|
|
19
|
+
} as const satisfies InfraEnvironmentSpec;
|
|
20
|
+
|
|
21
|
+
const invalidServiceSelections: Record<string, unknown>[] = [
|
|
22
|
+
{ database: { provider: 'postgres' } },
|
|
23
|
+
{ database: { provider: 'supabase', tier: 'enterprise' } },
|
|
24
|
+
{ objectStorage: { provider: 'auto' } },
|
|
25
|
+
{ objectStorage: { provider: 's3' } },
|
|
26
|
+
{ objectStorage: { provider: 'supabase', buckets: [1] } },
|
|
27
|
+
{ objectStorage: { provider: 'supabase', accountId: 'r2-account' } },
|
|
28
|
+
{ auth: { provider: 'custom' } },
|
|
29
|
+
{ auth: { provider: 'supabase', scope: 'unknown' } },
|
|
30
|
+
{ auth: { provider: 'supabase', authorization: { kind: 'ABAC', engine: 'cerbos' } } },
|
|
31
|
+
{ authz: { provider: 'native', kind: 'RBAC' } },
|
|
32
|
+
{ authz: { engine: 'cerbos', kind: 'ABAC' } },
|
|
33
|
+
{ authz: { provider: 'cerbos', kind: 'unknown' } },
|
|
34
|
+
{ secretStore: { provider: 'unknown' } },
|
|
35
|
+
{ secretStore: { provider: 'supabase-vault' } },
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
describe('sibling service configuration', () => {
|
|
39
|
+
it('accepts Supabase auth, Cerbos and independent R2 storage', () => {
|
|
40
|
+
expect(isInfraEnvironmentSpec(production)).toBe(true);
|
|
41
|
+
expect(isInfraEnvironmentSpec({ ...production, objectStorage: { provider: 'supabase' } })).toBe(
|
|
42
|
+
true,
|
|
43
|
+
);
|
|
44
|
+
expect(isInfraEnvironmentSpec({ ...local, auth: { provider: 'supabase' } })).toBe(true);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it.each(invalidServiceSelections)('rejects unsupported service selection: %j', (selection) => {
|
|
48
|
+
expect(isInfraEnvironmentSpec({ ...local, ...selection })).toBe(false);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -115,11 +115,20 @@ export type InfraSecretStoreSpec = {
|
|
|
115
115
|
[P in InfraProviderFor<'secretStore'>]: { readonly provider: P } & InfraSecretStoreConfigMap[P];
|
|
116
116
|
}[InfraProviderFor<'secretStore'>];
|
|
117
117
|
|
|
118
|
+
export interface InfraNetworkingTlsSpec {
|
|
119
|
+
/** First production slice: runtime-managed ACME using the HTTP-01 challenge. */
|
|
120
|
+
readonly mode: 'acme-http-01';
|
|
121
|
+
/** ACME registration and expiry-notification contact. */
|
|
122
|
+
readonly contactEmail: string;
|
|
123
|
+
}
|
|
124
|
+
|
|
118
125
|
export interface InfraNetworkingSpec {
|
|
119
126
|
/** Public DNS name intent, not automatic DNS/CDN vendor provisioning. */
|
|
120
127
|
readonly domain?: string;
|
|
121
128
|
/** Absolute HTTP(S) origin used by workloads that must know their external URL at startup. */
|
|
122
129
|
readonly publicBaseUrl?: string;
|
|
130
|
+
/** Runtime-neutral automatic TLS intent; the selected runtime owns concrete ingress configuration. */
|
|
131
|
+
readonly tls?: InfraNetworkingTlsSpec;
|
|
123
132
|
}
|
|
124
133
|
|
|
125
134
|
export interface InfraEnvironmentSpec {
|
|
@@ -51,6 +51,8 @@ export interface InfraWorkloadVolumeSpec {
|
|
|
51
51
|
readonly id: string;
|
|
52
52
|
readonly mountPath: string;
|
|
53
53
|
readonly sizeGiB: number;
|
|
54
|
+
/** Seed a newly created empty volume from the image contents at mountPath before workload start. */
|
|
55
|
+
readonly seed?: 'image';
|
|
54
56
|
/** Persistence survives down and is retained by default on destroy. */
|
|
55
57
|
readonly retention: 'retain' | 'delete-on-destroy';
|
|
56
58
|
}
|