dataiku-sdk 3.4.0 → 3.5.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.
Files changed (110) hide show
  1. package/README.md +3 -3
  2. package/dist/build-metadata.json +1 -1
  3. package/dist/src/cli/command-syntax.json +14524 -0
  4. package/dist/src/cli/commands/analysis.js +6 -9
  5. package/dist/src/cli/commands/api-deployer.js +15 -33
  6. package/dist/src/cli/commands/api-service.js +17 -27
  7. package/dist/src/cli/commands/app.js +22 -39
  8. package/dist/src/cli/commands/bundle.js +15 -24
  9. package/dist/src/cli/commands/business-app.js +10 -17
  10. package/dist/src/cli/commands/code-env.js +23 -36
  11. package/dist/src/cli/commands/code.js +4 -4
  12. package/dist/src/cli/commands/connection.js +12 -22
  13. package/dist/src/cli/commands/continuous-activity.js +6 -9
  14. package/dist/src/cli/commands/dashboard.js +8 -13
  15. package/dist/src/cli/commands/data-collection.js +9 -16
  16. package/dist/src/cli/commands/data-quality.js +14 -26
  17. package/dist/src/cli/commands/dataset.js +27 -50
  18. package/dist/src/cli/commands/discussion.js +7 -10
  19. package/dist/src/cli/commands/doctor.js +3 -3
  20. package/dist/src/cli/commands/flow-zone.js +8 -17
  21. package/dist/src/cli/commands/folder.js +12 -20
  22. package/dist/src/cli/commands/future.js +7 -10
  23. package/dist/src/cli/commands/group.js +7 -11
  24. package/dist/src/cli/commands/insight.js +7 -11
  25. package/dist/src/cli/commands/job.js +13 -23
  26. package/dist/src/cli/commands/knowledge-bank.js +5 -6
  27. package/dist/src/cli/commands/llm.js +5 -8
  28. package/dist/src/cli/commands/macro.js +9 -16
  29. package/dist/src/cli/commands/meaning.js +7 -11
  30. package/dist/src/cli/commands/metrics.js +7 -10
  31. package/dist/src/cli/commands/ml-task.js +12 -20
  32. package/dist/src/cli/commands/model-evaluation-store.js +7 -11
  33. package/dist/src/cli/commands/notebook.js +15 -27
  34. package/dist/src/cli/commands/plugin.js +35 -68
  35. package/dist/src/cli/commands/project-deployer.js +10 -22
  36. package/dist/src/cli/commands/project-folder.js +10 -17
  37. package/dist/src/cli/commands/project-git.js +38 -70
  38. package/dist/src/cli/commands/project-library.js +15 -23
  39. package/dist/src/cli/commands/project.js +9 -26
  40. package/dist/src/cli/commands/recipe.d.ts +16 -0
  41. package/dist/src/cli/commands/recipe.js +83 -94
  42. package/dist/src/cli/commands/saved-model.js +23 -39
  43. package/dist/src/cli/commands/scenario.js +20 -34
  44. package/dist/src/cli/commands/sql.js +4 -4
  45. package/dist/src/cli/commands/statistics.js +11 -18
  46. package/dist/src/cli/commands/streaming-endpoint.js +7 -11
  47. package/dist/src/cli/commands/user.js +11 -22
  48. package/dist/src/cli/commands/variable.js +3 -4
  49. package/dist/src/cli/commands/webapp.js +10 -16
  50. package/dist/src/cli/commands/wiki.js +9 -13
  51. package/dist/src/cli/commands/workspace.js +8 -14
  52. package/dist/src/cli/contract.d.ts +5 -15
  53. package/dist/src/cli/contract.js +156 -253
  54. package/dist/src/cli/doctor.js +1 -0
  55. package/dist/src/cli/env.d.ts +2 -0
  56. package/dist/src/cli/env.js +15 -1
  57. package/dist/src/cli/helpers/app-permissions.js +2 -1
  58. package/dist/src/cli/helpers/flow-zone.js +2 -1
  59. package/dist/src/cli/helpers/recipe.js +2 -1
  60. package/dist/src/cli/syntax.d.ts +83 -0
  61. package/dist/src/cli/syntax.js +217 -0
  62. package/dist/src/cli/types.d.ts +3 -0
  63. package/dist/src/cli/usage.d.ts +1 -1
  64. package/dist/src/cli/usage.js +4 -2
  65. package/dist/src/cli/version.js +2 -0
  66. package/dist/src/cli.js +37 -64
  67. package/dist/src/client.js +7 -6
  68. package/dist/src/errors.d.ts +12 -1
  69. package/dist/src/errors.js +28 -3
  70. package/dist/src/index.d.ts +1 -3
  71. package/dist/src/index.js +2 -2
  72. package/dist/src/resources/api-services.js +2 -3
  73. package/dist/src/resources/applications.js +2 -4
  74. package/dist/src/resources/code-envs.js +2 -2
  75. package/dist/src/resources/data-quality.js +4 -3
  76. package/dist/src/resources/datasets.d.ts +13 -0
  77. package/dist/src/resources/datasets.js +5 -4
  78. package/dist/src/resources/flow-zones.js +4 -2
  79. package/dist/src/resources/folders.js +4 -2
  80. package/dist/src/resources/futures.js +1 -3
  81. package/dist/src/resources/insights.js +3 -2
  82. package/dist/src/resources/jobs.js +4 -6
  83. package/dist/src/resources/macros.js +2 -4
  84. package/dist/src/resources/notebooks.js +2 -3
  85. package/dist/src/resources/project-git.js +9 -11
  86. package/dist/src/resources/project-library.d.ts +0 -2
  87. package/dist/src/resources/project-library.js +2 -7
  88. package/dist/src/resources/projects.js +4 -3
  89. package/dist/src/resources/recipes.d.ts +28 -0
  90. package/dist/src/resources/recipes.js +116 -84
  91. package/dist/src/resources/sql.js +8 -3
  92. package/dist/src/resources/statistics.js +2 -1
  93. package/dist/src/resources/variables.js +2 -1
  94. package/dist/src/resources/webapps.js +2 -3
  95. package/dist/src/schemas.d.ts +1 -2
  96. package/dist/src/schemas.js +1 -1
  97. package/dist/src/skill.js +6 -7
  98. package/dist/src/utils/cleanup-ledger.js +9 -8
  99. package/dist/src/utils/polling.d.ts +3 -0
  100. package/dist/src/utils/polling.js +3 -0
  101. package/dist/src/utils/project-archive.js +2 -2
  102. package/dist/src/utils/stable-hash.d.ts +3 -1
  103. package/dist/src/utils/stable-hash.js +2 -0
  104. package/package.json +4 -4
  105. package/plugin.json +1 -1
  106. package/skills/dataiku-dss/SKILL.md +2 -3
  107. package/skills/dataiku-dss/references/authentication.md +3 -3
  108. package/skills/dataiku-dss/references/coding.md +1 -1
  109. package/dist/src/utils/pagination.d.ts +0 -8
  110. package/dist/src/utils/pagination.js +0 -23
