@hale-bopp/valentino-engine 2.0.0 → 2.2.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 (51) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +2 -2
  3. package/dist/bin/commands/llms.d.ts +2 -0
  4. package/dist/bin/commands/llms.d.ts.map +1 -0
  5. package/dist/bin/commands/llms.js +84 -0
  6. package/dist/bin/commands/llms.js.map +1 -0
  7. package/dist/bin/valentino.js +6 -1
  8. package/dist/bin/valentino.js.map +1 -1
  9. package/dist/core/animation.d.ts +18 -0
  10. package/dist/core/animation.d.ts.map +1 -0
  11. package/dist/core/animation.js +91 -0
  12. package/dist/core/animation.js.map +1 -0
  13. package/dist/core/editor.d.ts +80 -0
  14. package/dist/core/editor.d.ts.map +1 -0
  15. package/dist/core/editor.js +421 -0
  16. package/dist/core/editor.js.map +1 -0
  17. package/dist/core/encoding.d.ts +32 -0
  18. package/dist/core/encoding.d.ts.map +1 -0
  19. package/dist/core/encoding.js +112 -0
  20. package/dist/core/encoding.js.map +1 -0
  21. package/dist/core/gallery.d.ts +53 -0
  22. package/dist/core/gallery.d.ts.map +1 -0
  23. package/dist/core/gallery.js +123 -0
  24. package/dist/core/gallery.js.map +1 -0
  25. package/dist/core/gallery.test.d.ts +2 -0
  26. package/dist/core/gallery.test.d.ts.map +1 -0
  27. package/dist/core/gallery.test.js +127 -0
  28. package/dist/core/gallery.test.js.map +1 -0
  29. package/dist/core/guardrails-cms.d.ts +31 -1
  30. package/dist/core/guardrails-cms.d.ts.map +1 -1
  31. package/dist/core/guardrails-cms.js +160 -0
  32. package/dist/core/guardrails-cms.js.map +1 -1
  33. package/dist/core/llms-generator.d.ts +36 -0
  34. package/dist/core/llms-generator.d.ts.map +1 -0
  35. package/dist/core/llms-generator.js +95 -0
  36. package/dist/core/llms-generator.js.map +1 -0
  37. package/dist/core/page-generator.d.ts +85 -0
  38. package/dist/core/page-generator.d.ts.map +1 -0
  39. package/dist/core/page-generator.js +353 -0
  40. package/dist/core/page-generator.js.map +1 -0
  41. package/dist/core/page-generator.test.d.ts +2 -0
  42. package/dist/core/page-generator.test.d.ts.map +1 -0
  43. package/dist/core/page-generator.test.js +138 -0
  44. package/dist/core/page-generator.test.js.map +1 -0
  45. package/dist/core/types.d.ts +11 -0
  46. package/dist/core/types.d.ts.map +1 -1
  47. package/dist/index.d.ts +14 -1
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +14 -2
  50. package/dist/index.js.map +1 -1
  51. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.1.0] — 2026-03-26
