@schalkneethling/miyagi-core 4.4.2 → 4.4.4

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 (115) hide show
  1. package/README.md +7 -2
  2. package/api/app.js +16 -16
  3. package/api/index.js +263 -262
  4. package/bin/miyagi.js +1 -1
  5. package/dist/css/iframe.css +6 -30
  6. package/frontend/assets/css/iframe/accordion-tabs.css +39 -39
  7. package/frontend/assets/css/iframe/jsontree.js.css +149 -149
  8. package/frontend/assets/css/iframe/prism.css +45 -45
  9. package/frontend/assets/css/iframe/styleguide/colors.css +27 -27
  10. package/frontend/assets/css/iframe/styleguide/fonts.css +23 -23
  11. package/frontend/assets/css/iframe/styleguide/index.css +58 -58
  12. package/frontend/assets/css/iframe/styleguide/spacings.css +10 -10
  13. package/frontend/assets/css/iframe.css +191 -191
  14. package/frontend/assets/css/main/menu/config-switcher.css +21 -21
  15. package/frontend/assets/css/main/menu/config-switchers.css +34 -34
  16. package/frontend/assets/css/main/menu/goto.css +16 -16
  17. package/frontend/assets/css/main/menu/nav.css +49 -49
  18. package/frontend/assets/css/main/menu/search.css +34 -34
  19. package/frontend/assets/css/main/menu/title.css +18 -18
  20. package/frontend/assets/css/main/menu.css +89 -89
  21. package/frontend/assets/css/main/reset.css +47 -47
  22. package/frontend/assets/css/main.css +41 -41
  23. package/frontend/assets/css/shared.css +16 -16
  24. package/frontend/assets/css/tokens.css +108 -107
  25. package/frontend/assets/js/_accordion-tabs.js +392 -392
  26. package/frontend/assets/js/_goto.js +59 -59
  27. package/frontend/assets/js/_iframe-links.js +14 -14
  28. package/frontend/assets/js/_is-triggered.js +3 -3
  29. package/frontend/assets/js/_main.js +369 -369
  30. package/frontend/assets/js/_mock-data.js +8 -8
  31. package/frontend/assets/js/_prism.js +1082 -1081
  32. package/frontend/assets/js/_search.js +186 -186
  33. package/frontend/assets/js/_socket.js +44 -44
  34. package/frontend/assets/js/config-switcher/development-mode.js +38 -38
  35. package/frontend/assets/js/config-switcher/index.js +55 -55
  36. package/frontend/assets/js/config-switcher/text-direction.js +22 -22
  37. package/frontend/assets/js/config-switcher/theme.js +68 -68
  38. package/frontend/assets/js/iframe.build.js +25 -25
  39. package/frontend/assets/js/iframe.js +38 -38
  40. package/frontend/assets/js/jsontree.js +979 -976
  41. package/frontend/assets/js/main.build.js +29 -29
  42. package/frontend/assets/js/main.js +31 -31
  43. package/frontend/assets/js/styleguide/color-converter.js +652 -652
  44. package/frontend/assets/js/styleguide/index.js +100 -100
  45. package/lib/build/index.js +1014 -1020
  46. package/lib/cli/app.js +16 -16
  47. package/lib/cli/component.js +50 -50
  48. package/lib/cli/doctor.js +130 -121
  49. package/lib/cli/drupal-assets.js +163 -157
  50. package/lib/cli/lint.js +196 -196
  51. package/lib/cli/run.js +150 -146
  52. package/lib/config.js +86 -86
  53. package/lib/constants/lint-log-levels.js +6 -6
  54. package/lib/drupal/load-assets-config.js +59 -60
  55. package/lib/drupal/resolve-library-assets.js +132 -141
  56. package/lib/errors.js +20 -20
  57. package/lib/generator/component.js +124 -124
  58. package/lib/generator/mocks.js +156 -156
  59. package/lib/helpers.js +68 -68
  60. package/lib/i18n/en.js +93 -93
  61. package/lib/i18n/index.js +8 -8
  62. package/lib/index.js +13 -13
  63. package/lib/init/args.js +153 -153
  64. package/lib/init/config.js +452 -438
  65. package/lib/init/engines.js +41 -41
  66. package/lib/init/index.js +83 -83
  67. package/lib/init/rendering.js +3 -3
  68. package/lib/init/static.js +90 -90
  69. package/lib/init/twing/cache.js +27 -27
  70. package/lib/init/twing/functions.js +37 -37
  71. package/lib/init/views.js +5 -5
  72. package/lib/logger.js +72 -72
  73. package/lib/mocks/get.js +88 -88
  74. package/lib/mocks/index.js +2 -2
  75. package/lib/mocks/resolve/ref.js +447 -447
  76. package/lib/mocks/resolve/tpl.js +218 -218
  77. package/lib/mocks/resolve.js +154 -154
  78. package/lib/render/helpers/resolve-assets.js +29 -39
  79. package/lib/render/helpers.js +27 -27
  80. package/lib/render/index.js +18 -18
  81. package/lib/render/views/iframe/component.docs.js +50 -50
  82. package/lib/render/views/iframe/component.js +249 -248
  83. package/lib/render/views/iframe/design-tokens/colors.js +38 -38
  84. package/lib/render/views/iframe/design-tokens/index.js +3 -3
  85. package/lib/render/views/iframe/design-tokens/sizes.js +35 -35
  86. package/lib/render/views/iframe/design-tokens/typography.js +37 -37
  87. package/lib/render/views/iframe/docs.js +42 -42
  88. package/lib/render/views/iframe/index.js +28 -28
  89. package/lib/render/views/iframe/variation.js +89 -89
  90. package/lib/render/views/iframe/variation.standalone.js +69 -68
  91. package/lib/render/views/main/component.docs.js +38 -38
  92. package/lib/render/views/main/component.js +55 -55
  93. package/lib/render/views/main/design-tokens.js +38 -38
  94. package/lib/render/views/main/docs.js +33 -33
  95. package/lib/render/views/main/index.js +33 -33
  96. package/lib/state/components.js +99 -99
  97. package/lib/state/css.js +33 -33
  98. package/lib/state/docs.js +72 -72
  99. package/lib/state/file-contents.js +154 -154
  100. package/lib/state/helpers.js +53 -53
  101. package/lib/state/index.js +39 -39
  102. package/lib/state/menu/index.js +202 -202
  103. package/lib/state/menu/structure.js +84 -84
  104. package/lib/state/partials.js +12 -12
  105. package/lib/state/source-tree.js +51 -51
  106. package/lib/styleguide/color-names.js +148 -148
  107. package/lib/styleguide/colors.js +113 -113
  108. package/lib/styleguide/helpers.js +33 -33
  109. package/lib/styleguide/index.js +4 -4
  110. package/lib/styleguide/media-queries.js +18 -18
  111. package/lib/styleguide/spacings.js +22 -22
  112. package/lib/styleguide/typography.js +46 -46
  113. package/lib/validator/mocks.js +110 -83
  114. package/lib/validator/schemas.js +236 -227
  115. package/package.json +120 -117
