@wirecat/zoom-cli 0.45.0 → 0.47.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 (57) hide show
  1. package/README.md +1 -1
  2. package/dist/agent-skill.d.ts.map +1 -1
  3. package/dist/agent-skill.js +4 -7
  4. package/dist/agent-skill.js.map +1 -1
  5. package/dist/commands.d.ts +2 -0
  6. package/dist/commands.d.ts.map +1 -1
  7. package/dist/commands.js +8 -1
  8. package/dist/commands.js.map +1 -1
  9. package/dist/config-issues.d.ts +26 -0
  10. package/dist/config-issues.d.ts.map +1 -0
  11. package/dist/config-issues.js +97 -0
  12. package/dist/config-issues.js.map +1 -0
  13. package/dist/config.d.ts +22 -4
  14. package/dist/config.d.ts.map +1 -1
  15. package/dist/config.js +122 -86
  16. package/dist/config.js.map +1 -1
  17. package/dist/contract-overrides.d.ts.map +1 -1
  18. package/dist/contract-overrides.js +0 -13
  19. package/dist/contract-overrides.js.map +1 -1
  20. package/dist/mcp-command.d.ts.map +1 -1
  21. package/dist/mcp-command.js +1 -9
  22. package/dist/mcp-command.js.map +1 -1
  23. package/dist/mcp.d.ts.map +1 -1
  24. package/dist/mcp.js +5 -4
  25. package/dist/mcp.js.map +1 -1
  26. package/dist/permissions.d.ts +0 -2
  27. package/dist/permissions.d.ts.map +1 -1
  28. package/dist/permissions.js +2 -12
  29. package/dist/permissions.js.map +1 -1
  30. package/dist/program-bindings.d.ts.map +1 -1
  31. package/dist/program-bindings.js +18 -20
  32. package/dist/program-bindings.js.map +1 -1
  33. package/dist/recording-schedule-setup.d.ts.map +1 -1
  34. package/dist/recording-schedule-setup.js +0 -1
  35. package/dist/recording-schedule-setup.js.map +1 -1
  36. package/dist/request-events.d.ts +9 -0
  37. package/dist/request-events.d.ts.map +1 -0
  38. package/dist/request-events.js +41 -0
  39. package/dist/request-events.js.map +1 -0
  40. package/dist/run.d.ts.map +1 -1
  41. package/dist/run.js +1 -2
  42. package/dist/run.js.map +1 -1
  43. package/dist/setup-commands.d.ts +4 -3
  44. package/dist/setup-commands.d.ts.map +1 -1
  45. package/dist/setup-commands.js +26 -23
  46. package/dist/setup-commands.js.map +1 -1
  47. package/dist/tokens.d.ts +1 -3
  48. package/dist/tokens.d.ts.map +1 -1
  49. package/dist/tokens.js +4 -19
  50. package/dist/tokens.js.map +1 -1
  51. package/dist/version.d.ts +1 -1
  52. package/dist/version.js +1 -1
  53. package/package.json +15 -15
  54. package/dist/run-recording.d.ts +0 -27
  55. package/dist/run-recording.d.ts.map +0 -1
  56. package/dist/run-recording.js +0 -106
  57. package/dist/run-recording.js.map +0 -1
