artifact-cafe 0.0.5 → 0.0.7
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/dist/index.js +617 -134
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -130,8 +130,11 @@ var threadActionSchema = z2.object({
|
|
|
130
130
|
guest: guestSchema.optional()
|
|
131
131
|
});
|
|
132
132
|
var commentAuthorSchema = z2.object({
|
|
133
|
+
avatarUrl: z2.string().nullable(),
|
|
133
134
|
displayName: z2.string(),
|
|
134
|
-
guestId: z2.string().nullable()
|
|
135
|
+
guestId: z2.string().nullable(),
|
|
136
|
+
isViewer: z2.boolean(),
|
|
137
|
+
kind: z2.enum(["member", "guest"])
|
|
135
138
|
});
|
|
136
139
|
var commentMessageSchema = z2.object({
|
|
137
140
|
author: commentAuthorSchema,
|
|
@@ -158,12 +161,14 @@ var commentExportQuerySchema = z2.object({
|
|
|
158
161
|
});
|
|
159
162
|
var commentExportReplySchema = z2.object({
|
|
160
163
|
author: z2.string(),
|
|
164
|
+
authorKind: z2.enum(["member", "guest"]),
|
|
161
165
|
body: z2.string(),
|
|
162
166
|
createdAt: z2.string()
|
|
163
167
|
});
|
|
164
168
|
var commentExportThreadSchema = z2.object({
|
|
165
169
|
anchor: anchorSchema,
|
|
166
170
|
author: z2.string(),
|
|
171
|
+
authorKind: z2.enum(["member", "guest"]),
|
|
167
172
|
body: z2.string(),
|
|
168
173
|
createdAt: z2.string(),
|
|
169
174
|
id: z2.string(),
|
|
@@ -199,6 +204,15 @@ import { z as z4 } from "zod";
|
|
|
199
204
|
var ownArtifactSchema = z4.object({
|
|
200
205
|
createdAt: z4.string(),
|
|
201
206
|
currentVersionNumber: z4.number().nullable(),
|
|
207
|
+
// Owned artifacts normally never expire; non-null only while an
|
|
208
|
+
// expiry is still set (e.g. an unclaimed publish surfaced here later).
|
|
209
|
+
expiresAt: z4.string().nullable(),
|
|
210
|
+
// SPEC-2 §8.4 — the containing folder's name for workspace-owned
|
|
211
|
+
// artifacts; always null for personal artifacts.
|
|
212
|
+
folderName: z4.string().nullable(),
|
|
213
|
+
// Whether a publish token is still active — revocable from the
|
|
214
|
+
// dashboard (§6.18); the token itself is never returned.
|
|
215
|
+
hasPublishToken: z4.boolean(),
|
|
202
216
|
id: z4.string(),
|
|
203
217
|
openThreads: z4.number(),
|
|
204
218
|
protected: z4.boolean(),
|
|
@@ -212,64 +226,217 @@ var ownArtifactSchema = z4.object({
|
|
|
212
226
|
var ownArtifactsResponseSchema = z4.object({
|
|
213
227
|
artifacts: z4.array(ownArtifactSchema)
|
|
214
228
|
});
|
|
229
|
+
var revokePublishTokenResponseSchema = z4.object({
|
|
230
|
+
revoked: z4.boolean()
|
|
231
|
+
});
|
|
215
232
|
|
|
216
233
|
// ../shared/src/owner.ts
|
|
234
|
+
import { z as z6 } from "zod";
|
|
235
|
+
|
|
236
|
+
// ../shared/src/workspaces.ts
|
|
217
237
|
import { z as z5 } from "zod";
|
|
218
|
-
var
|
|
219
|
-
var
|
|
220
|
-
|
|
238
|
+
var WORKSPACE_HANDLE_PATTERN = /^[a-z0-9](?:[a-z0-9-]{1,30}[a-z0-9])$/;
|
|
239
|
+
var workspaceRoleSchema = z5.enum(["owner", "admin", "member"]);
|
|
240
|
+
var workspaceInviteRoleSchema = z5.enum(["admin", "member"]);
|
|
241
|
+
var workspaceHandleSchema = z5.string().min(3).max(32).regex(WORKSPACE_HANDLE_PATTERN, {
|
|
242
|
+
message: "handle must be lowercase letters, digits, and hyphens, with no leading/trailing hyphen"
|
|
243
|
+
});
|
|
244
|
+
var createWorkspaceSchema = z5.object({
|
|
245
|
+
handle: workspaceHandleSchema.optional(),
|
|
246
|
+
name: z5.string().trim().min(1).max(100)
|
|
247
|
+
});
|
|
248
|
+
var updateWorkspaceSchema = z5.object({
|
|
249
|
+
handle: workspaceHandleSchema.optional(),
|
|
250
|
+
name: z5.string().trim().min(1).max(100).optional()
|
|
251
|
+
}).refine((body) => body.handle !== void 0 || body.name !== void 0, {
|
|
252
|
+
message: "provide at least one of name or handle"
|
|
253
|
+
});
|
|
254
|
+
var workspaceSchema = z5.object({
|
|
255
|
+
createdAt: z5.string(),
|
|
256
|
+
handle: z5.string(),
|
|
257
|
+
id: z5.string(),
|
|
258
|
+
name: z5.string(),
|
|
259
|
+
role: workspaceRoleSchema.nullable(),
|
|
260
|
+
updatedAt: z5.string()
|
|
261
|
+
});
|
|
262
|
+
var workspaceListResponseSchema = z5.object({
|
|
263
|
+
workspaces: z5.array(workspaceSchema)
|
|
264
|
+
});
|
|
265
|
+
var deleteWorkspaceResponseSchema = z5.object({
|
|
266
|
+
deleted: z5.literal(true)
|
|
267
|
+
});
|
|
268
|
+
var workspaceMemberSchema = z5.object({
|
|
269
|
+
createdAt: z5.string(),
|
|
270
|
+
email: z5.string().email(),
|
|
271
|
+
image: z5.string().nullable(),
|
|
272
|
+
name: z5.string(),
|
|
273
|
+
role: workspaceRoleSchema,
|
|
274
|
+
userId: z5.string()
|
|
275
|
+
});
|
|
276
|
+
var workspaceMemberListResponseSchema = z5.object({
|
|
277
|
+
members: z5.array(workspaceMemberSchema)
|
|
278
|
+
});
|
|
279
|
+
var updateWorkspaceMemberSchema = z5.object({
|
|
280
|
+
role: workspaceRoleSchema
|
|
281
|
+
});
|
|
282
|
+
var removeWorkspaceMemberResponseSchema = z5.object({
|
|
283
|
+
removed: z5.literal(true)
|
|
284
|
+
});
|
|
285
|
+
var createWorkspaceInviteSchema = z5.object({
|
|
286
|
+
email: z5.string().trim().toLowerCase().email().optional(),
|
|
287
|
+
expiresAt: z5.string().datetime(),
|
|
288
|
+
maxUses: z5.number().int().positive().optional(),
|
|
289
|
+
role: workspaceInviteRoleSchema
|
|
290
|
+
});
|
|
291
|
+
var workspaceInviteSchema = z5.object({
|
|
292
|
+
createdAt: z5.string(),
|
|
293
|
+
email: z5.string().email().nullable(),
|
|
294
|
+
expiresAt: z5.string(),
|
|
295
|
+
id: z5.string(),
|
|
296
|
+
maxUses: z5.number().int().positive().nullable(),
|
|
297
|
+
role: workspaceInviteRoleSchema,
|
|
298
|
+
tokenPrefix: z5.string(),
|
|
299
|
+
useCount: z5.number().int().nonnegative()
|
|
300
|
+
});
|
|
301
|
+
var createdWorkspaceInviteSchema = workspaceInviteSchema.extend({
|
|
302
|
+
url: z5.string().url()
|
|
303
|
+
});
|
|
304
|
+
var workspaceInviteListResponseSchema = z5.object({
|
|
305
|
+
invites: z5.array(workspaceInviteSchema)
|
|
306
|
+
});
|
|
307
|
+
var revokeWorkspaceInviteResponseSchema = z5.object({
|
|
308
|
+
revoked: z5.literal(true)
|
|
309
|
+
});
|
|
310
|
+
var acceptWorkspaceInviteSchema = z5.object({
|
|
311
|
+
token: z5.string().min(1)
|
|
312
|
+
});
|
|
313
|
+
var acceptWorkspaceInviteResponseSchema = z5.object({
|
|
314
|
+
role: workspaceRoleSchema,
|
|
315
|
+
workspace: workspaceSchema
|
|
316
|
+
});
|
|
317
|
+
var folderVisibilitySchema = z5.enum(["public", "workspace"]);
|
|
318
|
+
var artifactVisibilitySchema = z5.enum([
|
|
319
|
+
"public",
|
|
320
|
+
"unlisted",
|
|
321
|
+
"workspace"
|
|
322
|
+
]);
|
|
323
|
+
var createFolderSchema = z5.object({
|
|
324
|
+
name: z5.string().trim().min(1).max(100),
|
|
325
|
+
visibility: folderVisibilitySchema
|
|
326
|
+
});
|
|
327
|
+
var updateFolderSchema = z5.object({
|
|
328
|
+
// With `visibility`: bulk-update the folder's artifacts to match
|
|
329
|
+
// (SPEC-2 §3.4 "Changing a folder's visibility offers a bulk update").
|
|
330
|
+
cascade: z5.boolean().optional(),
|
|
331
|
+
name: z5.string().trim().min(1).max(100).optional(),
|
|
332
|
+
sortOrder: z5.number().int().min(0).optional(),
|
|
333
|
+
visibility: folderVisibilitySchema.optional()
|
|
334
|
+
}).refine(
|
|
335
|
+
(body) => body.name !== void 0 || body.visibility !== void 0 || body.sortOrder !== void 0,
|
|
336
|
+
{ message: "provide at least one of name, visibility, sortOrder" }
|
|
337
|
+
).refine((body) => !body.cascade || body.visibility !== void 0, {
|
|
338
|
+
message: "cascade requires visibility"
|
|
339
|
+
});
|
|
340
|
+
var folderSchema = z5.object({
|
|
341
|
+
createdAt: z5.string(),
|
|
342
|
+
id: z5.string(),
|
|
343
|
+
name: z5.string(),
|
|
344
|
+
// Permalink segment for the public folder page (/w/{handle}/f/{slug}).
|
|
345
|
+
// Server-derived from the name; renames regenerate it.
|
|
346
|
+
slug: z5.string(),
|
|
347
|
+
sortOrder: z5.number().int(),
|
|
348
|
+
updatedAt: z5.string(),
|
|
349
|
+
visibility: folderVisibilitySchema,
|
|
350
|
+
workspaceId: z5.string()
|
|
351
|
+
});
|
|
352
|
+
var folderListResponseSchema = z5.object({
|
|
353
|
+
folders: z5.array(folderSchema)
|
|
354
|
+
});
|
|
355
|
+
var deleteFolderResponseSchema = z5.object({
|
|
356
|
+
deleted: z5.literal(true)
|
|
357
|
+
});
|
|
358
|
+
var workspaceArtifactSchema = z5.object({
|
|
359
|
+
createdAt: z5.string(),
|
|
360
|
+
currentVersionNumber: z5.number().int().nullable(),
|
|
361
|
+
folderId: z5.string().nullable(),
|
|
362
|
+
id: z5.string(),
|
|
363
|
+
openCommentCount: z5.number().int().nonnegative(),
|
|
221
364
|
slug: z5.string(),
|
|
222
365
|
title: z5.string(),
|
|
223
|
-
|
|
366
|
+
updatedAt: z5.string(),
|
|
367
|
+
url: z5.string().url(),
|
|
368
|
+
versionCount: z5.number().int().nonnegative(),
|
|
369
|
+
visibility: artifactVisibilitySchema
|
|
370
|
+
});
|
|
371
|
+
var workspaceArtifactListResponseSchema = z5.object({
|
|
372
|
+
artifacts: z5.array(workspaceArtifactSchema)
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
// ../shared/src/owner.ts
|
|
376
|
+
var SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9-]{1,61}[a-z0-9])$/;
|
|
377
|
+
var claimResponseSchema = z6.object({
|
|
378
|
+
artifactId: z6.string(),
|
|
379
|
+
slug: z6.string(),
|
|
380
|
+
title: z6.string(),
|
|
381
|
+
url: z6.string().url()
|
|
224
382
|
});
|
|
225
|
-
var updateArtifactSchema =
|
|
226
|
-
|
|
383
|
+
var updateArtifactSchema = z6.object({
|
|
384
|
+
// SPEC-2 §6.4 — placement + visibility. `folderId: null` clears the
|
|
385
|
+
// folder; `workspaceId: null` moves the artifact out of its workspace
|
|
386
|
+
// (§5.5 ownership transfer).
|
|
387
|
+
folderId: z6.string().min(1).nullable().optional(),
|
|
388
|
+
slug: z6.string().min(3).max(63).regex(SLUG_PATTERN, {
|
|
227
389
|
message: "slug must be lowercase letters, digits, and hyphens, with no leading/trailing hyphen"
|
|
228
390
|
}).optional(),
|
|
229
|
-
title:
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
})
|
|
233
|
-
|
|
234
|
-
|
|
391
|
+
title: z6.string().min(1).max(200).optional(),
|
|
392
|
+
visibility: artifactVisibilitySchema.optional(),
|
|
393
|
+
workspaceId: z6.string().min(1).nullable().optional()
|
|
394
|
+
}).refine(
|
|
395
|
+
(body) => body.title !== void 0 || body.slug !== void 0 || body.visibility !== void 0 || body.folderId !== void 0 || body.workspaceId !== void 0,
|
|
396
|
+
{
|
|
397
|
+
message: "provide at least one of title, slug, visibility, folderId, workspaceId"
|
|
398
|
+
}
|
|
399
|
+
);
|
|
400
|
+
var deleteArtifactResponseSchema = z6.object({
|
|
401
|
+
deleted: z6.literal(true)
|
|
235
402
|
});
|
|
236
403
|
|
|
237
404
|
// ../shared/src/presence.ts
|
|
238
|
-
import { z as
|
|
405
|
+
import { z as z7 } from "zod";
|
|
239
406
|
var AGENT_PRESENCE = {
|
|
240
407
|
heartbeatSeconds: 15,
|
|
241
408
|
shellPollSeconds: 15,
|
|
242
409
|
ttlSeconds: 45
|
|
243
410
|
};
|
|
244
|
-
var agentHeartbeatResponseSchema =
|
|
245
|
-
listening:
|
|
246
|
-
ttlSeconds:
|
|
411
|
+
var agentHeartbeatResponseSchema = z7.object({
|
|
412
|
+
listening: z7.literal(true),
|
|
413
|
+
ttlSeconds: z7.number().int().positive()
|
|
247
414
|
});
|
|
248
|
-
var agentPresenceSchema =
|
|
249
|
-
listening:
|
|
250
|
-
versionNumber:
|
|
415
|
+
var agentPresenceSchema = z7.object({
|
|
416
|
+
listening: z7.boolean(),
|
|
417
|
+
versionNumber: z7.number().int().positive().nullable()
|
|
251
418
|
});
|
|
252
419
|
|
|
253
420
|
// ../shared/src/protection.ts
|
|
254
|
-
import { z as
|
|
421
|
+
import { z as z8 } from "zod";
|
|
255
422
|
var PASSWORD_MIN = 6;
|
|
256
423
|
var PASSWORD_MAX = 128;
|
|
257
|
-
var gatePasswordSchema =
|
|
258
|
-
var setProtectionSchema =
|
|
424
|
+
var gatePasswordSchema = z8.string().min(PASSWORD_MIN, `Password must be at least ${PASSWORD_MIN} characters.`).max(PASSWORD_MAX, `Password must be at most ${PASSWORD_MAX} characters.`);
|
|
425
|
+
var setProtectionSchema = z8.object({
|
|
259
426
|
password: gatePasswordSchema.nullable()
|
|
260
427
|
});
|
|
261
|
-
var protectionResponseSchema =
|
|
262
|
-
protected:
|
|
428
|
+
var protectionResponseSchema = z8.object({
|
|
429
|
+
protected: z8.boolean()
|
|
263
430
|
});
|
|
264
|
-
var unlockSchema =
|
|
265
|
-
password:
|
|
431
|
+
var unlockSchema = z8.object({
|
|
432
|
+
password: z8.string().min(1).max(1024)
|
|
266
433
|
});
|
|
267
|
-
var unlockResponseSchema =
|
|
268
|
-
unlocked:
|
|
434
|
+
var unlockResponseSchema = z8.object({
|
|
435
|
+
unlocked: z8.literal(true)
|
|
269
436
|
});
|
|
270
437
|
|
|
271
438
|
// ../shared/src/publish.ts
|
|
272
|
-
import { z as
|
|
439
|
+
import { z as z9 } from "zod";
|
|
273
440
|
function isSafeArtifactPath(p) {
|
|
274
441
|
if (p.length === 0 || p.length > 1024) {
|
|
275
442
|
return false;
|
|
@@ -282,128 +449,136 @@ function isSafeArtifactPath(p) {
|
|
|
282
449
|
}
|
|
283
450
|
return p.split("/").every((seg) => seg.length > 0 && seg !== "." && seg !== "..");
|
|
284
451
|
}
|
|
285
|
-
var manifestFileSchema =
|
|
286
|
-
hash:
|
|
287
|
-
mimeType:
|
|
288
|
-
path:
|
|
452
|
+
var manifestFileSchema = z9.object({
|
|
453
|
+
hash: z9.string().regex(/^sha256_[a-f0-9]{64}$/),
|
|
454
|
+
mimeType: z9.string().regex(/^[-\w.+]+\/[-\w.+]+$/, { message: "invalid MIME type" }),
|
|
455
|
+
path: z9.string().min(1).max(1024).refine(isSafeArtifactPath, {
|
|
289
456
|
message: "path must be a safe relative path"
|
|
290
457
|
}),
|
|
291
|
-
size:
|
|
458
|
+
size: z9.number().int().positive()
|
|
292
459
|
});
|
|
293
|
-
var publishSourceSchema =
|
|
294
|
-
agent:
|
|
295
|
-
runId:
|
|
296
|
-
type:
|
|
460
|
+
var publishSourceSchema = z9.object({
|
|
461
|
+
agent: z9.string().optional(),
|
|
462
|
+
runId: z9.string().optional(),
|
|
463
|
+
type: z9.literal("cli")
|
|
297
464
|
});
|
|
298
|
-
var createPublishSessionSchema =
|
|
299
|
-
artifactId:
|
|
300
|
-
entryPath:
|
|
301
|
-
files:
|
|
465
|
+
var createPublishSessionSchema = z9.object({
|
|
466
|
+
artifactId: z9.string().nullable(),
|
|
467
|
+
entryPath: z9.string().optional(),
|
|
468
|
+
files: z9.array(manifestFileSchema).min(1).max(1e3),
|
|
469
|
+
// SPEC-2 §6.4 — workspace placement is available only to authenticated
|
|
470
|
+
// members; the API enforces membership and folder ownership.
|
|
471
|
+
folderId: z9.string().min(1).optional(),
|
|
302
472
|
source: publishSourceSchema,
|
|
303
|
-
title:
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
473
|
+
title: z9.string().max(200).optional(),
|
|
474
|
+
workspaceId: z9.string().min(1).optional()
|
|
475
|
+
});
|
|
476
|
+
var publishSessionResponseSchema = z9.object({
|
|
477
|
+
artifactId: z9.string(),
|
|
478
|
+
expiresAt: z9.string(),
|
|
479
|
+
filesToUpload: z9.array(
|
|
480
|
+
z9.object({
|
|
481
|
+
method: z9.literal("PUT"),
|
|
482
|
+
path: z9.string(),
|
|
483
|
+
uploadUrl: z9.string().url()
|
|
313
484
|
})
|
|
314
485
|
),
|
|
315
|
-
publishSessionId:
|
|
316
|
-
skippedFiles:
|
|
317
|
-
versionId:
|
|
486
|
+
publishSessionId: z9.string(),
|
|
487
|
+
skippedFiles: z9.array(z9.string()),
|
|
488
|
+
versionId: z9.string()
|
|
318
489
|
});
|
|
319
|
-
var finalizeResponseSchema =
|
|
320
|
-
artifactId:
|
|
490
|
+
var finalizeResponseSchema = z9.object({
|
|
491
|
+
artifactId: z9.string(),
|
|
321
492
|
// API-key publishes create the artifact already claimed (SPEC §5.4) —
|
|
322
493
|
// the CLI uses this to tell "claim URL pending" from "already yours".
|
|
323
|
-
claimed:
|
|
494
|
+
claimed: z9.boolean(),
|
|
324
495
|
// Returned only on first publish of a new artifact (one-time).
|
|
325
|
-
claimUrl:
|
|
326
|
-
publishToken:
|
|
327
|
-
url:
|
|
328
|
-
versionId:
|
|
329
|
-
versionNumber:
|
|
330
|
-
});
|
|
331
|
-
var artifactResponseSchema =
|
|
332
|
-
claimed:
|
|
333
|
-
currentVersion:
|
|
334
|
-
entryUrl:
|
|
335
|
-
id:
|
|
336
|
-
versionNumber:
|
|
496
|
+
claimUrl: z9.string().url().optional(),
|
|
497
|
+
publishToken: z9.string().optional(),
|
|
498
|
+
url: z9.string().url(),
|
|
499
|
+
versionId: z9.string(),
|
|
500
|
+
versionNumber: z9.number().int().positive()
|
|
501
|
+
});
|
|
502
|
+
var artifactResponseSchema = z9.object({
|
|
503
|
+
claimed: z9.boolean(),
|
|
504
|
+
currentVersion: z9.object({
|
|
505
|
+
entryUrl: z9.string().url(),
|
|
506
|
+
id: z9.string(),
|
|
507
|
+
versionNumber: z9.number().int().positive()
|
|
337
508
|
}).nullable(),
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
509
|
+
// SPEC-2 §6.4 — placement + visibility surface on the artifact.
|
|
510
|
+
folderId: z9.string().nullable(),
|
|
511
|
+
id: z9.string(),
|
|
512
|
+
slug: z9.string(),
|
|
513
|
+
title: z9.string(),
|
|
514
|
+
visibility: z9.enum(["public", "unlisted", "workspace"]),
|
|
515
|
+
workspaceId: z9.string().nullable()
|
|
341
516
|
});
|
|
342
517
|
|
|
343
518
|
// ../shared/src/report.ts
|
|
344
|
-
import { z as
|
|
345
|
-
var reportRequestSchema =
|
|
346
|
-
reason:
|
|
519
|
+
import { z as z10 } from "zod";
|
|
520
|
+
var reportRequestSchema = z10.object({
|
|
521
|
+
reason: z10.string().max(1e3).optional()
|
|
347
522
|
});
|
|
348
|
-
var reportResponseSchema =
|
|
349
|
-
reported:
|
|
523
|
+
var reportResponseSchema = z10.object({
|
|
524
|
+
reported: z10.literal(true)
|
|
350
525
|
});
|
|
351
526
|
|
|
352
527
|
// ../shared/src/stats.ts
|
|
353
|
-
import { z as
|
|
354
|
-
var avgViewSecondsSchema =
|
|
355
|
-
var versionViewStatsSchema =
|
|
528
|
+
import { z as z11 } from "zod";
|
|
529
|
+
var avgViewSecondsSchema = z11.number().int().nonnegative().nullable();
|
|
530
|
+
var versionViewStatsSchema = z11.object({
|
|
356
531
|
avgViewSeconds: avgViewSecondsSchema,
|
|
357
532
|
// Views from inside the review shell's iframe vs. direct visits to
|
|
358
533
|
// the render URL. views = embeddedViews + directViews.
|
|
359
|
-
directViews:
|
|
360
|
-
embeddedViews:
|
|
534
|
+
directViews: z11.number().int().nonnegative(),
|
|
535
|
+
embeddedViews: z11.number().int().nonnegative(),
|
|
361
536
|
// Distinct hashed viewer IPs across the version's lifetime.
|
|
362
|
-
uniqueViewers:
|
|
363
|
-
versionNumber:
|
|
364
|
-
views:
|
|
537
|
+
uniqueViewers: z11.number().int().nonnegative(),
|
|
538
|
+
versionNumber: z11.number().int().positive(),
|
|
539
|
+
views: z11.number().int().nonnegative()
|
|
365
540
|
});
|
|
366
|
-
var dailyViewsSchema =
|
|
541
|
+
var dailyViewsSchema = z11.object({
|
|
367
542
|
avgViewSeconds: avgViewSecondsSchema,
|
|
368
543
|
// UTC day, YYYY-MM-DD.
|
|
369
|
-
day:
|
|
370
|
-
uniqueViewers:
|
|
371
|
-
views:
|
|
544
|
+
day: z11.string(),
|
|
545
|
+
uniqueViewers: z11.number().int().nonnegative(),
|
|
546
|
+
views: z11.number().int().nonnegative()
|
|
372
547
|
});
|
|
373
|
-
var artifactStatsResponseSchema =
|
|
548
|
+
var artifactStatsResponseSchema = z11.object({
|
|
374
549
|
avgViewSeconds: avgViewSecondsSchema,
|
|
375
|
-
daily:
|
|
550
|
+
daily: z11.array(dailyViewsSchema),
|
|
376
551
|
// Distinct hashed viewer IPs across all versions and days.
|
|
377
|
-
totalUniqueViewers:
|
|
378
|
-
totalViews:
|
|
379
|
-
versions:
|
|
552
|
+
totalUniqueViewers: z11.number().int().nonnegative(),
|
|
553
|
+
totalViews: z11.number().int().nonnegative(),
|
|
554
|
+
versions: z11.array(versionViewStatsSchema)
|
|
380
555
|
});
|
|
381
556
|
|
|
382
557
|
// ../shared/src/versions.ts
|
|
383
|
-
import { z as
|
|
384
|
-
var versionSourceSchema =
|
|
385
|
-
agentName:
|
|
386
|
-
type:
|
|
558
|
+
import { z as z12 } from "zod";
|
|
559
|
+
var versionSourceSchema = z12.object({
|
|
560
|
+
agentName: z12.string().nullable(),
|
|
561
|
+
type: z12.string()
|
|
387
562
|
});
|
|
388
|
-
var versionChangesSchema =
|
|
389
|
-
added:
|
|
390
|
-
changed:
|
|
391
|
-
removed:
|
|
563
|
+
var versionChangesSchema = z12.object({
|
|
564
|
+
added: z12.array(z12.string()),
|
|
565
|
+
changed: z12.array(z12.string()),
|
|
566
|
+
removed: z12.array(z12.string())
|
|
392
567
|
});
|
|
393
|
-
var versionSummarySchema =
|
|
568
|
+
var versionSummarySchema = z12.object({
|
|
394
569
|
// Absent for the first version — there is no previous version to diff against.
|
|
395
570
|
changes: versionChangesSchema.nullable(),
|
|
396
|
-
createdAt:
|
|
397
|
-
entryUrl:
|
|
398
|
-
fileCount:
|
|
399
|
-
id:
|
|
400
|
-
isCurrent:
|
|
571
|
+
createdAt: z12.string(),
|
|
572
|
+
entryUrl: z12.string().url(),
|
|
573
|
+
fileCount: z12.number().int().nonnegative(),
|
|
574
|
+
id: z12.string(),
|
|
575
|
+
isCurrent: z12.boolean(),
|
|
401
576
|
source: versionSourceSchema,
|
|
402
|
-
totalSizeBytes:
|
|
403
|
-
versionNumber:
|
|
577
|
+
totalSizeBytes: z12.number().int().nonnegative(),
|
|
578
|
+
versionNumber: z12.number().int().positive()
|
|
404
579
|
});
|
|
405
|
-
var versionListResponseSchema =
|
|
406
|
-
versions:
|
|
580
|
+
var versionListResponseSchema = z12.object({
|
|
581
|
+
versions: z12.array(versionSummarySchema)
|
|
407
582
|
});
|
|
408
583
|
|
|
409
584
|
// src/api.ts
|
|
@@ -507,6 +682,20 @@ function createApiClient(apiUrl2, publishToken) {
|
|
|
507
682
|
(d) => artifactListResponseSchema.parse(d)
|
|
508
683
|
);
|
|
509
684
|
},
|
|
685
|
+
async listFolders(workspaceId) {
|
|
686
|
+
return request(
|
|
687
|
+
`${base}/api/v1/workspaces/${workspaceId}/folders`,
|
|
688
|
+
{ headers, method: "GET" },
|
|
689
|
+
(d) => folderListResponseSchema.parse(d)
|
|
690
|
+
);
|
|
691
|
+
},
|
|
692
|
+
async listWorkspaces() {
|
|
693
|
+
return request(
|
|
694
|
+
`${base}/api/v1/workspaces`,
|
|
695
|
+
{ headers, method: "GET" },
|
|
696
|
+
(d) => workspaceListResponseSchema.parse(d)
|
|
697
|
+
);
|
|
698
|
+
},
|
|
510
699
|
// SPEC §6.14 — who the presented credential belongs to. Used by
|
|
511
700
|
// `login` to verify a pasted key and by `whoami`.
|
|
512
701
|
async me() {
|
|
@@ -552,17 +741,17 @@ import {
|
|
|
552
741
|
writeFileSync as writeFileSync2
|
|
553
742
|
} from "fs";
|
|
554
743
|
import path2 from "path";
|
|
555
|
-
import { z as
|
|
744
|
+
import { z as z14 } from "zod";
|
|
556
745
|
|
|
557
746
|
// src/credentials.ts
|
|
558
747
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
559
748
|
import { homedir } from "os";
|
|
560
749
|
import path from "path";
|
|
561
|
-
import { z as
|
|
750
|
+
import { z as z13 } from "zod";
|
|
562
751
|
var DEFAULT_API_URL = "https://artifact.cafe";
|
|
563
|
-
var credentialsSchema =
|
|
564
|
-
keys:
|
|
565
|
-
version:
|
|
752
|
+
var credentialsSchema = z13.object({
|
|
753
|
+
keys: z13.record(z13.string(), z13.string()),
|
|
754
|
+
version: z13.literal(1)
|
|
566
755
|
});
|
|
567
756
|
function credentialsPath() {
|
|
568
757
|
return path.join(homedir(), ".artifactcafe", "credentials");
|
|
@@ -612,15 +801,19 @@ function resolveApiKey(apiUrl2, flag) {
|
|
|
612
801
|
}
|
|
613
802
|
|
|
614
803
|
// src/config.ts
|
|
615
|
-
var configSchema =
|
|
616
|
-
apiUrl:
|
|
617
|
-
artifactId:
|
|
804
|
+
var configSchema = z14.object({
|
|
805
|
+
apiUrl: z14.string(),
|
|
806
|
+
artifactId: z14.string(),
|
|
807
|
+
folder: z14.string().optional(),
|
|
808
|
+
folderId: z14.string().optional(),
|
|
618
809
|
// Optional: a folder linked by `link` to an artifact you own carries no
|
|
619
810
|
// token — owner actions authorize via your stored login instead. A first
|
|
620
811
|
// publish still writes the anonymous-mode token here.
|
|
621
|
-
publishToken:
|
|
622
|
-
slug:
|
|
623
|
-
url:
|
|
812
|
+
publishToken: z14.string().optional(),
|
|
813
|
+
slug: z14.string(),
|
|
814
|
+
url: z14.string(),
|
|
815
|
+
workspace: z14.string().optional(),
|
|
816
|
+
workspaceId: z14.string().optional()
|
|
624
817
|
});
|
|
625
818
|
var CONFIG_DIR = ".artifactcafe";
|
|
626
819
|
var CONFIG_FILE = "config.json";
|
|
@@ -1029,6 +1222,7 @@ async function publish(opts) {
|
|
|
1029
1222
|
const token = (artifactId !== null && artifactId === config?.artifactId ? config.publishToken : void 0) ?? process.env.ARTIFACT_CAFE_TOKEN;
|
|
1030
1223
|
const apiUrl2 = process.env.ARTIFACT_CAFE_URL ?? config?.apiUrl ?? DEFAULT_API_URL;
|
|
1031
1224
|
const apiKey = resolveApiKey(apiUrl2, opts.apiKey);
|
|
1225
|
+
const placement = await resolvePlacement({ apiKey, apiUrl: apiUrl2, config, opts });
|
|
1032
1226
|
const { files, skipped } = scanDirectory(dir);
|
|
1033
1227
|
if (files.length === 0) {
|
|
1034
1228
|
throw new Error(`Nothing to publish in ${dir} (after ignore rules).`);
|
|
@@ -1046,12 +1240,14 @@ async function publish(opts) {
|
|
|
1046
1240
|
artifactId,
|
|
1047
1241
|
entryPath,
|
|
1048
1242
|
files: files.map(({ absPath: _absPath, ...manifest }) => manifest),
|
|
1243
|
+
...placement.folderId ? { folderId: placement.folderId } : {},
|
|
1049
1244
|
source: {
|
|
1050
1245
|
agent: process.env.ARTIFACT_CAFE_AGENT,
|
|
1051
1246
|
runId: process.env.ARTIFACT_CAFE_RUN_ID,
|
|
1052
1247
|
type: "cli"
|
|
1053
1248
|
},
|
|
1054
|
-
title: opts.title
|
|
1249
|
+
title: opts.title,
|
|
1250
|
+
...placement.workspaceId ? { workspaceId: placement.workspaceId } : {}
|
|
1055
1251
|
};
|
|
1056
1252
|
let credential = apiKey ?? token;
|
|
1057
1253
|
let client = createApiClient(apiUrl2, credential);
|
|
@@ -1083,13 +1279,19 @@ async function publish(opts) {
|
|
|
1083
1279
|
);
|
|
1084
1280
|
});
|
|
1085
1281
|
const result = await client.finalize(session.publishSessionId);
|
|
1086
|
-
|
|
1282
|
+
const existingToken = config?.artifactId === result.artifactId ? config.publishToken : void 0;
|
|
1283
|
+
const shouldWriteConfig = result.publishToken !== void 0 || config?.artifactId === result.artifactId || opts.workspace !== void 0 || opts.folder !== void 0;
|
|
1284
|
+
if (shouldWriteConfig) {
|
|
1087
1285
|
writeConfig(dir, {
|
|
1088
1286
|
apiUrl: apiUrl2,
|
|
1089
1287
|
artifactId: result.artifactId,
|
|
1090
|
-
|
|
1288
|
+
...placement.folder ? { folder: placement.folder } : {},
|
|
1289
|
+
...placement.folderId ? { folderId: placement.folderId } : {},
|
|
1290
|
+
...result.publishToken ?? existingToken ? { publishToken: result.publishToken ?? existingToken } : {},
|
|
1091
1291
|
slug: slugFromUrl(result.url),
|
|
1092
|
-
url: result.url
|
|
1292
|
+
url: result.url,
|
|
1293
|
+
...placement.workspace ? { workspace: placement.workspace } : {},
|
|
1294
|
+
...placement.workspaceId ? { workspaceId: placement.workspaceId } : {}
|
|
1093
1295
|
});
|
|
1094
1296
|
}
|
|
1095
1297
|
if (opts.password !== void 0) {
|
|
@@ -1105,8 +1307,12 @@ async function publish(opts) {
|
|
|
1105
1307
|
{
|
|
1106
1308
|
artifactId: result.artifactId,
|
|
1107
1309
|
claimed: result.claimed,
|
|
1310
|
+
folder: placement.folder ?? null,
|
|
1311
|
+
folderId: placement.folderId ?? null,
|
|
1108
1312
|
url: result.url,
|
|
1109
1313
|
versionNumber: result.versionNumber,
|
|
1314
|
+
workspace: placement.workspace ?? null,
|
|
1315
|
+
workspaceId: placement.workspaceId ?? null,
|
|
1110
1316
|
...result.claimUrl ? { claimUrl: result.claimUrl } : {},
|
|
1111
1317
|
...opts.password === void 0 ? {} : { protected: true },
|
|
1112
1318
|
filesUploaded: session.filesToUpload.map((f) => f.path),
|
|
@@ -1148,6 +1354,76 @@ ${result.claimUrl}
|
|
|
1148
1354
|
openInBrowser(result.url);
|
|
1149
1355
|
}
|
|
1150
1356
|
}
|
|
1357
|
+
async function resolvePlacement(params) {
|
|
1358
|
+
const { apiKey, apiUrl: apiUrl2, config, opts } = params;
|
|
1359
|
+
const hasPlacementFlag = opts.workspace !== void 0 || opts.folder !== void 0;
|
|
1360
|
+
if (!hasPlacementFlag && config?.workspaceId) {
|
|
1361
|
+
if (!apiKey) {
|
|
1362
|
+
throw new Error(
|
|
1363
|
+
`Publishing into workspace ${config.workspace ?? config.workspaceId} needs an account \u2014 run \`artifact-cafe login\` first (no API key for ${apiOrigin(apiUrl2)}).`
|
|
1364
|
+
);
|
|
1365
|
+
}
|
|
1366
|
+
return {
|
|
1367
|
+
...config.folder ? { folder: config.folder } : {},
|
|
1368
|
+
...config.folderId ? { folderId: config.folderId } : {},
|
|
1369
|
+
...config.workspace ? { workspace: config.workspace } : {},
|
|
1370
|
+
workspaceId: config.workspaceId
|
|
1371
|
+
};
|
|
1372
|
+
}
|
|
1373
|
+
if (!hasPlacementFlag) {
|
|
1374
|
+
return {};
|
|
1375
|
+
}
|
|
1376
|
+
if (!apiKey) {
|
|
1377
|
+
throw new Error(
|
|
1378
|
+
"Publishing into a workspace needs an account \u2014 run `artifact-cafe login` first."
|
|
1379
|
+
);
|
|
1380
|
+
}
|
|
1381
|
+
const workspaceHandle = opts.workspace ?? config?.workspace;
|
|
1382
|
+
if (!workspaceHandle) {
|
|
1383
|
+
throw new Error("--folder requires --workspace or a stored workspace.");
|
|
1384
|
+
}
|
|
1385
|
+
const client = createApiClient(apiUrl2, apiKey);
|
|
1386
|
+
let workspaceId;
|
|
1387
|
+
if (opts.workspace === void 0 && config?.workspaceId) {
|
|
1388
|
+
({ workspaceId } = config);
|
|
1389
|
+
} else {
|
|
1390
|
+
const data2 = await client.listWorkspaces();
|
|
1391
|
+
const workspace = data2.workspaces.find(
|
|
1392
|
+
(candidate) => candidate.handle === workspaceHandle
|
|
1393
|
+
);
|
|
1394
|
+
if (!workspace) {
|
|
1395
|
+
throw new Error(
|
|
1396
|
+
`No workspace with handle "${workspaceHandle}" belongs to this account.`
|
|
1397
|
+
);
|
|
1398
|
+
}
|
|
1399
|
+
workspaceId = workspace.id;
|
|
1400
|
+
}
|
|
1401
|
+
const folderName = opts.workspace !== void 0 && opts.folder === void 0 ? void 0 : opts.folder ?? config?.folder;
|
|
1402
|
+
if (!folderName) {
|
|
1403
|
+
return { workspace: workspaceHandle, workspaceId };
|
|
1404
|
+
}
|
|
1405
|
+
const data = await client.listFolders(workspaceId);
|
|
1406
|
+
const matches = data.folders.filter(
|
|
1407
|
+
(candidate) => candidate.name === folderName || candidate.id === folderName
|
|
1408
|
+
);
|
|
1409
|
+
if (matches.length === 0) {
|
|
1410
|
+
throw new Error(
|
|
1411
|
+
`No folder named "${folderName}" exists in workspace ${workspaceHandle}.`
|
|
1412
|
+
);
|
|
1413
|
+
}
|
|
1414
|
+
if (matches.length > 1) {
|
|
1415
|
+
throw new Error(
|
|
1416
|
+
`More than one folder is named "${folderName}" in workspace ${workspaceHandle}; pass the folder id instead.`
|
|
1417
|
+
);
|
|
1418
|
+
}
|
|
1419
|
+
const folder = matches[0];
|
|
1420
|
+
return {
|
|
1421
|
+
folder: folder.name,
|
|
1422
|
+
folderId: folder.id,
|
|
1423
|
+
workspace: workspaceHandle,
|
|
1424
|
+
workspaceId
|
|
1425
|
+
};
|
|
1426
|
+
}
|
|
1151
1427
|
async function inBatches(items, concurrency, fn) {
|
|
1152
1428
|
let next = 0;
|
|
1153
1429
|
const workers = Array.from(
|
|
@@ -1221,6 +1497,52 @@ function printCliError(err, json) {
|
|
|
1221
1497
|
}
|
|
1222
1498
|
}
|
|
1223
1499
|
|
|
1500
|
+
// src/folders.ts
|
|
1501
|
+
async function folders(opts) {
|
|
1502
|
+
const apiUrl2 = (process.env.ARTIFACT_CAFE_URL ?? DEFAULT_API_URL).replace(
|
|
1503
|
+
/\/$/,
|
|
1504
|
+
""
|
|
1505
|
+
);
|
|
1506
|
+
const key = resolveApiKey(apiUrl2, opts.apiKey);
|
|
1507
|
+
if (!key) {
|
|
1508
|
+
throw new Error(
|
|
1509
|
+
`Listing folders needs an account \u2014 run \`artifact-cafe login\` first (no API key for ${apiOrigin(apiUrl2)}).`
|
|
1510
|
+
);
|
|
1511
|
+
}
|
|
1512
|
+
const client = createApiClient(apiUrl2, key);
|
|
1513
|
+
const workspaceData = await client.listWorkspaces();
|
|
1514
|
+
const workspace = workspaceData.workspaces.find(
|
|
1515
|
+
(candidate) => candidate.handle === opts.workspace
|
|
1516
|
+
);
|
|
1517
|
+
if (!workspace) {
|
|
1518
|
+
throw new Error(
|
|
1519
|
+
`No workspace with handle "${opts.workspace}" belongs to this account.`
|
|
1520
|
+
);
|
|
1521
|
+
}
|
|
1522
|
+
const data = await client.listFolders(workspace.id);
|
|
1523
|
+
if (opts.json) {
|
|
1524
|
+
console.log(JSON.stringify(data, null, 2));
|
|
1525
|
+
return;
|
|
1526
|
+
}
|
|
1527
|
+
if (data.folders.length === 0) {
|
|
1528
|
+
console.log(`No folders in workspace ${workspace.handle}.`);
|
|
1529
|
+
return;
|
|
1530
|
+
}
|
|
1531
|
+
const plural = data.folders.length === 1 ? "" : "s";
|
|
1532
|
+
console.log(
|
|
1533
|
+
`${data.folders.length} folder${plural} in ${workspace.handle}
|
|
1534
|
+
`
|
|
1535
|
+
);
|
|
1536
|
+
for (const folder of data.folders) {
|
|
1537
|
+
printFolder(folder);
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1540
|
+
function printFolder(folder) {
|
|
1541
|
+
console.log(`${folder.name} (${folder.visibility})`);
|
|
1542
|
+
console.log(` ${folder.id}
|
|
1543
|
+
`);
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1224
1546
|
// src/link.ts
|
|
1225
1547
|
import path7 from "path";
|
|
1226
1548
|
import { createInterface } from "readline";
|
|
@@ -1401,7 +1723,7 @@ function promptSecret(question) {
|
|
|
1401
1723
|
}
|
|
1402
1724
|
async function login(opts) {
|
|
1403
1725
|
const base = apiUrl();
|
|
1404
|
-
const keysUrl = `${base}/
|
|
1726
|
+
const keysUrl = `${base}/dashboard?view=api-keys`;
|
|
1405
1727
|
let key = opts.apiKey?.trim();
|
|
1406
1728
|
if (!key) {
|
|
1407
1729
|
if (!opts.json) {
|
|
@@ -1483,7 +1805,7 @@ function logout(opts) {
|
|
|
1483
1805
|
}
|
|
1484
1806
|
console.log(`\u2713 Logged out of ${apiOrigin(base)} on this machine.`);
|
|
1485
1807
|
console.log(
|
|
1486
|
-
`The key itself is still active \u2014 revoke it at ${base}/
|
|
1808
|
+
`The key itself is still active \u2014 revoke it at ${base}/dashboard?view=api-keys if this machine is shared.`
|
|
1487
1809
|
);
|
|
1488
1810
|
}
|
|
1489
1811
|
|
|
@@ -1549,6 +1871,40 @@ async function protect(opts) {
|
|
|
1549
1871
|
);
|
|
1550
1872
|
}
|
|
1551
1873
|
|
|
1874
|
+
// src/workspaces.ts
|
|
1875
|
+
async function workspaces(opts) {
|
|
1876
|
+
const apiUrl2 = (process.env.ARTIFACT_CAFE_URL ?? DEFAULT_API_URL).replace(
|
|
1877
|
+
/\/$/,
|
|
1878
|
+
""
|
|
1879
|
+
);
|
|
1880
|
+
const key = resolveApiKey(apiUrl2, opts.apiKey);
|
|
1881
|
+
if (!key) {
|
|
1882
|
+
throw new Error(
|
|
1883
|
+
`Listing workspaces needs an account \u2014 run \`artifact-cafe login\` first (no API key for ${apiOrigin(apiUrl2)}).`
|
|
1884
|
+
);
|
|
1885
|
+
}
|
|
1886
|
+
const data = await createApiClient(apiUrl2, key).listWorkspaces();
|
|
1887
|
+
if (opts.json) {
|
|
1888
|
+
console.log(JSON.stringify(data, null, 2));
|
|
1889
|
+
return;
|
|
1890
|
+
}
|
|
1891
|
+
if (data.workspaces.length === 0) {
|
|
1892
|
+
console.log("No workspaces yet \u2014 create one from the dashboard.");
|
|
1893
|
+
return;
|
|
1894
|
+
}
|
|
1895
|
+
const plural = data.workspaces.length === 1 ? "" : "s";
|
|
1896
|
+
console.log(`${data.workspaces.length} workspace${plural}
|
|
1897
|
+
`);
|
|
1898
|
+
for (const workspace of data.workspaces) {
|
|
1899
|
+
printWorkspace(workspace);
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
function printWorkspace(workspace) {
|
|
1903
|
+
console.log(`${workspace.name} (${workspace.role ?? "non-member"})`);
|
|
1904
|
+
console.log(` ${workspace.handle} \xB7 ${workspace.id}
|
|
1905
|
+
`);
|
|
1906
|
+
}
|
|
1907
|
+
|
|
1552
1908
|
// src/index.ts
|
|
1553
1909
|
var publish2 = defineCommand({
|
|
1554
1910
|
args: {
|
|
@@ -1566,13 +1922,21 @@ var publish2 = defineCommand({
|
|
|
1566
1922
|
type: "positional"
|
|
1567
1923
|
},
|
|
1568
1924
|
entry: { description: "Entry file (default: auto-detect)", type: "string" },
|
|
1925
|
+
folder: {
|
|
1926
|
+
description: "Publish into this workspace folder name (or id)",
|
|
1927
|
+
type: "string"
|
|
1928
|
+
},
|
|
1569
1929
|
json: { description: "Machine-readable output", type: "boolean" },
|
|
1570
1930
|
"no-open": { description: "Don't open the review URL", type: "boolean" },
|
|
1571
1931
|
password: {
|
|
1572
1932
|
description: "Password-protect the artifact (min 6 chars)",
|
|
1573
1933
|
type: "string"
|
|
1574
1934
|
},
|
|
1575
|
-
title: { description: "Artifact title", type: "string" }
|
|
1935
|
+
title: { description: "Artifact title", type: "string" },
|
|
1936
|
+
workspace: {
|
|
1937
|
+
description: "Publish into this workspace handle",
|
|
1938
|
+
type: "string"
|
|
1939
|
+
}
|
|
1576
1940
|
},
|
|
1577
1941
|
meta: { description: "Publish a folder as an artifact", name: "publish" },
|
|
1578
1942
|
async run({ args }) {
|
|
@@ -1582,10 +1946,12 @@ var publish2 = defineCommand({
|
|
|
1582
1946
|
artifact: args.artifact,
|
|
1583
1947
|
dir: args.dir,
|
|
1584
1948
|
entry: args.entry,
|
|
1949
|
+
folder: args.folder,
|
|
1585
1950
|
json: Boolean(args.json),
|
|
1586
1951
|
open: !args["no-open"],
|
|
1587
1952
|
password: args.password,
|
|
1588
|
-
title: args.title
|
|
1953
|
+
title: args.title,
|
|
1954
|
+
workspace: args.workspace
|
|
1589
1955
|
});
|
|
1590
1956
|
} catch (err) {
|
|
1591
1957
|
printCliError(err, Boolean(args.json));
|
|
@@ -1669,6 +2035,60 @@ var list2 = defineCommand({
|
|
|
1669
2035
|
}
|
|
1670
2036
|
}
|
|
1671
2037
|
});
|
|
2038
|
+
var folders2 = defineCommand({
|
|
2039
|
+
args: {
|
|
2040
|
+
"api-key": {
|
|
2041
|
+
description: "List with this API key (default: stored login)",
|
|
2042
|
+
type: "string"
|
|
2043
|
+
},
|
|
2044
|
+
json: { description: "Machine-readable output", type: "boolean" },
|
|
2045
|
+
workspace: {
|
|
2046
|
+
description: "Workspace handle whose folders to list",
|
|
2047
|
+
required: true,
|
|
2048
|
+
type: "string"
|
|
2049
|
+
}
|
|
2050
|
+
},
|
|
2051
|
+
meta: {
|
|
2052
|
+
description: "List folders in a workspace",
|
|
2053
|
+
name: "folders"
|
|
2054
|
+
},
|
|
2055
|
+
async run({ args }) {
|
|
2056
|
+
try {
|
|
2057
|
+
await folders({
|
|
2058
|
+
apiKey: args["api-key"],
|
|
2059
|
+
json: Boolean(args.json),
|
|
2060
|
+
workspace: args.workspace
|
|
2061
|
+
});
|
|
2062
|
+
} catch (err) {
|
|
2063
|
+
printCliError(err, Boolean(args.json));
|
|
2064
|
+
process.exit(1);
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2067
|
+
});
|
|
2068
|
+
var workspaces2 = defineCommand({
|
|
2069
|
+
args: {
|
|
2070
|
+
"api-key": {
|
|
2071
|
+
description: "List with this API key (default: stored login)",
|
|
2072
|
+
type: "string"
|
|
2073
|
+
},
|
|
2074
|
+
json: { description: "Machine-readable output", type: "boolean" }
|
|
2075
|
+
},
|
|
2076
|
+
meta: {
|
|
2077
|
+
description: "List the workspaces your account belongs to",
|
|
2078
|
+
name: "workspaces"
|
|
2079
|
+
},
|
|
2080
|
+
async run({ args }) {
|
|
2081
|
+
try {
|
|
2082
|
+
await workspaces({
|
|
2083
|
+
apiKey: args["api-key"],
|
|
2084
|
+
json: Boolean(args.json)
|
|
2085
|
+
});
|
|
2086
|
+
} catch (err) {
|
|
2087
|
+
printCliError(err, Boolean(args.json));
|
|
2088
|
+
process.exit(1);
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
});
|
|
1672
2092
|
var link2 = defineCommand({
|
|
1673
2093
|
args: {
|
|
1674
2094
|
"api-key": {
|
|
@@ -1773,6 +2193,66 @@ var comments2 = defineCommand({
|
|
|
1773
2193
|
}
|
|
1774
2194
|
}
|
|
1775
2195
|
});
|
|
2196
|
+
var listen = defineCommand({
|
|
2197
|
+
args: {
|
|
2198
|
+
"api-key": {
|
|
2199
|
+
description: "Authorize with an account API key (default: stored login)",
|
|
2200
|
+
type: "string"
|
|
2201
|
+
},
|
|
2202
|
+
artifact: {
|
|
2203
|
+
description: "Act on an artifact ID instead of the linked folder",
|
|
2204
|
+
type: "string"
|
|
2205
|
+
},
|
|
2206
|
+
dir: {
|
|
2207
|
+
default: ".",
|
|
2208
|
+
description: "Published directory",
|
|
2209
|
+
type: "positional"
|
|
2210
|
+
},
|
|
2211
|
+
json: { description: "Machine-readable output", type: "boolean" },
|
|
2212
|
+
status: {
|
|
2213
|
+
default: "open",
|
|
2214
|
+
description: "Filter: open | resolved | all",
|
|
2215
|
+
type: "string"
|
|
2216
|
+
},
|
|
2217
|
+
timeout: {
|
|
2218
|
+
default: "900",
|
|
2219
|
+
description: "Give up after this many seconds (exit 2)",
|
|
2220
|
+
type: "string"
|
|
2221
|
+
},
|
|
2222
|
+
version: {
|
|
2223
|
+
default: "current",
|
|
2224
|
+
description: "Filter: current | all",
|
|
2225
|
+
type: "string"
|
|
2226
|
+
}
|
|
2227
|
+
},
|
|
2228
|
+
meta: {
|
|
2229
|
+
description: "Wait for new reviewer feedback (alias for comments --wait)",
|
|
2230
|
+
name: "listen"
|
|
2231
|
+
},
|
|
2232
|
+
async run({ args }) {
|
|
2233
|
+
try {
|
|
2234
|
+
const timeout = Number(args.timeout);
|
|
2235
|
+
if (!Number.isFinite(timeout) || timeout <= 0) {
|
|
2236
|
+
throw new Error(
|
|
2237
|
+
`--timeout must be a positive number of seconds (got "${args.timeout}").`
|
|
2238
|
+
);
|
|
2239
|
+
}
|
|
2240
|
+
await comments({
|
|
2241
|
+
apiKey: args["api-key"],
|
|
2242
|
+
artifact: args.artifact,
|
|
2243
|
+
dir: args.dir,
|
|
2244
|
+
json: Boolean(args.json),
|
|
2245
|
+
status: args.status,
|
|
2246
|
+
timeout,
|
|
2247
|
+
version: args.version,
|
|
2248
|
+
wait: true
|
|
2249
|
+
});
|
|
2250
|
+
} catch (err) {
|
|
2251
|
+
printCliError(err, Boolean(args.json));
|
|
2252
|
+
process.exit(1);
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
});
|
|
1776
2256
|
var protect2 = defineCommand({
|
|
1777
2257
|
args: {
|
|
1778
2258
|
"api-key": {
|
|
@@ -1882,14 +2362,17 @@ var main = defineCommand({
|
|
|
1882
2362
|
subCommands: {
|
|
1883
2363
|
comments: comments2,
|
|
1884
2364
|
dashboard,
|
|
2365
|
+
folders: folders2,
|
|
1885
2366
|
link: link2,
|
|
1886
2367
|
list: list2,
|
|
2368
|
+
listen,
|
|
1887
2369
|
login: login2,
|
|
1888
2370
|
logout: logout2,
|
|
1889
2371
|
open,
|
|
1890
2372
|
protect: protect2,
|
|
1891
2373
|
publish: publish2,
|
|
1892
|
-
whoami: whoami2
|
|
2374
|
+
whoami: whoami2,
|
|
2375
|
+
workspaces: workspaces2
|
|
1893
2376
|
}
|
|
1894
2377
|
});
|
|
1895
2378
|
runMain(main);
|