@elaraai/e3-cli 0.0.2-beta.8 → 1.0.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/LICENSE.md +4 -0
- package/README.md +169 -46
- package/dist/src/cli.js +197 -73
- package/dist/src/cli.js.map +1 -1
- package/dist/src/commands/auth.d.ts +23 -0
- package/dist/src/commands/auth.d.ts.map +1 -0
- package/dist/src/commands/auth.js +200 -0
- package/dist/src/commands/auth.js.map +1 -0
- package/dist/src/commands/complete.d.ts +14 -0
- package/dist/src/commands/complete.d.ts.map +1 -0
- package/dist/src/commands/complete.js +166 -0
- package/dist/src/commands/complete.js.map +1 -0
- package/dist/src/commands/complete.spec.d.ts +6 -0
- package/dist/src/commands/complete.spec.d.ts.map +1 -0
- package/dist/src/commands/complete.spec.js +63 -0
- package/dist/src/commands/complete.spec.js.map +1 -0
- package/dist/src/commands/completion-install.d.ts +47 -0
- package/dist/src/commands/completion-install.d.ts.map +1 -0
- package/dist/src/commands/completion-install.js +141 -0
- package/dist/src/commands/completion-install.js.map +1 -0
- package/dist/src/commands/completion-install.spec.d.ts +6 -0
- package/dist/src/commands/completion-install.spec.d.ts.map +1 -0
- package/dist/src/commands/completion-install.spec.js +136 -0
- package/dist/src/commands/completion-install.spec.js.map +1 -0
- package/dist/src/commands/completion.d.ts +12 -0
- package/dist/src/commands/completion.d.ts.map +1 -0
- package/dist/src/commands/completion.js +75 -0
- package/dist/src/commands/completion.js.map +1 -0
- package/dist/src/commands/completion.spec.d.ts +6 -0
- package/dist/src/commands/completion.spec.d.ts.map +1 -0
- package/dist/src/commands/completion.spec.js +48 -0
- package/dist/src/commands/completion.spec.js.map +1 -0
- package/dist/src/commands/convert.impl.spec.d.ts +6 -0
- package/dist/src/commands/convert.impl.spec.d.ts.map +1 -0
- package/dist/src/commands/convert.impl.spec.js +245 -0
- package/dist/src/commands/convert.impl.spec.js.map +1 -0
- package/dist/src/commands/dataset-status.d.ts +9 -0
- package/dist/src/commands/dataset-status.d.ts.map +1 -0
- package/dist/src/commands/dataset-status.js +77 -0
- package/dist/src/commands/dataset-status.js.map +1 -0
- package/dist/src/commands/find.d.ts +17 -0
- package/dist/src/commands/find.d.ts.map +1 -0
- package/dist/src/commands/find.js +59 -0
- package/dist/src/commands/find.js.map +1 -0
- package/dist/src/commands/find.spec.d.ts +6 -0
- package/dist/src/commands/find.spec.d.ts.map +1 -0
- package/dist/src/commands/find.spec.js +43 -0
- package/dist/src/commands/find.spec.js.map +1 -0
- package/dist/src/commands/get.d.ts +3 -0
- package/dist/src/commands/get.d.ts.map +1 -1
- package/dist/src/commands/get.js +43 -20
- package/dist/src/commands/get.js.map +1 -1
- package/dist/src/commands/get.spec.d.ts +6 -0
- package/dist/src/commands/get.spec.d.ts.map +1 -0
- package/dist/src/commands/get.spec.js +28 -0
- package/dist/src/commands/get.spec.js.map +1 -0
- package/dist/src/commands/list.d.ts +6 -2
- package/dist/src/commands/list.d.ts.map +1 -1
- package/dist/src/commands/list.js +189 -30
- package/dist/src/commands/list.js.map +1 -1
- package/dist/src/commands/logs.d.ts.map +1 -1
- package/dist/src/commands/logs.js +96 -70
- package/dist/src/commands/logs.js.map +1 -1
- package/dist/src/commands/package.d.ts.map +1 -1
- package/dist/src/commands/package.js +78 -18
- package/dist/src/commands/package.js.map +1 -1
- package/dist/src/commands/repo.d.ts +44 -0
- package/dist/src/commands/repo.d.ts.map +1 -0
- package/dist/src/commands/repo.js +278 -0
- package/dist/src/commands/repo.js.map +1 -0
- package/dist/src/commands/run.d.ts +12 -0
- package/dist/src/commands/run.d.ts.map +1 -1
- package/dist/src/commands/run.js +21 -13
- package/dist/src/commands/run.js.map +1 -1
- package/dist/src/commands/run.spec.d.ts +6 -0
- package/dist/src/commands/run.spec.d.ts.map +1 -0
- package/dist/src/commands/run.spec.js +39 -0
- package/dist/src/commands/run.spec.js.map +1 -0
- package/dist/src/commands/set.d.ts +1 -0
- package/dist/src/commands/set.d.ts.map +1 -1
- package/dist/src/commands/set.js +33 -32
- package/dist/src/commands/set.js.map +1 -1
- package/dist/src/commands/start.d.ts.map +1 -1
- package/dist/src/commands/start.js +270 -52
- package/dist/src/commands/start.js.map +1 -1
- package/dist/src/commands/watch.d.ts +5 -2
- package/dist/src/commands/watch.d.ts.map +1 -1
- package/dist/src/commands/watch.js +32 -26
- package/dist/src/commands/watch.js.map +1 -1
- package/dist/src/commands/workspace.d.ts +12 -1
- package/dist/src/commands/workspace.d.ts.map +1 -1
- package/dist/src/commands/workspace.js +332 -38
- package/dist/src/commands/workspace.js.map +1 -1
- package/dist/src/credentials.d.ts +123 -0
- package/dist/src/credentials.d.ts.map +1 -0
- package/dist/src/credentials.js +213 -0
- package/dist/src/credentials.js.map +1 -0
- package/dist/src/format.d.ts +18 -0
- package/dist/src/format.d.ts.map +1 -0
- package/dist/src/format.js +43 -0
- package/dist/src/format.js.map +1 -0
- package/dist/src/path-resolver.d.ts +86 -0
- package/dist/src/path-resolver.d.ts.map +1 -0
- package/dist/src/path-resolver.js +241 -0
- package/dist/src/path-resolver.js.map +1 -0
- package/dist/src/path-resolver.spec.d.ts +6 -0
- package/dist/src/path-resolver.spec.d.ts.map +1 -0
- package/dist/src/path-resolver.spec.js +247 -0
- package/dist/src/path-resolver.spec.js.map +1 -0
- package/dist/src/utils.d.ts +76 -1
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +104 -1
- package/dist/src/utils.js.map +1 -1
- package/dist/src/utils.spec.d.ts +6 -0
- package/dist/src/utils.spec.d.ts.map +1 -0
- package/dist/src/utils.spec.js +199 -0
- package/dist/src/utils.spec.js.map +1 -0
- package/package.json +22 -18
- package/scripts/postinstall.cjs +26 -0
- package/dist/src/commands/gc.d.ts +0 -12
- package/dist/src/commands/gc.d.ts.map +0 -1
- package/dist/src/commands/gc.js +0 -44
- package/dist/src/commands/gc.js.map +0 -1
- package/dist/src/commands/init.d.ts +0 -9
- package/dist/src/commands/init.d.ts.map +0 -1
- package/dist/src/commands/init.js +0 -33
- package/dist/src/commands/init.js.map +0 -1
- package/dist/src/commands/status.d.ts +0 -9
- package/dist/src/commands/status.d.ts.map +0 -1
- package/dist/src/commands/status.js +0 -157
- package/dist/src/commands/status.js.map +0 -1
- package/dist/src/commands/tree.d.ts +0 -14
- package/dist/src/commands/tree.d.ts.map +0 -1
- package/dist/src/commands/tree.js +0 -77
- package/dist/src/commands/tree.js.map +0 -1
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
|
+
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Tests for the dataset path resolver.
|
|
7
|
+
*
|
|
8
|
+
* The pure functions (`levenshtein`, `suggestSimilar`, `indexFromTree`,
|
|
9
|
+
* `indexFromRemoteEntries`, `resolveDatasetPathFromIndex`) are exercised
|
|
10
|
+
* directly without a real repository.
|
|
11
|
+
*/
|
|
12
|
+
import { describe, it } from 'node:test';
|
|
13
|
+
import assert from 'node:assert/strict';
|
|
14
|
+
import { variant } from '@elaraai/east';
|
|
15
|
+
import { levenshtein, suggestSimilar, indexFromTree, indexFromRemoteEntries, resolveDatasetPathFromIndex, } from './path-resolver.js';
|
|
16
|
+
// =============================================================================
|
|
17
|
+
// Tree fixture builders
|
|
18
|
+
// =============================================================================
|
|
19
|
+
function leaf(name) {
|
|
20
|
+
return { name, kind: 'dataset' };
|
|
21
|
+
}
|
|
22
|
+
function branch(name, children) {
|
|
23
|
+
return { name, kind: 'tree', children };
|
|
24
|
+
}
|
|
25
|
+
function inputs(...names) {
|
|
26
|
+
return branch('inputs', names.map(leaf));
|
|
27
|
+
}
|
|
28
|
+
function tasks(...names) {
|
|
29
|
+
return branch('tasks', names.map(leaf));
|
|
30
|
+
}
|
|
31
|
+
// Remote ListEntry builders
|
|
32
|
+
function remoteDataset(path) {
|
|
33
|
+
return variant('dataset', {
|
|
34
|
+
path,
|
|
35
|
+
type: variant('String', null),
|
|
36
|
+
hash: variant('none', null),
|
|
37
|
+
size: variant('none', null),
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function remoteTree(path) {
|
|
41
|
+
return variant('tree', { path, kind: variant('struct', null) });
|
|
42
|
+
}
|
|
43
|
+
// =============================================================================
|
|
44
|
+
// levenshtein
|
|
45
|
+
// =============================================================================
|
|
46
|
+
describe('levenshtein', () => {
|
|
47
|
+
it('returns 0 for identical strings', () => {
|
|
48
|
+
assert.strictEqual(levenshtein('abc', 'abc'), 0);
|
|
49
|
+
assert.strictEqual(levenshtein('', ''), 0);
|
|
50
|
+
});
|
|
51
|
+
it('returns length of the non-empty string when one side is empty', () => {
|
|
52
|
+
assert.strictEqual(levenshtein('', 'abc'), 3);
|
|
53
|
+
assert.strictEqual(levenshtein('xyz', ''), 3);
|
|
54
|
+
});
|
|
55
|
+
it('returns 1 for single insertion', () => {
|
|
56
|
+
assert.strictEqual(levenshtein('abc', 'abcd'), 1);
|
|
57
|
+
});
|
|
58
|
+
it('returns 1 for single deletion', () => {
|
|
59
|
+
assert.strictEqual(levenshtein('abcd', 'abc'), 1);
|
|
60
|
+
});
|
|
61
|
+
it('returns 1 for single substitution', () => {
|
|
62
|
+
assert.strictEqual(levenshtein('abc', 'abd'), 1);
|
|
63
|
+
});
|
|
64
|
+
it('handles the classic kitten/sitting case', () => {
|
|
65
|
+
assert.strictEqual(levenshtein('kitten', 'sitting'), 3);
|
|
66
|
+
});
|
|
67
|
+
it('handles unicode characters as JS code units', () => {
|
|
68
|
+
// résumé vs resume — two characters with accents replaced
|
|
69
|
+
assert.strictEqual(levenshtein('résumé', 'resume'), 2);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
// =============================================================================
|
|
73
|
+
// suggestSimilar
|
|
74
|
+
// =============================================================================
|
|
75
|
+
describe('suggestSimilar', () => {
|
|
76
|
+
it('returns exact match first', () => {
|
|
77
|
+
const result = suggestSimilar('greet', ['greeting', 'greet', 'grit'], 5);
|
|
78
|
+
assert.strictEqual(result[0], 'greet');
|
|
79
|
+
});
|
|
80
|
+
it('returns single-char typos within threshold', () => {
|
|
81
|
+
const result = suggestSimilar('greet', ['greeting', 'gret', 'shout'], 5);
|
|
82
|
+
assert.ok(result.includes('gret'));
|
|
83
|
+
});
|
|
84
|
+
it('filters out candidates beyond the threshold', () => {
|
|
85
|
+
// target length 5 → threshold = max(2, 2) = 2
|
|
86
|
+
const result = suggestSimilar('greet', ['completely-unrelated', 'gret'], 5);
|
|
87
|
+
assert.deepStrictEqual(result, ['gret']);
|
|
88
|
+
});
|
|
89
|
+
it('returns at most `max` candidates', () => {
|
|
90
|
+
const result = suggestSimilar('a', ['a', 'b', 'c', 'd', 'e', 'f'], 3);
|
|
91
|
+
assert.strictEqual(result.length, 3);
|
|
92
|
+
});
|
|
93
|
+
it('returns candidates in distance order', () => {
|
|
94
|
+
const result = suggestSimilar('hello', ['hellp', 'hxllo', 'help'], 5);
|
|
95
|
+
// hellp d=1, hxllo d=1, help d=2 (all within threshold)
|
|
96
|
+
// First two could be in either order (both d=1), but help must come last
|
|
97
|
+
assert.strictEqual(result[result.length - 1], 'help');
|
|
98
|
+
});
|
|
99
|
+
it('returns empty array when candidates is empty', () => {
|
|
100
|
+
assert.deepStrictEqual(suggestSimilar('greet', [], 5), []);
|
|
101
|
+
});
|
|
102
|
+
it('still applies threshold of 2 for very short targets', () => {
|
|
103
|
+
// target 'a' → threshold = max(2, 0) = 2
|
|
104
|
+
const result = suggestSimilar('a', ['ab', 'abc', 'abcd'], 5);
|
|
105
|
+
// ab d=1, abc d=2, abcd d=3 (excluded)
|
|
106
|
+
assert.ok(result.includes('ab'));
|
|
107
|
+
assert.ok(result.includes('abc'));
|
|
108
|
+
assert.ok(!result.includes('abcd'));
|
|
109
|
+
});
|
|
110
|
+
it('handles very long names with appropriate threshold', () => {
|
|
111
|
+
// target length 100 → threshold = 50; far-apart strings still excluded
|
|
112
|
+
const longName = 'a'.repeat(100);
|
|
113
|
+
const result = suggestSimilar(longName, ['b'.repeat(100)], 5);
|
|
114
|
+
// 100 edits — far above threshold of 50
|
|
115
|
+
assert.deepStrictEqual(result, []);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
// =============================================================================
|
|
119
|
+
// indexFromTree
|
|
120
|
+
// =============================================================================
|
|
121
|
+
describe('indexFromTree', () => {
|
|
122
|
+
it('returns [] for empty tree', () => {
|
|
123
|
+
assert.deepStrictEqual(indexFromTree([]), []);
|
|
124
|
+
});
|
|
125
|
+
it('indexes inputs as kind=input with [inputs, name] storage', () => {
|
|
126
|
+
const tree = [inputs('name', 'count')];
|
|
127
|
+
const result = indexFromTree(tree);
|
|
128
|
+
const name = result.find((e) => e.name === 'name');
|
|
129
|
+
assert.strictEqual(name.kind, 'input');
|
|
130
|
+
assert.deepStrictEqual(name.storage.map((s) => s.value), ['inputs', 'name']);
|
|
131
|
+
});
|
|
132
|
+
it('indexes tasks as kind=task-output with [tasks, name, output] storage', () => {
|
|
133
|
+
const tree = [tasks('greet')];
|
|
134
|
+
const result = indexFromTree(tree);
|
|
135
|
+
const greet = result.find((e) => e.name === 'greet');
|
|
136
|
+
assert.strictEqual(greet.kind, 'task-output');
|
|
137
|
+
assert.deepStrictEqual(greet.storage.map((s) => s.value), ['tasks', 'greet', 'output']);
|
|
138
|
+
});
|
|
139
|
+
it('indexes both inputs and tasks in a typical workspace', () => {
|
|
140
|
+
const tree = [inputs('name'), tasks('greet', 'shout')];
|
|
141
|
+
const result = indexFromTree(tree);
|
|
142
|
+
assert.strictEqual(result.length, 3);
|
|
143
|
+
assert.ok(result.some((e) => e.name === 'name' && e.kind === 'input'));
|
|
144
|
+
assert.ok(result.some((e) => e.name === 'greet' && e.kind === 'task-output'));
|
|
145
|
+
assert.ok(result.some((e) => e.name === 'shout' && e.kind === 'task-output'));
|
|
146
|
+
});
|
|
147
|
+
it('treats nested non-input/non-task branches as kind=other with dotted name', () => {
|
|
148
|
+
const tree = [branch('config', [leaf('value')])];
|
|
149
|
+
const result = indexFromTree(tree);
|
|
150
|
+
assert.strictEqual(result.length, 1);
|
|
151
|
+
const e = result[0];
|
|
152
|
+
assert.strictEqual(e.kind, 'other');
|
|
153
|
+
assert.strictEqual(e.name, 'config.value');
|
|
154
|
+
assert.deepStrictEqual(e.storage.map((s) => s.value), ['config', 'value']);
|
|
155
|
+
});
|
|
156
|
+
it('handles a leaf at the root (no prefix)', () => {
|
|
157
|
+
// unusual but well-defined: dataset at root would be kind=other with bare name
|
|
158
|
+
const tree = [leaf('bare')];
|
|
159
|
+
const result = indexFromTree(tree);
|
|
160
|
+
assert.strictEqual(result.length, 1);
|
|
161
|
+
assert.strictEqual(result[0].kind, 'other');
|
|
162
|
+
assert.strictEqual(result[0].name, 'bare');
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
// =============================================================================
|
|
166
|
+
// indexFromRemoteEntries
|
|
167
|
+
// =============================================================================
|
|
168
|
+
describe('indexFromRemoteEntries', () => {
|
|
169
|
+
it('returns [] for empty list', () => {
|
|
170
|
+
assert.deepStrictEqual(indexFromRemoteEntries([]), []);
|
|
171
|
+
});
|
|
172
|
+
it('indexes inputs.<name> as kind=input', () => {
|
|
173
|
+
const result = indexFromRemoteEntries([remoteDataset('inputs.name')]);
|
|
174
|
+
assert.strictEqual(result.length, 1);
|
|
175
|
+
assert.strictEqual(result[0].kind, 'input');
|
|
176
|
+
assert.strictEqual(result[0].name, 'name');
|
|
177
|
+
});
|
|
178
|
+
it('indexes tasks.<name> as kind=task-output with output suffix in storage', () => {
|
|
179
|
+
const result = indexFromRemoteEntries([remoteDataset('tasks.greet')]);
|
|
180
|
+
assert.strictEqual(result.length, 1);
|
|
181
|
+
assert.strictEqual(result[0].kind, 'task-output');
|
|
182
|
+
assert.strictEqual(result[0].name, 'greet');
|
|
183
|
+
assert.deepStrictEqual(result[0].storage.map((s) => s.value), ['tasks', 'greet', 'output']);
|
|
184
|
+
});
|
|
185
|
+
it('ignores tree entries (only datasets are indexable leaves)', () => {
|
|
186
|
+
const result = indexFromRemoteEntries([remoteTree('inputs'), remoteDataset('inputs.name')]);
|
|
187
|
+
assert.strictEqual(result.length, 1);
|
|
188
|
+
assert.strictEqual(result[0].name, 'name');
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
// =============================================================================
|
|
192
|
+
// resolveDatasetPathFromIndex
|
|
193
|
+
// =============================================================================
|
|
194
|
+
describe('resolveDatasetPathFromIndex', () => {
|
|
195
|
+
const index = indexFromTree([
|
|
196
|
+
inputs('name', 'count'),
|
|
197
|
+
tasks('greet', 'shout'),
|
|
198
|
+
]);
|
|
199
|
+
it('resolves a known input', () => {
|
|
200
|
+
const result = resolveDatasetPathFromIndex('dev.name', index);
|
|
201
|
+
assert.strictEqual(result.ws, 'dev');
|
|
202
|
+
assert.strictEqual(result.kind, 'input');
|
|
203
|
+
assert.deepStrictEqual(result.path.map((s) => s.value), ['inputs', 'name']);
|
|
204
|
+
});
|
|
205
|
+
it('resolves a known task with the output suffix added', () => {
|
|
206
|
+
const result = resolveDatasetPathFromIndex('dev.greet', index);
|
|
207
|
+
assert.strictEqual(result.kind, 'task-output');
|
|
208
|
+
assert.deepStrictEqual(result.path.map((s) => s.value), ['tasks', 'greet', 'output']);
|
|
209
|
+
});
|
|
210
|
+
it('errors on path with no name segment', () => {
|
|
211
|
+
assert.throws(() => resolveDatasetPathFromIndex('dev', index), /Path must include a name/);
|
|
212
|
+
});
|
|
213
|
+
it('rejects legacy inputs.<name> form with a hint', () => {
|
|
214
|
+
assert.throws(() => resolveDatasetPathFromIndex('dev.inputs.name', index), /Use the short form: 'dev.name'/);
|
|
215
|
+
});
|
|
216
|
+
it('rejects legacy tasks.<name>.output form with a hint', () => {
|
|
217
|
+
assert.throws(() => resolveDatasetPathFromIndex('dev.tasks.greet.output', index), /Use the short form: 'dev.greet'/);
|
|
218
|
+
});
|
|
219
|
+
it('suggests close matches for typos', () => {
|
|
220
|
+
assert.throws(() => resolveDatasetPathFromIndex('dev.gret', index), /Did you mean.*dev\.greet/s);
|
|
221
|
+
});
|
|
222
|
+
it('lists available names when no close match exists', () => {
|
|
223
|
+
assert.throws(() => resolveDatasetPathFromIndex('dev.completelyDifferentName', index), /Available names/);
|
|
224
|
+
});
|
|
225
|
+
it('caps the available list at 10 names with a "... and N more" suffix', () => {
|
|
226
|
+
const many = indexFromTree([
|
|
227
|
+
inputs(...Array.from({ length: 15 }, (_, i) => `in${i}`)),
|
|
228
|
+
]);
|
|
229
|
+
let err;
|
|
230
|
+
try {
|
|
231
|
+
resolveDatasetPathFromIndex('dev.completelyDifferentName', many);
|
|
232
|
+
}
|
|
233
|
+
catch (e) {
|
|
234
|
+
err = e;
|
|
235
|
+
}
|
|
236
|
+
assert.ok(err, 'expected error');
|
|
237
|
+
assert.match(err.message, /\.\.\. and 5 more/);
|
|
238
|
+
});
|
|
239
|
+
it('reports ambiguity when an input and task share a name', () => {
|
|
240
|
+
const ambig = indexFromTree([inputs('foo'), tasks('foo')]);
|
|
241
|
+
assert.throws(() => resolveDatasetPathFromIndex('dev.foo', ambig), /ambiguous/);
|
|
242
|
+
});
|
|
243
|
+
it('rejects nested field access past the leaf', () => {
|
|
244
|
+
assert.throws(() => resolveDatasetPathFromIndex('dev.greet.field', index), /Nested field access/);
|
|
245
|
+
});
|
|
246
|
+
});
|
|
247
|
+
//# sourceMappingURL=path-resolver.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-resolver.spec.js","sourceRoot":"","sources":["../../src/path-resolver.spec.ts"],"names":[],"mappings":"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"}
|
package/dist/src/utils.d.ts
CHANGED
|
@@ -2,8 +2,72 @@
|
|
|
2
2
|
* Copyright (c) 2025 Elara AI Pty Ltd
|
|
3
3
|
* Licensed under BSL 1.1. See LICENSE for details.
|
|
4
4
|
*/
|
|
5
|
+
/** Character width used when truncating object hashes for display. */
|
|
6
|
+
export declare const HASH_DISPLAY_WIDTH = 12;
|
|
7
|
+
/** Truncate a hash to `HASH_DISPLAY_WIDTH` chars with a trailing ellipsis. */
|
|
8
|
+
export declare function shortHash(hash: string): string;
|
|
5
9
|
import { parseDatasetPath, parsePackageRef } from '@elaraai/e3-types';
|
|
10
|
+
/**
|
|
11
|
+
* Resolve the `<repo>` positional argument with fallback to `E3_REPO` env var
|
|
12
|
+
* then `.` (cwd). Used by every command that accepts a repository argument so
|
|
13
|
+
* users in a current directory can drop the leading `.`.
|
|
14
|
+
*/
|
|
15
|
+
export declare function defaultRepoArg(arg: string | undefined): string;
|
|
16
|
+
/**
|
|
17
|
+
* Wrap a command handler whose first parameter is `<repo>` so that the
|
|
18
|
+
* Commander action callback can pass `string | undefined` and the handler
|
|
19
|
+
* still sees a fully-resolved repo string.
|
|
20
|
+
*/
|
|
21
|
+
export declare function withDefaultRepo<A extends unknown[]>(handler: (repo: string, ...args: A) => void | Promise<void>): (repo: string | undefined, ...args: A) => void | Promise<void>;
|
|
6
22
|
export { parseDatasetPath, parsePackageRef };
|
|
23
|
+
/**
|
|
24
|
+
* Repository location - either local filesystem or remote URL.
|
|
25
|
+
*/
|
|
26
|
+
export type RepoLocation = {
|
|
27
|
+
type: 'local';
|
|
28
|
+
path: string;
|
|
29
|
+
} | {
|
|
30
|
+
type: 'remote';
|
|
31
|
+
baseUrl: string;
|
|
32
|
+
repo: string;
|
|
33
|
+
token: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Parse a repository location argument.
|
|
37
|
+
*
|
|
38
|
+
* Supports:
|
|
39
|
+
* - Local paths: `.`, `./repo`, `/path/to/repo`
|
|
40
|
+
* - Remote URLs: `http://...`, `https://...`
|
|
41
|
+
*
|
|
42
|
+
* For remote URLs, the URL should be the user-facing "shareable" URL,
|
|
43
|
+
* e.g., `https://platform.example.com/repos/my_repo`.
|
|
44
|
+
* The CLI will internally add `/api` when making API calls.
|
|
45
|
+
*
|
|
46
|
+
* For remote locations, this function will load and validate the auth token.
|
|
47
|
+
* If not logged in or token is expired and cannot be refreshed, throws an error.
|
|
48
|
+
*
|
|
49
|
+
* @returns For local: { type: 'local', path: '/absolute/path/to/repo' }
|
|
50
|
+
* For remote: { type: 'remote', baseUrl: 'https://example.com', repo: 'my_repo', token: '...' }
|
|
51
|
+
*/
|
|
52
|
+
export declare function parseRepoLocation(arg: string): Promise<RepoLocation>;
|
|
53
|
+
/**
|
|
54
|
+
* Repository location without required token (for sync parsing).
|
|
55
|
+
*/
|
|
56
|
+
export type RepoLocationNoToken = {
|
|
57
|
+
type: 'local';
|
|
58
|
+
path: string;
|
|
59
|
+
} | {
|
|
60
|
+
type: 'remote';
|
|
61
|
+
baseUrl: string;
|
|
62
|
+
repo: string;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Parse a repository location (synchronous, no auth).
|
|
66
|
+
*
|
|
67
|
+
* Use this only for operations that don't need authentication (e.g., local repos).
|
|
68
|
+
* For remote repos, use parseRepoLocation() instead.
|
|
69
|
+
*/
|
|
70
|
+
export declare function parseRepoLocationSync(arg: string): RepoLocationNoToken;
|
|
7
71
|
/**
|
|
8
72
|
* Resolve repository path from CLI argument.
|
|
9
73
|
* Supports `.` for current directory and relative/absolute paths.
|
|
@@ -18,7 +82,18 @@ export declare function parsePackageSpec(spec: string): {
|
|
|
18
82
|
version: string;
|
|
19
83
|
};
|
|
20
84
|
/**
|
|
21
|
-
* Format error
|
|
85
|
+
* Format an error into a human-readable CLI message.
|
|
86
|
+
*
|
|
87
|
+
* Handles three error categories:
|
|
88
|
+
* - {@link ApiError} — humanizes the error code (e.g. `"package_not_found"` → `"Package not found"`)
|
|
89
|
+
* and appends details if present (string details verbatim, objects as JSON).
|
|
90
|
+
* - Standard `Error` — returns `.message`.
|
|
91
|
+
* - Other values — coerces to string via `String()`.
|
|
92
|
+
*
|
|
93
|
+
* The returned string is intended for `exitError()` which prefixes it with `"Error: "`.
|
|
94
|
+
*
|
|
95
|
+
* @param err - The caught error value (may be any type)
|
|
96
|
+
* @returns A single-line, human-readable error description
|
|
22
97
|
*/
|
|
23
98
|
export declare function formatError(err: unknown): string;
|
|
24
99
|
/**
|
package/dist/src/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,sEAAsE;AACtE,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC,8EAA8E;AAC9E,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAGD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAItE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAG9D;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,OAAO,EAAE,EACjD,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,IAEnD,MAAM,MAAM,GAAG,SAAS,EAAE,GAAG,MAAM,CAAC,0BAC7C;AAGD,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,CAAC;AAE7C;;GAEG;AACH,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAErE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAqB1E;AAED;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAC3B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,CActE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAGhF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAchD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAGhD"}
|
package/dist/src/utils.js
CHANGED
|
@@ -6,10 +6,93 @@
|
|
|
6
6
|
* CLI utilities for path parsing and resolution
|
|
7
7
|
*/
|
|
8
8
|
import { resolve } from 'path';
|
|
9
|
+
/** Character width used when truncating object hashes for display. */
|
|
10
|
+
export const HASH_DISPLAY_WIDTH = 12;
|
|
11
|
+
/** Truncate a hash to `HASH_DISPLAY_WIDTH` chars with a trailing ellipsis. */
|
|
12
|
+
export function shortHash(hash) {
|
|
13
|
+
return `${hash.slice(0, HASH_DISPLAY_WIDTH)}...`;
|
|
14
|
+
}
|
|
9
15
|
import { repoGet } from '@elaraai/e3-core';
|
|
10
16
|
import { parseDatasetPath, parsePackageRef } from '@elaraai/e3-types';
|
|
17
|
+
import { ApiError } from '@elaraai/e3-api-client';
|
|
18
|
+
import { getValidToken } from './credentials.js';
|
|
19
|
+
/**
|
|
20
|
+
* Resolve the `<repo>` positional argument with fallback to `E3_REPO` env var
|
|
21
|
+
* then `.` (cwd). Used by every command that accepts a repository argument so
|
|
22
|
+
* users in a current directory can drop the leading `.`.
|
|
23
|
+
*/
|
|
24
|
+
export function defaultRepoArg(arg) {
|
|
25
|
+
if (arg && arg.length > 0)
|
|
26
|
+
return arg;
|
|
27
|
+
return process.env.E3_REPO ?? '.';
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Wrap a command handler whose first parameter is `<repo>` so that the
|
|
31
|
+
* Commander action callback can pass `string | undefined` and the handler
|
|
32
|
+
* still sees a fully-resolved repo string.
|
|
33
|
+
*/
|
|
34
|
+
export function withDefaultRepo(handler) {
|
|
35
|
+
return (repo, ...args) => handler(defaultRepoArg(repo), ...args);
|
|
36
|
+
}
|
|
11
37
|
// Re-export for convenience
|
|
12
38
|
export { parseDatasetPath, parsePackageRef };
|
|
39
|
+
/**
|
|
40
|
+
* Parse a repository location argument.
|
|
41
|
+
*
|
|
42
|
+
* Supports:
|
|
43
|
+
* - Local paths: `.`, `./repo`, `/path/to/repo`
|
|
44
|
+
* - Remote URLs: `http://...`, `https://...`
|
|
45
|
+
*
|
|
46
|
+
* For remote URLs, the URL should be the user-facing "shareable" URL,
|
|
47
|
+
* e.g., `https://platform.example.com/repos/my_repo`.
|
|
48
|
+
* The CLI will internally add `/api` when making API calls.
|
|
49
|
+
*
|
|
50
|
+
* For remote locations, this function will load and validate the auth token.
|
|
51
|
+
* If not logged in or token is expired and cannot be refreshed, throws an error.
|
|
52
|
+
*
|
|
53
|
+
* @returns For local: { type: 'local', path: '/absolute/path/to/repo' }
|
|
54
|
+
* For remote: { type: 'remote', baseUrl: 'https://example.com', repo: 'my_repo', token: '...' }
|
|
55
|
+
*/
|
|
56
|
+
export async function parseRepoLocation(arg) {
|
|
57
|
+
if (arg.startsWith('https://') || arg.startsWith('http://')) {
|
|
58
|
+
const url = new URL(arg);
|
|
59
|
+
// Extract repo name from path: /repos/{repo}[/...]
|
|
60
|
+
const match = url.pathname.match(/^\/repos\/([^/]+)/);
|
|
61
|
+
if (!match) {
|
|
62
|
+
throw new Error(`Invalid remote URL: expected /repos/{repo} in path, got ${url.pathname}`);
|
|
63
|
+
}
|
|
64
|
+
// Load and validate token
|
|
65
|
+
const token = await getValidToken(url.origin);
|
|
66
|
+
return {
|
|
67
|
+
type: 'remote',
|
|
68
|
+
baseUrl: url.origin,
|
|
69
|
+
repo: match[1],
|
|
70
|
+
token,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
return { type: 'local', path: resolveRepo(arg) };
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Parse a repository location (synchronous, no auth).
|
|
77
|
+
*
|
|
78
|
+
* Use this only for operations that don't need authentication (e.g., local repos).
|
|
79
|
+
* For remote repos, use parseRepoLocation() instead.
|
|
80
|
+
*/
|
|
81
|
+
export function parseRepoLocationSync(arg) {
|
|
82
|
+
if (arg.startsWith('https://') || arg.startsWith('http://')) {
|
|
83
|
+
const url = new URL(arg);
|
|
84
|
+
const match = url.pathname.match(/^\/repos\/([^/]+)/);
|
|
85
|
+
if (!match) {
|
|
86
|
+
throw new Error(`Invalid remote URL: expected /repos/{repo} in path, got ${url.pathname}`);
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
type: 'remote',
|
|
90
|
+
baseUrl: url.origin,
|
|
91
|
+
repo: match[1],
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
return { type: 'local', path: resolveRepo(arg) };
|
|
95
|
+
}
|
|
13
96
|
/**
|
|
14
97
|
* Resolve repository path from CLI argument.
|
|
15
98
|
* Supports `.` for current directory and relative/absolute paths.
|
|
@@ -27,9 +110,29 @@ export function parsePackageSpec(spec) {
|
|
|
27
110
|
return { name, version: version ?? 'latest' };
|
|
28
111
|
}
|
|
29
112
|
/**
|
|
30
|
-
* Format error
|
|
113
|
+
* Format an error into a human-readable CLI message.
|
|
114
|
+
*
|
|
115
|
+
* Handles three error categories:
|
|
116
|
+
* - {@link ApiError} — humanizes the error code (e.g. `"package_not_found"` → `"Package not found"`)
|
|
117
|
+
* and appends details if present (string details verbatim, objects as JSON).
|
|
118
|
+
* - Standard `Error` — returns `.message`.
|
|
119
|
+
* - Other values — coerces to string via `String()`.
|
|
120
|
+
*
|
|
121
|
+
* The returned string is intended for `exitError()` which prefixes it with `"Error: "`.
|
|
122
|
+
*
|
|
123
|
+
* @param err - The caught error value (may be any type)
|
|
124
|
+
* @returns A single-line, human-readable error description
|
|
31
125
|
*/
|
|
32
126
|
export function formatError(err) {
|
|
127
|
+
if (err instanceof ApiError) {
|
|
128
|
+
// Humanize the error code: "execution_not_found" → "Execution not found"
|
|
129
|
+
const message = err.code.replace(/_/g, ' ').replace(/^\w/, c => c.toUpperCase());
|
|
130
|
+
if (err.details != null) {
|
|
131
|
+
const detail = typeof err.details === 'string' ? err.details : JSON.stringify(err.details);
|
|
132
|
+
return `${message}: ${detail}`;
|
|
133
|
+
}
|
|
134
|
+
return message;
|
|
135
|
+
}
|
|
33
136
|
if (err instanceof Error) {
|
|
34
137
|
return err.message;
|
|
35
138
|
}
|
package/dist/src/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.spec.d.ts","sourceRoot":"","sources":["../../src/utils.spec.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|