@emulsify/core 4.2.1 → 4.3.1

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 (84) hide show
  1. package/.storybook/main-vite.js +102 -37
  2. package/.storybook/main.js +20 -0
  3. package/.storybook/ready-reporter.js +230 -0
  4. package/README.md +186 -56
  5. package/config/a11y.config.js +2 -1
  6. package/config/vite/entries.js +4 -4
  7. package/config/vite/plugins/assets/copy-src-assets.js +120 -0
  8. package/config/vite/plugins/assets/copy-twig-files.js +130 -0
  9. package/config/vite/plugins/{css-asset-relativizer.js → assets/css-asset-relativizer.js} +9 -0
  10. package/config/vite/plugins/{mirror-components.js → assets/mirror-components.js} +2 -28
  11. package/config/vite/plugins/{source-file-index.js → assets/source-file-index.js} +1 -1
  12. package/config/vite/plugins/{svg-sprite.js → assets/svg-sprite.js} +2 -2
  13. package/config/vite/plugins/index.js +23 -14
  14. package/config/vite/plugins/reporter/asset-resolver.js +541 -0
  15. package/config/vite/plugins/reporter/build-errors.js +284 -0
  16. package/config/vite/plugins/reporter/diagnostics.js +367 -0
  17. package/config/vite/plugins/reporter/format.js +240 -0
  18. package/config/vite/plugins/reporter/index.js +417 -0
  19. package/config/vite/plugins/reporter/render.js +1332 -0
  20. package/config/vite/plugins/reporter/sass-logger.js +237 -0
  21. package/config/vite/plugins/reporter/source-roots.js +561 -0
  22. package/config/vite/plugins/reporter/verbosity.js +119 -0
  23. package/config/vite/plugins/reporter/vite-logger.js +249 -0
  24. package/config/vite/plugins/reporter/watch-mode.js +40 -0
  25. package/config/vite/plugins/{twig-extension-installers.js → twig/extension-installers.js} +1 -1
  26. package/config/vite/{twig-extensions.js → plugins/twig/extensions.js} +2 -2
  27. package/config/vite/plugins/{twig-module.js → twig/twig-module.js} +197 -85
  28. package/config/vite/plugins/{virtual-twig-asset-sources.js → twig/virtual-twig-asset-sources.js} +37 -136
  29. package/config/vite/plugins/{virtual-twig-globs.js → twig/virtual-twig-globs.js} +3 -32
  30. package/config/vite/plugins/{vituum-patch.js → twig/vituum-patch.js} +3 -3
  31. package/config/vite/plugins.js +1 -1
  32. package/config/vite/project-config.js +1 -1
  33. package/config/vite/project-structure.js +1 -1
  34. package/config/vite/utils/lru.js +77 -0
  35. package/config/vite/utils/package-version.js +42 -0
  36. package/config/vite/utils/paths.js +1 -9
  37. package/config/vite/utils/react-singleton.js +1 -1
  38. package/config/vite/vite.config.js +91 -5
  39. package/package.json +95 -57
  40. package/scripts/a11y.js +115 -23
  41. package/scripts/audit/checks/core-imports.js +78 -0
  42. package/scripts/audit/checks/css-asset-references.js +99 -0
  43. package/scripts/audit/checks/drupal-assumptions.js +48 -0
  44. package/scripts/audit/checks/files-outside-roots.js +53 -0
  45. package/scripts/audit/checks/generated-package-scripts.js +113 -0
  46. package/scripts/audit/checks/legacy-twig-stories.js +33 -0
  47. package/scripts/audit/checks/package-overrides.js +91 -0
  48. package/scripts/audit/checks/project-config.js +71 -0
  49. package/scripts/audit/checks/story-discovery.js +35 -0
  50. package/scripts/audit/checks/twig-references.js +69 -0
  51. package/scripts/audit/checks/twig-volume.js +54 -0
  52. package/scripts/audit/checks/webpack-patterns.js +86 -0
  53. package/scripts/audit/index.js +177 -0
  54. package/scripts/audit/lib/css.js +165 -0
  55. package/scripts/audit/lib/files.js +168 -0
  56. package/scripts/audit/lib/findings.js +31 -0
  57. package/scripts/audit/lib/package-json.js +65 -0
  58. package/scripts/audit/lib/twig.js +227 -0
  59. package/scripts/audit/report.js +273 -0
  60. package/scripts/audit-twig-stories.js +115 -78
  61. package/scripts/audit.js +150 -1632
  62. package/scripts/check-node-version.js +136 -10
  63. package/scripts/inspect-components.js +456 -0
  64. package/scripts/lib/cli.js +179 -0
  65. package/scripts/lib/fs.js +31 -0
  66. package/scripts/lib/proc.js +78 -0
  67. package/scripts/lib/text.js +14 -0
  68. package/scripts/loadYaml.js +2 -2
  69. package/src/extensions/shared/attributes.js +3 -3
  70. package/src/extensions/shared/lists.js +2 -6
  71. package/src/extensions/shared/root-relative.js +38 -0
  72. package/src/storybook/index.js +4 -0
  73. package/src/storybook/render-twig.js +1 -1
  74. package/src/storybook/render-web-component.js +459 -0
  75. package/src/storybook/twig/asset-source-runtime.js +193 -0
  76. package/src/storybook/twig/{source-extensions.js → constants.js} +3 -1
  77. package/src/storybook/twig/reference-paths.js +2 -13
  78. package/src/storybook/twig/setup.js +12 -2
  79. package/src/storybook/twig/source-function.js +5 -2
  80. package/config/vite/plugins/copy-src-assets.js +0 -76
  81. package/config/vite/plugins/copy-twig-files.js +0 -84
  82. package/config/vite/utils/unique.js +0 -36
  83. package/src/storybook/twig/include.js +0 -28
  84. package/src/storybook/twig/source-events.js +0 -5