@@ -1,23 +1,24 @@
1
+ import { unexpectedResponseError, } from "../../errors.js";
1
2
  import { writeResponseToFile, } from "../../utils/response-file.js";
2
3
  import { json, jsonInput, parseBooleanOption, requiredJsonInput, } from "../coerce.js";
3
4
  import { executionMode, } from "../flags.js";
4
5
  import { readIfExists, skipResult, } from "../output.js";
6
+ import { commandUsage, withUsage, } from "../syntax.js";
5
7
  import { requireArgs, UsageError, } from "../usage.js";
6
8
  /**
7
9
  * Mutating actions accept --plan (buildMutationPlan in contract.ts owns the
8
10
  * --plan path centrally); the handlers below keep --dry-run support with a
9
11
  * zero-request planned payload, mirroring set-active/delete.
10
12
  */
11
- export const savedModelCommands = {
13
+ export const savedModelCommands = withUsage("saved-model", {
12
14
  list: {
13
15
  handler: (c, _a, f) => c.savedModels.list(f["project-key"]),
14
- usage: "dss saved-model list [--project-key KEY]",
15
16
  description: "List saved models in a project.",
16
17
  examples: ["dss saved-model list --project-key PROJECT",],
17
18
  },
18
19
  "create-external": {
19
20
  handler: async (c, a, f) => {
20
- const usage = "dss saved-model create-external <name> --type MLFLOW_PYFUNC|PROXY_MODEL [--prediction-type TYPE] [--configuration JSON] [--data JSON] [--dry-run] [--project-key KEY]";
21
+ const usage = commandUsage("saved-model", "create-external");
21
22
  requireArgs(a, 1, usage);
22
23
  const savedModelType = f["type"]?.trim();
23
24
  if (savedModelType !== "MLFLOW_PYFUNC" && savedModelType !== "PROXY_MODEL") {
@@ -66,7 +67,6 @@ export const savedModelCommands = {
66
67
  : {}),
67
68
  }, projectKey);
68
69
  },
69
- usage: "dss saved-model create-external <name> --type MLFLOW_PYFUNC|PROXY_MODEL [--prediction-type TYPE] [--configuration JSON] [--data JSON] [--dry-run] [--project-key KEY]",
70
70
  description: "Create a saved model for MLflow or external (proxy) models. --type selects savedModelType; --prediction-type is BINARY_CLASSIFICATION, MULTICLASS, or REGRESSION; --configuration (JSON via --data/--data-file/--stdin) is the PROXY_MODEL protocol configuration forwarded as proxyModelConfiguration.",
71
71
  examples: [
72
72
  "dss saved-model create-external 'MLflow Demo' --type MLFLOW_PYFUNC --prediction-type BINARY_CLASSIFICATION",
@@ -75,16 +75,15 @@ export const savedModelCommands = {
75
75
  },
76
76
  get: {
77
77
  handler: (c, a, f) => {
78
- requireArgs(a, 1, "dss saved-model get <modelId> [--project-key KEY]");
78
+ requireArgs(a, 1, commandUsage("saved-model", "get"));
79
79
  return c.savedModels.get(a[0], f["project-key"]);
80
80
  },
81
- usage: "dss saved-model get <modelId> [--project-key KEY]",
82
81
  description: "Get a saved model.",
83
82
  examples: ["dss saved-model get MODEL_ID --project-key PROJECT",],
84
83
  },
85
84
  "update-settings": {
86
85
  handler: async (c, a, f) => {
87
- const usage = "dss saved-model update-settings <modelId> (--data JSON|--data-file PATH|--stdin) [--dry-run] [--project-key KEY]";
86
+ const usage = commandUsage("saved-model", "update-settings");
88
87
  requireArgs(a, 1, usage);
89
88
  const settings = requiredJsonInput(f, "Saved-model settings JSON is required via --data, --data-file, or --stdin (GET-then-PUT the full settings document).");
90
89
  const projectKey = f["project-key"];
@@ -103,7 +102,6 @@ export const savedModelCommands = {
103
102
  resource: "saved-model",
104
103
  }));
105
104
  },
106
- usage: "dss saved-model update-settings <modelId> (--data JSON|--data-file PATH|--stdin) [--dry-run] [--project-key KEY]",
107
105
  description: "Save the settings of a saved model. The payload must be the complete settings document as returned by `saved-model get` (GET-then-PUT workflow, per the official client).",
108
106
  examples: [
109
107
  "dss saved-model get MODEL_ID --project-key P | jq . > settings.json && dss saved-model update-settings MODEL_ID --data-file settings.json --project-key P",
@@ -111,19 +109,17 @@ export const savedModelCommands = {
111
109
  },
112
110
  "list-versions": {
113
111
  handler: (c, a, f) => {
114
- requireArgs(a, 1, "dss saved-model list-versions <modelId> [--project-key KEY]");
112
+ requireArgs(a, 1, commandUsage("saved-model", "list-versions"));
115
113
  return c.savedModels.listVersions(a[0], f["project-key"]);
116
114
  },
117
- usage: "dss saved-model list-versions <modelId> [--project-key KEY]",
118
115
  description: "List versions of a saved model.",
119
116
  examples: ["dss saved-model list-versions MODEL_ID --project-key PROJECT",],
120
117
  },
121
118
  "version-details": {
122
119
  handler: (c, a, f) => {
123
- requireArgs(a, 2, "dss saved-model version-details <modelId> <versionId> [--project-key KEY]");
120
+ requireArgs(a, 2, commandUsage("saved-model", "version-details"));
124
121
  return c.savedModels.versionDetails(a[0], a[1], f["project-key"]);
125
122
  },
126
- usage: "dss saved-model version-details <modelId> <versionId> [--project-key KEY]",
127
123
  description: "Get details for one saved-model version.",
128
124
  examples: [
129
125
  "dss saved-model version-details MODEL_ID VERSION_ID --project-key PROJECT",
@@ -131,10 +127,9 @@ export const savedModelCommands = {
131
127
  },
132
128
  "version-snippet": {
133
129
  handler: (c, a, f) => {
134
- requireArgs(a, 2, "dss saved-model version-snippet <modelId> <versionId> [--project-key KEY]");
130
+ requireArgs(a, 2, commandUsage("saved-model", "version-snippet"));
135
131
  return c.savedModels.versionSnippet(a[0], a[1], f["project-key"]);
136
132
  },
137
- usage: "dss saved-model version-snippet <modelId> <versionId> [--project-key KEY]",
138
133
  description: "Get the snippet (short summary) for one saved-model version.",
139
134
  examples: [
140
135
  "dss saved-model version-snippet MODEL_ID VERSION_ID --project-key PROJECT",
@@ -142,7 +137,7 @@ export const savedModelCommands = {
142
137
  },
143
138
  "set-active": {
144
139
  handler: async (c, a, f) => {
145
- requireArgs(a, 2, "dss saved-model set-active <modelId> <versionId> [--dry-run] [--project-key KEY]");
140
+ requireArgs(a, 2, commandUsage("saved-model", "set-active"));
146
141
  const projectKey = f["project-key"];
147
142
  if (executionMode(f).dryRun) {
148
143
  return {
@@ -157,7 +152,6 @@ export const savedModelCommands = {
157
152
  }
158
153
  return c.savedModels.setActiveVersion(a[0], a[1], projectKey);
159
154
  },
160
- usage: "dss saved-model set-active <modelId> <versionId> [--dry-run] [--project-key KEY]",
161
155
  description: "Set the active version of a saved model.",
162
156
  examples: [
163
157
  "dss saved-model set-active MODEL_ID VERSION_ID --project-key PROJECT",
@@ -166,7 +160,7 @@ export const savedModelCommands = {
166
160
  },
167
161
  "delete-versions": {
168
162
  handler: async (c, a, f) => {
169
- const usage = "dss saved-model delete-versions <modelId> <versionsCSV> [--remove-intermediate true|false] [--dry-run] [--project-key KEY]";
163
+ const usage = commandUsage("saved-model", "delete-versions");
170
164
  requireArgs(a, 2, usage);
171
165
  const versions = a[1].split(",").map((v) => v.trim()).filter((v) => v.length > 0);
172
166
  if (versions.length === 0) {
@@ -188,7 +182,6 @@ export const savedModelCommands = {
188
182
  await c.savedModels.deleteVersions(versions, { removeIntermediate, }, a[0], projectKey);
189
183
  return { deletedVersions: versions, resource: "saved-model", id: a[0], };
190
184
  },
191
- usage: "dss saved-model delete-versions <modelId> <versionsCSV> [--remove-intermediate true|false] [--dry-run] [--project-key KEY]",
192
185
  description: "Delete one or more versions of a saved model (comma-separated version ids). Destructive. Implemented as POST .../actions/delete-versions per the official Python client (the REST reference's GET entry is a doc bug); the transport never retries this request.",
193
186
  examples: [
194
187
  "dss saved-model delete-versions MODEL_ID VERSION_A,VERSION_B --project-key PROJECT",
@@ -197,7 +190,7 @@ export const savedModelCommands = {
197
190
  },
198
191
  delete: {
199
192
  handler: async (c, a, f) => {
200
- requireArgs(a, 1, "dss saved-model delete <modelId> [--if-exists] [--dry-run] [--project-key KEY]");
193
+ requireArgs(a, 1, commandUsage("saved-model", "delete"));
201
194
  const projectKey = f["project-key"];
202
195
  if (executionMode(f).dryRun || f["if-exists"] === true) {
203
196
  const current = await readIfExists(() => c.savedModels.get(a[0], projectKey));
@@ -210,7 +203,6 @@ export const savedModelCommands = {
210
203
  await c.savedModels.delete(a[0], projectKey);
211
204
  return { deleted: a[0], resource: "saved-model", };
212
205
  },
213
- usage: "dss saved-model delete <modelId> [--if-exists] [--dry-run] [--project-key KEY]",
214
206
  description: "Delete a saved model.",
215
207
  examples: [
216
208
  "dss saved-model delete MODEL_ID --if-exists --project-key PROJECT",
@@ -219,7 +211,7 @@ export const savedModelCommands = {
219
211
  },
220
212
  "import-mlflow-version": {
221
213
  handler: async (c, a, f) => {
222
- const usage = "dss saved-model import-mlflow-version <modelId> <versionId> --archive PATH [--code-env NAME] [--container-exec-config NAME] [--set-active true|false] [--binary-classification-threshold N] [--dry-run] [--project-key KEY]";
214
+ const usage = commandUsage("saved-model", "import-mlflow-version");
223
215
  requireArgs(a, 2, usage);
224
216
  const archive = f["archive"];
225
217
  if (!archive)
@@ -239,7 +231,6 @@ export const savedModelCommands = {
239
231
  }
240
232
  return c.savedModels.importMlflowVersion(archive, a[1], options, a[0], projectKey);
241
233
  },
242
- usage: "dss saved-model import-mlflow-version <modelId> <versionId> --archive PATH [--code-env NAME] [--container-exec-config NAME] [--set-active true|false] [--binary-classification-threshold N] [--dry-run] [--project-key KEY]",
243
234
  description: "Import a new MLflow version from a local zip archive of the MLflow model folder (multipart upload). The saved model must be of type MLFLOW_PYFUNC.",
244
235
  examples: [
245
236
  "dss saved-model import-mlflow-version MODEL_ID v1 --archive ./mlflow-model.zip --project-key PROJECT",
@@ -248,7 +239,7 @@ export const savedModelCommands = {
248
239
  },
249
240
  "import-mlflow-version-from-folder": {
250
241
  handler: async (c, a, f) => {
251
- const usage = "dss saved-model import-mlflow-version-from-folder <modelId> <versionId> --folder PROJECT.FOLDER_ID --path PATH [--code-env NAME] [--container-exec-config NAME] [--set-active true|false] [--binary-classification-threshold N] [--dry-run] [--project-key KEY]";
242
+ const usage = commandUsage("saved-model", "import-mlflow-version-from-folder");
252
243
  requireArgs(a, 2, usage);
253
244
  const folder = f["folder"];
254
245
  if (!folder) {
@@ -272,7 +263,6 @@ export const savedModelCommands = {
272
263
  }
273
264
  return c.savedModels.importMlflowVersionFromFolder(folder, path, a[1], options, a[0], projectKey);
274
265
  },
275
- usage: "dss saved-model import-mlflow-version-from-folder <modelId> <versionId> --folder PROJECT.FOLDER_ID --path PATH [--code-env NAME] [--container-exec-config NAME] [--set-active true|false] [--binary-classification-threshold N] [--dry-run] [--project-key KEY]",
276
266
  description: "Import a new MLflow version from an MLflow model folder stored in a managed folder (folderRef PROJECT_KEY.FOLDER_ID). Sends the backend-mandated multipart request with a zero-byte file part, matching the official Python client.",
277
267
  examples: [
278
268
  "dss saved-model import-mlflow-version-from-folder MODEL_ID v1 --folder PROJ.z7pSyYzE --path /artifacts/model --project-key PROJ",
@@ -280,10 +270,9 @@ export const savedModelCommands = {
280
270
  },
281
271
  "external-metadata-get": {
282
272
  handler: (c, a, f) => {
283
- requireArgs(a, 2, "dss saved-model external-metadata-get <modelId> <versionId> [--project-key KEY]");
273
+ requireArgs(a, 2, commandUsage("saved-model", "external-metadata-get"));
284
274
  return c.savedModels.externalMetadataGet(a[0], a[1], f["project-key"]);
285
275
  },
286
- usage: "dss saved-model external-metadata-get <modelId> <versionId> [--project-key KEY]",
287
276
  description: "Get the external-ml metadata of a saved-model version (MLflow or proxy).",
288
277
  examples: [
289
278
  "dss saved-model external-metadata-get MODEL_ID VERSION_ID --project-key PROJECT",
@@ -291,7 +280,7 @@ export const savedModelCommands = {
291
280
  },
292
281
  "external-metadata-put": {
293
282
  handler: async (c, a, f) => {
294
- const usage = "dss saved-model external-metadata-put <modelId> <versionId> (--data JSON|--data-file PATH|--stdin) [--container-exec-config NAME] [--dry-run] [--project-key KEY]";
283
+ const usage = commandUsage("saved-model", "external-metadata-put");
295
284
  requireArgs(a, 2, usage);
296
285
  const metadata = requiredJsonInput(f, "Metadata JSON is required via --data, --data-file, or --stdin (GET-then-PUT the full external-ml metadata document).");
297
286
  const projectKey = f["project-key"];
@@ -312,7 +301,6 @@ export const savedModelCommands = {
312
301
  }
313
302
  return c.savedModels.externalMetadataPut(a[0], a[1], metadata, containerExecConfigName === undefined ? undefined : { containerExecConfigName, }, projectKey).then(() => ({ updated: a[0], versionId: a[1], resource: "saved-model", }));
314
303
  },
315
- usage: "dss saved-model external-metadata-put <modelId> <versionId> (--data JSON|--data-file PATH|--stdin) [--container-exec-config NAME] [--dry-run] [--project-key KEY]",
316
304
  description: "Save the external-ml metadata of a saved-model version. The payload must be the full metadata document as returned by external-metadata-get (GET-then-PUT). DSS requires the containerExecConfigName query parameter; it defaults to NONE for an external API caller (LOCAL-CONFIG resolution) when --container-exec-config is omitted.",
317
305
  examples: [
318
306
  "dss saved-model external-metadata-put MODEL_ID VERSION_ID --data-file metadata.json --project-key PROJECT",
@@ -320,7 +308,7 @@ export const savedModelCommands = {
320
308
  },
321
309
  "evaluate-version": {
322
310
  handler: async (c, a, f) => {
323
- const usage = "dss saved-model evaluate-version <modelId> <versionId> --dataset REF [--container-exec-config NAME] [--sampling JSON] [--use-optimal-threshold true|false] [--skip-expensive-reports true|false] [--dry-run] [--project-key KEY]";
311
+ const usage = commandUsage("saved-model", "evaluate-version");
324
312
  requireArgs(a, 2, usage);
325
313
  const dataset = f["dataset"];
326
314
  if (!dataset)
@@ -367,7 +355,6 @@ export const savedModelCommands = {
367
355
  await c.savedModels.evaluateVersion(body, options, a[0], a[1], projectKey);
368
356
  return { evaluated: a[0], versionId: a[1], resource: "saved-model", };
369
357
  },
370
- usage: "dss saved-model evaluate-version <modelId> <versionId> --dataset REF [--container-exec-config NAME] [--sampling JSON] [--use-optimal-threshold true|false] [--skip-expensive-reports true|false] [--dry-run] [--project-key KEY]",
371
358
  description: 'Evaluate an external/MLflow model version on a dataset. external-metadata-put must have been called first. --sampling is an optional JSON sampling parameter (e.g. {"samplingMethod":"HEAD_SEQUENTIAL","maxRecords":100}).',
372
359
  examples: [
373
360
  "dss saved-model evaluate-version MODEL_ID VERSION_ID --dataset PROJECT.my-dataset --project-key PROJECT",
@@ -376,7 +363,7 @@ export const savedModelCommands = {
376
363
  },
377
364
  "download-scoring-jar": {
378
365
  handler: async (c, a, f) => {
379
- const usage = "dss saved-model download-scoring-jar <modelId> <versionId> --output PATH [--full-class-name NAME] [--include-libs true|false] [--project-key KEY]";
366
+ const usage = commandUsage("saved-model", "download-scoring-jar");
380
367
  requireArgs(a, 2, usage);
381
368
  const out = f["output"];
382
369
  if (!out)
@@ -390,12 +377,11 @@ export const savedModelCommands = {
390
377
  };
391
378
  const res = await c.savedModels.downloadScoringJar(jarOptions, a[0], a[1], f["project-key"]);
392
379
  if (!res.body) {
393
- throw new Error("savedModels.downloadScoringJar response did not include a body");
380
+ throw unexpectedResponseError("savedModels.downloadScoringJar response did not include a body");
394
381
  }
395
382
  const bytes = await writeResponseToFile(out, res);
396
383
  return { path: out, bytes, };
397
384
  },
398
- usage: "dss saved-model download-scoring-jar <modelId> <versionId> --output PATH [--full-class-name NAME] [--include-libs true|false] [--project-key KEY]",
399
385
  description: "Download the optimized scoring JAR of a version (license-gated server side). --full-class-name forwards the documented fullClassName query parameter; --include-libs toggles including scoring libraries.",
400
386
  examples: [
401
387
  "dss saved-model download-scoring-jar MODEL_ID VERSION_ID --output ./scoring.jar --project-key PROJECT",
@@ -404,18 +390,17 @@ export const savedModelCommands = {
404
390
  },
405
391
  "download-scoring-pmml": {
406
392
  handler: async (c, a, f) => {
407
- requireArgs(a, 2, "dss saved-model download-scoring-pmml <modelId> <versionId> --output PATH [--project-key KEY]");
393
+ requireArgs(a, 2, commandUsage("saved-model", "download-scoring-pmml"));
408
394
  const out = f["output"];
409
395
  if (!out)
410
396
  throw new UsageError("--output PATH is required.", "missing_required_flag");
411
397
  const res = await c.savedModels.downloadScoringPmml(a[0], a[1], f["project-key"]);
412
398
  if (!res.body) {
413
- throw new Error("savedModels.downloadScoringPmml response did not include a body");
399
+ throw unexpectedResponseError("savedModels.downloadScoringPmml response did not include a body");
414
400
  }
415
401
  const bytes = await writeResponseToFile(out, res);
416
402
  return { path: out, bytes, };
417
403
  },
418
- usage: "dss saved-model download-scoring-pmml <modelId> <versionId> --output PATH [--project-key KEY]",
419
404
  description: "Download the PMML scoring file of a version (license-gated server side).",
420
405
  examples: [
421
406
  "dss saved-model download-scoring-pmml MODEL_ID VERSION_ID --output ./model.pmml --project-key PROJECT",
@@ -423,7 +408,7 @@ export const savedModelCommands = {
423
408
  },
424
409
  "set-user-meta": {
425
410
  handler: async (c, a, f) => {
426
- const usage = "dss saved-model set-user-meta <modelId> <versionId> (--data JSON|--data-file PATH|--stdin) [--dry-run] [--project-key KEY]";
411
+ const usage = commandUsage("saved-model", "set-user-meta");
427
412
  requireArgs(a, 2, usage);
428
413
  const userMeta = requiredJsonInput(f, "User-meta JSON is required via --data, --data-file, or --stdin.");
429
414
  const projectKey = f["project-key"];
@@ -444,13 +429,12 @@ export const savedModelCommands = {
444
429
  resource: "saved-model",
445
430
  }));
446
431
  },
447
- usage: "dss saved-model set-user-meta <modelId> <versionId> (--data JSON|--data-file PATH|--stdin) [--dry-run] [--project-key KEY]",
448
432
  description: 'Update the user metadata of a model version. Send only the "userMeta" field of a previously-retrieved version-details object.',
449
433
  examples: [
450
434
  'dss saved-model set-user-meta MODEL_ID VERSION_ID --data \'{"name":"Churn model","description":"v2"}\' --project-key PROJECT',
451
435
  ],
452
436
  },
453
- };
437
+ });
454
438
  function mlflowImportOptions(f) {
455
439
  const codeEnvName = f["code-env"];
456
440
  const containerExecConfigName = f["container-exec-config"];
@@ -1,26 +1,25 @@
1
1
  import { jsonInput, num, parseBooleanOption, } from "../coerce.js";
2
2
  import { executionMode, } from "../flags.js";
3
3
  import { encodedProjectEndpoint, readIfExists, skipResult, } from "../output.js";
4
+ import { commandUsage, withUsage, } from "../syntax.js";
4
5
  import { requireArgs, UsageError, } from "../usage.js";
5
- export const scenarioCommands = {
6
+ export const scenarioCommands = withUsage("scenario", {
6
7
  list: {
7
8
  handler: (c, _a, f) => c.scenarios.list(f["project-key"]),
8
- usage: "dss scenario list [--project-key KEY]",
9
9
  description: "List all scenarios in a project.",
10
10
  examples: ["dss scenario list",],
11
11
  },
12
12
  get: {
13
13
  handler: (c, a, f) => {
14
- requireArgs(a, 1, "dss scenario get <id>");
14
+ requireArgs(a, 1, commandUsage("scenario", "get"));
15
15
  return c.scenarios.get(a[0], { projectKey: f["project-key"], });
16
16
  },
17
- usage: "dss scenario get <id> [--project-key KEY]",
18
17
  description: "Get raw scenario definition. For step-based scenario edits, patch params.steps; rawParams.params is DSS echo data.",
19
18
  examples: ["dss scenario get my_scenario",],
20
19
  },
21
20
  run: {
22
21
  handler: async (c, a, f) => {
23
- requireArgs(a, 1, "dss scenario run <id>");
22
+ requireArgs(a, 1, commandUsage("scenario", "run"));
24
23
  const pk = f["project-key"];
25
24
  const options = {
26
25
  pollIntervalMs: num(f["poll-interval"], "--poll-interval"),
@@ -42,13 +41,12 @@ export const scenarioCommands = {
42
41
  }
43
42
  return c.scenarios.run(a[0], pk);
44
43
  },
45
- usage: "dss scenario run <id> [--wait] [--timeout MS] [--poll-interval MS] [--dry-run] [--project-key KEY]",
46
44
  description: "Trigger a scenario run, optionally waiting for completion.",
47
45
  examples: ["dss scenario run my_scenario", "dss scenario run my_scenario --wait",],
48
46
  },
49
47
  "run-and-wait": {
50
48
  handler: async (c, a, f) => {
51
- requireArgs(a, 1, "dss scenario run-and-wait <id>");
49
+ requireArgs(a, 1, commandUsage("scenario", "run-and-wait"));
52
50
  const pk = f["project-key"];
53
51
  const options = {
54
52
  pollIntervalMs: num(f["poll-interval"], "--poll-interval"),
@@ -67,7 +65,6 @@ export const scenarioCommands = {
67
65
  }
68
66
  return c.scenarios.runAndWait(a[0], { ...options, projectKey: pk, });
69
67
  },
70
- usage: "dss scenario run-and-wait <id> [--timeout MS] [--poll-interval MS] [--dry-run] [--project-key KEY]",
71
68
  description: "Run a scenario and wait for completion.",
72
69
  examples: [
73
70
  "dss scenario run-and-wait my_scenario",
@@ -76,16 +73,15 @@ export const scenarioCommands = {
76
73
  },
77
74
  status: {
78
75
  handler: (c, a, f) => {
79
- requireArgs(a, 1, "dss scenario status <id>");
76
+ requireArgs(a, 1, commandUsage("scenario", "status"));
80
77
  return c.scenarios.status(a[0], f["project-key"]);
81
78
  },
82
- usage: "dss scenario status <id> [--project-key KEY]",
83
79
  description: "Get the current run status of a scenario.",
84
80
  examples: ["dss scenario status my_scenario",],
85
81
  },
86
82
  delete: {
87
83
  handler: async (c, a, f) => {
88
- requireArgs(a, 1, "dss scenario delete <id>");
84
+ requireArgs(a, 1, commandUsage("scenario", "delete"));
89
85
  const pk = f["project-key"];
90
86
  if (executionMode(f).dryRun || f["if-exists"] === true) {
91
87
  const current = await readIfExists(() => c.scenarios.get(a[0], { projectKey: pk, }));
@@ -98,13 +94,12 @@ export const scenarioCommands = {
98
94
  await c.scenarios.delete(a[0], pk);
99
95
  return { deleted: a[0], resource: "scenario", };
100
96
  },
101
- usage: "dss scenario delete <id> [--if-exists] [--dry-run] [--project-key KEY]",
102
97
  description: "Delete a scenario.",
103
98
  examples: ["dss scenario delete my_scenario", "dss scenario delete my_scenario --if-exists",],
104
99
  },
105
100
  create: {
106
101
  handler: async (c, a, f) => {
107
- requireArgs(a, 2, "dss scenario create <id> <name>");
102
+ requireArgs(a, 2, commandUsage("scenario", "create"));
108
103
  const pk = f["project-key"];
109
104
  const payload = {
110
105
  scenarioId: a[0],
@@ -135,7 +130,6 @@ export const scenarioCommands = {
135
130
  });
136
131
  return { created: a[0], name: a[1], resource: "scenario", };
137
132
  },
138
- usage: "dss scenario create <id> <name> [--type step_based|custom_python] [--if-not-exists] [--dry-run] [--project-key KEY]",
139
133
  description: "Create a new scenario.",
140
134
  examples: [
141
135
  'dss scenario create my_scenario "My Scenario"',
@@ -144,10 +138,10 @@ export const scenarioCommands = {
144
138
  },
145
139
  update: {
146
140
  handler: async (c, a, f) => {
147
- requireArgs(a, 1, "dss scenario update <id> [--data '{...}' | --data-file PATH | --stdin]");
141
+ requireArgs(a, 1, commandUsage("scenario", "update"));
148
142
  const data = jsonInput(f);
149
143
  if (data === undefined) {
150
- throw new UsageError("--data, --data-file, or --stdin is required. Usage: dss scenario update <id> [--data '{...}' | --data-file PATH | --stdin]");
144
+ throw new UsageError(`--data, --data-file, or --stdin is required. Usage: ${commandUsage("scenario", "update")}`);
151
145
  }
152
146
  const pk = f["project-key"];
153
147
  if (executionMode(f).dryRun) {
@@ -181,7 +175,6 @@ export const scenarioCommands = {
181
175
  unchangedPaths: result.unchangedPaths,
182
176
  };
183
177
  },
184
- usage: "dss scenario update <id> (--data '{...}' | --data-file PATH | --stdin) [--dry-run] [--project-key KEY]",
185
178
  description: "Update scenario settings via JSON merge; edit step-based scenario steps at params.steps, not rawParams.params.steps.",
186
179
  examples: [
187
180
  'dss scenario update my_scenario --data \'{"params":{"steps":[]}}\' --dry-run',
@@ -190,7 +183,7 @@ export const scenarioCommands = {
190
183
  },
191
184
  abort: {
192
185
  handler: async (c, a, f) => {
193
- requireArgs(a, 1, "dss scenario abort <id>");
186
+ requireArgs(a, 1, commandUsage("scenario", "abort"));
194
187
  const pk = f["project-key"];
195
188
  if (executionMode(f).dryRun) {
196
189
  return {
@@ -205,36 +198,33 @@ export const scenarioCommands = {
205
198
  await c.scenarios.abort(a[0], pk);
206
199
  return { aborted: a[0], resource: "scenario", };
207
200
  },
208
- usage: "dss scenario abort <id> [--dry-run] [--project-key KEY]",
209
201
  description: "Abort a running scenario. Returns when DSS accepts the abort; the scenario may take time to stop.",
210
202
  examples: ["dss scenario abort my_scenario",],
211
203
  },
212
204
  "last-runs": {
213
205
  handler: (c, a, f) => {
214
- requireArgs(a, 1, "dss scenario last-runs <id>");
206
+ requireArgs(a, 1, commandUsage("scenario", "last-runs"));
215
207
  return c.scenarios.getLastRuns(a[0], {
216
208
  limit: num(f["limit"], "--limit"),
217
209
  projectKey: f["project-key"],
218
210
  });
219
211
  },
220
- usage: "dss scenario last-runs <id> [--limit N] [--project-key KEY]",
221
212
  description: "List the most recent runs of a scenario (run id, start/end, outcome).",
222
213
  examples: ["dss scenario last-runs my_scenario --limit 10",],
223
214
  },
224
215
  "get-run": {
225
216
  handler: (c, a, f) => {
226
- requireArgs(a, 2, "dss scenario get-run <id> <runId>");
217
+ requireArgs(a, 2, commandUsage("scenario", "get-run"));
227
218
  return c.scenarios.getRunDetails(a[0], a[1], {
228
219
  projectKey: f["project-key"],
229
220
  });
230
221
  },
231
- usage: "dss scenario get-run <id> <runId> [--project-key KEY]",
232
222
  description: "Get the details of a specific scenario run, including per-step outcomes.",
233
223
  examples: ["dss scenario get-run my_scenario 2024-09-01-01-02-03-123",],
234
224
  },
235
225
  log: {
236
226
  handler: async (c, a, f) => {
237
- requireArgs(a, 2, "dss scenario log <id> <runId>");
227
+ requireArgs(a, 2, commandUsage("scenario", "log"));
238
228
  const result = await c.scenarios.getRunLog(a[0], a[1], {
239
229
  stepId: f["step-id"],
240
230
  maxLogBytes: num(f["max-log-bytes"], "--max-log-bytes"),
@@ -252,7 +242,6 @@ export const scenarioCommands = {
252
242
  }
253
243
  return result.text;
254
244
  },
255
- usage: "dss scenario log <id> <runId> [--step-id STEP_ID] [--max-log-bytes N] [--output PATH] [--project-key KEY]",
256
245
  description: "Get the log of a scenario run (or one step via --step-id). Byte-bounded at --max-log-bytes (default 1 MiB); --output PATH writes it to a file (stdout returns the path).",
257
246
  examples: [
258
247
  "dss scenario log my_scenario 2024-09-01-01-02-03-123",
@@ -261,19 +250,18 @@ export const scenarioCommands = {
261
250
  },
262
251
  "payload-get": {
263
252
  handler: (c, a, f) => {
264
- requireArgs(a, 1, "dss scenario payload-get <id>");
253
+ requireArgs(a, 1, commandUsage("scenario", "payload-get"));
265
254
  return c.scenarios.getPayload(a[0], { projectKey: f["project-key"], });
266
255
  },
267
- usage: "dss scenario payload-get <id> [--project-key KEY]",
268
256
  description: "Get the payload of a custom scenario (e.g. its Python script).",
269
257
  examples: ["dss scenario payload-get my_custom_scenario",],
270
258
  },
271
259
  "payload-set": {
272
260
  handler: async (c, a, f) => {
273
- requireArgs(a, 1, "dss scenario payload-set <id> (--data '{...}' | --data-file PATH | --stdin)");
261
+ requireArgs(a, 1, commandUsage("scenario", "payload-set"));
274
262
  const payload = jsonInput(f);
275
263
  if (payload === undefined) {
276
- throw new UsageError("--data, --data-file, or --stdin is required. Usage: dss scenario payload-set <id> (--data '{...}' | --data-file PATH | --stdin)");
264
+ throw new UsageError(`--data, --data-file, or --stdin is required. Usage: ${commandUsage("scenario", "payload-set")}`);
277
265
  }
278
266
  const pk = f["project-key"];
279
267
  if (executionMode(f).dryRun) {
@@ -290,7 +278,6 @@ export const scenarioCommands = {
290
278
  await c.scenarios.setPayload(a[0], payload, { projectKey: pk, });
291
279
  return { updated: a[0], resource: "scenario", part: "payload", };
292
280
  },
293
- usage: "dss scenario payload-set <id> (--data '{...}' | --data-file PATH | --stdin) [--dry-run] [--project-key KEY]",
294
281
  description: "Update the payload of a custom scenario (e.g. replace its Python script).",
295
282
  examples: [
296
283
  'dss scenario payload-set my_custom_scenario --data \'{"script":"print(1)"}\' --dry-run',
@@ -299,10 +286,10 @@ export const scenarioCommands = {
299
286
  },
300
287
  "active-set": {
301
288
  handler: async (c, a, f) => {
302
- requireArgs(a, 2, "dss scenario active-set <id> <true|false>");
289
+ requireArgs(a, 2, commandUsage("scenario", "active-set"));
303
290
  const active = parseBooleanOption(a[1], "active");
304
291
  if (active === undefined) {
305
- throw new UsageError("active must be 'true' or 'false'. Usage: dss scenario active-set <id> <true|false>");
292
+ throw new UsageError(`active must be 'true' or 'false'. Usage: ${commandUsage("scenario", "active-set")}`);
306
293
  }
307
294
  const pk = f["project-key"];
308
295
  if (executionMode(f).dryRun) {
@@ -318,11 +305,10 @@ export const scenarioCommands = {
318
305
  }
319
306
  return c.scenarios.setActive(a[0], active, { projectKey: pk, });
320
307
  },
321
- usage: "dss scenario active-set <id> <true|false> [--dry-run] [--project-key KEY]",
322
308
  description: "Activate or deactivate a scenario (light update; deactivated scenarios ignore triggers).",
323
309
  examples: [
324
310
  "dss scenario active-set my_scenario false",
325
311
  "dss scenario active-set my_scenario true --dry-run",
326
312
  ],
327
313
  },
328
- };
314
+ });
@@ -4,8 +4,9 @@ import { dirname, resolve, } from "node:path";
4
4
  import { writeResponseToFile, } from "../../utils/response-file.js";
5
5
  import { readStdinText, stripUtf8Bom, } from "../coerce.js";
6
6
  import { enqueueCliWarning, } from "../output.js";
7
+ import { commandUsage, withUsage, } from "../syntax.js";
7
8
  import { UsageError, } from "../usage.js";
8
- const SQL_QUERY_USAGE = "dss sql query (SQL | --sql QUERY | --sql-file PATH | --sql - | --stdin) (--connection CONN | --dataset FULL_NAME) [--database DB] [--output PATH|--output-file PATH] [--preview N] [--start-retries N] [--request-timeout MS] [--project-key KEY]";
9
+ const SQL_QUERY_USAGE = commandUsage("sql", "query");
9
10
  const DEFAULT_SQL_PREVIEW_ROWS = 5;
10
11
  /**
11
12
  * Parse `--preview N` into a non-negative row count. Rejects non-integers,
@@ -86,7 +87,7 @@ export function resolveSqlQueryInvocation(args, flags, projectKeyOverride) {
86
87
  type: "sql",
87
88
  };
88
89
  }
89
- export const sqlCommands = {
90
+ export const sqlCommands = withUsage("sql", {
90
91
  query: {
91
92
  handler: async (c, a, f) => {
92
93
  const outputFile = f["output"]
@@ -133,7 +134,6 @@ export const sqlCommands = {
133
134
  written: outputPath,
134
135
  };
135
136
  },
136
- usage: SQL_QUERY_USAGE,
137
137
  description: "Run potentially mutating SQL against a DSS connection or dataset. Use --preview N for bounded stdout or --output PATH for full rows. --start-retries may execute SQL more than once; use it only when repetition is safe.",
138
138
  examples: [
139
139
  "dss sql query 'SELECT * FROM orders LIMIT 10' --connection my_pg",
@@ -144,4 +144,4 @@ export const sqlCommands = {
144
144
  "dss sql query 'SELECT 1' --connection my_pg --start-retries 4",
145
145
  ],
146
146
  },
147
- };
147
+ });