gitsheets-axi 0.0.1
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 +201 -0
- package/README.md +116 -0
- package/dist/bin/gitsheets-axi.d.ts +3 -0
- package/dist/bin/gitsheets-axi.d.ts.map +1 -0
- package/dist/bin/gitsheets-axi.js +4 -0
- package/dist/bin/gitsheets-axi.js.map +1 -0
- package/dist/src/cli.d.ts +3 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +105 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/commands/attachment.d.ts +4 -0
- package/dist/src/commands/attachment.d.ts.map +1 -0
- package/dist/src/commands/attachment.js +356 -0
- package/dist/src/commands/attachment.js.map +1 -0
- package/dist/src/commands/check.d.ts +4 -0
- package/dist/src/commands/check.d.ts.map +1 -0
- package/dist/src/commands/check.js +136 -0
- package/dist/src/commands/check.js.map +1 -0
- package/dist/src/commands/delete.d.ts +4 -0
- package/dist/src/commands/delete.d.ts.map +1 -0
- package/dist/src/commands/delete.js +132 -0
- package/dist/src/commands/delete.js.map +1 -0
- package/dist/src/commands/diff.d.ts +4 -0
- package/dist/src/commands/diff.d.ts.map +1 -0
- package/dist/src/commands/diff.js +139 -0
- package/dist/src/commands/diff.js.map +1 -0
- package/dist/src/commands/home.d.ts +3 -0
- package/dist/src/commands/home.d.ts.map +1 -0
- package/dist/src/commands/home.js +71 -0
- package/dist/src/commands/home.js.map +1 -0
- package/dist/src/commands/infer.d.ts +4 -0
- package/dist/src/commands/infer.d.ts.map +1 -0
- package/dist/src/commands/infer.js +214 -0
- package/dist/src/commands/infer.js.map +1 -0
- package/dist/src/commands/init.d.ts +4 -0
- package/dist/src/commands/init.d.ts.map +1 -0
- package/dist/src/commands/init.js +172 -0
- package/dist/src/commands/init.js.map +1 -0
- package/dist/src/commands/migrate-config.d.ts +4 -0
- package/dist/src/commands/migrate-config.d.ts.map +1 -0
- package/dist/src/commands/migrate-config.js +161 -0
- package/dist/src/commands/migrate-config.js.map +1 -0
- package/dist/src/commands/normalize.d.ts +4 -0
- package/dist/src/commands/normalize.d.ts.map +1 -0
- package/dist/src/commands/normalize.js +142 -0
- package/dist/src/commands/normalize.js.map +1 -0
- package/dist/src/commands/patch.d.ts +4 -0
- package/dist/src/commands/patch.d.ts.map +1 -0
- package/dist/src/commands/patch.js +172 -0
- package/dist/src/commands/patch.js.map +1 -0
- package/dist/src/commands/push.d.ts +4 -0
- package/dist/src/commands/push.d.ts.map +1 -0
- package/dist/src/commands/push.js +112 -0
- package/dist/src/commands/push.js.map +1 -0
- package/dist/src/commands/query.d.ts +4 -0
- package/dist/src/commands/query.d.ts.map +1 -0
- package/dist/src/commands/query.js +141 -0
- package/dist/src/commands/query.js.map +1 -0
- package/dist/src/commands/read.d.ts +4 -0
- package/dist/src/commands/read.d.ts.map +1 -0
- package/dist/src/commands/read.js +149 -0
- package/dist/src/commands/read.js.map +1 -0
- package/dist/src/commands/sheets.d.ts +4 -0
- package/dist/src/commands/sheets.d.ts.map +1 -0
- package/dist/src/commands/sheets.js +142 -0
- package/dist/src/commands/sheets.js.map +1 -0
- package/dist/src/commands/upsert.d.ts +4 -0
- package/dist/src/commands/upsert.d.ts.map +1 -0
- package/dist/src/commands/upsert.js +137 -0
- package/dist/src/commands/upsert.js.map +1 -0
- package/dist/src/context.d.ts +17 -0
- package/dist/src/context.d.ts.map +1 -0
- package/dist/src/context.js +47 -0
- package/dist/src/context.js.map +1 -0
- package/dist/src/errors.d.ts +13 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +58 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/output/index.d.ts +3 -0
- package/dist/src/output/index.d.ts.map +1 -0
- package/dist/src/output/index.js +3 -0
- package/dist/src/output/index.js.map +1 -0
- package/dist/src/output/render.d.ts +28 -0
- package/dist/src/output/render.d.ts.map +1 -0
- package/dist/src/output/render.js +49 -0
- package/dist/src/output/render.js.map +1 -0
- package/dist/src/output/schema.d.ts +29 -0
- package/dist/src/output/schema.d.ts.map +1 -0
- package/dist/src/output/schema.js +51 -0
- package/dist/src/output/schema.js.map +1 -0
- package/dist/src/output/sheet-schema.d.ts +27 -0
- package/dist/src/output/sheet-schema.d.ts.map +1 -0
- package/dist/src/output/sheet-schema.js +114 -0
- package/dist/src/output/sheet-schema.js.map +1 -0
- package/dist/src/util/stdin.d.ts +7 -0
- package/dist/src/util/stdin.d.ts.map +1 -0
- package/dist/src/util/stdin.js +19 -0
- package/dist/src/util/stdin.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import { isAbsolute, join } from 'node:path';
|
|
2
|
+
import { readFile, stat } from 'node:fs/promises';
|
|
3
|
+
import { AxiError } from 'axi-sdk-js';
|
|
4
|
+
import { NotFoundError } from 'gitsheets';
|
|
5
|
+
import { translateError } from '../errors.js';
|
|
6
|
+
import { renderListResponse, renderObject } from '../output/render.js';
|
|
7
|
+
import { display, field } from '../output/schema.js';
|
|
8
|
+
import { readStdin } from '../util/stdin.js';
|
|
9
|
+
export const ATTACHMENT_HELP = `usage: gitsheets-axi attachment <subcommand> [args] [flags]
|
|
10
|
+
subcommands[4]:
|
|
11
|
+
list <sheet> <path> List attachments on a record
|
|
12
|
+
get <sheet> <path> <name> Get attachment metadata + base64 content
|
|
13
|
+
set <sheet> <path> <name> [--file f] [--data <text>]
|
|
14
|
+
Set an attachment (--file path, --data inline,
|
|
15
|
+
or piped on stdin)
|
|
16
|
+
delete <sheet> <path> [<name>] Delete one attachment by name, or all if name omitted
|
|
17
|
+
examples:
|
|
18
|
+
gitsheets-axi attachment list users jane
|
|
19
|
+
gitsheets-axi attachment get users jane avatar.jpg
|
|
20
|
+
gitsheets-axi attachment set users jane avatar.jpg --file ./pic.jpg
|
|
21
|
+
cat pic.jpg | gitsheets-axi attachment set users jane avatar.jpg
|
|
22
|
+
gitsheets-axi attachment delete users jane avatar.jpg
|
|
23
|
+
gitsheets-axi attachment delete users jane
|
|
24
|
+
notes:
|
|
25
|
+
Binary content in \`get\` is base64-encoded. Use \`--full\` to opt into
|
|
26
|
+
larger payloads (default cap: 64KB).
|
|
27
|
+
`;
|
|
28
|
+
const GET_PREVIEW_LIMIT = 64 * 1024;
|
|
29
|
+
export async function attachmentCommand(args, ctx) {
|
|
30
|
+
if (args.length === 0 || (args.length === 1 && args[0] === '--help')) {
|
|
31
|
+
return ATTACHMENT_HELP;
|
|
32
|
+
}
|
|
33
|
+
const sub = args[0];
|
|
34
|
+
const rest = args.slice(1);
|
|
35
|
+
switch (sub) {
|
|
36
|
+
case 'list':
|
|
37
|
+
return attachmentList(rest, ctx);
|
|
38
|
+
case 'get':
|
|
39
|
+
return attachmentGet(rest, ctx);
|
|
40
|
+
case 'set':
|
|
41
|
+
return attachmentSet(rest, ctx);
|
|
42
|
+
case 'delete':
|
|
43
|
+
return attachmentDelete(rest, ctx);
|
|
44
|
+
case '--help':
|
|
45
|
+
return ATTACHMENT_HELP;
|
|
46
|
+
default:
|
|
47
|
+
throw new AxiError(`Unknown subcommand: ${sub}`, 'VALIDATION_ERROR', [
|
|
48
|
+
'Subcommands: list, get, set, delete',
|
|
49
|
+
]);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function parseAttachmentBase(args, requireName) {
|
|
53
|
+
const positional = [];
|
|
54
|
+
const rest = [];
|
|
55
|
+
for (let i = 0; i < args.length; i++) {
|
|
56
|
+
const arg = args[i];
|
|
57
|
+
if (arg === undefined)
|
|
58
|
+
continue;
|
|
59
|
+
if (arg.startsWith('-')) {
|
|
60
|
+
rest.push(arg);
|
|
61
|
+
// Drag along the next token if it looks like a value
|
|
62
|
+
const next = args[i + 1];
|
|
63
|
+
if (next && !next.startsWith('-')) {
|
|
64
|
+
rest.push(next);
|
|
65
|
+
i++;
|
|
66
|
+
}
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
positional.push(arg);
|
|
70
|
+
}
|
|
71
|
+
if (positional.length < 2) {
|
|
72
|
+
throw new AxiError('attachment requires at least <sheet> <path>', 'VALIDATION_ERROR');
|
|
73
|
+
}
|
|
74
|
+
if (requireName && positional.length < 3) {
|
|
75
|
+
throw new AxiError('attachment requires <sheet> <path> <name>', 'VALIDATION_ERROR');
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
sheet: positional[0],
|
|
79
|
+
path: positional[1],
|
|
80
|
+
name: positional[2],
|
|
81
|
+
rest,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
async function openTargetSheet(ctx, sheetName, prefix) {
|
|
85
|
+
const repo = await ctx.repo();
|
|
86
|
+
try {
|
|
87
|
+
return await repo.openSheet(sheetName, prefix !== undefined ? { prefix } : {});
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
throw translateError(error);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function extractPrefix(rest) {
|
|
94
|
+
const i = rest.indexOf('--prefix');
|
|
95
|
+
if (i === -1)
|
|
96
|
+
return undefined;
|
|
97
|
+
const next = rest[i + 1];
|
|
98
|
+
if (!next) {
|
|
99
|
+
throw new AxiError('--prefix expects a path', 'VALIDATION_ERROR');
|
|
100
|
+
}
|
|
101
|
+
return next;
|
|
102
|
+
}
|
|
103
|
+
async function attachmentList(args, ctx) {
|
|
104
|
+
const { sheet: sheetName, path, rest } = parseAttachmentBase(args, false);
|
|
105
|
+
const prefix = extractPrefix(rest);
|
|
106
|
+
const sheet = await openTargetSheet(ctx, sheetName, prefix);
|
|
107
|
+
const items = [];
|
|
108
|
+
try {
|
|
109
|
+
for await (const attachment of sheet.attachments(path)) {
|
|
110
|
+
items.push({
|
|
111
|
+
name: attachment.name,
|
|
112
|
+
mime_type: attachment.mimeType,
|
|
113
|
+
hash: attachment.blob.hash,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
catch (error) {
|
|
118
|
+
throw translateError(error);
|
|
119
|
+
}
|
|
120
|
+
return renderListResponse({
|
|
121
|
+
summary: { sheet: sheetName, record: path },
|
|
122
|
+
name: 'attachments',
|
|
123
|
+
items,
|
|
124
|
+
schema: [field('name'), display('mime_type'), field('hash')],
|
|
125
|
+
emptyMessage: 'no attachments on this record',
|
|
126
|
+
suggestions: items.length > 0
|
|
127
|
+
? [
|
|
128
|
+
`Run \`gitsheets-axi attachment get ${sheetName} ${path} <name>\` to inspect content`,
|
|
129
|
+
]
|
|
130
|
+
: [
|
|
131
|
+
`Run \`gitsheets-axi attachment set ${sheetName} ${path} <name> --file <path>\` to add one`,
|
|
132
|
+
],
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
async function attachmentGet(args, ctx) {
|
|
136
|
+
const { sheet: sheetName, path, name, rest } = parseAttachmentBase(args, true);
|
|
137
|
+
const prefix = extractPrefix(rest);
|
|
138
|
+
const full = rest.includes('--full');
|
|
139
|
+
const sheet = await openTargetSheet(ctx, sheetName, prefix);
|
|
140
|
+
let attachmentBlob;
|
|
141
|
+
try {
|
|
142
|
+
attachmentBlob = await sheet.getAttachment(path, name);
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
throw translateError(error);
|
|
146
|
+
}
|
|
147
|
+
if (!attachmentBlob) {
|
|
148
|
+
throw new AxiError(`${sheetName}: no attachment ${name} on record at ${path}`, 'NOT_FOUND');
|
|
149
|
+
}
|
|
150
|
+
let buffer;
|
|
151
|
+
try {
|
|
152
|
+
const raw = await attachmentBlob.read();
|
|
153
|
+
buffer = typeof raw === 'string' ? Buffer.from(raw, 'utf-8') : Buffer.from(raw);
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
throw translateError(error);
|
|
157
|
+
}
|
|
158
|
+
const size = buffer.length;
|
|
159
|
+
const cap = full ? Number.POSITIVE_INFINITY : GET_PREVIEW_LIMIT;
|
|
160
|
+
const truncated = size > cap;
|
|
161
|
+
const slice = truncated ? buffer.subarray(0, GET_PREVIEW_LIMIT) : buffer;
|
|
162
|
+
const output = {
|
|
163
|
+
attachment: {
|
|
164
|
+
sheet: sheetName,
|
|
165
|
+
record: path,
|
|
166
|
+
name,
|
|
167
|
+
hash: attachmentBlob.hash,
|
|
168
|
+
size,
|
|
169
|
+
base64: slice.toString('base64'),
|
|
170
|
+
},
|
|
171
|
+
};
|
|
172
|
+
if (truncated) {
|
|
173
|
+
output['attachment']['truncated'] = true;
|
|
174
|
+
output['help'] = [
|
|
175
|
+
`Run \`gitsheets-axi attachment get ${sheetName} ${path} ${name} --full\` to fetch all ${size} bytes`,
|
|
176
|
+
];
|
|
177
|
+
}
|
|
178
|
+
return renderObject(output);
|
|
179
|
+
}
|
|
180
|
+
async function attachmentSet(args, ctx) {
|
|
181
|
+
const { sheet: sheetName, path, name, rest } = parseAttachmentBase(args, true);
|
|
182
|
+
const prefix = extractPrefix(rest);
|
|
183
|
+
const fileIdx = rest.indexOf('--file');
|
|
184
|
+
const dataIdx = rest.indexOf('--data');
|
|
185
|
+
const messageIdx = rest.indexOf('--message');
|
|
186
|
+
const fileArg = fileIdx >= 0 ? rest[fileIdx + 1] : undefined;
|
|
187
|
+
const dataArg = dataIdx >= 0 ? rest[dataIdx + 1] : undefined;
|
|
188
|
+
const message = messageIdx >= 0 ? rest[messageIdx + 1] : undefined;
|
|
189
|
+
// Acquire the content bytes.
|
|
190
|
+
let content;
|
|
191
|
+
if (fileArg) {
|
|
192
|
+
const absPath = isAbsolute(fileArg) ? fileArg : join(process.cwd(), fileArg);
|
|
193
|
+
try {
|
|
194
|
+
const buf = await readFile(absPath);
|
|
195
|
+
content = buf.toString('binary');
|
|
196
|
+
}
|
|
197
|
+
catch (err) {
|
|
198
|
+
throw new AxiError(`attachment set: cannot read ${fileArg}: ${err instanceof Error ? err.message : String(err)}`, 'NOT_FOUND');
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
else if (dataArg) {
|
|
202
|
+
content = dataArg;
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
content = await readStdin();
|
|
206
|
+
if (!content) {
|
|
207
|
+
throw new AxiError('attachment set needs content — pass --file <path>, --data <text>, or pipe on stdin', 'VALIDATION_ERROR');
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
const repo = await ctx.repo();
|
|
211
|
+
const sheet = await openTargetSheet(ctx, sheetName, prefix);
|
|
212
|
+
// Idempotency: check the existing attachment's content.
|
|
213
|
+
let existing;
|
|
214
|
+
try {
|
|
215
|
+
existing = await sheet.getAttachment(path, name);
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
throw translateError(error);
|
|
219
|
+
}
|
|
220
|
+
if (existing) {
|
|
221
|
+
try {
|
|
222
|
+
const existingText = await existing.read();
|
|
223
|
+
const existingStr = typeof existingText === 'string'
|
|
224
|
+
? existingText
|
|
225
|
+
: Buffer.from(existingText).toString('binary');
|
|
226
|
+
if (existingStr === content) {
|
|
227
|
+
return renderObject({
|
|
228
|
+
result: 'no-op',
|
|
229
|
+
sheet: sheetName,
|
|
230
|
+
record: path,
|
|
231
|
+
name,
|
|
232
|
+
hash: existing.hash,
|
|
233
|
+
reason: 'attachment bytes already match',
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
// Fall through and overwrite.
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const commitMessage = message ?? `${sheetName} setAttachment ${name} on ${path}`;
|
|
242
|
+
let commitHash = '';
|
|
243
|
+
try {
|
|
244
|
+
const result = await repo.transact({ message: commitMessage }, async (tx) => {
|
|
245
|
+
const txSheet = tx.sheet(sheetName, prefix !== undefined ? { prefix } : {});
|
|
246
|
+
await txSheet.setAttachment(path, name, content);
|
|
247
|
+
});
|
|
248
|
+
commitHash = result.commitHash ?? '';
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
throw translateError(error);
|
|
252
|
+
}
|
|
253
|
+
// Re-open the sheet to look up the new attachment hash — the `sheet`
|
|
254
|
+
// handle above is bound to the pre-commit tree.
|
|
255
|
+
let newHash = '';
|
|
256
|
+
try {
|
|
257
|
+
const fresh = await repo.openSheet(sheetName, prefix !== undefined ? { prefix } : {});
|
|
258
|
+
const created = await fresh.getAttachment(path, name);
|
|
259
|
+
newHash = created?.hash ?? '';
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
// not fatal — agent has the commit hash already
|
|
263
|
+
}
|
|
264
|
+
return renderObject({
|
|
265
|
+
result: existing ? 'overwritten' : 'created',
|
|
266
|
+
sheet: sheetName,
|
|
267
|
+
record: path,
|
|
268
|
+
name,
|
|
269
|
+
hash: newHash,
|
|
270
|
+
bytes: content.length,
|
|
271
|
+
commit: commitHash,
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
async function attachmentDelete(args, ctx) {
|
|
275
|
+
const { sheet: sheetName, path, name, rest } = parseAttachmentBase(args, false);
|
|
276
|
+
const prefix = extractPrefix(rest);
|
|
277
|
+
const messageIdx = rest.indexOf('--message');
|
|
278
|
+
const message = messageIdx >= 0 ? rest[messageIdx + 1] : undefined;
|
|
279
|
+
const repo = await ctx.repo();
|
|
280
|
+
const sheet = await openTargetSheet(ctx, sheetName, prefix);
|
|
281
|
+
if (name === undefined) {
|
|
282
|
+
// Delete all attachments on the record. Already idempotent in the library.
|
|
283
|
+
const before = await sheet.getAttachments(path);
|
|
284
|
+
const count = before ? Object.keys(before).length : 0;
|
|
285
|
+
if (count === 0) {
|
|
286
|
+
return renderObject({
|
|
287
|
+
result: 'no-op',
|
|
288
|
+
sheet: sheetName,
|
|
289
|
+
record: path,
|
|
290
|
+
reason: 'record has no attachments',
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
const commitMessage = message ?? `${sheetName} deleteAttachments on ${path}`;
|
|
294
|
+
let commitHash = '';
|
|
295
|
+
try {
|
|
296
|
+
const result = await repo.transact({ message: commitMessage }, async (tx) => {
|
|
297
|
+
const txSheet = tx.sheet(sheetName, prefix !== undefined ? { prefix } : {});
|
|
298
|
+
await txSheet.deleteAttachments(path);
|
|
299
|
+
});
|
|
300
|
+
commitHash = result.commitHash ?? '';
|
|
301
|
+
}
|
|
302
|
+
catch (error) {
|
|
303
|
+
throw translateError(error);
|
|
304
|
+
}
|
|
305
|
+
return renderObject({
|
|
306
|
+
result: 'committed',
|
|
307
|
+
sheet: sheetName,
|
|
308
|
+
record: path,
|
|
309
|
+
deleted: count,
|
|
310
|
+
commit: commitHash,
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
// Single-attachment delete; idempotent on already-missing.
|
|
314
|
+
const existing = await sheet.getAttachment(path, name);
|
|
315
|
+
if (!existing) {
|
|
316
|
+
return renderObject({
|
|
317
|
+
result: 'no-op',
|
|
318
|
+
sheet: sheetName,
|
|
319
|
+
record: path,
|
|
320
|
+
name,
|
|
321
|
+
reason: 'attachment already absent',
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
const commitMessage = message ?? `${sheetName} deleteAttachment ${name} on ${path}`;
|
|
325
|
+
let commitHash = '';
|
|
326
|
+
try {
|
|
327
|
+
const result = await repo.transact({ message: commitMessage }, async (tx) => {
|
|
328
|
+
const txSheet = tx.sheet(sheetName, prefix !== undefined ? { prefix } : {});
|
|
329
|
+
await txSheet.deleteAttachment(path, name);
|
|
330
|
+
});
|
|
331
|
+
commitHash = result.commitHash ?? '';
|
|
332
|
+
}
|
|
333
|
+
catch (error) {
|
|
334
|
+
if (error instanceof NotFoundError) {
|
|
335
|
+
return renderObject({
|
|
336
|
+
result: 'no-op',
|
|
337
|
+
sheet: sheetName,
|
|
338
|
+
record: path,
|
|
339
|
+
name,
|
|
340
|
+
reason: 'attachment vanished between check and delete',
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
throw translateError(error);
|
|
344
|
+
}
|
|
345
|
+
return renderObject({
|
|
346
|
+
result: 'committed',
|
|
347
|
+
sheet: sheetName,
|
|
348
|
+
record: path,
|
|
349
|
+
name,
|
|
350
|
+
commit: commitHash,
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
// stat() is exported here only to keep the import list tidy if we ever need
|
|
354
|
+
// file-size pre-checks in attachment set; suppress unused-import noise.
|
|
355
|
+
void stat;
|
|
356
|
+
//# sourceMappingURL=attachment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment.js","sourceRoot":"","sources":["../../../src/commands/attachment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { GitsheetsContext } from '../context.js';
|
|
2
|
+
export declare const CHECK_HELP = "usage: gitsheets-axi check <sheet> <file> [--fix] [--prefix p]\nflags[2]:\n --fix Rewrite the file in canonical form if not already canonical\n --prefix <p> Tenant sub-tree scope\nexamples:\n gitsheets-axi check users users/jane.toml\n gitsheets-axi check users users/jane.toml --fix\nexit codes:\n 0 File is canonical (or rewritten if --fix)\n 1 File is not canonical and --fix was not passed\n 22 ValidationError \u2014 record fails the sheet's JSON Schema\n 64 ConfigError \u2014 file failed to parse as the sheet's format\nbehavior:\n Reads from the working tree (not git). Never commits. Designed as a\n post-edit hook for agents that wrote a record directly: run with --fix\n to land in canonical form; run without to verify pre-commit.\n";
|
|
3
|
+
export declare function checkCommand(args: string[], ctx: GitsheetsContext): Promise<string>;
|
|
4
|
+
//# sourceMappingURL=check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../../src/commands/check.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAItD,eAAO,MAAM,UAAU,qxBAgBtB,CAAC;AAgDF,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC,MAAM,CAAC,CAsGjB"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { isAbsolute, join, relative } from 'node:path';
|
|
2
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { AxiError } from 'axi-sdk-js';
|
|
4
|
+
import { ConfigError, getFormat, NotFoundError, validateRecord } from 'gitsheets';
|
|
5
|
+
import { translateError } from '../errors.js';
|
|
6
|
+
import { renderObject } from '../output/render.js';
|
|
7
|
+
export const CHECK_HELP = `usage: gitsheets-axi check <sheet> <file> [--fix] [--prefix p]
|
|
8
|
+
flags[2]:
|
|
9
|
+
--fix Rewrite the file in canonical form if not already canonical
|
|
10
|
+
--prefix <p> Tenant sub-tree scope
|
|
11
|
+
examples:
|
|
12
|
+
gitsheets-axi check users users/jane.toml
|
|
13
|
+
gitsheets-axi check users users/jane.toml --fix
|
|
14
|
+
exit codes:
|
|
15
|
+
0 File is canonical (or rewritten if --fix)
|
|
16
|
+
1 File is not canonical and --fix was not passed
|
|
17
|
+
22 ValidationError — record fails the sheet's JSON Schema
|
|
18
|
+
64 ConfigError — file failed to parse as the sheet's format
|
|
19
|
+
behavior:
|
|
20
|
+
Reads from the working tree (not git). Never commits. Designed as a
|
|
21
|
+
post-edit hook for agents that wrote a record directly: run with --fix
|
|
22
|
+
to land in canonical form; run without to verify pre-commit.
|
|
23
|
+
`;
|
|
24
|
+
function parseCheckFlags(args) {
|
|
25
|
+
const flags = {
|
|
26
|
+
sheet: '',
|
|
27
|
+
file: '',
|
|
28
|
+
fix: false,
|
|
29
|
+
prefix: undefined,
|
|
30
|
+
};
|
|
31
|
+
const positional = [];
|
|
32
|
+
for (let i = 0; i < args.length; i++) {
|
|
33
|
+
const arg = args[i];
|
|
34
|
+
if (arg === undefined)
|
|
35
|
+
continue;
|
|
36
|
+
const next = args[i + 1];
|
|
37
|
+
if (arg === '--fix') {
|
|
38
|
+
flags.fix = true;
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (arg === '--prefix') {
|
|
42
|
+
if (!next)
|
|
43
|
+
throw new AxiError('--prefix expects a path', 'VALIDATION_ERROR');
|
|
44
|
+
flags.prefix = next;
|
|
45
|
+
i++;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (arg.startsWith('-')) {
|
|
49
|
+
throw new AxiError(`Unknown flag: ${arg}`, 'VALIDATION_ERROR', [
|
|
50
|
+
'Run `gitsheets-axi check --help`',
|
|
51
|
+
]);
|
|
52
|
+
}
|
|
53
|
+
positional.push(arg);
|
|
54
|
+
}
|
|
55
|
+
if (positional.length !== 2) {
|
|
56
|
+
throw new AxiError('check requires <sheet> <file>', 'VALIDATION_ERROR', [
|
|
57
|
+
'Example: gitsheets-axi check users users/jane.toml',
|
|
58
|
+
]);
|
|
59
|
+
}
|
|
60
|
+
flags.sheet = positional[0];
|
|
61
|
+
flags.file = positional[1];
|
|
62
|
+
return flags;
|
|
63
|
+
}
|
|
64
|
+
export async function checkCommand(args, ctx) {
|
|
65
|
+
if (args.length === 0 || (args.length === 1 && args[0] === '--help')) {
|
|
66
|
+
return CHECK_HELP;
|
|
67
|
+
}
|
|
68
|
+
const flags = parseCheckFlags(args);
|
|
69
|
+
const repo = await ctx.repo();
|
|
70
|
+
let sheet;
|
|
71
|
+
try {
|
|
72
|
+
sheet = await repo.openSheet(flags.sheet, flags.prefix !== undefined ? { prefix: flags.prefix } : {});
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
throw translateError(error);
|
|
76
|
+
}
|
|
77
|
+
const config = await sheet.readConfig();
|
|
78
|
+
const format = getFormat(config.format.type);
|
|
79
|
+
const absPath = isAbsolute(flags.file)
|
|
80
|
+
? flags.file
|
|
81
|
+
: join(process.cwd(), flags.file);
|
|
82
|
+
let original;
|
|
83
|
+
try {
|
|
84
|
+
original = await readFile(absPath, 'utf-8');
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
throw translateError(new NotFoundError('record_not_found', `check: cannot read ${flags.file}: ${err instanceof Error ? err.message : String(err)}`));
|
|
88
|
+
}
|
|
89
|
+
// Parse via the sheet's format. Failure → ConfigError → exit 64.
|
|
90
|
+
let record;
|
|
91
|
+
try {
|
|
92
|
+
record = format.parse(original, config.format);
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
throw translateError(new ConfigError('config_invalid', `check: failed to parse ${flags.file} as ${config.format.type}: ${err instanceof Error ? err.message : String(err)}`, { cause: err }));
|
|
96
|
+
}
|
|
97
|
+
// Validate against the sheet's schema → ValidationError → exit 22.
|
|
98
|
+
let validated;
|
|
99
|
+
try {
|
|
100
|
+
validated = await validateRecord({
|
|
101
|
+
record: { ...record },
|
|
102
|
+
schema: config.schema,
|
|
103
|
+
schemaSourcePath: `.gitsheets/${flags.sheet}.toml`,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
throw translateError(err);
|
|
108
|
+
}
|
|
109
|
+
const normalized = await sheet.normalizeRecord(validated);
|
|
110
|
+
const newText = await format.serialize({ ...normalized }, config.format);
|
|
111
|
+
const relPath = relative(process.cwd(), absPath) || flags.file;
|
|
112
|
+
if (newText === original) {
|
|
113
|
+
return renderObject({
|
|
114
|
+
result: 'ok',
|
|
115
|
+
file: relPath,
|
|
116
|
+
canonical: true,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
if (flags.fix) {
|
|
120
|
+
try {
|
|
121
|
+
await writeFile(absPath, newText, 'utf-8');
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
throw new AxiError(`check: could not write ${flags.file}: ${err instanceof Error ? err.message : String(err)}`, 'WRITE_ERROR');
|
|
125
|
+
}
|
|
126
|
+
return renderObject({
|
|
127
|
+
result: 'fixed',
|
|
128
|
+
file: relPath,
|
|
129
|
+
canonical: true,
|
|
130
|
+
bytes_changed: original.length !== newText.length || original !== newText,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
// Not canonical, --fix not passed. AXI behavior: error on stdout, exit 1.
|
|
134
|
+
throw new AxiError(`${flags.file} is not in canonical form`, 'NOT_CANONICAL', [`Re-run with \`--fix\` to rewrite ${flags.file}`]);
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../../src/commands/check.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGlF,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,CAAC,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;CAgBzB,CAAC;AASF,SAAS,eAAe,CAAC,IAAc;IACrC,MAAM,KAAK,GAAe;QACxB,KAAK,EAAE,EAAE;QACT,IAAI,EAAE,EAAE;QACR,GAAG,EAAE,KAAK;QACV,MAAM,EAAE,SAAS;KAClB,CAAC;IACF,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,GAAG,KAAK,SAAS;YAAE,SAAS;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACzB,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;YACpB,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC;YACjB,SAAS;QACX,CAAC;QACD,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;YACvB,IAAI,CAAC,IAAI;gBAAE,MAAM,IAAI,QAAQ,CAAC,yBAAyB,EAAE,kBAAkB,CAAC,CAAC;YAC7E,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;YACpB,CAAC,EAAE,CAAC;YACJ,SAAS;QACX,CAAC;QACD,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,QAAQ,CAAC,iBAAiB,GAAG,EAAE,EAAE,kBAAkB,EAAE;gBAC7D,kCAAkC;aACnC,CAAC,CAAC;QACL,CAAC;QACD,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,QAAQ,CAAC,+BAA+B,EAAE,kBAAkB,EAAE;YACtE,oDAAoD;SACrD,CAAC,CAAC;IACL,CAAC;IACD,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,CAAC,CAAE,CAAC;IAC7B,KAAK,CAAC,IAAI,GAAG,UAAU,CAAC,CAAC,CAAE,CAAC;IAC5B,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAc,EACd,GAAqB;IAErB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,EAAE,CAAC;QACrE,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAE9B,IAAI,KAAK,CAAC;IACV,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,IAAI,CAAC,SAAS,CAC1B,KAAK,CAAC,KAAK,EACX,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAC3D,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,cAAc,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,UAAU,EAAE,CAAC;IACxC,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAE7C,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC;QACpC,CAAC,CAAC,KAAK,CAAC,IAAI;QACZ,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAEpC,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,cAAc,CAClB,IAAI,aAAa,CACf,kBAAkB,EAClB,sBAAsB,KAAK,CAAC,IAAI,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CACxF,CACF,CAAC;IACJ,CAAC;IAED,iEAAiE;IACjE,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,cAAc,CAClB,IAAI,WAAW,CACb,gBAAgB,EAChB,0BAA0B,KAAK,CAAC,IAAI,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EACpH,EAAE,KAAK,EAAE,GAAG,EAAE,CACf,CACF,CAAC;IACJ,CAAC;IAED,mEAAmE;IACnE,IAAI,SAAS,CAAC;IACd,IAAI,CAAC;QACH,SAAS,GAAG,MAAM,cAAc,CAAC;YAC/B,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE;YACrB,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,gBAAgB,EAAE,cAAc,KAAK,CAAC,KAAK,OAAO;SACnD,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;IAC5B,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,KAAK,CAAC,eAAe,CAAC,SAAkB,CAAC,CAAC;IACnE,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,SAAS,CACpC,EAAE,GAAI,UAAsC,EAAE,EAC9C,MAAM,CAAC,MAAM,CACd,CAAC;IAEF,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC;IAE/D,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;QACzB,OAAO,YAAY,CAAC;YAClB,MAAM,EAAE,IAAI;YACZ,IAAI,EAAE,OAAO;YACb,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC;IACL,CAAC;IAED,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;QACd,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC7C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,QAAQ,CAChB,0BAA0B,KAAK,CAAC,IAAI,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAC3F,aAAa,CACd,CAAC;QACJ,CAAC;QACD,OAAO,YAAY,CAAC;YAClB,MAAM,EAAE,OAAO;YACf,IAAI,EAAE,OAAO;YACb,SAAS,EAAE,IAAI;YACf,aAAa,EAAE,QAAQ,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,IAAI,QAAQ,KAAK,OAAO;SAC1E,CAAC,CAAC;IACL,CAAC;IAED,0EAA0E;IAC1E,MAAM,IAAI,QAAQ,CAChB,GAAG,KAAK,CAAC,IAAI,2BAA2B,EACxC,eAAe,EACf,CAAC,oCAAoC,KAAK,CAAC,IAAI,EAAE,CAAC,CACnD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { GitsheetsContext } from '../context.js';
|
|
2
|
+
export declare const DELETE_HELP = "usage: gitsheets-axi delete <sheet> <path> [--prefix p] [--message m]\nflags[2]:\n --prefix <p> Tenant sub-tree scope\n --message <m> Commit message (default: \"<sheet> delete <path>\")\nexamples:\n gitsheets-axi delete users jane\n gitsheets-axi delete posts hello --message \"remove deprecated post\"\nidempotency:\n Already-missing records exit 0 with result: \"no-op\" \u2014 no commit, no\n error. Pattern: an agent re-running a workflow can safely call delete\n without checking existence first.\n";
|
|
3
|
+
export declare function deleteCommand(args: string[], ctx: GitsheetsContext): Promise<string>;
|
|
4
|
+
//# sourceMappingURL=delete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.d.ts","sourceRoot":"","sources":["../../../src/commands/delete.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAItD,eAAO,MAAM,WAAW,khBAWvB,CAAC;AAkDF,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,gBAAgB,GACpB,OAAO,CAAC,MAAM,CAAC,CAyEjB"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { AxiError } from 'axi-sdk-js';
|
|
2
|
+
import { NotFoundError, RECORD_PATH_KEY } from 'gitsheets';
|
|
3
|
+
import { translateError } from '../errors.js';
|
|
4
|
+
import { renderObject } from '../output/render.js';
|
|
5
|
+
export const DELETE_HELP = `usage: gitsheets-axi delete <sheet> <path> [--prefix p] [--message m]
|
|
6
|
+
flags[2]:
|
|
7
|
+
--prefix <p> Tenant sub-tree scope
|
|
8
|
+
--message <m> Commit message (default: "<sheet> delete <path>")
|
|
9
|
+
examples:
|
|
10
|
+
gitsheets-axi delete users jane
|
|
11
|
+
gitsheets-axi delete posts hello --message "remove deprecated post"
|
|
12
|
+
idempotency:
|
|
13
|
+
Already-missing records exit 0 with result: "no-op" — no commit, no
|
|
14
|
+
error. Pattern: an agent re-running a workflow can safely call delete
|
|
15
|
+
without checking existence first.
|
|
16
|
+
`;
|
|
17
|
+
function parseDeleteFlags(args) {
|
|
18
|
+
const flags = {
|
|
19
|
+
sheet: '',
|
|
20
|
+
path: '',
|
|
21
|
+
prefix: undefined,
|
|
22
|
+
message: undefined,
|
|
23
|
+
};
|
|
24
|
+
const positional = [];
|
|
25
|
+
for (let i = 0; i < args.length; i++) {
|
|
26
|
+
const arg = args[i];
|
|
27
|
+
if (arg === undefined)
|
|
28
|
+
continue;
|
|
29
|
+
const next = args[i + 1];
|
|
30
|
+
if (arg === '--prefix') {
|
|
31
|
+
if (!next)
|
|
32
|
+
throw new AxiError('--prefix expects a path', 'VALIDATION_ERROR');
|
|
33
|
+
flags.prefix = next;
|
|
34
|
+
i++;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (arg === '--message') {
|
|
38
|
+
if (!next)
|
|
39
|
+
throw new AxiError('--message expects a string', 'VALIDATION_ERROR');
|
|
40
|
+
flags.message = next;
|
|
41
|
+
i++;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (arg.startsWith('-')) {
|
|
45
|
+
throw new AxiError(`Unknown flag: ${arg}`, 'VALIDATION_ERROR', [
|
|
46
|
+
'Run `gitsheets-axi delete --help`',
|
|
47
|
+
]);
|
|
48
|
+
}
|
|
49
|
+
positional.push(arg);
|
|
50
|
+
}
|
|
51
|
+
if (positional.length !== 2) {
|
|
52
|
+
throw new AxiError('delete requires <sheet> <path>', 'VALIDATION_ERROR', [
|
|
53
|
+
'Example: gitsheets-axi delete users jane',
|
|
54
|
+
]);
|
|
55
|
+
}
|
|
56
|
+
flags.sheet = positional[0];
|
|
57
|
+
flags.path = positional[1];
|
|
58
|
+
return flags;
|
|
59
|
+
}
|
|
60
|
+
export async function deleteCommand(args, ctx) {
|
|
61
|
+
if (args.length === 0 || (args.length === 1 && args[0] === '--help')) {
|
|
62
|
+
return DELETE_HELP;
|
|
63
|
+
}
|
|
64
|
+
const flags = parseDeleteFlags(args);
|
|
65
|
+
const target = stripExtension(flags.path);
|
|
66
|
+
const repo = await ctx.repo();
|
|
67
|
+
let sheet;
|
|
68
|
+
try {
|
|
69
|
+
sheet = await repo.openSheet(flags.sheet, flags.prefix !== undefined ? { prefix: flags.prefix } : {});
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
throw translateError(error);
|
|
73
|
+
}
|
|
74
|
+
// Pre-flight existence check — idempotent on already-missing.
|
|
75
|
+
let exists = false;
|
|
76
|
+
try {
|
|
77
|
+
for await (const record of sheet.query()) {
|
|
78
|
+
const pathSym = record[RECORD_PATH_KEY];
|
|
79
|
+
if (pathSym === target) {
|
|
80
|
+
exists = true;
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
throw translateError(error);
|
|
87
|
+
}
|
|
88
|
+
if (!exists) {
|
|
89
|
+
return renderObject({
|
|
90
|
+
result: 'no-op',
|
|
91
|
+
sheet: flags.sheet,
|
|
92
|
+
path: target,
|
|
93
|
+
reason: 'record already absent',
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
const commitMessage = flags.message ?? `${flags.sheet} delete ${target}`;
|
|
97
|
+
try {
|
|
98
|
+
const result = await repo.transact({ message: commitMessage }, async (tx) => {
|
|
99
|
+
const txSheet = tx.sheet(flags.sheet, flags.prefix !== undefined ? { prefix: flags.prefix } : {});
|
|
100
|
+
await txSheet.delete(target);
|
|
101
|
+
});
|
|
102
|
+
return renderObject({
|
|
103
|
+
result: 'committed',
|
|
104
|
+
sheet: flags.sheet,
|
|
105
|
+
path: target,
|
|
106
|
+
commit: result.commitHash,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
// Edge: race where the record vanished between the existence check
|
|
111
|
+
// and the delete. Treat as no-op rather than failing.
|
|
112
|
+
if (error instanceof NotFoundError) {
|
|
113
|
+
return renderObject({
|
|
114
|
+
result: 'no-op',
|
|
115
|
+
sheet: flags.sheet,
|
|
116
|
+
path: target,
|
|
117
|
+
reason: 'record vanished between check and delete',
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
throw translateError(error);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function stripExtension(path) {
|
|
124
|
+
if (path.endsWith('.toml'))
|
|
125
|
+
return path.slice(0, -5);
|
|
126
|
+
if (path.endsWith('.md'))
|
|
127
|
+
return path.slice(0, -3);
|
|
128
|
+
if (path.endsWith('.mdx'))
|
|
129
|
+
return path.slice(0, -4);
|
|
130
|
+
return path;
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=delete.js.map
|