mage-obsidian 1.1.2 → 2.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.
- package/.github/workflows/ci.yml +38 -0
- package/.github/workflows/publish.yml +26 -25
- package/.oxlintrc.json +19 -0
- package/.prettierignore +7 -0
- package/.prettierrc.json +7 -0
- package/LICENSE +1 -1
- package/README.md +1 -0
- package/eslint.config.js +24 -0
- package/package.json +39 -13
- package/pnpm-workspace.yaml +4 -0
- package/src/cli/buildThemes.ts +263 -0
- package/src/config/default.ts +31 -0
- package/src/config/eslint.js +60 -0
- package/src/core/configResolver.ts +141 -0
- package/src/core/contractValidator.ts +56 -0
- package/src/core/cssResolver.ts +153 -0
- package/src/{service/generateInterceptors.js → core/generateInterceptors.ts} +79 -46
- package/src/core/generateJsconfig.ts +168 -0
- package/src/{service/moduleResolver.js → core/moduleResolver.ts} +79 -46
- package/src/core/preCompileFiles.ts +105 -0
- package/src/core/preCompileMagentoFiles.ts +34 -0
- package/src/core/themeResolverSync.ts +66 -0
- package/src/runtime/i18nCore.ts +113 -0
- package/src/runtime/interceptorManager.ts +186 -0
- package/src/runtime/islands.ts +84 -0
- package/src/runtime/sectionStoreCore.ts +259 -0
- package/src/utils/{findComponents.js → findComponents.ts} +29 -16
- package/src/utils/runWithConcurrency.ts +35 -0
- package/src/vite/defaultNodeResolver.ts +17 -0
- package/src/{service/inheritAssetsModuleResolver.js → vite/inheritAssetsModuleResolver.ts} +15 -11
- package/src/{service/inheritModuleResolver.js → vite/inheritModuleResolver.ts} +6 -10
- package/src/{service/interceptorsPlugin.js → vite/interceptorsPlugin.ts} +25 -19
- package/src/vite/magentoHrmRewrite.ts +44 -0
- package/src/vite/sharedPlugins.ts +54 -0
- package/src/vite/themeSourceWatcher.ts +96 -0
- package/src/vite/unresolvedModuleGuard.ts +87 -0
- package/tsconfig.json +34 -0
- package/vitest.config.js +18 -0
- package/jest.config.js +0 -5
- package/src/__tests__/__mocks__/configResolver.js +0 -35
- package/src/__tests__/fixtures/interceptors/emptyTarget.js +0 -2
- package/src/__tests__/fixtures/interceptors/pluginForNonFunction.js +0 -7
- package/src/__tests__/fixtures/interceptors/pluginModule.js +0 -13
- package/src/__tests__/fixtures/interceptors/targetModule.js +0 -12
- package/src/__tests__/fixtures/interceptors/targetNonFunction.js +0 -7
- package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameA/view/frontend/web/components/ComponentA.vue +0 -0
- package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameA/view/frontend/web/components/ComponentB.vue +0 -0
- package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameA/view/frontend/web/css/module.extend.css +0 -0
- package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameA/view/frontend/web/js/main.js +0 -0
- package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameA/view/frontend/web/main.js +0 -0
- package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameA/view/frontend/web/module.config.js +0 -9
- package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameB/view/frontend/web/components/ComponentA.vue +0 -0
- package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameB/view/frontend/web/components/ComponentB.vue +0 -0
- package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameB/view/frontend/web/css/module.extend.css +0 -2
- package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameB/view/frontend/web/js/main.js +0 -0
- package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameB/view/frontend/web/module.config.js +0 -7
- package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameC/view/frontend/web/components/ComponentA.vue +0 -0
- package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameC/view/frontend/web/components/ComponentB.vue +0 -0
- package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameC/view/frontend/web/css/module.extend.css +0 -2
- package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameC/view/frontend/web/js/main.js +0 -0
- package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameC/view/frontend/web/module.config.js +0 -7
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/components/ComponentA.vue +0 -0
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/components/ComponentB.vue +0 -0
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/css/module.extend.css +0 -0
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/js/main.js +0 -0
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameA/web/module.config.js +0 -2
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/components/ComponentA.vue +0 -0
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/components/ComponentB.vue +0 -0
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/css/module.extend.css +0 -0
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/js/main.js +0 -0
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameB/web/module.config.js +0 -2
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameNoConfig/web/components/ComponentA.vue +0 -0
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameNoConfig/web/components/ComponentB.vue +0 -0
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameNoConfig/web/css/module.extend.css +0 -0
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameNoConfig/web/js/main.js +0 -0
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/Vendor_ModuleNameNoConfig/web/module.config.js +0 -2
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/web/components/ComponentA.vue +0 -0
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/web/components/ComponentB.vue +0 -0
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/web/css/theme.source.css +0 -6
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/web/js/main.js +0 -0
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-a/web/theme.config.js +0 -5
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-b/web/css/theme.source.css +0 -6
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-b/web/theme.config.js +0 -5
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-c/Vendor_ModuleNameB/web/components/ComponentA.vue +0 -0
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-c/Vendor_ModuleNameB/web/components/ComponentB.vue +0 -0
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-c/Vendor_ModuleNameB/web/css/module.extend.css +0 -0
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-c/Vendor_ModuleNameB/web/js/main.js +0 -0
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-c/Vendor_ModuleNameB/web/module.config.js +0 -2
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-c/web/css/theme.source.css +0 -6
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-c/web/theme.config.js +0 -2
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-d/web/css/theme.source.css +0 -6
- package/src/__tests__/magento_scenarios/app/design/frontend/Vendor/theme-d/web/theme.config.js +0 -3
- package/src/__tests__/magento_scenarios/app/etc/mage_obsidian_frontend_modules_a.json +0 -53
- package/src/__tests__/magento_scenarios/app/etc/mage_obsidian_frontend_modules_b.json +0 -50
- package/src/__tests__/service/generateInterceptors.test.js +0 -196
- package/src/__tests__/service/inheritModuleResolver.test.js +0 -61
- package/src/__tests__/service/interceptorManager_magento_behavior.test.js +0 -137
- package/src/__tests__/service/moduleResolver.test.js +0 -194
- package/src/__tests__/service/themeResolverSync.test.js +0 -97
- package/src/__tests__/vite-plugins/interceptorsPlugin.test.js +0 -121
- package/src/config/default.js +0 -27
- package/src/scripts/buildThemes.js +0 -132
- package/src/service/configResolver.js +0 -63
- package/src/service/cssResolver.js +0 -73
- package/src/service/defaultNodeResolver.js +0 -16
- package/src/service/interceptorManager.js +0 -137
- package/src/service/magentoHrmRewrite.js +0 -43
- package/src/service/preCompileFiles.js +0 -37
- package/src/service/preCompileMagentoFiles.js +0 -16
- package/src/service/setupGlobals.js +0 -19
- package/src/service/themeResolverSync.js +0 -67
package/jest.config.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import path from "path";
|
|
2
|
-
import fs from "fs";
|
|
3
|
-
import { jest } from '@jest/globals';
|
|
4
|
-
import { fileURLToPath } from 'url';
|
|
5
|
-
|
|
6
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
-
const __dirname = path.dirname(__filename);
|
|
8
|
-
|
|
9
|
-
const createMockConfigResolver = (scenario) => {
|
|
10
|
-
const configPath = path.resolve(__dirname, `../magento_scenarios/app/etc/mage_obsidian_frontend_modules_${scenario}.json`);
|
|
11
|
-
const magentoConfigJson = fs.readFileSync(configPath, 'utf-8');
|
|
12
|
-
const mockMagentoConfig = JSON.parse(magentoConfigJson);
|
|
13
|
-
for (const key in mockMagentoConfig.modules) {
|
|
14
|
-
let module = mockMagentoConfig.modules[key];
|
|
15
|
-
module.src = path.resolve(__dirname, '..', module.src);
|
|
16
|
-
}
|
|
17
|
-
for (const key in mockMagentoConfig.themes) {
|
|
18
|
-
let theme = mockMagentoConfig.themes[key];
|
|
19
|
-
theme.src = path.resolve(__dirname, '..', theme.src);
|
|
20
|
-
}
|
|
21
|
-
return {
|
|
22
|
-
default: {
|
|
23
|
-
getMagentoConfig: jest.fn(() => mockMagentoConfig),
|
|
24
|
-
getModulesConfigArray: jest.fn(() => Object.entries(mockMagentoConfig.modules)),
|
|
25
|
-
getThemesConfigArray: jest.fn(() => Object.entries(mockMagentoConfig.themes)),
|
|
26
|
-
getAllMagentoModulesEnabled: jest.fn(() => mockMagentoConfig.allModules),
|
|
27
|
-
isDev: jest.fn(() => mockMagentoConfig.mode === 'development'),
|
|
28
|
-
getOutputDirFromTheme: jest.fn((themePath) => `${themePath}/output`),
|
|
29
|
-
getThemeDefinition: jest.fn((themeName) => mockMagentoConfig.themes[themeName]),
|
|
30
|
-
getModuleDefinition: jest.fn((moduleName) => mockMagentoConfig.modules[moduleName]),
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
export default createMockConfigResolver;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameA/view/frontend/web/js/main.js
DELETED
|
File without changes
|
package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameA/view/frontend/web/main.js
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameB/view/frontend/web/js/main.js
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/src/__tests__/magento_scenarios/app/code/Vendor/ModuleNameC/view/frontend/web/js/main.js
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"modules": {
|
|
3
|
-
"Vendor_ModuleNameA": {
|
|
4
|
-
"src": "magento_scenarios\/app\/code\/Vendor\/ModuleNameA"
|
|
5
|
-
},
|
|
6
|
-
"Vendor_ModuleNameB": {
|
|
7
|
-
"src": "magento_scenarios\/app\/code\/Vendor\/ModuleNameB"
|
|
8
|
-
},
|
|
9
|
-
"Vendor_ModuleNameC": {
|
|
10
|
-
"src": "magento_scenarios\/app\/code\/Vendor\/ModuleNameC"
|
|
11
|
-
}
|
|
12
|
-
},
|
|
13
|
-
"themes": {
|
|
14
|
-
"Vendor\/theme-a": {
|
|
15
|
-
"src": "magento_scenarios\/app\/design\/frontend\/Vendor\/theme-a",
|
|
16
|
-
"parent": null
|
|
17
|
-
},
|
|
18
|
-
"Vendor\/theme-b": {
|
|
19
|
-
"src": "magento_scenarios\/app\/design\/frontend\/Vendor\/theme-b",
|
|
20
|
-
"parent": "Vendor\/theme-a"
|
|
21
|
-
},
|
|
22
|
-
"Vendor\/theme-c": {
|
|
23
|
-
"src": "magento_scenarios\/app\/design\/frontend\/Vendor\/theme-c",
|
|
24
|
-
"parent": "Vendor\/theme-b"
|
|
25
|
-
},
|
|
26
|
-
"Vendor\/theme-d": {
|
|
27
|
-
"src": "magento_scenarios\/app\/design\/frontend\/Vendor\/theme-d",
|
|
28
|
-
"parent": null
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
"allModules": [
|
|
32
|
-
"Vendor_ModuleNameA",
|
|
33
|
-
"Vendor_ModuleNameB",
|
|
34
|
-
"Vendor_ModuleNameC"
|
|
35
|
-
],
|
|
36
|
-
"VUE_COMPONENTS_PATH": "components",
|
|
37
|
-
"JS_PATH": "js",
|
|
38
|
-
"FOLDERS_TO_WATCH": [
|
|
39
|
-
"components",
|
|
40
|
-
"js"
|
|
41
|
-
],
|
|
42
|
-
"ALLOWED_EXTENSIONS": [
|
|
43
|
-
"js",
|
|
44
|
-
"vue",
|
|
45
|
-
"cjs",
|
|
46
|
-
"ts"
|
|
47
|
-
],
|
|
48
|
-
"MODULE_CSS_EXTEND_FILE": "module.extend.css",
|
|
49
|
-
"MODULE_CONFIG_FILE": "module.config.js",
|
|
50
|
-
"THEME_CONFIG_FILE": "theme.config.js",
|
|
51
|
-
"THEME_CSS_SOURCE_FILE": "theme.source.css",
|
|
52
|
-
"LIB_PATH": "lib"
|
|
53
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"modules": {
|
|
3
|
-
"Vendor_ModuleNameA": {
|
|
4
|
-
"src": "magento_scenarios\/app\/code\/Vendor\/ModuleNameA"
|
|
5
|
-
},
|
|
6
|
-
"Vendor_ModuleNameC": {
|
|
7
|
-
"src": "magento_scenarios\/app\/code\/Vendor\/ModuleNameC"
|
|
8
|
-
}
|
|
9
|
-
},
|
|
10
|
-
"themes": {
|
|
11
|
-
"Vendor\/theme-a": {
|
|
12
|
-
"src": "magento_scenarios\/app\/design\/frontend\/Vendor\/theme-a",
|
|
13
|
-
"parent": null
|
|
14
|
-
},
|
|
15
|
-
"Vendor\/theme-b": {
|
|
16
|
-
"src": "magento_scenarios\/app\/design\/frontend\/Vendor\/theme-b",
|
|
17
|
-
"parent": "Vendor\/theme-a"
|
|
18
|
-
},
|
|
19
|
-
"Vendor\/theme-c": {
|
|
20
|
-
"src": "magento_scenarios\/app\/design\/frontend\/Vendor\/theme-c",
|
|
21
|
-
"parent": "Vendor\/theme-b"
|
|
22
|
-
},
|
|
23
|
-
"Vendor\/theme-d": {
|
|
24
|
-
"src": "magento_scenarios\/app\/design\/frontend\/Vendor\/theme-d",
|
|
25
|
-
"parent": null
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
"allModules": [
|
|
29
|
-
"Vendor_ModuleNameA",
|
|
30
|
-
"Vendor_ModuleNameB",
|
|
31
|
-
"Vendor_ModuleNameNoConfig"
|
|
32
|
-
],
|
|
33
|
-
"VUE_COMPONENTS_PATH": "components",
|
|
34
|
-
"JS_PATH": "js",
|
|
35
|
-
"FOLDERS_TO_WATCH": [
|
|
36
|
-
"components",
|
|
37
|
-
"js"
|
|
38
|
-
],
|
|
39
|
-
"ALLOWED_EXTENSIONS": [
|
|
40
|
-
"js",
|
|
41
|
-
"vue",
|
|
42
|
-
"cjs",
|
|
43
|
-
"ts"
|
|
44
|
-
],
|
|
45
|
-
"MODULE_CSS_EXTEND_FILE": "module.extend.css",
|
|
46
|
-
"MODULE_CONFIG_FILE": "module.config.js",
|
|
47
|
-
"THEME_CONFIG_FILE": "theme.config.js",
|
|
48
|
-
"THEME_CSS_SOURCE_FILE": "theme.source.css",
|
|
49
|
-
"LIB_PATH": "lib"
|
|
50
|
-
}
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import { jest } from '@jest/globals';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import { fileURLToPath } from 'url';
|
|
5
|
-
|
|
6
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
-
const fixturesDir = path.resolve(__dirname, '../fixtures/interceptors');
|
|
8
|
-
const targetModulePath = path.join(fixturesDir, 'targetModule.js');
|
|
9
|
-
const pluginModulePath = path.join(fixturesDir, 'pluginModule.js');
|
|
10
|
-
const targetNonFunctionPath = path.join(fixturesDir, 'targetNonFunction.js');
|
|
11
|
-
const pluginForNonFunctionPath = path.join(fixturesDir, 'pluginForNonFunction.js');
|
|
12
|
-
|
|
13
|
-
describe('generateInterceptors', () => {
|
|
14
|
-
let generateInterceptorsService;
|
|
15
|
-
let themeResolverMock;
|
|
16
|
-
let moduleResolverMock;
|
|
17
|
-
let interceptorManager;
|
|
18
|
-
|
|
19
|
-
beforeEach(async () => {
|
|
20
|
-
jest.resetModules();
|
|
21
|
-
|
|
22
|
-
themeResolverMock = {
|
|
23
|
-
getThemeConfig: jest.fn(),
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
moduleResolverMock = {
|
|
27
|
-
getModuleConfigByThemeConfig: jest.fn(),
|
|
28
|
-
getAllJsVueFilesWithInheritanceCached: jest.fn(),
|
|
29
|
-
getAllJsVueFilesWithInheritance: jest.fn(),
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
jest.unstable_mockModule('../../service/themeResolverSync.js', () => ({
|
|
33
|
-
default: themeResolverMock
|
|
34
|
-
}));
|
|
35
|
-
|
|
36
|
-
jest.unstable_mockModule('../../service/moduleResolver.js', () => ({
|
|
37
|
-
default: moduleResolverMock
|
|
38
|
-
}));
|
|
39
|
-
|
|
40
|
-
jest.unstable_mockModule('../../service/configResolver.js', () => ({
|
|
41
|
-
default: {
|
|
42
|
-
resolveLibRealPath: jest.fn().mockReturnValue('/mocked/path/to/interceptorManager')
|
|
43
|
-
}
|
|
44
|
-
}));
|
|
45
|
-
|
|
46
|
-
// Import real interceptorManager to reset state
|
|
47
|
-
interceptorManager = (await import('../../service/interceptorManager.js')).default;
|
|
48
|
-
interceptorManager.interceptors = {};
|
|
49
|
-
|
|
50
|
-
generateInterceptorsService = (await import('../../service/generateInterceptors.js')).default;
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
test('should generate interceptors correctly', async () => {
|
|
54
|
-
const themeName = 'Vendor/theme-test';
|
|
55
|
-
|
|
56
|
-
themeResolverMock.getThemeConfig.mockReturnValue({
|
|
57
|
-
src: '/path/to/theme'
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
moduleResolverMock.getModuleConfigByThemeConfig.mockResolvedValue({
|
|
61
|
-
interceptors: {
|
|
62
|
-
'TestPlugin': {
|
|
63
|
-
name: 'TestPlugin',
|
|
64
|
-
target: 'Vendor_TargetModule::js/target.js',
|
|
65
|
-
interceptor: 'Vendor_PluginModule::js/plugin.js',
|
|
66
|
-
sortOrder: 10,
|
|
67
|
-
active: true
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
const allFilesMap = {
|
|
73
|
-
'Vendor_TargetModule/js/target': targetModulePath,
|
|
74
|
-
'Vendor_PluginModule/js/plugin': pluginModulePath
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
moduleResolverMock.getAllJsVueFilesWithInheritanceCached.mockReturnValue(allFilesMap);
|
|
78
|
-
|
|
79
|
-
const result = await generateInterceptorsService.generateInterceptors(themeName);
|
|
80
|
-
|
|
81
|
-
const targetIdentifier = 'Vendor_TargetModule::js/target.js';
|
|
82
|
-
// Use bracket access check to avoid Jest treating '.' as nested property
|
|
83
|
-
expect(result[targetIdentifier]).toBeDefined();
|
|
84
|
-
|
|
85
|
-
const interceptorData = result[targetIdentifier];
|
|
86
|
-
expect(interceptorData).toHaveProperty('proxy');
|
|
87
|
-
expect(interceptorData).toHaveProperty('source');
|
|
88
|
-
expect(interceptorData).toHaveProperty('targetPath', targetModulePath);
|
|
89
|
-
expect(interceptorData.interceptors).toHaveLength(1);
|
|
90
|
-
expect(interceptorData.interceptors[0].name).toBe('TestPlugin');
|
|
91
|
-
|
|
92
|
-
// Verify Source Code Generation
|
|
93
|
-
const source = interceptorData.source;
|
|
94
|
-
expect(source).toContain(`import * as originalModule from '/@fs${targetModulePath}?originalIntercepted';`);
|
|
95
|
-
expect(source).toContain(`import * as interceptor_0 from '/@fs${pluginModulePath}';`);
|
|
96
|
-
expect(source).toContain(`interceptorManager.addInterceptor('${targetIdentifier}::targetFunction', 'TestPlugin', 'before', interceptor_0.beforeTargetFunction, 10);`);
|
|
97
|
-
expect(source).toContain(`interceptorManager.addInterceptor('${targetIdentifier}::default', 'TestPlugin', 'before', interceptor_0.beforeDefault, 10);`);
|
|
98
|
-
expect(source).toContain(`export const targetFunction = proxy.targetFunction;`);
|
|
99
|
-
|
|
100
|
-
// Verify Proxy Behavior
|
|
101
|
-
const proxy = interceptorData.proxy;
|
|
102
|
-
const resultFunc = await proxy.targetFunction('test');
|
|
103
|
-
expect(resultFunc).toBe('Original: Modified: test');
|
|
104
|
-
|
|
105
|
-
const resultAnother = await proxy.anotherFunction();
|
|
106
|
-
expect(resultAnother).toBe('Another - Modified');
|
|
107
|
-
|
|
108
|
-
const resultDefault = await proxy.default();
|
|
109
|
-
expect(resultDefault).toBe('Default'); // The mock plugin returns ['Default Modified'] but the original function ignores args and returns 'Default'.
|
|
110
|
-
// Wait, before interceptor modifies arguments.
|
|
111
|
-
// targetModule.js: export default function defaultExport() { return 'Default'; }
|
|
112
|
-
// It doesn't take arguments, so modifying arguments won't change output unless we check arguments.
|
|
113
|
-
// But we just want to verify it was registered.
|
|
114
|
-
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
test('should handle missing target module gracefully', async () => {
|
|
118
|
-
themeResolverMock.getThemeConfig.mockReturnValue({});
|
|
119
|
-
moduleResolverMock.getModuleConfigByThemeConfig.mockResolvedValue({
|
|
120
|
-
'Vendor_TargetModule': { interceptors: [] }
|
|
121
|
-
});
|
|
122
|
-
moduleResolverMock.getAllJsVueFilesWithInheritanceCached.mockReturnValue({});
|
|
123
|
-
|
|
124
|
-
const result = await generateInterceptorsService.generateInterceptors('Vendor/theme-missing');
|
|
125
|
-
expect(result).toEqual({});
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
test('should throw error if plugin targets non-existent method', async () => {
|
|
129
|
-
const themeName = 'Vendor/theme-test';
|
|
130
|
-
themeResolverMock.getThemeConfig.mockReturnValue({});
|
|
131
|
-
moduleResolverMock.getModuleConfigByThemeConfig.mockResolvedValue({
|
|
132
|
-
interceptors: {
|
|
133
|
-
'BadPlugin': {
|
|
134
|
-
name: 'BadPlugin',
|
|
135
|
-
target: 'Vendor_TargetModule::js/target.js',
|
|
136
|
-
interceptor: 'Vendor_PluginModule::js/plugin.js',
|
|
137
|
-
sortOrder: 10
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
const emptyTargetModulePath = path.join(fixturesDir, 'emptyTarget.js');
|
|
143
|
-
|
|
144
|
-
const allFilesMap = {
|
|
145
|
-
'Vendor_TargetModule/js/target': emptyTargetModulePath,
|
|
146
|
-
'Vendor_PluginModule/js/plugin': pluginModulePath
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
moduleResolverMock.getAllJsVueFilesWithInheritanceCached.mockReturnValue(allFilesMap);
|
|
150
|
-
|
|
151
|
-
// We expect the promise to reject because generateInterceptors throws on invalid target method
|
|
152
|
-
await expect(generateInterceptorsService.generateInterceptors(themeName))
|
|
153
|
-
.rejects
|
|
154
|
-
.toThrow(/does not export/);
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
test('should skip interception for non-function exports', async () => {
|
|
158
|
-
const themeName = 'Vendor/theme-test';
|
|
159
|
-
|
|
160
|
-
themeResolverMock.getThemeConfig.mockReturnValue({
|
|
161
|
-
src: '/path/to/theme'
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
moduleResolverMock.getModuleConfigByThemeConfig.mockResolvedValue({
|
|
165
|
-
interceptors: {
|
|
166
|
-
'TestPlugin': {
|
|
167
|
-
name: 'TestPlugin',
|
|
168
|
-
target: 'Vendor_TargetModule::js/targetNonFunction.js',
|
|
169
|
-
interceptor: 'Vendor_PluginModule::js/pluginForNonFunction.js',
|
|
170
|
-
sortOrder: 10,
|
|
171
|
-
active: true
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
const allFilesMap = {
|
|
177
|
-
'Vendor_TargetModule/js/targetNonFunction': targetNonFunctionPath,
|
|
178
|
-
'Vendor_PluginModule/js/pluginForNonFunction': pluginForNonFunctionPath
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
moduleResolverMock.getAllJsVueFilesWithInheritanceCached.mockReturnValue(allFilesMap);
|
|
182
|
-
|
|
183
|
-
const consoleSpy = jest.spyOn(console, 'warn').mockImplementation(() => {});
|
|
184
|
-
|
|
185
|
-
const result = await generateInterceptorsService.generateInterceptors(themeName);
|
|
186
|
-
|
|
187
|
-
const targetIdentifier = 'Vendor_TargetModule::js/targetNonFunction.js';
|
|
188
|
-
|
|
189
|
-
// Since both 'config' and 'default' are objects, and we are trying to intercept them,
|
|
190
|
-
// they should be skipped. If all are skipped, the targetIdentifier should not be in result.
|
|
191
|
-
expect(result[targetIdentifier]).toBeUndefined();
|
|
192
|
-
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('is not a function'));
|
|
193
|
-
|
|
194
|
-
consoleSpy.mockRestore();
|
|
195
|
-
});
|
|
196
|
-
});
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { jest } from '@jest/globals';
|
|
2
|
-
import createMockConfigResolver from '../__mocks__/configResolver.js';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import { fileURLToPath } from 'url';
|
|
5
|
-
|
|
6
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
-
const __dirname = path.dirname(__filename);
|
|
8
|
-
|
|
9
|
-
let scenarios = [
|
|
10
|
-
{
|
|
11
|
-
scenario: 'a',
|
|
12
|
-
themes: [
|
|
13
|
-
{ code: 'Vendor/theme-a', codeImport: 'Vendor_ModuleNameA::js/test', expected: '/TEST/web/js/test.js' },
|
|
14
|
-
{ code: 'Vendor/theme-a', codeImport: 'Vendor_ModuleNameA::js/test.vue', expected: '/TEST/web/js/test.js' },
|
|
15
|
-
{ code: 'Vendor/theme-a', codeImport: 'Vendor_ModuleNameA::js/test.css', expected: undefined },
|
|
16
|
-
{ code: 'Vendor/theme-a', codeImport: 'Vendor_ModuleNameB::js/test', expected: undefined },
|
|
17
|
-
{ code: 'Vendor/theme-a', codeImport: null, expected: undefined },
|
|
18
|
-
{ code: 'Vendor/theme-b', codeImport: 'Vendor_ModuleNameA::js/unknown', expected: undefined }
|
|
19
|
-
]
|
|
20
|
-
}
|
|
21
|
-
];
|
|
22
|
-
|
|
23
|
-
function mockConfigAndModules(scenario) {
|
|
24
|
-
jest.unstable_mockModule('#service/configResolver.js', () => ({
|
|
25
|
-
__esModule: true,
|
|
26
|
-
default: createMockConfigResolver(scenario).default,
|
|
27
|
-
}));
|
|
28
|
-
|
|
29
|
-
jest.unstable_mockModule('#service/moduleResolver.js', () => ({
|
|
30
|
-
__esModule: true,
|
|
31
|
-
default: {
|
|
32
|
-
getAllJsVueFilesWithInheritanceCached: jest.fn(() => ({
|
|
33
|
-
'Vendor_ModuleNameA/js/test': '/TEST/web/js/test.js',
|
|
34
|
-
})),
|
|
35
|
-
}
|
|
36
|
-
}));
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async function setupInheritModuleResolver(scenario) {
|
|
40
|
-
mockConfigAndModules(scenario);
|
|
41
|
-
const { default: inheritModuleResolverFactory } = await import('#service/inheritModuleResolver.js');
|
|
42
|
-
return inheritModuleResolverFactory();
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
describe('inherit-resolver', () => {
|
|
46
|
-
let inheritModuleResolver;
|
|
47
|
-
|
|
48
|
-
beforeEach(() => {
|
|
49
|
-
jest.resetModules();
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
test.each(scenarios.flatMap(({ scenario, themes }) =>
|
|
53
|
-
themes.map(({ code, codeImport, expected }) => ([scenario, code, codeImport, expected]))
|
|
54
|
-
))('Scenario "%s", Theme "%s", Import "%s"', async (scenario, code, codeImport, expected) => {
|
|
55
|
-
process.env.CURRENT_THEME = code;
|
|
56
|
-
inheritModuleResolver = await setupInheritModuleResolver(scenario);
|
|
57
|
-
const result = await inheritModuleResolver.resolveId.handler(codeImport);
|
|
58
|
-
|
|
59
|
-
expect(result).toEqual(expected);
|
|
60
|
-
});
|
|
61
|
-
});
|