@@ -2,26 +2,26 @@ import path from "node:path";
2
2
  import * as v from "valibot";
3
3
 
4
4
  const DrupalBlockSchema = v.object({
5
- libraries: v.string(),
6
- ignorePrefixes: v.optional(v.array(v.string())),
7
- mapping: v.optional(v.record(v.string(), v.string())),
8
- autoDiscoveryPrefixes: v.optional(v.nullable(v.array(v.string()))),
9
- components: v.optional(v.nullable(v.array(v.string()))),
5
+ libraries: v.string(),
6
+ ignorePrefixes: v.optional(v.array(v.string())),
7
+ mapping: v.optional(v.record(v.string(), v.string())),
8
+ autoDiscoveryPrefixes: v.optional(v.nullable(v.array(v.string()))),
9
+ components: v.optional(v.nullable(v.array(v.string()))),
10
10
  });
11
11
 
12
12
  const ConfigSchema = v.object({
13
- engine: v.picklist(["drupal"]),
14
- drupal: DrupalBlockSchema,
13
+ engine: v.picklist(["drupal"]),
14
+ drupal: DrupalBlockSchema,
15
15
  });
16
16
 
17
17
  export const NormalizedConfigSchema = v.object({
18
- engine: v.string(),
19
- libraries: v.optional(v.string()),
20
- ignorePrefixes: v.array(v.string()),
21
- mapping: v.record(v.string(), v.string()),
22
- autoDiscoveryPrefixes: v.nullable(v.array(v.string())),
23
- components: v.nullable(v.array(v.string())),
24
- dryRun: v.boolean(),
18
+ engine: v.string(),
19
+ libraries: v.optional(v.string()),
20
+ ignorePrefixes: v.array(v.string()),
21
+ mapping: v.record(v.string(), v.string()),
22
+ autoDiscoveryPrefixes: v.nullable(v.array(v.string())),
23
+ components: v.nullable(v.array(v.string())),
24
+ dryRun: v.boolean(),
25
25
  });
