npmdata 0.2.1 → 0.4.0
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 +368 -9
- package/bin/npmdata.js +4 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +117 -19
- package/dist/cli.js.map +1 -1
- package/dist/consumer.d.ts +32 -2
- package/dist/consumer.d.ts.map +1 -1
- package/dist/consumer.js +105 -18
- package/dist/consumer.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/npmdata-0.0.1.tgz +0 -0
- package/dist/publisher.d.ts +15 -3
- package/dist/publisher.d.ts.map +1 -1
- package/dist/publisher.js +66 -52
- package/dist/publisher.js.map +1 -1
- package/dist/runner.d.ts +30 -2
- package/dist/runner.d.ts.map +1 -1
- package/dist/runner.js +130 -73
- package/dist/runner.js.map +1 -1
- package/dist/types.d.ts +66 -10
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +2 -2
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,8 +1,368 @@
|
|
|
1
|
-
# npmdata
|
|
1
|
+
# npmdata
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Publish folders as npm packages and extract them in any workspace. Use it to distribute shared assets — ML datasets, documentation, ADRs, configuration files — across multiple projects through any npm-compatible registry.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## How it works
|
|
6
|
+
|
|
7
|
+
- **Publisher**: a project that has folders to share. Running `init` prepares its `package.json` so those folders are included when the package is published.
|
|
8
|
+
- **Consumer**: any project that installs that package and runs `extract` to download the files locally. A `.publisher` marker file is written alongside the managed files to track ownership and enable safe updates.
|
|
9
|
+
|
|
10
|
+
## Quick start
|
|
11
|
+
|
|
12
|
+
### 1. Prepare the publisher package
|
|
13
|
+
|
|
14
|
+
In the project whose folders you want to share:
|
|
15
|
+
|
|
16
|
+
```sh
|
|
17
|
+
# share specific folders by glob pattern (required)
|
|
18
|
+
pnpm dlx npmdata init --files "docs/**,data/**,configs/**"
|
|
19
|
+
|
|
20
|
+
# also bundle an additional package so consumers get data from both sources
|
|
21
|
+
pnpm dlx npmdata init --files "docs/**" --packages shared-configs@^1.0.0
|
|
22
|
+
|
|
23
|
+
# share multiple additional packages at once
|
|
24
|
+
pnpm dlx npmdata init --files "docs/**" --packages "shared-configs@^1.0.0,base-templates@2.x"
|
|
25
|
+
|
|
26
|
+
# skip .gitignore entries for managed files (gitignore is enabled by default)
|
|
27
|
+
pnpm dlx npmdata init --files "docs/**,data/**" --no-gitignore
|
|
28
|
+
|
|
29
|
+
# mark extracted files as unmanaged so consumers can edit them freely;
|
|
30
|
+
# files won't be tracked, made read-only, or added to .gitignore
|
|
31
|
+
pnpm dlx npmdata init --files "templates/**" --unmanaged
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
`init` updates `package.json` with the right `files`, `bin`, and `dependencies` fields so those folders are included when the package is published, and writes a thin `bin/npmdata.js` entry point. Then publish normally:
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
npm publish
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### 2. Extract files in a consumer project
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
# extract all files from the package
|
|
44
|
+
npx npmdata extract --packages my-shared-assets --output ./data
|
|
45
|
+
|
|
46
|
+
# extract from a specific version
|
|
47
|
+
npx npmdata extract --packages my-shared-assets@^2.0.0 --output ./data
|
|
48
|
+
|
|
49
|
+
# extract from multiple packages at once
|
|
50
|
+
npx npmdata extract --packages "my-shared-assets@^2.0.0,another-pkg@1.x" --output ./data
|
|
51
|
+
|
|
52
|
+
# extract only markdown files
|
|
53
|
+
npx npmdata extract --packages my-shared-assets --files "**/*.md" --output ./docs
|
|
54
|
+
|
|
55
|
+
# extract only files whose content matches a regex
|
|
56
|
+
npx npmdata extract --packages my-shared-assets --content-regex "env: production" --output ./configs
|
|
57
|
+
|
|
58
|
+
# overwrite files that are unmanaged or owned by a different package;
|
|
59
|
+
# the new package takes ownership in the marker file
|
|
60
|
+
npx npmdata extract --packages my-shared-assets --output ./data --force
|
|
61
|
+
|
|
62
|
+
# skip .gitignore entries for managed files (gitignore is enabled by default)
|
|
63
|
+
npx npmdata extract --packages my-shared-assets --output ./data --no-gitignore
|
|
64
|
+
|
|
65
|
+
# write files without a .npmdata marker or .gitignore entry; files won't be read-only
|
|
66
|
+
# and won't be tracked by npmdata; existing files are left unchanged
|
|
67
|
+
npx npmdata extract --packages my-shared-assets --output ./data --unmanaged
|
|
68
|
+
|
|
69
|
+
# preview what would change without writing any files
|
|
70
|
+
npx npmdata extract --packages my-shared-assets --output ./data --dry-run
|
|
71
|
+
|
|
72
|
+
# force-reinstall the package even if already installed (e.g. after a floating tag moves)
|
|
73
|
+
npx npmdata extract --packages my-shared-assets@latest --output ./data --upgrade
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`extract` logs every file change as it happens:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
A data/users-dataset/user1.json
|
|
80
|
+
M data/configs/app.config.json
|
|
81
|
+
D data/old-file.json
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
If the published package includes its own bin script (normally when it's prepared using "init") you can also call it directly so it extracts data that is inside the package itself:
|
|
85
|
+
|
|
86
|
+
```sh
|
|
87
|
+
npx my-shared-assets extract --output ./data
|
|
88
|
+
npx my-shared-assets check --output ./data
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
When the data package defines multiple `npmdata` entries in its `package.json`, you can limit which entries are processed using the `--tags` option. Only entries whose `tags` list includes at least one of the requested tags will be extracted; entries with no tags are skipped when a tag filter is active.
|
|
92
|
+
|
|
93
|
+
```sh
|
|
94
|
+
# run only entries tagged with "prod"
|
|
95
|
+
npx my-shared-assets --tags prod
|
|
96
|
+
|
|
97
|
+
# run entries tagged with either "prod" or "staging"
|
|
98
|
+
npx my-shared-assets --tags prod,staging
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
To use tags, add a `tags` array to each `npmdata` entry in the data package's `package.json`:
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"npmdata": [
|
|
106
|
+
{ "package": "my-shared-assets", "outputDir": "./data", "tags": ["prod"] },
|
|
107
|
+
{ "package": "my-dev-assets", "outputDir": "./dev-data", "tags": ["dev", "staging"] }
|
|
108
|
+
]
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Check the /examples folder to see this in action
|
|
113
|
+
|
|
114
|
+
### 3. Check files are in sync
|
|
115
|
+
|
|
116
|
+
```sh
|
|
117
|
+
npx npmdata check --packages my-shared-assets --output ./data
|
|
118
|
+
# exit 0 = in sync, exit 2 = differences found
|
|
119
|
+
|
|
120
|
+
# check multiple packages
|
|
121
|
+
npx npmdata check --packages "my-shared-assets,another-pkg" --output ./data
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The check command reports differences per package:
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
my-shared-assets@^2.0.0 FAIL
|
|
128
|
+
missing: data/new-file.json
|
|
129
|
+
modified: data/configs/app.config.json
|
|
130
|
+
extra: data/old-file.json
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 4. List managed files
|
|
134
|
+
|
|
135
|
+
```sh
|
|
136
|
+
# list all files managed by npmdata in an output directory
|
|
137
|
+
npx npmdata list --output ./data
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Output is grouped by package:
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
my-shared-assets@2.1.0
|
|
144
|
+
data/users-dataset/user1.json
|
|
145
|
+
data/configs/app.config.json
|
|
146
|
+
|
|
147
|
+
another-pkg@1.0.0
|
|
148
|
+
data/other-file.txt
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### 5. Purge managed files
|
|
152
|
+
|
|
153
|
+
Remove all files previously extracted by one or more packages without touching any other files in the output directory. No network access or package installation is required — only the local `.npmdata` marker state is used.
|
|
154
|
+
|
|
155
|
+
```sh
|
|
156
|
+
# remove all files managed by a package
|
|
157
|
+
npx npmdata purge --packages my-shared-assets --output ./data
|
|
158
|
+
|
|
159
|
+
# purge multiple packages at once
|
|
160
|
+
npx npmdata purge --packages "my-shared-assets,another-pkg" --output ./data
|
|
161
|
+
|
|
162
|
+
# preview what would be deleted without removing anything
|
|
163
|
+
npx npmdata purge --packages my-shared-assets --output ./data --dry-run
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
After a purge, the corresponding entries are removed from the `.npmdata` marker file and any empty directories are cleaned up. `.gitignore` sections written by `extract` are also removed.
|
|
167
|
+
|
|
168
|
+
## CLI reference
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
Usage:
|
|
172
|
+
npx npmdata [init|extract|check|list|purge] [options]
|
|
173
|
+
|
|
174
|
+
Commands:
|
|
175
|
+
init Set up publishing configuration in a package
|
|
176
|
+
extract Extract files from a published package into a local directory
|
|
177
|
+
check Verify local files are in sync with the published package
|
|
178
|
+
list List all files managed by npmdata in an output directory
|
|
179
|
+
purge Remove all managed files previously extracted by given packages
|
|
180
|
+
|
|
181
|
+
Global options:
|
|
182
|
+
--help, -h Show help
|
|
183
|
+
--version, -v Show version
|
|
184
|
+
|
|
185
|
+
Init options:
|
|
186
|
+
--files <patterns> Comma-separated glob patterns of files to publish (required)
|
|
187
|
+
e.g. "docs/**,data/**,configs/*.json"
|
|
188
|
+
--packages <specs> Comma-separated additional package specs to bundle as data sources.
|
|
189
|
+
Each spec is "name" or "name@version", e.g.
|
|
190
|
+
"shared-configs@^1.0.0,base-templates@2.x".
|
|
191
|
+
Listed under `npmdata.additionalPackages` in package.json and
|
|
192
|
+
added to `dependencies` so consumers pull data from all of them.
|
|
193
|
+
--no-gitignore Skip adding .gitignore entries for managed files
|
|
194
|
+
(gitignore is enabled by default)
|
|
195
|
+
--unmanaged Mark all generated npmdata entries as unmanaged: extracted files
|
|
196
|
+
are written without a .npmdata marker, without updating .gitignore,
|
|
197
|
+
and without being made read-only. Existing files are skipped.
|
|
198
|
+
|
|
199
|
+
Extract options:
|
|
200
|
+
--packages <specs> Comma-separated package specs (required).
|
|
201
|
+
Each spec is "name" or "name@version", e.g.
|
|
202
|
+
"my-pkg@^1.0.0,other-pkg@2.x"
|
|
203
|
+
--output, -o <dir> Output directory (default: current directory)
|
|
204
|
+
--force Overwrite existing unmanaged files or files owned by a different package
|
|
205
|
+
--no-gitignore Skip creating/updating .gitignore (gitignore is enabled by default)
|
|
206
|
+
--unmanaged Write files without a .npmdata marker, .gitignore update, or read-only
|
|
207
|
+
flag. Existing files are skipped. Files can be freely edited afterwards
|
|
208
|
+
and are not tracked by npmdata.
|
|
209
|
+
--files <patterns> Comma-separated glob patterns to filter files
|
|
210
|
+
--content-regex <regex> Regex to filter files by content
|
|
211
|
+
--dry-run Preview changes without writing any files
|
|
212
|
+
--upgrade Reinstall the package even if already present
|
|
213
|
+
|
|
214
|
+
Check options:
|
|
215
|
+
--packages <specs> Same format as extract (required)
|
|
216
|
+
--output, -o <dir> Output directory to check (default: current directory)
|
|
217
|
+
|
|
218
|
+
Purge options:
|
|
219
|
+
--packages <specs> Comma-separated package names whose managed files should be removed
|
|
220
|
+
--output, -o <dir> Output directory to purge from (default: current directory)
|
|
221
|
+
--dry-run Simulate purge without removing any files
|
|
222
|
+
--silent Suppress per-file output
|
|
223
|
+
|
|
224
|
+
List options:
|
|
225
|
+
--output, -o <dir> Output directory to inspect (default: current directory)
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Library usage
|
|
229
|
+
|
|
230
|
+
`npmdata` also exports a programmatic API:
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
import { extract, check, list, purge, initPublisher, parsePackageSpec, isBinaryFile } from 'npmdata';
|
|
234
|
+
import type { ConsumerConfig, ConsumerResult, CheckResult, PurgeConfig, ProgressEvent } from 'npmdata';
|
|
235
|
+
|
|
236
|
+
// extract files from one package
|
|
237
|
+
const result = await extract({
|
|
238
|
+
packages: ['my-shared-assets@^2.0.0'],
|
|
239
|
+
outputDir: './data',
|
|
240
|
+
gitignore: true,
|
|
241
|
+
});
|
|
242
|
+
console.log(result.added, result.modified, result.deleted);
|
|
243
|
+
|
|
244
|
+
// dry-run: preview changes without writing files
|
|
245
|
+
const preview = await extract({
|
|
246
|
+
packages: ['my-shared-assets@^2.0.0'],
|
|
247
|
+
outputDir: './data',
|
|
248
|
+
dryRun: true,
|
|
249
|
+
});
|
|
250
|
+
console.log('Would add', preview.added, 'files');
|
|
251
|
+
|
|
252
|
+
// force-reinstall the package even if already present
|
|
253
|
+
await extract({
|
|
254
|
+
packages: ['my-shared-assets@latest'],
|
|
255
|
+
outputDir: './data',
|
|
256
|
+
upgrade: true,
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// extract without npmdata tracking: files are writable, no .npmdata marker is written,
|
|
260
|
+
// no .gitignore entry is created. Existing files are left untouched (skipped).
|
|
261
|
+
await extract({
|
|
262
|
+
packages: ['shared-templates'],
|
|
263
|
+
outputDir: './templates',
|
|
264
|
+
unmanaged: true,
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
// track progress file-by-file
|
|
268
|
+
await extract({
|
|
269
|
+
packages: ['my-shared-assets@^2.0.0'],
|
|
270
|
+
outputDir: './data',
|
|
271
|
+
onProgress: (event: ProgressEvent) => {
|
|
272
|
+
if (event.type === 'file-added') console.log('A', event.file);
|
|
273
|
+
if (event.type === 'file-modified') console.log('M', event.file);
|
|
274
|
+
if (event.type === 'file-deleted') console.log('D', event.file);
|
|
275
|
+
},
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
// extract files from multiple packages into the same output directory
|
|
279
|
+
const multiResult = await extract({
|
|
280
|
+
packages: ['my-shared-assets@^2.0.0', 'another-pkg@1.x'],
|
|
281
|
+
outputDir: './data',
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
// check sync status — per-package breakdown
|
|
285
|
+
const status = await check({
|
|
286
|
+
packages: ['my-shared-assets'],
|
|
287
|
+
outputDir: './data',
|
|
288
|
+
});
|
|
289
|
+
if (!status.ok) {
|
|
290
|
+
console.log('Overall differences:', status.differences);
|
|
291
|
+
for (const pkg of status.sourcePackages) {
|
|
292
|
+
if (!pkg.ok) {
|
|
293
|
+
console.log(pkg.name, 'missing:', pkg.differences.missing);
|
|
294
|
+
console.log(pkg.name, 'modified:', pkg.differences.modified);
|
|
295
|
+
console.log(pkg.name, 'extra:', pkg.differences.extra);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// remove all files previously extracted by a package (no network required)
|
|
301
|
+
await purge({
|
|
302
|
+
packages: ['my-shared-assets'],
|
|
303
|
+
outputDir: './data',
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
// dry-run: preview what would be deleted without removing anything
|
|
307
|
+
const purgePreview = await purge({
|
|
308
|
+
packages: ['my-shared-assets'],
|
|
309
|
+
outputDir: './data',
|
|
310
|
+
dryRun: true,
|
|
311
|
+
});
|
|
312
|
+
console.log('Would delete', purgePreview.deleted, 'files');
|
|
313
|
+
|
|
314
|
+
// track progress during purge
|
|
315
|
+
await purge({
|
|
316
|
+
packages: ['my-shared-assets'],
|
|
317
|
+
outputDir: './data',
|
|
318
|
+
onProgress: (event: ProgressEvent) => {
|
|
319
|
+
if (event.type === 'file-deleted') console.log('D', event.file);
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
// list all files managed by npmdata in an output directory
|
|
324
|
+
const managed = await list('./data');
|
|
325
|
+
// managed is Record<string, string[]> keyed by "package@version"
|
|
326
|
+
|
|
327
|
+
// initialize a publisher package
|
|
328
|
+
await initPublisher(['docs', 'data'], { workingDir: './my-package' });
|
|
329
|
+
|
|
330
|
+
// utility: parse a package spec string
|
|
331
|
+
const { name, version } = parsePackageSpec('my-pkg@^1.0.0');
|
|
332
|
+
|
|
333
|
+
// utility: detect whether a file is binary
|
|
334
|
+
const binary = isBinaryFile('/path/to/file.bin');
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### `ProgressEvent` type
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
type ProgressEvent =
|
|
341
|
+
| { type: 'package-start'; packageName: string; packageVersion: string }
|
|
342
|
+
| { type: 'package-end'; packageName: string; packageVersion: string }
|
|
343
|
+
| { type: 'file-added'; packageName: string; file: string }
|
|
344
|
+
| { type: 'file-modified'; packageName: string; file: string }
|
|
345
|
+
| { type: 'file-deleted'; packageName: string; file: string }
|
|
346
|
+
| { type: 'file-skipped'; packageName: string; file: string };
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
See [lib/README.md](lib/README.md) for the full API reference.
|
|
350
|
+
|
|
351
|
+
## Managed file tracking
|
|
352
|
+
|
|
353
|
+
Extracted files are set read-only (`444`) and tracked in a `.publisher` marker file in each output directory. On subsequent extractions:
|
|
354
|
+
|
|
355
|
+
- Unchanged files are skipped.
|
|
356
|
+
- Updated files are overwritten.
|
|
357
|
+
- Files removed from the package are deleted locally.
|
|
358
|
+
|
|
359
|
+
The marker file uses a `|`-delimited format; files written by older versions of `npmdata` using the comma-delimited format are read correctly for backward compatibility.
|
|
360
|
+
|
|
361
|
+
Multiple packages can coexist in the same output directory; each owns its own files.
|
|
362
|
+
|
|
363
|
+
## Developer Notes
|
|
364
|
+
|
|
365
|
+
### Module overview
|
|
6
366
|
|
|
7
367
|
| Module | Purpose |
|
|
8
368
|
|---|---|
|
|
@@ -13,11 +373,11 @@ This document covers the internal architecture for contributors working on this
|
|
|
13
373
|
| `utils.ts` | File I/O helpers: glob matching via `minimatch`, SHA-256 hashing, CSV marker read/write, package manager detection |
|
|
14
374
|
| `types.ts` | Shared TypeScript types and constants (e.g. `DEFAULT_FILENAME_PATTERNS`) |
|
|
15
375
|
|
|
16
|
-
|
|
376
|
+
### Publish side (`publisher.ts`)
|
|
17
377
|
|
|
18
378
|
`initPublisher()` modifies the target `package.json` to include `files`, `bin`, and `dependencies` fields, then writes a thin `bin/npmdata.js` that calls `runner.run(__dirname)`. The generated script is kept minimal on purpose — all logic lives in this library.
|
|
19
379
|
|
|
20
|
-
|
|
380
|
+
### Consumer side (`consumer.ts`)
|
|
21
381
|
|
|
22
382
|
`extract()` flow:
|
|
23
383
|
1. Detects the package manager (`pnpm` / `yarn` / `npm`) via lock-file presence.
|
|
@@ -28,19 +388,18 @@ This document covers the internal architecture for contributors working on this
|
|
|
28
388
|
|
|
29
389
|
`check()` performs the same resolution for each package in `config.packages` but compares SHA-256 hashes without writing any files.
|
|
30
390
|
|
|
31
|
-
|
|
391
|
+
### Marker file (`.publisher`)
|
|
32
392
|
|
|
33
393
|
Each output directory that contains managed files gets a `.publisher` CSV file. Columns: `path`, `packageName`, `packageVersion`, `sha256`. This is the source of truth for drift detection and clean removal.
|
|
34
394
|
|
|
35
|
-
|
|
395
|
+
### Key design decisions
|
|
36
396
|
|
|
37
397
|
- No runtime dependencies beyond `semver` and `minimatch` to keep the consumer install footprint small.
|
|
38
398
|
- File identity is tracked by path + hash, not by timestamp, to be deterministic across machines.
|
|
39
399
|
- The bin script generated by `initPublisher` contains no logic; all behaviour is versioned inside this library.
|
|
40
400
|
|
|
41
|
-
|
|
401
|
+
### Dev workflow
|
|
42
402
|
|
|
43
403
|
```
|
|
44
404
|
make build lint-fix test
|
|
45
405
|
```
|
|
46
|
-
|
package/bin/npmdata.js
ADDED
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAaA;;GAEG;AAEH,wBAAsB,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAaA;;GAEG;AAEH,wBAAsB,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAgVhE"}
|
package/dist/cli.js
CHANGED
|
@@ -37,39 +37,53 @@ async function cli(processArgs) {
|
|
|
37
37
|
// Handle init command
|
|
38
38
|
if (command === 'init') {
|
|
39
39
|
// eslint-disable-next-line functional/no-let
|
|
40
|
-
let
|
|
40
|
+
let sourceFilesFlag;
|
|
41
41
|
// eslint-disable-next-line functional/no-let
|
|
42
42
|
let additionalPackagesFlag;
|
|
43
|
-
//
|
|
43
|
+
// eslint-disable-next-line functional/no-let
|
|
44
|
+
let initGitignore = true;
|
|
45
|
+
// eslint-disable-next-line functional/no-let
|
|
46
|
+
let initUnmanaged = false;
|
|
47
|
+
// Parse args for --files and --packages flags
|
|
44
48
|
// eslint-disable-next-line functional/no-let
|
|
45
49
|
for (let i = 1; i < args.length; i += 1) {
|
|
46
|
-
if (args[i] === '--
|
|
50
|
+
if (args[i] === '--files') {
|
|
47
51
|
// eslint-disable-next-line no-plusplus
|
|
48
|
-
|
|
52
|
+
sourceFilesFlag = args[++i];
|
|
49
53
|
}
|
|
50
54
|
else if (args[i] === '--packages') {
|
|
51
55
|
// eslint-disable-next-line no-plusplus
|
|
52
56
|
additionalPackagesFlag = args[++i];
|
|
53
57
|
}
|
|
58
|
+
else if (args[i] === '--no-gitignore') {
|
|
59
|
+
initGitignore = false;
|
|
60
|
+
}
|
|
61
|
+
else if (args[i] === '--unmanaged') {
|
|
62
|
+
initUnmanaged = true;
|
|
63
|
+
}
|
|
54
64
|
}
|
|
55
|
-
// --
|
|
56
|
-
if (!
|
|
57
|
-
console.error('Error: --
|
|
65
|
+
// --files is required
|
|
66
|
+
if (!sourceFilesFlag) {
|
|
67
|
+
console.error('Error: --files option is required for init command');
|
|
58
68
|
printUsage();
|
|
59
69
|
return 1;
|
|
60
70
|
}
|
|
61
|
-
const
|
|
71
|
+
const fileGlobs = sourceFilesFlag.split(',').map((f) => f.trim());
|
|
62
72
|
const additionalPackages = additionalPackagesFlag
|
|
63
73
|
? additionalPackagesFlag.split(',').map((p) => p.trim())
|
|
64
74
|
: [];
|
|
65
|
-
const result = await (0, publisher_1.initPublisher)(
|
|
75
|
+
const result = await (0, publisher_1.initPublisher)(fileGlobs, {
|
|
76
|
+
additionalPackages,
|
|
77
|
+
gitignore: initGitignore,
|
|
78
|
+
...(initUnmanaged ? { unmanaged: true } : {}),
|
|
79
|
+
});
|
|
66
80
|
if (!result.success) {
|
|
67
81
|
console.error(`\nError: ${result.message}`);
|
|
68
82
|
return 1;
|
|
69
83
|
}
|
|
70
84
|
console.log(`\n${result.message}`);
|
|
71
|
-
if (result.
|
|
72
|
-
console.log(`\nThe following
|
|
85
|
+
if (result.publishedFiles) {
|
|
86
|
+
console.log(`\nThe following file patterns will be published: ${result.publishedFiles.join(', ')}`);
|
|
73
87
|
}
|
|
74
88
|
if (result.additionalPackages && result.additionalPackages.length > 0) {
|
|
75
89
|
console.log(`\nAdditional data source packages: ${result.additionalPackages.join(', ')}`);
|
|
@@ -106,19 +120,85 @@ async function cli(processArgs) {
|
|
|
106
120
|
}
|
|
107
121
|
return 0;
|
|
108
122
|
}
|
|
123
|
+
// Handle purge command
|
|
124
|
+
if (command === 'purge') {
|
|
125
|
+
let purgePackageSpecs;
|
|
126
|
+
let purgeOutDir = process.cwd();
|
|
127
|
+
let purgeOutputFlagProvided = false;
|
|
128
|
+
let purgeDryRun = false;
|
|
129
|
+
let purgeSilent = false;
|
|
130
|
+
for (let i = 1; i < args.length; i++) {
|
|
131
|
+
if (args[i] === '--packages') {
|
|
132
|
+
purgePackageSpecs = args[++i];
|
|
133
|
+
}
|
|
134
|
+
else if (args[i] === '--output' || args[i] === '-o') {
|
|
135
|
+
purgeOutDir = args[++i];
|
|
136
|
+
purgeOutputFlagProvided = true;
|
|
137
|
+
}
|
|
138
|
+
else if (args[i] === '--dry-run') {
|
|
139
|
+
purgeDryRun = true;
|
|
140
|
+
}
|
|
141
|
+
else if (args[i] === '--silent') {
|
|
142
|
+
purgeSilent = true;
|
|
143
|
+
}
|
|
144
|
+
else if (!args[i].startsWith('-')) {
|
|
145
|
+
purgeOutDir = args[i];
|
|
146
|
+
purgeOutputFlagProvided = true;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (!purgePackageSpecs) {
|
|
150
|
+
console.error(`Error: --packages option is required for 'purge' command`);
|
|
151
|
+
printUsage();
|
|
152
|
+
return 1;
|
|
153
|
+
}
|
|
154
|
+
if (!purgeOutputFlagProvided && !purgeSilent) {
|
|
155
|
+
console.info(`No --output specified. Using current directory: ${purgeOutDir}`);
|
|
156
|
+
}
|
|
157
|
+
const purgePackages = purgePackageSpecs.split(',').map((s) => s.trim());
|
|
158
|
+
const purgeOnProgress = purgeSilent
|
|
159
|
+
? // eslint-disable-next-line no-undefined
|
|
160
|
+
undefined
|
|
161
|
+
: (event) => {
|
|
162
|
+
switch (event.type) {
|
|
163
|
+
case 'package-start':
|
|
164
|
+
console.log(`\n>> Package ${event.packageName}`);
|
|
165
|
+
break;
|
|
166
|
+
case 'file-deleted':
|
|
167
|
+
console.log(`D\t${event.file}`);
|
|
168
|
+
break;
|
|
169
|
+
default:
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
if (!purgeSilent) {
|
|
174
|
+
if (purgeDryRun)
|
|
175
|
+
console.info('Dry run: simulating purge (no files will be removed)...');
|
|
176
|
+
else
|
|
177
|
+
console.info('Purging managed files...');
|
|
178
|
+
}
|
|
179
|
+
const purgeResult = await (0, consumer_1.purge)({
|
|
180
|
+
packages: purgePackages,
|
|
181
|
+
outputDir: node_path_1.default.resolve(purgeOutDir),
|
|
182
|
+
dryRun: purgeDryRun,
|
|
183
|
+
onProgress: purgeOnProgress,
|
|
184
|
+
});
|
|
185
|
+
console.log(`\nPurge complete: ${purgeResult.deleted.length} deleted${purgeDryRun ? ' (dry run)' : ''}`);
|
|
186
|
+
return 0;
|
|
187
|
+
}
|
|
109
188
|
// Consumer commands (extract, check)
|
|
110
189
|
if (!['extract', 'check'].includes(command)) {
|
|
111
|
-
console.error(`Error: unknown command '${command}'. Use 'init', 'extract', 'check', or 'list'`);
|
|
190
|
+
console.error(`Error: unknown command '${command}'. Use 'init', 'extract', 'check', 'purge', or 'list'`);
|
|
112
191
|
printUsage();
|
|
113
192
|
return 1;
|
|
114
193
|
}
|
|
115
194
|
// Parse options common to extract and check
|
|
116
195
|
let packageSpecs;
|
|
117
196
|
let force = false;
|
|
118
|
-
let gitignore =
|
|
197
|
+
let gitignore = true;
|
|
119
198
|
let dryRun = false;
|
|
120
199
|
let upgrade = false;
|
|
121
200
|
let silent = false;
|
|
201
|
+
let unmanaged = false;
|
|
122
202
|
let filenamePatterns;
|
|
123
203
|
let contentRegexes;
|
|
124
204
|
let outDir = process.cwd();
|
|
@@ -133,8 +213,8 @@ async function cli(processArgs) {
|
|
|
133
213
|
else if (args[i] === '--silent') {
|
|
134
214
|
silent = true;
|
|
135
215
|
}
|
|
136
|
-
else if (args[i] === '--gitignore') {
|
|
137
|
-
gitignore =
|
|
216
|
+
else if (args[i] === '--no-gitignore') {
|
|
217
|
+
gitignore = false;
|
|
138
218
|
}
|
|
139
219
|
else if (args[i] === '--dry-run') {
|
|
140
220
|
dryRun = true;
|
|
@@ -142,6 +222,9 @@ async function cli(processArgs) {
|
|
|
142
222
|
else if (args[i] === '--upgrade') {
|
|
143
223
|
upgrade = true;
|
|
144
224
|
}
|
|
225
|
+
else if (args[i] === '--unmanaged') {
|
|
226
|
+
unmanaged = true;
|
|
227
|
+
}
|
|
145
228
|
else if (args[i] === '--files') {
|
|
146
229
|
filenamePatterns = args[++i];
|
|
147
230
|
}
|
|
@@ -195,6 +278,7 @@ async function cli(processArgs) {
|
|
|
195
278
|
gitignore,
|
|
196
279
|
dryRun,
|
|
197
280
|
upgrade,
|
|
281
|
+
unmanaged,
|
|
198
282
|
onProgress,
|
|
199
283
|
filenamePatterns: filenamePatterns
|
|
200
284
|
? filenamePatterns.split(',')
|
|
@@ -250,12 +334,13 @@ function printUsage() {
|
|
|
250
334
|
npmdata
|
|
251
335
|
|
|
252
336
|
Usage:
|
|
253
|
-
npx npmdata [init|extract|check|list] [options]
|
|
337
|
+
npx npmdata [init|extract|check|purge|list] [options]
|
|
254
338
|
|
|
255
339
|
Commands:
|
|
256
340
|
init Initialize publishing configuration
|
|
257
341
|
extract Extract files from one or more published packages
|
|
258
342
|
check Verify if local files are in sync with packages
|
|
343
|
+
purge Remove all managed files written by given packages
|
|
259
344
|
list List all managed files in the output directory
|
|
260
345
|
|
|
261
346
|
Global Options:
|
|
@@ -263,10 +348,12 @@ Global Options:
|
|
|
263
348
|
--version, -v Show version
|
|
264
349
|
|
|
265
350
|
Init Options:
|
|
266
|
-
--
|
|
351
|
+
--files <patterns> Comma-separated glob patterns of files to publish (required)
|
|
352
|
+
e.g. "docs/**,data/**,configs/*.json"
|
|
267
353
|
--packages <specs> Comma-separated additional package specs to use as data sources.
|
|
268
354
|
Each spec is "name" or "name@version"
|
|
269
355
|
e.g. "shared-data@^1.0.0,other-pkg@2.x"
|
|
356
|
+
--unmanaged Mark all npmdata entries as unmanaged (see Extract options)
|
|
270
357
|
|
|
271
358
|
Extract / Check Options:
|
|
272
359
|
--packages <specs> Comma-separated package specs to extract from (required).
|
|
@@ -274,18 +361,27 @@ Extract / Check Options:
|
|
|
274
361
|
e.g. "my-pkg@^1.2.3,other-pkg@2.x"
|
|
275
362
|
--output, -o <dir> Output directory (default: current directory, with a warning)
|
|
276
363
|
--force Allow overwriting existing unmanaged files
|
|
277
|
-
--gitignore
|
|
364
|
+
--no-gitignore Skip creating/updating .gitignore (gitignore is enabled by default)
|
|
365
|
+
--unmanaged Write files without a .npmdata marker, .gitignore update, or
|
|
366
|
+
read-only flag. Existing files are skipped. Files can be freely
|
|
367
|
+
edited afterwards and are not tracked by npmdata.
|
|
278
368
|
--dry-run Simulate extraction without writing any files
|
|
279
369
|
--upgrade Re-install packages even when a satisfying version is installed
|
|
280
370
|
--silent Print only the final result line, suppressing package and file listing
|
|
281
371
|
--files <pattern> Comma-separated shell glob patterns to filter files
|
|
282
372
|
--content-regex <regex> Regex pattern to match file contents
|
|
283
373
|
|
|
374
|
+
Purge Options:
|
|
375
|
+
--packages <specs> Comma-separated package names whose managed files should be removed
|
|
376
|
+
--output, -o <dir> Output directory to purge from (default: current directory)
|
|
377
|
+
--dry-run Simulate purge without removing any files
|
|
378
|
+
--silent Suppress per-file output
|
|
379
|
+
|
|
284
380
|
List Options:
|
|
285
381
|
--output, -o <dir> Directory to inspect (default: current directory)
|
|
286
382
|
|
|
287
383
|
Examples:
|
|
288
|
-
npx npmdata init --
|
|
384
|
+
npx npmdata init --files "data/**,docs/**,configs/*.json"
|
|
289
385
|
npx npmdata extract --packages mydataset --output ./data
|
|
290
386
|
npx npmdata extract --packages mydataset@^2.0.0 --output ./data
|
|
291
387
|
npx npmdata extract --packages "mydataset@^2.0.0,otherpkg@1.x" --output ./data
|
|
@@ -296,6 +392,8 @@ Examples:
|
|
|
296
392
|
npx npmdata check --packages mydataset --output ./data
|
|
297
393
|
npx npmdata check --packages "mydataset,otherpkg" --output ./data
|
|
298
394
|
npx npmdata list --output ./data
|
|
395
|
+
npx npmdata purge --packages mydataset --output ./data
|
|
396
|
+
npx npmdata purge --packages "mydataset,otherpkg" --output ./data
|
|
299
397
|
`);
|
|
300
398
|
}
|
|
301
399
|
//# sourceMappingURL=cli.js.map
|