mage-obsidian 1.0.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 (71) hide show
  1. package/jest.config.js +5 -0
  2. package/package.json +37 -0
  3. package/src/__tests__/__mocks__/configResolver.js +35 -0
  4. package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameA/view/frontend/web/components/ComponentA.vue +0 -0
  5. package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameA/view/frontend/web/components/ComponentB.vue +0 -0
  6. package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameA/view/frontend/web/css/module.extend.css +0 -0
  7. package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameA/view/frontend/web/js/main.js +0 -0
  8. package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameA/view/frontend/web/main.js +0 -0
  9. package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameA/view/frontend/web/module.config.cjs +9 -0
  10. package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameB/view/frontend/web/components/ComponentA.vue +0 -0
  11. package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameB/view/frontend/web/components/ComponentB.vue +0 -0
  12. package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameB/view/frontend/web/css/module.extend.css +2 -0
  13. package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameB/view/frontend/web/js/main.js +0 -0
  14. package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameB/view/frontend/web/module.config.cjs +7 -0
  15. package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameC/view/frontend/web/components/ComponentA.vue +0 -0
  16. package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameC/view/frontend/web/components/ComponentB.vue +0 -0
  17. package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameC/view/frontend/web/css/module.extend.css +2 -0
  18. package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameC/view/frontend/web/js/main.js +0 -0
  19. package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameC/view/frontend/web/module.config.cjs +7 -0
  20. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/components/ComponentA.vue +0 -0
  21. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/components/ComponentB.vue +0 -0
  22. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/css/module.extend.css +0 -0
  23. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/js/main.js +0 -0
  24. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/module.config.cjs +8 -0
  25. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/components/ComponentA.vue +0 -0
  26. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/components/ComponentB.vue +0 -0
  27. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/css/module.extend.css +0 -0
  28. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/js/main.js +0 -0
  29. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/module.config.cjs +7 -0
  30. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameNoConfig/web/components/ComponentA.vue +0 -0
  31. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameNoConfig/web/components/ComponentB.vue +0 -0
  32. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameNoConfig/web/css/module.extend.css +0 -0
  33. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameNoConfig/web/js/main.js +0 -0
  34. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameNoConfig/web/module.config.cjs +8 -0
  35. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/web/components/ComponentA.vue +0 -0
  36. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/web/components/ComponentB.vue +0 -0
  37. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/web/css/tailwind.source.css +6 -0
  38. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/web/js/main.js +0 -0
  39. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/web/theme.config.cjs +18 -0
  40. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-b/web/css/tailwind.source.css +6 -0
  41. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-b/web/theme.config.cjs +22 -0
  42. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-c/Vendor_ModuleNameB/web/components/ComponentA.vue +0 -0
  43. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-c/Vendor_ModuleNameB/web/components/ComponentB.vue +0 -0
  44. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-c/Vendor_ModuleNameB/web/css/module.extend.css +0 -0
  45. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-c/Vendor_ModuleNameB/web/js/main.js +0 -0
  46. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-c/Vendor_ModuleNameB/web/module.config.cjs +9 -0
  47. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-c/web/css/tailwind.source.css +6 -0
  48. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-c/web/theme.config.cjs +16 -0
  49. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-d/web/css/tailwind.source.css +6 -0
  50. package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-d/web/theme.config.cjs +14 -0
  51. package/src/__tests__/magento_scenarios/app/etc/mage_obsidian_frontend_modules_a.json +53 -0
  52. package/src/__tests__/magento_scenarios/app/etc/mage_obsidian_frontend_modules_b.json +50 -0
  53. package/src/__tests__/service/inheritModuleResolver.test.js +69 -0
  54. package/src/__tests__/service/moduleResolver.test.js +192 -0
  55. package/src/__tests__/service/moduleResolverSync.test.js +187 -0
  56. package/src/__tests__/service/themeResolverSync.test.js +164 -0
  57. package/src/config/default.cjs +41 -0
  58. package/src/scripts/buildThemes.js +131 -0
  59. package/src/service/configResolver.cjs +39 -0
  60. package/src/service/cssResolver.js +55 -0
  61. package/src/service/inheritModuleResolver.js +57 -0
  62. package/src/service/magentoHrmRewrite.js +24 -0
  63. package/src/service/moduleResolver.js +103 -0
  64. package/src/service/moduleResolverSync.cjs +84 -0
  65. package/src/service/preCompileFiles.js +37 -0
  66. package/src/service/preCompileMagentoFiles.js +16 -0
  67. package/src/service/setupGlobals.js +19 -0
  68. package/src/service/tailwindResolver.cjs +15 -0
  69. package/src/service/themeResolverSync.cjs +80 -0
  70. package/src/templates/base_main_js_file.js +5 -0
  71. package/src/utils/findComponents.js +70 -0
