@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 Start interactive module browser
33
- ay m Same using alias
34
- ay m crm Jump straight to the CRM module
35
- ay m crm consumers Jump to CRM consumers collection`)
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
- .action(async (moduleArg, collectionArg, options) => {
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
- if (!process.stdin.isTTY) {
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tolinax/ayoune-cli",
3
- "version": "2026.2.4",
3
+ "version": "2026.3.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "./index.js",