@dereekb/dbx-cli 13.11.1 → 13.11.2

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.
@@ -136,7 +136,7 @@ function stripJsonComments(text) {
136
136
  import { readdirSync, readFileSync as readFileSync3, statSync } from "node:fs";
137
137
  import { join as join2 } from "node:path";
138
138
 
139
- // packages/dbx-cli/firebase-api-manifest/src/generate-api-manifest/extract-crud.ts
139
+ // packages/dbx-cli/manifest-extract/src/lib/extract-crud.ts
140
140
  import { Node as Node2, Project as Project2 } from "ts-morph";
141
141
  var SUPPORTED_VERBS = /* @__PURE__ */ new Set(["create", "read", "update", "delete", "query"]);
142
142
  function extractCrudEntries(source) {
@@ -147,24 +147,51 @@ function extractCrudEntries(source) {
147
147
  const crudConfigType = findTypeAliasByEnding(sourceFile, "ModelCrudFunctionsConfig");
148
148
  const groupName = inferGroupName(sourceFile);
149
149
  const functionsClassName = findFunctionsClassName(sourceFile);
150
+ const typeDocsCache = /* @__PURE__ */ new Map();
151
+ const resolveTypeDocs = (typeName) => {
152
+ if (!typeName) {
153
+ return void 0;
154
+ }
155
+ if (typeDocsCache.has(typeName)) {
156
+ return typeDocsCache.get(typeName);
157
+ }
158
+ const docs = readTypeDocs(sourceFile, typeName);
159
+ if (docs) {
160
+ typeDocsCache.set(typeName, docs);
161
+ }
162
+ return docs;
163
+ };
150
164
  if (crudConfigType) {
151
165
  const literal = crudConfigType.getTypeNode();
152
166
  if (literal && Node2.isTypeLiteral(literal)) {
153
167
  for (const member of literal.getMembers()) {
154
- if (!Node2.isPropertySignature(member)) continue;
168
+ if (!Node2.isPropertySignature(member)) {
169
+ continue;
170
+ }
155
171
  const modelName = member.getName();
156
172
  modelKeys.push(modelName);
157
173
  const valueNode = member.getTypeNode();
158
- if (!valueNode) continue;
159
- if (isNullLiteralType(valueNode)) continue;
174
+ if (!valueNode) {
175
+ continue;
176
+ }
177
+ if (isNullLiteralType(valueNode)) {
178
+ continue;
179
+ }
160
180
  if (Node2.isTypeLiteral(valueNode)) {
161
181
  for (const verbMember of valueNode.getMembers()) {
162
- if (!Node2.isPropertySignature(verbMember)) continue;
163
- const verb = verbMember.getName();
164
- if (!SUPPORTED_VERBS.has(verb)) continue;
182
+ if (!Node2.isPropertySignature(verbMember)) {
183
+ continue;
184
+ }
185
+ const verbName = verbMember.getName();
186
+ if (!SUPPORTED_VERBS.has(verbName)) {
187
+ continue;
188
+ }
189
+ const verb = verbName;
165
190
  const verbValueNode = verbMember.getTypeNode();
166
- if (!verbValueNode) continue;
167
- collectVerbEntries({ modelName, verb, valueNode: verbValueNode, entries });
191
+ if (!verbValueNode) {
192
+ continue;
193
+ }
194
+ collectVerbEntries({ modelName, verb, valueNode: verbValueNode, entries, fallbackDescription: readJsDocSummary(verbMember), resolveTypeDocs });
168
195
  }
169
196
  }
170
197
  }
@@ -175,17 +202,26 @@ function extractCrudEntries(source) {
175
202
  const literal = functionTypeMap.getTypeNode();
176
203
  if (literal && Node2.isTypeLiteral(literal)) {
177
204
  for (const member of literal.getMembers()) {
178
- if (!Node2.isPropertySignature(member)) continue;
205
+ if (!Node2.isPropertySignature(member)) {
206
+ continue;
207
+ }
179
208
  const key = member.getName();
180
209
  const valueNode = member.getTypeNode();
181
210
  const tuple = valueNode ? readTupleParamsResult(valueNode) : void 0;
211
+ const paramsDocs = resolveTypeDocs(tuple?.params);
212
+ const resultDocs = resolveTypeDocs(tuple?.result);
182
213
  entries.push({
183
214
  model: key,
184
215
  verb: "standalone",
185
216
  specifier: void 0,
186
217
  paramsTypeName: tuple?.params,
187
218
  resultTypeName: tuple?.result,
188
- line: member.getStartLineNumber()
219
+ line: member.getStartLineNumber(),
220
+ description: readJsDocSummary(member),
221
+ paramsTypeDescription: paramsDocs?.typeDescription,
222
+ paramsFields: paramsDocs?.fields,
223
+ resultTypeDescription: resultDocs?.typeDescription,
224
+ resultFields: resultDocs?.fields
189
225
  });
190
226
  }
191
227
  }
@@ -194,15 +230,21 @@ function extractCrudEntries(source) {
194
230
  }
195
231
  function findTypeAliasByEnding(sourceFile, ending) {
196
232
  for (const alias of sourceFile.getTypeAliases()) {
197
- if (alias.getName().endsWith(ending) && alias.getTypeNode()) return alias;
233
+ if (alias.getName().endsWith(ending) && alias.getTypeNode()) {
234
+ return alias;
235
+ }
198
236
  }
199
237
  return void 0;
200
238
  }
201
239
  function findFunctionsClassName(sourceFile) {
202
240
  for (const cls of sourceFile.getClasses()) {
203
- if (!cls.isAbstract()) continue;
241
+ if (!cls.isAbstract()) {
242
+ continue;
243
+ }
204
244
  const name = cls.getName();
205
- if (name?.endsWith("Functions")) return name;
245
+ if (name?.endsWith("Functions")) {
246
+ return name;
247
+ }
206
248
  }
207
249
  return void 0;
208
250
  }
@@ -211,14 +253,18 @@ function inferGroupName(sourceFile) {
211
253
  const name = alias.getName();
212
254
  if (name.endsWith("ModelCrudFunctionsConfig")) {
213
255
  const stem = name.slice(0, -"ModelCrudFunctionsConfig".length);
214
- if (stem.length > 0) return stem;
256
+ if (stem.length > 0) {
257
+ return stem;
258
+ }
215
259
  }
216
260
  }
217
261
  for (const alias of sourceFile.getTypeAliases()) {
218
262
  const name = alias.getName();
219
263
  if (name.endsWith("FunctionTypeMap")) {
220
264
  const stem = name.slice(0, -"FunctionTypeMap".length);
221
- if (stem.length > 0) return stem;
265
+ if (stem.length > 0) {
266
+ return stem;
267
+ }
222
268
  }
223
269
  }
224
270
  return void 0;
@@ -226,50 +272,74 @@ function inferGroupName(sourceFile) {
226
272
  function isNullLiteralType(node) {
227
273
  if (Node2.isLiteralTypeNode(node)) {
228
274
  const literal = node.getLiteral();
229
- if (Node2.isNullLiteral(literal)) return true;
275
+ if (Node2.isNullLiteral(literal)) {
276
+ return true;
277
+ }
230
278
  }
231
279
  return false;
232
280
  }
233
281
  function collectVerbEntries(input) {
234
- const { modelName, verb, valueNode, entries } = input;
282
+ const { modelName, verb, valueNode, entries, fallbackDescription, resolveTypeDocs } = input;
235
283
  if (Node2.isTypeLiteral(valueNode)) {
236
284
  for (const specMember of valueNode.getMembers()) {
237
- if (!Node2.isPropertySignature(specMember)) continue;
285
+ if (!Node2.isPropertySignature(specMember)) {
286
+ continue;
287
+ }
238
288
  const specifier = specMember.getName();
239
289
  const leafNode = specMember.getTypeNode();
240
290
  const leaf2 = leafNode ? readTupleParamsResult(leafNode) ?? readBareParams(leafNode) : void 0;
291
+ const paramsDocs2 = resolveTypeDocs(leaf2?.params);
292
+ const resultDocs2 = resolveTypeDocs(leaf2?.result);
241
293
  entries.push({
242
294
  model: modelName,
243
295
  verb,
244
296
  specifier,
245
297
  paramsTypeName: leaf2?.params,
246
298
  resultTypeName: leaf2?.result,
247
- line: specMember.getStartLineNumber()
299
+ line: specMember.getStartLineNumber(),
300
+ description: readJsDocSummary(specMember),
301
+ paramsTypeDescription: paramsDocs2?.typeDescription,
302
+ paramsFields: paramsDocs2?.fields,
303
+ resultTypeDescription: resultDocs2?.typeDescription,
304
+ resultFields: resultDocs2?.fields
248
305
  });
249
306
  }
250
307
  return;
251
308
  }
252
309
  const leaf = readTupleParamsResult(valueNode) ?? readBareParams(valueNode);
310
+ const paramsDocs = resolveTypeDocs(leaf?.params);
311
+ const resultDocs = resolveTypeDocs(leaf?.result);
253
312
  entries.push({
254
313
  model: modelName,
255
314
  verb,
256
315
  specifier: void 0,
257
316
  paramsTypeName: leaf?.params,
258
317
  resultTypeName: leaf?.result,
259
- line: valueNode.getStartLineNumber()
318
+ line: valueNode.getStartLineNumber(),
319
+ description: fallbackDescription,
320
+ paramsTypeDescription: paramsDocs?.typeDescription,
321
+ paramsFields: paramsDocs?.fields,
322
+ resultTypeDescription: resultDocs?.typeDescription,
323
+ resultFields: resultDocs?.fields
260
324
  });
261
325
  }
262
326
  function readTupleParamsResult(node) {
263
- if (!Node2.isTupleTypeNode(node)) return void 0;
327
+ if (!Node2.isTupleTypeNode(node)) {
328
+ return void 0;
329
+ }
264
330
  const elements = node.getElements();
265
- if (elements.length === 0) return void 0;
331
+ if (elements.length === 0) {
332
+ return void 0;
333
+ }
266
334
  const params = elements[0] ? typeNodeName(elements[0]) : void 0;
267
335
  const result = elements[1] ? typeNodeName(elements[1]) : void 0;
268
336
  return { params, result };
269
337
  }
270
338
  function readBareParams(node) {
271
339
  const params = typeNodeName(node);
272
- if (!params) return void 0;
340
+ if (!params) {
341
+ return void 0;
342
+ }
273
343
  return { params, result: void 0 };
274
344
  }
275
345
  function typeNodeName(node) {
@@ -279,6 +349,40 @@ function typeNodeName(node) {
279
349
  const text = node.getText().trim();
280
350
  return text.length > 0 ? text : void 0;
281
351
  }
352
+ function readTypeDocs(sourceFile, typeName) {
353
+ const interfaceDecl = sourceFile.getInterface(typeName);
354
+ if (interfaceDecl) {
355
+ const typeDescription = readJsDocSummary(interfaceDecl);
356
+ const fields = [];
357
+ for (const property of interfaceDecl.getProperties()) {
358
+ const fieldName = property.getName();
359
+ const description = readJsDocSummary(property);
360
+ const typeNode = property.getTypeNode();
361
+ const typeText = typeNode?.getText().trim() ?? "";
362
+ const field = description ? { name: fieldName, typeText, description } : { name: fieldName, typeText };
363
+ fields.push(field);
364
+ }
365
+ if (!typeDescription && fields.length === 0) {
366
+ return void 0;
367
+ }
368
+ return { typeDescription, fields: fields.length > 0 ? fields : void 0 };
369
+ }
370
+ const typeAlias = sourceFile.getTypeAlias(typeName);
371
+ if (typeAlias) {
372
+ const typeDescription = readJsDocSummary(typeAlias);
373
+ return typeDescription ? { typeDescription } : void 0;
374
+ }
375
+ return void 0;
376
+ }
377
+ function readJsDocSummary(node) {
378
+ const docs = node.getJsDocs();
379
+ if (docs.length === 0) {
380
+ return void 0;
381
+ }
382
+ const last = docs[docs.length - 1];
383
+ const description = last.getDescription().trim();
384
+ return description.length > 0 ? description : void 0;
385
+ }
282
386
 
283
387
  // packages/dbx-cli/firebase-api-manifest/src/generate-api-manifest/find-api-files.ts
284
388
  function findApiFiles(packageRoot) {
@@ -437,10 +541,23 @@ function renderEntry({ entry, validatorName }) {
437
541
  validatorName ? `paramsValidator: ${validatorName}` : void 0,
438
542
  entry.resultTypeName ? `resultTypeName: ${JSON.stringify(entry.resultTypeName)}` : void 0,
439
543
  `groupName: ${JSON.stringify(entry.groupName)}`,
440
- `sourceFile: ${JSON.stringify(entry.sourceFile)}`
544
+ `sourceFile: ${JSON.stringify(entry.sourceFile)}`,
545
+ entry.description ? `description: ${JSON.stringify(entry.description)}` : void 0,
546
+ entry.paramsTypeDescription ? `paramsTypeDescription: ${JSON.stringify(entry.paramsTypeDescription)}` : void 0,
547
+ entry.paramsFields && entry.paramsFields.length > 0 ? `paramsFields: ${renderDocFields(entry.paramsFields)}` : void 0,
548
+ entry.resultTypeDescription ? `resultTypeDescription: ${JSON.stringify(entry.resultTypeDescription)}` : void 0,
549
+ entry.resultFields && entry.resultFields.length > 0 ? `resultFields: ${renderDocFields(entry.resultFields)}` : void 0
441
550
  ];
442
551
  return ` { ${fields.filter((v) => Boolean(v)).join(", ")} }`;
443
552
  }
553
+ function renderDocFields(fields) {
554
+ const items = fields.map((field) => {
555
+ const parts = [`name: ${JSON.stringify(field.name)}`, `typeText: ${JSON.stringify(field.typeText)}`];
556
+ if (field.description) parts.push(`description: ${JSON.stringify(field.description)}`);
557
+ return `{ ${parts.join(", ")} }`;
558
+ });
559
+ return `[${items.join(", ")}]`;
560
+ }
444
561
  async function formatWithPrettier(source, outputFile) {
445
562
  const config = await resolveConfig(outputFile);
446
563
  return format(source, { ...config, filepath: outputFile });
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dereekb/dbx-cli-firebase-api-manifest",
3
- "version": "13.11.1",
3
+ "version": "13.11.2",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "devDependencies": {
package/index.cjs.js CHANGED
@@ -1660,7 +1660,7 @@ function mergeOutputCommandsConfig(existing, updates) {
1660
1660
  * The `model.*` write scopes filtered out by {@link filterReadOnlyModelScopes}.
1661
1661
  *
1662
1662
  * Mirrors the write half of the dbx-components callModel CRUD scope set
1663
- * (`CALL_MODEL_OIDC_SCOPES` in `@dereekb/firebase-server/oidc`) — duplicated here so the
1663
+ * (`CALL_MODEL_OIDC_SCOPES` in `@dereekb/firebase`) — duplicated here so the
1664
1664
  * CLI doesn't take a server-side dependency just to know the names.
1665
1665
  */ var MODEL_WRITE_OIDC_SCOPES = [
1666
1666
  'model.create',
@@ -7093,6 +7093,15 @@ var SKIPPED_VERBS = new Set([
7093
7093
  'standalone'
7094
7094
  ]);
7095
7095
  var ALL_HELP_FLAG = '--all-help';
7096
+ var HELP_MODE_FLAG = '--help-mode';
7097
+ /**
7098
+ * Default help mode when no override is supplied.
7099
+ */ var DEFAULT_MANIFEST_HELP_MODE = 'both';
7100
+ var MANIFEST_HELP_MODES = new Set([
7101
+ 'action',
7102
+ 'params',
7103
+ 'both'
7104
+ ]);
7096
7105
  /**
7097
7106
  * Default schema format when no override is supplied.
7098
7107
  */ var DEFAULT_MANIFEST_HELP_DATA_FORMAT = 'jsonschema';
@@ -7125,7 +7134,7 @@ var DATA_HELP_FLAG = '--data-help';
7125
7134
  * @returns The yargs `CommandModule[]` ready to be passed to `runCli({ apiCommands })`. Empty
7126
7135
  * when the manifest has no callable entries.
7127
7136
  */ function buildManifestCommands(manifest, options) {
7128
- var _ref, _ref1, _ref2, _ref3, _ref4;
7137
+ var _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
7129
7138
  var callable = manifest.filter(function(e) {
7130
7139
  return !SKIPPED_VERBS.has(e.verb);
7131
7140
  });
@@ -7162,15 +7171,17 @@ var DATA_HELP_FLAG = '--data-help';
7162
7171
  }
7163
7172
  var argv = (_ref = options === null || options === void 0 ? void 0 : options.argv) !== null && _ref !== void 0 ? _ref : process.argv;
7164
7173
  var dataHelpFormat = (_ref1 = options === null || options === void 0 ? void 0 : options.dataHelpFormat) !== null && _ref1 !== void 0 ? _ref1 : detectDataHelpFormat(argv);
7165
- var focusHelp = ((_ref2 = options === null || options === void 0 ? void 0 : options.focusHelpOnDataHelp) !== null && _ref2 !== void 0 ? _ref2 : true) && hasDataHelpFlag(argv) && !hasAllHelpFlag(argv);
7166
- var hideOnFocus = focusHelp ? (_ref3 = options === null || options === void 0 ? void 0 : options.hiddenWhenFocused) !== null && _ref3 !== void 0 ? _ref3 : STANDARD_GLOBAL_OPTION_NAMES : [];
7167
- var modelCommandName = (_ref4 = options === null || options === void 0 ? void 0 : options.modelCommandName) !== null && _ref4 !== void 0 ? _ref4 : DEFAULT_MANIFEST_MODEL_COMMAND_NAME;
7174
+ var helpMode = (_ref2 = options === null || options === void 0 ? void 0 : options.helpMode) !== null && _ref2 !== void 0 ? _ref2 : detectHelpMode(argv);
7175
+ var focusHelp = ((_ref3 = options === null || options === void 0 ? void 0 : options.focusHelpOnDataHelp) !== null && _ref3 !== void 0 ? _ref3 : true) && hasDataHelpFlag(argv) && !hasAllHelpFlag(argv);
7176
+ var hideOnFocus = focusHelp ? (_ref4 = options === null || options === void 0 ? void 0 : options.hiddenWhenFocused) !== null && _ref4 !== void 0 ? _ref4 : STANDARD_GLOBAL_OPTION_NAMES : [];
7177
+ var modelCommandName = (_ref5 = options === null || options === void 0 ? void 0 : options.modelCommandName) !== null && _ref5 !== void 0 ? _ref5 : DEFAULT_MANIFEST_MODEL_COMMAND_NAME;
7168
7178
  var sortedModels = _to_consumable_array(byModel.entries()).sort(function(param, param1) {
7169
7179
  var _param = _sliced_to_array(param, 1), a = _param[0], _param1 = _sliced_to_array(param1, 1), b = _param1[0];
7170
7180
  return a.localeCompare(b);
7171
7181
  });
7172
7182
  var context = {
7173
7183
  dataHelpFormat: dataHelpFormat,
7184
+ helpMode: helpMode,
7174
7185
  hideOnFocus: hideOnFocus
7175
7186
  };
7176
7187
  return [
@@ -7263,6 +7274,38 @@ var DATA_HELP_FLAG = '--data-help';
7263
7274
  function parseDataHelpFormat(value) {
7264
7275
  return MANIFEST_HELP_DATA_FORMATS.has(value) ? value : undefined;
7265
7276
  }
7277
+ /**
7278
+ * Inspects an argv array for `--help-mode=<mode>` or `--help-mode <mode>` and
7279
+ * returns the requested {@link ManifestHelpMode}. Unrecognized values fall
7280
+ * back to {@link DEFAULT_MANIFEST_HELP_MODE}.
7281
+ *
7282
+ * Implemented as a raw argv scan (rather than going through yargs) because the
7283
+ * value is needed when each command's builder runs — which is before yargs
7284
+ * parses argv.
7285
+ *
7286
+ * @param argv - argv to inspect (defaults to `process.argv`).
7287
+ * @returns The detected mode, or {@link DEFAULT_MANIFEST_HELP_MODE}.
7288
+ */ function detectHelpMode() {
7289
+ var argv = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : process.argv;
7290
+ var result = DEFAULT_MANIFEST_HELP_MODE;
7291
+ for(var i = 0; i < argv.length; i++){
7292
+ var arg = argv[i];
7293
+ if (arg.startsWith("".concat(HELP_MODE_FLAG, "="))) {
7294
+ var _parseHelpMode;
7295
+ result = (_parseHelpMode = parseHelpMode(arg.slice(HELP_MODE_FLAG.length + 1))) !== null && _parseHelpMode !== void 0 ? _parseHelpMode : result;
7296
+ break;
7297
+ }
7298
+ if (arg === HELP_MODE_FLAG && i + 1 < argv.length) {
7299
+ var _parseHelpMode1;
7300
+ result = (_parseHelpMode1 = parseHelpMode(argv[i + 1])) !== null && _parseHelpMode1 !== void 0 ? _parseHelpMode1 : result;
7301
+ break;
7302
+ }
7303
+ }
7304
+ return result;
7305
+ }
7306
+ function parseHelpMode(value) {
7307
+ return MANIFEST_HELP_MODES.has(value) ? value : undefined;
7308
+ }
7266
7309
  function buildModelCommand(model, entries, context) {
7267
7310
  return {
7268
7311
  command: "".concat(model, " <action>"),
@@ -7297,14 +7340,15 @@ function buildModelCommand(model, entries, context) {
7297
7340
  };
7298
7341
  }
7299
7342
  function buildEntryCommand(entry, context) {
7300
- var _entry_description;
7343
+ var _oneLineDescription;
7301
7344
  var action = entry.specifier && entry.specifier !== '_' ? "".concat(entry.verb, "-").concat(entry.specifier) : entry.verb;
7302
7345
  var specPart = entry.specifier && entry.specifier !== '_' ? ' ' + entry.specifier : '';
7303
- var describe = (_entry_description = entry.description) !== null && _entry_description !== void 0 ? _entry_description : "".concat(entry.verb).concat(specPart, " on ").concat(entry.model);
7304
- var epilogue = buildEntryEpilogue(entry, context.dataHelpFormat);
7346
+ var fallbackDescribe = "".concat(entry.verb).concat(specPart, " on ").concat(entry.model);
7347
+ var describeOneLine = (_oneLineDescription = oneLineDescription(entry.description)) !== null && _oneLineDescription !== void 0 ? _oneLineDescription : fallbackDescribe;
7348
+ var epilogue = buildEntryEpilogue(entry, context);
7305
7349
  return {
7306
7350
  command: action,
7307
- describe: describe,
7351
+ describe: describeOneLine,
7308
7352
  builder: function builder(yargs) {
7309
7353
  var y = yargs.option('data', {
7310
7354
  type: 'string',
@@ -7353,6 +7397,12 @@ function buildEntryCommand(entry, context) {
7353
7397
  }
7354
7398
  };
7355
7399
  }
7400
+ function oneLineDescription(description) {
7401
+ var _description_split_;
7402
+ if (!description) return undefined;
7403
+ var firstLine = (_description_split_ = description.split('\n', 1)[0]) === null || _description_split_ === void 0 ? void 0 : _description_split_.trim();
7404
+ return firstLine && firstLine.length > 0 ? firstLine : undefined;
7405
+ }
7356
7406
  function hideGlobalOptions(yargs, names) {
7357
7407
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
7358
7408
  try {
@@ -7376,37 +7426,145 @@ function hideGlobalOptions(yargs, names) {
7376
7426
  }
7377
7427
  }
7378
7428
  /**
7379
- * Builds the help epilogue for a manifest-driven command. Surfaces the params
7380
- * arktype validator (as JSON Schema and/or the arktype expression — see
7381
- * {@link ManifestHelpDataFormat}) along with the params/result type names and
7382
- * the source `.api.ts` path for traceability. Designed to give both humans
7383
- * and LLM agents enough information from `--help` alone to construct a valid
7384
- * `--data` payload.
7429
+ * Builds the help epilogue for a manifest-driven command. Surfaces the action
7430
+ * description JSDoc, the params interface description and per-field
7431
+ * descriptions, the params arktype validator (as JSON Schema and/or arktype
7432
+ * expression — see {@link ManifestHelpDataFormat}), and the source `.api.ts`
7433
+ * path for traceability. Designed to give both humans and LLM agents enough
7434
+ * information from `--help` alone to understand a command and construct a
7435
+ * valid `--data` payload.
7385
7436
  *
7386
7437
  * @param entry - Manifest entry whose metadata becomes the help epilogue.
7387
- * @param dataHelpFormat - Format used for the `Params Schema` section.
7438
+ * @param context - Builder context controlling schema format and which sections
7439
+ * to render (see {@link ManifestHelpMode}).
7388
7440
  * @returns Multi-section epilogue string, or `undefined` when the entry has no
7389
7441
  * metadata worth surfacing.
7390
- */ function buildEntryEpilogue(entry, dataHelpFormat) {
7391
- var _sections;
7442
+ */ function buildEntryEpilogue(entry, context) {
7443
+ var dataHelpFormat = context.dataHelpFormat, helpMode = context.helpMode;
7444
+ var showAction = helpMode === 'action' || helpMode === 'both';
7445
+ var showParams = helpMode === 'params' || helpMode === 'both';
7392
7446
  var sections = [];
7393
- if (entry.paramsTypeName) {
7394
- sections.push("Params: ".concat(entry.paramsTypeName));
7395
- }
7396
- var schemaSections = renderParamsSchemaSections(entry, dataHelpFormat);
7397
- (_sections = sections).push.apply(_sections, _to_consumable_array(schemaSections));
7398
- if (entry.resultTypeName) {
7399
- sections.push("Result: ".concat(entry.resultTypeName));
7447
+ if (showAction) {
7448
+ var actionSection = buildActionSection(entry);
7449
+ if (actionSection) sections.push(actionSection);
7450
+ }
7451
+ var schemaSections = [];
7452
+ if (showParams) {
7453
+ var _sections;
7454
+ var paramsSection = buildParamsSection(entry);
7455
+ if (paramsSection) sections.push(paramsSection);
7456
+ schemaSections = renderParamsSchemaSections(entry, dataHelpFormat);
7457
+ (_sections = sections).push.apply(_sections, _to_consumable_array(schemaSections));
7458
+ var resultSection = buildResultSection(entry);
7459
+ if (resultSection) {
7460
+ sections.push(resultSection);
7461
+ } else if (entry.resultTypeName) {
7462
+ sections.push("Result: ".concat(entry.resultTypeName));
7463
+ }
7400
7464
  }
7401
7465
  if (entry.sourceFile) {
7402
7466
  sections.push("Source: ".concat(entry.sourceFile));
7403
7467
  }
7404
- if (schemaSections.length > 0 && dataHelpFormat !== 'both') {
7468
+ if (showParams && schemaSections.length > 0 && dataHelpFormat !== 'both') {
7405
7469
  var other = dataHelpFormat === 'jsonschema' ? 'arktype' : 'jsonschema';
7406
7470
  sections.push("(Pass --data-help=".concat(other, " or --data-help=both to switch the schema format above.)"));
7407
7471
  }
7472
+ if (helpMode === 'both' && (entry.description || entry.paramsTypeDescription || entry.paramsFields && entry.paramsFields.length > 0)) {
7473
+ sections.push("(Pass --help-mode=action or --help-mode=params to focus this help on a single section.)");
7474
+ }
7408
7475
  return sections.length > 0 ? sections.join('\n\n') : undefined;
7409
7476
  }
7477
+ function buildActionSection(entry) {
7478
+ if (!entry.description) return undefined;
7479
+ return "About:\n".concat(indentLines(entry.description, ' '));
7480
+ }
7481
+ function buildParamsSection(entry) {
7482
+ if (!entry.paramsTypeName && !entry.paramsTypeDescription && !(entry.paramsFields && entry.paramsFields.length > 0)) {
7483
+ return undefined;
7484
+ }
7485
+ var lines = [];
7486
+ if (entry.paramsTypeName) {
7487
+ lines.push("Params: ".concat(entry.paramsTypeName));
7488
+ }
7489
+ if (entry.paramsTypeDescription) {
7490
+ lines.push(indentLines(entry.paramsTypeDescription, ' '));
7491
+ }
7492
+ if (entry.paramsFields && entry.paramsFields.length > 0) {
7493
+ lines.push('');
7494
+ lines.push('Fields:');
7495
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
7496
+ try {
7497
+ for(var _iterator = entry.paramsFields[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
7498
+ var field = _step.value;
7499
+ var header = " - ".concat(field.name, ": ").concat(field.typeText);
7500
+ lines.push(header);
7501
+ if (field.description) {
7502
+ lines.push(indentLines(field.description, ' '));
7503
+ }
7504
+ }
7505
+ } catch (err) {
7506
+ _didIteratorError = true;
7507
+ _iteratorError = err;
7508
+ } finally{
7509
+ try {
7510
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
7511
+ _iterator.return();
7512
+ }
7513
+ } finally{
7514
+ if (_didIteratorError) {
7515
+ throw _iteratorError;
7516
+ }
7517
+ }
7518
+ }
7519
+ }
7520
+ return lines.join('\n');
7521
+ }
7522
+ function buildResultSection(entry) {
7523
+ if (!entry.resultTypeDescription && !(entry.resultFields && entry.resultFields.length > 0)) {
7524
+ return undefined;
7525
+ }
7526
+ var lines = [];
7527
+ if (entry.resultTypeName) {
7528
+ lines.push("Result: ".concat(entry.resultTypeName));
7529
+ }
7530
+ if (entry.resultTypeDescription) {
7531
+ lines.push(indentLines(entry.resultTypeDescription, ' '));
7532
+ }
7533
+ if (entry.resultFields && entry.resultFields.length > 0) {
7534
+ lines.push('');
7535
+ lines.push('Fields:');
7536
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
7537
+ try {
7538
+ for(var _iterator = entry.resultFields[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
7539
+ var field = _step.value;
7540
+ var header = " - ".concat(field.name, ": ").concat(field.typeText);
7541
+ lines.push(header);
7542
+ if (field.description) {
7543
+ lines.push(indentLines(field.description, ' '));
7544
+ }
7545
+ }
7546
+ } catch (err) {
7547
+ _didIteratorError = true;
7548
+ _iteratorError = err;
7549
+ } finally{
7550
+ try {
7551
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
7552
+ _iterator.return();
7553
+ }
7554
+ } finally{
7555
+ if (_didIteratorError) {
7556
+ throw _iteratorError;
7557
+ }
7558
+ }
7559
+ }
7560
+ }
7561
+ return lines.join('\n');
7562
+ }
7563
+ function indentLines(text, indent) {
7564
+ return text.split('\n').map(function(line) {
7565
+ return "".concat(indent).concat(line);
7566
+ }).join('\n');
7567
+ }
7410
7568
  function renderParamsSchemaSections(entry, dataHelpFormat) {
7411
7569
  var sections = [];
7412
7570
  if (!entry.paramsValidator) {
@@ -8119,6 +8277,7 @@ exports.CliError = CliError;
8119
8277
  exports.DEFAULT_CLI_OIDC_SCOPES = DEFAULT_CLI_OIDC_SCOPES;
8120
8278
  exports.DEFAULT_CLI_SECRET_PATTERNS = DEFAULT_CLI_SECRET_PATTERNS;
8121
8279
  exports.DEFAULT_MANIFEST_HELP_DATA_FORMAT = DEFAULT_MANIFEST_HELP_DATA_FORMAT;
8280
+ exports.DEFAULT_MANIFEST_HELP_MODE = DEFAULT_MANIFEST_HELP_MODE;
8122
8281
  exports.DEFAULT_MANIFEST_MODEL_COMMAND_NAME = DEFAULT_MANIFEST_MODEL_COMMAND_NAME;
8123
8282
  exports.DUMP_MERGE_MODES = DUMP_MERGE_MODES;
8124
8283
  exports.DUMP_OUTPUT_MODES = DUMP_OUTPUT_MODES;
@@ -8150,6 +8309,7 @@ exports.createOutputCommand = createOutputCommand;
8150
8309
  exports.createOutputMiddleware = createOutputMiddleware;
8151
8310
  exports.defaultDoctorChecks = defaultDoctorChecks;
8152
8311
  exports.detectDataHelpFormat = detectDataHelpFormat;
8312
+ exports.detectHelpMode = detectHelpMode;
8153
8313
  exports.discoverOidcMetadata = discoverOidcMetadata;
8154
8314
  exports.dumpTimestamp = dumpTimestamp;
8155
8315
  exports.exchangeAuthorizationCode = exchangeAuthorizationCode;