@zwa73/dev-utils 1.0.37 → 1.0.38

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.
@@ -1,2 +1,2 @@
1
1
  import { UtilDT } from "./UtilDevTool";
2
- export declare const regionMacro: typeof UtilDT.regionMacro;
2
+ export declare const regionMacro: typeof UtilDT.regionMacro, fileMacro: typeof UtilDT.fileMacro, commentMacro: typeof UtilDT.commentMacro;
package/dist/QuickFunc.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.regionMacro = void 0;
3
+ exports.commentMacro = exports.fileMacro = exports.regionMacro = void 0;
4
4
  const UtilDevTool_1 = require("./UtilDevTool");
5
- exports.regionMacro = UtilDevTool_1.UtilDT.regionMacro;
5
+ exports.regionMacro = UtilDevTool_1.UtilDT.regionMacro, exports.fileMacro = UtilDevTool_1.UtilDT.fileMacro, exports.commentMacro = UtilDevTool_1.UtilDT.commentMacro;
@@ -47,16 +47,33 @@ export declare namespace UtilDT {
47
47
  */
48
48
  export function batchNode(filepath: string | string[], opt?: BatchNodeOpt): Promise<void>;
49
49
  /**宏的可选参数 */
50
- type MacroOpt = {
50
+ type MacroOpt = Partial<{
51
51
  /**宏展开的目标文件 */
52
- targetPath: string;
53
- };
52
+ filePath: string[] | string;
53
+ /**使用glob匹配而非文件路径 */
54
+ glob: boolean;
55
+ }>;
54
56
  /**将codeText写入对应region
55
- * @param regionId - 区域id
57
+ * @param regionId - 区域id \`//#region ${id}\`
56
58
  * @param codeText - 文本
57
59
  * @param opt - 可选参数
58
60
  * @param opt.targetPath - 目标文件 默认为去除".macro"的同名文件
59
61
  */
60
62
  export function regionMacro(regionId: string, codeText: string | (() => string | Promise<string>), opt?: MacroOpt): Promise<void>;
63
+ /**将codeText写入对应注释下
64
+ * @param commentId - 注释id \`// ${id}\`
65
+ * @param codeText - 文本
66
+ * @param opt - 可选参数
67
+ * @param opt.filePath - 目标文件 默认为去除".macro"的同名文件
68
+ * @param opt.glob - 使用glob匹配而非文件路径
69
+ */
70
+ export function commentMacro(commentId: string, codeText: string | (() => string | Promise<string>), opt?: MacroOpt): Promise<void>;
71
+ /**将codeText写入对应文件 不存在则创建
72
+ * @param codeText - 文本
73
+ * @param opt - 可选参数
74
+ * @param opt.filePath - 目标文件 默认为去除".macro"的同名文件
75
+ * @param opt.glob - 使用glob匹配而非文件路径
76
+ */
77
+ export function fileMacro(codeText: string | (() => string | Promise<string>), opt?: MacroOpt): Promise<void>;
61
78
  export {};
62
79
  }
@@ -132,8 +132,22 @@ var UtilDT;
132
132
  await utils_1.UtilFunc.exec(cmd, { outlvl: 'info', errlvl: 'warn' });
133
133
  }
134
134
  UtilDT.batchNode = batchNode;
