@tolinax/ayoune-cli 2026.2.4 → 2026.3.1

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.
Files changed (90) hide show
  1. package/package.json +160 -158
  2. package/data/defaultActions.js +0 -9
  3. package/data/modelsAndRights.js +0 -3189
  4. package/data/modules.js +0 -111
  5. package/data/operations.js +0 -5
  6. package/data/services.js +0 -139
  7. package/index.js +0 -11
  8. package/lib/api/apiCallHandler.js +0 -68
  9. package/lib/api/apiClient.js +0 -100
  10. package/lib/api/auditCallHandler.js +0 -21
  11. package/lib/api/decodeToken.js +0 -4
  12. package/lib/api/handleAPIError.js +0 -59
  13. package/lib/api/login.js +0 -45
  14. package/lib/commands/createActionsCommand.js +0 -109
  15. package/lib/commands/createAiCommand.js +0 -188
  16. package/lib/commands/createAliasCommand.js +0 -106
  17. package/lib/commands/createAuditCommand.js +0 -49
  18. package/lib/commands/createBatchCommand.js +0 -304
  19. package/lib/commands/createCompletionsCommand.js +0 -169
  20. package/lib/commands/createConfigCommand.js +0 -208
  21. package/lib/commands/createCopyCommand.js +0 -39
  22. package/lib/commands/createCreateCommand.js +0 -50
  23. package/lib/commands/createDeleteCommand.js +0 -98
  24. package/lib/commands/createDeployCommand.js +0 -666
  25. package/lib/commands/createDescribeCommand.js +0 -42
  26. package/lib/commands/createEditCommand.js +0 -43
  27. package/lib/commands/createEventsCommand.js +0 -60
  28. package/lib/commands/createExecCommand.js +0 -182
  29. package/lib/commands/createExportCommand.js +0 -219
  30. package/lib/commands/createGetCommand.js +0 -47
  31. package/lib/commands/createJobsCommand.js +0 -168
  32. package/lib/commands/createListCommand.js +0 -49
  33. package/lib/commands/createLoginCommand.js +0 -18
  34. package/lib/commands/createLogoutCommand.js +0 -21
  35. package/lib/commands/createModulesCommand.js +0 -89
  36. package/lib/commands/createMonitorCommand.js +0 -283
  37. package/lib/commands/createPermissionsCommand.js +0 -241
  38. package/lib/commands/createProgram.js +0 -185
  39. package/lib/commands/createSearchCommand.js +0 -101
  40. package/lib/commands/createServicesCommand.js +0 -228
  41. package/lib/commands/createStorageCommand.js +0 -54
  42. package/lib/commands/createStreamCommand.js +0 -50
  43. package/lib/commands/createSyncCommand.js +0 -177
  44. package/lib/commands/createTemplateCommand.js +0 -238
  45. package/lib/commands/createUpdateCommand.js +0 -115
  46. package/lib/commands/createUsersCommand.js +0 -285
  47. package/lib/commands/createWebhooksCommand.js +0 -156
  48. package/lib/commands/createWhoAmICommand.js +0 -88
  49. package/lib/exitCodes.js +0 -6
  50. package/lib/helpers/addSpacesToCamelCase.js +0 -5
  51. package/lib/helpers/config.js +0 -6
  52. package/lib/helpers/configLoader.js +0 -60
  53. package/lib/helpers/formatDocument.js +0 -176
  54. package/lib/helpers/handleResponseFormatOptions.js +0 -85
  55. package/lib/helpers/initializeSettings.js +0 -14
  56. package/lib/helpers/localStorage.js +0 -4
  57. package/lib/helpers/makeRandomToken.js +0 -27
  58. package/lib/helpers/parseInt.js +0 -7
  59. package/lib/helpers/requireArg.js +0 -9
  60. package/lib/helpers/saveFile.js +0 -39
  61. package/lib/models/getCollections.js +0 -15
  62. package/lib/models/getModelsInModules.js +0 -13
  63. package/lib/models/getModuleFromCollection.js +0 -7
  64. package/lib/operations/handleAuditOperation.js +0 -22
  65. package/lib/operations/handleCollectionOperation.js +0 -91
  66. package/lib/operations/handleCopySingleOperation.js +0 -22
  67. package/lib/operations/handleCreateSingleOperation.js +0 -35
  68. package/lib/operations/handleDeleteSingleOperation.js +0 -14
  69. package/lib/operations/handleDescribeSingleOperation.js +0 -22
  70. package/lib/operations/handleEditOperation.js +0 -51
  71. package/lib/operations/handleEditRawOperation.js +0 -35
  72. package/lib/operations/handleGetOperation.js +0 -29
  73. package/lib/operations/handleGetSingleOperation.js +0 -20
  74. package/lib/operations/handleListOperation.js +0 -63
  75. package/lib/operations/handleSingleAuditOperation.js +0 -27
  76. package/lib/prompts/promptAudits.js +0 -15
  77. package/lib/prompts/promptCollection.js +0 -13
  78. package/lib/prompts/promptCollectionInModule.js +0 -13
  79. package/lib/prompts/promptCollectionWithModule.js +0 -15
  80. package/lib/prompts/promptConfirm.js +0 -12
  81. package/lib/prompts/promptDefaultAction.js +0 -13
  82. package/lib/prompts/promptEntry.js +0 -19
  83. package/lib/prompts/promptFileName.js +0 -12
  84. package/lib/prompts/promptFilePath.js +0 -18
  85. package/lib/prompts/promptModule.js +0 -19
  86. package/lib/prompts/promptName.js +0 -11
  87. package/lib/prompts/promptOperation.js +0 -13
  88. package/lib/socket/customerSocketClient.js +0 -13
  89. package/lib/socket/socketClient.js +0 -12
  90. package/lib/types.js +0 -1
