js-dev-tool 1.0.14 → 1.0.16

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/README.md CHANGED
@@ -37,12 +37,13 @@ rws help: (R)ecord(W)ebpack(S)ize
37
37
  dest - if not specified then apply "./logs/webpack-size.json"
38
38
 
39
39
  cjbm help: (C)onvert (J)S to (B)rowser (M)odule
40
- ex - jstool -cmd cjbm [-root ./build | -basePath "./dist/esm,extra-tests/mini-semaphore"] [-ext js] [-targets "['core.js', 'object.js']"]
40
+ ex - jstool -cmd cjbm [-root ./build | -basePath "./dist/esm,extra-tests/mini-semaphore"] [-ext js] [-test /\.js$/] [-targets "['core.js', 'object.js']"]
41
41
  note:
42
42
  root - Recursively searches for files.
43
43
  This option is useful, but if there are directories that need to be avoided, use the 'basePath' option
44
44
  basePath - can be "<path>,<path>,..." (array type arg)
45
45
  ext - specifies the module extension for import clauses. default is "js"
46
+ test - Any file extension can be specified. (The default is /\.js$/)
46
47
  targets - specify this if you want to apply it only to a specific file.
47
48
  the file specified here should be directly under `basePath`!
48
49
  value must be array type arg, "['<path>', '<path>',...]" or "<path>,<path>,..."