package/README.md CHANGED
@@ -143,7 +143,7 @@ More: [compared with other tools](https://github.com/WireCatLabs/zoom-cli/blob/m
143
143
 
144
144
  | Task | Commands |
145
145
  |---|---|
146
- | Set up and log in | `config show`, `config set <key> <value>`, `session start [--browser <program>]`, `session status [--check]`, `doctor` |
146
+ | Set up and log in | `config show`, `config set <key> <value>`, `config unset <key>`, `session start [--browser <program>]`, `session status [--check]`, `doctor` |
147
147
  | Bring meetings in | `meetings sync [--since-time <time>] [--lookback-days <days>]`, `meetings import <folder>`, `watch [api\|files] [folder] --jsonl` |
148
148
  | Read stored meetings | `meetings list`, `meetings show <meeting>`, `meetings transcript <meeting>`, `meetings summary <meeting>`, `meetings export <meeting> --format markdown\|vtt`, `events list` |
149
149
  | Search | `search meetings <query>`, `meetings people <query>`, `search all <query>` |
@@ -1 +1 @@
1
- {"version":3,"file":"agent-skill.d.ts","sourceRoot":"","sources":["../src/agent-skill.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,gBAAgB,EAAgB,MAAM,yBAAyB,CAAA;AAE7E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKxC,QAAA,MAAM,8BAA8B,YACzB,OAAO,eACH,gBAAgB,gCAE5B,IAiBF,CAAA;AAED,eAAO,MAAM,oBAAoB,YAAa,UAAU,CAAC,OAAO,8BAA8B,CAAC,SAY9F,CAAA"}
1
+ {"version":3,"file":"agent-skill.d.ts","sourceRoot":"","sources":["../src/agent-skill.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,gBAAgB,EAAgB,MAAM,yBAAyB,CAAA;AAE7E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKxC,QAAA,MAAM,8BAA8B,YACzB,OAAO,eACH,gBAAgB,gCAE5B,IAcF,CAAA;AAED,eAAO,MAAM,oBAAoB,YAAa,UAAU,CAAC,OAAO,8BAA8B,CAAC,SAY9F,CAAA"}
@@ -7,13 +7,10 @@ import { VERSION } from "./version.js";
7
7
  const addZoomSkillCommandsDefinition = (program, environment, skill = new URL("../skills/zoom-cli/SKILL.md", import.meta.url)) => {
8
8
  const command = skillCommand({ command: "zm", appName: "zoom-cli", version: VERSION }, skill, environment);
9
9
  for (const child of command.commands) {
10
- const install = child.name() === "install";
11
- if (install)
12
- grantsAuthority(child);
13
- annotate(child, {
14
- effects: install ? LOCAL_WRITE : NO_EFFECTS,
15
- examples: [install ? "zm skill install --for agents --json" : "zm skill show --json"],
16
- });
10
+ if (child.name() === "install")
11
+ annotate(grantsAuthority(child), { effects: LOCAL_WRITE, examples: ["zm skill install --for agents --json"] });
12
+ if (child.name() === "show")
13
+ annotate(child, { examples: ["zm skill show --json"] });
17
14
  }
18
15
  // addCommand, unlike command(), does not pass these down, and commander's defaults print plain text and exit 1.
19
16
  const inheritFailureHandling = (target) => {
@@ -1 +1 @@
1
- {"version":3,"file":"agent-skill.js","sourceRoot":"","sources":["../src/agent-skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AAC7E,OAAO,EAAyB,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAC7E,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,IAAI,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAEpH,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAA;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,MAAM,8BAA8B,GAAG,CACrC,OAAgB,EAChB,WAA6B,EAC7B,KAAK,GAAG,IAAI,GAAG,CAAC,6BAA6B,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,EACzD,EAAE;IACR,MAAM,OAAO,GAAG,YAAY,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,CAAA;IAC1G,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,KAAK,SAAS,CAAA;QAC1C,IAAI,OAAO;YAAE,eAAe,CAAC,KAAK,CAAC,CAAA;QACnC,QAAQ,CAAC,KAAK,EAAE;YACd,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU;YAC3C,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,sCAAsC,CAAC,CAAC,CAAC,sBAAsB,CAAC;SACtF,CAAC,CAAA;IACJ,CAAC;IACD,gHAAgH;IAChH,MAAM,sBAAsB,GAAG,CAAC,MAAe,EAAE,EAAE;QACjD,MAAM,CAAC,YAAY,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,CAAA;QAChE,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,QAAQ;YAAE,sBAAsB,CAAC,KAAK,CAAC,CAAA;IACpE,CAAC,CAAA;IACD,sBAAsB,CAAC,OAAO,CAAC,CAAA;IAC/B,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,CAAA;AAChE,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,GAAG,IAAuD,EAAE,EAAE;IACjG,sBAAsB,CACpB,kBAAkB,CAAC,EAAE,EAAE,IAAI,GAAG,CAAC,6BAA6B,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAC/E,8HAA8H,EAC9H,GAAG,EAAE;QACH,8BAA8B,CAAC,GAAG,IAAI,CAAC,CAAA;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,OAAO,CAAC,CAAA;QAC9E,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAA;QAC1E,OAAO,OAAO,CAAA;IAChB,CAAC,EACD,eAAe,CAAC,KAAK,CACtB,CAAA;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"agent-skill.js","sourceRoot":"","sources":["../src/agent-skill.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAA;AAC7E,OAAO,EAAyB,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAC7E,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,IAAI,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAEpH,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAA;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,MAAM,8BAA8B,GAAG,CACrC,OAAgB,EAChB,WAA6B,EAC7B,KAAK,GAAG,IAAI,GAAG,CAAC,6BAA6B,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,EACzD,EAAE;IACR,MAAM,OAAO,GAAG,YAAY,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,WAAW,CAAC,CAAA;IAC1G,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrC,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,SAAS;YAC5B,QAAQ,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC,sCAAsC,CAAC,EAAE,CAAC,CAAA;QAChH,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,MAAM;YAAE,QAAQ,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAA;IACtF,CAAC;IACD,gHAAgH;IAChH,MAAM,sBAAsB,GAAG,CAAC,MAAe,EAAE,EAAE;QACjD,MAAM,CAAC,YAAY,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,CAAA;QAChE,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,QAAQ;YAAE,sBAAsB,CAAC,KAAK,CAAC,CAAA;IACpE,CAAC,CAAA;IACD,sBAAsB,CAAC,OAAO,CAAC,CAAA;IAC/B,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,CAAA;AAChE,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,GAAG,IAAuD,EAAE,EAAE;IACjG,sBAAsB,CACpB,kBAAkB,CAAC,EAAE,EAAE,IAAI,GAAG,CAAC,6BAA6B,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAC/E,8HAA8H,EAC9H,GAAG,EAAE;QACH,8BAA8B,CAAC,GAAG,IAAI,CAAC,CAAA;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,OAAO,CAAC,CAAA;QAC9E,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAA;QAC1E,OAAO,OAAO,CAAA;IAChB,CAAC,EACD,eAAe,CAAC,KAAK,CACtB,CAAA;AACH,CAAC,CAAA"}
@@ -10,6 +10,8 @@ declare const addStandardCommandsDefinition: (program: Command, deps: StandardCo
10
10
  export declare const annotateMeetingCommands: (program: Command) => void;
11
11
  /** The top-level commands that act for no account, so their examples carry no profile word. */
12
12
  export declare const PROFILE_FREE: Set<string>;
13
+ /** Help then shows these without a profile: `zm doctor`, not `zm personal doctor`. */
14
+ export declare const markProfileFree: (program: Command) => void;
13
15
  /** cli-core's `runs`, read without a profile: one log per computer, whatever profile a run was for. */
14
16
  export declare const zoomRunsCommand: () => Command;
15
17
  export declare const addStandardCommands: (...args: Parameters<typeof addStandardCommandsDefinition>) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,KAAK,IAAI,EAUV,MAAM,uBAAuB,CAAA;AAC9B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKxC,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAA;IAC5B,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3B,MAAM,EAAE,MAAM,OAAO,CAAA;IACrB,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CACpD;AACD,QAAA,MAAM,6BAA6B,YAAa,OAAO,QAAQ,oBAAoB,KAAG,IAyCrF,CAAA;AAED,eAAO,MAAM,uBAAuB,YAAa,OAAO,KAAG,IAyB1D,CAAA;AACD,+FAA+F;AAC/F,eAAO,MAAM,YAAY,aAWvB,CAAA;AAEF,uGAAuG;AACvG,eAAO,MAAM,eAAe,QAAO,OAUlC,CAAA;AAoBD,eAAO,MAAM,mBAAmB,YAAa,UAAU,CAAC,OAAO,6BAA6B,CAAC,SAY5F,CAAA"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,KAAK,IAAI,EAYV,MAAM,uBAAuB,CAAA;AAC9B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKxC,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAA;IAC5B,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3B,MAAM,EAAE,MAAM,OAAO,CAAA;IACrB,aAAa,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CACpD;AACD,QAAA,MAAM,6BAA6B,YAAa,OAAO,QAAQ,oBAAoB,KAAG,IA0CrF,CAAA;AAED,eAAO,MAAM,uBAAuB,YAAa,OAAO,KAAG,IAyB1D,CAAA;AACD,+FAA+F;AAC/F,eAAO,MAAM,YAAY,aAWvB,CAAA;AAEF,sFAAsF;AACtF,eAAO,MAAM,eAAe,YAAa,OAAO,KAAG,IAElD,CAAA;AAED,uGAAuG;AACvG,eAAO,MAAM,eAAe,QAAO,OAUlC,CAAA;AAoBD,eAAO,MAAM,mBAAmB,YAAa,UAAU,CAAC,OAAO,6BAA6B,CAAC,SAY5F,CAAA"}
package/dist/commands.js CHANGED
@@ -1,12 +1,13 @@
1
1
  import { CliError } from "@wirecat/cli-base";
2
2
  import { annotate, customizeSharedCommand, describeOptions, describeProgram, flatten, metaOf, } from "@wirecat/cli-base/commands";
3
3
  import { formatSuggestions, suggest } from "@wirecat/cli-base/completion";
4
- import { commandsCommand, hasSharedContract, itemOf, LOCAL_READ, NO_EFFECTS, overrideSharedContract, REMOTE_READ, runsCommand, sharedCommandTemplate, } from "@wirecat/cli-core/cli";
4
+ import { commandsCommand, hasSharedContract, itemOf, LOCAL_READ, NO_EFFECTS, overrideSharedContract, profileFree, REMOTE_READ, runsCommand, sharedCommandTemplate, sharedStoreCommand, } from "@wirecat/cli-core/cli";
5
5
  import { wholeList } from "./answer-output.js";
6
6
  import { SHELL_OVERRIDES } from "./contract-overrides.js";
7
7
  import { ZM } from "./read-only.js";
8
8
  const addStandardCommandsDefinition = (program, deps) => {
9
9
  program.addCommand(commandsCommand(ZM).copyInheritedSettings(program));
10
+ program.addCommand(sharedStoreCommand().copyInheritedSettings(program));
10
11
  annotate(program
11
12
  .command("complete")
12
13
  .description("answer shell completion requests")
@@ -74,6 +75,12 @@ export const PROFILE_FREE = new Set([
74
75
  "models",
75
76
  "runs",
76
77
  ]);
78
+ /** Help then shows these without a profile: `zm doctor`, not `zm personal doctor`. */
79
+ export const markProfileFree = (program) => {
80
+ for (const command of program.commands)
81
+ if (PROFILE_FREE.has(command.name()))
82
+ profileFree(command);
83
+ };
77
84
  /** cli-core's `runs`, read without a profile: one log per computer, whatever profile a run was for. */
78
85
  export const zoomRunsCommand = () => {
79
86
  const runs = runsCommand(ZM);
@@ -1 +1 @@
1
- {"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { type ConfigIssue } from "@wirecat/cli-core/cli";
2
+ import type * as v from "valibot";
3
+ /** An issue with the path in the file that `config unset` removes. */
4
+ export interface LocatedIssue extends ConfigIssue {
5
+ at: string[];
6
+ }
7
+ type Node = Record<string, unknown>;
8
+ export declare const isNode: (value: unknown) => value is Node;
9
+ /** The name `config set` and `config unset` take for each setting the file keeps under another key. */
10
+ export declare const SETTING_NAMES: Readonly<Record<string, string>>;
11
+ /** A problem with the whole file, which no `config unset` can fix. */
12
+ export declare const fileIssue: (file: string, what: string) => LocatedIssue;
13
+ /**
14
+ * Every problem in the file's text, one per part `config unset` removes, and the file as written — `null` when it is
15
+ * not a JSON object and nothing in it can be changed. `permissionKeys`: the command paths a permission may name.
16
+ */
17
+ export declare const configIssues: (text: string, file: string, schema: v.GenericSchema, permissionKeys?: ReadonlySet<string>) => {
18
+ issues: LocatedIssue[];
19
+ raw: Node | null;
20
+ };
21
+ /** The file without the parts the issues name: what still loads, and what `config unset` would leave. */
22
+ export declare const withoutIssues: (raw: unknown, issues: readonly LocatedIssue[]) => unknown;
23
+ export declare const removeAt: (raw: unknown, at: readonly string[]) => void;
24
+ export declare const publicIssue: ({ at: _, ...issue }: LocatedIssue) => ConfigIssue;
25
+ export {};
26
+ //# sourceMappingURL=config-issues.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-issues.d.ts","sourceRoot":"","sources":["../src/config-issues.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,uBAAuB,CAAA;AACzE,OAAO,KAAK,KAAK,CAAC,MAAM,SAAS,CAAA;AAEjC,sEAAsE;AACtE,MAAM,WAAW,YAAa,SAAQ,WAAW;IAC/C,EAAE,EAAE,MAAM,EAAE,CAAA;CACb;AAED,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AACnC,eAAO,MAAM,MAAM,UAAW,OAAO,KAAG,KAAK,IAAI,IACqB,CAAA;AAEtE,uGAAuG;AACvG,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQ1D,CAAA;AAID,sEAAsE;AACtE,eAAO,MAAM,SAAS,SAAU,MAAM,QAAQ,MAAM,KAAG,YAA+D,CAAA;AAuCtH;;;GAGG;AACH,eAAO,MAAM,YAAY,SACjB,MAAM,QACN,MAAM,UACJ,CAAC,CAAC,aAAa,mBACN,WAAW,CAAC,MAAM,CAAC,KACnC;IAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IAAC,GAAG,EAAE,IAAI,GAAG,IAAI,CAAA;CAmB5C,CAAA;AAED,yGAAyG;AACzG,eAAO,MAAM,aAAa,QAAS,OAAO,UAAU,SAAS,YAAY,EAAE,KAAG,OAI7E,CAAA;AAED,eAAO,MAAM,QAAQ,QAAS,OAAO,MAAM,SAAS,MAAM,EAAE,KAAG,IAG9D,CAAA;AAED,eAAO,MAAM,WAAW,wBAAyB,YAAY,KAAG,WAAoB,CAAA"}
@@ -0,0 +1,97 @@
1
+ import { checkConfigText } from "@wirecat/cli-core/cli";
2
+ export const isNode = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
3
+ /** The name `config set` and `config unset` take for each setting the file keeps under another key. */
4
+ export const SETTING_NAMES = {
5
+ client_id: "zoom.client_id",
6
+ source: "source",
7
+ files_folder: "files.folder",
8
+ files_timezone: "files.timezone",
9
+ context_sources: "context.sources",
10
+ record: "record",
11
+ keep_runs_for_days: "keep_runs_for_days",
12
+ };
13
+ const SHELL_SAFE = /^[A-Za-z0-9_.:@-]*$/;
14
+ /** A problem with the whole file, which no `config unset` can fix. */
15
+ export const fileIssue = (file, what) => ({ kind: "invalid_value", file, what, at: [] });
16
+ /**
17
+ * Where the issue sits in the file, cut to what `config unset` removes: a whole top-level setting, so a broken part
18
+ * of `context_sources` removes the list. A key the file holds as written wins over cutting it at a dot.
19
+ */
20
+ const pathOf = (raw, { profile, key }) => {
21
+ if (key === undefined)
22
+ return [];
23
+ if (profile !== undefined) {
24
+ const entry = isNode(raw.profiles) ? raw.profiles[profile] : undefined;
25
+ const permission = key.startsWith("permissions.") && !(isNode(entry) && Object.hasOwn(entry, key));
26
+ return permission
27
+ ? ["profiles", profile, "permissions", key.slice("permissions.".length)]
28
+ : ["profiles", profile, key];
29
+ }
30
+ if (Object.hasOwn(raw, key))
31
+ return [key];
32
+ if (key.startsWith("profiles."))
33
+ return ["profiles", key.slice("profiles.".length)];
34
+ return [key.split(".")[0]];
35
+ };
36
+ /** The shared issue in zm's words: the setting names `config set` takes, and a fix that removes the whole setting. */
37
+ const inZmTerms = (raw, issue) => {
38
+ const { fix: _, key: shared, ...rest } = issue;
39
+ const at = pathOf(raw, issue);
40
+ const [first] = at;
41
+ if (shared === undefined || first === undefined)
42
+ return { ...rest, at };
43
+ const key = first === "profiles" ? shared : (SETTING_NAMES[first] ?? first);
44
+ const named = key + shared.slice(first === "profiles" ? shared.length : first.length);
45
+ const fixable = [key, issue.profile ?? ""].every((word) => SHELL_SAFE.test(word));
46
+ return {
47
+ ...rest,
48
+ kind: issue.kind === "missing_setting" ? "invalid_value" : issue.kind,
49
+ key,
50
+ what: issue.what.replace(`setting ${shared}`, `setting ${named}`),
51
+ ...(fixable ? { fix: `zm${issue.profile === undefined ? "" : ` ${issue.profile}`} config unset ${key}` } : {}),
52
+ at,
53
+ };
54
+ };
55
+ /**
56
+ * Every problem in the file's text, one per part `config unset` removes, and the file as written — `null` when it is
57
+ * not a JSON object and nothing in it can be changed. `permissionKeys`: the command paths a permission may name.
58
+ */
59
+ export const configIssues = (text, file, schema, permissionKeys) => {
60
+ const checked = checkConfigText(text, { file, tool: "zm", schema });
61
+ const broken = checked.issues.find((issue) => issue.kind === "invalid_json");
62
+ if (broken)
63
+ return { issues: [{ ...broken, at: [] }], raw: null };
64
+ const raw = JSON.parse(text);
65
+ if (!isNode(raw))
66
+ return { issues: [fileIssue(file, "the file has to be an object, in braces")], raw: null };
67
+ const found = new Map();
68
+ const add = (issue) => {
69
+ const id = issue.at.join("\u0000");
70
+ if (!found.has(id))
71
+ found.set(id, issue);
72
+ };
73
+ for (const issue of checked.issues)
74
+ add(inZmTerms(raw, issue));
75
+ if (permissionKeys) {
76
+ // checkConfigText checks permission keys only in what loads, and a broken part of a setting leaves nothing loaded.
77
+ const rest = JSON.stringify(withoutIssues(raw, [...found.values()]));
78
+ for (const issue of checkConfigText(rest, { file, tool: "zm", schema, knownPermissions: permissionKeys }).issues)
79
+ if (issue.kind === "unknown_permission")
80
+ add(inZmTerms(raw, issue));
81
+ }
82
+ return { issues: [...found.values()], raw };
83
+ };
84
+ /** The file without the parts the issues name: what still loads, and what `config unset` would leave. */
85
+ export const withoutIssues = (raw, issues) => {
86
+ const copy = structuredClone(raw);
87
+ for (const { at } of issues)
88
+ removeAt(copy, at);
89
+ return copy;
90
+ };
91
+ export const removeAt = (raw, at) => {
92
+ const parent = at.slice(0, -1).reduce((node, key) => (isNode(node) ? node[key] : undefined), raw);
93
+ if (isNode(parent))
94
+ delete parent[at.at(-1)];
95
+ };
96
+ export const publicIssue = ({ at: _, ...issue }) => issue;
97
+ //# sourceMappingURL=config-issues.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-issues.js","sourceRoot":"","sources":["../src/config-issues.ts"],"names":[],"mappings":"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"}
package/dist/config.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { type Level } from "@wirecat/cli-core/sends";
2
+ import { type LocatedIssue } from "./config-issues.js";
2
3
  import { type ConfiguredContextSource } from "./context-sources.js";
3
4
  export { profileAccountKey } from "./profile.js";
4
5
  export interface ZoomConfig {
@@ -11,19 +12,36 @@ export interface ZoomConfig {
11
12
  profiles: string[];
12
13
  /** What each profile may do: a command path, dotted, to a level (WC-PERM-1). */
13
14
  permissions: Record<string, Record<string, Level>>;
14
- /** The profile that owns a login saved before profiles were words; only that one may take it over. */
15
- legacyProfile: string | null;
16
15
  contextSources?: ConfiguredContextSource[];
17
16
  /** Keep every run, not only the failed ones. */
18
17
  record?: boolean;
19
18
  keepRunsForDays?: number;
20
19
  }
21
- export declare const readConfig: (path: string) => ZoomConfig;
20
+ export interface ConfigInspection {
21
+ found: boolean;
22
+ /** Every problem in the file; the config below is what loads without them. */
23
+ issues: LocatedIssue[];
24
+ /** The file as written, or null when it is not a JSON object and nothing can be changed in it. */
25
+ raw: Record<string, unknown> | null;
26
+ config: ZoomConfig;
27
+ }
28
+ /**
29
+ * Reads the file without refusing it, for `doctor` and `config`. `permissionKeys`: the command paths a permission may
30
+ * name; without them a saved key is not checked.
31
+ */
32
+ export declare const inspectConfig: (path: string, permissionKeys?: ReadonlySet<string>) => ConfigInspection;
33
+ /** The settings every command but `config` and `doctor` runs on; a file with any problem is refused. */
34
+ export declare const readConfig: (path: string, permissionKeys?: ReadonlySet<string>) => ZoomConfig;
22
35
  /**
23
36
  * `profile`: the one named on the command line, for the settings that belong to a profile. `permissionKeys`: the
24
37
  * command paths a permission may name.
25
38
  */
26
- export declare const setConfig: (path: string, key: string, value: string, profile?: () => string, permissionKeys?: ReadonlySet<string>) => ZoomConfig;
39
+ export declare const setConfig: (path: string, key: string, value: string, profile?: () => string | undefined, permissionKeys?: ReadonlySet<string>) => ZoomConfig;
40
+ /**
41
+ * Removes a setting, or any part of the file `doctor` reports a problem in, by the name its fix gives.
42
+ * `profile`: the one named, if any; `context.sources` without one removes every profile's sources.
43
+ */
44
+ export declare const unsetConfig: (path: string, key: string, profile: string | undefined, permissionKeys?: ReadonlySet<string>) => ZoomConfig;
27
45
  /** A successful login makes a profile; the store account and the archive follow it by name. */
28
46
  export declare const addProfile: (path: string, profile: string) => void;
29
47
  /** The zone a transcript file name's time is read in: `files.timezone`, else this computer's. */
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAU,KAAK,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAE5D,OAAO,EAAE,KAAK,uBAAuB,EAA+C,MAAM,sBAAsB,CAAA;AAIhH,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAEhD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,MAAM,EAAE,KAAK,GAAG,OAAO,CAAA;IACvB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,iEAAiE;IACjE,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,+FAA+F;IAC/F,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,gFAAgF;IAChF,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;IAClD,sGAAsG;IACtG,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,cAAc,CAAC,EAAE,uBAAuB,EAAE,CAAA;IAC1C,gDAAgD;IAChD,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AA4CD,eAAO,MAAM,UAAU,SAAU,MAAM,KAAG,UAkCzC,CAAA;AAiBD;;;GAGG;AACH,eAAO,MAAM,SAAS,SACd,MAAM,OACP,MAAM,SACJ,MAAM,YACH,MAAM,MAAM,mBACL,WAAW,CAAC,MAAM,CAAC,KACnC,UAuDF,CAAA;AAED,+FAA+F;AAC/F,eAAO,MAAM,UAAU,SAAU,MAAM,WAAW,MAAM,KAAG,IAK1D,CAAA;AAED,iGAAiG;AACjG,eAAO,MAAM,SAAS,WAAY,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,KAAG,MACI,CAAA"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAU,KAAK,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAE5D,OAAO,EAIL,KAAK,YAAY,EAKlB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EAAE,KAAK,uBAAuB,EAA+C,MAAM,sBAAsB,CAAA;AAIhH,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAEhD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,MAAM,EAAE,KAAK,GAAG,OAAO,CAAA;IACvB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,iEAAiE;IACjE,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,+FAA+F;IAC/F,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,gFAAgF;IAChF,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;IAClD,cAAc,CAAC,EAAE,uBAAuB,EAAE,CAAA;IAC1C,gDAAgD;IAChD,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AA6CD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAA;IACd,8EAA8E;IAC9E,MAAM,EAAE,YAAY,EAAE,CAAA;IACtB,kGAAkG;IAClG,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACnC,MAAM,EAAE,UAAU,CAAA;CACnB;AAkBD;;;GAGG;AACH,eAAO,MAAM,aAAa,SAAU,MAAM,mBAAmB,WAAW,CAAC,MAAM,CAAC,KAAG,gBAkBlF,CAAA;AAED,wGAAwG;AACxG,eAAO,MAAM,UAAU,SAAU,MAAM,mBAAmB,WAAW,CAAC,MAAM,CAAC,KAAG,UAI/E,CAAA;AA0BD;;;GAGG;AACH,eAAO,MAAM,SAAS,SACd,MAAM,OACP,MAAM,SACJ,MAAM,YACH,MAAM,MAAM,GAAG,SAAS,mBACjB,WAAW,CAAC,MAAM,CAAC,KACnC,UAiDC,CAAA;AAEJ;;;GAGG;AACH,eAAO,MAAM,WAAW,SAChB,MAAM,OACP,MAAM,WACF,MAAM,GAAG,SAAS,mBACV,WAAW,CAAC,MAAM,CAAC,KACnC,UAgBC,CAAA;AAWJ,+FAA+F;AAC/F,eAAO,MAAM,UAAU,SAAU,MAAM,WAAW,MAAM,KAAG,IAK1D,CAAA;AAED,iGAAiG;AACjG,eAAO,MAAM,SAAS,WAAY,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,KAAG,MACI,CAAA"}
package/dist/config.js CHANGED
@@ -1,8 +1,9 @@
1
- import { existsSync } from "node:fs";
2
- import { CliError, isCliError, saveConfigFile } from "@wirecat/cli-base";
3
- import { loadSnakeCaseConfig } from "@wirecat/cli-core/cli";
1
+ import { existsSync, readFileSync, statSync } from "node:fs";
2
+ import { CliError, saveConfigFile } from "@wirecat/cli-base";
3
+ import { issueMessage } from "@wirecat/cli-core/cli";
4
4
  import { LEVELS } from "@wirecat/cli-core/sends";
5
5
  import * as v from "valibot";
6
+ import { configIssues, fileIssue, isNode, publicIssue, removeAt, SETTING_NAMES, withoutIssues, } from "./config-issues.js";
6
7
  import { contextSourcesSchema, replaceContextSources } from "./context-sources.js";
7
8
  import { parsePermissions } from "./permissions.js";
8
9
  import { profilePattern } from "./profile.js";
@@ -11,9 +12,9 @@ const ProfileEntry = v.strictObject({
11
12
  permissions: v.optional(v.record(v.pipe(v.string(), v.regex(/^[a-z][a-z.-]*$/)), v.picklist(LEVELS))),
12
13
  });
13
14
  const ConfigFile = v.strictObject({
14
- client_id: v.nullable(v.pipe(v.string(), v.check((id) => id.trim() !== "" && !/\s/.test(id)))),
15
- source: v.picklist(["api", "files"]),
16
- files_folder: v.nullable(v.string()),
15
+ client_id: v.optional(v.nullable(v.pipe(v.string(), v.check((id) => id.trim() !== "" && !/\s/.test(id), "has to be a Zoom client ID, without spaces")))),
16
+ source: v.optional(v.picklist(["api", "files"])),
17
+ files_folder: v.optional(v.nullable(v.string())),
17
18
  files_timezone: v.optional(v.nullable(v.pipe(v.string(), v.check((zone) => {
18
19
  try {
19
20
  new Intl.DateTimeFormat("en", { timeZone: zone });
@@ -22,101 +23,110 @@ const ConfigFile = v.strictObject({
22
23
  catch {
23
24
  return false;
24
25
  }
25
- })))),
26
- account_profile: v.optional(v.nullable(v.pipe(v.string(), v.regex(profilePattern)))),
27
- profiles: v.optional(v.record(v.pipe(v.string(), v.regex(profilePattern)), ProfileEntry)),
26
+ }, "has to be an IANA time zone, such as Europe/Madrid")))),
27
+ profiles: v.optional(v.record(v.pipe(v.string(), v.regex(profilePattern, "has to be a profile name of 64 characters at most")), ProfileEntry)),
28
28
  context_sources: v.optional(contextSourcesSchema),
29
29
  record: v.optional(v.boolean()),
30
30
  keep_runs_for_days: v.optional(v.pipe(v.number(), v.integer(), v.minValue(1))),
31
31
  });
32
- // The loader's issue text quotes the offending value ("received …"), which can be the client id.
33
- const keyOnly = (message) => {
34
- const [head, first] = message.split("\n");
35
- const key = first?.trim().split(":")[0];
36
- return key ? `${head?.replace(/:$/, "")}: ${key}` : message;
37
- };
38
- export const readConfig = (path) => {
32
+ const DOCTOR = "zm doctor";
33
+ const configOf = (file) => ({
34
+ clientId: file.client_id ?? null,
35
+ source: file.source ?? "api",
36
+ filesFolder: file.files_folder ?? null,
37
+ filesTimezone: file.files_timezone ?? null,
38
+ profiles: Object.keys(file.profiles ?? {}).sort(),
39
+ permissions: Object.fromEntries(Object.entries(file.profiles ?? {}).flatMap(([name, entry]) => entry.permissions ? [[name, entry.permissions]] : [])),
40
+ ...(file.context_sources === undefined ? {} : { contextSources: file.context_sources }),
41
+ ...(file.record === undefined ? {} : { record: file.record }),
42
+ ...(file.keep_runs_for_days === undefined ? {} : { keepRunsForDays: file.keep_runs_for_days }),
43
+ });
44
+ /**
45
+ * Reads the file without refusing it, for `doctor` and `config`. `permissionKeys`: the command paths a permission may
46
+ * name; without them a saved key is not checked.
47
+ */
48
+ export const inspectConfig = (path, permissionKeys) => {
49
+ let text;
39
50
  try {
40
- const file = loadSnakeCaseConfig(path, ConfigFile, () => {
41
- if (existsSync(path))
42
- throw new CliError("configuration_error", `${path} could not be read`);
43
- return {
44
- client_id: null,
45
- source: "api",
46
- files_folder: null,
47
- files_timezone: null,
48
- account_profile: null,
49
- };
50
- });
51
- return {
52
- clientId: file.client_id,
53
- source: file.source,
54
- filesFolder: file.files_folder,
55
- filesTimezone: file.files_timezone ?? null,
56
- profiles: [
57
- ...new Set([...Object.keys(file.profiles ?? {}), ...(file.account_profile ? [file.account_profile] : [])]),
58
- ].sort(),
59
- legacyProfile: file.account_profile ?? null,
60
- permissions: Object.fromEntries(Object.entries(file.profiles ?? {}).flatMap(([name, entry]) => entry.permissions ? [[name, entry.permissions]] : [])),
61
- ...(file.context_sources === undefined ? {} : { contextSources: file.context_sources }),
62
- ...(file.record === undefined ? {} : { record: file.record }),
63
- ...(file.keep_runs_for_days === undefined ? {} : { keepRunsForDays: file.keep_runs_for_days }),
64
- };
51
+ text = readFileSync(path, "utf8");
65
52
  }
66
- catch (error) {
67
- if (isCliError(error))
68
- throw new CliError("configuration_error", keyOnly(error.message));
69
- throw new CliError("configuration_error", `${path} could not be read`);
53
+ catch {
54
+ if (!existsSync(path))
55
+ return { found: false, issues: [], raw: {}, config: configOf({}) };
56
+ const what = statSync(path, { throwIfNoEntry: false })?.isDirectory()
57
+ ? "the path is a folder, not a file"
58
+ : "the file could not be read";
59
+ return { found: true, issues: [fileIssue(path, what)], raw: null, config: configOf({}) };
70
60
  }
61
+ const { issues, raw } = configIssues(text, path, ConfigFile, permissionKeys);
62
+ return {
63
+ found: true,
64
+ issues,
65
+ raw,
66
+ config: configOf(raw ? v.parse(ConfigFile, withoutIssues(raw, issues)) : {}),
67
+ };
71
68
  };
72
- const saveConfig = (path, config) => saveConfigFile(path, {
73
- client_id: config.clientId,
74
- source: config.source,
75
- files_folder: config.filesFolder,
76
- files_timezone: config.filesTimezone,
77
- ...(config.legacyProfile ? { account_profile: config.legacyProfile } : {}),
78
- profiles: Object.fromEntries(config.profiles.map((name) => [name, config.permissions[name] ? { permissions: config.permissions[name] } : {}])),
79
- ...(config.contextSources === undefined ? {} : { context_sources: config.contextSources }),
80
- ...(config.record === undefined ? {} : { record: config.record }),
81
- ...(config.keepRunsForDays === undefined ? {} : { keep_runs_for_days: config.keepRunsForDays }),
82
- });
69
+ /** The settings every command but `config` and `doctor` runs on; a file with any problem is refused. */
70
+ export const readConfig = (path, permissionKeys) => {
71
+ const { issues, config } = inspectConfig(path, permissionKeys);
72
+ if (issues.length > 0)
73
+ throw new CliError("configuration_error", issueMessage(issues.map(publicIssue), DOCTOR));
74
+ return config;
75
+ };
76
+ /** Changes the file as written: whatever else it holds, problems included, stays as it was. */
77
+ const changeFile = (path, permissionKeys, change) => {
78
+ const inspection = inspectConfig(path, permissionKeys);
79
+ if (!inspection.raw)
80
+ throw new CliError("configuration_error", issueMessage(inspection.issues.map(publicIssue), DOCTOR));
81
+ const raw = structuredClone(inspection.raw);
82
+ change(raw, inspection);
83
+ saveConfigFile(path, raw);
84
+ return inspectConfig(path, permissionKeys).config;
85
+ };
86
+ const profileEntry = (raw, profile) => {
87
+ if (!isNode(raw.profiles))
88
+ raw.profiles = {};
89
+ const profiles = raw.profiles;
90
+ if (!isNode(profiles[profile]))
91
+ profiles[profile] = {};
92
+ return profiles[profile];
93
+ };
94
+ const FILE_KEYS = Object.fromEntries(Object.entries(SETTING_NAMES).map(([file, name]) => [name, file]));
83
95
  /**
84
96
  * `profile`: the one named on the command line, for the settings that belong to a profile. `permissionKeys`: the
85
97
  * command paths a permission may name.
86
98
  */
87
- export const setConfig = (path, key, value, profile, permissionKeys) => {
88
- const config = readConfig(path);
99
+ export const setConfig = (path, key, value, profile, permissionKeys) => changeFile(path, permissionKeys, (raw, { config, issues }) => {
89
100
  switch (key) {
90
101
  case "permissions": {
91
102
  const name = profile?.();
92
103
  if (!name)
93
104
  throw new CliError("validation_error", "name a profile: `zm <profile> config set permissions …`");
94
- config.permissions[name] = parsePermissions(value, permissionKeys ?? new Set());
95
- if (!config.profiles.includes(name))
96
- config.profiles = [...config.profiles, name].sort();
97
- break;
105
+ profileEntry(raw, name).permissions = parsePermissions(value, permissionKeys ?? new Set());
106
+ return;
107
+ }
108
+ case "context.sources": {
109
+ const broken = issues.find((issue) => issue.at[0] === "context_sources");
110
+ if (broken)
111
+ throw new CliError("configuration_error", issueMessage([publicIssue(broken)], DOCTOR));
112
+ raw.context_sources = replaceContextSources(value, profile?.() ?? null, config.contextSources);
113
+ return;
98
114
  }
99
- case "context.sources":
100
- config.contextSources = replaceContextSources(value, profile?.() ?? null, config.contextSources);
101
- break;
102
115
  case "zoom.client_id":
103
- case "zoom.clientId":
104
116
  if (!value.trim() || /\s/.test(value))
105
117
  throw new CliError("validation_error", "client id must not contain whitespace");
106
- config.clientId = value;
107
- break;
108
- case "account.profile":
109
- throw new CliError("validation_error", `the profile is the first word now, not a setting: \`zm ${profilePattern.test(value) ? value : "<profile>"} …\``, { profiles: config.profiles });
118
+ raw.client_id = value;
119
+ return;
110
120
  case "source":
111
121
  if (value !== "api" && value !== "files")
112
122
  throw new CliError("validation_error", "source must be api or files");
113
- config.source = value;
114
- break;
123
+ raw.source = value;
124
+ return;
115
125
  case "files.folder":
116
126
  if (!value.trim())
117
127
  throw new CliError("validation_error", "folder must not be empty");
118
- config.filesFolder = value;
119
- break;
128
+ raw.files_folder = value;
129
+ return;
120
130
  case "files.timezone":
121
131
  try {
122
132
  new Intl.DateTimeFormat("en", { timeZone: value });
@@ -124,31 +134,57 @@ export const setConfig = (path, key, value, profile, permissionKeys) => {
124
134
  catch {
125
135
  throw new CliError("validation_error", "expected an IANA time zone");
126
136
  }
127
- config.filesTimezone = value;
128
- break;
137
+ raw.files_timezone = value;
138
+ return;
129
139
  case "record":
130
140
  if (value !== "true" && value !== "false")
131
141
  throw new CliError("validation_error", "record must be true or false");
132
- config.record = value === "true";
133
- break;
142
+ raw.record = value === "true";
143
+ return;
134
144
  case "keep_runs_for_days":
135
145
  if (!/^[1-9]\d{0,4}$/.test(value))
136
146
  throw new CliError("validation_error", "keep_runs_for_days must be a whole number of days, 1 or more");
137
- config.keepRunsForDays = Number(value);
138
- break;
147
+ raw.keep_runs_for_days = Number(value);
148
+ return;
139
149
  default:
140
150
  throw new CliError("validation_error", "unknown config key");
141
151
  }
142
- saveConfig(path, config);
143
- return config;
152
+ });
153
+ /**
154
+ * Removes a setting, or any part of the file `doctor` reports a problem in, by the name its fix gives.
155
+ * `profile`: the one named, if any; `context.sources` without one removes every profile's sources.
156
+ */
157
+ export const unsetConfig = (path, key, profile, permissionKeys) => changeFile(path, permissionKeys, (raw, { issues }) => {
158
+ const reported = issues.find((issue) => issue.key === key && (issue.profile === undefined || issue.profile === profile));
159
+ if (key === "context.sources" && !reported && profile !== undefined && Array.isArray(raw.context_sources)) {
160
+ raw.context_sources = raw.context_sources.filter((source) => !isNode(source) || source.profile !== profile);
161
+ return;
162
+ }
163
+ const at = reported?.at ?? (FILE_KEYS[key] ? [FILE_KEYS[key]] : profileSettingAt(key, profile));
164
+ removeAt(raw, at);
165
+ // Removing the last permission removes the section, as the file had none before it.
166
+ const entry = isNode(raw.profiles) ? raw.profiles[at[1] ?? ""] : undefined;
167
+ if (at[2] === "permissions" && isNode(entry) && isNode(entry.permissions)) {
168
+ if (Object.keys(entry.permissions).length === 0)
169
+ delete entry.permissions;
170
+ }
171
+ });
172
+ const profileSettingAt = (key, profile) => {
173
+ if (key !== "permissions" && !key.startsWith("permissions."))
174
+ throw new CliError("validation_error", "unknown config key");
175
+ if (!profile)
176
+ throw new CliError("validation_error", `name a profile: \`zm <profile> config unset ${key}\``);
177
+ return key === "permissions"
178
+ ? ["profiles", profile, "permissions"]
179
+ : ["profiles", profile, "permissions", key.slice("permissions.".length)];
144
180
  };
145
181
  /** A successful login makes a profile; the store account and the archive follow it by name. */
146
182
  export const addProfile = (path, profile) => {
147
- const config = readConfig(path);
148
- if (config.profiles.includes(profile))
183
+ if (readConfig(path).profiles.includes(profile))
149
184
  return;
150
- config.profiles = [...config.profiles, profile].sort();
151
- saveConfig(path, config);
185
+ changeFile(path, undefined, (raw) => {
186
+ profileEntry(raw, profile);
187
+ });
152
188
  };
153
189
  /** The zone a transcript file name's time is read in: `files.timezone`, else this computer's. */
154
190
  export const filesZone = (config) => config.filesTimezone ?? Intl.DateTimeFormat().resolvedOptions().timeZone;