@prisma/composer 0.1.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.
Files changed (50) hide show
  1. package/LICENSE +201 -0
  2. package/dist/app-config-BUqyK6N6-CVq3uvHF.d.mts +188 -0
  3. package/dist/assertions.d.mts +31 -0
  4. package/dist/assertions.mjs +35 -0
  5. package/dist/assertions.mjs.map +1 -0
  6. package/dist/bin.mjs +1134 -0
  7. package/dist/bin.mjs.map +1 -0
  8. package/dist/casts-Ci5rYYaR.mjs +82 -0
  9. package/dist/casts-Ci5rYYaR.mjs.map +1 -0
  10. package/dist/casts.d.mts +78 -0
  11. package/dist/casts.mjs +2 -0
  12. package/dist/config-BVVgDSdq.d.mts +1 -0
  13. package/dist/config-ob5OhCSP-sP3GW3uu.d.mts +477 -0
  14. package/dist/config.d.mts +2 -0
  15. package/dist/config.mjs +9 -0
  16. package/dist/config.mjs.map +1 -0
  17. package/dist/deploy-BVVgDSdq.d.mts +1 -0
  18. package/dist/deploy.d.mts +2 -0
  19. package/dist/deploy.mjs +154 -0
  20. package/dist/deploy.mjs.map +1 -0
  21. package/dist/dist-zBU8ASQW.mjs +181 -0
  22. package/dist/dist-zBU8ASQW.mjs.map +1 -0
  23. package/dist/graph-BYdCQKya-BI0njTow.mjs +595 -0
  24. package/dist/graph-BYdCQKya-BI0njTow.mjs.map +1 -0
  25. package/dist/index-CZSc9drz.d.mts +47 -0
  26. package/dist/index-Dh4Zro0y.d.mts +15 -0
  27. package/dist/index.d.mts +3 -0
  28. package/dist/index.mjs +3 -0
  29. package/dist/nextjs-control.d.mts +13 -0
  30. package/dist/nextjs-control.mjs +108 -0
  31. package/dist/nextjs-control.mjs.map +1 -0
  32. package/dist/nextjs.d.mts +2 -0
  33. package/dist/nextjs.mjs +12 -0
  34. package/dist/nextjs.mjs.map +1 -0
  35. package/dist/node-control.d.mts +9 -0
  36. package/dist/node-control.mjs +70 -0
  37. package/dist/node-control.mjs.map +1 -0
  38. package/dist/node.d.mts +10 -0
  39. package/dist/node.mjs +11 -0
  40. package/dist/node.mjs.map +1 -0
  41. package/dist/rpc.d.mts +43 -0
  42. package/dist/rpc.mjs +132 -0
  43. package/dist/rpc.mjs.map +1 -0
  44. package/dist/testing.d.mts +24 -0
  45. package/dist/testing.mjs +45 -0
  46. package/dist/testing.mjs.map +1 -0
  47. package/dist/tsdown.d.mts +9 -0
  48. package/dist/tsdown.mjs +35 -0
  49. package/dist/tsdown.mjs.map +1 -0
  50. package/package.json +68 -0
