@caelo-cms/shared 0.10.22 → 0.10.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-tools.d.ts +289 -273
- package/dist/ai-tools.d.ts.map +1 -1
- package/dist/ai-tools.js +342 -323
- package/dist/ai-tools.js.map +1 -1
- package/dist/auth-forms.d.ts.map +1 -1
- package/dist/auth-forms.js +4 -1
- package/dist/auth-forms.js.map +1 -1
- package/dist/base-css.d.ts +35 -0
- package/dist/base-css.d.ts.map +1 -0
- package/dist/base-css.js +40 -0
- package/dist/base-css.js.map +1 -0
- package/dist/build-page.d.ts +330 -0
- package/dist/build-page.d.ts.map +1 -0
- package/dist/build-page.js +282 -0
- package/dist/build-page.js.map +1 -0
- package/dist/content.d.ts +322 -9
- package/dist/content.d.ts.map +1 -1
- package/dist/content.js +354 -11
- package/dist/content.js.map +1 -1
- package/dist/css-gradient-scan.d.ts +14 -0
- package/dist/css-gradient-scan.d.ts.map +1 -0
- package/dist/css-gradient-scan.js +81 -0
- package/dist/css-gradient-scan.js.map +1 -0
- package/dist/css-var-scan.d.ts +56 -0
- package/dist/css-var-scan.d.ts.map +1 -0
- package/dist/css-var-scan.js +97 -0
- package/dist/css-var-scan.js.map +1 -0
- package/dist/design-draft-shell.d.ts +21 -0
- package/dist/design-draft-shell.d.ts.map +1 -0
- package/dist/design-draft-shell.js +81 -0
- package/dist/design-draft-shell.js.map +1 -0
- package/dist/design-manifest.d.ts +36 -0
- package/dist/design-manifest.d.ts.map +1 -0
- package/dist/design-manifest.js +90 -0
- package/dist/design-manifest.js.map +1 -0
- package/dist/fonts.d.ts +89 -0
- package/dist/fonts.d.ts.map +1 -0
- package/dist/fonts.js +241 -0
- package/dist/fonts.js.map +1 -0
- package/dist/genesis-inventory.d.ts +32 -0
- package/dist/genesis-inventory.d.ts.map +1 -0
- package/dist/genesis-inventory.js +186 -0
- package/dist/genesis-inventory.js.map +1 -0
- package/dist/genesis.d.ts +102 -0
- package/dist/genesis.d.ts.map +1 -0
- package/dist/genesis.js +145 -0
- package/dist/genesis.js.map +1 -0
- package/dist/i18n.d.ts +29 -36
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +53 -128
- package/dist/i18n.js.map +1 -1
- package/dist/index.d.ts +28 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -1
- package/dist/index.js.map +1 -1
- package/dist/interactions.d.ts +23 -0
- package/dist/interactions.d.ts.map +1 -0
- package/dist/interactions.js +44 -0
- package/dist/interactions.js.map +1 -0
- package/dist/media.d.ts +101 -16
- package/dist/media.d.ts.map +1 -1
- package/dist/media.js +126 -15
- package/dist/media.js.map +1 -1
- package/dist/page-log.d.ts +94 -0
- package/dist/page-log.d.ts.map +1 -0
- package/dist/page-log.js +111 -0
- package/dist/page-log.js.map +1 -0
- package/dist/preview-compose.d.ts +85 -12
- package/dist/preview-compose.d.ts.map +1 -1
- package/dist/preview-compose.js +157 -67
- package/dist/preview-compose.js.map +1 -1
- package/dist/proposal-status.d.ts +40 -0
- package/dist/proposal-status.d.ts.map +1 -0
- package/dist/proposal-status.js +34 -0
- package/dist/proposal-status.js.map +1 -0
- package/dist/responsive-images.d.ts +64 -0
- package/dist/responsive-images.d.ts.map +1 -0
- package/dist/responsive-images.js +98 -0
- package/dist/responsive-images.js.map +1 -0
- package/dist/safe-keys.d.ts +9 -0
- package/dist/safe-keys.d.ts.map +1 -0
- package/dist/safe-keys.js +20 -0
- package/dist/safe-keys.js.map +1 -0
- package/dist/seo.d.ts +11 -16
- package/dist/seo.d.ts.map +1 -1
- package/dist/seo.js +7 -23
- package/dist/seo.js.map +1 -1
- package/dist/skills.d.ts +14 -68
- package/dist/skills.d.ts.map +1 -1
- package/dist/skills.js +19 -113
- package/dist/skills.js.map +1 -1
- package/dist/strip-cdata.d.ts +7 -0
- package/dist/strip-cdata.d.ts.map +1 -0
- package/dist/strip-cdata.js +48 -0
- package/dist/strip-cdata.js.map +1 -0
- package/dist/structured-sets.d.ts +6 -52
- package/dist/structured-sets.d.ts.map +1 -1
- package/dist/structured-sets.js +6 -68
- package/dist/structured-sets.js.map +1 -1
- package/dist/subagents.d.ts +105 -3
- package/dist/subagents.d.ts.map +1 -1
- package/dist/subagents.js +224 -41
- package/dist/subagents.js.map +1 -1
- package/dist/template-engine.d.ts +85 -0
- package/dist/template-engine.d.ts.map +1 -0
- package/dist/template-engine.js +403 -0
- package/dist/template-engine.js.map +1 -0
- package/dist/theme-importers/auto-detect.d.ts +26 -0
- package/dist/theme-importers/auto-detect.d.ts.map +1 -0
- package/dist/theme-importers/auto-detect.js +42 -0
- package/dist/theme-importers/auto-detect.js.map +1 -0
- package/dist/theme-importers/css-comments.d.ts +12 -0
- package/dist/theme-importers/css-comments.d.ts.map +1 -0
- package/dist/theme-importers/css-comments.js +15 -0
- package/dist/theme-importers/css-comments.js.map +1 -0
- package/dist/theme-importers/dtcg.d.ts +46 -0
- package/dist/theme-importers/dtcg.d.ts.map +1 -0
- package/dist/theme-importers/dtcg.js +111 -0
- package/dist/theme-importers/dtcg.js.map +1 -0
- package/dist/theme-importers/loose.d.ts +3 -0
- package/dist/theme-importers/loose.d.ts.map +1 -0
- package/dist/theme-importers/loose.js +76 -0
- package/dist/theme-importers/loose.js.map +1 -0
- package/dist/theme-importers/shadcn.d.ts +24 -0
- package/dist/theme-importers/shadcn.d.ts.map +1 -0
- package/dist/theme-importers/shadcn.js +135 -0
- package/dist/theme-importers/shadcn.js.map +1 -0
- package/dist/theme-importers/style-dictionary.d.ts +17 -0
- package/dist/theme-importers/style-dictionary.d.ts.map +1 -0
- package/dist/theme-importers/style-dictionary.js +125 -0
- package/dist/theme-importers/style-dictionary.js.map +1 -0
- package/dist/theme-importers/tailwind.d.ts +3 -0
- package/dist/theme-importers/tailwind.d.ts.map +1 -0
- package/dist/theme-importers/tailwind.js +218 -0
- package/dist/theme-importers/tailwind.js.map +1 -0
- package/dist/theme-literal-binding.d.ts +37 -0
- package/dist/theme-literal-binding.d.ts.map +1 -0
- package/dist/theme-literal-binding.js +138 -0
- package/dist/theme-literal-binding.js.map +1 -0
- package/dist/theme-normalize.d.ts +31 -0
- package/dist/theme-normalize.d.ts.map +1 -0
- package/dist/theme-normalize.js +587 -0
- package/dist/theme-normalize.js.map +1 -0
- package/dist/theme-ramp.d.ts +55 -0
- package/dist/theme-ramp.d.ts.map +1 -0
- package/dist/theme-ramp.js +149 -0
- package/dist/theme-ramp.js.map +1 -0
- package/dist/theme-render.d.ts +105 -0
- package/dist/theme-render.d.ts.map +1 -0
- package/dist/theme-render.js +441 -0
- package/dist/theme-render.js.map +1 -0
- package/dist/themes-errors.d.ts +109 -0
- package/dist/themes-errors.d.ts.map +1 -0
- package/dist/themes-errors.js +170 -0
- package/dist/themes-errors.js.map +1 -0
- package/dist/themes.d.ts +343 -0
- package/dist/themes.d.ts.map +1 -0
- package/dist/themes.js +697 -0
- package/dist/themes.js.map +1 -0
- package/dist/version.d.ts +7 -4
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +6 -3
- package/dist/version.js.map +1 -1
- package/package.json +10 -2
- package/src/__tests__/redos-hardening.test.ts +160 -0
- package/src/ai-tools-add-module-modes.test.ts +106 -0
- package/src/ai-tools-position.test.ts +134 -0
- package/src/ai-tools.test.ts +81 -0
- package/src/ai-tools.ts +1105 -0
- package/src/auth-forms.ts +36 -0
- package/src/base-css.ts +42 -0
- package/src/build-page.test.ts +228 -0
- package/src/build-page.ts +319 -0
- package/src/cap-failures.ts +67 -0
- package/src/content.test.ts +170 -0
- package/src/content.ts +620 -0
- package/src/context.ts +43 -0
- package/src/css-gradient-scan.ts +88 -0
- package/src/css-var-scan.test.ts +96 -0
- package/src/css-var-scan.ts +144 -0
- package/src/derive-module-type.test.ts +80 -0
- package/src/design-draft-shell.test.ts +85 -0
- package/src/design-draft-shell.ts +109 -0
- package/src/design-manifest.ts +93 -0
- package/src/fonts.test.ts +157 -0
- package/src/fonts.ts +296 -0
- package/src/genesis-inventory.test.ts +86 -0
- package/src/genesis-inventory.ts +215 -0
- package/src/genesis-sanitize.test.ts +35 -0
- package/src/genesis.ts +158 -0
- package/src/i18n.test.ts +58 -0
- package/src/i18n.ts +91 -0
- package/src/index.test.ts +10 -0
- package/src/index.ts +59 -0
- package/src/interactions.ts +48 -0
- package/src/logger.ts +147 -0
- package/src/media.test.ts +160 -0
- package/src/media.ts +355 -0
- package/src/page-log.test.ts +163 -0
- package/src/page-log.ts +124 -0
- package/src/preview-compose.test.ts +637 -0
- package/src/preview-compose.ts +656 -0
- package/src/preview-scanner.test.ts +96 -0
- package/src/preview-scanner.ts +214 -0
- package/src/proposal-status.test.ts +69 -0
- package/src/proposal-status.ts +40 -0
- package/src/responsive-images.test.ts +104 -0
- package/src/responsive-images.ts +151 -0
- package/src/result.ts +29 -0
- package/src/safe-keys.ts +21 -0
- package/src/seo.test.ts +194 -0
- package/src/seo.ts +233 -0
- package/src/skills.ts +48 -0
- package/src/snapshots.test.ts +80 -0
- package/src/snapshots.ts +81 -0
- package/src/strip-cdata.test.ts +41 -0
- package/src/strip-cdata.ts +50 -0
- package/src/structured-sets.ts +114 -0
- package/src/subagents.test.ts +262 -0
- package/src/subagents.ts +432 -0
- package/src/template-engine.test.ts +379 -0
- package/src/template-engine.ts +520 -0
- package/src/theme-gradient.test.ts +92 -0
- package/src/theme-importers/__tests__/proto-pollution.test.ts +54 -0
- package/src/theme-importers/auto-detect.ts +84 -0
- package/src/theme-importers/css-comments.ts +15 -0
- package/src/theme-importers/dtcg.ts +106 -0
- package/src/theme-importers/loose.ts +76 -0
- package/src/theme-importers/shadcn.ts +133 -0
- package/src/theme-importers/style-dictionary.ts +125 -0
- package/src/theme-importers/tailwind.ts +217 -0
- package/src/theme-literal-binding.test.ts +71 -0
- package/src/theme-literal-binding.ts +159 -0
- package/src/theme-motion.test.ts +115 -0
- package/src/theme-normalize-envelope.test.ts +43 -0
- package/src/theme-normalize-gradient.test.ts +135 -0
- package/src/theme-normalize.ts +661 -0
- package/src/theme-ramp.ts +187 -0
- package/src/theme-render-sanitize.test.ts +45 -0
- package/src/theme-render.test.ts +119 -0
- package/src/theme-render.ts +487 -0
- package/src/theme-shadow.test.ts +56 -0
- package/src/themes-errors.ts +199 -0
- package/src/themes.ts +842 -0
- package/src/version.ts +66 -0
- package/dist/translation.d.ts +0 -127
- package/dist/translation.d.ts.map +0 -1
- package/dist/translation.js +0 -208
- package/dist/translation.js.map +0 -1
package/dist/genesis.js
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MPL-2.0
|
|
2
|
+
/**
|
|
3
|
+
* issue #163 — Site Genesis shared shapes; issue #375 generalises the
|
|
4
|
+
* same draft loop to growth-time.
|
|
5
|
+
*
|
|
6
|
+
* Design-time is divergent: the AI drafts complete freeform HTML pages
|
|
7
|
+
* (one per design direction) and the operator picks one; the CMS
|
|
8
|
+
* structure is derived FROM that choice (#164's compiler). Growth-time
|
|
9
|
+
* reuses the identical draft → present → select → materialise loop at
|
|
10
|
+
* smaller scope: `page` and `module` drafts are FRAGMENTS bound to the
|
|
11
|
+
* site's `var(--…)` theme tokens, composed into the real theme shell
|
|
12
|
+
* only at view time (never an AI approximation of the theme — #375).
|
|
13
|
+
* These are the boundary schemas for the brief + the draft rows.
|
|
14
|
+
*/
|
|
15
|
+
import { z } from "zod";
|
|
16
|
+
/**
|
|
17
|
+
* The structured Design Brief the discovery dialog produces. Every
|
|
18
|
+
* field optional — the AI fills what the conversation answered; the
|
|
19
|
+
* draft prompts degrade gracefully on gaps. Stored on
|
|
20
|
+
* `site_defaults.design_brief`.
|
|
21
|
+
*/
|
|
22
|
+
export const designBriefSchema = z
|
|
23
|
+
.object({
|
|
24
|
+
audience: z.string().min(1).max(500).optional(),
|
|
25
|
+
/** 3–5 adjectives the operator wants the design to feel like. */
|
|
26
|
+
moodWords: z.array(z.string().min(1).max(40)).max(12).optional(),
|
|
27
|
+
tone: z.string().min(1).max(300).optional(),
|
|
28
|
+
industry: z.string().min(1).max(200).optional(),
|
|
29
|
+
differentiators: z.string().min(1).max(1000).optional(),
|
|
30
|
+
imageryDirection: z.string().min(1).max(500).optional(),
|
|
31
|
+
avoid: z.string().min(1).max(500).optional(),
|
|
32
|
+
})
|
|
33
|
+
.strict();
|
|
34
|
+
/** Complete single-file drafts stay well under this (inline CSS only). */
|
|
35
|
+
export const GENESIS_DRAFT_MAX_HTML_BYTES = 300_000;
|
|
36
|
+
export const genesisDraftStatus = z.enum(["candidate", "selected", "discarded"]);
|
|
37
|
+
/** issue #199 — where a draft came from. */
|
|
38
|
+
export const genesisDraftSourceKind = z.enum(["genesis", "byod_image", "byod_html"]);
|
|
39
|
+
/**
|
|
40
|
+
* issue #375 — what a draft covers. `site` is the Genesis case (a whole
|
|
41
|
+
* new design); `page` / `module` are growth-time variants of something
|
|
42
|
+
* that already exists.
|
|
43
|
+
*/
|
|
44
|
+
export const designDraftScope = z.enum(["site", "page", "module"]);
|
|
45
|
+
/**
|
|
46
|
+
* issue #375 — how a draft's HTML is stored. `site` drafts are complete
|
|
47
|
+
* standalone documents (Genesis, unchanged); `page`/`module` drafts are
|
|
48
|
+
* fragments that only become a renderable document when composed with
|
|
49
|
+
* the site's real theme shell at view time — so a stored variant never
|
|
50
|
+
* freezes a stale copy of the theme.
|
|
51
|
+
*/
|
|
52
|
+
export const designDraftFormat = z.enum(["document", "fragment"]);
|
|
53
|
+
/** The stored format is fully determined by the scope (see the paired
|
|
54
|
+
* DB CHECK constraint): `site` → standalone document, else fragment. */
|
|
55
|
+
export function draftFormatForScope(scope) {
|
|
56
|
+
return scope === "site" ? "document" : "fragment";
|
|
57
|
+
}
|
|
58
|
+
const addDraftBase = z
|
|
59
|
+
.object({
|
|
60
|
+
/** Human-readable design direction ("bold editorial"). */
|
|
61
|
+
direction: z.string().min(3).max(120),
|
|
62
|
+
/** Why this direction fits the brief — shown beside the preview. */
|
|
63
|
+
rationale: z.string().max(1000).default(""),
|
|
64
|
+
/** Site scope: complete self-contained single-file HTML. Page/module
|
|
65
|
+
* scope: an HTML fragment bound to the site's `var(--…)` tokens. */
|
|
66
|
+
html: z.string().min(200).max(GENESIS_DRAFT_MAX_HTML_BYTES),
|
|
67
|
+
/** issue #375 — what this draft covers; `site` is the Genesis case. */
|
|
68
|
+
scope: designDraftScope.default("site"),
|
|
69
|
+
/** issue #375 — page scope: the page this variant redesigns. Module
|
|
70
|
+
* scope: optional page context for "this module as used on …". */
|
|
71
|
+
targetPageId: z.string().uuid().optional(),
|
|
72
|
+
/** issue #375 — module scope: the module this variant restyles. */
|
|
73
|
+
targetModuleId: z.string().uuid().optional(),
|
|
74
|
+
/** issue #375 — groups one request's variants into one comparison.
|
|
75
|
+
* Omit on the first save (the op mints and returns it); pass it on
|
|
76
|
+
* every sibling save of the same round. */
|
|
77
|
+
variantSetId: z.string().uuid().optional(),
|
|
78
|
+
/** issue #199 — 'byod_image' (AI reproduction of an operator
|
|
79
|
+
* mockup) / 'byod_html' (operator HTML, sanitised at the op). */
|
|
80
|
+
sourceKind: genesisDraftSourceKind.default("genesis"),
|
|
81
|
+
/** issue #199 — byod_image only: the uploaded mockup's media
|
|
82
|
+
* asset. The parity gate uses THIS image as the reference. */
|
|
83
|
+
referenceAssetId: z.string().uuid().optional(),
|
|
84
|
+
})
|
|
85
|
+
.strict();
|
|
86
|
+
/** Scope/target pairing rules shared by the op and the AI tool. */
|
|
87
|
+
export const genesisAddDraftInput = addDraftBase.superRefine((v, ctx) => {
|
|
88
|
+
if (v.scope === "site") {
|
|
89
|
+
if (v.targetPageId !== undefined || v.targetModuleId !== undefined) {
|
|
90
|
+
ctx.addIssue({
|
|
91
|
+
code: z.ZodIssueCode.custom,
|
|
92
|
+
message: "site-scope drafts take no target — drop targetPageId/targetModuleId",
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else if (v.sourceKind !== "genesis") {
|
|
97
|
+
ctx.addIssue({
|
|
98
|
+
code: z.ZodIssueCode.custom,
|
|
99
|
+
message: "byod drafts are site-scope only (issue #199); growth-time variants use sourceKind 'genesis'",
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
else if (v.scope === "page") {
|
|
103
|
+
if (v.targetPageId === undefined || v.targetModuleId !== undefined) {
|
|
104
|
+
ctx.addIssue({
|
|
105
|
+
code: z.ZodIssueCode.custom,
|
|
106
|
+
message: "page-scope drafts need targetPageId (and no targetModuleId)",
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
else if (v.targetModuleId === undefined) {
|
|
111
|
+
ctx.addIssue({
|
|
112
|
+
code: z.ZodIssueCode.custom,
|
|
113
|
+
message: "module-scope drafts need targetModuleId (targetPageId is optional page context)",
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
/**
|
|
118
|
+
* issue #199 — strip <script> blocks from operator-provided draft
|
|
119
|
+
* HTML. Defense in depth: drafts render inside sandbox="" iframes
|
|
120
|
+
* (scripts never execute there), but stored HTML flows onward into
|
|
121
|
+
* materialisation, so the boundary removes them outright. Linear
|
|
122
|
+
* scan per the #113 discipline; case-insensitive; unterminated
|
|
123
|
+
* script blocks drop everything to EOF (never leak half a script).
|
|
124
|
+
*/
|
|
125
|
+
export function sanitizeDraftHtml(html) {
|
|
126
|
+
const lower = html.toLowerCase();
|
|
127
|
+
let out = "";
|
|
128
|
+
let from = 0;
|
|
129
|
+
while (true) {
|
|
130
|
+
const open = lower.indexOf("<script", from);
|
|
131
|
+
if (open === -1) {
|
|
132
|
+
out += html.slice(from);
|
|
133
|
+
return out;
|
|
134
|
+
}
|
|
135
|
+
out += html.slice(from, open);
|
|
136
|
+
const close = lower.indexOf("</script", open);
|
|
137
|
+
if (close === -1)
|
|
138
|
+
return out;
|
|
139
|
+
const closeEnd = lower.indexOf(">", close);
|
|
140
|
+
if (closeEnd === -1)
|
|
141
|
+
return out;
|
|
142
|
+
from = closeEnd + 1;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=genesis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"genesis.js","sourceRoot":"","sources":["../src/genesis.ts"],"names":[],"mappings":"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"}
|
package/dist/i18n.d.ts
CHANGED
|
@@ -1,49 +1,42 @@
|
|
|
1
|
-
export interface LocaleConfig {
|
|
2
|
-
code: string;
|
|
3
|
-
displayName: string;
|
|
4
|
-
urlStrategy: "none" | "subdirectory" | "subdomain" | "domain";
|
|
5
|
-
urlHost: string | null;
|
|
6
|
-
isDefault: boolean;
|
|
7
|
-
}
|
|
8
1
|
/**
|
|
9
|
-
*
|
|
10
|
-
* no DB access — so the static generator can call it for every page
|
|
11
|
-
* without round-trips.
|
|
2
|
+
* Strip leading and trailing `/` characters with a single linear scan.
|
|
12
3
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* @returns Absolute URL, including scheme + host.
|
|
4
|
+
* Replaces the regex `/^\/+|\/+$/g`, whose trailing-slash branch
|
|
5
|
+
* backtracks O(n²) on a long run of slashes that is not at end-of-string
|
|
6
|
+
* (CodeQL js/polynomial-redos). This char-index walk is unconditionally
|
|
7
|
+
* linear and produces byte-identical output for every input.
|
|
18
8
|
*/
|
|
19
|
-
export declare function
|
|
9
|
+
export declare function trimSlashes(s: string): string;
|
|
20
10
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
11
|
+
* Strip only trailing `/` characters with a single linear scan — the
|
|
12
|
+
* non-backtracking replacement for `/\/+$/` (same ReDoS class as above).
|
|
13
|
+
* Used for base URLs, which carry a scheme and must keep their leading
|
|
14
|
+
* characters.
|
|
15
|
+
*/
|
|
16
|
+
export declare function trimTrailingSlashes(s: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* The "magic slug" sentinel test: a page whose slug is empty, `home`,
|
|
19
|
+
* or `index` is the locale root by convention even without an explicit
|
|
20
|
+
* `locales.home_page_id` designation. Leading/trailing slashes are
|
|
21
|
+
* ignored so `/home/` reads the same as `home`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function isHomeSlug(slug: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* The single home-decision predicate every URL/output-path site must
|
|
26
|
+
* use so canonical, hreflang, redirects, and the emitted file agree
|
|
27
|
+
* (0184 explicit-homepage feature). A page is the locale root when it
|
|
28
|
+
* IS the locale's designated `home_page_id` OR carries a magic slug.
|
|
24
29
|
*
|
|
25
|
-
*
|
|
30
|
+
* @param pageId The page being resolved.
|
|
31
|
+
* @param slug That page's slug.
|
|
32
|
+
* @param localeHomePageId `locales.home_page_id` for the page's locale
|
|
33
|
+
* (null/undefined when no page is designated).
|
|
26
34
|
*/
|
|
27
|
-
export declare function
|
|
28
|
-
localeCode: string;
|
|
29
|
-
url: string;
|
|
30
|
-
isDefault: boolean;
|
|
31
|
-
}>): string;
|
|
35
|
+
export declare function pageIsLocaleHome(pageId: string, slug: string, localeHomePageId: string | null | undefined): boolean;
|
|
32
36
|
/**
|
|
33
37
|
* Canonical-JSON serializer + sha256 → hex. Stable across runs because
|
|
34
38
|
* keys are sorted. The output is used for `pages.content_hash` so that
|
|
35
39
|
* a Mode-2 translation can detect whether its source has changed.
|
|
36
40
|
*/
|
|
37
41
|
export declare function computeContentHash(value: unknown): Promise<string>;
|
|
38
|
-
export interface LocaleLintWarning {
|
|
39
|
-
code: string;
|
|
40
|
-
message: string;
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Cross-row config sanity checks. Run at:
|
|
44
|
-
* - propose-time (warnings stored on the proposal preview)
|
|
45
|
-
* - render-time (no fail-loudly per CLAUDE.md §2 since the renderer
|
|
46
|
-
* can still emit; surfaced in admin UI as banners)
|
|
47
|
-
*/
|
|
48
|
-
export declare function lintLocaleConfig(locales: ReadonlyArray<LocaleConfig>, advancedUrlRouting: boolean): LocaleLintWarning[];
|
|
49
42
|
//# sourceMappingURL=i18n.d.ts.map
|
package/dist/i18n.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAgBA;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAM7C;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAIrD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGhD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC1C,OAAO,CAET;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAWxE"}
|
package/dist/i18n.js
CHANGED
|
@@ -1,105 +1,68 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MPL-2.0
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Slug/URL primitives shared between the static generator, the preview
|
|
4
|
+
* op, and the admin UI. Epic #380 Phase A (#383): locale URL shaping
|
|
5
|
+
* (resolveLocaleUrl, buildHreflangLinks) is deleted — URL shape beyond
|
|
6
|
+
* base + slug becomes a plugin contribution on the URL composition
|
|
7
|
+
* point (#390). What survives until the page-identity cut (#384):
|
|
5
8
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* resolveLocaleUrl(locale, slug, defaultLocaleCode, siteBaseUrl) —
|
|
11
|
-
* builds the public URL for a (locale, slug) tuple given the
|
|
12
|
-
* locale's url_strategy + url_host. Used by:
|
|
13
|
-
* - hreflang emitter
|
|
14
|
-
* - sitemap.xml emitter (when extended for i18n)
|
|
15
|
-
* - language-selector module
|
|
16
|
-
*
|
|
17
|
-
* buildHreflangLinks(currentLocale, perLocaleUrls, defaultLocaleCode) —
|
|
18
|
-
* emits the `<link rel="alternate" hreflang=...>` markup.
|
|
19
|
-
*
|
|
20
|
-
* lintLocaleConfig(locales, advancedUrlRouting) — surfaces config
|
|
21
|
-
* warnings (mixed strategies, missing url_host for subdomain/
|
|
22
|
-
* domain, default locale using `none` alongside subdirectory
|
|
23
|
-
* siblings, advanced strategy chosen while toggle is off).
|
|
9
|
+
* isHomeSlug / pageIsLocaleHome — the home-decision predicate.
|
|
10
|
+
* computeContentHash — drives `pages.content_hash` (removed in #384).
|
|
11
|
+
* trimSlashes / trimTrailingSlashes — linear-scan slug hygiene.
|
|
24
12
|
*/
|
|
25
13
|
const TEXT_ENCODER = new TextEncoder();
|
|
26
14
|
/**
|
|
27
|
-
*
|
|
28
|
-
* no DB access — so the static generator can call it for every page
|
|
29
|
-
* without round-trips.
|
|
15
|
+
* Strip leading and trailing `/` characters with a single linear scan.
|
|
30
16
|
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* @returns Absolute URL, including scheme + host.
|
|
17
|
+
* Replaces the regex `/^\/+|\/+$/g`, whose trailing-slash branch
|
|
18
|
+
* backtracks O(n²) on a long run of slashes that is not at end-of-string
|
|
19
|
+
* (CodeQL js/polynomial-redos). This char-index walk is unconditionally
|
|
20
|
+
* linear and produces byte-identical output for every input.
|
|
36
21
|
*/
|
|
37
|
-
export function
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const isHome = stripped === "" || stripped === "home" || stripped === "index";
|
|
46
|
-
// tail: the path component appended after `<base>/` or `<base>/<locale>/`.
|
|
47
|
-
// 'directory' style: trailing slash for non-home so the URL points at
|
|
48
|
-
// the directory the bucket serves index.html from.
|
|
49
|
-
// 'no-extension' style: no trailing slash, no extension — the URL
|
|
50
|
-
// points at the bare-slug object the bucket serves directly.
|
|
51
|
-
const tail = isHome ? "" : pageUrlStyle === "no-extension" ? stripped : `${stripped}/`;
|
|
52
|
-
const base = siteBaseUrl.replace(/\/+$/, "");
|
|
53
|
-
switch (locale.urlStrategy) {
|
|
54
|
-
case "none":
|
|
55
|
-
return tail ? `${base}/${tail}` : `${base}/`;
|
|
56
|
-
case "subdirectory":
|
|
57
|
-
// Default locale with strategy `subdirectory` still gets the prefix
|
|
58
|
-
// unless the migration set strategy=none for it. The decision is
|
|
59
|
-
// explicit per locale row, not implicit on isDefault.
|
|
60
|
-
return tail ? `${base}/${locale.code}/${tail}` : `${base}/${locale.code}/`;
|
|
61
|
-
case "subdomain": {
|
|
62
|
-
if (!locale.urlHost) {
|
|
63
|
-
throw new Error(`locale '${locale.code}' uses url_strategy='subdomain' without url_host — config invalid`);
|
|
64
|
-
}
|
|
65
|
-
const protocol = base.startsWith("http://") ? "http://" : "https://";
|
|
66
|
-
return tail ? `${protocol}${locale.urlHost}/${tail}` : `${protocol}${locale.urlHost}/`;
|
|
67
|
-
}
|
|
68
|
-
case "domain": {
|
|
69
|
-
if (!locale.urlHost) {
|
|
70
|
-
throw new Error(`locale '${locale.code}' uses url_strategy='domain' without url_host — config invalid`);
|
|
71
|
-
}
|
|
72
|
-
const protocol = base.startsWith("http://") ? "http://" : "https://";
|
|
73
|
-
return tail ? `${protocol}${locale.urlHost}/${tail}` : `${protocol}${locale.urlHost}/`;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
22
|
+
export function trimSlashes(s) {
|
|
23
|
+
let start = 0;
|
|
24
|
+
let end = s.length;
|
|
25
|
+
while (start < end && s.charCodeAt(start) === 47 /* '/' */)
|
|
26
|
+
start += 1;
|
|
27
|
+
while (end > start && s.charCodeAt(end - 1) === 47 /* '/' */)
|
|
28
|
+
end -= 1;
|
|
29
|
+
return s.slice(start, end);
|
|
76
30
|
}
|
|
77
31
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
|
|
32
|
+
* Strip only trailing `/` characters with a single linear scan — the
|
|
33
|
+
* non-backtracking replacement for `/\/+$/` (same ReDoS class as above).
|
|
34
|
+
* Used for base URLs, which carry a scheme and must keep their leading
|
|
35
|
+
* characters.
|
|
36
|
+
*/
|
|
37
|
+
export function trimTrailingSlashes(s) {
|
|
38
|
+
let end = s.length;
|
|
39
|
+
while (end > 0 && s.charCodeAt(end - 1) === 47 /* '/' */)
|
|
40
|
+
end -= 1;
|
|
41
|
+
return s.slice(0, end);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The "magic slug" sentinel test: a page whose slug is empty, `home`,
|
|
45
|
+
* or `index` is the locale root by convention even without an explicit
|
|
46
|
+
* `locales.home_page_id` designation. Leading/trailing slashes are
|
|
47
|
+
* ignored so `/home/` reads the same as `home`.
|
|
83
48
|
*/
|
|
84
|
-
export function
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const lines = [];
|
|
88
|
-
for (const v of perLocaleUrls) {
|
|
89
|
-
lines.push(`<link rel="alternate" hreflang="${escapeAttr(v.localeCode)}" href="${escapeAttr(v.url)}" />`);
|
|
90
|
-
}
|
|
91
|
-
const def = perLocaleUrls.find((v) => v.isDefault);
|
|
92
|
-
if (def) {
|
|
93
|
-
lines.push(`<link rel="alternate" hreflang="x-default" href="${escapeAttr(def.url)}" />`);
|
|
94
|
-
}
|
|
95
|
-
return lines.join("\n");
|
|
49
|
+
export function isHomeSlug(slug) {
|
|
50
|
+
const s = trimSlashes(slug);
|
|
51
|
+
return s === "" || s === "home" || s === "index";
|
|
96
52
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
53
|
+
/**
|
|
54
|
+
* The single home-decision predicate every URL/output-path site must
|
|
55
|
+
* use so canonical, hreflang, redirects, and the emitted file agree
|
|
56
|
+
* (0184 explicit-homepage feature). A page is the locale root when it
|
|
57
|
+
* IS the locale's designated `home_page_id` OR carries a magic slug.
|
|
58
|
+
*
|
|
59
|
+
* @param pageId The page being resolved.
|
|
60
|
+
* @param slug That page's slug.
|
|
61
|
+
* @param localeHomePageId `locales.home_page_id` for the page's locale
|
|
62
|
+
* (null/undefined when no page is designated).
|
|
63
|
+
*/
|
|
64
|
+
export function pageIsLocaleHome(pageId, slug, localeHomePageId) {
|
|
65
|
+
return (localeHomePageId != null && pageId === localeHomePageId) || isHomeSlug(slug);
|
|
103
66
|
}
|
|
104
67
|
/**
|
|
105
68
|
* Canonical-JSON serializer + sha256 → hex. Stable across runs because
|
|
@@ -119,42 +82,4 @@ export async function computeContentHash(value) {
|
|
|
119
82
|
const digest = await crypto.subtle.digest("SHA-256", TEXT_ENCODER.encode(canonical));
|
|
120
83
|
return [...new Uint8Array(digest)].map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
121
84
|
}
|
|
122
|
-
/**
|
|
123
|
-
* Cross-row config sanity checks. Run at:
|
|
124
|
-
* - propose-time (warnings stored on the proposal preview)
|
|
125
|
-
* - render-time (no fail-loudly per CLAUDE.md §2 since the renderer
|
|
126
|
-
* can still emit; surfaced in admin UI as banners)
|
|
127
|
-
*/
|
|
128
|
-
export function lintLocaleConfig(locales, advancedUrlRouting) {
|
|
129
|
-
const warnings = [];
|
|
130
|
-
const usingAdvanced = locales.some((l) => l.urlStrategy === "subdomain" || l.urlStrategy === "domain");
|
|
131
|
-
if (usingAdvanced && !advancedUrlRouting) {
|
|
132
|
-
warnings.push({
|
|
133
|
-
code: "advanced-routing-disabled",
|
|
134
|
-
message: "one or more locales use 'subdomain' or 'domain' strategy but Advanced URL Routing is disabled — enable it under /security/locales",
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
for (const l of locales) {
|
|
138
|
-
if ((l.urlStrategy === "subdomain" || l.urlStrategy === "domain") && !l.urlHost) {
|
|
139
|
-
warnings.push({
|
|
140
|
-
code: "missing-url-host",
|
|
141
|
-
message: `locale '${l.code}' uses url_strategy='${l.urlStrategy}' without url_host`,
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
// Default-locale 'none' alongside subdirectory siblings is a common
|
|
146
|
-
// mixed config; surface it so users know the default's URL stays bare
|
|
147
|
-
// while siblings get prefixed.
|
|
148
|
-
const def = locales.find((l) => l.isDefault);
|
|
149
|
-
const subdirSiblings = locales.filter((l) => !l.isDefault && l.urlStrategy === "subdirectory");
|
|
150
|
-
if (def && def.urlStrategy === "none" && subdirSiblings.length > 0) {
|
|
151
|
-
warnings.push({
|
|
152
|
-
code: "mixed-default-none-subdir",
|
|
153
|
-
message: `default locale '${def.code}' uses 'none' while ${subdirSiblings
|
|
154
|
-
.map((l) => l.code)
|
|
155
|
-
.join(", ")} use 'subdirectory' — this is valid but unusual; verify hreflang renders correctly`,
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
return warnings;
|
|
159
|
-
}
|
|
160
85
|
//# sourceMappingURL=i18n.js.map
|
package/dist/i18n.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC
|
|
1
|
+
{"version":3,"file":"i18n.js","sourceRoot":"","sources":["../src/i18n.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC;;;;;;;;;;GAUG;AAEH,MAAM,YAAY,GAAG,IAAI,WAAW,EAAE,CAAC;AAEvC;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,CAAS;IACnC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC;IACnB,OAAO,KAAK,GAAG,GAAG,IAAI,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,SAAS;QAAE,KAAK,IAAI,CAAC,CAAC;IACvE,OAAO,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,SAAS;QAAE,GAAG,IAAI,CAAC,CAAC;IACvE,OAAO,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAC7B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,CAAS;IAC3C,IAAI,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC;IACnB,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,SAAS;QAAE,GAAG,IAAI,CAAC,CAAC;IACnE,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACzB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,MAAM,CAAC,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAC5B,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,OAAO,CAAC;AACnD,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAAc,EACd,IAAY,EACZ,gBAA2C;IAE3C,OAAO,CAAC,gBAAgB,IAAI,IAAI,IAAI,MAAM,KAAK,gBAAgB,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;AACvF,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,KAAc;IACrD,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;QACpD,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1D,MAAM,MAAM,GAA4B,EAAE,CAAC;YAC3C,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE;gBAAE,MAAM,CAAC,CAAC,CAAC,GAAI,GAA+B,CAAC,CAAC,CAAC,CAAC;YACzF,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;IACrF,OAAO,CAAC,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC1F,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,20 +1,47 @@
|
|
|
1
1
|
export declare const PROJECT_NAME = "caelo-cms";
|
|
2
2
|
export * from "./ai-tools.js";
|
|
3
3
|
export * from "./auth-forms.js";
|
|
4
|
+
export * from "./base-css.js";
|
|
5
|
+
export * from "./build-page.js";
|
|
4
6
|
export * from "./cap-failures.js";
|
|
5
7
|
export * from "./content.js";
|
|
6
8
|
export * from "./context.js";
|
|
9
|
+
export * from "./css-gradient-scan.js";
|
|
10
|
+
export * from "./css-var-scan.js";
|
|
11
|
+
export * from "./design-draft-shell.js";
|
|
12
|
+
export * from "./design-manifest.js";
|
|
13
|
+
export * from "./fonts.js";
|
|
14
|
+
export * from "./genesis.js";
|
|
15
|
+
export * from "./genesis-inventory.js";
|
|
7
16
|
export * from "./i18n.js";
|
|
17
|
+
export * from "./interactions.js";
|
|
8
18
|
export { type LogContext, type Logger, type LoggerOptions, type LogLevel, makeLogger, mintRequestId, redact, type ServiceName, type StructuredLogEntry, } from "./logger.js";
|
|
9
19
|
export * from "./media.js";
|
|
20
|
+
export * from "./page-log.js";
|
|
10
21
|
export * from "./preview-compose.js";
|
|
11
22
|
export * from "./preview-scanner.js";
|
|
23
|
+
export * from "./proposal-status.js";
|
|
24
|
+
export * from "./responsive-images.js";
|
|
12
25
|
export * from "./result.js";
|
|
26
|
+
export * from "./safe-keys.js";
|
|
13
27
|
export * from "./seo.js";
|
|
14
28
|
export * from "./skills.js";
|
|
15
29
|
export * from "./snapshots.js";
|
|
30
|
+
export * from "./strip-cdata.js";
|
|
16
31
|
export * from "./structured-sets.js";
|
|
17
32
|
export * from "./subagents.js";
|
|
18
|
-
export * from "./
|
|
33
|
+
export * from "./template-engine.js";
|
|
34
|
+
export * from "./theme-importers/auto-detect.js";
|
|
35
|
+
export * from "./theme-importers/dtcg.js";
|
|
36
|
+
export * from "./theme-importers/loose.js";
|
|
37
|
+
export * from "./theme-importers/shadcn.js";
|
|
38
|
+
export * from "./theme-importers/style-dictionary.js";
|
|
39
|
+
export * from "./theme-importers/tailwind.js";
|
|
40
|
+
export * from "./theme-literal-binding.js";
|
|
41
|
+
export * from "./theme-normalize.js";
|
|
42
|
+
export * from "./theme-ramp.js";
|
|
43
|
+
export * from "./theme-render.js";
|
|
44
|
+
export * from "./themes.js";
|
|
45
|
+
export * from "./themes-errors.js";
|
|
19
46
|
export { CAELO_VERSION, CALEO_VERSION, type CaeloVersion, parseVersion } from "./version.js";
|
|
20
47
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,cAAc,CAAC;AAExC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,OAAO,EACL,KAAK,UAAU,EACf,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,QAAQ,EACb,UAAU,EACV,aAAa,EACb,MAAM,EACN,KAAK,WAAW,EAChB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC;AACrB,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,YAAY,cAAc,CAAC;AAExC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,OAAO,EACL,KAAK,UAAU,EACf,KAAK,MAAM,EACX,KAAK,aAAa,EAClB,KAAK,QAAQ,EACb,UAAU,EACV,aAAa,EACb,MAAM,EACN,KAAK,WAAW,EAChB,KAAK,kBAAkB,GACxB,MAAM,aAAa,CAAC;AACrB,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,KAAK,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,20 +2,47 @@
|
|
|
2
2
|
export const PROJECT_NAME = "caelo-cms";
|
|
3
3
|
export * from "./ai-tools.js";
|
|
4
4
|
export * from "./auth-forms.js";
|
|
5
|
+
export * from "./base-css.js";
|
|
6
|
+
export * from "./build-page.js";
|
|
5
7
|
export * from "./cap-failures.js";
|
|
6
8
|
export * from "./content.js";
|
|
7
9
|
export * from "./context.js";
|
|
10
|
+
export * from "./css-gradient-scan.js";
|
|
11
|
+
export * from "./css-var-scan.js";
|
|
12
|
+
export * from "./design-draft-shell.js";
|
|
13
|
+
export * from "./design-manifest.js";
|
|
14
|
+
export * from "./fonts.js";
|
|
15
|
+
export * from "./genesis.js";
|
|
16
|
+
export * from "./genesis-inventory.js";
|
|
8
17
|
export * from "./i18n.js";
|
|
18
|
+
export * from "./interactions.js";
|
|
9
19
|
export { makeLogger, mintRequestId, redact, } from "./logger.js";
|
|
10
20
|
export * from "./media.js";
|
|
21
|
+
export * from "./page-log.js";
|
|
11
22
|
export * from "./preview-compose.js";
|
|
12
23
|
export * from "./preview-scanner.js";
|
|
24
|
+
export * from "./proposal-status.js";
|
|
25
|
+
export * from "./responsive-images.js";
|
|
13
26
|
export * from "./result.js";
|
|
27
|
+
export * from "./safe-keys.js";
|
|
14
28
|
export * from "./seo.js";
|
|
15
29
|
export * from "./skills.js";
|
|
16
30
|
export * from "./snapshots.js";
|
|
31
|
+
export * from "./strip-cdata.js";
|
|
17
32
|
export * from "./structured-sets.js";
|
|
18
33
|
export * from "./subagents.js";
|
|
19
|
-
export * from "./
|
|
34
|
+
export * from "./template-engine.js";
|
|
35
|
+
export * from "./theme-importers/auto-detect.js";
|
|
36
|
+
export * from "./theme-importers/dtcg.js";
|
|
37
|
+
export * from "./theme-importers/loose.js";
|
|
38
|
+
export * from "./theme-importers/shadcn.js";
|
|
39
|
+
export * from "./theme-importers/style-dictionary.js";
|
|
40
|
+
export * from "./theme-importers/tailwind.js";
|
|
41
|
+
export * from "./theme-literal-binding.js";
|
|
42
|
+
export * from "./theme-normalize.js";
|
|
43
|
+
export * from "./theme-ramp.js";
|
|
44
|
+
export * from "./theme-render.js";
|
|
45
|
+
export * from "./themes.js";
|
|
46
|
+
export * from "./themes-errors.js";
|
|
20
47
|
export { CAELO_VERSION, CALEO_VERSION, parseVersion } from "./version.js";
|
|
21
48
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAC;AAExC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC;AAC1B,OAAO,EAKL,UAAU,EACV,aAAa,EACb,MAAM,GAGP,MAAM,aAAa,CAAC;AACrB,cAAc,YAAY,CAAC;AAC3B,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,aAAa,CAAC;AAC5B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mCAAmC;AAEnC,MAAM,CAAC,MAAM,YAAY,GAAG,WAAW,CAAC;AAExC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,wBAAwB,CAAC;AACvC,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,OAAO,EAKL,UAAU,EACV,aAAa,EACb,MAAM,GAGP,MAAM,aAAa,CAAC;AACrB,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AACrC,cAAc,kCAAkC,CAAC;AACjD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,aAAa,CAAC;AAC5B,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAqB,YAAY,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* issue #160 — the vetted interaction baseline (epic #149).
|
|
3
|
+
*
|
|
4
|
+
* A header without a working mobile menu reads as broken, not minimal
|
|
5
|
+
* — and hand-rolled per-module JS gets focus/aria handling wrong more
|
|
6
|
+
* often than right. This module carries the FUNCTIONAL (non-aesthetic)
|
|
7
|
+
* CSS + JS for the built-in nav renderer: hamburger toggle under the
|
|
8
|
+
* mobile breakpoint, `aria-expanded` bookkeeping, escape-to-close.
|
|
9
|
+
* All colors/spacing stay the module/theme's business — these rules
|
|
10
|
+
* only govern show/hide behaviour, so they don't violate the
|
|
11
|
+
* no-global-look re-scope (#151).
|
|
12
|
+
*
|
|
13
|
+
* The composer includes each asset ONCE per page when at least one
|
|
14
|
+
* nav-menu module rendered (natural dedup, same rule as #158).
|
|
15
|
+
*/
|
|
16
|
+
/** Functional-only rules: collapse/expand mechanics, zero aesthetics. */
|
|
17
|
+
export declare const NAV_FUNCTIONAL_CSS: string;
|
|
18
|
+
/**
|
|
19
|
+
* Toggle behaviour. Runs deferred; idempotent per element via the
|
|
20
|
+
* data attribute; closes on Escape and returns focus to the toggle.
|
|
21
|
+
*/
|
|
22
|
+
export declare const NAV_TOGGLE_JS: string;
|
|
23
|
+
//# sourceMappingURL=interactions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactions.d.ts","sourceRoot":"","sources":["../src/interactions.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AAEH,yEAAyE;AACzE,eAAO,MAAM,kBAAkB,QAO1B,CAAC;AAEN;;;GAGG;AACH,eAAO,MAAM,aAAa,QAejB,CAAC"}
|