@prisma/composer 0.1.0-dev.18 → 0.1.0-dev.3
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/{app-config-DJdU4ubR-BwioNK8j.d.mts → app-config-5mXxjaEl-D2Q6MU5g.d.mts} +19 -105
- package/dist/assertions.d.mts +1 -1
- package/dist/assertions.mjs.map +1 -1
- package/dist/bin.mjs +266 -81
- package/dist/bin.mjs.map +1 -1
- package/dist/casts-Ci5rYYaR.mjs.map +1 -1
- package/dist/casts.d.mts +1 -1
- package/dist/config-C23NciC8.d.mts +1 -0
- package/dist/config.d.mts +3 -3
- package/dist/config.mjs +1 -2
- package/dist/config.mjs.map +1 -1
- package/dist/deploy-C23NciC8.d.mts +1 -0
- package/dist/deploy.d.mts +2 -2
- package/dist/deploy.mjs +5 -12
- package/dist/deploy.mjs.map +1 -1
- package/dist/dist-B0axxnBf.mjs.map +1 -1
- package/dist/{graph-B7NcPiOr-aSUOCGTH.d.mts → graph-D383dfW2-Cepin3Om.d.mts} +3 -3
- package/dist/{graph-types-BgT9UEdm-Bz-_OcJH.d.mts → graph-types-COu3ss99-CrJcsbDJ.d.mts} +4 -4
- package/dist/{index-B2DJ5CN4.d.mts → index-8wU5wpMV.d.mts} +3 -3
- package/dist/{nextjs-DLyeRR7M-B9ukbB2L.d.mts → index-DIyo-rxT.d.mts} +5 -5
- package/dist/index.d.mts +3 -3
- package/dist/nextjs-control.d.mts +5 -5
- package/dist/nextjs-control.mjs.map +1 -1
- package/dist/nextjs.d.mts +2 -2
- package/dist/nextjs.mjs.map +1 -1
- package/dist/node-control.d.mts +4 -4
- package/dist/node-control.mjs.map +1 -1
- package/dist/node.d.mts +4 -4
- package/dist/node.mjs.map +1 -1
- package/dist/report.d.mts +3 -3
- package/dist/report.mjs.map +1 -1
- package/dist/{service-rpc.d.mts → rpc.d.mts} +11 -19
- package/dist/rpc.mjs +184 -0
- package/dist/rpc.mjs.map +1 -0
- package/dist/testing.d.mts +2 -2
- package/dist/testing.mjs.map +1 -1
- package/package.json +14 -14
- package/dist/config-ByZICgry.d.mts +0 -1
- package/dist/container-transport-DKmKg5JQ-DKWs0ubK.mjs +0 -45
- package/dist/container-transport-DKmKg5JQ-DKWs0ubK.mjs.map +0 -1
- package/dist/deploy-ByZICgry.d.mts +0 -1
- package/dist/service-rpc.mjs +0 -353
- package/dist/service-rpc.mjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { P as RunnableServiceNode, k as ProvisionNeed, o as Contract, s as DependencyEnd } from "./graph-types-
|
|
2
|
-
import "./index-
|
|
1
|
+
import { P as RunnableServiceNode, k as ProvisionNeed, o as Contract, s as DependencyEnd } from "./graph-types-COu3ss99-CrJcsbDJ.mjs";
|
|
2
|
+
import "./index-8wU5wpMV.mjs";
|
|
3
3
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
4
|
-
//#region ../../0-framework/2-authoring/
|
|
4
|
+
//#region ../../0-framework/2-authoring/rpc/dist/index.d.mts
|
|
5
5
|
//#region src/rpc.d.ts
|
|
6
6
|
/** ADR-0031's need brand for RPC's per-binding service key — the target registers a provisioner under this. */
|
|
7
7
|
declare const RPC_PEER_KEY: unique symbol;
|
|
@@ -37,25 +37,17 @@ declare function contract<Fns extends Record<string, (input: any) => Promise<any
|
|
|
37
37
|
declare const RPC_ACCEPTED_KEYS_ENV = "COMPOSER_RPC_ACCEPTED_KEYS";
|
|
38
38
|
type AnyRunnable = RunnableServiceNode<any, any, any>;
|
|
39
39
|
type CmpOf<C> = C extends Contract<string, infer Cmp> ? Cmp : never;
|
|
40
|
-
|
|
41
|
-
interface RpcHandlerContext {
|
|
42
|
-
/** The call's idempotency key (same across its retries), or `undefined` for a keyless caller that opted out of dedup. */
|
|
43
|
-
readonly idempotencyKey: string | undefined;
|
|
44
|
-
}
|
|
45
|
-
type HandlerFor<Fn, LoadedDeps> = Fn extends ((input: infer I) => Promise<infer O>) ? (input: I, deps: LoadedDeps, ctx: RpcHandlerContext) => Promise<O> : never;
|
|
40
|
+
type HandlerFor<Fn, LoadedDeps> = Fn extends ((input: infer I) => Promise<infer O>) ? (input: I, deps: LoadedDeps) => Promise<O> : never;
|
|
46
41
|
/** Every exposed port's methods, turned into a handler map typed off S's own `expose` and `load()`. */
|
|
47
42
|
type Handlers<S extends AnyRunnable> = { [Port in keyof NonNullable<S['expose']>]: { [M in keyof CmpOf<NonNullable<S['expose']>[Port]>]: HandlerFor<CmpOf<NonNullable<S['expose']>[Port]>[M], ReturnType<S['load']>>; }; };
|
|
48
43
|
/**
|
|
49
|
-
* Routes `POST /rpc/<method>`:
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* masks its message behind a generic 500 and logs the real error; an
|
|
55
|
-
* unknown method or invalid input is a 4xx. `load()` is called exactly
|
|
56
|
-
* once, here, before the handler ever runs.
|
|
44
|
+
* Routes `POST /rpc/<method>`: parses JSON, validates input, calls the
|
|
45
|
+
* handler with `service.load()`'s deps, validates the output, and responds
|
|
46
|
+
* JSON. An unknown method or invalid input is a 4xx; a handler (or output
|
|
47
|
+
* validation) failure is a 5xx — either way the process does not crash.
|
|
48
|
+
* `load()` is called exactly once, here, before the handler ever runs.
|
|
57
49
|
*/
|
|
58
50
|
declare function serve<S extends AnyRunnable, H extends Handlers<S>>(service: S, handlers: H): (req: Request) => Promise<Response>;
|
|
59
51
|
//#endregion
|
|
60
|
-
export { type Client, type Handlers, RPC_ACCEPTED_KEYS_ENV, RPC_PEER_KEY, type
|
|
61
|
-
//# sourceMappingURL=
|
|
52
|
+
export { type Client, type Handlers, RPC_ACCEPTED_KEYS_ENV, RPC_PEER_KEY, type Transport, contract, makeClient, perBindingToken, rpc, serve };
|
|
53
|
+
//# sourceMappingURL=rpc.d.mts.map
|
package/dist/rpc.mjs
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { t as blindCast } from "./casts-Ci5rYYaR.mjs";
|
|
2
|
+
import { i as dependency, p as provisionNeed } from "./graph-BmrUEdo9-6Oq1hSmS.mjs";
|
|
3
|
+
import { l as string } from "./dist-B0axxnBf.mjs";
|
|
4
|
+
//#region ../../0-framework/2-authoring/rpc/dist/index.mjs
|
|
5
|
+
async function standardValidate(schema, value) {
|
|
6
|
+
const result = await schema["~standard"].validate(value);
|
|
7
|
+
if (result.issues !== void 0) throw new Error(`Schema validation failed: ${result.issues.map((issue) => issue.message).join("; ")}`);
|
|
8
|
+
return result.value;
|
|
9
|
+
}
|
|
10
|
+
/** `<base>/rpc/<method>`, preserving a base URL's own path (e.g. a mount point). */
|
|
11
|
+
function methodUrl(base, method) {
|
|
12
|
+
const normalizedBase = base.endsWith("/") ? base : `${base}/`;
|
|
13
|
+
return new URL(`rpc/${method}`, normalizedBase).toString();
|
|
14
|
+
}
|
|
15
|
+
/** The server's `{ error }` body, if the response has one — undefined otherwise. */
|
|
16
|
+
async function errorDetail(res) {
|
|
17
|
+
try {
|
|
18
|
+
const body = await res.json();
|
|
19
|
+
return typeof body === "object" && body !== null && "error" in body ? String(body.error) : void 0;
|
|
20
|
+
} catch {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function makeClient(contract, url, opts) {
|
|
25
|
+
const send = opts?.fetch ?? fetch;
|
|
26
|
+
const headers = { "content-type": "application/json" };
|
|
27
|
+
if (opts?.serviceKey !== void 0) headers["Authorization"] = `Bearer ${opts.serviceKey}`;
|
|
28
|
+
const client = {};
|
|
29
|
+
for (const [method, schemas] of Object.entries(blindCast(contract.__cmp))) client[method] = async (input) => {
|
|
30
|
+
const res = await send(new Request(methodUrl(url, method), {
|
|
31
|
+
method: "POST",
|
|
32
|
+
headers,
|
|
33
|
+
body: JSON.stringify(input)
|
|
34
|
+
}));
|
|
35
|
+
if (!res.ok) {
|
|
36
|
+
const detail = await errorDetail(res);
|
|
37
|
+
throw new Error(`RPC call "${method}" failed: ${res.status} ${res.statusText}` + (detail !== void 0 ? ` — ${detail}` : ""));
|
|
38
|
+
}
|
|
39
|
+
return standardValidate(schemas.output, await res.json());
|
|
40
|
+
};
|
|
41
|
+
return blindCast(client);
|
|
42
|
+
}
|
|
43
|
+
function contract(fns) {
|
|
44
|
+
const value = {
|
|
45
|
+
kind: "rpc",
|
|
46
|
+
__cmp: fns,
|
|
47
|
+
satisfies: (required) => value === required
|
|
48
|
+
};
|
|
49
|
+
return Object.freeze(value);
|
|
50
|
+
}
|
|
51
|
+
/** ADR-0031's need brand for RPC's per-binding service key — the target registers a provisioner under this. */
|
|
52
|
+
const RPC_PEER_KEY = Symbol.for("prisma:rpc/per-binding-key");
|
|
53
|
+
/** The provisioning need `rpc()`'s `serviceKey` param declares (ADR-0030): a shared, unguessable value the target mints per consumer edge. */
|
|
54
|
+
const perBindingToken = () => provisionNeed(RPC_PEER_KEY);
|
|
55
|
+
function rpc(arg) {
|
|
56
|
+
if (!isRpcContract(arg)) return arg;
|
|
57
|
+
return dependency({
|
|
58
|
+
type: "rpc",
|
|
59
|
+
connection: {
|
|
60
|
+
params: {
|
|
61
|
+
url: string(),
|
|
62
|
+
serviceKey: string({
|
|
63
|
+
optional: true,
|
|
64
|
+
provision: perBindingToken()
|
|
65
|
+
})
|
|
66
|
+
},
|
|
67
|
+
hydrate: ({ url, serviceKey }) => makeClient(arg, url, { serviceKey })
|
|
68
|
+
},
|
|
69
|
+
required: arg
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function isRpcContract(value) {
|
|
73
|
+
return typeof value === "object" && value !== null && "kind" in value && value.kind === "rpc" && "__cmp" in value && "satisfies" in value;
|
|
74
|
+
}
|
|
75
|
+
/** The reserved env var the target (slice 2) writes the accepted key set to. */
|
|
76
|
+
const RPC_ACCEPTED_KEYS_ENV = "COMPOSER_RPC_ACCEPTED_KEYS";
|
|
77
|
+
function jsonResponse(body, status = 200) {
|
|
78
|
+
return new Response(JSON.stringify(body), {
|
|
79
|
+
status,
|
|
80
|
+
headers: { "content-type": "application/json" }
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
/** The provisioned accepted key set, or undefined when the deploy never provisioned one (local/test — enforcement off). */
|
|
84
|
+
function acceptedKeys() {
|
|
85
|
+
const raw = process.env[RPC_ACCEPTED_KEYS_ENV];
|
|
86
|
+
if (raw === void 0 || raw === "") return void 0;
|
|
87
|
+
let parsed;
|
|
88
|
+
try {
|
|
89
|
+
parsed = JSON.parse(raw);
|
|
90
|
+
} catch {
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
return Array.isArray(parsed) && parsed.every((key) => typeof key === "string") ? parsed : [];
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Length-independent constant-time string equality — no early exit on the
|
|
97
|
+
* first mismatched character or on a length difference, so a caller cannot
|
|
98
|
+
* time its way toward a valid key. No `node:crypto`, to keep this module
|
|
99
|
+
* runtime-agnostic.
|
|
100
|
+
*/
|
|
101
|
+
function constantTimeEquals(a, b) {
|
|
102
|
+
const length = Math.max(a.length, b.length);
|
|
103
|
+
let diff = a.length ^ b.length;
|
|
104
|
+
for (let i = 0; i < length; i++) diff |= (i < a.length ? a.charCodeAt(i) : 0) ^ (i < b.length ? b.charCodeAt(i) : 0);
|
|
105
|
+
return diff === 0;
|
|
106
|
+
}
|
|
107
|
+
/** Whether `presented` is a member of `accepted` — always compares against every key. */
|
|
108
|
+
function isAcceptedKey(presented, accepted) {
|
|
109
|
+
let matched = false;
|
|
110
|
+
for (const key of accepted) matched = constantTimeEquals(presented, key) || matched;
|
|
111
|
+
return matched;
|
|
112
|
+
}
|
|
113
|
+
const BEARER_PREFIX = "Bearer ";
|
|
114
|
+
/** The bearer token on `Authorization`, or `''` if the header is missing or malformed. */
|
|
115
|
+
function bearerToken(req) {
|
|
116
|
+
const header = req.headers.get("authorization");
|
|
117
|
+
return header?.startsWith(BEARER_PREFIX) ? header.slice(7) : "";
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Flattens every exposed port's methods into one method → {schemas, handler}
|
|
121
|
+
* table. RPC dispatch is flat (`/rpc/<method>`), so a method name exposed by
|
|
122
|
+
* more than one port is a construction-time error, as is a missing handler.
|
|
123
|
+
*/
|
|
124
|
+
function methodTable(expose, handlers) {
|
|
125
|
+
const table = /* @__PURE__ */ new Map();
|
|
126
|
+
for (const [port, contract] of Object.entries(expose)) {
|
|
127
|
+
const portHandlers = handlers[port] ?? {};
|
|
128
|
+
for (const [method, fn] of Object.entries(contract.__cmp)) {
|
|
129
|
+
if (table.has(method)) throw new Error(`serve(): method "${method}" is exposed by more than one port — RPC dispatch is flat (POST /rpc/<method>), so method names must be unique across a service's exposed ports.`);
|
|
130
|
+
const handler = portHandlers[method];
|
|
131
|
+
if (handler === void 0) throw new Error(`serve(): no handler supplied for exposed method "${port}.${method}".`);
|
|
132
|
+
const { input, output } = blindCast(fn);
|
|
133
|
+
table.set(method, {
|
|
134
|
+
input,
|
|
135
|
+
output,
|
|
136
|
+
handler
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return table;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Routes `POST /rpc/<method>`: parses JSON, validates input, calls the
|
|
144
|
+
* handler with `service.load()`'s deps, validates the output, and responds
|
|
145
|
+
* JSON. An unknown method or invalid input is a 4xx; a handler (or output
|
|
146
|
+
* validation) failure is a 5xx — either way the process does not crash.
|
|
147
|
+
* `load()` is called exactly once, here, before the handler ever runs.
|
|
148
|
+
*/
|
|
149
|
+
function serve(service, handlers) {
|
|
150
|
+
const table = methodTable(service.expose ?? {}, blindCast(handlers));
|
|
151
|
+
const deps = service.load();
|
|
152
|
+
return async (req) => {
|
|
153
|
+
const accepted = acceptedKeys();
|
|
154
|
+
if (accepted !== void 0 && !isAcceptedKey(bearerToken(req), accepted)) return jsonResponse({ error: "Unauthorized: missing or invalid service key" }, 401);
|
|
155
|
+
const { pathname } = new URL(req.url);
|
|
156
|
+
const methodName = /^\/rpc\/([^/]+)$/.exec(pathname)?.[1];
|
|
157
|
+
if (methodName === void 0) return jsonResponse({ error: `Not found: ${pathname}` }, 404);
|
|
158
|
+
const method = table.get(methodName);
|
|
159
|
+
if (method === void 0) return jsonResponse({ error: `Unknown RPC method "${methodName}"` }, 404);
|
|
160
|
+
if (req.method !== "POST") return jsonResponse({ error: `Method "${methodName}" requires POST` }, 405);
|
|
161
|
+
let body;
|
|
162
|
+
try {
|
|
163
|
+
body = await req.json();
|
|
164
|
+
} catch {
|
|
165
|
+
return jsonResponse({ error: "Request body must be JSON" }, 400);
|
|
166
|
+
}
|
|
167
|
+
let input;
|
|
168
|
+
try {
|
|
169
|
+
input = await standardValidate(method.input, body);
|
|
170
|
+
} catch (err) {
|
|
171
|
+
return jsonResponse({ error: err instanceof Error ? err.message : String(err) }, 400);
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
const result = await method.handler(input, deps);
|
|
175
|
+
return jsonResponse(await standardValidate(method.output, result));
|
|
176
|
+
} catch (err) {
|
|
177
|
+
return jsonResponse({ error: err instanceof Error ? err.message : String(err) }, 500);
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
//#endregion
|
|
182
|
+
export { RPC_ACCEPTED_KEYS_ENV, RPC_PEER_KEY, contract, makeClient, perBindingToken, rpc, serve };
|
|
183
|
+
|
|
184
|
+
//# sourceMappingURL=rpc.mjs.map
|
package/dist/rpc.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc.mjs","names":[],"sources":["../../../0-framework/2-authoring/rpc/dist/index.mjs"],"sourcesContent":["import { blindCast } from \"@internal/foundation/casts\";\nimport { dependency, provisionNeed, string } from \"@internal/core\";\n//#region src/standard-schema.ts\nasync function standardValidate(schema, value) {\n\tconst result = await schema[\"~standard\"].validate(value);\n\tif (result.issues !== void 0) throw new Error(`Schema validation failed: ${result.issues.map((issue) => issue.message).join(\"; \")}`);\n\treturn result.value;\n}\n//#endregion\n//#region src/client.ts\n/** `<base>/rpc/<method>`, preserving a base URL's own path (e.g. a mount point). */\nfunction methodUrl(base, method) {\n\tconst normalizedBase = base.endsWith(\"/\") ? base : `${base}/`;\n\treturn new URL(`rpc/${method}`, normalizedBase).toString();\n}\n/** The server's `{ error }` body, if the response has one — undefined otherwise. */\nasync function errorDetail(res) {\n\ttry {\n\t\tconst body = await res.json();\n\t\treturn typeof body === \"object\" && body !== null && \"error\" in body ? String(body.error) : void 0;\n\t} catch {\n\t\treturn;\n\t}\n}\nfunction makeClient(contract, url, opts) {\n\tconst send = opts?.fetch ?? fetch;\n\tconst headers = { \"content-type\": \"application/json\" };\n\tif (opts?.serviceKey !== void 0) headers[\"Authorization\"] = `Bearer ${opts.serviceKey}`;\n\tconst client = {};\n\tfor (const [method, schemas] of Object.entries(blindCast(contract.__cmp))) client[method] = async (input) => {\n\t\tconst res = await send(new Request(methodUrl(url, method), {\n\t\t\tmethod: \"POST\",\n\t\t\theaders,\n\t\t\tbody: JSON.stringify(input)\n\t\t}));\n\t\tif (!res.ok) {\n\t\t\tconst detail = await errorDetail(res);\n\t\t\tthrow new Error(`RPC call \"${method}\" failed: ${res.status} ${res.statusText}` + (detail !== void 0 ? ` — ${detail}` : \"\"));\n\t\t}\n\t\treturn standardValidate(schemas.output, await res.json());\n\t};\n\treturn blindCast(client);\n}\n//#endregion\n//#region src/contract.ts\nfunction contract(fns) {\n\tconst value = {\n\t\tkind: \"rpc\",\n\t\t__cmp: fns,\n\t\tsatisfies: (required) => value === required\n\t};\n\treturn Object.freeze(value);\n}\n//#endregion\n//#region src/rpc.ts\n/** ADR-0031's need brand for RPC's per-binding service key — the target registers a provisioner under this. */\nconst RPC_PEER_KEY = Symbol.for(\"prisma:rpc/per-binding-key\");\n/** The provisioning need `rpc()`'s `serviceKey` param declares (ADR-0030): a shared, unguessable value the target mints per consumer edge. */\nconst perBindingToken = () => provisionNeed(RPC_PEER_KEY);\nfunction rpc(arg) {\n\tif (!isRpcContract(arg)) return arg;\n\treturn dependency({\n\t\ttype: \"rpc\",\n\t\tconnection: {\n\t\t\tparams: {\n\t\t\t\turl: string(),\n\t\t\t\tserviceKey: string({\n\t\t\t\t\toptional: true,\n\t\t\t\t\tprovision: perBindingToken()\n\t\t\t\t})\n\t\t\t},\n\t\t\thydrate: ({ url, serviceKey }) => makeClient(arg, url, { serviceKey })\n\t\t},\n\t\trequired: arg\n\t});\n}\nfunction isRpcContract(value) {\n\treturn typeof value === \"object\" && value !== null && \"kind\" in value && value.kind === \"rpc\" && \"__cmp\" in value && \"satisfies\" in value;\n}\n//#endregion\n//#region src/serve.ts\n/** The reserved env var the target (slice 2) writes the accepted key set to. */\nconst RPC_ACCEPTED_KEYS_ENV = \"COMPOSER_RPC_ACCEPTED_KEYS\";\nfunction jsonResponse(body, status = 200) {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: { \"content-type\": \"application/json\" }\n\t});\n}\n/** The provisioned accepted key set, or undefined when the deploy never provisioned one (local/test — enforcement off). */\nfunction acceptedKeys() {\n\tconst raw = process.env[RPC_ACCEPTED_KEYS_ENV];\n\tif (raw === void 0 || raw === \"\") return void 0;\n\tlet parsed;\n\ttry {\n\t\tparsed = JSON.parse(raw);\n\t} catch {\n\t\treturn [];\n\t}\n\treturn Array.isArray(parsed) && parsed.every((key) => typeof key === \"string\") ? parsed : [];\n}\n/**\n* Length-independent constant-time string equality — no early exit on the\n* first mismatched character or on a length difference, so a caller cannot\n* time its way toward a valid key. No `node:crypto`, to keep this module\n* runtime-agnostic.\n*/\nfunction constantTimeEquals(a, b) {\n\tconst length = Math.max(a.length, b.length);\n\tlet diff = a.length ^ b.length;\n\tfor (let i = 0; i < length; i++) diff |= (i < a.length ? a.charCodeAt(i) : 0) ^ (i < b.length ? b.charCodeAt(i) : 0);\n\treturn diff === 0;\n}\n/** Whether `presented` is a member of `accepted` — always compares against every key. */\nfunction isAcceptedKey(presented, accepted) {\n\tlet matched = false;\n\tfor (const key of accepted) matched = constantTimeEquals(presented, key) || matched;\n\treturn matched;\n}\nconst BEARER_PREFIX = \"Bearer \";\n/** The bearer token on `Authorization`, or `''` if the header is missing or malformed. */\nfunction bearerToken(req) {\n\tconst header = req.headers.get(\"authorization\");\n\treturn header?.startsWith(BEARER_PREFIX) ? header.slice(7) : \"\";\n}\n/**\n* Flattens every exposed port's methods into one method → {schemas, handler}\n* table. RPC dispatch is flat (`/rpc/<method>`), so a method name exposed by\n* more than one port is a construction-time error, as is a missing handler.\n*/\nfunction methodTable(expose, handlers) {\n\tconst table = /* @__PURE__ */ new Map();\n\tfor (const [port, contract] of Object.entries(expose)) {\n\t\tconst portHandlers = handlers[port] ?? {};\n\t\tfor (const [method, fn] of Object.entries(contract.__cmp)) {\n\t\t\tif (table.has(method)) throw new Error(`serve(): method \"${method}\" is exposed by more than one port — RPC dispatch is flat (POST /rpc/<method>), so method names must be unique across a service's exposed ports.`);\n\t\t\tconst handler = portHandlers[method];\n\t\t\tif (handler === void 0) throw new Error(`serve(): no handler supplied for exposed method \"${port}.${method}\".`);\n\t\t\tconst { input, output } = blindCast(fn);\n\t\t\ttable.set(method, {\n\t\t\t\tinput,\n\t\t\t\toutput,\n\t\t\t\thandler\n\t\t\t});\n\t\t}\n\t}\n\treturn table;\n}\n/**\n* Routes `POST /rpc/<method>`: parses JSON, validates input, calls the\n* handler with `service.load()`'s deps, validates the output, and responds\n* JSON. An unknown method or invalid input is a 4xx; a handler (or output\n* validation) failure is a 5xx — either way the process does not crash.\n* `load()` is called exactly once, here, before the handler ever runs.\n*/\nfunction serve(service, handlers) {\n\tconst table = methodTable(service.expose ?? {}, blindCast(handlers));\n\tconst deps = service.load();\n\treturn async (req) => {\n\t\tconst accepted = acceptedKeys();\n\t\tif (accepted !== void 0 && !isAcceptedKey(bearerToken(req), accepted)) return jsonResponse({ error: \"Unauthorized: missing or invalid service key\" }, 401);\n\t\tconst { pathname } = new URL(req.url);\n\t\tconst methodName = /^\\/rpc\\/([^/]+)$/.exec(pathname)?.[1];\n\t\tif (methodName === void 0) return jsonResponse({ error: `Not found: ${pathname}` }, 404);\n\t\tconst method = table.get(methodName);\n\t\tif (method === void 0) return jsonResponse({ error: `Unknown RPC method \"${methodName}\"` }, 404);\n\t\tif (req.method !== \"POST\") return jsonResponse({ error: `Method \"${methodName}\" requires POST` }, 405);\n\t\tlet body;\n\t\ttry {\n\t\t\tbody = await req.json();\n\t\t} catch {\n\t\t\treturn jsonResponse({ error: \"Request body must be JSON\" }, 400);\n\t\t}\n\t\tlet input;\n\t\ttry {\n\t\t\tinput = await standardValidate(method.input, body);\n\t\t} catch (err) {\n\t\t\treturn jsonResponse({ error: err instanceof Error ? err.message : String(err) }, 400);\n\t\t}\n\t\ttry {\n\t\t\tconst result = await method.handler(input, deps);\n\t\t\treturn jsonResponse(await standardValidate(method.output, result));\n\t\t} catch (err) {\n\t\t\treturn jsonResponse({ error: err instanceof Error ? err.message : String(err) }, 500);\n\t\t}\n\t};\n}\n//#endregion\nexport { RPC_ACCEPTED_KEYS_ENV, RPC_PEER_KEY, contract, makeClient, perBindingToken, rpc, serve };\n\n//# sourceMappingURL=index.mjs.map"],"mappings":"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"}
|
package/dist/testing.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { B as Secrets, H as Values, O as Params, P as RunnableServiceNode, c as Deps, m as HydratedDeps, u as Expose } from "./graph-types-
|
|
1
|
+
import { B as Secrets, H as Values, O as Params, P as RunnableServiceNode, c as Deps, m as HydratedDeps, u as Expose } from "./graph-types-COu3ss99-CrJcsbDJ.mjs";
|
|
2
2
|
//#region ../../0-framework/1-core/core/dist/testing.d.mts
|
|
3
|
-
//#region src/testing.d.ts
|
|
3
|
+
//#region src/exports/testing.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* `mockService`'s override argument: every declared dependency, typed against
|
|
6
6
|
* its own hydrated shape (`Client<C>` for an RPC dep, the resource binding
|
package/dist/testing.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.mjs","names":[],"sources":["../../../0-framework/1-core/core/dist/testing.mjs"],"sourcesContent":["import { blindCast } from \"@internal/foundation/casts\";\n//#region src/testing.ts\n/**\n* The unit-test seam (testing.md § Unit): `mockService` replaces a service\n* node's `load()` and `config()` output so any code that pulls dependencies or\n* params through them — a page, a server action, a helper — runs against typed\n* doubles with no server and no environment. Target-agnostic: every service\n* node has `load()`/`config()`. It does no module mocking; wiring the\n* substitution into a test runner (`vi.mock`, `mock.module`) stays in the test.\n* The integration seam (`bootstrapService`) is target-specific and lives in the\n* target's own testing entry (e.g. `@prisma/composer-prisma-cloud/testing`).\n*/\nfunction paramDefaults(params) {\n\tconst defaults = {};\n\tfor (const [name, param] of Object.entries(params)) if (param.default !== void 0) defaults[name] = param.default;\n\treturn blindCast(defaults);\n}\n/**\n* Returns a service node whose `load()` yields the dependency doubles and\n* `config()` yields the service's params (defaults overlaid with any\n* overrides) — everything else about the node (its deps, params, build,\n* expose) is unchanged. `overrides` is one flat object: dependency keys route\n* to `load()`, param keys to `config()`. `run()` is not meaningful on a mock\n* (there is no boot, no environment) and throws if called.\n*/\nfunction mockService(service, overrides) {\n\tconst entries = Object.entries(overrides);\n\tconst deps = blindCast(Object.fromEntries(entries.filter(([name]) => name in service.inputs)));\n\tconst config = blindCast({\n\t\t...paramDefaults(service.params),\n\t\t...Object.fromEntries(entries.filter(([name]) => name in service.params))\n\t});\n\treturn Object.freeze({\n\t\t...service,\n\t\trun() {\n\t\t\tthrow new Error(`mockService(): \"${service.name}\" is a load()/config()-only mock — it has no run() (no boot, no environment).`);\n\t\t},\n\t\tload: () => deps,\n\t\tconfig: () => config\n\t});\n}\n//#endregion\nexport { mockService };\n\n//# sourceMappingURL=testing.mjs.map"],"mappings":";;;;;;;;;;;;AAYA,SAAS,cAAc,QAAQ;CAC9B,MAAM,WAAW,CAAC;CAClB,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,MAAM,GAAG,IAAI,MAAM,YAAY,KAAK,GAAG,SAAS,QAAQ,MAAM;CACzG,OAAO,UAAU,QAAQ;AAC1B;;;;;;;;;AASA,SAAS,YAAY,SAAS,WAAW;CACxC,MAAM,UAAU,OAAO,QAAQ,SAAS;CACxC,MAAM,OAAO,UAAU,OAAO,YAAY,QAAQ,QAAQ,CAAC,UAAU,QAAQ,QAAQ,MAAM,CAAC,CAAC;CAC7F,MAAM,SAAS,UAAU;EACxB,GAAG,cAAc,QAAQ,MAAM;EAC/B,GAAG,OAAO,YAAY,QAAQ,QAAQ,CAAC,UAAU,QAAQ,QAAQ,MAAM,CAAC;CACzE,CAAC;CACD,OAAO,OAAO,OAAO;EACpB,GAAG;EACH,MAAM;GACL,MAAM,IAAI,MAAM,mBAAmB,QAAQ,KAAK,8EAA8E;EAC/H;EACA,YAAY;EACZ,cAAc;CACf,CAAC;AACF"}
|
|
1
|
+
{"version":3,"file":"testing.mjs","names":[],"sources":["../../../0-framework/1-core/core/dist/testing.mjs"],"sourcesContent":["import { blindCast } from \"@internal/foundation/casts\";\n//#region src/exports/testing.ts\n/**\n* The unit-test seam (testing.md § Unit): `mockService` replaces a service\n* node's `load()` and `config()` output so any code that pulls dependencies or\n* params through them — a page, a server action, a helper — runs against typed\n* doubles with no server and no environment. Target-agnostic: every service\n* node has `load()`/`config()`. It does no module mocking; wiring the\n* substitution into a test runner (`vi.mock`, `mock.module`) stays in the test.\n* The integration seam (`bootstrapService`) is target-specific and lives in the\n* target's own testing entry (e.g. `@prisma/composer-prisma-cloud/testing`).\n*/\nfunction paramDefaults(params) {\n\tconst defaults = {};\n\tfor (const [name, param] of Object.entries(params)) if (param.default !== void 0) defaults[name] = param.default;\n\treturn blindCast(defaults);\n}\n/**\n* Returns a service node whose `load()` yields the dependency doubles and\n* `config()` yields the service's params (defaults overlaid with any\n* overrides) — everything else about the node (its deps, params, build,\n* expose) is unchanged. `overrides` is one flat object: dependency keys route\n* to `load()`, param keys to `config()`. `run()` is not meaningful on a mock\n* (there is no boot, no environment) and throws if called.\n*/\nfunction mockService(service, overrides) {\n\tconst entries = Object.entries(overrides);\n\tconst deps = blindCast(Object.fromEntries(entries.filter(([name]) => name in service.inputs)));\n\tconst config = blindCast({\n\t\t...paramDefaults(service.params),\n\t\t...Object.fromEntries(entries.filter(([name]) => name in service.params))\n\t});\n\treturn Object.freeze({\n\t\t...service,\n\t\trun() {\n\t\t\tthrow new Error(`mockService(): \"${service.name}\" is a load()/config()-only mock — it has no run() (no boot, no environment).`);\n\t\t},\n\t\tload: () => deps,\n\t\tconfig: () => config\n\t});\n}\n//#endregion\nexport { mockService };\n\n//# sourceMappingURL=testing.mjs.map"],"mappings":";;;;;;;;;;;;AAYA,SAAS,cAAc,QAAQ;CAC9B,MAAM,WAAW,CAAC;CAClB,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,MAAM,GAAG,IAAI,MAAM,YAAY,KAAK,GAAG,SAAS,QAAQ,MAAM;CACzG,OAAO,UAAU,QAAQ;AAC1B;;;;;;;;;AASA,SAAS,YAAY,SAAS,WAAW;CACxC,MAAM,UAAU,OAAO,QAAQ,SAAS;CACxC,MAAM,OAAO,UAAU,OAAO,YAAY,QAAQ,QAAQ,CAAC,UAAU,QAAQ,QAAQ,MAAM,CAAC,CAAC;CAC7F,MAAM,SAAS,UAAU;EACxB,GAAG,cAAc,QAAQ,MAAM;EAC/B,GAAG,OAAO,YAAY,QAAQ,QAAQ,CAAC,UAAU,QAAQ,QAAQ,MAAM,CAAC;CACzE,CAAC;CACD,OAAO,OAAO,OAAO;EACpB,GAAG;EACH,MAAM;GACL,MAAM,IAAI,MAAM,mBAAmB,QAAQ,KAAK,8EAA8E;EAC/H;EACA,YAAY;EACZ,cAAc;CACf,CAAC;AACF"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma/composer",
|
|
3
|
-
"version": "0.1.0-dev.
|
|
3
|
+
"version": "0.1.0-dev.3",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "Prisma Composer — build a Prisma App by composing Modules. Core authoring, deploy pipeline, the prisma-composer CLI, and the
|
|
5
|
+
"description": "Prisma Composer — build a Prisma App by composing Modules. Core authoring, deploy pipeline, the prisma-composer CLI, and the rpc/node/nextjs authoring surfaces.",
|
|
6
6
|
"bin": {
|
|
7
7
|
"prisma-composer": "./dist/bin.mjs"
|
|
8
8
|
},
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"./testing": "./dist/testing.mjs",
|
|
15
15
|
"./casts": "./dist/casts.mjs",
|
|
16
16
|
"./assertions": "./dist/assertions.mjs",
|
|
17
|
-
"./
|
|
17
|
+
"./rpc": "./dist/rpc.mjs",
|
|
18
18
|
"./node": "./dist/node.mjs",
|
|
19
19
|
"./node/control": "./dist/node-control.mjs",
|
|
20
20
|
"./nextjs": "./dist/nextjs.mjs",
|
|
@@ -33,20 +33,20 @@
|
|
|
33
33
|
"effect": "4.0.0-beta.93",
|
|
34
34
|
"esbuild": "^0.28.1",
|
|
35
35
|
"postgres": "^3.4.9",
|
|
36
|
-
"@prisma/management-api-sdk": "^1.
|
|
36
|
+
"@prisma/management-api-sdk": "^1.47.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@internal/assemble": "0.1.0-dev.
|
|
40
|
-
"@internal/cli": "0.1.0-dev.
|
|
41
|
-
"@internal/core": "0.1.0-dev.
|
|
42
|
-
"@internal/foundation": "0.1.0-dev.
|
|
43
|
-
"@internal/lowering": "0.1.0-dev.
|
|
44
|
-
"@internal/nextjs": "0.1.0-dev.
|
|
45
|
-
"@internal/node": "0.1.0-dev.
|
|
46
|
-
"@internal/
|
|
47
|
-
"@internal/tsdown-config": "0.1.0-dev.
|
|
39
|
+
"@internal/assemble": "0.1.0-dev.3",
|
|
40
|
+
"@internal/cli": "0.1.0-dev.3",
|
|
41
|
+
"@internal/core": "0.1.0-dev.3",
|
|
42
|
+
"@internal/foundation": "0.1.0-dev.3",
|
|
43
|
+
"@internal/lowering": "0.1.0-dev.3",
|
|
44
|
+
"@internal/nextjs": "0.1.0-dev.3",
|
|
45
|
+
"@internal/node": "0.1.0-dev.3",
|
|
46
|
+
"@internal/rpc": "0.1.0-dev.3",
|
|
47
|
+
"@internal/tsdown-config": "0.1.0-dev.3",
|
|
48
48
|
"@types/node": "^25.9.3",
|
|
49
|
-
"tsdown": "^0.22.
|
|
49
|
+
"tsdown": "^0.22.4",
|
|
50
50
|
"typescript": "^6.0.3"
|
|
51
51
|
},
|
|
52
52
|
"license": "Apache-2.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import "./app-config-DJdU4ubR-BwioNK8j.mjs";
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
//#region ../../0-framework/1-core/core/dist/container-transport-DKmKg5JQ.mjs
|
|
2
|
-
/** '@prisma/composer-prisma-cloud' → 'PRISMA_COMPOSER_CONTAINER_PRISMA_COMPOSER_PRISMA_CLOUD' */
|
|
3
|
-
function containerEnvVarName(extensionId) {
|
|
4
|
-
return `PRISMA_COMPOSER_CONTAINER_${extensionId.toUpperCase().replace(/[^A-Z0-9]+/g, "_").replace(/^_+|_+$/g, "")}`;
|
|
5
|
-
}
|
|
6
|
-
function collisionError(a, b, varName) {
|
|
7
|
-
return /* @__PURE__ */ new Error(`Extension ids "${a}" and "${b}" both mangle to the container transport variable "${varName}" — rename one of the extensions.`);
|
|
8
|
-
}
|
|
9
|
-
function emptySerializeError(extensionId) {
|
|
10
|
-
return /* @__PURE__ */ new Error(`Extension "${extensionId}"'s container instance serialized to an empty string — ContainerInstance.serialize() must return a non-empty string.`);
|
|
11
|
-
}
|
|
12
|
-
/** The env entries the CLI sets on the alchemy process: `{ [containerEnvVarName(id)]: instance.serialize() }` for every resolved instance. */
|
|
13
|
-
function containerEnv(instances) {
|
|
14
|
-
const env = {};
|
|
15
|
-
const ownerByVarName = /* @__PURE__ */ new Map();
|
|
16
|
-
for (const [extensionId, instance] of instances) {
|
|
17
|
-
const varName = containerEnvVarName(extensionId);
|
|
18
|
-
const owner = ownerByVarName.get(varName);
|
|
19
|
-
if (owner !== void 0) throw collisionError(owner, extensionId, varName);
|
|
20
|
-
ownerByVarName.set(varName, extensionId);
|
|
21
|
-
const serialized = instance.serialize();
|
|
22
|
-
if (serialized.length === 0) throw emptySerializeError(extensionId);
|
|
23
|
-
env[varName] = serialized;
|
|
24
|
-
}
|
|
25
|
-
return env;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* The alchemy-process side: for each extension with a container descriptor
|
|
29
|
-
* whose var is present in `env`, call its deserialize. Absent var → no entry.
|
|
30
|
-
*/
|
|
31
|
-
function deserializeContainers(extensions, env) {
|
|
32
|
-
const instances = /* @__PURE__ */ new Map();
|
|
33
|
-
for (const extension of extensions) {
|
|
34
|
-
const descriptor = extension.container;
|
|
35
|
-
if (descriptor === void 0) continue;
|
|
36
|
-
const serialized = env[containerEnvVarName(extension.id)];
|
|
37
|
-
if (serialized === void 0) continue;
|
|
38
|
-
instances.set(extension.id, descriptor.deserialize(serialized));
|
|
39
|
-
}
|
|
40
|
-
return instances;
|
|
41
|
-
}
|
|
42
|
-
//#endregion
|
|
43
|
-
export { containerEnvVarName as n, deserializeContainers as r, containerEnv as t };
|
|
44
|
-
|
|
45
|
-
//# sourceMappingURL=container-transport-DKmKg5JQ-DKWs0ubK.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"container-transport-DKmKg5JQ-DKWs0ubK.mjs","names":[],"sources":["../../../0-framework/1-core/core/dist/container-transport-DKmKg5JQ.mjs"],"sourcesContent":["//#region src/container-transport.ts\n/** '@prisma/composer-prisma-cloud' → 'PRISMA_COMPOSER_CONTAINER_PRISMA_COMPOSER_PRISMA_CLOUD' */\nfunction containerEnvVarName(extensionId) {\n\treturn `PRISMA_COMPOSER_CONTAINER_${extensionId.toUpperCase().replace(/[^A-Z0-9]+/g, \"_\").replace(/^_+|_+$/g, \"\")}`;\n}\nfunction collisionError(a, b, varName) {\n\treturn /* @__PURE__ */ new Error(`Extension ids \"${a}\" and \"${b}\" both mangle to the container transport variable \"${varName}\" — rename one of the extensions.`);\n}\nfunction emptySerializeError(extensionId) {\n\treturn /* @__PURE__ */ new Error(`Extension \"${extensionId}\"'s container instance serialized to an empty string — ContainerInstance.serialize() must return a non-empty string.`);\n}\n/** The env entries the CLI sets on the alchemy process: `{ [containerEnvVarName(id)]: instance.serialize() }` for every resolved instance. */\nfunction containerEnv(instances) {\n\tconst env = {};\n\tconst ownerByVarName = /* @__PURE__ */ new Map();\n\tfor (const [extensionId, instance] of instances) {\n\t\tconst varName = containerEnvVarName(extensionId);\n\t\tconst owner = ownerByVarName.get(varName);\n\t\tif (owner !== void 0) throw collisionError(owner, extensionId, varName);\n\t\townerByVarName.set(varName, extensionId);\n\t\tconst serialized = instance.serialize();\n\t\tif (serialized.length === 0) throw emptySerializeError(extensionId);\n\t\tenv[varName] = serialized;\n\t}\n\treturn env;\n}\n/**\n* The alchemy-process side: for each extension with a container descriptor\n* whose var is present in `env`, call its deserialize. Absent var → no entry.\n*/\nfunction deserializeContainers(extensions, env) {\n\tconst instances = /* @__PURE__ */ new Map();\n\tfor (const extension of extensions) {\n\t\tconst descriptor = extension.container;\n\t\tif (descriptor === void 0) continue;\n\t\tconst serialized = env[containerEnvVarName(extension.id)];\n\t\tif (serialized === void 0) continue;\n\t\tinstances.set(extension.id, descriptor.deserialize(serialized));\n\t}\n\treturn instances;\n}\n//#endregion\nexport { containerEnvVarName as n, deserializeContainers as r, containerEnv as t };\n\n//# sourceMappingURL=container-transport-DKmKg5JQ.mjs.map"],"mappings":";;AAEA,SAAS,oBAAoB,aAAa;CACzC,OAAO,6BAA6B,YAAY,YAAY,CAAC,CAAC,QAAQ,eAAe,GAAG,CAAC,CAAC,QAAQ,YAAY,EAAE;AACjH;AACA,SAAS,eAAe,GAAG,GAAG,SAAS;CACtC,uBAAuB,IAAI,MAAM,kBAAkB,EAAE,SAAS,EAAE,qDAAqD,QAAQ,kCAAkC;AAChK;AACA,SAAS,oBAAoB,aAAa;CACzC,uBAAuB,IAAI,MAAM,cAAc,YAAY,qHAAqH;AACjL;;AAEA,SAAS,aAAa,WAAW;CAChC,MAAM,MAAM,CAAC;CACb,MAAM,iCAAiC,IAAI,IAAI;CAC/C,KAAK,MAAM,CAAC,aAAa,aAAa,WAAW;EAChD,MAAM,UAAU,oBAAoB,WAAW;EAC/C,MAAM,QAAQ,eAAe,IAAI,OAAO;EACxC,IAAI,UAAU,KAAK,GAAG,MAAM,eAAe,OAAO,aAAa,OAAO;EACtE,eAAe,IAAI,SAAS,WAAW;EACvC,MAAM,aAAa,SAAS,UAAU;EACtC,IAAI,WAAW,WAAW,GAAG,MAAM,oBAAoB,WAAW;EAClE,IAAI,WAAW;CAChB;CACA,OAAO;AACR;;;;;AAKA,SAAS,sBAAsB,YAAY,KAAK;CAC/C,MAAM,4BAA4B,IAAI,IAAI;CAC1C,KAAK,MAAM,aAAa,YAAY;EACnC,MAAM,aAAa,UAAU;EAC7B,IAAI,eAAe,KAAK,GAAG;EAC3B,MAAM,aAAa,IAAI,oBAAoB,UAAU,EAAE;EACvD,IAAI,eAAe,KAAK,GAAG;EAC3B,UAAU,IAAI,UAAU,IAAI,WAAW,YAAY,UAAU,CAAC;CAC/D;CACA,OAAO;AACR"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import "./app-config-DJdU4ubR-BwioNK8j.mjs";
|