@@ -0,0 +1,192 @@
1
+ import { jest } from '@jest/globals';
2
+ import createMockConfigResolver from '../__mocks__/configResolver.js';
3
+ import path from 'path';
4
+ import {fileURLToPath} from 'url';
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = path.dirname(__filename);
7
+ const MAGENTO_SCENARIOS_PATH = path.resolve(__dirname,'../magento_scenarios');
8
+
9
+ let scenarios = [
10
+ {
11
+ scenario: 'a',
12
+ themes: [
13
+ {
14
+ code: 'Vendor/theme-a',
15
+ expected: {
16
+ 'Vendor_ModuleNameA/components/ComponentA': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/components/ComponentA.vue',
17
+ 'Vendor_ModuleNameA/components/ComponentB': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/components/ComponentB.vue',
18
+ 'Vendor_ModuleNameA/js/main': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/js/main.js',
19
+ 'Vendor_ModuleNameB/components/ComponentA': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/components/ComponentA.vue',
20
+ 'Vendor_ModuleNameB/components/ComponentB': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/components/ComponentB.vue',
21
+ 'Vendor_ModuleNameB/js/main': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/js/main.js',
22
+ 'Vendor_ModuleNameC/components/ComponentA': 'app/code/Vendor/ModuleNameC/view/frontend/web/components/ComponentA.vue',
23
+ 'Vendor_ModuleNameC/components/ComponentB': 'app/code/Vendor/ModuleNameC/view/frontend/web/components/ComponentB.vue',
24
+ 'Vendor_ModuleNameC/js/main': 'app/code/Vendor/ModuleNameC/view/frontend/web/js/main.js',
25
+ 'Theme/components/ComponentA': 'app/design/frontend/Vendor/theme-a/web/components/ComponentA.vue',
26
+ 'Theme/components/ComponentB': 'app/design/frontend/Vendor/theme-a/web/components/ComponentB.vue',
27
+ 'Theme/js/main': 'app/design/frontend/Vendor/theme-a/web/js/main.js'
28
+ }
29
+ },
30
+ {
31
+ code: 'Vendor/theme-b',
32
+ expected: {
33
+ 'Vendor_ModuleNameA/components/ComponentA': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/components/ComponentA.vue',
34
+ 'Vendor_ModuleNameA/components/ComponentB': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/components/ComponentB.vue',
35
+ 'Vendor_ModuleNameA/js/main': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/js/main.js',
36
+ 'Vendor_ModuleNameB/components/ComponentA': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/components/ComponentA.vue',
37
+ 'Vendor_ModuleNameB/components/ComponentB': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/components/ComponentB.vue',
38
+ 'Vendor_ModuleNameB/js/main': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/js/main.js',
39
+ 'Vendor_ModuleNameC/components/ComponentA': 'app/code/Vendor/ModuleNameC/view/frontend/web/components/ComponentA.vue',
40
+ 'Vendor_ModuleNameC/components/ComponentB': 'app/code/Vendor/ModuleNameC/view/frontend/web/components/ComponentB.vue',
41
+ 'Vendor_ModuleNameC/js/main': 'app/code/Vendor/ModuleNameC/view/frontend/web/js/main.js',
42
+ 'Theme/components/ComponentA': 'app/design/frontend/Vendor/theme-a/web/components/ComponentA.vue',
43
+ 'Theme/components/ComponentB': 'app/design/frontend/Vendor/theme-a/web/components/ComponentB.vue',
44
+ 'Theme/js/main': 'app/design/frontend/Vendor/theme-a/web/js/main.js'
45
+ }
46
+ },
47
+ {
48
+ code: 'Vendor/theme-c',
49
+ expected: {
50
+ 'Vendor_ModuleNameA/components/ComponentA': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/components/ComponentA.vue',
51
+ 'Vendor_ModuleNameA/components/ComponentB': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/components/ComponentB.vue',
52
+ 'Vendor_ModuleNameA/js/main': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/js/main.js',
53
+ 'Vendor_ModuleNameB/components/ComponentA': 'app/design/frontend/Vendor/theme-c/Vendor_ModuleNameB/web/components/ComponentA.vue',
54
+ 'Vendor_ModuleNameB/components/ComponentB': 'app/design/frontend/Vendor/theme-c/Vendor_ModuleNameB/web/components/ComponentB.vue',
55
+ 'Vendor_ModuleNameB/js/main': 'app/design/frontend/Vendor/theme-c/Vendor_ModuleNameB/web/js/main.js',
56
+ 'Vendor_ModuleNameC/components/ComponentA': 'app/code/Vendor/ModuleNameC/view/frontend/web/components/ComponentA.vue',
57
+ 'Vendor_ModuleNameC/components/ComponentB': 'app/code/Vendor/ModuleNameC/view/frontend/web/components/ComponentB.vue',
58
+ 'Vendor_ModuleNameC/js/main': 'app/code/Vendor/ModuleNameC/view/frontend/web/js/main.js',
59
+ 'Theme/components/ComponentA': 'app/design/frontend/Vendor/theme-a/web/components/ComponentA.vue',
60
+ 'Theme/components/ComponentB': 'app/design/frontend/Vendor/theme-a/web/components/ComponentB.vue',
61
+ 'Theme/js/main': 'app/design/frontend/Vendor/theme-a/web/js/main.js'
62
+ }
63
+ },
64
+ {
65
+ code: 'Vendor/theme-d',
66
+ expected: {
67
+ 'Vendor_ModuleNameA/components/ComponentA': 'app/code/Vendor/ModuleNameA/view/frontend/web/components/ComponentA.vue',
68
+ 'Vendor_ModuleNameA/components/ComponentB': 'app/code/Vendor/ModuleNameA/view/frontend/web/components/ComponentB.vue',
69
+ 'Vendor_ModuleNameA/js/main': 'app/code/Vendor/ModuleNameA/view/frontend/web/js/main.js',
70
+ 'Vendor_ModuleNameB/components/ComponentA': 'app/code/Vendor/ModuleNameB/view/frontend/web/components/ComponentA.vue',
71
+ 'Vendor_ModuleNameB/components/ComponentB': 'app/code/Vendor/ModuleNameB/view/frontend/web/components/ComponentB.vue',
72
+ 'Vendor_ModuleNameB/js/main': 'app/code/Vendor/ModuleNameB/view/frontend/web/js/main.js',
73
+ 'Vendor_ModuleNameC/components/ComponentA': 'app/code/Vendor/ModuleNameC/view/frontend/web/components/ComponentA.vue',
74
+ 'Vendor_ModuleNameC/components/ComponentB': 'app/code/Vendor/ModuleNameC/view/frontend/web/components/ComponentB.vue',
75
+ 'Vendor_ModuleNameC/js/main': 'app/code/Vendor/ModuleNameC/view/frontend/web/js/main.js',
76
+ }
77
+ },
78
+ ]
79
+ },
80
+ {
81
+ scenario: 'b',
82
+ themes: [
83
+ {
84
+ code: 'Vendor/theme-a',
85
+ expected: {
86
+ 'Vendor_ModuleNameA/components/ComponentA': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/components/ComponentA.vue',
87
+ 'Vendor_ModuleNameA/components/ComponentB': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/components/ComponentB.vue',
88
+ 'Vendor_ModuleNameA/js/main': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/js/main.js',
89
+ 'Vendor_ModuleNameB/components/ComponentA': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/components/ComponentA.vue',
90
+ 'Vendor_ModuleNameB/components/ComponentB': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/components/ComponentB.vue',
91
+ 'Vendor_ModuleNameB/js/main': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/js/main.js',
92
+ 'Vendor_ModuleNameC/components/ComponentA': 'app/code/Vendor/ModuleNameC/view/frontend/web/components/ComponentA.vue',
93
+ 'Vendor_ModuleNameC/components/ComponentB': 'app/code/Vendor/ModuleNameC/view/frontend/web/components/ComponentB.vue',
94
+ 'Vendor_ModuleNameC/js/main': 'app/code/Vendor/ModuleNameC/view/frontend/web/js/main.js',
95
+ 'Theme/components/ComponentA': 'app/design/frontend/Vendor/theme-a/web/components/ComponentA.vue',
96
+ 'Theme/components/ComponentB': 'app/design/frontend/Vendor/theme-a/web/components/ComponentB.vue',
97
+ 'Theme/js/main': 'app/design/frontend/Vendor/theme-a/web/js/main.js',
98
+ 'Vendor_ModuleNameNoConfig/components/ComponentA': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameNoConfig/web/components/ComponentA.vue',
99
+ 'Vendor_ModuleNameNoConfig/components/ComponentB': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameNoConfig/web/components/ComponentB.vue',
100
+ 'Vendor_ModuleNameNoConfig/js/main': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameNoConfig/web/js/main.js',
101
+ }
102
+ },
103
+ {
104
+ code: 'Vendor/theme-b',
105
+ expected: {
106
+ 'Vendor_ModuleNameA/components/ComponentA': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/components/ComponentA.vue',
107
+ 'Vendor_ModuleNameA/components/ComponentB': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/components/ComponentB.vue',
108
+ 'Vendor_ModuleNameA/js/main': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/js/main.js',
109
+ 'Vendor_ModuleNameB/components/ComponentA': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/components/ComponentA.vue',
110
+ 'Vendor_ModuleNameB/components/ComponentB': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/components/ComponentB.vue',
111
+ 'Vendor_ModuleNameB/js/main': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/js/main.js',
112
+ 'Vendor_ModuleNameC/components/ComponentA': 'app/code/Vendor/ModuleNameC/view/frontend/web/components/ComponentA.vue',
113
+ 'Vendor_ModuleNameC/components/ComponentB': 'app/code/Vendor/ModuleNameC/view/frontend/web/components/ComponentB.vue',
114
+ 'Vendor_ModuleNameC/js/main': 'app/code/Vendor/ModuleNameC/view/frontend/web/js/main.js',
115
+ 'Theme/components/ComponentA': 'app/design/frontend/Vendor/theme-a/web/components/ComponentA.vue',
116
+ 'Theme/components/ComponentB': 'app/design/frontend/Vendor/theme-a/web/components/ComponentB.vue',
117
+ 'Theme/js/main': 'app/design/frontend/Vendor/theme-a/web/js/main.js',
118
+ 'Vendor_ModuleNameNoConfig/components/ComponentA': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameNoConfig/web/components/ComponentA.vue',
119
+ 'Vendor_ModuleNameNoConfig/components/ComponentB': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameNoConfig/web/components/ComponentB.vue',
120
+ 'Vendor_ModuleNameNoConfig/js/main': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameNoConfig/web/js/main.js',
121
+ }
122
+ },
123
+ {
124
+ code: 'Vendor/theme-c',
125
+ expected: {
126
+ 'Vendor_ModuleNameA/components/ComponentA': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/components/ComponentA.vue',
127
+ 'Vendor_ModuleNameA/components/ComponentB': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/components/ComponentB.vue',
128
+ 'Vendor_ModuleNameA/js/main': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/js/main.js',
129
+ 'Vendor_ModuleNameB/components/ComponentA': 'app/design/frontend/Vendor/theme-c/Vendor_ModuleNameB/web/components/ComponentA.vue',
130
+ 'Vendor_ModuleNameB/components/ComponentB': 'app/design/frontend/Vendor/theme-c/Vendor_ModuleNameB/web/components/ComponentB.vue',
131
+ 'Vendor_ModuleNameB/js/main': 'app/design/frontend/Vendor/theme-c/Vendor_ModuleNameB/web/js/main.js',
132
+ 'Vendor_ModuleNameC/components/ComponentA': 'app/code/Vendor/ModuleNameC/view/frontend/web/components/ComponentA.vue',
133
+ 'Vendor_ModuleNameC/components/ComponentB': 'app/code/Vendor/ModuleNameC/view/frontend/web/components/ComponentB.vue',
134
+ 'Vendor_ModuleNameC/js/main': 'app/code/Vendor/ModuleNameC/view/frontend/web/js/main.js',
135
+ 'Theme/components/ComponentA': 'app/design/frontend/Vendor/theme-a/web/components/ComponentA.vue',
136
+ 'Theme/components/ComponentB': 'app/design/frontend/Vendor/theme-a/web/components/ComponentB.vue',
137
+ 'Theme/js/main': 'app/design/frontend/Vendor/theme-a/web/js/main.js',
138
+ 'Vendor_ModuleNameNoConfig/components/ComponentA': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameNoConfig/web/components/ComponentA.vue',
139
+ 'Vendor_ModuleNameNoConfig/components/ComponentB': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameNoConfig/web/components/ComponentB.vue',
140
+ 'Vendor_ModuleNameNoConfig/js/main': 'app/design/frontend/Vendor/theme-a/Vendor_ModuleNameNoConfig/web/js/main.js',
141
+ }
142
+ },
143
+ {
144
+ code: 'Vendor/theme-d',
145
+ expected: {
146
+ 'Vendor_ModuleNameA/components/ComponentA': 'app/code/Vendor/ModuleNameA/view/frontend/web/components/ComponentA.vue',
147
+ 'Vendor_ModuleNameA/components/ComponentB': 'app/code/Vendor/ModuleNameA/view/frontend/web/components/ComponentB.vue',
148
+ 'Vendor_ModuleNameA/js/main': 'app/code/Vendor/ModuleNameA/view/frontend/web/js/main.js',
149
+ 'Vendor_ModuleNameC/components/ComponentA': 'app/code/Vendor/ModuleNameC/view/frontend/web/components/ComponentA.vue',
150
+ 'Vendor_ModuleNameC/components/ComponentB': 'app/code/Vendor/ModuleNameC/view/frontend/web/components/ComponentB.vue',
151
+ 'Vendor_ModuleNameC/js/main': 'app/code/Vendor/ModuleNameC/view/frontend/web/js/main.js',
152
+ }
153
+ },
154
+ ]
155
+ },
156
+ ];
157
+
158
+ for (const scenario of scenarios) {
159
+ for (const key in scenario.themes) {
160
+ let themes = scenario.themes[key];
161
+ for (const key in themes.expected) {
162
+ let expected = themes.expected[key];
163
+ themes.expected[key] = path.resolve(MAGENTO_SCENARIOS_PATH, expected);
164
+ }
165
+ }
166
+ }
167
+
168
+ describe('getAllJsVueFilesWithInheritance', () => {
169
+ let moduleResolver;
170
+
171
+ beforeEach(async () => {
172
+ jest.resetModules()
173
+ });
174
+
175
+ test.each(scenarios.flatMap(({ scenario, themes }) =>
176
+ themes.map(({ code, expected }) => ([ scenario, code, expected ]))
177
+ ))('Scenario "%s", Theme "%s"', async (scenario, code, expected) => {
178
+ jest.unstable_mockModule(
179
+ '#service/configResolver.cjs',
180
+ () => createMockConfigResolver(scenario)
181
+ );
182
+ moduleResolver = await import('#service/moduleResolver.js');
183
+ moduleResolver = moduleResolver.default;
184
+
185
+ const result = await moduleResolver.getAllJsVueFilesWithInheritance(code);
186
+
187
+ // Mensaje personalizado para errores
188
+ expect(result).toEqual(expected, `Failed for scenario "${scenario}", theme "${code}"`);
189
+ });
190
+
191
+
192
+ });
@@ -0,0 +1,187 @@
1
+ import { jest } from '@jest/globals';
2
+ import createMockConfigResolver from '../__mocks__/configResolver.js';
3
+ import path from 'path';
4
+ import {fileURLToPath} from 'url';
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = path.dirname(__filename);
7
+
8
+ let scenarios = [
9
+ {
10
+ scenario: 'a',
11
+ themes: [
12
+ {
13
+ code: 'Vendor/theme-a',
14
+ expected: {
15
+ tailwind: {
16
+ content: [
17
+ 'magento_scenarios/app/code/Vendor/ModuleNameA/templates/**/*.phtml',
18
+ 'magento_scenarios/app/code/Vendor/ModuleNameA/web/from_theme',
19
+ 'magento_scenarios/app/code/Vendor/ModuleNameB/templates/**/*.phtml',
20
+ 'magento_scenarios/app/code/Vendor/ModuleNameC/templates/**/*.phtml'
21
+ ]
22
+ }
23
+ }
24
+ },
25
+ {
26
+ code: 'Vendor/theme-b',
27
+ expected: {
28
+ tailwind: {
29
+ content: [
30
+ 'magento_scenarios/app/code/Vendor/ModuleNameA/templates/**/*.phtml',
31
+ 'magento_scenarios/app/code/Vendor/ModuleNameA/web/from_theme',
32
+ 'magento_scenarios/app/code/Vendor/ModuleNameB/templates/**/*.phtml',
33
+ 'magento_scenarios/app/code/Vendor/ModuleNameC/templates/**/*.phtml'
34
+ ]
35
+ }
36
+ }
37
+ },
38
+ {
39
+ code: 'Vendor/theme-c',
40
+ expected: {
41
+ tailwind: {}
42
+ }
43
+ },
44
+ {
45
+ code: 'Vendor/theme-d',
46
+ expected: {
47
+ tailwind: {
48
+ theme: { extend: {} },
49
+ plugins: [],
50
+ content: [
51
+ 'magento_scenarios/app/code/Vendor/ModuleNameA/templates/**/*.phtml',
52
+ 'magento_scenarios/app/code/Vendor/ModuleNameB/templates/**/*.phtml'
53
+ ]
54
+ }
55
+ }
56
+ }
57
+ ]
58
+ }
59
+ ];
60
+
61
+ for (const scenario of scenarios) {
62
+ for (const themeKey in scenario.themes) {
63
+ let theme = scenario.themes[themeKey];
64
+ const expected = theme.expected;
65
+ expected.tailwind.content = expected.tailwind.content?.map((content) => path.resolve(__dirname, '..', content));
66
+ }
67
+ }
68
+
69
+
70
+ let scenariosForResolveFileByTheme = [
71
+ {
72
+ scenario: 'a',
73
+ themes: [
74
+ {
75
+ code: 'Vendor/theme-a',
76
+ moduleName: 'Vendor_ModuleNameA',
77
+ filePath: 'module.config.cjs',
78
+ includeTailwindConfigFromParentThemes: true,
79
+ expected: 'magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/module.config.cjs'
80
+ },
81
+ {
82
+ code: 'Vendor/theme-a',
83
+ moduleName: 'Vendor_ModuleNameA',
84
+ filePath: 'no_exist_file.cjs',
85
+ includeTailwindConfigFromParentThemes: true,
86
+ expected: null
87
+ },
88
+ {
89
+ code: 'Vendor/theme-b',
90
+ moduleName: 'Vendor_ModuleNameA',
91
+ filePath: 'module.config.cjs',
92
+ includeTailwindConfigFromParentThemes: true,
93
+ expected: 'magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/module.config.cjs'
94
+ },
95
+ {
96
+ code: 'Vendor/theme-b',
97
+ moduleName: 'Vendor_ModuleNameA',
98
+ filePath: 'module.config.cjs',
99
+ includeTailwindConfigFromParentThemes: false,
100
+ expected: null
101
+ },
102
+ {
103
+ code: 'Vendor/theme-c',
104
+ moduleName: 'Vendor_ModuleNameA',
105
+ filePath: 'module.config.cjs',
106
+ includeTailwindConfigFromParentThemes: true,
107
+ expected: 'magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/module.config.cjs'
108
+ },
109
+ {
110
+ code: 'Vendor/theme-c',
111
+ moduleName: 'Vendor_ModuleNameB',
112
+ filePath: 'module.config.cjs',
113
+ includeTailwindConfigFromParentThemes: true,
114
+ expected: 'magento_scenarios/app/design/frontend/Vendor/theme-c/Vendor_ModuleNameB/web/module.config.cjs'
115
+ },
116
+ {
117
+ code: 'Vendor/theme-d',
118
+ moduleName: 'Vendor_ModuleNameA',
119
+ filePath: 'module.config.cjs',
120
+ includeTailwindConfigFromParentThemes: false,
121
+ expected: null
122
+ },
123
+ {
124
+ code: 'Vendor/theme-d',
125
+ moduleName: 'Vendor_ModuleNameA',
126
+ filePath: 'module.config.cjs',
127
+ includeTailwindConfigFromParentThemes: true,
128
+ expected: null
129
+ }
130
+ ]
131
+ }
132
+ ];
133
+
134
+ for (const scenario of scenariosForResolveFileByTheme) {
135
+ for (const themeKey in scenario.themes) {
136
+ let theme = scenario.themes[themeKey];
137
+ if (!theme.expected) continue;
138
+ theme.expected = path.resolve(__dirname, '..', theme.expected)
139
+ }
140
+ }
141
+
142
+ async function setupResolvers(scenario) {
143
+ jest.mock(
144
+ '#service/configResolver.cjs',
145
+ () => createMockConfigResolver(scenario).default
146
+ );
147
+ let moduleResolver = await import('#service/moduleResolverSync.cjs');
148
+ let themeResolver = await import('#service/themeResolverSync.cjs');
149
+
150
+ return { themeResolver, moduleResolver };
151
+ }
152
+
153
+ describe('getModuleConfigByThemeConfig', () => {
154
+ beforeEach(() => {
155
+ jest.resetModules();
156
+ });
157
+
158
+ test.each(scenarios.flatMap(({ scenario, themes }) =>
159
+ themes.map(({ code, expected }) => ([ scenario, code, expected ]))
160
+ ))('Scenario "%s", Theme "%s"', async ( scenario, code, expected ) => {
161
+ const { themeResolver, moduleResolver } = await setupResolvers(scenario);
162
+ const themeConfig = await themeResolver.getThemeConfig(code);
163
+ const result = await moduleResolver.getModuleConfigByThemeConfig(code, themeConfig);
164
+ expect(result).toEqual(
165
+ expected,
166
+ `Expected:\n${JSON.stringify(expected, null, 2)}\nReceived:\n${JSON.stringify(result, null, 2)}\nScenario: "${scenario}", Theme: "${code}"`
167
+ );
168
+ });
169
+ });
170
+
171
+ describe('resolveFileByTheme', () => {
172
+ beforeEach(() => {
173
+ jest.resetModules();
174
+ });
175
+
176
+ test.each(scenariosForResolveFileByTheme.flatMap(({ scenario, themes }) =>
177
+ themes.map(({ code, expected, moduleName, filePath, includeTailwindConfigFromParentThemes }) => ([scenario, code, expected, moduleName, filePath, includeTailwindConfigFromParentThemes]))
178
+ ))('Scenario "%s", Theme "%s"', async ( scenario, code, expected, moduleName, filePath, includeTailwindConfigFromParentThemes ) => {
179
+ const { moduleResolver } = await setupResolvers(scenario);
180
+ const result = await moduleResolver.resolveFileByTheme(code, moduleName, filePath, includeTailwindConfigFromParentThemes);
181
+ expect(result).toEqual(
182
+ expected,
183
+ `Expected:\n${JSON.stringify(expected, null, 2)}\nReceived:\n${JSON.stringify(result, null, 2)}\nScenario: "${scenario}", Theme: "${code}"`
184
+ );
185
+ });
186
+ });
187
+
@@ -0,0 +1,164 @@
1
+ import { jest } from '@jest/globals';
2
+ import createMockConfigResolver from '../__mocks__/configResolver.js';
3
+ import path from 'path';
4
+ import {fileURLToPath} from 'url';
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = path.dirname(__filename);
7
+
8
+ let scenarios = [
9
+ {
10
+ scenario: 'a',
11
+ themes: [
12
+ {
13
+ code: 'Vendor/theme-a',
14
+ expected: {
15
+ tailwind: {
16
+ theme: { extend: {} },
17
+ plugins: [],
18
+ content: [
19
+ 'magento_scenarios/app/design/frontend/Vendor/theme-a/web/**/*.{vue,js}',
20
+ 'magento_scenarios/app/design/frontend/Vendor/theme-a/**/*.phtml',
21
+ 'magento_scenarios/app/design/frontend/Vendor/theme-a/*/page_layout/override/base/*.xml'
22
+ ]
23
+ },
24
+ includeTailwindConfigFromParentThemes: true,
25
+ includeCssSourceFromParentThemes: true,
26
+ ignoredCssFromModules: [
27
+ 'Vendor_ModuleNameA'
28
+ ],
29
+ ignoredTailwindConfigFromModules: [],
30
+ exposeNpmPackages: []
31
+ }
32
+ },
33
+ {
34
+ code: 'Vendor/theme-b',
35
+ expected: {
36
+ tailwind: {
37
+ theme: {
38
+ extend: {
39
+ textColor: {
40
+ 'primary': '#3490dc',
41
+ 'secondary': '#ffed4a',
42
+ 'danger': '#e3342f',
43
+ },
44
+ }
45
+ },
46
+ plugins: [],
47
+ content: [
48
+ 'magento_scenarios/app/design/frontend/Vendor/theme-a/web/**/*.{vue,js}',
49
+ 'magento_scenarios/app/design/frontend/Vendor/theme-a/**/*.phtml',
50
+ 'magento_scenarios/app/design/frontend/Vendor/theme-a/*/page_layout/override/base/*.xml',
51
+ 'magento_scenarios/app/design/frontend/Vendor/theme-b/web/**/*.{vue,js}',
52
+ 'magento_scenarios/app/design/frontend/Vendor/theme-b/**/*.phtml',
53
+ 'magento_scenarios/app/design/frontend/Vendor/theme-b/*/page_layout/override/base/*.xml'
54
+ ]
55
+ },
56
+ includeTailwindConfigFromParentThemes: true,
57
+ includeCssSourceFromParentThemes: true,
58
+ ignoredCssFromModules: [
59
+ 'Vendor_ModuleNameA',
60
+ 'Vendor_ModuleNameNoConfig'
61
+ ],
62
+ ignoredTailwindConfigFromModules: [],
63
+ exposeNpmPackages: []
64
+ }
65
+ },
66
+ {
67
+ code: 'Vendor/theme-c',
68
+ expected: {
69
+ tailwind: {
70
+ theme: { extend: {} },
71
+ plugins: [],
72
+ content: [
73
+ 'magento_scenarios/app/design/frontend/Vendor/theme-c/web/**/*.{vue,js}',
74
+ 'magento_scenarios/app/design/frontend/Vendor/theme-c/**/*.phtml',
75
+ 'magento_scenarios/app/design/frontend/Vendor/theme-c/*/page_layout/override/base/*.xml'
76
+ ]
77
+ },
78
+ includeTailwindConfigFromParentThemes: false,
79
+ includeCssSourceFromParentThemes: true,
80
+ ignoredCssFromModules: [],
81
+ ignoredTailwindConfigFromModules: 'all',
82
+ exposeNpmPackages: []
83
+ }
84
+ },
85
+ {
86
+ code: 'Vendor/theme-d',
87
+ expected: {
88
+ tailwind: {
89
+ theme: { extend: {} },
90
+ plugins: [],
91
+ content: []
92
+ },
93
+ includeTailwindConfigFromParentThemes: true,
94
+ includeCssSourceFromParentThemes: false,
95
+ ignoredCssFromModules: [],
96
+ ignoredTailwindConfigFromModules: [
97
+ 'Vendor_ModuleNameC'
98
+ ],
99
+ exposeNpmPackages: []
100
+ }
101
+ }
102
+ ]
103
+ }
104
+ ];
105
+
106
+ for (const scenario of scenarios) {
107
+ for (const themeKey in scenario.themes) {
108
+ let theme = scenario.themes[themeKey];
109
+ const expected = theme.expected;
110
+ expected.tailwind.content = expected.tailwind.content?.map((content) => path.resolve(__dirname, '..', content));
111
+ }
112
+ }
113
+
114
+ async function setupThemeResolver(scenario) {
115
+ jest.mock(
116
+ '#service/configResolver.cjs',
117
+ () => createMockConfigResolver(scenario).default
118
+ );
119
+ let resolver = await import('#service/themeResolverSync.cjs');
120
+ return resolver.default;
121
+ }
122
+
123
+ describe('getThemeConfig', () => {
124
+ let themeResolver;
125
+
126
+ beforeEach(() => {
127
+ jest.resetModules();
128
+ });
129
+
130
+ test.each(scenarios.flatMap(({ scenario, themes }) =>
131
+ themes.map(({ code, expected }) => ([ scenario, code, expected ]))
132
+ ))('Scenario "%s", Theme "%s"', async ( scenario, code, expected ) => {
133
+ themeResolver = await setupThemeResolver(scenario);
134
+
135
+ const result = await themeResolver.getThemeConfig(code);
136
+
137
+ expect(result).toEqual(
138
+ expected,
139
+ `Expected:\n${JSON.stringify(expected, null, 2)}\nReceived:\n${JSON.stringify(result, null, 2)}\nScenario: "${scenario}", Theme: "${code}"`
140
+ );
141
+ });
142
+ });
143
+
144
+ describe('getTailwindThemeConfig', () => {
145
+ let themeResolver;
146
+
147
+ beforeEach(() => {
148
+ jest.resetModules();
149
+ });
150
+
151
+ test.each(scenarios.flatMap(({ scenario, themes }) =>
152
+ themes.map(({ code, expected }) => ([ scenario, code, expected ]))
153
+ ))('Scenario "%s", Theme "%s"', async ( scenario, code, expected ) => {
154
+ themeResolver = await setupThemeResolver(scenario);
155
+
156
+ const result = await themeResolver.getTailwindThemeConfig(code);
157
+
158
+ expect(result).toMatchObject(
159
+ expected.tailwind,
160
+ `Expected:\n${JSON.stringify(expected.tailwind, null, 2)}\nReceived:\n${JSON.stringify(result, null, 2)}\nScenario: "${scenario}", Theme: "${code}"`
161
+ );
162
+ });
163
+ });
164
+
@@ -0,0 +1,41 @@
1
+ const path = require('path');
2
+ const { fileURLToPath } = require('url');
3
+
4
+ const BASE_PATH = process.cwd();
5
+
6
+ const DEPENDENCY_CONFIG_FILENAME = 'mage_obsidian_frontend_modules.json';
7
+ const MAGENTO_CONFIG_RELATIVE_PATH = 'app/etc/';
8
+ const DEPENDENCY_CONFIG_FILE_PATH = path.resolve(
9
+ BASE_PATH,
10
+ '..',
11
+ MAGENTO_CONFIG_RELATIVE_PATH,
12
+ DEPENDENCY_CONFIG_FILENAME
13
+ );
14
+
15
+ const MODULE_WEB_PATH = 'view/frontend/web/';
16
+ const THEME_MODULE_WEB_PATH = 'web/';
17
+ const MODULE_CSS_FOLDER = 'css';
18
+
19
+ const THEME_CSS_FOLDER = 'css';
20
+
21
+ const OUTPUT_THEME_DIR = 'web/generated';
22
+ const OUTPUT_JS_DIR = 'js/';
23
+ const OUTPUT_CSS_DIR = 'css/';
24
+ const PRECOMPILED_FOLDER = '.precompiled';
25
+
26
+ const ALL_JS_VUE_FILES_WITH_INHERITANCE_FILE_NAME = 'allJsVueFilesWithInheritance.json';
27
+
28
+ module.exports = {
29
+ DEPENDENCY_CONFIG_FILENAME,
30
+ MAGENTO_CONFIG_RELATIVE_PATH,
31
+ DEPENDENCY_CONFIG_FILE_PATH,
32
+ MODULE_WEB_PATH,
33
+ THEME_MODULE_WEB_PATH,
34
+ MODULE_CSS_FOLDER,
35
+ THEME_CSS_FOLDER,
36
+ OUTPUT_THEME_DIR,
37
+ OUTPUT_JS_DIR,
38
+ OUTPUT_CSS_DIR,
39
+ PRECOMPILED_FOLDER,
40
+ ALL_JS_VUE_FILES_WITH_INHERITANCE_FILE_NAME,
41
+ };