@tolinax/ayoune-cli 2026.8.1 → 2026.9.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/lib/api/apiCallHandler.js +1 -1
- package/lib/api/apiClient.js +74 -62
- package/lib/commands/_registry.js +279 -0
- package/lib/commands/aggregate/_shared.js +21 -0
- package/lib/commands/aggregate/_stageBuilders.js +295 -0
- package/lib/commands/aggregate/exec.js +51 -0
- package/lib/commands/aggregate/index.js +38 -0
- package/lib/commands/aggregate/list.js +43 -0
- package/lib/commands/aggregate/models.js +43 -0
- package/lib/commands/aggregate/run.js +53 -0
- package/lib/commands/aggregate/save.js +53 -0
- package/lib/commands/aggregate/validate.js +47 -0
- package/lib/commands/aggregate/wizard.js +174 -0
- package/lib/commands/createAggregateCommand.js +5 -658
- package/lib/commands/createDeployCommand.js +5 -642
- package/lib/commands/createProgram.js +251 -161
- package/lib/commands/createServicesCommand.js +4 -5
- package/lib/commands/createWhoAmICommand.js +5 -5
- package/lib/commands/deploy/_token.js +8 -0
- package/lib/commands/deploy/alerts.js +43 -0
- package/lib/commands/deploy/clusters.js +62 -0
- package/lib/commands/deploy/dashboard.js +31 -0
- package/lib/commands/deploy/deployments.js +216 -0
- package/lib/commands/deploy/index.js +31 -0
- package/lib/commands/deploy/pipelines.js +82 -0
- package/lib/commands/deploy/plans.js +147 -0
- package/lib/commands/deploy/pods.js +70 -0
- package/lib/commands/deploy/repos.js +63 -0
- package/lib/helpers/dateFormat.js +119 -0
- package/lib/helpers/formatDocument.js +4 -5
- package/lib/helpers/initializeSettings.js +8 -11
- package/lib/helpers/logo.js +86 -13
- package/lib/helpers/saveFile.js +4 -9
- package/lib/models/getModelsInModules.js +6 -8
- package/lib/models/getModuleFromCollection.js +2 -2
- package/lib/operations/handleCollectionOperation.js +2 -3
- package/package.json +2 -12
package/lib/api/apiClient.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import https from "https";
|
|
1
|
+
import { http } from "@tolinax/ayoune-core/lib/http/index.js";
|
|
3
2
|
import chalk from "chalk";
|
|
4
|
-
import axiosRetry from "axios-retry";
|
|
5
3
|
import { config } from "../helpers/config.js";
|
|
6
|
-
const httpsAgent = new https.Agent({ rejectUnauthorized: false });
|
|
7
4
|
let debugEnabled = false;
|
|
8
5
|
export function enableDebug() {
|
|
9
6
|
debugEnabled = true;
|
|
@@ -13,14 +10,6 @@ function debugLog(prefix, ...args) {
|
|
|
13
10
|
return;
|
|
14
11
|
console.error(chalk.dim(` [debug] ${prefix}`), ...args);
|
|
15
12
|
}
|
|
16
|
-
const api = axios.create({
|
|
17
|
-
timeout: 30000,
|
|
18
|
-
httpsAgent,
|
|
19
|
-
});
|
|
20
|
-
const audit = axios.create({
|
|
21
|
-
baseURL: config.auditUrl,
|
|
22
|
-
httpsAgent,
|
|
23
|
-
});
|
|
24
13
|
// Modules that don't follow the standard {module}-api.ayoune.app pattern
|
|
25
14
|
const MODULE_HOST_OVERRIDES = {
|
|
26
15
|
su: "https://api-v1.ayoune.app/api/su",
|
|
@@ -33,52 +22,6 @@ const MODULE_HOST_OVERRIDES = {
|
|
|
33
22
|
export function getModuleBaseUrl(module) {
|
|
34
23
|
return MODULE_HOST_OVERRIDES[module] || `https://${module}-api.ayoune.app`;
|
|
35
24
|
}
|
|
36
|
-
function addDebugInterceptors(instance) {
|
|
37
|
-
instance.interceptors.request.use((req) => {
|
|
38
|
-
var _a, _b, _c;
|
|
39
|
-
const url = `${req.baseURL || ""}/${req.url || ""}`.replace(/\/+/g, "/").replace(":/", "://");
|
|
40
|
-
debugLog(`${chalk.yellow((_a = req.method) === null || _a === void 0 ? void 0 : _a.toUpperCase())} ${chalk.cyan(url)}`);
|
|
41
|
-
if (req.params && Object.keys(req.params).length) {
|
|
42
|
-
debugLog("params:", JSON.stringify(req.params));
|
|
43
|
-
}
|
|
44
|
-
if (req.data) {
|
|
45
|
-
debugLog("body:", JSON.stringify(req.data).substring(0, 200));
|
|
46
|
-
}
|
|
47
|
-
const auth = ((_b = req.headers) === null || _b === void 0 ? void 0 : _b.Authorization) || ((_c = req.headers) === null || _c === void 0 ? void 0 : _c.authorization);
|
|
48
|
-
if (auth) {
|
|
49
|
-
const token = String(auth);
|
|
50
|
-
debugLog("auth:", token.substring(0, 15) + "..." + token.substring(token.length - 10));
|
|
51
|
-
}
|
|
52
|
-
return req;
|
|
53
|
-
});
|
|
54
|
-
instance.interceptors.response.use((res) => {
|
|
55
|
-
var _a, _b;
|
|
56
|
-
const meta = (_a = res.data) === null || _a === void 0 ? void 0 : _a.meta;
|
|
57
|
-
const total = (_b = meta === null || meta === void 0 ? void 0 : meta.pageInfo) === null || _b === void 0 ? void 0 : _b.totalEntries;
|
|
58
|
-
const time = meta === null || meta === void 0 ? void 0 : meta.responseTime;
|
|
59
|
-
debugLog(`${chalk.green(res.status)} ${res.statusText}` +
|
|
60
|
-
(time ? ` ${chalk.dim(`(${time}ms)`)}` : "") +
|
|
61
|
-
(total !== undefined ? ` ${chalk.dim(`[${total} entries]`)}` : ""));
|
|
62
|
-
if (res.data) {
|
|
63
|
-
const body = JSON.stringify(res.data);
|
|
64
|
-
debugLog("response:", body.length > 500 ? body.substring(0, 500) + "..." : body);
|
|
65
|
-
}
|
|
66
|
-
return res;
|
|
67
|
-
}, (err) => {
|
|
68
|
-
if (err.response) {
|
|
69
|
-
debugLog(`${chalk.red(err.response.status)} ${err.response.statusText}`);
|
|
70
|
-
if (err.response.data) {
|
|
71
|
-
debugLog("response:", JSON.stringify(err.response.data).substring(0, 500));
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
debugLog(chalk.red(`network error: ${err.message}`));
|
|
76
|
-
}
|
|
77
|
-
return Promise.reject(err);
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
addDebugInterceptors(api);
|
|
81
|
-
addDebugInterceptors(audit);
|
|
82
25
|
const retryConfig = {
|
|
83
26
|
retries: 3,
|
|
84
27
|
retryDelay: (retryCount, error) => {
|
|
@@ -100,10 +43,79 @@ const retryConfig = {
|
|
|
100
43
|
retryCondition: (error) => {
|
|
101
44
|
var _a;
|
|
102
45
|
// Retry on network errors, 5xx, and 429 (rate limit)
|
|
103
|
-
|
|
104
|
-
|
|
46
|
+
const status = (_a = error.response) === null || _a === void 0 ? void 0 : _a.status;
|
|
47
|
+
if (!status)
|
|
48
|
+
return true; // network error
|
|
49
|
+
return status >= 500 || status === 429;
|
|
105
50
|
},
|
|
106
51
|
};
|
|
107
|
-
|
|
108
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Debug-aware HTTP request wrapper.
|
|
54
|
+
* Logs request/response details to stderr when debug mode is enabled.
|
|
55
|
+
*/
|
|
56
|
+
async function debugRequest(client, requestConfig) {
|
|
57
|
+
var _a, _b, _c, _d;
|
|
58
|
+
const url = `${requestConfig.baseURL || ""}/${requestConfig.url || ""}`.replace(/\/+/g, "/").replace(":/", "://");
|
|
59
|
+
const method = (requestConfig.method || "GET").toUpperCase();
|
|
60
|
+
if (debugEnabled) {
|
|
61
|
+
debugLog(`${chalk.yellow(method)} ${chalk.cyan(url)}`);
|
|
62
|
+
if (requestConfig.params && Object.keys(requestConfig.params).length) {
|
|
63
|
+
debugLog("params:", JSON.stringify(requestConfig.params));
|
|
64
|
+
}
|
|
65
|
+
if (requestConfig.data) {
|
|
66
|
+
debugLog("body:", JSON.stringify(requestConfig.data).substring(0, 200));
|
|
67
|
+
}
|
|
68
|
+
const auth = ((_a = requestConfig.headers) === null || _a === void 0 ? void 0 : _a.Authorization) || ((_b = requestConfig.headers) === null || _b === void 0 ? void 0 : _b.authorization);
|
|
69
|
+
if (auth) {
|
|
70
|
+
const token = String(auth);
|
|
71
|
+
debugLog("auth:", token.substring(0, 15) + "..." + token.substring(token.length - 10));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
const res = await client.request(requestConfig);
|
|
76
|
+
if (debugEnabled) {
|
|
77
|
+
const meta = (_c = res.data) === null || _c === void 0 ? void 0 : _c.meta;
|
|
78
|
+
const total = (_d = meta === null || meta === void 0 ? void 0 : meta.pageInfo) === null || _d === void 0 ? void 0 : _d.totalEntries;
|
|
79
|
+
const time = meta === null || meta === void 0 ? void 0 : meta.responseTime;
|
|
80
|
+
debugLog(`${chalk.green(res.status)} ${res.statusText}` +
|
|
81
|
+
(time ? ` ${chalk.dim(`(${time}ms)`)}` : "") +
|
|
82
|
+
(total !== undefined ? ` ${chalk.dim(`[${total} entries]`)}` : ""));
|
|
83
|
+
if (res.data) {
|
|
84
|
+
const body = JSON.stringify(res.data);
|
|
85
|
+
debugLog("response:", body.length > 500 ? body.substring(0, 500) + "..." : body);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return res;
|
|
89
|
+
}
|
|
90
|
+
catch (err) {
|
|
91
|
+
if (debugEnabled) {
|
|
92
|
+
if (err.response) {
|
|
93
|
+
debugLog(`${chalk.red(err.response.status)} ${err.response.statusText}`);
|
|
94
|
+
if (err.response.data) {
|
|
95
|
+
debugLog("response:", JSON.stringify(err.response.data).substring(0, 500));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
debugLog(chalk.red(`network error: ${err.message}`));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
throw err;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const apiClient = http.create({
|
|
106
|
+
timeout: 30000,
|
|
107
|
+
retry: retryConfig,
|
|
108
|
+
logging: false,
|
|
109
|
+
metrics: false,
|
|
110
|
+
});
|
|
111
|
+
const auditClient = http.create({
|
|
112
|
+
baseURL: config.auditUrl,
|
|
113
|
+
retry: retryConfig,
|
|
114
|
+
logging: false,
|
|
115
|
+
metrics: false,
|
|
116
|
+
});
|
|
117
|
+
/** Callable API client that supports debug logging */
|
|
118
|
+
const api = (requestConfig) => debugRequest(apiClient, requestConfig);
|
|
119
|
+
/** Callable audit client that supports debug logging */
|
|
120
|
+
const audit = (requestConfig) => debugRequest(auditClient, requestConfig);
|
|
109
121
|
export { api, audit };
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
// Lazy command registry for the `ay` CLI.
|
|
2
|
+
//
|
|
3
|
+
// Each command is described by a stub (name + aliases + one-line description)
|
|
4
|
+
// plus a `loader` that dynamically imports its registration function. This lets
|
|
5
|
+
// `createProgram` register the FULL command for only the one the user actually
|
|
6
|
+
// invoked, instead of importing all 41 command modules eagerly on every cold
|
|
7
|
+
// start. Help mode falls back to registering lightweight stubs for every entry
|
|
8
|
+
// so `ay` / `ay --help` still produce a complete listing.
|
|
9
|
+
//
|
|
10
|
+
// To add a new command:
|
|
11
|
+
// 1. Create `src/lib/commands/createXxxCommand.ts` exporting `createXxxCommand`
|
|
12
|
+
// 2. Append a CommandSpec entry below
|
|
13
|
+
// 3. (optional) add a corresponding test
|
|
14
|
+
//
|
|
15
|
+
// Adding/removing entries here is the ONLY thing `createProgram` needs to know
|
|
16
|
+
// about — there are no static imports of command modules anywhere.
|
|
17
|
+
export const COMMAND_REGISTRY = [
|
|
18
|
+
{
|
|
19
|
+
name: "modules",
|
|
20
|
+
aliases: ["m"],
|
|
21
|
+
description: "Browse modules, collections, and operations interactively",
|
|
22
|
+
loader: async () => (await import("./createModulesCommand.js")).createModulesCommand,
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: "list",
|
|
26
|
+
aliases: ["l"],
|
|
27
|
+
description: "List entries in a collection with pagination support",
|
|
28
|
+
loader: async () => (await import("./createListCommand.js")).createListCommand,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: "get",
|
|
32
|
+
aliases: ["g"],
|
|
33
|
+
description: "Get a single entry by ID",
|
|
34
|
+
loader: async () => (await import("./createGetCommand.js")).createGetCommand,
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: "edit",
|
|
38
|
+
aliases: ["e"],
|
|
39
|
+
description: "Edit an existing entry",
|
|
40
|
+
loader: async () => (await import("./createEditCommand.js")).createEditCommand,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: "copy",
|
|
44
|
+
aliases: ["cp"],
|
|
45
|
+
description: "Copy an existing entry",
|
|
46
|
+
loader: async () => (await import("./createCopyCommand.js")).createCopyCommand,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: "describe",
|
|
50
|
+
aliases: ["d"],
|
|
51
|
+
description: "Show the schema of a collection",
|
|
52
|
+
loader: async () => (await import("./createDescribeCommand.js")).createDescribeCommand,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
name: "create",
|
|
56
|
+
aliases: ["c"],
|
|
57
|
+
description: "Create a new entry",
|
|
58
|
+
loader: async () => (await import("./createCreateCommand.js")).createCreateCommand,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: "storage",
|
|
62
|
+
aliases: ["s"],
|
|
63
|
+
description: "Manage local CLI storage (tokens, preferences)",
|
|
64
|
+
loader: async () => (await import("./createStorageCommand.js")).createStorageCommand,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
name: "audit",
|
|
68
|
+
aliases: ["history"],
|
|
69
|
+
description: "Inspect the audit trail for an entry or collection",
|
|
70
|
+
loader: async () => (await import("./createAuditCommand.js")).createAuditCommand,
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: "stream",
|
|
74
|
+
aliases: ["listen"],
|
|
75
|
+
description: "Stream live updates from a collection",
|
|
76
|
+
loader: async () => (await import("./createStreamCommand.js")).createStreamCommand,
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: "events",
|
|
80
|
+
aliases: ["sub"],
|
|
81
|
+
description: "Subscribe to platform events",
|
|
82
|
+
loader: async () => (await import("./createEventsCommand.js")).createEventsCommand,
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: "whoami",
|
|
86
|
+
aliases: ["who"],
|
|
87
|
+
description: "Show the currently authenticated user",
|
|
88
|
+
loader: async () => (await import("./createWhoAmICommand.js")).createWhoAmICommand,
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: "logout",
|
|
92
|
+
aliases: ["signout"],
|
|
93
|
+
description: "Clear stored credentials and sign out",
|
|
94
|
+
loader: async () => (await import("./createLogoutCommand.js")).createLogoutCommand,
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: "actions",
|
|
98
|
+
aliases: ["act"],
|
|
99
|
+
description: "List available custom actions for a collection",
|
|
100
|
+
loader: async () => (await import("./createActionsCommand.js")).createActionsCommand,
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: "exec",
|
|
104
|
+
aliases: ["x"],
|
|
105
|
+
description: "Execute a custom action by name",
|
|
106
|
+
loader: async () => (await import("./createExecCommand.js")).createExecCommand,
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
name: "ai",
|
|
110
|
+
description: "Interact with aYOUne AI services",
|
|
111
|
+
loader: async () => (await import("./createAiCommand.js")).createAiCommand,
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: "services",
|
|
115
|
+
aliases: ["svc"],
|
|
116
|
+
description: "Discover and inspect platform services and endpoints",
|
|
117
|
+
loader: async () => (await import("./createServicesCommand.js")).createServicesCommand,
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
name: "deploy",
|
|
121
|
+
aliases: ["dp"],
|
|
122
|
+
description: "Deployments, pipelines, clusters, repos, and dashboards",
|
|
123
|
+
loader: async () => (await import("./createDeployCommand.js")).createDeployCommand,
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
name: "monitor",
|
|
127
|
+
aliases: ["mon"],
|
|
128
|
+
description: "Monitor logs, alerts, sessions, and uptime checks",
|
|
129
|
+
loader: async () => (await import("./createMonitorCommand.js")).createMonitorCommand,
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
name: "delete",
|
|
133
|
+
aliases: ["rm"],
|
|
134
|
+
description: "Delete an entry by ID",
|
|
135
|
+
loader: async () => (await import("./createDeleteCommand.js")).createDeleteCommand,
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: "update",
|
|
139
|
+
aliases: ["u"],
|
|
140
|
+
description: "Update fields on an existing entry",
|
|
141
|
+
loader: async () => (await import("./createUpdateCommand.js")).createUpdateCommand,
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
name: "batch",
|
|
145
|
+
description: "Run bulk operations on multiple entries (for scripts and AI agents)",
|
|
146
|
+
loader: async () => (await import("./createBatchCommand.js")).createBatchCommand,
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: "search",
|
|
150
|
+
aliases: ["find"],
|
|
151
|
+
description: "Full-text and model search across collections",
|
|
152
|
+
loader: async () => (await import("./createSearchCommand.js")).createSearchCommand,
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
name: "webhooks",
|
|
156
|
+
aliases: ["hooks"],
|
|
157
|
+
description: "Manage outbound webhooks",
|
|
158
|
+
loader: async () => (await import("./createWebhooksCommand.js")).createWebhooksCommand,
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
name: "jobs",
|
|
162
|
+
aliases: ["j"],
|
|
163
|
+
description: "Inspect job queues, triggers, automations, and notifications",
|
|
164
|
+
loader: async () => (await import("./createJobsCommand.js")).createJobsCommand,
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
name: "export",
|
|
168
|
+
aliases: ["exp"],
|
|
169
|
+
description: "Export collection data with pagination and format selection",
|
|
170
|
+
loader: async () => (await import("./createExportCommand.js")).createExportCommand,
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
name: "users",
|
|
174
|
+
description: "Manage users, teams, and roles",
|
|
175
|
+
loader: async () => (await import("./createUsersCommand.js")).createUsersCommand,
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: "sync",
|
|
179
|
+
description: "Synchronize platform data across systems",
|
|
180
|
+
loader: async () => (await import("./createSyncCommand.js")).createSyncCommand,
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
name: "permissions",
|
|
184
|
+
aliases: ["perms"],
|
|
185
|
+
description: "Manage permissions, requests, and rights",
|
|
186
|
+
loader: async () => (await import("./createPermissionsCommand.js")).createPermissionsCommand,
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
name: "templates",
|
|
190
|
+
aliases: ["tmpl"],
|
|
191
|
+
description: "Manage platform templates (email, notification, report, store)",
|
|
192
|
+
loader: async () => (await import("./createTemplateCommand.js")).createTemplateCommand,
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
name: "access",
|
|
196
|
+
description: "Show accessible modules and collections for the current user",
|
|
197
|
+
loader: async () => (await import("./createAccessCommand.js")).createAccessCommand,
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
name: "aggregate",
|
|
201
|
+
aliases: ["agg"],
|
|
202
|
+
description: "Run, save, and manage MongoDB aggregation pipelines",
|
|
203
|
+
loader: async () => (await import("./createAggregateCommand.js")).createAggregateCommand,
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
name: "db",
|
|
207
|
+
description: "Copy query results to external databases and manage targets",
|
|
208
|
+
loader: async () => (await import("./createDbCommand.js")).createDbCommand,
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
name: "setup",
|
|
212
|
+
description: "Interactive setup wizard for self-hosted aYOUne deployments",
|
|
213
|
+
loader: async () => (await import("./createSetupCommand.js")).createSetupCommand,
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
name: "status",
|
|
217
|
+
description: "Check health status of aYOUne platform services",
|
|
218
|
+
loader: async () => (await import("./createStatusCommand.js")).createStatusCommand,
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
name: "self-host-update",
|
|
222
|
+
aliases: ["shu"],
|
|
223
|
+
description: "Check for and apply updates to a self-hosted aYOUne deployment",
|
|
224
|
+
loader: async () => (await import("./createSelfHostUpdateCommand.js")).createSelfHostUpdateCommand,
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
name: "context",
|
|
228
|
+
aliases: ["ctx"],
|
|
229
|
+
description: "Manage the active entity context (auto-injects collection/ID)",
|
|
230
|
+
loader: async () => (await import("./createContextCommand.js")).createContextCommand,
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
name: "completions",
|
|
234
|
+
aliases: ["completion"],
|
|
235
|
+
description: "Generate shell completion script (bash/zsh/fish)",
|
|
236
|
+
loader: async () => (await import("./createCompletionsCommand.js")).createCompletionsCommand,
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
name: "alias",
|
|
240
|
+
description: "Manage custom command aliases",
|
|
241
|
+
loader: async () => (await import("./createAliasCommand.js")).createAliasCommand,
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
name: "config",
|
|
245
|
+
description: "Manage default CLI options stored in ~/.config/ayoune/config.json",
|
|
246
|
+
loader: async () => (await import("./createConfigCommand.js")).createConfigCommand,
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
name: "login",
|
|
250
|
+
aliases: ["auth"],
|
|
251
|
+
description: "Authenticate with the aYOUne platform",
|
|
252
|
+
loader: async () => (await import("./createLoginCommand.js")).createLoginCommand,
|
|
253
|
+
},
|
|
254
|
+
];
|
|
255
|
+
/**
|
|
256
|
+
* Look up a command spec by name OR alias. Used for resolving the user's
|
|
257
|
+
* argv[2] before deciding which loader to fire.
|
|
258
|
+
*/
|
|
259
|
+
export function findCommandSpec(nameOrAlias) {
|
|
260
|
+
return COMMAND_REGISTRY.find((spec) => { var _a, _b; return spec.name === nameOrAlias || ((_b = (_a = spec.aliases) === null || _a === void 0 ? void 0 : _a.includes(nameOrAlias)) !== null && _b !== void 0 ? _b : false); });
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Register a lightweight stub (name + aliases + description, no options, no
|
|
264
|
+
* action) for every command. Used to populate `ay --help` output without
|
|
265
|
+
* loading any command modules.
|
|
266
|
+
*
|
|
267
|
+
* The stub's action is intentionally empty: in help mode commander never
|
|
268
|
+
* invokes it, and on the lazy path we replace the stub with the real command
|
|
269
|
+
* before parsing.
|
|
270
|
+
*/
|
|
271
|
+
export function registerStubsForHelp(program) {
|
|
272
|
+
for (const spec of COMMAND_REGISTRY) {
|
|
273
|
+
const cmd = program.command(spec.name).description(spec.description);
|
|
274
|
+
if (spec.aliases) {
|
|
275
|
+
for (const alias of spec.aliases)
|
|
276
|
+
cmd.alias(alias);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Helpers shared across all `ay aggregate` subcommands. Kept in their own
|
|
2
|
+
// module so each subcommand file can import only what it needs and the wizard
|
|
3
|
+
// stage builders don't pollute the cold-start path of `ay agg run`.
|
|
4
|
+
/**
|
|
5
|
+
* Aggregation API responses come in two shapes depending on the route:
|
|
6
|
+
*
|
|
7
|
+
* - `/aggregation/{model}` returns a raw array of documents
|
|
8
|
+
* - `/aggregation/queries/execute/{id}` returns `{ payload, meta }`
|
|
9
|
+
*
|
|
10
|
+
* Normalize both into the `{ payload, meta }` shape that
|
|
11
|
+
* `handleResponseFormatOptions` expects, so each subcommand can pipe straight
|
|
12
|
+
* to it without per-call branching.
|
|
13
|
+
*/
|
|
14
|
+
export function wrapAggResult(res) {
|
|
15
|
+
if (Array.isArray(res)) {
|
|
16
|
+
return { payload: res, meta: { resultCount: res.length } };
|
|
17
|
+
}
|
|
18
|
+
if ((res === null || res === void 0 ? void 0 : res.payload) !== undefined)
|
|
19
|
+
return res;
|
|
20
|
+
return { payload: res, meta: {} };
|
|
21
|
+
}
|