@antv/infographic 0.1.3 → 0.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 (181) hide show
  1. package/README.md +54 -40
  2. package/README.zh-CN.md +52 -36
  3. package/dist/infographic.min.js +110 -105
  4. package/dist/infographic.min.js.map +1 -1
  5. package/esm/constants/element.d.ts +1 -1
  6. package/esm/constants/index.d.ts +1 -0
  7. package/esm/constants/index.js +1 -0
  8. package/esm/constants/service.d.ts +1 -0
  9. package/esm/constants/service.js +1 -0
  10. package/esm/designs/components/Illus.js +1 -1
  11. package/esm/designs/structures/chart-wordcloud.d.ts +11 -0
  12. package/esm/designs/structures/chart-wordcloud.js +156 -0
  13. package/esm/designs/structures/hierarchy-tree.d.ts +2 -0
  14. package/esm/designs/structures/hierarchy-tree.js +179 -50
  15. package/esm/designs/structures/index.d.ts +2 -0
  16. package/esm/designs/structures/index.js +2 -0
  17. package/esm/designs/structures/sequence-stairs-front.d.ts +8 -0
  18. package/esm/designs/structures/sequence-stairs-front.js +116 -0
  19. package/esm/designs/types.d.ts +8 -0
  20. package/esm/editor/managers/state.js +1 -1
  21. package/esm/exporter/font.js +4 -9
  22. package/esm/index.d.ts +2 -0
  23. package/esm/index.js +1 -0
  24. package/esm/options/parser.d.ts +1 -1
  25. package/esm/options/parser.js +33 -15
  26. package/esm/renderer/composites/icon.js +1 -1
  27. package/esm/renderer/composites/illus.js +1 -1
  28. package/esm/resource/loader.d.ts +2 -2
  29. package/esm/resource/loader.js +22 -11
  30. package/esm/resource/loaders/index.d.ts +1 -0
  31. package/esm/resource/loaders/index.js +1 -0
  32. package/esm/resource/loaders/remote.d.ts +1 -1
  33. package/esm/resource/loaders/remote.js +12 -3
  34. package/esm/resource/loaders/search.d.ts +1 -0
  35. package/esm/resource/loaders/search.js +52 -0
  36. package/esm/resource/types/index.d.ts +1 -0
  37. package/esm/resource/types/resource.d.ts +8 -1
  38. package/esm/resource/types/scene.d.ts +1 -0
  39. package/esm/resource/utils/data-uri.js +20 -11
  40. package/esm/resource/utils/parser.js +92 -1
  41. package/esm/resource/utils/ref.js +2 -2
  42. package/esm/runtime/Infographic.d.ts +10 -6
  43. package/esm/runtime/Infographic.js +66 -17
  44. package/esm/runtime/utils.d.ts +4 -2
  45. package/esm/runtime/utils.js +33 -13
  46. package/esm/syntax/index.d.ts +3 -0
  47. package/esm/syntax/index.js +101 -0
  48. package/esm/syntax/mapper.d.ts +3 -0
  49. package/esm/syntax/mapper.js +334 -0
  50. package/esm/syntax/parser.d.ts +14 -0
  51. package/esm/syntax/parser.js +142 -0
  52. package/esm/syntax/schema.d.ts +6 -0
  53. package/esm/syntax/schema.js +86 -0
  54. package/esm/syntax/types.d.ts +68 -0
  55. package/esm/syntax/types.js +1 -0
  56. package/esm/templates/built-in.js +4 -0
  57. package/esm/templates/hierarchy-tree.js +25 -11
  58. package/esm/templates/sequence-stairs.d.ts +2 -0
  59. package/esm/templates/sequence-stairs.js +42 -0
  60. package/esm/templates/word-cloud.d.ts +2 -0
  61. package/esm/templates/word-cloud.js +19 -0
  62. package/esm/themes/types.d.ts +1 -1
  63. package/esm/utils/design.d.ts +2 -0
  64. package/esm/utils/design.js +10 -0
  65. package/esm/utils/fetch.d.ts +1 -0
  66. package/esm/utils/fetch.js +61 -0
  67. package/esm/utils/font.js +11 -1
  68. package/esm/utils/index.d.ts +2 -0
  69. package/esm/utils/index.js +2 -0
  70. package/lib/constants/element.d.ts +1 -1
  71. package/lib/constants/index.d.ts +1 -0
  72. package/lib/constants/index.js +1 -0
  73. package/lib/constants/service.d.ts +1 -0
  74. package/lib/constants/service.js +4 -0
  75. package/lib/designs/components/Illus.js +1 -1
  76. package/lib/designs/structures/chart-wordcloud.d.ts +11 -0
  77. package/lib/designs/structures/chart-wordcloud.js +160 -0
  78. package/lib/designs/structures/hierarchy-tree.d.ts +2 -0
  79. package/lib/designs/structures/hierarchy-tree.js +179 -50
  80. package/lib/designs/structures/index.d.ts +2 -0
  81. package/lib/designs/structures/index.js +2 -0
  82. package/lib/designs/structures/sequence-stairs-front.d.ts +8 -0
  83. package/lib/designs/structures/sequence-stairs-front.js +120 -0
  84. package/lib/designs/types.d.ts +8 -0
  85. package/lib/editor/managers/state.js +1 -1
  86. package/lib/exporter/font.js +3 -8
  87. package/lib/index.d.ts +2 -0
  88. package/lib/index.js +4 -1
  89. package/lib/options/parser.d.ts +1 -1
  90. package/lib/options/parser.js +32 -14
  91. package/lib/renderer/composites/icon.js +1 -1
  92. package/lib/renderer/composites/illus.js +1 -1
  93. package/lib/resource/loader.d.ts +2 -2
  94. package/lib/resource/loader.js +21 -10
  95. package/lib/resource/loaders/index.d.ts +1 -0
  96. package/lib/resource/loaders/index.js +1 -0
  97. package/lib/resource/loaders/remote.d.ts +1 -1
  98. package/lib/resource/loaders/remote.js +12 -3
  99. package/lib/resource/loaders/search.d.ts +1 -0
  100. package/lib/resource/loaders/search.js +55 -0
  101. package/lib/resource/types/index.d.ts +1 -0
  102. package/lib/resource/types/resource.d.ts +8 -1
  103. package/lib/resource/types/scene.d.ts +1 -0
  104. package/lib/resource/utils/data-uri.js +20 -11
  105. package/lib/resource/utils/parser.js +92 -1
  106. package/lib/resource/utils/ref.js +2 -2
  107. package/lib/runtime/Infographic.d.ts +10 -6
  108. package/lib/runtime/Infographic.js +65 -16
  109. package/lib/runtime/utils.d.ts +4 -2
  110. package/lib/runtime/utils.js +35 -13
  111. package/lib/syntax/index.d.ts +3 -0
  112. package/lib/syntax/index.js +104 -0
  113. package/lib/syntax/mapper.d.ts +3 -0
  114. package/lib/syntax/mapper.js +341 -0
  115. package/lib/syntax/parser.d.ts +14 -0
  116. package/lib/syntax/parser.js +146 -0
  117. package/lib/syntax/schema.d.ts +6 -0
  118. package/lib/syntax/schema.js +89 -0
  119. package/lib/syntax/types.d.ts +68 -0
  120. package/lib/syntax/types.js +2 -0
  121. package/lib/templates/built-in.js +4 -0
  122. package/lib/templates/hierarchy-tree.js +25 -11
  123. package/lib/templates/sequence-stairs.d.ts +2 -0
  124. package/lib/templates/sequence-stairs.js +45 -0
  125. package/lib/templates/word-cloud.d.ts +2 -0
  126. package/lib/templates/word-cloud.js +22 -0
  127. package/lib/themes/types.d.ts +1 -1
  128. package/lib/utils/design.d.ts +2 -0
  129. package/lib/utils/design.js +13 -0
  130. package/lib/utils/fetch.d.ts +1 -0
  131. package/lib/utils/fetch.js +67 -0
  132. package/lib/utils/font.js +11 -1
  133. package/lib/utils/index.d.ts +2 -0
  134. package/lib/utils/index.js +2 -0
  135. package/package.json +14 -2
  136. package/src/constants/element.ts +1 -1
  137. package/src/constants/index.ts +1 -0
  138. package/src/constants/service.ts +1 -0
  139. package/src/designs/components/Illus.tsx +1 -1
  140. package/src/designs/structures/chart-wordcloud.tsx +278 -0
  141. package/src/designs/structures/hierarchy-tree.tsx +212 -59
  142. package/src/designs/structures/index.ts +2 -0
  143. package/src/designs/structures/sequence-stairs-front.tsx +291 -0
  144. package/src/designs/types.ts +9 -0
  145. package/src/editor/managers/state.ts +1 -1
  146. package/src/exporter/font.ts +4 -9
  147. package/src/index.ts +2 -0
  148. package/src/options/parser.ts +57 -28
  149. package/src/renderer/composites/icon.ts +1 -1
  150. package/src/renderer/composites/illus.ts +1 -1
  151. package/src/resource/loader.ts +22 -8
  152. package/src/resource/loaders/index.ts +1 -0
  153. package/src/resource/loaders/remote.ts +11 -3
  154. package/src/resource/loaders/search.ts +53 -0
  155. package/src/resource/types/index.ts +2 -1
  156. package/src/resource/types/resource.ts +12 -1
  157. package/src/resource/types/scene.ts +1 -0
  158. package/src/resource/utils/data-uri.ts +20 -11
  159. package/src/resource/utils/parser.ts +103 -2
  160. package/src/resource/utils/ref.ts +2 -2
  161. package/src/runtime/Infographic.tsx +103 -22
  162. package/src/runtime/utils.ts +38 -16
  163. package/src/syntax/index.ts +124 -0
  164. package/src/syntax/mapper.ts +496 -0
  165. package/src/syntax/parser.ts +171 -0
  166. package/src/syntax/schema.ts +112 -0
  167. package/src/syntax/types.ts +100 -0
  168. package/src/templates/built-in.ts +4 -0
  169. package/src/templates/hierarchy-tree.ts +34 -11
  170. package/src/templates/sequence-stairs.ts +44 -0
  171. package/src/templates/word-cloud.ts +21 -0
  172. package/src/themes/types.ts +1 -1
  173. package/src/utils/design.ts +14 -0
  174. package/src/utils/fetch.ts +90 -0
  175. package/src/utils/font.ts +11 -1
  176. package/src/utils/index.ts +2 -0
  177. package/esm/resource/types/font.d.ts +0 -12
  178. package/lib/resource/types/font.d.ts +0 -12
  179. package/src/resource/types/font.ts +0 -23
  180. /package/esm/resource/types/{font.js → scene.js} +0 -0
  181. /package/lib/resource/types/{font.js → scene.js} +0 -0