135
+ //#region macro工具
136
+ const parseMacroPaths = (basePath, opt) => {
137
+ return opt?.filePath
138
+ ? opt.glob
139
+ ? utils_1.UtilFT.fileSearchGlob(process.cwd(), opt.filePath)
140
+ : typeof opt?.filePath === "string" ? [opt?.filePath] : opt?.filePath
141
+ : [basePath.replace(/(.+)\.macro\.(js|ts|cjs|mjs)$/, "$1.$2")];
142
+ };
143
+ const readFile = async (basePath) => (await fs.promises.readFile(basePath, 'utf-8')).replaceAll("\r\n", "\n");
144
+ const parseCodeText = async (codeText, opt) => {
145
+ const strText = typeof codeText === "function" ? await codeText(opt) : codeText;
146
+ return strText.split('\n').map((line) => `${opt.inent}${line}`).join('\n');
147
+ };
148
+ //#endregion
135
149
  /**将codeText写入对应region
136
- * @param regionId - 区域id
150
+ * @param regionId - 区域id \`//#region ${id}\`
137
151
  * @param codeText - 文本
138
152
  * @param opt - 可选参数
139
153
  * @param opt.targetPath - 目标文件 默认为去除".macro"的同名文件
@@ -141,34 +155,104 @@ var UtilDT;
141
155
  async function regionMacro(regionId, codeText, opt) {
142
156
  const loc = utils_1.UtilFunc.getFuncLoc(2);
143
157
  if (!loc) {
144
- utils_1.SLogger.error(`UtilDT.macro 未能找到函数位置`);
158
+ utils_1.SLogger.error(`UtilDT.regionMacro 未能找到函数位置`);
145
159
  return;
146
160
  }
147
- ;
148
- const baseFilePath = opt?.targetPath
149
- ? path.resolve(process.cwd(), opt.targetPath)
150
- : loc.filePath.replace(/(.+)\.macro\.(js|ts|cjs|mjs)$/, "$1.$2");
151
- const queuefunc = async () => {
152
- if (!(await utils_1.UtilFT.pathExists(baseFilePath))) {
153
- utils_1.SLogger.error(`UtilDT.macro ${baseFilePath} 不存在`);
154
- return;
155
- }
156
- ;
157
- const text = (await fs.promises.readFile(baseFilePath, 'utf-8')).replaceAll("\r\n", "\n");
158
- const getregex = () => new RegExp(`([^\\S\\n]*)(//#region ${regionId}(?!\\S).*\\n)` +
159
- /([\s\S]*?)/.source +
160
- /([^\S\n]*\/\/#endregion(?!\S).*)/.source, "g");
161
- if (!(getregex().test(text))) {
162
- utils_1.SLogger.error(`UtilDT.macro 无法找到区域 ${regionId}`);
163
- return;
164
- }
165
- const match = getregex().exec(text);
166
- const strText = typeof codeText === "function" ? await codeText() : codeText;
167
- const mapText = strText.split('\n').map((line) => `${match[1]}${line}`).join('\n');
168
- const ntext = text.replace(getregex(), `$1$2${mapText}\n$4`);
169
- await fs.promises.writeFile(baseFilePath, ntext, 'utf-8');
170
- };
171
- await utils_1.UtilFunc.queueProc(path.posix.normalize(baseFilePath.replaceAll("\\", "/")), queuefunc);
161
+ const plist = [];
162
+ const filePaths = parseMacroPaths(loc.filePath, opt);
163
+ for (const filePath of filePaths) {
164
+ const queuefunc = async () => {
165
+ if (!(await utils_1.UtilFT.pathExists(filePath))) {
166
+ utils_1.SLogger.error(`UtilDT.regionMacro ${filePath} 不存在`);
167
+ return;
168
+ }
169
+ const text = await readFile(filePath);
170
+ const getregex = () => new RegExp(`([^\\S\\n]*)(//#region ${regionId}(?!\\S).*\\n)` +
171
+ /([\s\S]*?)/.source +
172
+ /([^\S\n]*\/\/#endregion(?!\S).*)/.source, "g");
173
+ if (!getregex().test(text)) {
174
+ if (!opt?.glob)
175
+ utils_1.SLogger.error(`UtilDT.regionMacro 无法找到区域 ${regionId}`);
176
+ return;
177
+ }
178
+ const match = getregex().exec(text);
179
+ const parseCode = await parseCodeText(codeText, { text: (0, utils_1.dedent)(match[3]), inent: match[1], filePath });
180
+ const ntext = text.replace(getregex(), `$1$2${parseCode}\n$4`);
181
+ await fs.promises.writeFile(filePath, ntext, 'utf-8');
182
+ };
183
+ plist.push(utils_1.UtilFunc.queueProc(path.posix.normalize(filePath.replaceAll("\\", "/")), queuefunc));
184
+ }
185
+ await Promise.all(plist);
172
186
  }
173
187
  UtilDT.regionMacro = regionMacro;
188
+ /**将codeText写入对应注释下
189
+ * @param commentId - 注释id \`// ${id}\`
190
+ * @param codeText - 文本
191
+ * @param opt - 可选参数
192
+ * @param opt.filePath - 目标文件 默认为去除".macro"的同名文件
193
+ * @param opt.glob - 使用glob匹配而非文件路径
194
+ */
195
+ 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
+ const plist = [];
202
+ const filePaths = parseMacroPaths(loc.filePath, opt);
203
+ for (const filePath of filePaths) {
204
+ const queuefunc = async () => {
205
+ if (!(await utils_1.UtilFT.pathExists(filePath))) {
206
+ utils_1.SLogger.error(`UtilDT.commentMacro ${filePath} 不存在`);
207
+ return;
208
+ }
209
+ const text = await readFile(filePath);
210
+ const getregex = () => new RegExp(`([^\\S\\n]*)(// ${commentId}(?!\\S).*)` +
211
+ /(\n|)/.source +
212
+ /([^\n]*)/.source, "g");
213
+ if (!getregex().test(text)) {
214
+ if (!opt?.glob)
215
+ utils_1.SLogger.error(`UtilDT.commentMacro 无法找到注释 ${commentId}`);
216
+ return;
217
+ }
218
+ const match = getregex().exec(text);
219
+ const parseCode = await parseCodeText(codeText, { text: match[3], inent: match[1], filePath });
220
+ if (parseCode.includes('\n')) {
221
+ utils_1.SLogger.error(`UtilDT.commentMacro 无法使用多行文本, 考虑使用regionMacro ${codeText}`);
222
+ return;
223
+ }
224
+ const ntext = text.replace(getregex(), `$1$2\n${parseCode}`);
225
+ await fs.promises.writeFile(filePath, ntext, 'utf-8');
226
+ };
227
+ plist.push(utils_1.UtilFunc.queueProc(path.posix.normalize(filePath.replaceAll("\\", "/")), queuefunc));
228
+ }
229
+ await Promise.all(plist);
230
+ }
231
+ UtilDT.commentMacro = commentMacro;
232
+ /**将codeText写入对应文件 不存在则创建
233
+ * @param codeText - 文本
234
+ * @param opt - 可选参数
235
+ * @param opt.filePath - 目标文件 默认为去除".macro"的同名文件
236
+ * @param opt.glob - 使用glob匹配而非文件路径
237
+ */
238
+ 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
+ const plist = [];
245
+ const filePaths = parseMacroPaths(loc.filePath, opt);
246
+ for (const filePath of filePaths) {
247
+ const queuefunc = async () => {
248
+ await utils_1.UtilFT.ensurePathExists(filePath);
249
+ const text = await readFile(filePath);
250
+ const parseCode = await parseCodeText(codeText, { text, inent: '', filePath });
251
+ await fs.promises.writeFile(filePath, parseCode, 'utf-8');
252
+ };
253
+ plist.push(utils_1.UtilFunc.queueProc(path.posix.normalize(filePath.replaceAll("\\", "/")), queuefunc));
254
+ }
255
+ await Promise.all(plist);
256
+ }
257
+ UtilDT.fileMacro = fileMacro;
174
258
  })(UtilDT || (exports.UtilDT = UtilDT = {}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zwa73/dev-utils",
3
- "version": "1.0.37",
3
+ "version": "1.0.38",
4
4
  "description": "编译与调试工具",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -16,13 +16,14 @@
16
16
  "author": "zwa73",
17
17
  "license": "ISC",
18
18
  "dependencies": {
19
- "@zwa73/utils": "^1.0.114",
19
+ "@zwa73/utils": "^1.0.117",
20
20
  "commander": "^11.1.0",
21
21
  "ts-node": "^10.9.2",
22
22
  "tsconfig-paths": "^4.2.0",
23
23
  "typescript-json-schema": "^0.63.0"
24
24
  },
25
25
  "devDependencies": {
26
+ "@types/fluent-ffmpeg": "^2.1.24",
26
27
  "@types/jest": "^29.5.12",
27
28
  "@types/node": "^20.11.19",
28
29
  "jest": "^29.7.0",
package/src/QuickFunc.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import { UtilDT } from "./UtilDevTool";
2
2
 
3
3
  export const {
4
- regionMacro
4
+ regionMacro ,
5
+ fileMacro ,
6
+ commentMacro,
5
7
  } = UtilDT;
@@ -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, getFuncLoc } from '@zwa73/utils';
4
+ import { JObject, SLogger, UtilFT, UtilFunc, dedent } from '@zwa73/utils';
5
5
 
6
6
  export namespace UtilDT{
7
7
 
@@ -132,13 +132,38 @@ export async function batchNode(filepath:string|string[],opt?:BatchNodeOpt) {
132
132
  }
133
133
 
134
134
  /**宏的可选参数 */
135
- type MacroOpt = {
135
+ type MacroOpt = Partial<{
136
136
  /**宏展开的目标文件 */
137
- targetPath:string;
137
+ filePath:string[]|string;
138
+ /**使用glob匹配而非文件路径 */
139
+ glob:boolean;
140
+ }>
141
+ /**codeText的参数 */
142
+ type CdeeTextOpt = {
143
+ /**展开宏的目标文件 */
144
+ filePath:string;
145
+ /**展开宏区域的原文本 */
146
+ text:string;
147
+ /**缩进 会自动应用 */
148
+ inent:string;
138
149
  }
139
-
150
+ //#region macro工具
151
+ const parseMacroPaths = (basePath:string,opt?:MacroOpt)=>{
152
+ return opt?.filePath
153
+ ? opt.glob
154
+ ? UtilFT.fileSearchGlob(process.cwd(),opt.filePath)
155
+ : typeof opt?.filePath==="string" ? [opt?.filePath] : opt?.filePath
156
+ : [basePath.replace(/(.+)\.macro\.(js|ts|cjs|mjs)$/,"$1.$2")];
157
+ }
158
+ const readFile = async (basePath:string)=>
159
+ (await fs.promises.readFile(basePath,'utf-8')).replaceAll("\r\n","\n");
160
+ const parseCodeText = async (codeText:string|((opt:CdeeTextOpt)=>string|Promise<string>),opt:CdeeTextOpt)=>{
161
+ const strText = typeof codeText === "function" ? await codeText(opt) : codeText;
162
+ return strText.split('\n').map((line)=>`${opt.inent}${line}`).join('\n');
163
+ }
164
+ //#endregion
140
165
  /**将codeText写入对应region
141
- * @param regionId - 区域id
166
+ * @param regionId - 区域id \`//#region ${id}\`
142
167
  * @param codeText - 文本
143
168
  * @param opt - 可选参数
144
169
  * @param opt.targetPath - 目标文件 默认为去除".macro"的同名文件
@@ -146,33 +171,103 @@ type MacroOpt = {
146
171
  export async function regionMacro(regionId:string,codeText:string|(()=>string|Promise<string>),opt?:MacroOpt){
147
172
  const loc = UtilFunc.getFuncLoc(2);
148
173
  if(!loc){
149
- SLogger.error(`UtilDT.macro 未能找到函数位置`);
174
+ SLogger.error(`UtilDT.regionMacro 未能找到函数位置`);
150
175
  return
151
- };
152
- const baseFilePath = opt?.targetPath
153
- ? path.resolve(process.cwd(),opt.targetPath)
154
- : loc.filePath.replace(/(.+)\.macro\.(js|ts|cjs|mjs)$/,"$1.$2");
155
- const queuefunc = async ()=>{
156
- if(!(await UtilFT.pathExists(baseFilePath))) {
157
- SLogger.error(`UtilDT.macro ${baseFilePath} 不存在`);
158
- return
159
- };
160
- const text = (await fs.promises.readFile(baseFilePath,'utf-8')).replaceAll("\r\n","\n");
161
- const getregex = ()=>new RegExp(
162
- `([^\\S\\n]*)(//#region ${regionId}(?!\\S).*\\n)`+
163
- /([\s\S]*?)/.source+
164
- /([^\S\n]*\/\/#endregion(?!\S).*)/.source
165
- ,"g");
166
- if (!(getregex().test(text))) {
167
- SLogger.error(`UtilDT.macro 无法找到区域 ${regionId}`);
168
- return;
176
+ }
177
+ const plist:Promise<void>[] = [];
178
+ const filePaths = parseMacroPaths(loc.filePath,opt);
179
+ for(const filePath of filePaths){
180
+ const queuefunc = async ()=>{
181
+ if(!(await UtilFT.pathExists(filePath))) {
182
+ SLogger.error(`UtilDT.regionMacro ${filePath} 不存在`);
183
+ return
184
+ }
185
+ const text = await readFile(filePath);
186
+ const getregex = ()=>new RegExp(
187
+ `([^\\S\\n]*)(//#region ${regionId}(?!\\S).*\\n)`+
188
+ /([\s\S]*?)/.source+
189
+ /([^\S\n]*\/\/#endregion(?!\S).*)/.source
190
+ ,"g");
191
+ if (!getregex().test(text)) {
192
+ if(!opt?.glob) SLogger.error(`UtilDT.regionMacro 无法找到区域 ${regionId}`);
193
+ return;
194
+ }
195
+ const match = getregex().exec(text)!;
196
+ const parseCode = await parseCodeText(codeText,{text:dedent(match[3]),inent:match[1],filePath});
197
+ const ntext = text.replace(getregex(), `$1$2${parseCode}\n$4`);
198
+ await fs.promises.writeFile(filePath, ntext, 'utf-8');
199
+ }
200
+ plist.push(UtilFunc.queueProc(path.posix.normalize(filePath.replaceAll("\\","/")),queuefunc))
201
+ }
202
+ await Promise.all(plist);
203
+ }
204
+ /**将codeText写入对应注释下
205
+ * @param commentId - 注释id \`// ${id}\`
206
+ * @param codeText - 文本
207
+ * @param opt - 可选参数
208
+ * @param opt.filePath - 目标文件 默认为去除".macro"的同名文件
209
+ * @param opt.glob - 使用glob匹配而非文件路径
210
+ */
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
+ }
217
+ const plist:Promise<void>[] = [];
218
+ const filePaths = parseMacroPaths(loc.filePath,opt);
219
+ for(const filePath of filePaths){
220
+ const queuefunc = async ()=>{
221
+ if(!(await UtilFT.pathExists(filePath))) {
222
+ SLogger.error(`UtilDT.commentMacro ${filePath} 不存在`);
223
+ return
224
+ }
225
+ const text = await readFile(filePath);
226
+ const getregex = ()=>new RegExp(
227
+ `([^\\S\\n]*)(// ${commentId}(?!\\S).*)`+
228
+ /(\n|)/.source +
229
+ /([^\n]*)/.source
230
+ ,"g");
231
+ if (!getregex().test(text)) {
232
+ if(!opt?.glob) SLogger.error(`UtilDT.commentMacro 无法找到注释 ${commentId}`);
233
+ return;
234
+ }
235
+ const match = getregex().exec(text)!;
236
+ const parseCode = await parseCodeText(codeText,{text:match[3],inent:match[1],filePath});
237
+ if(parseCode.includes('\n')){
238
+ SLogger.error(`UtilDT.commentMacro 无法使用多行文本, 考虑使用regionMacro ${codeText}`);
239
+ return;
240
+ }
241
+ const ntext = text.replace(getregex(), `$1$2\n${parseCode}`);
242
+ await fs.promises.writeFile(filePath, ntext, 'utf-8');
243
+ }
244
+ plist.push(UtilFunc.queueProc(path.posix.normalize(filePath.replaceAll("\\","/")),queuefunc))
245
+ }
246
+ await Promise.all(plist);
247
+ }
248
+ /**将codeText写入对应文件 不存在则创建
249
+ * @param codeText - 文本
250
+ * @param opt - 可选参数
251
+ * @param opt.filePath - 目标文件 默认为去除".macro"的同名文件
252
+ * @param opt.glob - 使用glob匹配而非文件路径
253
+ */
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
+ }
260
+ const plist:Promise<void>[] = [];
261
+ const filePaths = parseMacroPaths(loc.filePath,opt);
262
+ for(const filePath of filePaths){
263
+ const queuefunc = async ()=>{
264
+ await UtilFT.ensurePathExists(filePath);
265
+ const text = await readFile(filePath);
266
+ const parseCode = await parseCodeText(codeText,{text,inent:'',filePath});
267
+ await fs.promises.writeFile(filePath, parseCode, 'utf-8');
169
268
  }
170
- const match = getregex().exec(text)!;
171
- const strText = typeof codeText === "function" ? await codeText() : codeText;
172
- const mapText = strText.split('\n').map((line)=>`${match[1]}${line}`).join('\n');
173
- const ntext = text.replace(getregex(), `$1$2${mapText}\n$4`);
174
- await fs.promises.writeFile(baseFilePath, ntext, 'utf-8');
269
+ plist.push(UtilFunc.queueProc(path.posix.normalize(filePath.replaceAll("\\","/")),queuefunc))
175
270
  }
176
- await UtilFunc.queueProc(path.posix.normalize(baseFilePath.replaceAll("\\","/")),queuefunc);
271
+ await Promise.all(plist);
177
272
  }
