@zwa73/dev-utils 1.0.38 → 1.0.39
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 +3 -0
- package/dist/UtilDevTool.d.ts +16 -4
- package/dist/UtilDevTool.js +82 -50
- package/dist/UtilMacro.d.ts +7 -0
- package/dist/UtilMacro.js +30 -0
- package/dist/index.js +1 -0
- package/package.json +1 -1
- package/src/Macro.macro.ts +4 -0
- package/src/UtilDevTool.ts +95 -61
- package/src/UtilMacro.ts +24 -0
- package/src/index.ts +4 -3
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
package/dist/UtilDevTool.d.ts
CHANGED
@@ -53,13 +53,25 @@ 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
|
+
/**展开宏的目标文件 */
|
61
|
+
filePath: string;
|
62
|
+
/**展开宏区域的原文本 */
|
63
|
+
text: string;
|
64
|
+
/**缩进 会自动应用 */
|
65
|
+
inent: string;
|
66
|
+
};
|
56
67
|
/**将codeText写入对应region
|
57
68
|
* @param regionId - 区域id \`//#region ${id}\`
|
58
69
|
* @param codeText - 文本
|
59
70
|
* @param opt - 可选参数
|
60
|
-
* @param opt.
|
71
|
+
* @param opt.filePath - 目标文件 默认为去除".macro"的同名文件
|
72
|
+
* @param opt.glob - 使用glob匹配而非文件路径
|
61
73
|
*/
|
62
|
-
export function regionMacro(regionId: string, codeText: string | (() => string | Promise<string>), opt?: MacroOpt): Promise<void>;
|
74
|
+
export function regionMacro(regionId: string | RegExp, codeText: string | ((opt: CodeTextOpt) => string | Promise<string>), opt?: MacroOpt): Promise<void>;
|
63
75
|
/**将codeText写入对应注释下
|
64
76
|
* @param commentId - 注释id \`// ${id}\`
|
65
77
|
* @param codeText - 文本
|
@@ -67,13 +79,13 @@ export declare namespace UtilDT {
|
|
67
79
|
* @param opt.filePath - 目标文件 默认为去除".macro"的同名文件
|
68
80
|
* @param opt.glob - 使用glob匹配而非文件路径
|
69
81
|
*/
|
70
|
-
export function commentMacro(commentId: string, codeText: string | (() => string | Promise<string>), opt?: MacroOpt): Promise<void>;
|
82
|
+
export function commentMacro(commentId: string | RegExp, codeText: string | ((opt: CodeTextOpt) => string | Promise<string>), opt?: MacroOpt): Promise<void>;
|
71
83
|
/**将codeText写入对应文件 不存在则创建
|
72
84
|
* @param codeText - 文本
|
73
85
|
* @param opt - 可选参数
|
74
86
|
* @param opt.filePath - 目标文件 默认为去除".macro"的同名文件
|
75
87
|
* @param opt.glob - 使用glob匹配而非文件路径
|
76
88
|
*/
|
77
|
-
export function fileMacro(codeText: string | (() => string | Promise<string>), opt?: MacroOpt): Promise<void>;
|
89
|
+
export function fileMacro(codeText: string | ((opt: CodeTextOpt) => string | Promise<string>), opt?: MacroOpt): Promise<void>;
|
78
90
|
export {};
|
79
91
|
}
|
package/dist/UtilDevTool.js
CHANGED
@@ -126,59 +126,83 @@ 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
|
+
text: (0, utils_1.dedent)(content),
|
196
|
+
inent,
|
197
|
+
filePath
|
198
|
+
});
|
199
|
+
fileText = fileText.replace(match[0], `${prefix}${inent}${comment}${parseCode}\n${endcomment}`);
|
200
|
+
regex.lastIndex += fileText.length - ol;
|
177
201
|
}
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
202
|
+
if (hasMatch)
|
203
|
+
await fs.promises.writeFile(filePath, fileText, 'utf-8');
|
204
|
+
else if (!opt?.glob)
|
205
|
+
utils_1.SLogger.error(`UtilDT.regionMacro 无法找到区域 ${regionId}`);
|
182
206
|
};
|
183
207
|
plist.push(utils_1.UtilFunc.queueProc(path.posix.normalize(filePath.replaceAll("\\", "/")), queuefunc));
|
184
208
|
}
|
@@ -193,36 +217,49 @@ var UtilDT;
|
|
193
217
|
* @param opt.glob - 使用glob匹配而非文件路径
|
194
218
|
*/
|
195
219
|
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
220
|
const plist = [];
|
202
|
-
const filePaths = parseMacroPaths(
|
221
|
+
const filePaths = parseMacroPaths(opt);
|
203
222
|
for (const filePath of filePaths) {
|
204
223
|
const queuefunc = async () => {
|
205
224
|
if (!(await utils_1.UtilFT.pathExists(filePath))) {
|
206
225
|
utils_1.SLogger.error(`UtilDT.commentMacro ${filePath} 不存在`);
|
207
226
|
return;
|
208
227
|
}
|
209
|
-
|
210
|
-
const
|
211
|
-
/(\n|)/.source +
|
228
|
+
let fileText = await readFile(filePath);
|
229
|
+
const regex = new RegExp(/(^|\n)([^\S\n]*)(\/\/ (.*))(\n|)/.source +
|
212
230
|
/([^\n]*)/.source, "g");
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
231
|
+
let match;
|
232
|
+
let hasMatch = false;
|
233
|
+
while (match = regex.exec(fileText)) {
|
234
|
+
const id = match[4];
|
235
|
+
const prefix = match[1];
|
236
|
+
const content = match[6];
|
237
|
+
const inent = match[2];
|
238
|
+
const comment = match[3];
|
239
|
+
const idregex = typeof commentId === "string"
|
240
|
+
? literalRegex(commentId) : commentId;
|
241
|
+
let idmatch = idregex.exec(id);
|
242
|
+
if (idmatch == null)
|
243
|
+
continue;
|
244
|
+
hasMatch = true;
|
245
|
+
const ol = fileText.length;
|
246
|
+
const parseCode = await parseCodeText(codeText, {
|
247
|
+
matchId: idmatch[0],
|
248
|
+
text: (0, utils_1.dedent)(content),
|
249
|
+
inent,
|
250
|
+
filePath
|
251
|
+
});
|
252
|
+
if (parseCode.includes('\n')) {
|
253
|
+
utils_1.SLogger.error(`UtilDT.commentMacro 无法使用多行文本, 考虑使用regionMacro ${codeText}`);
|
254
|
+
return;
|
255
|
+
}
|
256
|
+
fileText = fileText.replace(match[0], `${prefix}${inent}${comment}\n${parseCode}`);
|
257
|
+
regex.lastIndex += fileText.length - ol;
|
217
258
|
}
|
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');
|
259
|
+
if (hasMatch)
|
260
|
+
await fs.promises.writeFile(filePath, fileText, 'utf-8');
|
261
|
+
else if (!opt?.glob)
|
262
|
+
utils_1.SLogger.error(`UtilDT.commentMacro 无法找到注释 ${commentId}`);
|
226
263
|
};
|
227
264
|
plist.push(utils_1.UtilFunc.queueProc(path.posix.normalize(filePath.replaceAll("\\", "/")), queuefunc));
|
228
265
|
}
|
@@ -236,18 +273,13 @@ var UtilDT;
|
|
236
273
|
* @param opt.glob - 使用glob匹配而非文件路径
|
237
274
|
*/
|
238
275
|
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
276
|
const plist = [];
|
245
|
-
const filePaths = parseMacroPaths(
|
277
|
+
const filePaths = parseMacroPaths(opt);
|
246
278
|
for (const filePath of filePaths) {
|
247
279
|
const queuefunc = async () => {
|
248
280
|
await utils_1.UtilFT.ensurePathExists(filePath);
|
249
281
|
const text = await readFile(filePath);
|
250
|
-
const parseCode = await parseCodeText(codeText, { text, inent: '', filePath });
|
282
|
+
const parseCode = await parseCodeText(codeText, { matchId: '', text, inent: '', filePath });
|
251
283
|
await fs.promises.writeFile(filePath, parseCode, 'utf-8');
|
252
284
|
};
|
253
285
|
plist.push(utils_1.UtilFunc.queueProc(path.posix.normalize(filePath.replaceAll("\\", "/")), queuefunc));
|
@@ -0,0 +1,30 @@
|
|
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 }) => {
|
18
|
+
const globp = /export (\S*)/.exec(matchId)[1];
|
19
|
+
const basedir = path_1.default.dirname(filePath).replaceAll('\\', '/');
|
20
|
+
const result = utils_1.UtilFT.fileSearchGlob(basedir, globp, { normalize: 'posix' })
|
21
|
+
.map((file) => path_1.default.posix.relative(basedir, file))
|
22
|
+
.map((file) => path_1.default.parse(file).name)
|
23
|
+
.filter((file) => file != path_1.default.parse(filePath).name)
|
24
|
+
.map((file) => `export * from './${file}'`)
|
25
|
+
.join(';');
|
26
|
+
return result;
|
27
|
+
}, { glob: true, filePath: glob });
|
28
|
+
}
|
29
|
+
UtilMacro.exportComment = exportComment;
|
30
|
+
})(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,9 @@ type MacroOpt = Partial<{
|
|
139
139
|
glob:boolean;
|
140
140
|
}>
|
141
141
|
/**codeText的参数 */
|
142
|
-
type
|
142
|
+
type CodeTextOpt = {
|
143
|
+
/**匹配的region/comment id */
|
144
|
+
matchId:string;
|
143
145
|
/**展开宏的目标文件 */
|
144
146
|
filePath:string;
|
145
147
|
/**展开宏区域的原文本 */
|
@@ -148,54 +150,78 @@ type CdeeTextOpt = {
|
|
148
150
|
inent:string;
|
149
151
|
}
|
150
152
|
//#region macro工具
|
151
|
-
const parseMacroPaths = (
|
153
|
+
const parseMacroPaths = (opt?:MacroOpt)=>{
|
154
|
+
const loc = UtilFunc.getFuncLoc(3);
|
155
|
+
if(!loc && !opt?.filePath) throwError(`parseMacroPaths 未能找到函数位置`);
|
156
|
+
const basePath = loc?.filePath!;
|
152
157
|
return opt?.filePath
|
153
158
|
? opt.glob
|
154
|
-
? UtilFT.fileSearchGlob(process.cwd(),opt.filePath)
|
155
|
-
: typeof opt?.filePath==="string"
|
156
|
-
|
159
|
+
? UtilFT.fileSearchGlob(process.cwd(),opt.filePath,{normalize:"posix"})
|
160
|
+
: typeof opt?.filePath==="string"
|
161
|
+
? [opt?.filePath.replaceAll('\\','/')]
|
162
|
+
: opt?.filePath.map((filepath)=>filepath.replaceAll('\\','/'))
|
163
|
+
: [basePath.replace(/(.+)\.macro\.(js|ts|cjs|mjs)$/,"$1.$2").replaceAll('\\','/')];
|
157
164
|
}
|
158
165
|
const readFile = async (basePath:string)=>
|
159
166
|
(await fs.promises.readFile(basePath,'utf-8')).replaceAll("\r\n","\n");
|
160
|
-
const parseCodeText = async (codeText:string|((opt:
|
167
|
+
const parseCodeText = async (codeText:string|((opt:CodeTextOpt)=>string|Promise<string>),opt:CodeTextOpt)=>{
|
161
168
|
const strText = typeof codeText === "function" ? await codeText(opt) : codeText;
|
162
169
|
return strText.split('\n').map((line)=>`${opt.inent}${line}`).join('\n');
|
163
170
|
}
|
171
|
+
const literalRegex = (str:string)=>new RegExp(
|
172
|
+
`^${str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')}(?!\\S)`);
|
164
173
|
//#endregion
|
165
174
|
/**将codeText写入对应region
|
166
175
|
* @param regionId - 区域id \`//#region ${id}\`
|
167
176
|
* @param codeText - 文本
|
168
177
|
* @param opt - 可选参数
|
169
|
-
* @param opt.
|
178
|
+
* @param opt.filePath - 目标文件 默认为去除".macro"的同名文件
|
179
|
+
* @param opt.glob - 使用glob匹配而非文件路径
|
170
180
|
*/
|
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
|
-
}
|
181
|
+
export async function regionMacro(regionId:string|RegExp,codeText:string|((opt:CodeTextOpt)=>string|Promise<string>),opt?:MacroOpt){
|
177
182
|
const plist:Promise<void>[] = [];
|
178
|
-
const filePaths = parseMacroPaths(
|
183
|
+
const filePaths = parseMacroPaths(opt);
|
179
184
|
for(const filePath of filePaths){
|
180
185
|
const queuefunc = async ()=>{
|
181
186
|
if(!(await UtilFT.pathExists(filePath))) {
|
182
187
|
SLogger.error(`UtilDT.regionMacro ${filePath} 不存在`);
|
183
188
|
return
|
184
189
|
}
|
185
|
-
|
186
|
-
const
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
190
|
+
let fileText = await readFile(filePath);
|
191
|
+
const regex = new RegExp(
|
192
|
+
/(^|\n)([^\S\n]*)(\/\/#region (.*)\n)/.source+
|
193
|
+
/([\s\S]*?)/.source+
|
194
|
+
/([^\S\n]*\/\/#endregion(?!\S).*)/.source
|
195
|
+
,"g")
|
196
|
+
regex.lastIndex=0;
|
197
|
+
let match:RegExpExecArray|null;
|
198
|
+
let hasMatch = false;
|
199
|
+
while(match = regex.exec(fileText)){
|
200
|
+
const id = match[4];
|
201
|
+
const prefix = match[1];
|
202
|
+
const content = match[5];
|
203
|
+
const inent = match[2];
|
204
|
+
const comment = match[3];
|
205
|
+
const endcomment = match[6];
|
206
|
+
|
207
|
+
const idregex = typeof regionId === "string"
|
208
|
+
? literalRegex(regionId) : regionId;
|
209
|
+
let idmatch = idregex.exec(id);
|
210
|
+
if(idmatch==null) continue;
|
211
|
+
hasMatch=true;
|
212
|
+
const ol = fileText.length;
|
213
|
+
const parseCode = await parseCodeText(codeText,{
|
214
|
+
matchId :idmatch[0],
|
215
|
+
text :dedent(content),
|
216
|
+
inent ,
|
217
|
+
filePath
|
218
|
+
});
|
219
|
+
fileText = fileText.replace(match[0], `${prefix}${inent}${comment}${parseCode}\n${endcomment}`);
|
220
|
+
regex.lastIndex += fileText.length - ol;
|
194
221
|
}
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
await fs.promises.writeFile(filePath, ntext, 'utf-8');
|
222
|
+
if(hasMatch)
|
223
|
+
await fs.promises.writeFile(filePath, fileText, 'utf-8');
|
224
|
+
else if(!opt?.glob) SLogger.error(`UtilDT.regionMacro 无法找到区域 ${regionId}`);
|
199
225
|
}
|
200
226
|
plist.push(UtilFunc.queueProc(path.posix.normalize(filePath.replaceAll("\\","/")),queuefunc))
|
201
227
|
}
|
@@ -208,38 +234,51 @@ export async function regionMacro(regionId:string,codeText:string|(()=>string|Pr
|
|
208
234
|
* @param opt.filePath - 目标文件 默认为去除".macro"的同名文件
|
209
235
|
* @param opt.glob - 使用glob匹配而非文件路径
|
210
236
|
*/
|
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
|
-
}
|
237
|
+
export async function commentMacro(commentId:string|RegExp,codeText:string|((opt:CodeTextOpt)=>string|Promise<string>),opt?:MacroOpt){
|
217
238
|
const plist:Promise<void>[] = [];
|
218
|
-
const filePaths = parseMacroPaths(
|
239
|
+
const filePaths = parseMacroPaths(opt);
|
219
240
|
for(const filePath of filePaths){
|
220
241
|
const queuefunc = async ()=>{
|
221
242
|
if(!(await UtilFT.pathExists(filePath))) {
|
222
243
|
SLogger.error(`UtilDT.commentMacro ${filePath} 不存在`);
|
223
244
|
return
|
224
245
|
}
|
225
|
-
|
226
|
-
const
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
246
|
+
let fileText = await readFile(filePath);
|
247
|
+
const regex = new RegExp(
|
248
|
+
/(^|\n)([^\S\n]*)(\/\/ (.*))(\n|)/.source+
|
249
|
+
/([^\n]*)/.source
|
250
|
+
,"g")
|
251
|
+
let match:RegExpExecArray|null;
|
252
|
+
let hasMatch = false;
|
253
|
+
while(match = regex.exec(fileText)){
|
254
|
+
const id = match[4];
|
255
|
+
const prefix = match[1];
|
256
|
+
const content = match[6];
|
257
|
+
const inent = match[2];
|
258
|
+
const comment = match[3];
|
259
|
+
|
260
|
+
const idregex = typeof commentId === "string"
|
261
|
+
? literalRegex(commentId) : commentId;
|
262
|
+
let idmatch = idregex.exec(id);
|
263
|
+
if(idmatch==null) continue;
|
264
|
+
hasMatch=true;
|
265
|
+
const ol = fileText.length;
|
266
|
+
const parseCode = await parseCodeText(codeText,{
|
267
|
+
matchId :idmatch[0],
|
268
|
+
text :dedent(content),
|
269
|
+
inent ,
|
270
|
+
filePath
|
271
|
+
});
|
272
|
+
if(parseCode.includes('\n')){
|
273
|
+
SLogger.error(`UtilDT.commentMacro 无法使用多行文本, 考虑使用regionMacro ${codeText}`);
|
274
|
+
return;
|
275
|
+
}
|
276
|
+
fileText = fileText.replace(match[0], `${prefix}${inent}${comment}\n${parseCode}`);
|
277
|
+
regex.lastIndex += fileText.length - ol;
|
240
278
|
}
|
241
|
-
|
242
|
-
|
279
|
+
if(hasMatch)
|
280
|
+
await fs.promises.writeFile(filePath, fileText, 'utf-8');
|
281
|
+
else if(!opt?.glob) SLogger.error(`UtilDT.commentMacro 无法找到注释 ${commentId}`);
|
243
282
|
}
|
244
283
|
plist.push(UtilFunc.queueProc(path.posix.normalize(filePath.replaceAll("\\","/")),queuefunc))
|
245
284
|
}
|
@@ -251,19 +290,14 @@ export async function commentMacro(commentId:string,codeText:string|(()=>string|
|
|
251
290
|
* @param opt.filePath - 目标文件 默认为去除".macro"的同名文件
|
252
291
|
* @param opt.glob - 使用glob匹配而非文件路径
|
253
292
|
*/
|
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
|
-
}
|
293
|
+
export async function fileMacro(codeText:string|((opt:CodeTextOpt)=>string|Promise<string>),opt?:MacroOpt){
|
260
294
|
const plist:Promise<void>[] = [];
|
261
|
-
const filePaths = parseMacroPaths(
|
295
|
+
const filePaths = parseMacroPaths(opt);
|
262
296
|
for(const filePath of filePaths){
|
263
297
|
const queuefunc = async ()=>{
|
264
298
|
await UtilFT.ensurePathExists(filePath);
|
265
299
|
const text = await readFile(filePath);
|
266
|
-
const parseCode = await parseCodeText(codeText,{text,inent:'',filePath});
|
300
|
+
const parseCode = await parseCodeText(codeText,{matchId:'',text,inent:'',filePath});
|
267
301
|
await fs.promises.writeFile(filePath, parseCode, 'utf-8');
|
268
302
|
}
|
269
303
|
plist.push(UtilFunc.queueProc(path.posix.normalize(filePath.replaceAll("\\","/")),queuefunc))
|
package/src/UtilMacro.ts
ADDED
@@ -0,0 +1,24 @@
|
|
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})=>{
|
13
|
+
const globp = /export (\S*)/.exec(matchId)![1];
|
14
|
+
const basedir = path.dirname(filePath).replaceAll('\\','/');
|
15
|
+
const result = UtilFT.fileSearchGlob(basedir,globp,{normalize:'posix'})
|
16
|
+
.map((file)=>path.posix.relative(basedir,file))
|
17
|
+
.map((file)=>path.parse(file).name)
|
18
|
+
.filter((file)=>file!=path.parse(filePath).name)
|
19
|
+
.map((file)=>`export * from './${file}'`)
|
20
|
+
.join(';');
|
21
|
+
return result;
|
22
|
+
},{glob:true,filePath:glob});
|
23
|
+
}
|
24
|
+
}
|
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 *
|