@windwalker-io/core 4.2.4 → 4.2.6
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/LICENSE +19 -19
- package/dist/debugger/debugger-BOPm1u5O.js +2 -0
- package/dist/debugger/debugger.js +16 -17
- package/dist/debugger/vue-animate.min-DEk1PxEb.js +2 -0
- package/dist/debugger-console.css +1 -6
- package/dist/next.js +38 -37
- package/package.json +2 -2
- package/src/asset-bundler.mjs +114 -114
- package/src/debugger/types/global.d.js +2 -2
- package/src/index.mjs +10 -11
- package/src/legacy/4.0/js-sync.mjs +74 -74
- package/src/next/fusion/index.ts +2 -2
- package/src/next/fusion/plugins/assets.ts +29 -29
- package/src/next/fusion/plugins/index.ts +3 -3
- package/src/next/fusion/plugins/systemjs.ts +66 -66
- package/src/next/fusion/processors/cloneAssets.ts +81 -81
- package/src/next/fusion/processors/cssModulize.ts +128 -127
- package/src/next/fusion/processors/index.ts +4 -4
- package/src/next/fusion/processors/installVendors.ts +184 -178
- package/src/next/fusion/processors/jsModulize.ts +306 -300
- package/src/next/index.ts +2 -2
- package/src/next/utilities/asset-sync.ts +47 -47
- package/src/next/utilities/crypto.ts +11 -11
- package/src/next/utilities/fs.ts +61 -61
- package/src/next/utilities/index.ts +5 -5
- package/src/next/utilities/modules.ts +17 -17
- package/dist/debugger/debugger-ChQADeB6.js +0 -2
- package/dist/debugger/vue-animate.min-BkEL-t1R.js +0 -9
package/src/index.mjs
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Part of funclass project.
|
|
3
|
-
*
|
|
4
|
-
* @copyright Copyright (C) 2021 LYRASOFT.
|
|
5
|
-
* @license __LICENSE__
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
export * from './asset-sync.mjs';
|
|
9
|
-
export * from './asset-bundler.mjs';
|
|
10
|
-
export * from './install-vendors.mjs';
|
|
11
|
-
export * from './app.ts';
|
|
1
|
+
/**
|
|
2
|
+
* Part of funclass project.
|
|
3
|
+
*
|
|
4
|
+
* @copyright Copyright (C) 2021 LYRASOFT.
|
|
5
|
+
* @license __LICENSE__
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export * from './asset-sync.mjs';
|
|
9
|
+
export * from './asset-bundler.mjs';
|
|
10
|
+
export * from './install-vendors.mjs';
|
|
@@ -1,74 +1,74 @@
|
|
|
1
|
-
import { findModules } from '
|
|
2
|
-
import { dest as toDest, src, ts } from '@windwalker-io/fusion';
|
|
3
|
-
import { postStream, prepareStream } from '@windwalker-io/fusion/src/lifecycles.js';
|
|
4
|
-
import { extractDest } from '@windwalker-io/fusion/src/utilities/utilities.js';
|
|
5
|
-
import { existsSync } from 'fs';
|
|
6
|
-
import rename from 'gulp-rename';
|
|
7
|
-
import path from 'path';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* @deprecated
|
|
11
|
-
*/
|
|
12
|
-
export function jsSync(source = 'src/Module', dest, options = {}) {
|
|
13
|
-
const tsOptions = options.ts || {};
|
|
14
|
-
|
|
15
|
-
if (!tsOptions.tsconfig) {
|
|
16
|
-
tsOptions.tsconfig = path.resolve('tsconfig.json');
|
|
17
|
-
|
|
18
|
-
if (!existsSync(tsOptions.tsconfig)) {
|
|
19
|
-
tsOptions.tsconfig = path.resolve('node_modules/@windwalker-io/unicorn/tsconfig.js.json');
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const sourceList = [];
|
|
24
|
-
|
|
25
|
-
sourceList.push(...findModules('**/assets/*.{js,mjs}'));
|
|
26
|
-
sourceList.push(source + '**/assets/*.{js,mjs}');
|
|
27
|
-
|
|
28
|
-
let stream = prepareStream(src(sourceList));
|
|
29
|
-
|
|
30
|
-
stream = stream.pipe(rename((path) => {
|
|
31
|
-
path.dirname = path.dirname.replace(/assets$/, '').toLowerCase();
|
|
32
|
-
}));
|
|
33
|
-
|
|
34
|
-
const jsDest = extractDest(dest);
|
|
35
|
-
|
|
36
|
-
//
|
|
37
|
-
// // if (dest.merge) {
|
|
38
|
-
// // stream = stream.pipe(rename(path.basename(dest.file)));
|
|
39
|
-
// // }
|
|
40
|
-
//
|
|
41
|
-
stream = stream.pipe(toDest(jsDest.path).on('error', e => console.error(e)));
|
|
42
|
-
|
|
43
|
-
return Promise.all([
|
|
44
|
-
new Promise((resolve) => {
|
|
45
|
-
postStream(stream).on('end', (event) => {
|
|
46
|
-
const data = {
|
|
47
|
-
event,
|
|
48
|
-
src,
|
|
49
|
-
dest: jsDest,
|
|
50
|
-
stream
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
resolve(data);
|
|
54
|
-
});
|
|
55
|
-
}),
|
|
56
|
-
// Legacy mode
|
|
57
|
-
ts(
|
|
58
|
-
[
|
|
59
|
-
...findModules('**/assets/*.ts'),
|
|
60
|
-
'node_modules/@windwalker-io/unicorn/src/types/*.d.ts',
|
|
61
|
-
`${source}/**/*.ts`,
|
|
62
|
-
],
|
|
63
|
-
dest,
|
|
64
|
-
{
|
|
65
|
-
rename: (path) => {
|
|
66
|
-
path.dirname = path.dirname.replace(/assets$/, '').toLowerCase();
|
|
67
|
-
},
|
|
68
|
-
...tsOptions
|
|
69
|
-
}
|
|
70
|
-
)
|
|
71
|
-
]).then((v) => {
|
|
72
|
-
return v[0];
|
|
73
|
-
});
|
|
74
|
-
}
|
|
1
|
+
import { findModules } from '../../index.mjs';
|
|
2
|
+
import { dest as toDest, src, ts } from '@windwalker-io/fusion';
|
|
3
|
+
import { postStream, prepareStream } from '@windwalker-io/fusion/src/lifecycles.js';
|
|
4
|
+
import { extractDest } from '@windwalker-io/fusion/src/utilities/utilities.js';
|
|
5
|
+
import { existsSync } from 'fs';
|
|
6
|
+
import rename from 'gulp-rename';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @deprecated
|
|
11
|
+
*/
|
|
12
|
+
export function jsSync(source = 'src/Module', dest, options = {}) {
|
|
13
|
+
const tsOptions = options.ts || {};
|
|
14
|
+
|
|
15
|
+
if (!tsOptions.tsconfig) {
|
|
16
|
+
tsOptions.tsconfig = path.resolve('tsconfig.json');
|
|
17
|
+
|
|
18
|
+
if (!existsSync(tsOptions.tsconfig)) {
|
|
19
|
+
tsOptions.tsconfig = path.resolve('node_modules/@windwalker-io/unicorn/tsconfig.js.json');
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const sourceList = [];
|
|
24
|
+
|
|
25
|
+
sourceList.push(...findModules('**/assets/*.{js,mjs}'));
|
|
26
|
+
sourceList.push(source + '**/assets/*.{js,mjs}');
|
|
27
|
+
|
|
28
|
+
let stream = prepareStream(src(sourceList));
|
|
29
|
+
|
|
30
|
+
stream = stream.pipe(rename((path) => {
|
|
31
|
+
path.dirname = path.dirname.replace(/assets$/, '').toLowerCase();
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
const jsDest = extractDest(dest);
|
|
35
|
+
|
|
36
|
+
//
|
|
37
|
+
// // if (dest.merge) {
|
|
38
|
+
// // stream = stream.pipe(rename(path.basename(dest.file)));
|
|
39
|
+
// // }
|
|
40
|
+
//
|
|
41
|
+
stream = stream.pipe(toDest(jsDest.path).on('error', e => console.error(e)));
|
|
42
|
+
|
|
43
|
+
return Promise.all([
|
|
44
|
+
new Promise((resolve) => {
|
|
45
|
+
postStream(stream).on('end', (event) => {
|
|
46
|
+
const data = {
|
|
47
|
+
event,
|
|
48
|
+
src,
|
|
49
|
+
dest: jsDest,
|
|
50
|
+
stream
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
resolve(data);
|
|
54
|
+
});
|
|
55
|
+
}),
|
|
56
|
+
// Legacy mode
|
|
57
|
+
ts(
|
|
58
|
+
[
|
|
59
|
+
...findModules('**/assets/*.ts'),
|
|
60
|
+
'node_modules/@windwalker-io/unicorn/src/types/*.d.ts',
|
|
61
|
+
`${source}/**/*.ts`,
|
|
62
|
+
],
|
|
63
|
+
dest,
|
|
64
|
+
{
|
|
65
|
+
rename: (path) => {
|
|
66
|
+
path.dirname = path.dirname.replace(/assets$/, '').toLowerCase();
|
|
67
|
+
},
|
|
68
|
+
...tsOptions
|
|
69
|
+
}
|
|
70
|
+
)
|
|
71
|
+
]).then((v) => {
|
|
72
|
+
return v[0];
|
|
73
|
+
});
|
|
74
|
+
}
|
package/src/next/fusion/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './plugins';
|
|
2
|
-
export * from './processors';
|
|
1
|
+
export * from './plugins';
|
|
2
|
+
export * from './processors';
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import { type FusionPlugin } from '@windwalker-io/fusion-next';
|
|
2
|
-
import { getAvailableForReposition, handleCloneAssets, handleReposition } from '../processors/cloneAssets';
|
|
3
|
-
|
|
4
|
-
export interface WindwalkerAssetsOptions {
|
|
5
|
-
clone?: Record<string, string>;
|
|
6
|
-
reposition?: Record<string, string>;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function globalAssets(options: WindwalkerAssetsOptions): FusionPlugin {
|
|
10
|
-
return {
|
|
11
|
-
name: 'core:global-assets',
|
|
12
|
-
buildConfig(builder) {
|
|
13
|
-
const clone = options.clone || {};
|
|
14
|
-
let reposition = options.reposition || {};
|
|
15
|
-
|
|
16
|
-
reposition = { ...reposition, ...getAvailableForReposition(clone) };
|
|
17
|
-
|
|
18
|
-
// Handle reposition
|
|
19
|
-
handleReposition(builder, reposition);
|
|
20
|
-
|
|
21
|
-
const clonePatterns = Object.keys(clone);
|
|
22
|
-
|
|
23
|
-
// Handle clone
|
|
24
|
-
if (clonePatterns.length > 0) {
|
|
25
|
-
handleCloneAssets(builder, clonePatterns);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
}
|
|
1
|
+
import { type FusionPlugin } from '@windwalker-io/fusion-next';
|
|
2
|
+
import { getAvailableForReposition, handleCloneAssets, handleReposition } from '../processors/cloneAssets';
|
|
3
|
+
|
|
4
|
+
export interface WindwalkerAssetsOptions {
|
|
5
|
+
clone?: Record<string, string>;
|
|
6
|
+
reposition?: Record<string, string>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function globalAssets(options: WindwalkerAssetsOptions): FusionPlugin {
|
|
10
|
+
return {
|
|
11
|
+
name: 'core:global-assets',
|
|
12
|
+
buildConfig(builder) {
|
|
13
|
+
const clone = options.clone || {};
|
|
14
|
+
let reposition = options.reposition || {};
|
|
15
|
+
|
|
16
|
+
reposition = { ...reposition, ...getAvailableForReposition(clone) };
|
|
17
|
+
|
|
18
|
+
// Handle reposition
|
|
19
|
+
handleReposition(builder, reposition);
|
|
20
|
+
|
|
21
|
+
const clonePatterns = Object.keys(clone);
|
|
22
|
+
|
|
23
|
+
// Handle clone
|
|
24
|
+
if (clonePatterns.length > 0) {
|
|
25
|
+
handleCloneAssets(builder, clonePatterns);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from './assets';
|
|
2
|
-
export * from './systemjs';
|
|
3
|
-
|
|
1
|
+
export * from './assets';
|
|
2
|
+
export * from './systemjs';
|
|
3
|
+
|
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
import fs from 'fs-extra';
|
|
2
|
-
import { resolve } from 'node:path';
|
|
3
|
-
import type { OutputAsset, OutputChunk } from 'rollup';
|
|
4
|
-
import type { PluginOption } from 'vite';
|
|
5
|
-
|
|
6
|
-
export function injectSystemJS(systemPath?: string, filter?: (file: OutputAsset | OutputChunk) => any): PluginOption {
|
|
7
|
-
systemPath ??= resolve('node_modules/systemjs/dist/system.min.js');
|
|
8
|
-
|
|
9
|
-
return {
|
|
10
|
-
name: 'core:inject-systemjs',
|
|
11
|
-
async generateBundle(options, bundle) {
|
|
12
|
-
if (options.format !== 'system') {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const systemjsCode = fs.readFileSync(
|
|
17
|
-
resolve(systemPath),
|
|
18
|
-
'utf-8'
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
for (const file of Object.values(bundle)) {
|
|
22
|
-
if (filter && !filter(file)) {
|
|
23
|
-
continue;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (file.type === 'chunk' && file.isEntry && file.fileName.endsWith('.js')) {
|
|
27
|
-
file.code = systemjsCode + '\n' + file.code;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function systemCSSFix(): PluginOption {
|
|
35
|
-
return {
|
|
36
|
-
name: 'core:systemjs-css-fix',
|
|
37
|
-
async generateBundle(options, bundle) {
|
|
38
|
-
if (options.format !== 'system') {
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
43
|
-
if (fileName.endsWith('.css') && 'code' in chunk) {
|
|
44
|
-
const regex = /__vite_style__\.textContent\s*=\s*"([\s\S]*?)";/;
|
|
45
|
-
let match = chunk.code.match(regex);
|
|
46
|
-
|
|
47
|
-
// For minified
|
|
48
|
-
if (!match) {
|
|
49
|
-
const regex = /\.textContent\s*=\s*`([\s\S]*?)`/;
|
|
50
|
-
match = chunk.code.match(regex);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (match && match[1]) {
|
|
54
|
-
chunk.code = match[1]
|
|
55
|
-
.replace(/\\"/g, '"')
|
|
56
|
-
.replace(/\\n/g, '\n')
|
|
57
|
-
.replace(/\\t/g, '\t')
|
|
58
|
-
.replace(/\\\\/g, '\\')
|
|
59
|
-
.replace(/\/\*\$vite\$:\d+\*\/$/, '')
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import type { OutputAsset, OutputChunk } from 'rollup';
|
|
4
|
+
import type { PluginOption } from 'vite';
|
|
5
|
+
|
|
6
|
+
export function injectSystemJS(systemPath?: string, filter?: (file: OutputAsset | OutputChunk) => any): PluginOption {
|
|
7
|
+
systemPath ??= resolve('node_modules/systemjs/dist/system.min.js');
|
|
8
|
+
|
|
9
|
+
return {
|
|
10
|
+
name: 'core:inject-systemjs',
|
|
11
|
+
async generateBundle(options, bundle) {
|
|
12
|
+
if (options.format !== 'system') {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const systemjsCode = fs.readFileSync(
|
|
17
|
+
resolve(systemPath),
|
|
18
|
+
'utf-8'
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
for (const file of Object.values(bundle)) {
|
|
22
|
+
if (filter && !filter(file)) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (file.type === 'chunk' && file.isEntry && file.fileName.endsWith('.js')) {
|
|
27
|
+
file.code = systemjsCode + '\n' + file.code;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function systemCSSFix(): PluginOption {
|
|
35
|
+
return {
|
|
36
|
+
name: 'core:systemjs-css-fix',
|
|
37
|
+
async generateBundle(options, bundle) {
|
|
38
|
+
if (options.format !== 'system') {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
43
|
+
if (fileName.endsWith('.css') && 'code' in chunk) {
|
|
44
|
+
const regex = /__vite_style__\.textContent\s*=\s*"([\s\S]*?)";/;
|
|
45
|
+
let match = chunk.code.match(regex);
|
|
46
|
+
|
|
47
|
+
// For minified
|
|
48
|
+
if (!match) {
|
|
49
|
+
const regex = /\.textContent\s*=\s*`([\s\S]*?)`/;
|
|
50
|
+
match = chunk.code.match(regex);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (match && match[1]) {
|
|
54
|
+
chunk.code = match[1]
|
|
55
|
+
.replace(/\\"/g, '"')
|
|
56
|
+
.replace(/\\n/g, '\n')
|
|
57
|
+
.replace(/\\t/g, '\t')
|
|
58
|
+
.replace(/\\\\/g, '\\')
|
|
59
|
+
.replace(/\/\*\$vite\$:\d+\*\/$/, '')
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
@@ -1,81 +1,81 @@
|
|
|
1
|
-
import { callback, type ConfigBuilder } from '@windwalker-io/fusion-next';
|
|
2
|
-
import isGlob from 'is-glob';
|
|
3
|
-
import micromatch from 'micromatch';
|
|
4
|
-
import { normalize } from 'node:path';
|
|
5
|
-
import { relative } from 'node:path';
|
|
6
|
-
import { containsMiddleGlob, removeLastGlob, uniqId } from '../../utilities';
|
|
7
|
-
|
|
8
|
-
export function cloneAssets(patterns: Record<string, string>) {
|
|
9
|
-
return callback((taskName, builder) => {
|
|
10
|
-
const reposition = getAvailableForReposition(patterns);
|
|
11
|
-
|
|
12
|
-
handleReposition(builder, reposition);
|
|
13
|
-
|
|
14
|
-
handleCloneAssets(builder, Object.keys(patterns));
|
|
15
|
-
|
|
16
|
-
return null;
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function getAvailableForReposition(patterns: Record<string, string>) {
|
|
21
|
-
const reposition: Record<string, string> = {};
|
|
22
|
-
|
|
23
|
-
for (const from in patterns) {
|
|
24
|
-
// If clone from contains middle glob: eg. `assets/**/files`, we cannot handle the naming
|
|
25
|
-
// Let the naming options to handle it.
|
|
26
|
-
if (!containsMiddleGlob(from)) {
|
|
27
|
-
reposition[from] = patterns[from];
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return reposition;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function handleCloneAssets(builder: ConfigBuilder, clonePatterns: string[]) {
|
|
35
|
-
// An module starts `hidden:` will be ignored by fusion
|
|
36
|
-
const id = uniqId('hidden:clone-asset-') + '.js';
|
|
37
|
-
|
|
38
|
-
const task = builder.addTask(id);
|
|
39
|
-
|
|
40
|
-
builder.resolveIdCallbacks.push((src) => {
|
|
41
|
-
if (src === id) {
|
|
42
|
-
return id;
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
builder.loadCallbacks.push((src) => {
|
|
47
|
-
if (src === id) {
|
|
48
|
-
const glob = clonePatterns
|
|
49
|
-
// Replace slash to unix style
|
|
50
|
-
.map(v => v.replace(/\\/g, '/'))
|
|
51
|
-
// Glob in virtual module should start with /
|
|
52
|
-
.map(v => v.startsWith('./') || !v.startsWith('/') ? `/${v}` : v)
|
|
53
|
-
// wrap with quotes
|
|
54
|
-
.map(v => `'${v}'`)
|
|
55
|
-
// join it to string.
|
|
56
|
-
.join(', ');
|
|
57
|
-
|
|
58
|
-
return `import.meta.glob(${glob});\n`;
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export function handleReposition(builder: ConfigBuilder, reposition: Record<string, string>) {
|
|
64
|
-
builder.assetFileNamesCallbacks.push((assetInfo) => {
|
|
65
|
-
const fileName = assetInfo.originalFileName!;
|
|
66
|
-
|
|
67
|
-
for (const base in reposition) {
|
|
68
|
-
if (match(fileName, base)) {
|
|
69
|
-
return normalize(reposition[base] + relative(removeLastGlob(base), fileName)).replace(/\\/g, '/');
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
function match(str: string, pattern: string) {
|
|
76
|
-
if (isGlob(pattern)) {
|
|
77
|
-
return micromatch.isMatch(str, pattern);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
return str.startsWith(pattern);
|
|
81
|
-
}
|
|
1
|
+
import { callback, type ConfigBuilder } from '@windwalker-io/fusion-next';
|
|
2
|
+
import isGlob from 'is-glob';
|
|
3
|
+
import micromatch from 'micromatch';
|
|
4
|
+
import { normalize } from 'node:path';
|
|
5
|
+
import { relative } from 'node:path';
|
|
6
|
+
import { containsMiddleGlob, removeLastGlob, uniqId } from '../../utilities';
|
|
7
|
+
|
|
8
|
+
export function cloneAssets(patterns: Record<string, string>) {
|
|
9
|
+
return callback((taskName, builder) => {
|
|
10
|
+
const reposition = getAvailableForReposition(patterns);
|
|
11
|
+
|
|
12
|
+
handleReposition(builder, reposition);
|
|
13
|
+
|
|
14
|
+
handleCloneAssets(builder, Object.keys(patterns));
|
|
15
|
+
|
|
16
|
+
return null;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function getAvailableForReposition(patterns: Record<string, string>) {
|
|
21
|
+
const reposition: Record<string, string> = {};
|
|
22
|
+
|
|
23
|
+
for (const from in patterns) {
|
|
24
|
+
// If clone from contains middle glob: eg. `assets/**/files`, we cannot handle the naming
|
|
25
|
+
// Let the naming options to handle it.
|
|
26
|
+
if (!containsMiddleGlob(from)) {
|
|
27
|
+
reposition[from] = patterns[from];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return reposition;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function handleCloneAssets(builder: ConfigBuilder, clonePatterns: string[]) {
|
|
35
|
+
// An module starts `hidden:` will be ignored by fusion
|
|
36
|
+
const id = uniqId('hidden:clone-asset-') + '.js';
|
|
37
|
+
|
|
38
|
+
const task = builder.addTask(id);
|
|
39
|
+
|
|
40
|
+
builder.resolveIdCallbacks.push((src) => {
|
|
41
|
+
if (src === id) {
|
|
42
|
+
return id;
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
builder.loadCallbacks.push((src) => {
|
|
47
|
+
if (src === id) {
|
|
48
|
+
const glob = clonePatterns
|
|
49
|
+
// Replace slash to unix style
|
|
50
|
+
.map(v => v.replace(/\\/g, '/'))
|
|
51
|
+
// Glob in virtual module should start with /
|
|
52
|
+
.map(v => v.startsWith('./') || !v.startsWith('/') ? `/${v}` : v)
|
|
53
|
+
// wrap with quotes
|
|
54
|
+
.map(v => `'${v}'`)
|
|
55
|
+
// join it to string.
|
|
56
|
+
.join(', ');
|
|
57
|
+
|
|
58
|
+
return `import.meta.glob(${glob});\n`;
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function handleReposition(builder: ConfigBuilder, reposition: Record<string, string>) {
|
|
64
|
+
builder.assetFileNamesCallbacks.push((assetInfo) => {
|
|
65
|
+
const fileName = assetInfo.originalFileName!;
|
|
66
|
+
|
|
67
|
+
for (const base in reposition) {
|
|
68
|
+
if (match(fileName, base)) {
|
|
69
|
+
return normalize(reposition[base] + relative(removeLastGlob(base), fileName)).replace(/\\/g, '/');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function match(str: string, pattern: string) {
|
|
76
|
+
if (isGlob(pattern)) {
|
|
77
|
+
return micromatch.isMatch(str, pattern);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return str.startsWith(pattern);
|
|
81
|
+
}
|