@@ -3,7 +3,8 @@
3
3
  */
4
4
 
5
5
  import { registerTwigExtensions } from '../../extensions/twig/index.js';
6
- import twigInclude from './include.js';
6
+ import { createTwigIncludeFunction } from './include-function.js';
7
+ import resolveTemplate from './resolver.js';
7
8
  import twigSource from './source.js';
8
9
 
9
10
  /**
@@ -35,5 +36,14 @@ export function setupTwig(twig, options = {}) {
35
36
  return twig;
36
37
  }
37
38
 
38
- export { default as twigInclude } from './include.js';
39
+ /**
40
+ * Twig `include()` runtime helper.
41
+ *
42
+ * @param {Object} Twig - Twig.js module.
43
+ * @returns {undefined}
44
+ */
45
+ export function twigInclude(Twig) {
46
+ Twig.extendFunction('include', createTwigIncludeFunction(resolveTemplate));
47
+ }
48
+
39
49
  export { default as twigSource } from './source.js';
@@ -8,8 +8,11 @@ import {
8
8
  isAssetTextLoading,
9
9
  whenAssetTextLoaded,
10
10
  } from 'virtual:emulsify-twig-asset-sources';
11
- import { IMAGE_ASSET_EXTS, INLINE_ASSET_EXTS } from './source-extensions.js';
12
- import { TWIG_SOURCE_LOADED_EVENT } from './source-events.js';
11
+ import {
12
+ IMAGE_ASSET_EXTS,
13
+ INLINE_ASSET_EXTS,
14
+ TWIG_SOURCE_LOADED_EVENT,
15
+ } from './constants.js';
13
16
 
14
17
  const DEFAULT_ENV =
15
18
  (typeof __EMULSIFY_ENV__ !== 'undefined' && __EMULSIFY_ENV__) || {};
