@zwa73/dev-utils 1.0.38 → 1.0.40
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/dist/Macro.macro.d.ts +1 -0
- package/dist/Macro.macro.js +4 -0
- package/dist/UtilDevTool.d.ts +18 -4
- package/dist/UtilDevTool.js +90 -50
- package/dist/UtilMacro.d.ts +7 -0
- package/dist/UtilMacro.js +29 -0
- package/dist/index.js +1 -0
- package/package.json +1 -1
- package/src/Macro.macro.ts +4 -0
- package/src/UtilDevTool.ts +105 -61
- package/src/UtilMacro.ts +23 -0
- package/src/index.ts +4 -3
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
package/dist/UtilDevTool.d.ts
CHANGED
@@ -53,13 +53,27 @@ export declare namespace UtilDT {
|
|
53
53
|
/**使用glob匹配而非文件路径 */
|
54
54
|
glob: boolean;
|
55
55
|
}>;
|
56
|
+
/**codeText的参数 */
|
57
|
+
type CodeTextOpt = {
|
58
|
+
/**匹配的region/comment id */
|
59
|
+
matchId: string;
|
60
|
+
/**region/comment id正则的执行结果*/
|
61
|
+
execArr: RegExpExecArray;
|
62
|
+
/**展开宏的目标文件 */
|
63
|
+
filePath: string;
|
64
|
+
/**展开宏区域的原文本 */
|
65
|
+
text: string;
|
66
|
+
/**缩进 会自动应用 */
|
67
|
+
inent: string;
|
68
|
+
};
|
56
69
|
/**将codeText写入对应region
|
57
70
|
* @param regionId - 区域id \`//#region ${id}\`
|
58
71
|
* @param codeText - 文本
|
59
72
|
* @param opt - 可选参数
|
60
|
-
* @param opt.
|
73
|
+
* @param opt.filePath - 目标文件 默认为去除".macro"的同名文件
|
74
|
+
* @param opt.glob - 使用glob匹配而非文件路径
|
61
75
|
*/
|
62
|
-
export function regionMacro(regionId: string, codeText: string | (() => string | Promise<string>), opt?: MacroOpt): Promise<void>;
|
76
|
+
export function regionMacro(regionId: string | RegExp, codeText: string | ((opt: CodeTextOpt) => string | Promise<string>), opt?: MacroOpt): Promise<void>;
|
63
77
|
/**将codeText写入对应注释下
|
64
78
|
* @param commentId - 注释id \`// ${id}\`
|
65
79
|
* @param codeText - 文本
|
@@ -67,13 +81,13 @@ export declare namespace UtilDT {
|
|
67
81
|
* @param opt.filePath - 目标文件 默认为去除".macro"的同名文件
|
68
82
|
* @param opt.glob - 使用glob匹配而非文件路径
|
69
83
|
*/
|
70
|
-
export function commentMacro(commentId: string, codeText: string | (() => string | Promise<string>), opt?: MacroOpt): Promise<void>;
|
84
|
+
export function commentMacro(commentId: string | RegExp, codeText: string | ((opt: CodeTextOpt) => string | Promise<string>), opt?: MacroOpt): Promise<void>;
|
71
85
|
/**将codeText写入对应文件 不存在则创建
|
72
86
|
* @param codeText - 文本
|
73
87
|
* @param opt - 可选参数
|
74
88
|
* @param opt.filePath - 目标文件 默认为去除".macro"的同名文件
|
75
89
|
* @param opt.glob - 使用glob匹配而非文件路径
|
76
90
|
*/
|
77
|
-
export function fileMacro(codeText: string | (() => string | Promise<string>), opt?: MacroOpt): Promise<void>;
|
91
|
+
export function fileMacro(codeText: string | ((opt: Omit<CodeTextOpt, 'ident' | 'matchId' | 'execArr'>) => string | Promise<string>), opt?: MacroOpt): Promise<void>;
|
78
92
|
export {};
|
79
93
|
}
|
package/dist/UtilDevTool.js
CHANGED
@@ -126,59 +126,84 @@ var UtilDT;
|
|
126
126
|
// 将所有的相对路径转换为绝对路径
|
127
127
|
const absolutePaths = filepath.map(fp => path.resolve(process.cwd(), fp).replaceAll("\\", "/"));
|
128
128
|
// 创建一个字符串,其中包含所有文件的 require 语句
|
129
|
-
const requires = absolutePaths.map(fp => `require('${fp}')
|
129
|
+
const requires = absolutePaths.map(fp => `require('${fp}')`).join(';');
|
130
130
|
// 创建并执行 ts-node 命令
|
131
131
|
const cmd = `ts-node -r tsconfig-paths/register -e "${requires}" ${opt?.project ? `-P "${opt.project}"` : ""}`;
|
132
132
|
await utils_1.UtilFunc.exec(cmd, { outlvl: 'info', errlvl: 'warn' });
|
133
133
|
}
|
134
134
|
UtilDT.batchNode = batchNode;
|
135
135
|
//#region macro工具
|
136
|
-
const parseMacroPaths = (
|
136
|
+
const parseMacroPaths = (opt) => {
|
137
|
+
const loc = utils_1.UtilFunc.getFuncLoc(3);
|
138
|
+
if (!loc && !opt?.filePath)
|
139
|
+
(0, utils_1.throwError)(`parseMacroPaths 未能找到函数位置`);
|
140
|
+
const basePath = loc?.filePath;
|
137
141
|
return opt?.filePath
|
138
142
|
? opt.glob
|
139
|
-
? utils_1.UtilFT.fileSearchGlob(process.cwd(), opt.filePath)
|
140
|
-
: typeof opt?.filePath === "string"
|
141
|
-
|
143
|
+
? utils_1.UtilFT.fileSearchGlob(process.cwd(), opt.filePath, { normalize: "posix" })
|
144
|
+
: typeof opt?.filePath === "string"
|
145
|
+
? [opt?.filePath.replaceAll('\\', '/')]
|
146
|
+
: opt?.filePath.map((filepath) => filepath.replaceAll('\\', '/'))
|
147
|
+
: [basePath.replace(/(.+)\.macro\.(js|ts|cjs|mjs)$/, "$1.$2").replaceAll('\\', '/')];
|
142
148
|
};
|
143
149
|
const readFile = async (basePath) => (await fs.promises.readFile(basePath, 'utf-8')).replaceAll("\r\n", "\n");
|
144
150
|
const parseCodeText = async (codeText, opt) => {
|
145
151
|
const strText = typeof codeText === "function" ? await codeText(opt) : codeText;
|
146
152
|
return strText.split('\n').map((line) => `${opt.inent}${line}`).join('\n');
|
147
153
|
};
|
154
|
+
const literalRegex = (str) => new RegExp(`^${str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')}(?!\\S)`);
|
148
155
|
//#endregion
|
149
156
|
/**将codeText写入对应region
|
150
157
|
* @param regionId - 区域id \`//#region ${id}\`
|
151
158
|
* @param codeText - 文本
|
152
159
|
* @param opt - 可选参数
|
153
|
-
* @param opt.
|
160
|
+
* @param opt.filePath - 目标文件 默认为去除".macro"的同名文件
|
161
|
+
* @param opt.glob - 使用glob匹配而非文件路径
|
154
162
|
*/
|
155
163
|
async function regionMacro(regionId, codeText, opt) {
|
156
|
-
const loc = utils_1.UtilFunc.getFuncLoc(2);
|
157
|
-
if (!loc) {
|
158
|
-
utils_1.SLogger.error(`UtilDT.regionMacro 未能找到函数位置`);
|
159
|
-
return;
|
160
|
-
}
|
161
164
|
const plist = [];
|
162
|
-
const filePaths = parseMacroPaths(
|
165
|
+
const filePaths = parseMacroPaths(opt);
|
163
166
|
for (const filePath of filePaths) {
|
164
167
|
const queuefunc = async () => {
|
165
168
|
if (!(await utils_1.UtilFT.pathExists(filePath))) {
|
166
169
|
utils_1.SLogger.error(`UtilDT.regionMacro ${filePath} 不存在`);
|
167
170
|
return;
|
168
171
|
}
|
169
|
-
|
170
|
-
const
|
172
|
+
let fileText = await readFile(filePath);
|
173
|
+
const regex = new RegExp(/(^|\n)([^\S\n]*)(\/\/#region (.*)\n)/.source +
|
171
174
|
/([\s\S]*?)/.source +
|
172
175
|
/([^\S\n]*\/\/#endregion(?!\S).*)/.source, "g");
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
176
|
+
regex.lastIndex = 0;
|
177
|
+
let match;
|
178
|
+
let hasMatch = false;
|
179
|
+
while (match = regex.exec(fileText)) {
|
180
|
+
const id = match[4];
|
181
|
+
const prefix = match[1];
|
182
|
+
const content = match[5];
|
183
|
+
const inent = match[2];
|
184
|
+
const comment = match[3];
|
185
|
+
const endcomment = match[6];
|
186
|
+
const idregex = typeof regionId === "string"
|
187
|
+
? literalRegex(regionId) : regionId;
|
188
|
+
let idmatch = idregex.exec(id);
|
189
|
+
if (idmatch == null)
|
190
|
+
continue;
|
191
|
+
hasMatch = true;
|
192
|
+
const ol = fileText.length;
|
193
|
+
const parseCode = await parseCodeText(codeText, {
|
194
|
+
matchId: idmatch[0],
|
195
|
+
execArr: idmatch,
|
196
|
+
text: (0, utils_1.dedent)(content),
|
197
|
+
inent,
|
198
|
+
filePath
|
199
|
+
});
|
200
|
+
fileText = fileText.replace(match[0], `${prefix}${inent}${comment}${parseCode}\n${endcomment}`);
|
201
|
+
regex.lastIndex += fileText.length - ol;
|
177
202
|
}
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
203
|
+
if (hasMatch)
|
204
|
+
await fs.promises.writeFile(filePath, fileText, 'utf-8');
|
205
|
+
else if (!opt?.glob)
|
206
|
+
utils_1.SLogger.error(`UtilDT.regionMacro 无法找到区域 ${regionId}`);
|
182
207
|
};
|
183
208
|
plist.push(utils_1.UtilFunc.queueProc(path.posix.normalize(filePath.replaceAll("\\", "/")), queuefunc));
|
184
209
|
}
|
@@ -193,36 +218,50 @@ var UtilDT;
|
|
193
218
|
* @param opt.glob - 使用glob匹配而非文件路径
|
194
219
|
*/
|
195
220
|
async function commentMacro(commentId, codeText, opt) {
|
196
|
-
const loc = utils_1.UtilFunc.getFuncLoc(2);
|
197
|
-
if (!loc) {
|
198
|
-
utils_1.SLogger.error(`UtilDT.commentMacro 未能找到函数位置`);
|
199
|
-
return;
|
200
|
-
}
|
201
221
|
const plist = [];
|
202
|
-
const filePaths = parseMacroPaths(
|
222
|
+
const filePaths = parseMacroPaths(opt);
|
203
223
|
for (const filePath of filePaths) {
|
204
224
|
const queuefunc = async () => {
|
205
225
|
if (!(await utils_1.UtilFT.pathExists(filePath))) {
|
206
226
|
utils_1.SLogger.error(`UtilDT.commentMacro ${filePath} 不存在`);
|
207
227
|
return;
|
208
228
|
}
|
209
|
-
|
210
|
-
const
|
211
|
-
/(\n|)/.source +
|
229
|
+
let fileText = await readFile(filePath);
|
230
|
+
const regex = new RegExp(/(^|\n)([^\S\n]*)(\/\/ (.*))(\n|)/.source +
|
212
231
|
/([^\n]*)/.source, "g");
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
232
|
+
let match;
|
233
|
+
let hasMatch = false;
|
234
|
+
while (match = regex.exec(fileText)) {
|
235
|
+
const id = match[4];
|
236
|
+
const prefix = match[1];
|
237
|
+
const content = match[6];
|
238
|
+
const inent = match[2];
|
239
|
+
const comment = match[3];
|
240
|
+
const idregex = typeof commentId === "string"
|
241
|
+
? literalRegex(commentId) : commentId;
|
242
|
+
let idmatch = idregex.exec(id);
|
243
|
+
if (idmatch == null)
|
244
|
+
continue;
|
245
|
+
hasMatch = true;
|
246
|
+
const ol = fileText.length;
|
247
|
+
const parseCode = await parseCodeText(codeText, {
|
248
|
+
matchId: idmatch[0],
|
249
|
+
execArr: idmatch,
|
250
|
+
text: (0, utils_1.dedent)(content),
|
251
|
+
inent,
|
252
|
+
filePath
|
253
|
+
});
|
254
|
+
if (parseCode.includes('\n')) {
|
255
|
+
utils_1.SLogger.error(`UtilDT.commentMacro 无法使用多行文本, 考虑使用regionMacro ${codeText}`);
|
256
|
+
return;
|
257
|
+
}
|
258
|
+
fileText = fileText.replace(match[0], `${prefix}${inent}${comment}\n${parseCode}`);
|
259
|
+
regex.lastIndex += fileText.length - ol;
|
217
260
|
}
|
218
|
-
|
219
|
-
|
220
|
-
if (
|
221
|
-
utils_1.SLogger.error(`UtilDT.commentMacro
|
222
|
-
return;
|
223
|
-
}
|
224
|
-
const ntext = text.replace(getregex(), `$1$2\n${parseCode}`);
|
225
|
-
await fs.promises.writeFile(filePath, ntext, 'utf-8');
|
261
|
+
if (hasMatch)
|
262
|
+
await fs.promises.writeFile(filePath, fileText, 'utf-8');
|
263
|
+
else if (!opt?.glob)
|
264
|
+
utils_1.SLogger.error(`UtilDT.commentMacro 无法找到注释 ${commentId}`);
|
226
265
|
};
|
227
266
|
plist.push(utils_1.UtilFunc.queueProc(path.posix.normalize(filePath.replaceAll("\\", "/")), queuefunc));
|
228
267
|
}
|
@@ -236,18 +275,19 @@ var UtilDT;
|
|
236
275
|
* @param opt.glob - 使用glob匹配而非文件路径
|
237
276
|
*/
|
238
277
|
async function fileMacro(codeText, opt) {
|
239
|
-
const loc = utils_1.UtilFunc.getFuncLoc(2);
|
240
|
-
if (!loc) {
|
241
|
-
utils_1.SLogger.error(`UtilDT.fileMacro 未能找到函数位置`);
|
242
|
-
return;
|
243
|
-
}
|
244
278
|
const plist = [];
|
245
|
-
const filePaths = parseMacroPaths(
|
279
|
+
const filePaths = parseMacroPaths(opt);
|
246
280
|
for (const filePath of filePaths) {
|
247
281
|
const queuefunc = async () => {
|
248
282
|
await utils_1.UtilFT.ensurePathExists(filePath);
|
249
283
|
const text = await readFile(filePath);
|
250
|
-
const parseCode = await parseCodeText(codeText, {
|
284
|
+
const parseCode = await parseCodeText(codeText, {
|
285
|
+
matchId: '',
|
286
|
+
execArr: /''/.exec(''),
|
287
|
+
text,
|
288
|
+
inent: '',
|
289
|
+
filePath
|
290
|
+
});
|
251
291
|
await fs.promises.writeFile(filePath, parseCode, 'utf-8');
|
252
292
|
};
|
253
293
|
plist.push(utils_1.UtilFunc.queueProc(path.posix.normalize(filePath.replaceAll("\\", "/")), queuefunc));
|
@@ -0,0 +1,29 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
exports.UtilMacro = void 0;
|
7
|
+
const utils_1 = require("@zwa73/utils");
|
8
|
+
const QuickFunc_1 = require("./QuickFunc");
|
9
|
+
const path_1 = __importDefault(require("path"));
|
10
|
+
var UtilMacro;
|
11
|
+
(function (UtilMacro) {
|
12
|
+
/**根据注释批量生成导出
|
13
|
+
* @param glob - 应用的golb
|
14
|
+
* @example
|
15
|
+
*/
|
16
|
+
function exportComment(glob) {
|
17
|
+
(0, QuickFunc_1.commentMacro)(/export (\S*)/, ({ filePath, matchId, execArr }) => {
|
18
|
+
const basedir = path_1.default.dirname(filePath).replaceAll('\\', '/');
|
19
|
+
const result = utils_1.UtilFT.fileSearchGlob(basedir, execArr[1], { normalize: 'posix' })
|
20
|
+
.map((file) => path_1.default.posix.relative(basedir, file))
|
21
|
+
.map((file) => path_1.default.parse(file).name)
|
22
|
+
.filter((file) => file != path_1.default.parse(filePath).name)
|
23
|
+
.map((file) => `export * from './${file}'`)
|
24
|
+
.join(';');
|
25
|
+
return result.length > 0 ? `${result};` : result;
|
26
|
+
}, { glob: true, filePath: glob });
|
27
|
+
}
|
28
|
+
UtilMacro.exportComment = exportComment;
|
29
|
+
})(UtilMacro || (exports.UtilMacro = UtilMacro = {}));
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
package/src/UtilDevTool.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import * as path from 'path';
|
2
2
|
import * as TJS from 'typescript-json-schema';
|
3
3
|
import * as fs from 'fs';
|
4
|
-
import { JObject, SLogger, UtilFT, UtilFunc, dedent } from '@zwa73/utils';
|
4
|
+
import { JObject, SLogger, UtilFT, UtilFunc, dedent, throwError } from '@zwa73/utils';
|
5
5
|
|
6
6
|
export namespace UtilDT{
|
7
7
|
|
@@ -125,7 +125,7 @@ export async function batchNode(filepath:string|string[],opt?:BatchNodeOpt) {
|
|
125
125
|
// 将所有的相对路径转换为绝对路径
|
126
126
|
const absolutePaths = filepath.map(fp => path.resolve(process.cwd(), fp).replaceAll("\\","/"));
|
127
127
|
// 创建一个字符串,其中包含所有文件的 require 语句
|
128
|
-
const requires = absolutePaths.map(fp => `require('${fp}')
|
128
|
+
const requires = absolutePaths.map(fp => `require('${fp}')`).join(';');
|
129
129
|
// 创建并执行 ts-node 命令
|
130
130
|
const cmd = `ts-node -r tsconfig-paths/register -e "${requires}" ${opt?.project?`-P "${opt.project}"` : ""}`;
|
131
131
|
await UtilFunc.exec(cmd, { outlvl: 'info', errlvl: 'warn' });
|
@@ -139,7 +139,11 @@ type MacroOpt = Partial<{
|
|
139
139
|
glob:boolean;
|
140
140
|
}>
|
141
141
|
/**codeText的参数 */
|
142
|
-
type
|
142
|
+
type CodeTextOpt = {
|
143
|
+
/**匹配的region/comment id */
|
144
|
+
matchId:string;
|
145
|
+
/**region/comment id正则的执行结果*/
|
146
|
+
execArr:RegExpExecArray;
|
143
147
|
/**展开宏的目标文件 */
|
144
148
|
filePath:string;
|
145
149
|
/**展开宏区域的原文本 */
|
@@ -148,54 +152,79 @@ type CdeeTextOpt = {
|
|
148
152
|
inent:string;
|
149
153
|
}
|
150
154
|
//#region macro工具
|
151
|
-
const parseMacroPaths = (
|
155
|
+
const parseMacroPaths = (opt?:MacroOpt)=>{
|
156
|
+
const loc = UtilFunc.getFuncLoc(3);
|
157
|
+
if(!loc && !opt?.filePath) throwError(`parseMacroPaths 未能找到函数位置`);
|
158
|
+
const basePath = loc?.filePath!;
|
152
159
|
return opt?.filePath
|
153
160
|
? opt.glob
|
154
|
-
? UtilFT.fileSearchGlob(process.cwd(),opt.filePath)
|
155
|
-
: typeof opt?.filePath==="string"
|
156
|
-
|
161
|
+
? UtilFT.fileSearchGlob(process.cwd(),opt.filePath,{normalize:"posix"})
|
162
|
+
: typeof opt?.filePath==="string"
|
163
|
+
? [opt?.filePath.replaceAll('\\','/')]
|
164
|
+
: opt?.filePath.map((filepath)=>filepath.replaceAll('\\','/'))
|
165
|
+
: [basePath.replace(/(.+)\.macro\.(js|ts|cjs|mjs)$/,"$1.$2").replaceAll('\\','/')];
|
157
166
|
}
|
158
167
|
const readFile = async (basePath:string)=>
|
159
168
|
(await fs.promises.readFile(basePath,'utf-8')).replaceAll("\r\n","\n");
|
160
|
-
const parseCodeText = async (codeText:string|((opt:
|
169
|
+
const parseCodeText = async (codeText:string|((opt:CodeTextOpt)=>string|Promise<string>),opt:CodeTextOpt)=>{
|
161
170
|
const strText = typeof codeText === "function" ? await codeText(opt) : codeText;
|
162
171
|
return strText.split('\n').map((line)=>`${opt.inent}${line}`).join('\n');
|
163
172
|
}
|
173
|
+
const literalRegex = (str:string)=>new RegExp(
|
174
|
+
`^${str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')}(?!\\S)`);
|
164
175
|
//#endregion
|
165
176
|
/**将codeText写入对应region
|
166
177
|
* @param regionId - 区域id \`//#region ${id}\`
|
167
178
|
* @param codeText - 文本
|
168
179
|
* @param opt - 可选参数
|
169
|
-
* @param opt.
|
180
|
+
* @param opt.filePath - 目标文件 默认为去除".macro"的同名文件
|
181
|
+
* @param opt.glob - 使用glob匹配而非文件路径
|
170
182
|
*/
|
171
|
-
export async function regionMacro(regionId:string,codeText:string|(()=>string|Promise<string>),opt?:MacroOpt){
|
172
|
-
const loc = UtilFunc.getFuncLoc(2);
|
173
|
-
if(!loc){
|
174
|
-
SLogger.error(`UtilDT.regionMacro 未能找到函数位置`);
|
175
|
-
return
|
176
|
-
}
|
183
|
+
export async function regionMacro(regionId:string|RegExp,codeText:string|((opt:CodeTextOpt)=>string|Promise<string>),opt?:MacroOpt){
|
177
184
|
const plist:Promise<void>[] = [];
|
178
|
-
const filePaths = parseMacroPaths(
|
185
|
+
const filePaths = parseMacroPaths(opt);
|
179
186
|
for(const filePath of filePaths){
|
180
187
|
const queuefunc = async ()=>{
|
181
188
|
if(!(await UtilFT.pathExists(filePath))) {
|
182
189
|
SLogger.error(`UtilDT.regionMacro ${filePath} 不存在`);
|
183
190
|
return
|
184
191
|
}
|
185
|
-
|
186
|
-
const
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
192
|
+
let fileText = await readFile(filePath);
|
193
|
+
const regex = new RegExp(
|
194
|
+
/(^|\n)([^\S\n]*)(\/\/#region (.*)\n)/.source+
|
195
|
+
/([\s\S]*?)/.source+
|
196
|
+
/([^\S\n]*\/\/#endregion(?!\S).*)/.source
|
197
|
+
,"g")
|
198
|
+
regex.lastIndex=0;
|
199
|
+
let match:RegExpExecArray|null;
|
200
|
+
let hasMatch = false;
|
201
|
+
while(match = regex.exec(fileText)){
|
202
|
+
const id = match[4];
|
203
|
+
const prefix = match[1];
|
204
|
+
const content = match[5];
|
205
|
+
const inent = match[2];
|
206
|
+
const comment = match[3];
|
207
|
+
const endcomment = match[6];
|
208
|
+
|
209
|
+
const idregex = typeof regionId === "string"
|
210
|
+
? literalRegex(regionId) : regionId;
|
211
|
+
let idmatch = idregex.exec(id);
|
212
|
+
if(idmatch==null) continue;
|
213
|
+
hasMatch=true;
|
214
|
+
const ol = fileText.length;
|
215
|
+
const parseCode = await parseCodeText(codeText,{
|
216
|
+
matchId :idmatch[0],
|
217
|
+
execArr :idmatch,
|
218
|
+
text :dedent(content),
|
219
|
+
inent ,
|
220
|
+
filePath
|
221
|
+
});
|
222
|
+
fileText = fileText.replace(match[0], `${prefix}${inent}${comment}${parseCode}\n${endcomment}`);
|
223
|
+
regex.lastIndex += fileText.length - ol;
|
194
224
|
}
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
await fs.promises.writeFile(filePath, ntext, 'utf-8');
|
225
|
+
if(hasMatch)
|
226
|
+
await fs.promises.writeFile(filePath, fileText, 'utf-8');
|
227
|
+
else if(!opt?.glob) SLogger.error(`UtilDT.regionMacro 无法找到区域 ${regionId}`);
|
199
228
|
}
|
200
229
|
plist.push(UtilFunc.queueProc(path.posix.normalize(filePath.replaceAll("\\","/")),queuefunc))
|
201
230
|
}
|
@@ -208,38 +237,52 @@ export async function regionMacro(regionId:string,codeText:string|(()=>string|Pr
|
|
208
237
|
* @param opt.filePath - 目标文件 默认为去除".macro"的同名文件
|
209
238
|
* @param opt.glob - 使用glob匹配而非文件路径
|
210
239
|
*/
|
211
|
-
export async function commentMacro(commentId:string,codeText:string|(()=>string|Promise<string>),opt?:MacroOpt){
|
212
|
-
const loc = UtilFunc.getFuncLoc(2);
|
213
|
-
if(!loc){
|
214
|
-
SLogger.error(`UtilDT.commentMacro 未能找到函数位置`);
|
215
|
-
return
|
216
|
-
}
|
240
|
+
export async function commentMacro(commentId:string|RegExp,codeText:string|((opt:CodeTextOpt)=>string|Promise<string>),opt?:MacroOpt){
|
217
241
|
const plist:Promise<void>[] = [];
|
218
|
-
const filePaths = parseMacroPaths(
|
242
|
+
const filePaths = parseMacroPaths(opt);
|
219
243
|
for(const filePath of filePaths){
|
220
244
|
const queuefunc = async ()=>{
|
221
245
|
if(!(await UtilFT.pathExists(filePath))) {
|
222
246
|
SLogger.error(`UtilDT.commentMacro ${filePath} 不存在`);
|
223
247
|
return
|
224
248
|
}
|
225
|
-
|
226
|
-
const
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
249
|
+
let fileText = await readFile(filePath);
|
250
|
+
const regex = new RegExp(
|
251
|
+
/(^|\n)([^\S\n]*)(\/\/ (.*))(\n|)/.source+
|
252
|
+
/([^\n]*)/.source
|
253
|
+
,"g")
|
254
|
+
let match:RegExpExecArray|null;
|
255
|
+
let hasMatch = false;
|
256
|
+
while(match = regex.exec(fileText)){
|
257
|
+
const id = match[4];
|
258
|
+
const prefix = match[1];
|
259
|
+
const content = match[6];
|
260
|
+
const inent = match[2];
|
261
|
+
const comment = match[3];
|
262
|
+
|
263
|
+
const idregex = typeof commentId === "string"
|
264
|
+
? literalRegex(commentId) : commentId;
|
265
|
+
let idmatch = idregex.exec(id);
|
266
|
+
if(idmatch==null) continue;
|
267
|
+
hasMatch=true;
|
268
|
+
const ol = fileText.length;
|
269
|
+
const parseCode = await parseCodeText(codeText,{
|
270
|
+
matchId :idmatch[0],
|
271
|
+
execArr :idmatch,
|
272
|
+
text :dedent(content),
|
273
|
+
inent ,
|
274
|
+
filePath
|
275
|
+
});
|
276
|
+
if(parseCode.includes('\n')){
|
277
|
+
SLogger.error(`UtilDT.commentMacro 无法使用多行文本, 考虑使用regionMacro ${codeText}`);
|
278
|
+
return;
|
279
|
+
}
|
280
|
+
fileText = fileText.replace(match[0], `${prefix}${inent}${comment}\n${parseCode}`);
|
281
|
+
regex.lastIndex += fileText.length - ol;
|
240
282
|
}
|
241
|
-
|
242
|
-
|
283
|
+
if(hasMatch)
|
284
|
+
await fs.promises.writeFile(filePath, fileText, 'utf-8');
|
285
|
+
else if(!opt?.glob) SLogger.error(`UtilDT.commentMacro 无法找到注释 ${commentId}`);
|
243
286
|
}
|
244
287
|
plist.push(UtilFunc.queueProc(path.posix.normalize(filePath.replaceAll("\\","/")),queuefunc))
|
245
288
|
}
|
@@ -251,19 +294,20 @@ export async function commentMacro(commentId:string,codeText:string|(()=>string|
|
|
251
294
|
* @param opt.filePath - 目标文件 默认为去除".macro"的同名文件
|
252
295
|
* @param opt.glob - 使用glob匹配而非文件路径
|
253
296
|
*/
|
254
|
-
export async function fileMacro(codeText:string|(()=>string|Promise<string>),opt?:MacroOpt){
|
255
|
-
const loc = UtilFunc.getFuncLoc(2);
|
256
|
-
if(!loc){
|
257
|
-
SLogger.error(`UtilDT.fileMacro 未能找到函数位置`);
|
258
|
-
return
|
259
|
-
}
|
297
|
+
export async function fileMacro(codeText:string|((opt:Omit<CodeTextOpt,'ident'|'matchId'|'execArr'>)=>string|Promise<string>),opt?:MacroOpt){
|
260
298
|
const plist:Promise<void>[] = [];
|
261
|
-
const filePaths = parseMacroPaths(
|
299
|
+
const filePaths = parseMacroPaths(opt);
|
262
300
|
for(const filePath of filePaths){
|
263
301
|
const queuefunc = async ()=>{
|
264
302
|
await UtilFT.ensurePathExists(filePath);
|
265
303
|
const text = await readFile(filePath);
|
266
|
-
const parseCode = await parseCodeText(codeText,{
|
304
|
+
const parseCode = await parseCodeText(codeText,{
|
305
|
+
matchId:'',
|
306
|
+
execArr:/''/.exec('')!,
|
307
|
+
text,
|
308
|
+
inent:'',
|
309
|
+
filePath
|
310
|
+
});
|
267
311
|
await fs.promises.writeFile(filePath, parseCode, 'utf-8');
|
268
312
|
}
|
269
313
|
plist.push(UtilFunc.queueProc(path.posix.normalize(filePath.replaceAll("\\","/")),queuefunc))
|
package/src/UtilMacro.ts
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
import { UtilFT } from "@zwa73/utils";
|
2
|
+
import { commentMacro } from "./QuickFunc"
|
3
|
+
import path from "path";
|
4
|
+
|
5
|
+
|
6
|
+
export namespace UtilMacro{
|
7
|
+
/**根据注释批量生成导出
|
8
|
+
* @param glob - 应用的golb
|
9
|
+
* @example
|
10
|
+
*/
|
11
|
+
export function exportComment(glob:string){
|
12
|
+
commentMacro(/export (\S*)/,({filePath,matchId,execArr})=>{
|
13
|
+
const basedir = path.dirname(filePath).replaceAll('\\','/');
|
14
|
+
const result = UtilFT.fileSearchGlob(basedir,execArr[1],{normalize:'posix'})
|
15
|
+
.map((file)=>path.posix.relative(basedir,file))
|
16
|
+
.map((file)=>path.parse(file).name)
|
17
|
+
.filter((file)=>file!=path.parse(filePath).name)
|
18
|
+
.map((file)=>`export * from './${file}'`)
|
19
|
+
.join(';');
|
20
|
+
return result.length>0? `${result};` : result;
|
21
|
+
},{glob:true,filePath:glob});
|
22
|
+
}
|
23
|
+
}
|
package/src/index.ts
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
-
export * from './UtilDevTool';
|
2
|
-
export * from './Command';
|
3
|
-
export * from "./QuickFunc";
|
1
|
+
export * from './UtilDevTool';
|
2
|
+
export * from './Command';
|
3
|
+
export * from "./QuickFunc";
|
4
|
+
//export *
|