@fairmint/captable-ai 0.1.37 → 0.1.39
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.js +202 -183
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -17321,80 +17321,6 @@ async function requireAuth() {
|
|
|
17321
17321
|
return creds;
|
|
17322
17322
|
}
|
|
17323
17323
|
|
|
17324
|
-
// src/auth/refresh-portals.ts
|
|
17325
|
-
var PORTALS_TTL_MS = 3e5;
|
|
17326
|
-
var REQUEST_TIMEOUT_MS = 1e4;
|
|
17327
|
-
function isStoredPortal(v) {
|
|
17328
|
-
if (typeof v !== "object" || v === null) return false;
|
|
17329
|
-
const obj = v;
|
|
17330
|
-
return typeof obj.id === "string";
|
|
17331
|
-
}
|
|
17332
|
-
function parsePortals(body) {
|
|
17333
|
-
if (typeof body !== "object" || body === null) return null;
|
|
17334
|
-
if (!("portals" in body)) return null;
|
|
17335
|
-
const portals = body.portals;
|
|
17336
|
-
if (!Array.isArray(portals)) return null;
|
|
17337
|
-
if (!portals.every(isStoredPortal)) return null;
|
|
17338
|
-
return portals;
|
|
17339
|
-
}
|
|
17340
|
-
function cachedPortalsNeedNameRefresh(portals) {
|
|
17341
|
-
return portals.some((portal) => typeof portal.name !== "string" || portal.name.trim() === "");
|
|
17342
|
-
}
|
|
17343
|
-
async function refreshPortalsIfStale(creds, force = false) {
|
|
17344
|
-
if (!force && !cachedPortalsNeedNameRefresh(creds.portals) && creds.portalsLastFetchedAt && Date.now() - Date.parse(creds.portalsLastFetchedAt) < PORTALS_TTL_MS) {
|
|
17345
|
-
return creds;
|
|
17346
|
-
}
|
|
17347
|
-
if (isTokenExpired(creds.accessToken)) {
|
|
17348
|
-
return creds;
|
|
17349
|
-
}
|
|
17350
|
-
try {
|
|
17351
|
-
const res = await fetch(`${getApiUrl()}/auth/portals`, {
|
|
17352
|
-
headers: { Authorization: `Bearer ${creds.accessToken}` },
|
|
17353
|
-
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
17354
|
-
});
|
|
17355
|
-
if (!res.ok) {
|
|
17356
|
-
return creds;
|
|
17357
|
-
}
|
|
17358
|
-
const body = await res.json();
|
|
17359
|
-
const portals = parsePortals(body);
|
|
17360
|
-
if (portals) {
|
|
17361
|
-
const updated = {
|
|
17362
|
-
...creds,
|
|
17363
|
-
portals,
|
|
17364
|
-
portalsLastFetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
17365
|
-
};
|
|
17366
|
-
await writeCredentials(updated);
|
|
17367
|
-
return updated;
|
|
17368
|
-
}
|
|
17369
|
-
} catch {
|
|
17370
|
-
process.stderr.write("Warning: Could not refresh company list (using cached data).\n");
|
|
17371
|
-
}
|
|
17372
|
-
return creds;
|
|
17373
|
-
}
|
|
17374
|
-
async function markPortalsFetched(creds) {
|
|
17375
|
-
creds.portalsLastFetchedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
17376
|
-
await writeCredentials(creds);
|
|
17377
|
-
}
|
|
17378
|
-
async function refreshCachedPortalNames() {
|
|
17379
|
-
try {
|
|
17380
|
-
const creds = await readCredentials();
|
|
17381
|
-
if (!creds) return;
|
|
17382
|
-
const updated = await refreshPortalsIfStale(creds, true);
|
|
17383
|
-
const config2 = await readConfig();
|
|
17384
|
-
const activeId = config2.activePortal?.id;
|
|
17385
|
-
if (!activeId) return;
|
|
17386
|
-
const portal = updated.portals.find((candidate) => candidate.id === activeId);
|
|
17387
|
-
if (portal) await setActivePortal(portal);
|
|
17388
|
-
} catch {
|
|
17389
|
-
process.stderr.write(
|
|
17390
|
-
"Warning: Could not refresh company name after updating the company list.\n"
|
|
17391
|
-
);
|
|
17392
|
-
}
|
|
17393
|
-
}
|
|
17394
|
-
|
|
17395
|
-
// src/output.ts
|
|
17396
|
-
import { renameSync, rmSync, writeFileSync } from "fs";
|
|
17397
|
-
|
|
17398
17324
|
// src/exit-codes.ts
|
|
17399
17325
|
var EXIT = {
|
|
17400
17326
|
OK: 0,
|
|
@@ -17408,6 +17334,7 @@ var EXIT = {
|
|
|
17408
17334
|
};
|
|
17409
17335
|
|
|
17410
17336
|
// src/output.ts
|
|
17337
|
+
import { renameSync, rmSync, writeFileSync } from "fs";
|
|
17411
17338
|
function write(msg) {
|
|
17412
17339
|
process.stdout.write(`${msg}
|
|
17413
17340
|
`);
|
|
@@ -17513,111 +17440,6 @@ function exitWithUsage(message, usageLine, code = "USAGE") {
|
|
|
17513
17440
|
process.exit(EXIT.USAGE);
|
|
17514
17441
|
}
|
|
17515
17442
|
|
|
17516
|
-
// src/validate-flags.ts
|
|
17517
|
-
function restorePositional(args, value, originalIndex) {
|
|
17518
|
-
const insertAt = args.positionalIndexes.findIndex((index) => index > originalIndex);
|
|
17519
|
-
if (insertAt === -1) {
|
|
17520
|
-
args.positional.push(value);
|
|
17521
|
-
args.positionalIndexes.push(originalIndex);
|
|
17522
|
-
return;
|
|
17523
|
-
}
|
|
17524
|
-
args.positional.splice(insertAt, 0, value);
|
|
17525
|
-
args.positionalIndexes.splice(insertAt, 0, originalIndex);
|
|
17526
|
-
}
|
|
17527
|
-
function validateFlags(args, allowed) {
|
|
17528
|
-
const valueFlags = new Set(allowed.flags ?? []);
|
|
17529
|
-
const booleanFlags = new Set(allowed.booleans ?? []);
|
|
17530
|
-
const allAllowed = /* @__PURE__ */ new Set([...valueFlags, ...booleanFlags]);
|
|
17531
|
-
const allList = [...allAllowed].map((f) => `--${f}`).join(", ");
|
|
17532
|
-
for (const key of Object.keys(args.flags)) {
|
|
17533
|
-
if (!allAllowed.has(key)) {
|
|
17534
|
-
exitWithError(
|
|
17535
|
-
`Unknown flag: --${key}. Allowed flags: ${allList || "(none)"}`,
|
|
17536
|
-
"UNKNOWN_FLAG",
|
|
17537
|
-
void 0,
|
|
17538
|
-
EXIT.USAGE
|
|
17539
|
-
);
|
|
17540
|
-
}
|
|
17541
|
-
if (booleanFlags.has(key) && !valueFlags.has(key) && args.flagValueSources[key] === "next") {
|
|
17542
|
-
args.boolean.add(key);
|
|
17543
|
-
restorePositional(args, args.flags[key], args.flagValueIndexes[key]);
|
|
17544
|
-
delete args.flags[key];
|
|
17545
|
-
delete args.flagValueSources[key];
|
|
17546
|
-
delete args.flagValueIndexes[key];
|
|
17547
|
-
continue;
|
|
17548
|
-
}
|
|
17549
|
-
if (booleanFlags.has(key) && !valueFlags.has(key)) {
|
|
17550
|
-
exitWithError(
|
|
17551
|
-
`Flag --${key} does not take a value.`,
|
|
17552
|
-
"UNEXPECTED_FLAG_VALUE",
|
|
17553
|
-
void 0,
|
|
17554
|
-
EXIT.USAGE
|
|
17555
|
-
);
|
|
17556
|
-
}
|
|
17557
|
-
}
|
|
17558
|
-
for (const key of args.boolean) {
|
|
17559
|
-
if (valueFlags.has(key)) {
|
|
17560
|
-
exitWithError(`Flag --${key} requires a value.`, "MISSING_FLAG_VALUE", void 0, EXIT.USAGE);
|
|
17561
|
-
}
|
|
17562
|
-
if (!booleanFlags.has(key)) {
|
|
17563
|
-
exitWithError(
|
|
17564
|
-
`Unknown flag: --${key}. Allowed flags: ${allList || "(none)"}`,
|
|
17565
|
-
"UNKNOWN_FLAG",
|
|
17566
|
-
void 0,
|
|
17567
|
-
EXIT.USAGE
|
|
17568
|
-
);
|
|
17569
|
-
}
|
|
17570
|
-
}
|
|
17571
|
-
}
|
|
17572
|
-
|
|
17573
|
-
// src/commands/auth-status.ts
|
|
17574
|
-
async function runAuthStatus(args) {
|
|
17575
|
-
validateFlags(args, { flags: [], booleans: [] });
|
|
17576
|
-
let creds = await readCredentials();
|
|
17577
|
-
const config2 = await readConfig();
|
|
17578
|
-
if (creds) {
|
|
17579
|
-
creds = await refreshPortalsIfStale(creds);
|
|
17580
|
-
}
|
|
17581
|
-
if (!creds) {
|
|
17582
|
-
if (isJsonMode()) {
|
|
17583
|
-
printJson({ data: { authenticated: false } });
|
|
17584
|
-
} else {
|
|
17585
|
-
printLine("Not logged in. Run: captable-ai login");
|
|
17586
|
-
}
|
|
17587
|
-
return;
|
|
17588
|
-
}
|
|
17589
|
-
const expired = isTokenExpired(creds.accessToken);
|
|
17590
|
-
const payload = decodeJwtPayload(creds.accessToken);
|
|
17591
|
-
const expiresAt = typeof payload.exp === "number" ? new Date(payload.exp * 1e3).toISOString() : creds.expiresAt;
|
|
17592
|
-
const activeCompany = resolveActiveCompany(config2, creds.portals);
|
|
17593
|
-
const status = {
|
|
17594
|
-
authenticated: true,
|
|
17595
|
-
expired,
|
|
17596
|
-
user: creds.user,
|
|
17597
|
-
activeCompany,
|
|
17598
|
-
tokenExpiresAt: expiresAt,
|
|
17599
|
-
companyCount: creds.portals.length
|
|
17600
|
-
};
|
|
17601
|
-
if (isJsonMode()) {
|
|
17602
|
-
printJson({ data: status });
|
|
17603
|
-
return;
|
|
17604
|
-
}
|
|
17605
|
-
printLine(
|
|
17606
|
-
expired ? "Status: Expired (will auto-refresh on next command)" : "Status: Authenticated"
|
|
17607
|
-
);
|
|
17608
|
-
printLine();
|
|
17609
|
-
printKeyValue([
|
|
17610
|
-
["Email", creds.user.email],
|
|
17611
|
-
["User ID", creds.user.id],
|
|
17612
|
-
["Token expires", expiresAt],
|
|
17613
|
-
["Active company", activeCompany ? activeCompany.name ?? activeCompany.id : "(none)"],
|
|
17614
|
-
["Companies available", String(creds.portals.length)]
|
|
17615
|
-
]);
|
|
17616
|
-
}
|
|
17617
|
-
|
|
17618
|
-
// src/commands/export.ts
|
|
17619
|
-
import { renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
17620
|
-
|
|
17621
17443
|
// src/api.ts
|
|
17622
17444
|
function isRecord2(value) {
|
|
17623
17445
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -17634,7 +17456,7 @@ function coerceDetails(raw) {
|
|
|
17634
17456
|
}
|
|
17635
17457
|
return details.length > 0 ? details : void 0;
|
|
17636
17458
|
}
|
|
17637
|
-
var
|
|
17459
|
+
var REQUEST_TIMEOUT_MS = 3e4;
|
|
17638
17460
|
function exitForRefreshFailure(err, softFail = false) {
|
|
17639
17461
|
if (err instanceof Error && err.name === "AuthError") {
|
|
17640
17462
|
failRequest(
|
|
@@ -17694,7 +17516,7 @@ async function refreshTokens(creds) {
|
|
|
17694
17516
|
method: "POST",
|
|
17695
17517
|
headers: { "Content-Type": "application/json" },
|
|
17696
17518
|
body: JSON.stringify({ refreshToken: creds.refreshToken, clientType: "cli" }),
|
|
17697
|
-
signal: AbortSignal.timeout(
|
|
17519
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
17698
17520
|
});
|
|
17699
17521
|
} catch (fetchErr) {
|
|
17700
17522
|
const err = new Error(
|
|
@@ -17764,7 +17586,7 @@ async function apiRequest(path, opts = {}) {
|
|
|
17764
17586
|
const buildFetchOpts = () => ({
|
|
17765
17587
|
method,
|
|
17766
17588
|
headers: { ...headers },
|
|
17767
|
-
signal: AbortSignal.timeout(
|
|
17589
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
|
|
17768
17590
|
...body !== void 0 ? { body: JSON.stringify(body) } : {}
|
|
17769
17591
|
});
|
|
17770
17592
|
let res;
|
|
@@ -17893,6 +17715,182 @@ async function handleResponse(res, softFail = false) {
|
|
|
17893
17715
|
return parsed;
|
|
17894
17716
|
}
|
|
17895
17717
|
|
|
17718
|
+
// src/auth/refresh-portals.ts
|
|
17719
|
+
var PORTALS_TTL_MS = 3e5;
|
|
17720
|
+
var REQUEST_TIMEOUT_MS2 = 1e4;
|
|
17721
|
+
function isStoredPortal(v) {
|
|
17722
|
+
if (typeof v !== "object" || v === null) return false;
|
|
17723
|
+
const obj = v;
|
|
17724
|
+
return typeof obj.id === "string";
|
|
17725
|
+
}
|
|
17726
|
+
function parsePortals(body) {
|
|
17727
|
+
if (typeof body !== "object" || body === null) return null;
|
|
17728
|
+
if (!("portals" in body)) return null;
|
|
17729
|
+
const portals = body.portals;
|
|
17730
|
+
if (!Array.isArray(portals)) return null;
|
|
17731
|
+
if (!portals.every(isStoredPortal)) return null;
|
|
17732
|
+
return portals;
|
|
17733
|
+
}
|
|
17734
|
+
function cachedPortalsNeedNameRefresh(portals) {
|
|
17735
|
+
return portals.some((portal) => typeof portal.name !== "string" || portal.name.trim() === "");
|
|
17736
|
+
}
|
|
17737
|
+
async function refreshPortalsIfStale(creds, force = false) {
|
|
17738
|
+
if (!force && !cachedPortalsNeedNameRefresh(creds.portals) && creds.portalsLastFetchedAt && Date.now() - Date.parse(creds.portalsLastFetchedAt) < PORTALS_TTL_MS) {
|
|
17739
|
+
return creds;
|
|
17740
|
+
}
|
|
17741
|
+
if (isTokenExpired(creds.accessToken)) {
|
|
17742
|
+
return creds;
|
|
17743
|
+
}
|
|
17744
|
+
try {
|
|
17745
|
+
const res = await fetch(`${getApiUrl()}/auth/portals`, {
|
|
17746
|
+
headers: { Authorization: `Bearer ${creds.accessToken}` },
|
|
17747
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS2)
|
|
17748
|
+
});
|
|
17749
|
+
if (!res.ok) {
|
|
17750
|
+
return creds;
|
|
17751
|
+
}
|
|
17752
|
+
const body = await res.json();
|
|
17753
|
+
const portals = parsePortals(body);
|
|
17754
|
+
if (portals) {
|
|
17755
|
+
const updated = {
|
|
17756
|
+
...creds,
|
|
17757
|
+
portals,
|
|
17758
|
+
portalsLastFetchedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
17759
|
+
};
|
|
17760
|
+
await writeCredentials(updated);
|
|
17761
|
+
return updated;
|
|
17762
|
+
}
|
|
17763
|
+
} catch {
|
|
17764
|
+
process.stderr.write("Warning: Could not refresh company list (using cached data).\n");
|
|
17765
|
+
}
|
|
17766
|
+
return creds;
|
|
17767
|
+
}
|
|
17768
|
+
async function markPortalsFetched(creds) {
|
|
17769
|
+
creds.portalsLastFetchedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
17770
|
+
await writeCredentials(creds);
|
|
17771
|
+
}
|
|
17772
|
+
async function refreshCachedPortalNames() {
|
|
17773
|
+
try {
|
|
17774
|
+
const creds = await readCredentials();
|
|
17775
|
+
if (!creds) return;
|
|
17776
|
+
const updated = await refreshPortalsIfStale(creds, true);
|
|
17777
|
+
const config2 = await readConfig();
|
|
17778
|
+
const activeId = config2.activePortal?.id;
|
|
17779
|
+
if (!activeId) return;
|
|
17780
|
+
const portal = updated.portals.find((candidate) => candidate.id === activeId);
|
|
17781
|
+
if (portal) await setActivePortal(portal);
|
|
17782
|
+
} catch {
|
|
17783
|
+
process.stderr.write(
|
|
17784
|
+
"Warning: Could not refresh company name after updating the company list.\n"
|
|
17785
|
+
);
|
|
17786
|
+
}
|
|
17787
|
+
}
|
|
17788
|
+
|
|
17789
|
+
// src/validate-flags.ts
|
|
17790
|
+
function restorePositional(args, value, originalIndex) {
|
|
17791
|
+
const insertAt = args.positionalIndexes.findIndex((index) => index > originalIndex);
|
|
17792
|
+
if (insertAt === -1) {
|
|
17793
|
+
args.positional.push(value);
|
|
17794
|
+
args.positionalIndexes.push(originalIndex);
|
|
17795
|
+
return;
|
|
17796
|
+
}
|
|
17797
|
+
args.positional.splice(insertAt, 0, value);
|
|
17798
|
+
args.positionalIndexes.splice(insertAt, 0, originalIndex);
|
|
17799
|
+
}
|
|
17800
|
+
function validateFlags(args, allowed) {
|
|
17801
|
+
const valueFlags = new Set(allowed.flags ?? []);
|
|
17802
|
+
const booleanFlags = new Set(allowed.booleans ?? []);
|
|
17803
|
+
const allAllowed = /* @__PURE__ */ new Set([...valueFlags, ...booleanFlags]);
|
|
17804
|
+
const allList = [...allAllowed].map((f) => `--${f}`).join(", ");
|
|
17805
|
+
for (const key of Object.keys(args.flags)) {
|
|
17806
|
+
if (!allAllowed.has(key)) {
|
|
17807
|
+
exitWithError(
|
|
17808
|
+
`Unknown flag: --${key}. Allowed flags: ${allList || "(none)"}`,
|
|
17809
|
+
"UNKNOWN_FLAG",
|
|
17810
|
+
void 0,
|
|
17811
|
+
EXIT.USAGE
|
|
17812
|
+
);
|
|
17813
|
+
}
|
|
17814
|
+
if (booleanFlags.has(key) && !valueFlags.has(key) && args.flagValueSources[key] === "next") {
|
|
17815
|
+
args.boolean.add(key);
|
|
17816
|
+
restorePositional(args, args.flags[key], args.flagValueIndexes[key]);
|
|
17817
|
+
delete args.flags[key];
|
|
17818
|
+
delete args.flagValueSources[key];
|
|
17819
|
+
delete args.flagValueIndexes[key];
|
|
17820
|
+
continue;
|
|
17821
|
+
}
|
|
17822
|
+
if (booleanFlags.has(key) && !valueFlags.has(key)) {
|
|
17823
|
+
exitWithError(
|
|
17824
|
+
`Flag --${key} does not take a value.`,
|
|
17825
|
+
"UNEXPECTED_FLAG_VALUE",
|
|
17826
|
+
void 0,
|
|
17827
|
+
EXIT.USAGE
|
|
17828
|
+
);
|
|
17829
|
+
}
|
|
17830
|
+
}
|
|
17831
|
+
for (const key of args.boolean) {
|
|
17832
|
+
if (valueFlags.has(key)) {
|
|
17833
|
+
exitWithError(`Flag --${key} requires a value.`, "MISSING_FLAG_VALUE", void 0, EXIT.USAGE);
|
|
17834
|
+
}
|
|
17835
|
+
if (!booleanFlags.has(key)) {
|
|
17836
|
+
exitWithError(
|
|
17837
|
+
`Unknown flag: --${key}. Allowed flags: ${allList || "(none)"}`,
|
|
17838
|
+
"UNKNOWN_FLAG",
|
|
17839
|
+
void 0,
|
|
17840
|
+
EXIT.USAGE
|
|
17841
|
+
);
|
|
17842
|
+
}
|
|
17843
|
+
}
|
|
17844
|
+
}
|
|
17845
|
+
|
|
17846
|
+
// src/commands/auth-status.ts
|
|
17847
|
+
async function runAuthStatus(args) {
|
|
17848
|
+
validateFlags(args, { flags: [], booleans: [] });
|
|
17849
|
+
let creds = await readCredentials();
|
|
17850
|
+
const config2 = await readConfig();
|
|
17851
|
+
if (creds) {
|
|
17852
|
+
creds = await refreshPortalsIfStale(creds);
|
|
17853
|
+
}
|
|
17854
|
+
if (!creds) {
|
|
17855
|
+
if (isJsonMode()) {
|
|
17856
|
+
printJson({ data: { authenticated: false } });
|
|
17857
|
+
} else {
|
|
17858
|
+
printLine("Not logged in. Run: captable-ai login");
|
|
17859
|
+
}
|
|
17860
|
+
return;
|
|
17861
|
+
}
|
|
17862
|
+
const expired = isTokenExpired(creds.accessToken);
|
|
17863
|
+
const payload = decodeJwtPayload(creds.accessToken);
|
|
17864
|
+
const expiresAt = typeof payload.exp === "number" ? new Date(payload.exp * 1e3).toISOString() : creds.expiresAt;
|
|
17865
|
+
const activeCompany = resolveActiveCompany(config2, creds.portals);
|
|
17866
|
+
const status = {
|
|
17867
|
+
authenticated: true,
|
|
17868
|
+
expired,
|
|
17869
|
+
user: creds.user,
|
|
17870
|
+
activeCompany,
|
|
17871
|
+
tokenExpiresAt: expiresAt,
|
|
17872
|
+
companyCount: creds.portals.length
|
|
17873
|
+
};
|
|
17874
|
+
if (isJsonMode()) {
|
|
17875
|
+
printJson({ data: status });
|
|
17876
|
+
return;
|
|
17877
|
+
}
|
|
17878
|
+
printLine(
|
|
17879
|
+
expired ? "Status: Expired (will auto-refresh on next command)" : "Status: Authenticated"
|
|
17880
|
+
);
|
|
17881
|
+
printLine();
|
|
17882
|
+
printKeyValue([
|
|
17883
|
+
["Email", creds.user.email],
|
|
17884
|
+
["User ID", creds.user.id],
|
|
17885
|
+
["Token expires", expiresAt],
|
|
17886
|
+
["Active company", activeCompany ? activeCompany.name ?? activeCompany.id : "(none)"],
|
|
17887
|
+
["Companies available", String(creds.portals.length)]
|
|
17888
|
+
]);
|
|
17889
|
+
}
|
|
17890
|
+
|
|
17891
|
+
// src/commands/export.ts
|
|
17892
|
+
import { renameSync as renameSync2, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
17893
|
+
|
|
17896
17894
|
// src/flags.ts
|
|
17897
17895
|
function looksLikeFlag(value) {
|
|
17898
17896
|
if (!value.startsWith("-")) return false;
|
|
@@ -20924,6 +20922,20 @@ async function hashFile(path) {
|
|
|
20924
20922
|
const data = await readFile4(path);
|
|
20925
20923
|
return createHash2("sha256").update(data).digest("hex");
|
|
20926
20924
|
}
|
|
20925
|
+
async function openImportSession(portalId) {
|
|
20926
|
+
try {
|
|
20927
|
+
const res = await apiRequest("/import-sessions", {
|
|
20928
|
+
method: "POST",
|
|
20929
|
+
body: { portalId },
|
|
20930
|
+
// Optional: a failure must throw to the catch below, not exit the process.
|
|
20931
|
+
softFail: true
|
|
20932
|
+
});
|
|
20933
|
+
const id = res.data?.session?.id;
|
|
20934
|
+
return typeof id === "string" ? id : null;
|
|
20935
|
+
} catch {
|
|
20936
|
+
return null;
|
|
20937
|
+
}
|
|
20938
|
+
}
|
|
20927
20939
|
async function runDocumentsUpload(args, rawArgv) {
|
|
20928
20940
|
if (rawArgv.includes("--help") || rawArgv.includes("-h")) {
|
|
20929
20941
|
process.stdout.write(
|
|
@@ -20953,11 +20965,15 @@ async function runDocumentsUpload(args, rawArgv) {
|
|
|
20953
20965
|
});
|
|
20954
20966
|
}
|
|
20955
20967
|
if (!isJsonMode()) printLine(`Preparing ${files.length} file(s)...`);
|
|
20968
|
+
const importSessionId = await openImportSession(portalId);
|
|
20956
20969
|
const prepareRes = await apiRequest(
|
|
20957
20970
|
`/${portalId}/documents/prepare`,
|
|
20958
20971
|
{
|
|
20959
20972
|
method: "POST",
|
|
20960
|
-
body: {
|
|
20973
|
+
body: {
|
|
20974
|
+
files: files.map(({ path: _, ...f }) => f),
|
|
20975
|
+
...importSessionId === null ? {} : { importSessionId }
|
|
20976
|
+
}
|
|
20961
20977
|
}
|
|
20962
20978
|
);
|
|
20963
20979
|
const documents = prepareRes.data?.documents ?? [];
|
|
@@ -24504,6 +24520,9 @@ function exitForThrownError(err) {
|
|
|
24504
24520
|
if (err instanceof AuthRequiredError) {
|
|
24505
24521
|
exitWithError(err.message, "AUTH_REQUIRED", void 0, EXIT.AUTH);
|
|
24506
24522
|
}
|
|
24523
|
+
if (err instanceof ApiRequestError) {
|
|
24524
|
+
exitWithError(err.message, err.code ?? "ERROR", err.details, EXIT.SERVER_ERROR);
|
|
24525
|
+
}
|
|
24507
24526
|
exitWithError(err.message, "ERROR", void 0, EXIT.SERVER_ERROR);
|
|
24508
24527
|
}
|
|
24509
24528
|
async function main() {
|
package/package.json
CHANGED