@dazhicheng/common 1.0.4 → 1.0.5
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/.env +20 -0
- package/.gitignore +0 -1
- package/.stylelintrc.cjs +76 -76
- package/nginx_dev.conf +26 -0
- package/nginx_test.conf +26 -0
- package/package.json +9 -11
- package/src/types/index.d.ts +1 -0
- package/sync-common.mjs +277 -0
package/.env
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# 【通用】环境变量
|
|
2
|
+
|
|
3
|
+
# 版本号
|
|
4
|
+
VITE_VERSION = 1.0.0
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# 应用部署基础路径(如部署在子目录 /admin,则设置为 /admin/)
|
|
8
|
+
VITE_BASE_URL = /
|
|
9
|
+
|
|
10
|
+
# 权限模式【 frontend 前端模式 / backend 后端模式 】
|
|
11
|
+
VITE_ACCESS_MODE = backend
|
|
12
|
+
|
|
13
|
+
# 跨域请求时是否携带 Cookie(开启前需确保后端支持)
|
|
14
|
+
VITE_WITH_CREDENTIALS = false
|
|
15
|
+
|
|
16
|
+
# 是否打开路由信息
|
|
17
|
+
VITE_OPEN_ROUTE_INFO = false
|
|
18
|
+
|
|
19
|
+
# 锁屏加密密钥
|
|
20
|
+
VITE_LOCK_ENCRYPT_KEY = s3cur3k3y4adpro
|
package/.gitignore
CHANGED
package/.stylelintrc.cjs
CHANGED
|
@@ -1,76 +1,76 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
extends: [
|
|
3
|
-
'stylelint-config-standard',
|
|
4
|
-
'stylelint-config-recommended-scss',
|
|
5
|
-
'stylelint-config-recommended-vue/scss',
|
|
6
|
-
'stylelint-config-html/vue',
|
|
7
|
-
'stylelint-config-recess-order',
|
|
8
|
-
],
|
|
9
|
-
overrides: [
|
|
10
|
-
{
|
|
11
|
-
files: ['**/*.{vue,html}'],
|
|
12
|
-
customSyntax: 'postcss-html',
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
files: ['**/*.{css,scss}'],
|
|
16
|
-
customSyntax: 'postcss-scss',
|
|
17
|
-
},
|
|
18
|
-
],
|
|
19
|
-
rules: {
|
|
20
|
-
'import-notation': 'string',
|
|
21
|
-
'selector-class-pattern': null,
|
|
22
|
-
'custom-property-pattern': null,
|
|
23
|
-
'keyframes-name-pattern': null,
|
|
24
|
-
'no-descending-specificity': null,
|
|
25
|
-
'no-empty-source': null,
|
|
26
|
-
'property-no-vendor-prefix': null,
|
|
27
|
-
'selector-pseudo-class-no-unknown': [
|
|
28
|
-
true,
|
|
29
|
-
{
|
|
30
|
-
ignorePseudoClasses: ['global', 'export', 'deep'],
|
|
31
|
-
},
|
|
32
|
-
],
|
|
33
|
-
'property-no-unknown': [
|
|
34
|
-
true,
|
|
35
|
-
{
|
|
36
|
-
ignoreProperties: [],
|
|
37
|
-
},
|
|
38
|
-
],
|
|
39
|
-
'at-rule-no-unknown': [
|
|
40
|
-
true,
|
|
41
|
-
{
|
|
42
|
-
ignoreAtRules: [
|
|
43
|
-
'apply',
|
|
44
|
-
'use',
|
|
45
|
-
'mixin',
|
|
46
|
-
'include',
|
|
47
|
-
'extend',
|
|
48
|
-
'each',
|
|
49
|
-
'if',
|
|
50
|
-
'else',
|
|
51
|
-
'for',
|
|
52
|
-
'while',
|
|
53
|
-
'reference',
|
|
54
|
-
],
|
|
55
|
-
},
|
|
56
|
-
],
|
|
57
|
-
'scss/at-rule-no-unknown': [
|
|
58
|
-
true,
|
|
59
|
-
{
|
|
60
|
-
ignoreAtRules: [
|
|
61
|
-
'apply',
|
|
62
|
-
'use',
|
|
63
|
-
'mixin',
|
|
64
|
-
'include',
|
|
65
|
-
'extend',
|
|
66
|
-
'each',
|
|
67
|
-
'if',
|
|
68
|
-
'else',
|
|
69
|
-
'for',
|
|
70
|
-
'while',
|
|
71
|
-
'reference',
|
|
72
|
-
],
|
|
73
|
-
},
|
|
74
|
-
],
|
|
75
|
-
},
|
|
76
|
-
};
|
|
1
|
+
module.exports = {
|
|
2
|
+
extends: [
|
|
3
|
+
'stylelint-config-standard',
|
|
4
|
+
'stylelint-config-recommended-scss',
|
|
5
|
+
'stylelint-config-recommended-vue/scss',
|
|
6
|
+
'stylelint-config-html/vue',
|
|
7
|
+
'stylelint-config-recess-order',
|
|
8
|
+
],
|
|
9
|
+
overrides: [
|
|
10
|
+
{
|
|
11
|
+
files: ['**/*.{vue,html}'],
|
|
12
|
+
customSyntax: 'postcss-html',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
files: ['**/*.{css,scss}'],
|
|
16
|
+
customSyntax: 'postcss-scss',
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
rules: {
|
|
20
|
+
'import-notation': 'string',
|
|
21
|
+
'selector-class-pattern': null,
|
|
22
|
+
'custom-property-pattern': null,
|
|
23
|
+
'keyframes-name-pattern': null,
|
|
24
|
+
'no-descending-specificity': null,
|
|
25
|
+
'no-empty-source': null,
|
|
26
|
+
'property-no-vendor-prefix': null,
|
|
27
|
+
'selector-pseudo-class-no-unknown': [
|
|
28
|
+
true,
|
|
29
|
+
{
|
|
30
|
+
ignorePseudoClasses: ['global', 'export', 'deep'],
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
'property-no-unknown': [
|
|
34
|
+
true,
|
|
35
|
+
{
|
|
36
|
+
ignoreProperties: [],
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
'at-rule-no-unknown': [
|
|
40
|
+
true,
|
|
41
|
+
{
|
|
42
|
+
ignoreAtRules: [
|
|
43
|
+
'apply',
|
|
44
|
+
'use',
|
|
45
|
+
'mixin',
|
|
46
|
+
'include',
|
|
47
|
+
'extend',
|
|
48
|
+
'each',
|
|
49
|
+
'if',
|
|
50
|
+
'else',
|
|
51
|
+
'for',
|
|
52
|
+
'while',
|
|
53
|
+
'reference',
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
'scss/at-rule-no-unknown': [
|
|
58
|
+
true,
|
|
59
|
+
{
|
|
60
|
+
ignoreAtRules: [
|
|
61
|
+
'apply',
|
|
62
|
+
'use',
|
|
63
|
+
'mixin',
|
|
64
|
+
'include',
|
|
65
|
+
'extend',
|
|
66
|
+
'each',
|
|
67
|
+
'if',
|
|
68
|
+
'else',
|
|
69
|
+
'for',
|
|
70
|
+
'while',
|
|
71
|
+
'reference',
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
},
|
|
76
|
+
};
|
package/nginx_dev.conf
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# HTTP 服务器 - 保持原有配置
|
|
2
|
+
server_name localhost;
|
|
3
|
+
charset utf-8;
|
|
4
|
+
|
|
5
|
+
root /usr/share/nginx/html;
|
|
6
|
+
index index.html;
|
|
7
|
+
|
|
8
|
+
location / {
|
|
9
|
+
try_files $uri $uri/ /index.html;
|
|
10
|
+
# CORS 配置
|
|
11
|
+
add_header 'Access-Control-Allow-Origin' '*' always;
|
|
12
|
+
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
|
|
13
|
+
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
location /dev-api/ {
|
|
17
|
+
proxy_set_header Host $host;
|
|
18
|
+
proxy_set_header X-Real-Ip $remote_addr;
|
|
19
|
+
proxy_set_header X-Forwarded-For $remote_addr;
|
|
20
|
+
proxy_pass http://116.6.49.180:11000/;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
error_page 500 502 503 504 /50x.html;
|
|
24
|
+
location = /50x.html {
|
|
25
|
+
root html;
|
|
26
|
+
}
|
package/nginx_test.conf
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# HTTP 服务器 - 保持原有配置
|
|
2
|
+
server_name localhost;
|
|
3
|
+
charset utf-8;
|
|
4
|
+
|
|
5
|
+
root /usr/share/nginx/html;
|
|
6
|
+
index index.html;
|
|
7
|
+
|
|
8
|
+
location / {
|
|
9
|
+
try_files $uri $uri/ /index.html;
|
|
10
|
+
# CORS 配置
|
|
11
|
+
add_header 'Access-Control-Allow-Origin' '*' always;
|
|
12
|
+
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
|
|
13
|
+
add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization' always;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
location /test-api/ {
|
|
17
|
+
proxy_set_header Host $host;
|
|
18
|
+
proxy_set_header X-Real-Ip $remote_addr;
|
|
19
|
+
proxy_set_header X-Forwarded-For $remote_addr;
|
|
20
|
+
proxy_pass http://116.6.49.180:11001/;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
error_page 500 502 503 504 /50x.html;
|
|
24
|
+
location = /50x.html {
|
|
25
|
+
root html;
|
|
26
|
+
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dazhicheng/common",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "共享配置文件",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"types": "./src/types/index.d.ts",
|
|
6
7
|
"files": [
|
|
7
8
|
"commitlint.config.cjs",
|
|
8
9
|
".husky",
|
|
@@ -11,20 +12,17 @@
|
|
|
11
12
|
".stylelintignore",
|
|
12
13
|
".gitignore",
|
|
13
14
|
".gitattributes",
|
|
15
|
+
".env",
|
|
14
16
|
"eslint.config.mjs",
|
|
15
17
|
"tsconfig.json",
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
+
"Dockerfile",
|
|
19
|
+
"nginx_dev.conf",
|
|
20
|
+
"nginx_test.conf",
|
|
21
|
+
"sync-common.mjs",
|
|
22
|
+
"src/types/index.d.ts"
|
|
18
23
|
],
|
|
19
24
|
"exports": {
|
|
20
|
-
"./
|
|
21
|
-
"./.prettierrc": "./.prettierrc",
|
|
22
|
-
"./.stylelintrc.cjs": "./.stylelintrc.cjs",
|
|
23
|
-
"./.stylelintignore": "./.stylelintignore",
|
|
24
|
-
"./.gitignore": "./.gitignore",
|
|
25
|
-
"./.gitattributes": "./.gitattributes",
|
|
26
|
-
"./eslint.config.mjs": "./eslint.config.mjs",
|
|
27
|
-
"./tsconfig.json": "./tsconfig.json"
|
|
25
|
+
"./sync-common.mjs": "./sync-common.mjs"
|
|
28
26
|
},
|
|
29
27
|
"publishConfig": {
|
|
30
28
|
"access": "public"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/sync-common.mjs
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { createRequire } from 'module';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = path.dirname(__filename);
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
const commonDir = __dirname;
|
|
10
|
+
|
|
11
|
+
const markerPattern = /^<<<(before|common|after)>>>$/gm;
|
|
12
|
+
const textLikeFiles = new Set([
|
|
13
|
+
'.gitignore',
|
|
14
|
+
'.stylelintignore',
|
|
15
|
+
'.gitattributes',
|
|
16
|
+
'.prettierrc',
|
|
17
|
+
'.env',
|
|
18
|
+
]);
|
|
19
|
+
const directLikeFiles = new Set([
|
|
20
|
+
'Dockerfile',
|
|
21
|
+
'nginx_dev.conf',
|
|
22
|
+
'nginx_test.conf',
|
|
23
|
+
'commit-msg',
|
|
24
|
+
'pre-commit',
|
|
25
|
+
'.stylelintrc.cjs',
|
|
26
|
+
'commitlint.config.cjs',
|
|
27
|
+
'eslint.config.mjs',
|
|
28
|
+
'tsconfig.json',
|
|
29
|
+
]);
|
|
30
|
+
const defaultManagedFiles = [
|
|
31
|
+
'.gitignore',
|
|
32
|
+
'.stylelintignore',
|
|
33
|
+
'.gitattributes',
|
|
34
|
+
'.prettierrc',
|
|
35
|
+
'.env',
|
|
36
|
+
'.stylelintrc.cjs',
|
|
37
|
+
'commitlint.config.cjs',
|
|
38
|
+
'Dockerfile',
|
|
39
|
+
'eslint.config.mjs',
|
|
40
|
+
'tsconfig.json',
|
|
41
|
+
{ name: 'nginx_dev.conf' },
|
|
42
|
+
{ name: 'nginx_test.conf' },
|
|
43
|
+
{ name: 'commit-msg', dir: '.husky' },
|
|
44
|
+
{ name: 'pre-commit', dir: '.husky' },
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
const getFileRelativePath = (file) => (file.dir ? path.join(file.dir, file.name) : file.name);
|
|
48
|
+
const getFileKey = (file) => `${file.dir ?? ''}::${file.name}`;
|
|
49
|
+
|
|
50
|
+
const ensureCommonFile = (file) => {
|
|
51
|
+
const filePath = path.join(commonDir, getFileRelativePath(file));
|
|
52
|
+
if (!fs.existsSync(filePath)) {
|
|
53
|
+
throw new Error(`Missing common file: ${filePath}`);
|
|
54
|
+
}
|
|
55
|
+
return filePath;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const parseLocalSections = (filePath) => {
|
|
59
|
+
if (!filePath || !fs.existsSync(filePath)) {
|
|
60
|
+
return { before: '', after: '', hasMarkers: false };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const rawContent = fs.readFileSync(filePath, 'utf8').trim();
|
|
64
|
+
if (!rawContent) {
|
|
65
|
+
return { before: '', after: '', hasMarkers: false };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const markers = [...rawContent.matchAll(markerPattern)];
|
|
69
|
+
if (markers.length === 0) {
|
|
70
|
+
return { before: '', after: rawContent, hasMarkers: false };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const sections = {
|
|
74
|
+
before: '',
|
|
75
|
+
common: '',
|
|
76
|
+
after: '',
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
for (let index = 0; index < markers.length; index += 1) {
|
|
80
|
+
const current = markers[index];
|
|
81
|
+
const next = markers[index + 1];
|
|
82
|
+
const sectionName = current[1];
|
|
83
|
+
const start = current.index + current[0].length;
|
|
84
|
+
const end = next ? next.index : rawContent.length;
|
|
85
|
+
sections[sectionName] = rawContent.slice(start, end).trim();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
before: sections.before,
|
|
90
|
+
after: sections.after,
|
|
91
|
+
hasMarkers: true,
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const getDefaultHeader = (fileName) => {
|
|
96
|
+
if (!textLikeFiles.has(fileName)) {
|
|
97
|
+
return '';
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return `# base\n# 由 scripts/sync-common.mjs 根据 @dazhicheng/common/${fileName} 自动生成,请勿直接修改\n\n`;
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const getDefaultLocalFiles = (file) => ({
|
|
104
|
+
merged: path.join('local', getFileRelativePath(file)),
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const getDefaultBlockHeaders = (fileName) => {
|
|
108
|
+
if (textLikeFiles.has(fileName)) {
|
|
109
|
+
return {
|
|
110
|
+
before: '# project specific\n',
|
|
111
|
+
common: '',
|
|
112
|
+
after: '\n\n# project specific\n',
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (directLikeFiles.has(fileName)) {
|
|
117
|
+
return {
|
|
118
|
+
before: '# 这里是增量\n\n',
|
|
119
|
+
common: '# 这里是 common 的内容\n\n',
|
|
120
|
+
after: '\n\n# 这里还是增量\n\n',
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
before: '',
|
|
126
|
+
common: '',
|
|
127
|
+
after: '',
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const getDefaultFileConfig = (file) => ({
|
|
132
|
+
name: file.name,
|
|
133
|
+
dir: file.dir,
|
|
134
|
+
header: getDefaultHeader(file.name),
|
|
135
|
+
localFiles: getDefaultLocalFiles(file),
|
|
136
|
+
blockHeaders: getDefaultBlockHeaders(file.name),
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const mergeFileConfig = (defaultFile, projectFile = {}) => ({
|
|
140
|
+
...defaultFile,
|
|
141
|
+
...projectFile,
|
|
142
|
+
localFiles: {
|
|
143
|
+
...(defaultFile.localFiles ?? {}),
|
|
144
|
+
...(projectFile.localFiles ?? {}),
|
|
145
|
+
},
|
|
146
|
+
blockHeaders: {
|
|
147
|
+
...(defaultFile.blockHeaders ?? {}),
|
|
148
|
+
...(projectFile.blockHeaders ?? {}),
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
const normalizeFileEntry = (file) => {
|
|
153
|
+
if (typeof file === 'string') {
|
|
154
|
+
return { name: file };
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return file;
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const normalizeFiles = (config = {}) => {
|
|
161
|
+
if (Array.isArray(config)) {
|
|
162
|
+
return config.map(normalizeFileEntry);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (Array.isArray(config.files)) {
|
|
166
|
+
return config.files.map(normalizeFileEntry);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return [
|
|
170
|
+
...(config.textFiles ?? []).map((file) => ({ type: 'textFiles', ...normalizeFileEntry(file) })),
|
|
171
|
+
...(config.directFiles ?? []).map((file) => ({
|
|
172
|
+
type: 'directFiles',
|
|
173
|
+
...normalizeFileEntry(file),
|
|
174
|
+
})),
|
|
175
|
+
];
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const mergeManagedFiles = (projectConfig = {}, runtimeConfig = {}) => {
|
|
179
|
+
const defaultFiles = normalizeFiles(defaultManagedFiles).map((file) =>
|
|
180
|
+
mergeFileConfig(getDefaultFileConfig(file), file),
|
|
181
|
+
);
|
|
182
|
+
const projectFiles = normalizeFiles(projectConfig);
|
|
183
|
+
const runtimeFiles = normalizeFiles(runtimeConfig);
|
|
184
|
+
const mergedMap = new Map(defaultFiles.map((file) => [getFileKey(file), { ...file }]));
|
|
185
|
+
|
|
186
|
+
for (const projectFile of projectFiles) {
|
|
187
|
+
const key = getFileKey(projectFile);
|
|
188
|
+
const current = mergedMap.get(key) ?? getDefaultFileConfig(projectFile);
|
|
189
|
+
mergedMap.set(key, mergeFileConfig(current, projectFile));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
for (const runtimeFile of runtimeFiles) {
|
|
193
|
+
const key = getFileKey(runtimeFile);
|
|
194
|
+
const current = mergedMap.get(key) ?? getDefaultFileConfig(runtimeFile);
|
|
195
|
+
mergedMap.set(key, mergeFileConfig(current, runtimeFile));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return [...mergedMap.values()].filter((file) => file.enabled !== false);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
const logGenerated = ({ rootDir, targetPath, commonPath, localPaths, usedLocalPaths }) => {
|
|
202
|
+
const targetName = path.relative(rootDir, targetPath).replaceAll('\\', '/');
|
|
203
|
+
const commonName = `@dazhicheng/common/${path.relative(commonDir, commonPath).replaceAll('\\', '/')}`;
|
|
204
|
+
const sourceText = [commonName, ...usedLocalPaths].join(' + ');
|
|
205
|
+
|
|
206
|
+
console.log(`[sync:common] generated ${targetName} <- ${sourceText}`);
|
|
207
|
+
if (localPaths.length > 0) {
|
|
208
|
+
console.log(`[sync:common] 如需项目增量,请修改 ${localPaths.join(' / ')}`);
|
|
209
|
+
console.log(
|
|
210
|
+
'[sync:common] 单个 local 文件可使用 <<<before>>> / <<<common>>> / <<<after>>> 标记',
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
const renderFile = ({ file, commonContent, localSections, usedLocalPaths }) => {
|
|
216
|
+
let output = file.header ?? '';
|
|
217
|
+
|
|
218
|
+
if (localSections.before) {
|
|
219
|
+
usedLocalPaths.push(file.localFiles.merged);
|
|
220
|
+
output += `${file.blockHeaders.before ?? ''}${localSections.before}\n\n`;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
output += `${file.blockHeaders.common ?? ''}${commonContent}`;
|
|
224
|
+
|
|
225
|
+
if (localSections.after) {
|
|
226
|
+
if (!usedLocalPaths.includes(file.localFiles.merged)) {
|
|
227
|
+
usedLocalPaths.push(file.localFiles.merged);
|
|
228
|
+
}
|
|
229
|
+
output += `${file.blockHeaders.after ?? ''}${localSections.after}\n`;
|
|
230
|
+
} else {
|
|
231
|
+
output += '\n';
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return output;
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
const syncFiles = ({ files, rootDir }) => {
|
|
238
|
+
for (const file of files) {
|
|
239
|
+
const commonPath = ensureCommonFile(file);
|
|
240
|
+
const targetPath = path.join(rootDir, getFileRelativePath(file));
|
|
241
|
+
const targetDir = path.dirname(targetPath);
|
|
242
|
+
if (!fs.existsSync(targetDir)) {
|
|
243
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
244
|
+
}
|
|
245
|
+
const mergedPath = file.localFiles?.merged ? path.join(rootDir, file.localFiles.merged) : '';
|
|
246
|
+
const localSections = parseLocalSections(mergedPath);
|
|
247
|
+
const commonContent = fs.readFileSync(commonPath, 'utf8').trimEnd();
|
|
248
|
+
const usedLocalPaths = [];
|
|
249
|
+
const output = renderFile({ file, commonContent, localSections, usedLocalPaths });
|
|
250
|
+
|
|
251
|
+
fs.writeFileSync(targetPath, output);
|
|
252
|
+
logGenerated({
|
|
253
|
+
rootDir,
|
|
254
|
+
targetPath,
|
|
255
|
+
commonPath,
|
|
256
|
+
localPaths: Object.values(file.localFiles ?? {}).filter(Boolean),
|
|
257
|
+
usedLocalPaths,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
export const runSyncCommon = async ({ rootDir, files = [], config = {} }) => {
|
|
263
|
+
const runtimeConfig = {
|
|
264
|
+
...(config ?? {}),
|
|
265
|
+
files: [...normalizeFiles(config ?? {}), ...normalizeFiles(files)],
|
|
266
|
+
};
|
|
267
|
+
const managedFiles = mergeManagedFiles({}, runtimeConfig);
|
|
268
|
+
|
|
269
|
+
syncFiles({ files: managedFiles, rootDir });
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
const isDirectRun = process.argv[1] && path.resolve(process.argv[1]) === __filename;
|
|
273
|
+
|
|
274
|
+
if (isDirectRun) {
|
|
275
|
+
const cwd = process.cwd();
|
|
276
|
+
await runSyncCommon({ rootDir: cwd });
|
|
277
|
+
}
|