package/dist/rpc.mjs ADDED
@@ -0,0 +1,132 @@
1
+ import { t as blindCast } from "./casts-Ci5rYYaR.mjs";
2
+ import { i as dependency } from "./graph-BYdCQKya-BI0njTow.mjs";
3
+ import { c as string } from "./dist-zBU8ASQW.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 client = {};
27
+ for (const [method, schemas] of Object.entries(blindCast(contract.__cmp))) client[method] = async (input) => {
28
+ const res = await send(new Request(methodUrl(url, method), {
29
+ method: "POST",
30
+ headers: { "content-type": "application/json" },
31
+ body: JSON.stringify(input)
32
+ }));
33
+ if (!res.ok) {
34
+ const detail = await errorDetail(res);
35
+ throw new Error(`RPC call "${method}" failed: ${res.status} ${res.statusText}` + (detail !== void 0 ? ` — ${detail}` : ""));
36
+ }
37
+ return standardValidate(schemas.output, await res.json());
38
+ };
39
+ return blindCast(client);
40
+ }
41
+ function contract(fns) {
42
+ const value = {
43
+ kind: "rpc",
44
+ __cmp: fns,
45
+ satisfies: (required) => value === required
46
+ };
47
+ return Object.freeze(value);
48
+ }
49
+ function rpc(arg) {
50
+ if (!isRpcContract(arg)) return arg;
51
+ return dependency({
52
+ type: "rpc",
53
+ connection: {
54
+ params: { url: string() },
55
+ hydrate: ({ url }) => makeClient(arg, url)
56
+ },
57
+ required: arg
58
+ });
59
+ }
60
+ function isRpcContract(value) {
61
+ return typeof value === "object" && value !== null && "kind" in value && value.kind === "rpc" && "__cmp" in value && "satisfies" in value;
62
+ }
63
+ function jsonResponse(body, status = 200) {
64
+ return new Response(JSON.stringify(body), {
65
+ status,
66
+ headers: { "content-type": "application/json" }
67
+ });
68
+ }
69
+ /**
70
+ * Flattens every exposed port's methods into one method → {schemas, handler}
71
+ * table. RPC dispatch is flat (`/rpc/<method>`), so a method name exposed by
72
+ * more than one port is a construction-time error, as is a missing handler.
73
+ */
74
+ function methodTable(expose, handlers) {
75
+ const table = /* @__PURE__ */ new Map();
76
+ for (const [port, contract] of Object.entries(expose)) {
77
+ const portHandlers = handlers[port] ?? {};
78
+ for (const [method, fn] of Object.entries(contract.__cmp)) {
79
+ 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.`);
80
+ const handler = portHandlers[method];
81
+ if (handler === void 0) throw new Error(`serve(): no handler supplied for exposed method "${port}.${method}".`);
82
+ const { input, output } = blindCast(fn);
83
+ table.set(method, {
84
+ input,
85
+ output,
86
+ handler
87
+ });
88
+ }
89
+ }
90
+ return table;
91
+ }
92
+ /**
93
+ * Routes `POST /rpc/<method>`: parses JSON, validates input, calls the
94
+ * handler with `service.load()`'s deps, validates the output, and responds
95
+ * JSON. An unknown method or invalid input is a 4xx; a handler (or output
96
+ * validation) failure is a 5xx — either way the process does not crash.
97
+ * `load()` is called exactly once, here, before the handler ever runs.
98
+ */
99
+ function serve(service, handlers) {
100
+ const table = methodTable(service.expose ?? {}, blindCast(handlers));
101
+ const deps = service.load();
102
+ return async (req) => {
103
+ const { pathname } = new URL(req.url);
104
+ const methodName = /^\/rpc\/([^/]+)$/.exec(pathname)?.[1];
105
+ if (methodName === void 0) return jsonResponse({ error: `Not found: ${pathname}` }, 404);
106
+ const method = table.get(methodName);
107
+ if (method === void 0) return jsonResponse({ error: `Unknown RPC method "${methodName}"` }, 404);
108
+ if (req.method !== "POST") return jsonResponse({ error: `Method "${methodName}" requires POST` }, 405);
109
+ let body;
110
+ try {
111
+ body = await req.json();
112
+ } catch {
113
+ return jsonResponse({ error: "Request body must be JSON" }, 400);
114
+ }
115
+ let input;
116
+ try {
117
+ input = await standardValidate(method.input, body);
118
+ } catch (err) {
119
+ return jsonResponse({ error: err instanceof Error ? err.message : String(err) }, 400);
120
+ }
121
+ try {
122
+ const result = await method.handler(input, deps);
123
+ return jsonResponse(await standardValidate(method.output, result));
124
+ } catch (err) {
125
+ return jsonResponse({ error: err instanceof Error ? err.message : String(err) }, 500);
126
+ }
127
+ };
128
+ }
129
+ //#endregion
130
+ export { contract, makeClient, rpc, serve };
131
+
132
+ //# sourceMappingURL=rpc.mjs.map
@@ -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, 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 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: { \"content-type\": \"application/json\" },\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\nfunction rpc(arg) {\n\tif (!isRpcContract(arg)) return arg;\n\treturn dependency({\n\t\ttype: \"rpc\",\n\t\tconnection: {\n\t\t\tparams: { url: string() },\n\t\t\thydrate: ({ url }) => makeClient(arg, url)\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\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/**\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 { 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 { contract, makeClient, rpc, serve };\n\n//# sourceMappingURL=index.mjs.map"],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { D as RunnableServiceNode, F as Values, N as Secrets, S as Params, c as Deps, m as HydratedDeps, u as Expose } from "./config-ob5OhCSP-sP3GW3uu.mjs";
2
+
3
+ //#region ../../0-framework/1-core/core/dist/testing.d.mts
4
+ //#region src/testing.d.ts
5
+ /**
6
+ * `mockService`'s override argument: every declared dependency, typed against
7
+ * its own hydrated shape (`Client<C>` for an RPC dep, the resource binding
8
+ * for a resource dep) — a double of the wrong shape is a compile error. The
9
+ * service's own params are optional; an omitted one falls back to its
10
+ * declared default, same as a real `load()`.
11
+ */
12
+ type LoadOverrides<D extends Deps, P extends Params> = HydratedDeps<D> & Partial<Values<P>>;
13
+ /**
14
+ * Returns a service node whose `load()` yields the dependency doubles and
15
+ * `config()` yields the service's params (defaults overlaid with any
16
+ * overrides) — everything else about the node (its deps, params, build,
17
+ * expose) is unchanged. `overrides` is one flat object: dependency keys route
18
+ * to `load()`, param keys to `config()`. `run()` is not meaningful on a mock
19
+ * (there is no boot, no environment) and throws if called.
20
+ */
21
+ declare function mockService<D extends Deps, P extends Params, E extends Expose, S extends Secrets>(service: RunnableServiceNode<D, P, E, S>, overrides: LoadOverrides<D, P>): RunnableServiceNode<D, P, E, S>; //#endregion
22
+ //#endregion
23
+ export { LoadOverrides, mockService };
24
+ //# sourceMappingURL=testing.d.mts.map
@@ -0,0 +1,45 @@
1
+ import { t as blindCast } from "./casts-Ci5rYYaR.mjs";
2
+ //#region ../../0-framework/1-core/core/dist/testing.mjs
3
+ /**
4
+ * The unit-test seam (testing.md § Unit): `mockService` replaces a service
5
+ * node's `load()` and `config()` output so any code that pulls dependencies or
6
+ * params through them — a page, a server action, a helper — runs against typed
7
+ * doubles with no server and no environment. Target-agnostic: every service
8
+ * node has `load()`/`config()`. It does no module mocking; wiring the
9
+ * substitution into a test runner (`vi.mock`, `mock.module`) stays in the test.
10
+ * The integration seam (`bootstrapService`) is target-specific and lives in the
11
+ * target's own testing entry (e.g. `@prisma/composer-prisma-cloud/testing`).
12
+ */
13
+ function paramDefaults(params) {
14
+ const defaults = {};
15
+ for (const [name, param] of Object.entries(params)) if (param.default !== void 0) defaults[name] = param.default;
16
+ return blindCast(defaults);
17
+ }
18
+ /**
19
+ * Returns a service node whose `load()` yields the dependency doubles and
20
+ * `config()` yields the service's params (defaults overlaid with any
21
+ * overrides) — everything else about the node (its deps, params, build,
22
+ * expose) is unchanged. `overrides` is one flat object: dependency keys route
23
+ * to `load()`, param keys to `config()`. `run()` is not meaningful on a mock
24
+ * (there is no boot, no environment) and throws if called.
25
+ */
26
+ function mockService(service, overrides) {
27
+ const entries = Object.entries(overrides);
28
+ const deps = blindCast(Object.fromEntries(entries.filter(([name]) => name in service.inputs)));
29
+ const config = blindCast({
30
+ ...paramDefaults(service.params),
31
+ ...Object.fromEntries(entries.filter(([name]) => name in service.params))
32
+ });
33
+ return Object.freeze({
34
+ ...service,
35
+ run() {
36
+ throw new Error(`mockService(): "${service.name}" is a load()/config()-only mock — it has no run() (no boot, no environment).`);
37
+ },
38
+ load: () => deps,
39
+ config: () => config
40
+ });
41
+ }
42
+ //#endregion
43
+ export { mockService };
44
+
45
+ //# sourceMappingURL=testing.mjs.map
@@ -0,0 +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"}
@@ -0,0 +1,9 @@
1
+ import { UserConfig } from "tsdown";
2
+
3
+ //#region src/tsdown.d.ts
4
+ declare function prismaTsDownConfig(config: UserConfig & {
5
+ entry: NonNullable<UserConfig['entry']>;
6
+ }): UserConfig;
7
+ //#endregion
8
+ export { prismaTsDownConfig };
9
+ //# sourceMappingURL=tsdown.d.mts.map
@@ -0,0 +1,35 @@
1
+ //#region src/tsdown.ts
2
+ /**
3
+ * `tsdown` config for a Prisma App's own runnable — the build ADR-0005 expects
4
+ * an app to produce before deploy. Its one job is a **self-contained** ESM
5
+ * bundle: `node_modules` is never shipped, so everything the entry touches at
6
+ * runtime must be inlined, and the artifact must not lean on bun's runtime
7
+ * auto-install to fill gaps. So it inlines EVERYTHING except the runtime's own
8
+ * built-ins (`bun`, `bun:*`, `node:*`) — a denylist, not a per-package
9
+ * allowlist. Allowlists are the trap: `noExternal: [/^pg$/]` inlines `pg` but
10
+ * misses its subpath imports (`pg/lib/*`), which then vanish from the bundle and
11
+ * crash the service at boot. This mirrors the deploy wrapper's own inline
12
+ * policy, so app and wrapper are self-contained the same way.
13
+ *
14
+ * Pass your `entry` (and any override); everything else is dictated.
15
+ */
16
+ const appBaseConfig = {
17
+ outDir: "dist",
18
+ format: "esm",
19
+ platform: "node",
20
+ external: ["bun"],
21
+ noExternal: [/^(?!bun$)(?!bun:)(?!node:).+/],
22
+ dts: false,
23
+ sourcemap: false,
24
+ clean: true
25
+ };
26
+ function prismaTsDownConfig(config) {
27
+ return {
28
+ ...appBaseConfig,
29
+ ...config
30
+ };
31
+ }
32
+ //#endregion
33
+ export { prismaTsDownConfig };
34
+
35
+ //# sourceMappingURL=tsdown.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tsdown.mjs","names":[],"sources":["../src/tsdown.ts"],"sourcesContent":["import type { UserConfig } from 'tsdown';\n\n/**\n * `tsdown` config for a Prisma App's own runnable — the build ADR-0005 expects\n * an app to produce before deploy. Its one job is a **self-contained** ESM\n * bundle: `node_modules` is never shipped, so everything the entry touches at\n * runtime must be inlined, and the artifact must not lean on bun's runtime\n * auto-install to fill gaps. So it inlines EVERYTHING except the runtime's own\n * built-ins (`bun`, `bun:*`, `node:*`) — a denylist, not a per-package\n * allowlist. Allowlists are the trap: `noExternal: [/^pg$/]` inlines `pg` but\n * misses its subpath imports (`pg/lib/*`), which then vanish from the bundle and\n * crash the service at boot. This mirrors the deploy wrapper's own inline\n * policy, so app and wrapper are self-contained the same way.\n *\n * Pass your `entry` (and any override); everything else is dictated.\n */\nconst appBaseConfig: UserConfig = {\n outDir: 'dist',\n format: 'esm',\n platform: 'node',\n external: ['bun'],\n // Inline everything except runtime built-ins (bun/bun:/node:).\n noExternal: [/^(?!bun$)(?!bun:)(?!node:).+/],\n dts: false,\n sourcemap: false,\n clean: true,\n};\n\nexport function prismaTsDownConfig(\n config: UserConfig & { entry: NonNullable<UserConfig['entry']> },\n): UserConfig {\n return {\n ...appBaseConfig,\n ...config,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,MAAM,gBAA4B;CAChC,QAAQ;CACR,QAAQ;CACR,UAAU;CACV,UAAU,CAAC,KAAK;CAEhB,YAAY,CAAC,8BAA8B;CAC3C,KAAK;CACL,WAAW;CACX,OAAO;AACT;AAEA,SAAgB,mBACd,QACY;CACZ,OAAO;EACL,GAAG;EACH,GAAG;CACL;AACF"}
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@prisma/composer",
3
+ "version": "0.1.0",
4
+ "type": "module",
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
+ "bin": {
7
+ "prisma-composer": "./dist/bin.mjs"
8
+ },
9
+ "exports": {
10
+ ".": "./dist/index.mjs",
11
+ "./config": "./dist/config.mjs",
12
+ "./deploy": "./dist/deploy.mjs",
13
+ "./testing": "./dist/testing.mjs",
14
+ "./casts": "./dist/casts.mjs",
15
+ "./assertions": "./dist/assertions.mjs",
16
+ "./rpc": "./dist/rpc.mjs",
17
+ "./node": "./dist/node.mjs",
18
+ "./node/control": "./dist/node-control.mjs",
19
+ "./nextjs": "./dist/nextjs.mjs",
20
+ "./nextjs/control": "./dist/nextjs-control.mjs",
21
+ "./tsdown": "./dist/tsdown.mjs",
22
+ "./package.json": "./package.json"
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "dependencies": {
28
+ "@standard-schema/spec": "^1.1.0",
29
+ "alchemy": "2.0.0-beta.59",
30
+ "arktype": "^2.2.3",
31
+ "c12": "^3.3.4",
32
+ "clipanion": "^3.2.1",
33
+ "effect": "4.0.0-beta.92",
34
+ "postgres": "^3.4.9",
35
+ "@prisma/management-api-sdk": "^1.47.0",
36
+ "tsdown": "^0.22.3"
37
+ },
38
+ "devDependencies": {
39
+ "@internal/assemble": "0.1.0",
40
+ "@internal/cli": "0.1.0",
41
+ "@internal/core": "0.1.0",
42
+ "@internal/foundation": "0.1.0",
43
+ "@internal/lowering": "0.1.0",
44
+ "@internal/nextjs": "0.1.0",
45
+ "@internal/node": "0.1.0",
46
+ "@internal/rpc": "0.1.0",
47
+ "@internal/tsdown-config": "0.1.0",
48
+ "@types/node": "^25.9.3",
49
+ "typescript": "^6.0.3"
50
+ },
51
+ "license": "Apache-2.0",
52
+ "repository": {
53
+ "type": "git",
54
+ "url": "https://github.com/prisma/compose.git",
55
+ "directory": "packages/9-public/composer"
56
+ },
57
+ "engines": {
58
+ "node": ">=24"
59
+ },
60
+ "publishConfig": {
61
+ "access": "public"
62
+ },
63
+ "scripts": {
64
+ "build": "tsdown",
65
+ "clean": "rm -rf dist",
66
+ "typecheck": "tsc --noEmit"
67
+ }
68
+ }