@fluid-app/fluid-cli-payments 0.1.320 → 0.1.321
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/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +58 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;iBAgEgB,0BAAA,CACd,MAAA,EAAQ,OAAA,EACR,GAAA,EAAK,cAAA;AAAA,cA8UD,MAAA,EAAQ,WAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NAV_HELP, assertInteractive, createDomainCommand, terminalPrompter } from "@fluid-app/fluid-cli";
|
|
1
|
+
import { NAV_HELP, assertInteractive, createDomainCommand, declareInputs, exitOnInputsError, terminalPrompter } from "@fluid-app/fluid-cli";
|
|
2
2
|
import { readFile } from "node:fs/promises";
|
|
3
3
|
import { basename, extname } from "node:path";
|
|
4
4
|
import prompts from "prompts";
|
|
@@ -611,6 +611,22 @@ const readLocalFile = async (path) => {
|
|
|
611
611
|
bytes
|
|
612
612
|
};
|
|
613
613
|
};
|
|
614
|
+
/** A FileReader that serves the command's declared inputs. */
|
|
615
|
+
function inputsReader(inputs) {
|
|
616
|
+
return async (path) => {
|
|
617
|
+
let bytes;
|
|
618
|
+
try {
|
|
619
|
+
bytes = inputs.readFile(path);
|
|
620
|
+
} catch (error) {
|
|
621
|
+
exitOnInputsError(error);
|
|
622
|
+
throw new OnboardingError(`Can't read ${path}.`);
|
|
623
|
+
}
|
|
624
|
+
return {
|
|
625
|
+
name: basename(path),
|
|
626
|
+
bytes
|
|
627
|
+
};
|
|
628
|
+
};
|
|
629
|
+
}
|
|
614
630
|
/** The company the token acts for. */
|
|
615
631
|
async function currentCompanyId(client) {
|
|
616
632
|
const me = await client.get("/api/company/v1/companies/me");
|
|
@@ -1133,6 +1149,38 @@ function coerce(field, key, raw) {
|
|
|
1133
1149
|
return value;
|
|
1134
1150
|
}
|
|
1135
1151
|
}
|
|
1152
|
+
/** Split a `--file key=path` flag into its key and trimmed path. */
|
|
1153
|
+
function splitFile(raw) {
|
|
1154
|
+
const [key, path] = splitAssignment(raw, "--file");
|
|
1155
|
+
return [key, path.trim()];
|
|
1156
|
+
}
|
|
1157
|
+
/**
|
|
1158
|
+
* The local inputs of `--file key=path` flags: each path as a file, plus the
|
|
1159
|
+
* key it is bound to. An empty path is refused, and so is a repeated key
|
|
1160
|
+
* unless the field takes several files.
|
|
1161
|
+
*/
|
|
1162
|
+
function fileInputs(files) {
|
|
1163
|
+
const specs = [];
|
|
1164
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1165
|
+
for (const raw of files) {
|
|
1166
|
+
const [key, path] = splitFile(raw);
|
|
1167
|
+
if (!path) throw new OnboardingError(`--file ${key} needs a path.`);
|
|
1168
|
+
const index = counts.get(key) ?? 0;
|
|
1169
|
+
const repeatable = fieldFor(key)?.type === "files";
|
|
1170
|
+
if (index > 0 && !repeatable) throw new OnboardingError(`--file ${key} was given more than once.`);
|
|
1171
|
+
counts.set(key, index + 1);
|
|
1172
|
+
specs.push({
|
|
1173
|
+
kind: "ref",
|
|
1174
|
+
name: repeatable ? `file:${key}:${index}` : `file:${key}`,
|
|
1175
|
+
value: path
|
|
1176
|
+
});
|
|
1177
|
+
specs.push({
|
|
1178
|
+
kind: "file",
|
|
1179
|
+
path
|
|
1180
|
+
});
|
|
1181
|
+
}
|
|
1182
|
+
return specs;
|
|
1183
|
+
}
|
|
1136
1184
|
/** Parse `--set` and `--file` flags into a plan. */
|
|
1137
1185
|
function buildPlan(sets, files) {
|
|
1138
1186
|
const plan = emptyPlan();
|
|
@@ -1159,18 +1207,19 @@ function buildPlan(sets, files) {
|
|
|
1159
1207
|
plan[group][attributeOf(key)] = coerced;
|
|
1160
1208
|
}
|
|
1161
1209
|
for (const raw of files) {
|
|
1162
|
-
const [key, path] =
|
|
1210
|
+
const [key, path] = splitFile(raw);
|
|
1163
1211
|
const field = fieldFor(key);
|
|
1164
1212
|
if (!field || ![
|
|
1165
1213
|
"file",
|
|
1166
1214
|
"files",
|
|
1167
1215
|
"link_or_file"
|
|
1168
1216
|
].includes(field.type)) throw new OnboardingError(field ? `${key} isn't a document; use --set.` : `Unknown document "${key}". Run \`fluid payments onboarding fields\`.`);
|
|
1169
|
-
if (!path
|
|
1217
|
+
if (!path) throw new OnboardingError(`--file ${key} needs a path.`);
|
|
1218
|
+
if (field.type !== "files" && plan.files.some((f) => f.key === key)) throw new OnboardingError(`--file ${key} was given more than once.`);
|
|
1170
1219
|
plan.files.push({
|
|
1171
1220
|
key,
|
|
1172
1221
|
field,
|
|
1173
|
-
path
|
|
1222
|
+
path
|
|
1174
1223
|
});
|
|
1175
1224
|
}
|
|
1176
1225
|
return plan;
|
|
@@ -2192,7 +2241,7 @@ function registerOnboardingCommands(parent, ctx) {
|
|
|
2192
2241
|
if (!OPTION_LISTS.includes(list)) throw new OnboardingError(`List must be one of ${OPTION_LISTS.join(", ")}.`);
|
|
2193
2242
|
ctx.output(await listOptions(await client(ctx), list, opts.country));
|
|
2194
2243
|
}));
|
|
2195
|
-
onboarding.command("set").description("Save fields and upload documents, then print what's still missing (changes live data)").option("--set <key=value>", "A field from `fields`, e.g. entity.legal_name=Acme Inc (repeatable)", collect, []).option("--file <key=path>", "Upload a document, e.g. entity.business_license=./license.pdf (repeatable)", collect, []).option("--entity <id|new>", "Which legal entity entity.* fields go to").option("--bank <id|new>", "Which bank account bank.* fields go to").option("--owner <id|new>", "Which person owner.* fields go to").option("--id-type <type>", `Government ID type for owner.government_issued_ids: ${ID_TYPES.join(", ")}`).option("--replace-files", "Replace a multi-file document's files instead of adding to them", false).option("--yes", "Confirm without a prompt", false).action((opts) => run(async () => {
|
|
2244
|
+
declareInputs(onboarding.command("set").description("Save fields and upload documents, then print what's still missing (changes live data)").option("--set <key=value>", "A field from `fields`, e.g. entity.legal_name=Acme Inc (repeatable)", collect, []).option("--file <key=path>", "Upload a document, e.g. entity.business_license=./license.pdf (repeatable)", collect, []).option("--entity <id|new>", "Which legal entity entity.* fields go to").option("--bank <id|new>", "Which bank account bank.* fields go to").option("--owner <id|new>", "Which person owner.* fields go to").option("--id-type <type>", `Government ID type for owner.government_issued_ids: ${ID_TYPES.join(", ")}`).option("--replace-files", "Replace a multi-file document's files instead of adding to them", false).option("--yes", "Confirm without a prompt", false).action((opts) => run(async () => {
|
|
2196
2245
|
const plan = buildPlan(opts.set, opts.file);
|
|
2197
2246
|
if (isEmptyPlan(plan)) throw new OnboardingError("Pass fields with --set key=value or documents with --file key=path.");
|
|
2198
2247
|
const targets = {
|
|
@@ -2206,7 +2255,7 @@ function registerOnboardingCommands(parent, ctx) {
|
|
|
2206
2255
|
const companyId = await currentCompanyId(api);
|
|
2207
2256
|
const snapshot = await loadSnapshot(api, companyId);
|
|
2208
2257
|
await confirmChange(`Save ${opts.set.length + opts.file.length} onboarding change(s) for company ${companyId}?`, opts.yes);
|
|
2209
|
-
const saved = await applyPlan(api, snapshot, plan, targets);
|
|
2258
|
+
const saved = await applyPlan(api, snapshot, plan, targets, inputsReader(ctx.inputs));
|
|
2210
2259
|
const after = summarize(await loadSnapshot(api, companyId));
|
|
2211
2260
|
ctx.output({
|
|
2212
2261
|
saved,
|
|
@@ -2217,7 +2266,7 @@ function registerOnboardingCommands(parent, ctx) {
|
|
|
2217
2266
|
steps: after.steps,
|
|
2218
2267
|
missing: after.missing
|
|
2219
2268
|
});
|
|
2220
|
-
}));
|
|
2269
|
+
})), (opts) => fileInputs(opts["file"] ?? []));
|
|
2221
2270
|
onboarding.command("walk").description("Answer the form question by question in the terminal: go back, skip, jump to a step, or change an answer; each answer is saved as you go (changes live data)").option("--step <id>", `Start at a step: ${STEPS.map((s) => s.id).join(", ")}`).action((opts) => run(async () => {
|
|
2222
2271
|
assertInteractive("`show` to see what's missing and `set` to fill it in");
|
|
2223
2272
|
const step = opts.step;
|
|
@@ -2227,7 +2276,8 @@ function registerOnboardingCommands(parent, ctx) {
|
|
|
2227
2276
|
ctx.output(await walkOnboarding({
|
|
2228
2277
|
api,
|
|
2229
2278
|
companyId,
|
|
2230
|
-
prompter: terminalPrompter()
|
|
2279
|
+
prompter: terminalPrompter(),
|
|
2280
|
+
readLocal: inputsReader(ctx.inputs)
|
|
2231
2281
|
}, { step }));
|
|
2232
2282
|
}));
|
|
2233
2283
|
onboarding.command("remove <record> <id>").description("Remove a legal entity, bank account, or person by id, or a country by ISO code (changes live data)").option("--yes", "Confirm without a prompt", false).action((record, id, opts) => run(async () => {
|