178
273
  }
@@ -1,4 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "include": ["./src/**/*.ts", "./src/**/*.js"]
4
- }
@@ -1,22 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "allowJs": true,
4
- "strict": true,
5
- "target": "ES2022",
6
- "module": "CommonJS",
7
- "moduleResolution": "node",
8
- "esModuleInterop": true,
9
- "outDir": "./dist",
10
- "declaration": true,
11
- "baseUrl": ".",
12
- "emitDecoratorMetadata": true,
13
- "experimentalDecorators": true,
14
- "paths": {
15
- "@src/*": ["./src/*"],
16
- "@/*": ["./*"],
17
- "@": ["./src/index"]
18
- }
19
- },
20
- "include": ["./src/**/*.ts", "./src/**/*.js", "./jest/**/*.ts"],
21
- "exclude": ["./node_modules/**/*"]
22
- }
@@ -1,4 +0,0 @@
1
- {
2
- "extends": "./tsconfig.json",
3
- "include": ["./src/**/*.ts", "./src/**/*.js"]
4
- }
package/tsconfig.json DELETED
@@ -1,22 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "allowJs": true,
4
- "strict": true,
5
- "target": "ES2022",
6
- "module": "commonjs",
7
- "moduleResolution": "node",
8
- "esModuleInterop": true,
9
- "outDir": "./dist",
10
- "declaration": true,
11
- "baseUrl": ".",
12
- "emitDecoratorMetadata": true,
13
- "experimentalDecorators": true,
14
- "paths": {
15
- "@src/*": ["./src/*"],
16
- "@/*" : ["./*"],
17
- "@" : ["./src/index"]
18
- }
19
- },
20
- "include": ["./src/**/*.ts", "./src/**/*.js","./jest/**/*.ts"],
21
- "exclude": ["./node_modules/**/*"]
22
- }