@@ -1,238 +0,0 @@
1
- import { apiCallHandler } from "../api/apiCallHandler.js";
2
- import { handleResponseFormatOptions } from "../helpers/handleResponseFormatOptions.js";
3
- import { saveFile } from "../helpers/saveFile.js";
4
- import { spinner } from "../../index.js";
5
- import { EXIT_GENERAL_ERROR } from "../exitCodes.js";
6
- export function createTemplateCommand(program) {
7
- const tmpl = program
8
- .command("templates")
9
- .alias("tmpl")
10
- .description("Manage platform templates (email, notification, report, store)");
11
- // ── EMAIL TEMPLATES ────────────────────────────────────
12
- const email = tmpl
13
- .command("email")
14
- .description("Manage email templates");
15
- // ay templates email list
16
- email
17
- .command("list")
18
- .alias("ls")
19
- .description("List email templates")
20
- .option("--search <query>", "Search by name")
21
- .option("-l, --limit <number>", "Limit results", parseInt, 50)
22
- .option("-p, --page <number>", "Page number", parseInt, 1)
23
- .action(async (options) => {
24
- var _a, _b, _c;
25
- try {
26
- const opts = { ...program.opts(), ...options };
27
- spinner.start({ text: "Fetching email templates...", color: "magenta" });
28
- const params = {
29
- page: opts.page,
30
- limit: opts.limit,
31
- responseFormat: opts.responseFormat,
32
- verbosity: opts.verbosity,
33
- };
34
- if (opts.search)
35
- params.q = opts.search;
36
- const res = await apiCallHandler("marketing", "emailtemplates", "get", null, params);
37
- handleResponseFormatOptions(opts, res);
38
- const total = (_c = (_b = (_a = res.meta) === null || _a === void 0 ? void 0 : _a.pageInfo) === null || _b === void 0 ? void 0 : _b.totalEntries) !== null && _c !== void 0 ? _c : 0;
39
- spinner.success({ text: `Found ${total} email templates` });
40
- spinner.stop();
41
- if (opts.save)
42
- await saveFile("email-templates", opts, res);
43
- }
44
- catch (e) {
45
- spinner.error({ text: e.message || "Failed to list email templates" });
46
- process.exit(EXIT_GENERAL_ERROR);
47
- }
48
- });
49
- // ay templates email get <id>
50
- email
51
- .command("get <id>")
52
- .description("Get email template details")
53
- .action(async (id, options) => {
54
- try {
55
- const opts = { ...program.opts(), ...options };
56
- spinner.start({ text: `Fetching email template ${id}...`, color: "magenta" });
57
- const res = await apiCallHandler("marketing", `emailtemplates/${id}`, "get", null, {
58
- responseFormat: opts.responseFormat,
59
- verbosity: opts.verbosity,
60
- });
61
- handleResponseFormatOptions(opts, res);
62
- spinner.success({ text: `Email template ${id} loaded` });
63
- spinner.stop();
64
- }
65
- catch (e) {
66
- spinner.error({ text: e.message || "Failed to get email template" });
67
- process.exit(EXIT_GENERAL_ERROR);
68
- }
69
- });
70
- // ── NOTIFICATION TEMPLATES ─────────────────────────────
71
- const notify = tmpl
72
- .command("notification")
73
- .alias("notify")
74
- .description("Manage notification templates");
75
- // ay templates notification list
76
- notify
77
- .command("list")
78
- .alias("ls")
79
- .description("List notification templates")
80
- .option("-l, --limit <number>", "Limit results", parseInt, 50)
81
- .option("-p, --page <number>", "Page number", parseInt, 1)
82
- .action(async (options) => {
83
- var _a, _b, _c;
84
- try {
85
- const opts = { ...program.opts(), ...options };
86
- spinner.start({ text: "Fetching notification templates...", color: "magenta" });
87
- const res = await apiCallHandler("config", "notificationtemplates", "get", null, {
88
- page: opts.page,
89
- limit: opts.limit,
90
- responseFormat: opts.responseFormat,
91
- verbosity: opts.verbosity,
92
- });
93
- handleResponseFormatOptions(opts, res);
94
- const total = (_c = (_b = (_a = res.meta) === null || _a === void 0 ? void 0 : _a.pageInfo) === null || _b === void 0 ? void 0 : _b.totalEntries) !== null && _c !== void 0 ? _c : 0;
95
- spinner.success({ text: `Found ${total} notification templates` });
96
- spinner.stop();
97
- if (opts.save)
98
- await saveFile("notification-templates", opts, res);
99
- }
100
- catch (e) {
101
- spinner.error({ text: e.message || "Failed to list notification templates" });
102
- process.exit(EXIT_GENERAL_ERROR);
103
- }
104
- });
105
- // ay templates notification get <id>
106
- notify
107
- .command("get <id>")
108
- .description("Get notification template details")
109
- .action(async (id, options) => {
110
- try {
111
- const opts = { ...program.opts(), ...options };
112
- spinner.start({ text: `Fetching notification template ${id}...`, color: "magenta" });
113
- const res = await apiCallHandler("config", `notificationtemplates/${id}`, "get", null, {
114
- responseFormat: opts.responseFormat,
115
- verbosity: opts.verbosity,
116
- });
117
- handleResponseFormatOptions(opts, res);
118
- spinner.success({ text: `Notification template ${id} loaded` });
119
- spinner.stop();
120
- }
121
- catch (e) {
122
- spinner.error({ text: e.message || "Failed to get notification template" });
123
- process.exit(EXIT_GENERAL_ERROR);
124
- }
125
- });
126
- // ── REPORT TEMPLATES ───────────────────────────────────
127
- const report = tmpl
128
- .command("report")
129
- .description("Manage report templates");
130
- // ay templates report list
131
- report
132
- .command("list")
133
- .alias("ls")
134
- .description("List report templates")
135
- .option("-l, --limit <number>", "Limit results", parseInt, 50)
136
- .action(async (options) => {
137
- var _a, _b, _c;
138
- try {
139
- const opts = { ...program.opts(), ...options };
140
- spinner.start({ text: "Fetching report templates...", color: "magenta" });
141
- const res = await apiCallHandler("reporting", "reporttemplates", "get", null, {
142
- limit: opts.limit,
143
- responseFormat: opts.responseFormat,
144
- verbosity: opts.verbosity,
145
- });
146
- handleResponseFormatOptions(opts, res);
147
- const total = (_c = (_b = (_a = res.meta) === null || _a === void 0 ? void 0 : _a.pageInfo) === null || _b === void 0 ? void 0 : _b.totalEntries) !== null && _c !== void 0 ? _c : 0;
148
- spinner.success({ text: `Found ${total} report templates` });
149
- spinner.stop();
150
- if (opts.save)
151
- await saveFile("report-templates", opts, res);
152
- }
153
- catch (e) {
154
- spinner.error({ text: e.message || "Failed to list report templates" });
155
- process.exit(EXIT_GENERAL_ERROR);
156
- }
157
- });
158
- // ── STORE TEMPLATES ────────────────────────────────────
159
- const store = tmpl
160
- .command("store")
161
- .description("Browse template store / marketplace");
162
- // ay templates store list
163
- store
164
- .command("list")
165
- .alias("ls")
166
- .description("List available store templates")
167
- .option("--category <category>", "Filter by category")
168
- .option("--search <query>", "Search templates")
169
- .option("-l, --limit <number>", "Limit results", parseInt, 50)
170
- .option("-p, --page <number>", "Page number", parseInt, 1)
171
- .action(async (options) => {
172
- var _a, _b, _c;
173
- try {
174
- const opts = { ...program.opts(), ...options };
175
- spinner.start({ text: "Fetching store templates...", color: "magenta" });
176
- const params = {
177
- page: opts.page,
178
- limit: opts.limit,
179
- responseFormat: opts.responseFormat,
180
- verbosity: opts.verbosity,
181
- };
182
- if (opts.category)
183
- params.category = opts.category;
184
- if (opts.search)
185
- params.q = opts.search;
186
- const res = await apiCallHandler("config", "templategroups", "get", null, params);
187
- handleResponseFormatOptions(opts, res);
188
- const total = (_c = (_b = (_a = res.meta) === null || _a === void 0 ? void 0 : _a.pageInfo) === null || _b === void 0 ? void 0 : _b.totalEntries) !== null && _c !== void 0 ? _c : 0;
189
- spinner.success({ text: `Found ${total} store templates` });
190
- spinner.stop();
191
- if (opts.save)
192
- await saveFile("store-templates", opts, res);
193
- }
194
- catch (e) {
195
- spinner.error({ text: e.message || "Failed to list store templates" });
196
- process.exit(EXIT_GENERAL_ERROR);
197
- }
198
- });
199
- // ay templates store get <id>
200
- store
201
- .command("get <id>")
202
- .description("Get store template details")
203
- .action(async (id, options) => {
204
- try {
205
- const opts = { ...program.opts(), ...options };
206
- spinner.start({ text: `Fetching store template ${id}...`, color: "magenta" });
207
- const res = await apiCallHandler("config", `templategroups/${id}`, "get", null, {
208
- responseFormat: opts.responseFormat,
209
- verbosity: opts.verbosity,
210
- });
211
- handleResponseFormatOptions(opts, res);
212
- spinner.success({ text: `Store template ${id} loaded` });
213
- spinner.stop();
214
- }
215
- catch (e) {
216
- spinner.error({ text: e.message || "Failed to get store template" });
217
- process.exit(EXIT_GENERAL_ERROR);
218
- }
219
- });
220
- // ay templates store install <id>
221
- store
222
- .command("install <id>")
223
- .description("Install a template from the store")
224
- .action(async (id, options) => {
225
- try {
226
- const opts = { ...program.opts(), ...options };
227
- spinner.start({ text: `Installing template ${id}...`, color: "magenta" });
228
- const res = await apiCallHandler("config", `templategroups/${id}/install`, "post", null, { responseFormat: opts.responseFormat });
229
- handleResponseFormatOptions(opts, res);
230
- spinner.success({ text: `Template ${id} installed` });
231
- spinner.stop();
232
- }
233
- catch (e) {
234
- spinner.error({ text: e.message || "Failed to install template" });
235
- process.exit(EXIT_GENERAL_ERROR);
236
- }
237
- });
238
- }
@@ -1,115 +0,0 @@
1
- import { Argument } from "commander";
2
- import { getModuleFromCollection } from "../models/getModuleFromCollection.js";
3
- import { apiCallHandler } from "../api/apiCallHandler.js";
4
- import { handleResponseFormatOptions } from "../helpers/handleResponseFormatOptions.js";
5
- import { saveFile } from "../helpers/saveFile.js";
6
- import { localStorage } from "../helpers/localStorage.js";
7
- import { spinner } from "../../index.js";
8
- import { EXIT_GENERAL_ERROR, EXIT_MISUSE } from "../exitCodes.js";
9
- export function createUpdateCommand(program) {
10
- program
11
- .command("update")
12
- .alias("u")
13
- .description("Update an entry non-interactively (for scripts and AI agents)")
14
- .addHelpText("after", `
15
- Unlike 'edit' (which opens an interactive editor), 'update' accepts changes
16
- as JSON via --body, --body-file, or --body-stdin. Perfect for automation.
17
-
18
- Examples:
19
- ay update contacts 64a1b2c3 --body '{"firstName":"Jane"}'
20
- ay update products 64a1b2c3 --body-file changes.json
21
- echo '{"status":"active"}' | ay update contacts 64a1b2c3 --body-stdin
22
- ay u tasks 64a1b2c3 --body '{"done":true}' --force`)
23
- .addArgument(new Argument("[collection]", "The collection to use").default(localStorage.getItem("lastCollection"), `The last used collection (${localStorage.getItem("lastCollection")})`))
24
- .addArgument(new Argument("[id]", "The ID of the entry to update").default(localStorage.getItem("lastId"), `The last used id (${localStorage.getItem("lastId")})`))
25
- .option("--body <json>", "Update data as JSON string")
26
- .option("--body-file <path>", "Read update data from JSON file")
27
- .option("--body-stdin", "Read update data from stdin")
28
- .option("--merge", "Merge with existing entry (GET + merge + PUT)", false)
29
- .action(async (collection, id, options) => {
30
- try {
31
- if (!collection) {
32
- spinner.error({ text: "Missing required argument: collection" });
33
- process.exit(EXIT_MISUSE);
34
- }
35
- if (!id) {
36
- spinner.error({ text: "Missing required argument: id" });
37
- process.exit(EXIT_MISUSE);
38
- }
39
- const opts = { ...program.opts(), ...options };
40
- const module = getModuleFromCollection(collection);
41
- // Parse body from various sources
42
- let body = null;
43
- if (opts.body) {
44
- try {
45
- body = JSON.parse(opts.body);
46
- }
47
- catch (_a) {
48
- spinner.error({ text: "Invalid JSON in --body" });
49
- process.exit(EXIT_MISUSE);
50
- }
51
- }
52
- if (opts.bodyFile) {
53
- const fs = await import("fs");
54
- const content = fs.readFileSync(opts.bodyFile, "utf-8");
55
- try {
56
- body = JSON.parse(content);
57
- }
58
- catch (_b) {
59
- spinner.error({ text: `Invalid JSON in file: ${opts.bodyFile}` });
60
- process.exit(EXIT_MISUSE);
61
- }
62
- }
63
- if (opts.bodyStdin && !process.stdin.isTTY) {
64
- const chunks = [];
65
- for await (const chunk of process.stdin) {
66
- chunks.push(chunk);
67
- }
68
- const stdinContent = Buffer.concat(chunks).toString("utf-8").trim();
69
- if (stdinContent) {
70
- try {
71
- body = JSON.parse(stdinContent);
72
- }
73
- catch (_c) {
74
- spinner.error({ text: "Invalid JSON from stdin" });
75
- process.exit(EXIT_MISUSE);
76
- }
77
- }
78
- }
79
- if (!body) {
80
- spinner.error({ text: "No update data provided. Use --body, --body-file, or --body-stdin." });
81
- process.exit(EXIT_MISUSE);
82
- }
83
- // Merge mode: GET existing → merge → PUT
84
- if (opts.merge) {
85
- spinner.start({ text: `Fetching ${id} from ${collection}...`, color: "magenta" });
86
- const existing = await apiCallHandler(module.module, `${collection.toLowerCase()}/${id}`, "get", null, { responseFormat: "json" });
87
- const existingData = (existing === null || existing === void 0 ? void 0 : existing.payload) || {};
88
- body = { ...existingData, ...body };
89
- spinner.update({ text: `Updating ${id} in ${collection} (merged)...` });
90
- }
91
- else {
92
- spinner.start({ text: `Updating ${id} in ${collection}...`, color: "magenta" });
93
- }
94
- // Ensure _id is set
95
- body._id = id;
96
- const res = await apiCallHandler(module.module, collection.toLowerCase(), "put", body, {
97
- responseFormat: opts.responseFormat,
98
- verbosity: opts.verbosity,
99
- hideMeta: opts.hideMeta,
100
- });
101
- handleResponseFormatOptions(opts, res);
102
- spinner.success({ text: `Updated entry ${id} in ${collection}` });
103
- spinner.stop();
104
- localStorage.setItem("lastModule", module.module);
105
- localStorage.setItem("lastCollection", collection);
106
- localStorage.setItem("lastId", id);
107
- if (opts.save)
108
- await saveFile("update", opts, res);
109
- }
110
- catch (e) {
111
- spinner.error({ text: e.message || "An unexpected error occurred" });
112
- process.exit(EXIT_GENERAL_ERROR);
113
- }
114
- });
115
- }
@@ -1,285 +0,0 @@
1
- import chalk from "chalk";
2
- import { apiCallHandler } from "../api/apiCallHandler.js";
3
- import { handleResponseFormatOptions } from "../helpers/handleResponseFormatOptions.js";
4
- import { saveFile } from "../helpers/saveFile.js";
5
- import { spinner } from "../../index.js";
6
- import { EXIT_GENERAL_ERROR, EXIT_MISUSE } from "../exitCodes.js";
7
- export function createUsersCommand(program) {
8
- const users = program
9
- .command("users")
10
- .description("Manage users, teams, and roles");
11
- // ── USERS ──────────────────────────────────────────────
12
- // ay users list
13
- users
14
- .command("list")
15
- .alias("ls")
16
- .description("List users")
17
- .option("--search <query>", "Search by name or email")
18
- .option("--role <roleId>", "Filter by role ID")
19
- .option("--active", "Show only active users")
20
- .option("-l, --limit <number>", "Limit results", parseInt, 50)
21
- .option("-p, --page <number>", "Page number", parseInt, 1)
22
- .action(async (options) => {
23
- var _a, _b, _c;
24
- try {
25
- const opts = { ...program.opts(), ...options };
26
- spinner.start({ text: "Fetching users...", color: "magenta" });
27
- const params = {
28
- page: opts.page,
29
- limit: opts.limit,
30
- responseFormat: opts.responseFormat,
31
- verbosity: opts.verbosity,
32
- };
33
- if (opts.search)
34
- params.q = opts.search;
35
- if (opts.role)
36
- params.role = opts.role;
37
- if (opts.active)
38
- params.active = "true";
39
- const res = await apiCallHandler("config", "users", "get", null, params);
40
- handleResponseFormatOptions(opts, res);
41
- const total = (_c = (_b = (_a = res.meta) === null || _a === void 0 ? void 0 : _a.pageInfo) === null || _b === void 0 ? void 0 : _b.totalEntries) !== null && _c !== void 0 ? _c : 0;
42
- spinner.success({ text: `Found ${total} users` });
43
- spinner.stop();
44
- if (opts.save)
45
- await saveFile("users-list", opts, res);
46
- }
47
- catch (e) {
48
- spinner.error({ text: e.message || "Failed to list users" });
49
- process.exit(EXIT_GENERAL_ERROR);
50
- }
51
- });
52
- // ay users get <id>
53
- users
54
- .command("get <id>")
55
- .description("Get user details")
56
- .action(async (id, options) => {
57
- try {
58
- const opts = { ...program.opts(), ...options };
59
- spinner.start({ text: `Fetching user ${id}...`, color: "magenta" });
60
- const res = await apiCallHandler("config", `users/${id}`, "get", null, {
61
- responseFormat: opts.responseFormat,
62
- verbosity: opts.verbosity,
63
- });
64
- handleResponseFormatOptions(opts, res);
65
- spinner.success({ text: `User ${id} loaded` });
66
- spinner.stop();
67
- }
68
- catch (e) {
69
- spinner.error({ text: e.message || "Failed to get user" });
70
- process.exit(EXIT_GENERAL_ERROR);
71
- }
72
- });
73
- // ay users invite --email <email> --role <roleId>
74
- users
75
- .command("invite")
76
- .description("Invite a new user")
77
- .requiredOption("--email <email>", "Email address of the user to invite")
78
- .option("--role <roleId>", "Role ID to assign")
79
- .option("--firstName <name>", "First name")
80
- .option("--lastName <name>", "Last name")
81
- .action(async (options) => {
82
- try {
83
- const opts = { ...program.opts(), ...options };
84
- spinner.start({ text: `Inviting ${opts.email}...`, color: "magenta" });
85
- const body = { email: opts.email };
86
- if (opts.role)
87
- body.role = opts.role;
88
- if (opts.firstName)
89
- body.firstName = opts.firstName;
90
- if (opts.lastName)
91
- body.lastName = opts.lastName;
92
- const res = await apiCallHandler("config", "users", "post", body, {
93
- responseFormat: opts.responseFormat,
94
- });
95
- handleResponseFormatOptions(opts, res);
96
- spinner.success({ text: `Invitation sent to ${opts.email}` });
97
- spinner.stop();
98
- }
99
- catch (e) {
100
- spinner.error({ text: e.message || "Failed to invite user" });
101
- process.exit(EXIT_GENERAL_ERROR);
102
- }
103
- });
104
- // ay users deactivate <id>
105
- users
106
- .command("deactivate <id>")
107
- .description("Deactivate a user account")
108
- .action(async (id, options) => {
109
- try {
110
- const opts = { ...program.opts(), ...options };
111
- if (!opts.force && process.stdin.isTTY) {
112
- const inquirer = (await import("inquirer")).default;
113
- const { confirmed } = await inquirer.prompt([
114
- { type: "confirm", name: "confirmed", message: `Deactivate user ${id}?`, default: false },
115
- ]);
116
- if (!confirmed) {
117
- console.error(chalk.yellow(" Aborted."));
118
- return;
119
- }
120
- }
121
- spinner.start({ text: `Deactivating user ${id}...`, color: "magenta" });
122
- const res = await apiCallHandler("config", "users", "put", { _id: id, active: false }, {
123
- responseFormat: opts.responseFormat,
124
- });
125
- handleResponseFormatOptions(opts, res);
126
- spinner.success({ text: `User ${id} deactivated` });
127
- spinner.stop();
128
- }
129
- catch (e) {
130
- spinner.error({ text: e.message || "Failed to deactivate user" });
131
- process.exit(EXIT_GENERAL_ERROR);
132
- }
133
- });
134
- // ── TEAMS ──────────────────────────────────────────────
135
- const teams = users
136
- .command("teams")
137
- .description("Manage teams");
138
- // ay users teams list
139
- teams
140
- .command("list")
141
- .alias("ls")
142
- .description("List teams")
143
- .option("--search <query>", "Search teams by name")
144
- .option("-l, --limit <number>", "Limit results", parseInt, 50)
145
- .option("-p, --page <number>", "Page number", parseInt, 1)
146
- .action(async (options) => {
147
- var _a, _b, _c;
148
- try {
149
- const opts = { ...program.opts(), ...options };
150
- spinner.start({ text: "Fetching teams...", color: "magenta" });
151
- const params = {
152
- page: opts.page,
153
- limit: opts.limit,
154
- responseFormat: opts.responseFormat,
155
- verbosity: opts.verbosity,
156
- };
157
- if (opts.search)
158
- params.q = opts.search;
159
- const res = await apiCallHandler("config", "teams", "get", null, params);
160
- handleResponseFormatOptions(opts, res);
161
- const total = (_c = (_b = (_a = res.meta) === null || _a === void 0 ? void 0 : _a.pageInfo) === null || _b === void 0 ? void 0 : _b.totalEntries) !== null && _c !== void 0 ? _c : 0;
162
- spinner.success({ text: `Found ${total} teams` });
163
- spinner.stop();
164
- if (opts.save)
165
- await saveFile("teams-list", opts, res);
166
- }
167
- catch (e) {
168
- spinner.error({ text: e.message || "Failed to list teams" });
169
- process.exit(EXIT_GENERAL_ERROR);
170
- }
171
- });
172
- // ay users teams get <id>
173
- teams
174
- .command("get <id>")
175
- .description("Get team details with members")
176
- .action(async (id, options) => {
177
- try {
178
- const opts = { ...program.opts(), ...options };
179
- spinner.start({ text: `Fetching team ${id}...`, color: "magenta" });
180
- const res = await apiCallHandler("config", `teams/${id}`, "get", null, {
181
- responseFormat: opts.responseFormat,
182
- verbosity: opts.verbosity,
183
- });
184
- handleResponseFormatOptions(opts, res);
185
- spinner.success({ text: `Team ${id} loaded` });
186
- spinner.stop();
187
- }
188
- catch (e) {
189
- spinner.error({ text: e.message || "Failed to get team" });
190
- process.exit(EXIT_GENERAL_ERROR);
191
- }
192
- });
193
- // ay users teams create --body '{...}'
194
- teams
195
- .command("create")
196
- .description("Create a new team")
197
- .option("--name <name>", "Team name")
198
- .option("--body <json>", "Full team definition as JSON")
199
- .action(async (options) => {
200
- try {
201
- const opts = { ...program.opts(), ...options };
202
- let body = null;
203
- if (opts.body) {
204
- try {
205
- body = JSON.parse(opts.body);
206
- }
207
- catch (_a) {
208
- spinner.error({ text: "Invalid JSON in --body" });
209
- process.exit(EXIT_MISUSE);
210
- }
211
- }
212
- else if (opts.name) {
213
- body = { name: opts.name };
214
- }
215
- if (!body) {
216
- spinner.error({ text: "Provide team definition via --name or --body" });
217
- process.exit(EXIT_MISUSE);
218
- }
219
- spinner.start({ text: "Creating team...", color: "magenta" });
220
- const res = await apiCallHandler("config", "teams", "post", body, {
221
- responseFormat: opts.responseFormat,
222
- });
223
- handleResponseFormatOptions(opts, res);
224
- spinner.success({ text: "Team created" });
225
- spinner.stop();
226
- }
227
- catch (e) {
228
- spinner.error({ text: e.message || "Failed to create team" });
229
- process.exit(EXIT_GENERAL_ERROR);
230
- }
231
- });
232
- // ── ROLES ──────────────────────────────────────────────
233
- const roles = users
234
- .command("roles")
235
- .description("Manage roles");
236
- // ay users roles list
237
- roles
238
- .command("list")
239
- .alias("ls")
240
- .description("List available roles")
241
- .option("-l, --limit <number>", "Limit results", parseInt, 50)
242
- .action(async (options) => {
243
- var _a, _b, _c;
244
- try {
245
- const opts = { ...program.opts(), ...options };
246
- spinner.start({ text: "Fetching roles...", color: "magenta" });
247
- const res = await apiCallHandler("config", "roles", "get", null, {
248
- limit: opts.limit,
249
- responseFormat: opts.responseFormat,
250
- verbosity: opts.verbosity,
251
- });
252
- handleResponseFormatOptions(opts, res);
253
- const total = (_c = (_b = (_a = res.meta) === null || _a === void 0 ? void 0 : _a.pageInfo) === null || _b === void 0 ? void 0 : _b.totalEntries) !== null && _c !== void 0 ? _c : 0;
254
- spinner.success({ text: `Found ${total} roles` });
255
- spinner.stop();
256
- if (opts.save)
257
- await saveFile("roles-list", opts, res);
258
- }
259
- catch (e) {
260
- spinner.error({ text: e.message || "Failed to list roles" });
261
- process.exit(EXIT_GENERAL_ERROR);
262
- }
263
- });
264
- // ay users roles get <id>
265
- roles
266
- .command("get <id>")
267
- .description("Get role details with permissions")
268
- .action(async (id, options) => {
269
- try {
270
- const opts = { ...program.opts(), ...options };
271
- spinner.start({ text: `Fetching role ${id}...`, color: "magenta" });
272
- const res = await apiCallHandler("config", `roles/${id}`, "get", null, {
273
- responseFormat: opts.responseFormat,
274
- verbosity: opts.verbosity,
275
- });
276
- handleResponseFormatOptions(opts, res);
277
- spinner.success({ text: `Role ${id} loaded` });
278
- spinner.stop();
279
- }
280
- catch (e) {
281
- spinner.error({ text: e.message || "Failed to get role" });
282
- process.exit(EXIT_GENERAL_ERROR);
283
- }
284
- });
285
- }