@tolinax/ayoune-cli 2026.3.0 → 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.
- package/package.json +160 -158
- package/data/defaultActions.js +0 -9
- package/data/modelsAndRights.js +0 -3189
- package/data/modules.js +0 -111
- package/data/operations.js +0 -5
- package/data/services.js +0 -139
- package/index.js +0 -11
- package/lib/api/apiCallHandler.js +0 -68
- package/lib/api/apiClient.js +0 -100
- package/lib/api/auditCallHandler.js +0 -21
- package/lib/api/decodeToken.js +0 -4
- package/lib/api/handleAPIError.js +0 -59
- package/lib/api/login.js +0 -45
- package/lib/commands/createActionsCommand.js +0 -109
- package/lib/commands/createAiCommand.js +0 -188
- package/lib/commands/createAliasCommand.js +0 -106
- package/lib/commands/createAuditCommand.js +0 -49
- package/lib/commands/createBatchCommand.js +0 -304
- package/lib/commands/createCompletionsCommand.js +0 -169
- package/lib/commands/createConfigCommand.js +0 -208
- package/lib/commands/createCopyCommand.js +0 -39
- package/lib/commands/createCreateCommand.js +0 -50
- package/lib/commands/createDeleteCommand.js +0 -98
- package/lib/commands/createDeployCommand.js +0 -666
- package/lib/commands/createDescribeCommand.js +0 -42
- package/lib/commands/createEditCommand.js +0 -43
- package/lib/commands/createEventsCommand.js +0 -60
- package/lib/commands/createExecCommand.js +0 -182
- package/lib/commands/createExportCommand.js +0 -219
- package/lib/commands/createGetCommand.js +0 -47
- package/lib/commands/createJobsCommand.js +0 -168
- package/lib/commands/createListCommand.js +0 -49
- package/lib/commands/createLoginCommand.js +0 -18
- package/lib/commands/createLogoutCommand.js +0 -21
- package/lib/commands/createModulesCommand.js +0 -150
- package/lib/commands/createMonitorCommand.js +0 -283
- package/lib/commands/createPermissionsCommand.js +0 -241
- package/lib/commands/createProgram.js +0 -185
- package/lib/commands/createSearchCommand.js +0 -101
- package/lib/commands/createServicesCommand.js +0 -228
- package/lib/commands/createStorageCommand.js +0 -54
- package/lib/commands/createStreamCommand.js +0 -50
- package/lib/commands/createSyncCommand.js +0 -177
- package/lib/commands/createTemplateCommand.js +0 -238
- package/lib/commands/createUpdateCommand.js +0 -115
- package/lib/commands/createUsersCommand.js +0 -285
- package/lib/commands/createWebhooksCommand.js +0 -156
- package/lib/commands/createWhoAmICommand.js +0 -88
- package/lib/exitCodes.js +0 -6
- package/lib/helpers/addSpacesToCamelCase.js +0 -5
- package/lib/helpers/config.js +0 -6
- package/lib/helpers/configLoader.js +0 -60
- package/lib/helpers/formatDocument.js +0 -176
- package/lib/helpers/handleResponseFormatOptions.js +0 -85
- package/lib/helpers/initializeSettings.js +0 -14
- package/lib/helpers/localStorage.js +0 -4
- package/lib/helpers/makeRandomToken.js +0 -27
- package/lib/helpers/parseInt.js +0 -7
- package/lib/helpers/requireArg.js +0 -9
- package/lib/helpers/saveFile.js +0 -39
- package/lib/models/getCollections.js +0 -15
- package/lib/models/getModelsInModules.js +0 -13
- package/lib/models/getModuleFromCollection.js +0 -7
- package/lib/operations/handleAuditOperation.js +0 -22
- package/lib/operations/handleCollectionOperation.js +0 -91
- package/lib/operations/handleCopySingleOperation.js +0 -22
- package/lib/operations/handleCreateSingleOperation.js +0 -35
- package/lib/operations/handleDeleteSingleOperation.js +0 -14
- package/lib/operations/handleDescribeSingleOperation.js +0 -22
- package/lib/operations/handleEditOperation.js +0 -51
- package/lib/operations/handleEditRawOperation.js +0 -35
- package/lib/operations/handleGetOperation.js +0 -29
- package/lib/operations/handleGetSingleOperation.js +0 -20
- package/lib/operations/handleListOperation.js +0 -63
- package/lib/operations/handleSingleAuditOperation.js +0 -27
- package/lib/prompts/promptAudits.js +0 -15
- package/lib/prompts/promptCollection.js +0 -13
- package/lib/prompts/promptCollectionInModule.js +0 -13
- package/lib/prompts/promptCollectionWithModule.js +0 -15
- package/lib/prompts/promptConfirm.js +0 -12
- package/lib/prompts/promptDefaultAction.js +0 -13
- package/lib/prompts/promptEntry.js +0 -19
- package/lib/prompts/promptFileName.js +0 -12
- package/lib/prompts/promptFilePath.js +0 -18
- package/lib/prompts/promptModule.js +0 -19
- package/lib/prompts/promptName.js +0 -11
- package/lib/prompts/promptOperation.js +0 -13
- package/lib/socket/customerSocketClient.js +0 -13
- package/lib/socket/socketClient.js +0 -12
- package/lib/types.js +0 -1
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
//Defines the main program structure for command line interface
|
|
2
|
-
import { Option } from "commander";
|
|
3
|
-
import chalk from "chalk";
|
|
4
|
-
import path from "path";
|
|
5
|
-
import os from "os";
|
|
6
|
-
import { spinner } from "../../index.js";
|
|
7
|
-
import { createModulesCommand } from "./createModulesCommand.js";
|
|
8
|
-
import { createListCommand } from "./createListCommand.js";
|
|
9
|
-
import { createGetCommand } from "./createGetCommand.js";
|
|
10
|
-
import { createEditCommand } from "./createEditCommand.js";
|
|
11
|
-
import { createLoginCommand } from "./createLoginCommand.js";
|
|
12
|
-
import { createDescribeCommand } from "./createDescribeCommand.js";
|
|
13
|
-
import { createCopyCommand } from "./createCopyCommand.js";
|
|
14
|
-
import { createCreateCommand } from "./createCreateCommand.js";
|
|
15
|
-
import { createStorageCommand } from "./createStorageCommand.js";
|
|
16
|
-
import { createAuditCommand } from "./createAuditCommand.js";
|
|
17
|
-
import { createStreamCommand } from "./createStreamCommand.js";
|
|
18
|
-
import { createEventsCommand } from "./createEventsCommand.js";
|
|
19
|
-
import { createWhoAmICommand } from "./createWhoAmICommand.js";
|
|
20
|
-
import { createLogoutCommand } from "./createLogoutCommand.js";
|
|
21
|
-
import { createCompletionsCommand } from "./createCompletionsCommand.js";
|
|
22
|
-
import { createAliasCommand, registerUserAliases } from "./createAliasCommand.js";
|
|
23
|
-
import { createConfigCommand } from "./createConfigCommand.js";
|
|
24
|
-
import { createActionsCommand } from "./createActionsCommand.js";
|
|
25
|
-
import { createExecCommand } from "./createExecCommand.js";
|
|
26
|
-
import { createAiCommand } from "./createAiCommand.js";
|
|
27
|
-
import { enableDebug } from "../api/apiClient.js";
|
|
28
|
-
import { enableDryRun } from "../api/apiCallHandler.js";
|
|
29
|
-
import { enableJsonErrors } from "../api/handleAPIError.js";
|
|
30
|
-
import { createServicesCommand } from "./createServicesCommand.js";
|
|
31
|
-
import { createDeployCommand } from "./createDeployCommand.js";
|
|
32
|
-
import { createMonitorCommand } from "./createMonitorCommand.js";
|
|
33
|
-
import { createDeleteCommand } from "./createDeleteCommand.js";
|
|
34
|
-
import { createUpdateCommand } from "./createUpdateCommand.js";
|
|
35
|
-
import { createBatchCommand } from "./createBatchCommand.js";
|
|
36
|
-
import { createSearchCommand } from "./createSearchCommand.js";
|
|
37
|
-
import { createWebhooksCommand } from "./createWebhooksCommand.js";
|
|
38
|
-
import { createJobsCommand } from "./createJobsCommand.js";
|
|
39
|
-
import { createExportCommand } from "./createExportCommand.js";
|
|
40
|
-
import { createUsersCommand } from "./createUsersCommand.js";
|
|
41
|
-
import { createSyncCommand } from "./createSyncCommand.js";
|
|
42
|
-
import { createPermissionsCommand } from "./createPermissionsCommand.js";
|
|
43
|
-
import { createTemplateCommand } from "./createTemplateCommand.js";
|
|
44
|
-
import { localStorage } from "../helpers/localStorage.js";
|
|
45
|
-
import { login } from "../api/login.js";
|
|
46
|
-
import { loadConfig } from "../helpers/configLoader.js";
|
|
47
|
-
export function createProgram(program) {
|
|
48
|
-
program
|
|
49
|
-
.version("2024.8.0")
|
|
50
|
-
.addOption(new Option("-r, --responseFormat <format>", "Set the output format")
|
|
51
|
-
.choices(["json", "csv", "yaml", "table"])
|
|
52
|
-
.default("json"))
|
|
53
|
-
.addOption(new Option("-v, --verbosity <level>", "Set the verbosity level of the returned meta information")
|
|
54
|
-
.choices(["default", "extended", "minimal"])
|
|
55
|
-
.default("default")
|
|
56
|
-
.conflicts("hideMeta"))
|
|
57
|
-
.addOption(new Option("-m, --hideMeta", "Returns only the payload without meta information. ")
|
|
58
|
-
.default(false)
|
|
59
|
-
.conflicts("verbosity"))
|
|
60
|
-
.addOption(new Option("-s, --save", "Saves the response as file"))
|
|
61
|
-
.addOption(new Option("-d, --debug", "Show detailed request/response information"))
|
|
62
|
-
.addOption(new Option("-o, --outPath [filePath]", "Lets you set a path").default(path.join(os.homedir(), "aYOUne")))
|
|
63
|
-
.addOption(new Option("-n, --name [fileName]", "Lets you set a filename"))
|
|
64
|
-
.addOption(new Option("-q, --quiet", "Suppress all output except errors and results"))
|
|
65
|
-
.addOption(new Option("--force", "Skip confirmation prompts for destructive actions"))
|
|
66
|
-
.addOption(new Option("--dry-run", "Preview what a command would do without executing"))
|
|
67
|
-
.addOption(new Option("--jq <expression>", "Filter JSON output using JMESPath expression"))
|
|
68
|
-
.addOption(new Option("--columns <fields>", "Comma-separated list of columns to display"))
|
|
69
|
-
.addOption(new Option("--no-color", "Disable colored output"))
|
|
70
|
-
.addOption(new Option("--json-errors", "Output errors as JSON to stderr (for AI agents/scripts)"))
|
|
71
|
-
.description("aYOUne - Business as a Service Command Line Interface");
|
|
72
|
-
program.showHelpAfterError();
|
|
73
|
-
program.showSuggestionAfterError(true);
|
|
74
|
-
createModulesCommand(program);
|
|
75
|
-
createListCommand(program);
|
|
76
|
-
createGetCommand(program);
|
|
77
|
-
createEditCommand(program);
|
|
78
|
-
createCopyCommand(program);
|
|
79
|
-
createDescribeCommand(program);
|
|
80
|
-
createCreateCommand(program);
|
|
81
|
-
createStorageCommand(program);
|
|
82
|
-
createAuditCommand(program);
|
|
83
|
-
createStreamCommand(program);
|
|
84
|
-
createEventsCommand(program);
|
|
85
|
-
createWhoAmICommand(program);
|
|
86
|
-
createLogoutCommand(program);
|
|
87
|
-
createActionsCommand(program);
|
|
88
|
-
createExecCommand(program);
|
|
89
|
-
createAiCommand(program);
|
|
90
|
-
createServicesCommand(program);
|
|
91
|
-
createDeployCommand(program);
|
|
92
|
-
createMonitorCommand(program);
|
|
93
|
-
createDeleteCommand(program);
|
|
94
|
-
createUpdateCommand(program);
|
|
95
|
-
createBatchCommand(program);
|
|
96
|
-
createSearchCommand(program);
|
|
97
|
-
createWebhooksCommand(program);
|
|
98
|
-
createJobsCommand(program);
|
|
99
|
-
createExportCommand(program);
|
|
100
|
-
createUsersCommand(program);
|
|
101
|
-
createSyncCommand(program);
|
|
102
|
-
createPermissionsCommand(program);
|
|
103
|
-
createTemplateCommand(program);
|
|
104
|
-
createCompletionsCommand(program);
|
|
105
|
-
createAliasCommand(program);
|
|
106
|
-
createConfigCommand(program);
|
|
107
|
-
registerUserAliases(program);
|
|
108
|
-
createLoginCommand(program);
|
|
109
|
-
program.addHelpText("beforeAll", `
|
|
110
|
-
__ ______ _ _
|
|
111
|
-
\\ \\ / / __ \\| | | |
|
|
112
|
-
__ \\ \\_/ / | | | | | |_ __ ___
|
|
113
|
-
/ _\` \\ /| | | | | | | '_ \\ / _ \\
|
|
114
|
-
| (_| || | | |__| | |__| | | | | __/
|
|
115
|
-
\\__,_||_| \\____/ \\____/|_| |_|\\___|
|
|
116
|
-
`);
|
|
117
|
-
program.configureHelp({
|
|
118
|
-
sortOptions: true,
|
|
119
|
-
sortSubcommands: true,
|
|
120
|
-
showGlobalOptions: true,
|
|
121
|
-
});
|
|
122
|
-
// Respect NO_COLOR env var (no-color.org standard)
|
|
123
|
-
if (process.env.NO_COLOR !== undefined) {
|
|
124
|
-
chalk.level = 0;
|
|
125
|
-
}
|
|
126
|
-
program.hook("preAction", async (thisCommand) => {
|
|
127
|
-
var _a;
|
|
128
|
-
// Apply saved defaults — only when the user didn't pass the flag explicitly
|
|
129
|
-
const config = loadConfig();
|
|
130
|
-
const defaults = (_a = config.defaults) !== null && _a !== void 0 ? _a : {};
|
|
131
|
-
const rawArgs = process.argv.slice(2);
|
|
132
|
-
if (defaults.responseFormat && !rawArgs.some(a => ["-r", "--responseFormat"].includes(a)))
|
|
133
|
-
program.setOptionValue("responseFormat", defaults.responseFormat);
|
|
134
|
-
if (defaults.verbosity && !rawArgs.some(a => ["-v", "--verbosity"].includes(a)))
|
|
135
|
-
program.setOptionValue("verbosity", defaults.verbosity);
|
|
136
|
-
if (defaults.outPath && !rawArgs.some(a => ["-o", "--outPath"].includes(a)))
|
|
137
|
-
program.setOptionValue("outPath", defaults.outPath);
|
|
138
|
-
if (defaults.hideMeta && !rawArgs.some(a => ["-m", "--hideMeta"].includes(a)))
|
|
139
|
-
program.setOptionValue("hideMeta", defaults.hideMeta);
|
|
140
|
-
if (defaults.quiet && !rawArgs.some(a => ["-q", "--quiet"].includes(a)))
|
|
141
|
-
program.setOptionValue("quiet", defaults.quiet);
|
|
142
|
-
if (defaults.force && !rawArgs.some(a => ["--force"].includes(a)))
|
|
143
|
-
program.setOptionValue("force", defaults.force);
|
|
144
|
-
if (defaults.dryRun && !rawArgs.some(a => ["--dry-run"].includes(a)))
|
|
145
|
-
program.setOptionValue("dryRun", defaults.dryRun);
|
|
146
|
-
const opts = program.opts();
|
|
147
|
-
if (opts.color === false) {
|
|
148
|
-
chalk.level = 0;
|
|
149
|
-
}
|
|
150
|
-
if (opts.debug) {
|
|
151
|
-
enableDebug();
|
|
152
|
-
}
|
|
153
|
-
if (opts.dryRun) {
|
|
154
|
-
enableDryRun();
|
|
155
|
-
}
|
|
156
|
-
if (opts.jsonErrors) {
|
|
157
|
-
enableJsonErrors();
|
|
158
|
-
}
|
|
159
|
-
if (opts.quiet) {
|
|
160
|
-
spinner.start = () => spinner;
|
|
161
|
-
spinner.update = () => spinner;
|
|
162
|
-
spinner.success = () => spinner;
|
|
163
|
-
spinner.stop = () => spinner;
|
|
164
|
-
// spinner.error left intact
|
|
165
|
-
}
|
|
166
|
-
// Token from env var (headless/AI agent mode) — takes precedence over stored token
|
|
167
|
-
const envToken = process.env.AYOUNE_TOKEN;
|
|
168
|
-
if (envToken && !localStorage.getItem("token")) {
|
|
169
|
-
localStorage.setItem("token", envToken);
|
|
170
|
-
}
|
|
171
|
-
// First-run onboarding: auto-login if no token stored
|
|
172
|
-
const cmdName = thisCommand.name();
|
|
173
|
-
const skipAuth = ["login", "logout", "whoami", "completions", "alias", "config", "help"];
|
|
174
|
-
if (!skipAuth.includes(cmdName) && process.stdin.isTTY) {
|
|
175
|
-
const token = localStorage.getItem("token");
|
|
176
|
-
if (!token) {
|
|
177
|
-
console.error(chalk.cyan.bold("\n Welcome to aYOUne CLI!\n"));
|
|
178
|
-
console.error(chalk.dim(" You need to authenticate before using this command.\n"));
|
|
179
|
-
await login();
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
//Parse command line arguments
|
|
184
|
-
program.parse(process.argv);
|
|
185
|
-
}
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { getModuleFromCollection } from "../models/getModuleFromCollection.js";
|
|
2
|
-
import { apiCallHandler } from "../api/apiCallHandler.js";
|
|
3
|
-
import { handleResponseFormatOptions } from "../helpers/handleResponseFormatOptions.js";
|
|
4
|
-
import { saveFile } from "../helpers/saveFile.js";
|
|
5
|
-
import { localStorage } from "../helpers/localStorage.js";
|
|
6
|
-
import { spinner } from "../../index.js";
|
|
7
|
-
import { EXIT_GENERAL_ERROR } from "../exitCodes.js";
|
|
8
|
-
export function createSearchCommand(program) {
|
|
9
|
-
program
|
|
10
|
-
.command("search <collection> [query]")
|
|
11
|
-
.alias("find")
|
|
12
|
-
.description("Search entries in a collection with advanced filtering")
|
|
13
|
-
.addHelpText("after", `
|
|
14
|
-
Examples:
|
|
15
|
-
ay search contacts "John" Full-text search
|
|
16
|
-
ay search contacts --filter "status=active" Filter by field
|
|
17
|
-
ay search products --filter "price>100" Comparison filter
|
|
18
|
-
ay search orders --filter "status=paid" --sort "-createdAt"
|
|
19
|
-
ay search leads --filter "source=website,stage=qualified" --fields "name,email,stage"
|
|
20
|
-
ay find invoices --filter "total>500" --count Just count matches`)
|
|
21
|
-
.option("--filter <filters>", "Comma-separated key=value filters (supports =, !=, >, <, >=, <=)")
|
|
22
|
-
.option("--fields <fields>", "Comma-separated fields to return (projection)")
|
|
23
|
-
.option("--sort <field>", "Sort by field (prefix with - for descending)", "-createdAt")
|
|
24
|
-
.option("--count", "Only return count of matching entries", false)
|
|
25
|
-
.option("-l, --limit <number>", "Limit results", parseInt, 25)
|
|
26
|
-
.option("-p, --page <number>", "Page number", parseInt, 1)
|
|
27
|
-
.action(async (collection, query, options) => {
|
|
28
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
29
|
-
try {
|
|
30
|
-
const opts = { ...program.opts(), ...options };
|
|
31
|
-
const module = getModuleFromCollection(collection);
|
|
32
|
-
spinner.start({ text: `Searching ${collection}...`, color: "magenta" });
|
|
33
|
-
const params = {
|
|
34
|
-
page: opts.page,
|
|
35
|
-
limit: opts.limit,
|
|
36
|
-
sort: opts.sort,
|
|
37
|
-
responseFormat: opts.responseFormat,
|
|
38
|
-
verbosity: opts.verbosity,
|
|
39
|
-
hideMeta: opts.hideMeta,
|
|
40
|
-
};
|
|
41
|
-
if (query) {
|
|
42
|
-
params.q = query;
|
|
43
|
-
}
|
|
44
|
-
if (opts.fields) {
|
|
45
|
-
params.fields = opts.fields;
|
|
46
|
-
}
|
|
47
|
-
// Parse filters into query params
|
|
48
|
-
if (opts.filter) {
|
|
49
|
-
const filters = opts.filter.split(",");
|
|
50
|
-
for (const f of filters) {
|
|
51
|
-
const match = f.match(/^(\w+)(!=|>=|<=|>|<|=)(.+)$/);
|
|
52
|
-
if (match) {
|
|
53
|
-
const [, key, op, value] = match;
|
|
54
|
-
if (op === "=") {
|
|
55
|
-
params[key] = value;
|
|
56
|
-
}
|
|
57
|
-
else if (op === "!=") {
|
|
58
|
-
params[`${key}[ne]`] = value;
|
|
59
|
-
}
|
|
60
|
-
else if (op === ">") {
|
|
61
|
-
params[`${key}[gt]`] = value;
|
|
62
|
-
}
|
|
63
|
-
else if (op === "<") {
|
|
64
|
-
params[`${key}[lt]`] = value;
|
|
65
|
-
}
|
|
66
|
-
else if (op === ">=") {
|
|
67
|
-
params[`${key}[gte]`] = value;
|
|
68
|
-
}
|
|
69
|
-
else if (op === "<=") {
|
|
70
|
-
params[`${key}[lte]`] = value;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
const res = await apiCallHandler(module.module, collection.toLowerCase(), "get", null, params);
|
|
76
|
-
if (opts.count) {
|
|
77
|
-
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;
|
|
78
|
-
spinner.success({ text: `${total} matching entries in ${collection}` });
|
|
79
|
-
spinner.stop();
|
|
80
|
-
console.log(total);
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
handleResponseFormatOptions(opts, res);
|
|
84
|
-
const total = (_f = (_e = (_d = res.meta) === null || _d === void 0 ? void 0 : _d.pageInfo) === null || _e === void 0 ? void 0 : _e.totalEntries) !== null && _f !== void 0 ? _f : 0;
|
|
85
|
-
const page = (_j = (_h = (_g = res.meta) === null || _g === void 0 ? void 0 : _g.pageInfo) === null || _h === void 0 ? void 0 : _h.page) !== null && _j !== void 0 ? _j : 1;
|
|
86
|
-
const totalPages = (_m = (_l = (_k = res.meta) === null || _k === void 0 ? void 0 : _k.pageInfo) === null || _l === void 0 ? void 0 : _l.totalPages) !== null && _m !== void 0 ? _m : 1;
|
|
87
|
-
spinner.success({
|
|
88
|
-
text: `Found ${total} entries in ${collection} (page ${page}/${totalPages})`,
|
|
89
|
-
});
|
|
90
|
-
spinner.stop();
|
|
91
|
-
localStorage.setItem("lastModule", module.module);
|
|
92
|
-
localStorage.setItem("lastCollection", collection);
|
|
93
|
-
if (opts.save)
|
|
94
|
-
await saveFile("search", opts, res);
|
|
95
|
-
}
|
|
96
|
-
catch (e) {
|
|
97
|
-
spinner.error({ text: e.message || "Search failed" });
|
|
98
|
-
process.exit(EXIT_GENERAL_ERROR);
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
}
|
|
@@ -1,228 +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
|
-
import { aYOUneModules } from "../../data/modules.js";
|
|
7
|
-
import { aYOUneServices } from "../../data/services.js";
|
|
8
|
-
function buildServiceRegistry() {
|
|
9
|
-
const services = [];
|
|
10
|
-
// APIs from modules
|
|
11
|
-
for (const m of aYOUneModules) {
|
|
12
|
-
services.push({
|
|
13
|
-
name: m.label,
|
|
14
|
-
type: "api",
|
|
15
|
-
module: m.module,
|
|
16
|
-
host: m.host,
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
// Services
|
|
20
|
-
for (const s of aYOUneServices) {
|
|
21
|
-
services.push({
|
|
22
|
-
name: s.label,
|
|
23
|
-
type: "service",
|
|
24
|
-
module: s.module,
|
|
25
|
-
host: s.host,
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
return services;
|
|
29
|
-
}
|
|
30
|
-
export function createServicesCommand(program) {
|
|
31
|
-
const svc = program
|
|
32
|
-
.command("services")
|
|
33
|
-
.alias("svc")
|
|
34
|
-
.description("Discover and manage aYOUne platform services");
|
|
35
|
-
// ay services list
|
|
36
|
-
svc
|
|
37
|
-
.command("list")
|
|
38
|
-
.alias("ls")
|
|
39
|
-
.description("List all registered services, APIs, and gateways")
|
|
40
|
-
.option("--type <type>", "Filter by type: api, service, gateway, worker")
|
|
41
|
-
.option("--module <module>", "Filter by module name")
|
|
42
|
-
.action(async (options) => {
|
|
43
|
-
try {
|
|
44
|
-
const opts = { ...program.opts(), ...options };
|
|
45
|
-
spinner.start({ text: "Loading service registry...", color: "magenta" });
|
|
46
|
-
let services = buildServiceRegistry();
|
|
47
|
-
if (opts.type) {
|
|
48
|
-
services = services.filter((s) => s.type === opts.type);
|
|
49
|
-
}
|
|
50
|
-
if (opts.module) {
|
|
51
|
-
services = services.filter((s) => s.module === opts.module);
|
|
52
|
-
}
|
|
53
|
-
const res = {
|
|
54
|
-
payload: services,
|
|
55
|
-
meta: { responseTime: 0, pageInfo: { totalEntries: services.length, page: 1, totalPages: 1 } },
|
|
56
|
-
};
|
|
57
|
-
handleResponseFormatOptions(opts, res);
|
|
58
|
-
spinner.success({ text: `Found ${services.length} services` });
|
|
59
|
-
spinner.stop();
|
|
60
|
-
if (opts.save)
|
|
61
|
-
await saveFile("services-list", opts, res);
|
|
62
|
-
}
|
|
63
|
-
catch (e) {
|
|
64
|
-
spinner.error({ text: e.message || "Failed to list services" });
|
|
65
|
-
process.exit(EXIT_GENERAL_ERROR);
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
// ay services endpoints <host>
|
|
69
|
-
svc
|
|
70
|
-
.command("endpoints <host>")
|
|
71
|
-
.alias("ep")
|
|
72
|
-
.description("List API endpoints for a service host")
|
|
73
|
-
.addHelpText("after", `
|
|
74
|
-
Examples:
|
|
75
|
-
ay services endpoints ai.ayoune.app
|
|
76
|
-
ay services endpoints crm-api.ayoune.app -r table`)
|
|
77
|
-
.action(async (host, options) => {
|
|
78
|
-
try {
|
|
79
|
-
const opts = { ...program.opts(), ...options };
|
|
80
|
-
spinner.start({ text: `Fetching endpoints for ${host}...`, color: "magenta" });
|
|
81
|
-
const res = await apiCallHandler("config", "ayouneapiactions", "get", null, {
|
|
82
|
-
limit: 500,
|
|
83
|
-
responseFormat: "json",
|
|
84
|
-
});
|
|
85
|
-
if (!(res === null || res === void 0 ? void 0 : res.payload)) {
|
|
86
|
-
spinner.error({ text: "No API actions found" });
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
const endpoints = (Array.isArray(res.payload) ? res.payload : [])
|
|
90
|
-
.filter((a) => {
|
|
91
|
-
const h = a.host || "";
|
|
92
|
-
return h.includes(host) && !a.deprecated;
|
|
93
|
-
})
|
|
94
|
-
.map((a) => ({
|
|
95
|
-
method: (a.method || "GET").toUpperCase(),
|
|
96
|
-
endpoint: a.endpoint || "",
|
|
97
|
-
operationId: a.operationId || "",
|
|
98
|
-
action: a.action || "",
|
|
99
|
-
description: a.shortDescription || a.description || "",
|
|
100
|
-
}))
|
|
101
|
-
.sort((a, b) => a.endpoint.localeCompare(b.endpoint));
|
|
102
|
-
const formattedRes = {
|
|
103
|
-
payload: endpoints,
|
|
104
|
-
meta: { responseTime: 0, pageInfo: { totalEntries: endpoints.length, page: 1, totalPages: 1 } },
|
|
105
|
-
};
|
|
106
|
-
handleResponseFormatOptions(opts, formattedRes);
|
|
107
|
-
spinner.success({ text: `Found ${endpoints.length} endpoints on ${host}` });
|
|
108
|
-
spinner.stop();
|
|
109
|
-
if (opts.save)
|
|
110
|
-
await saveFile("service-endpoints", opts, formattedRes);
|
|
111
|
-
}
|
|
112
|
-
catch (e) {
|
|
113
|
-
spinner.error({ text: e.message || "Failed to fetch endpoints" });
|
|
114
|
-
process.exit(EXIT_GENERAL_ERROR);
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
// ay services health [host]
|
|
118
|
-
svc
|
|
119
|
-
.command("health [host]")
|
|
120
|
-
.description("Check health of a service or all services")
|
|
121
|
-
.option("--timeout <ms>", "Request timeout in ms", parseInt, 5000)
|
|
122
|
-
.action(async (host, options) => {
|
|
123
|
-
try {
|
|
124
|
-
const opts = { ...program.opts(), ...options };
|
|
125
|
-
const targets = host
|
|
126
|
-
? [{ name: host, host }]
|
|
127
|
-
: buildServiceRegistry().map((s) => ({ name: s.name, host: s.host }));
|
|
128
|
-
// Deduplicate by host
|
|
129
|
-
const uniqueTargets = [...new Map(targets.map((t) => [t.host, t])).values()];
|
|
130
|
-
spinner.start({ text: `Checking ${uniqueTargets.length} service(s)...`, color: "magenta" });
|
|
131
|
-
const { default: axios } = await import("axios");
|
|
132
|
-
const https = await import("https");
|
|
133
|
-
const agent = new https.Agent({ rejectUnauthorized: false });
|
|
134
|
-
const results = await Promise.allSettled(uniqueTargets.map(async (t) => {
|
|
135
|
-
const start = Date.now();
|
|
136
|
-
try {
|
|
137
|
-
const resp = await axios.get(`https://${t.host}/`, {
|
|
138
|
-
timeout: opts.timeout,
|
|
139
|
-
httpsAgent: agent,
|
|
140
|
-
validateStatus: () => true,
|
|
141
|
-
});
|
|
142
|
-
return {
|
|
143
|
-
host: t.host,
|
|
144
|
-
name: t.name,
|
|
145
|
-
status: resp.status < 500 ? "healthy" : "unhealthy",
|
|
146
|
-
statusCode: resp.status,
|
|
147
|
-
responseTime: Date.now() - start,
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
catch (e) {
|
|
151
|
-
return {
|
|
152
|
-
host: t.host,
|
|
153
|
-
name: t.name,
|
|
154
|
-
status: "unreachable",
|
|
155
|
-
statusCode: 0,
|
|
156
|
-
responseTime: Date.now() - start,
|
|
157
|
-
error: e.code || e.message,
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
}));
|
|
161
|
-
const payload = results.map((r) => (r.status === "fulfilled" ? r.value : { status: "error" }));
|
|
162
|
-
const healthy = payload.filter((p) => p.status === "healthy").length;
|
|
163
|
-
const res = {
|
|
164
|
-
payload,
|
|
165
|
-
meta: {
|
|
166
|
-
responseTime: 0,
|
|
167
|
-
pageInfo: { totalEntries: payload.length, page: 1, totalPages: 1 },
|
|
168
|
-
},
|
|
169
|
-
};
|
|
170
|
-
handleResponseFormatOptions(opts, res);
|
|
171
|
-
spinner.success({ text: `${healthy}/${uniqueTargets.length} services healthy` });
|
|
172
|
-
spinner.stop();
|
|
173
|
-
if (opts.save)
|
|
174
|
-
await saveFile("services-health", opts, res);
|
|
175
|
-
}
|
|
176
|
-
catch (e) {
|
|
177
|
-
spinner.error({ text: e.message || "Health check failed" });
|
|
178
|
-
process.exit(EXIT_GENERAL_ERROR);
|
|
179
|
-
}
|
|
180
|
-
});
|
|
181
|
-
// ay services describe <module>
|
|
182
|
-
svc
|
|
183
|
-
.command("describe <module>")
|
|
184
|
-
.alias("desc")
|
|
185
|
-
.description("Show detailed info about a module/service")
|
|
186
|
-
.action(async (moduleName, options) => {
|
|
187
|
-
try {
|
|
188
|
-
const opts = { ...program.opts(), ...options };
|
|
189
|
-
spinner.start({ text: `Describing ${moduleName}...`, color: "magenta" });
|
|
190
|
-
// Find matching entries
|
|
191
|
-
const apis = aYOUneModules.filter((m) => m.module === moduleName);
|
|
192
|
-
const svcs = aYOUneServices.filter((s) => s.module === moduleName);
|
|
193
|
-
// Fetch endpoint count from apiactions
|
|
194
|
-
const res = await apiCallHandler("config", "ayouneapiactions", "get", null, {
|
|
195
|
-
limit: 500,
|
|
196
|
-
responseFormat: "json",
|
|
197
|
-
});
|
|
198
|
-
const allActions = Array.isArray(res === null || res === void 0 ? void 0 : res.payload) ? res.payload : [];
|
|
199
|
-
const moduleActions = allActions.filter((a) => a.nameSpace === moduleName && !a.deprecated);
|
|
200
|
-
const methods = {};
|
|
201
|
-
for (const a of moduleActions) {
|
|
202
|
-
const m = (a.method || "GET").toUpperCase();
|
|
203
|
-
methods[m] = (methods[m] || 0) + 1;
|
|
204
|
-
}
|
|
205
|
-
const description = {
|
|
206
|
-
module: moduleName,
|
|
207
|
-
apis: apis.map((a) => ({ label: a.label, host: a.host })),
|
|
208
|
-
services: svcs.map((s) => ({ label: s.label, host: s.host })),
|
|
209
|
-
endpoints: {
|
|
210
|
-
total: moduleActions.length,
|
|
211
|
-
byMethod: methods,
|
|
212
|
-
},
|
|
213
|
-
capabilities: [...new Set(moduleActions.map((a) => a.capability).filter(Boolean))].sort(),
|
|
214
|
-
};
|
|
215
|
-
const formattedRes = {
|
|
216
|
-
payload: description,
|
|
217
|
-
meta: { responseTime: 0 },
|
|
218
|
-
};
|
|
219
|
-
handleResponseFormatOptions(opts, formattedRes);
|
|
220
|
-
spinner.success({ text: `Module: ${moduleName} — ${moduleActions.length} endpoints` });
|
|
221
|
-
spinner.stop();
|
|
222
|
-
}
|
|
223
|
-
catch (e) {
|
|
224
|
-
spinner.error({ text: e.message || "Failed to describe service" });
|
|
225
|
-
process.exit(EXIT_GENERAL_ERROR);
|
|
226
|
-
}
|
|
227
|
-
});
|
|
228
|
-
}
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import chalk from "chalk";
|
|
2
|
-
import { localStorage } from "../helpers/localStorage.js";
|
|
3
|
-
import { loadConfig } from "../helpers/configLoader.js";
|
|
4
|
-
import { spinner } from "../../index.js";
|
|
5
|
-
import { EXIT_GENERAL_ERROR } from "../exitCodes.js";
|
|
6
|
-
const REDACT_KEYS = new Set(["token", "refreshToken"]);
|
|
7
|
-
function redact(value) {
|
|
8
|
-
if (value.length <= 8)
|
|
9
|
-
return "••••";
|
|
10
|
-
return value.slice(0, 4) + "••••" + value.slice(-4);
|
|
11
|
-
}
|
|
12
|
-
export function createStorageCommand(program) {
|
|
13
|
-
program
|
|
14
|
-
.command("storage")
|
|
15
|
-
.alias("s")
|
|
16
|
-
.description("Display stored session data and preferences")
|
|
17
|
-
.action(async () => {
|
|
18
|
-
var _a, _b;
|
|
19
|
-
try {
|
|
20
|
-
const storage = {};
|
|
21
|
-
for (let i = 0; i < localStorage.length; i++) {
|
|
22
|
-
const key = localStorage.key(i);
|
|
23
|
-
if (key) {
|
|
24
|
-
const value = (_a = localStorage.getItem(key)) !== null && _a !== void 0 ? _a : "";
|
|
25
|
-
storage[key] = REDACT_KEYS.has(key) ? redact(value) : value;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
console.log();
|
|
29
|
-
console.log(chalk.bold(" Session Storage"));
|
|
30
|
-
console.log(chalk.dim(` ${"─".repeat(44)}`));
|
|
31
|
-
const maxKey = Math.max(...Object.keys(storage).map((k) => k.length), 0);
|
|
32
|
-
for (const [key, value] of Object.entries(storage)) {
|
|
33
|
-
console.log(` ${chalk.dim(key.padEnd(maxKey + 2))} ${chalk.white(value)}`);
|
|
34
|
-
}
|
|
35
|
-
const config = loadConfig();
|
|
36
|
-
const defaults = (_b = config.defaults) !== null && _b !== void 0 ? _b : {};
|
|
37
|
-
const defaultEntries = Object.entries(defaults).filter(([, v]) => v !== undefined && v !== null);
|
|
38
|
-
if (defaultEntries.length > 0) {
|
|
39
|
-
console.log();
|
|
40
|
-
console.log(chalk.bold(" Config Defaults"));
|
|
41
|
-
console.log(chalk.dim(` ${"─".repeat(44)}`));
|
|
42
|
-
const maxDefault = Math.max(...defaultEntries.map(([k]) => k.length));
|
|
43
|
-
for (const [key, value] of defaultEntries) {
|
|
44
|
-
console.log(` ${chalk.dim(key.padEnd(maxDefault + 2))} ${chalk.white(String(value))}`);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
console.log();
|
|
48
|
-
}
|
|
49
|
-
catch (e) {
|
|
50
|
-
spinner.error({ text: e.message || "An unexpected error occurred" });
|
|
51
|
-
process.exit(EXIT_GENERAL_ERROR);
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { Option } from "commander";
|
|
2
|
-
import { localStorage } from "../helpers/localStorage.js";
|
|
3
|
-
import { decodeToken } from "../api/decodeToken.js";
|
|
4
|
-
import { customerSocket } from "../socket/customerSocketClient.js";
|
|
5
|
-
import { spinner } from "../../index.js";
|
|
6
|
-
import yaml from "js-yaml";
|
|
7
|
-
import { EXIT_GENERAL_ERROR } from "../exitCodes.js";
|
|
8
|
-
export function createStreamCommand(program) {
|
|
9
|
-
program
|
|
10
|
-
.command("stream")
|
|
11
|
-
.alias("listen")
|
|
12
|
-
.description("Subscribe to real-time data changes via WebSocket")
|
|
13
|
-
.addHelpText("after", `
|
|
14
|
-
Examples:
|
|
15
|
-
ay stream Stream all data changes as JSON
|
|
16
|
-
ay stream -f yaml Stream changes in YAML format
|
|
17
|
-
ay listen -l minimal Stream with minimal detail`)
|
|
18
|
-
.addOption(new Option("-f, --format <format>", "Set the output format")
|
|
19
|
-
.choices(["json", "yaml", "table"])
|
|
20
|
-
.default("json"))
|
|
21
|
-
.addOption(new Option("-l, --level <level>", "Set the detail level")
|
|
22
|
-
.choices(["default", "minimal", "extended"])
|
|
23
|
-
.default("default"))
|
|
24
|
-
.action(async (options) => {
|
|
25
|
-
try {
|
|
26
|
-
const tokenPayload = decodeToken(localStorage.getItem("token"));
|
|
27
|
-
const user = tokenPayload.payload;
|
|
28
|
-
console.log(`Starting stream with [${user._customerID}]`);
|
|
29
|
-
spinner.start({ text: `Starting stream with [${user._customerID}]` });
|
|
30
|
-
const socket = customerSocket(user);
|
|
31
|
-
spinner.update({ text: "Stream active" });
|
|
32
|
-
socket.onAny((channel, data) => {
|
|
33
|
-
spinner.update({ text: `Received [${channel}]` });
|
|
34
|
-
if (options.format === "table") {
|
|
35
|
-
console.table(data);
|
|
36
|
-
}
|
|
37
|
-
if (options.format === "yaml") {
|
|
38
|
-
console.log(yaml.dump(data));
|
|
39
|
-
}
|
|
40
|
-
if (options.format === "json") {
|
|
41
|
-
console.log(JSON.stringify(data, null, 2));
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
catch (e) {
|
|
46
|
-
spinner.error({ text: e.message || "An unexpected error occurred" });
|
|
47
|
-
process.exit(EXIT_GENERAL_ERROR);
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
}
|