@@ -1,21 +1,43 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.mergeOptions = mergeOptions;
4
+ exports.cloneOptions = cloneOptions;
5
+ exports.isCompleteParsedInfographicOptions = isCompleteParsedInfographicOptions;
6
+ const lodash_es_1 = require("lodash-es");
7
+ const utils_1 = require("../utils");
4
8
  function mergeOptions(object, source) {
5
- return {
9
+ const base = {
6
10
  ...object,
7
11
  ...source,
8
- design: {
9
- ...object.design,
10
- ...source.design,
11
- },
12
- themeConfig: {
13
- ...object.themeConfig,
14
- ...source.themeConfig,
15
- },
16
- svg: {
17
- ...object.svg,
18
- ...source.svg,
19
- },
20
12
  };
13
+ if (object.design || source.design) {
14
+ base.design = { ...object.design, ...source.design };
15
+ }
16
+ if (object.themeConfig || source.themeConfig) {
17
+ base.themeConfig = { ...object.themeConfig, ...source.themeConfig };
18
+ }
19
+ if (object.svg || source.svg) {
20
+ base.svg = { ...object.svg, ...source.svg };
21
+ }
22
+ return base;
23
+ }
24
+ function cloneOptions(options) {
25
+ const cloned = { ...options };
26
+ if (cloned.data)
27
+ cloned.data = (0, lodash_es_1.cloneDeep)(cloned.data);
28
+ if (cloned.elements)
29
+ cloned.elements = (0, lodash_es_1.cloneDeep)(cloned.elements);
30
+ return cloned;
31
+ }
32
+ function isCompleteParsedInfographicOptions(options) {
33
+ const { design, data } = options;
34
+ if (!design)
35
+ return false;
36
+ if (!(0, utils_1.isNonNullableParsedDesignsOptions)(design))
37
+ return false;
38
+ if (!data)
39
+ return false;
40
+ if (!Array.isArray(data.items) || data.items.length < 1)
41
+ return false;
42
+ return true;
21
43
  }
@@ -0,0 +1,3 @@
1
+ import type { SyntaxParseResult } from './types';
2
+ export declare function parseSyntax(input: string): SyntaxParseResult;
3
+ export type { SyntaxError, SyntaxNode, SyntaxParseResult } from './types';
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseSyntax = parseSyntax;
4
+ const mapper_1 = require("./mapper");
5
+ const parser_1 = require("./parser");
6
+ const schema_1 = require("./schema");
7
+ function resolveTemplate(node, errors) {
8
+ if (!node)
9
+ return undefined;
10
+ const mapped = (0, mapper_1.mapWithSchema)(node, schema_1.TemplateSchema, 'template', errors);
11
+ if (!mapped)
12
+ return undefined;
13
+ if (typeof mapped === 'string')
14
+ return mapped;
15
+ if (typeof mapped === 'object' && typeof mapped.type === 'string') {
16
+ return mapped.type;
17
+ }
18
+ return undefined;
19
+ }
20
+ function parseSyntax(input) {
21
+ const { ast, errors } = (0, parser_1.parseSyntaxToAst)(input);
22
+ const warnings = [];
23
+ const options = {};
24
+ const mergedEntries = { ...ast.entries };
25
+ const infographicNode = ast.entries.infographic;
26
+ let templateFromInfographic;
27
+ if (infographicNode && infographicNode.kind === 'object') {
28
+ if (infographicNode.value)
29
+ templateFromInfographic = infographicNode.value;
30
+ Object.entries(infographicNode.entries).forEach(([key, value]) => {
31
+ if (!(key in mergedEntries))
32
+ mergedEntries[key] = value;
33
+ });
34
+ }
35
+ const allowedRootKeys = new Set([
36
+ 'infographic',
37
+ 'template',
38
+ 'design',
39
+ 'data',
40
+ 'theme',
41
+ 'width',
42
+ 'height',
43
+ ]);
44
+ Object.keys(mergedEntries).forEach((key) => {
45
+ if (!allowedRootKeys.has(key)) {
46
+ errors.push({
47
+ path: key,
48
+ line: mergedEntries[key].line,
49
+ code: 'unknown_key',
50
+ message: 'Unknown top-level key.',
51
+ raw: key,
52
+ });
53
+ }
54
+ });
55
+ const templateNode = mergedEntries.template;
56
+ const templateValue = resolveTemplate(templateNode, errors);
57
+ if (templateValue)
58
+ options.template = templateValue;
59
+ if (!options.template && templateFromInfographic) {
60
+ options.template = templateFromInfographic;
61
+ }
62
+ const designNode = mergedEntries.design;
63
+ if (designNode) {
64
+ const design = (0, mapper_1.mapWithSchema)(designNode, schema_1.DesignSchema, 'design', errors);
65
+ if (design)
66
+ options.design = design;
67
+ }
68
+ const dataNode = mergedEntries.data;
69
+ if (dataNode) {
70
+ const data = (0, mapper_1.mapWithSchema)(dataNode, schema_1.DataSchema, 'data', errors);
71
+ if (data)
72
+ options.data = data;
73
+ }
74
+ const themeNode = mergedEntries.theme;
75
+ if (themeNode) {
76
+ const theme = (0, mapper_1.mapWithSchema)(themeNode, schema_1.ThemeSchema, 'theme', errors);
77
+ if (theme && typeof theme === 'object') {
78
+ const { type, ...rest } = theme;
79
+ if (typeof type === 'string' && type)
80
+ options.theme = type;
81
+ if (Object.keys(rest).length > 0) {
82
+ options.themeConfig = rest;
83
+ }
84
+ }
85
+ }
86
+ const widthNode = mergedEntries.width;
87
+ if (widthNode) {
88
+ const width = (0, mapper_1.mapWithSchema)(widthNode, schema_1.RootSchema.fields.width, 'width', errors);
89
+ if (width !== undefined)
90
+ options.width = width;
91
+ }
92
+ const heightNode = mergedEntries.height;
93
+ if (heightNode) {
94
+ const height = (0, mapper_1.mapWithSchema)(heightNode, schema_1.RootSchema.fields.height, 'height', errors);
95
+ if (height !== undefined)
96
+ options.height = height;
97
+ }
98
+ return {
99
+ options,
100
+ errors,
101
+ warnings,
102
+ ast,
103
+ };
104
+ }
@@ -0,0 +1,3 @@
1
+ import type { SchemaNode, SyntaxError, SyntaxNode } from './types';
2
+ export declare function mapWithSchema(node: SyntaxNode, schema: SchemaNode, path: string, errors: SyntaxError[]): any;
3
+ export declare function mapUnknownToObject(node: SyntaxNode): any;
@@ -0,0 +1,341 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.mapWithSchema = mapWithSchema;
7
+ exports.mapUnknownToObject = mapUnknownToObject;
8
+ const tinycolor2_1 = __importDefault(require("tinycolor2"));
9
+ const parser_1 = require("./parser");
10
+ function createValueNode(value, line) {
11
+ return { kind: 'value', line, value };
12
+ }
13
+ const HEX_COLOR_PATTERN = /^(#[0-9a-f]{8}|#[0-9a-f]{6}|#[0-9a-f]{4}|#[0-9a-f]{3})/i;
14
+ const FUNCTION_COLOR_PATTERN = /^((?:rgb|rgba|hsl|hsla)\([^)]*\))/i;
15
+ function parseScalar(value) {
16
+ const trimmed = value.trim();
17
+ if (trimmed === 'true')
18
+ return true;
19
+ if (trimmed === 'false')
20
+ return false;
21
+ if (/^-?\d+(\.\d+)?$/.test(trimmed))
22
+ return parseFloat(trimmed);
23
+ return trimmed;
24
+ }
25
+ function readScalar(node) {
26
+ if (node.kind === 'value')
27
+ return node.value;
28
+ if (node.kind === 'object')
29
+ return node.value;
30
+ return undefined;
31
+ }
32
+ function addError(errors, node, path, code, message, raw) {
33
+ errors.push({
34
+ path,
35
+ line: node.line,
36
+ code,
37
+ message,
38
+ raw,
39
+ });
40
+ }
41
+ function splitArrayValue(value, split = 'any') {
42
+ let text = value.trim();
43
+ if (text.startsWith('[') && text.endsWith(']')) {
44
+ text = text.slice(1, -1).trim();
45
+ }
46
+ if (!text)
47
+ return [];
48
+ let parts;
49
+ if (split === 'comma') {
50
+ parts = text.split(',');
51
+ }
52
+ else if (split === 'space') {
53
+ parts = text.split(/\s+/);
54
+ }
55
+ else {
56
+ parts = text.split(/[,\s]+/);
57
+ }
58
+ const normalized = [];
59
+ for (const part of parts) {
60
+ const trimmedPart = part.trim();
61
+ if (!trimmedPart)
62
+ continue;
63
+ if (trimmedPart === '#' || trimmedPart === '//')
64
+ break;
65
+ normalized.push(trimmedPart);
66
+ }
67
+ return normalized;
68
+ }
69
+ function stripColorComments(value) {
70
+ let trimmed = value.trim();
71
+ const hashIndex = trimmed.search(/\s+#(?![0-9a-f])/i);
72
+ if (hashIndex >= 0) {
73
+ trimmed = trimmed.slice(0, hashIndex).trimEnd();
74
+ }
75
+ const slashIndex = trimmed.indexOf('//');
76
+ if (slashIndex >= 0) {
77
+ trimmed = trimmed.slice(0, slashIndex).trimEnd();
78
+ }
79
+ return trimmed;
80
+ }
81
+ function normalizeExplicitColor(value) {
82
+ const trimmed = stripColorComments(value);
83
+ if (!trimmed)
84
+ return undefined;
85
+ const hexMatch = trimmed.match(HEX_COLOR_PATTERN);
86
+ if (hexMatch && hexMatch[0].length === trimmed.length) {
87
+ return trimmed;
88
+ }
89
+ const funcMatch = trimmed.match(FUNCTION_COLOR_PATTERN);
90
+ if (funcMatch && funcMatch[1].length === trimmed.length) {
91
+ return trimmed;
92
+ }
93
+ if ((0, tinycolor2_1.default)(trimmed).isValid())
94
+ return trimmed;
95
+ return undefined;
96
+ }
97
+ function mapColor(node, path, errors, options = {}) {
98
+ const value = readScalar(node);
99
+ if (value === undefined) {
100
+ addError(errors, node, path, 'schema_mismatch', 'Expected color value.');
101
+ return undefined;
102
+ }
103
+ const normalized = normalizeExplicitColor(value);
104
+ if (!normalized) {
105
+ if (!options.soft) {
106
+ addError(errors, node, path, 'invalid_value', 'Invalid color value.', value);
107
+ }
108
+ return undefined;
109
+ }
110
+ return normalized;
111
+ }
112
+ function shouldTreatPaletteStringAsArray(trimmed, parts) {
113
+ if (parts.length > 1)
114
+ return true;
115
+ if (trimmed.startsWith('[') && trimmed.endsWith(']'))
116
+ return true;
117
+ return normalizeExplicitColor(trimmed) !== undefined;
118
+ }
119
+ function mapUnknown(node) {
120
+ if (node.kind === 'array') {
121
+ return node.items.map((item) => mapUnknown(item));
122
+ }
123
+ if (node.kind === 'value')
124
+ return parseScalar(node.value);
125
+ const hasEntries = Object.keys(node.entries).length > 0;
126
+ if (!hasEntries && node.value !== undefined) {
127
+ return parseScalar(node.value);
128
+ }
129
+ const result = {};
130
+ if (node.value !== undefined) {
131
+ result.value = parseScalar(node.value);
132
+ }
133
+ Object.entries(node.entries).forEach(([key, child]) => {
134
+ result[key] = mapUnknown(child);
135
+ });
136
+ return result;
137
+ }
138
+ function mapUnion(node, schema, path, errors) {
139
+ let bestValue = undefined;
140
+ let bestErrors = null;
141
+ for (const variant of schema.variants) {
142
+ const variantErrors = [];
143
+ const value = mapWithSchema(node, variant, path, variantErrors);
144
+ if (bestErrors === null || variantErrors.length < bestErrors.length) {
145
+ bestErrors = variantErrors;
146
+ bestValue = value;
147
+ }
148
+ }
149
+ if (bestErrors)
150
+ errors.push(...bestErrors);
151
+ return bestValue;
152
+ }
153
+ function mapWithSchema(node, schema, path, errors) {
154
+ switch (schema.kind) {
155
+ case 'union':
156
+ return mapUnion(node, schema, path, errors);
157
+ case 'string': {
158
+ const value = readScalar(node);
159
+ if (value === undefined) {
160
+ addError(errors, node, path, 'schema_mismatch', 'Expected string value.');
161
+ return undefined;
162
+ }
163
+ return value;
164
+ }
165
+ case 'number': {
166
+ const value = readScalar(node);
167
+ if (value === undefined) {
168
+ addError(errors, node, path, 'schema_mismatch', 'Expected number value.');
169
+ return undefined;
170
+ }
171
+ const trimmed = value.trim();
172
+ const match = trimmed.match(/^(-?\d+(\.\d+)?)(?:\s*(#|\/\/).*)?$/);
173
+ if (!match) {
174
+ addError(errors, node, path, 'invalid_value', 'Invalid number value.', value);
175
+ return undefined;
176
+ }
177
+ return parseFloat(match[1]);
178
+ }
179
+ case 'boolean': {
180
+ const value = readScalar(node);
181
+ if (value === undefined) {
182
+ addError(errors, node, path, 'schema_mismatch', 'Expected boolean value.');
183
+ return undefined;
184
+ }
185
+ if (value !== 'true' && value !== 'false') {
186
+ addError(errors, node, path, 'invalid_value', 'Invalid boolean value.', value);
187
+ return undefined;
188
+ }
189
+ return value === 'true';
190
+ }
191
+ case 'enum': {
192
+ const value = readScalar(node);
193
+ if (value === undefined) {
194
+ addError(errors, node, path, 'schema_mismatch', 'Expected enum value.');
195
+ return undefined;
196
+ }
197
+ if (!schema.values.includes(value)) {
198
+ addError(errors, node, path, 'invalid_value', 'Invalid enum value.', value);
199
+ return undefined;
200
+ }
201
+ return value;
202
+ }
203
+ case 'array': {
204
+ if (node.kind === 'array') {
205
+ return node.items
206
+ .map((item, index) => mapWithSchema(item, schema.item, `${path}[${index}]`, errors))
207
+ .filter((value) => value !== undefined);
208
+ }
209
+ if (node.kind === 'object' && Object.keys(node.entries).length > 0) {
210
+ addError(errors, node, path, 'schema_mismatch', 'Expected array value.');
211
+ return undefined;
212
+ }
213
+ const scalar = readScalar(node);
214
+ if (scalar === undefined) {
215
+ addError(errors, node, path, 'schema_mismatch', 'Expected array value.');
216
+ return undefined;
217
+ }
218
+ const trimmed = scalar.trim();
219
+ if (trimmed.startsWith('[') && !trimmed.endsWith(']')) {
220
+ return undefined;
221
+ }
222
+ const parts = splitArrayValue(scalar, schema.split);
223
+ return parts
224
+ .map((part, index) => mapWithSchema(createValueNode(part, node.line), schema.item, `${path}[${index}]`, errors))
225
+ .filter((value) => value !== undefined);
226
+ }
227
+ case 'palette': {
228
+ if (node.kind === 'array') {
229
+ const values = mapWithSchema(node, { kind: 'array', item: { kind: 'color' }, split: 'any' }, path, errors);
230
+ return Array.isArray(values) && values.length > 0 ? values : undefined;
231
+ }
232
+ if (node.kind === 'object' && Object.keys(node.entries).length > 0) {
233
+ addError(errors, node, path, 'schema_mismatch', 'Expected palette value.');
234
+ return undefined;
235
+ }
236
+ const scalar = readScalar(node);
237
+ if (scalar === undefined) {
238
+ addError(errors, node, path, 'schema_mismatch', 'Expected palette value.');
239
+ return undefined;
240
+ }
241
+ const trimmed = scalar.trim();
242
+ if (trimmed.startsWith('[') && !trimmed.endsWith(']')) {
243
+ return undefined;
244
+ }
245
+ const directColor = normalizeExplicitColor(trimmed);
246
+ if (directColor) {
247
+ return [directColor];
248
+ }
249
+ const parts = splitArrayValue(scalar, 'any');
250
+ if (shouldTreatPaletteStringAsArray(trimmed, parts)) {
251
+ const values = parts
252
+ .map((part, index) => mapColor(createValueNode(part, node.line), `${path}[${index}]`, errors))
253
+ .filter((value) => value !== undefined);
254
+ return values.length > 0 ? values : undefined;
255
+ }
256
+ return scalar;
257
+ }
258
+ case 'color': {
259
+ return mapColor(node, path, errors, { soft: schema.soft });
260
+ }
261
+ case 'object': {
262
+ if (node.kind === 'array') {
263
+ addError(errors, node, path, 'schema_mismatch', 'Expected object value.');
264
+ return undefined;
265
+ }
266
+ const result = {};
267
+ if (node.kind === 'value') {
268
+ if (schema.shorthandKey) {
269
+ result[schema.shorthandKey] = node.value;
270
+ return result;
271
+ }
272
+ const inline = (0, parser_1.parseInlineKeyValue)(node.value);
273
+ if (inline?.value !== undefined) {
274
+ if (schema.fields[inline.key]) {
275
+ const value = mapWithSchema(createValueNode(inline.value, node.line), schema.fields[inline.key], `${path}.${inline.key}`, errors);
276
+ if (value !== undefined)
277
+ result[inline.key] = value;
278
+ return result;
279
+ }
280
+ if (schema.allowUnknown) {
281
+ result[inline.key] = parseScalar(inline.value);
282
+ return result;
283
+ }
284
+ addError(errors, node, `${path}.${inline.key}`, 'unknown_key', 'Unknown key in object.', inline.key);
285
+ return result;
286
+ }
287
+ if (schema.allowUnknown) {
288
+ result.value = parseScalar(node.value);
289
+ return result;
290
+ }
291
+ addError(errors, node, path, 'invalid_value', 'Expected object value.');
292
+ return undefined;
293
+ }
294
+ if (node.value !== undefined) {
295
+ if (schema.shorthandKey && result[schema.shorthandKey] === undefined) {
296
+ result[schema.shorthandKey] = node.value;
297
+ }
298
+ else {
299
+ const inline = (0, parser_1.parseInlineKeyValue)(node.value);
300
+ if (inline?.value !== undefined) {
301
+ if (schema.fields[inline.key]) {
302
+ const value = mapWithSchema(createValueNode(inline.value, node.line), schema.fields[inline.key], `${path}.${inline.key}`, errors);
303
+ if (value !== undefined && result[inline.key] === undefined) {
304
+ result[inline.key] = value;
305
+ }
306
+ }
307
+ else if (schema.allowUnknown) {
308
+ result[inline.key] = parseScalar(inline.value);
309
+ }
310
+ else {
311
+ addError(errors, node, `${path}.${inline.key}`, 'unknown_key', 'Unknown key in object.', inline.key);
312
+ }
313
+ }
314
+ else if (schema.allowUnknown) {
315
+ result.value = parseScalar(node.value);
316
+ }
317
+ }
318
+ }
319
+ Object.entries(node.entries).forEach(([key, child]) => {
320
+ const fieldSchema = schema.fields[key];
321
+ if (!fieldSchema) {
322
+ if (schema.allowUnknown) {
323
+ result[key] = mapUnknown(child);
324
+ return;
325
+ }
326
+ addError(errors, child, `${path}.${key}`, 'unknown_key', 'Unknown key in object.', key);
327
+ return;
328
+ }
329
+ const value = mapWithSchema(child, fieldSchema, `${path}.${key}`, errors);
330
+ if (value !== undefined)
331
+ result[key] = value;
332
+ });
333
+ return result;
334
+ }
335
+ default:
336
+ return undefined;
337
+ }
338
+ }
339
+ function mapUnknownToObject(node) {
340
+ return mapUnknown(node);
341
+ }
@@ -0,0 +1,14 @@
1
+ import type { ObjectNode, SyntaxError } from './types';
2
+ interface ParseResult {
3
+ ast: ObjectNode;
4
+ errors: SyntaxError[];
5
+ }
6
+ export declare function parseSyntaxToAst(input: string): ParseResult;
7
+ export declare function parseInlineKeyValue(value: string): {
8
+ key: string;
9
+ value: string;
10
+ } | {
11
+ key: string;
12
+ value: undefined;
13
+ } | null;
14
+ export {};
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseSyntaxToAst = parseSyntaxToAst;
4
+ exports.parseInlineKeyValue = parseInlineKeyValue;
5
+ function isWhitespace(char) {
6
+ return char === ' ' || char === '\t';
7
+ }
8
+ function getIndentInfo(line) {
9
+ let indent = 0;
10
+ let index = 0;
11
+ while (index < line.length) {
12
+ const char = line[index];
13
+ if (char === ' ') {
14
+ indent += 1;
15
+ index += 1;
16
+ continue;
17
+ }
18
+ if (char === '\t') {
19
+ indent += 2;
20
+ index += 1;
21
+ continue;
22
+ }
23
+ break;
24
+ }
25
+ return { indent, content: line.slice(index) };
26
+ }
27
+ function stripComments(content) {
28
+ return content.trimEnd();
29
+ }
30
+ function parseKeyValue(raw) {
31
+ const text = raw.trim();
32
+ if (!text)
33
+ return null;
34
+ const match = text.match(/^([^:\s=]+)\s*[:=]\s*(.*)$/);
35
+ if (match) {
36
+ return { key: match[1], value: match[2].trim() };
37
+ }
38
+ const matchSpace = text.match(/^([^\s]+)\s+(.*)$/);
39
+ if (matchSpace) {
40
+ return { key: matchSpace[1], value: matchSpace[2].trim() };
41
+ }
42
+ return { key: text, value: undefined };
43
+ }
44
+ function createObjectNode(line, value) {
45
+ return { kind: 'object', line, value, entries: {} };
46
+ }
47
+ function createArrayNode(line) {
48
+ return { kind: 'array', line, items: [] };
49
+ }
50
+ function parseSyntaxToAst(input) {
51
+ const errors = [];
52
+ const root = createObjectNode(0);
53
+ const stack = [
54
+ { indent: -1, node: root, parent: null, key: null },
55
+ ];
56
+ const lines = input.split(/\r?\n/);
57
+ lines.forEach((line, index) => {
58
+ const lineNumber = index + 1;
59
+ if (!line.trim())
60
+ return;
61
+ const { indent, content } = getIndentInfo(line);
62
+ const stripped = stripComments(content);
63
+ if (!stripped.trim())
64
+ return;
65
+ while (stack.length > 1 && indent <= stack[stack.length - 1].indent) {
66
+ stack.pop();
67
+ }
68
+ const parentFrame = stack[stack.length - 1];
69
+ let parentNode = parentFrame.node;
70
+ const trimmed = stripped.trim();
71
+ if (trimmed.startsWith('-') &&
72
+ (trimmed.length === 1 || isWhitespace(trimmed[1]))) {
73
+ if (parentNode.kind !== 'array') {
74
+ if (parentNode.kind === 'object' &&
75
+ Object.keys(parentNode.entries).length === 0 &&
76
+ parentNode.value === undefined &&
77
+ parentFrame.parent &&
78
+ parentFrame.key) {
79
+ const arrayNode = createArrayNode(parentNode.line);
80
+ if (parentFrame.parent.kind === 'object') {
81
+ parentFrame.parent.entries[parentFrame.key] = arrayNode;
82
+ }
83
+ else if (parentFrame.parent.kind === 'array') {
84
+ const indexInParent = parentFrame.parent.items.indexOf(parentNode);
85
+ if (indexInParent >= 0)
86
+ parentFrame.parent.items[indexInParent] = arrayNode;
87
+ }
88
+ parentFrame.node = arrayNode;
89
+ parentNode = arrayNode;
90
+ }
91
+ else {
92
+ errors.push({
93
+ path: '',
94
+ line: lineNumber,
95
+ code: 'bad_list',
96
+ message: 'List item is not under an array container.',
97
+ raw: trimmed,
98
+ });
99
+ return;
100
+ }
101
+ }
102
+ const itemContent = trimmed.slice(1).trim();
103
+ const itemNode = createObjectNode(lineNumber, itemContent || undefined);
104
+ parentNode.items.push(itemNode);
105
+ stack.push({
106
+ indent,
107
+ node: itemNode,
108
+ parent: parentNode,
109
+ });
110
+ return;
111
+ }
112
+ const parsed = parseKeyValue(trimmed);
113
+ if (!parsed) {
114
+ errors.push({
115
+ path: '',
116
+ line: lineNumber,
117
+ code: 'bad_syntax',
118
+ message: 'Invalid syntax line.',
119
+ raw: trimmed,
120
+ });
121
+ return;
122
+ }
123
+ if (parentNode.kind !== 'object') {
124
+ errors.push({
125
+ path: '',
126
+ line: lineNumber,
127
+ code: 'bad_syntax',
128
+ message: 'Key-value pair is not under an object container.',
129
+ raw: trimmed,
130
+ });
131
+ return;
132
+ }
133
+ const node = createObjectNode(lineNumber, parsed.value);
134
+ parentNode.entries[parsed.key] = node;
135
+ stack.push({
136
+ indent,
137
+ node,
138
+ parent: parentNode,
139
+ key: parsed.key,
140
+ });
141
+ });
142
+ return { ast: root, errors };
143
+ }
144
+ function parseInlineKeyValue(value) {
145
+ return parseKeyValue(value);
146
+ }
@@ -0,0 +1,6 @@
1
+ import type { ObjectSchema } from './types';
2
+ export declare const ThemeSchema: ObjectSchema;
3
+ export declare const DesignSchema: ObjectSchema;
4
+ export declare const DataSchema: ObjectSchema;
5
+ export declare const TemplateSchema: ObjectSchema;
6
+ export declare const RootSchema: ObjectSchema;