primitive-admin 1.0.22 → 1.0.24
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/bin/primitive.js +28 -6
- package/dist/bin/primitive.js.map +1 -1
- package/dist/src/commands/auth.js +1 -1
- package/dist/src/commands/auth.js.map +1 -1
- package/dist/src/commands/database-types.js +453 -0
- package/dist/src/commands/database-types.js.map +1 -0
- package/dist/src/commands/databases.js +139 -262
- package/dist/src/commands/databases.js.map +1 -1
- package/dist/src/commands/email-templates.js +267 -0
- package/dist/src/commands/email-templates.js.map +1 -0
- package/dist/src/commands/group-type-configs.js +189 -0
- package/dist/src/commands/group-type-configs.js.map +1 -0
- package/dist/src/commands/groups.js +0 -66
- package/dist/src/commands/groups.js.map +1 -1
- package/dist/src/commands/init.js +125 -48
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/rule-sets.js +110 -18
- package/dist/src/commands/rule-sets.js.map +1 -1
- package/dist/src/commands/sync.js +117 -3
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/lib/api-client.js +18 -0
- package/dist/src/lib/api-client.js.map +1 -1
- package/dist/src/lib/constants.js +3 -0
- package/dist/src/lib/constants.js.map +1 -0
- package/dist/src/lib/template.js +35 -14
- package/dist/src/lib/template.js.map +1 -1
- package/dist/src/lib/version-check.js +169 -0
- package/dist/src/lib/version-check.js.map +1 -0
- package/package.json +3 -2
|
@@ -19,12 +19,12 @@ Examples:
|
|
|
19
19
|
$ primitive databases create "My Database"
|
|
20
20
|
$ primitive databases get <database-id>
|
|
21
21
|
$ primitive databases records models <database-id>
|
|
22
|
-
$ primitive databases records
|
|
23
|
-
$ primitive databases
|
|
22
|
+
$ primitive databases records describe <database-id> <model-name>
|
|
23
|
+
$ primitive databases operations list <database-id>
|
|
24
|
+
$ primitive databases operations execute <database-id> <operation-name> --params '{"key":"value"}'
|
|
24
25
|
$ primitive databases indexes list <database-id>
|
|
25
26
|
$ primitive databases indexes create <database-id> --model contacts --field email
|
|
26
27
|
$ primitive databases permissions list <database-id>
|
|
27
|
-
$ primitive databases group-permissions list <database-id>
|
|
28
28
|
`);
|
|
29
29
|
// List databases
|
|
30
30
|
databases
|
|
@@ -50,7 +50,7 @@ Examples:
|
|
|
50
50
|
console.log(formatTable(list, [
|
|
51
51
|
{ header: "ID", key: "databaseId", format: formatId },
|
|
52
52
|
{ header: "TITLE", key: "title" },
|
|
53
|
-
{ header: "
|
|
53
|
+
{ header: "TYPE", key: "databaseType", format: (v) => v || "—" },
|
|
54
54
|
{ header: "PERMISSION", key: "permission" },
|
|
55
55
|
{ header: "CREATED", key: "createdAt", format: formatDate },
|
|
56
56
|
]));
|
|
@@ -66,16 +66,13 @@ Examples:
|
|
|
66
66
|
.description("Create a new database")
|
|
67
67
|
.argument("<title>", "Database title")
|
|
68
68
|
.option("--app <app-id>", "App ID")
|
|
69
|
-
.
|
|
69
|
+
.requiredOption("--type <database-type>", "Database type (required)")
|
|
70
70
|
.option("--json", "Output as JSON")
|
|
71
71
|
.action(async (title, options) => {
|
|
72
72
|
const resolvedAppId = resolveAppId(undefined, options);
|
|
73
73
|
const client = new ApiClient();
|
|
74
74
|
try {
|
|
75
|
-
const params = { title };
|
|
76
|
-
if (options.defaultPermission) {
|
|
77
|
-
params.defaultPermission = options.defaultPermission;
|
|
78
|
-
}
|
|
75
|
+
const params = { title, databaseType: options.type };
|
|
79
76
|
const result = await client.createDatabase(resolvedAppId, params);
|
|
80
77
|
if (options.json) {
|
|
81
78
|
json(result);
|
|
@@ -84,8 +81,8 @@ Examples:
|
|
|
84
81
|
success("Database created.");
|
|
85
82
|
keyValue("Database ID", result.databaseId);
|
|
86
83
|
keyValue("Title", result.title);
|
|
87
|
-
if (result.
|
|
88
|
-
keyValue("
|
|
84
|
+
if (result.databaseType) {
|
|
85
|
+
keyValue("Database Type", result.databaseType);
|
|
89
86
|
}
|
|
90
87
|
}
|
|
91
88
|
catch (err) {
|
|
@@ -111,9 +108,8 @@ Examples:
|
|
|
111
108
|
}
|
|
112
109
|
keyValue("Database ID", result.databaseId);
|
|
113
110
|
keyValue("Title", result.title);
|
|
114
|
-
keyValue("
|
|
115
|
-
keyValue("
|
|
116
|
-
keyValue("Permission", result.permission);
|
|
111
|
+
keyValue("Database Type", result.databaseType || "none");
|
|
112
|
+
keyValue("Permission", result.permission || "none");
|
|
117
113
|
keyValue("Created", formatDate(result.createdAt));
|
|
118
114
|
}
|
|
119
115
|
catch (err) {
|
|
@@ -124,12 +120,11 @@ Examples:
|
|
|
124
120
|
// Update database
|
|
125
121
|
databases
|
|
126
122
|
.command("update")
|
|
127
|
-
.description("Update a database (title,
|
|
123
|
+
.description("Update a database (title, type)")
|
|
128
124
|
.argument("<database-id>", "Database ID")
|
|
129
125
|
.option("--app <app-id>", "App ID")
|
|
130
126
|
.option("--title <title>", "New title")
|
|
131
|
-
.option("--
|
|
132
|
-
.option("--rule-set-id <id>", "Attach a rule set (use 'none' to detach)")
|
|
127
|
+
.option("--type <database-type>", "Database type (use 'none' to clear)")
|
|
133
128
|
.option("--json", "Output as JSON")
|
|
134
129
|
.action(async (databaseId, options) => {
|
|
135
130
|
const resolvedAppId = resolveAppId(undefined, options);
|
|
@@ -138,20 +133,14 @@ Examples:
|
|
|
138
133
|
if (options.title) {
|
|
139
134
|
params.title = options.title;
|
|
140
135
|
}
|
|
141
|
-
if (options.
|
|
142
|
-
params.
|
|
143
|
-
options.
|
|
144
|
-
? null
|
|
145
|
-
: options.defaultPermission;
|
|
146
|
-
}
|
|
147
|
-
if (options.ruleSetId !== undefined) {
|
|
148
|
-
params.ruleSetId =
|
|
149
|
-
options.ruleSetId === "none"
|
|
136
|
+
if (options.type !== undefined) {
|
|
137
|
+
params.databaseType =
|
|
138
|
+
options.type === "none"
|
|
150
139
|
? null
|
|
151
|
-
: options.
|
|
140
|
+
: options.type;
|
|
152
141
|
}
|
|
153
142
|
if (Object.keys(params).length === 0) {
|
|
154
|
-
error("Provide at least one of --title
|
|
143
|
+
error("Provide at least one of --title or --type.");
|
|
155
144
|
process.exit(1);
|
|
156
145
|
}
|
|
157
146
|
try {
|
|
@@ -163,8 +152,7 @@ Examples:
|
|
|
163
152
|
success("Database updated.");
|
|
164
153
|
keyValue("Database ID", result.databaseId);
|
|
165
154
|
keyValue("Title", result.title);
|
|
166
|
-
keyValue("
|
|
167
|
-
keyValue("Rule Set", result.ruleSetId || "none");
|
|
155
|
+
keyValue("Database Type", result.databaseType || "none");
|
|
168
156
|
}
|
|
169
157
|
catch (err) {
|
|
170
158
|
error(err.message);
|
|
@@ -248,7 +236,7 @@ Examples:
|
|
|
248
236
|
.description("Grant a user permission on a database")
|
|
249
237
|
.argument("<database-id>", "Database ID")
|
|
250
238
|
.requiredOption("--user-id <user-id>", "User ID to grant permission to")
|
|
251
|
-
.requiredOption("--permission <permission>", "Permission level:
|
|
239
|
+
.requiredOption("--permission <permission>", "Permission level: manager")
|
|
252
240
|
.option("--app <app-id>", "App ID")
|
|
253
241
|
.option("--json", "Output as JSON")
|
|
254
242
|
.action(async (databaseId, options) => {
|
|
@@ -305,10 +293,10 @@ Examples:
|
|
|
305
293
|
process.exit(1);
|
|
306
294
|
}
|
|
307
295
|
});
|
|
308
|
-
// ---- Records subcommand group ----
|
|
296
|
+
// ---- Records subcommand group (models & describe only) ----
|
|
309
297
|
const records = databases
|
|
310
298
|
.command("records")
|
|
311
|
-
.description("
|
|
299
|
+
.description("Inspect models and schemas in a database");
|
|
312
300
|
// List models
|
|
313
301
|
records
|
|
314
302
|
.command("models")
|
|
@@ -371,64 +359,38 @@ Examples:
|
|
|
371
359
|
process.exit(1);
|
|
372
360
|
}
|
|
373
361
|
});
|
|
374
|
-
//
|
|
375
|
-
|
|
376
|
-
.command("
|
|
377
|
-
.description("
|
|
362
|
+
// ---- Metadata subcommand group ----
|
|
363
|
+
const metadata = databases
|
|
364
|
+
.command("metadata")
|
|
365
|
+
.description("Manage database metadata");
|
|
366
|
+
metadata
|
|
367
|
+
.command("update")
|
|
368
|
+
.description("Update database metadata (merge with existing)")
|
|
378
369
|
.argument("<database-id>", "Database ID")
|
|
379
|
-
.
|
|
380
|
-
.option("--filter <json>", "Filter as JSON", "{}")
|
|
381
|
-
.option("--limit <n>", "Max records to return", "25")
|
|
382
|
-
.option("--cursor <cursor>", "Pagination cursor")
|
|
370
|
+
.requiredOption("--data <json>", "Metadata fields as JSON (merged with existing)")
|
|
383
371
|
.option("--app <app-id>", "App ID")
|
|
384
372
|
.option("--json", "Output as JSON")
|
|
385
|
-
.action(async (databaseId,
|
|
373
|
+
.action(async (databaseId, options) => {
|
|
386
374
|
const resolvedAppId = resolveAppId(undefined, options);
|
|
387
375
|
const client = new ApiClient();
|
|
388
|
-
let
|
|
376
|
+
let data;
|
|
389
377
|
try {
|
|
390
|
-
|
|
378
|
+
data = JSON.parse(options.data);
|
|
391
379
|
}
|
|
392
380
|
catch {
|
|
393
|
-
error("Invalid --
|
|
381
|
+
error("Invalid --data JSON.");
|
|
394
382
|
process.exit(1);
|
|
383
|
+
return;
|
|
395
384
|
}
|
|
396
385
|
try {
|
|
397
|
-
const
|
|
398
|
-
modelName,
|
|
399
|
-
filter,
|
|
400
|
-
options: { limit: parseInt(options.limit, 10) },
|
|
401
|
-
};
|
|
402
|
-
if (options.cursor)
|
|
403
|
-
body.options.cursor = options.cursor;
|
|
404
|
-
const result = await client.queryDatabaseRecords(resolvedAppId, databaseId, body);
|
|
405
|
-
const data = result.data || [];
|
|
386
|
+
const result = await client.updateDatabaseMetadata(resolvedAppId, databaseId, data);
|
|
406
387
|
if (options.json) {
|
|
407
388
|
json(result);
|
|
408
389
|
return;
|
|
409
390
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
}
|
|
414
|
-
// Derive columns from first record
|
|
415
|
-
const cols = Object.keys(data[0]).filter((k) => k !== "type");
|
|
416
|
-
console.log(formatTable(data, cols.map((c) => ({
|
|
417
|
-
header: c.toUpperCase(),
|
|
418
|
-
key: c,
|
|
419
|
-
format: (v) => {
|
|
420
|
-
if (v === null || v === undefined)
|
|
421
|
-
return "—";
|
|
422
|
-
if (typeof v === "object") {
|
|
423
|
-
const s = JSON.stringify(v);
|
|
424
|
-
return s.length > 50 ? s.slice(0, 47) + "..." : s;
|
|
425
|
-
}
|
|
426
|
-
const s = String(v);
|
|
427
|
-
return s.length > 50 ? s.slice(0, 47) + "..." : s;
|
|
428
|
-
},
|
|
429
|
-
}))));
|
|
430
|
-
if (result.hasMore) {
|
|
431
|
-
info(`More records available. Use --cursor ${result.cursor} to continue.`);
|
|
391
|
+
success("Metadata updated.");
|
|
392
|
+
if (result.metadata) {
|
|
393
|
+
keyValue("Metadata", JSON.stringify(result.metadata));
|
|
432
394
|
}
|
|
433
395
|
}
|
|
434
396
|
catch (err) {
|
|
@@ -436,116 +398,134 @@ Examples:
|
|
|
436
398
|
process.exit(1);
|
|
437
399
|
}
|
|
438
400
|
});
|
|
439
|
-
//
|
|
440
|
-
|
|
441
|
-
.command("
|
|
442
|
-
.description("
|
|
401
|
+
// ---- Operations subcommand group ----
|
|
402
|
+
const operations = databases
|
|
403
|
+
.command("operations")
|
|
404
|
+
.description("List and execute registered operations on a database");
|
|
405
|
+
// List operations
|
|
406
|
+
operations
|
|
407
|
+
.command("list")
|
|
408
|
+
.description("List registered operations available on a database")
|
|
443
409
|
.argument("<database-id>", "Database ID")
|
|
444
|
-
.argument("<model-name>", "Model name")
|
|
445
|
-
.option("--filter <json>", "Filter as JSON", "{}")
|
|
446
410
|
.option("--app <app-id>", "App ID")
|
|
447
411
|
.option("--json", "Output as JSON")
|
|
448
|
-
.action(async (databaseId,
|
|
412
|
+
.action(async (databaseId, options) => {
|
|
449
413
|
const resolvedAppId = resolveAppId(undefined, options);
|
|
450
414
|
const client = new ApiClient();
|
|
451
|
-
let filter = {};
|
|
452
|
-
try {
|
|
453
|
-
filter = JSON.parse(options.filter);
|
|
454
|
-
}
|
|
455
|
-
catch {
|
|
456
|
-
error("Invalid --filter JSON.");
|
|
457
|
-
process.exit(1);
|
|
458
|
-
}
|
|
459
415
|
try {
|
|
460
|
-
const result = await client.
|
|
461
|
-
|
|
462
|
-
filter,
|
|
463
|
-
});
|
|
416
|
+
const result = await client.listDatabaseOperations(resolvedAppId, databaseId);
|
|
417
|
+
const list = Array.isArray(result) ? result : [];
|
|
464
418
|
if (options.json) {
|
|
465
|
-
json(
|
|
419
|
+
json(list);
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
if (list.length === 0) {
|
|
423
|
+
info("No operations found.");
|
|
466
424
|
return;
|
|
467
425
|
}
|
|
468
|
-
console.log(
|
|
426
|
+
console.log(formatTable(list, [
|
|
427
|
+
{ header: "NAME", key: "name" },
|
|
428
|
+
{ header: "TYPE", key: "type" },
|
|
429
|
+
{ header: "MODEL", key: "modelName" },
|
|
430
|
+
{ header: "ACCESS", key: "access" },
|
|
431
|
+
]));
|
|
469
432
|
}
|
|
470
433
|
catch (err) {
|
|
471
434
|
error(err.message);
|
|
472
435
|
process.exit(1);
|
|
473
436
|
}
|
|
474
437
|
});
|
|
475
|
-
//
|
|
476
|
-
|
|
477
|
-
.command("
|
|
478
|
-
.description("
|
|
438
|
+
// Execute operation
|
|
439
|
+
operations
|
|
440
|
+
.command("execute")
|
|
441
|
+
.description("Execute a registered operation on a database")
|
|
479
442
|
.argument("<database-id>", "Database ID")
|
|
480
|
-
.argument("<
|
|
481
|
-
.option("--
|
|
482
|
-
.
|
|
443
|
+
.argument("<operation-name>", "Operation name")
|
|
444
|
+
.option("--params <json>", "Operation parameters as JSON")
|
|
445
|
+
.option("--limit <n>", "Max records to return (for queries)")
|
|
446
|
+
.option("--cursor <cursor>", "Pagination cursor")
|
|
447
|
+
.option("--token <jwt>", "Execute as a specific user (dev/test — JWT visible in process args)")
|
|
483
448
|
.option("--app <app-id>", "App ID")
|
|
484
449
|
.option("--json", "Output as JSON")
|
|
485
|
-
.
|
|
450
|
+
.option("--timing", "Show server-side timing breakdown")
|
|
451
|
+
.action(async (databaseId, operationName, options) => {
|
|
486
452
|
const resolvedAppId = resolveAppId(undefined, options);
|
|
487
453
|
const client = new ApiClient();
|
|
488
|
-
let
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
454
|
+
let params;
|
|
455
|
+
if (options.params) {
|
|
456
|
+
try {
|
|
457
|
+
params = JSON.parse(options.params);
|
|
458
|
+
}
|
|
459
|
+
catch {
|
|
460
|
+
error("Invalid --params JSON.");
|
|
461
|
+
process.exit(1);
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
496
464
|
}
|
|
497
|
-
const
|
|
465
|
+
const body = {};
|
|
466
|
+
if (params)
|
|
467
|
+
body.params = params;
|
|
468
|
+
if (options.limit)
|
|
469
|
+
body.limit = parseInt(options.limit, 10);
|
|
470
|
+
if (options.cursor)
|
|
471
|
+
body.cursor = options.cursor;
|
|
498
472
|
try {
|
|
499
|
-
const result = await client.
|
|
500
|
-
modelName,
|
|
501
|
-
id,
|
|
502
|
-
data,
|
|
503
|
-
});
|
|
473
|
+
const result = await client.executeDatabaseOperation(resolvedAppId, databaseId, operationName, body, options.token, { timing: !!options.timing });
|
|
504
474
|
if (options.json) {
|
|
505
475
|
json(result);
|
|
506
476
|
return;
|
|
507
477
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
{
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
if (
|
|
538
|
-
|
|
539
|
-
|
|
478
|
+
// Smart display based on result shape
|
|
479
|
+
if (result.data && Array.isArray(result.data)) {
|
|
480
|
+
if (result.data.length === 0) {
|
|
481
|
+
info("No records found.");
|
|
482
|
+
}
|
|
483
|
+
else {
|
|
484
|
+
const cols = Object.keys(result.data[0]).filter((k) => k !== "type");
|
|
485
|
+
console.log(formatTable(result.data, cols.map((c) => ({
|
|
486
|
+
header: c.toUpperCase(),
|
|
487
|
+
key: c,
|
|
488
|
+
format: (v) => {
|
|
489
|
+
if (v === null || v === undefined)
|
|
490
|
+
return "—";
|
|
491
|
+
if (typeof v === "object") {
|
|
492
|
+
const s = JSON.stringify(v);
|
|
493
|
+
return s.length > 50 ? s.slice(0, 47) + "..." : s;
|
|
494
|
+
}
|
|
495
|
+
const s = String(v);
|
|
496
|
+
return s.length > 50 ? s.slice(0, 47) + "..." : s;
|
|
497
|
+
},
|
|
498
|
+
}))));
|
|
499
|
+
}
|
|
500
|
+
if (result.hasMore) {
|
|
501
|
+
info(`More records available. Use --cursor ${result.cursor} to continue.`);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
else if (result.count !== undefined) {
|
|
505
|
+
console.log(`Count: ${result.count}`);
|
|
506
|
+
}
|
|
507
|
+
else if (result.result !== undefined) {
|
|
508
|
+
// Aggregate result
|
|
509
|
+
json(result);
|
|
510
|
+
}
|
|
511
|
+
else if (result.results && Array.isArray(result.results)) {
|
|
512
|
+
// Batch/mutation results
|
|
513
|
+
success(`Operation executed (${result.results.length} result${result.results.length === 1 ? "" : "s"}).`);
|
|
514
|
+
}
|
|
515
|
+
else if (result.success !== undefined) {
|
|
516
|
+
success("Operation executed.");
|
|
517
|
+
}
|
|
518
|
+
else {
|
|
519
|
+
json(result);
|
|
520
|
+
}
|
|
521
|
+
// Display timing if present
|
|
522
|
+
if (result._timing) {
|
|
523
|
+
console.log("");
|
|
524
|
+
console.log("Timing:");
|
|
525
|
+
for (const [key, value] of Object.entries(result._timing)) {
|
|
526
|
+
console.log(` ${key}: ${value}ms`);
|
|
527
|
+
}
|
|
540
528
|
}
|
|
541
|
-
}
|
|
542
|
-
const client = new ApiClient();
|
|
543
|
-
try {
|
|
544
|
-
await client.deleteDatabaseRecord(resolvedAppId, databaseId, {
|
|
545
|
-
modelName,
|
|
546
|
-
id: recordId,
|
|
547
|
-
});
|
|
548
|
-
success(`Record ${recordId} deleted.`);
|
|
549
529
|
}
|
|
550
530
|
catch (err) {
|
|
551
531
|
error(err.message);
|
|
@@ -661,108 +641,5 @@ Examples:
|
|
|
661
641
|
process.exit(1);
|
|
662
642
|
}
|
|
663
643
|
});
|
|
664
|
-
// ---- Group Permissions subcommand group ----
|
|
665
|
-
const groupPermissions = databases
|
|
666
|
-
.command("group-permissions")
|
|
667
|
-
.description("Manage group permissions on a database");
|
|
668
|
-
// List group permissions
|
|
669
|
-
groupPermissions
|
|
670
|
-
.command("list")
|
|
671
|
-
.description("List group permissions for a database")
|
|
672
|
-
.argument("<database-id>", "Database ID")
|
|
673
|
-
.option("--app <app-id>", "App ID")
|
|
674
|
-
.option("--json", "Output as JSON")
|
|
675
|
-
.action(async (databaseId, options) => {
|
|
676
|
-
const resolvedAppId = resolveAppId(undefined, options);
|
|
677
|
-
const client = new ApiClient();
|
|
678
|
-
try {
|
|
679
|
-
const result = await client.listDatabaseGroupPermissions(resolvedAppId, databaseId);
|
|
680
|
-
const list = Array.isArray(result) ? result : result?.permissions ?? [];
|
|
681
|
-
if (options.json) {
|
|
682
|
-
json(list);
|
|
683
|
-
return;
|
|
684
|
-
}
|
|
685
|
-
if (list.length === 0) {
|
|
686
|
-
info("No group permissions found.");
|
|
687
|
-
return;
|
|
688
|
-
}
|
|
689
|
-
console.log(formatTable(list, [
|
|
690
|
-
{ header: "GROUP_TYPE", key: "groupType" },
|
|
691
|
-
{ header: "GROUP_ID", key: "groupId" },
|
|
692
|
-
{ header: "PERMISSION", key: "permission" },
|
|
693
|
-
{ header: "GRANTED", key: "grantedAt", format: formatDate },
|
|
694
|
-
]));
|
|
695
|
-
}
|
|
696
|
-
catch (err) {
|
|
697
|
-
error(err.message);
|
|
698
|
-
process.exit(1);
|
|
699
|
-
}
|
|
700
|
-
});
|
|
701
|
-
// Grant group permission
|
|
702
|
-
groupPermissions
|
|
703
|
-
.command("grant")
|
|
704
|
-
.description("Grant a group permission on a database")
|
|
705
|
-
.argument("<database-id>", "Database ID")
|
|
706
|
-
.requiredOption("--group-type <type>", "Group type")
|
|
707
|
-
.requiredOption("--group-id <id>", "Group ID")
|
|
708
|
-
.requiredOption("--permission <permission>", "Permission level: read-write or reader")
|
|
709
|
-
.option("--app <app-id>", "App ID")
|
|
710
|
-
.option("--json", "Output as JSON")
|
|
711
|
-
.action(async (databaseId, options) => {
|
|
712
|
-
const resolvedAppId = resolveAppId(undefined, options);
|
|
713
|
-
const client = new ApiClient();
|
|
714
|
-
try {
|
|
715
|
-
const result = await client.grantDatabaseGroupPermission(resolvedAppId, databaseId, {
|
|
716
|
-
groupType: options.groupType,
|
|
717
|
-
groupId: options.groupId,
|
|
718
|
-
permission: options.permission,
|
|
719
|
-
});
|
|
720
|
-
if (options.json) {
|
|
721
|
-
json(result);
|
|
722
|
-
return;
|
|
723
|
-
}
|
|
724
|
-
success(`Permission '${options.permission}' granted to group ${options.groupType}/${options.groupId}.`);
|
|
725
|
-
}
|
|
726
|
-
catch (err) {
|
|
727
|
-
error(err.message);
|
|
728
|
-
process.exit(1);
|
|
729
|
-
}
|
|
730
|
-
});
|
|
731
|
-
// Revoke group permission
|
|
732
|
-
groupPermissions
|
|
733
|
-
.command("revoke")
|
|
734
|
-
.description("Revoke a group's permission on a database")
|
|
735
|
-
.argument("<database-id>", "Database ID")
|
|
736
|
-
.argument("<group-type>", "Group type")
|
|
737
|
-
.argument("<group-id>", "Group ID")
|
|
738
|
-
.option("--app <app-id>", "App ID")
|
|
739
|
-
.option("-y, --yes", "Skip confirmation prompt")
|
|
740
|
-
.action(async (databaseId, groupType, groupId, options) => {
|
|
741
|
-
const resolvedAppId = resolveAppId(undefined, options);
|
|
742
|
-
if (!options.yes) {
|
|
743
|
-
const inquirer = await import("inquirer");
|
|
744
|
-
const { confirm } = await inquirer.default.prompt([
|
|
745
|
-
{
|
|
746
|
-
type: "confirm",
|
|
747
|
-
name: "confirm",
|
|
748
|
-
message: `Revoke permission for group ${groupType}/${groupId} on database ${databaseId}?`,
|
|
749
|
-
default: false,
|
|
750
|
-
},
|
|
751
|
-
]);
|
|
752
|
-
if (!confirm) {
|
|
753
|
-
info("Cancelled.");
|
|
754
|
-
return;
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
const client = new ApiClient();
|
|
758
|
-
try {
|
|
759
|
-
await client.revokeDatabaseGroupPermission(resolvedAppId, databaseId, groupType, groupId);
|
|
760
|
-
success(`Permission revoked for group ${groupType}/${groupId}.`);
|
|
761
|
-
}
|
|
762
|
-
catch (err) {
|
|
763
|
-
error(err.message);
|
|
764
|
-
process.exit(1);
|
|
765
|
-
}
|
|
766
|
-
});
|
|
767
644
|
}
|
|
768
645
|
//# sourceMappingURL=databases.js.map
|