@chat-de-hp/site 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 (55) hide show
  1. package/README.md +50 -0
  2. package/bin/chat-de-hp.js +11 -0
  3. package/dist/astro.d.ts +12 -0
  4. package/dist/astro.d.ts.map +1 -0
  5. package/dist/astro.js +77 -0
  6. package/dist/cli.d.ts +3 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +36 -0
  9. package/dist/config.d.ts +6 -0
  10. package/dist/config.d.ts.map +1 -0
  11. package/dist/config.js +40 -0
  12. package/dist/contracts/forms.d.ts +135 -0
  13. package/dist/contracts/forms.d.ts.map +1 -0
  14. package/dist/contracts/forms.js +89 -0
  15. package/dist/control-plane.d.ts +51 -0
  16. package/dist/control-plane.d.ts.map +1 -0
  17. package/dist/control-plane.js +50 -0
  18. package/dist/generator.d.ts +17 -0
  19. package/dist/generator.d.ts.map +1 -0
  20. package/dist/generator.js +207 -0
  21. package/dist/index.d.ts +2 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +1 -0
  24. package/dist/internal/astro-plugins.d.ts +9 -0
  25. package/dist/internal/astro-plugins.d.ts.map +1 -0
  26. package/dist/internal/astro-plugins.js +22 -0
  27. package/dist/internal/forms-plugin.d.ts +3 -0
  28. package/dist/internal/forms-plugin.d.ts.map +1 -0
  29. package/dist/internal/forms-plugin.js +29 -0
  30. package/dist/internal/primitive-names.d.ts +3 -0
  31. package/dist/internal/primitive-names.d.ts.map +1 -0
  32. package/dist/internal/primitive-names.js +5 -0
  33. package/dist/internal/registry.d.ts +32 -0
  34. package/dist/internal/registry.d.ts.map +1 -0
  35. package/dist/internal/registry.js +88 -0
  36. package/dist/primitives/forms-astro.d.ts +2 -0
  37. package/dist/primitives/forms-astro.d.ts.map +1 -0
  38. package/dist/primitives/forms-astro.js +1 -0
  39. package/dist/primitives/forms-styles.css +1 -0
  40. package/dist/primitives/forms.d.ts +5 -0
  41. package/dist/primitives/forms.d.ts.map +1 -0
  42. package/dist/primitives/forms.js +4 -0
  43. package/dist/runtime/contracts.d.ts +60 -0
  44. package/dist/runtime/contracts.d.ts.map +1 -0
  45. package/dist/runtime/contracts.js +1 -0
  46. package/dist/runtime/index.d.ts +4 -0
  47. package/dist/runtime/index.d.ts.map +1 -0
  48. package/dist/runtime/index.js +2 -0
  49. package/dist/runtime/worker-core.d.ts +7 -0
  50. package/dist/runtime/worker-core.d.ts.map +1 -0
  51. package/dist/runtime/worker-core.js +619 -0
  52. package/dist/runtime/worker.d.ts +5 -0
  53. package/dist/runtime/worker.d.ts.map +1 -0
  54. package/dist/runtime/worker.js +5 -0
  55. package/package.json +102 -0