@@ -75,12 +76,15 @@ minify help: jstool -cmd minify -basePath extra-tests/web/mini-semaphore [-test
75
76
  test - can be omit, default is `/\.js$/`
76
77
  suffix - can be omit, default is ".mini"
77
78
 
78
- rmc help: $ jstool -cmd rmc -basePath "./dist/cjs,./dist/cjs/gulp" -test "/\.(js|d\.ts)$/"
79
+ rmc help: $ jstool -cmd rmc [-rmc4ts[:keepBangLine]] -basePath "./dist/cjs,./dist/cjs/gulp" -test "/\.(js|d\.ts)$/"
79
80
  note: basePath - can be "<path>,<path>,..." (array type arg)
80
- test - can be omit, defulat `/.js$/`
81
- rmc4ts - for typescript source.
81
+ test - can be omit, defulat `/.js$/`
82
+ rmc4ts- for typescript source.
82
83
  keep comment that start with "/*" when "*/" end mark appears in same line.
83
84
  if start with "/*-" remove it
85
+ rmc4ts=keepBangLine (2025/12/24)
86
+ - In addition to the "rmc4ts" processing, it also preserves line comments that start with "//!".
87
+
84
88
  ```
85
89
 
86
90
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js-dev-tool",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
4
4
  "bin": {
5
5
  "jstool": "tools.js"
6
6
  },
package/regex.d.ts CHANGED
@@ -8,14 +8,49 @@
8
8
  /**
9
9
  * @file js-dev-scripts/regex.d.ts
10
10
  */
11
+ declare global {
12
+ interface RegExp/* extends TypedRegExp<string, string>*/ {
13
+ /**
14
+ * Executes a search on a string using a regular expression pattern, and returns an array containing the results of that search.
15
+ * @param string The String object or string literal on which to perform the search.
16
+ */
17
+ exec<const P extends string, const F extends string = "">(this: TypedRegExp<P, F>, string: string): RegExpExecArrayFixed< this > | null;
18
+ }
19
+ interface RegExpConstructor {
20
+ new <const P extends string, const F extends string = "">(pattern: P, flags?: F): RegExp & {
21
+ readonly source: P;
22
+ readonly flags: F;
23
+ };
24
+ <const P extends string, const F extends string = "">(pattern: P, flags?: F): RegExp & {
25
+ readonly source: P;
26
+ readonly flags: F;
27
+ };
28
+ readonly "prototype": RegExp;
29
+ }
30
+ }
31
+ /*!
32
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
33
+ // Basics
34
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
35
+ */
11
36
  /**
12
37
  * Extracts the literal type from the source property of a RegExp.
13
38
  * @template R - A RegExp type.
14
39
  */
15
40
  export type ReSource<R extends RegExp> = R extends RegExp & { readonly source: infer T } ? T : never;
16
- export declare function createRegExp<P extends string>(pattern: P, flags?: string): RegExp & {
41
+ export type TypedRegExp<const P extends string, const F extends string = ""> = RegExp & {
17
42
  readonly source: P;
43
+ readonly flags: F;
18
44
  };
45
+ export declare function createRegExp<
46
+ const P extends string,
47
+ const F extends string = ""
48
+ >(pattern: P, flags?: F): TypedRegExp<P, F>;
49
+ /*!
50
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
51
+ // Named Capture Groups
52
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
53
+ */
19
54
  type FirstChar<S extends string> = S extends `${infer F}${infer _}` ? F : never;
20
55
  /**
21
56
  * Recursively extracts parts that match the format (?<GroupName>...) from a string pattern,
@@ -34,41 +69,43 @@ export type ExtractGroupNames<S extends string> =
34
69
  * Creates an object type with keys as the extracted group names and values as strings.
35
70
  * If no groups are found, it results in an empty object.
36
71
  * @template R - A RegExp type.
72
+ * @date 2025/12/24 14:46:30 - It may be possible to extract the group name accurately (?)
37
73
  */
38
- export type ReGroups<R extends RegExp> = {
39
- [K in ExtractGroupNames<ReSource<R>>]?: string;
40
- };
41
- export type PreprocessEscapes<S extends string, Result extends string = ""> =
74
+ export type ReGroups<R extends RegExp> = R extends (/*RegExp &*/ { readonly source: infer T })
75
+ ? {
76
+ [K in ExtractGroupNames<T>]?: string;
77
+ } : never;
78
+ /**
79
+ * Preprocesses escape sequences in a string pattern by replacing escaped backslashes and characters.
80
+ *
81
+ * + NOTE: This type is used to preprocess the pattern string before counting capture groups.
82
+ *
83
+ * @template S - A string pattern.
84
+ * @template Result - The resulting string after preprocessing.
85
+ * @internal
86
+ */
87
+ export type __PreprocessEscapes<S extends string, Result extends string = ""> =
42
88
  S extends `\\\\${infer Rest}`
43
- ? PreprocessEscapes<Rest, `${Result}__`>
89
+ ? __PreprocessEscapes<Rest, `${Result}__`>
44
90
  : S extends `\\${infer Next}${infer Rest}`
45
- ? PreprocessEscapes<Rest, `${Result}_`>
91
+ ? __PreprocessEscapes<Rest, `${Result}_!`>
46
92
  : S extends `${infer Char}${infer Rest}`
47
- ? PreprocessEscapes<Rest, `${Result}${Char}`>
93
+ ? __PreprocessEscapes<Rest, `${Result}${Char}`>
48
94
  : Result;
49
95
  /**
50
96
  * Counts the exact number of capture groups in a string pattern.
51
97
  * @template S - A string pattern.
52
98
  * @template Counter - An array used to count the capture groups.
53
- *
54
- * @todo FIXME: 多く count してしまう場合あり. 2025/3/18 15:47:57
55
- * @deprecated text base の parse には限界があり cost が見合わないので、この type は将来削除予定!
56
99
  */
57
100
  export type CountCaptureGroups<
58
101
  S extends string,
59
102
  Counter extends unknown[] = []
60
103
  > =
61
- S extends `${infer _Before}(${infer Rest}`
62
- ? _Before extends "\\"
63
- ? never
64
- : Rest extends `?:${infer After}`
65
- | `?=${infer After}`
66
- | `?!${infer After}`
67
- | `?<=${infer After}`
68
- | `?<!${infer After}`
69
- ? CountCaptureGroups<After, Counter>
104
+ __PreprocessEscapes<S> extends `${infer _Before}(${infer Rest}`
105
+ ? Rest extends `${"?:" | "?=" | "?!" | "?<=" | "?<!"}${infer After}`
106
+ ? CountCaptureGroups<After, Counter>
70
107
  : CountCaptureGroups<Rest, [...Counter, unknown]>
71
- : Counter['length'];
108
+ : Counter["length"];
72
109
  /**
73
110
  * Represents a fixed version of RegExpExecArray that includes the matched string,
74
111
  * captures, and optionally named groups.
@@ -79,20 +116,31 @@ export type CountCaptureGroups<
79
116
  export type RegExpExecArrayFixed<
80
117
  R extends RegExp,
81
118
  S extends ReSource<R> = ReSource<R>,
82
- GroupCount extends number = CountCaptureGroups<
83
- PreprocessEscapes<S>
84
- >
85
- > = [match: string, ...ExtractCaptures<GroupCount>] & {
119
+ GroupCount extends number = CountCaptureGroups<S>
120
+ > = [match: string, ...BuildCaptureTuple<GroupCount>] & {
86
121
  groups?: ReGroups<R>;
122
+ index: number;
123
+ input: string;
87
124
  };
125
+ export type TupleOf<
126
+ Count extends number, ArrayType,
127
+ Result extends ArrayType[] = []
128
+ > = Result["length"] extends Count
129
+ ? Result
130
+ : TupleOf<Count, ArrayType, [...Result, ArrayType]>;
88
131
  /**
89
- * Generates an array type with a length corresponding to the number of capture groups.
90
- * @template Count - The number of capture groups.
91
- * @template Result - The resulting array type.
132
+ * Builds a tuple type whose length equals the number of capture groups.
133
+ * @template Count - Number of capture groups.
134
+ * @template Result - Accumulator (internal).
92
135
  */
93
- export type ExtractCaptures<Count extends number, Result extends unknown[] = []> =
94
- Result['length'] extends Count
95
- ? Result : ExtractCaptures<Count, [...Result, string]>;
136
+ export type BuildCaptureTuple<
137
+ Count extends number, ArrayType = string,
138
+ > = TupleOf<Count, ArrayType>;
139
+ /*!
140
+ // ============================================================================
141
+ // Helper Types for Replacer
142
+ // ============================================================================
143
+ */
96
144
  /**
97
145
  * Creates the parameter types for String.replace callback function.
98
146
  *
@@ -103,12 +151,10 @@ export type ExtractCaptures<Count extends number, Result extends unknown[] = []>
103
151
  export type ReplaceCallbackParams<
104
152
  R extends RegExp,
105
153
  S extends ReSource<R> = ReSource<R>,
106
- GroupCount extends number = CountCaptureGroups<
107
- PreprocessEscapes<S>
108
- >
154
+ GroupCount extends number = CountCaptureGroups<S>
109
155
  > = [
110
156
  match: string,
111
- ...captures: ExtractCaptures<GroupCount>,
157
+ ...captures: BuildCaptureTuple<GroupCount>,
112
158
  offset: number,
113
159
  input: string,
114
160
  groups: ReGroups<R>
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "1.0.14"
2
+ "version": "1.0.16"
3
3
  }
package/tool-lib/cjbm.js CHANGED
@@ -6,49 +6,32 @@
6
6
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7
7
  */
8
8
  /// <reference path="./tools.d.ts"/>
9
- /// <reference path="../regex.d.ts"/>
10
9
  // @ts-check
11
10
  /**
12
11
  * @file (C)onvert (J)S to (B)rowser (M)odule
13
12
  */
14
13
  const fs = require("fs");
15
14
  const path = require("path");
16
- const RE_TEXT = String.raw`
17
- # NOTE: PCRE での検証時は line comment assertion を (?<!\/\/|\/\/\s)(?:(?<!@)import|export) とすること (regex101.com)
18
- # 正しくは: (?<!\s*\/\/+.*?)(?:(?<!@)import|export)
19
- (?<!\s*\/\/+.*?)(?:(?<!@)import|export)
20
- \s*
21
- (?:
22
- # 2025/12/22 14:57:44 - support quote character detection ["']
23
- # global import, import "./"; import './global.mjs';
24
- (?<qcGlobal>["'])(?!https?:)(?=[.\/]+)(?:
25
- (?<globalName>(?:[.\/]+)?[^'"]+?)(?:\.(?<globalExt>(?:c|m)?jsx?))?
26
- )\k<qcGlobal>|
27
- # dynamic import, import("...") import('...')
28
- \(\s*
29
- (?<qcDynamic>["'])(?!https?:)(?=[.\/]+)(?<dynamicName>(?:[.\/]+)?[^'"]+?)(?:\.(?<dynamicExt>(?:c|m)?jsx?))?\k<qcDynamic>
30
- \s*\)|
31
- # esm import/export
32
- (?:(?<clause>.+?|(?:\w+\s*,)?\s*\{[^}]+\})\s*from)\s*
33
- (?<qcEsm>["'])(?!https?:)(?=[.\/]+)
34
- (?:
35
- (?<moduleName>(?:[.\/]+)?[^'"]+?)(?:\.(?<moduleExt>(?:c|m)?jsx?))?
36
- )\k<qcEsm>
37
- )
38
- (?=\s*;)?
39
- `;
40
15
  /**
41
- * @date 2025/12/22 16:09:36
42
- * @see https://regex101.com/r/uMMsD4/31
16
+ * @type {typeof XRegex.createRegExp}
43
17
  */
44
- const reImportExportDetection = new RegExp(
45
- RE_TEXT.replace(/\s*\(\?\#.*\)\s*$|(?<!\\)\#\s*.*$|\s+/gm, ""), "g",
18
+ function createRegExp(pattern, flags) {
19
+ return new RegExp(pattern, flags);
20
+ }
21
+ const reImportExportDetection = createRegExp(
22
+ `(?<!\\s*\\/\\/+.*?)(?:(?<!@)import|export)\\s*(?:(?<qcGlobal>["'])(?!https?:)(?=[.\\/]+)\
23
+ (?:(?<globalName>(?:[.\\/]+)?[^'"]+?)(?:\\.(?<globalExt>(?:c|m)?jsx?))?)\\k<qcGlobal>|\\(\\s*(?<qcDynamic>["'])(?!https?:)(?=[.\\/]+)(?<dynamicName>(?:[.\\/]+)?[^'"]+?)\
24
+ (?:\\.(?<dynamicExt>(?:c|m)?jsx?))?\\k<qcDynamic>\\s*\\)|(?:(?<clause>.+?|(?:\\w+\\s*,)?\\s*\\{[^}]+\\})\\s*from)\\s*(?<qcEsm>["'])(?!https?:)(?=[.\\/]+)\
25
+ (?:(?<moduleName>(?:[.\\/]+)?[^'"]+?)(?:\\.(?<moduleExt>(?:c|m)?jsx?))?)\\k<qcEsm>)(?=\\s*;)?`, "g"
46
26
  );
27
+ /**
28
+ * @typedef {XRegex.ReplacerFunctionSignature<typeof reImportExportDetection>} TImportExportDetectRegexReplacer
29
+ */
47
30
  /**
48
31
  * Generates a replacer function to update import/export statements with a new file extension.
49
32
  *
50
33
  * @param {string} ext - The new file extension to use.
51
- * @returns {TRegexImportExportDetectorReplacer} A function to update import/export statements with the specified file extension.
34
+ * @returns {TImportExportDetectRegexReplacer} A function to update import/export statements with the specified file extension.
52
35
  * @date 2025/2/16 18:38:39
53
36
  * @date 2025/12/22 16:05:13 - ./tool-lib/cjbm-resources/cjbm-browser-test.mjs を参照
54
37
  */
@@ -57,11 +40,18 @@ function getReplacer(ext) {
57
40
  * NOTE: Replacement is only performed with the syntax "$` is $1".
58
41
  * String concatenation is not allowed.
59
42
  */
60
- /** @type {TRegexImportExportDetectorReplacer} */
61
- const replacer = (
62
- $0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _offset, _input, { clause, dynamicName, globalName, moduleName, qcDynamic, qcEsm, qcGlobal }
43
+ /** @type {TImportExportDetectRegexReplacer} */
44
+ return (
45
+ match, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _offset, _input, groups
63
46
  ) => {
64
- const kword = $0.startsWith("import") ? "import" : "export";
47
+ const {
48
+ clause,
49
+ dynamicName,
50
+ globalName,
51
+ moduleName,
52
+ qcDynamic, qcEsm, qcGlobal,
53
+ } = groups;
54
+ const kword = match.startsWith("import") ? "import" : "export";
65
55
  const qc = qcDynamic || qcEsm || qcGlobal;
66
56
  let whichName = /** @type {string} */ (
67
57
  globalName || moduleName || dynamicName
@@ -79,7 +69,6 @@ function getReplacer(ext) {
79
69
  `(${modId})`
80
70
  }`;
81
71
  };
82
- return replacer;
83
72
  }
84
73
  /**
85
74
  * @param {string} ext
@@ -6,16 +6,10 @@
6
6
  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7
7
  */
8
8
  /// <reference path="../regex.d.ts"/>
9
- declare const ImportExportDetectRegex = `(?<!\\s*\\/\\/+.*?)(?:(?<!@)import|export)\\s*(?:(?<qcGlobal>["'])(?!https?:)(?=[.\\/]+)\
10
- (?:(?<globalName>(?:[.\\/]+)?[^'"]+?)(?:\\.(?<globalExt>(?:c|m)?jsx?))?)\\k<qcGlobal>|\\(\\s*(?<qcDynamic>["'])(?!https?:)(?=[.\\/]+)(?<dynamicName>(?:[.\\/]+)?[^'"]+?)\
11
- (?:\\.(?<dynamicExt>(?:c|m)?jsx?))?\\k<qcDynamic>\\s*\\)|(?:(?<clause>.+?|(?:\\w+\\s*,)?\\s*\\{[^}]+\\})\\s*from)\\s*(?<qcEsm>["'])(?!https?:)(?=[.\\/]+)\
12
- (?:(?<moduleName>(?:[.\\/]+)?[^'"]+?)(?:\\.(?<moduleExt>(?:c|m)?jsx?))?)\\k<qcEsm>)(?=\\s*;)?`;
13
- declare const reOk: ReturnType<typeof XRegex.createRegExp<typeof ImportExportDetectRegex>>;
14
9
  /**
15
10
  * @date 2023-10-25
16
11
  */
17
12
  declare global {
18
- type TRegexImportExportDetectorReplacer = XRegex.ReplacerFunctionSignature<typeof reOk>;
19
13
  declare function processSources(
20
14
  taskName: string,
21
15
  process: (source: string) => Promise<string> | string,
@@ -82,7 +76,7 @@ declare global {
82
76
  /** replace */
83
77
  regex: RegExp;
84
78
  /** rmc */
85
- rmc4ts: boolean;
79
+ rmc4ts: boolean | "keepBangLine";
86
80
  /**
87
81
  * webpacked source path.
88
82
  * @default `./dist/webpack/index.js`
package/tools.js CHANGED
@@ -206,9 +206,12 @@ const ToolFunctions = {
206
206
  fn() {
207
207
  const rmc = require("rm-cstyle-cmts");
208
208
  if (params.rmc4ts) {
209
+ const keepBangLine = params.rmc4ts === "keepBangLine";
209
210
  rmc.setListener(({ event, fragment }) => {
210
211
  if (event === /*EScannerEvent.MultiLineComment*/ 1) {
211
212
  return /^\/\*(\*|!)\s|^\/\*(?!-).+\*\/$/.test(fragment);
213
+ } else if (keepBangLine && event === /*EScannerEvent.SingleLineComment*/0) {
214
+ return /^\/\/+!/.test(fragment);
212
215
  }
213
216
  return false;
214
217
  });
@@ -228,12 +231,14 @@ const ToolFunctions = {
228
231
  },
229
232
  );
230
233
  },
231
- help: `$ jstool -cmd rmc -basePath "./dist/cjs,./dist/cjs/gulp" -test "/\\.(js|d\\.ts)$/"
234
+ help: `$ jstool -cmd rmc [-rmc4ts[:keepBangLine]] -basePath "./dist/cjs,./dist/cjs/gulp" -test "/\\.(js|d\\.ts)$/"
232
235
  note: basePath - can be "<path>,<path>,..." (array type arg)
233
- test - can be omit, defulat \`/\.js$/\`
234
- rmc4ts - for typescript source.
236
+ test - can be omit, defulat \`/\.js$/\`
237
+ rmc4ts- for typescript source.
235
238
  keep comment that start with "/*" when "*/" end mark appears in same line.
236
239
  if start with "/*-" remove it
240
+ rmc4ts=keepBangLine (2025/12/24)
241
+ - In addition to the "rmc4ts" processing, it also preserves line comments that start with "//!".
237
242
  `,
238
243
  },
239
244
  backup: {