@tolinax/ayoune-cli 2026.2.4 → 2026.3.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.
|
@@ -7,10 +7,15 @@ import { handleCollectionOperation } from "../operations/handleCollectionOperati
|
|
|
7
7
|
import { localStorage } from "../helpers/localStorage.js";
|
|
8
8
|
import { parseInteger } from "../helpers/parseInt.js";
|
|
9
9
|
import { handleGetOperation } from "../operations/handleGetOperation.js";
|
|
10
|
+
import { handleCreateSingleOperation } from "../operations/handleCreateSingleOperation.js";
|
|
11
|
+
import { handleDeleteSingleOperation } from "../operations/handleDeleteSingleOperation.js";
|
|
10
12
|
import { aYOUneModules } from "../../data/modules.js";
|
|
11
13
|
import { getModelsInModules } from "../models/getModelsInModules.js";
|
|
14
|
+
import { apiCallHandler } from "../api/apiCallHandler.js";
|
|
15
|
+
import { handleResponseFormatOptions } from "../helpers/handleResponseFormatOptions.js";
|
|
12
16
|
import { spinner } from "../../index.js";
|
|
13
17
|
import { EXIT_GENERAL_ERROR, EXIT_MISUSE } from "../exitCodes.js";
|
|
18
|
+
const DIRECT_OPERATIONS = ["list", "get", "create", "delete"];
|
|
14
19
|
function resolveModule(input) {
|
|
15
20
|
const lower = input.toLowerCase();
|
|
16
21
|
const match = aYOUneModules.find((m) => m.module === lower || m.label.toLowerCase() === lower);
|
|
@@ -24,25 +29,28 @@ function resolveCollection(module, input) {
|
|
|
24
29
|
}
|
|
25
30
|
export function createModulesCommand(program) {
|
|
26
31
|
program
|
|
27
|
-
.command("modules [module] [collection]")
|
|
32
|
+
.command("modules [module] [collection] [operation] [subject]")
|
|
28
33
|
.alias("m")
|
|
29
34
|
.description("Browse modules, collections, and entries interactively")
|
|
30
35
|
.addHelpText("after", `
|
|
31
36
|
Examples:
|
|
32
|
-
ay modules
|
|
33
|
-
ay m
|
|
34
|
-
ay m crm
|
|
35
|
-
ay m crm consumers
|
|
37
|
+
ay modules Start interactive module browser
|
|
38
|
+
ay m Same using alias
|
|
39
|
+
ay m crm Jump straight to the CRM module
|
|
40
|
+
ay m crm consumers Jump to CRM consumers collection
|
|
41
|
+
ay m pm projects list List all projects
|
|
42
|
+
ay m pm projects create "Migration" Create a new project
|
|
43
|
+
ay m pm projects get <id> Get a project by ID
|
|
44
|
+
ay m pm projects delete <id> Delete a project by ID`)
|
|
36
45
|
.option("-p, --page <number>", "Page", parseInteger, 1)
|
|
37
46
|
.option("-l, --limit <number>", "Limit", parseInteger, 20)
|
|
38
47
|
.option("-f, --from <date>", "From date")
|
|
39
|
-
.
|
|
48
|
+
.option("-a, --all", "Fetch all pages (list only)")
|
|
49
|
+
.option("-q, --search <term>", "Search term")
|
|
50
|
+
.action(async (moduleArg, collectionArg, operationArg, subjectArg, options) => {
|
|
40
51
|
try {
|
|
41
52
|
const opts = { ...program.opts(), ...options };
|
|
42
|
-
|
|
43
|
-
spinner.error({ text: "The modules command requires an interactive terminal" });
|
|
44
|
-
process.exit(EXIT_MISUSE);
|
|
45
|
-
}
|
|
53
|
+
// ─── Resolve module ──────────────────────────────────
|
|
46
54
|
let module;
|
|
47
55
|
if (moduleArg) {
|
|
48
56
|
const resolved = resolveModule(moduleArg);
|
|
@@ -53,8 +61,13 @@ Examples:
|
|
|
53
61
|
module = resolved;
|
|
54
62
|
}
|
|
55
63
|
else {
|
|
64
|
+
if (!process.stdin.isTTY) {
|
|
65
|
+
spinner.error({ text: "The modules command requires an interactive terminal" });
|
|
66
|
+
process.exit(EXIT_MISUSE);
|
|
67
|
+
}
|
|
56
68
|
module = await promptModule();
|
|
57
69
|
}
|
|
70
|
+
// ─── Resolve collection ──────────────────────────────
|
|
58
71
|
let collection;
|
|
59
72
|
if (collectionArg) {
|
|
60
73
|
const resolved = resolveCollection(module, collectionArg);
|
|
@@ -65,11 +78,59 @@ Examples:
|
|
|
65
78
|
collection = resolved;
|
|
66
79
|
}
|
|
67
80
|
else {
|
|
81
|
+
if (!process.stdin.isTTY) {
|
|
82
|
+
spinner.error({ text: "Missing required argument: collection" });
|
|
83
|
+
process.exit(EXIT_MISUSE);
|
|
84
|
+
}
|
|
68
85
|
collection = await promptCollectionInModule(module);
|
|
69
86
|
}
|
|
70
|
-
const operation = await promptOperation();
|
|
71
87
|
localStorage.setItem("lastModule", module);
|
|
72
88
|
localStorage.setItem("lastCollection", collection);
|
|
89
|
+
// ─── Direct operation mode ───────────────────────────
|
|
90
|
+
if (operationArg && DIRECT_OPERATIONS.includes(operationArg.toLowerCase())) {
|
|
91
|
+
const op = operationArg.toLowerCase();
|
|
92
|
+
if (op === "list") {
|
|
93
|
+
const { result } = await handleListOperation(module, collection, opts);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
if (op === "get") {
|
|
97
|
+
if (!subjectArg) {
|
|
98
|
+
spinner.error({ text: "Missing required argument: id" });
|
|
99
|
+
process.exit(EXIT_MISUSE);
|
|
100
|
+
}
|
|
101
|
+
spinner.start({ text: `Getting ${collection} ${subjectArg}...`, color: "magenta" });
|
|
102
|
+
const res = await apiCallHandler(module, `${collection.toLowerCase()}/${subjectArg}`, "get", null, {
|
|
103
|
+
responseFormat: opts.responseFormat,
|
|
104
|
+
verbosity: opts.verbosity,
|
|
105
|
+
});
|
|
106
|
+
handleResponseFormatOptions(opts, res);
|
|
107
|
+
spinner.success({ text: `Got ${collection} [${subjectArg}]` });
|
|
108
|
+
spinner.stop();
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (op === "create") {
|
|
112
|
+
if (!subjectArg) {
|
|
113
|
+
spinner.error({ text: "Missing required argument: name/subject" });
|
|
114
|
+
process.exit(EXIT_MISUSE);
|
|
115
|
+
}
|
|
116
|
+
await handleCreateSingleOperation(module, collection, subjectArg, opts);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (op === "delete") {
|
|
120
|
+
if (!subjectArg) {
|
|
121
|
+
spinner.error({ text: "Missing required argument: id" });
|
|
122
|
+
process.exit(EXIT_MISUSE);
|
|
123
|
+
}
|
|
124
|
+
await handleDeleteSingleOperation(module, collection, subjectArg, opts);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// ─── Interactive mode (no operation provided) ────────
|
|
129
|
+
if (!process.stdin.isTTY) {
|
|
130
|
+
spinner.error({ text: "Interactive mode requires a terminal. Use: ay m <module> <collection> <operation> [subject]" });
|
|
131
|
+
process.exit(EXIT_MISUSE);
|
|
132
|
+
}
|
|
133
|
+
const operation = await promptOperation();
|
|
73
134
|
let entry = "";
|
|
74
135
|
if (operation === "list") {
|
|
75
136
|
const { result } = await handleListOperation(module, collection, opts);
|