@@ -0,0 +1,207 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { access, mkdir, readFile, rename, rm, writeFile, } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ import { pathToFileURL } from "node:url";
5
+ import { parse as parseJsonc, printParseErrorCode, } from "jsonc-parser";
6
+ import { resolveSiteDefinition } from "./internal/registry.js";
7
+ const GENERATED_DIRECTORY = join(".chat-de-hp", "generated");
8
+ export async function loadSiteConfig(root) {
9
+ const candidates = [
10
+ "chat-de-hp.config.ts",
11
+ "chat-de-hp.config.mjs",
12
+ "chat-de-hp.config.js",
13
+ ];
14
+ const configPath = await firstExistingPath(candidates.map((candidate) => join(root, candidate)));
15
+ if (!configPath) {
16
+ throw new Error(`Could not find chat-de-hp.config.ts in ${root}.`);
17
+ }
18
+ const module = await import(`${pathToFileURL(configPath).href}?chat-de-hp=${randomUUID()}`);
19
+ return module.default;
20
+ }
21
+ export function renderGeneratedSiteFiles(config) {
22
+ const resolved = resolveSiteDefinition(config);
23
+ const imports = resolved.primitives.map((primitive) => `import { ${primitive.runtimeSymbol} } from ${JSON.stringify(primitive.runtimeImport)};`);
24
+ const symbols = resolved.primitives.map((primitive) => primitive.runtimeSymbol);
25
+ const runtime = [
26
+ 'import type { GeneratedSiteRuntime } from "@chat-de-hp/site/runtime";',
27
+ ...imports,
28
+ "",
29
+ "export const generatedSiteRuntime = {",
30
+ ` primitives: [${symbols.join(", ")}],`,
31
+ "} satisfies GeneratedSiteRuntime;",
32
+ "",
33
+ ].join("\n");
34
+ return {
35
+ manifest: `${JSON.stringify(resolved.manifest, null, 2)}\n`,
36
+ runtime,
37
+ };
38
+ }
39
+ export async function generateSiteFiles(options) {
40
+ const config = options.config ?? (await loadSiteConfig(options.root));
41
+ const expected = renderGeneratedSiteFiles(config);
42
+ await validateSiteWranglerBindings(options.root, JSON.parse(expected.manifest));
43
+ const paths = generatedPaths(options.root);
44
+ if (options.check) {
45
+ const stale = await staleGeneratedFiles(paths, expected);
46
+ if (stale.length > 0) {
47
+ throw new Error(`Generated files are stale: ${stale.join(", ")}. Run \`bunx chat-de-hp generate\`.`);
48
+ }
49
+ return expected;
50
+ }
51
+ await writeGeneratedFilesAtomically(options.root, expected, options.onCurrentGeneratedDirectoryMoved);
52
+ return expected;
53
+ }
54
+ export async function validateSiteWranglerBindings(root, manifest) {
55
+ const wranglerPath = await firstExistingPath([
56
+ join(root, "wrangler.jsonc"),
57
+ join(root, "wrangler.json"),
58
+ ]);
59
+ if (!wranglerPath) {
60
+ throw new Error(`Could not find wrangler.jsonc in ${root}.`);
61
+ }
62
+ const errors = [];
63
+ const wrangler = parseJsonc(await readFile(wranglerPath, "utf-8"), errors, {
64
+ allowTrailingComma: true,
65
+ });
66
+ if (errors.length > 0) {
67
+ throw new Error(`${wranglerPath} is invalid JSONC: ${errors
68
+ .map((error) => printParseErrorCode(error.error))
69
+ .join(", ")}.`);
70
+ }
71
+ if (!isRecord(wrangler)) {
72
+ throw new Error(`${wranglerPath} must contain a JSON object.`);
73
+ }
74
+ const configured = configuredWranglerBindings(wrangler);
75
+ const missing = [];
76
+ const mismatched = [];
77
+ for (const required of manifest.requiredBindings) {
78
+ const types = configured.get(required.name);
79
+ if (!types) {
80
+ missing.push(`${required.name} (${required.type})`);
81
+ }
82
+ else if (!types.has(required.type)) {
83
+ mismatched.push(`${required.name} requires ${required.type}, found ${[...types].sort().join("/")}`);
84
+ }
85
+ }
86
+ if (missing.length > 0 || mismatched.length > 0) {
87
+ throw new Error([
88
+ "wrangler.jsonc does not satisfy the generated site manifest.",
89
+ missing.length > 0 ? `Missing: ${missing.join(", ")}.` : "",
90
+ mismatched.length > 0 ? `Wrong type: ${mismatched.join(", ")}.` : "",
91
+ ]
92
+ .filter(Boolean)
93
+ .join(" "));
94
+ }
95
+ }
96
+ function configuredWranglerBindings(wrangler) {
97
+ const bindings = new Map();
98
+ addArrayBindings(bindings, wrangler.d1_databases, "binding", "d1");
99
+ addArrayBindings(bindings, wrangler.r2_buckets, "binding", "r2_bucket");
100
+ addArrayBindings(bindings, wrangler.kv_namespaces, "binding", "kv_namespace");
101
+ addObjectBinding(bindings, wrangler.images, "binding", "images");
102
+ addArrayBindings(bindings, wrangler.send_email, "name", "send_email");
103
+ addArrayBindings(bindings, wrangler.worker_loaders, "binding", "worker_loader");
104
+ return bindings;
105
+ }
106
+ function addArrayBindings(bindings, value, nameKey, type) {
107
+ if (!Array.isArray(value)) {
108
+ return;
109
+ }
110
+ for (const entry of value) {
111
+ addObjectBinding(bindings, entry, nameKey, type);
112
+ }
113
+ }
114
+ function addObjectBinding(bindings, value, nameKey, type) {
115
+ if (!isRecord(value) || typeof value[nameKey] !== "string") {
116
+ return;
117
+ }
118
+ const name = value[nameKey];
119
+ const types = bindings.get(name) ?? new Set();
120
+ types.add(type);
121
+ bindings.set(name, types);
122
+ }
123
+ function isRecord(value) {
124
+ return typeof value === "object" && value !== null && !Array.isArray(value);
125
+ }
126
+ function generatedPaths(root) {
127
+ return {
128
+ manifest: join(root, GENERATED_DIRECTORY, "manifest.json"),
129
+ runtime: join(root, GENERATED_DIRECTORY, "runtime.ts"),
130
+ };
131
+ }
132
+ async function staleGeneratedFiles(paths, expected) {
133
+ const entries = [
134
+ [paths.manifest, expected.manifest],
135
+ [paths.runtime, expected.runtime],
136
+ ];
137
+ const stale = [];
138
+ for (const [path, content] of entries) {
139
+ try {
140
+ if ((await readFile(path, "utf-8")) !== content) {
141
+ stale.push(path);
142
+ }
143
+ }
144
+ catch {
145
+ stale.push(path);
146
+ }
147
+ }
148
+ return stale;
149
+ }
150
+ async function writeGeneratedFilesAtomically(root, content, onCurrentDirectoryMoved) {
151
+ const generatedDirectory = join(root, GENERATED_DIRECTORY);
152
+ const parentDirectory = dirname(generatedDirectory);
153
+ const transactionId = randomUUID();
154
+ const temporaryDirectory = join(parentDirectory, `.generated.${transactionId}.tmp`);
155
+ const backupDirectory = join(parentDirectory, `.generated.${transactionId}.backup`);
156
+ let currentDirectoryMoved = false;
157
+ let replacementInstalled = false;
158
+ await mkdir(parentDirectory, { recursive: true });
159
+ await mkdir(temporaryDirectory);
160
+ try {
161
+ await Promise.all([
162
+ writeFile(join(temporaryDirectory, "runtime.ts"), content.runtime, "utf-8"),
163
+ writeFile(join(temporaryDirectory, "manifest.json"), content.manifest, "utf-8"),
164
+ ]);
165
+ if (await pathExists(generatedDirectory)) {
166
+ await rename(generatedDirectory, backupDirectory);
167
+ currentDirectoryMoved = true;
168
+ await onCurrentDirectoryMoved?.();
169
+ }
170
+ await rename(temporaryDirectory, generatedDirectory);
171
+ replacementInstalled = true;
172
+ }
173
+ catch (error) {
174
+ if (currentDirectoryMoved && !replacementInstalled) {
175
+ await rename(backupDirectory, generatedDirectory);
176
+ currentDirectoryMoved = false;
177
+ }
178
+ throw error;
179
+ }
180
+ finally {
181
+ await rm(temporaryDirectory, { force: true, recursive: true });
182
+ if (currentDirectoryMoved && replacementInstalled) {
183
+ await rm(backupDirectory, { force: true, recursive: true });
184
+ }
185
+ }
186
+ }
187
+ async function pathExists(path) {
188
+ try {
189
+ await access(path);
190
+ return true;
191
+ }
192
+ catch {
193
+ return false;
194
+ }
195
+ }
196
+ async function firstExistingPath(paths) {
197
+ for (const path of paths) {
198
+ try {
199
+ await access(path);
200
+ return path;
201
+ }
202
+ catch {
203
+ // Try the next supported config extension.
204
+ }
205
+ }
206
+ return null;
207
+ }
@@ -0,0 +1,2 @@
1
+ export { defineChatDeHpSite, type ChatDeHpSiteConfig } from "./config.js";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export { defineChatDeHpSite } from "./config.js";
@@ -0,0 +1,9 @@
1
+ type ApprovedAstroPlugin = {
2
+ readonly entrypoint?: string;
3
+ readonly id: string;
4
+ };
5
+ declare const ASTRO_PLUGIN_IDS: readonly ["cloudflare-email", "emdash-forms"];
6
+ export type SiteAstroPluginId = (typeof ASTRO_PLUGIN_IDS)[number];
7
+ export declare function createApprovedAstroPlugins(pluginIds: readonly SiteAstroPluginId[]): ApprovedAstroPlugin[];
8
+ export {};
9
+ //# sourceMappingURL=astro-plugins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"astro-plugins.d.ts","sourceRoot":"","sources":["../../src/internal/astro-plugins.ts"],"names":[],"mappings":"AAIA,KAAK,mBAAmB,GAAG;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,QAAA,MAAM,gBAAgB,+CAAgD,CAAC;AAEvE,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAUlE,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,SAAS,iBAAiB,EAAE,GACtC,mBAAmB,EAAE,CAIvB"}
@@ -0,0 +1,22 @@
1
+ import { cloudflareEmail } from "@emdash-cms/cloudflare/plugins";
2
+ import { approvedFormsPlugin } from "./forms-plugin.js";
3
+ const ASTRO_PLUGIN_IDS = ["cloudflare-email", "emdash-forms"];
4
+ const ASTRO_PLUGIN_FACTORIES = {
5
+ "cloudflare-email": approvedCloudflareEmailPlugin,
6
+ "emdash-forms": approvedFormsPlugin,
7
+ };
8
+ export function createApprovedAstroPlugins(pluginIds) {
9
+ return [...new Set(pluginIds)]
10
+ .sort((a, b) => a.localeCompare(b))
11
+ .map((id) => ASTRO_PLUGIN_FACTORIES[id]());
12
+ }
13
+ function approvedCloudflareEmailPlugin() {
14
+ return {
15
+ ...cloudflareEmail({
16
+ binding: "SEND_EMAIL",
17
+ from: process.env.FORM_EMAIL_FROM ?? "forms@chat-de-hp.com",
18
+ }),
19
+ entrypoint: import.meta
20
+ .resolve("@emdash-cms/cloudflare/plugins/cloudflare-email"),
21
+ };
22
+ }
@@ -0,0 +1,3 @@
1
+ import type { PluginDescriptor } from "emdash";
2
+ export declare function approvedFormsPlugin(): PluginDescriptor;
3
+ //# sourceMappingURL=forms-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forms-plugin.d.ts","sourceRoot":"","sources":["../../src/internal/forms-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAO/C,wBAAgB,mBAAmB,IAAI,gBAAgB,CAwBtD"}
@@ -0,0 +1,29 @@
1
+ const FORMS_PLUGIN_VERSION = "0.2.4";
2
+ // @emdash-cms/plugin-forms currently publishes TypeScript entrypoints, which
3
+ // Node cannot execute while loading astro.config.mjs. Keep this descriptor in
4
+ // lockstep with formsPlugin(); the package test compares its public metadata.
5
+ export function approvedFormsPlugin() {
6
+ return {
7
+ adminEntry: import.meta.resolve("@emdash-cms/plugin-forms/admin"),
8
+ adminPages: [
9
+ { icon: "list", label: "Forms", path: "/" },
10
+ { icon: "inbox", label: "Submissions", path: "/submissions" },
11
+ ],
12
+ adminWidgets: [
13
+ { id: "recent-submissions", size: "half", title: "Recent Submissions" },
14
+ ],
15
+ allowedHosts: ["*"],
16
+ capabilities: ["email:send", "media:write", "network:request"],
17
+ componentsEntry: import.meta.resolve("@emdash-cms/plugin-forms/astro"),
18
+ entrypoint: import.meta.resolve("@emdash-cms/plugin-forms"),
19
+ id: "emdash-forms",
20
+ options: {},
21
+ storage: {
22
+ forms: { indexes: ["status", "createdAt"], uniqueIndexes: ["slug"] },
23
+ submissions: {
24
+ indexes: ["formId", "status", "starred", "createdAt"],
25
+ },
26
+ },
27
+ version: FORMS_PLUGIN_VERSION,
28
+ };
29
+ }
@@ -0,0 +1,3 @@
1
+ export declare const KNOWN_PRIMITIVE_IDS: readonly ["forms"];
2
+ export declare function isKnownPrimitiveId(value: string): boolean;
3
+ //# sourceMappingURL=primitive-names.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"primitive-names.d.ts","sourceRoot":"","sources":["../../src/internal/primitive-names.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,oBAAqB,CAAC;AAItD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEzD"}
@@ -0,0 +1,5 @@
1
+ export const KNOWN_PRIMITIVE_IDS = ["forms"];
2
+ const KNOWN_PRIMITIVES = new Set(KNOWN_PRIMITIVE_IDS);
3
+ export function isKnownPrimitiveId(value) {
4
+ return KNOWN_PRIMITIVES.has(value);
5
+ }
@@ -0,0 +1,32 @@
1
+ import type { ChatDeHpSiteConfig } from "../config.js";
2
+ import { type SiteRuntimeManifest } from "../control-plane.js";
3
+ import type { SiteAstroPluginId } from "./astro-plugins.js";
4
+ type PrimitiveDefinition = {
5
+ astroPluginIds: readonly SiteAstroPluginId[];
6
+ capabilityIds: readonly CapabilityId[];
7
+ id: string;
8
+ runtimeImport: string;
9
+ runtimeSymbol: string;
10
+ schemaVersion: number;
11
+ };
12
+ declare const CAPABILITY_REGISTRY: {
13
+ readonly "email.send": {
14
+ readonly astroPluginIds: readonly ["cloudflare-email"];
15
+ readonly id: "email.send";
16
+ readonly provider: "cloudflare-email";
17
+ readonly requiredBindings: readonly [{
18
+ readonly name: "SEND_EMAIL";
19
+ readonly type: "send_email";
20
+ }];
21
+ readonly schemaVersion: 1;
22
+ };
23
+ };
24
+ type CapabilityId = keyof typeof CAPABILITY_REGISTRY;
25
+ export type ResolvedSiteDefinition = {
26
+ astroPluginIds: readonly SiteAstroPluginId[];
27
+ manifest: SiteRuntimeManifest;
28
+ primitives: readonly PrimitiveDefinition[];
29
+ };
30
+ export declare function resolveSiteDefinition(input: ChatDeHpSiteConfig | unknown): ResolvedSiteDefinition;
31
+ export {};
32
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/internal/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,OAAO,EAKL,KAAK,mBAAmB,EACzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAU5D,KAAK,mBAAmB,GAAG;IACzB,cAAc,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC7C,aAAa,EAAE,SAAS,YAAY,EAAE,CAAC;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAUF,QAAA,MAAM,mBAAmB;;;;;;;;;;;CAQ0C,CAAC;AAEpE,KAAK,YAAY,GAAG,MAAM,OAAO,mBAAmB,CAAC;AAarD,MAAM,MAAM,sBAAsB,GAAG;IACnC,cAAc,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC7C,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,UAAU,EAAE,SAAS,mBAAmB,EAAE,CAAC;CAC5C,CAAC;AAEF,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,kBAAkB,GAAG,OAAO,GAClC,sBAAsB,CA4CxB"}
@@ -0,0 +1,88 @@
1
+ import { parseChatDeHpSiteConfig } from "../config.js";
2
+ import { SITE_RUNTIME_NAME, SITE_RUNTIME_PROTOCOL_VERSION, SITE_RUNTIME_VERSION, } from "../control-plane.js";
3
+ const BASE_BINDINGS = [
4
+ { name: "DB", type: "d1" },
5
+ { name: "IMAGES", type: "images" },
6
+ { name: "LOADER", type: "worker_loader" },
7
+ { name: "MEDIA", type: "r2_bucket" },
8
+ { name: "SESSION", type: "kv_namespace" },
9
+ ];
10
+ const CAPABILITY_REGISTRY = {
11
+ "email.send": {
12
+ astroPluginIds: ["cloudflare-email"],
13
+ id: "email.send",
14
+ provider: "cloudflare-email",
15
+ requiredBindings: [{ name: "SEND_EMAIL", type: "send_email" }],
16
+ schemaVersion: 1,
17
+ },
18
+ };
19
+ const PRIMITIVE_REGISTRY = {
20
+ forms: {
21
+ astroPluginIds: ["emdash-forms"],
22
+ capabilityIds: ["email.send"],
23
+ id: "forms",
24
+ runtimeImport: "@chat-de-hp/site/primitives/forms",
25
+ runtimeSymbol: "formsRuntimeContribution",
26
+ schemaVersion: 1,
27
+ },
28
+ };
29
+ export function resolveSiteDefinition(input) {
30
+ const config = parseChatDeHpSiteConfig(input);
31
+ const definitions = config.primitives.map((id) => {
32
+ const definition = PRIMITIVE_REGISTRY[id];
33
+ if (!definition) {
34
+ throw new Error(`chat-de-hp.config.ts contains unknown primitive ${JSON.stringify(id)}.`);
35
+ }
36
+ return definition;
37
+ });
38
+ const primitives = [...definitions].sort((a, b) => a.id.localeCompare(b.id));
39
+ const capabilities = resolveCapabilities(primitives);
40
+ const astroPluginIds = deduplicateStrings([
41
+ ...capabilities.flatMap((capability) => capability.astroPluginIds),
42
+ ...primitives.flatMap((primitive) => primitive.astroPluginIds),
43
+ ]);
44
+ const requiredBindings = deduplicateBindings([
45
+ ...BASE_BINDINGS,
46
+ ...capabilities.flatMap((capability) => capability.requiredBindings),
47
+ ]);
48
+ return {
49
+ astroPluginIds,
50
+ manifest: {
51
+ capabilities: capabilities.map(({ id, provider, schemaVersion }) => ({
52
+ id,
53
+ provider,
54
+ schemaVersion,
55
+ })),
56
+ primitives: primitives.map(({ id, schemaVersion }) => ({
57
+ id,
58
+ schemaVersion,
59
+ })),
60
+ requiredBindings,
61
+ runtime: {
62
+ name: SITE_RUNTIME_NAME,
63
+ protocolVersion: SITE_RUNTIME_PROTOCOL_VERSION,
64
+ version: SITE_RUNTIME_VERSION,
65
+ },
66
+ schemaVersion: 1,
67
+ },
68
+ primitives,
69
+ };
70
+ }
71
+ function resolveCapabilities(primitives) {
72
+ const ids = deduplicateStrings(primitives.flatMap((primitive) => primitive.capabilityIds));
73
+ return ids.map((id) => CAPABILITY_REGISTRY[id]);
74
+ }
75
+ function deduplicateStrings(values) {
76
+ return [...new Set(values)].sort((a, b) => a.localeCompare(b));
77
+ }
78
+ function deduplicateBindings(bindings) {
79
+ const byName = new Map();
80
+ for (const binding of bindings) {
81
+ const existing = byName.get(binding.name);
82
+ if (existing && existing.type !== binding.type) {
83
+ throw new Error(`Binding ${binding.name} has conflicting types ${existing.type} and ${binding.type}.`);
84
+ }
85
+ byName.set(binding.name, { ...binding });
86
+ }
87
+ return [...byName.values()].sort((a, b) => a.name.localeCompare(b.name));
88
+ }
@@ -0,0 +1,2 @@
1
+ export { blockComponents } from "@emdash-cms/plugin-forms/astro";
2
+ //# sourceMappingURL=forms-astro.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forms-astro.d.ts","sourceRoot":"","sources":["../../src/primitives/forms-astro.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC"}
@@ -0,0 +1 @@
1
+ export { blockComponents } from "@emdash-cms/plugin-forms/astro";
@@ -0,0 +1 @@
1
+ @import "@emdash-cms/plugin-forms/styles";
@@ -0,0 +1,5 @@
1
+ export declare const formsRuntimeContribution: {
2
+ readonly id: "forms";
3
+ readonly routes: readonly [];
4
+ };
5
+ //# sourceMappingURL=forms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forms.d.ts","sourceRoot":"","sources":["../../src/primitives/forms.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,wBAAwB;;;CAGW,CAAC"}
@@ -0,0 +1,4 @@
1
+ export const formsRuntimeContribution = {
2
+ id: "forms",
3
+ routes: [],
4
+ };
@@ -0,0 +1,60 @@
1
+ export type ChatDeHpExecutionContext = {
2
+ passThroughOnException?(): void;
3
+ waitUntil(promise: Promise<unknown>): void;
4
+ };
5
+ export type ChatDeHpSiteEnv = {
6
+ ASSETS?: {
7
+ fetch(request: Request): Promise<Response>;
8
+ };
9
+ CHAT_DE_HP_BOOTSTRAP_SECRET?: string;
10
+ DB?: ChatDeHpD1Database;
11
+ FORM_EMAIL_FROM?: string;
12
+ MEDIA?: ChatDeHpR2Bucket;
13
+ PUBLIC_URL?: string;
14
+ SITE_ID?: string;
15
+ SITE_NAME?: string;
16
+ [binding: string]: unknown;
17
+ };
18
+ export type ChatDeHpD1Database = {
19
+ prepare(query: string): ChatDeHpD1PreparedStatement;
20
+ };
21
+ export type ChatDeHpD1PreparedStatement = {
22
+ bind(...values: unknown[]): ChatDeHpD1PreparedStatement;
23
+ first<T = Record<string, unknown>>(): Promise<T | null>;
24
+ run(): Promise<unknown>;
25
+ };
26
+ export type ChatDeHpR2Bucket = {
27
+ delete(key: string): Promise<unknown>;
28
+ get(key: string): Promise<ChatDeHpR2Object | null>;
29
+ put(key: string, value: ArrayBuffer | ArrayBufferView | ReadableStream | string, options?: {
30
+ customMetadata?: Record<string, string>;
31
+ httpMetadata?: {
32
+ contentDisposition?: string;
33
+ contentType?: string;
34
+ };
35
+ }): Promise<unknown>;
36
+ };
37
+ export type ChatDeHpR2Object = {
38
+ body: ReadableStream;
39
+ customMetadata?: Record<string, string>;
40
+ httpMetadata?: {
41
+ contentDisposition?: string;
42
+ contentType?: string;
43
+ };
44
+ };
45
+ export type ChatDeHpRuntimeRoute = {
46
+ handle(request: Request, env: ChatDeHpSiteEnv, context: ChatDeHpExecutionContext): Promise<Response> | Response;
47
+ method?: string;
48
+ pathname: string;
49
+ };
50
+ export type ChatDeHpRuntimeContribution = {
51
+ id: string;
52
+ routes: readonly ChatDeHpRuntimeRoute[];
53
+ };
54
+ export type GeneratedSiteRuntime = {
55
+ primitives: readonly ChatDeHpRuntimeContribution[];
56
+ };
57
+ export type ChatDeHpAstroHandler = {
58
+ fetch(request: Request, env: ChatDeHpSiteEnv, context: ChatDeHpExecutionContext): Promise<Response>;
59
+ };
60
+ //# sourceMappingURL=contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../src/runtime/contracts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ export { PluginBridge } from "@emdash-cms/cloudflare/sandbox";
2
+ export type { ChatDeHpExecutionContext, ChatDeHpRuntimeContribution, ChatDeHpRuntimeRoute, ChatDeHpSiteEnv, GeneratedSiteRuntime, } from "./contracts.js";
3
+ export { createChatDeHpSiteWorker } from "./worker.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAE9D,YAAY,EACV,wBAAwB,EACxB,2BAA2B,EAC3B,oBAAoB,EACpB,eAAe,EACf,oBAAoB,GACrB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { PluginBridge } from "@emdash-cms/cloudflare/sandbox";
2
+ export { createChatDeHpSiteWorker } from "./worker.js";
@@ -0,0 +1,7 @@
1
+ import type { ChatDeHpAstroHandler, ChatDeHpExecutionContext, ChatDeHpSiteEnv, GeneratedSiteRuntime } from "./contracts.js";
2
+ type Env = ChatDeHpSiteEnv;
3
+ export declare function createChatDeHpSiteWorkerWithHandler(runtime: GeneratedSiteRuntime, astroHandler: ChatDeHpAstroHandler): {
4
+ fetch(request: Request, env: Env, context: ChatDeHpExecutionContext): Promise<Response>;
5
+ };
6
+ export {};
7
+ //# sourceMappingURL=worker-core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-core.d.ts","sourceRoot":"","sources":["../../src/runtime/worker-core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EAEpB,wBAAwB,EAExB,eAAe,EACf,oBAAoB,EACrB,MAAM,gBAAgB,CAAC;AAExB,KAAK,GAAG,GAAG,eAAe,CAAC;AA4xB3B,wBAAgB,mCAAmC,CACjD,OAAO,EAAE,oBAAoB,EAC7B,YAAY,EAAE,oBAAoB;mBAKX,OAAO,OAAO,GAAG,WAAW,wBAAwB;EAgC5E"}