@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.
- package/README.md +50 -0
- package/bin/chat-de-hp.js +11 -0
- package/dist/astro.d.ts +12 -0
- package/dist/astro.d.ts.map +1 -0
- package/dist/astro.js +77 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +36 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +40 -0
- package/dist/contracts/forms.d.ts +135 -0
- package/dist/contracts/forms.d.ts.map +1 -0
- package/dist/contracts/forms.js +89 -0
- package/dist/control-plane.d.ts +51 -0
- package/dist/control-plane.d.ts.map +1 -0
- package/dist/control-plane.js +50 -0
- package/dist/generator.d.ts +17 -0
- package/dist/generator.d.ts.map +1 -0
- package/dist/generator.js +207 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -0
- package/dist/internal/astro-plugins.d.ts +9 -0
- package/dist/internal/astro-plugins.d.ts.map +1 -0
- package/dist/internal/astro-plugins.js +22 -0
- package/dist/internal/forms-plugin.d.ts +3 -0
- package/dist/internal/forms-plugin.d.ts.map +1 -0
- package/dist/internal/forms-plugin.js +29 -0
- package/dist/internal/primitive-names.d.ts +3 -0
- package/dist/internal/primitive-names.d.ts.map +1 -0
- package/dist/internal/primitive-names.js +5 -0
- package/dist/internal/registry.d.ts +32 -0
- package/dist/internal/registry.d.ts.map +1 -0
- package/dist/internal/registry.js +88 -0
- package/dist/primitives/forms-astro.d.ts +2 -0
- package/dist/primitives/forms-astro.d.ts.map +1 -0
- package/dist/primitives/forms-astro.js +1 -0
- package/dist/primitives/forms-styles.css +1 -0
- package/dist/primitives/forms.d.ts +5 -0
- package/dist/primitives/forms.d.ts.map +1 -0
- package/dist/primitives/forms.js +4 -0
- package/dist/runtime/contracts.d.ts +60 -0
- package/dist/runtime/contracts.d.ts.map +1 -0
- package/dist/runtime/contracts.js +1 -0
- package/dist/runtime/index.d.ts +4 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +2 -0
- package/dist/runtime/worker-core.d.ts +7 -0
- package/dist/runtime/worker-core.d.ts.map +1 -0
- package/dist/runtime/worker-core.js +619 -0
- package/dist/runtime/worker.d.ts +5 -0
- package/dist/runtime/worker.d.ts.map +1 -0
- package/dist/runtime/worker.js +5 -0
- package/package.json +102 -0
package/README.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# `@chat-de-hp/site`
|
|
2
|
+
|
|
3
|
+
The public, platform-owned runtime for Chat de HP Astro sites. Site source
|
|
4
|
+
declares product primitives; this package owns the approved EmDash plugins,
|
|
5
|
+
Cloudflare providers, Worker endpoints, and generated deployment metadata.
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
// chat-de-hp.config.ts
|
|
9
|
+
import { defineChatDeHpSite } from "@chat-de-hp/site";
|
|
10
|
+
|
|
11
|
+
export default defineChatDeHpSite({ primitives: ["forms"] });
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
// astro.config.mjs
|
|
16
|
+
import { createChatDeHpAstroConfig } from "@chat-de-hp/site/astro";
|
|
17
|
+
import site from "./chat-de-hp.config.ts";
|
|
18
|
+
|
|
19
|
+
export default createChatDeHpAstroConfig(site, {
|
|
20
|
+
prefetch: {
|
|
21
|
+
defaultStrategy: "hover",
|
|
22
|
+
prefetchAll: true,
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Pass ordinary Astro options such as `fonts`, `image`, `prefetch`, `security`,
|
|
28
|
+
and `vite` through the optional second argument. The package keeps ownership of
|
|
29
|
+
the adapter, server output, EmDash integration, and primitive providers.
|
|
30
|
+
|
|
31
|
+
Install, development, typecheck, and build hooks run `chat-de-hp generate`
|
|
32
|
+
after changes to the site config. `.chat-de-hp/generated/` is an ignored build
|
|
33
|
+
output: do not edit or commit it. The deployment artifact carries the validated
|
|
34
|
+
runtime manifest used by the control plane.
|
|
35
|
+
|
|
36
|
+
Sites pin an exact package version. Each release also publishes the compatible
|
|
37
|
+
direct-site Astro, EmDash, React, and tooling policy in its package metadata.
|
|
38
|
+
Platform upgrades apply that set together and refresh the lockfile as one
|
|
39
|
+
operator-managed source update. The next install or build regenerates the
|
|
40
|
+
runtime locally.
|
|
41
|
+
|
|
42
|
+
## Vocabulary
|
|
43
|
+
|
|
44
|
+
- A **primitive** is a product feature such as `forms`.
|
|
45
|
+
- A **capability** is infrastructure needed by a primitive.
|
|
46
|
+
- A **provider** is the approved implementation of a capability.
|
|
47
|
+
- The generated **runtime manifest** records the exact deployed composition.
|
|
48
|
+
|
|
49
|
+
Version 0.1.0 supports the `forms` primitive. Arbitrary plugins and providers
|
|
50
|
+
are intentionally not part of the author-facing interface.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { existsSync } from "node:fs";
|
|
4
|
+
|
|
5
|
+
const builtCli = new URL("../dist/cli.js", import.meta.url);
|
|
6
|
+
if (!existsSync(builtCli)) {
|
|
7
|
+
throw new Error(
|
|
8
|
+
"@chat-de-hp/site is missing dist/cli.js. Reinstall a complete published package."
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
await import(builtCli.href);
|
package/dist/astro.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AstroIntegration } from "astro";
|
|
2
|
+
import { defineConfig } from "astro/config";
|
|
3
|
+
import type { ChatDeHpSiteConfig } from "./config.js";
|
|
4
|
+
type AnyAstroUserConfig = Parameters<typeof defineConfig>[0];
|
|
5
|
+
declare const SITE_ASTRO_OPTION_KEYS: readonly ["build", "compressHTML", "devToolbar", "env", "fonts", "i18n", "image", "integrations", "markdown", "prefetch", "redirects", "scopedStyleStrategy", "security", "server", "site", "trailingSlash", "vite"];
|
|
6
|
+
type SiteAstroOptionKey = Extract<(typeof SITE_ASTRO_OPTION_KEYS)[number], keyof AnyAstroUserConfig>;
|
|
7
|
+
export type ChatDeHpAstroOptions = Omit<Pick<AnyAstroUserConfig, SiteAstroOptionKey>, "integrations"> & {
|
|
8
|
+
integrations?: readonly AstroIntegration[];
|
|
9
|
+
};
|
|
10
|
+
export declare function createChatDeHpAstroConfig(site: ChatDeHpSiteConfig, options?: ChatDeHpAstroOptions): AnyAstroUserConfig;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=astro.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"astro.d.ts","sourceRoot":"","sources":["../src/astro.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAmB,MAAM,OAAO,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAItD,KAAK,kBAAkB,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7D,QAAA,MAAM,sBAAsB,sNAkBlB,CAAC;AACX,KAAK,kBAAkB,GAAG,OAAO,CAC/B,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,EACvC,MAAM,kBAAkB,CACzB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,IAAI,CACrC,IAAI,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,EAC5C,cAAc,CACf,GAAG;IACF,YAAY,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;CAC5C,CAAC;AAOF,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,kBAAkB,EACxB,OAAO,GAAE,oBAAyB,GACjC,kBAAkB,CAiCpB"}
|
package/dist/astro.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import cloudflare from "@astrojs/cloudflare";
|
|
2
|
+
import react from "@astrojs/react";
|
|
3
|
+
import { d1, r2 } from "@emdash-cms/cloudflare";
|
|
4
|
+
import { defineConfig } from "astro/config";
|
|
5
|
+
import emdash from "emdash/astro";
|
|
6
|
+
import { createApprovedAstroPlugins } from "./internal/astro-plugins.js";
|
|
7
|
+
import { resolveSiteDefinition } from "./internal/registry.js";
|
|
8
|
+
const SITE_ASTRO_OPTION_KEYS = [
|
|
9
|
+
"build",
|
|
10
|
+
"compressHTML",
|
|
11
|
+
"devToolbar",
|
|
12
|
+
"env",
|
|
13
|
+
"fonts",
|
|
14
|
+
"i18n",
|
|
15
|
+
"image",
|
|
16
|
+
"integrations",
|
|
17
|
+
"markdown",
|
|
18
|
+
"prefetch",
|
|
19
|
+
"redirects",
|
|
20
|
+
"scopedStyleStrategy",
|
|
21
|
+
"security",
|
|
22
|
+
"server",
|
|
23
|
+
"site",
|
|
24
|
+
"trailingSlash",
|
|
25
|
+
"vite",
|
|
26
|
+
];
|
|
27
|
+
const PLATFORM_INTEGRATION_NAMES = new Set([
|
|
28
|
+
"@astrojs/cloudflare",
|
|
29
|
+
"@astrojs/react",
|
|
30
|
+
"emdash",
|
|
31
|
+
]);
|
|
32
|
+
export function createChatDeHpAstroConfig(site, options = {}) {
|
|
33
|
+
rejectLockedOptions(options);
|
|
34
|
+
const resolved = resolveSiteDefinition(site);
|
|
35
|
+
const { devToolbar, image, integrations: siteIntegrations = [], ...siteOptions } = options;
|
|
36
|
+
rejectPlatformIntegrations(siteIntegrations);
|
|
37
|
+
const plugins = createApprovedAstroPlugins(resolved.astroPluginIds);
|
|
38
|
+
return defineConfig({
|
|
39
|
+
...siteOptions,
|
|
40
|
+
adapter: cloudflare(),
|
|
41
|
+
devToolbar: devToolbar ?? { enabled: false },
|
|
42
|
+
image: {
|
|
43
|
+
layout: "constrained",
|
|
44
|
+
responsiveStyles: true,
|
|
45
|
+
...image,
|
|
46
|
+
},
|
|
47
|
+
integrations: [
|
|
48
|
+
...siteIntegrations,
|
|
49
|
+
react(),
|
|
50
|
+
emdash({
|
|
51
|
+
database: d1({ binding: "DB", coalesce: true, session: "auto" }),
|
|
52
|
+
plugins: plugins,
|
|
53
|
+
storage: r2({ binding: "MEDIA" }),
|
|
54
|
+
}),
|
|
55
|
+
],
|
|
56
|
+
output: "server",
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function rejectLockedOptions(options) {
|
|
60
|
+
for (const key of ["adapter", "output"]) {
|
|
61
|
+
if (Object.hasOwn(options, key)) {
|
|
62
|
+
throw new Error(`createChatDeHpAstroConfig does not allow overriding ${key}.`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const unsupported = Object.keys(options).filter((key) => !SITE_ASTRO_OPTION_KEYS.includes(key));
|
|
66
|
+
if (unsupported.length > 0) {
|
|
67
|
+
throw new Error(`createChatDeHpAstroConfig does not support option(s): ${unsupported
|
|
68
|
+
.sort()
|
|
69
|
+
.join(", ")}.`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function rejectPlatformIntegrations(integrations) {
|
|
73
|
+
const duplicate = integrations.find((integration) => PLATFORM_INTEGRATION_NAMES.has(integration.name));
|
|
74
|
+
if (duplicate) {
|
|
75
|
+
throw new Error(`createChatDeHpAstroConfig owns the ${duplicate.name} integration.`);
|
|
76
|
+
}
|
|
77
|
+
}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { generateSiteFiles } from "./generator.js";
|
|
4
|
+
const args = process.argv.slice(2);
|
|
5
|
+
const command = args.shift();
|
|
6
|
+
try {
|
|
7
|
+
if (command !== "generate") {
|
|
8
|
+
throw new Error("Usage: chat-de-hp generate [--check] [--root <directory>]");
|
|
9
|
+
}
|
|
10
|
+
let check = false;
|
|
11
|
+
let root = process.cwd();
|
|
12
|
+
while (args.length > 0) {
|
|
13
|
+
const argument = args.shift();
|
|
14
|
+
if (argument === "--check") {
|
|
15
|
+
check = true;
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (argument === "--root") {
|
|
19
|
+
const value = args.shift();
|
|
20
|
+
if (!value) {
|
|
21
|
+
throw new Error("--root requires a directory.");
|
|
22
|
+
}
|
|
23
|
+
root = resolve(value);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
throw new Error(`Unknown argument: ${argument}`);
|
|
27
|
+
}
|
|
28
|
+
await generateSiteFiles({ check, root });
|
|
29
|
+
console.log(check
|
|
30
|
+
? "Chat de HP generated files are current."
|
|
31
|
+
: "Generated Chat de HP runtime files.");
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
35
|
+
process.exitCode = 1;
|
|
36
|
+
}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type ChatDeHpSiteConfig<TPrimitives extends readonly string[] = readonly string[]> = {
|
|
2
|
+
primitives: TPrimitives;
|
|
3
|
+
};
|
|
4
|
+
export declare function defineChatDeHpSite<const TPrimitives extends readonly string[]>(config: ChatDeHpSiteConfig<TPrimitives>): ChatDeHpSiteConfig<TPrimitives>;
|
|
5
|
+
export declare function parseChatDeHpSiteConfig(value: unknown): ChatDeHpSiteConfig;
|
|
6
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,kBAAkB,CAC5B,WAAW,SAAS,SAAS,MAAM,EAAE,GAAG,SAAS,MAAM,EAAE,IACvD;IACF,UAAU,EAAE,WAAW,CAAC;CACzB,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,WAAW,SAAS,SAAS,MAAM,EAAE,EAC5E,MAAM,EAAE,kBAAkB,CAAC,WAAW,CAAC,GACtC,kBAAkB,CAAC,WAAW,CAAC,CAEjC;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CA2C1E"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { isKnownPrimitiveId } from "./internal/primitive-names.js";
|
|
2
|
+
const CONFIG_FILENAME = "chat-de-hp.config.ts";
|
|
3
|
+
export function defineChatDeHpSite(config) {
|
|
4
|
+
return parseChatDeHpSiteConfig(config);
|
|
5
|
+
}
|
|
6
|
+
export function parseChatDeHpSiteConfig(value) {
|
|
7
|
+
if (!isRecord(value)) {
|
|
8
|
+
throw configError("must export an object");
|
|
9
|
+
}
|
|
10
|
+
const unsupportedKeys = Object.keys(value).filter((key) => key !== "primitives");
|
|
11
|
+
if (unsupportedKeys.length > 0) {
|
|
12
|
+
throw configError(`contains unsupported key(s): ${unsupportedKeys.sort().join(", ")}`);
|
|
13
|
+
}
|
|
14
|
+
if (!Array.isArray(value.primitives)) {
|
|
15
|
+
throw configError("primitives must be an array of strings");
|
|
16
|
+
}
|
|
17
|
+
const primitives = value.primitives.map((primitive, index) => {
|
|
18
|
+
if (typeof primitive !== "string" || primitive.length === 0) {
|
|
19
|
+
throw configError(`primitives[${index}] must be a non-empty string`);
|
|
20
|
+
}
|
|
21
|
+
if (!/^[a-z][a-z0-9-]*$/u.test(primitive)) {
|
|
22
|
+
throw configError(`primitive ${JSON.stringify(primitive)} is malformed`);
|
|
23
|
+
}
|
|
24
|
+
if (!isKnownPrimitiveId(primitive)) {
|
|
25
|
+
throw configError(`contains unknown primitive ${JSON.stringify(primitive)}`);
|
|
26
|
+
}
|
|
27
|
+
return primitive;
|
|
28
|
+
});
|
|
29
|
+
const duplicate = primitives.find((primitive, index) => primitives.indexOf(primitive) !== index);
|
|
30
|
+
if (duplicate) {
|
|
31
|
+
throw configError(`contains duplicate primitive ${JSON.stringify(duplicate)}`);
|
|
32
|
+
}
|
|
33
|
+
return Object.freeze({ primitives: Object.freeze([...primitives]) });
|
|
34
|
+
}
|
|
35
|
+
function configError(message) {
|
|
36
|
+
return new Error(`${CONFIG_FILENAME} ${message}.`);
|
|
37
|
+
}
|
|
38
|
+
function isRecord(value) {
|
|
39
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
40
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const siteFormFieldSchema: z.ZodObject<{
|
|
3
|
+
condition: z.ZodOptional<z.ZodObject<{
|
|
4
|
+
field: z.ZodString;
|
|
5
|
+
op: z.ZodEnum<{
|
|
6
|
+
eq: "eq";
|
|
7
|
+
neq: "neq";
|
|
8
|
+
filled: "filled";
|
|
9
|
+
empty: "empty";
|
|
10
|
+
}>;
|
|
11
|
+
value: z.ZodOptional<z.ZodString>;
|
|
12
|
+
}, z.core.$strip>>;
|
|
13
|
+
defaultValue: z.ZodOptional<z.ZodString>;
|
|
14
|
+
helpText: z.ZodOptional<z.ZodString>;
|
|
15
|
+
id: z.ZodString;
|
|
16
|
+
label: z.ZodString;
|
|
17
|
+
name: z.ZodString;
|
|
18
|
+
options: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
19
|
+
label: z.ZodString;
|
|
20
|
+
value: z.ZodString;
|
|
21
|
+
}, z.core.$strip>>>;
|
|
22
|
+
placeholder: z.ZodOptional<z.ZodString>;
|
|
23
|
+
required: z.ZodBoolean;
|
|
24
|
+
type: z.ZodEnum<{
|
|
25
|
+
number: "number";
|
|
26
|
+
text: "text";
|
|
27
|
+
email: "email";
|
|
28
|
+
file: "file";
|
|
29
|
+
url: "url";
|
|
30
|
+
date: "date";
|
|
31
|
+
textarea: "textarea";
|
|
32
|
+
tel: "tel";
|
|
33
|
+
select: "select";
|
|
34
|
+
radio: "radio";
|
|
35
|
+
checkbox: "checkbox";
|
|
36
|
+
"checkbox-group": "checkbox-group";
|
|
37
|
+
hidden: "hidden";
|
|
38
|
+
}>;
|
|
39
|
+
validation: z.ZodOptional<z.ZodObject<{
|
|
40
|
+
accept: z.ZodOptional<z.ZodString>;
|
|
41
|
+
max: z.ZodOptional<z.ZodNumber>;
|
|
42
|
+
maxFileSize: z.ZodOptional<z.ZodNumber>;
|
|
43
|
+
maxLength: z.ZodOptional<z.ZodNumber>;
|
|
44
|
+
min: z.ZodOptional<z.ZodNumber>;
|
|
45
|
+
minLength: z.ZodOptional<z.ZodNumber>;
|
|
46
|
+
pattern: z.ZodOptional<z.ZodString>;
|
|
47
|
+
patternMessage: z.ZodOptional<z.ZodString>;
|
|
48
|
+
}, z.core.$strip>>;
|
|
49
|
+
width: z.ZodDefault<z.ZodEnum<{
|
|
50
|
+
half: "half";
|
|
51
|
+
full: "full";
|
|
52
|
+
}>>;
|
|
53
|
+
}, z.core.$strip>;
|
|
54
|
+
export declare const siteFormInputSchema: z.ZodObject<{
|
|
55
|
+
name: z.ZodString;
|
|
56
|
+
pages: z.ZodArray<z.ZodObject<{
|
|
57
|
+
fields: z.ZodArray<z.ZodObject<{
|
|
58
|
+
condition: z.ZodOptional<z.ZodObject<{
|
|
59
|
+
field: z.ZodString;
|
|
60
|
+
op: z.ZodEnum<{
|
|
61
|
+
eq: "eq";
|
|
62
|
+
neq: "neq";
|
|
63
|
+
filled: "filled";
|
|
64
|
+
empty: "empty";
|
|
65
|
+
}>;
|
|
66
|
+
value: z.ZodOptional<z.ZodString>;
|
|
67
|
+
}, z.core.$strip>>;
|
|
68
|
+
defaultValue: z.ZodOptional<z.ZodString>;
|
|
69
|
+
helpText: z.ZodOptional<z.ZodString>;
|
|
70
|
+
id: z.ZodString;
|
|
71
|
+
label: z.ZodString;
|
|
72
|
+
name: z.ZodString;
|
|
73
|
+
options: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
74
|
+
label: z.ZodString;
|
|
75
|
+
value: z.ZodString;
|
|
76
|
+
}, z.core.$strip>>>;
|
|
77
|
+
placeholder: z.ZodOptional<z.ZodString>;
|
|
78
|
+
required: z.ZodBoolean;
|
|
79
|
+
type: z.ZodEnum<{
|
|
80
|
+
number: "number";
|
|
81
|
+
text: "text";
|
|
82
|
+
email: "email";
|
|
83
|
+
file: "file";
|
|
84
|
+
url: "url";
|
|
85
|
+
date: "date";
|
|
86
|
+
textarea: "textarea";
|
|
87
|
+
tel: "tel";
|
|
88
|
+
select: "select";
|
|
89
|
+
radio: "radio";
|
|
90
|
+
checkbox: "checkbox";
|
|
91
|
+
"checkbox-group": "checkbox-group";
|
|
92
|
+
hidden: "hidden";
|
|
93
|
+
}>;
|
|
94
|
+
validation: z.ZodOptional<z.ZodObject<{
|
|
95
|
+
accept: z.ZodOptional<z.ZodString>;
|
|
96
|
+
max: z.ZodOptional<z.ZodNumber>;
|
|
97
|
+
maxFileSize: z.ZodOptional<z.ZodNumber>;
|
|
98
|
+
maxLength: z.ZodOptional<z.ZodNumber>;
|
|
99
|
+
min: z.ZodOptional<z.ZodNumber>;
|
|
100
|
+
minLength: z.ZodOptional<z.ZodNumber>;
|
|
101
|
+
pattern: z.ZodOptional<z.ZodString>;
|
|
102
|
+
patternMessage: z.ZodOptional<z.ZodString>;
|
|
103
|
+
}, z.core.$strip>>;
|
|
104
|
+
width: z.ZodDefault<z.ZodEnum<{
|
|
105
|
+
half: "half";
|
|
106
|
+
full: "full";
|
|
107
|
+
}>>;
|
|
108
|
+
}, z.core.$strip>>;
|
|
109
|
+
title: z.ZodOptional<z.ZodString>;
|
|
110
|
+
}, z.core.$strip>>;
|
|
111
|
+
settings: z.ZodOptional<z.ZodObject<{
|
|
112
|
+
autoresponder: z.ZodOptional<z.ZodObject<{
|
|
113
|
+
body: z.ZodString;
|
|
114
|
+
subject: z.ZodString;
|
|
115
|
+
}, z.core.$strip>>;
|
|
116
|
+
confirmationMessage: z.ZodOptional<z.ZodString>;
|
|
117
|
+
digestEnabled: z.ZodOptional<z.ZodBoolean>;
|
|
118
|
+
digestHour: z.ZodOptional<z.ZodNumber>;
|
|
119
|
+
nextLabel: z.ZodOptional<z.ZodString>;
|
|
120
|
+
notifyEmails: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
121
|
+
prevLabel: z.ZodOptional<z.ZodString>;
|
|
122
|
+
redirectUrl: z.ZodUnion<[z.ZodOptional<z.ZodString>, z.ZodLiteral<"">]>;
|
|
123
|
+
retentionDays: z.ZodOptional<z.ZodNumber>;
|
|
124
|
+
spamProtection: z.ZodOptional<z.ZodEnum<{
|
|
125
|
+
none: "none";
|
|
126
|
+
honeypot: "honeypot";
|
|
127
|
+
turnstile: "turnstile";
|
|
128
|
+
}>>;
|
|
129
|
+
submitLabel: z.ZodOptional<z.ZodString>;
|
|
130
|
+
webhookUrl: z.ZodUnion<[z.ZodOptional<z.ZodString>, z.ZodLiteral<"">]>;
|
|
131
|
+
}, z.core.$strip>>;
|
|
132
|
+
slug: z.ZodString;
|
|
133
|
+
}, z.core.$strip>;
|
|
134
|
+
export type SiteFormInput = z.infer<typeof siteFormInputSchema>;
|
|
135
|
+
//# sourceMappingURL=forms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forms.d.ts","sourceRoot":"","sources":["../../src/contracts/forms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsD9B,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoC9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const siteFormFieldSchema = z.object({
|
|
3
|
+
condition: z
|
|
4
|
+
.object({
|
|
5
|
+
field: z.string().min(1),
|
|
6
|
+
op: z.enum(["eq", "neq", "filled", "empty"]),
|
|
7
|
+
value: z.string().optional(),
|
|
8
|
+
})
|
|
9
|
+
.optional(),
|
|
10
|
+
defaultValue: z.string().optional(),
|
|
11
|
+
helpText: z.string().optional(),
|
|
12
|
+
id: z.string().min(1),
|
|
13
|
+
label: z.string().min(1),
|
|
14
|
+
name: z
|
|
15
|
+
.string()
|
|
16
|
+
.min(1)
|
|
17
|
+
.regex(/^[a-zA-Z][a-zA-Z0-9_-]*$/u),
|
|
18
|
+
options: z
|
|
19
|
+
.array(z.object({
|
|
20
|
+
label: z.string().min(1),
|
|
21
|
+
value: z.string().min(1),
|
|
22
|
+
}))
|
|
23
|
+
.optional(),
|
|
24
|
+
placeholder: z.string().optional(),
|
|
25
|
+
required: z.boolean(),
|
|
26
|
+
type: z.enum([
|
|
27
|
+
"text",
|
|
28
|
+
"email",
|
|
29
|
+
"textarea",
|
|
30
|
+
"number",
|
|
31
|
+
"tel",
|
|
32
|
+
"url",
|
|
33
|
+
"date",
|
|
34
|
+
"select",
|
|
35
|
+
"radio",
|
|
36
|
+
"checkbox",
|
|
37
|
+
"checkbox-group",
|
|
38
|
+
"file",
|
|
39
|
+
"hidden",
|
|
40
|
+
]),
|
|
41
|
+
validation: z
|
|
42
|
+
.object({
|
|
43
|
+
accept: z.string().optional(),
|
|
44
|
+
max: z.number().optional(),
|
|
45
|
+
maxFileSize: z.number().int().min(1).optional(),
|
|
46
|
+
maxLength: z.number().int().min(1).optional(),
|
|
47
|
+
min: z.number().optional(),
|
|
48
|
+
minLength: z.number().int().min(0).optional(),
|
|
49
|
+
pattern: z.string().optional(),
|
|
50
|
+
patternMessage: z.string().optional(),
|
|
51
|
+
})
|
|
52
|
+
.optional(),
|
|
53
|
+
width: z.enum(["full", "half"]).default("full"),
|
|
54
|
+
});
|
|
55
|
+
export const siteFormInputSchema = z.object({
|
|
56
|
+
name: z.string().min(1).max(200),
|
|
57
|
+
pages: z
|
|
58
|
+
.array(z.object({
|
|
59
|
+
fields: z.array(siteFormFieldSchema).min(1),
|
|
60
|
+
title: z.string().optional(),
|
|
61
|
+
}))
|
|
62
|
+
.min(1),
|
|
63
|
+
settings: z
|
|
64
|
+
.object({
|
|
65
|
+
autoresponder: z
|
|
66
|
+
.object({
|
|
67
|
+
body: z.string().min(1),
|
|
68
|
+
subject: z.string().min(1),
|
|
69
|
+
})
|
|
70
|
+
.optional(),
|
|
71
|
+
confirmationMessage: z.string().min(1).optional(),
|
|
72
|
+
digestEnabled: z.boolean().optional(),
|
|
73
|
+
digestHour: z.number().int().min(0).max(23).optional(),
|
|
74
|
+
nextLabel: z.string().optional(),
|
|
75
|
+
notifyEmails: z.array(z.string().email()).optional(),
|
|
76
|
+
prevLabel: z.string().optional(),
|
|
77
|
+
redirectUrl: z.string().url().optional().or(z.literal("")),
|
|
78
|
+
retentionDays: z.number().int().min(0).optional(),
|
|
79
|
+
spamProtection: z.enum(["none", "honeypot", "turnstile"]).optional(),
|
|
80
|
+
submitLabel: z.string().min(1).optional(),
|
|
81
|
+
webhookUrl: z.string().url().optional().or(z.literal("")),
|
|
82
|
+
})
|
|
83
|
+
.optional(),
|
|
84
|
+
slug: z
|
|
85
|
+
.string()
|
|
86
|
+
.min(1)
|
|
87
|
+
.max(100)
|
|
88
|
+
.regex(/^[a-z][a-z0-9-]*$/u),
|
|
89
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const SITE_RUNTIME_NAME: "@chat-de-hp/site";
|
|
3
|
+
export declare const SITE_RUNTIME_VERSION: string;
|
|
4
|
+
export declare const SITE_RUNTIME_PROTOCOL_VERSION: 1;
|
|
5
|
+
export declare const SITE_RUNTIME_PRIMITIVES: readonly [{
|
|
6
|
+
readonly id: "forms";
|
|
7
|
+
readonly schemaVersion: 1;
|
|
8
|
+
}];
|
|
9
|
+
export declare const siteRuntimeBindingSchema: z.ZodObject<{
|
|
10
|
+
name: z.ZodString;
|
|
11
|
+
type: z.ZodEnum<{
|
|
12
|
+
d1: "d1";
|
|
13
|
+
images: "images";
|
|
14
|
+
kv_namespace: "kv_namespace";
|
|
15
|
+
r2_bucket: "r2_bucket";
|
|
16
|
+
send_email: "send_email";
|
|
17
|
+
worker_loader: "worker_loader";
|
|
18
|
+
}>;
|
|
19
|
+
}, z.core.$loose>;
|
|
20
|
+
export declare const siteRuntimeManifestSchema: z.ZodObject<{
|
|
21
|
+
capabilities: z.ZodArray<z.ZodObject<{
|
|
22
|
+
id: z.ZodString;
|
|
23
|
+
provider: z.ZodString;
|
|
24
|
+
schemaVersion: z.ZodNumber;
|
|
25
|
+
}, z.core.$loose>>;
|
|
26
|
+
primitives: z.ZodArray<z.ZodObject<{
|
|
27
|
+
id: z.ZodString;
|
|
28
|
+
schemaVersion: z.ZodNumber;
|
|
29
|
+
}, z.core.$loose>>;
|
|
30
|
+
requiredBindings: z.ZodArray<z.ZodObject<{
|
|
31
|
+
name: z.ZodString;
|
|
32
|
+
type: z.ZodEnum<{
|
|
33
|
+
d1: "d1";
|
|
34
|
+
images: "images";
|
|
35
|
+
kv_namespace: "kv_namespace";
|
|
36
|
+
r2_bucket: "r2_bucket";
|
|
37
|
+
send_email: "send_email";
|
|
38
|
+
worker_loader: "worker_loader";
|
|
39
|
+
}>;
|
|
40
|
+
}, z.core.$loose>>;
|
|
41
|
+
runtime: z.ZodObject<{
|
|
42
|
+
name: z.ZodLiteral<"@chat-de-hp/site">;
|
|
43
|
+
protocolVersion: z.ZodLiteral<1>;
|
|
44
|
+
version: z.ZodString;
|
|
45
|
+
}, z.core.$loose>;
|
|
46
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
47
|
+
}, z.core.$loose>;
|
|
48
|
+
export type SiteRuntimeBinding = z.infer<typeof siteRuntimeBindingSchema>;
|
|
49
|
+
export type SiteRuntimeManifest = z.infer<typeof siteRuntimeManifestSchema>;
|
|
50
|
+
export declare function parseSiteRuntimeManifest(value: unknown): SiteRuntimeManifest;
|
|
51
|
+
//# sourceMappingURL=control-plane.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control-plane.d.ts","sourceRoot":"","sources":["../src/control-plane.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,iBAAiB,EAAG,kBAA2B,CAAC;AAC7D,eAAO,MAAM,oBAAoB,QAAsB,CAAC;AACxD,eAAO,MAAM,6BAA6B,EAAG,CAAU,CAAC;AACxD,eAAO,MAAM,uBAAuB;;;EAE1B,CAAC;AAEX,eAAO,MAAM,wBAAwB;;;;;;;;;;iBAYrB,CAAC;AAEjB,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6BtB,CAAC;AAEjB,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAC1E,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CAE5E"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import packageJson from "../package.json" with { type: "json" };
|
|
3
|
+
export const SITE_RUNTIME_NAME = "@chat-de-hp/site";
|
|
4
|
+
export const SITE_RUNTIME_VERSION = packageJson.version;
|
|
5
|
+
export const SITE_RUNTIME_PROTOCOL_VERSION = 1;
|
|
6
|
+
export const SITE_RUNTIME_PRIMITIVES = [
|
|
7
|
+
{ id: "forms", schemaVersion: 1 },
|
|
8
|
+
];
|
|
9
|
+
export const siteRuntimeBindingSchema = z
|
|
10
|
+
.object({
|
|
11
|
+
name: z.string().min(1),
|
|
12
|
+
type: z.enum([
|
|
13
|
+
"d1",
|
|
14
|
+
"images",
|
|
15
|
+
"kv_namespace",
|
|
16
|
+
"r2_bucket",
|
|
17
|
+
"send_email",
|
|
18
|
+
"worker_loader",
|
|
19
|
+
]),
|
|
20
|
+
})
|
|
21
|
+
.passthrough();
|
|
22
|
+
export const siteRuntimeManifestSchema = z
|
|
23
|
+
.object({
|
|
24
|
+
capabilities: z.array(z
|
|
25
|
+
.object({
|
|
26
|
+
id: z.string().min(1),
|
|
27
|
+
provider: z.string().min(1),
|
|
28
|
+
schemaVersion: z.number().int().positive(),
|
|
29
|
+
})
|
|
30
|
+
.passthrough()),
|
|
31
|
+
primitives: z.array(z
|
|
32
|
+
.object({
|
|
33
|
+
id: z.string().min(1),
|
|
34
|
+
schemaVersion: z.number().int().positive(),
|
|
35
|
+
})
|
|
36
|
+
.passthrough()),
|
|
37
|
+
requiredBindings: z.array(siteRuntimeBindingSchema),
|
|
38
|
+
runtime: z
|
|
39
|
+
.object({
|
|
40
|
+
name: z.literal(SITE_RUNTIME_NAME),
|
|
41
|
+
protocolVersion: z.literal(SITE_RUNTIME_PROTOCOL_VERSION),
|
|
42
|
+
version: z.string().min(1),
|
|
43
|
+
})
|
|
44
|
+
.passthrough(),
|
|
45
|
+
schemaVersion: z.literal(1),
|
|
46
|
+
})
|
|
47
|
+
.passthrough();
|
|
48
|
+
export function parseSiteRuntimeManifest(value) {
|
|
49
|
+
return siteRuntimeManifestSchema.parse(value);
|
|
50
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ChatDeHpSiteConfig } from "./config.js";
|
|
2
|
+
import type { SiteRuntimeManifest } from "./control-plane.js";
|
|
3
|
+
export type GeneratedSiteFiles = {
|
|
4
|
+
manifest: string;
|
|
5
|
+
runtime: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function loadSiteConfig(root: string): Promise<unknown>;
|
|
8
|
+
export declare function renderGeneratedSiteFiles(config: ChatDeHpSiteConfig | unknown): GeneratedSiteFiles;
|
|
9
|
+
export declare function generateSiteFiles(options: {
|
|
10
|
+
check?: boolean;
|
|
11
|
+
config?: ChatDeHpSiteConfig | unknown;
|
|
12
|
+
/** @internal */
|
|
13
|
+
onCurrentGeneratedDirectoryMoved?: () => Promise<void>;
|
|
14
|
+
root: string;
|
|
15
|
+
}): Promise<GeneratedSiteFiles>;
|
|
16
|
+
export declare function validateSiteWranglerBindings(root: string, manifest: SiteRuntimeManifest): Promise<void>;
|
|
17
|
+
//# sourceMappingURL=generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAEV,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAK5B,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiBnE;AAED,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,kBAAkB,GAAG,OAAO,GACnC,kBAAkB,CAuBpB;AAED,wBAAsB,iBAAiB,CAAC,OAAO,EAAE;IAC/C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC;IAEtC,gBAAgB;IAChB,gCAAgC,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,IAAI,EAAE,MAAM,CAAC;CACd,+BAyBA;AAED,wBAAsB,4BAA4B,CAChD,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,mBAAmB,iBAkD9B"}
|