@domino-sdk/relay-cli 0.1.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/dist/index.js ADDED
@@ -0,0 +1,428 @@
1
+ // src/index.ts
2
+ import {
3
+ projectDeploymentSchema,
4
+ deploymentPreviewSchema,
5
+ publishDeploymentSchema,
6
+ deploymentResultSchema,
7
+ catalogDeploymentPreviewSchema,
8
+ questCatalogSchema,
9
+ questDraftSchema,
10
+ questPublicationPreviewSchema,
11
+ catalogDeploymentSchema,
12
+ saveQuestDraftSchema,
13
+ publishQuestDraftSchema
14
+ } from "@domino-sdk/relay";
15
+ import { z as z2 } from "zod";
16
+
17
+ // src/hosting.ts
18
+ import { z } from "zod";
19
+ import { identifier } from "@domino-sdk/relay";
20
+ var repositorySchema = z.object({
21
+ id: z.string().uuid(),
22
+ organization: identifier,
23
+ project: identifier,
24
+ remote: z.string().url(),
25
+ defaultBranch: z.string(),
26
+ status: z.enum(["provisioning", "ready"])
27
+ });
28
+ var createRepositorySchema = z.object({
29
+ starter: z.literal("campaign").default("campaign")
30
+ }).strict();
31
+ var deviceStartSchema = z.object({
32
+ challenge: z.string().regex(/^[a-f0-9]{64}$/)
33
+ }).strict();
34
+ var deviceRedeemSchema = z.object({
35
+ id: z.string().uuid(),
36
+ verifier: z.string().min(43).max(128)
37
+ }).strict();
38
+ var deviceApproveSchema = z.object({
39
+ id: z.string().uuid(),
40
+ code: z.string().regex(/^[A-F0-9]{4}-[A-F0-9]{4}$/)
41
+ }).strict();
42
+ var commitSchema = z.string().regex(/^[a-f0-9]{40}$/);
43
+ var stageRequestSchema = z.object({
44
+ commit: commitSchema,
45
+ requestId: z.string().uuid()
46
+ }).strict();
47
+ var buildIdentitySchema = z.object({
48
+ id: z.string().uuid(),
49
+ repository: z.string().uuid(),
50
+ organization: identifier,
51
+ project: identifier,
52
+ commit: commitSchema,
53
+ createdAt: z.number(),
54
+ actor: z.string()
55
+ });
56
+ var buildPhaseSchema = z.enum([
57
+ "queued",
58
+ "source",
59
+ "install",
60
+ "check",
61
+ "build",
62
+ "deploy",
63
+ "ready",
64
+ "failed"
65
+ ]);
66
+ var buildStatusSchema = z.object({
67
+ phase: buildPhaseSchema,
68
+ updatedAt: z.number(),
69
+ message: z.string()
70
+ });
71
+ var assetPathSchema = z.string().max(512).refine(
72
+ (path) => path.startsWith("/") && !/[\\\u0000-\u001f?#%]/.test(path) && path.slice(1).split("/").every((part) => part.length > 0 && !part.startsWith(".")) && !path.startsWith("/relay/") && !path.startsWith("/__domino/"),
73
+ "Expected a public asset path without hidden or reserved segments"
74
+ );
75
+ var buildArtifactsSchema = z.object({
76
+ format: z.literal(1),
77
+ assets: z.array(
78
+ z.object({
79
+ path: assetPathSchema,
80
+ content: z.string().max(14e6).regex(
81
+ /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/
82
+ ),
83
+ size: z.number().int().min(0).max(1e7)
84
+ }).strict()
85
+ ).min(1).max(500),
86
+ quests: z.unknown(),
87
+ catalog: z.unknown()
88
+ }).strict().superRefine((value, ctx) => {
89
+ if (new Set(value.assets.map((a) => a.path)).size !== value.assets.length)
90
+ ctx.addIssue({ code: "custom", message: "Duplicate asset paths" });
91
+ if (!value.assets.some((a) => a.path === "/index.html"))
92
+ ctx.addIssue({
93
+ code: "custom",
94
+ message: "Build must include index.html"
95
+ });
96
+ if (value.assets.reduce((sum, a) => sum + a.size, 0) > 1e7)
97
+ ctx.addIssue({ code: "custom", message: "Staging assets exceed 10 MB" });
98
+ });
99
+
100
+ // src/index.ts
101
+ import {
102
+ walletConnectionSchema,
103
+ solanaBalanceSchema,
104
+ collectionPreviewSchema,
105
+ collectionBeginSchema,
106
+ collectionResolveSchema,
107
+ pickupCatalogSchema,
108
+ pickupAvailabilitySchema,
109
+ configurePickupSchema,
110
+ entitlementSchema,
111
+ identifier as identifier2,
112
+ snapshotSchema,
113
+ memberProgressSchema
114
+ } from "@domino-sdk/relay";
115
+ var environmentSchema = z2.enum(["test", "live"]);
116
+ var roleSchema = z2.enum(["editor", "reviewer", "staff"]);
117
+ var permissionSchema = z2.enum([
118
+ "read",
119
+ "publish",
120
+ "review",
121
+ "confirm",
122
+ "handover",
123
+ "inventory",
124
+ "access"
125
+ ]);
126
+ var rolePermissions = {
127
+ editor: ["read", "publish", "inventory"],
128
+ reviewer: ["read", "review"],
129
+ staff: ["read", "confirm", "handover"]
130
+ };
131
+ var projectSchema = z2.object({
132
+ id: z2.string().min(1),
133
+ organization: identifier2,
134
+ project: identifier2,
135
+ name: z2.string(),
136
+ subtitle: z2.string(),
137
+ initials: z2.string(),
138
+ color: z2.string(),
139
+ permissions: z2.array(permissionSchema),
140
+ environments: z2.array(environmentSchema)
141
+ });
142
+ var projectInputSchema = z2.object({ project: identifier2, name: z2.string().trim().min(1).max(80) }).strict();
143
+ var grantSchema = z2.object({
144
+ subject: z2.string().min(1).max(200),
145
+ roles: z2.array(roleSchema),
146
+ environments: z2.array(environmentSchema)
147
+ }).strict();
148
+ var accessSchema = z2.object({
149
+ actor: z2.string(),
150
+ organization: z2.string(),
151
+ admin: z2.boolean(),
152
+ local: z2.boolean(),
153
+ projects: z2.array(projectSchema)
154
+ });
155
+ var querySchema = z2.object({
156
+ q: z2.string().max(200).default(""),
157
+ filter: z2.string().max(50).default("all"),
158
+ offset: z2.coerce.number().int().min(0).max(1e6).default(0),
159
+ limit: z2.coerce.number().int().min(1).max(100).default(25)
160
+ });
161
+ var accountProfileSchema = z2.object({
162
+ name: z2.string().optional(),
163
+ email: z2.string().optional(),
164
+ emailVerified: z2.boolean().default(false),
165
+ imageUrl: z2.string().url().optional()
166
+ });
167
+ var memberAccountSchema = z2.object({
168
+ provider: z2.string(),
169
+ subject: z2.string(),
170
+ signInEnabled: z2.boolean(),
171
+ profile: accountProfileSchema.optional()
172
+ });
173
+ var operationSchema = z2.object({
174
+ target: z2.string(),
175
+ paused: z2.boolean(),
176
+ revision: z2.number().int(),
177
+ reason: z2.string(),
178
+ actor: z2.string().nullable(),
179
+ changedAt: z2.number()
180
+ });
181
+ var operationInputSchema = z2.object({
182
+ target: z2.union([
183
+ z2.literal("redemptions"),
184
+ z2.string().regex(/^quest:[\w-]+$/)
185
+ ]),
186
+ paused: z2.boolean(),
187
+ revision: z2.number().int().nonnegative(),
188
+ reason: z2.string().trim().min(1).max(500),
189
+ actionId: identifier2
190
+ }).strict();
191
+ var memberSchema = z2.object({
192
+ id: z2.string(),
193
+ accounts: z2.array(memberAccountSchema).default([]),
194
+ attempts: z2.number(),
195
+ completions: z2.number(),
196
+ rewards: z2.number(),
197
+ lastActivity: z2.number().nullable()
198
+ });
199
+ var metricsSchema = z2.object({
200
+ quests: z2.number(),
201
+ members: z2.number(),
202
+ attempts: z2.number(),
203
+ completions: z2.number(),
204
+ review: z2.number(),
205
+ failed: z2.number(),
206
+ entitlements: z2.number()
207
+ });
208
+ var readinessSchema = z2.object({
209
+ checks: z2.array(
210
+ z2.object({
211
+ id: z2.string(),
212
+ status: z2.enum(["ready", "blocked"]),
213
+ title: z2.string(),
214
+ detail: z2.string()
215
+ })
216
+ )
217
+ });
218
+ var inventorySchema = z2.object({
219
+ item: z2.string(),
220
+ available: z2.number(),
221
+ reserved: z2.number(),
222
+ allocated: z2.number().default(0)
223
+ });
224
+ var auditRecordSchema = z2.object({
225
+ id: z2.string(),
226
+ action: z2.string(),
227
+ actor: z2.string().nullable(),
228
+ detail: z2.string(),
229
+ at: z2.number(),
230
+ attempt: z2.string().nullable()
231
+ });
232
+ var pageSchema = z2.object({
233
+ snapshot: snapshotSchema,
234
+ members: z2.array(memberSchema),
235
+ metrics: metricsSchema,
236
+ total: z2.number(),
237
+ offset: z2.number(),
238
+ limit: z2.number(),
239
+ inventory: z2.array(inventorySchema),
240
+ operations: z2.array(operationSchema).default([]),
241
+ audit: z2.array(auditRecordSchema).default([]),
242
+ questCounts: z2.record(z2.string(), z2.number())
243
+ });
244
+ var memberDetailSchema = z2.object({
245
+ snapshot: snapshotSchema,
246
+ member: memberSchema,
247
+ progress: memberProgressSchema,
248
+ passes: z2.array(
249
+ z2.object({
250
+ provider: z2.string(),
251
+ event: z2.string(),
252
+ subject: z2.string(),
253
+ attempt: identifier2.nullable()
254
+ })
255
+ ).default([]),
256
+ wallet: z2.object({
257
+ connection: walletConnectionSchema.nullable(),
258
+ observation: z2.object({ attempt: identifier2, balance: solanaBalanceSchema }).nullable()
259
+ }).default({ connection: null, observation: null })
260
+ });
261
+ var stockInputSchema = z2.object({
262
+ item: identifier2,
263
+ quantity: z2.number().int().positive().max(1e6),
264
+ actionId: identifier2
265
+ }).strict();
266
+ var tokenInputSchema = z2.object({
267
+ name: z2.string().trim().min(1).max(80),
268
+ project: identifier2,
269
+ environment: environmentSchema,
270
+ permissions: z2.array(permissionSchema).min(1),
271
+ days: z2.number().int().min(1).max(90).default(30)
272
+ }).strict();
273
+ var tokenSchema = z2.object({
274
+ id: z2.string(),
275
+ name: z2.string(),
276
+ project: z2.string(),
277
+ environment: environmentSchema,
278
+ permissions: z2.array(permissionSchema),
279
+ expiresAt: z2.number()
280
+ });
281
+ function createManagementClient(options) {
282
+ async function raw(path, init) {
283
+ const headers = new Headers(init?.headers);
284
+ const token = await options.getToken?.();
285
+ if (token) headers.set("Authorization", `Bearer ${token}`);
286
+ if (options.organization)
287
+ headers.set("X-Relay-Organization", options.organization);
288
+ if (options.project) headers.set("X-Relay-Project", options.project);
289
+ if (options.environment)
290
+ headers.set("X-Relay-Environment", options.environment);
291
+ const response = await fetch(`${options.baseUrl}/management/v1${path}`, {
292
+ ...init,
293
+ headers
294
+ });
295
+ if (!response.ok) {
296
+ const error = z2.object({ error: z2.string() }).safeParse(await response.json().catch(() => null));
297
+ throw new Error(
298
+ error.success ? error.data.error : `Request failed (${response.status})`
299
+ );
300
+ }
301
+ return response;
302
+ }
303
+ async function request(path, schema, input, method = "POST") {
304
+ const response = await raw(
305
+ path,
306
+ input === void 0 ? void 0 : {
307
+ method,
308
+ headers: { "Content-Type": "application/json" },
309
+ body: JSON.stringify(input)
310
+ }
311
+ );
312
+ return schema.parse(await response.json());
313
+ }
314
+ return {
315
+ raw,
316
+ request,
317
+ deployments: {
318
+ preview: (input) => request(
319
+ "/deployments/preview",
320
+ deploymentPreviewSchema,
321
+ projectDeploymentSchema.parse(input)
322
+ ),
323
+ publish: (input) => request(
324
+ "/deployments/publish",
325
+ deploymentResultSchema,
326
+ publishDeploymentSchema.parse(input)
327
+ )
328
+ },
329
+ catalog: {
330
+ read: () => request("/catalog", questCatalogSchema),
331
+ previewDeployment: (input) => request(
332
+ "/catalog/deploy/preview",
333
+ catalogDeploymentPreviewSchema,
334
+ catalogDeploymentSchema.parse(input)
335
+ ),
336
+ deploy: (input) => request(
337
+ "/catalog/deploy",
338
+ questCatalogSchema,
339
+ catalogDeploymentSchema.parse(input)
340
+ ),
341
+ saveDraft: (input) => request(
342
+ "/catalog/drafts",
343
+ questDraftSchema,
344
+ saveQuestDraftSchema.parse(input)
345
+ ),
346
+ preview: (input) => request(
347
+ "/catalog/preview",
348
+ questPublicationPreviewSchema,
349
+ publishQuestDraftSchema.parse(input)
350
+ ),
351
+ publish: (input) => request(
352
+ "/catalog/publish",
353
+ questPublicationPreviewSchema,
354
+ publishQuestDraftSchema.parse(input)
355
+ )
356
+ },
357
+ collection: {
358
+ resolve: (code) => request(
359
+ "/collection/resolve",
360
+ collectionPreviewSchema,
361
+ collectionResolveSchema.parse({ code })
362
+ ),
363
+ begin: (input) => request(
364
+ "/collection/begin",
365
+ entitlementSchema,
366
+ collectionBeginSchema.parse(input)
367
+ )
368
+ },
369
+ inventory: {
370
+ catalog: () => request("/pickup-inventory", z2.array(pickupCatalogSchema)),
371
+ configure: (input) => request(
372
+ "/pickup-inventory",
373
+ pickupCatalogSchema,
374
+ configurePickupSchema.parse(input)
375
+ ),
376
+ availability: (entitlement) => request(
377
+ `/pickup-inventory/${encodeURIComponent(entitlement)}`,
378
+ pickupAvailabilitySchema
379
+ )
380
+ },
381
+ readiness: () => request("/readiness", readinessSchema),
382
+ access: () => request("/access", accessSchema),
383
+ createProject: (input) => request("/projects", projectSchema, input),
384
+ page: (page, query) => request(
385
+ `/${page}?${new URLSearchParams(Object.entries(query).map(([k, v]) => [k, String(v)]))}`,
386
+ pageSchema
387
+ ),
388
+ member: (id) => request(`/members/${encodeURIComponent(id)}`, memberDetailSchema)
389
+ };
390
+ }
391
+ export {
392
+ accessSchema,
393
+ accountProfileSchema,
394
+ assetPathSchema,
395
+ auditRecordSchema,
396
+ buildArtifactsSchema,
397
+ buildIdentitySchema,
398
+ buildPhaseSchema,
399
+ buildStatusSchema,
400
+ commitSchema,
401
+ createManagementClient,
402
+ createRepositorySchema,
403
+ deviceApproveSchema,
404
+ deviceRedeemSchema,
405
+ deviceStartSchema,
406
+ environmentSchema,
407
+ grantSchema,
408
+ inventorySchema,
409
+ memberAccountSchema,
410
+ memberDetailSchema,
411
+ memberSchema,
412
+ metricsSchema,
413
+ operationInputSchema,
414
+ operationSchema,
415
+ pageSchema,
416
+ permissionSchema,
417
+ projectInputSchema,
418
+ projectSchema,
419
+ querySchema,
420
+ readinessSchema,
421
+ repositorySchema,
422
+ rolePermissions,
423
+ roleSchema,
424
+ stageRequestSchema,
425
+ stockInputSchema,
426
+ tokenInputSchema,
427
+ tokenSchema
428
+ };
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@domino-sdk/relay-cli",
3
+ "type": "module",
4
+ "exports": {
5
+ ".": {
6
+ "types": "./dist/index.d.ts",
7
+ "default": "./dist/index.js"
8
+ }
9
+ },
10
+ "dependencies": {
11
+ "commander": "15.0.0",
12
+ "zod": "4.3.6",
13
+ "@domino-sdk/relay": "0.1.0"
14
+ },
15
+ "version": "0.1.0",
16
+ "bin": {
17
+ "domino": "./cli.mjs"
18
+ },
19
+ "license": "UNLICENSED",
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+https://github.com/GetDomino/relay.git",
23
+ "directory": "packages/management"
24
+ },
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "engines": {
29
+ "node": ">=24 <25"
30
+ },
31
+ "files": [
32
+ "dist",
33
+ "cli",
34
+ "cli.mjs"
35
+ ],
36
+ "description": "Domino CLI and agent skills for Relay projects",
37
+ "scripts": {
38
+ "typecheck": "tsc --noEmit",
39
+ "build": "tsup src/index.ts --format esm --dts --clean"
40
+ }
41
+ }