pattern-collector-anyjs-story 1.16.2

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 KeshavSoft
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to do so, subject to the
10
+ following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,155 @@
1
+ # pattern-collector-anyjs-pull-lines 🔍
2
+
3
+ > **A powerful, configurable tool to scan JavaScript/ESM files and pull structured line matches using custom regular expressions.**
4
+
5
+ [![npm version](https://img.shields.io/npm/v/pattern-collector-anyjs-pull-lines.svg?style=flat-square&color=38bdf8)](https://www.npmjs.com/package/pattern-collector-anyjs-pull-lines)
6
+ [![license](https://img.shields.io/npm/l/pattern-collector-anyjs-pull-lines.svg?style=flat-square&color=34d399)](LICENSE)
7
+
8
+ 🔗 **Quick Links:**
9
+ * 📦 **NPM Registry**: [npmjs.com/package/pattern-collector-anyjs-pull-lines](https://www.npmjs.com/package/pattern-collector-anyjs-pull-lines)
10
+ * 💻 **GitHub Repo**: [github.com/keshavsoft/pattern-collector-anyjs-pull-lines](https://github.com/keshavsoft/pattern-collector-anyjs-pull-lines)
11
+ * 🌐 **Live Documentation**: [keshavsoft.github.io/pattern-collector-anyjs-pull-lines](https://keshavsoft.github.io/pattern-collector-anyjs-pull-lines/)
12
+
13
+
14
+ ---
15
+
16
+ ## 📖 Overview
17
+
18
+ `pattern-collector-anyjs-pull-lines` is a modular ES module that allows you to static-analyze JavaScript or ESM source code. It scans file contents to identify specific patterns (such as `import` statements or routing configurations) and extracts line details, line numbers, variable names, and directory paths.
19
+
20
+ This library is particularly useful for building automated routing trees, generating bundle maps, or auditing source code patterns.
21
+
22
+ ---
23
+
24
+ ## ✨ Features
25
+
26
+ - **🧩 Modular Design**: Leveraging clean, focused sub-modules for flexible ESM pattern extraction.
27
+ - **🏷️ Line Tracking**: Identifies exactly which line number each pattern appears on.
28
+ - **🧩 Custom Extraction Regex**: Extracts variables, directories, and paths using flexible capturing groups in your regular expressions.
29
+ - **📦 ESM Native**: Built for modern ES module environments.
30
+
31
+ ---
32
+
33
+ ## 🔗 Dependency Chain
34
+
35
+ * [`pattern-collector-anyjs-pull-lines-all`](https://www.npmjs.com/package/pattern-collector-anyjs-pull-lines-all) - listed in [`package.json`](package.json) as `^1.3.3`.
36
+ * [`pattern-collector-anyjs-pull-lines-consumption`](https://www.npmjs.com/package/pattern-collector-anyjs-pull-lines-consumption) - listed in [`package.json`](package.json) as `^1.2.1`.
37
+ * [`pattern-collector-anyjs-pull-lines-export`](https://www.npmjs.com/package/pattern-collector-anyjs-pull-lines-export) - listed in [`package.json`](package.json) as `^1.2.2`.
38
+ * [`pattern-collector-anyjs-pull-lines-import`](https://www.npmjs.com/package/pattern-collector-anyjs-pull-lines-import) - listed in [`package.json`](package.json) as `^1.9.3`.
39
+ * [`pattern-collector-anyjs-pull-lines-import-npm`](https://www.npmjs.com/package/pattern-collector-anyjs-pull-lines-import-npm) - listed in [`package.json`](package.json) as `^1.2.1`.
40
+
41
+ ---
42
+
43
+ ## 🚀 Installation
44
+
45
+ ```bash
46
+ npm install pattern-collector-anyjs-pull-lines
47
+ ```
48
+
49
+ ---
50
+
51
+ ## 💻 Usage Example
52
+
53
+ Here is a quick example showing how to extract import and route usage patterns:
54
+
55
+ ```javascript
56
+ import pullLines from 'pattern-collector-anyjs-pull-lines';
57
+
58
+ const code = `
59
+ import express from 'express';
60
+ import { router as routerFromv1 } from "./v1/routes.js";
61
+ import { router as routerFromv2 } from "./v2/routes.js";
62
+
63
+ const router = express.Router();
64
+ router.use("/v1", routerFromv1);
65
+ `;
66
+
67
+ const result = pullLines({
68
+ fileContent: code,
69
+ importRegex: {
70
+ // Captures the router variable alias and the module folder name
71
+ parseRegex: /import\s*\{[^}]*router\s+as\s+(\w+)[^}]*\}\s*from\s*['"]\.\/([^/]+)\/.*['"]/,
72
+ // Search regex to identify import lines
73
+ searchString: /^[ \t]*import\b.*from\s+['"]\.[^'"]*['"];/gm
74
+ },
75
+ consumptionRegex: {
76
+ // Captures routing paths and the associated router variable names
77
+ parseRegex: /router\.use\s*\(\s*['"`]\/?([^'"`]+)['"`]\s*,\s*(\w+)/,
78
+ // Search regex to identify route usage lines
79
+ searchString: /^[ \t]*router\.use\b.*?;/gm
80
+ }
81
+ });
82
+
83
+ console.log(result);
84
+ /*
85
+ Output:
86
+ {
87
+ importLines: [
88
+ {
89
+ variable: 'routerFromv1',
90
+ folderName: 'v1',
91
+ line: 'import { router as routerFromv1 } from "./v1/routes.js";',
92
+ lineNumber: 3
93
+ },
94
+ {
95
+ variable: 'routerFromv2',
96
+ folderName: 'v2',
97
+ line: 'import { router as routerFromv2 } from "./v2/routes.js";',
98
+ lineNumber: 4
99
+ }
100
+ ],
101
+ useLines: [
102
+ {
103
+ variable: 'v1',
104
+ folderName: 'routerFromv1',
105
+ line: 'router.use("/v1", routerFromv1);',
106
+ lineNumber: 7
107
+ }
108
+ ]
109
+ }
110
+ */
111
+ ```
112
+
113
+ ---
114
+
115
+ ## 🛠️ API Reference
116
+
117
+ ### `default(options)`
118
+
119
+ The default export is a function that parses the provided content and returns matching pattern details.
120
+
121
+ #### Parameters
122
+
123
+ An options object containing:
124
+
125
+ * **`fileContent`** `(string)`: The raw javascript source code string to analyze.
126
+ * **`importRegex`** `(object)`: Config for parsing import statements:
127
+ - `searchRegex` / `searchString` `(RegExp)`: Regular expression with `g` flag to search for import statements in the code.
128
+ - `parseRegex` `(RegExp)`: Regular expression with capture groups to extract specific variables (`variable`) and folder names (`folderName`).
129
+ * **`consumptionRegex`** `(object)`: Config for parsing route consumption statements:
130
+ - `searchRegex` / `searchString` `(RegExp)`: Regular expression with `g` flag to search for route usage patterns.
131
+ - `parseRegex` `(RegExp)`: Regular expression with capture groups to extract paths and variables.
132
+ * **`showLog`** `(boolean)` *(optional)*: When set to `true`, outputs intermediate matching arrays to the console.
133
+ * **`showLogStep1`** `(boolean)` *(optional)*: When set to `true`, outputs step-by-step extraction details.
134
+
135
+ #### Returns
136
+
137
+ * **`Object`**:
138
+ - `importLines` `(Array<Object>)`: Extracted import matching objects.
139
+ - `useLines` `(Array<Object>)`: Extracted usage matching objects.
140
+
141
+ Each item in the lists has the following shape:
142
+ ```typescript
143
+ {
144
+ variable: string; // Captured variable name from parseRegex
145
+ folderName: string; // Captured directory or value from parseRegex
146
+ line: string; // Full original line matching the search regex
147
+ lineNumber: number; // 1-indexed line number in the source file
148
+ }
149
+ ```
150
+
151
+ ---
152
+
153
+ ## ⚖️ License
154
+
155
+ MIT License. Designed with ❤️ by [KeshavSoft](https://github.com/keshavsoft).
@@ -0,0 +1,13 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { fileURLToPath } from "url";
4
+
5
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
+
7
+ export default function getLatestVersion() {
8
+ const versions = fs.readdirSync(path.join(__dirname, ".."))
9
+ .filter(n => /^v\d+$/.test(n))
10
+ .sort((a, b) => parseInt(a.slice(1)) - parseInt(b.slice(1)));
11
+
12
+ return versions.at(-1);
13
+ };
@@ -0,0 +1,27 @@
1
+ import pullLines from "pattern-collector-anyjs-pull-lines";
2
+ import pullLinesStory from "pattern-collector-anyjs-pull-lines-story";
3
+
4
+ const startFunc = ({ fileContent, searchRules, parseRules
5
+ }) => {
6
+ let allLines;
7
+
8
+ const lines = pullLines({
9
+ fileContent,
10
+ consumptionSearchRegex: searchRules?.consumptionRegex?.searchRegex,
11
+ importSearchRegex: searchRules?.importRegex?.searchRegex,
12
+ exportSearchRegex: searchRules?.exportRegex?.searchRegex,
13
+ importSearchNpmRegex: searchRules?.importNpmRegex?.searchRegex
14
+ });
15
+
16
+ const linesStory = pullLinesStory({
17
+ inLines: lines,
18
+ importNpmRegex: parseRules?.parseRules?.importNpmRegex,
19
+ importRegex: parseRules?.parseRules?.importRegex,
20
+ consumptionRegex: parseRules?.parseRules?.consumptionRegex,
21
+ exportRegex: parseRules?.parseRules?.exportRegex,
22
+ });
23
+
24
+ return { lines, linesStory };
25
+ };
26
+
27
+ export default startFunc;
@@ -0,0 +1,29 @@
1
+ // import pullLines from "pattern-collector-anyjs-pull-lines";
2
+ // import pullLinesStory from "pattern-collector-anyjs-pull-lines-story";
3
+ import pullLines from "./pullLines/index.js";
4
+ import pullLinesStory from "./pullLinesStory/index.js";
5
+
6
+ const startFunc = ({ fileContent, searchRules, parseRules
7
+ }) => {
8
+ let allLines;
9
+
10
+ const lines = pullLines({
11
+ fileContent,
12
+ consumptionSearchRegex: searchRules?.consumptionRegex?.searchRegex,
13
+ importSearchRegex: searchRules?.importRegex?.searchRegex,
14
+ exportSearchRegex: searchRules?.exportRegex?.searchRegex,
15
+ importSearchNpmRegex: searchRules?.importNpmRegex?.searchRegex
16
+ });
17
+
18
+ const linesStory = pullLinesStory({
19
+ inLines: lines,
20
+ importNpmRegex: parseRules?.parseRules?.importNpmRegex,
21
+ importRegex: parseRules?.parseRules?.importRegex,
22
+ consumptionRegex: parseRules?.parseRules?.consumptionRegex,
23
+ exportRegex: parseRules?.parseRules?.exportRegex,
24
+ });
25
+
26
+ return { lines, linesStory };
27
+ };
28
+
29
+ export default startFunc;
@@ -0,0 +1,68 @@
1
+ const getLine = ({ fileContent, inIndex }) => {
2
+ const start = fileContent.lastIndexOf('\n', inIndex) + 1;
3
+
4
+ let end = fileContent.indexOf('\n', inIndex);
5
+
6
+ if (end === -1) {
7
+ end = fileContent.length;
8
+ }
9
+
10
+ let line = fileContent.substring(start, end);
11
+
12
+ if (line.endsWith('\r')) {
13
+ line = line.slice(0, -1);
14
+ }
15
+
16
+ return line;
17
+ };
18
+
19
+ const getCurrentLineNumber = ({
20
+ fileContent,
21
+ inCurrentLine,
22
+ inLastPosition,
23
+ inCurrentPosition
24
+ }) => {
25
+ let line = inCurrentLine;
26
+
27
+ for (let i = inLastPosition; i < inCurrentPosition; i++) {
28
+ if (fileContent[i] === '\n') {
29
+ line++;
30
+ }
31
+ }
32
+
33
+ return line;
34
+ };
35
+
36
+ const startFunc = ({ fileContent, searchRegex }) => {
37
+ const matches = [];
38
+ let match;
39
+
40
+ let currentLine = 1;
41
+ let lastPosition = 0;
42
+
43
+ while ((match = searchRegex.exec(fileContent)) !== null) {
44
+ currentLine = getCurrentLineNumber({
45
+ fileContent,
46
+ inCurrentLine: currentLine,
47
+ inLastPosition: lastPosition,
48
+ inCurrentPosition: match.index
49
+ });
50
+
51
+ lastPosition = match.index;
52
+
53
+ const line = getLine({
54
+ fileContent,
55
+ inIndex: match.index
56
+ });
57
+
58
+ matches.push({
59
+ match: match[0],
60
+ line,
61
+ lineNumber: currentLine
62
+ });
63
+ }
64
+
65
+ return matches;
66
+ };
67
+
68
+ export default startFunc;
@@ -0,0 +1,37 @@
1
+ import patternCollector from "../patternCollector/index.js";
2
+
3
+ const startFunc = ({ fileContent, importSearchRegex, consumptionSearchRegex,
4
+ exportSearchRegex, importSearchNpmRegex
5
+ }) => {
6
+ let allLines;
7
+
8
+ const importLinesFromNpm = patternCollector({
9
+ fileContent,
10
+ searchRegex: importSearchNpmRegex
11
+ });
12
+
13
+ const importLines = patternCollector({
14
+ fileContent,
15
+ searchRegex: importSearchRegex
16
+ });
17
+
18
+ let useLines = patternCollector({
19
+ fileContent,
20
+ searchRegex: consumptionSearchRegex
21
+ });
22
+
23
+ let exportLines = patternCollector({
24
+ fileContent,
25
+ searchRegex: exportSearchRegex
26
+ });
27
+
28
+ return {
29
+ allLines,
30
+ importLinesFromNpm,
31
+ importLines,
32
+ useLines,
33
+ exportLines
34
+ };
35
+ };
36
+
37
+ export default startFunc;
@@ -0,0 +1,45 @@
1
+ import patternBase from "pattern-collector-base-regex-n-parts";
2
+
3
+ const startFunc = ({ inLines, importNpmRegex, importRegex,
4
+ consumptionRegex, exportRegex
5
+ }) => {
6
+ const importLinesFromNpm = inLines?.importLinesFromNpm.map(element => {
7
+ return patternBase({
8
+ matchLine: element?.match, parseRegex: importNpmRegex?.parseRegex,
9
+ nParts: importNpmRegex?.nParts
10
+ });
11
+ });
12
+
13
+
14
+ const importLines = inLines?.importLines.map(element => {
15
+ // console.log("a : ", element, importRegex);
16
+
17
+ return patternBase({
18
+ matchLine: element.match, parseRegex: importRegex?.parseRegex,
19
+ nParts: importRegex?.nParts
20
+ });
21
+ });
22
+
23
+ const useLines = inLines?.useLines.map(element => {
24
+ return patternBase({
25
+ matchLine: element?.match, parseRegex: consumptionRegex?.parseRegex,
26
+ nParts: consumptionRegex?.nParts
27
+ });
28
+ });
29
+
30
+ const exportLines = inLines?.exportLines.map(element => {
31
+ return patternBase({
32
+ matchLine: element?.match, parseRegex: exportRegex?.parseRegex,
33
+ nParts: exportRegex?.nParts
34
+ });
35
+ });
36
+
37
+ return {
38
+ importLinesFromNpm,
39
+ importLines,
40
+ useLines,
41
+ exportLines
42
+ };
43
+ };
44
+
45
+ export default startFunc;
package/index.js ADDED
@@ -0,0 +1,14 @@
1
+ import { createRequire } from "module";
2
+ import getLatestVersion from "./bin/core/getLatestVersion.js";
3
+
4
+ const require = createRequire(import.meta.url);
5
+
6
+ const v = getLatestVersion();
7
+ const latestModule = require(`./bin/${v}/index.js`);
8
+
9
+ const load = (args) => {
10
+
11
+ return latestModule.default(args);
12
+ };
13
+
14
+ export default load;
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "pattern-collector-anyjs-story",
3
+ "version": "1.16.2",
4
+ "description": "A powerful, configurable tool to scan JavaScript/ESM files and pull structured line matches using custom regular expressions.",
5
+ "keywords": [
6
+ "pattern",
7
+ "regex",
8
+ "parser",
9
+ "import",
10
+ "analyzer",
11
+ "esm",
12
+ "extractor"
13
+ ],
14
+ "dependencies": {
15
+ "pattern-collector-base-regex-n-parts": "^1.6.10"
16
+ },
17
+ "type": "module",
18
+ "exports": {
19
+ ".": "./index.js"
20
+ },
21
+ "files": [
22
+ "bin/",
23
+ "index.js",
24
+ "README.md",
25
+ "LICENSE"
26
+ ],
27
+ "homepage": "https://github.com/keshavsoft/pattern-collector-anyjs-story#readme",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/keshavsoft/pattern-collector-anyjs-story.git"
31
+ },
32
+ "bugs": {
33
+ "url": "https://github.com/keshavsoft/pattern-collector-anyjs-story/issues"
34
+ }
35
+ }