bunderstack 0.23.4 → 0.24.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/CHANGELOG.md +67 -0
- package/README.md +7 -4
- package/dist/api/builder.d.ts +13 -11
- package/dist/api/builder.d.ts.map +1 -1
- package/dist/api/builder.js.map +1 -1
- package/dist/api/context.d.ts +6 -6
- package/dist/api/context.d.ts.map +1 -1
- package/dist/api/context.js +1 -1
- package/dist/api/context.js.map +1 -1
- package/dist/api/crud-router.d.ts +6 -6
- package/dist/api/realtime-router.d.ts +1 -1
- package/dist/api/storage-router.d.ts +5 -5
- package/dist/auth.d.ts +20 -9
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +3 -8
- package/dist/auth.js.map +1 -1
- package/dist/backend-internals.d.ts +5 -13
- package/dist/backend-internals.d.ts.map +1 -1
- package/dist/backend-internals.js.map +1 -1
- package/dist/backend.d.ts +39 -5
- package/dist/backend.d.ts.map +1 -1
- package/dist/backend.js +37 -46
- package/dist/backend.js.map +1 -1
- package/dist/blueprint-generator.d.ts +1 -0
- package/dist/blueprint-generator.d.ts.map +1 -1
- package/dist/blueprint-generator.js +29 -1
- package/dist/blueprint-generator.js.map +1 -1
- package/dist/blueprint.d.ts +2 -1
- package/dist/blueprint.d.ts.map +1 -1
- package/dist/blueprint.js +9 -2
- package/dist/blueprint.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +14 -2
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +23 -25
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -1
- package/dist/config.js.map +1 -1
- package/dist/email/smtp.d.ts +7 -1
- package/dist/email/smtp.d.ts.map +1 -1
- package/dist/email/smtp.js +5 -1
- package/dist/email/smtp.js.map +1 -1
- package/dist/email.d.ts +3 -29
- package/dist/email.d.ts.map +1 -1
- package/dist/email.js +1 -194
- package/dist/email.js.map +1 -1
- package/dist/env-probe.d.ts +9 -0
- package/dist/env-probe.d.ts.map +1 -0
- package/dist/env-probe.js +73 -0
- package/dist/env-probe.js.map +1 -0
- package/dist/env.d.ts +2 -5
- package/dist/env.d.ts.map +1 -1
- package/dist/env.js +2 -9
- package/dist/env.js.map +1 -1
- package/dist/hosted-contract.d.ts +11 -0
- package/dist/hosted-contract.d.ts.map +1 -0
- package/dist/hosted-contract.js +46 -0
- package/dist/hosted-contract.js.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/inspect.d.ts +15 -0
- package/dist/inspect.d.ts.map +1 -0
- package/dist/inspect.js +43 -0
- package/dist/inspect.js.map +1 -0
- package/dist/internal-tables-pg.d.ts +43 -94
- package/dist/internal-tables-pg.d.ts.map +1 -1
- package/dist/internal-tables-pg.js +14 -17
- package/dist/internal-tables-pg.js.map +1 -1
- package/dist/internal-tables.d.ts +213 -488
- package/dist/internal-tables.d.ts.map +1 -1
- package/dist/internal-tables.js +33 -33
- package/dist/internal-tables.js.map +1 -1
- package/dist/jobs/define.d.ts +20 -20
- package/dist/jobs/define.d.ts.map +1 -1
- package/dist/jobs/define.js.map +1 -1
- package/dist/manifest-diff.d.ts +6 -0
- package/dist/manifest-diff.d.ts.map +1 -0
- package/dist/manifest-diff.js +42 -0
- package/dist/manifest-diff.js.map +1 -0
- package/dist/manifest.d.ts +10 -2
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +27 -29
- package/dist/manifest.js.map +1 -1
- package/dist/messaging/email.d.ts +16 -0
- package/dist/messaging/email.d.ts.map +1 -0
- package/dist/messaging/email.js +8 -0
- package/dist/messaging/email.js.map +1 -0
- package/dist/messaging/index.d.ts +8 -0
- package/dist/messaging/index.d.ts.map +1 -0
- package/dist/messaging/index.js +4 -0
- package/dist/messaging/index.js.map +1 -0
- package/dist/messaging/journal.d.ts +4 -0
- package/dist/messaging/journal.d.ts.map +1 -0
- package/dist/messaging/journal.js +19 -0
- package/dist/messaging/journal.js.map +1 -0
- package/dist/messaging/runtime.d.ts +16 -0
- package/dist/messaging/runtime.d.ts.map +1 -0
- package/dist/messaging/runtime.js +213 -0
- package/dist/messaging/runtime.js.map +1 -0
- package/dist/messaging/standalone.d.ts +27 -0
- package/dist/messaging/standalone.d.ts.map +1 -0
- package/dist/messaging/standalone.js +18 -0
- package/dist/messaging/standalone.js.map +1 -0
- package/dist/messaging/telegram.d.ts +16 -0
- package/dist/messaging/telegram.d.ts.map +1 -0
- package/dist/messaging/telegram.js +5 -0
- package/dist/messaging/telegram.js.map +1 -0
- package/dist/messaging/types.d.ts +22 -0
- package/dist/messaging/types.d.ts.map +1 -0
- package/dist/messaging/types.js +17 -0
- package/dist/messaging/types.js.map +1 -0
- package/dist/provision-internals.d.ts +1 -1
- package/dist/provision-internals.js +1 -1
- package/dist/provision-internals.js.map +1 -1
- package/dist/provision-runtime.d.ts +7 -0
- package/dist/provision-runtime.d.ts.map +1 -0
- package/dist/provision-runtime.js +50 -0
- package/dist/provision-runtime.js.map +1 -0
- package/dist/provision-schema.d.ts +16 -0
- package/dist/provision-schema.d.ts.map +1 -0
- package/dist/provision-schema.js +63 -0
- package/dist/provision-schema.js.map +1 -0
- package/dist/provision.d.ts +4 -21
- package/dist/provision.d.ts.map +1 -1
- package/dist/provision.js +10 -111
- package/dist/provision.js.map +1 -1
- package/dist/runtime.d.ts +17 -14
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +20 -33
- package/dist/runtime.js.map +1 -1
- package/dist/schema-export-pg.d.ts +1 -1
- package/dist/schema-export-pg.d.ts.map +1 -1
- package/dist/schema-export-pg.js +1 -1
- package/dist/schema-export-pg.js.map +1 -1
- package/dist/schema-export.d.ts +1 -1
- package/dist/schema-export.d.ts.map +1 -1
- package/dist/schema-export.js +1 -1
- package/dist/schema-export.js.map +1 -1
- package/dist/testing/fixture.d.ts +3 -3
- package/dist/testing/fixture.d.ts.map +1 -1
- package/dist/testing/fixture.js +12 -10
- package/dist/testing/fixture.js.map +1 -1
- package/dist/testing/messaging.d.ts +21 -0
- package/dist/testing/messaging.d.ts.map +1 -0
- package/dist/testing/messaging.js +34 -0
- package/dist/testing/messaging.js.map +1 -0
- package/dist/testing.d.ts +1 -0
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js.map +1 -1
- package/llms-full.txt +416 -226
- package/llms.txt +4 -3
- package/package.json +10 -2
- package/skills/creating-bunderstack-apps/references/application-structure.md +16 -7
- package/skills/creating-bunderstack-apps/references/verification.md +7 -6
- package/skills/migrating-to-bunderstack/SKILL.md +75 -51
- package/skills/migrating-to-bunderstack/references/audit-checklist.md +2 -2
- package/skills/migrating-to-bunderstack/references/runtime-replacements.md +20 -15
package/dist/email.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"email.js","sourceRoot":"","sources":["../src/email.ts"],"names":[],"mappings":"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","sourcesContent":["// src/email.ts — email sending: console / resend / custom adapters.\n// SMTP is provided by the static `bunderstack/email-smtp` factory subpath.\n\nimport { and, eq } from 'drizzle-orm'\n\nimport type { AnyDb } from './dialect'\n\nimport { emailsTableFor } from './internal-tables'\n\nexport type EmailMessage = {\n to: string | string[]\n subject: string\n html?: string\n text?: string\n from?: string\n replyTo?: string\n cc?: string | string[]\n bcc?: string | string[]\n}\n\nexport type SentEmail = { id?: string; providerId?: string }\n\ntype AdapterSentEmail = { id?: string }\n\n/** Adapters receive the message with `from` already resolved. */\nexport type EmailAdapter = {\n send(msg: EmailMessage & { from: string }): Promise<AdapterSentEmail>\n}\n\nexport type EmailConfigInput = {\n from: string\n provider?: 'resend' | 'console' | EmailAdapter | EmailAdapter['send']\n}\n\nexport type EmailFacade = {\n send(msg: EmailMessage): Promise<SentEmail>\n}\n\nexport type CreateEmailOptions = {\n env: {\n RESEND_API_KEY?: string\n SMTP_URL?: string\n NODE_ENV?: string\n BUNDERSTACK_EMAIL_PROVIDER?: string\n BUNDERSTACK_EMAIL_FROM?: string\n BUNDERHOST_ENVIRONMENT_ID?: string\n }\n /** Internal application db. Present when created through bunderstack. */\n db?: AnyDb\n /** Test seam for the resend adapter. */\n fetchFn?: typeof fetch\n /** Internal runtime substitution used by isolated test fixtures. */\n adapterOverride?: EmailAdapter\n}\n\n/** Root string provider tag ('resend' | 'console') or undefined. */\nexport function emailProviderTag(\n config: EmailConfigInput | undefined,\n): string | undefined {\n return typeof config?.provider === 'string' ? config.provider : undefined\n}\n\nconst toArray = (v: string | string[] | undefined) =>\n v === undefined ? undefined : Array.isArray(v) ? v : [v]\n\nfunction createConsoleAdapter(): EmailAdapter {\n return {\n async send(msg) {\n const line = '─'.repeat(60)\n console.log(\n [\n line,\n '📧 email (console provider — not sent)',\n `from: ${msg.from}`,\n `to: ${toArray(msg.to)!.join(', ')}`,\n `subject: ${msg.subject}`,\n line,\n msg.text ?? msg.html ?? '',\n line,\n ].join('\\n'),\n )\n return { id: '' }\n },\n }\n}\n\nconst captureAdapter: EmailAdapter = { send: async () => ({}) }\n\nfunction createResendAdapter(\n apiKey: string,\n fetchFn: typeof fetch,\n): EmailAdapter {\n return {\n async send(msg) {\n const res = await fetchFn('https://api.resend.com/emails', {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${apiKey}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n from: msg.from,\n to: toArray(msg.to),\n subject: msg.subject,\n html: msg.html,\n text: msg.text,\n reply_to: msg.replyTo,\n cc: toArray(msg.cc),\n bcc: toArray(msg.bcc),\n tags: (msg as EmailMessage & { tags?: unknown }).tags,\n }),\n })\n if (!res.ok) {\n throw new Error(`resend API error (${res.status}): ${await res.text()}`)\n }\n const data = (await res.json()) as { id?: string }\n return { id: data.id ?? '' }\n },\n }\n}\n\nfunction resolveAdapter(\n config: EmailConfigInput,\n opts: CreateEmailOptions,\n): { adapter: EmailAdapter; provider: string; capture: boolean } {\n if (opts.adapterOverride) {\n return {\n adapter: opts.adapterOverride,\n provider: 'capture',\n capture: true,\n }\n }\n const managedProvider = opts.env.BUNDERSTACK_EMAIL_PROVIDER\n const provider = managedProvider === 'resend' ? 'resend' : config.provider\n if (typeof provider === 'function') {\n return { adapter: { send: provider }, provider: 'custom', capture: false }\n }\n if (typeof provider === 'object') {\n return { adapter: provider, provider: 'custom', capture: false }\n }\n const fetchFn = opts.fetchFn ?? globalThis.fetch.bind(globalThis)\n switch (provider) {\n case 'resend':\n return {\n adapter: createResendAdapter(opts.env.RESEND_API_KEY ?? '', fetchFn),\n provider: 'resend',\n capture: false,\n }\n\n case 'console':\n return {\n adapter: createConsoleAdapter(),\n provider: 'capture',\n capture: true,\n }\n case undefined:\n return {\n adapter:\n opts.env.NODE_ENV === 'production'\n ? captureAdapter\n : createConsoleAdapter(),\n provider: 'capture',\n capture: true,\n }\n default:\n if (provider === 'smtp') {\n throw new Error(\n \"email provider 'smtp' was removed. Import `smtp` from 'bunderstack/email-smtp' instead.\",\n )\n }\n return {\n adapter: createConsoleAdapter(),\n provider: 'capture',\n capture: true,\n }\n }\n}\n\nasync function insertJournal(\n db: AnyDb | undefined,\n value: Record<string, unknown>,\n) {\n if (!db) return\n const table = emailsTableFor(db)\n await db.insert(table).values(value)\n}\n\nasync function updateJournal(\n db: AnyDb | undefined,\n id: string,\n value: Record<string, unknown>,\n expectedStatus?: string,\n) {\n if (!db) return\n const table = emailsTableFor(db)\n await db\n .update(table)\n .set(value)\n .where(\n expectedStatus\n ? and(eq(table.id, id), eq(table.status, expectedStatus))\n : eq(table.id, id),\n )\n}\n\nexport function createEmail(\n config: EmailConfigInput | undefined,\n opts: CreateEmailOptions,\n): EmailFacade {\n if (!config) {\n return {\n async send() {\n throw new Error(\n 'email is not configured — add an email key to your bunderstack config',\n )\n },\n }\n }\n const resolved = resolveAdapter(config, opts)\n return {\n async send(msg) {\n if (!msg.html && !msg.text) {\n throw new Error('email message needs html or text content')\n }\n const id = `email_${crypto.randomUUID()}`\n const now = Date.now()\n const from = opts.env.BUNDERSTACK_EMAIL_FROM ?? msg.from ?? config.from\n await insertJournal(opts.db, {\n id,\n provider: resolved.provider,\n status: resolved.capture ? 'captured' : 'sending',\n from,\n toJson: JSON.stringify(toArray(msg.to) ?? []),\n ccJson: JSON.stringify(toArray(msg.cc) ?? []),\n bccJson: JSON.stringify(toArray(msg.bcc) ?? []),\n replyTo: msg.replyTo,\n subject: msg.subject,\n html: msg.html,\n text: msg.text,\n createdAt: now,\n updatedAt: now,\n })\n if (resolved.capture) {\n await resolved.adapter.send({ ...msg, from })\n return { id }\n }\n try {\n const tags = [\n { name: 'bunderstack_email_id', value: id },\n ...(opts.env.BUNDERHOST_ENVIRONMENT_ID\n ? [\n {\n name: 'bunderhost_environment_id',\n value: opts.env.BUNDERHOST_ENVIRONMENT_ID,\n },\n ]\n : []),\n ]\n const sent = await resolved.adapter.send({\n ...msg,\n from,\n tags,\n } as EmailMessage & {\n from: string\n })\n await updateJournal(\n opts.db,\n id,\n {\n providerId: sent.id || undefined,\n status: 'sent',\n updatedAt: Date.now(),\n },\n 'sending',\n )\n return { id, providerId: sent.id || undefined }\n } catch (error) {\n await updateJournal(\n opts.db,\n id,\n {\n status: 'failed',\n error: error instanceof Error ? error.message : String(error),\n updatedAt: Date.now(),\n },\n 'sending',\n )\n throw error\n }\n },\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"email.js","sourceRoot":"","sources":["../src/email.ts"],"names":[],"mappings":"","sourcesContent":["export type EmailMessage = {\n to: string | string[]\n subject: string\n html?: string\n text?: string\n from?: string\n replyTo?: string\n cc?: string | string[]\n bcc?: string | string[]\n}\n\nexport type SentEmail = { id?: string; providerId?: string }\n\n/** Adapters receive the message with `from` already resolved. */\nexport type EmailAdapter = {\n send(msg: EmailMessage & { from: string }): Promise<{ id?: string }>\n}\n\nexport type EmailFacade = {\n send(msg: EmailMessage): Promise<SentEmail>\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { EnvConfigInput } from './env.js';
|
|
2
|
+
export declare class BlueprintProbeError extends Error {
|
|
3
|
+
constructor(key: string);
|
|
4
|
+
}
|
|
5
|
+
export declare function createEnvProbeSources(envSchema: EnvConfigInput | undefined, configured: Record<string, string | undefined>): readonly [
|
|
6
|
+
Record<string, string | undefined>,
|
|
7
|
+
Record<string, string | undefined>
|
|
8
|
+
];
|
|
9
|
+
//# sourceMappingURL=env-probe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-probe.d.ts","sourceRoot":"","sources":["../src/env-probe.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AAyB3C,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,GAAG,EAAE,MAAM;CAOxB;AAmCD,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,cAAc,GAAG,SAAS,EACrC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAC7C,SAAS;IACV,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC,CAUA"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { validateStandardSchema } from './standard-schema.js';
|
|
2
|
+
const CANDIDATES = [
|
|
3
|
+
undefined,
|
|
4
|
+
'',
|
|
5
|
+
'probe',
|
|
6
|
+
'true',
|
|
7
|
+
'false',
|
|
8
|
+
'0',
|
|
9
|
+
'1',
|
|
10
|
+
'https://example.invalid',
|
|
11
|
+
'file:./bunderstack-probe.db',
|
|
12
|
+
'probe@example.invalid',
|
|
13
|
+
'00000000-0000-4000-8000-000000000000',
|
|
14
|
+
];
|
|
15
|
+
const BASE_SOURCE = {
|
|
16
|
+
NODE_ENV: 'production',
|
|
17
|
+
AUTH_SECRET: 'bunderstack-blueprint-probe-secret',
|
|
18
|
+
DATABASE_URL: 'file:./bunderstack-blueprint-probe.db',
|
|
19
|
+
BUNDERSTACK_ROLE: 'all',
|
|
20
|
+
};
|
|
21
|
+
export class BlueprintProbeError extends Error {
|
|
22
|
+
constructor(key) {
|
|
23
|
+
super(`[bunderstack] cannot synthesize a valid blueprint probe for env key ${key}; ` +
|
|
24
|
+
'provide a valid value while generating the blueprint');
|
|
25
|
+
this.name = 'BlueprintProbeError';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function identity(value) {
|
|
29
|
+
if (value === undefined)
|
|
30
|
+
return 'undefined';
|
|
31
|
+
if (typeof value === 'number' && Number.isNaN(value))
|
|
32
|
+
return 'number:NaN';
|
|
33
|
+
try {
|
|
34
|
+
return `${typeof value}:${JSON.stringify(value)}`;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return `${typeof value}:${String(value)}`;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function acceptedValues(key, schema, configured) {
|
|
41
|
+
const accepted = [];
|
|
42
|
+
const outputs = new Set();
|
|
43
|
+
for (const candidate of [configured, ...CANDIDATES]) {
|
|
44
|
+
try {
|
|
45
|
+
const output = validateStandardSchema(schema, candidate, 'env');
|
|
46
|
+
const id = identity(output);
|
|
47
|
+
if (outputs.has(id))
|
|
48
|
+
continue;
|
|
49
|
+
outputs.add(id);
|
|
50
|
+
accepted.push(candidate);
|
|
51
|
+
if (accepted.length === 2)
|
|
52
|
+
return accepted;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// Candidate failures are expected. The eventual error names only the key.
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (accepted.length === 0)
|
|
59
|
+
throw new BlueprintProbeError(key);
|
|
60
|
+
return accepted;
|
|
61
|
+
}
|
|
62
|
+
export function createEnvProbeSources(envSchema, configured) {
|
|
63
|
+
const first = { ...BASE_SOURCE };
|
|
64
|
+
const second = { ...BASE_SOURCE };
|
|
65
|
+
const variables = { ...envSchema?.server, ...envSchema?.client };
|
|
66
|
+
for (const [key, schema] of Object.entries(variables)) {
|
|
67
|
+
const values = acceptedValues(key, schema, configured[key]);
|
|
68
|
+
first[key] = values[0];
|
|
69
|
+
second[key] = values[1] ?? values[0];
|
|
70
|
+
}
|
|
71
|
+
return [first, second];
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=env-probe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-probe.js","sourceRoot":"","sources":["../src/env-probe.ts"],"names":[],"mappings":"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","sourcesContent":["import type { StandardSchemaV1 } from '@standard-schema/spec'\n\nimport type { EnvConfigInput } from './env'\n\nimport { validateStandardSchema } from './standard-schema'\n\nconst CANDIDATES: readonly (string | undefined)[] = [\n undefined,\n '',\n 'probe',\n 'true',\n 'false',\n '0',\n '1',\n 'https://example.invalid',\n 'file:./bunderstack-probe.db',\n 'probe@example.invalid',\n '00000000-0000-4000-8000-000000000000',\n]\n\nconst BASE_SOURCE = {\n NODE_ENV: 'production',\n AUTH_SECRET: 'bunderstack-blueprint-probe-secret',\n DATABASE_URL: 'file:./bunderstack-blueprint-probe.db',\n BUNDERSTACK_ROLE: 'all',\n} satisfies Record<string, string | undefined>\n\nexport class BlueprintProbeError extends Error {\n constructor(key: string) {\n super(\n `[bunderstack] cannot synthesize a valid blueprint probe for env key ${key}; ` +\n 'provide a valid value while generating the blueprint',\n )\n this.name = 'BlueprintProbeError'\n }\n}\n\nfunction identity(value: unknown): string {\n if (value === undefined) return 'undefined'\n if (typeof value === 'number' && Number.isNaN(value)) return 'number:NaN'\n try {\n return `${typeof value}:${JSON.stringify(value)}`\n } catch {\n return `${typeof value}:${String(value)}`\n }\n}\n\nfunction acceptedValues(\n key: string,\n schema: StandardSchemaV1,\n configured: string | undefined,\n): (string | undefined)[] {\n const accepted: (string | undefined)[] = []\n const outputs = new Set<string>()\n for (const candidate of [configured, ...CANDIDATES]) {\n try {\n const output = validateStandardSchema(schema, candidate, 'env')\n const id = identity(output)\n if (outputs.has(id)) continue\n outputs.add(id)\n accepted.push(candidate)\n if (accepted.length === 2) return accepted\n } catch {\n // Candidate failures are expected. The eventual error names only the key.\n }\n }\n if (accepted.length === 0) throw new BlueprintProbeError(key)\n return accepted\n}\n\nexport function createEnvProbeSources(\n envSchema: EnvConfigInput | undefined,\n configured: Record<string, string | undefined>,\n): readonly [\n Record<string, string | undefined>,\n Record<string, string | undefined>,\n] {\n const first: Record<string, string | undefined> = { ...BASE_SOURCE }\n const second: Record<string, string | undefined> = { ...BASE_SOURCE }\n const variables = { ...envSchema?.server, ...envSchema?.client }\n for (const [key, schema] of Object.entries(variables)) {\n const values = acceptedValues(key, schema, configured[key])\n first[key] = values[0]\n second[key] = values[1] ?? values[0]\n }\n return [first, second]\n}\n"]}
|
package/dist/env.d.ts
CHANGED
|
@@ -31,9 +31,8 @@ export type BaseEnv = {
|
|
|
31
31
|
AUTH_SECRET: string;
|
|
32
32
|
REDIS_URL?: string;
|
|
33
33
|
RESEND_API_KEY?: string;
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
BUNDERSTACK_EMAIL_FROM?: string;
|
|
34
|
+
BUNDERSTACK_MESSAGING_CONFIG?: string;
|
|
35
|
+
BUNDERSTACK_BLUEPRINT_PATH?: string;
|
|
37
36
|
BUNDERHOST_ENVIRONMENT_ID?: string;
|
|
38
37
|
/** Deployed commit SHA, injected by the platform. Reported by readiness. */
|
|
39
38
|
BUNDERSTACK_REVISION?: string;
|
|
@@ -50,8 +49,6 @@ export declare class BunderstackEnvError extends Error {
|
|
|
50
49
|
constructor(issues: string[]);
|
|
51
50
|
}
|
|
52
51
|
export type ValidateEnvOptions = {
|
|
53
|
-
/** String tag of the configured email provider ('resend' | 'smtp'), if any. */
|
|
54
|
-
emailProvider?: string;
|
|
55
52
|
/** Value source; defaults to process.env. Tests pass this explicitly. */
|
|
56
53
|
source?: Record<string, string | undefined>;
|
|
57
54
|
/** Dialect-aware DATABASE_URL fallback; bunderstack passes it. */
|
package/dist/env.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAO7D,eAAO,MAAM,aAAa,EAAG,SAAkB,CAAA;AAE/C;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;IACzC,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;CAClC,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAA;AAItD,0DAA0D;AAC1D,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAO7D,eAAO,MAAM,aAAa,EAAG,SAAkB,CAAA;AAE/C;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;IACzC,2EAA2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,gEAAgE;IAChE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;CAClC,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAA;AAItD,0DAA0D;AAC1D,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,4BAA4B,CAAC,EAAE,MAAM,CAAA;IACrC,0BAA0B,CAAC,EAAE,MAAM,CAAA;IACnC,yBAAyB,CAAC,EAAE,MAAM,CAAA;IAClC,4EAA4E;IAC5E,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,gBAAgB,EAAE,eAAe,CAAA;CAClC,CAAA;AAED,KAAK,SAAS,CAAC,CAAC,IACd,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GACtC;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,GACtD,OAAO,CAAA;AAGb,MAAM,MAAM,YAAY,CAAC,IAAI,SAAS,cAAc,GAAG,SAAS,IAAI;IAClE,IAAI;CACL,SAAS,CAAC,cAAc,CAAC,GACtB,OAAO,GACL,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,GACtC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,GACxC,OAAO,CAAA;AAEX,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAA;gBAEb,MAAM,EAAE,MAAM,EAAE;CAK7B;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;IAC3C,kEAAkE;IAClE,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B,CAAA;AAqCD,wBAAgB,WAAW,CAAC,IAAI,SAAS,cAAc,GAAG,SAAS,EACjE,SAAS,EAAE,IAAI,EACf,OAAO,GAAE,kBAAuB,GAC/B,YAAY,CAAC,IAAI,CAAC,CAqCpB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,SAAS,cAAc,EACzD,SAAS,EAAE,IAAI,GACd,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAsB3B"}
|
package/dist/env.js
CHANGED
|
@@ -45,9 +45,8 @@ export function validateEnv(envConfig, options = {}) {
|
|
|
45
45
|
AUTH_SECRET: source.AUTH_SECRET ?? DEV_AUTH_SECRET,
|
|
46
46
|
REDIS_URL: source.REDIS_URL,
|
|
47
47
|
RESEND_API_KEY: source.RESEND_API_KEY,
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
BUNDERSTACK_EMAIL_FROM: source.BUNDERSTACK_EMAIL_FROM,
|
|
48
|
+
BUNDERSTACK_MESSAGING_CONFIG: source.BUNDERSTACK_MESSAGING_CONFIG,
|
|
49
|
+
BUNDERSTACK_BLUEPRINT_PATH: source.BUNDERSTACK_BLUEPRINT_PATH,
|
|
51
50
|
BUNDERHOST_ENVIRONMENT_ID: source.BUNDERHOST_ENVIRONMENT_ID,
|
|
52
51
|
BUNDERSTACK_REVISION: source.BUNDERSTACK_REVISION,
|
|
53
52
|
BUNDERSTACK_ROLE: (source.BUNDERSTACK_ROLE ?? 'all'),
|
|
@@ -59,12 +58,6 @@ export function validateEnv(envConfig, options = {}) {
|
|
|
59
58
|
!ROLES.includes(source.BUNDERSTACK_ROLE)) {
|
|
60
59
|
issues.push(`BUNDERSTACK_ROLE: must be one of ${ROLES.join(', ')} (got "${String(source.BUNDERSTACK_ROLE)}")`);
|
|
61
60
|
}
|
|
62
|
-
if (options.emailProvider === 'resend' && !source.RESEND_API_KEY) {
|
|
63
|
-
issues.push("RESEND_API_KEY: required when email provider is 'resend'");
|
|
64
|
-
}
|
|
65
|
-
if (options.emailProvider === 'smtp' && !source.SMTP_URL) {
|
|
66
|
-
issues.push("SMTP_URL: required when email provider is 'smtp'");
|
|
67
|
-
}
|
|
68
61
|
const userVars = {};
|
|
69
62
|
validateSection(envConfig?.server, 'server', source, issues, userVars);
|
|
70
63
|
validateSection(envConfig?.client, 'client', source, issues, userVars);
|
package/dist/env.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"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","sourcesContent":["// src/env.ts — env validation. Browser-safe: type-only Standard Schema import.\nimport type { StandardSchemaV1 } from '@standard-schema/spec'\n\nimport {\n StandardSchemaValidationError,\n validateStandardSchema,\n} from './standard-schema'\n\nexport const CLIENT_PREFIX = 'PUBLIC_' as const\n\n/**\n * Static, value-free metadata about an environment key. It reaches the manifest\n * and the committed blueprint, so it must never contain a value or a secret.\n */\nexport type EnvVarMeta = {\n /**\n * Whether the value is a secret. Defaults to `true` for server keys and\n * `false` for client keys. A client key can never be sensitive: `PUBLIC_*`\n * values are compiled into the browser bundle.\n */\n sensitive?: boolean\n /** Prose shown to whoever fills this key in. Max 200 characters. */\n description?: string\n}\n\nexport type EnvConfigInput = {\n server?: Record<string, StandardSchemaV1>\n client?: Record<string, StandardSchemaV1>\n /** Explicit value source for client vars (e.g. Vite's import.meta.env). */\n runtimeEnv?: Record<string, unknown>\n /** Value-free metadata per key, keyed by the key's own name. */\n meta?: Record<string, EnvVarMeta>\n}\n\nexport type BunderstackRole = 'all' | 'web' | 'worker'\n\nconst ROLES: readonly BunderstackRole[] = ['all', 'web', 'worker']\n\n/** Vars bunderstack itself consumes, always validated. */\nexport type BaseEnv = {\n NODE_ENV?: string\n DATABASE_URL: string\n DATABASE_AUTH_TOKEN?: string\n AUTH_SECRET: string\n REDIS_URL?: string\n RESEND_API_KEY?: string\n SMTP_URL?: string\n BUNDERSTACK_EMAIL_PROVIDER?: string\n BUNDERSTACK_EMAIL_FROM?: string\n BUNDERHOST_ENVIRONMENT_ID?: string\n /** Deployed commit SHA, injected by the platform. Reported by readiness. */\n BUNDERSTACK_REVISION?: string\n BUNDERSTACK_ROLE: BunderstackRole\n}\n\ntype InferVars<T> =\n T extends Record<string, StandardSchemaV1>\n ? { [K in keyof T]: StandardSchemaV1.InferOutput<T[K]> }\n : unknown\n\n// Non-distributive so `ValidatedEnv<undefined>` is BaseEnv, not `never`.\nexport type ValidatedEnv<TEnv extends EnvConfigInput | undefined> = [\n TEnv,\n] extends [EnvConfigInput]\n ? BaseEnv &\n InferVars<NonNullable<TEnv>['server']> &\n InferVars<NonNullable<TEnv>['client']>\n : BaseEnv\n\nexport class BunderstackEnvError extends Error {\n readonly issues: string[]\n\n constructor(issues: string[]) {\n super(`Invalid environment:\\n - ${issues.join('\\n - ')}`)\n this.name = 'BunderstackEnvError'\n this.issues = issues\n }\n}\n\nexport type ValidateEnvOptions = {\n /** String tag of the configured email provider ('resend' | 'smtp'), if any. */\n emailProvider?: string\n /** Value source; defaults to process.env. Tests pass this explicitly. */\n source?: Record<string, string | undefined>\n /** Dialect-aware DATABASE_URL fallback; bunderstack passes it. */\n defaultDatabaseUrl?: string\n}\n\nconst DEV_AUTH_SECRET = 'dev-secret-change-in-prod'\n\nfunction validateSection(\n section: Record<string, StandardSchemaV1> | undefined,\n kind: 'server' | 'client',\n source: Record<string, unknown>,\n issues: string[],\n out: Record<string, unknown>,\n) {\n for (const [key, schema] of Object.entries(section ?? {})) {\n const isPublic = key.startsWith(CLIENT_PREFIX)\n if (kind === 'server' && isPublic) {\n issues.push(\n `${key}: server vars must not start with ${CLIENT_PREFIX} (move it to env.client)`,\n )\n continue\n }\n if (kind === 'client' && !isPublic) {\n issues.push(\n `${key}: client vars must start with ${CLIENT_PREFIX} (rename it or move it to env.server)`,\n )\n continue\n }\n try {\n out[key] = validateStandardSchema(schema, source[key], 'env')\n } catch (error) {\n if (!(error instanceof StandardSchemaValidationError)) throw error\n for (const issue of error.issues) {\n const path = issue.path.map(String).join('.')\n issues.push(`${key}${path ? `.${path}` : ''}: ${issue.message}`)\n }\n }\n }\n}\n\nexport function validateEnv<TEnv extends EnvConfigInput | undefined>(\n envConfig: TEnv,\n options: ValidateEnvOptions = {},\n): ValidatedEnv<TEnv> {\n const source =\n options.source ?? (process.env as Record<string, string | undefined>)\n const issues: string[] = []\n const isProduction = source.NODE_ENV === 'production'\n\n const base: BaseEnv = {\n NODE_ENV: source.NODE_ENV,\n DATABASE_URL:\n source.DATABASE_URL ?? options.defaultDatabaseUrl ?? 'file:./data.db',\n DATABASE_AUTH_TOKEN: source.DATABASE_AUTH_TOKEN,\n AUTH_SECRET: source.AUTH_SECRET ?? DEV_AUTH_SECRET,\n REDIS_URL: source.REDIS_URL,\n RESEND_API_KEY: source.RESEND_API_KEY,\n SMTP_URL: source.SMTP_URL,\n BUNDERSTACK_EMAIL_PROVIDER: source.BUNDERSTACK_EMAIL_PROVIDER,\n BUNDERSTACK_EMAIL_FROM: source.BUNDERSTACK_EMAIL_FROM,\n BUNDERHOST_ENVIRONMENT_ID: source.BUNDERHOST_ENVIRONMENT_ID,\n BUNDERSTACK_REVISION: source.BUNDERSTACK_REVISION,\n BUNDERSTACK_ROLE: (source.BUNDERSTACK_ROLE ?? 'all') as BunderstackRole,\n }\n if (isProduction && !source.AUTH_SECRET) {\n issues.push('AUTH_SECRET: required in production')\n }\n if (\n source.BUNDERSTACK_ROLE !== undefined &&\n !ROLES.includes(source.BUNDERSTACK_ROLE as BunderstackRole)\n ) {\n issues.push(\n `BUNDERSTACK_ROLE: must be one of ${ROLES.join(', ')} (got \"${String(source.BUNDERSTACK_ROLE)}\")`,\n )\n }\n if (options.emailProvider === 'resend' && !source.RESEND_API_KEY) {\n issues.push(\"RESEND_API_KEY: required when email provider is 'resend'\")\n }\n if (options.emailProvider === 'smtp' && !source.SMTP_URL) {\n issues.push(\"SMTP_URL: required when email provider is 'smtp'\")\n }\n\n const userVars: Record<string, unknown> = {}\n validateSection(envConfig?.server, 'server', source, issues, userVars)\n validateSection(envConfig?.client, 'client', source, issues, userVars)\n\n if (issues.length > 0) throw new BunderstackEnvError(issues)\n return { ...base, ...userVars } as ValidatedEnv<TEnv>\n}\n\n/**\n * Browser-side companion (t3-env style): validates ONLY the client section.\n * Server keys exist on the returned object as traps that throw on access, so\n * a leaked import fails loudly instead of silently reading undefined.\n */\nexport function createClientEnv<TEnv extends EnvConfigInput>(\n envConfig: TEnv,\n): InferVars<TEnv['client']> {\n const source =\n envConfig.runtimeEnv ??\n (typeof process !== 'undefined'\n ? (process.env as Record<string, unknown>)\n : {})\n const issues: string[] = []\n const values: Record<string, unknown> = {}\n validateSection(envConfig.client, 'client', source, issues, values)\n if (issues.length > 0) throw new BunderstackEnvError(issues)\n\n const serverKeys = new Set(Object.keys(envConfig.server ?? {}))\n return new Proxy(values, {\n get(target, prop) {\n if (typeof prop === 'string' && serverKeys.has(prop)) {\n throw new Error(\n `${prop} is server-only and not available in client env`,\n )\n }\n return Reflect.get(target, prop)\n },\n }) as InferVars<TEnv['client']>\n}\n"]}
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"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","sourcesContent":["// src/env.ts — env validation. Browser-safe: type-only Standard Schema import.\nimport type { StandardSchemaV1 } from '@standard-schema/spec'\n\nimport {\n StandardSchemaValidationError,\n validateStandardSchema,\n} from './standard-schema'\n\nexport const CLIENT_PREFIX = 'PUBLIC_' as const\n\n/**\n * Static, value-free metadata about an environment key. It reaches the manifest\n * and the committed blueprint, so it must never contain a value or a secret.\n */\nexport type EnvVarMeta = {\n /**\n * Whether the value is a secret. Defaults to `true` for server keys and\n * `false` for client keys. A client key can never be sensitive: `PUBLIC_*`\n * values are compiled into the browser bundle.\n */\n sensitive?: boolean\n /** Prose shown to whoever fills this key in. Max 200 characters. */\n description?: string\n}\n\nexport type EnvConfigInput = {\n server?: Record<string, StandardSchemaV1>\n client?: Record<string, StandardSchemaV1>\n /** Explicit value source for client vars (e.g. Vite's import.meta.env). */\n runtimeEnv?: Record<string, unknown>\n /** Value-free metadata per key, keyed by the key's own name. */\n meta?: Record<string, EnvVarMeta>\n}\n\nexport type BunderstackRole = 'all' | 'web' | 'worker'\n\nconst ROLES: readonly BunderstackRole[] = ['all', 'web', 'worker']\n\n/** Vars bunderstack itself consumes, always validated. */\nexport type BaseEnv = {\n NODE_ENV?: string\n DATABASE_URL: string\n DATABASE_AUTH_TOKEN?: string\n AUTH_SECRET: string\n REDIS_URL?: string\n RESEND_API_KEY?: string\n BUNDERSTACK_MESSAGING_CONFIG?: string\n BUNDERSTACK_BLUEPRINT_PATH?: string\n BUNDERHOST_ENVIRONMENT_ID?: string\n /** Deployed commit SHA, injected by the platform. Reported by readiness. */\n BUNDERSTACK_REVISION?: string\n BUNDERSTACK_ROLE: BunderstackRole\n}\n\ntype InferVars<T> =\n T extends Record<string, StandardSchemaV1>\n ? { [K in keyof T]: StandardSchemaV1.InferOutput<T[K]> }\n : unknown\n\n// Non-distributive so `ValidatedEnv<undefined>` is BaseEnv, not `never`.\nexport type ValidatedEnv<TEnv extends EnvConfigInput | undefined> = [\n TEnv,\n] extends [EnvConfigInput]\n ? BaseEnv &\n InferVars<NonNullable<TEnv>['server']> &\n InferVars<NonNullable<TEnv>['client']>\n : BaseEnv\n\nexport class BunderstackEnvError extends Error {\n readonly issues: string[]\n\n constructor(issues: string[]) {\n super(`Invalid environment:\\n - ${issues.join('\\n - ')}`)\n this.name = 'BunderstackEnvError'\n this.issues = issues\n }\n}\n\nexport type ValidateEnvOptions = {\n /** Value source; defaults to process.env. Tests pass this explicitly. */\n source?: Record<string, string | undefined>\n /** Dialect-aware DATABASE_URL fallback; bunderstack passes it. */\n defaultDatabaseUrl?: string\n}\n\nconst DEV_AUTH_SECRET = 'dev-secret-change-in-prod'\n\nfunction validateSection(\n section: Record<string, StandardSchemaV1> | undefined,\n kind: 'server' | 'client',\n source: Record<string, unknown>,\n issues: string[],\n out: Record<string, unknown>,\n) {\n for (const [key, schema] of Object.entries(section ?? {})) {\n const isPublic = key.startsWith(CLIENT_PREFIX)\n if (kind === 'server' && isPublic) {\n issues.push(\n `${key}: server vars must not start with ${CLIENT_PREFIX} (move it to env.client)`,\n )\n continue\n }\n if (kind === 'client' && !isPublic) {\n issues.push(\n `${key}: client vars must start with ${CLIENT_PREFIX} (rename it or move it to env.server)`,\n )\n continue\n }\n try {\n out[key] = validateStandardSchema(schema, source[key], 'env')\n } catch (error) {\n if (!(error instanceof StandardSchemaValidationError)) throw error\n for (const issue of error.issues) {\n const path = issue.path.map(String).join('.')\n issues.push(`${key}${path ? `.${path}` : ''}: ${issue.message}`)\n }\n }\n }\n}\n\nexport function validateEnv<TEnv extends EnvConfigInput | undefined>(\n envConfig: TEnv,\n options: ValidateEnvOptions = {},\n): ValidatedEnv<TEnv> {\n const source =\n options.source ?? (process.env as Record<string, string | undefined>)\n const issues: string[] = []\n const isProduction = source.NODE_ENV === 'production'\n\n const base: BaseEnv = {\n NODE_ENV: source.NODE_ENV,\n DATABASE_URL:\n source.DATABASE_URL ?? options.defaultDatabaseUrl ?? 'file:./data.db',\n DATABASE_AUTH_TOKEN: source.DATABASE_AUTH_TOKEN,\n AUTH_SECRET: source.AUTH_SECRET ?? DEV_AUTH_SECRET,\n REDIS_URL: source.REDIS_URL,\n RESEND_API_KEY: source.RESEND_API_KEY,\n BUNDERSTACK_MESSAGING_CONFIG: source.BUNDERSTACK_MESSAGING_CONFIG,\n BUNDERSTACK_BLUEPRINT_PATH: source.BUNDERSTACK_BLUEPRINT_PATH,\n BUNDERHOST_ENVIRONMENT_ID: source.BUNDERHOST_ENVIRONMENT_ID,\n BUNDERSTACK_REVISION: source.BUNDERSTACK_REVISION,\n BUNDERSTACK_ROLE: (source.BUNDERSTACK_ROLE ?? 'all') as BunderstackRole,\n }\n if (isProduction && !source.AUTH_SECRET) {\n issues.push('AUTH_SECRET: required in production')\n }\n if (\n source.BUNDERSTACK_ROLE !== undefined &&\n !ROLES.includes(source.BUNDERSTACK_ROLE as BunderstackRole)\n ) {\n issues.push(\n `BUNDERSTACK_ROLE: must be one of ${ROLES.join(', ')} (got \"${String(source.BUNDERSTACK_ROLE)}\")`,\n )\n }\n const userVars: Record<string, unknown> = {}\n validateSection(envConfig?.server, 'server', source, issues, userVars)\n validateSection(envConfig?.client, 'client', source, issues, userVars)\n\n if (issues.length > 0) throw new BunderstackEnvError(issues)\n return { ...base, ...userVars } as ValidatedEnv<TEnv>\n}\n\n/**\n * Browser-side companion (t3-env style): validates ONLY the client section.\n * Server keys exist on the returned object as traps that throw on access, so\n * a leaked import fails loudly instead of silently reading undefined.\n */\nexport function createClientEnv<TEnv extends EnvConfigInput>(\n envConfig: TEnv,\n): InferVars<TEnv['client']> {\n const source =\n envConfig.runtimeEnv ??\n (typeof process !== 'undefined'\n ? (process.env as Record<string, unknown>)\n : {})\n const issues: string[] = []\n const values: Record<string, unknown> = {}\n validateSection(envConfig.client, 'client', source, issues, values)\n if (issues.length > 0) throw new BunderstackEnvError(issues)\n\n const serverKeys = new Set(Object.keys(envConfig.server ?? {}))\n return new Proxy(values, {\n get(target, prop) {\n if (typeof prop === 'string' && serverKeys.has(prop)) {\n throw new Error(\n `${prop} is server-only and not available in client env`,\n )\n }\n return Reflect.get(target, prop)\n },\n }) as InferVars<TEnv['client']>\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BunderstackManifest } from './manifest.js';
|
|
2
|
+
export declare class HostedBlueprintMismatchError extends Error {
|
|
3
|
+
constructor(paths: readonly {
|
|
4
|
+
kind: string;
|
|
5
|
+
path: string;
|
|
6
|
+
}[]);
|
|
7
|
+
}
|
|
8
|
+
export declare function manifestFromBlueprint(source: string): BunderstackManifest;
|
|
9
|
+
export declare function assertManifestMatchesBlueprint(manifest: BunderstackManifest, source: string): void;
|
|
10
|
+
export declare function assertHostedBlueprintFile(manifest: BunderstackManifest, path: string): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=hosted-contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosted-contract.d.ts","sourceRoot":"","sources":["../src/hosted-contract.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAKrD,qBAAa,4BAA6B,SAAQ,KAAK;gBACzC,KAAK,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE;CAO7D;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,CAuBzE;AAED,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,mBAAmB,EAC7B,MAAM,EAAE,MAAM,GACb,IAAI,CAIN;AAED,wBAAsB,yBAAyB,CAC7C,QAAQ,EAAE,mBAAmB,EAC7B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAMf"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { parseBlueprintYaml } from './blueprint.js';
|
|
2
|
+
import { diffManifests } from './manifest-diff.js';
|
|
3
|
+
export class HostedBlueprintMismatchError extends Error {
|
|
4
|
+
constructor(paths) {
|
|
5
|
+
super('[bunderstack] runtime declaration does not match the committed blueprint:\n' +
|
|
6
|
+
paths.map(({ kind, path }) => ` - ${kind}: ${path}`).join('\n'));
|
|
7
|
+
this.name = 'HostedBlueprintMismatchError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export function manifestFromBlueprint(source) {
|
|
11
|
+
const blueprint = parseBlueprintYaml(source);
|
|
12
|
+
return {
|
|
13
|
+
version: blueprint.bunderstack.manifestVersion,
|
|
14
|
+
database: {
|
|
15
|
+
dialect: blueprint.resources.database.dialect,
|
|
16
|
+
migrationsDirectory: blueprint.resources.database.migrationsDirectory,
|
|
17
|
+
tables: blueprint.resources.database.tables,
|
|
18
|
+
},
|
|
19
|
+
storage: blueprint.resources.storage,
|
|
20
|
+
realtime: blueprint.resources.realtime ?? { required: false },
|
|
21
|
+
messaging: blueprint.resources.messaging,
|
|
22
|
+
environment: blueprint.environment.map((entry) => ({
|
|
23
|
+
...entry,
|
|
24
|
+
sensitive: entry.sensitive ?? entry.scope === 'server',
|
|
25
|
+
})),
|
|
26
|
+
api: blueprint.api ?? { operations: [] },
|
|
27
|
+
background: {
|
|
28
|
+
jobs: blueprint.background.jobs,
|
|
29
|
+
cron: blueprint.background.cron,
|
|
30
|
+
maintenance: blueprint.background.maintenance,
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export function assertManifestMatchesBlueprint(manifest, source) {
|
|
35
|
+
const differences = diffManifests(manifestFromBlueprint(source), manifest);
|
|
36
|
+
if (differences.length > 0)
|
|
37
|
+
throw new HostedBlueprintMismatchError(differences);
|
|
38
|
+
}
|
|
39
|
+
export async function assertHostedBlueprintFile(manifest, path) {
|
|
40
|
+
const file = Bun.file(path);
|
|
41
|
+
if (!(await file.exists())) {
|
|
42
|
+
throw new Error(`[bunderstack] hosted blueprint does not exist: ${path}`);
|
|
43
|
+
}
|
|
44
|
+
assertManifestMatchesBlueprint(manifest, await file.text());
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=hosted-contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosted-contract.js","sourceRoot":"","sources":["../src/hosted-contract.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAE/C,MAAM,OAAO,4BAA6B,SAAQ,KAAK;IACrD,YAAY,KAAgD;QAC1D,KAAK,CACH,6EAA6E;YAC3E,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CACnE,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAA;IAC5C,CAAC;CACF;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAc;IAClD,MAAM,SAAS,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAA;IAC5C,OAAO;QACL,OAAO,EAAE,SAAS,CAAC,WAAW,CAAC,eAAe;QAC9C,QAAQ,EAAE;YACR,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO;YAC7C,mBAAmB,EAAE,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,mBAAmB;YACrE,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM;SAC5C;QACD,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,OAAO;QACpC,QAAQ,EAAE,SAAS,CAAC,SAAS,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE;QAC7D,SAAS,EAAE,SAAS,CAAC,SAAS,CAAC,SAAS;QACxC,WAAW,EAAE,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACjD,GAAG,KAAK;YACR,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ;SACvD,CAAC,CAAC;QACH,GAAG,EAAE,SAAS,CAAC,GAAG,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE;QACxC,UAAU,EAAE;YACV,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC,IAAI;YAC/B,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC,IAAI;YAC/B,WAAW,EAAE,SAAS,CAAC,UAAU,CAAC,WAAW;SAC9C;KACF,CAAA;AACH,CAAC;AAED,MAAM,UAAU,8BAA8B,CAC5C,QAA6B,EAC7B,MAAc;IAEd,MAAM,WAAW,GAAG,aAAa,CAAC,qBAAqB,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAAA;IAC1E,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC;QACxB,MAAM,IAAI,4BAA4B,CAAC,WAAW,CAAC,CAAA;AACvD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,QAA6B,EAC7B,IAAY;IAEZ,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC3B,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,kDAAkD,IAAI,EAAE,CAAC,CAAA;IAC3E,CAAC;IACD,8BAA8B,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;AAC7D,CAAC","sourcesContent":["import type { BunderstackManifest } from './manifest'\n\nimport { parseBlueprintYaml } from './blueprint'\nimport { diffManifests } from './manifest-diff'\n\nexport class HostedBlueprintMismatchError extends Error {\n constructor(paths: readonly { kind: string; path: string }[]) {\n super(\n '[bunderstack] runtime declaration does not match the committed blueprint:\\n' +\n paths.map(({ kind, path }) => ` - ${kind}: ${path}`).join('\\n'),\n )\n this.name = 'HostedBlueprintMismatchError'\n }\n}\n\nexport function manifestFromBlueprint(source: string): BunderstackManifest {\n const blueprint = parseBlueprintYaml(source)\n return {\n version: blueprint.bunderstack.manifestVersion,\n database: {\n dialect: blueprint.resources.database.dialect,\n migrationsDirectory: blueprint.resources.database.migrationsDirectory,\n tables: blueprint.resources.database.tables,\n },\n storage: blueprint.resources.storage,\n realtime: blueprint.resources.realtime ?? { required: false },\n messaging: blueprint.resources.messaging,\n environment: blueprint.environment.map((entry) => ({\n ...entry,\n sensitive: entry.sensitive ?? entry.scope === 'server',\n })),\n api: blueprint.api ?? { operations: [] },\n background: {\n jobs: blueprint.background.jobs,\n cron: blueprint.background.cron,\n maintenance: blueprint.background.maintenance,\n },\n }\n}\n\nexport function assertManifestMatchesBlueprint(\n manifest: BunderstackManifest,\n source: string,\n): void {\n const differences = diffManifests(manifestFromBlueprint(source), manifest)\n if (differences.length > 0)\n throw new HostedBlueprintMismatchError(differences)\n}\n\nexport async function assertHostedBlueprintFile(\n manifest: BunderstackManifest,\n path: string,\n): Promise<void> {\n const file = Bun.file(path)\n if (!(await file.exists())) {\n throw new Error(`[bunderstack] hosted blueprint does not exist: ${path}`)\n }\n assertManifestMatchesBlueprint(manifest, await file.text())\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export * from './backend.js';
|
|
2
|
+
export { createMessaging, resend, customEmail, telegram } from './messaging/index.js';
|
|
3
|
+
export type { MessagingConfig, MessagingDescriptor, MessagingFacade, MessagingFacades, TelegramMessage, } from './messaging/index.js';
|
|
2
4
|
export type { AppRunWorkerOptions, AppStartWorkerOptions, AuthInstance, BucketNamesOf, BunderstackApp, StorageFacade, } from './runtime.js';
|
|
3
5
|
export { listSpec } from './api/list-spec.js';
|
|
4
6
|
export type { ListSpecOptions } from './api/list-spec.js';
|
|
@@ -14,8 +16,7 @@ export { buildManifest, parseManifest } from './manifest.js';
|
|
|
14
16
|
export type { ApiOperation, ApiOperationEffect, BunderstackManifest, ManifestEnvVar, } from './manifest.js';
|
|
15
17
|
export { buildReadinessReport, readinessReportSchema } from './readiness.js';
|
|
16
18
|
export type { ReadinessCheck, ReadinessCheckName, ReadinessCode, ReadinessReport, ReadinessStatus, } from './readiness.js';
|
|
17
|
-
export {
|
|
18
|
-
export type { EmailMessage, EmailAdapter, EmailConfigInput, EmailFacade, } from './email.js';
|
|
19
|
+
export type { EmailMessage, EmailAdapter } from './email.js';
|
|
19
20
|
export { createJobsBuilder } from './jobs/index.js';
|
|
20
21
|
export type { BunderstackJobContext, BunderstackJobsBuilder, BackgroundDefinition, BackgroundDefs, CronDefinition, CronInvocation, EnqueueOptions, JobContext, JobDefinition, JobsDefs, JobsFacade, JobsRuntimeFacade, QueueJobDefinition, QueueJobKeys, RunWorkerOptions, StartWorkerOptions, WorkerHandle, } from './jobs/index.js';
|
|
21
22
|
export { defineAccess, validateAndResolveAccess, checkAccess, AUTH_TABLE_NAMES, } from './access.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,YAAY,EACV,mBAAmB,EACnB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,cAAc,EACd,aAAa,GACd,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACtD,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,MAAM,CAAA;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAC3C,YAAY,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACvE,YAAY,EACV,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,GACf,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,OAAO,CAAA;AACzE,YAAY,EAAE,cAAc,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAA;AAClE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACzD,YAAY,EACV,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,GACf,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AACzE,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,eAAe,GAChB,MAAM,aAAa,CAAA;AACpB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from './backend.js';
|
|
2
|
+
export { createMessaging, resend, customEmail, telegram } from './messaging/index.js';
|
|
2
3
|
export { listSpec } from './api/list-spec.js';
|
|
3
4
|
export { MAX_LIST_LIMIT } from './list-query.js';
|
|
4
5
|
export { BunderstackError } from './errors.js';
|
|
@@ -6,7 +7,6 @@ export { resolveConfig, resolveAuthConfig, defineAuth } from './config.js';
|
|
|
6
7
|
export { validateEnv, createClientEnv, BunderstackEnvError } from './env.js';
|
|
7
8
|
export { buildManifest, parseManifest } from './manifest.js';
|
|
8
9
|
export { buildReadinessReport, readinessReportSchema } from './readiness.js';
|
|
9
|
-
export { createEmail } from './email.js';
|
|
10
10
|
export { createJobsBuilder } from './jobs/index.js';
|
|
11
11
|
export { defineAccess, validateAndResolveAccess, checkAccess, AUTH_TABLE_NAMES, } from './access.js';
|
|
12
12
|
export { typeid, generate as generateTypeId, parse as parseTypeId, asTypeId, } from './typeid.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAA;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAgB5E,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAG1C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAE3C,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AASvE,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,OAAO,CAAA;AAEzE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAOzD,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AASzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAoBhD,OAAO,EACL,YAAY,EACZ,wBAAwB,EACxB,WAAW,EACX,gBAAgB,GACjB,MAAM,UAAU,CAAA;AAOjB,OAAO,EACL,MAAM,EACN,QAAQ,IAAI,cAAc,EAC1B,KAAK,IAAI,WAAW,EACpB,QAAQ,GACT,MAAM,UAAU,CAAA;AAejB,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAMxD,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAU3D,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,2BAA2B,GAC5B,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA","sourcesContent":["export * from './backend'\nexport { createMessaging, resend, customEmail, telegram } from './messaging'\nexport type {\n MessagingConfig,\n MessagingDescriptor,\n MessagingFacade,\n MessagingFacades,\n TelegramMessage,\n} from './messaging'\nexport type {\n AppRunWorkerOptions,\n AppStartWorkerOptions,\n AuthInstance,\n BucketNamesOf,\n BunderstackApp,\n StorageFacade,\n} from './runtime'\nexport { listSpec } from './api/list-spec'\nexport type { ListSpecOptions } from './api/list-spec'\nexport type { BunderstackDb, BunderstackTx } from './db'\nexport { MAX_LIST_LIMIT } from './list-query'\nexport { BunderstackError } from './errors'\nexport type { BunderstackErrorCode } from './errors'\nexport { resolveConfig, resolveAuthConfig, defineAuth } from './config'\nexport type {\n AuthConfigContext,\n AuthConfigFactory,\n AuthConfigInput,\n BetterAuthConfig,\n BunderstackConfig,\n ResolvedConfig,\n} from './config'\nexport { validateEnv, createClientEnv, BunderstackEnvError } from './env'\nexport type { EnvConfigInput, BaseEnv, ValidatedEnv } from './env'\nexport { buildManifest, parseManifest } from './manifest'\nexport type {\n ApiOperation,\n ApiOperationEffect,\n BunderstackManifest,\n ManifestEnvVar,\n} from './manifest'\nexport { buildReadinessReport, readinessReportSchema } from './readiness'\nexport type {\n ReadinessCheck,\n ReadinessCheckName,\n ReadinessCode,\n ReadinessReport,\n ReadinessStatus,\n} from './readiness'\nexport type { EmailMessage, EmailAdapter } from './email'\nexport { createJobsBuilder } from './jobs/index'\nexport type {\n BunderstackJobContext,\n BunderstackJobsBuilder,\n BackgroundDefinition,\n BackgroundDefs,\n CronDefinition,\n CronInvocation,\n EnqueueOptions,\n JobContext,\n JobDefinition,\n JobsDefs,\n JobsFacade,\n JobsRuntimeFacade,\n QueueJobDefinition,\n QueueJobKeys,\n RunWorkerOptions,\n StartWorkerOptions,\n WorkerHandle,\n} from './jobs/index'\nexport {\n defineAccess,\n validateAndResolveAccess,\n checkAccess,\n AUTH_TABLE_NAMES,\n} from './access'\nexport type {\n TableAccessInput,\n OperationRule,\n AccessContext,\n AccessUser,\n} from './access'\nexport {\n typeid,\n generate as generateTypeId,\n parse as parseTypeId,\n asTypeId,\n} from './typeid'\nexport type { TypeId } from './typeid'\nexport type {\n DatabaseAdapter,\n DatabaseConnection,\n DatabaseConnectionResult,\n} from './database/adapter'\nexport type { StorageAdapter } from './storage/index'\nexport type {\n StorageConfigInput,\n BucketConfigInput,\n ResolvedBucket,\n} from './storage/buckets'\nexport type { TransformSpec } from './storage/thumbnails'\nexport type { RealtimeAction } from './realtime/publisher'\nexport { createRealtimeFacade } from './realtime/facade'\nexport type {\n RealtimeFacade,\n RealtimeTransport,\n SchemaTable,\n} from './realtime/facade'\nexport { createApiBuilder, defineApi } from './api/builder'\nexport type { BunderstackApiBuilder, ApiFactory } from './api/builder'\nexport type { ApiContext } from './api/context'\nexport type {\n CrudApiRouterFor,\n ExposedApiTables,\n MergeApiRouterTypes,\n UnifiedApiRouter,\n} from './api/types'\nexport type { TableCrudProcedures } from './api/crud-router'\nexport {\n buildApiRegistry,\n mergeApiRoutersStrict,\n normalizeApiPath,\n normalizeForeignOpenAPISpec,\n} from './api/registry'\nexport { mergeOpenAPISpecs } from './api/openapi'\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AnyRouter } from '@orpc/server';
|
|
2
|
+
import type { BunderstackDefinitionConfig } from './backend.js';
|
|
3
|
+
import type { BaseEnv, EnvConfigInput } from './env.js';
|
|
4
|
+
import type { JobsDefs } from './jobs/index.js';
|
|
5
|
+
import type { BunderstackManifest } from './manifest.js';
|
|
6
|
+
export type AnyDefinitionConfig = BunderstackDefinitionConfig<Record<string, unknown>, any, any, any, any, any, any, any>;
|
|
7
|
+
export type InspectedDefinition = {
|
|
8
|
+
readonly config: AnyDefinitionConfig;
|
|
9
|
+
readonly jobsDefs: JobsDefs | undefined;
|
|
10
|
+
readonly customApiRouter: AnyRouter | undefined;
|
|
11
|
+
readonly manifest: BunderstackManifest;
|
|
12
|
+
readonly env: BaseEnv;
|
|
13
|
+
};
|
|
14
|
+
export declare function inspectConfig(input: AnyDefinitionConfig, envConfig: EnvConfigInput | undefined, env: BaseEnv): InspectedDefinition;
|
|
15
|
+
//# sourceMappingURL=inspect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../src/inspect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAE7C,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,WAAW,CAAA;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,OAAO,CAAA;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AACtC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAarD,MAAM,MAAM,mBAAmB,GAAG,2BAA2B,CAC3D,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvB,GAAG,EACH,GAAG,EACH,GAAG,EACH,GAAG,EACH,GAAG,EACH,GAAG,EACH,GAAG,CACJ,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAA;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,eAAe,EAAE,SAAS,GAAG,SAAS,CAAA;IAC/C,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAA;IACtC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAA;CACtB,CAAA;AAED,wBAAgB,aAAa,CAC3B,KAAK,EAAE,mBAAmB,EAC1B,SAAS,EAAE,cAAc,GAAG,SAAS,EACrC,GAAG,EAAE,OAAO,GACX,mBAAmB,CAqCrB"}
|
package/dist/inspect.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { createApiBuilder } from './api/builder.js';
|
|
2
|
+
import { describeApiOperations } from './api/catalog.js';
|
|
3
|
+
import { detectDialect } from './dialect.js';
|
|
4
|
+
import { createJobsBuilder, validateJobsDefs } from './jobs/index.js';
|
|
5
|
+
import { buildManifest } from './manifest.js';
|
|
6
|
+
import { STORAGE_SWEEP_JOB_NAME, STORAGE_SWEEP_SCHEDULE, } from './storage/background.js';
|
|
7
|
+
import { resolveBuckets } from './storage/buckets.js';
|
|
8
|
+
export function inspectConfig(input, envConfig, env) {
|
|
9
|
+
const config = { ...input };
|
|
10
|
+
const dialect = detectDialect(config.schema);
|
|
11
|
+
const jobsDefs = config.jobs
|
|
12
|
+
? typeof config.jobs === 'function'
|
|
13
|
+
? config.jobs(createJobsBuilder())
|
|
14
|
+
: config.jobs
|
|
15
|
+
: undefined;
|
|
16
|
+
if (jobsDefs)
|
|
17
|
+
validateJobsDefs(jobsDefs);
|
|
18
|
+
const customApiRouter = typeof config.api === 'function'
|
|
19
|
+
? config.api(createApiBuilder())
|
|
20
|
+
: config.api;
|
|
21
|
+
const manifest = buildManifest({
|
|
22
|
+
schema: config.schema,
|
|
23
|
+
dialect,
|
|
24
|
+
migrationsDirectory: config.database.migrations ?? './migrations',
|
|
25
|
+
storage: resolveBuckets(config.storage, {}),
|
|
26
|
+
envConfig,
|
|
27
|
+
messaging: config.messaging,
|
|
28
|
+
realtime: Boolean(config.realtime),
|
|
29
|
+
api: describeApiOperations(customApiRouter),
|
|
30
|
+
jobs: config.storage
|
|
31
|
+
? {
|
|
32
|
+
...jobsDefs,
|
|
33
|
+
[STORAGE_SWEEP_JOB_NAME]: {
|
|
34
|
+
kind: 'cron',
|
|
35
|
+
schedule: STORAGE_SWEEP_SCHEDULE,
|
|
36
|
+
handler: () => { },
|
|
37
|
+
},
|
|
38
|
+
}
|
|
39
|
+
: jobsDefs,
|
|
40
|
+
});
|
|
41
|
+
return { config, jobsDefs, customApiRouter, manifest, env };
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=inspect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect.js","sourceRoot":"","sources":["../src/inspect.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAA;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAA;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1C,OAAO,EACL,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAqBlD,MAAM,UAAU,aAAa,CAC3B,KAA0B,EAC1B,SAAqC,EACrC,GAAY;IAEZ,MAAM,MAAM,GAAG,EAAE,GAAG,KAAK,EAAyB,CAAA;IAClD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IAC5C,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI;QAC1B,CAAC,CAAC,OAAO,MAAM,CAAC,IAAI,KAAK,UAAU;YACjC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAClC,CAAC,CAAC,MAAM,CAAC,IAAI;QACf,CAAC,CAAC,SAAS,CAAA;IACb,IAAI,QAAQ;QAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAA;IAExC,MAAM,eAAe,GACnB,OAAO,MAAM,CAAC,GAAG,KAAK,UAAU;QAC9B,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QAChC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAA;IAEhB,MAAM,QAAQ,GAAG,aAAa,CAAC;QAC7B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO;QACP,mBAAmB,EAAE,MAAM,CAAC,QAAQ,CAAC,UAAU,IAAI,cAAc;QACjE,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QAC3C,SAAS;QACT,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;QAClC,GAAG,EAAE,qBAAqB,CAAC,eAAe,CAAC;QAC3C,IAAI,EAAE,MAAM,CAAC,OAAO;YAClB,CAAC,CAAC;gBACE,GAAG,QAAQ;gBACX,CAAC,sBAAsB,CAAC,EAAE;oBACxB,IAAI,EAAE,MAAM;oBACZ,QAAQ,EAAE,sBAAsB;oBAChC,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC;iBAClB;aACF;YACH,CAAC,CAAC,QAAQ;KACb,CAAC,CAAA;IAEF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAA;AAC7D,CAAC","sourcesContent":["import type { AnyRouter } from '@orpc/server'\n\nimport type { BunderstackDefinitionConfig } from './backend'\nimport type { BaseEnv, EnvConfigInput } from './env'\nimport type { JobsDefs } from './jobs'\nimport type { BunderstackManifest } from './manifest'\n\nimport { createApiBuilder } from './api/builder'\nimport { describeApiOperations } from './api/catalog'\nimport { detectDialect } from './dialect'\nimport { createJobsBuilder, validateJobsDefs } from './jobs'\nimport { buildManifest } from './manifest'\nimport {\n STORAGE_SWEEP_JOB_NAME,\n STORAGE_SWEEP_SCHEDULE,\n} from './storage/background'\nimport { resolveBuckets } from './storage/buckets'\n\nexport type AnyDefinitionConfig = BunderstackDefinitionConfig<\n Record<string, unknown>,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n>\n\nexport type InspectedDefinition = {\n readonly config: AnyDefinitionConfig\n readonly jobsDefs: JobsDefs | undefined\n readonly customApiRouter: AnyRouter | undefined\n readonly manifest: BunderstackManifest\n readonly env: BaseEnv\n}\n\nexport function inspectConfig(\n input: AnyDefinitionConfig,\n envConfig: EnvConfigInput | undefined,\n env: BaseEnv,\n): InspectedDefinition {\n const config = { ...input } as AnyDefinitionConfig\n const dialect = detectDialect(config.schema)\n const jobsDefs = config.jobs\n ? typeof config.jobs === 'function'\n ? config.jobs(createJobsBuilder())\n : config.jobs\n : undefined\n if (jobsDefs) validateJobsDefs(jobsDefs)\n\n const customApiRouter =\n typeof config.api === 'function'\n ? config.api(createApiBuilder())\n : config.api\n\n const manifest = buildManifest({\n schema: config.schema,\n dialect,\n migrationsDirectory: config.database.migrations ?? './migrations',\n storage: resolveBuckets(config.storage, {}),\n envConfig,\n messaging: config.messaging,\n realtime: Boolean(config.realtime),\n api: describeApiOperations(customApiRouter),\n jobs: config.storage\n ? {\n ...jobsDefs,\n [STORAGE_SWEEP_JOB_NAME]: {\n kind: 'cron',\n schedule: STORAGE_SWEEP_SCHEDULE,\n handler: () => {},\n },\n }\n : jobsDefs,\n })\n\n return { config, jobsDefs, customApiRouter, manifest, env }\n}\n"]}
|