primitive-admin 1.0.21 → 1.0.22
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/src/commands/databases.js +768 -0
- package/dist/src/commands/databases.js.map +1 -0
- package/dist/src/commands/groups.js +432 -0
- package/dist/src/commands/groups.js.map +1 -0
- package/dist/src/commands/rule-sets.js +274 -0
- package/dist/src/commands/rule-sets.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { ApiClient } from "../lib/api-client.js";
|
|
2
|
+
import { getCurrentAppId } from "../lib/config.js";
|
|
3
|
+
import { success, error, info, keyValue, formatTable, formatId, formatDate, json, } from "../lib/output.js";
|
|
4
|
+
function resolveAppId(appId, options) {
|
|
5
|
+
const resolved = appId || options.app || getCurrentAppId();
|
|
6
|
+
if (!resolved) {
|
|
7
|
+
error("No app specified. Use <app-id>, --app, or 'primitive use <app-id>' to set context.");
|
|
8
|
+
process.exit(1);
|
|
9
|
+
}
|
|
10
|
+
return resolved;
|
|
11
|
+
}
|
|
12
|
+
export function registerRuleSetsCommands(program) {
|
|
13
|
+
const ruleSets = program
|
|
14
|
+
.command("rule-sets")
|
|
15
|
+
.description("Create and manage access rule sets for databases")
|
|
16
|
+
.addHelpText("after", `
|
|
17
|
+
Examples:
|
|
18
|
+
$ primitive rule-sets list
|
|
19
|
+
$ primitive rule-sets create "My Rules" --resource-type database --rules '{"Task":{"read":"true","write":"record.createdBy == user.userId"}}'
|
|
20
|
+
$ primitive rule-sets get <rule-set-id>
|
|
21
|
+
$ primitive rule-sets update <rule-set-id> --name "Updated Rules"
|
|
22
|
+
$ primitive rule-sets delete <rule-set-id>
|
|
23
|
+
$ primitive rule-sets attach <rule-set-id> --database <database-id>
|
|
24
|
+
$ primitive rule-sets detach --database <database-id>
|
|
25
|
+
`);
|
|
26
|
+
// List rule sets
|
|
27
|
+
ruleSets
|
|
28
|
+
.command("list")
|
|
29
|
+
.description("List access rule sets in an app")
|
|
30
|
+
.argument("[app-id]", "App ID (uses current app if not specified)")
|
|
31
|
+
.option("--app <app-id>", "App ID")
|
|
32
|
+
.option("--resource-type <type>", "Filter by resource type (database, document, workflow, api)")
|
|
33
|
+
.option("--json", "Output as JSON")
|
|
34
|
+
.action(async (appId, options) => {
|
|
35
|
+
const resolvedAppId = resolveAppId(appId, options);
|
|
36
|
+
const client = new ApiClient();
|
|
37
|
+
try {
|
|
38
|
+
const params = {};
|
|
39
|
+
if (options.resourceType)
|
|
40
|
+
params.resourceType = options.resourceType;
|
|
41
|
+
const result = await client.listRuleSets(resolvedAppId, params);
|
|
42
|
+
const list = Array.isArray(result) ? result : result?.ruleSets ?? [];
|
|
43
|
+
if (options.json) {
|
|
44
|
+
json(list);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (list.length === 0) {
|
|
48
|
+
info("No rule sets found.");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
console.log(formatTable(list, [
|
|
52
|
+
{ header: "ID", key: "ruleSetId", format: formatId },
|
|
53
|
+
{ header: "NAME", key: "name" },
|
|
54
|
+
{ header: "TYPE", key: "resourceType" },
|
|
55
|
+
{ header: "VERSION", key: "version" },
|
|
56
|
+
{ header: "MODIFIED", key: "modifiedAt", format: formatDate },
|
|
57
|
+
]));
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
error(err.message);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
// Create rule set
|
|
65
|
+
ruleSets
|
|
66
|
+
.command("create")
|
|
67
|
+
.description("Create a new access rule set")
|
|
68
|
+
.argument("<name>", "Rule set name")
|
|
69
|
+
.requiredOption("--resource-type <type>", "Resource type: database, document, workflow, or api")
|
|
70
|
+
.requiredOption("--rules <json>", "Rules as JSON string")
|
|
71
|
+
.option("--description <text>", "Optional description")
|
|
72
|
+
.option("--app <app-id>", "App ID")
|
|
73
|
+
.option("--json", "Output as JSON")
|
|
74
|
+
.action(async (name, options) => {
|
|
75
|
+
const resolvedAppId = resolveAppId(undefined, options);
|
|
76
|
+
const client = new ApiClient();
|
|
77
|
+
let rules;
|
|
78
|
+
try {
|
|
79
|
+
rules = JSON.parse(options.rules);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
error("Invalid JSON in --rules. Provide a valid JSON object.");
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
const data = {
|
|
87
|
+
name,
|
|
88
|
+
resourceType: options.resourceType,
|
|
89
|
+
rules,
|
|
90
|
+
};
|
|
91
|
+
if (options.description)
|
|
92
|
+
data.description = options.description;
|
|
93
|
+
const result = await client.createRuleSet(resolvedAppId, data);
|
|
94
|
+
if (options.json) {
|
|
95
|
+
json(result);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
success("Rule set created.");
|
|
99
|
+
keyValue("Rule Set ID", result.ruleSetId);
|
|
100
|
+
keyValue("Name", result.name);
|
|
101
|
+
keyValue("Resource Type", result.resourceType);
|
|
102
|
+
keyValue("Version", result.version);
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
error(err.message);
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
// Get rule set
|
|
110
|
+
ruleSets
|
|
111
|
+
.command("get")
|
|
112
|
+
.description("Get rule set details")
|
|
113
|
+
.argument("<rule-set-id>", "Rule set ID")
|
|
114
|
+
.option("--app <app-id>", "App ID")
|
|
115
|
+
.option("--json", "Output as JSON")
|
|
116
|
+
.action(async (ruleSetId, options) => {
|
|
117
|
+
const resolvedAppId = resolveAppId(undefined, options);
|
|
118
|
+
const client = new ApiClient();
|
|
119
|
+
try {
|
|
120
|
+
const result = await client.getRuleSet(resolvedAppId, ruleSetId);
|
|
121
|
+
if (options.json) {
|
|
122
|
+
json(result);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
keyValue("Rule Set ID", result.ruleSetId);
|
|
126
|
+
keyValue("Name", result.name);
|
|
127
|
+
if (result.description)
|
|
128
|
+
keyValue("Description", result.description);
|
|
129
|
+
keyValue("Resource Type", result.resourceType);
|
|
130
|
+
keyValue("Version", String(result.version));
|
|
131
|
+
keyValue("Created", formatDate(result.createdAt));
|
|
132
|
+
keyValue("Modified", formatDate(result.modifiedAt));
|
|
133
|
+
console.log("\nRules:");
|
|
134
|
+
console.log(JSON.stringify(result.rules, null, 2));
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
error(err.message);
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
// Update rule set
|
|
142
|
+
ruleSets
|
|
143
|
+
.command("update")
|
|
144
|
+
.description("Update a rule set")
|
|
145
|
+
.argument("<rule-set-id>", "Rule set ID")
|
|
146
|
+
.option("--name <name>", "New name")
|
|
147
|
+
.option("--description <text>", "New description")
|
|
148
|
+
.option("--rules <json>", "New rules as JSON string")
|
|
149
|
+
.option("--app <app-id>", "App ID")
|
|
150
|
+
.option("--json", "Output as JSON")
|
|
151
|
+
.action(async (ruleSetId, options) => {
|
|
152
|
+
const resolvedAppId = resolveAppId(undefined, options);
|
|
153
|
+
const client = new ApiClient();
|
|
154
|
+
const data = {};
|
|
155
|
+
if (options.name)
|
|
156
|
+
data.name = options.name;
|
|
157
|
+
if (options.description !== undefined)
|
|
158
|
+
data.description = options.description;
|
|
159
|
+
if (options.rules) {
|
|
160
|
+
try {
|
|
161
|
+
data.rules = JSON.parse(options.rules);
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
error("Invalid JSON in --rules. Provide a valid JSON object.");
|
|
165
|
+
process.exit(1);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (Object.keys(data).length === 0) {
|
|
169
|
+
error("Nothing to update. Provide --name, --description, or --rules.");
|
|
170
|
+
process.exit(1);
|
|
171
|
+
}
|
|
172
|
+
try {
|
|
173
|
+
const result = await client.updateRuleSet(resolvedAppId, ruleSetId, data);
|
|
174
|
+
if (options.json) {
|
|
175
|
+
json(result);
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
success("Rule set updated.");
|
|
179
|
+
keyValue("Rule Set ID", result.ruleSetId);
|
|
180
|
+
keyValue("Name", result.name);
|
|
181
|
+
keyValue("Version", String(result.version));
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
error(err.message);
|
|
185
|
+
process.exit(1);
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
// Delete rule set
|
|
189
|
+
ruleSets
|
|
190
|
+
.command("delete")
|
|
191
|
+
.description("Delete a rule set")
|
|
192
|
+
.argument("<rule-set-id>", "Rule set ID")
|
|
193
|
+
.option("--app <app-id>", "App ID")
|
|
194
|
+
.option("-y, --yes", "Skip confirmation prompt")
|
|
195
|
+
.action(async (ruleSetId, options) => {
|
|
196
|
+
const resolvedAppId = resolveAppId(undefined, options);
|
|
197
|
+
if (!options.yes) {
|
|
198
|
+
const inquirer = await import("inquirer");
|
|
199
|
+
const { confirm } = await inquirer.default.prompt([
|
|
200
|
+
{
|
|
201
|
+
type: "confirm",
|
|
202
|
+
name: "confirm",
|
|
203
|
+
message: `Delete rule set ${ruleSetId}? This cannot be undone.`,
|
|
204
|
+
default: false,
|
|
205
|
+
},
|
|
206
|
+
]);
|
|
207
|
+
if (!confirm) {
|
|
208
|
+
info("Cancelled.");
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
const client = new ApiClient();
|
|
213
|
+
try {
|
|
214
|
+
await client.deleteRuleSet(resolvedAppId, ruleSetId);
|
|
215
|
+
success(`Rule set ${ruleSetId} deleted.`);
|
|
216
|
+
}
|
|
217
|
+
catch (err) {
|
|
218
|
+
error(err.message);
|
|
219
|
+
process.exit(1);
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
// Attach rule set to a database
|
|
223
|
+
ruleSets
|
|
224
|
+
.command("attach")
|
|
225
|
+
.description("Attach a rule set to a database")
|
|
226
|
+
.argument("<rule-set-id>", "Rule set ID")
|
|
227
|
+
.requiredOption("--database <database-id>", "Database ID to attach the rule set to")
|
|
228
|
+
.option("--app <app-id>", "App ID")
|
|
229
|
+
.option("--json", "Output as JSON")
|
|
230
|
+
.action(async (ruleSetId, options) => {
|
|
231
|
+
const resolvedAppId = resolveAppId(undefined, options);
|
|
232
|
+
const client = new ApiClient();
|
|
233
|
+
try {
|
|
234
|
+
const result = await client.updateDatabase(resolvedAppId, options.database, {
|
|
235
|
+
ruleSetId,
|
|
236
|
+
});
|
|
237
|
+
if (options.json) {
|
|
238
|
+
json(result);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
success(`Rule set ${ruleSetId} attached to database ${options.database}.`);
|
|
242
|
+
}
|
|
243
|
+
catch (err) {
|
|
244
|
+
error(err.message);
|
|
245
|
+
process.exit(1);
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
// Detach rule set from a database
|
|
249
|
+
ruleSets
|
|
250
|
+
.command("detach")
|
|
251
|
+
.description("Detach the rule set from a database")
|
|
252
|
+
.requiredOption("--database <database-id>", "Database ID to detach the rule set from")
|
|
253
|
+
.option("--app <app-id>", "App ID")
|
|
254
|
+
.option("--json", "Output as JSON")
|
|
255
|
+
.action(async (options) => {
|
|
256
|
+
const resolvedAppId = resolveAppId(undefined, options);
|
|
257
|
+
const client = new ApiClient();
|
|
258
|
+
try {
|
|
259
|
+
const result = await client.updateDatabase(resolvedAppId, options.database, {
|
|
260
|
+
ruleSetId: null,
|
|
261
|
+
});
|
|
262
|
+
if (options.json) {
|
|
263
|
+
json(result);
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
success(`Rule set detached from database ${options.database}.`);
|
|
267
|
+
}
|
|
268
|
+
catch (err) {
|
|
269
|
+
error(err.message);
|
|
270
|
+
process.exit(1);
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=rule-sets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-sets.js","sourceRoot":"","sources":["../../../src/commands/rule-sets.ts"],"names":[],"mappings":"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"}
|