26
26
 
27
27
  /** @typedef {v.InferOutput<typeof NormalizedConfigSchema>} NormalizedConfig */
@@ -38,57 +38,56 @@ export const NormalizedConfigSchema = v.object({
38
38
  * @returns {Promise<NormalizedConfig>} normalized config
39
39
  */
40
40
  export async function loadAssetsConfig(cliArgs) {
41
- let fileConfig = null;
41
+ let fileConfig = null;
42
42
 
43
- const configPath = cliArgs.config || ".miyagi-assets.js";
43
+ const configPath = cliArgs.config || ".miyagi-assets.js";
44
44
 
45
- try {
46
- const resolved = path.resolve(configPath);
47
- const mod = await import(resolved);
48
- fileConfig = mod.default || mod;
49
- } catch {
50
- if (!cliArgs.libraries) {
51
- throw new Error(
52
- `Could not load config file "${configPath}" and no --libraries flag provided.`,
53
- );
54
- }
55
- }
45
+ try {
46
+ const resolved = path.resolve(configPath);
47
+ const mod = await import(resolved);
48
+ fileConfig = mod.default || mod;
49
+ } catch {
50
+ if (!cliArgs.libraries) {
51
+ throw new Error(
52
+ `Could not load config file "${configPath}" and no --libraries flag provided.`,
53
+ );
54
+ }
55
+ }
56
56
 
57
- if (fileConfig) {
58
- const result = v.safeParse(ConfigSchema, fileConfig);
57
+ if (fileConfig) {
58
+ const result = v.safeParse(ConfigSchema, fileConfig);
59
59
 
60
- if (!result.success) {
61
- const messages = result.issues.map((issue) => {
62
- const issuePath =
63
- issue.path?.map((path) => path.key).join(".") || "root";
64
- return `${issuePath}: ${issue.message}`;
65
- });
66
- throw new Error(`Invalid config: ${messages.join("; ")}`);
67
- }
60
+ if (!result.success) {
61
+ const messages = result.issues.map((issue) => {
62
+ const issuePath =
63
+ issue.path?.map((path) => path.key).join(".") || "root";
64
+ return `${issuePath}: ${issue.message}`;
65
+ });
66
+ throw new Error(`Invalid config: ${messages.join("; ")}`);
67
+ }
68
68
 
69
- const { engine } = result.output;
70
- const engineBlock = result.output[engine];
69
+ const { engine } = result.output;
70
+ const engineBlock = result.output[engine];
71
71
 
72
- return {
73
- engine,
74
- libraries: cliArgs.libraries || engineBlock.libraries,
75
- ignorePrefixes:
76
- cliArgs.ignorePrefixes || engineBlock.ignorePrefixes || [],
77
- mapping: engineBlock.mapping || {},
78
- autoDiscoveryPrefixes: engineBlock.autoDiscoveryPrefixes ?? null,
79
- components:
80
- cliArgs.components || engineBlock.components || null,
81
- dryRun: cliArgs.dryRun || false,
82
- };
83
- }
72
+ return {
73
+ engine,
74
+ libraries: cliArgs.libraries || engineBlock.libraries,
75
+ ignorePrefixes:
76
+ cliArgs.ignorePrefixes || engineBlock.ignorePrefixes || [],
77
+ mapping: engineBlock.mapping || {},
78
+ autoDiscoveryPrefixes: engineBlock.autoDiscoveryPrefixes ?? null,
79
+ components: cliArgs.components || engineBlock.components || null,
80
+ dryRun: cliArgs.dryRun || false,
81
+ };
82
+ }
84
83
 
85
- return {
86
- engine: cliArgs.engine || "drupal",
87
- libraries: cliArgs.libraries,
88
- ignorePrefixes: cliArgs.ignorePrefixes || [],
89
- mapping: {},
90
- autoDiscoveryPrefixes: null,
91
- components: cliArgs.components || null,
92
- dryRun: cliArgs.dryRun || false,
93
- };
84
+ return {
85
+ engine: cliArgs.engine || "drupal",
86
+ libraries: cliArgs.libraries,
87
+ ignorePrefixes: cliArgs.ignorePrefixes || [],
88
+ mapping: {},
89
+ autoDiscoveryPrefixes: null,
90
+ components: cliArgs.components || null,
91
+ dryRun: cliArgs.dryRun || false,
92
+ };
94
93
  }
@@ -16,41 +16,39 @@ import yaml from "js-yaml";
16
16
  * @returns {Record<string, LibraryEntry>}
17
17
  */
18
18
  export function parseLibrariesYaml(yamlContent) {
19
- /**
20
- * @type {Record<string, {
21
- * css?: Record<string, Record<string, object>>,
22
- * js?: Record<string, {attributes?: {type?: string}}>,
23
- * dependencies?: string[]
24
- * }>}
25
- */
26
- const raw = /** @type {never} */ (yaml.load(yamlContent));
27
- /** @type {Record<string, LibraryEntry>} */
28
- const map = {};
29
-
30
- for (const [name, entry] of Object.entries(raw)) {
31
- const css = entry.css
32
- ? Object.values(entry.css).flatMap(Object.keys)
33
- : [];
34
-
35
- const js = entry.js
36
- ? Object.entries(entry.js).map(([src, opts]) =>
37
- opts?.attributes?.type
38
- ? { src, type: opts.attributes.type }
39
- : { src },
40
- )
41
- : [];
42
-
43
- const dependencies = (entry.dependencies || [])
44
- .filter((dep) => dep.includes("/"))
45
- .map((dep) => ({
46
- prefix: dep.slice(0, dep.indexOf("/")),
47
- name: dep.slice(dep.indexOf("/") + 1),
48
- }));
49
-
50
- map[name] = { css, js, dependencies };
51
- }
52
-
53
- return map;
19
+ /**
20
+ * @type {Record<string, {
21
+ * css?: Record<string, Record<string, object>>,
22
+ * js?: Record<string, {attributes?: {type?: string}}>,
23
+ * dependencies?: string[]
24
+ * }>}
25
+ */
26
+ const raw = /** @type {never} */ (yaml.load(yamlContent));
27
+ /** @type {Record<string, LibraryEntry>} */
28
+ const map = {};
29
+
30
+ for (const [name, entry] of Object.entries(raw)) {
31
+ const css = entry.css ? Object.values(entry.css).flatMap(Object.keys) : [];
32
+
33
+ const js = entry.js
34
+ ? Object.entries(entry.js).map(([src, opts]) =>
35
+ opts?.attributes?.type
36
+ ? { src, type: opts.attributes.type }
37
+ : { src },
38
+ )
39
+ : [];
40
+
41
+ const dependencies = (entry.dependencies || [])
42
+ .filter((dep) => dep.includes("/"))
43
+ .map((dep) => ({
44
+ prefix: dep.slice(0, dep.indexOf("/")),
45
+ name: dep.slice(dep.indexOf("/") + 1),
46
+ }));
47
+
48
+ map[name] = { css, js, dependencies };
49
+ }
50
+
51
+ return map;
54
52
  }
55
53
 
56
54
  /**
@@ -64,65 +62,61 @@ export function parseLibrariesYaml(yamlContent) {
64
62
  * @returns {{css: string[], js: JsEntry[]}}
65
63
  */
66
64
  export function resolveComponentAssets(
67
- libraryName,
68
- librariesMap,
69
- ignorePrefixes,
65
+ libraryName,
66
+ librariesMap,
67
+ ignorePrefixes,
70
68
  ) {
71
- const cssSet = [];
72
- const jsSet = [];
73
- const resolved = new Set();
74
-
75
- /**
76
- * @param {string} name
77
- * @param {Set<string>} ancestors
78
- */
79
- function walk(name, ancestors) {
80
- if (ancestors.has(name)) {
81
- console.warn(
82
- `Circular dependency detected: "${name}" already in chain.`,
83
- );
84
- return;
85
- }
86
-
87
- if (resolved.has(name)) {
88
- return;
89
- }
90
-
91
- const lib = librariesMap[name];
92
- if (!lib) {
93
- console.warn(
94
- `Dependency "${name}" not found in libraries — skipping.`,
95
- );
96
- return;
97
- }
98
-
99
- const chain = new Set(ancestors);
100
- chain.add(name);
101
-
102
- for (const dep of lib.dependencies) {
103
- if (ignorePrefixes.includes(dep.prefix)) {
104
- continue;
105
- }
106
- walk(dep.name, chain);
107
- }
108
-
109
- for (const cssFile of lib.css) {
110
- if (!cssSet.includes(cssFile)) {
111
- cssSet.push(cssFile);
112
- }
113
- }
114
-
115
- for (const jsEntry of lib.js) {
116
- if (!jsSet.some((entry) => entry.src === jsEntry.src)) {
117
- jsSet.push(jsEntry);
118
- }
119
- }
120
-
121
- resolved.add(name);
122
- }
123
-
124
- walk(libraryName, new Set());
125
- return { css: cssSet, js: jsSet };
69
+ const cssSet = [];
70
+ const jsSet = [];
71
+ const resolved = new Set();
72
+
73
+ /**
74
+ * @param {string} name
75
+ * @param {Set<string>} ancestors
76
+ */
77
+ function walk(name, ancestors) {
78
+ if (ancestors.has(name)) {
79
+ console.warn(`Circular dependency detected: "${name}" already in chain.`);
80
+ return;
81
+ }
82
+
83
+ if (resolved.has(name)) {
84
+ return;
85
+ }
86
+
87
+ const lib = librariesMap[name];
88
+ if (!lib) {
89
+ console.warn(`Dependency "${name}" not found in libraries — skipping.`);
90
+ return;
91
+ }
92
+
93
+ const chain = new Set(ancestors);
94
+ chain.add(name);
95
+
96
+ for (const dep of lib.dependencies) {
97
+ if (ignorePrefixes.includes(dep.prefix)) {
98
+ continue;
99
+ }
100
+ walk(dep.name, chain);
101
+ }
102
+
103
+ for (const cssFile of lib.css) {
104
+ if (!cssSet.includes(cssFile)) {
105
+ cssSet.push(cssFile);
106
+ }
107
+ }
108
+
109
+ for (const jsEntry of lib.js) {
110
+ if (!jsSet.some((entry) => entry.src === jsEntry.src)) {
111
+ jsSet.push(jsEntry);
112
+ }
113
+ }
114
+
115
+ resolved.add(name);
116
+ }
117
+
118
+ walk(libraryName, new Set());
119
+ return { css: cssSet, js: jsSet };
126
120
  }
127
121
 
128
122
  const DEFAULT_PREFIXES = ["element-", "pattern-", "template-", "component-"];
@@ -137,53 +131,50 @@ const DEFAULT_PREFIXES = ["element-", "pattern-", "template-", "component-"];
137
131
  * @returns {string|null} component folder relative path, or null if not found
138
132
  */
139
133
  export function mapLibraryToComponent(
140
- libraryName,
141
- mapping,
142
- componentsFolder,
143
- autoDiscoveryPrefixes = DEFAULT_PREFIXES,
134
+ libraryName,
135
+ mapping,
136
+ componentsFolder,
137
+ autoDiscoveryPrefixes = DEFAULT_PREFIXES,
144
138
  ) {
145
- if (mapping[libraryName]) {
146
- return mapping[libraryName];
147
- }
148
-
149
- const candidates = [libraryName];
150
-
151
- for (const prefix of autoDiscoveryPrefixes) {
152
- if (libraryName.startsWith(prefix)) {
153
- candidates.push(libraryName.slice(prefix.length));
154
- }
155
- }
156
-
157
- try {
158
- /** @type {string[]} */
159
- const searchDirs = [componentsFolder];
160
- while (searchDirs.length > 0) {
161
- const dir = /** @type {string} */ (searchDirs.pop());
162
-
163
- if (!fs.existsSync(dir)) {
164
- continue;
165
- }
166
-
167
- const entries = fs.readdirSync(dir, { withFileTypes: true });
168
-
169
- for (const entry of entries) {
170
- if (!entry.isDirectory()) {
171
- continue;
172
- }
173
-
174
- if (candidates.includes(entry.name)) {
175
- return path.relative(
176
- componentsFolder,
177
- path.join(dir, entry.name),
178
- );
179
- }
180
- searchDirs.push(path.join(dir, entry.name));
181
- }
182
- }
183
- } catch {
184
- // Swallow filesystem errors (missing/unreadable dirs) intentionally.
185
- // Caller handles null return with a user-facing warning.
186
- }
187
-
188
- return null;
139
+ if (mapping[libraryName]) {
140
+ return mapping[libraryName];
141
+ }
142
+
143
+ const candidates = [libraryName];
144
+
145
+ for (const prefix of autoDiscoveryPrefixes) {
146
+ if (libraryName.startsWith(prefix)) {
147
+ candidates.push(libraryName.slice(prefix.length));
148
+ }
149
+ }
150
+
151
+ try {
152
+ /** @type {string[]} */
153
+ const searchDirs = [componentsFolder];
154
+ while (searchDirs.length > 0) {
155
+ const dir = /** @type {string} */ (searchDirs.pop());
156
+
157
+ if (!fs.existsSync(dir)) {
158
+ continue;
159
+ }
160
+
161
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
162
+
163
+ for (const entry of entries) {
164
+ if (!entry.isDirectory()) {
165
+ continue;
166
+ }
167
+
168
+ if (candidates.includes(entry.name)) {
169
+ return path.relative(componentsFolder, path.join(dir, entry.name));
170
+ }
171
+ searchDirs.push(path.join(dir, entry.name));
172
+ }
173
+ }
174
+ } catch {
175
+ // Swallow filesystem errors (missing/unreadable dirs) intentionally.
176
+ // Caller handles null return with a user-facing warning.
177
+ }
178
+
179
+ return null;
189
180
  }
package/lib/errors.js CHANGED
@@ -5,27 +5,27 @@
5
5
  * not a unique code for every possible failure.
6
6
  */
7
7
  export const EXIT_CODES = Object.freeze({
8
- SUCCESS: 0,
9
- GENERAL_ERROR: 1,
10
- CLI_USAGE_ERROR: 2,
11
- CONFIG_ERROR: 3,
12
- VALIDATION_ERROR: 4,
8
+ SUCCESS: 0,
9
+ GENERAL_ERROR: 1,
10
+ CLI_USAGE_ERROR: 2,
11
+ CONFIG_ERROR: 3,
12
+ VALIDATION_ERROR: 4,
13
13
  });
14
14
 
15
15
  export class MiyagiError extends Error {
16
- /**
17
- * @param {string} message
18
- * @param {object} [options]
19
- * @param {number} [options.code] Exit code from `EXIT_CODES`.
20
- * @param {boolean} [options.logged] True if this error was already sent to the logger and should not be logged again at the CLI boundary.
21
- */
22
- constructor(
23
- message,
24
- { code = EXIT_CODES.GENERAL_ERROR, logged = false } = {},
25
- ) {
26
- super(message);
27
- this.name = "MiyagiError";
28
- this.code = code;
29
- this.logged = logged;
30
- }
16
+ /**
17
+ * @param {string} message
18
+ * @param {object} [options]
19
+ * @param {number} [options.code] Exit code from `EXIT_CODES`.
20
+ * @param {boolean} [options.logged] True if this error was already sent to the logger and should not be logged again at the CLI boundary.
21
+ */
22
+ constructor(
23
+ message,
24
+ { code = EXIT_CODES.GENERAL_ERROR, logged = false } = {},
25
+ ) {
26
+ super(message);
27
+ this.name = "MiyagiError";
28
+ this.code = code;
29
+ this.logged = logged;
30
+ }
31
31
  }