@stndrds/cli 1.0.0-alpha.218 → 1.0.0-alpha.227

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 (2) hide show
  1. package/dist/bin.mjs +70 -11
  2. package/package.json +1 -1
package/dist/bin.mjs CHANGED
@@ -32,16 +32,10 @@ function createClient(config) {
32
32
  "Content-Type": "application/json",
33
33
  ...tenantId ? { "X-Tenant-ID": tenantId } : {}
34
34
  };
35
- async function request(method, path, options) {
36
- const url = buildUrl(apiUrl, path, options?.params);
35
+ async function sendRequest(url, init) {
37
36
  let response;
38
37
  try {
39
- response = await fetch(url, {
40
- method,
41
- headers,
42
- body: options?.body ? JSON.stringify(options.body) : void 0,
43
- signal: AbortSignal.timeout(3e4)
44
- });
38
+ response = await fetch(url, { ...init, signal: AbortSignal.timeout(3e4) });
45
39
  } catch (error) {
46
40
  if (error instanceof TypeError || error instanceof DOMException && error.name === "TimeoutError") {
47
41
  throw new ApiClientError(0, `Could not connect to ${apiUrl}. Is the server running?`);
@@ -58,6 +52,19 @@ function createClient(config) {
58
52
  }
59
53
  return data;
60
54
  }
55
+ function request(method, path, options) {
56
+ const url = buildUrl(apiUrl, path, options?.params);
57
+ return sendRequest(url, {
58
+ method,
59
+ headers,
60
+ body: options?.body ? JSON.stringify(options.body) : void 0
61
+ });
62
+ }
63
+ function postMultipart(path, form) {
64
+ const url = buildUrl(apiUrl, path);
65
+ const { "Content-Type": _ct, ...multipartHeaders } = headers;
66
+ return sendRequest(url, { method: "POST", headers: multipartHeaders, body: form });
67
+ }
61
68
  return {
62
69
  get(path, params) {
63
70
  return request("GET", path, { params });
@@ -73,7 +80,8 @@ function createClient(config) {
73
80
  },
74
81
  delete(path) {
75
82
  return request("DELETE", path);
76
- }
83
+ },
84
+ postMultipart
77
85
  };
78
86
  }
79
87
 
@@ -263,6 +271,38 @@ function registerDocumentsCommand(program) {
263
271
  });
264
272
  }
265
273
 
274
+ // src/commands/folders.ts
275
+ import { readFile } from "fs/promises";
276
+ function registerFoldersCommand(program) {
277
+ const folders = program.command("folders").description("Manage record drive folders");
278
+ folders.command("reconcile-paths").description("Create a folder tree on a record drive from paths").argument("<object>", "object name (e.g. contacts)").argument("<recordId>", "record ID owning the drive").option(
279
+ "--path <path>",
280
+ "folder path to create (repeatable)",
281
+ (val, acc) => {
282
+ acc.push(val);
283
+ return acc;
284
+ },
285
+ []
286
+ ).option("--paths-file <file>", "file containing one path per line").option("--mode <mode>", "reconcile mode: repair or dryRun", "repair").action(async (objectName, recordId, opts, cmd) => {
287
+ const paths = [...opts.path];
288
+ if (opts.pathsFile) {
289
+ const content = await readFile(opts.pathsFile, "utf-8");
290
+ const filePaths = content.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
291
+ paths.push(...filePaths);
292
+ }
293
+ if (paths.length === 0) {
294
+ throw new Error("No paths provided. Pass at least one --path or a non-empty --paths-file.");
295
+ }
296
+ const client = getClientFromCommand(cmd);
297
+ const result = await client.post(`/folders/record-drive/${recordId}/reconcile-paths`, {
298
+ objectName,
299
+ paths,
300
+ mode: opts.mode
301
+ });
302
+ formatOutput(result, getFormat(cmd));
303
+ });
304
+ }
305
+
266
306
  // src/commands/keys.ts
267
307
  import chalk3 from "chalk";
268
308
  function registerKeysCommand(program) {
@@ -297,6 +337,8 @@ function registerKeysCommand(program) {
297
337
  }
298
338
 
299
339
  // src/commands/records.ts
340
+ import { readFile as readFile2 } from "fs/promises";
341
+ import { basename } from "path";
300
342
  function parseSortFlag(sort) {
301
343
  const [attribute, direction = "asc"] = sort.split(":");
302
344
  return [{ attribute, direction }];
@@ -353,6 +395,22 @@ function registerRecordsCommand(program) {
353
395
  const result = await client.post(`/records/${objectName}/search`, body);
354
396
  formatOutput(result, getFormat(cmd));
355
397
  });
398
+ records.command("attach-document").description("Upload and attach a local file to a record").argument("<object>", "object name (e.g. contacts)").argument("<recordId>", "record ID").requiredOption("--file <path>", "local file path to upload").option("--attribute <attr>", "attribute name to attach the document to").option("--parent-id <folderId>", "parent folder ID").option("--title <title>", "document title (defaults to filename)").action(async (objectName, recordId, opts, cmd) => {
399
+ const fileContent = await readFile2(opts.file);
400
+ const fileName = basename(opts.file);
401
+ const title = opts.title ?? fileName;
402
+ const form = new FormData();
403
+ form.append("files", new Blob([fileContent]), fileName);
404
+ form.append("title", title);
405
+ if (opts.attribute) form.append("attributeName", opts.attribute);
406
+ if (opts.parentId) form.append("parentId", opts.parentId);
407
+ const client = getClientFromCommand(cmd);
408
+ const result = await client.postMultipart(
409
+ `/records/${objectName}/${recordId}/documents/attach`,
410
+ form
411
+ );
412
+ formatOutput(result, getFormat(cmd));
413
+ });
356
414
  }
357
415
 
358
416
  // src/commands/root.ts
@@ -361,7 +419,7 @@ import { createInterface } from "readline/promises";
361
419
  import chalk4 from "chalk";
362
420
 
363
421
  // src/config.ts
364
- import { mkdir, readFile, rm, writeFile } from "fs/promises";
422
+ import { mkdir, readFile as readFile3, rm, writeFile } from "fs/promises";
365
423
  import { homedir } from "os";
366
424
  import { dirname, join } from "path";
367
425
  var DEFAULT_API_URL = "http://localhost:4100/v1";
@@ -375,7 +433,7 @@ function getConfigPath() {
375
433
  }
376
434
  async function readConfig() {
377
435
  try {
378
- const raw = await readFile(getConfigPath(), "utf8");
436
+ const raw = await readFile3(getConfigPath(), "utf8");
379
437
  const parsed = JSON.parse(raw);
380
438
  return {
381
439
  currentProfile: parsed.currentProfile,
@@ -758,6 +816,7 @@ function createProgram() {
758
816
  registerRecordsCommand(program);
759
817
  registerSchemaCommand(program);
760
818
  registerDocumentsCommand(program);
819
+ registerFoldersCommand(program);
761
820
  registerKeysCommand(program);
762
821
  registerAuthCommand(program);
763
822
  registerAutofillCommand(program);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stndrds/cli",
3
- "version": "1.0.0-alpha.218",
3
+ "version": "1.0.0-alpha.227",
4
4
  "description": "CLI tool to interact with Standards API",
5
5
  "type": "module",
6
6
  "bin": {