@ankhorage/contracts 19.2.2 → 19.3.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 +6 -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/types/infraManifest.d.ts +8 -0
- package/dist/types/infraManifest.d.ts.map +1 -1
- package/dist/types/infraManifest.js.map +1 -1
- package/package.json +1 -1
- package/src/infra/isInfraEnvironmentSpec.ts +19 -1
- package/src/infraNetworking.test.ts +52 -0
- package/src/types/infraManifest.ts +9 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @ankhorage/contracts
|
|
2
2
|
|
|
3
|
+
## 19.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 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.
|
|
8
|
+
|
|
3
9
|
## 19.2.2
|
|
4
10
|
|
|
5
11
|
### 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":"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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) &&\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"]}
|
|
@@ -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":"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,mBAAmB;IAClC,yEAAyE;IACzE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,8FAA8F;IAC9F,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"infraManifest.d.ts","sourceRoot":"","sources":["../../src/types/infraManifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -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"]}
|
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 (
|
|
@@ -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
|
+
});
|
|
@@ -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 {
|