@hraness/sponge 0.2.6 → 0.3.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 +21 -9
- package/bin/sponge.js +8 -7
- package/dist/contracts/index.js +24 -6
- package/dist/contracts/validate.js +106 -29
- package/dist/migrations/008.d.ts +3 -0
- package/dist/migrations/008.js +5 -0
- package/dist/migrations/009.d.ts +3 -0
- package/dist/migrations/009.js +8 -0
- package/dist/migrations/010.d.ts +3 -0
- package/dist/migrations/010.js +11 -0
- package/dist/migrations/index.d.ts +15 -0
- package/dist/migrations/index.js +39 -0
- package/dist/src/acquisition/capture.js +87 -28
- package/dist/src/acquisition/cleanup.d.ts +0 -4
- package/dist/src/acquisition/cleanup.js +3 -5
- package/dist/src/acquisition/errors.js +17 -2
- package/dist/src/acquisition/files.d.ts +0 -1
- package/dist/src/acquisition/files.js +14 -11
- package/dist/src/acquisition/index.d.ts +2 -3
- package/dist/src/acquisition/index.js +1 -2
- package/dist/src/acquisition/lock.js +1 -1
- package/dist/src/acquisition/normalize.js +57 -18
- package/dist/src/acquisition/pins.js +22 -4
- package/dist/src/acquisition/process.js +67 -29
- package/dist/src/acquisition/runtime.d.ts +5 -7
- package/dist/src/acquisition/runtime.js +129 -68
- package/dist/src/acquisition/verify-helper.js +10 -3
- package/dist/src/annotations/quote.js +40 -12
- package/dist/src/annotations/store.d.ts +0 -1
- package/dist/src/annotations/store.js +66 -14
- package/dist/src/app/article.d.ts +2 -1
- package/dist/src/app/article.js +66 -70
- package/dist/src/app/bundle-files.d.ts +0 -4
- package/dist/src/app/bundle-files.js +11 -14
- package/dist/src/app/markdown.js +18 -6
- package/dist/src/app/source.d.ts +0 -4
- package/dist/src/app/source.js +18 -14
- package/dist/src/cli/arguments.d.ts +2 -8
- package/dist/src/cli/arguments.js +67 -80
- package/dist/src/cli/commands.d.ts +42 -0
- package/dist/src/cli/commands.js +795 -0
- package/dist/src/cli/config.js +12 -9
- package/dist/src/cli/digest.d.ts +1 -1
- package/dist/src/cli/digest.js +38 -16
- package/dist/src/cli/import.js +25 -4
- package/dist/src/cli/indexing.d.ts +2 -0
- package/dist/src/cli/indexing.js +26 -9
- package/dist/src/cli/main.js +47 -386
- package/dist/src/cli/portability.d.ts +0 -2
- package/dist/src/cli/portability.js +13 -8
- package/dist/src/cli/queue.js +12 -8
- package/dist/src/cli/runtimes.d.ts +1 -3
- package/dist/src/cli/runtimes.js +13 -6
- package/dist/src/cli/terminal.js +1 -1
- package/dist/src/cli/worker.d.ts +7 -0
- package/dist/src/cli/worker.js +54 -15
- package/dist/src/derivations/kinds.d.ts +34 -0
- package/dist/src/derivations/kinds.js +14 -0
- package/dist/src/derivations/types.d.ts +48 -0
- package/dist/src/derivations/types.js +1 -0
- package/dist/src/digest/derivation.d.ts +25 -0
- package/dist/src/digest/derivation.js +124 -0
- package/dist/src/digest/editorial.d.ts +9 -46
- package/dist/src/digest/editorial.js +57 -49
- package/dist/src/digest/endpoint.js +63 -27
- package/dist/src/digest/pipeline.d.ts +49 -28
- package/dist/src/digest/pipeline.js +343 -100
- package/dist/src/digest/schema.d.ts +11 -25
- package/dist/src/digest/schema.js +86 -18
- package/dist/src/errors.d.ts +46 -0
- package/dist/src/errors.js +117 -0
- package/dist/src/identity/query-policy.d.ts +0 -5
- package/dist/src/identity/query-policy.js +61 -9
- package/dist/src/identity/uri.d.ts +6 -5
- package/dist/src/identity/uri.js +37 -18
- package/dist/src/identity/visibility.d.ts +11 -1
- package/dist/src/identity/visibility.js +81 -17
- package/dist/src/importers/apply.js +104 -36
- package/dist/src/importers/custody.js +27 -9
- package/dist/src/importers/inspect.js +125 -38
- package/dist/src/importers/jungle-digest.d.ts +3 -6
- package/dist/src/importers/jungle-digest.js +196 -69
- package/dist/src/importers/jungle-store.d.ts +15 -6
- package/dist/src/importers/jungle-store.js +122 -28
- package/dist/src/importers/jungle.d.ts +14 -14
- package/dist/src/importers/jungle.js +136 -31
- package/dist/src/importers/manifest.js +57 -21
- package/dist/src/importers/verify-helper.js +18 -4
- package/dist/src/indexing/image.js +29 -10
- package/dist/src/indexing/index.d.ts +37 -6
- package/dist/src/indexing/index.js +360 -124
- package/dist/src/indexing/jobs.js +156 -47
- package/dist/src/indexing/prune-run.d.ts +2 -0
- package/dist/src/indexing/prune-run.js +69 -26
- package/dist/src/indexing/prune.d.ts +12 -3
- package/dist/src/indexing/prune.js +85 -35
- package/dist/src/indexing/runner.d.ts +2 -1
- package/dist/src/indexing/runner.js +83 -40
- package/dist/src/indexing/upgrade.d.ts +9 -0
- package/dist/src/indexing/upgrade.js +79 -0
- package/dist/src/inference/asr/bridge.js +6 -2
- package/dist/src/inference/asr/protocol.js +109 -19
- package/dist/src/inference/asr/runtime.js +58 -21
- package/dist/src/inference/asr/windows.js +9 -5
- package/dist/src/inference/embedding/index.d.ts +2 -6
- package/dist/src/inference/embedding/index.js +89 -29
- package/dist/src/ingest/attempt.d.ts +29 -0
- package/dist/src/ingest/attempt.js +55 -0
- package/dist/src/media/capture-helper.js +7 -2
- package/dist/src/media/capture.d.ts +2 -1
- package/dist/src/media/capture.js +124 -43
- package/dist/src/media/handler.d.ts +4 -2
- package/dist/src/media/handler.js +88 -70
- package/dist/src/media/transcribe.js +63 -21
- package/dist/src/metadata/article.js +49 -17
- package/dist/src/models/artifacts.d.ts +10 -8
- package/dist/src/models/artifacts.js +237 -106
- package/dist/src/models/catalog.d.ts +2 -5
- package/dist/src/models/catalog.js +94 -25
- package/dist/src/models/download.js +55 -15
- package/dist/src/models/runtime.d.ts +0 -2
- package/dist/src/models/runtime.js +69 -33
- package/dist/src/pdf/capture-helper.js +3 -1
- package/dist/src/pdf/capture.d.ts +2 -1
- package/dist/src/pdf/capture.js +95 -27
- package/dist/src/pdf/errors.js +12 -1
- package/dist/src/pdf/handler.d.ts +2 -1
- package/dist/src/pdf/handler.js +70 -71
- package/dist/src/pdf/index.d.ts +1 -3
- package/dist/src/pdf/index.js +0 -2
- package/dist/src/pdf/input.js +12 -7
- package/dist/src/pdf/normalize.js +80 -21
- package/dist/src/pdf/source-identity.js +3 -2
- package/dist/src/pdf/source.js +12 -8
- package/dist/src/pdf/verify-helper.js +15 -3
- package/dist/src/portability/backup.d.ts +2 -9
- package/dist/src/portability/backup.js +106 -22
- package/dist/src/portability/database.js +51 -17
- package/dist/src/portability/export.js +35 -9
- package/dist/src/portability/files.d.ts +1 -4
- package/dist/src/portability/files.js +127 -67
- package/dist/src/portability/gc.js +65 -22
- package/dist/src/publish/component.js +1 -1
- package/dist/src/publish/feed.d.ts +2 -2
- package/dist/src/publish/feed.js +75 -29
- package/dist/src/publish/identity.d.ts +5 -1
- package/dist/src/publish/identity.js +31 -11
- package/dist/src/publish/index.d.ts +2 -3
- package/dist/src/publish/index.js +34 -21
- package/dist/src/publish/projection.d.ts +2 -9
- package/dist/src/publish/projection.js +21 -14
- package/dist/src/search/extension.js +3 -1
- package/dist/src/search/hybrid.d.ts +3 -8
- package/dist/src/search/hybrid.js +45 -11
- package/dist/src/search/lexical.js +18 -4
- package/dist/src/search/query.js +56 -25
- package/dist/src/search/vector.js +37 -10
- package/dist/src/service/launch-agent.d.ts +5 -3
- package/dist/src/service/launch-agent.js +272 -83
- package/dist/src/service/lifetime.js +47 -14
- package/dist/src/service/loop.d.ts +3 -3
- package/dist/src/service/loop.js +47 -19
- package/dist/src/store/annotations.d.ts +32 -0
- package/dist/src/store/annotations.js +44 -0
- package/dist/src/store/backups.d.ts +18 -0
- package/dist/src/store/backups.js +110 -0
- package/dist/src/store/blobs.d.ts +24 -0
- package/dist/src/store/blobs.js +139 -0
- package/dist/src/store/changes.d.ts +5 -12
- package/dist/src/store/changes.js +108 -56
- package/dist/src/store/context.d.ts +15 -0
- package/dist/src/store/context.js +19 -0
- package/dist/src/store/derivations.d.ts +42 -0
- package/dist/src/store/derivations.js +104 -0
- package/dist/src/store/files.d.ts +0 -2
- package/dist/src/store/files.js +19 -24
- package/dist/src/store/ids.d.ts +30 -0
- package/dist/src/store/ids.js +34 -0
- package/dist/src/store/imports.d.ts +26 -0
- package/dist/src/store/imports.js +57 -0
- package/dist/src/store/index.d.ts +3 -186
- package/dist/src/store/index.js +2 -809
- package/dist/src/store/lease.d.ts +20 -0
- package/dist/src/store/lease.js +62 -0
- package/dist/src/store/library.d.ts +75 -0
- package/dist/src/store/library.js +174 -0
- package/dist/src/store/open.d.ts +7 -0
- package/dist/src/store/open.js +183 -0
- package/dist/src/store/queue.d.ts +65 -0
- package/dist/src/store/queue.js +327 -0
- package/dist/src/store/revisions.d.ts +12 -0
- package/dist/src/store/revisions.js +189 -0
- package/dist/src/store/search-index.d.ts +63 -0
- package/dist/src/store/search-index.js +190 -0
- package/dist/src/store/sync-ready.d.ts +6 -0
- package/dist/src/store/sync-ready.js +121 -0
- package/dist/src/store/types.d.ts +1 -5
- package/dist/src/store/types.js +1 -8
- package/dist/src/util/canonical.d.ts +2 -0
- package/dist/src/util/canonical.js +17 -0
- package/dist/src/util/exact.d.ts +2 -0
- package/dist/src/util/exact.js +9 -0
- package/dist/src/util/fsync.d.ts +4 -0
- package/dist/src/util/fsync.js +22 -0
- package/dist/src/util/hash.d.ts +4 -0
- package/dist/src/util/hash.js +8 -0
- package/dist/src/worker/basic.d.ts +0 -1
- package/dist/src/worker/basic.js +23 -7
- package/dist/src/worker/custody.d.ts +4 -1
- package/dist/src/worker/custody.js +111 -38
- package/dist/src/worker/engine.d.ts +2 -1
- package/dist/src/worker/engine.js +42 -20
- package/dist/src/worker/identity.js +13 -5
- package/dist/src/worker/journal.d.ts +1 -1
- package/dist/src/worker/journal.js +54 -24
- package/dist/src/worker/lock.d.ts +18 -0
- package/dist/src/worker/lock.js +196 -0
- package/dist/src/worker/runtime-gc.d.ts +4 -3
- package/dist/src/worker/runtime-gc.js +68 -41
- package/dist/src/worker/supervisor-child.js +19 -6
- package/dist/src/worker/supervisor.js +41 -8
- package/native/runtime-manifest.json +4 -4
- package/package.json +10 -2
- package/dist/src/digest/store.d.ts +0 -57
- package/dist/src/digest/store.js +0 -79
- package/dist/src/store/foundation.d.ts +0 -7
- package/dist/src/store/foundation.js +0 -7
package/dist/src/app/source.js
CHANGED
|
@@ -1,36 +1,40 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { sha256 } from '../util/hash.js';
|
|
2
2
|
import { campaignFields, filterQuery } from '../identity/query-policy.js';
|
|
3
|
-
|
|
4
|
-
code = 'invalid-input';
|
|
5
|
-
constructor() { super('invalid-input'); }
|
|
6
|
-
}
|
|
3
|
+
import { SpongeError } from '../errors.js';
|
|
7
4
|
/** Identity normalization removes only known campaign fields; private realms remain distinct. */
|
|
8
5
|
function webSource(locator, realm, kind) {
|
|
9
|
-
if (Buffer.byteLength(locator) > 8192 ||
|
|
10
|
-
|
|
6
|
+
if (Buffer.byteLength(locator) > 8192 ||
|
|
7
|
+
!realm ||
|
|
8
|
+
Buffer.byteLength(realm) > 256 ||
|
|
9
|
+
/[\u0000-\u001f\u007f]/u.test(locator + realm))
|
|
10
|
+
throw new SpongeError('invalid-input');
|
|
11
11
|
const normalized = normalizeWebLocator(locator);
|
|
12
|
-
const sourceKey =
|
|
12
|
+
const sourceKey = sha256(JSON.stringify([kind, realm, normalized]));
|
|
13
13
|
return { sourceKey, locator, realm };
|
|
14
14
|
}
|
|
15
15
|
/** The identity form of an http(s) locator; source keys and shareable URIs both use it. Its output pins every existing source key. */
|
|
16
16
|
export function normalizeWebLocator(locator) {
|
|
17
17
|
if (Buffer.byteLength(locator) > 8192 || /[\u0000-\u001f\u007f]/u.test(locator))
|
|
18
|
-
throw new
|
|
18
|
+
throw new SpongeError('invalid-input');
|
|
19
19
|
let url;
|
|
20
20
|
try {
|
|
21
21
|
url = new URL(locator);
|
|
22
22
|
}
|
|
23
23
|
catch {
|
|
24
|
-
throw new
|
|
24
|
+
throw new SpongeError('invalid-input');
|
|
25
25
|
}
|
|
26
26
|
if (!['http:', 'https:'].includes(url.protocol) || url.username || url.password || !url.hostname)
|
|
27
|
-
throw new
|
|
27
|
+
throw new SpongeError('invalid-input');
|
|
28
28
|
// Undecodable keys are kept: they cannot be campaign fields.
|
|
29
29
|
if (url.search)
|
|
30
|
-
url.search = filterQuery(url.search, key => campaignFields.has(key));
|
|
30
|
+
url.search = filterQuery(url.search, (key) => campaignFields.has(key));
|
|
31
31
|
// URL normalizes host casing/default ports. Preserve query order, unknown fields and fragments.
|
|
32
32
|
return url.href;
|
|
33
33
|
}
|
|
34
|
-
export function articleSource(locator, realm = 'public') {
|
|
34
|
+
export function articleSource(locator, realm = 'public') {
|
|
35
|
+
return webSource(locator, realm, 'article');
|
|
36
|
+
}
|
|
35
37
|
/** A page and its media can be saved independently without changing existing article identities. */
|
|
36
|
-
export function mediaSource(locator, realm = 'public') {
|
|
38
|
+
export function mediaSource(locator, realm = 'public') {
|
|
39
|
+
return webSource(locator, realm, 'media');
|
|
40
|
+
}
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
positional: string[];
|
|
4
|
-
flags: Record<string, string | true>;
|
|
5
|
-
library?: string;
|
|
6
|
-
json: boolean;
|
|
7
|
-
}
|
|
8
|
-
/** No shell grammar, implicit option coercion, duplicate flags, or unbounded argv. */
|
|
1
|
+
import { type Arguments } from './commands.js';
|
|
2
|
+
/** No shell grammar, implicit option coercion, duplicate flags, or unbounded argv. Commands and their rules live in the registry. */
|
|
9
3
|
export declare function parseArguments(argv: string[]): Arguments;
|
|
@@ -1,47 +1,30 @@
|
|
|
1
1
|
import { isAbsolute } from 'node:path';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
show: { count: 1, flags: { format: 'value' } },
|
|
10
|
-
delete: { count: 1, flags: {} },
|
|
11
|
-
refresh: { count: 1, flags: { wait: 'boolean', language: 'value', 'force-local': 'boolean', 'allow-private-network': 'boolean' } },
|
|
12
|
-
search: { count: 1, flags: { mode: 'value', limit: 'value', profile: 'value' } },
|
|
13
|
-
run: { count: 0, flags: { drain: 'boolean', language: 'value', 'force-local': 'boolean', 'allow-private-network': 'boolean' } },
|
|
14
|
-
setup: { count: 0, flags: { capture: 'boolean', asr: 'boolean', embedding: 'boolean' } },
|
|
15
|
-
doctor: { count: 0, flags: {} },
|
|
16
|
-
queue: { count: -1, flags: {} },
|
|
17
|
-
export: { count: 1, flags: { output: 'value' } },
|
|
18
|
-
backup: { count: 0, flags: { output: 'value' } },
|
|
19
|
-
restore: { count: 1, flags: { into: 'value' } },
|
|
20
|
-
gc: { count: 0, flags: { 'dry-run': 'boolean', apply: 'value', runtimes: 'boolean' } },
|
|
21
|
-
worker: { count: 1, flags: { language: 'value', 'force-local': 'boolean' } },
|
|
22
|
-
index: { count: -1, flags: { profile: 'value', keep: 'value', 'dry-run': 'boolean', vacuum: 'boolean' } },
|
|
23
|
-
visibility: { count: 2, flags: {} },
|
|
24
|
-
highlight: { count: 2, flags: { note: 'value', occurrence: 'value' } },
|
|
25
|
-
comment: { count: 2, flags: { on: 'value' } },
|
|
26
|
-
publish: { count: 0, flags: { 'dry-run': 'boolean', output: 'value', 'min-age-days': 'value', title: 'value', 'base-url': 'value' } },
|
|
27
|
-
digest: { count: 1, flags: { endpoint: 'value', model: 'value', 'check-support': 'boolean' } },
|
|
28
|
-
review: { count: 1, flags: { accept: 'value', reject: 'value' } },
|
|
29
|
-
import: { count: -1, flags: { apply: 'boolean', 'dry-run': 'boolean', limit: 'value', offset: 'value' } },
|
|
2
|
+
import { SpongeError } from '../errors.js';
|
|
3
|
+
import { command as lookup, commands } from './commands.js';
|
|
4
|
+
const globals = {
|
|
5
|
+
library: 'value',
|
|
6
|
+
json: 'boolean',
|
|
7
|
+
debug: 'boolean',
|
|
8
|
+
help: 'boolean',
|
|
30
9
|
};
|
|
31
|
-
/**
|
|
10
|
+
/** A usage error names its command so the CLI can print that command's synopsis. */
|
|
11
|
+
const usage = (command) => {
|
|
12
|
+
throw new SpongeError('invalid-input', { detail: command ? { command } : {} });
|
|
13
|
+
};
|
|
14
|
+
/** No shell grammar, implicit option coercion, duplicate flags, or unbounded argv. Commands and their rules live in the registry. */
|
|
32
15
|
export function parseArguments(argv) {
|
|
33
|
-
if (argv.length > 32 || argv.some(arg => Buffer.byteLength(arg) > 8192 || /[\u0000-\u001f\u007f]/u.test(arg)))
|
|
34
|
-
|
|
35
|
-
if (argv.length === 0 || argv.length === 1 && ['--help', '-h'].includes(argv[0]))
|
|
36
|
-
return { command: 'help', positional: [], flags: {}, json: false };
|
|
16
|
+
if (argv.length > 32 || argv.some((arg) => Buffer.byteLength(arg) > 8192 || /[\u0000-\u001f\u007f]/u.test(arg)))
|
|
17
|
+
usage();
|
|
18
|
+
if (argv.length === 0 || (argv.length === 1 && ['--help', '-h'].includes(argv[0])))
|
|
19
|
+
return { command: 'help', positional: [], flags: {}, json: false, debug: false };
|
|
37
20
|
if (argv.length === 1 && argv[0] === '--version')
|
|
38
|
-
return { command: 'version', positional: [], flags: {}, json: false };
|
|
21
|
+
return { command: 'version', positional: [], flags: {}, json: false, debug: false };
|
|
39
22
|
// Global flags are valid before or after the command.
|
|
40
23
|
let command;
|
|
41
24
|
const flags = Object.create(null);
|
|
42
25
|
const positional = [];
|
|
43
|
-
const allFlags = {
|
|
44
|
-
for (const spec of
|
|
26
|
+
const allFlags = { ...globals };
|
|
27
|
+
for (const spec of commands)
|
|
45
28
|
Object.assign(allFlags, spec.flags);
|
|
46
29
|
let literal = false;
|
|
47
30
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -52,15 +35,15 @@ export function parseArguments(argv) {
|
|
|
52
35
|
}
|
|
53
36
|
if (arg.startsWith('--') && !literal) {
|
|
54
37
|
const key = arg.slice(2);
|
|
55
|
-
const kind = (command
|
|
38
|
+
const kind = lookup(command)?.flags[key] ?? allFlags[key];
|
|
56
39
|
if (!kind || Object.hasOwn(flags, key))
|
|
57
|
-
|
|
40
|
+
usage(command);
|
|
58
41
|
if (kind === 'boolean')
|
|
59
42
|
flags[key] = true;
|
|
60
43
|
else {
|
|
61
44
|
const value = argv[++i];
|
|
62
45
|
if (!value || value.startsWith('--'))
|
|
63
|
-
|
|
46
|
+
usage(command);
|
|
64
47
|
flags[key] = value;
|
|
65
48
|
}
|
|
66
49
|
}
|
|
@@ -69,55 +52,59 @@ export function parseArguments(argv) {
|
|
|
69
52
|
else
|
|
70
53
|
positional.push(arg);
|
|
71
54
|
}
|
|
72
|
-
const spec = command
|
|
73
|
-
if (!command
|
|
74
|
-
|
|
75
|
-
if (
|
|
76
|
-
|
|
55
|
+
const spec = lookup(command);
|
|
56
|
+
if (!command && flags.help)
|
|
57
|
+
return { command: 'help', positional: [], flags: {}, json: false, debug: flags.debug === true };
|
|
58
|
+
if (!command || !spec)
|
|
59
|
+
return usage();
|
|
60
|
+
if (flags.help)
|
|
61
|
+
return { command: 'help', positional: [spec.name], flags: {}, json: false, debug: flags.debug === true };
|
|
62
|
+
if (typeof spec.positional === 'number' ? positional.length !== spec.positional : !spec.positional(positional))
|
|
63
|
+
usage(command);
|
|
64
|
+
if (Object.keys(flags).some((key) => !Object.hasOwn(globals, key) && !Object.hasOwn(spec.flags, key)))
|
|
65
|
+
usage(command);
|
|
66
|
+
if (spec.check && !spec.check(positional, flags))
|
|
67
|
+
usage(command);
|
|
77
68
|
const library = flags.library;
|
|
78
69
|
if (library !== undefined && (typeof library !== 'string' || !isAbsolute(library)))
|
|
79
|
-
|
|
70
|
+
usage(command);
|
|
80
71
|
if (flags.kind && !['article', 'pdf', 'media'].includes(String(flags.kind)))
|
|
81
|
-
|
|
72
|
+
usage(command);
|
|
82
73
|
if (flags.format && !['markdown', 'json'].includes(String(flags.format)))
|
|
83
|
-
|
|
74
|
+
usage(command);
|
|
84
75
|
if (flags.mode && !['lexical', 'hybrid'].includes(String(flags.mode)))
|
|
85
|
-
|
|
86
|
-
if (flags.limit &&
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
76
|
+
usage(command);
|
|
77
|
+
if (flags.limit &&
|
|
78
|
+
(!/^[1-9]\d{0,3}$/u.test(String(flags.limit)) ||
|
|
79
|
+
Number(flags.limit) > (command === 'import' && positional[0] === 'jungle' ? 1000 : 100)))
|
|
80
|
+
usage(command);
|
|
90
81
|
if (flags['allow-private-network'] && command !== 'run' && !flags.wait)
|
|
91
|
-
|
|
92
|
-
if (['export', 'backup'].includes(command) && (typeof flags.output !== 'string' || !isAbsolute(flags.output)))
|
|
93
|
-
throw new InputError();
|
|
94
|
-
if (command === 'restore' && (typeof flags.into !== 'string' || !isAbsolute(flags.into) || flags.library !== undefined || !isAbsolute(positional[0])))
|
|
95
|
-
throw new InputError();
|
|
96
|
-
if (command === 'gc' && (flags.runtimes ? flags.apply !== undefined : Boolean(flags['dry-run']) === Boolean(flags.apply) || flags.apply !== undefined && !isAbsolute(String(flags.apply))))
|
|
97
|
-
throw new InputError();
|
|
98
|
-
if (command === 'worker' && !['install', 'status', 'uninstall', 'serve'].includes(positional[0]))
|
|
99
|
-
throw new InputError();
|
|
100
|
-
if (command === 'import' && (!isAbsolute(positional.at(-1)) || flags.apply && flags['dry-run'] || flags.offset !== undefined && !/^(0|[1-9][0-9]{0,5})$/.test(String(flags.offset))))
|
|
101
|
-
throw new InputError();
|
|
102
|
-
if (command === 'visibility' && !['public', 'private', 'default'].includes(positional[1]) || command === 'publish' && (Boolean(flags['dry-run']) === Boolean(flags.output) || flags.output !== undefined && (typeof flags.output !== 'string' || !isAbsolute(flags.output)) || (flags.title !== undefined || flags['base-url'] !== undefined) && !flags.output || flags['min-age-days'] !== undefined && !/^(0|[1-9][0-9]{0,3})$/.test(String(flags['min-age-days'])) || Number(flags['min-age-days'] ?? 0) > 3650 || flags.title !== undefined && String(flags.title).length > 200 || flags['base-url'] !== undefined && !/^https:\/\//.test(String(flags['base-url']))))
|
|
103
|
-
throw new InputError();
|
|
104
|
-
if (command === 'digest' && (Boolean(flags.endpoint) !== Boolean(flags.model) || flags['check-support'] && !flags.endpoint || flags.model !== undefined && !/^[\w.:/@+-]{1,256}$/.test(String(flags.model))))
|
|
105
|
-
throw new InputError();
|
|
106
|
-
if (command === 'review' && (flags.accept === undefined && flags.reject === undefined || [flags.accept, flags.reject].some(v => v !== undefined && !reviewSpec.test(String(v)))))
|
|
107
|
-
throw new InputError();
|
|
82
|
+
usage(command);
|
|
108
83
|
if (flags.occurrence !== undefined && !/^(0|[1-9][0-9]{0,4})$/.test(String(flags.occurrence)))
|
|
109
|
-
|
|
84
|
+
usage(command);
|
|
110
85
|
if (flags.language !== undefined && flags.language !== 'en')
|
|
111
|
-
|
|
86
|
+
usage(command);
|
|
112
87
|
if (flags['force-local'] && command === 'worker' && positional[0] === 'install')
|
|
113
|
-
|
|
88
|
+
usage(command);
|
|
114
89
|
if (flags['force-local'] && !flags.language)
|
|
115
|
-
|
|
116
|
-
if ((flags.language || flags['force-local']) &&
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
if (flags.
|
|
121
|
-
|
|
122
|
-
|
|
90
|
+
usage(command);
|
|
91
|
+
if ((flags.language || flags['force-local']) &&
|
|
92
|
+
((['add', 'refresh'].includes(command) && !flags.wait) ||
|
|
93
|
+
(command === 'worker' && !['serve', 'install'].includes(positional[0]))))
|
|
94
|
+
usage(command);
|
|
95
|
+
if (flags.keep !== undefined && !/^(0|[1-9]|1[0-6])$/.test(String(flags.keep)))
|
|
96
|
+
usage(command);
|
|
97
|
+
if (flags.profile &&
|
|
98
|
+
(!(command === 'search' ||
|
|
99
|
+
(command === 'index' && (positional[0] === 'create' || (positional[0] === 'status' && positional.length === 1)))) ||
|
|
100
|
+
!/^[a-zA-Z0-9_-]{1,128}$/.test(String(flags.profile))))
|
|
101
|
+
usage(command);
|
|
102
|
+
return {
|
|
103
|
+
command,
|
|
104
|
+
positional,
|
|
105
|
+
flags,
|
|
106
|
+
library: library,
|
|
107
|
+
json: flags.json === true || flags.format === 'json',
|
|
108
|
+
debug: flags.debug === true,
|
|
109
|
+
};
|
|
123
110
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { LibraryStore } from '../store/index.js';
|
|
2
|
+
/** A parsed command line (see `arguments.ts`). */
|
|
3
|
+
export interface Arguments {
|
|
4
|
+
command: string;
|
|
5
|
+
positional: string[];
|
|
6
|
+
flags: Record<string, string | true>;
|
|
7
|
+
library?: string;
|
|
8
|
+
json: boolean;
|
|
9
|
+
debug: boolean;
|
|
10
|
+
}
|
|
11
|
+
type Flags = Arguments['flags'];
|
|
12
|
+
export interface Context {
|
|
13
|
+
args: Arguments;
|
|
14
|
+
store: LibraryStore;
|
|
15
|
+
version: string;
|
|
16
|
+
signal: AbortSignal;
|
|
17
|
+
emit: (data: unknown, text?: string) => void;
|
|
18
|
+
write: (text: string | Uint8Array) => void;
|
|
19
|
+
captureRoot: string;
|
|
20
|
+
nativeRoot: string;
|
|
21
|
+
}
|
|
22
|
+
export interface Command {
|
|
23
|
+
name: string;
|
|
24
|
+
summary: string;
|
|
25
|
+
/** Help lines: [synopsis without `sponge`, description]. */
|
|
26
|
+
usage: readonly (readonly [string, string])[];
|
|
27
|
+
/** Positional count, or a predicate over the positionals. */
|
|
28
|
+
positional: number | ((p: string[]) => boolean);
|
|
29
|
+
flags: Readonly<Record<string, 'value' | 'boolean'>>;
|
|
30
|
+
/** Command-specific usage rules beyond arity and flag names; false is a usage error. */
|
|
31
|
+
check?: (p: string[], f: Flags) => boolean;
|
|
32
|
+
/** none: no library; create: init may create it; open: an existing library. */
|
|
33
|
+
library: 'none' | 'create' | 'open';
|
|
34
|
+
handler: (c: Context) => Promise<number> | number;
|
|
35
|
+
}
|
|
36
|
+
export declare const commands: readonly Command[];
|
|
37
|
+
export declare const command: (name: string | undefined) => Command | undefined;
|
|
38
|
+
export declare function help(): string;
|
|
39
|
+
/** One command's synopsis lines; also the hint printed for its usage errors. */
|
|
40
|
+
export declare const usageOf: (name: string) => string;
|
|
41
|
+
export declare function commandHelp(name: string): string;
|
|
42
|
+
export {};
|