@clickraft/cli 0.1.8 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -3
- package/README.md +7 -0
- package/dist/cli.js +598 -123
- package/dist/cli.js.map +1 -1
- package/dist/index.js +598 -123
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -170,6 +170,12 @@ var EXIT_CODE_MAP = {
|
|
|
170
170
|
retryable: false,
|
|
171
171
|
hint: "Resource not found."
|
|
172
172
|
},
|
|
173
|
+
FEATURE_DISABLED: {
|
|
174
|
+
exitCode: 2,
|
|
175
|
+
category: "usage",
|
|
176
|
+
retryable: false,
|
|
177
|
+
hint: "This endpoint is not enabled. Contact support if you believe this is in error."
|
|
178
|
+
},
|
|
173
179
|
FORBIDDEN: {
|
|
174
180
|
exitCode: 4,
|
|
175
181
|
category: "permission",
|
|
@@ -715,6 +721,10 @@ function buildUrl(baseUrl, path, query) {
|
|
|
715
721
|
if (query) {
|
|
716
722
|
for (const [key, value] of Object.entries(query)) {
|
|
717
723
|
if (value === void 0) continue;
|
|
724
|
+
if (Array.isArray(value)) {
|
|
725
|
+
for (const item of value) url.searchParams.append(key, item);
|
|
726
|
+
continue;
|
|
727
|
+
}
|
|
718
728
|
url.searchParams.append(key, String(value));
|
|
719
729
|
}
|
|
720
730
|
}
|
|
@@ -848,65 +858,8 @@ function buildPayload(args) {
|
|
|
848
858
|
return payload;
|
|
849
859
|
}
|
|
850
860
|
|
|
851
|
-
// src/
|
|
852
|
-
import { z as
|
|
853
|
-
var GenerateCreateRequestSchema = z3.object({
|
|
854
|
-
modelSlug: z3.string().min(1).max(100),
|
|
855
|
-
input: z3.object({
|
|
856
|
-
prompt: z3.string().max(1e4).optional(),
|
|
857
|
-
referenceImageUrl: z3.string().url().optional(),
|
|
858
|
-
referenceImages: z3.array(z3.string().url()).max(8).optional(),
|
|
859
|
-
aspectRatio: z3.string().regex(/^\d+:\d+$/).optional(),
|
|
860
|
-
resolution: z3.string().regex(/^\d+x\d+$/).optional(),
|
|
861
|
-
durationSeconds: z3.number().int().min(1).max(60).optional(),
|
|
862
|
-
providerParams: z3.record(z3.string(), z3.unknown()).optional()
|
|
863
|
-
}).strict(),
|
|
864
|
-
options: z3.object({
|
|
865
|
-
workflowId: z3.string().uuid().optional(),
|
|
866
|
-
nodeId: z3.string().optional()
|
|
867
|
-
}).strict().optional()
|
|
868
|
-
}).strict();
|
|
869
|
-
var GenerateCreateResponseSchema = z3.object({
|
|
870
|
-
jobId: z3.string().uuid(),
|
|
871
|
-
status: z3.enum(["queued", "processing", "completed", "failed"]),
|
|
872
|
-
estimatedSeconds: z3.number().int().nonnegative().nullable(),
|
|
873
|
-
creditsCharged: z3.number().int().nonnegative()
|
|
874
|
-
}).strict();
|
|
875
|
-
var GenerationStatusSchema = z3.enum([
|
|
876
|
-
"queued",
|
|
877
|
-
"processing",
|
|
878
|
-
"uploading",
|
|
879
|
-
"completed",
|
|
880
|
-
"failed",
|
|
881
|
-
"cancelled"
|
|
882
|
-
]);
|
|
883
|
-
var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
884
|
-
"completed",
|
|
885
|
-
"failed",
|
|
886
|
-
"cancelled"
|
|
887
|
-
]);
|
|
888
|
-
function isTerminalStatus(status) {
|
|
889
|
-
return TERMINAL_STATUSES.has(status);
|
|
890
|
-
}
|
|
891
|
-
var GenerationResultSchema = z3.object({
|
|
892
|
-
jobId: z3.string().uuid(),
|
|
893
|
-
status: GenerationStatusSchema,
|
|
894
|
-
modelSlug: z3.string(),
|
|
895
|
-
resultUrl: z3.string().url().nullable(),
|
|
896
|
-
thumbnailUrl: z3.string().url().nullable(),
|
|
897
|
-
errorCode: z3.string().nullable(),
|
|
898
|
-
errorMessage: z3.string().nullable(),
|
|
899
|
-
creditsCharged: z3.number().int().nonnegative(),
|
|
900
|
-
creditsRefunded: z3.boolean(),
|
|
901
|
-
startedAt: z3.string().nullable(),
|
|
902
|
-
completedAt: z3.string().nullable()
|
|
903
|
-
}).strict();
|
|
904
|
-
|
|
905
|
-
// src/commands/upload.ts
|
|
906
|
-
import { createHash as createHash2 } from "crypto";
|
|
907
|
-
import { readFile as readFile2, stat as stat2 } from "fs/promises";
|
|
908
|
-
import { basename } from "path";
|
|
909
|
-
import { request as undiciRequest2 } from "undici";
|
|
861
|
+
// src/commands/balance.ts
|
|
862
|
+
import { z as z4 } from "zod";
|
|
910
863
|
|
|
911
864
|
// src/auth/credentials.ts
|
|
912
865
|
import {
|
|
@@ -950,31 +903,31 @@ function getCredentialsPath(ctx = {}) {
|
|
|
950
903
|
}
|
|
951
904
|
|
|
952
905
|
// src/auth/types.ts
|
|
953
|
-
import { z as
|
|
954
|
-
var DeviceAuthorizationRequestSchema =
|
|
955
|
-
client_id:
|
|
956
|
-
scope:
|
|
906
|
+
import { z as z3 } from "zod";
|
|
907
|
+
var DeviceAuthorizationRequestSchema = z3.object({
|
|
908
|
+
client_id: z3.string(),
|
|
909
|
+
scope: z3.string()
|
|
957
910
|
});
|
|
958
|
-
var DeviceAuthorizationResponseSchema =
|
|
959
|
-
device_code:
|
|
960
|
-
user_code:
|
|
961
|
-
verification_uri:
|
|
962
|
-
verification_uri_complete:
|
|
963
|
-
expires_in:
|
|
964
|
-
interval:
|
|
911
|
+
var DeviceAuthorizationResponseSchema = z3.object({
|
|
912
|
+
device_code: z3.string(),
|
|
913
|
+
user_code: z3.string().min(1),
|
|
914
|
+
verification_uri: z3.string().url(),
|
|
915
|
+
verification_uri_complete: z3.string().url().optional(),
|
|
916
|
+
expires_in: z3.number().int().positive(),
|
|
917
|
+
interval: z3.number().int().positive().default(5)
|
|
965
918
|
});
|
|
966
|
-
var DeviceTokenPollRequestSchema =
|
|
967
|
-
client_id:
|
|
968
|
-
device_code:
|
|
969
|
-
grant_type:
|
|
919
|
+
var DeviceTokenPollRequestSchema = z3.object({
|
|
920
|
+
client_id: z3.string(),
|
|
921
|
+
device_code: z3.string(),
|
|
922
|
+
grant_type: z3.literal("urn:ietf:params:oauth:grant-type:device_code")
|
|
970
923
|
});
|
|
971
|
-
var TokenResponseSchema =
|
|
972
|
-
access_token:
|
|
973
|
-
token_type:
|
|
974
|
-
expires_in:
|
|
975
|
-
scope:
|
|
924
|
+
var TokenResponseSchema = z3.object({
|
|
925
|
+
access_token: z3.string(),
|
|
926
|
+
token_type: z3.literal("Bearer"),
|
|
927
|
+
expires_in: z3.number().int().positive(),
|
|
928
|
+
scope: z3.string()
|
|
976
929
|
});
|
|
977
|
-
var DeviceTokenPollErrorCodeSchema =
|
|
930
|
+
var DeviceTokenPollErrorCodeSchema = z3.enum([
|
|
978
931
|
"authorization_pending",
|
|
979
932
|
"slow_down",
|
|
980
933
|
"access_denied",
|
|
@@ -985,27 +938,27 @@ var DeviceTokenPollErrorCodeSchema = z4.enum([
|
|
|
985
938
|
"unsupported_grant_type",
|
|
986
939
|
"invalid_scope"
|
|
987
940
|
]);
|
|
988
|
-
var DeviceTokenPollErrorSchema =
|
|
941
|
+
var DeviceTokenPollErrorSchema = z3.object({
|
|
989
942
|
error: DeviceTokenPollErrorCodeSchema,
|
|
990
|
-
error_description:
|
|
943
|
+
error_description: z3.string().optional()
|
|
991
944
|
});
|
|
992
|
-
var CredentialsProfileSchema =
|
|
993
|
-
apiBaseUrl:
|
|
994
|
-
accessToken:
|
|
995
|
-
tokenType:
|
|
996
|
-
tokenPrefix:
|
|
997
|
-
organizationId:
|
|
998
|
-
organizationSlug:
|
|
999
|
-
userId:
|
|
1000
|
-
scopes:
|
|
1001
|
-
expiresAt:
|
|
1002
|
-
issuedAt:
|
|
1003
|
-
clientId:
|
|
945
|
+
var CredentialsProfileSchema = z3.object({
|
|
946
|
+
apiBaseUrl: z3.string().url(),
|
|
947
|
+
accessToken: z3.string(),
|
|
948
|
+
tokenType: z3.literal("Bearer"),
|
|
949
|
+
tokenPrefix: z3.string(),
|
|
950
|
+
organizationId: z3.string().uuid(),
|
|
951
|
+
organizationSlug: z3.string(),
|
|
952
|
+
userId: z3.string().uuid(),
|
|
953
|
+
scopes: z3.array(z3.string()),
|
|
954
|
+
expiresAt: z3.string().datetime(),
|
|
955
|
+
issuedAt: z3.string().datetime(),
|
|
956
|
+
clientId: z3.string()
|
|
1004
957
|
}).strict();
|
|
1005
|
-
var CredentialsFileSchema =
|
|
1006
|
-
version:
|
|
1007
|
-
defaultProfile:
|
|
1008
|
-
profiles:
|
|
958
|
+
var CredentialsFileSchema = z3.object({
|
|
959
|
+
version: z3.literal(1),
|
|
960
|
+
defaultProfile: z3.string(),
|
|
961
|
+
profiles: z3.record(z3.string(), CredentialsProfileSchema)
|
|
1009
962
|
}).strict();
|
|
1010
963
|
|
|
1011
964
|
// src/auth/credentials.ts
|
|
@@ -1237,20 +1190,158 @@ function trim(value) {
|
|
|
1237
1190
|
return t.length === 0 ? void 0 : t;
|
|
1238
1191
|
}
|
|
1239
1192
|
|
|
1240
|
-
// src/
|
|
1193
|
+
// src/commands/balance.ts
|
|
1194
|
+
var BalanceResponseSchema = z4.object({
|
|
1195
|
+
totalCredits: z4.number(),
|
|
1196
|
+
subscriptionCredits: z4.number(),
|
|
1197
|
+
purchasedCredits: z4.number(),
|
|
1198
|
+
promotionalCredits: z4.number(),
|
|
1199
|
+
rateLimit: z4.object({
|
|
1200
|
+
apiBurstPerMinute: z4.number()
|
|
1201
|
+
}).strict()
|
|
1202
|
+
}).strict();
|
|
1203
|
+
async function getBalance(options) {
|
|
1204
|
+
const config = await loadConfig({
|
|
1205
|
+
flagProfile: options.profile,
|
|
1206
|
+
credentialsPath: options.credentialsPath
|
|
1207
|
+
});
|
|
1208
|
+
if (!config.accessToken) {
|
|
1209
|
+
throw new AuthError("AUTH_TOKEN_MISSING", `Not authenticated. Run \`clickraft login\` first.`);
|
|
1210
|
+
}
|
|
1211
|
+
const factory = options.apiClientFactory ?? ((apiBaseUrl, accessToken) => new ApiClient({
|
|
1212
|
+
apiBaseUrl,
|
|
1213
|
+
accessToken,
|
|
1214
|
+
signal: options.signal,
|
|
1215
|
+
cloudflareAccess: config.cloudflareAccess
|
|
1216
|
+
}));
|
|
1217
|
+
const client = factory(config.apiBaseUrl, config.accessToken);
|
|
1218
|
+
const data = await client.request({
|
|
1219
|
+
method: "GET",
|
|
1220
|
+
path: "/balance",
|
|
1221
|
+
responseSchema: BalanceResponseSchema,
|
|
1222
|
+
signal: options.signal
|
|
1223
|
+
});
|
|
1224
|
+
return data;
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
// src/commands/brand-model/list.ts
|
|
1241
1228
|
import { z as z5 } from "zod";
|
|
1229
|
+
var BrandModelSummarySchema = z5.object({
|
|
1230
|
+
id: z5.string().uuid(),
|
|
1231
|
+
source: z5.enum(["system", "user"]),
|
|
1232
|
+
slug: z5.string().nullable(),
|
|
1233
|
+
name: z5.string(),
|
|
1234
|
+
description: z5.string().nullable(),
|
|
1235
|
+
thumbnailUrl: z5.string().nullable(),
|
|
1236
|
+
tags: z5.array(z5.string()),
|
|
1237
|
+
category: z5.string().nullable(),
|
|
1238
|
+
isPremium: z5.boolean().nullable(),
|
|
1239
|
+
isFeatured: z5.boolean().nullable(),
|
|
1240
|
+
badgeText: z5.string().nullable(),
|
|
1241
|
+
usageCount: z5.number().nullable(),
|
|
1242
|
+
createdAt: z5.string()
|
|
1243
|
+
}).strict();
|
|
1244
|
+
var BrandModelsListResponseSchema = z5.object({
|
|
1245
|
+
brandModels: z5.array(BrandModelSummarySchema)
|
|
1246
|
+
}).strict();
|
|
1247
|
+
async function listBrandModels(options) {
|
|
1248
|
+
const config = await loadConfig({
|
|
1249
|
+
flagProfile: options.profile,
|
|
1250
|
+
credentialsPath: options.credentialsPath
|
|
1251
|
+
});
|
|
1252
|
+
if (!config.accessToken) {
|
|
1253
|
+
throw new AuthError("AUTH_TOKEN_MISSING", `Not authenticated. Run \`clickraft login\` first.`);
|
|
1254
|
+
}
|
|
1255
|
+
const factory = options.apiClientFactory ?? ((apiBaseUrl, accessToken) => new ApiClient({
|
|
1256
|
+
apiBaseUrl,
|
|
1257
|
+
accessToken,
|
|
1258
|
+
signal: options.signal,
|
|
1259
|
+
cloudflareAccess: config.cloudflareAccess
|
|
1260
|
+
}));
|
|
1261
|
+
const client = factory(config.apiBaseUrl, config.accessToken);
|
|
1262
|
+
const data = await client.request({
|
|
1263
|
+
method: "GET",
|
|
1264
|
+
path: "/brand-models",
|
|
1265
|
+
responseSchema: BrandModelsListResponseSchema,
|
|
1266
|
+
signal: options.signal
|
|
1267
|
+
});
|
|
1268
|
+
return data.brandModels;
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
// src/schemas/jobs.ts
|
|
1272
|
+
import { z as z6 } from "zod";
|
|
1273
|
+
var GenerateCreateRequestSchema = z6.object({
|
|
1274
|
+
modelSlug: z6.string().min(1).max(100),
|
|
1275
|
+
input: z6.object({
|
|
1276
|
+
prompt: z6.string().max(1e4).optional(),
|
|
1277
|
+
referenceImageUrl: z6.string().url().optional(),
|
|
1278
|
+
referenceImages: z6.array(z6.string().url()).max(8).optional(),
|
|
1279
|
+
aspectRatio: z6.string().regex(/^\d+:\d+$/).optional(),
|
|
1280
|
+
resolution: z6.string().regex(/^\d+x\d+$/).optional(),
|
|
1281
|
+
durationSeconds: z6.number().int().min(1).max(60).optional(),
|
|
1282
|
+
providerParams: z6.record(z6.string(), z6.unknown()).optional()
|
|
1283
|
+
}).strict(),
|
|
1284
|
+
options: z6.object({
|
|
1285
|
+
workflowId: z6.string().uuid().optional(),
|
|
1286
|
+
nodeId: z6.string().optional()
|
|
1287
|
+
}).strict().optional()
|
|
1288
|
+
}).strict();
|
|
1289
|
+
var GenerateCreateResponseSchema = z6.object({
|
|
1290
|
+
jobId: z6.string().uuid(),
|
|
1291
|
+
status: z6.enum(["queued", "processing", "completed", "failed"]),
|
|
1292
|
+
estimatedSeconds: z6.number().int().nonnegative().nullable(),
|
|
1293
|
+
creditsCharged: z6.number().int().nonnegative()
|
|
1294
|
+
}).strict();
|
|
1295
|
+
var GenerationStatusSchema = z6.enum([
|
|
1296
|
+
"queued",
|
|
1297
|
+
"processing",
|
|
1298
|
+
"uploading",
|
|
1299
|
+
"completed",
|
|
1300
|
+
"failed",
|
|
1301
|
+
"cancelled"
|
|
1302
|
+
]);
|
|
1303
|
+
var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
1304
|
+
"completed",
|
|
1305
|
+
"failed",
|
|
1306
|
+
"cancelled"
|
|
1307
|
+
]);
|
|
1308
|
+
function isTerminalStatus(status) {
|
|
1309
|
+
return TERMINAL_STATUSES.has(status);
|
|
1310
|
+
}
|
|
1311
|
+
var GenerationResultSchema = z6.object({
|
|
1312
|
+
jobId: z6.string().uuid(),
|
|
1313
|
+
status: GenerationStatusSchema,
|
|
1314
|
+
modelSlug: z6.string(),
|
|
1315
|
+
resultUrl: z6.string().url().nullable(),
|
|
1316
|
+
thumbnailUrl: z6.string().url().nullable(),
|
|
1317
|
+
errorCode: z6.string().nullable(),
|
|
1318
|
+
errorMessage: z6.string().nullable(),
|
|
1319
|
+
creditsCharged: z6.number().int().nonnegative(),
|
|
1320
|
+
creditsRefunded: z6.boolean(),
|
|
1321
|
+
startedAt: z6.string().nullable(),
|
|
1322
|
+
completedAt: z6.string().nullable()
|
|
1323
|
+
}).strict();
|
|
1324
|
+
|
|
1325
|
+
// src/commands/upload.ts
|
|
1326
|
+
import { createHash as createHash2 } from "crypto";
|
|
1327
|
+
import { readFile as readFile2, stat as stat2 } from "fs/promises";
|
|
1328
|
+
import { basename } from "path";
|
|
1329
|
+
import { request as undiciRequest2 } from "undici";
|
|
1330
|
+
|
|
1331
|
+
// src/schemas/assets.ts
|
|
1332
|
+
import { z as z7 } from "zod";
|
|
1242
1333
|
var MAX_UPLOAD_SIZE_BYTES = 15 * 1024 * 1024;
|
|
1243
|
-
var UploadRequestSchema =
|
|
1244
|
-
filename:
|
|
1245
|
-
contentType:
|
|
1246
|
-
sizeBytes:
|
|
1247
|
-
contentHash:
|
|
1334
|
+
var UploadRequestSchema = z7.object({
|
|
1335
|
+
filename: z7.string().min(1).max(255),
|
|
1336
|
+
contentType: z7.string().regex(/^[\w-]+\/[\w+.-]+$/),
|
|
1337
|
+
sizeBytes: z7.number().int().positive().max(MAX_UPLOAD_SIZE_BYTES),
|
|
1338
|
+
contentHash: z7.string().regex(/^sha256:[0-9a-f]{64}$/)
|
|
1248
1339
|
}).strict();
|
|
1249
|
-
var UploadResponseSchema =
|
|
1250
|
-
assetId:
|
|
1251
|
-
uploadUrl:
|
|
1252
|
-
publicUrl:
|
|
1253
|
-
deduplicated:
|
|
1340
|
+
var UploadResponseSchema = z7.object({
|
|
1341
|
+
assetId: z7.string().uuid(),
|
|
1342
|
+
uploadUrl: z7.string().url(),
|
|
1343
|
+
publicUrl: z7.string().url(),
|
|
1344
|
+
deduplicated: z7.boolean()
|
|
1254
1345
|
}).strict();
|
|
1255
1346
|
|
|
1256
1347
|
// src/commands/upload.ts
|
|
@@ -2218,21 +2309,112 @@ function inspectTelemetry(options = {}) {
|
|
|
2218
2309
|
};
|
|
2219
2310
|
}
|
|
2220
2311
|
|
|
2312
|
+
// src/commands/template/internal.ts
|
|
2313
|
+
async function buildTemplateClient(opts) {
|
|
2314
|
+
const cfg = await loadConfig({
|
|
2315
|
+
flagProfile: opts.profile,
|
|
2316
|
+
flagApiBaseUrl: opts.apiBaseUrl,
|
|
2317
|
+
flagToken: opts.token
|
|
2318
|
+
});
|
|
2319
|
+
return new ApiClient({
|
|
2320
|
+
apiBaseUrl: cfg.apiBaseUrl,
|
|
2321
|
+
accessToken: cfg.accessToken,
|
|
2322
|
+
signal: opts.signal,
|
|
2323
|
+
cloudflareAccess: cfg.cloudflareAccess
|
|
2324
|
+
});
|
|
2325
|
+
}
|
|
2326
|
+
|
|
2327
|
+
// src/schemas/templates.ts
|
|
2328
|
+
import { z as z8 } from "zod";
|
|
2329
|
+
var DeclaredParamSchema = z8.object({
|
|
2330
|
+
name: z8.string(),
|
|
2331
|
+
type: z8.string(),
|
|
2332
|
+
required: z8.boolean(),
|
|
2333
|
+
defaultValue: z8.string().nullable().optional(),
|
|
2334
|
+
enumValues: z8.array(z8.string()).nullable().optional(),
|
|
2335
|
+
description: z8.string().nullable().optional()
|
|
2336
|
+
}).strict();
|
|
2337
|
+
var TemplateSummarySchema = z8.object({
|
|
2338
|
+
id: z8.string().uuid(),
|
|
2339
|
+
source: z8.enum(["own", "system"]),
|
|
2340
|
+
name: z8.string(),
|
|
2341
|
+
description: z8.string().nullable(),
|
|
2342
|
+
category: z8.string().nullable(),
|
|
2343
|
+
thumbnailUrl: z8.string().nullable(),
|
|
2344
|
+
tags: z8.array(z8.string()),
|
|
2345
|
+
createdAt: z8.string()
|
|
2346
|
+
}).strict();
|
|
2347
|
+
var TemplateDetailSchema = TemplateSummarySchema.extend({
|
|
2348
|
+
declaredParams: z8.array(DeclaredParamSchema),
|
|
2349
|
+
timesUsed: z8.number()
|
|
2350
|
+
}).strict();
|
|
2351
|
+
var TemplatesListResponseSchema = z8.object({
|
|
2352
|
+
templates: z8.array(TemplateSummarySchema),
|
|
2353
|
+
cursor: z8.string().nullable(),
|
|
2354
|
+
hasMore: z8.boolean()
|
|
2355
|
+
}).strict();
|
|
2356
|
+
|
|
2357
|
+
// src/commands/template/list.ts
|
|
2358
|
+
async function listTemplates(opts) {
|
|
2359
|
+
const client = opts.client ?? await buildTemplateClient(opts);
|
|
2360
|
+
const data = await client.request({
|
|
2361
|
+
method: "GET",
|
|
2362
|
+
path: "/templates",
|
|
2363
|
+
query: {
|
|
2364
|
+
q: opts.q,
|
|
2365
|
+
tags: opts.tags,
|
|
2366
|
+
scope: opts.scope,
|
|
2367
|
+
cursor: opts.cursor,
|
|
2368
|
+
limit: opts.limit
|
|
2369
|
+
},
|
|
2370
|
+
responseSchema: TemplatesListResponseSchema,
|
|
2371
|
+
signal: opts.signal
|
|
2372
|
+
});
|
|
2373
|
+
return data;
|
|
2374
|
+
}
|
|
2375
|
+
|
|
2376
|
+
// src/commands/template/find.ts
|
|
2377
|
+
async function findTemplates(opts) {
|
|
2378
|
+
return listTemplates({
|
|
2379
|
+
q: opts.query,
|
|
2380
|
+
tags: opts.tags,
|
|
2381
|
+
scope: opts.scope,
|
|
2382
|
+
limit: opts.limit,
|
|
2383
|
+
cursor: opts.cursor,
|
|
2384
|
+
profile: opts.profile,
|
|
2385
|
+
apiBaseUrl: opts.apiBaseUrl,
|
|
2386
|
+
token: opts.token,
|
|
2387
|
+
signal: opts.signal,
|
|
2388
|
+
client: opts.client
|
|
2389
|
+
});
|
|
2390
|
+
}
|
|
2391
|
+
|
|
2392
|
+
// src/commands/template/get.ts
|
|
2393
|
+
async function getTemplate(opts) {
|
|
2394
|
+
const client = opts.client ?? await buildTemplateClient(opts);
|
|
2395
|
+
return client.request({
|
|
2396
|
+
method: "GET",
|
|
2397
|
+
path: `/templates/${encodeURIComponent(opts.id)}`,
|
|
2398
|
+
responseSchema: TemplateDetailSchema,
|
|
2399
|
+
signal: opts.signal
|
|
2400
|
+
});
|
|
2401
|
+
}
|
|
2402
|
+
|
|
2221
2403
|
// src/commands/tokens/list.ts
|
|
2222
|
-
import { z as
|
|
2223
|
-
var TokenRowSchema =
|
|
2224
|
-
id:
|
|
2225
|
-
organizationId:
|
|
2226
|
-
userId:
|
|
2227
|
-
clientId:
|
|
2228
|
-
tokenPrefix:
|
|
2229
|
-
name:
|
|
2230
|
-
scopes:
|
|
2231
|
-
lastUsedAt:
|
|
2232
|
-
expiresAt:
|
|
2233
|
-
createdAt:
|
|
2404
|
+
import { z as z9 } from "zod";
|
|
2405
|
+
var TokenRowSchema = z9.object({
|
|
2406
|
+
id: z9.string().uuid(),
|
|
2407
|
+
organizationId: z9.string().uuid(),
|
|
2408
|
+
userId: z9.string().uuid(),
|
|
2409
|
+
clientId: z9.string().nullable(),
|
|
2410
|
+
tokenPrefix: z9.string(),
|
|
2411
|
+
name: z9.string().nullable(),
|
|
2412
|
+
scopes: z9.array(z9.string()),
|
|
2413
|
+
lastUsedAt: z9.string().nullable(),
|
|
2414
|
+
expiresAt: z9.string(),
|
|
2415
|
+
createdAt: z9.string()
|
|
2234
2416
|
}).strict();
|
|
2235
|
-
var TokensListResponseSchema =
|
|
2417
|
+
var TokensListResponseSchema = z9.array(TokenRowSchema);
|
|
2236
2418
|
async function listTokens(options) {
|
|
2237
2419
|
const config = await loadConfig({
|
|
2238
2420
|
flagProfile: options.profile,
|
|
@@ -2592,6 +2774,99 @@ function renderTelemetryState(state, out) {
|
|
|
2592
2774
|
];
|
|
2593
2775
|
out.write(lines.join("\n") + "\n");
|
|
2594
2776
|
}
|
|
2777
|
+
var fmtNum = new Intl.NumberFormat("en-US");
|
|
2778
|
+
function renderBalance(data, out) {
|
|
2779
|
+
const pad = 22;
|
|
2780
|
+
const lines = [
|
|
2781
|
+
`${"Total credits:".padEnd(pad)}${fmtNum.format(data.totalCredits).padStart(12)}`,
|
|
2782
|
+
`${"\u251C\u2500 Subscription:".padEnd(pad)}${fmtNum.format(data.subscriptionCredits).padStart(12)}`,
|
|
2783
|
+
`${"\u251C\u2500 Purchased:".padEnd(pad)}${fmtNum.format(data.purchasedCredits).padStart(12)}`,
|
|
2784
|
+
`${"\u2514\u2500 Promotional:".padEnd(pad)}${fmtNum.format(data.promotionalCredits).padStart(12)}`,
|
|
2785
|
+
"",
|
|
2786
|
+
`${"Rate limit:".padEnd(pad)}${fmtNum.format(data.rateLimit.apiBurstPerMinute).padStart(12)} req/min`
|
|
2787
|
+
];
|
|
2788
|
+
out.write(lines.join("\n") + "\n");
|
|
2789
|
+
}
|
|
2790
|
+
function renderBrandModelsList(models, out) {
|
|
2791
|
+
if (models.length === 0) {
|
|
2792
|
+
out.write("No brand models.\n");
|
|
2793
|
+
return;
|
|
2794
|
+
}
|
|
2795
|
+
const MAX_TAGS = 3;
|
|
2796
|
+
const headers = ["SOURCE", "NAME", "SLUG", "CATEGORY", "TAGS"];
|
|
2797
|
+
const data = models.map((m) => {
|
|
2798
|
+
const shown = m.tags.slice(0, MAX_TAGS).join(", ");
|
|
2799
|
+
const extra = m.tags.length > MAX_TAGS ? ` +${m.tags.length - MAX_TAGS} more` : "";
|
|
2800
|
+
return [
|
|
2801
|
+
m.source,
|
|
2802
|
+
m.name,
|
|
2803
|
+
m.slug ?? "\u2014",
|
|
2804
|
+
m.category ?? "\u2014",
|
|
2805
|
+
m.tags.length > 0 ? shown + extra : "\u2014"
|
|
2806
|
+
];
|
|
2807
|
+
});
|
|
2808
|
+
const widths = headers.map(
|
|
2809
|
+
(header, i) => Math.max(header.length, ...data.map((cells) => cells[i].length))
|
|
2810
|
+
);
|
|
2811
|
+
const padRow = (cells) => cells.map((cell, i) => cell.padEnd(widths[i])).join(" ").trimEnd();
|
|
2812
|
+
out.write(padRow(headers) + "\n");
|
|
2813
|
+
for (const cells of data) out.write(padRow(cells) + "\n");
|
|
2814
|
+
}
|
|
2815
|
+
function renderTemplatesList(result, out) {
|
|
2816
|
+
const { templates } = result;
|
|
2817
|
+
if (templates.length === 0) {
|
|
2818
|
+
out.write("No templates.\n");
|
|
2819
|
+
return;
|
|
2820
|
+
}
|
|
2821
|
+
const MAX_TAGS = 3;
|
|
2822
|
+
const headers = ["SOURCE", "NAME", "CATEGORY", "TAGS", "CREATED"];
|
|
2823
|
+
const data = templates.map((t) => {
|
|
2824
|
+
const shown = t.tags.slice(0, MAX_TAGS).join(", ");
|
|
2825
|
+
const extra = t.tags.length > MAX_TAGS ? ` +${t.tags.length - MAX_TAGS} more` : "";
|
|
2826
|
+
return [
|
|
2827
|
+
t.source,
|
|
2828
|
+
t.name,
|
|
2829
|
+
t.category ?? "\u2014",
|
|
2830
|
+
t.tags.length > 0 ? shown + extra : "\u2014",
|
|
2831
|
+
t.createdAt.slice(0, 10)
|
|
2832
|
+
];
|
|
2833
|
+
});
|
|
2834
|
+
const widths = headers.map(
|
|
2835
|
+
(header, i) => Math.max(header.length, ...data.map((cells) => cells[i].length))
|
|
2836
|
+
);
|
|
2837
|
+
const padRow = (cells) => cells.map((cell, i) => cell.padEnd(widths[i])).join(" ").trimEnd();
|
|
2838
|
+
out.write(padRow(headers) + "\n");
|
|
2839
|
+
for (const cells of data) out.write(padRow(cells) + "\n");
|
|
2840
|
+
if (result.hasMore) {
|
|
2841
|
+
out.write("\nMore results available. Use --cursor to fetch the next page.\n");
|
|
2842
|
+
}
|
|
2843
|
+
}
|
|
2844
|
+
function renderTemplateDetail(detail, out) {
|
|
2845
|
+
const pad = 17;
|
|
2846
|
+
const lines = [
|
|
2847
|
+
detail.name,
|
|
2848
|
+
`${"ID:".padEnd(pad)}${detail.id}`,
|
|
2849
|
+
`${"Source:".padEnd(pad)}${detail.source}`,
|
|
2850
|
+
`${"Category:".padEnd(pad)}${detail.category ?? "\u2014"}`,
|
|
2851
|
+
`${"Tags:".padEnd(pad)}${detail.tags.length > 0 ? detail.tags.join(", ") : "\u2014"}`,
|
|
2852
|
+
`${"Created:".padEnd(pad)}${detail.createdAt.slice(0, 10)}`,
|
|
2853
|
+
`${"Times used:".padEnd(pad)}${detail.timesUsed}`
|
|
2854
|
+
];
|
|
2855
|
+
if (detail.description) {
|
|
2856
|
+
lines.push("", detail.description);
|
|
2857
|
+
}
|
|
2858
|
+
lines.push("", "Declared parameters:");
|
|
2859
|
+
if (detail.declaredParams.length === 0) {
|
|
2860
|
+
lines.push(" (none)");
|
|
2861
|
+
} else {
|
|
2862
|
+
for (const p of detail.declaredParams) {
|
|
2863
|
+
const req = p.required ? "required" : "optional";
|
|
2864
|
+
const desc = p.description ? `: ${p.description}` : "";
|
|
2865
|
+
lines.push(` - ${p.name} (${p.type}, ${req})${desc}`);
|
|
2866
|
+
}
|
|
2867
|
+
}
|
|
2868
|
+
out.write(lines.join("\n") + "\n");
|
|
2869
|
+
}
|
|
2595
2870
|
function formatExpiresAt(iso) {
|
|
2596
2871
|
const ms = Date.parse(iso);
|
|
2597
2872
|
if (Number.isNaN(ms)) return iso;
|
|
@@ -2685,6 +2960,22 @@ async function runCommand(parsed, ctx, rc) {
|
|
|
2685
2960
|
emit(state, renderTelemetryState, ctx, rc);
|
|
2686
2961
|
return 0;
|
|
2687
2962
|
}
|
|
2963
|
+
case "balance": {
|
|
2964
|
+
const data = await getBalance({
|
|
2965
|
+
profile: stringFlag(parsed.flags.profile),
|
|
2966
|
+
signal: rc.signal
|
|
2967
|
+
});
|
|
2968
|
+
emit(data, renderBalance, ctx, rc);
|
|
2969
|
+
return 0;
|
|
2970
|
+
}
|
|
2971
|
+
case "brand-model.list": {
|
|
2972
|
+
const models = await listBrandModels({
|
|
2973
|
+
profile: stringFlag(parsed.flags.profile),
|
|
2974
|
+
signal: rc.signal
|
|
2975
|
+
});
|
|
2976
|
+
emit(models, renderBrandModelsList, ctx, rc);
|
|
2977
|
+
return 0;
|
|
2978
|
+
}
|
|
2688
2979
|
default:
|
|
2689
2980
|
throw new ApiError(
|
|
2690
2981
|
"INPUT_INVALID_FORMAT",
|
|
@@ -2757,7 +3048,9 @@ var COMMAND_FLAGS = {
|
|
|
2757
3048
|
},
|
|
2758
3049
|
logout: { profile: "string", all: "boolean", revoke: "boolean", json: "boolean" },
|
|
2759
3050
|
"tokens.list": { profile: "string", json: "boolean" },
|
|
2760
|
-
"telemetry.inspect": { json: "boolean" }
|
|
3051
|
+
"telemetry.inspect": { json: "boolean" },
|
|
3052
|
+
balance: { profile: "string", json: "boolean" },
|
|
3053
|
+
"brand-model.list": { profile: "string", json: "boolean" }
|
|
2761
3054
|
};
|
|
2762
3055
|
function validateFlags(parsed) {
|
|
2763
3056
|
const allowed = COMMAND_FLAGS[parsed.command.join(".")];
|
|
@@ -2798,7 +3091,12 @@ function renderRootHelp(version) {
|
|
|
2798
3091
|
" login Authenticate via OAuth device flow",
|
|
2799
3092
|
" logout Remove credentials (optional server-side revoke)",
|
|
2800
3093
|
" tokens list List the caller's API tokens",
|
|
3094
|
+
" balance Show credit balance and rate limits",
|
|
3095
|
+
" brand-model list List available brand models",
|
|
2801
3096
|
" telemetry inspect Show current telemetry state and payload shape",
|
|
3097
|
+
" template list List available templates",
|
|
3098
|
+
" template get Fetch a template by ID",
|
|
3099
|
+
" template find Search templates by keyword",
|
|
2802
3100
|
" generate create Submit a generation job and wait for completion",
|
|
2803
3101
|
" generate wait Wait for an existing job to reach a terminal state",
|
|
2804
3102
|
" generate get Fetch the current state of a job",
|
|
@@ -2848,6 +3146,32 @@ function renderCommandHelp(command) {
|
|
|
2848
3146
|
" --json Emit JSON envelope instead of human output",
|
|
2849
3147
|
""
|
|
2850
3148
|
].join("\n");
|
|
3149
|
+
case "balance":
|
|
3150
|
+
return [
|
|
3151
|
+
"Usage: clickraft balance [options]",
|
|
3152
|
+
"",
|
|
3153
|
+
"Options:",
|
|
3154
|
+
" --profile <name> Read credentials from a specific profile",
|
|
3155
|
+
" --json Emit JSON envelope instead of human output",
|
|
3156
|
+
""
|
|
3157
|
+
].join("\n");
|
|
3158
|
+
case "brand-model":
|
|
3159
|
+
return [
|
|
3160
|
+
"Usage: clickraft brand-model <subcommand> [options]",
|
|
3161
|
+
"",
|
|
3162
|
+
"Subcommands:",
|
|
3163
|
+
" list List available brand models",
|
|
3164
|
+
""
|
|
3165
|
+
].join("\n");
|
|
3166
|
+
case "brand-model list":
|
|
3167
|
+
return [
|
|
3168
|
+
"Usage: clickraft brand-model list [options]",
|
|
3169
|
+
"",
|
|
3170
|
+
"Options:",
|
|
3171
|
+
" --profile <name> Read credentials from a specific profile",
|
|
3172
|
+
" --json Emit JSON envelope instead of human output",
|
|
3173
|
+
""
|
|
3174
|
+
].join("\n");
|
|
2851
3175
|
case "telemetry inspect":
|
|
2852
3176
|
return [
|
|
2853
3177
|
"Usage: clickraft telemetry inspect [options]",
|
|
@@ -2856,6 +3180,62 @@ function renderCommandHelp(command) {
|
|
|
2856
3180
|
" --json Emit JSON envelope instead of human output",
|
|
2857
3181
|
""
|
|
2858
3182
|
].join("\n");
|
|
3183
|
+
case "template":
|
|
3184
|
+
return [
|
|
3185
|
+
"Usage: clickraft template <subcommand> [options]",
|
|
3186
|
+
"",
|
|
3187
|
+
"Subcommands:",
|
|
3188
|
+
" list List available templates",
|
|
3189
|
+
" get Fetch a template by ID",
|
|
3190
|
+
" find Search templates by keyword",
|
|
3191
|
+
""
|
|
3192
|
+
].join("\n");
|
|
3193
|
+
case "template list":
|
|
3194
|
+
return [
|
|
3195
|
+
"Usage: clickraft template list [options]",
|
|
3196
|
+
"",
|
|
3197
|
+
"Options:",
|
|
3198
|
+
" --scope <scope> Filter by scope: own, system, or all (default: all)",
|
|
3199
|
+
" --q <query> Free-text search query",
|
|
3200
|
+
" --tags <tag> Filter by tag (repeatable)",
|
|
3201
|
+
" --cursor <token> Pagination cursor from a previous response",
|
|
3202
|
+
" --limit <n> Max results per page (1-50, default: 20)",
|
|
3203
|
+
" --profile <name>",
|
|
3204
|
+
" --api-base-url <url>",
|
|
3205
|
+
" --token <token>",
|
|
3206
|
+
" --json",
|
|
3207
|
+
""
|
|
3208
|
+
].join("\n");
|
|
3209
|
+
case "template get":
|
|
3210
|
+
return [
|
|
3211
|
+
"Usage: clickraft template get <id> [options]",
|
|
3212
|
+
"",
|
|
3213
|
+
"Fetches a single template by its ID, including declared parameters.",
|
|
3214
|
+
"",
|
|
3215
|
+
"Options:",
|
|
3216
|
+
" --profile <name>",
|
|
3217
|
+
" --api-base-url <url>",
|
|
3218
|
+
" --token <token>",
|
|
3219
|
+
" --json",
|
|
3220
|
+
""
|
|
3221
|
+
].join("\n");
|
|
3222
|
+
case "template find":
|
|
3223
|
+
return [
|
|
3224
|
+
"Usage: clickraft template find <query> [options]",
|
|
3225
|
+
"",
|
|
3226
|
+
"Searches templates by keyword. Shorthand for `template list --q <query>`.",
|
|
3227
|
+
"",
|
|
3228
|
+
"Options:",
|
|
3229
|
+
" --tags <tag> Filter by tag (repeatable)",
|
|
3230
|
+
" --scope <scope> Filter by scope: own, system, or all (default: all)",
|
|
3231
|
+
" --limit <n> Max results per page (1-50, default: 20)",
|
|
3232
|
+
" --cursor <token> Pagination cursor from a previous response",
|
|
3233
|
+
" --profile <name>",
|
|
3234
|
+
" --api-base-url <url>",
|
|
3235
|
+
" --token <token>",
|
|
3236
|
+
" --json",
|
|
3237
|
+
""
|
|
3238
|
+
].join("\n");
|
|
2859
3239
|
case "generate":
|
|
2860
3240
|
return [
|
|
2861
3241
|
"Usage: clickraft generate <subcommand> [options]",
|
|
@@ -2977,6 +3357,14 @@ function matchNewCommand(argv) {
|
|
|
2977
3357
|
if (sub === void 0 || sub.startsWith("-")) return { kind: "sub-help", verb: "jobs" };
|
|
2978
3358
|
return { kind: "unknown-sub", verb: "jobs", sub };
|
|
2979
3359
|
}
|
|
3360
|
+
if (verb === "template") {
|
|
3361
|
+
const sub = argv[1];
|
|
3362
|
+
if (sub === "list") return { kind: "cmd", path: "template.list", verbTokenCount: 2 };
|
|
3363
|
+
if (sub === "get") return { kind: "cmd", path: "template.get", verbTokenCount: 2 };
|
|
3364
|
+
if (sub === "find") return { kind: "cmd", path: "template.find", verbTokenCount: 2 };
|
|
3365
|
+
if (sub === void 0 || sub.startsWith("-")) return { kind: "sub-help", verb: "template" };
|
|
3366
|
+
return { kind: "unknown-sub", verb: "template", sub };
|
|
3367
|
+
}
|
|
2980
3368
|
return null;
|
|
2981
3369
|
}
|
|
2982
3370
|
async function runNewCommand(newCmd, options, stdout, stderr) {
|
|
@@ -3027,6 +3415,12 @@ async function runNewCommand(newCmd, options, stdout, stderr) {
|
|
|
3027
3415
|
return await runJobsWait(argvAfterVerb, ctx, rc);
|
|
3028
3416
|
case "upload":
|
|
3029
3417
|
return await runUploadCmd(argvAfterVerb, ctx, rc);
|
|
3418
|
+
case "template.list":
|
|
3419
|
+
return await runTemplateList(argvAfterVerb, ctx, rc);
|
|
3420
|
+
case "template.get":
|
|
3421
|
+
return await runTemplateGet(argvAfterVerb, ctx, rc);
|
|
3422
|
+
case "template.find":
|
|
3423
|
+
return await runTemplateFind(argvAfterVerb, ctx, rc);
|
|
3030
3424
|
}
|
|
3031
3425
|
} catch (err) {
|
|
3032
3426
|
if (isAbortedError(err, options.signal)) {
|
|
@@ -3221,6 +3615,87 @@ function exitCodeForResult(result) {
|
|
|
3221
3615
|
}
|
|
3222
3616
|
return 0;
|
|
3223
3617
|
}
|
|
3618
|
+
async function runTemplateList(argv, ctx, rc) {
|
|
3619
|
+
const parsed = parseArgs(argv, {
|
|
3620
|
+
string: [...COMMON_RICH_STRING_FLAGS, "scope", "q", "cursor", "limit"],
|
|
3621
|
+
boolean: [...COMMON_RICH_BOOL_FLAGS],
|
|
3622
|
+
array: ["tags"]
|
|
3623
|
+
});
|
|
3624
|
+
const result = await listTemplates({
|
|
3625
|
+
q: parsed.string.q,
|
|
3626
|
+
tags: parsed.array.tags,
|
|
3627
|
+
scope: parsed.string.scope,
|
|
3628
|
+
cursor: parsed.string.cursor,
|
|
3629
|
+
limit: optionalInt(parsed.string.limit, "limit"),
|
|
3630
|
+
profile: parsed.string.profile,
|
|
3631
|
+
apiBaseUrl: parsed.string["api-base-url"],
|
|
3632
|
+
token: parsed.string.token,
|
|
3633
|
+
signal: rc.signal
|
|
3634
|
+
});
|
|
3635
|
+
ctx.nextCursor = result.cursor ?? void 0;
|
|
3636
|
+
emitTemplateList(result, ctx, rc);
|
|
3637
|
+
return 0;
|
|
3638
|
+
}
|
|
3639
|
+
async function runTemplateGet(argv, ctx, rc) {
|
|
3640
|
+
const parsed = parseArgs(argv, {
|
|
3641
|
+
string: [...COMMON_RICH_STRING_FLAGS],
|
|
3642
|
+
boolean: [...COMMON_RICH_BOOL_FLAGS]
|
|
3643
|
+
});
|
|
3644
|
+
const id = parsed.positional[0];
|
|
3645
|
+
if (!id) throw new ArgError("Missing required <id> argument.");
|
|
3646
|
+
const detail = await getTemplate({
|
|
3647
|
+
id,
|
|
3648
|
+
profile: parsed.string.profile,
|
|
3649
|
+
apiBaseUrl: parsed.string["api-base-url"],
|
|
3650
|
+
token: parsed.string.token,
|
|
3651
|
+
signal: rc.signal
|
|
3652
|
+
});
|
|
3653
|
+
emitTemplateDetail(detail, ctx, rc);
|
|
3654
|
+
return 0;
|
|
3655
|
+
}
|
|
3656
|
+
async function runTemplateFind(argv, ctx, rc) {
|
|
3657
|
+
const parsed = parseArgs(argv, {
|
|
3658
|
+
string: [...COMMON_RICH_STRING_FLAGS, "scope", "cursor", "limit"],
|
|
3659
|
+
boolean: [...COMMON_RICH_BOOL_FLAGS],
|
|
3660
|
+
array: ["tags"]
|
|
3661
|
+
});
|
|
3662
|
+
const query = parsed.positional[0];
|
|
3663
|
+
if (!query) throw new ArgError("Missing required <query> argument.");
|
|
3664
|
+
const result = await findTemplates({
|
|
3665
|
+
query,
|
|
3666
|
+
tags: parsed.array.tags,
|
|
3667
|
+
scope: parsed.string.scope,
|
|
3668
|
+
cursor: parsed.string.cursor,
|
|
3669
|
+
limit: optionalInt(parsed.string.limit, "limit"),
|
|
3670
|
+
profile: parsed.string.profile,
|
|
3671
|
+
apiBaseUrl: parsed.string["api-base-url"],
|
|
3672
|
+
token: parsed.string.token,
|
|
3673
|
+
signal: rc.signal
|
|
3674
|
+
});
|
|
3675
|
+
ctx.nextCursor = result.cursor ?? void 0;
|
|
3676
|
+
emitTemplateList(result, ctx, rc);
|
|
3677
|
+
return 0;
|
|
3678
|
+
}
|
|
3679
|
+
function emitTemplateList(result, ctx, rc) {
|
|
3680
|
+
if (rc.signal?.aborted) {
|
|
3681
|
+
throw new AuthError("AUTH_FLOW_CANCELLED", "Cancelled.");
|
|
3682
|
+
}
|
|
3683
|
+
if (rc.jsonMode) {
|
|
3684
|
+
rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + "\n");
|
|
3685
|
+
return;
|
|
3686
|
+
}
|
|
3687
|
+
renderTemplatesList(result, rc.stdout);
|
|
3688
|
+
}
|
|
3689
|
+
function emitTemplateDetail(detail, ctx, rc) {
|
|
3690
|
+
if (rc.signal?.aborted) {
|
|
3691
|
+
throw new AuthError("AUTH_FLOW_CANCELLED", "Cancelled.");
|
|
3692
|
+
}
|
|
3693
|
+
if (rc.jsonMode) {
|
|
3694
|
+
rc.stdout.write(JSON.stringify(wrapSuccess(detail, ctx)) + "\n");
|
|
3695
|
+
return;
|
|
3696
|
+
}
|
|
3697
|
+
renderTemplateDetail(detail, rc.stdout);
|
|
3698
|
+
}
|
|
3224
3699
|
|
|
3225
3700
|
// src/index.ts
|
|
3226
3701
|
var __filename2 = fileURLToPath(import.meta.url);
|