@intercom/cli 0.8.3 → 0.9.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.
- package/CHANGELOG.md +8 -0
- package/dist/index.js +184 -32
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
View it from the CLI with `intercom changelog`.
|
|
9
9
|
|
|
10
|
+
## [0.9.0] - 2026-07-03
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- `fin attributes upload <file>` creates or updates Fin custom attributes from a YAML file. Attributes were previously read-only (`list`). The file can be a list of attributes, a single attribute, or the full `type: attribute` / `attributes:` server shape — the CLI normalizes it and sets the routing type for you. Each attribute needs a dotted `name` (e.g. `user.order_status`) and a data `type` (`string`, `integer`, `decimal`, `float`, `boolean`, `list`, `date`, `object`, or `array`).
|
|
15
|
+
- `fin procedures get <id> [output] --with-simulations` downloads a procedure's simulations alongside it. With the flag, `[output]` is a directory (default: current directory) and the CLI writes both `procedure.yaml` and `simulations.yaml`. Without it, `[output]` is a single file for the procedure YAML (previously `get` could only print to stdout).
|
|
16
|
+
- `fin simulations upload <file>` re-uploads a simulation set (the `simulations.yaml` written by `fin procedures get --with-simulations`, or `fin simulations list` output), completing the export/edit/re-import round-trip for a procedure's tests.
|
|
17
|
+
|
|
10
18
|
## [0.8.3] - 2026-06-18
|
|
11
19
|
|
|
12
20
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -2569,8 +2569,8 @@ Examples:
|
|
|
2569
2569
|
import { writeFile as writeFile3 } from "fs/promises";
|
|
2570
2570
|
|
|
2571
2571
|
// src/commands/fin/procedures.ts
|
|
2572
|
-
import { readFile as readFile2 } from "fs/promises";
|
|
2573
|
-
import { basename } from "path";
|
|
2572
|
+
import { readFile as readFile2, mkdir as mkdir2 } from "fs/promises";
|
|
2573
|
+
import { basename, join as join3 } from "path";
|
|
2574
2574
|
import AdmZip from "adm-zip";
|
|
2575
2575
|
function registerProceduresCommand(fin) {
|
|
2576
2576
|
const procedures = fin.command("procedures").description("Manage Fin SDK procedures");
|
|
@@ -2591,7 +2591,21 @@ function registerProceduresCommand(fin) {
|
|
|
2591
2591
|
return table({ columns: ["ID", "NAME"], rows });
|
|
2592
2592
|
}, items);
|
|
2593
2593
|
});
|
|
2594
|
-
procedures.command("get <id>").description("Download a procedure by ID
|
|
2594
|
+
procedures.command("get <id> [output]").description("Download a procedure by ID as YAML (writes to [output], or stdout)").option("--with-simulations", "Also download the procedure's simulations").option("--verbose", "Show HTTP request/response details").addHelpText(
|
|
2595
|
+
"after",
|
|
2596
|
+
`
|
|
2597
|
+
Examples:
|
|
2598
|
+
$ intercom fin procedures get proc-1 # print YAML to stdout
|
|
2599
|
+
$ intercom fin procedures get proc-1 procedure.yaml # write YAML to a file
|
|
2600
|
+
$ intercom fin procedures get proc-1 ./out --with-simulations
|
|
2601
|
+
# writes ./out/procedure.yaml and ./out/simulations.yaml
|
|
2602
|
+
|
|
2603
|
+
With --with-simulations, [output] is treated as a directory (default: current
|
|
2604
|
+
directory). Without it, [output] is a single file for the procedure YAML.
|
|
2605
|
+
|
|
2606
|
+
Re-import the pieces with \`intercom fin procedures upload <procedure.yaml>\`
|
|
2607
|
+
and \`intercom fin simulations upload <simulations.yaml>\`.`
|
|
2608
|
+
).action(async function(id, output) {
|
|
2595
2609
|
const opts = this.optsWithGlobals();
|
|
2596
2610
|
const client = await resolveClient(opts);
|
|
2597
2611
|
const buffer = await client.getBuffer(`/fin-sdk/procedures/${id}/download`);
|
|
@@ -2600,7 +2614,28 @@ function registerProceduresCommand(fin) {
|
|
|
2600
2614
|
if (!entry) {
|
|
2601
2615
|
throw new Error("procedure.yaml not found in downloaded ZIP");
|
|
2602
2616
|
}
|
|
2603
|
-
|
|
2617
|
+
const procedureYaml = zip.readAsText(entry);
|
|
2618
|
+
let simulationsYaml;
|
|
2619
|
+
if (opts.withSimulations) {
|
|
2620
|
+
simulationsYaml = await client.getText(`/fin-sdk/procedures/${id}/simulations`);
|
|
2621
|
+
}
|
|
2622
|
+
if (opts.withSimulations) {
|
|
2623
|
+
const dir = output ?? ".";
|
|
2624
|
+
await mkdir2(dir, { recursive: true });
|
|
2625
|
+
const procedurePath = join3(dir, "procedure.yaml");
|
|
2626
|
+
const simulationsPath = join3(dir, "simulations.yaml");
|
|
2627
|
+
await atomicWriteFile(procedurePath, procedureYaml, 420);
|
|
2628
|
+
await atomicWriteFile(simulationsPath, simulationsYaml ?? "", 420);
|
|
2629
|
+
console.error(`Wrote procedure ${id} to ${procedurePath}`);
|
|
2630
|
+
console.error(`Wrote simulations to ${simulationsPath}`);
|
|
2631
|
+
return;
|
|
2632
|
+
}
|
|
2633
|
+
if (output) {
|
|
2634
|
+
await atomicWriteFile(output, procedureYaml, 420);
|
|
2635
|
+
console.error(`Wrote procedure ${id} to ${output}`);
|
|
2636
|
+
} else {
|
|
2637
|
+
console.log(procedureYaml);
|
|
2638
|
+
}
|
|
2604
2639
|
});
|
|
2605
2640
|
procedures.command("upload <file>").description("Upload a procedure file to Fin SDK").option("--json", "Output as JSON").option("--jq <expr>", "Filter JSON output with jq expression").option("--verbose", "Show HTTP request/response details").action(async function(filePath) {
|
|
2606
2641
|
const opts = this.optsWithGlobals();
|
|
@@ -2766,6 +2801,29 @@ Optional fields: state (live or paused, default: paused), audiences`
|
|
|
2766
2801
|
}
|
|
2767
2802
|
|
|
2768
2803
|
// src/commands/fin/attributes.ts
|
|
2804
|
+
import { readFile as readFile3 } from "fs/promises";
|
|
2805
|
+
import { basename as basename2 } from "path";
|
|
2806
|
+
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
2807
|
+
var ATTRIBUTE_TYPE = "attribute";
|
|
2808
|
+
function buildAttributesUploadBody(raw) {
|
|
2809
|
+
let parsed;
|
|
2810
|
+
try {
|
|
2811
|
+
parsed = parseYaml(raw);
|
|
2812
|
+
} catch {
|
|
2813
|
+
return raw;
|
|
2814
|
+
}
|
|
2815
|
+
if (Array.isArray(parsed)) {
|
|
2816
|
+
return stringifyYaml({ type: ATTRIBUTE_TYPE, attributes: parsed });
|
|
2817
|
+
}
|
|
2818
|
+
if (parsed == null || typeof parsed !== "object") {
|
|
2819
|
+
return raw;
|
|
2820
|
+
}
|
|
2821
|
+
const obj = parsed;
|
|
2822
|
+
if (Array.isArray(obj.attributes)) {
|
|
2823
|
+
return stringifyYaml({ ...obj, type: ATTRIBUTE_TYPE });
|
|
2824
|
+
}
|
|
2825
|
+
return stringifyYaml({ type: ATTRIBUTE_TYPE, attributes: [obj] });
|
|
2826
|
+
}
|
|
2769
2827
|
function registerAttributesCommand(fin) {
|
|
2770
2828
|
const attributes = fin.command("attributes").description("Manage Fin SDK attributes");
|
|
2771
2829
|
attributes.command("list").description("List Fin SDK attributes").option("--json", "Output as JSON").option("--verbose", "Show HTTP request/response details").action(async function() {
|
|
@@ -2785,6 +2843,49 @@ function registerAttributesCommand(fin) {
|
|
|
2785
2843
|
return table({ columns: ["NAME", "TYPE", "DESCRIPTION"], rows });
|
|
2786
2844
|
}, items);
|
|
2787
2845
|
});
|
|
2846
|
+
attributes.command("upload <file>").description("Upload attributes from a YAML file (creates or updates)").option("--json", "Output as JSON").option("--jq <expr>", "Filter JSON output with jq expression").option("--verbose", "Show HTTP request/response details").addHelpText(
|
|
2847
|
+
"after",
|
|
2848
|
+
`
|
|
2849
|
+
The file holds one or more attributes. The CLI wraps them in the bulk shape the
|
|
2850
|
+
server expects and sets the routing type for you, so any of these work:
|
|
2851
|
+
|
|
2852
|
+
# a list of attributes
|
|
2853
|
+
- name: user.order_status # name must contain a dot
|
|
2854
|
+
type: string # data type: string, integer, decimal, float,
|
|
2855
|
+
description: Order state # boolean, list, date, object, or array
|
|
2856
|
+
|
|
2857
|
+
# ...or a single attribute
|
|
2858
|
+
name: company.tier
|
|
2859
|
+
type: string
|
|
2860
|
+
|
|
2861
|
+
# ...or the full server shape
|
|
2862
|
+
type: attribute
|
|
2863
|
+
attributes:
|
|
2864
|
+
- name: user.order_status
|
|
2865
|
+
type: string
|
|
2866
|
+
|
|
2867
|
+
Examples:
|
|
2868
|
+
$ intercom fin attributes upload ./attributes.yaml
|
|
2869
|
+
$ intercom fin attributes upload ./attributes.yaml --json`
|
|
2870
|
+
).action(async function(filePath) {
|
|
2871
|
+
const opts = this.optsWithGlobals();
|
|
2872
|
+
const client = await resolveClient(opts);
|
|
2873
|
+
const fileContent = await readFile3(filePath, "utf8");
|
|
2874
|
+
const yamlBody = buildAttributesUploadBody(fileContent);
|
|
2875
|
+
const formData = new FormData();
|
|
2876
|
+
const blob = new Blob([yamlBody], { type: "application/x-yaml" });
|
|
2877
|
+
formData.append("file_data", blob, basename2(filePath));
|
|
2878
|
+
const result = await client.postFormData("/fin-sdk/upload", formData);
|
|
2879
|
+
render(
|
|
2880
|
+
result,
|
|
2881
|
+
opts,
|
|
2882
|
+
() => detail({
|
|
2883
|
+
"ID": result.id != null ? String(result.id) : void 0,
|
|
2884
|
+
"Type": result.type != null ? String(result.type) : void 0,
|
|
2885
|
+
"Message": result.message != null ? String(result.message) : void 0
|
|
2886
|
+
})
|
|
2887
|
+
);
|
|
2888
|
+
});
|
|
2788
2889
|
}
|
|
2789
2890
|
|
|
2790
2891
|
// src/commands/fin/audiences.ts
|
|
@@ -2809,16 +2910,16 @@ function registerAudiencesCommand(fin) {
|
|
|
2809
2910
|
}
|
|
2810
2911
|
|
|
2811
2912
|
// src/commands/fin/workflows.ts
|
|
2812
|
-
import { readFile as
|
|
2813
|
-
import { basename as
|
|
2814
|
-
import { parse as
|
|
2913
|
+
import { readFile as readFile4 } from "fs/promises";
|
|
2914
|
+
import { basename as basename3 } from "path";
|
|
2915
|
+
import { parse as parseYaml2, stringify as stringifyYaml2 } from "yaml";
|
|
2815
2916
|
var STATE_LIVE = "live";
|
|
2816
2917
|
var STATE_PAUSED = "paused";
|
|
2817
2918
|
var WORKFLOW_TYPE = "workflow";
|
|
2818
2919
|
function ensureWorkflowType(raw) {
|
|
2819
2920
|
let parsed;
|
|
2820
2921
|
try {
|
|
2821
|
-
parsed =
|
|
2922
|
+
parsed = parseYaml2(raw);
|
|
2822
2923
|
} catch {
|
|
2823
2924
|
return raw;
|
|
2824
2925
|
}
|
|
@@ -2830,7 +2931,7 @@ function ensureWorkflowType(raw) {
|
|
|
2830
2931
|
return raw;
|
|
2831
2932
|
}
|
|
2832
2933
|
obj.type = WORKFLOW_TYPE;
|
|
2833
|
-
return
|
|
2934
|
+
return stringifyYaml2(obj);
|
|
2834
2935
|
}
|
|
2835
2936
|
function registerWorkflowsCommand(fin) {
|
|
2836
2937
|
const workflows = fin.command("workflows").description("Manage Fin SDK workflows");
|
|
@@ -2867,7 +2968,7 @@ The YAML it prints is ready to edit and re-upload with
|
|
|
2867
2968
|
const client = await resolveClient(opts);
|
|
2868
2969
|
const text = await client.getText(`/fin-sdk/workflows/${id}`);
|
|
2869
2970
|
if (opts.json || opts.jq || opts.agent) {
|
|
2870
|
-
const parsed =
|
|
2971
|
+
const parsed = parseYaml2(text);
|
|
2871
2972
|
render(parsed, opts, () => formatJson(parsed));
|
|
2872
2973
|
return;
|
|
2873
2974
|
}
|
|
@@ -2892,11 +2993,11 @@ The YAML file's id field determines whether this creates or updates:
|
|
|
2892
2993
|
).action(async function(filePath) {
|
|
2893
2994
|
const opts = this.optsWithGlobals();
|
|
2894
2995
|
const client = await resolveClient(opts);
|
|
2895
|
-
const fileContent = await
|
|
2996
|
+
const fileContent = await readFile4(filePath, "utf8");
|
|
2896
2997
|
const yamlBody = ensureWorkflowType(fileContent);
|
|
2897
2998
|
const formData = new FormData();
|
|
2898
2999
|
const blob = new Blob([yamlBody], { type: "application/x-yaml" });
|
|
2899
|
-
formData.append("file_data", blob,
|
|
3000
|
+
formData.append("file_data", blob, basename3(filePath));
|
|
2900
3001
|
const result = await client.postFormData("/fin-sdk/upload", formData);
|
|
2901
3002
|
render(
|
|
2902
3003
|
result,
|
|
@@ -2925,13 +3026,13 @@ overwritten (the server does not expose a concurrency token).`
|
|
|
2925
3026
|
const text = await client.getText(`/fin-sdk/workflows/${id}`);
|
|
2926
3027
|
let parsed;
|
|
2927
3028
|
try {
|
|
2928
|
-
parsed =
|
|
3029
|
+
parsed = parseYaml2(text);
|
|
2929
3030
|
} catch (err) {
|
|
2930
3031
|
throw new Error(`server returned unparseable YAML for workflow ${id}: ${err.message}`);
|
|
2931
3032
|
}
|
|
2932
3033
|
parsed.type = WORKFLOW_TYPE;
|
|
2933
3034
|
parsed.state = STATE_LIVE;
|
|
2934
|
-
const yamlBody =
|
|
3035
|
+
const yamlBody = stringifyYaml2(parsed);
|
|
2935
3036
|
const formData = new FormData();
|
|
2936
3037
|
const blob = new Blob([yamlBody], { type: "application/x-yaml" });
|
|
2937
3038
|
formData.append("file_data", blob, `workflow-${id}.yaml`);
|
|
@@ -2962,13 +3063,13 @@ overwritten (the server does not expose a concurrency token).`
|
|
|
2962
3063
|
const text = await client.getText(`/fin-sdk/workflows/${id}`);
|
|
2963
3064
|
let parsed;
|
|
2964
3065
|
try {
|
|
2965
|
-
parsed =
|
|
3066
|
+
parsed = parseYaml2(text);
|
|
2966
3067
|
} catch (err) {
|
|
2967
3068
|
throw new Error(`server returned unparseable YAML for workflow ${id}: ${err.message}`);
|
|
2968
3069
|
}
|
|
2969
3070
|
parsed.type = WORKFLOW_TYPE;
|
|
2970
3071
|
parsed.state = STATE_PAUSED;
|
|
2971
|
-
const yamlBody =
|
|
3072
|
+
const yamlBody = stringifyYaml2(parsed);
|
|
2972
3073
|
const formData = new FormData();
|
|
2973
3074
|
const blob = new Blob([yamlBody], { type: "application/x-yaml" });
|
|
2974
3075
|
formData.append("file_data", blob, `workflow-${id}.yaml`);
|
|
@@ -2986,6 +3087,27 @@ overwritten (the server does not expose a concurrency token).`
|
|
|
2986
3087
|
}
|
|
2987
3088
|
|
|
2988
3089
|
// src/commands/fin/simulations.ts
|
|
3090
|
+
import { readFile as readFile5 } from "fs/promises";
|
|
3091
|
+
import { basename as basename4 } from "path";
|
|
3092
|
+
import { parse as parseYaml3, stringify as stringifyYaml3 } from "yaml";
|
|
3093
|
+
var SIMULATION_SET_TYPE = "simulation_set";
|
|
3094
|
+
function ensureSimulationSetType(raw) {
|
|
3095
|
+
let parsed;
|
|
3096
|
+
try {
|
|
3097
|
+
parsed = parseYaml3(raw);
|
|
3098
|
+
} catch {
|
|
3099
|
+
return raw;
|
|
3100
|
+
}
|
|
3101
|
+
if (parsed == null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
3102
|
+
return raw;
|
|
3103
|
+
}
|
|
3104
|
+
const obj = parsed;
|
|
3105
|
+
if (obj.type != null && obj.type !== "") {
|
|
3106
|
+
return raw;
|
|
3107
|
+
}
|
|
3108
|
+
obj.type = SIMULATION_SET_TYPE;
|
|
3109
|
+
return stringifyYaml3(obj);
|
|
3110
|
+
}
|
|
2989
3111
|
function registerSimulationsCommand(fin) {
|
|
2990
3112
|
const simulations = fin.command("simulations").description("Manage Fin SDK simulations");
|
|
2991
3113
|
simulations.command("list <procedure_id>").description("List simulations for a procedure (displays YAML)").option("--verbose", "Show HTTP request/response details").action(async function(procedureId) {
|
|
@@ -2994,6 +3116,36 @@ function registerSimulationsCommand(fin) {
|
|
|
2994
3116
|
const text = await client.getText(`/fin-sdk/procedures/${procedureId}/simulations`);
|
|
2995
3117
|
console.log(text);
|
|
2996
3118
|
});
|
|
3119
|
+
simulations.command("upload <file>").description("Upload a simulation set YAML file for its procedure").option("--json", "Output as JSON").option("--jq <expr>", "Filter JSON output with jq expression").option("--verbose", "Show HTTP request/response details").addHelpText(
|
|
3120
|
+
"after",
|
|
3121
|
+
`
|
|
3122
|
+
The file is a simulation set carrying its own procedure_id, as produced by
|
|
3123
|
+
\`intercom fin procedures get <id> ./out --with-simulations\` (writes
|
|
3124
|
+
./out/simulations.yaml) or \`intercom fin simulations list <procedure_id>\`.
|
|
3125
|
+
This completes the export/edit/re-import round-trip for a procedure's tests.
|
|
3126
|
+
|
|
3127
|
+
Example:
|
|
3128
|
+
$ intercom fin simulations upload ./out/simulations.yaml`
|
|
3129
|
+
).action(async function(filePath) {
|
|
3130
|
+
const opts = this.optsWithGlobals();
|
|
3131
|
+
const client = await resolveClient(opts);
|
|
3132
|
+
const fileContent = await readFile5(filePath, "utf8");
|
|
3133
|
+
const yamlBody = ensureSimulationSetType(fileContent);
|
|
3134
|
+
const formData = new FormData();
|
|
3135
|
+
const blob = new Blob([yamlBody], { type: "application/x-yaml" });
|
|
3136
|
+
formData.append("file_data", blob, basename4(filePath));
|
|
3137
|
+
const result = await client.postFormData("/fin-sdk/upload", formData);
|
|
3138
|
+
render(
|
|
3139
|
+
result,
|
|
3140
|
+
opts,
|
|
3141
|
+
() => detail({
|
|
3142
|
+
"ID": result.id != null ? String(result.id) : void 0,
|
|
3143
|
+
"Procedure ID": result.procedure_id != null ? String(result.procedure_id) : void 0,
|
|
3144
|
+
"Type": result.type != null ? String(result.type) : void 0,
|
|
3145
|
+
"Message": result.message != null ? String(result.message) : void 0
|
|
3146
|
+
})
|
|
3147
|
+
);
|
|
3148
|
+
});
|
|
2997
3149
|
simulations.command("run <procedure_id> [test_id]").description("Run one or all simulations for a procedure").option("--json", "Output as JSON").option("--verbose", "Show HTTP request/response details").action(async function(procedureId, testId) {
|
|
2998
3150
|
const opts = this.optsWithGlobals();
|
|
2999
3151
|
const client = await resolveClient(opts);
|
|
@@ -3223,8 +3375,8 @@ Fin is live on workspace ${appId}`);
|
|
|
3223
3375
|
}
|
|
3224
3376
|
|
|
3225
3377
|
// src/commands/fin/monitors.ts
|
|
3226
|
-
import { mkdir as
|
|
3227
|
-
import { join as
|
|
3378
|
+
import { mkdir as mkdir3, writeFile as writeFile2 } from "fs/promises";
|
|
3379
|
+
import { join as join4, relative, dirname } from "path";
|
|
3228
3380
|
import { stringify } from "yaml";
|
|
3229
3381
|
async function resolveMonitorId(client, nameOrId) {
|
|
3230
3382
|
if (/^\d+$/.test(nameOrId)) {
|
|
@@ -3305,14 +3457,14 @@ Examples:
|
|
|
3305
3457
|
);
|
|
3306
3458
|
return;
|
|
3307
3459
|
}
|
|
3308
|
-
const outputPath = opts.output ??
|
|
3460
|
+
const outputPath = opts.output ?? join4(
|
|
3309
3461
|
process.cwd(),
|
|
3310
3462
|
"src",
|
|
3311
3463
|
"qa",
|
|
3312
3464
|
"bulk-actions",
|
|
3313
3465
|
"flagged-conversations.yaml"
|
|
3314
3466
|
);
|
|
3315
|
-
await
|
|
3467
|
+
await mkdir3(dirname(outputPath), { recursive: true });
|
|
3316
3468
|
await writeFile2(outputPath, buildWorkingSetYaml(result, since), "utf-8");
|
|
3317
3469
|
const relPath = relative(process.cwd(), outputPath);
|
|
3318
3470
|
console.log(
|
|
@@ -3330,8 +3482,8 @@ Examples:
|
|
|
3330
3482
|
}
|
|
3331
3483
|
|
|
3332
3484
|
// src/commands/fin/conversation.ts
|
|
3333
|
-
import { readFile as
|
|
3334
|
-
import { join as
|
|
3485
|
+
import { readFile as readFile6 } from "fs/promises";
|
|
3486
|
+
import { join as join5 } from "path";
|
|
3335
3487
|
import { parse } from "yaml";
|
|
3336
3488
|
var PLACEHOLDER_MESSAGE = "Your message here \u2014 this will be sent to all conversations listed below.";
|
|
3337
3489
|
function validateWorkingSet(ws) {
|
|
@@ -3381,7 +3533,7 @@ function registerConversationCommand(fin) {
|
|
|
3381
3533
|
).option(
|
|
3382
3534
|
"--file <path>",
|
|
3383
3535
|
"Path to the working set YAML file",
|
|
3384
|
-
|
|
3536
|
+
join5(process.cwd(), "src", "qa", "bulk-actions", "flagged-conversations.yaml")
|
|
3385
3537
|
).option("--dry-run", "Preview actions without sending").option("--yes", "Skip confirmation prompt (required in TTY mode)").option(
|
|
3386
3538
|
"--json",
|
|
3387
3539
|
"Output result as JSON"
|
|
@@ -3395,7 +3547,7 @@ Examples:
|
|
|
3395
3547
|
$ fin conversation bulk-send --json`
|
|
3396
3548
|
).action(async function() {
|
|
3397
3549
|
const opts = this.optsWithGlobals();
|
|
3398
|
-
const filePath = opts.file ??
|
|
3550
|
+
const filePath = opts.file ?? join5(
|
|
3399
3551
|
process.cwd(),
|
|
3400
3552
|
"src",
|
|
3401
3553
|
"qa",
|
|
@@ -3404,7 +3556,7 @@ Examples:
|
|
|
3404
3556
|
);
|
|
3405
3557
|
let raw;
|
|
3406
3558
|
try {
|
|
3407
|
-
raw = await
|
|
3559
|
+
raw = await readFile6(filePath, "utf-8");
|
|
3408
3560
|
} catch (err) {
|
|
3409
3561
|
const e = err;
|
|
3410
3562
|
if (e.code === "ENOENT") {
|
|
@@ -3565,7 +3717,7 @@ Examples:
|
|
|
3565
3717
|
|
|
3566
3718
|
// src/commands/setup.ts
|
|
3567
3719
|
import { readdirSync, readFileSync as readFileSync4, statSync } from "fs";
|
|
3568
|
-
import { join as
|
|
3720
|
+
import { join as join6, basename as basename5 } from "path";
|
|
3569
3721
|
function isGreenfield(opts) {
|
|
3570
3722
|
return !!(opts.email && opts.name && (process.env.INTERCOM_PASSWORD || opts.passwordStdin));
|
|
3571
3723
|
}
|
|
@@ -3623,8 +3775,8 @@ function buildPlan(opts) {
|
|
|
3623
3775
|
}
|
|
3624
3776
|
if (mdFiles.length > 0) {
|
|
3625
3777
|
const articleCommands = mdFiles.map((file) => {
|
|
3626
|
-
const title =
|
|
3627
|
-
return `intercom articles create -f title="${title}" -F body=@${
|
|
3778
|
+
const title = basename5(file, ".md").replace(/-/g, " ").replace(/\b\w/g, (c2) => c2.toUpperCase());
|
|
3779
|
+
return `intercom articles create -f title="${title}" -F body=@${join6(opts.articlesFrom, file)} -f author_id=$(intercom me --json | jq -r .id)`;
|
|
3628
3780
|
});
|
|
3629
3781
|
steps.push({
|
|
3630
3782
|
step: stepNum++,
|
|
@@ -3690,8 +3842,8 @@ async function runPostAuthSteps(client, opts, results, appId) {
|
|
|
3690
3842
|
let created = 0;
|
|
3691
3843
|
let skipped = 0;
|
|
3692
3844
|
for (const file of mdFiles) {
|
|
3693
|
-
const title =
|
|
3694
|
-
const body = readFileSync4(
|
|
3845
|
+
const title = basename5(file, ".md").replace(/-/g, " ").replace(/\b\w/g, (c2) => c2.toUpperCase());
|
|
3846
|
+
const body = readFileSync4(join6(opts.articlesFrom, file), "utf-8");
|
|
3695
3847
|
if (existingTitles.has(title)) {
|
|
3696
3848
|
skipped++;
|
|
3697
3849
|
} else {
|
|
@@ -4168,7 +4320,7 @@ function registerPricingCommand(program) {
|
|
|
4168
4320
|
}
|
|
4169
4321
|
|
|
4170
4322
|
// src/commands/config.ts
|
|
4171
|
-
import { join as
|
|
4323
|
+
import { join as join7 } from "path";
|
|
4172
4324
|
var SUPPORTED_KEYS = ["default_workspace", "timeout"];
|
|
4173
4325
|
function configDir() {
|
|
4174
4326
|
return process.env.INTERCOM_CONFIG_DIR ?? defaultConfigDir();
|
|
@@ -4257,7 +4409,7 @@ function registerConfigCommand(program) {
|
|
|
4257
4409
|
console.log(`Set ${key} = ${value}`);
|
|
4258
4410
|
});
|
|
4259
4411
|
cmd.command("path").description("Show configuration file path").action(async function() {
|
|
4260
|
-
console.log(
|
|
4412
|
+
console.log(join7(configDir(), "config.json"));
|
|
4261
4413
|
});
|
|
4262
4414
|
}
|
|
4263
4415
|
|