@prisma/composer-prisma-cloud 0.3.0-dev.8 → 0.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/dist/compute-main.mjs +4 -20
- package/dist/compute-main.mjs.map +1 -1
- package/dist/control.d.mts +1 -1
- package/dist/control.mjs +17 -28
- package/dist/control.mjs.map +1 -1
- package/dist/cron/index.d.mts +26 -33
- package/dist/cron/index.d.mts.map +1 -1
- package/dist/cron/index.mjs +77 -202
- package/dist/cron/index.mjs.map +1 -1
- package/dist/cron/scheduler-entrypoint.mjs +114 -133
- package/dist/cron/scheduler-entrypoint.mjs.map +1 -1
- package/dist/cron/scheduler-service.mjs +76 -200
- package/dist/cron/scheduler-service.mjs.map +1 -1
- package/dist/email/email-entrypoint.mjs +126 -162
- package/dist/email/email-entrypoint.mjs.map +1 -1
- package/dist/email/email-service.mjs +79 -230
- package/dist/email/email-service.mjs.map +1 -1
- package/dist/email/index.d.mts +29 -33
- package/dist/email/index.d.mts.map +1 -1
- package/dist/email/index.mjs +84 -236
- package/dist/email/index.mjs.map +1 -1
- package/dist/email/testing.mjs +89 -112
- package/dist/email/testing.mjs.map +1 -1
- package/dist/index.d.mts +43 -51
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +51 -47
- package/dist/index.mjs.map +1 -1
- package/dist/local-target.mjs +1 -1
- package/dist/local-target.mjs.map +1 -1
- package/dist/{secret-BVGxqHxY-DYDfiULl.mjs → param-BTzY0ne5-CW6ojZ3E.mjs} +4 -45
- package/dist/param-BTzY0ne5-CW6ojZ3E.mjs.map +1 -0
- package/dist/{preflight-names-CpJUd9ZA-BCU-W3cT.mjs → preflight-names-BPL-qsZF-BfoRgbgb.mjs} +14 -30
- package/dist/{preflight-names-CpJUd9ZA-BCU-W3cT.mjs.map → preflight-names-BPL-qsZF-BfoRgbgb.mjs.map} +1 -1
- package/dist/{provisioned-edges-Cxy18aoh-CUnaY96r.mjs → provisioned-edges-C1wSO3cx-YC5C19f9.mjs} +3 -3
- package/dist/{provisioned-edges-Cxy18aoh-CUnaY96r.mjs.map → provisioned-edges-C1wSO3cx-YC5C19f9.mjs.map} +1 -1
- package/dist/secret-rz_ZqNeq-_xd97Jd9.mjs +47 -0
- package/dist/secret-rz_ZqNeq-_xd97Jd9.mjs.map +1 -0
- package/dist/serializer-CJiOhF2d-DJUjQj1i.mjs +251 -0
- package/dist/serializer-CJiOhF2d-DJUjQj1i.mjs.map +1 -0
- package/dist/{serializer-BD_6nkr4-DWn5NNTC.d.mts → serializer-Cx5slrV4-xJfH6EWS.d.mts} +2 -2
- package/dist/serializer-Cx5slrV4-xJfH6EWS.d.mts.map +1 -0
- package/dist/storage/index.d.mts +26 -31
- package/dist/storage/index.d.mts.map +1 -1
- package/dist/storage/index.mjs +89 -215
- package/dist/storage/index.mjs.map +1 -1
- package/dist/storage/storage-entrypoint.mjs +122 -147
- package/dist/storage/storage-entrypoint.mjs.map +1 -1
- package/dist/storage/storage-service.mjs +87 -212
- package/dist/storage/storage-service.mjs.map +1 -1
- package/dist/streams/index.d.mts +22 -29
- package/dist/streams/index.d.mts.map +1 -1
- package/dist/streams/index.mjs +88 -213
- package/dist/streams/index.mjs.map +1 -1
- package/dist/streams/streams-entrypoint.mjs +118 -139
- package/dist/streams/streams-entrypoint.mjs.map +1 -1
- package/dist/streams/streams-service.mjs +87 -212
- package/dist/streams/streams-service.mjs.map +1 -1
- package/dist/testing.d.mts +5 -19
- package/dist/testing.d.mts.map +1 -1
- package/dist/testing.mjs +3 -11
- package/dist/testing.mjs.map +1 -1
- package/package.json +18 -18
- package/dist/secret-BVGxqHxY-DYDfiULl.mjs.map +0 -1
- package/dist/serializer-BD_6nkr4-DWn5NNTC.d.mts.map +0 -1
- package/dist/serializer-sVE4UAmg-CikRngbR.mjs +0 -475
- package/dist/serializer-sVE4UAmg-CikRngbR.mjs.map +0 -1
|
@@ -508,13 +508,6 @@ function startStorageServer(opts) {
|
|
|
508
508
|
stop: () => server.stop(true)
|
|
509
509
|
};
|
|
510
510
|
}
|
|
511
|
-
const nodeBuild = (opts) => ({
|
|
512
|
-
extension: "@prisma/composer/node",
|
|
513
|
-
type: "node",
|
|
514
|
-
module: opts.module,
|
|
515
|
-
entry: opts.entry,
|
|
516
|
-
...opts.dir === void 0 ? {} : { dir: opts.dir }
|
|
517
|
-
});
|
|
518
511
|
/**
|
|
519
512
|
* **Last-resort escape hatch for unsafe type assertions. Not a sanctioned tool to reach for.**
|
|
520
513
|
*
|
|
@@ -587,6 +580,11 @@ function freezeParams(params) {
|
|
|
587
580
|
for (const [name, param] of Object.entries(params)) frozen[name] = Object.freeze({ ...param });
|
|
588
581
|
return Object.freeze(frozen);
|
|
589
582
|
}
|
|
583
|
+
function freezeSecrets(secrets) {
|
|
584
|
+
const frozen = {};
|
|
585
|
+
for (const [name, need] of Object.entries(secrets)) frozen[name] = Object.freeze({ ...need });
|
|
586
|
+
return blindCast(Object.freeze(frozen));
|
|
587
|
+
}
|
|
590
588
|
/** A frozen shallow copy that keeps the caller's declared type. */
|
|
591
589
|
function frozenShallowCopy(obj) {
|
|
592
590
|
return blindCast(Object.freeze({ ...obj }));
|
|
@@ -640,8 +638,7 @@ function resource(def) {
|
|
|
640
638
|
}
|
|
641
639
|
/**
|
|
642
640
|
* Constructs a branded, frozen Service node — declarations only (inputs,
|
|
643
|
-
* params,
|
|
644
|
-
* carries no runtime behavior.
|
|
641
|
+
* params, build adapter, and the ports it exposes). Pure; carries no runtime behavior.
|
|
645
642
|
*/
|
|
646
643
|
function service$1(def) {
|
|
647
644
|
requireName(def.name, "service");
|
|
@@ -649,7 +646,8 @@ function service$1(def) {
|
|
|
649
646
|
requireType(def.type, "service");
|
|
650
647
|
requireConfigKeySegmentNames(Object.keys(def.inputs), "input", "service");
|
|
651
648
|
requireConfigKeySegmentNames(Object.keys(def.params), "param", "service");
|
|
652
|
-
|
|
649
|
+
requireConfigKeySegmentNames(Object.keys(def.secrets ?? {}), "secret", "service");
|
|
650
|
+
for (const slot of Object.keys(def.secrets ?? {})) if (Object.hasOwn(def.params, slot)) throw new Error(`service() secret slot "${slot}" collides with a param of the same name — a secret slot and a service param derive the same config key (COMPOSER_<addr>_${slot.toUpperCase()}); rename one.`);
|
|
653
651
|
return Object.freeze({
|
|
654
652
|
[NODE]: true,
|
|
655
653
|
kind: "service",
|
|
@@ -658,7 +656,7 @@ function service$1(def) {
|
|
|
658
656
|
type: def.type,
|
|
659
657
|
inputs: frozenShallowCopy(def.inputs),
|
|
660
658
|
params: freezeParams(def.params),
|
|
661
|
-
|
|
659
|
+
secretSlots: freezeSecrets(def.secrets ?? blindCast({})),
|
|
662
660
|
build: Object.freeze({ ...def.build }),
|
|
663
661
|
expose: def.expose !== void 0 ? frozenShallowCopy(def.expose) : void 0
|
|
664
662
|
});
|
|
@@ -691,16 +689,11 @@ function dependency(def) {
|
|
|
691
689
|
* `JSON.stringify`, and `console.log`/`util.inspect` all print `[REDACTED]`, so
|
|
692
690
|
* a secret can't leak through an accidental log or serialization.
|
|
693
691
|
*
|
|
694
|
-
*
|
|
695
|
-
*
|
|
696
|
-
* symbol key is invisible to `JSON.stringify` and `Object.keys`, so the box's
|
|
697
|
-
* public shape still matches the platform's own `secrecy` type
|
|
698
|
-
* (pdp-control-plane).
|
|
692
|
+
* Shape matches the platform's own `secrecy` type (pdp-control-plane). The class
|
|
693
|
+
* is nominal enough on its own — no phantom brand.
|
|
699
694
|
*/
|
|
700
695
|
const REDACTED = "[REDACTED]";
|
|
701
|
-
const SECRET_BOX = blindCast(Symbol.for("prisma:secret-box"));
|
|
702
696
|
var SecretBox = class {
|
|
703
|
-
[SECRET_BOX] = true;
|
|
704
697
|
#value;
|
|
705
698
|
constructor(value) {
|
|
706
699
|
this.#value = value;
|
|
@@ -766,6 +759,31 @@ function hydrateSync(root, config) {
|
|
|
766
759
|
}
|
|
767
760
|
return deps;
|
|
768
761
|
}
|
|
762
|
+
/**
|
|
763
|
+
* Wraps each of a service's resolved secret values in a redacting `SecretBox`
|
|
764
|
+
* — what the node's `secrets()` accessor returns (ADR-0021, sibling to
|
|
765
|
+
* `load()`/`config()`). The RESOLUTION of a secret's value (the boot
|
|
766
|
+
* double-lookup that reads the platform var the pointer names) is the target
|
|
767
|
+
* pack's job; core is handed the already-resolved strings and only boxes them,
|
|
768
|
+
* so a secret is redacted by TYPE from here on. A declared slot missing from
|
|
769
|
+
* `values` is a target contract violation, named loudly.
|
|
770
|
+
*/
|
|
771
|
+
function hydrateSecrets(root, values) {
|
|
772
|
+
const boxed = {};
|
|
773
|
+
for (const slot of Object.keys(root.secretSlots)) {
|
|
774
|
+
const value = values[slot];
|
|
775
|
+
if (value === void 0) throw new Error(`secret slot "${slot}" has no resolved value — the target must resolve every declared secret before hydrateSecrets().`);
|
|
776
|
+
boxed[slot] = new SecretBox(value);
|
|
777
|
+
}
|
|
778
|
+
return blindCast(boxed);
|
|
779
|
+
}
|
|
780
|
+
const nodeBuild = (opts) => ({
|
|
781
|
+
extension: "@prisma/composer/node",
|
|
782
|
+
type: "node",
|
|
783
|
+
module: opts.module,
|
|
784
|
+
entry: opts.entry,
|
|
785
|
+
...opts.dir === void 0 ? {} : { dir: opts.dir }
|
|
786
|
+
});
|
|
769
787
|
const liftArray = (data) => Array.isArray(data) ? data : [data];
|
|
770
788
|
/**
|
|
771
789
|
* Splits an array into two arrays based on the result of a predicate
|
|
@@ -7973,7 +7991,7 @@ function coerceEnvSourcedParam(raw, d, key) {
|
|
|
7973
7991
|
/**
|
|
7974
7992
|
* Boot: read each declared param from env by its key, reverse the param's own
|
|
7975
7993
|
* serialization (missing/invalid fails loudly), assemble the typed Config.
|
|
7976
|
-
*
|
|
7994
|
+
* Secrets ride a separate channel (deserializeSecrets), not this one.
|
|
7977
7995
|
*/
|
|
7978
7996
|
const deserialize = (node, address) => {
|
|
7979
7997
|
const service = {};
|
|
@@ -8010,84 +8028,40 @@ const stash = (node, config) => {
|
|
|
8010
8028
|
process.env[configKey("", d)] = encode(d.owner, value);
|
|
8011
8029
|
}
|
|
8012
8030
|
};
|
|
8013
|
-
/** The
|
|
8014
|
-
const
|
|
8015
|
-
/** The input document row's key for a service address. */
|
|
8016
|
-
const inputKey = (address) => configKey(address, {
|
|
8031
|
+
/** The pointer-row key for a secret slot: COMPOSER_<addr>_<slot> (secrets are service-level). */
|
|
8032
|
+
const secretKey = (address, slot) => configKey(address, {
|
|
8017
8033
|
owner: "service",
|
|
8018
|
-
name:
|
|
8034
|
+
name: slot
|
|
8019
8035
|
});
|
|
8020
|
-
const SECRET_MARKER = "$secret";
|
|
8021
|
-
const ESCAPED_KEY = /^\$\$+secret$/;
|
|
8022
|
-
/** True for the framework's secret pointer: `{ "$secret": "<PLATFORM_VAR>" }` and nothing else. */
|
|
8023
|
-
function isSecretPointer(value) {
|
|
8024
|
-
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.keys(value).length === 1 && SECRET_MARKER in value && typeof value[SECRET_MARKER] === "string";
|
|
8025
|
-
}
|
|
8026
|
-
/** A plain data object (not an array, not a class instance) — the only object shape a binding/document may nest. */
|
|
8027
|
-
function isPlainObject(value) {
|
|
8028
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
8029
|
-
const proto = Object.getPrototypeOf(value);
|
|
8030
|
-
return proto === Object.prototype || proto === null;
|
|
8031
|
-
}
|
|
8032
8036
|
/**
|
|
8033
|
-
* Boot:
|
|
8034
|
-
*
|
|
8035
|
-
* platform
|
|
8036
|
-
*
|
|
8037
|
-
* the env var — a deployed environment always writes it; a local harness must
|
|
8038
|
-
* supply it (set the row to the serialized input document).
|
|
8037
|
+
* Boot: resolve every secret slot to its value by double-lookup — read the
|
|
8038
|
+
* pointer key (the platform NAME), then read that platform var. A missing
|
|
8039
|
+
* pointer or a missing/empty platform value is a loud failure naming both keys.
|
|
8040
|
+
* Returns a plain Record for core's `hydrateSecrets` to box.
|
|
8039
8041
|
*/
|
|
8040
|
-
|
|
8041
|
-
const
|
|
8042
|
-
|
|
8043
|
-
|
|
8044
|
-
|
|
8045
|
-
|
|
8046
|
-
|
|
8047
|
-
|
|
8048
|
-
|
|
8049
|
-
}
|
|
8050
|
-
|
|
8051
|
-
|
|
8052
|
-
}
|
|
8053
|
-
const hydrated = hydrateInputDocument(parsed, key);
|
|
8054
|
-
try {
|
|
8055
|
-
return standardValidateSync(schema, hydrated);
|
|
8056
|
-
} catch (cause) {
|
|
8057
|
-
const message = cause instanceof Error ? cause.message : String(cause);
|
|
8058
|
-
throw new Error(`invalid input document (env ${key}): ${message}`);
|
|
8059
|
-
}
|
|
8060
|
-
}
|
|
8061
|
-
/** Reverses the document encoding: `$secret` pointers become redacting boxes over the named platform vars; escaped reserved keys drop one "$". */
|
|
8062
|
-
function hydrateInputDocument(value, key) {
|
|
8063
|
-
if (isSecretPointer(value)) {
|
|
8064
|
-
const name = value[SECRET_MARKER];
|
|
8065
|
-
const secret = process.env[name];
|
|
8066
|
-
if (secret === void 0 || secret === "") throw new Error(`secret input is not provisioned (env ${key} → ${name}): the platform var "${name}" is unset or empty.`);
|
|
8067
|
-
return new SecretBox(secret);
|
|
8068
|
-
}
|
|
8069
|
-
if (Array.isArray(value)) return value.map((member) => hydrateInputDocument(member, key));
|
|
8070
|
-
if (isPlainObject(value)) {
|
|
8071
|
-
const out = {};
|
|
8072
|
-
for (const [k, member] of Object.entries(value)) {
|
|
8073
|
-
const read = ESCAPED_KEY.test(k) ? k.slice(1) : k;
|
|
8074
|
-
out[read] = hydrateInputDocument(member, key);
|
|
8075
|
-
}
|
|
8076
|
-
return out;
|
|
8077
|
-
}
|
|
8078
|
-
return value;
|
|
8079
|
-
}
|
|
8042
|
+
const deserializeSecrets = (node, address) => {
|
|
8043
|
+
const values = {};
|
|
8044
|
+
for (const slot of Object.keys(node.secretSlots)) {
|
|
8045
|
+
const key = secretKey(address, slot);
|
|
8046
|
+
const name = process.env[key];
|
|
8047
|
+
if (name === void 0 || name === "") throw new Error(`missing secret pointer for slot "${slot}" (env ${key}) — the deploy did not write it.`);
|
|
8048
|
+
const value = process.env[name];
|
|
8049
|
+
if (value === void 0 || value === "") throw new Error(`secret "${slot}" is not provisioned (env ${key} → ${name}): the platform var "${name}" is unset or empty.`);
|
|
8050
|
+
values[slot] = value;
|
|
8051
|
+
}
|
|
8052
|
+
return values;
|
|
8053
|
+
};
|
|
8080
8054
|
/**
|
|
8081
|
-
* run()'s setup step for
|
|
8082
|
-
* address-free key, so the address-free `
|
|
8083
|
-
*
|
|
8084
|
-
* platform vars.
|
|
8055
|
+
* run()'s setup step for secrets: re-emit each slot's pointer NAME under its
|
|
8056
|
+
* address-free key, so the address-free `deserializeSecrets` double-looks-up
|
|
8057
|
+
* identically. Never the value — the value stays only in the platform var.
|
|
8085
8058
|
*/
|
|
8086
|
-
const
|
|
8087
|
-
|
|
8088
|
-
|
|
8089
|
-
|
|
8090
|
-
|
|
8059
|
+
const stashSecrets = (node, address) => {
|
|
8060
|
+
for (const slot of Object.keys(node.secretSlots)) {
|
|
8061
|
+
const name = process.env[secretKey(address, slot)];
|
|
8062
|
+
if (name === void 0) continue;
|
|
8063
|
+
process.env[secretKey("", slot)] = name;
|
|
8064
|
+
}
|
|
8091
8065
|
};
|
|
8092
8066
|
/**
|
|
8093
8067
|
* Boot: for each reserved provider param, read its address-scoped row through
|
|
@@ -8270,24 +8244,20 @@ Object.freeze({
|
|
|
8270
8244
|
});
|
|
8271
8245
|
const reservedParams = { port: number$1({ default: 3e3 }) };
|
|
8272
8246
|
/**
|
|
8273
|
-
* A Prisma Compute service — declarations only (deps +
|
|
8274
|
-
*
|
|
8275
|
-
*
|
|
8276
|
-
*
|
|
8247
|
+
* A Prisma Compute service — declarations only (deps + params + build + the
|
|
8248
|
+
* ports it exposes), no descriptor. `params` merges with the reserved
|
|
8249
|
+
* `ReservedParams` (`port`); a user param whose name collides with a reserved
|
|
8250
|
+
* one fails at authoring, the same way a colliding dependency name does.
|
|
8277
8251
|
*
|
|
8278
8252
|
* · run(address, boot) — the process controller: deserialize the platform
|
|
8279
8253
|
* environment (keyed off `address`, the extension's ONE env read) into a
|
|
8280
|
-
* typed Config, re-emit it
|
|
8281
|
-
*
|
|
8282
|
-
* · load() /
|
|
8283
|
-
* load() hydrates + memoizes the deps,
|
|
8284
|
-
*
|
|
8285
|
-
* platform var, validates with the declared schema, and memoizes (ADR-0042).
|
|
8254
|
+
* typed Config, re-emit it under address-free process-local stash keys,
|
|
8255
|
+
* then call boot() to start the app's entry.
|
|
8256
|
+
* · load() / config() — called from inside the app's entry: read the stash;
|
|
8257
|
+
* load() hydrates + memoizes the deps, config() returns the typed params.
|
|
8258
|
+
* Separate accessors so a dep and a param never share a namespace (ADR-0021).
|
|
8286
8259
|
* · origin() — this service's platform-assigned public origin, read from the
|
|
8287
8260
|
* stash `run()` populates; memoized per process.
|
|
8288
|
-
* · port() — this service's resolved reserved port (the value `run()` routes
|
|
8289
|
-
* to and exports as PORT), read from that same stash via #processConfig();
|
|
8290
|
-
* defaults to 3000 when the platform binds none.
|
|
8291
8261
|
*
|
|
8292
8262
|
* The underlying node carries `extension: '@prisma/composer-prisma-cloud'` —
|
|
8293
8263
|
* the control-plane registry key `prisma-composer deploy` resolves through the
|
|
@@ -8297,7 +8267,8 @@ const reservedParams = { port: number$1({ default: 3e3 }) };
|
|
|
8297
8267
|
var ComputeService = class {
|
|
8298
8268
|
#resolved;
|
|
8299
8269
|
#loadedDeps;
|
|
8300
|
-
#
|
|
8270
|
+
#loadedParams;
|
|
8271
|
+
#loadedSecrets;
|
|
8301
8272
|
#origin;
|
|
8302
8273
|
constructor(node) {
|
|
8303
8274
|
Object.assign(this, node);
|
|
@@ -8310,7 +8281,7 @@ var ComputeService = class {
|
|
|
8310
8281
|
const config = deserialize(this, address);
|
|
8311
8282
|
stash(this, config);
|
|
8312
8283
|
stashProviderParams(RESERVED_PROVIDER_PARAMS, address);
|
|
8313
|
-
|
|
8284
|
+
stashSecrets(this, address);
|
|
8314
8285
|
const port = config.service["port"];
|
|
8315
8286
|
if (typeof port === "number") process.env["PORT"] = String(port);
|
|
8316
8287
|
return boot();
|
|
@@ -8319,9 +8290,13 @@ var ComputeService = class {
|
|
|
8319
8290
|
if (this.#loadedDeps === void 0) this.#loadedDeps = blindCast(hydrateSync(this, this.#processConfig()));
|
|
8320
8291
|
return this.#loadedDeps;
|
|
8321
8292
|
}
|
|
8322
|
-
|
|
8323
|
-
if (this.#
|
|
8324
|
-
return this.#
|
|
8293
|
+
config() {
|
|
8294
|
+
if (this.#loadedParams === void 0) this.#loadedParams = blindCast(this.#processConfig().service);
|
|
8295
|
+
return this.#loadedParams;
|
|
8296
|
+
}
|
|
8297
|
+
secrets() {
|
|
8298
|
+
if (this.#loadedSecrets === void 0) this.#loadedSecrets = blindCast(hydrateSecrets(this, deserializeSecrets(this, "")));
|
|
8299
|
+
return this.#loadedSecrets;
|
|
8325
8300
|
}
|
|
8326
8301
|
/** This service's platform-assigned public origin — read from the stash
|
|
8327
8302
|
* run() populates and memoized per process. Throws if called before run()
|
|
@@ -8330,24 +8305,26 @@ var ComputeService = class {
|
|
|
8330
8305
|
this.#origin ??= readOrigin();
|
|
8331
8306
|
return this.#origin;
|
|
8332
8307
|
}
|
|
8333
|
-
/** This service's resolved reserved port — the value run() routes to and
|
|
8334
|
-
* exports as PORT — read the same way load() reads the stash. Defaults to
|
|
8335
|
-
* 3000 when the platform binds none. */
|
|
8336
|
-
port() {
|
|
8337
|
-
const port = this.#processConfig().service["port"];
|
|
8338
|
-
if (typeof port !== "number") throw new Error(`service "${this.name}" resolved a non-numeric port — the reserved port param is number({ default: 3000 }), so a stashed config always carries a number here.`);
|
|
8339
|
-
return port;
|
|
8340
|
-
}
|
|
8341
8308
|
};
|
|
8342
8309
|
const compute = (def) => {
|
|
8343
|
-
|
|
8310
|
+
const userParams = def.params ?? blindCast({});
|
|
8311
|
+
for (const reserved of Object.keys(reservedParams)) {
|
|
8312
|
+
if (reserved in def.deps) throw new Error(`compute(): dependency "${reserved}" collides with the reserved service param of the same name — rename the dependency.`);
|
|
8313
|
+
if (reserved in userParams) throw new Error(`compute(): param "${reserved}" collides with the reserved service param of the same name — rename the param.`);
|
|
8314
|
+
}
|
|
8315
|
+
for (const name of Object.keys(userParams)) if (name.toUpperCase() === "ORIGIN") throw new Error(`compute(): param "${name}" collides with the framework-written origin row — rename the param.`);
|
|
8316
|
+
for (const name of Object.keys(def.secrets ?? {})) if (name.toUpperCase() === "ORIGIN") throw new Error(`compute(): secret "${name}" collides with the framework-written origin row — rename the secret.`);
|
|
8317
|
+
const params = blindCast({
|
|
8318
|
+
...userParams,
|
|
8319
|
+
...reservedParams
|
|
8320
|
+
});
|
|
8344
8321
|
const instance = new ComputeService(service$1({
|
|
8345
8322
|
name: def.name,
|
|
8346
8323
|
extension: "@prisma/composer-prisma-cloud",
|
|
8347
8324
|
type: "compute",
|
|
8348
8325
|
inputs: def.deps,
|
|
8349
|
-
params
|
|
8350
|
-
...def.
|
|
8326
|
+
params,
|
|
8327
|
+
...def.secrets !== void 0 ? { secrets: def.secrets } : {},
|
|
8351
8328
|
build: def.build,
|
|
8352
8329
|
...def.expose !== void 0 ? { expose: def.expose } : {}
|
|
8353
8330
|
}));
|
|
@@ -8415,21 +8392,21 @@ function s3Credentials(opts) {
|
|
|
8415
8392
|
/**
|
|
8416
8393
|
* The storage service authoring factory — a `compute` service routed to the
|
|
8417
8394
|
* `s3-store` lowering instead of `compute`'s. It is exactly `compute`'s
|
|
8418
|
-
* runnable (run/load/
|
|
8419
|
-
*
|
|
8420
|
-
*
|
|
8421
|
-
*
|
|
8422
|
-
*
|
|
8423
|
-
*
|
|
8424
|
-
*
|
|
8425
|
-
*
|
|
8395
|
+
* runnable (run/load/config, deps, params, build, expose) with the routing
|
|
8396
|
+
* `type` overridden to `'s3-store'`: nothing at runtime keys off `type` (the
|
|
8397
|
+
* serializer keys off the deployment address and each param's owner/name, and
|
|
8398
|
+
* `load`/`config` off deps/params), so only the deploy-time descriptor lookup
|
|
8399
|
+
* sees the override and routes to the extended-output lowering (§ 5). The
|
|
8400
|
+
* return type is compute's exactly (including the reserved `port` param). The
|
|
8401
|
+
* storage module (D4b) calls this with its `db`/`credentials` deps, a `bucket`
|
|
8402
|
+
* param, and `expose: { store: s3Contract }`.
|
|
8426
8403
|
*
|
|
8427
|
-
* `compute()`'s result is a `ComputeService` instance — its run/load/
|
|
8428
|
-
* origin methods live on the class prototype, not as the instance's
|
|
8429
|
-
* properties, so a plain object spread (`{ ...node }`) would silently
|
|
8430
|
-
* them. Building a fresh `ComputeService` from the same data fields
|
|
8431
|
-
* `{ ...node }` DOES copy — they're the node's own enumerable
|
|
8432
|
-
* with `type` overridden keeps every method intact.
|
|
8404
|
+
* `compute()`'s result is a `ComputeService` instance — its run/load/config/
|
|
8405
|
+
* secrets/origin methods live on the class prototype, not as the instance's
|
|
8406
|
+
* own properties, so a plain object spread (`{ ...node }`) would silently
|
|
8407
|
+
* drop them. Building a fresh `ComputeService` from the same data fields
|
|
8408
|
+
* (which `{ ...node }` DOES copy — they're the node's own enumerable
|
|
8409
|
+
* properties) with `type` overridden keeps every method intact.
|
|
8433
8410
|
*/
|
|
8434
8411
|
function s3StoreService(def) {
|
|
8435
8412
|
const instance = new ComputeService({
|
|
@@ -8452,22 +8429,21 @@ const s3Contract = Object.freeze({
|
|
|
8452
8429
|
/**
|
|
8453
8430
|
* The storage service node (like cron's `scheduler.ts` + `scheduler-service.ts`
|
|
8454
8431
|
* combined): `storageService` builds the `s3-store` service — a Postgres `db`
|
|
8455
|
-
* dependency, a minted `credentials` dependency, a `bucket`
|
|
8456
|
-
*
|
|
8457
|
-
*
|
|
8458
|
-
*
|
|
8459
|
-
*
|
|
8460
|
-
*
|
|
8432
|
+
* dependency, a minted `credentials` dependency, a `bucket` param, and the
|
|
8433
|
+
* `store` port exposing `s3Contract`. The deploy bootstrap runs the
|
|
8434
|
+
* default-exported bare node (`main.run(address, boot)`); the real bucket comes
|
|
8435
|
+
* from serialized config at runtime, so the default's `bucket` is only a
|
|
8436
|
+
* placeholder — exactly like `scheduler-service.ts` default-exports
|
|
8437
|
+
* `cronScheduler({ jobs: [] })`.
|
|
8461
8438
|
*/
|
|
8462
|
-
|
|
8463
|
-
function storageService() {
|
|
8439
|
+
function storageService(opts) {
|
|
8464
8440
|
return s3StoreService({
|
|
8465
8441
|
name: "storage",
|
|
8466
8442
|
deps: {
|
|
8467
8443
|
db: postgres(),
|
|
8468
8444
|
credentials: s3Credentials()
|
|
8469
8445
|
},
|
|
8470
|
-
|
|
8446
|
+
params: { bucket: string$1({ default: opts.bucket }) },
|
|
8471
8447
|
build: nodeBuild({
|
|
8472
8448
|
module: new URL("./storage-service.mjs", import.meta.url).href,
|
|
8473
8449
|
entry: "./storage-entrypoint.mjs"
|
|
@@ -8475,11 +8451,10 @@ function storageService() {
|
|
|
8475
8451
|
expose: { store: s3Contract }
|
|
8476
8452
|
});
|
|
8477
8453
|
}
|
|
8478
|
-
storageService();
|
|
8479
|
-
const service = storageService();
|
|
8454
|
+
storageService({ bucket: "storage" });
|
|
8455
|
+
const service = storageService({ bucket: "storage" });
|
|
8480
8456
|
const { db, credentials } = service.load();
|
|
8481
|
-
const { bucket } = service.
|
|
8482
|
-
const port = service.port();
|
|
8457
|
+
const { bucket, port } = service.config();
|
|
8483
8458
|
startStorageServer({
|
|
8484
8459
|
store: await createPgStore(db.url),
|
|
8485
8460
|
credentials,
|