@supacloud/compiler 0.45.1 → 0.46.1
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/DELIVERY.md +20 -0
- package/README.md +16 -12
- package/dist/cli.js +352 -52
- package/dist/config.d.ts +3 -3
- package/dist/delivery-bundle-protocol.d.ts +7 -2
- package/dist/delivery-bundle-worker.js +16 -4
- package/dist/effect-governance.d.ts +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +353 -52
- package/dist/inspect.d.ts +5 -0
- package/dist/migration-app-version.d.ts +1 -1
- package/dist/migration-elysia-version.d.ts +1 -1
- package/dist/source-semantics.d.ts +7 -1
- package/dist/type-safety.d.ts +4 -0
- package/dist/types.d.ts +3 -0
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -807,12 +807,15 @@ function validateGraph(graph, options = false) {
|
|
|
807
807
|
if (typeof options === "object" && options.commandCapabilities) {
|
|
808
808
|
const hostCaps = options.commandCapabilities;
|
|
809
809
|
const rpcCaps = command.rpc && Object.hasOwn(hostCaps.rpc ?? {}, command.rpc) ? hostCaps.rpc?.[command.rpc] : undefined;
|
|
810
|
-
if (hostCaps.requirePersistentAdapters && (command.rpc !== undefined && (!rpcCaps?.boundary || rpcCaps.audit !== true || rpcCaps.idempotency !== true) || hostCaps.permission !== true || !command.permission || !command.audit || command.idempotency !== "required" || command.rpc !== undefined && rpcCaps?.boundary === "database" && (rpcCaps.transaction !== true || command.transaction !== "required") || command.rpc === undefined && (hostCaps.audit !== true || hostCaps.idempotency !== true || hostCaps.transaction !== true || command.transaction !== "required"))) {
|
|
810
|
+
if (hostCaps.requirePersistentAdapters && (command.rpc !== undefined && (!rpcCaps?.boundary || rpcCaps.audit !== true || rpcCaps.idempotency !== true) || hostCaps.permission !== true || !command.permission || !command.audit || command.idempotency !== "required" || command.rpc !== undefined && rpcCaps?.boundary === "database" && (rpcCaps.transaction !== true || command.transaction !== "required") || command.rpc === undefined && (hostCaps.audit !== true || hostCaps.idempotency !== true || hostCaps.transaction !== true || command.transaction !== "required") || command.rpc !== undefined && rpcCaps?.boundary === "external" && rpcCaps.reconcile !== true)) {
|
|
811
811
|
error("command-persistence-required", `Command ${command.name} requires an explicit persistent adapter, permission, audit and idempotency policy.`, module.file, module.line, "Register a named database/external adapter, enable permission checks and declare permission, audit and required idempotency on the command.");
|
|
812
812
|
}
|
|
813
813
|
if (rpcCaps?.boundary === "external" && (command.transaction === "required" || rpcCaps.transaction === true)) {
|
|
814
814
|
error("command-external-transaction", `Command ${command.name} calls an external service; use durable intent and reconciliation, not transaction: 'required'.`, module.file, module.line, "Use transaction: 'none' with createExternalCommand; recover with read-only reconciliation. Do not claim a database transaction covers a remote request.");
|
|
815
815
|
}
|
|
816
|
+
if (rpcCaps?.boundary === "external" && rpcCaps.reconcile !== true) {
|
|
817
|
+
error("command-reconcile-required", `Command ${command.name} uses an external adapter without a receipt reconciliation capability.`, module.file, module.line, "Declare reconcile: true only when the adapter can look up the same idempotency key and resolve unknown outcomes without redispatching.");
|
|
818
|
+
}
|
|
816
819
|
const caps = command.rpc ? {
|
|
817
820
|
permission: hostCaps.permission,
|
|
818
821
|
audit: rpcCaps?.audit === true,
|
|
@@ -1229,6 +1232,7 @@ var init_validate = __esm(() => {
|
|
|
1229
1232
|
"invalid-job-timeout": { code: "SC4015", docsUrl: "https://supacloud.dev/errors/SC4015" },
|
|
1230
1233
|
"invalid-job-attempts": { code: "SC4016", docsUrl: "https://supacloud.dev/errors/SC4016" },
|
|
1231
1234
|
"invalid-job-idempotency": { code: "SC4017", docsUrl: "https://supacloud.dev/errors/SC4017" },
|
|
1235
|
+
"job-retry-idempotency-required": { code: "SC4027", docsUrl: "https://supacloud.dev/errors/SC4027" },
|
|
1232
1236
|
"invalid-job-mode": { code: "SC4018", docsUrl: "https://supacloud.dev/errors/SC4018" },
|
|
1233
1237
|
"invalid-job-schema": { code: "SC4019", docsUrl: "https://supacloud.dev/errors/SC4019" },
|
|
1234
1238
|
"command-persistence-required": { code: "SC4020", docsUrl: "https://supacloud.dev/errors/SC4020" },
|
|
@@ -1238,6 +1242,7 @@ var init_validate = __esm(() => {
|
|
|
1238
1242
|
"command-idempotency-unsupported": { code: "SC4024", docsUrl: "https://supacloud.dev/errors/SC4024" },
|
|
1239
1243
|
"command-transaction-rpc-only": { code: "SC4025", docsUrl: "https://supacloud.dev/errors/SC4025" },
|
|
1240
1244
|
"command-transaction-unsupported": { code: "SC4026", docsUrl: "https://supacloud.dev/errors/SC4026" },
|
|
1245
|
+
"command-reconcile-required": { code: "SC4028", docsUrl: "https://supacloud.dev/errors/SC4028" },
|
|
1241
1246
|
"invalid-route-contract": { code: "SC3020", docsUrl: "https://supacloud.dev/errors/SC3020" },
|
|
1242
1247
|
"route-contract-required": { code: "SC3021", docsUrl: "https://supacloud.dev/errors/SC3021" },
|
|
1243
1248
|
"route-contract-unverified": { code: "SC3022", docsUrl: "https://supacloud.dev/errors/SC3022" },
|
|
@@ -14557,6 +14562,11 @@ function parseDeliveryOptions(value) {
|
|
|
14557
14562
|
if (value.targets?.some((target) => target.compute && target.isolation === "shared")) {
|
|
14558
14563
|
throw new DeliveryConfigurationError;
|
|
14559
14564
|
}
|
|
14565
|
+
for (const target of value.targets ?? []) {
|
|
14566
|
+
const invalidShape = target.kind === "function" ? target.function === undefined || target.modules !== undefined || target.compute !== undefined : target.modules === undefined || target.function !== undefined;
|
|
14567
|
+
if (invalidShape)
|
|
14568
|
+
throw new DeliveryConfigurationError;
|
|
14569
|
+
}
|
|
14560
14570
|
const migrations = value.build?.migrations ?? [];
|
|
14561
14571
|
try {
|
|
14562
14572
|
validateWorkerExecution(value.execution?.groups ?? []);
|
|
@@ -14573,7 +14583,7 @@ function parseDeliveryPlanResult(value) {
|
|
|
14573
14583
|
throw new Error("Invalid delivery plan result.");
|
|
14574
14584
|
return value;
|
|
14575
14585
|
}
|
|
14576
|
-
var objectOptions, reference, references, kind, isolation, DeliveryFilePathSchema, DeliveryOptionsSchema, DeliveryDiagnosticSchema, routeSchema, jobSchema, DeliveryTargetSchema, DeliveryPlanSchema, DeliveryPlanResultSchema, DeliveryConfigurationError;
|
|
14586
|
+
var objectOptions, reference, references, kind, isolation, DeliveryFilePathSchema, functionTarget, DeliveryOptionsSchema, DeliveryDiagnosticSchema, routeSchema, jobSchema, DeliveryTargetSchema, DeliveryPlanSchema, DeliveryPlanResultSchema, DeliveryConfigurationError;
|
|
14577
14587
|
var init_delivery_schema = __esm(() => {
|
|
14578
14588
|
init_build();
|
|
14579
14589
|
init_value2();
|
|
@@ -14581,22 +14591,28 @@ var init_delivery_schema = __esm(() => {
|
|
|
14581
14591
|
objectOptions = { additionalProperties: false };
|
|
14582
14592
|
reference = String2({ minLength: 1, maxLength: 128, pattern: "^[A-Za-z][A-Za-z0-9_.:/-]*$" });
|
|
14583
14593
|
references = _Array_(reference, { uniqueItems: true });
|
|
14584
|
-
kind = Union([Literal("api"), Literal("jobs"), Literal("webhook")]);
|
|
14594
|
+
kind = Union([Literal("api"), Literal("jobs"), Literal("webhook"), Literal("function")]);
|
|
14585
14595
|
isolation = Union([Literal("shared"), Literal("process")]);
|
|
14586
14596
|
DeliveryFilePathSchema = String2({
|
|
14587
14597
|
maxLength: 512,
|
|
14588
14598
|
pattern: "^(?:[A-Za-z0-9_-][A-Za-z0-9_.-]*/)*[A-Za-z0-9_-][A-Za-z0-9_.-]*$"
|
|
14589
14599
|
});
|
|
14600
|
+
functionTarget = _Object_({
|
|
14601
|
+
slug: String2({ pattern: "^[a-z][a-z0-9-]{0,62}$" }),
|
|
14602
|
+
entrypoint: DeliveryFilePathSchema,
|
|
14603
|
+
verifyJwt: Boolean2()
|
|
14604
|
+
}, objectOptions);
|
|
14590
14605
|
DeliveryOptionsSchema = _Object_({
|
|
14591
14606
|
version: Literal(1),
|
|
14592
14607
|
execution: Optional(WorkerExecutionSchema),
|
|
14593
14608
|
targets: Optional(_Array_(_Object_({
|
|
14594
14609
|
name: String2({ pattern: "^[a-z][a-z0-9-]{0,62}$" }),
|
|
14595
14610
|
kind,
|
|
14596
|
-
modules: _Array_(reference, { minItems: 1, uniqueItems: true }),
|
|
14611
|
+
modules: Optional(_Array_(reference, { minItems: 1, uniqueItems: true })),
|
|
14597
14612
|
isolation: Optional(isolation),
|
|
14598
14613
|
capabilities: Optional(references),
|
|
14599
|
-
compute: Optional(ComputeResourcesSchema)
|
|
14614
|
+
compute: Optional(ComputeResourcesSchema),
|
|
14615
|
+
function: Optional(functionTarget)
|
|
14600
14616
|
}, objectOptions))),
|
|
14601
14617
|
runtime: Optional(_Object_({
|
|
14602
14618
|
processIsolation: Boolean2(),
|
|
@@ -14674,6 +14690,7 @@ var init_delivery_schema = __esm(() => {
|
|
|
14674
14690
|
routes: _Array_(routeSchema),
|
|
14675
14691
|
jobs: _Array_(jobSchema),
|
|
14676
14692
|
externalTokens: _Array_(String2()),
|
|
14693
|
+
function: Optional(functionTarget),
|
|
14677
14694
|
requirements: _Object_({
|
|
14678
14695
|
processIsolation: Boolean2(),
|
|
14679
14696
|
durableQueue: Boolean2(),
|
|
@@ -15059,7 +15076,7 @@ function createContextPack(graph, subject) {
|
|
|
15059
15076
|
}
|
|
15060
15077
|
}
|
|
15061
15078
|
}
|
|
15062
|
-
const modules = graph.modules.filter((module) => selected.has(module.name));
|
|
15079
|
+
const modules = graph.modules.filter((module) => selected.has(module.name)).map(sanitizeContextModule);
|
|
15063
15080
|
const queryDocuments = graph.graphql?.documents.filter((file) => modules.some((module) => {
|
|
15064
15081
|
const path = relative6(dirname5(module.file), file);
|
|
15065
15082
|
return path !== ".." && !path.startsWith(`..${sep6}`);
|
|
@@ -15101,7 +15118,12 @@ function createContextPack(graph, subject) {
|
|
|
15101
15118
|
singleResult: "async-await",
|
|
15102
15119
|
eventComposition: "rxjs",
|
|
15103
15120
|
angularHost: "@supacloud/app/angular",
|
|
15104
|
-
cancellation: "explicit-owner-signal"
|
|
15121
|
+
cancellation: "explicit-owner-signal",
|
|
15122
|
+
readTransport: "postgrest-supabase-js",
|
|
15123
|
+
writeTransport: "command-rpc",
|
|
15124
|
+
writeRetry: "disabled",
|
|
15125
|
+
externalOutcome: "receipt-reconcile",
|
|
15126
|
+
databaseSource: "drizzle-append-only"
|
|
15105
15127
|
},
|
|
15106
15128
|
relatedModules: {
|
|
15107
15129
|
imports: subjectModule.imports.filter((name) => selected.has(name)),
|
|
@@ -15109,6 +15131,44 @@ function createContextPack(graph, subject) {
|
|
|
15109
15131
|
}
|
|
15110
15132
|
};
|
|
15111
15133
|
}
|
|
15134
|
+
function sanitizeContextModule(module) {
|
|
15135
|
+
const sanitizeAspect = (aspect) => ({
|
|
15136
|
+
...aspect,
|
|
15137
|
+
expression: "[omitted]"
|
|
15138
|
+
});
|
|
15139
|
+
return {
|
|
15140
|
+
...module,
|
|
15141
|
+
providers: module.providers.map((provider) => ({
|
|
15142
|
+
...provider,
|
|
15143
|
+
...provider.useValueExpr === undefined ? {} : { useValueExpr: "[omitted]" },
|
|
15144
|
+
...provider.useFactoryName === undefined ? {} : { useFactoryName: "[omitted]" },
|
|
15145
|
+
...provider.functionalInjects === undefined ? {} : {
|
|
15146
|
+
functionalInjects: provider.functionalInjects.map((inject) => ({ ...inject, expression: "[omitted]" }))
|
|
15147
|
+
}
|
|
15148
|
+
})),
|
|
15149
|
+
...module.aspects === undefined ? {} : { aspects: module.aspects.map(sanitizeAspect) },
|
|
15150
|
+
controllers: module.controllers.map((controller) => ({
|
|
15151
|
+
...controller,
|
|
15152
|
+
...controller.functionalInjects === undefined ? {} : {
|
|
15153
|
+
functionalInjects: controller.functionalInjects.map((inject) => ({ ...inject, expression: "[omitted]" }))
|
|
15154
|
+
},
|
|
15155
|
+
routes: controller.routes.map((route) => ({
|
|
15156
|
+
...route,
|
|
15157
|
+
...route.aspects === undefined ? {} : { aspects: route.aspects.map(sanitizeAspect) }
|
|
15158
|
+
}))
|
|
15159
|
+
})),
|
|
15160
|
+
commands: module.commands.map((command) => ({
|
|
15161
|
+
...command,
|
|
15162
|
+
...command.aspects === undefined ? {} : { aspects: command.aspects.map(sanitizeAspect) }
|
|
15163
|
+
})),
|
|
15164
|
+
...module.jobs === undefined ? {} : {
|
|
15165
|
+
jobs: module.jobs.map((job) => ({
|
|
15166
|
+
...job,
|
|
15167
|
+
...job.aspects === undefined ? {} : { aspects: job.aspects.map(sanitizeAspect) }
|
|
15168
|
+
}))
|
|
15169
|
+
}
|
|
15170
|
+
};
|
|
15171
|
+
}
|
|
15112
15172
|
function resolveContextModule(graph, subject) {
|
|
15113
15173
|
const exact = graph.modules.find((module) => module.name === subject);
|
|
15114
15174
|
if (exact)
|
|
@@ -16425,8 +16485,172 @@ var init_deployment_evidence = __esm(() => {
|
|
|
16425
16485
|
}, closed8);
|
|
16426
16486
|
});
|
|
16427
16487
|
|
|
16488
|
+
// node_modules/@supacloud/delivery/src/delivery-tuple.ts
|
|
16489
|
+
var sha2563, commit, isoDate2, DELIVERY_TUPLE_SCHEMA = "supacloud.fa-delivery-tuple.v1", FaDeliveryTupleSchema;
|
|
16490
|
+
var init_delivery_tuple = __esm(() => {
|
|
16491
|
+
init_build();
|
|
16492
|
+
init_value2();
|
|
16493
|
+
sha2563 = String2({ pattern: "^[a-f0-9]{64}$" });
|
|
16494
|
+
commit = String2({ pattern: "^(?:[a-f0-9]{40}|[a-f0-9]{64})$" });
|
|
16495
|
+
isoDate2 = String2({ minLength: 20, maxLength: 40 });
|
|
16496
|
+
FaDeliveryTupleSchema = _Object_({
|
|
16497
|
+
schema: Literal(DELIVERY_TUPLE_SCHEMA),
|
|
16498
|
+
customer: Literal("xigu-fa"),
|
|
16499
|
+
fa_commit: commit,
|
|
16500
|
+
cli: _Object_({
|
|
16501
|
+
version: String2({ pattern: "^\\d+\\.\\d+\\.\\d+$" })
|
|
16502
|
+
}, { additionalProperties: false }),
|
|
16503
|
+
platform_commit: commit,
|
|
16504
|
+
edge_runtime: _Object_({
|
|
16505
|
+
version: String2({ minLength: 1, maxLength: 128 }),
|
|
16506
|
+
artifact_sha256: sha2563
|
|
16507
|
+
}, { additionalProperties: false }),
|
|
16508
|
+
compatibility_window: _Object_({
|
|
16509
|
+
contract_schema: String2({ minLength: 1, maxLength: 128 }),
|
|
16510
|
+
starts_at: isoDate2,
|
|
16511
|
+
ends_at: isoDate2,
|
|
16512
|
+
old_client_supported: Boolean2(),
|
|
16513
|
+
partial_deployment_supported: Boolean2()
|
|
16514
|
+
}, { additionalProperties: false })
|
|
16515
|
+
}, { additionalProperties: false });
|
|
16516
|
+
});
|
|
16517
|
+
|
|
16518
|
+
// node_modules/@supacloud/delivery/src/contract-matrix.ts
|
|
16519
|
+
var closed9, sha2564, generation, versions, CONTRACT_MATRIX_SCHEMA = "supacloud.consumer-contract-matrix.v1", FA_CONTRACT_SCENARIOS, ConsumerContractMatrixSchema;
|
|
16520
|
+
var init_contract_matrix = __esm(() => {
|
|
16521
|
+
init_build();
|
|
16522
|
+
init_value2();
|
|
16523
|
+
closed9 = { additionalProperties: false };
|
|
16524
|
+
sha2564 = String2({ pattern: "^[a-f0-9]{64}$" });
|
|
16525
|
+
generation = Union([Literal("old"), Literal("new")]);
|
|
16526
|
+
versions = _Object_({ old: sha2564, new: sha2564 }, closed9);
|
|
16527
|
+
FA_CONTRACT_SCENARIOS = [
|
|
16528
|
+
"missing-display-field",
|
|
16529
|
+
"missing-authority-field",
|
|
16530
|
+
"added-field",
|
|
16531
|
+
"legacy-envelope",
|
|
16532
|
+
"lost-write-response",
|
|
16533
|
+
"downgrade"
|
|
16534
|
+
];
|
|
16535
|
+
ConsumerContractMatrixSchema = _Object_({
|
|
16536
|
+
schema: Literal(CONTRACT_MATRIX_SCHEMA),
|
|
16537
|
+
customer: Literal("xigu-fa"),
|
|
16538
|
+
baseline_tuple_sha256: sha2564,
|
|
16539
|
+
candidate_tuple_sha256: sha2564,
|
|
16540
|
+
artifacts: _Object_({ frontend: versions, functions: versions, database: versions }, closed9),
|
|
16541
|
+
cases: _Array_(_Object_({
|
|
16542
|
+
frontend: generation,
|
|
16543
|
+
functions: generation,
|
|
16544
|
+
database: generation,
|
|
16545
|
+
scenarios: _Array_(_Object_({
|
|
16546
|
+
name: Enum(FA_CONTRACT_SCENARIOS),
|
|
16547
|
+
expected: Union([Literal("compatible"), Literal("blocked-safely")])
|
|
16548
|
+
}, closed9), { minItems: FA_CONTRACT_SCENARIOS.length, maxItems: FA_CONTRACT_SCENARIOS.length })
|
|
16549
|
+
}, closed9), { minItems: 8, maxItems: 8 })
|
|
16550
|
+
}, closed9);
|
|
16551
|
+
});
|
|
16552
|
+
|
|
16553
|
+
// node_modules/@supacloud/delivery/src/fa-stability.ts
|
|
16554
|
+
var closed10, hash3, label, timestamp2, count2, environment2, FA_REQUIRED_ACCEPTANCE, FA_BUSINESS_OPERATIONS, operation, proof, FaBusinessObservationSchema, FaServiceObjectivesSchema, FaStabilityEvidenceSchema;
|
|
16555
|
+
var init_fa_stability = __esm(() => {
|
|
16556
|
+
init_build();
|
|
16557
|
+
init_value2();
|
|
16558
|
+
init_delivery_files();
|
|
16559
|
+
init_contract_matrix();
|
|
16560
|
+
init_delivery_tuple();
|
|
16561
|
+
closed10 = { additionalProperties: false };
|
|
16562
|
+
hash3 = String2({ pattern: "^[a-f0-9]{64}$" });
|
|
16563
|
+
label = String2({ minLength: 1, maxLength: 256, pattern: "\\S" });
|
|
16564
|
+
timestamp2 = String2({ minLength: 24, maxLength: 24 });
|
|
16565
|
+
count2 = Integer({ minimum: 0, maximum: Number.MAX_SAFE_INTEGER });
|
|
16566
|
+
environment2 = Union([Literal("test"), Literal("production")]);
|
|
16567
|
+
FA_REQUIRED_ACCEPTANCE = {
|
|
16568
|
+
login: "real-browser",
|
|
16569
|
+
permissions: "real-http",
|
|
16570
|
+
upload: "real-http",
|
|
16571
|
+
"async-task": "real-worker",
|
|
16572
|
+
deploy: "real-http",
|
|
16573
|
+
"database-migration": "real-database",
|
|
16574
|
+
schedule: "real-worker",
|
|
16575
|
+
rollback: "real-drill",
|
|
16576
|
+
"error-policy": "real-http",
|
|
16577
|
+
"alert-delivery": "real-drill"
|
|
16578
|
+
};
|
|
16579
|
+
FA_BUSINESS_OPERATIONS = ["login", "permissions", "upload", "async-task", "report", "deploy"];
|
|
16580
|
+
operation = Enum(FA_BUSINESS_OPERATIONS);
|
|
16581
|
+
proof = _Object_({
|
|
16582
|
+
path: String2({ pattern: "^[A-Za-z0-9_-][A-Za-z0-9_./-]{0,255}$" }),
|
|
16583
|
+
sha256: hash3
|
|
16584
|
+
}, closed10);
|
|
16585
|
+
FaBusinessObservationSchema = _Object_({
|
|
16586
|
+
id: String2({ pattern: "^[A-Za-z0-9_-]{1,128}$" }),
|
|
16587
|
+
tuple_sha256: hash3,
|
|
16588
|
+
operation,
|
|
16589
|
+
started_at: timestamp2,
|
|
16590
|
+
finished_at: timestamp2,
|
|
16591
|
+
outcome: Enum(["success", "failure", "timeout", "unknown"]),
|
|
16592
|
+
attempts: Integer({ minimum: 1, maximum: 1000 }),
|
|
16593
|
+
rollbacks: count2
|
|
16594
|
+
}, closed10);
|
|
16595
|
+
FaServiceObjectivesSchema = _Object_({
|
|
16596
|
+
status: Literal("approved"),
|
|
16597
|
+
owner: label,
|
|
16598
|
+
approval_reference: label,
|
|
16599
|
+
approved_at: timestamp2,
|
|
16600
|
+
project_ref: String2({ pattern: "^[a-z0-9-]{1,20}$" }),
|
|
16601
|
+
environment: environment2,
|
|
16602
|
+
alert_route: label,
|
|
16603
|
+
window_hours: Number2({ exclusiveMinimum: 0, maximum: 8760 }),
|
|
16604
|
+
max_evidence_age_hours: Number2({ exclusiveMinimum: 0, maximum: 168 }),
|
|
16605
|
+
operations: _Array_(_Object_({
|
|
16606
|
+
operation,
|
|
16607
|
+
minimum_samples: Integer({ minimum: 1, maximum: Number.MAX_SAFE_INTEGER }),
|
|
16608
|
+
availability_percent: Number2({ exclusiveMinimum: 0, maximum: 100 }),
|
|
16609
|
+
p95_ms: Number2({ exclusiveMinimum: 0, maximum: Number.MAX_SAFE_INTEGER })
|
|
16610
|
+
}, closed10), { minItems: FA_BUSINESS_OPERATIONS.length, maxItems: FA_BUSINESS_OPERATIONS.length })
|
|
16611
|
+
}, closed10);
|
|
16612
|
+
FaStabilityEvidenceSchema = _Object_({
|
|
16613
|
+
schema: Literal("supacloud.fa-stability-evidence.v1"),
|
|
16614
|
+
environment: environment2,
|
|
16615
|
+
project_ref: String2({ pattern: "^[a-z0-9-]{1,20}$" }),
|
|
16616
|
+
tuple_sha256: hash3,
|
|
16617
|
+
matrix_sha256: hash3,
|
|
16618
|
+
objectives_sha256: hash3,
|
|
16619
|
+
recorded_at: timestamp2,
|
|
16620
|
+
window_start: timestamp2,
|
|
16621
|
+
window_end: timestamp2,
|
|
16622
|
+
reviewed_by: label,
|
|
16623
|
+
review_reference: label,
|
|
16624
|
+
acceptance: _Array_(_Object_({
|
|
16625
|
+
id: Enum(Object.keys(FA_REQUIRED_ACCEPTANCE)),
|
|
16626
|
+
execution: Enum([
|
|
16627
|
+
"real-browser",
|
|
16628
|
+
"real-http",
|
|
16629
|
+
"real-worker",
|
|
16630
|
+
"real-database",
|
|
16631
|
+
"real-drill",
|
|
16632
|
+
"local-fake"
|
|
16633
|
+
]),
|
|
16634
|
+
passed: Boolean2(),
|
|
16635
|
+
measured_at: timestamp2,
|
|
16636
|
+
proof
|
|
16637
|
+
}, closed10), { minItems: 10, maxItems: 10 }),
|
|
16638
|
+
matrix: _Array_(_Object_({
|
|
16639
|
+
combination: label,
|
|
16640
|
+
scenario: label,
|
|
16641
|
+
outcome: Union([Literal("compatible"), Literal("blocked-safely")]),
|
|
16642
|
+
execution: Union([Literal("real-http-and-database"), Literal("local-fake")]),
|
|
16643
|
+
passed: Boolean2(),
|
|
16644
|
+
measured_at: timestamp2,
|
|
16645
|
+
proof
|
|
16646
|
+
}, closed10), { minItems: 48, maxItems: 48 }),
|
|
16647
|
+
observation: proof,
|
|
16648
|
+
alert: _Object_({ route: label, acknowledged_by: label, delivered_at: timestamp2 }, closed10)
|
|
16649
|
+
}, closed10);
|
|
16650
|
+
});
|
|
16651
|
+
|
|
16428
16652
|
// node_modules/@supacloud/delivery/src/application-promotion.ts
|
|
16429
|
-
var
|
|
16653
|
+
var closed11, projectRef2, sha2565, nullableActivation2, nullableDigest, observation, blocker, ApplicationPromotionPlanSchema;
|
|
16430
16654
|
var init_application_promotion = __esm(() => {
|
|
16431
16655
|
init_build();
|
|
16432
16656
|
init_value2();
|
|
@@ -16434,11 +16658,11 @@ var init_application_promotion = __esm(() => {
|
|
|
16434
16658
|
init_application_activation();
|
|
16435
16659
|
init_application_configuration();
|
|
16436
16660
|
init_application_release();
|
|
16437
|
-
|
|
16661
|
+
closed11 = { additionalProperties: false };
|
|
16438
16662
|
projectRef2 = String2({ pattern: "^[a-z0-9-]{1,20}$" });
|
|
16439
|
-
|
|
16663
|
+
sha2565 = ApplicationReleaseIdSchema;
|
|
16440
16664
|
nullableActivation2 = Union([ApplicationActivationIdSchema, Null()]);
|
|
16441
|
-
nullableDigest = Union([
|
|
16665
|
+
nullableDigest = Union([sha2565, Null()]);
|
|
16442
16666
|
observation = {
|
|
16443
16667
|
activation_id: nullableActivation2,
|
|
16444
16668
|
receipt_confirmed: Boolean2(),
|
|
@@ -16464,33 +16688,33 @@ var init_application_promotion = __esm(() => {
|
|
|
16464
16688
|
project_ref: projectRef2,
|
|
16465
16689
|
application_id: ApplicationIdSchema,
|
|
16466
16690
|
environment_id: ApplicationIdSchema,
|
|
16467
|
-
manifest_sha256:
|
|
16468
|
-
plan_sha256:
|
|
16691
|
+
manifest_sha256: sha2565,
|
|
16692
|
+
plan_sha256: sha2565,
|
|
16469
16693
|
source: _Object_({
|
|
16470
16694
|
project_ref: projectRef2,
|
|
16471
16695
|
environment_id: ApplicationIdSchema,
|
|
16472
|
-
release_id:
|
|
16696
|
+
release_id: sha2565,
|
|
16473
16697
|
...observation
|
|
16474
|
-
},
|
|
16698
|
+
}, closed11),
|
|
16475
16699
|
target: _Object_({
|
|
16476
|
-
candidate_release_id:
|
|
16477
|
-
current_release_id: Union([
|
|
16700
|
+
candidate_release_id: sha2565,
|
|
16701
|
+
current_release_id: Union([sha2565, Null()]),
|
|
16478
16702
|
artifact_action: Union([Literal("materialize"), Literal("reuse")]),
|
|
16479
16703
|
configuration_id: Union([ApplicationConfigurationIdSchema, Null()]),
|
|
16480
16704
|
configuration: Union([ApplicationConfigurationViewSchema, Null()]),
|
|
16481
16705
|
...observation
|
|
16482
|
-
},
|
|
16706
|
+
}, closed11),
|
|
16483
16707
|
migrations: _Object_({
|
|
16484
|
-
ledger_digest:
|
|
16708
|
+
ledger_digest: sha2565,
|
|
16485
16709
|
ledger_compatible: Boolean2(),
|
|
16486
16710
|
project_migrations_applied: Boolean2(),
|
|
16487
16711
|
pending_versions: _Array_(String2({ pattern: "^\\d{1,20}$" }), { maxItems: 4096, uniqueItems: true }),
|
|
16488
16712
|
operator_provisioning_required: Boolean2()
|
|
16489
|
-
},
|
|
16713
|
+
}, closed11),
|
|
16490
16714
|
backup: _Object_({
|
|
16491
16715
|
required: Boolean2(),
|
|
16492
16716
|
confirmed: Literal(false)
|
|
16493
|
-
},
|
|
16717
|
+
}, closed11),
|
|
16494
16718
|
action: Union([Literal("promote"), Literal("no-op"), Literal("blocked")]),
|
|
16495
16719
|
blockers: _Array_(Enum([...blocker]), {
|
|
16496
16720
|
maxItems: blocker.length,
|
|
@@ -16499,7 +16723,7 @@ var init_application_promotion = __esm(() => {
|
|
|
16499
16723
|
steps: _Array_(String2({ minLength: 1, maxLength: 64 }), { maxItems: 8, uniqueItems: true }),
|
|
16500
16724
|
execution_performed: Literal(false),
|
|
16501
16725
|
data_recovery: Literal("separate-required")
|
|
16502
|
-
},
|
|
16726
|
+
}, closed11);
|
|
16503
16727
|
});
|
|
16504
16728
|
|
|
16505
16729
|
// node_modules/@supacloud/delivery/src/application-runtime-identity.ts
|
|
@@ -16631,6 +16855,9 @@ var init_src = __esm(() => {
|
|
|
16631
16855
|
init_application_release_transfer();
|
|
16632
16856
|
init_application_configuration();
|
|
16633
16857
|
init_deployment_evidence();
|
|
16858
|
+
init_delivery_tuple();
|
|
16859
|
+
init_contract_matrix();
|
|
16860
|
+
init_fa_stability();
|
|
16634
16861
|
init_application_promotion();
|
|
16635
16862
|
init_application_runtime_identity();
|
|
16636
16863
|
init_delivery_build_schema();
|
|
@@ -17377,7 +17604,7 @@ import { createHash as createHash12 } from "node:crypto";
|
|
|
17377
17604
|
import { mkdir as mkdir6, readFile as readFile14 } from "node:fs/promises";
|
|
17378
17605
|
import { dirname as dirname12, relative as relative12, resolve as resolve24 } from "node:path";
|
|
17379
17606
|
import * as ts18 from "@typescript/typescript6";
|
|
17380
|
-
function
|
|
17607
|
+
function hash4(value) {
|
|
17381
17608
|
return createHash12("sha256").update(value).digest("hex");
|
|
17382
17609
|
}
|
|
17383
17610
|
function importPath(out, path) {
|
|
@@ -17443,7 +17670,7 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
17443
17670
|
const inputs = {};
|
|
17444
17671
|
const addInput = async (path) => {
|
|
17445
17672
|
const absolute = resolve24(rootDir, path);
|
|
17446
|
-
inputs[relative12(rootDir, absolute).replaceAll("\\", "/")] =
|
|
17673
|
+
inputs[relative12(rootDir, absolute).replaceAll("\\", "/")] = hash4(await readFile14(absolute, "utf8"));
|
|
17447
17674
|
};
|
|
17448
17675
|
await addInput(postgrestTypes);
|
|
17449
17676
|
await addInput(drizzleSchema);
|
|
@@ -17482,7 +17709,7 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
17482
17709
|
role: options.role,
|
|
17483
17710
|
inputs: Object.fromEntries(Object.entries(inputs).sort(([a], [b]) => a.localeCompare(b))),
|
|
17484
17711
|
migrationOrder: options.migrations.map((path) => relative12(rootDir, resolve24(rootDir, path)).replaceAll("\\", "/")),
|
|
17485
|
-
outputs: Object.fromEntries(Object.entries(files).sort(([a], [b]) => a.localeCompare(b)).map(([file, text]) => [file,
|
|
17712
|
+
outputs: Object.fromEntries(Object.entries(files).sort(([a], [b]) => a.localeCompare(b)).map(([file, text]) => [file, hash4(text)]))
|
|
17486
17713
|
};
|
|
17487
17714
|
files["database.manifest.json"] = JSON.stringify(manifest, null, 2) + `
|
|
17488
17715
|
`;
|
|
@@ -21104,9 +21331,25 @@ import * as ts9 from "@typescript/typescript6";
|
|
|
21104
21331
|
var SOURCE_SEMANTIC_DIAGNOSTIC_CODES = {
|
|
21105
21332
|
"source-unsafe-any": { errorCode: "SC6009", docsUrl: "https://supacloud.dev/errors/SC6009" },
|
|
21106
21333
|
"source-floating-promise": { errorCode: "SC6010", docsUrl: "https://supacloud.dev/errors/SC6010" },
|
|
21107
|
-
"source-non-exhaustive-switch": { errorCode: "SC6011", docsUrl: "https://supacloud.dev/errors/SC6011" }
|
|
21334
|
+
"source-non-exhaustive-switch": { errorCode: "SC6011", docsUrl: "https://supacloud.dev/errors/SC6011" },
|
|
21335
|
+
"source-alternative-library": { errorCode: "SC6012", docsUrl: "https://supacloud.dev/errors/SC6012" }
|
|
21108
21336
|
};
|
|
21109
|
-
|
|
21337
|
+
var DEFAULT_ALTERNATIVE_LIBRARIES = [
|
|
21338
|
+
"@apollo/client",
|
|
21339
|
+
"@urql/core",
|
|
21340
|
+
"graphql-request",
|
|
21341
|
+
"kefir",
|
|
21342
|
+
"most",
|
|
21343
|
+
"@pgflow",
|
|
21344
|
+
"pgflow",
|
|
21345
|
+
"pg_durable",
|
|
21346
|
+
"react-relay",
|
|
21347
|
+
"redux-observable",
|
|
21348
|
+
"urql",
|
|
21349
|
+
"wonka",
|
|
21350
|
+
"xstream"
|
|
21351
|
+
];
|
|
21352
|
+
function scanSourceSemantics(source, checker, file, rootDir, options = {}) {
|
|
21110
21353
|
const diagnostics = [];
|
|
21111
21354
|
const report = (code, node, message) => {
|
|
21112
21355
|
diagnostics.push({
|
|
@@ -21118,6 +21361,16 @@ function scanSourceSemantics(source, checker, file, rootDir) {
|
|
|
21118
21361
|
line: source.getLineAndCharacterOfPosition(node.getStart(source)).line + 1
|
|
21119
21362
|
});
|
|
21120
21363
|
};
|
|
21364
|
+
const allowedLibraries = new Set(options.allowAlternativeLibraries ?? []);
|
|
21365
|
+
for (const statement of source.statements) {
|
|
21366
|
+
if (!ts9.isImportDeclaration(statement) || !ts9.isStringLiteral(statement.moduleSpecifier))
|
|
21367
|
+
continue;
|
|
21368
|
+
const moduleName = statement.moduleSpecifier.text;
|
|
21369
|
+
const alternative = DEFAULT_ALTERNATIVE_LIBRARIES.find((name) => moduleName === name || moduleName.startsWith(`${name}/`));
|
|
21370
|
+
if (alternative && !allowedLibraries.has(alternative) && !allowedLibraries.has(moduleName)) {
|
|
21371
|
+
report("source-alternative-library", statement.moduleSpecifier, `Production source imports alternative library "${moduleName}". Use the governed Supabase client/PostgREST transport and RxJS event composition by default, or allow this package explicitly in typeSafety.allowAlternativeLibraries for a documented boundary.`);
|
|
21372
|
+
}
|
|
21373
|
+
}
|
|
21121
21374
|
const unsafe = (value, target) => {
|
|
21122
21375
|
if (isUnknownBoundary(target, checker) || containsAny(target, checker, new Set, rootDir))
|
|
21123
21376
|
return;
|
|
@@ -21398,7 +21651,7 @@ function scanProductionSource(options) {
|
|
|
21398
21651
|
}
|
|
21399
21652
|
for (const sourceFile of sourceFiles) {
|
|
21400
21653
|
scanSourceFile(sourceFile, checker, rootDir, diagnostics, options.strict ?? false);
|
|
21401
|
-
diagnostics.push(...scanSourceSemantics(sourceFile, checker, normalizeRelative(rootDir, sourceFile.fileName), rootDir));
|
|
21654
|
+
diagnostics.push(...scanSourceSemantics(sourceFile, checker, normalizeRelative(rootDir, sourceFile.fileName), rootDir, options.allowAlternativeLibraries === undefined ? {} : { allowAlternativeLibraries: options.allowAlternativeLibraries }));
|
|
21402
21655
|
diagnostics.push(...scanDrizzleSql(sourceFile, checker, normalizeRelative(rootDir, sourceFile.fileName), options.strict ?? false));
|
|
21403
21656
|
const scanner = ts10.createScanner(ts10.ScriptTarget.Latest, false, sourceFile.languageVariant, sourceFile.text);
|
|
21404
21657
|
for (let kind = scanner.scan();kind !== ts10.SyntaxKind.EndOfFileToken; kind = scanner.scan()) {
|
|
@@ -21660,6 +21913,17 @@ function validateEffectPolicies(graph, options = {}) {
|
|
|
21660
21913
|
}
|
|
21661
21914
|
return diagnostics;
|
|
21662
21915
|
}
|
|
21916
|
+
function validateJobPolicies(graph) {
|
|
21917
|
+
const diagnostics = [];
|
|
21918
|
+
for (const module of graph.modules) {
|
|
21919
|
+
for (const job of module.jobs ?? []) {
|
|
21920
|
+
if (job.maxAttempts !== undefined && job.maxAttempts > 1 && job.idempotency !== "required") {
|
|
21921
|
+
diagnostics.push(diagnostic("job-retry-idempotency-required", `Job ${job.name} (${job.className}) enables ${job.maxAttempts} attempts without an idempotency contract.`, module.file, 'Use idempotency: "required" with a durable receipt, or set maxAttempts: 1.'));
|
|
21922
|
+
}
|
|
21923
|
+
}
|
|
21924
|
+
}
|
|
21925
|
+
return diagnostics;
|
|
21926
|
+
}
|
|
21663
21927
|
|
|
21664
21928
|
// src/database-governance.ts
|
|
21665
21929
|
import { execFile } from "node:child_process";
|
|
@@ -21709,13 +21973,19 @@ async function checkDatabaseGovernance(rootDir, value) {
|
|
|
21709
21973
|
|
|
21710
21974
|
// src/compile.ts
|
|
21711
21975
|
function withDefaultGovernance(options) {
|
|
21712
|
-
return
|
|
21713
|
-
|
|
21714
|
-
|
|
21715
|
-
|
|
21716
|
-
|
|
21717
|
-
|
|
21718
|
-
|
|
21976
|
+
return {
|
|
21977
|
+
...options,
|
|
21978
|
+
requireRouteContracts: options.requireRouteContracts ?? true,
|
|
21979
|
+
disallowControllerDirectDb: options.disallowControllerDirectDb ?? true,
|
|
21980
|
+
detectOrphanModules: options.detectOrphanModules ?? true,
|
|
21981
|
+
...options.commandCapabilities === undefined ? { commandCapabilities: {
|
|
21982
|
+
requirePersistentAdapters: true,
|
|
21983
|
+
permission: true,
|
|
21984
|
+
audit: true,
|
|
21985
|
+
idempotency: true,
|
|
21986
|
+
transaction: true
|
|
21987
|
+
} } : {}
|
|
21988
|
+
};
|
|
21719
21989
|
}
|
|
21720
21990
|
async function renderOptionalGraphql(options) {
|
|
21721
21991
|
return options.graphql ? (await Promise.resolve().then(() => (init_graphql(), exports_graphql))).renderGraphql(options) : { diagnostics: [], files: {} };
|
|
@@ -21727,7 +21997,8 @@ async function compileProject(options) {
|
|
|
21727
21997
|
...graph.diagnostics ?? [],
|
|
21728
21998
|
...validateGraph(graph, options),
|
|
21729
21999
|
...validateClientSchemaBoundaries(graph, options),
|
|
21730
|
-
...validateEffectPolicies(graph, options.effect)
|
|
22000
|
+
...validateEffectPolicies(graph, options.effect),
|
|
22001
|
+
...validateJobPolicies(graph)
|
|
21731
22002
|
];
|
|
21732
22003
|
const databaseDiagnostics = await checkDatabaseGovernance(options.rootDir, options.databaseGovernance);
|
|
21733
22004
|
diagnostics.push(...databaseDiagnostics);
|
|
@@ -21797,7 +22068,8 @@ async function checkProject(options) {
|
|
|
21797
22068
|
...graph.diagnostics ?? [],
|
|
21798
22069
|
...validateGraph(graph, options),
|
|
21799
22070
|
...validateClientSchemaBoundaries(graph, options),
|
|
21800
|
-
...validateEffectPolicies(graph, options.effect)
|
|
22071
|
+
...validateEffectPolicies(graph, options.effect),
|
|
22072
|
+
...validateJobPolicies(graph)
|
|
21801
22073
|
];
|
|
21802
22074
|
const databaseDiagnostics = await checkDatabaseGovernance(options.rootDir, options.databaseGovernance);
|
|
21803
22075
|
diagnostics.push(...databaseDiagnostics);
|
|
@@ -21877,7 +22149,8 @@ function resolveTypeSafety(options) {
|
|
|
21877
22149
|
return {
|
|
21878
22150
|
noAnyInGenerated: true,
|
|
21879
22151
|
scanProductionSource: true,
|
|
21880
|
-
...options.typeSafety?.exclude ? { exclude: options.typeSafety.exclude } : {}
|
|
22152
|
+
...options.typeSafety?.exclude ? { exclude: options.typeSafety.exclude } : {},
|
|
22153
|
+
...options.typeSafety?.allowAlternativeLibraries ? { allowAlternativeLibraries: options.typeSafety.allowAlternativeLibraries } : {}
|
|
21881
22154
|
};
|
|
21882
22155
|
}
|
|
21883
22156
|
|
|
@@ -21932,7 +22205,7 @@ function createDeliveryPlan(graph, input, validation) {
|
|
|
21932
22205
|
if (target.name === "api" && target.kind !== "api" || target.name === "jobs" && target.kind !== "jobs") {
|
|
21933
22206
|
fail("delivery-reserved-target", `"${target.name}" is reserved for its matching workload kind.`, "Rename the target or use the matching kind.");
|
|
21934
22207
|
}
|
|
21935
|
-
for (const name of sorted(target.modules)) {
|
|
22208
|
+
for (const name of sorted(target.modules ?? [])) {
|
|
21936
22209
|
if (!modules.has(name)) {
|
|
21937
22210
|
fail("delivery-unknown-module", `Target "${target.name}" refers to unknown module "${name}".`, "Select a module name from the compiler graph.");
|
|
21938
22211
|
continue;
|
|
@@ -21946,6 +22219,23 @@ function createDeliveryPlan(graph, input, validation) {
|
|
|
21946
22219
|
}
|
|
21947
22220
|
}
|
|
21948
22221
|
const targets = new Map;
|
|
22222
|
+
for (const declaration of declarations.values()) {
|
|
22223
|
+
if (declaration.kind !== "function" || declaration.function === undefined)
|
|
22224
|
+
continue;
|
|
22225
|
+
targets.set(declaration.name, {
|
|
22226
|
+
name: declaration.name,
|
|
22227
|
+
kind: "function",
|
|
22228
|
+
isolation: "shared",
|
|
22229
|
+
roots: [],
|
|
22230
|
+
modules: [],
|
|
22231
|
+
routes: [],
|
|
22232
|
+
jobs: [],
|
|
22233
|
+
externalTokens: [],
|
|
22234
|
+
function: declaration.function,
|
|
22235
|
+
requirements: { processIsolation: false, durableQueue: false, capabilities: sorted(declaration.capabilities ?? []) },
|
|
22236
|
+
runtimeStatus: options.runtime === undefined ? "unchecked" : "declared-compatible"
|
|
22237
|
+
});
|
|
22238
|
+
}
|
|
21949
22239
|
function getTarget(name, fallback) {
|
|
21950
22240
|
const existing = targets.get(name);
|
|
21951
22241
|
if (existing)
|
|
@@ -22814,6 +23104,14 @@ async function buildDeliveryProject(options, delivery) {
|
|
|
22814
23104
|
const planned = createDeliveryPlan({ ...checked.graph, diagnostics: checked.diagnostics }, settings, options);
|
|
22815
23105
|
if (!planned.ok)
|
|
22816
23106
|
return failed(planned.diagnostics);
|
|
23107
|
+
if (planned.plan.targets.some((target) => target.kind === "function")) {
|
|
23108
|
+
return failed([{
|
|
23109
|
+
severity: "error",
|
|
23110
|
+
code: "delivery-function-build-unsupported",
|
|
23111
|
+
message: "Function target rendering is not implemented yet; the delivery build only produces HTTP and Worker application objects.",
|
|
23112
|
+
suggestion: "Declare HTTP/Worker application targets for now; Function and schedule delivery is tracked separately."
|
|
23113
|
+
}]);
|
|
23114
|
+
}
|
|
22817
23115
|
if (options.graphql && checked.mismatches.some((mismatch) => mismatch.startsWith("graphql"))) {
|
|
22818
23116
|
throw new Error("Refresh GraphQL artifacts with compile before building independent targets.");
|
|
22819
23117
|
}
|
|
@@ -23767,10 +24065,10 @@ import { readFileSync as readFileSync4 } from "node:fs";
|
|
|
23767
24065
|
import { resolve as resolve17 } from "node:path";
|
|
23768
24066
|
|
|
23769
24067
|
// src/migration-app-version.ts
|
|
23770
|
-
var MIGRATION_APP_VERSION = "0.
|
|
24068
|
+
var MIGRATION_APP_VERSION = "0.27.0";
|
|
23771
24069
|
|
|
23772
24070
|
// src/migration-elysia-version.ts
|
|
23773
|
-
var MIGRATION_ELYSIA_VERSION = "0.
|
|
24071
|
+
var MIGRATION_ELYSIA_VERSION = "0.30.0";
|
|
23774
24072
|
|
|
23775
24073
|
// src/migration-policy.ts
|
|
23776
24074
|
var cachedCompilerVersion;
|
|
@@ -24739,7 +25037,7 @@ function isRecord2(value) {
|
|
|
24739
25037
|
function arrayLength(value) {
|
|
24740
25038
|
return Array.isArray(value) ? value.length : undefined;
|
|
24741
25039
|
}
|
|
24742
|
-
async function
|
|
25040
|
+
async function sha2566(path) {
|
|
24743
25041
|
return createHash11("sha256").update(await readFile11(path)).digest("hex");
|
|
24744
25042
|
}
|
|
24745
25043
|
function overallStatus(findings) {
|
|
@@ -24816,7 +25114,7 @@ async function assessMigration(options) {
|
|
|
24816
25114
|
contractsManifest = {
|
|
24817
25115
|
path: contractsManifestPath,
|
|
24818
25116
|
present: true,
|
|
24819
|
-
sha256: await
|
|
25117
|
+
sha256: await sha2566(contractsManifestPath),
|
|
24820
25118
|
version: 1,
|
|
24821
25119
|
...commands === undefined ? {} : { commands },
|
|
24822
25120
|
...routes === undefined ? {} : { routes },
|
|
@@ -24839,9 +25137,9 @@ async function assessMigration(options) {
|
|
|
24839
25137
|
const diff = diffOpenApiDocuments(await readOpenApiJson(baselinePath), await readOpenApiJson(currentPath));
|
|
24840
25138
|
openApi = {
|
|
24841
25139
|
baselinePath,
|
|
24842
|
-
baselineSha256: await
|
|
25140
|
+
baselineSha256: await sha2566(baselinePath),
|
|
24843
25141
|
currentPath,
|
|
24844
|
-
currentSha256: await
|
|
25142
|
+
currentSha256: await sha2566(currentPath),
|
|
24845
25143
|
diff
|
|
24846
25144
|
};
|
|
24847
25145
|
if (!diff.ok) {
|
|
@@ -24932,11 +25230,13 @@ var DEFAULT_SUPACLOUD_CONFIG = {
|
|
|
24932
25230
|
outDir: "generated",
|
|
24933
25231
|
include: ["**/*.module.ts", "**/*.ts"],
|
|
24934
25232
|
strict: true,
|
|
24935
|
-
requireRouteContracts:
|
|
25233
|
+
requireRouteContracts: true,
|
|
24936
25234
|
generateClient: true,
|
|
24937
25235
|
generateOpenApi: true,
|
|
24938
25236
|
generatePermissions: true,
|
|
24939
25237
|
treeShakeUnusedProviders: true,
|
|
25238
|
+
disallowControllerDirectDb: true,
|
|
25239
|
+
detectOrphanModules: true,
|
|
24940
25240
|
commandCapabilities: {
|
|
24941
25241
|
requirePersistentAdapters: true,
|
|
24942
25242
|
permission: true,
|
|
@@ -24991,9 +25291,9 @@ function validateGovernanceConfig(config) {
|
|
|
24991
25291
|
if (!isRecord(adapters))
|
|
24992
25292
|
throw new Error("commandCapabilities.rpc must contain named adapters.");
|
|
24993
25293
|
for (const [name, adapter] of Object.entries(adapters)) {
|
|
24994
|
-
if (!name.trim() || !isRecord(adapter) || Object.keys(adapter).some((key) => !["audit", "idempotency", "transaction", "boundary"].includes(key)))
|
|
25294
|
+
if (!name.trim() || !isRecord(adapter) || Object.keys(adapter).some((key) => !["audit", "idempotency", "reconcile", "transaction", "boundary"].includes(key)))
|
|
24995
25295
|
throw new Error("Invalid command adapter.");
|
|
24996
|
-
for (const key of ["audit", "idempotency", "transaction"]) {
|
|
25296
|
+
for (const key of ["audit", "idempotency", "reconcile", "transaction"]) {
|
|
24997
25297
|
if (adapter[key] !== undefined && typeof adapter[key] !== "boolean")
|
|
24998
25298
|
throw new Error("Invalid command adapter capability.");
|
|
24999
25299
|
}
|
|
@@ -25018,8 +25318,8 @@ function validateGovernanceConfig(config) {
|
|
|
25018
25318
|
}
|
|
25019
25319
|
if (config.typeSafety !== undefined) {
|
|
25020
25320
|
const rules = config.typeSafety;
|
|
25021
|
-
if (!isRecord(rules) || Object.keys(rules).some((key) => !["scanProductionSource", "noAnyInGenerated", "exclude"].includes(key)) || rules["scanProductionSource"] !== undefined && typeof rules["scanProductionSource"] !== "boolean" || rules["noAnyInGenerated"] !== undefined && typeof rules["noAnyInGenerated"] !== "boolean" || rules["exclude"] !== undefined && !isStrings(rules["exclude"])) {
|
|
25022
|
-
throw new Error("typeSafety accepts boolean scanProductionSource/noAnyInGenerated and
|
|
25321
|
+
if (!isRecord(rules) || Object.keys(rules).some((key) => !["scanProductionSource", "noAnyInGenerated", "exclude", "allowAlternativeLibraries"].includes(key)) || rules["scanProductionSource"] !== undefined && typeof rules["scanProductionSource"] !== "boolean" || rules["noAnyInGenerated"] !== undefined && typeof rules["noAnyInGenerated"] !== "boolean" || rules["exclude"] !== undefined && !isStrings(rules["exclude"]) || rules["allowAlternativeLibraries"] !== undefined && !isStrings(rules["allowAlternativeLibraries"])) {
|
|
25322
|
+
throw new Error("typeSafety accepts boolean scanProductionSource/noAnyInGenerated and string arrays exclude/allowAlternativeLibraries.");
|
|
25023
25323
|
}
|
|
25024
25324
|
}
|
|
25025
25325
|
for (const key of ["allowRouteCommandBindings", "disallowControllerDirectDb", "detectOrphanModules"]) {
|
|
@@ -25078,8 +25378,8 @@ function resolveSupacloudConfig(config = {}, cwd = process.cwd()) {
|
|
|
25078
25378
|
}
|
|
25079
25379
|
},
|
|
25080
25380
|
...resolved.allowRouteCommandBindings === undefined ? {} : { allowRouteCommandBindings: resolved.allowRouteCommandBindings },
|
|
25081
|
-
|
|
25082
|
-
|
|
25381
|
+
disallowControllerDirectDb: resolved.disallowControllerDirectDb ?? DEFAULT_SUPACLOUD_CONFIG.disallowControllerDirectDb,
|
|
25382
|
+
detectOrphanModules: resolved.detectOrphanModules ?? DEFAULT_SUPACLOUD_CONFIG.detectOrphanModules,
|
|
25083
25383
|
effect: resolved.effect === undefined ? { ...DEFAULT_SUPACLOUD_CONFIG.effect } : { ...DEFAULT_SUPACLOUD_CONFIG.effect, ...resolved.effect },
|
|
25084
25384
|
treeShakeUnusedProviders: resolved.treeShakeUnusedProviders ?? DEFAULT_SUPACLOUD_CONFIG.treeShakeUnusedProviders,
|
|
25085
25385
|
...resolved.graphql === undefined || resolved.graphql === false ? {} : { graphql: {
|
|
@@ -25494,6 +25794,7 @@ export {
|
|
|
25494
25794
|
validateEffectPolicies,
|
|
25495
25795
|
validateFeatureSpec,
|
|
25496
25796
|
validateGraph,
|
|
25797
|
+
validateJobPolicies,
|
|
25497
25798
|
validateRouteContracts,
|
|
25498
25799
|
watchProject,
|
|
25499
25800
|
writeOpenApiJson
|