4
+
5
+ ### Added
6
+ - **CMS Guardrails (PBI #605)**: 6 new checks — `checkOgImageExists`, `checkMediaOrphans`, `checkMediaMissingAlt`, `checkBreadcrumbDepth`, `checkLanguageCoverage`, `checkDuplicateRoutes` (12/14 total)
7
+ - **LLMs.txt Generator (PBI #614)**: `generateLlmsTxt` (L0 compact) + `generateLlmsFullTxt` (L1 detailed) + CLI `valentino llms`
8
+ - **Animation Presets (PBI #611)**: `AnimationSpec` on `SectionPresentationBase`, 5 presets (fade-up/in, slide-left/right, scale-in), `probeAnimations` validation, `resolveAnimationCSS` for consumers
9
+ - **Encoding Guardrail (PBI #629)**: `checkMojibake` (14 Latin-1/Win-1252 patterns), `checkTypography` (15+ rules for IT/EN/FR/DE/ES), `checkEncoding` combined
10
+
11
+ ### Changed
12
+ - CLI now has 10 commands (was 9): added `llms`
13
+ - Test suite: 239 tests across 16 suites (was 170/13)
14
+ - Core modules: 17 (was 14)
15
+ - `collectPureCmsWarnings` accepts new options: `mediaManifest`, `contentByLang`
16
+
3
17
  ## [2.0.0] — 2026-03-26
4
18
 
5
19
  ### Breaking Changes
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Valentino Engine
2
2
 
3
- > **Antifragile Open Source UI Design Engine** — part of the [HALE-BOPP](https://dev.azure.com/EasyWayData/EasyWay-DataPortal/_git/hale-bopp-valentino-engine) family.
3
+ > **Antifragile Open Source UI Design Engine** — part of the [HALE-BOPP](https://github.com/hale-bopp-data) family.
4
4
 
5
5
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
6
6
  [![npm](https://img.shields.io/npm/v/@hale-bopp/valentino-engine)](https://www.npmjs.com/package/@hale-bopp/valentino-engine)
@@ -101,7 +101,7 @@ Any MCP-compatible AI agent can connect to Valentino Engine:
101
101
 
102
102
  ## Contributing
103
103
 
104
- PRs welcome! Please link your PR to an ADO Work Item under [Epic #480](https://dev.azure.com/EasyWayData/EasyWay-DataPortal/_workitems/edit/480).
104
+ PRs welcome! See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
105
105
 
106
106
  ## License
107
107
 
@@ -0,0 +1,2 @@
1
+ export declare function runLlms(args: string[]): void;
2
+ //# sourceMappingURL=llms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llms.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/llms.ts"],"names":[],"mappings":"AA0BA,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAoE5C"}
@@ -0,0 +1,84 @@
1
+ /**
2
+ * CLI command: valentino llms <manifest.json> [options]
3
+ * Generates llms.txt and llms-full.txt from a pages manifest.
4
+ */
5
+ import { readFileSync, writeFileSync } from 'node:fs';
6
+ import { resolve } from 'node:path';
7
+ import { generateLlmsTxt, generateLlmsFullTxt } from '../../core/llms-generator.js';
8
+ function loadJson(path) {
9
+ return JSON.parse(readFileSync(path, 'utf-8'));
10
+ }
11
+ function flattenKeys(obj, prefix = '') {
12
+ const result = {};
13
+ for (const [key, value] of Object.entries(obj)) {
14
+ const fullKey = prefix ? `${prefix}.${key}` : key;
15
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
16
+ Object.assign(result, flattenKeys(value, fullKey));
17
+ }
18
+ else if (typeof value === 'string') {
19
+ result[fullKey] = value;
20
+ }
21
+ }
22
+ return result;
23
+ }
24
+ export function runLlms(args) {
25
+ const manifestPath = args.find((a) => !a.startsWith('--'));
26
+ if (!manifestPath) {
27
+ console.error('Usage: valentino llms <manifest.json> [--content content.json] [--site "Name"] [--tagline "..."] [--base-url https://...] [--out-dir ./public] [--specs-dir ./pages]');
28
+ process.exit(1);
29
+ }
30
+ // Parse options
31
+ const getOpt = (flag) => {
32
+ const idx = args.indexOf(flag);
33
+ return idx >= 0 && idx + 1 < args.length ? args[idx + 1] : undefined;
34
+ };
35
+ const contentPath = getOpt('--content');
36
+ const siteName = getOpt('--site') || 'Site';
37
+ const tagline = getOpt('--tagline');
38
+ const baseUrl = getOpt('--base-url');
39
+ const outDir = getOpt('--out-dir') || '.';
40
+ const specsDir = getOpt('--specs-dir');
41
+ const capsRaw = getOpt('--capabilities');
42
+ // Load manifest
43
+ const manifest = loadJson(resolve(manifestPath));
44
+ // Content resolver
45
+ let contentMap = {};
46
+ if (contentPath) {
47
+ const raw = loadJson(resolve(contentPath));
48
+ contentMap = flattenKeys(raw);
49
+ }
50
+ const resolveContent = (key) => contentMap[key];
51
+ // Load page specs if dir provided
52
+ let specsById;
53
+ if (specsDir) {
54
+ specsById = new Map();
55
+ for (const page of manifest.pages) {
56
+ try {
57
+ const specPath = resolve(specsDir, page.spec.replace(/^\/pages\//, ''));
58
+ const spec = loadJson(specPath);
59
+ specsById.set(page.id, spec);
60
+ }
61
+ catch {
62
+ // Spec not found — skip
63
+ }
64
+ }
65
+ }
66
+ // Capabilities
67
+ const capabilities = capsRaw
68
+ ? capsRaw.split(';').map((s) => s.trim()).filter(Boolean)
69
+ : undefined;
70
+ const options = { siteName, tagline, baseUrl, capabilities, resolveContent, specsById };
71
+ // Generate
72
+ const llmsTxt = generateLlmsTxt(manifest, options);
73
+ const llmsFullTxt = generateLlmsFullTxt(manifest, options);
74
+ // Write
75
+ const outLlms = resolve(outDir, 'llms.txt');
76
+ const outFull = resolve(outDir, 'llms-full.txt');
77
+ writeFileSync(outLlms, llmsTxt, 'utf-8');
78
+ writeFileSync(outFull, llmsFullTxt, 'utf-8');
79
+ const llmsLines = llmsTxt.split('\n').length;
80
+ const fullLines = llmsFullTxt.split('\n').length;
81
+ console.log(`✅ Generated ${outLlms} (${llmsLines} lines)`);
82
+ console.log(`✅ Generated ${outFull} (${fullLines} lines)`);
83
+ }
84
+ //# sourceMappingURL=llms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llms.js","sourceRoot":"","sources":["../../../src/bin/commands/llms.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,7 @@ import { runCatalogResolve } from './commands/catalog.js';
11
11
  import { runManifestResolve } from './commands/manifest.js';
12
12
  import { runContrast } from './commands/contrast.js';
13
13
  import { runInit } from './commands/init.js';
14
+ import { runLlms } from './commands/llms.js';
14
15
  const [, , command, ...args] = process.argv;
15
16
  switch (command) {
16
17
  case 'init':
@@ -47,6 +48,9 @@ switch (command) {
47
48
  case 'contrast':
48
49
  runContrast(args);
49
50
  break;
51
+ case 'llms':
52
+ runLlms(args);
53
+ break;
50
54
  default:
51
55
  console.log(`
52
56
  🎨 Valentino Engine v0.1.0 — Antifragile Open Source UI Design Engine
@@ -60,8 +64,9 @@ Usage:
60
64
  valentino contrast <foreground> <background> [AA|AAA] Check WCAG contrast ratio
61
65
  valentino catalog resolve <spec.json> --catalog <catalog.json> Resolve spec with catalog
62
66
  valentino manifest resolve <manifest.json> --route /path Resolve route to page ID
67
+ valentino llms <manifest.json> [--content c.json] [--site N] Generate llms.txt + llms-full.txt
63
68
 
64
- Epic: https://dev.azure.com/EasyWayData/EasyWay-DataPortal/_workitems/edit/480
69
+ GitHub: https://github.com/hale-bopp-data/valentino-engine
65
70
  `);
66
71
  }
67
72
  //# sourceMappingURL=valentino.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"valentino.js","sourceRoot":"","sources":["../../src/bin/valentino.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,MAAM,CAAC,EAAC,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;AAE3C,QAAQ,OAAO,EAAE,CAAC;IACd,KAAK,MAAM;QACP,OAAO,CAAC,IAAI,CAAC,CAAC;QACd,MAAM;IAEV,KAAK,OAAO;QACR,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,MAAM;IAEV,KAAK,UAAU;QACX,WAAW,CAAC,IAAI,CAAC,CAAC;QAClB,MAAM;IAEV,KAAK,YAAY;QACb,aAAa,EAAE,CAAC;QAChB,MAAM;IAEV,KAAK,OAAO;QACR,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM;IAEV,KAAK,SAAS;QACV,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS;YAAE,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;aACvD,CAAC;YACF,OAAO,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAC;YACvF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QACD,MAAM;IAEV,KAAK,UAAU;QACX,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS;YAAE,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;aACxD,CAAC;YACF,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAC;YACjF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QACD,MAAM;IAEV,KAAK,UAAU;QACX,WAAW,CAAC,IAAI,CAAC,CAAC;QAClB,MAAM;IAEV;QACI,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;CAcnB,CAAC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"valentino.js","sourceRoot":"","sources":["../../src/bin/valentino.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,MAAM,CAAC,EAAC,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;AAE3C,QAAQ,OAAO,EAAE,CAAC;IACd,KAAK,MAAM;QACP,OAAO,CAAC,IAAI,CAAC,CAAC;QACd,MAAM;IAEV,KAAK,OAAO;QACR,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,MAAM;IAEV,KAAK,UAAU;QACX,WAAW,CAAC,IAAI,CAAC,CAAC;QAClB,MAAM;IAEV,KAAK,YAAY;QACb,aAAa,EAAE,CAAC;QAChB,MAAM;IAEV,KAAK,OAAO;QACR,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1C,MAAM;IAEV,KAAK,SAAS;QACV,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS;YAAE,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;aACvD,CAAC;YACF,OAAO,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAC;YACvF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QACD,MAAM;IAEV,KAAK,UAAU;QACX,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS;YAAE,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;aACxD,CAAC;YACF,OAAO,CAAC,KAAK,CAAC,iEAAiE,CAAC,CAAC;YACjF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QACD,MAAM;IAEV,KAAK,UAAU;QACX,WAAW,CAAC,IAAI,CAAC,CAAC;QAClB,MAAM;IAEV,KAAK,MAAM;QACP,OAAO,CAAC,IAAI,CAAC,CAAC;QACd,MAAM;IAEV;QACI,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;CAenB,CAAC,CAAC;AACH,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Animation Presets — Validation and CSS generation for declarative section animations.
3
+ * No DOM — pure functions only. The consumer applies CSS/IntersectionObserver.
4
+ * PBI #611.
5
+ */
6
+ import type { AnimationPreset, AnimationSpec, SectionSpec } from './types.js';
7
+ export type AnimationWarning = {
8
+ type: string;
9
+ section: number;
10
+ message: string;
11
+ };
12
+ /** Validate animation specs across all sections of a page. */
13
+ export declare function probeAnimations(sections: SectionSpec[]): AnimationWarning[];
14
+ /** Resolve animation to CSS custom properties for a section. */
15
+ export declare function resolveAnimationCSS(anim: AnimationSpec): Record<string, string>;
16
+ /** List of all valid animation presets. */
17
+ export declare const ANIMATION_PRESETS: readonly AnimationPreset[];
18
+ //# sourceMappingURL=animation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animation.d.ts","sourceRoot":"","sources":["../../src/core/animation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9E,MAAM,MAAM,gBAAgB,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC;AAMF,8DAA8D;AAC9D,wBAAgB,eAAe,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,gBAAgB,EAAE,CAsD3E;AAED,gEAAgE;AAChE,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAoC/E;AAED,2CAA2C;AAC3C,eAAO,MAAM,iBAAiB,EAAE,SAAS,eAAe,EAA4E,CAAC"}
@@ -0,0 +1,91 @@
1
+ const VALID_PRESETS = new Set(['fade-up', 'fade-in', 'slide-left', 'slide-right', 'scale-in', 'none']);
2
+ const VALID_DELAYS = new Set(['none', 'stagger']);
3
+ const VALID_TRIGGERS = new Set(['viewport', 'immediate']);
4
+ /** Validate animation specs across all sections of a page. */
5
+ export function probeAnimations(sections) {
6
+ const warnings = [];
7
+ for (let i = 0; i < sections.length; i++) {
8
+ const section = sections[i];
9
+ const anim = section.animation;
10
+ if (!anim)
11
+ continue;
12
+ if (anim.entrance && !VALID_PRESETS.has(anim.entrance)) {
13
+ warnings.push({
14
+ type: 'animation-invalid-preset',
15
+ section: i,
16
+ message: `Section ${i} (${section.type}): unknown animation preset "${anim.entrance}". Valid: ${[...VALID_PRESETS].join(', ')}`,
17
+ });
18
+ }
19
+ if (anim.delay && !VALID_DELAYS.has(anim.delay)) {
20
+ warnings.push({
21
+ type: 'animation-invalid-delay',
22
+ section: i,
23
+ message: `Section ${i} (${section.type}): unknown delay "${anim.delay}". Valid: ${[...VALID_DELAYS].join(', ')}`,
24
+ });
25
+ }
26
+ if (anim.trigger && !VALID_TRIGGERS.has(anim.trigger)) {
27
+ warnings.push({
28
+ type: 'animation-invalid-trigger',
29
+ section: i,
30
+ message: `Section ${i} (${section.type}): unknown trigger "${anim.trigger}". Valid: ${[...VALID_TRIGGERS].join(', ')}`,
31
+ });
32
+ }
33
+ if (anim.duration !== undefined && (anim.duration < 0 || anim.duration > 5000)) {
34
+ warnings.push({
35
+ type: 'animation-duration-out-of-range',
36
+ section: i,
37
+ message: `Section ${i} (${section.type}): duration ${anim.duration}ms is out of range (0-5000)`,
38
+ });
39
+ }
40
+ // Stagger on non-list sections is a no-op warning
41
+ if (anim.delay === 'stagger') {
42
+ const listTypes = new Set(['cards', 'stats', 'how-it-works', 'data-list', 'component-showcase']);
43
+ if (!listTypes.has(section.type)) {
44
+ warnings.push({
45
+ type: 'animation-stagger-no-effect',
46
+ section: i,
47
+ message: `Section ${i} (${section.type}): "stagger" delay has no effect on non-list sections`,
48
+ });
49
+ }
50
+ }
51
+ }
52
+ return warnings;
53
+ }
54
+ /** Resolve animation to CSS custom properties for a section. */
55
+ export function resolveAnimationCSS(anim) {
56
+ const preset = anim.entrance || 'none';
57
+ const duration = anim.duration || 400;
58
+ const delay = anim.delay || 'none';
59
+ if (preset === 'none')
60
+ return {};
61
+ const css = {
62
+ '--v-anim-duration': `${duration}ms`,
63
+ '--v-anim-delay-mode': delay,
64
+ };
65
+ switch (preset) {
66
+ case 'fade-up':
67
+ css['--v-anim-opacity'] = '0';
68
+ css['--v-anim-transform'] = 'translateY(20px)';
69
+ break;
70
+ case 'fade-in':
71
+ css['--v-anim-opacity'] = '0';
72
+ css['--v-anim-transform'] = 'none';
73
+ break;
74
+ case 'slide-left':
75
+ css['--v-anim-opacity'] = '0';
76
+ css['--v-anim-transform'] = 'translateX(40px)';
77
+ break;
78
+ case 'slide-right':
79
+ css['--v-anim-opacity'] = '0';
80
+ css['--v-anim-transform'] = 'translateX(-40px)';
81
+ break;
82
+ case 'scale-in':
83
+ css['--v-anim-opacity'] = '0';
84
+ css['--v-anim-transform'] = 'scale(0.95)';
85
+ break;
86
+ }
87
+ return css;
88
+ }
89
+ /** List of all valid animation presets. */
90
+ export const ANIMATION_PRESETS = ['fade-up', 'fade-in', 'slide-left', 'slide-right', 'scale-in', 'none'];
91
+ //# sourceMappingURL=animation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animation.js","sourceRoot":"","sources":["../../src/core/animation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Editor utilities — Pure functions for visual page spec editing.
3
+ * PBI #602 — Editor visuale non-tecnico.
4
+ *
5
+ * Provides:
6
+ * - generateEditorSchema(sectionType) — JSON-like schema for form generation
7
+ * - applySectionPatch(spec, sectionIndex, patch) — immutable update + validation
8
+ * - getEditableSectionTypes() — list of section types supported by editor
9
+ */
10
+ import type { PageSpecV1, SectionSpec } from './types.js';
11
+ export type EditorFieldType = 'string' | 'text' | 'number' | 'boolean' | 'enum' | 'array' | 'object' | 'json';
12
+ export type EditorFieldSpec = {
13
+ key: string;
14
+ label: string;
15
+ type: EditorFieldType;
16
+ required?: boolean;
17
+ enumValues?: string[];
18
+ defaultValue?: unknown;
19
+ group?: string;
20
+ description?: string;
21
+ /** For array fields: schema of each item */
22
+ itemFields?: EditorFieldSpec[];
23
+ /** For object fields: nested fields */
24
+ children?: EditorFieldSpec[];
25
+ };
26
+ export type EditorSectionSchema = {
27
+ sectionType: string;
28
+ label: string;
29
+ fields: EditorFieldSpec[];
30
+ };
31
+ /**
32
+ * Returns the list of section types that the editor supports.
33
+ */
34
+ export declare function getEditableSectionTypes(): string[];
35
+ /**
36
+ * Generates the editor schema for a given section type.
37
+ * Returns null if the section type is not supported.
38
+ */
39
+ export declare function generateEditorSchema(sectionType: string): EditorSectionSchema | null;
40
+ /**
41
+ * Returns editor schemas for all supported section types.
42
+ */
43
+ export declare function generateAllEditorSchemas(): EditorSectionSchema[];
44
+ export type SectionPatchWarning = {
45
+ field: string;
46
+ message: string;
47
+ };
48
+ export type SectionPatchResult = {
49
+ spec: PageSpecV1;
50
+ warnings: SectionPatchWarning[];
51
+ };
52
+ /**
53
+ * Apply a patch (key-value map) to a section within a PageSpec.
54
+ * Returns a new PageSpec (immutable) + validation warnings.
55
+ *
56
+ * Keys use dot notation for nested fields (e.g. "presentation.surface").
57
+ * If value is null/undefined, the field is removed.
58
+ */
59
+ export declare function applySectionPatch(spec: PageSpecV1, sectionIndex: number, patch: Record<string, unknown>): SectionPatchResult;
60
+ /**
61
+ * Add a new section to a PageSpec at a given index.
62
+ * Returns the updated spec.
63
+ */
64
+ export declare function addSection(spec: PageSpecV1, section: SectionSpec, atIndex?: number): PageSpecV1;
65
+ /**
66
+ * Remove a section from a PageSpec by index.
67
+ * Returns the updated spec.
68
+ */
69
+ export declare function removeSection(spec: PageSpecV1, sectionIndex: number): PageSpecV1;
70
+ /**
71
+ * Move a section within a PageSpec (reorder).
72
+ * Returns the updated spec.
73
+ */
74
+ export declare function moveSection(spec: PageSpecV1, fromIndex: number, toIndex: number): PageSpecV1;
75
+ /**
76
+ * Update page-level fields (id, titleKey, profile, themeId, chrome, seo).
77
+ * Returns the updated spec.
78
+ */
79
+ export declare function applyPagePatch(spec: PageSpecV1, patch: Partial<Omit<PageSpecV1, 'version' | 'sections'>>): PageSpecV1;
80
+ //# sourceMappingURL=editor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor.d.ts","sourceRoot":"","sources":["../../src/core/editor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACR,UAAU,EACV,WAAW,EAGd,MAAM,YAAY,CAAC;AAOpB,MAAM,MAAM,eAAe,GACrB,QAAQ,GACR,MAAM,GACN,QAAQ,GACR,SAAS,GACT,MAAM,GACN,OAAO,GACP,QAAQ,GACR,MAAM,CAAC;AAEb,MAAM,MAAM,eAAe,GAAG;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4CAA4C;IAC5C,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,uCAAuC;IACvC,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,eAAe,EAAE,CAAC;CAC7B,CAAC;AAwRF;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,EAAE,CAElD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAGpF;AAED;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,mBAAmB,EAAE,CAEhE;AAMD,MAAM,MAAM,mBAAmB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CACnC,CAAC;AA8BF;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC7B,IAAI,EAAE,UAAU,EAChB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,kBAAkB,CA2DpB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACtB,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,WAAW,EACpB,OAAO,CAAC,EAAE,MAAM,GACjB,UAAU,CAKZ;AAED;;;GAGG;AACH,wBAAgB,aAAa,CACzB,IAAI,EAAE,UAAU,EAChB,YAAY,EAAE,MAAM,GACrB,UAAU,CAKZ;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACvB,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GAChB,UAAU,CASZ;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC1B,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,GAAG,UAAU,CAAC,CAAC,GACzD,UAAU,CAEZ"}