@awesomeness-js/utils 1.0.25 → 1.1.3
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 +111 -85
- package/build/build.js +6 -1
- package/index.js +36 -9
- package/package.json +3 -2
- package/schemas.js +1 -0
- package/src/build.js +78 -2
- package/src/getAllFiles.js +1 -1
- package/src/shouldIgnore.js +99 -0
- package/src/utils/buildFileDataList.js +5 -1
- package/src/utils/generateFile.js +42 -8
- package/src/utils/generateFlatExportLines.js +7 -1
- package/src/utils/generateImportStatements.js +5 -1
- package/src/utils/generateNamedExports.js +43 -9
- package/src/utils/generateNamespaceCode.js +13 -2
- package/src/utils/generateNamespaceExportLines.js +13 -2
- package/src/utils/writeHotWrapper.js +42 -0
- package/tests/ignore.test.js +55 -0
- package/tests/namedExports.test.js +13 -0
- package/types/build.d.ts +5 -1
- package/types/index.d.ts +106 -79
- package/types/shouldIgnore.d.ts +1 -0
- package/types/utils/buildFileDataList.d.ts +5 -1
- package/types/utils/generateFile.d.ts +8 -1
- package/types/utils/generateFlatExportLines.d.ts +7 -1
- package/types/utils/generateImportStatements.d.ts +5 -1
- package/types/utils/generateNamedExports.d.ts +7 -1
- package/types/utils/generateNamespaceCode.d.ts +7 -1
- package/types/utils/generateNamespaceExportLines.d.ts +6 -1
- package/types/utils/writeHotWrapper.d.ts +4 -0
- package/src/utils/shouldIgnore.js +0 -63
package/README.md
CHANGED
|
@@ -1,44 +1,51 @@
|
|
|
1
1
|
# Nothing Special
|
|
2
2
|
|
|
3
|
-
Just some <u>zero dependency</u
|
|
3
|
+
Just some <u>zero dependency</u>* utils that every [Awesomeness.js](https://github.com/awesomeness-js) project uses.
|
|
4
4
|
|
|
5
|
+
**Perfect?** Far from it.
|
|
6
|
+
|
|
7
|
+
Better than what you have now? For sure.
|
|
5
8
|
|
|
6
9
|
---
|
|
7
10
|
|
|
8
11
|
# 🚀 Auto-Generate API Exports for Your Node.js Project
|
|
9
12
|
|
|
10
|
-
|
|
11
13
|
## 📌 Why "build" Exists
|
|
12
14
|
|
|
13
|
-
When
|
|
15
|
+
When you’re building a Node.js project, pulling functions together into a clean, predictable API shouldn’t feel like busywork. But maintaining a manual `index.js` is a waste of time, and Webpack? That’s a browser bundler—great for shipping front-end bundles, useless for building a logical backend export layer.
|
|
16
|
+
|
|
17
|
+
This script takes that grunt work off your plate and does it **right**:
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
✅ **Consolidates all exports** into a single, perfectly structured API object
|
|
20
|
+
✅ **Keeps function names and namespaces** exactly as your folder structure dictates—no mystery, no guessing
|
|
21
|
+
✅ **Pulls in JSDoc comments** so your documentation is baked right into the build. Intellisense loves this.
|
|
22
|
+
✅ **Runs in plain Node.js**—zero bundlers, zero fluff, zero excuses
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
Hint: Use the [Awesomeness Intellitip](https://marketplace.visualstudio.com/items?itemName=awesomeness.awesomeness-intellitip) VS Code Extension for classy hover documentation.
|
|
16
26
|
|
|
17
|
-
✅ **Consolidates all exports** into a structured API object.
|
|
18
|
-
✅ **Preserves function names and namespaces** based on folder structure.
|
|
19
|
-
✅ **Extracts JSDoc comments** for better documentation.
|
|
20
|
-
✅ **Works in plain Node.js**—no need for Webpack or extra dependencies.
|
|
21
27
|
|
|
22
28
|
---
|
|
23
29
|
|
|
24
|
-
##
|
|
30
|
+
## 💡 Why Use This Over Webpack or Manual Indexing?
|
|
25
31
|
|
|
26
|
-
|
|
32
|
+
Webpack is a great bundler, but it’s not suited for building a structured export layer for backend code. This script offers a focused, ergonomic solution:
|
|
27
33
|
|
|
28
|
-
✔ **
|
|
29
|
-
✔ **Automatic function export generation**—No need to manually update an `index.js`.
|
|
34
|
+
✔ **Automatic export generation** — no more maintaining `index.js` by hand
|
|
30
35
|
✔ **JSDoc extraction**—Includes comments directly in the generated file.
|
|
31
36
|
✔ **Simple and predictable**—You control how exports are structured.
|
|
32
37
|
✔ **Namespace support**—Uses folder structure to organize functions logically.
|
|
38
|
+
✔ **Minimal setup** — one line to generate your exports
|
|
39
|
+
✔ **Dev-friendly hot rebuild** — optional file watching with HMR-style rebuilds
|
|
33
40
|
|
|
34
|
-
|
|
41
|
+
> Uses `chokidar` under the hood for reliable cross-platform file watching.
|
|
35
42
|
|
|
36
43
|
---
|
|
37
44
|
|
|
38
|
-
##
|
|
45
|
+
## ⚙️ How It Works
|
|
39
46
|
|
|
40
|
-
1. **Scans** the `./src` directory for `.js` files
|
|
41
|
-
2. **Generates** import statements
|
|
47
|
+
1. **Scans** the `./src` directory for `.js` files
|
|
48
|
+
2. **Generates** import statements
|
|
42
49
|
3. **Creates** an API object that mirrors your folder structure.
|
|
43
50
|
4. **Extracts JSDoc comments** from each file and attaches them to the exports.
|
|
44
51
|
5. **Outputs** a clean, structured `index.js` file, ready to use.
|
|
@@ -47,103 +54,122 @@ With this script, you can stop wasting time managing exports and focus on writin
|
|
|
47
54
|
|
|
48
55
|
## 🔧 Usage
|
|
49
56
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
By default, this will:
|
|
53
|
-
- Scan `./src` for JavaScript files
|
|
54
|
-
- Generate an `index.js` file
|
|
55
|
-
- Structure exports based on your folder hierarchy
|
|
56
|
-
|
|
57
|
-
```javascript
|
|
57
|
+
To run it:
|
|
58
58
|
|
|
59
|
+
```js
|
|
59
60
|
import { build } from '@awesomeness-js/utils';
|
|
60
61
|
|
|
61
|
-
build();
|
|
62
|
-
|
|
62
|
+
await build();
|
|
63
63
|
```
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
This will:
|
|
66
|
+
- Scan the `./src` directory
|
|
67
|
+
- Create or overwrite `./index.js`
|
|
68
|
+
- Structure exports based on your file and folder layout
|
|
68
69
|
|
|
69
|
-
|
|
70
|
+
Customize it:
|
|
70
71
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
```js
|
|
73
|
+
await build({
|
|
74
|
+
src: './my-functions',
|
|
75
|
+
dest: './api.js',
|
|
76
|
+
includeComments: true,
|
|
77
|
+
useTabs: true,
|
|
78
|
+
hotModuleReload: true // Enable hot reload for dev
|
|
74
79
|
});
|
|
75
80
|
```
|
|
76
81
|
|
|
77
82
|
---
|
|
78
83
|
|
|
79
|
-
##
|
|
84
|
+
## 📦 Example Output
|
|
80
85
|
|
|
81
|
-
|
|
86
|
+
Given this folder structure:
|
|
82
87
|
|
|
83
88
|
```
|
|
84
89
|
src/
|
|
85
|
-
|
|
86
|
-
│ ├──
|
|
87
|
-
│ ├──
|
|
88
|
-
|
|
89
|
-
│ ├──
|
|
90
|
-
|
|
90
|
+
├── roxbury/
|
|
91
|
+
│ ├── didYouJustGrabMyAss.js
|
|
92
|
+
│ ├── areYouGuysBrothers.js
|
|
93
|
+
├── bros/
|
|
94
|
+
│ ├── didWeJustBecomeBestFriends.js
|
|
95
|
+
│ ├── prestigeWorldwide.js
|
|
96
|
+
├── rickyBobby/
|
|
97
|
+
│ ├── iWakeUpAndPissExcellence.js
|
|
98
|
+
│ ├── iRaiseWinners.js
|
|
99
|
+
│ ├── shakeAndBake.js
|
|
100
|
+
├── oldSchool/
|
|
101
|
+
│ ├── youMyBoyBlue.js
|
|
102
|
+
├── news/
|
|
103
|
+
│ ├── thatEscalatedQuickly.js
|
|
104
|
+
│ ├── stayClassy.js
|
|
105
|
+
│ ├── milkWasABadChoice.js
|
|
106
|
+
├── tommy/
|
|
107
|
+
│ ├── roomService.js
|
|
108
|
+
│ ├── fatGuyInALittleCoat.js
|
|
109
|
+
├── menInTights/
|
|
110
|
+
│ ├── youGrewBoobs.js
|
|
111
|
+
│ ├── merryMen/
|
|
112
|
+
│ │ ├── snipTheTip.js
|
|
91
113
|
```
|
|
92
114
|
|
|
93
|
-
Your generated `index.js` will look like this:
|
|
94
|
-
|
|
95
|
-
```javascript
|
|
96
|
-
/**
|
|
97
|
-
* This file is auto-generated by the build script.
|
|
98
|
-
* It consolidates API functions for use in the application.
|
|
99
|
-
* Do not edit manually.
|
|
100
|
-
*/
|
|
101
|
-
|
|
102
|
-
import utils_formatDate from './src/utils/formatDate.js';
|
|
103
|
-
import utils_generateId from './src/utils/generateId.js';
|
|
104
|
-
import services_fetchData from './src/services/fetchData.js';
|
|
105
|
-
import calculate from './src/calculate.js';
|
|
106
|
-
|
|
107
|
-
export { calculate };
|
|
108
|
-
export default {
|
|
109
|
-
utils: {
|
|
110
|
-
formatDate: utils_formatDate,
|
|
111
|
-
generateId: utils_generateId
|
|
112
|
-
},
|
|
113
|
-
services: {
|
|
114
|
-
fetchData: services_fetchData
|
|
115
|
-
},
|
|
116
|
-
calculate
|
|
117
|
-
};
|
|
118
|
-
```
|
|
119
115
|
|
|
120
|
-
|
|
121
|
-
and will look like this
|
|
122
|
-
```javascript
|
|
123
|
-
import { calculate } from './api.js';
|
|
124
|
-
const result = calculate(5, 10);
|
|
125
|
-
console.log(result);
|
|
126
|
-
```
|
|
116
|
+
#### Use it like:
|
|
127
117
|
|
|
128
|
-
|
|
118
|
+
```js
|
|
119
|
+
|
|
120
|
+
// Default import: full API
|
|
121
|
+
import api from './index.js';
|
|
122
|
+
|
|
123
|
+
// Use the full API
|
|
124
|
+
api.roxbury.didYouJustGrabMyAss();
|
|
125
|
+
|
|
126
|
+
// perfect for CTRL+F
|
|
127
|
+
api.rickyBobby.shakeAndBake();
|
|
128
|
+
|
|
129
|
+
// deep
|
|
130
|
+
api.menInTights.youGrewBoobs();
|
|
131
|
+
api.menInTights.merryMen.snipTheTip();
|
|
129
132
|
|
|
130
|
-
```javascript
|
|
131
|
-
import { utils } from './api.js';
|
|
132
|
-
const id = utils.generateId();
|
|
133
|
-
console.log(id);
|
|
134
133
|
```
|
|
135
134
|
|
|
135
|
+
```js
|
|
136
|
+
|
|
137
|
+
// Named import also work
|
|
138
|
+
import { youMyBoy, roxbury } from './api.js';
|
|
136
139
|
|
|
140
|
+
// Use the named group
|
|
141
|
+
youMyBoy.blue();
|
|
142
|
+
roxbury.didYouGrabMyAss();
|
|
143
|
+
|
|
144
|
+
```
|
|
137
145
|
|
|
138
146
|
---
|
|
139
147
|
|
|
140
|
-
##
|
|
148
|
+
## 💪 Who’s This For?
|
|
149
|
+
|
|
150
|
+
- **Teams** who want **clean and consistent** APIs
|
|
151
|
+
- **Expert** ~~developers~~ **architects** obsessed with
|
|
152
|
+
- organization
|
|
153
|
+
- hierarchy
|
|
154
|
+
- explicit namespacing
|
|
155
|
+
- clean code
|
|
156
|
+
- **Champions** who know CTRL+F `app.roxbury.didYouJustGrabMyAss` will <u>always beat</u> any “magic” refactor tool when it comes to finding **every. single. usage.**
|
|
157
|
+
- Developers who refuse to hide functions behind lazy aliases, and instead demand predictable, grep-able APIs that tell you **exactly where the code lives.**
|
|
158
|
+
|
|
159
|
+
If you want a smarter way to manage and structure exports in a Node.js project — without extra tooling bloat — this script was built for you.
|
|
141
160
|
|
|
142
|
-
|
|
143
|
-
- **Backend teams** managing large function directories.
|
|
144
|
-
- **Anyone tired of manually updating `index.js` files.**
|
|
161
|
+
If that makes you hard, you’re in the right place.
|
|
145
162
|
|
|
146
|
-
If you
|
|
163
|
+
> If it makes you mad… you’ve probably never built a scalable codebase.
|
|
164
|
+
|
|
165
|
+
---
|
|
147
166
|
|
|
148
|
-
|
|
167
|
+
**Ready to make development great again?**
|
|
168
|
+
👉 [awesomenessjs.com](https://awesomenessjs.com)
|
|
149
169
|
|
|
170
|
+
---
|
|
171
|
+
✱ disclaimer... *Kinda zero dependencies.*
|
|
172
|
+
Zero **prod** dependencies.
|
|
173
|
+
> dev dependencies:
|
|
174
|
+
> `chokidar` for hot module reloading (HMR)
|
|
175
|
+
> `vitest` for testing
|
package/build/build.js
CHANGED
|
@@ -4,10 +4,15 @@ build({
|
|
|
4
4
|
src: './src',
|
|
5
5
|
dest: './index.js',
|
|
6
6
|
dts: false,
|
|
7
|
+
hotModuleReload: false,
|
|
8
|
+
hotCallback: (file) => {
|
|
9
|
+
|
|
10
|
+
console.log(`[build callback] processed ${file}`);
|
|
11
|
+
|
|
12
|
+
},
|
|
7
13
|
ignore: [
|
|
8
14
|
'ignoreMe.js',
|
|
9
15
|
'ignoreFolder/*',
|
|
10
|
-
//'namespaceExample/*',
|
|
11
16
|
],
|
|
12
17
|
});
|
|
13
18
|
|
package/index.js
CHANGED
|
@@ -20,13 +20,12 @@ import _each from './src/each.js';
|
|
|
20
20
|
import _eachAsync from './src/eachAsync.js';
|
|
21
21
|
import _encrypt from './src/encrypt.js';
|
|
22
22
|
import _getAllFiles from './src/getAllFiles.js';
|
|
23
|
-
import _ignoreFolder_ignoreMe from './src/ignoreFolder/ignoreMe.js';
|
|
24
|
-
import _ignoreMe from './src/ignoreMe.js';
|
|
25
23
|
import _isUUID from './src/isUUID.js';
|
|
26
24
|
import _md5 from './src/md5.js';
|
|
27
25
|
import _password_check from './src/password/check.js';
|
|
28
26
|
import _password_hash from './src/password/hash.js';
|
|
29
27
|
import _setLocalEnvs from './src/setLocalEnvs.js';
|
|
28
|
+
import _shouldIgnore from './src/shouldIgnore.js';
|
|
30
29
|
import _thingType from './src/thingType.js';
|
|
31
30
|
import _toPennies from './src/toPennies.js';
|
|
32
31
|
import _utils_buildExportsTree from './src/utils/buildExportsTree.js';
|
|
@@ -39,7 +38,7 @@ import _utils_generateImportStatements from './src/utils/generateImportStatement
|
|
|
39
38
|
import _utils_generateNamedExports from './src/utils/generateNamedExports.js';
|
|
40
39
|
import _utils_generateNamespaceCode from './src/utils/generateNamespaceCode.js';
|
|
41
40
|
import _utils_generateNamespaceExportLines from './src/utils/generateNamespaceExportLines.js';
|
|
42
|
-
import
|
|
41
|
+
import _utils_writeHotWrapper from './src/utils/writeHotWrapper.js';
|
|
43
42
|
import _uuid from './src/uuid.js';
|
|
44
43
|
import _validateSchema from './src/validateSchema.js';
|
|
45
44
|
|
|
@@ -52,15 +51,46 @@ export { _each as each };
|
|
|
52
51
|
export { _eachAsync as eachAsync };
|
|
53
52
|
export { _encrypt as encrypt };
|
|
54
53
|
export { _getAllFiles as getAllFiles };
|
|
55
|
-
export { _ignoreMe as ignoreMe };
|
|
56
54
|
export { _isUUID as isUUID };
|
|
57
55
|
export { _md5 as md5 };
|
|
58
56
|
export { _setLocalEnvs as setLocalEnvs };
|
|
57
|
+
export { _shouldIgnore as shouldIgnore };
|
|
59
58
|
export { _thingType as thingType };
|
|
60
59
|
export { _toPennies as toPennies };
|
|
61
60
|
export { _uuid as uuid };
|
|
62
61
|
export { _validateSchema as validateSchema };
|
|
63
62
|
|
|
63
|
+
export const clean = {
|
|
64
|
+
array: _clean_array,
|
|
65
|
+
boolean: _clean_boolean,
|
|
66
|
+
integer: _clean_integer,
|
|
67
|
+
number: _clean_number,
|
|
68
|
+
object: _clean_object,
|
|
69
|
+
string: _clean_string,
|
|
70
|
+
timestamp: _clean_timestamp,
|
|
71
|
+
uuid: _clean_uuid
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
export const password = {
|
|
75
|
+
check: _password_check,
|
|
76
|
+
hash: _password_hash
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export const utils = {
|
|
80
|
+
buildExportsTree: _utils_buildExportsTree,
|
|
81
|
+
buildFileDataList: _utils_buildFileDataList,
|
|
82
|
+
clean: _utils_clean,
|
|
83
|
+
extractJSDocComment: _utils_extractJSDocComment,
|
|
84
|
+
generateFile: _utils_generateFile,
|
|
85
|
+
generateFlatExportLines: _utils_generateFlatExportLines,
|
|
86
|
+
generateImportStatements: _utils_generateImportStatements,
|
|
87
|
+
generateNamedExports: _utils_generateNamedExports,
|
|
88
|
+
generateNamespaceCode: _utils_generateNamespaceCode,
|
|
89
|
+
generateNamespaceExportLines: _utils_generateNamespaceExportLines,
|
|
90
|
+
writeHotWrapper: _utils_writeHotWrapper
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
|
|
64
94
|
export default {
|
|
65
95
|
/**
|
|
66
96
|
* Builds a file from the specified source directory and writes it to the destination file.
|
|
@@ -99,10 +129,10 @@ export default {
|
|
|
99
129
|
eachAsync: _eachAsync,
|
|
100
130
|
encrypt: _encrypt,
|
|
101
131
|
getAllFiles: _getAllFiles,
|
|
102
|
-
ignoreMe: _ignoreMe,
|
|
103
132
|
isUUID: _isUUID,
|
|
104
133
|
md5: _md5,
|
|
105
134
|
setLocalEnvs: _setLocalEnvs,
|
|
135
|
+
shouldIgnore: _shouldIgnore,
|
|
106
136
|
thingType: _thingType,
|
|
107
137
|
toPennies: _toPennies,
|
|
108
138
|
uuid: _uuid,
|
|
@@ -117,9 +147,6 @@ export default {
|
|
|
117
147
|
timestamp: _clean_timestamp,
|
|
118
148
|
uuid: _clean_uuid,
|
|
119
149
|
},
|
|
120
|
-
ignoreFolder: {
|
|
121
|
-
ignoreMe: _ignoreFolder_ignoreMe,
|
|
122
|
-
},
|
|
123
150
|
password: {
|
|
124
151
|
check: _password_check,
|
|
125
152
|
hash: _password_hash,
|
|
@@ -135,6 +162,6 @@ export default {
|
|
|
135
162
|
generateNamedExports: _utils_generateNamedExports,
|
|
136
163
|
generateNamespaceCode: _utils_generateNamespaceCode,
|
|
137
164
|
generateNamespaceExportLines: _utils_generateNamespaceExportLines,
|
|
138
|
-
|
|
165
|
+
writeHotWrapper: _utils_writeHotWrapper,
|
|
139
166
|
},
|
|
140
167
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@awesomeness-js/utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "Awesomeness - Utils",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"access": "public"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"vitest": "^3.0.9"
|
|
24
|
+
"vitest": "^3.0.9",
|
|
25
|
+
"chokidar": "^4.0.3"
|
|
25
26
|
}
|
|
26
27
|
}
|
package/schemas.js
CHANGED
package/src/build.js
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { writeFileSync } from 'fs';
|
|
14
14
|
import generateFile from './utils/generateFile.js';
|
|
15
|
+
import writeHotWrapper from './utils/writeHotWrapper.js';
|
|
15
16
|
|
|
16
17
|
async function build({
|
|
17
18
|
src = './src',
|
|
@@ -20,10 +21,85 @@ async function build({
|
|
|
20
21
|
ignore = [],
|
|
21
22
|
includeComments = true,
|
|
22
23
|
dts = false,
|
|
23
|
-
useTabs = true
|
|
24
|
+
useTabs = true,
|
|
25
|
+
hotModuleReload = false,
|
|
26
|
+
hotCallback = null,
|
|
27
|
+
hotSource = './hot-source.js' // generated only when hot is enabled
|
|
24
28
|
} = {}) {
|
|
25
29
|
|
|
26
|
-
|
|
30
|
+
const gen = () => generateFile({
|
|
31
|
+
src,
|
|
32
|
+
exportRoots,
|
|
33
|
+
ignore,
|
|
34
|
+
includeComments,
|
|
35
|
+
dts,
|
|
36
|
+
useTabs
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const buildHot = () => {
|
|
40
|
+
|
|
41
|
+
// 1) write payload that the wrapper imports
|
|
42
|
+
writeFileSync(hotSource, gen());
|
|
43
|
+
console.log(`[build] wrote ${hotSource}`);
|
|
44
|
+
|
|
45
|
+
// 2) ensure index.js is a hot wrapper
|
|
46
|
+
writeHotWrapper({
|
|
47
|
+
dest,
|
|
48
|
+
hotSource
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
console.log(`[build] ensured hot wrapper ${dest}`);
|
|
52
|
+
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const buildCold = () => {
|
|
56
|
+
|
|
57
|
+
// single-file classic output (no second file)
|
|
58
|
+
writeFileSync(dest, gen());
|
|
59
|
+
console.log(`[build] wrote ${dest}`);
|
|
60
|
+
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
if (hotModuleReload) {
|
|
64
|
+
|
|
65
|
+
buildHot();
|
|
66
|
+
|
|
67
|
+
// watch only src; each change regenerates hot-source.js (wrapper auto-reloads it)
|
|
68
|
+
const chokidar = (await import('chokidar')).default;
|
|
69
|
+
|
|
70
|
+
console.log(`[build] watching ${src} for changes...`);
|
|
71
|
+
const watcher = chokidar.watch(src, {
|
|
72
|
+
ignoreInitial: true,
|
|
73
|
+
ignored: ignore
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
let timeout;
|
|
77
|
+
|
|
78
|
+
watcher.on('all', (_event, file) => {
|
|
79
|
+
|
|
80
|
+
clearTimeout(timeout);
|
|
81
|
+
timeout = setTimeout(() => {
|
|
82
|
+
|
|
83
|
+
console.log(`[build] change detected in ${file}, rebuilding payload...`);
|
|
84
|
+
writeFileSync(hotSource, gen());
|
|
85
|
+
|
|
86
|
+
if(typeof hotCallback === 'function') {
|
|
87
|
+
|
|
88
|
+
hotCallback(file);
|
|
89
|
+
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
console.log(`[build] ready.`);
|
|
93
|
+
|
|
94
|
+
}, 50);
|
|
95
|
+
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
} else {
|
|
99
|
+
|
|
100
|
+
buildCold();
|
|
101
|
+
|
|
102
|
+
}
|
|
27
103
|
|
|
28
104
|
return true;
|
|
29
105
|
|
package/src/getAllFiles.js
CHANGED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
export default function shouldIgnore(filePath, ignorePatterns) {
|
|
2
|
+
|
|
3
|
+
const normalizePath = (p) => {
|
|
4
|
+
|
|
5
|
+
let v = String(p).replace(/\\/g, '/'); // Windows → POSIX
|
|
6
|
+
|
|
7
|
+
v = v.replace(/^\.\/+/, ''); // strip leading ./
|
|
8
|
+
v = v.replace(/\/+/g, '/'); // collapse multiple slashes
|
|
9
|
+
// if the path includes /src/, make it relative to src
|
|
10
|
+
v = v.replace(/^.*\/src(\/|$)/, '/'); // ".../src/foo" → "/foo"
|
|
11
|
+
if (!v.startsWith('/')) v = '/' + v; // ensure leading slash
|
|
12
|
+
// strip trailing slash except for root
|
|
13
|
+
if (v.length > 1 && v.endsWith('/')) v = v.slice(0, -1);
|
|
14
|
+
|
|
15
|
+
return v.toLowerCase(); // case-insensitive
|
|
16
|
+
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const normalizePattern = (p) => {
|
|
20
|
+
|
|
21
|
+
let v = String(p).replace(/\\/g, '/').replace(/^\.\/+/, '').replace(/\/+/g, '/');
|
|
22
|
+
|
|
23
|
+
if (!v.includes('*') && !v.includes('.') && !v.endsWith('/')) v += '/';
|
|
24
|
+
if (!v.startsWith('/')) v = '/' + v;
|
|
25
|
+
|
|
26
|
+
return v.toLowerCase(); // case-insensitive
|
|
27
|
+
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const pathCandidates = (() => {
|
|
31
|
+
|
|
32
|
+
const p = normalizePath(filePath);
|
|
33
|
+
const noSrc = String(filePath).replace(/\\/g, '/').replace(/^\.\/+/, '');
|
|
34
|
+
const alt = (noSrc.startsWith('/') ? noSrc : '/' + noSrc).toLowerCase();
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
return Array.from(new Set([ p, alt ]));
|
|
38
|
+
|
|
39
|
+
})();
|
|
40
|
+
|
|
41
|
+
const matches = (fp, pat) => {
|
|
42
|
+
|
|
43
|
+
// 1) "*.ext" anywhere
|
|
44
|
+
if (/^\/\*\.[^/]+$/.test(pat)) {
|
|
45
|
+
|
|
46
|
+
const ext = pat.slice(2); // "*.js" -> ".js"
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
return fp.endsWith(ext);
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 2) "folder/*" => only immediate children (no subfolders)
|
|
54
|
+
if (pat.endsWith('/*')) {
|
|
55
|
+
|
|
56
|
+
const base = pat.slice(0, -2);
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
return fp.startsWith(base + '/') && !fp.slice(base.length + 1).includes('/');
|
|
60
|
+
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// 3) "folder/*.ext" => files with ext in that folder (no subfolders)
|
|
64
|
+
if (pat.includes('/*')) {
|
|
65
|
+
|
|
66
|
+
const [ base, tail ] = pat.split('/*');
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
return fp.startsWith(base + '/') &&
|
|
70
|
+
fp.endsWith(tail) &&
|
|
71
|
+
!fp.slice(base.length + 1).includes('/');
|
|
72
|
+
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// 4) Plain directory "folder/" => whole dir + subdirs
|
|
76
|
+
if (pat.endsWith('/')) {
|
|
77
|
+
|
|
78
|
+
const base = pat.slice(0, -1);
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
return fp === base || fp.startsWith(base + '/');
|
|
82
|
+
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// 5) Exact file
|
|
86
|
+
return fp === pat;
|
|
87
|
+
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
return ignorePatterns.some((raw) => {
|
|
91
|
+
|
|
92
|
+
const pat = normalizePattern(raw);
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
return pathCandidates.some((fp) => matches(fp, pat));
|
|
96
|
+
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
}
|
|
@@ -2,7 +2,11 @@ import getAllFiles from '../getAllFiles.js';
|
|
|
2
2
|
import extractJSDocComment from './extractJSDocComment.js';
|
|
3
3
|
import { join } from 'path';
|
|
4
4
|
|
|
5
|
-
export default function buildFileDataList(
|
|
5
|
+
export default function buildFileDataList({
|
|
6
|
+
src,
|
|
7
|
+
ignore,
|
|
8
|
+
includeComments
|
|
9
|
+
}) {
|
|
6
10
|
|
|
7
11
|
const allFiles = getAllFiles(src, {
|
|
8
12
|
ignore,
|