@@ -1,76 +0,0 @@
1
- /**
2
- * @file Static source asset copy plugin.
3
- *
4
- * Copies non-code source assets beside the JS/CSS/Twig output that references
5
- * them, preserving component and global routing semantics.
6
- */
7
-
8
- import { copyFileSync, mkdirSync } from 'fs';
9
- import { dirname, join } from 'path';
10
-
11
- import {
12
- copiedComponentOutputPath,
13
- copiedGlobalOutputPath,
14
- findSourceRoot,
15
- } from '../project-structure.js';
16
- import {
17
- createSourceFileIndex,
18
- isStaticSourceAsset,
19
- } from './source-file-index.js';
20
-
21
- /**
22
- * Copy non-code assets from source roots to `dist/`.
23
- *
24
- * @param {{ structure: object, sourceFileIndex?: object }} opts - Plugin options.
25
- * @returns {import('vite').PluginOption} Copy plugin.
26
- */
27
- export function copyAllSrcAssetsPlugin({
28
- structure,
29
- sourceFileIndex = createSourceFileIndex(structure),
30
- }) {
31
- let outDir = 'dist';
32
-
33
- const copyToOutDir = (absPath, relDest) => {
34
- if (!relDest) return;
35
- const destPath = join(outDir, relDest);
36
- mkdirSync(dirname(destPath), { recursive: true });
37
- try {
38
- copyFileSync(absPath, destPath);
39
- } catch {
40
- /* noop */
41
- }
42
- };
43
-
44
- return {
45
- name: 'emulsify-copy-all-src-assets',
46
- apply: 'build',
47
- enforce: 'post',
48
-
49
- /** Capture outDir. */
50
- configResolved(cfg) {
51
- outDir = cfg.build?.outDir || 'dist';
52
- },
53
-
54
- /** Copy before the mirror plugin moves dist/components to the project root. */
55
- writeBundle() {
56
- for (const file of sourceFileIndex.componentFiles()) {
57
- if (!isStaticSourceAsset(file.absPath)) continue;
58
- copyToOutDir(
59
- file.absPath,
60
- copiedComponentOutputPath(file.absPath, structure),
61
- );
62
- }
63
-
64
- for (const file of sourceFileIndex.globalFiles()) {
65
- if (!isStaticSourceAsset(file.absPath)) continue;
66
- if (findSourceRoot(file.absPath, structure.componentRootRecords)) {
67
- continue;
68
- }
69
- copyToOutDir(
70
- file.absPath,
71
- copiedGlobalOutputPath(file.absPath, structure),
72
- );
73
- }
74
- },
75
- };
76
- }
@@ -1,84 +0,0 @@
1
- /**
2
- * @file Twig template and component metadata copy plugin.
3
- *
4
- * Copies canonical source Twig files and component metadata to the emitted dist
5
- * structure using the same routing rules as compiled JS and CSS entries.
6
- */
7
-
8
- import { copyFileSync, mkdirSync } from 'fs';
9
- import { dirname, join } from 'path';
10
-
11
- import {
12
- copiedComponentOutputPath,
13
- copiedGlobalOutputPath,
14
- } from '../project-structure.js';
15
- import {
16
- createSourceFileIndex,
17
- isComponentMetadataFile,
18
- } from './source-file-index.js';
19
-
20
- /** Determine whether a Twig file is a partial (filename starts with `_`). */
21
- const isPartial = (filePath) =>
22
- (filePath.split('/')?.pop() || '').trim().startsWith('_');
23
-
24
- /**
25
- * Copy Twig templates and component metadata to `dist/`.
26
- *
27
- * @param {{ structure: object, sourceFileIndex?: object }} opts - Plugin options.
28
- * @returns {import('vite').PluginOption} Copy plugin.
29
- */
30
- export function copyTwigFilesPlugin({
31
- structure,
32
- sourceFileIndex = createSourceFileIndex(structure),
33
- }) {
34
- let outDir = 'dist';
35
-
36
- const copyToOutDir = (absPath, relDest) => {
37
- if (!relDest) return;
38
- const destPath = join(outDir, relDest);
39
- mkdirSync(dirname(destPath), { recursive: true });
40
- try {
41
- copyFileSync(absPath, destPath);
42
- } catch {
43
- /* noop */
44
- }
45
- };
46
-
47
- return {
48
- name: 'emulsify-copy-twig-files',
49
- apply: 'build',
50
- enforce: 'post',
51
-
52
- /** Capture the final outDir. */
53
- configResolved(cfg) {
54
- outDir = cfg.build?.outDir || 'dist';
55
- },
56
-
57
- /** Copy before the mirror plugin moves dist/components to the project root. */
58
- writeBundle() {
59
- for (const file of sourceFileIndex.componentFiles()) {
60
- if (file.absPath.endsWith('.twig')) {
61
- if (isPartial(file.relPath)) continue;
62
- copyToOutDir(
63
- file.absPath,
64
- copiedComponentOutputPath(file.absPath, structure),
65
- );
66
- } else if (isComponentMetadataFile(file.absPath)) {
67
- copyToOutDir(
68
- file.absPath,
69
- copiedComponentOutputPath(file.absPath, structure),
70
- );
71
- }
72
- }
73
-
74
- for (const file of sourceFileIndex.globalFiles()) {
75
- if (!file.absPath.endsWith('.twig')) continue;
76
- if (isPartial(file.relPath)) continue;
77
- copyToOutDir(
78
- file.absPath,
79
- copiedGlobalOutputPath(file.absPath, structure),
80
- );
81
- }
82
- },
83
- };
84
- }
@@ -1,36 +0,0 @@
1
- /**
2
- * @file Shared array de-duplication helpers.
3
- */
4
-
5
- /**
6
- * Return values in first-seen order with duplicates removed.
7
- *
8
- * @template T
9
- * @param {T[]} values - Values to deduplicate.
10
- * @returns {T[]} Unique values.
11
- */
12
- export function unique(values = []) {
13
- return Array.from(new Set(values));
14
- }
15
-
16
- /**
17
- * Return values in first-seen order with duplicates removed by key.
18
- *
19
- * @template T
20
- * @param {T[]} values - Values to deduplicate.
21
- * @param {(value: T) => *} keyFn - Function that returns a comparable key.
22
- * @returns {T[]} Unique values.
23
- */
24
- export function uniqueBy(values = [], keyFn) {
25
- const seen = new Set();
26
- const result = [];
27
-
28
- for (const value of values) {
29
- const key = keyFn(value);
30
- if (seen.has(key)) continue;
31
- seen.add(key);
32
- result.push(value);
33
- }
34
-
35
- return result;
36
- }
@@ -1,28 +0,0 @@
1
- /**
2
- * @file Twig include() runtime helper for Storybook-rendered templates.
3
- */
4
-
5
- import { createTwigIncludeFunction as createIncludeFunction } from './include-function.js';
6
- import resolveTemplate from './resolver.js';
7
-
8
- /**
9
- * Create a Twig.js `include()` function with the Storybook template resolver.
10
- *
11
- * @param {Function} resolver - Template resolver.
12
- * @returns {Function} Twig.js function implementation.
13
- */
14
- export function createTwigIncludeFunction(resolver = resolveTemplate) {
15
- return createIncludeFunction(resolver);
16
- }
17
-
18
- /**
19
- * Twig `include()` runtime helper.
20
- *
21
- * @param {Object} Twig - Twig.js module.
22
- * @returns {undefined}
23
- */
24
- function twigInclude(Twig) {
25
- Twig.extendFunction('include', createIncludeFunction(resolveTemplate));
26
- }
27
-
28
- export default twigInclude;
@@ -1,5 +0,0 @@
1
- /**
2
- * @file Shared events for lazy Twig source loading.
3
- */
4
-
5
- export const TWIG_SOURCE_LOADED_EVENT = 'emulsify:twig-source-loaded';