@stripe/link-cli 0.8.2 → 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/README.md +13 -0
- package/dist/cli.js +1940 -770
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -8835,19 +8835,19 @@ var require_range = __commonJS({
|
|
|
8835
8835
|
var replaceCaret = (comp, options) => {
|
|
8836
8836
|
debug("caret", comp, options);
|
|
8837
8837
|
const r = options.loose ? re[t.CARETLOOSE] : re[t.CARET];
|
|
8838
|
-
const
|
|
8838
|
+
const z13 = options.includePrerelease ? "-0" : "";
|
|
8839
8839
|
return comp.replace(r, (_, M, m, p, pr) => {
|
|
8840
8840
|
debug("caret", comp, _, M, m, p, pr);
|
|
8841
8841
|
let ret;
|
|
8842
8842
|
if (isX(M)) {
|
|
8843
8843
|
ret = "";
|
|
8844
8844
|
} else if (isX(m)) {
|
|
8845
|
-
ret = `>=${M}.0.0${
|
|
8845
|
+
ret = `>=${M}.0.0${z13} <${+M + 1}.0.0-0`;
|
|
8846
8846
|
} else if (isX(p)) {
|
|
8847
8847
|
if (M === "0") {
|
|
8848
|
-
ret = `>=${M}.${m}.0${
|
|
8848
|
+
ret = `>=${M}.${m}.0${z13} <${M}.${+m + 1}.0-0`;
|
|
8849
8849
|
} else {
|
|
8850
|
-
ret = `>=${M}.${m}.0${
|
|
8850
|
+
ret = `>=${M}.${m}.0${z13} <${+M + 1}.0.0-0`;
|
|
8851
8851
|
}
|
|
8852
8852
|
} else if (pr) {
|
|
8853
8853
|
debug("replaceCaret pr", pr);
|
|
@@ -8864,9 +8864,9 @@ var require_range = __commonJS({
|
|
|
8864
8864
|
debug("no pr");
|
|
8865
8865
|
if (M === "0") {
|
|
8866
8866
|
if (m === "0") {
|
|
8867
|
-
ret = `>=${M}.${m}.${p}${
|
|
8867
|
+
ret = `>=${M}.${m}.${p}${z13} <${M}.${m}.${+p + 1}-0`;
|
|
8868
8868
|
} else {
|
|
8869
|
-
ret = `>=${M}.${m}.${p}${
|
|
8869
|
+
ret = `>=${M}.${m}.${p}${z13} <${M}.${+m + 1}.0-0`;
|
|
8870
8870
|
}
|
|
8871
8871
|
} else {
|
|
8872
8872
|
ret = `>=${M}.${m}.${p} <${+M + 1}.0.0-0`;
|
|
@@ -11148,6 +11148,173 @@ function requireFetchImplementation(config) {
|
|
|
11148
11148
|
}
|
|
11149
11149
|
return config.fetch;
|
|
11150
11150
|
}
|
|
11151
|
+
function isRecord(value) {
|
|
11152
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
11153
|
+
}
|
|
11154
|
+
function requireBoolean(value, field) {
|
|
11155
|
+
if (typeof value !== "boolean") {
|
|
11156
|
+
throw new TypeError(`Expected ${field} to be a boolean`);
|
|
11157
|
+
}
|
|
11158
|
+
return value;
|
|
11159
|
+
}
|
|
11160
|
+
function extractErrorMessage(data, rawBody) {
|
|
11161
|
+
if (isRecord(data)) {
|
|
11162
|
+
if (typeof data.error === "string") {
|
|
11163
|
+
return data.error;
|
|
11164
|
+
}
|
|
11165
|
+
if (isRecord(data.error)) {
|
|
11166
|
+
const nested = data.error;
|
|
11167
|
+
if (typeof nested.message === "string") {
|
|
11168
|
+
return nested.message;
|
|
11169
|
+
}
|
|
11170
|
+
if (typeof nested.code === "string") {
|
|
11171
|
+
return nested.code;
|
|
11172
|
+
}
|
|
11173
|
+
}
|
|
11174
|
+
if (typeof data.message === "string") {
|
|
11175
|
+
return data.message;
|
|
11176
|
+
}
|
|
11177
|
+
}
|
|
11178
|
+
return rawBody || "unknown error";
|
|
11179
|
+
}
|
|
11180
|
+
var BaseResource = class {
|
|
11181
|
+
verbose;
|
|
11182
|
+
getAccessToken;
|
|
11183
|
+
fetchImpl;
|
|
11184
|
+
endpoint;
|
|
11185
|
+
logger;
|
|
11186
|
+
constructor(options, endpointPath) {
|
|
11187
|
+
const config = resolveLinkSdkConfig(options);
|
|
11188
|
+
this.verbose = config.verbose;
|
|
11189
|
+
this.getAccessToken = config.getAccessToken;
|
|
11190
|
+
this.fetchImpl = requireFetchImplementation(config);
|
|
11191
|
+
this.endpoint = `${config.apiBaseUrl}${endpointPath}`;
|
|
11192
|
+
this.logger = config.logger;
|
|
11193
|
+
}
|
|
11194
|
+
async rawFetch(opts) {
|
|
11195
|
+
if (this.verbose) {
|
|
11196
|
+
const redactedHeaders = { ...opts.headers };
|
|
11197
|
+
if (redactedHeaders.Authorization)
|
|
11198
|
+
redactedHeaders.Authorization = "Bearer <redacted>";
|
|
11199
|
+
this.logger.debug(`> ${opts.method} ${opts.url}`);
|
|
11200
|
+
this.logger.debug(` Headers: ${JSON.stringify(redactedHeaders)}`);
|
|
11201
|
+
}
|
|
11202
|
+
let response;
|
|
11203
|
+
try {
|
|
11204
|
+
response = await this.fetchImpl(opts.url, {
|
|
11205
|
+
method: opts.method,
|
|
11206
|
+
headers: opts.headers
|
|
11207
|
+
});
|
|
11208
|
+
} catch (error) {
|
|
11209
|
+
throw new LinkTransportError(
|
|
11210
|
+
`Request failed: ${opts.method} ${opts.url}`,
|
|
11211
|
+
{ cause: error }
|
|
11212
|
+
);
|
|
11213
|
+
}
|
|
11214
|
+
const rawBody = await response.text();
|
|
11215
|
+
let data = null;
|
|
11216
|
+
try {
|
|
11217
|
+
data = JSON.parse(rawBody);
|
|
11218
|
+
} catch {
|
|
11219
|
+
}
|
|
11220
|
+
if (this.verbose) {
|
|
11221
|
+
this.logger.debug(`< ${response.status} ${response.statusText}`);
|
|
11222
|
+
response.headers.forEach((value, key) => {
|
|
11223
|
+
this.logger.debug(` ${key}: ${value}`);
|
|
11224
|
+
});
|
|
11225
|
+
this.logger.debug(rawBody);
|
|
11226
|
+
}
|
|
11227
|
+
return { status: response.status, data, rawBody };
|
|
11228
|
+
}
|
|
11229
|
+
async apiFetch(opts) {
|
|
11230
|
+
const token = await this.getAccessToken();
|
|
11231
|
+
const authedOpts = {
|
|
11232
|
+
...opts,
|
|
11233
|
+
headers: {
|
|
11234
|
+
...opts.headers,
|
|
11235
|
+
Authorization: `Bearer ${token}`
|
|
11236
|
+
}
|
|
11237
|
+
};
|
|
11238
|
+
const res = await this.rawFetch(authedOpts);
|
|
11239
|
+
if (res.status === 401) {
|
|
11240
|
+
const refreshedToken = await this.getAccessToken({ forceRefresh: true });
|
|
11241
|
+
authedOpts.headers.Authorization = `Bearer ${refreshedToken}`;
|
|
11242
|
+
return this.rawFetch(authedOpts);
|
|
11243
|
+
}
|
|
11244
|
+
return res;
|
|
11245
|
+
}
|
|
11246
|
+
throwApiError(operation, status, data, rawBody, cause) {
|
|
11247
|
+
const msg = extractErrorMessage(data, rawBody);
|
|
11248
|
+
throw new LinkApiError(`Failed to ${operation} (${status}): ${msg}`, {
|
|
11249
|
+
status,
|
|
11250
|
+
rawBody,
|
|
11251
|
+
details: data,
|
|
11252
|
+
cause
|
|
11253
|
+
});
|
|
11254
|
+
}
|
|
11255
|
+
};
|
|
11256
|
+
function normalizeBalances(value) {
|
|
11257
|
+
if (!Array.isArray(value)) {
|
|
11258
|
+
throw new TypeError("Expected balances to be an array");
|
|
11259
|
+
}
|
|
11260
|
+
return value.map((item, index) => {
|
|
11261
|
+
if (!isRecord(item)) {
|
|
11262
|
+
throw new TypeError(`Expected balances[${index}] to be an object`);
|
|
11263
|
+
}
|
|
11264
|
+
return item;
|
|
11265
|
+
});
|
|
11266
|
+
}
|
|
11267
|
+
function normalizeBalancesPage(value) {
|
|
11268
|
+
if (!isRecord(value)) {
|
|
11269
|
+
throw new TypeError("Expected response body to be an object");
|
|
11270
|
+
}
|
|
11271
|
+
const { data, has_more, ...rest } = value;
|
|
11272
|
+
const normalized = normalizeBalances(data);
|
|
11273
|
+
return {
|
|
11274
|
+
...rest,
|
|
11275
|
+
data: normalized,
|
|
11276
|
+
...has_more !== void 0 ? { has_more: requireBoolean(has_more, "has_more") } : {}
|
|
11277
|
+
};
|
|
11278
|
+
}
|
|
11279
|
+
var BalancesResource = class extends BaseResource {
|
|
11280
|
+
constructor(options = {}) {
|
|
11281
|
+
super(options, "/balances");
|
|
11282
|
+
}
|
|
11283
|
+
buildUrl(params) {
|
|
11284
|
+
const url = new URL(this.endpoint);
|
|
11285
|
+
if (params.limit !== void 0) {
|
|
11286
|
+
url.searchParams.set("limit", String(params.limit));
|
|
11287
|
+
}
|
|
11288
|
+
if (params.starting_after !== void 0) {
|
|
11289
|
+
url.searchParams.set("starting_after", params.starting_after);
|
|
11290
|
+
}
|
|
11291
|
+
if (params.ending_before !== void 0) {
|
|
11292
|
+
url.searchParams.set("ending_before", params.ending_before);
|
|
11293
|
+
}
|
|
11294
|
+
return url.toString();
|
|
11295
|
+
}
|
|
11296
|
+
list(params = {}) {
|
|
11297
|
+
return this.listBalances(params);
|
|
11298
|
+
}
|
|
11299
|
+
async listBalances(params = {}) {
|
|
11300
|
+
const { status, data, rawBody } = await this.apiFetch({
|
|
11301
|
+
method: "GET",
|
|
11302
|
+
url: this.buildUrl(params)
|
|
11303
|
+
});
|
|
11304
|
+
if (status < 200 || status >= 300) {
|
|
11305
|
+
this.throwApiError("list balances", status, data, rawBody);
|
|
11306
|
+
}
|
|
11307
|
+
try {
|
|
11308
|
+
return normalizeBalancesPage(data);
|
|
11309
|
+
} catch (error) {
|
|
11310
|
+
const reason = error instanceof Error ? `: ${error.message}` : "";
|
|
11311
|
+
throw new LinkApiError(
|
|
11312
|
+
`Failed to list balances (${status}): invalid response shape${reason}`,
|
|
11313
|
+
{ status, rawBody, details: data, cause: error }
|
|
11314
|
+
);
|
|
11315
|
+
}
|
|
11316
|
+
}
|
|
11317
|
+
};
|
|
11151
11318
|
var PaymentMethodsResource = class {
|
|
11152
11319
|
verbose;
|
|
11153
11320
|
getAccessToken;
|
|
@@ -11318,6 +11485,68 @@ var ShippingAddressResource = class {
|
|
|
11318
11485
|
return body?.shipping_addresses ?? [];
|
|
11319
11486
|
}
|
|
11320
11487
|
};
|
|
11488
|
+
function normalizeSources(value) {
|
|
11489
|
+
if (!Array.isArray(value)) {
|
|
11490
|
+
throw new TypeError("Expected sources to be an array");
|
|
11491
|
+
}
|
|
11492
|
+
return value.map((item, index) => {
|
|
11493
|
+
if (!isRecord(item)) {
|
|
11494
|
+
throw new TypeError(`Expected sources[${index}] to be an object`);
|
|
11495
|
+
}
|
|
11496
|
+
return item;
|
|
11497
|
+
});
|
|
11498
|
+
}
|
|
11499
|
+
function normalizeSourcesPage(value) {
|
|
11500
|
+
if (!isRecord(value)) {
|
|
11501
|
+
throw new TypeError("Expected response body to be an object");
|
|
11502
|
+
}
|
|
11503
|
+
const { data, has_more, ...rest } = value;
|
|
11504
|
+
const normalized = normalizeSources(data);
|
|
11505
|
+
return {
|
|
11506
|
+
...rest,
|
|
11507
|
+
data: normalized,
|
|
11508
|
+
...has_more !== void 0 ? { has_more: requireBoolean(has_more, "has_more") } : {}
|
|
11509
|
+
};
|
|
11510
|
+
}
|
|
11511
|
+
var SourcesResource = class extends BaseResource {
|
|
11512
|
+
constructor(options = {}) {
|
|
11513
|
+
super(options, "/sources");
|
|
11514
|
+
}
|
|
11515
|
+
buildUrl(params) {
|
|
11516
|
+
const url = new URL(this.endpoint);
|
|
11517
|
+
if (params.limit !== void 0) {
|
|
11518
|
+
url.searchParams.set("limit", String(params.limit));
|
|
11519
|
+
}
|
|
11520
|
+
if (params.starting_after !== void 0) {
|
|
11521
|
+
url.searchParams.set("starting_after", params.starting_after);
|
|
11522
|
+
}
|
|
11523
|
+
if (params.ending_before !== void 0) {
|
|
11524
|
+
url.searchParams.set("ending_before", params.ending_before);
|
|
11525
|
+
}
|
|
11526
|
+
return url.toString();
|
|
11527
|
+
}
|
|
11528
|
+
list(params = {}) {
|
|
11529
|
+
return this.listSources(params);
|
|
11530
|
+
}
|
|
11531
|
+
async listSources(params = {}) {
|
|
11532
|
+
const { status, data, rawBody } = await this.apiFetch({
|
|
11533
|
+
method: "GET",
|
|
11534
|
+
url: this.buildUrl(params)
|
|
11535
|
+
});
|
|
11536
|
+
if (status < 200 || status >= 300) {
|
|
11537
|
+
this.throwApiError("list sources", status, data, rawBody);
|
|
11538
|
+
}
|
|
11539
|
+
try {
|
|
11540
|
+
return normalizeSourcesPage(data);
|
|
11541
|
+
} catch (error) {
|
|
11542
|
+
const reason = error instanceof Error ? `: ${error.message}` : "";
|
|
11543
|
+
throw new LinkApiError(
|
|
11544
|
+
`Failed to list sources (${status}): invalid response shape${reason}`,
|
|
11545
|
+
{ status, rawBody, details: data, cause: error }
|
|
11546
|
+
);
|
|
11547
|
+
}
|
|
11548
|
+
}
|
|
11549
|
+
};
|
|
11321
11550
|
function normalizeSpendRequest(data) {
|
|
11322
11551
|
const sr = data;
|
|
11323
11552
|
if (typeof sr.shared_payment_token === "string") {
|
|
@@ -11524,6 +11753,140 @@ var SpendRequestResource = class {
|
|
|
11524
11753
|
return normalizeSpendRequest(data);
|
|
11525
11754
|
}
|
|
11526
11755
|
};
|
|
11756
|
+
function requireString(value, field) {
|
|
11757
|
+
if (typeof value !== "string") {
|
|
11758
|
+
throw new TypeError(`Expected ${field} to be a string`);
|
|
11759
|
+
}
|
|
11760
|
+
return value;
|
|
11761
|
+
}
|
|
11762
|
+
function requireNullableString(value, field) {
|
|
11763
|
+
if (value === null) {
|
|
11764
|
+
return null;
|
|
11765
|
+
}
|
|
11766
|
+
if (typeof value !== "string") {
|
|
11767
|
+
throw new TypeError(`Expected ${field} to be a string or null`);
|
|
11768
|
+
}
|
|
11769
|
+
return value;
|
|
11770
|
+
}
|
|
11771
|
+
function requireNumber(value, field) {
|
|
11772
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
11773
|
+
throw new TypeError(`Expected ${field} to be a finite number`);
|
|
11774
|
+
}
|
|
11775
|
+
return value;
|
|
11776
|
+
}
|
|
11777
|
+
function requireTransactionOrigin(value, field) {
|
|
11778
|
+
if (value === "link" || value === "external_connection") {
|
|
11779
|
+
return value;
|
|
11780
|
+
}
|
|
11781
|
+
throw new TypeError(`Expected ${field} to be a transaction origin`);
|
|
11782
|
+
}
|
|
11783
|
+
function normalizeTransactions(value) {
|
|
11784
|
+
if (!Array.isArray(value)) {
|
|
11785
|
+
throw new TypeError("Expected transactions to be an array");
|
|
11786
|
+
}
|
|
11787
|
+
return value.map((item, index) => {
|
|
11788
|
+
if (!isRecord(item)) {
|
|
11789
|
+
throw new TypeError(`Expected transactions[${index}] to be an object`);
|
|
11790
|
+
}
|
|
11791
|
+
return {
|
|
11792
|
+
id: requireString(item.id, `transactions[${index}].id`),
|
|
11793
|
+
source_id: requireNullableString(
|
|
11794
|
+
item.source_id,
|
|
11795
|
+
`transactions[${index}].source_id`
|
|
11796
|
+
),
|
|
11797
|
+
amount: requireNumber(item.amount, `transactions[${index}].amount`),
|
|
11798
|
+
currency: requireString(item.currency, `transactions[${index}].currency`),
|
|
11799
|
+
created_date: requireString(
|
|
11800
|
+
item.created_date,
|
|
11801
|
+
`transactions[${index}].created_date`
|
|
11802
|
+
),
|
|
11803
|
+
description: requireString(
|
|
11804
|
+
item.description,
|
|
11805
|
+
`transactions[${index}].description`
|
|
11806
|
+
),
|
|
11807
|
+
origin: requireTransactionOrigin(
|
|
11808
|
+
item.origin,
|
|
11809
|
+
`transactions[${index}].origin`
|
|
11810
|
+
),
|
|
11811
|
+
category: requireNullableString(
|
|
11812
|
+
item.category,
|
|
11813
|
+
`transactions[${index}].category`
|
|
11814
|
+
),
|
|
11815
|
+
status: requireString(item.status, `transactions[${index}].status`)
|
|
11816
|
+
};
|
|
11817
|
+
});
|
|
11818
|
+
}
|
|
11819
|
+
function normalizeTransactionsPage(value) {
|
|
11820
|
+
if (Array.isArray(value)) {
|
|
11821
|
+
return { data: normalizeTransactions(value) };
|
|
11822
|
+
}
|
|
11823
|
+
if (!isRecord(value)) {
|
|
11824
|
+
throw new TypeError("Expected response body to be an object");
|
|
11825
|
+
}
|
|
11826
|
+
const { data, has_more, ...rest } = value;
|
|
11827
|
+
const normalized = normalizeTransactions(data);
|
|
11828
|
+
return {
|
|
11829
|
+
...rest,
|
|
11830
|
+
data: normalized,
|
|
11831
|
+
...has_more !== void 0 ? { has_more: requireBoolean(has_more, "has_more") } : {}
|
|
11832
|
+
};
|
|
11833
|
+
}
|
|
11834
|
+
var TransactionsResource = class extends BaseResource {
|
|
11835
|
+
constructor(options = {}) {
|
|
11836
|
+
super(options, "/transactions");
|
|
11837
|
+
}
|
|
11838
|
+
buildUrl(params) {
|
|
11839
|
+
const url = new URL(this.endpoint);
|
|
11840
|
+
if (params.limit !== void 0) {
|
|
11841
|
+
url.searchParams.set("limit", String(params.limit));
|
|
11842
|
+
}
|
|
11843
|
+
if (params.starting_after !== void 0) {
|
|
11844
|
+
url.searchParams.set("starting_after", params.starting_after);
|
|
11845
|
+
}
|
|
11846
|
+
if (params.ending_before !== void 0) {
|
|
11847
|
+
url.searchParams.set("ending_before", params.ending_before);
|
|
11848
|
+
}
|
|
11849
|
+
if (params.start_date !== void 0) {
|
|
11850
|
+
url.searchParams.set("date_start", params.start_date);
|
|
11851
|
+
}
|
|
11852
|
+
if (params.end_date !== void 0) {
|
|
11853
|
+
url.searchParams.set("date_end", params.end_date);
|
|
11854
|
+
}
|
|
11855
|
+
if (params.category !== void 0) {
|
|
11856
|
+
url.searchParams.set("category", params.category);
|
|
11857
|
+
}
|
|
11858
|
+
if (params.origin !== void 0) {
|
|
11859
|
+
url.searchParams.set("origin", params.origin);
|
|
11860
|
+
}
|
|
11861
|
+
if (params.sources !== void 0) {
|
|
11862
|
+
for (const source of params.sources) {
|
|
11863
|
+
url.searchParams.append("sources[]", source);
|
|
11864
|
+
}
|
|
11865
|
+
}
|
|
11866
|
+
return url.toString();
|
|
11867
|
+
}
|
|
11868
|
+
list(params = {}) {
|
|
11869
|
+
return this.listTransactions(params);
|
|
11870
|
+
}
|
|
11871
|
+
async listTransactions(params = {}) {
|
|
11872
|
+
const { status, data, rawBody } = await this.apiFetch({
|
|
11873
|
+
method: "GET",
|
|
11874
|
+
url: this.buildUrl(params)
|
|
11875
|
+
});
|
|
11876
|
+
if (status < 200 || status >= 300) {
|
|
11877
|
+
this.throwApiError("list transactions", status, data, rawBody);
|
|
11878
|
+
}
|
|
11879
|
+
try {
|
|
11880
|
+
return normalizeTransactionsPage(data);
|
|
11881
|
+
} catch (error) {
|
|
11882
|
+
const reason = error instanceof Error ? `: ${error.message}` : "";
|
|
11883
|
+
throw new LinkApiError(
|
|
11884
|
+
`Failed to list transactions (${status}): invalid response shape${reason}`,
|
|
11885
|
+
{ status, rawBody, details: data, cause: error }
|
|
11886
|
+
);
|
|
11887
|
+
}
|
|
11888
|
+
}
|
|
11889
|
+
};
|
|
11527
11890
|
var UserInfoResource = class {
|
|
11528
11891
|
verbose;
|
|
11529
11892
|
getAccessToken;
|
|
@@ -11616,6 +11979,12 @@ var UserInfoResource = class {
|
|
|
11616
11979
|
};
|
|
11617
11980
|
}
|
|
11618
11981
|
};
|
|
11982
|
+
var SOURCE_ACTIONS = [
|
|
11983
|
+
"read_balances",
|
|
11984
|
+
"read_external_transactions",
|
|
11985
|
+
"read_link_transactions",
|
|
11986
|
+
"read_source_details"
|
|
11987
|
+
];
|
|
11619
11988
|
var REPORT_OUTCOMES = ["success", "blocked", "abandoned"];
|
|
11620
11989
|
var REPORT_TAGS = [
|
|
11621
11990
|
"stripe_checkout",
|
|
@@ -11843,12 +12212,69 @@ var ReportResource = class {
|
|
|
11843
12212
|
};
|
|
11844
12213
|
|
|
11845
12214
|
// src/cli.tsx
|
|
11846
|
-
import { Cli as
|
|
12215
|
+
import { Cli as Cli14 } from "incur";
|
|
11847
12216
|
|
|
11848
12217
|
// src/commands/auth/index.tsx
|
|
11849
12218
|
import { Cli } from "incur";
|
|
11850
12219
|
import { Text as Text4 } from "ink";
|
|
11851
12220
|
|
|
12221
|
+
// src/auth/authorization-details.ts
|
|
12222
|
+
var INVALID_AUTHORIZATION_DETAIL_MESSAGE = "authorization-detail must be valid JSON";
|
|
12223
|
+
function dedupe(values) {
|
|
12224
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12225
|
+
const result = [];
|
|
12226
|
+
for (const value of values) {
|
|
12227
|
+
if (seen.has(value)) {
|
|
12228
|
+
continue;
|
|
12229
|
+
}
|
|
12230
|
+
seen.add(value);
|
|
12231
|
+
result.push(value);
|
|
12232
|
+
}
|
|
12233
|
+
return result;
|
|
12234
|
+
}
|
|
12235
|
+
function parseAuthorizationDetails(entries) {
|
|
12236
|
+
const parsed = [];
|
|
12237
|
+
for (const entry of entries ?? []) {
|
|
12238
|
+
try {
|
|
12239
|
+
parsed.push(JSON.parse(entry));
|
|
12240
|
+
} catch {
|
|
12241
|
+
throw new Error(INVALID_AUTHORIZATION_DETAIL_MESSAGE);
|
|
12242
|
+
}
|
|
12243
|
+
}
|
|
12244
|
+
return parsed;
|
|
12245
|
+
}
|
|
12246
|
+
function buildAuthorizationDetails(sourceActions, authorizationDetails) {
|
|
12247
|
+
const details = [];
|
|
12248
|
+
const uniqueSourceActions = dedupe(sourceActions ?? []);
|
|
12249
|
+
if (uniqueSourceActions.length > 0) {
|
|
12250
|
+
details.push({
|
|
12251
|
+
type: "source",
|
|
12252
|
+
actions: uniqueSourceActions
|
|
12253
|
+
});
|
|
12254
|
+
}
|
|
12255
|
+
if (authorizationDetails) {
|
|
12256
|
+
details.push(...authorizationDetails);
|
|
12257
|
+
}
|
|
12258
|
+
return details;
|
|
12259
|
+
}
|
|
12260
|
+
|
|
12261
|
+
// src/auth/scopes.ts
|
|
12262
|
+
var DEFAULT_SCOPES = [
|
|
12263
|
+
"userinfo:read",
|
|
12264
|
+
"payment_methods.agentic"
|
|
12265
|
+
];
|
|
12266
|
+
var DEFAULT_SCOPE = DEFAULT_SCOPES.join(" ");
|
|
12267
|
+
function parseScopeTokens(scope) {
|
|
12268
|
+
return scope.trim().split(/\s+/).filter(Boolean);
|
|
12269
|
+
}
|
|
12270
|
+
function normalizeScopeInput(scope) {
|
|
12271
|
+
if (scope === void 0) {
|
|
12272
|
+
return void 0;
|
|
12273
|
+
}
|
|
12274
|
+
const normalized = parseScopeTokens(scope);
|
|
12275
|
+
return normalized.length > 0 ? normalized.join(" ") : void 0;
|
|
12276
|
+
}
|
|
12277
|
+
|
|
11852
12278
|
// src/utils/poll-until.ts
|
|
11853
12279
|
async function* pollUntil(options) {
|
|
11854
12280
|
const { fn, isTerminal, interval, timeout, maxAttempts } = options;
|
|
@@ -11965,6 +12391,9 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
11965
12391
|
var Login = ({
|
|
11966
12392
|
authResource,
|
|
11967
12393
|
clientName,
|
|
12394
|
+
scope,
|
|
12395
|
+
sourceActions,
|
|
12396
|
+
authorizationDetails,
|
|
11968
12397
|
authStorage: authStorage2 = storage,
|
|
11969
12398
|
onComplete
|
|
11970
12399
|
}) => {
|
|
@@ -11985,7 +12414,12 @@ var Login = ({
|
|
|
11985
12414
|
useEffect(() => {
|
|
11986
12415
|
const initAuth = async () => {
|
|
11987
12416
|
try {
|
|
11988
|
-
const authRequest = await authResource.initiateDeviceAuth(
|
|
12417
|
+
const authRequest = await authResource.initiateDeviceAuth({
|
|
12418
|
+
clientName,
|
|
12419
|
+
scope,
|
|
12420
|
+
sourceActions,
|
|
12421
|
+
authorizationDetails
|
|
12422
|
+
});
|
|
11989
12423
|
setUserCode(authRequest.user_code);
|
|
11990
12424
|
setVerificationUrl(authRequest.verification_url_complete);
|
|
11991
12425
|
setDeviceCode(authRequest.device_code);
|
|
@@ -11996,7 +12430,7 @@ var Login = ({
|
|
|
11996
12430
|
}
|
|
11997
12431
|
};
|
|
11998
12432
|
initAuth();
|
|
11999
|
-
}, [authResource, clientName]);
|
|
12433
|
+
}, [authResource, authorizationDetails, clientName, scope, sourceActions]);
|
|
12000
12434
|
useEffect(() => {
|
|
12001
12435
|
if (status !== "waiting" || !deviceCode) return;
|
|
12002
12436
|
const startPolling = async () => {
|
|
@@ -12035,17 +12469,17 @@ var Login = ({
|
|
|
12035
12469
|
if (status === "declined") {
|
|
12036
12470
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
12037
12471
|
/* @__PURE__ */ jsx(Text, { color: "red", children: "\u2717 Authorization failed" }),
|
|
12038
|
-
Object.entries(scopeEligibility).map(([
|
|
12472
|
+
Object.entries(scopeEligibility).map(([scope2, info]) => /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [
|
|
12039
12473
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
12040
12474
|
/* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
12041
|
-
|
|
12475
|
+
scope2,
|
|
12042
12476
|
":"
|
|
12043
12477
|
] }),
|
|
12044
12478
|
" ineligible",
|
|
12045
12479
|
info.ineligibility_reasons.length > 0 ? ` (${info.ineligibility_reasons.join(", ")})` : ""
|
|
12046
12480
|
] }),
|
|
12047
12481
|
info.description ? /* @__PURE__ */ jsx(Text, { dimColor: true, children: info.description }) : null
|
|
12048
|
-
] },
|
|
12482
|
+
] }, scope2))
|
|
12049
12483
|
] });
|
|
12050
12484
|
}
|
|
12051
12485
|
if (status === "error") {
|
|
@@ -12169,10 +12603,18 @@ var Logout = ({
|
|
|
12169
12603
|
|
|
12170
12604
|
// src/commands/auth/schema.ts
|
|
12171
12605
|
import { z } from "incur";
|
|
12606
|
+
var SOURCE_ACTIONS_DESCRIPTION = SOURCE_ACTIONS.join(", ");
|
|
12172
12607
|
var loginOptions = z.object({
|
|
12173
12608
|
clientName: z.string().default("Link CLI").describe(
|
|
12174
12609
|
"Agent or app name shown in the Link app when approving the device connection"
|
|
12175
12610
|
),
|
|
12611
|
+
scope: z.string().optional().describe(
|
|
12612
|
+
"Optional space-separated Link scopes to request. Quote the value when passing multiple scopes."
|
|
12613
|
+
),
|
|
12614
|
+
sourceActions: z.array(z.enum(SOURCE_ACTIONS)).default([]).describe(
|
|
12615
|
+
`Source action to request via authorization_details (repeatable). Accepted values: ${SOURCE_ACTIONS_DESCRIPTION}.`
|
|
12616
|
+
),
|
|
12617
|
+
authorizationDetail: z.array(z.string()).default([]).describe("Freeform authorization_details entry as raw JSON (repeatable)."),
|
|
12176
12618
|
interval: z.coerce.number().default(0).describe(
|
|
12177
12619
|
"Poll interval in seconds. When > 0, polls until authenticated or timeout is reached, yielding status on each attempt."
|
|
12178
12620
|
),
|
|
@@ -12328,12 +12770,30 @@ function createAuthCli(authResource, getUpdateInfo2, authStorage2, envAccessToke
|
|
|
12328
12770
|
outputPolicy: "agent-only",
|
|
12329
12771
|
async *run(c) {
|
|
12330
12772
|
const clientName = c.options.clientName?.trim();
|
|
12773
|
+
const scope = normalizeScopeInput(c.options.scope);
|
|
12774
|
+
let authorizationDetails;
|
|
12331
12775
|
if (!clientName || clientName.length === 0) {
|
|
12332
12776
|
return c.error({
|
|
12333
12777
|
code: "INVALID_INPUT",
|
|
12334
12778
|
message: "client-name must be a non-empty string"
|
|
12335
12779
|
});
|
|
12336
12780
|
}
|
|
12781
|
+
if (c.options.scope !== void 0 && !scope) {
|
|
12782
|
+
return c.error({
|
|
12783
|
+
code: "INVALID_INPUT",
|
|
12784
|
+
message: "scope must be a non-empty string when provided"
|
|
12785
|
+
});
|
|
12786
|
+
}
|
|
12787
|
+
try {
|
|
12788
|
+
authorizationDetails = parseAuthorizationDetails(
|
|
12789
|
+
c.options.authorizationDetail
|
|
12790
|
+
);
|
|
12791
|
+
} catch (error) {
|
|
12792
|
+
return c.error({
|
|
12793
|
+
code: "INVALID_INPUT",
|
|
12794
|
+
message: error.message
|
|
12795
|
+
});
|
|
12796
|
+
}
|
|
12337
12797
|
const existingAuth = storage2.getAuth();
|
|
12338
12798
|
if (existingAuth?.refresh_token) {
|
|
12339
12799
|
try {
|
|
@@ -12365,6 +12825,9 @@ function createAuthCli(authResource, getUpdateInfo2, authStorage2, envAccessToke
|
|
|
12365
12825
|
{
|
|
12366
12826
|
authResource,
|
|
12367
12827
|
clientName,
|
|
12828
|
+
scope,
|
|
12829
|
+
sourceActions: c.options.sourceActions,
|
|
12830
|
+
authorizationDetails,
|
|
12368
12831
|
authStorage: storage2,
|
|
12369
12832
|
onComplete: () => {
|
|
12370
12833
|
}
|
|
@@ -12373,7 +12836,12 @@ function createAuthCli(authResource, getUpdateInfo2, authStorage2, envAccessToke
|
|
|
12373
12836
|
() => ({ authenticated: true, token_type: "Bearer" })
|
|
12374
12837
|
);
|
|
12375
12838
|
}
|
|
12376
|
-
const authRequest = await authResource.initiateDeviceAuth(
|
|
12839
|
+
const authRequest = await authResource.initiateDeviceAuth({
|
|
12840
|
+
clientName,
|
|
12841
|
+
scope,
|
|
12842
|
+
sourceActions: c.options.sourceActions,
|
|
12843
|
+
authorizationDetails
|
|
12844
|
+
});
|
|
12377
12845
|
storage2.setPendingDeviceAuth({
|
|
12378
12846
|
device_code: authRequest.device_code,
|
|
12379
12847
|
interval: authRequest.interval,
|
|
@@ -12503,29 +12971,200 @@ function createAuthCli(authResource, getUpdateInfo2, authStorage2, envAccessToke
|
|
|
12503
12971
|
return cli2;
|
|
12504
12972
|
}
|
|
12505
12973
|
|
|
12974
|
+
// src/commands/balances/index.tsx
|
|
12975
|
+
import { Cli as Cli2 } from "incur";
|
|
12976
|
+
|
|
12977
|
+
// src/utils/require-auth.ts
|
|
12978
|
+
var NOT_AUTHENTICATED_ERROR = {
|
|
12979
|
+
code: "NOT_AUTHENTICATED",
|
|
12980
|
+
message: 'Not authenticated. Run "link-cli auth login" first.',
|
|
12981
|
+
cta: {
|
|
12982
|
+
commands: [{ command: "auth login", description: "Log in to Link" }]
|
|
12983
|
+
}
|
|
12984
|
+
};
|
|
12985
|
+
function requireAuth(authStorage2, envAccessToken2) {
|
|
12986
|
+
const store = authStorage2 ?? storage;
|
|
12987
|
+
return (c, next) => {
|
|
12988
|
+
if (!envAccessToken2 && !store.isAuthenticated()) {
|
|
12989
|
+
return c.error(NOT_AUTHENTICATED_ERROR);
|
|
12990
|
+
}
|
|
12991
|
+
return next();
|
|
12992
|
+
};
|
|
12993
|
+
}
|
|
12994
|
+
function requireAuthGuard(c, authStorage2, envAccessToken2) {
|
|
12995
|
+
const store = authStorage2 ?? storage;
|
|
12996
|
+
if (!envAccessToken2 && !store.isAuthenticated()) {
|
|
12997
|
+
c.error(NOT_AUTHENTICATED_ERROR);
|
|
12998
|
+
}
|
|
12999
|
+
}
|
|
13000
|
+
|
|
13001
|
+
// src/commands/balances/list.tsx
|
|
13002
|
+
import { Box as Box4, Text as Text5 } from "ink";
|
|
13003
|
+
import Spinner3 from "ink-spinner";
|
|
13004
|
+
import { useCallback as useCallback2 } from "react";
|
|
13005
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
13006
|
+
var COLUMN_GAP = " ";
|
|
13007
|
+
var SOURCE_ID_MIN = 16;
|
|
13008
|
+
var SOURCE_ID_MAX = 48;
|
|
13009
|
+
var TYPE_WIDTH = 12;
|
|
13010
|
+
var CURRENT_WIDTH = 15;
|
|
13011
|
+
var CURRENCY_WIDTH = 8;
|
|
13012
|
+
function truncateCell(value, width) {
|
|
13013
|
+
if (value.length <= width) {
|
|
13014
|
+
return value;
|
|
13015
|
+
}
|
|
13016
|
+
if (width <= 3) {
|
|
13017
|
+
return value.slice(0, width);
|
|
13018
|
+
}
|
|
13019
|
+
return `${value.slice(0, width - 3)}...`;
|
|
13020
|
+
}
|
|
13021
|
+
function formatCell(value, width) {
|
|
13022
|
+
return truncateCell(value, width).padEnd(width);
|
|
13023
|
+
}
|
|
13024
|
+
function formatCents(cents) {
|
|
13025
|
+
const dollars = Math.abs(cents) / 100;
|
|
13026
|
+
const formatted = `$${dollars.toFixed(2)}`;
|
|
13027
|
+
return cents < 0 ? `-${formatted}` : formatted;
|
|
13028
|
+
}
|
|
13029
|
+
function sourceIdWidth(balances) {
|
|
13030
|
+
if (balances.length === 0) return SOURCE_ID_MIN;
|
|
13031
|
+
const maxLen = Math.max(...balances.map((b) => (b.source_id ?? "").length));
|
|
13032
|
+
return Math.min(SOURCE_ID_MAX, Math.max(SOURCE_ID_MIN, maxLen));
|
|
13033
|
+
}
|
|
13034
|
+
var BalancesList = ({
|
|
13035
|
+
resource,
|
|
13036
|
+
params,
|
|
13037
|
+
onComplete
|
|
13038
|
+
}) => {
|
|
13039
|
+
const action = useCallback2(
|
|
13040
|
+
() => resource.listBalances(params),
|
|
13041
|
+
[resource, params]
|
|
13042
|
+
);
|
|
13043
|
+
const { status, data: page, error } = useAsyncAction(action, onComplete);
|
|
13044
|
+
const balances = page?.data ?? [];
|
|
13045
|
+
const nextCursor = page?.has_more && balances.length > 0 ? balances[balances.length - 1].source_id : null;
|
|
13046
|
+
const idWidth = sourceIdWidth(balances);
|
|
13047
|
+
const headerRow = [
|
|
13048
|
+
formatCell("Source ID", idWidth),
|
|
13049
|
+
formatCell("Balance type", TYPE_WIDTH),
|
|
13050
|
+
formatCell("Current balance", CURRENT_WIDTH),
|
|
13051
|
+
formatCell("Currency", CURRENCY_WIDTH)
|
|
13052
|
+
].join(COLUMN_GAP);
|
|
13053
|
+
const separatorRow = "-".repeat(headerRow.length);
|
|
13054
|
+
const rows = balances.map(
|
|
13055
|
+
(balance) => [
|
|
13056
|
+
formatCell(balance.source_id ?? "-", idWidth),
|
|
13057
|
+
formatCell(balance.type ?? "-", TYPE_WIDTH),
|
|
13058
|
+
formatCell(
|
|
13059
|
+
balance.current != null ? formatCents(balance.current) : "-",
|
|
13060
|
+
CURRENT_WIDTH
|
|
13061
|
+
),
|
|
13062
|
+
formatCell(balance.currency ?? "-", CURRENCY_WIDTH)
|
|
13063
|
+
].join(COLUMN_GAP)
|
|
13064
|
+
);
|
|
13065
|
+
if (status === "loading") {
|
|
13066
|
+
return /* @__PURE__ */ jsx5(Box4, { children: /* @__PURE__ */ jsxs4(Text5, { color: "cyan", children: [
|
|
13067
|
+
/* @__PURE__ */ jsx5(Spinner3, { type: "dots" }),
|
|
13068
|
+
" Loading balances..."
|
|
13069
|
+
] }) });
|
|
13070
|
+
}
|
|
13071
|
+
if (status === "error") {
|
|
13072
|
+
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
|
|
13073
|
+
/* @__PURE__ */ jsx5(Text5, { color: "red", children: "Failed to load balances" }),
|
|
13074
|
+
/* @__PURE__ */ jsx5(Text5, { color: "red", children: error })
|
|
13075
|
+
] });
|
|
13076
|
+
}
|
|
13077
|
+
if (balances.length === 0) {
|
|
13078
|
+
return /* @__PURE__ */ jsx5(Box4, { children: /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "No balances found" }) });
|
|
13079
|
+
}
|
|
13080
|
+
return /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", children: [
|
|
13081
|
+
/* @__PURE__ */ jsx5(Text5, { bold: true, children: "Balances" }),
|
|
13082
|
+
/* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
|
|
13083
|
+
/* @__PURE__ */ jsx5(Text5, { bold: true, children: headerRow }),
|
|
13084
|
+
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: separatorRow }),
|
|
13085
|
+
rows.map((row, index) => /* @__PURE__ */ jsx5(Text5, { children: row }, balances[index].source_id ?? `balance-${index}`))
|
|
13086
|
+
] }),
|
|
13087
|
+
page?.has_more !== void 0 ? /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginTop: 1, children: [
|
|
13088
|
+
/* @__PURE__ */ jsxs4(Text5, { dimColor: true, children: [
|
|
13089
|
+
"has_more: ",
|
|
13090
|
+
String(page.has_more)
|
|
13091
|
+
] }),
|
|
13092
|
+
typeof nextCursor === "string" && nextCursor.length > 0 ? /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: `next page: --starting-after ${nextCursor}` }) : null
|
|
13093
|
+
] }) : null
|
|
13094
|
+
] });
|
|
13095
|
+
};
|
|
13096
|
+
|
|
13097
|
+
// src/commands/balances/schema.ts
|
|
13098
|
+
import { z as z2 } from "incur";
|
|
13099
|
+
var listOptions = z2.object({
|
|
13100
|
+
limit: z2.coerce.number().int().positive().max(100).optional().describe("Maximum number of balances to return (1-100)."),
|
|
13101
|
+
startingAfter: z2.string().optional().describe("Cursor: return balances after this balance ID."),
|
|
13102
|
+
endingBefore: z2.string().optional().describe("Cursor: return balances before this balance ID.")
|
|
13103
|
+
});
|
|
13104
|
+
|
|
13105
|
+
// src/commands/balances/index.tsx
|
|
13106
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
13107
|
+
function createBalancesCli(createResource, authStorage2, envAccessToken2) {
|
|
13108
|
+
const cli2 = Cli2.create("balances", {
|
|
13109
|
+
description: "List balances from your Link wallet"
|
|
13110
|
+
});
|
|
13111
|
+
cli2.command("list", {
|
|
13112
|
+
description: "List balances from your Link wallet",
|
|
13113
|
+
options: listOptions,
|
|
13114
|
+
outputPolicy: "agent-only",
|
|
13115
|
+
middleware: [requireAuth(authStorage2, envAccessToken2)],
|
|
13116
|
+
async run(c) {
|
|
13117
|
+
const opts = c.options;
|
|
13118
|
+
const resource = createResource();
|
|
13119
|
+
const params = {};
|
|
13120
|
+
if (opts.limit !== void 0) params.limit = opts.limit;
|
|
13121
|
+
if (opts.startingAfter !== void 0)
|
|
13122
|
+
params.starting_after = opts.startingAfter;
|
|
13123
|
+
if (opts.endingBefore !== void 0)
|
|
13124
|
+
params.ending_before = opts.endingBefore;
|
|
13125
|
+
if (!c.agent && !c.formatExplicit) {
|
|
13126
|
+
return renderInteractive(
|
|
13127
|
+
/* @__PURE__ */ jsx6(
|
|
13128
|
+
BalancesList,
|
|
13129
|
+
{
|
|
13130
|
+
resource,
|
|
13131
|
+
params,
|
|
13132
|
+
onComplete: () => {
|
|
13133
|
+
}
|
|
13134
|
+
}
|
|
13135
|
+
),
|
|
13136
|
+
() => resource.listBalances(params)
|
|
13137
|
+
);
|
|
13138
|
+
}
|
|
13139
|
+
return resource.listBalances(params);
|
|
13140
|
+
}
|
|
13141
|
+
});
|
|
13142
|
+
return cli2;
|
|
13143
|
+
}
|
|
13144
|
+
|
|
12506
13145
|
// src/commands/demo/index.tsx
|
|
12507
|
-
import { Cli as
|
|
13146
|
+
import { Cli as Cli3, z as z3 } from "incur";
|
|
12508
13147
|
|
|
12509
13148
|
// src/commands/demo/demo-runner.tsx
|
|
12510
|
-
import { Box as
|
|
12511
|
-
import { useCallback as
|
|
13149
|
+
import { Box as Box9, Text as Text11, useApp, useInput as useInput4 } from "ink";
|
|
13150
|
+
import { useCallback as useCallback3, useState as useState7 } from "react";
|
|
12512
13151
|
|
|
12513
13152
|
// src/utils/markdown-text.tsx
|
|
12514
|
-
import { Text as
|
|
12515
|
-
import { jsx as
|
|
13153
|
+
import { Text as Text6 } from "ink";
|
|
13154
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
12516
13155
|
var MarkdownText = ({
|
|
12517
13156
|
children,
|
|
12518
13157
|
dimColor
|
|
12519
13158
|
}) => {
|
|
12520
13159
|
const parts = tokenize(children);
|
|
12521
|
-
return /* @__PURE__ */
|
|
13160
|
+
return /* @__PURE__ */ jsx7(Text6, { dimColor, children: parts.map((part) => {
|
|
12522
13161
|
if (part.type === "bold") {
|
|
12523
|
-
return /* @__PURE__ */
|
|
13162
|
+
return /* @__PURE__ */ jsx7(Text6, { bold: true, children: part.text }, part.key);
|
|
12524
13163
|
}
|
|
12525
13164
|
if (part.type === "code") {
|
|
12526
|
-
return /* @__PURE__ */
|
|
13165
|
+
return /* @__PURE__ */ jsx7(Text6, { color: "yellow", children: part.text }, part.key);
|
|
12527
13166
|
}
|
|
12528
|
-
return /* @__PURE__ */
|
|
13167
|
+
return /* @__PURE__ */ jsx7(Text6, { children: part.text }, part.key);
|
|
12529
13168
|
}) });
|
|
12530
13169
|
};
|
|
12531
13170
|
function tokenize(input) {
|
|
@@ -12560,7 +13199,7 @@ function tokenize(input) {
|
|
|
12560
13199
|
}
|
|
12561
13200
|
|
|
12562
13201
|
// src/commands/spend-request/app-download-qr-codes.tsx
|
|
12563
|
-
import { Box as
|
|
13202
|
+
import { Box as Box5, Text as Text7 } from "ink";
|
|
12564
13203
|
import { useMemo } from "react";
|
|
12565
13204
|
|
|
12566
13205
|
// src/utils/render-qr-matrix.ts
|
|
@@ -12597,24 +13236,24 @@ function renderQrMatrix(url) {
|
|
|
12597
13236
|
}
|
|
12598
13237
|
|
|
12599
13238
|
// src/commands/spend-request/app-download-qr-codes.tsx
|
|
12600
|
-
import { jsx as
|
|
13239
|
+
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
12601
13240
|
var DOWNLOAD_URL = "https://link.com/download";
|
|
12602
13241
|
var AppDownloadQrCodes = () => {
|
|
12603
13242
|
const qrLines = useMemo(() => renderQrMatrix(DOWNLOAD_URL), []);
|
|
12604
|
-
return /* @__PURE__ */
|
|
12605
|
-
/* @__PURE__ */
|
|
12606
|
-
/* @__PURE__ */
|
|
13243
|
+
return /* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", marginTop: 1, children: [
|
|
13244
|
+
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children: "Get the Link app to approve spend requests from your phone" }),
|
|
13245
|
+
/* @__PURE__ */ jsxs5(Box5, { flexDirection: "column", alignItems: "flex-start", marginTop: 1, children: [
|
|
12607
13246
|
qrLines.map((line, i) => (
|
|
12608
13247
|
// biome-ignore lint/suspicious/noArrayIndexKey: stable static array
|
|
12609
|
-
/* @__PURE__ */
|
|
13248
|
+
/* @__PURE__ */ jsx8(Text7, { children: line }, i)
|
|
12610
13249
|
)),
|
|
12611
|
-
/* @__PURE__ */
|
|
13250
|
+
/* @__PURE__ */ jsx8(Text7, { dimColor: true, children: DOWNLOAD_URL })
|
|
12612
13251
|
] })
|
|
12613
13252
|
] });
|
|
12614
13253
|
};
|
|
12615
13254
|
|
|
12616
13255
|
// src/commands/demo/card-flow.tsx
|
|
12617
|
-
import { Box as
|
|
13256
|
+
import { Box as Box6, Text as Text8, useInput as useInput2 } from "ink";
|
|
12618
13257
|
import { useEffect as useEffect4, useRef as useRef2, useState as useState4 } from "react";
|
|
12619
13258
|
|
|
12620
13259
|
// src/utils/poll-until-approved.ts
|
|
@@ -12779,7 +13418,7 @@ var ONBOARD = {
|
|
|
12779
13418
|
};
|
|
12780
13419
|
|
|
12781
13420
|
// src/commands/demo/card-flow.tsx
|
|
12782
|
-
import { Fragment, jsx as
|
|
13421
|
+
import { Fragment, jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
12783
13422
|
function formatPmLabel(pm) {
|
|
12784
13423
|
return `${pm.card_details?.brand ?? pm.type} ****${pm.card_details?.last4 ?? ""}`;
|
|
12785
13424
|
}
|
|
@@ -12963,22 +13602,22 @@ var CardFlow = ({
|
|
|
12963
13602
|
];
|
|
12964
13603
|
return order.indexOf(step) > order.indexOf(target);
|
|
12965
13604
|
};
|
|
12966
|
-
const prompt = (label = "Press [Enter] to continue") => /* @__PURE__ */
|
|
13605
|
+
const prompt = (label = "Press [Enter] to continue") => /* @__PURE__ */ jsxs6(Text8, { dimColor: true, children: [
|
|
12967
13606
|
"\n",
|
|
12968
13607
|
">",
|
|
12969
13608
|
" ",
|
|
12970
13609
|
label
|
|
12971
13610
|
] });
|
|
12972
|
-
return /* @__PURE__ */
|
|
12973
|
-
/* @__PURE__ */
|
|
12974
|
-
/* @__PURE__ */
|
|
12975
|
-
/* @__PURE__ */
|
|
12976
|
-
/* @__PURE__ */
|
|
12977
|
-
/* @__PURE__ */
|
|
13611
|
+
return /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", gap: 1, children: [
|
|
13612
|
+
/* @__PURE__ */ jsx9(Text8, { bold: true, color: "cyan", children: CARD_FLOW.title }),
|
|
13613
|
+
/* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
13614
|
+
/* @__PURE__ */ jsxs6(Box6, { flexDirection: "row", gap: 1, children: [
|
|
13615
|
+
/* @__PURE__ */ jsx9(Text8, { color: "yellow", children: "[testmode]" }),
|
|
13616
|
+
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: DEMO_MERCHANT_URL })
|
|
12978
13617
|
] }),
|
|
12979
|
-
/* @__PURE__ */
|
|
12980
|
-
/* @__PURE__ */
|
|
12981
|
-
/* @__PURE__ */
|
|
13618
|
+
/* @__PURE__ */ jsx9(MarkdownText, { children: CARD_FLOW.intro.description }),
|
|
13619
|
+
/* @__PURE__ */ jsxs6(Box6, { marginTop: 1, flexDirection: "column", children: [
|
|
13620
|
+
/* @__PURE__ */ jsx9(Text8, { children: "What happens:" }),
|
|
12982
13621
|
CARD_FLOW.intro.steps.map((s, i) => {
|
|
12983
13622
|
const doneAfter = [
|
|
12984
13623
|
"pick-pm",
|
|
@@ -12994,17 +13633,17 @@ var CardFlow = ({
|
|
|
12994
13633
|
];
|
|
12995
13634
|
const done = pastStep(doneAfter[i]);
|
|
12996
13635
|
const active = !done && (step === activeFrom[i] || pastStep(activeFrom[i]));
|
|
12997
|
-
return done ? /* @__PURE__ */
|
|
13636
|
+
return done ? /* @__PURE__ */ jsxs6(Text8, { dimColor: true, strikethrough: true, children: [
|
|
12998
13637
|
" ",
|
|
12999
13638
|
i + 1,
|
|
13000
13639
|
". ",
|
|
13001
13640
|
s
|
|
13002
|
-
] }, s) : active ? /* @__PURE__ */
|
|
13641
|
+
] }, s) : active ? /* @__PURE__ */ jsxs6(Text8, { bold: true, color: "cyan", children: [
|
|
13003
13642
|
" ",
|
|
13004
13643
|
i + 1,
|
|
13005
13644
|
". ",
|
|
13006
13645
|
s
|
|
13007
|
-
] }, s) : /* @__PURE__ */
|
|
13646
|
+
] }, s) : /* @__PURE__ */ jsxs6(Text8, { dimColor: true, children: [
|
|
13008
13647
|
" ",
|
|
13009
13648
|
i + 1,
|
|
13010
13649
|
". ",
|
|
@@ -13014,45 +13653,45 @@ var CardFlow = ({
|
|
|
13014
13653
|
] }),
|
|
13015
13654
|
step === "intro" && prompt(CARD_FLOW.intro.prompt)
|
|
13016
13655
|
] }),
|
|
13017
|
-
step === "fetch-pm" && /* @__PURE__ */
|
|
13018
|
-
(step === "pick-pm" || step === "explain-pm") && /* @__PURE__ */
|
|
13019
|
-
step === "pick-pm" && paymentMethods.length > 1 && /* @__PURE__ */
|
|
13020
|
-
/* @__PURE__ */
|
|
13021
|
-
/* @__PURE__ */
|
|
13656
|
+
step === "fetch-pm" && /* @__PURE__ */ jsx9(Box6, { flexDirection: "column", children: /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "Fetching payment methods from your Link wallet..." }) }),
|
|
13657
|
+
(step === "pick-pm" || step === "explain-pm") && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
13658
|
+
step === "pick-pm" && paymentMethods.length > 1 && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
13659
|
+
/* @__PURE__ */ jsx9(Text8, { children: "Which payment method should we use for the demo?" }),
|
|
13660
|
+
/* @__PURE__ */ jsx9(Box6, { flexDirection: "column", marginTop: 1, children: paymentMethods.map((pm, i) => /* @__PURE__ */ jsx9(Text8, { children: i === selectedPmIndex ? /* @__PURE__ */ jsxs6(Text8, { color: "cyan", bold: true, children: [
|
|
13022
13661
|
">",
|
|
13023
13662
|
" ",
|
|
13024
13663
|
formatPmLabel(pm),
|
|
13025
13664
|
pm.is_default ? " (default)" : ""
|
|
13026
|
-
] }) : /* @__PURE__ */
|
|
13665
|
+
] }) : /* @__PURE__ */ jsxs6(Text8, { dimColor: true, children: [
|
|
13027
13666
|
" ",
|
|
13028
13667
|
formatPmLabel(pm),
|
|
13029
13668
|
pm.is_default ? " (default)" : ""
|
|
13030
13669
|
] }) }, pm.id)) }),
|
|
13031
|
-
/* @__PURE__ */
|
|
13670
|
+
/* @__PURE__ */ jsx9(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "Use \u2191\u2193 to select, [Enter] to confirm" }) })
|
|
13032
13671
|
] }),
|
|
13033
|
-
paymentMethod && /* @__PURE__ */
|
|
13034
|
-
/* @__PURE__ */
|
|
13672
|
+
paymentMethod && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
13673
|
+
/* @__PURE__ */ jsxs6(Text8, { color: "green", children: [
|
|
13035
13674
|
"\u2713 Using ",
|
|
13036
|
-
/* @__PURE__ */
|
|
13675
|
+
/* @__PURE__ */ jsx9(Text8, { bold: true, children: pmLabel }),
|
|
13037
13676
|
paymentMethod.is_default ? " (default)" : ""
|
|
13038
13677
|
] }),
|
|
13039
13678
|
step === "explain-pm" && prompt(CARD_FLOW.explainPm.prompt)
|
|
13040
13679
|
] })
|
|
13041
13680
|
] }),
|
|
13042
|
-
step === "create-spend" && /* @__PURE__ */
|
|
13043
|
-
/* @__PURE__ */
|
|
13044
|
-
/* @__PURE__ */
|
|
13681
|
+
step === "create-spend" && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
13682
|
+
/* @__PURE__ */ jsx9(MarkdownText, { children: CARD_FLOW.createSpend.description }),
|
|
13683
|
+
/* @__PURE__ */ jsx9(Box6, { marginY: 1, children: /* @__PURE__ */ jsx9(Text8, { color: "cyan", children: CARD_FLOW.createSpend.loading }) })
|
|
13045
13684
|
] }),
|
|
13046
|
-
(step === "await-approval" || step === "approval-timeout") && spendRequest && /* @__PURE__ */
|
|
13047
|
-
/* @__PURE__ */
|
|
13685
|
+
(step === "await-approval" || step === "approval-timeout") && spendRequest && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
13686
|
+
/* @__PURE__ */ jsxs6(Text8, { color: "green", children: [
|
|
13048
13687
|
"\u2713 Spend request created (",
|
|
13049
13688
|
spendRequest.id,
|
|
13050
13689
|
")"
|
|
13051
13690
|
] }),
|
|
13052
|
-
step === "await-approval" && /* @__PURE__ */
|
|
13053
|
-
/* @__PURE__ */
|
|
13054
|
-
/* @__PURE__ */
|
|
13055
|
-
|
|
13691
|
+
step === "await-approval" && /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
13692
|
+
/* @__PURE__ */ jsx9(Text8, { children: CARD_FLOW.approval.description }),
|
|
13693
|
+
/* @__PURE__ */ jsxs6(
|
|
13694
|
+
Box6,
|
|
13056
13695
|
{
|
|
13057
13696
|
flexDirection: "column",
|
|
13058
13697
|
borderStyle: "round",
|
|
@@ -13061,21 +13700,21 @@ var CardFlow = ({
|
|
|
13061
13700
|
paddingY: 1,
|
|
13062
13701
|
marginTop: 1,
|
|
13063
13702
|
children: [
|
|
13064
|
-
/* @__PURE__ */
|
|
13703
|
+
/* @__PURE__ */ jsxs6(Text8, { children: [
|
|
13065
13704
|
"Approve at:",
|
|
13066
13705
|
" ",
|
|
13067
|
-
/* @__PURE__ */
|
|
13706
|
+
/* @__PURE__ */ jsx9(Text8, { bold: true, color: "cyan", children: approvalUrl })
|
|
13068
13707
|
] }),
|
|
13069
|
-
/* @__PURE__ */
|
|
13708
|
+
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: CARD_FLOW.approval.browserHint })
|
|
13070
13709
|
]
|
|
13071
13710
|
}
|
|
13072
13711
|
),
|
|
13073
|
-
/* @__PURE__ */
|
|
13712
|
+
/* @__PURE__ */ jsx9(Box6, { marginY: 1, children: /* @__PURE__ */ jsx9(Text8, { color: "cyan", children: CARD_FLOW.approval.loading }) })
|
|
13074
13713
|
] }),
|
|
13075
|
-
step === "approval-timeout" && /* @__PURE__ */
|
|
13076
|
-
/* @__PURE__ */
|
|
13077
|
-
/* @__PURE__ */
|
|
13078
|
-
|
|
13714
|
+
step === "approval-timeout" && /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
13715
|
+
/* @__PURE__ */ jsx9(Text8, { color: "yellow", children: "\u26A0 Approval timed out (5 min). Still pending \u2014 you can still approve." }),
|
|
13716
|
+
/* @__PURE__ */ jsxs6(
|
|
13717
|
+
Box6,
|
|
13079
13718
|
{
|
|
13080
13719
|
flexDirection: "column",
|
|
13081
13720
|
borderStyle: "round",
|
|
@@ -13084,38 +13723,38 @@ var CardFlow = ({
|
|
|
13084
13723
|
paddingY: 1,
|
|
13085
13724
|
marginTop: 1,
|
|
13086
13725
|
children: [
|
|
13087
|
-
/* @__PURE__ */
|
|
13726
|
+
/* @__PURE__ */ jsxs6(Text8, { children: [
|
|
13088
13727
|
"Approve at:",
|
|
13089
13728
|
" ",
|
|
13090
|
-
/* @__PURE__ */
|
|
13729
|
+
/* @__PURE__ */ jsx9(Text8, { bold: true, color: "cyan", children: approvalUrl })
|
|
13091
13730
|
] }),
|
|
13092
|
-
/* @__PURE__ */
|
|
13731
|
+
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "Press [Enter] to open in browser" })
|
|
13093
13732
|
]
|
|
13094
13733
|
}
|
|
13095
13734
|
),
|
|
13096
|
-
/* @__PURE__ */
|
|
13735
|
+
/* @__PURE__ */ jsx9(Box6, { marginTop: 1, children: /* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "r Retry polling q Quit demo" }) })
|
|
13097
13736
|
] })
|
|
13098
13737
|
] }),
|
|
13099
|
-
(step === "show-card" || step === "open-url" || step === "done") && card && /* @__PURE__ */
|
|
13100
|
-
/* @__PURE__ */
|
|
13101
|
-
/* @__PURE__ */
|
|
13102
|
-
/* @__PURE__ */
|
|
13103
|
-
/* @__PURE__ */
|
|
13104
|
-
/* @__PURE__ */
|
|
13738
|
+
(step === "show-card" || step === "open-url" || step === "done") && card && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
13739
|
+
/* @__PURE__ */ jsx9(Text8, { color: "green", children: "\u2713 Approved!" }),
|
|
13740
|
+
/* @__PURE__ */ jsx9(MarkdownText, { children: CARD_FLOW.showCard.description }),
|
|
13741
|
+
/* @__PURE__ */ jsx9(Box6, { flexDirection: "column", paddingX: 2, marginTop: 1, children: /* @__PURE__ */ jsxs6(Text8, { children: [
|
|
13742
|
+
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "Number " }),
|
|
13743
|
+
/* @__PURE__ */ jsx9(Text8, { bold: true, children: formatCardNumber(card.number) }),
|
|
13105
13744
|
" ",
|
|
13106
|
-
/* @__PURE__ */
|
|
13107
|
-
/* @__PURE__ */
|
|
13745
|
+
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "Exp " }),
|
|
13746
|
+
/* @__PURE__ */ jsx9(Text8, { bold: true, children: formatExpiry(card.exp_month, card.exp_year) }),
|
|
13108
13747
|
" ",
|
|
13109
|
-
/* @__PURE__ */
|
|
13110
|
-
/* @__PURE__ */
|
|
13111
|
-
card.billing_address?.postal_code && /* @__PURE__ */
|
|
13748
|
+
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "CVC " }),
|
|
13749
|
+
/* @__PURE__ */ jsx9(Text8, { bold: true, children: card.cvc }),
|
|
13750
|
+
card.billing_address?.postal_code && /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
13112
13751
|
" ",
|
|
13113
|
-
/* @__PURE__ */
|
|
13114
|
-
/* @__PURE__ */
|
|
13752
|
+
/* @__PURE__ */ jsx9(Text8, { dimColor: true, children: "Zip " }),
|
|
13753
|
+
/* @__PURE__ */ jsx9(Text8, { bold: true, children: card.billing_address.postal_code })
|
|
13115
13754
|
] }),
|
|
13116
|
-
card.valid_until && /* @__PURE__ */
|
|
13755
|
+
card.valid_until && /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
13117
13756
|
" ",
|
|
13118
|
-
/* @__PURE__ */
|
|
13757
|
+
/* @__PURE__ */ jsxs6(Text8, { dimColor: true, children: [
|
|
13119
13758
|
"expires",
|
|
13120
13759
|
" ",
|
|
13121
13760
|
new Date(card.valid_until).toLocaleTimeString([], {
|
|
@@ -13127,14 +13766,14 @@ var CardFlow = ({
|
|
|
13127
13766
|
] }) }),
|
|
13128
13767
|
step === "show-card" && prompt(CARD_FLOW.showCard.prompt)
|
|
13129
13768
|
] }),
|
|
13130
|
-
step === "done" && /* @__PURE__ */
|
|
13131
|
-
/* @__PURE__ */
|
|
13769
|
+
step === "done" && /* @__PURE__ */ jsxs6(Box6, { flexDirection: "column", children: [
|
|
13770
|
+
/* @__PURE__ */ jsxs6(Text8, { color: "green", children: [
|
|
13132
13771
|
"\u2713 ",
|
|
13133
13772
|
CARD_FLOW.done.success
|
|
13134
13773
|
] }),
|
|
13135
|
-
/* @__PURE__ */
|
|
13774
|
+
/* @__PURE__ */ jsx9(Text8, { children: CARD_FLOW.done.detail })
|
|
13136
13775
|
] }),
|
|
13137
|
-
step === "error" && /* @__PURE__ */
|
|
13776
|
+
step === "error" && /* @__PURE__ */ jsxs6(Text8, { color: "red", children: [
|
|
13138
13777
|
"Error: ",
|
|
13139
13778
|
error
|
|
13140
13779
|
] })
|
|
@@ -13142,7 +13781,7 @@ var CardFlow = ({
|
|
|
13142
13781
|
};
|
|
13143
13782
|
|
|
13144
13783
|
// src/commands/demo/spt-flow.tsx
|
|
13145
|
-
import { Box as
|
|
13784
|
+
import { Box as Box8, Text as Text10, useInput as useInput3 } from "ink";
|
|
13146
13785
|
import { useEffect as useEffect6, useRef as useRef3, useState as useState6 } from "react";
|
|
13147
13786
|
|
|
13148
13787
|
// src/commands/mpp/decode.ts
|
|
@@ -13224,13 +13863,13 @@ function decodeStripeChallenge(challengeHeader) {
|
|
|
13224
13863
|
}
|
|
13225
13864
|
|
|
13226
13865
|
// src/commands/mpp/pay.tsx
|
|
13227
|
-
import { Box as
|
|
13228
|
-
import
|
|
13866
|
+
import { Box as Box7, Text as Text9 } from "ink";
|
|
13867
|
+
import Spinner4 from "ink-spinner";
|
|
13229
13868
|
import { Credential, Method } from "mppx";
|
|
13230
13869
|
import { Mppx, Transport } from "mppx/client";
|
|
13231
13870
|
import { Methods as StripeMethods } from "mppx/stripe";
|
|
13232
13871
|
import { useEffect as useEffect5, useState as useState5 } from "react";
|
|
13233
|
-
import { jsx as
|
|
13872
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
13234
13873
|
function buildHeaders(data, headers) {
|
|
13235
13874
|
const result = {};
|
|
13236
13875
|
if (data !== void 0) {
|
|
@@ -13404,21 +14043,21 @@ function MppPay({
|
|
|
13404
14043
|
done: "Done"
|
|
13405
14044
|
};
|
|
13406
14045
|
if (error) {
|
|
13407
|
-
return /* @__PURE__ */
|
|
14046
|
+
return /* @__PURE__ */ jsxs7(Text9, { color: "red", children: [
|
|
13408
14047
|
"Error: ",
|
|
13409
14048
|
error
|
|
13410
14049
|
] });
|
|
13411
14050
|
}
|
|
13412
|
-
return /* @__PURE__ */
|
|
13413
|
-
step !== "done" && /* @__PURE__ */
|
|
13414
|
-
/* @__PURE__ */
|
|
14051
|
+
return /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
14052
|
+
step !== "done" && /* @__PURE__ */ jsx10(Box7, { children: /* @__PURE__ */ jsxs7(Text9, { color: "cyan", children: [
|
|
14053
|
+
/* @__PURE__ */ jsx10(Spinner4, { type: "dots" }),
|
|
13415
14054
|
" ",
|
|
13416
14055
|
stepLabels[step],
|
|
13417
14056
|
"..."
|
|
13418
14057
|
] }) }),
|
|
13419
|
-
result && /* @__PURE__ */
|
|
13420
|
-
/* @__PURE__ */
|
|
13421
|
-
|
|
14058
|
+
result && /* @__PURE__ */ jsxs7(Box7, { flexDirection: "column", children: [
|
|
14059
|
+
/* @__PURE__ */ jsxs7(
|
|
14060
|
+
Text9,
|
|
13422
14061
|
{
|
|
13423
14062
|
color: result.status >= 400 ? "red" : result.status >= 300 ? "yellow" : "green",
|
|
13424
14063
|
children: [
|
|
@@ -13427,13 +14066,13 @@ function MppPay({
|
|
|
13427
14066
|
]
|
|
13428
14067
|
}
|
|
13429
14068
|
),
|
|
13430
|
-
/* @__PURE__ */
|
|
14069
|
+
/* @__PURE__ */ jsx10(Text9, { children: result.body })
|
|
13431
14070
|
] })
|
|
13432
14071
|
] });
|
|
13433
14072
|
}
|
|
13434
14073
|
|
|
13435
14074
|
// src/commands/demo/spt-flow.tsx
|
|
13436
|
-
import { Fragment as Fragment2, jsx as
|
|
14075
|
+
import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
13437
14076
|
var SptFlow = ({
|
|
13438
14077
|
spendRequestRepo: spendRequestRepo2,
|
|
13439
14078
|
paymentMethodsResource,
|
|
@@ -13616,26 +14255,26 @@ var SptFlow = ({
|
|
|
13616
14255
|
];
|
|
13617
14256
|
return order.indexOf(step) > order.indexOf(target);
|
|
13618
14257
|
};
|
|
13619
|
-
const prompt = (label = "Press [Enter] to continue") => /* @__PURE__ */
|
|
14258
|
+
const prompt = (label = "Press [Enter] to continue") => /* @__PURE__ */ jsxs8(Text10, { dimColor: true, children: [
|
|
13620
14259
|
"\n",
|
|
13621
14260
|
">",
|
|
13622
14261
|
" ",
|
|
13623
14262
|
label
|
|
13624
14263
|
] });
|
|
13625
|
-
return /* @__PURE__ */
|
|
13626
|
-
/* @__PURE__ */
|
|
13627
|
-
/* @__PURE__ */
|
|
13628
|
-
/* @__PURE__ */
|
|
13629
|
-
/* @__PURE__ */
|
|
13630
|
-
/* @__PURE__ */
|
|
14264
|
+
return /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", gap: 1, children: [
|
|
14265
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, color: "cyan", children: SPT_FLOW.title }),
|
|
14266
|
+
/* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
14267
|
+
/* @__PURE__ */ jsxs8(Box8, { flexDirection: "row", gap: 1, children: [
|
|
14268
|
+
/* @__PURE__ */ jsx11(Text10, { color: "yellow", children: "[testmode]" }),
|
|
14269
|
+
/* @__PURE__ */ jsxs8(Text10, { dimColor: true, children: [
|
|
13631
14270
|
DEMO_CLIMATE_API_URL,
|
|
13632
14271
|
" ",
|
|
13633
14272
|
DEMO_MPP_DEV_URL
|
|
13634
14273
|
] })
|
|
13635
14274
|
] }),
|
|
13636
|
-
/* @__PURE__ */
|
|
13637
|
-
/* @__PURE__ */
|
|
13638
|
-
/* @__PURE__ */
|
|
14275
|
+
/* @__PURE__ */ jsx11(MarkdownText, { children: SPT_FLOW.intro.description }),
|
|
14276
|
+
/* @__PURE__ */ jsxs8(Box8, { marginTop: 1, flexDirection: "column", children: [
|
|
14277
|
+
/* @__PURE__ */ jsx11(Text10, { children: SPT_FLOW.intro.preamble }),
|
|
13639
14278
|
SPT_FLOW.intro.steps.map((s, i) => {
|
|
13640
14279
|
const doneAfter = [
|
|
13641
14280
|
"pick-pm",
|
|
@@ -13654,17 +14293,17 @@ var SptFlow = ({
|
|
|
13654
14293
|
const done = pastStep(doneAfter[i]);
|
|
13655
14294
|
const active = !done && (step === activeFrom[i] || pastStep(activeFrom[i]));
|
|
13656
14295
|
const label = s.replace(/`/g, "");
|
|
13657
|
-
return done ? /* @__PURE__ */
|
|
14296
|
+
return done ? /* @__PURE__ */ jsxs8(Text10, { dimColor: true, strikethrough: true, children: [
|
|
13658
14297
|
" ",
|
|
13659
14298
|
i + 1,
|
|
13660
14299
|
". ",
|
|
13661
14300
|
label
|
|
13662
|
-
] }, s) : active ? /* @__PURE__ */
|
|
14301
|
+
] }, s) : active ? /* @__PURE__ */ jsxs8(Text10, { bold: true, color: "cyan", children: [
|
|
13663
14302
|
" ",
|
|
13664
14303
|
i + 1,
|
|
13665
14304
|
". ",
|
|
13666
14305
|
label
|
|
13667
|
-
] }, s) : /* @__PURE__ */
|
|
14306
|
+
] }, s) : /* @__PURE__ */ jsxs8(Text10, { dimColor: true, children: [
|
|
13668
14307
|
" ",
|
|
13669
14308
|
i + 1,
|
|
13670
14309
|
". ",
|
|
@@ -13674,47 +14313,47 @@ var SptFlow = ({
|
|
|
13674
14313
|
] }),
|
|
13675
14314
|
step === "intro" && prompt(SPT_FLOW.intro.prompt)
|
|
13676
14315
|
] }),
|
|
13677
|
-
step === "fetch-pm" && /* @__PURE__ */
|
|
13678
|
-
step === "pick-pm" && paymentMethods.length > 1 && /* @__PURE__ */
|
|
13679
|
-
/* @__PURE__ */
|
|
13680
|
-
/* @__PURE__ */
|
|
14316
|
+
step === "fetch-pm" && /* @__PURE__ */ jsx11(Box8, { marginY: 1, children: /* @__PURE__ */ jsx11(Text10, { color: "cyan", children: "Fetching payment methods..." }) }),
|
|
14317
|
+
step === "pick-pm" && paymentMethods.length > 1 && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
14318
|
+
/* @__PURE__ */ jsx11(Text10, { children: "Which payment method should we use for the demo?" }),
|
|
14319
|
+
/* @__PURE__ */ jsx11(Box8, { flexDirection: "column", marginTop: 1, children: paymentMethods.map((pm, i) => /* @__PURE__ */ jsx11(Text10, { children: i === selectedPmIndex ? /* @__PURE__ */ jsxs8(Text10, { color: "cyan", bold: true, children: [
|
|
13681
14320
|
">",
|
|
13682
14321
|
" ",
|
|
13683
14322
|
pm.card_details ? `${pm.card_details.brand} ****${pm.card_details.last4}` : pm.type,
|
|
13684
14323
|
pm.is_default ? " (default)" : ""
|
|
13685
|
-
] }) : /* @__PURE__ */
|
|
14324
|
+
] }) : /* @__PURE__ */ jsxs8(Text10, { dimColor: true, children: [
|
|
13686
14325
|
" ",
|
|
13687
14326
|
pm.card_details ? `${pm.card_details.brand} ****${pm.card_details.last4}` : pm.type,
|
|
13688
14327
|
pm.is_default ? " (default)" : ""
|
|
13689
14328
|
] }) }, pm.id)) }),
|
|
13690
|
-
/* @__PURE__ */
|
|
14329
|
+
/* @__PURE__ */ jsx11(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "Use \u2191\u2193 to select, [Enter] to confirm" }) })
|
|
13691
14330
|
] }),
|
|
13692
|
-
(step === "probe" || step === "explain-402") && /* @__PURE__ */
|
|
13693
|
-
/* @__PURE__ */
|
|
13694
|
-
step === "probe" && /* @__PURE__ */
|
|
13695
|
-
step === "explain-402" && networkId && /* @__PURE__ */
|
|
13696
|
-
/* @__PURE__ */
|
|
13697
|
-
/* @__PURE__ */
|
|
14331
|
+
(step === "probe" || step === "explain-402") && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
14332
|
+
/* @__PURE__ */ jsx11(MarkdownText, { children: SPT_FLOW.probe.description }),
|
|
14333
|
+
step === "probe" && /* @__PURE__ */ jsx11(Box8, { marginY: 1, children: /* @__PURE__ */ jsx11(Text10, { color: "cyan", children: SPT_FLOW.probe.loading }) }),
|
|
14334
|
+
step === "explain-402" && networkId && /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
14335
|
+
/* @__PURE__ */ jsx11(MarkdownText, { children: SPT_FLOW.probe.detail }),
|
|
14336
|
+
/* @__PURE__ */ jsxs8(Text10, { color: "green", children: [
|
|
13698
14337
|
"\u2713 Got HTTP 402 \u2014 network_id: ",
|
|
13699
|
-
/* @__PURE__ */
|
|
14338
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, children: networkId })
|
|
13700
14339
|
] }),
|
|
13701
14340
|
prompt(SPT_FLOW.probe.prompt)
|
|
13702
14341
|
] })
|
|
13703
14342
|
] }),
|
|
13704
|
-
step === "create-spend" && /* @__PURE__ */
|
|
13705
|
-
/* @__PURE__ */
|
|
13706
|
-
/* @__PURE__ */
|
|
14343
|
+
step === "create-spend" && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
14344
|
+
/* @__PURE__ */ jsx11(MarkdownText, { children: SPT_FLOW.createSpend.description }),
|
|
14345
|
+
/* @__PURE__ */ jsx11(Box8, { marginY: 1, children: /* @__PURE__ */ jsx11(Text10, { color: "cyan", children: SPT_FLOW.createSpend.loading }) })
|
|
13707
14346
|
] }),
|
|
13708
|
-
(step === "await-approval" || step === "approval-timeout") && spendRequest && /* @__PURE__ */
|
|
13709
|
-
/* @__PURE__ */
|
|
14347
|
+
(step === "await-approval" || step === "approval-timeout") && spendRequest && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
14348
|
+
/* @__PURE__ */ jsxs8(Text10, { color: "green", children: [
|
|
13710
14349
|
"\u2713 Spend request created (",
|
|
13711
14350
|
spendRequest.id,
|
|
13712
14351
|
")"
|
|
13713
14352
|
] }),
|
|
13714
|
-
step === "await-approval" && /* @__PURE__ */
|
|
13715
|
-
/* @__PURE__ */
|
|
13716
|
-
/* @__PURE__ */
|
|
13717
|
-
|
|
14353
|
+
step === "await-approval" && /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
14354
|
+
/* @__PURE__ */ jsx11(Text10, { children: SPT_FLOW.approval.description }),
|
|
14355
|
+
/* @__PURE__ */ jsxs8(
|
|
14356
|
+
Box8,
|
|
13718
14357
|
{
|
|
13719
14358
|
flexDirection: "column",
|
|
13720
14359
|
borderStyle: "round",
|
|
@@ -13723,21 +14362,21 @@ var SptFlow = ({
|
|
|
13723
14362
|
paddingY: 1,
|
|
13724
14363
|
marginTop: 1,
|
|
13725
14364
|
children: [
|
|
13726
|
-
/* @__PURE__ */
|
|
14365
|
+
/* @__PURE__ */ jsxs8(Text10, { children: [
|
|
13727
14366
|
"Approve at:",
|
|
13728
14367
|
" ",
|
|
13729
|
-
/* @__PURE__ */
|
|
14368
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, color: "cyan", children: approvalUrl })
|
|
13730
14369
|
] }),
|
|
13731
|
-
/* @__PURE__ */
|
|
14370
|
+
/* @__PURE__ */ jsx11(Text10, { dimColor: true, children: SPT_FLOW.approval.browserHint })
|
|
13732
14371
|
]
|
|
13733
14372
|
}
|
|
13734
14373
|
),
|
|
13735
|
-
/* @__PURE__ */
|
|
14374
|
+
/* @__PURE__ */ jsx11(Box8, { marginY: 1, children: /* @__PURE__ */ jsx11(Text10, { color: "cyan", children: SPT_FLOW.approval.loading }) })
|
|
13736
14375
|
] }),
|
|
13737
|
-
step === "approval-timeout" && /* @__PURE__ */
|
|
13738
|
-
/* @__PURE__ */
|
|
13739
|
-
/* @__PURE__ */
|
|
13740
|
-
|
|
14376
|
+
step === "approval-timeout" && /* @__PURE__ */ jsxs8(Fragment2, { children: [
|
|
14377
|
+
/* @__PURE__ */ jsx11(Text10, { color: "yellow", children: "\u26A0 Approval timed out (5 min). Still pending \u2014 you can still approve." }),
|
|
14378
|
+
/* @__PURE__ */ jsxs8(
|
|
14379
|
+
Box8,
|
|
13741
14380
|
{
|
|
13742
14381
|
flexDirection: "column",
|
|
13743
14382
|
borderStyle: "round",
|
|
@@ -13746,35 +14385,35 @@ var SptFlow = ({
|
|
|
13746
14385
|
paddingY: 1,
|
|
13747
14386
|
marginTop: 1,
|
|
13748
14387
|
children: [
|
|
13749
|
-
/* @__PURE__ */
|
|
14388
|
+
/* @__PURE__ */ jsxs8(Text10, { children: [
|
|
13750
14389
|
"Approve at:",
|
|
13751
14390
|
" ",
|
|
13752
|
-
/* @__PURE__ */
|
|
14391
|
+
/* @__PURE__ */ jsx11(Text10, { bold: true, color: "cyan", children: approvalUrl })
|
|
13753
14392
|
] }),
|
|
13754
|
-
/* @__PURE__ */
|
|
14393
|
+
/* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "Press [Enter] to open in browser" })
|
|
13755
14394
|
]
|
|
13756
14395
|
}
|
|
13757
14396
|
),
|
|
13758
|
-
/* @__PURE__ */
|
|
14397
|
+
/* @__PURE__ */ jsx11(Box8, { marginTop: 1, children: /* @__PURE__ */ jsx11(Text10, { dimColor: true, children: "r Retry polling q Quit demo" }) })
|
|
13759
14398
|
] })
|
|
13760
14399
|
] }),
|
|
13761
|
-
(step === "mpp-pay-gate" || step === "mpp-pay") && /* @__PURE__ */
|
|
13762
|
-
/* @__PURE__ */
|
|
13763
|
-
/* @__PURE__ */
|
|
14400
|
+
(step === "mpp-pay-gate" || step === "mpp-pay") && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
14401
|
+
/* @__PURE__ */ jsx11(Text10, { color: "green", children: "\u2713 Approved!" }),
|
|
14402
|
+
/* @__PURE__ */ jsx11(MarkdownText, { children: SPT_FLOW.mppPay.description }),
|
|
13764
14403
|
step === "mpp-pay-gate" && prompt(SPT_FLOW.mppPay.prompt),
|
|
13765
|
-
step === "mpp-pay" && /* @__PURE__ */
|
|
14404
|
+
step === "mpp-pay" && /* @__PURE__ */ jsx11(Box8, { marginY: 1, children: /* @__PURE__ */ jsx11(Text10, { color: "cyan", children: SPT_FLOW.mppPay.loading }) })
|
|
13766
14405
|
] }),
|
|
13767
|
-
step === "done" && payResult && /* @__PURE__ */
|
|
13768
|
-
/* @__PURE__ */
|
|
14406
|
+
step === "done" && payResult && /* @__PURE__ */ jsxs8(Box8, { flexDirection: "column", children: [
|
|
14407
|
+
/* @__PURE__ */ jsxs8(Text10, { bold: true, color: "green", children: [
|
|
13769
14408
|
"\u2713 ",
|
|
13770
14409
|
SPT_FLOW.done.success,
|
|
13771
14410
|
" (HTTP ",
|
|
13772
14411
|
payResult.status,
|
|
13773
14412
|
")"
|
|
13774
14413
|
] }),
|
|
13775
|
-
/* @__PURE__ */
|
|
14414
|
+
/* @__PURE__ */ jsx11(MarkdownText, { children: SPT_FLOW.done.detail })
|
|
13776
14415
|
] }),
|
|
13777
|
-
step === "error" && /* @__PURE__ */
|
|
14416
|
+
step === "error" && /* @__PURE__ */ jsxs8(Text10, { color: "red", children: [
|
|
13778
14417
|
"Error: ",
|
|
13779
14418
|
error
|
|
13780
14419
|
] })
|
|
@@ -13782,7 +14421,7 @@ var SptFlow = ({
|
|
|
13782
14421
|
};
|
|
13783
14422
|
|
|
13784
14423
|
// src/commands/demo/demo-runner.tsx
|
|
13785
|
-
import { Fragment as Fragment3, jsx as
|
|
14424
|
+
import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
13786
14425
|
var DemoRunner = ({
|
|
13787
14426
|
authRepo: authRepo2,
|
|
13788
14427
|
spendRequestRepo: spendRequestRepo2,
|
|
@@ -13824,7 +14463,7 @@ var DemoRunner = ({
|
|
|
13824
14463
|
setPhase("spt-flow");
|
|
13825
14464
|
}
|
|
13826
14465
|
});
|
|
13827
|
-
const onCardComplete =
|
|
14466
|
+
const onCardComplete = useCallback3(
|
|
13828
14467
|
(result) => {
|
|
13829
14468
|
setPaymentMethodId(result.paymentMethodId);
|
|
13830
14469
|
setCardSuccess(result.success);
|
|
@@ -13840,7 +14479,7 @@ var DemoRunner = ({
|
|
|
13840
14479
|
},
|
|
13841
14480
|
[runSpt, onComplete, exit]
|
|
13842
14481
|
);
|
|
13843
|
-
const onSptComplete =
|
|
14482
|
+
const onSptComplete = useCallback3(
|
|
13844
14483
|
(success) => {
|
|
13845
14484
|
setSptSuccess(success);
|
|
13846
14485
|
setPhase("summary");
|
|
@@ -13851,12 +14490,12 @@ var DemoRunner = ({
|
|
|
13851
14490
|
},
|
|
13852
14491
|
[onComplete, exit]
|
|
13853
14492
|
);
|
|
13854
|
-
return /* @__PURE__ */
|
|
13855
|
-
/* @__PURE__ */
|
|
13856
|
-
/* @__PURE__ */
|
|
13857
|
-
/* @__PURE__ */
|
|
14493
|
+
return /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", gap: 1, children: [
|
|
14494
|
+
/* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
14495
|
+
/* @__PURE__ */ jsx12(Text11, { bold: true, children: DEMO_MENU.title }),
|
|
14496
|
+
/* @__PURE__ */ jsx12(Text11, { children: DEMO_MENU.subtitle })
|
|
13858
14497
|
] }),
|
|
13859
|
-
phase === "auth" && /* @__PURE__ */
|
|
14498
|
+
phase === "auth" && /* @__PURE__ */ jsx12(
|
|
13860
14499
|
Login,
|
|
13861
14500
|
{
|
|
13862
14501
|
authResource: authRepo2,
|
|
@@ -13865,25 +14504,25 @@ var DemoRunner = ({
|
|
|
13865
14504
|
onComplete: () => setPhase(postAuthPhase)
|
|
13866
14505
|
}
|
|
13867
14506
|
),
|
|
13868
|
-
phase === "menu" && /* @__PURE__ */
|
|
13869
|
-
/* @__PURE__ */
|
|
13870
|
-
/* @__PURE__ */
|
|
13871
|
-
/* @__PURE__ */
|
|
14507
|
+
phase === "menu" && /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
14508
|
+
/* @__PURE__ */ jsx12(Text11, { children: DEMO_MENU.question }),
|
|
14509
|
+
/* @__PURE__ */ jsx12(Box9, { flexDirection: "column", marginTop: 1, gap: 1, children: DEMO_MENU.options.map((opt, i) => /* @__PURE__ */ jsx12(Box9, { flexDirection: "column", children: i === menuIndex ? /* @__PURE__ */ jsxs9(Fragment3, { children: [
|
|
14510
|
+
/* @__PURE__ */ jsxs9(Text11, { color: "cyan", bold: true, children: [
|
|
13872
14511
|
">",
|
|
13873
14512
|
" ",
|
|
13874
14513
|
opt.label
|
|
13875
14514
|
] }),
|
|
13876
|
-
/* @__PURE__ */
|
|
14515
|
+
/* @__PURE__ */ jsxs9(Text11, { color: "cyan", children: [
|
|
13877
14516
|
" ",
|
|
13878
14517
|
opt.description
|
|
13879
14518
|
] })
|
|
13880
|
-
] }) : /* @__PURE__ */
|
|
14519
|
+
] }) : /* @__PURE__ */ jsxs9(Text11, { dimColor: true, children: [
|
|
13881
14520
|
" ",
|
|
13882
14521
|
opt.label
|
|
13883
14522
|
] }) }, opt.key)) }),
|
|
13884
|
-
/* @__PURE__ */
|
|
14523
|
+
/* @__PURE__ */ jsx12(Box9, { marginTop: 1, children: /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: DEMO_MENU.hint }) })
|
|
13885
14524
|
] }),
|
|
13886
|
-
runCard && phase !== "menu" && /* @__PURE__ */
|
|
14525
|
+
runCard && phase !== "menu" && /* @__PURE__ */ jsx12(
|
|
13887
14526
|
CardFlow,
|
|
13888
14527
|
{
|
|
13889
14528
|
spendRequestRepo: spendRequestRepo2,
|
|
@@ -13892,19 +14531,19 @@ var DemoRunner = ({
|
|
|
13892
14531
|
onComplete: onCardComplete
|
|
13893
14532
|
}
|
|
13894
14533
|
),
|
|
13895
|
-
phase === "card-done" && /* @__PURE__ */
|
|
13896
|
-
/* @__PURE__ */
|
|
13897
|
-
/* @__PURE__ */
|
|
13898
|
-
/* @__PURE__ */
|
|
14534
|
+
phase === "card-done" && /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
14535
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "\u2500\u2500\u2500" }),
|
|
14536
|
+
/* @__PURE__ */ jsx12(MarkdownText, { children: DEMO_MENU.transition }),
|
|
14537
|
+
/* @__PURE__ */ jsxs9(Text11, { dimColor: true, children: [
|
|
13899
14538
|
"\n",
|
|
13900
14539
|
">",
|
|
13901
14540
|
" ",
|
|
13902
14541
|
DEMO_MENU.transitionPrompt
|
|
13903
14542
|
] })
|
|
13904
14543
|
] }),
|
|
13905
|
-
runSpt && (phase === "spt-flow" || phase === "summary") && /* @__PURE__ */
|
|
13906
|
-
runCard && /* @__PURE__ */
|
|
13907
|
-
/* @__PURE__ */
|
|
14544
|
+
runSpt && (phase === "spt-flow" || phase === "summary") && /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
14545
|
+
runCard && /* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "\u2500\u2500\u2500" }),
|
|
14546
|
+
/* @__PURE__ */ jsx12(
|
|
13908
14547
|
SptFlow,
|
|
13909
14548
|
{
|
|
13910
14549
|
spendRequestRepo: spendRequestRepo2,
|
|
@@ -13914,30 +14553,30 @@ var DemoRunner = ({
|
|
|
13914
14553
|
}
|
|
13915
14554
|
)
|
|
13916
14555
|
] }),
|
|
13917
|
-
phase === "summary" && /* @__PURE__ */
|
|
13918
|
-
/* @__PURE__ */
|
|
13919
|
-
/* @__PURE__ */
|
|
13920
|
-
cardSuccess !== null && /* @__PURE__ */
|
|
14556
|
+
phase === "summary" && /* @__PURE__ */ jsxs9(Box9, { flexDirection: "column", children: [
|
|
14557
|
+
/* @__PURE__ */ jsx12(Text11, { dimColor: true, children: "\u2500\u2500\u2500" }),
|
|
14558
|
+
/* @__PURE__ */ jsx12(Text11, { bold: true, children: "Done!" }),
|
|
14559
|
+
cardSuccess !== null && /* @__PURE__ */ jsxs9(Text11, { color: cardSuccess ? "green" : "red", children: [
|
|
13921
14560
|
cardSuccess ? "\u2713" : "\u2717",
|
|
13922
14561
|
" Virtual card flow"
|
|
13923
14562
|
] }),
|
|
13924
|
-
sptSuccess !== null && /* @__PURE__ */
|
|
14563
|
+
sptSuccess !== null && /* @__PURE__ */ jsxs9(Text11, { color: sptSuccess ? "green" : "red", children: [
|
|
13925
14564
|
sptSuccess ? "\u2713" : "\u2717",
|
|
13926
14565
|
" Machine payment flow"
|
|
13927
14566
|
] }),
|
|
13928
|
-
/* @__PURE__ */
|
|
14567
|
+
/* @__PURE__ */ jsx12(AppDownloadQrCodes, {})
|
|
13929
14568
|
] })
|
|
13930
14569
|
] });
|
|
13931
14570
|
};
|
|
13932
14571
|
|
|
13933
14572
|
// src/commands/demo/index.tsx
|
|
13934
|
-
import { jsx as
|
|
13935
|
-
var demoOptions =
|
|
13936
|
-
onlyCard:
|
|
13937
|
-
onlySpt:
|
|
14573
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
14574
|
+
var demoOptions = z3.object({
|
|
14575
|
+
onlyCard: z3.boolean().default(false).describe("Run only the virtual card flow"),
|
|
14576
|
+
onlySpt: z3.boolean().default(false).describe("Run only the machine payment (SPT) flow")
|
|
13938
14577
|
});
|
|
13939
14578
|
function createDemoCli(authRepo2, spendRequestRepo2, createPaymentMethodsResource, authStorage2) {
|
|
13940
|
-
return
|
|
14579
|
+
return Cli3.create("demo", {
|
|
13941
14580
|
description: "Run an interactive demo of both Link payment flows (virtual card + machine payment)",
|
|
13942
14581
|
options: demoOptions,
|
|
13943
14582
|
outputPolicy: "agent-only",
|
|
@@ -13950,7 +14589,7 @@ function createDemoCli(authRepo2, spendRequestRepo2, createPaymentMethodsResourc
|
|
|
13950
14589
|
}
|
|
13951
14590
|
const paymentMethodsResource = createPaymentMethodsResource();
|
|
13952
14591
|
return renderInteractive(
|
|
13953
|
-
/* @__PURE__ */
|
|
14592
|
+
/* @__PURE__ */ jsx13(
|
|
13954
14593
|
DemoRunner,
|
|
13955
14594
|
{
|
|
13956
14595
|
authRepo: authRepo2,
|
|
@@ -13970,85 +14609,61 @@ function createDemoCli(authRepo2, spendRequestRepo2, createPaymentMethodsResourc
|
|
|
13970
14609
|
}
|
|
13971
14610
|
|
|
13972
14611
|
// src/commands/mpp/index.tsx
|
|
13973
|
-
import { Cli as
|
|
13974
|
-
|
|
13975
|
-
// src/utils/require-auth.ts
|
|
13976
|
-
var NOT_AUTHENTICATED_ERROR = {
|
|
13977
|
-
code: "NOT_AUTHENTICATED",
|
|
13978
|
-
message: 'Not authenticated. Run "link-cli auth login" first.',
|
|
13979
|
-
cta: {
|
|
13980
|
-
commands: [{ command: "auth login", description: "Log in to Link" }]
|
|
13981
|
-
}
|
|
13982
|
-
};
|
|
13983
|
-
function requireAuth(authStorage2, envAccessToken2) {
|
|
13984
|
-
const store = authStorage2 ?? storage;
|
|
13985
|
-
return (c, next) => {
|
|
13986
|
-
if (!envAccessToken2 && !store.isAuthenticated()) {
|
|
13987
|
-
return c.error(NOT_AUTHENTICATED_ERROR);
|
|
13988
|
-
}
|
|
13989
|
-
return next();
|
|
13990
|
-
};
|
|
13991
|
-
}
|
|
13992
|
-
function requireAuthGuard(c, authStorage2, envAccessToken2) {
|
|
13993
|
-
const store = authStorage2 ?? storage;
|
|
13994
|
-
if (!envAccessToken2 && !store.isAuthenticated()) {
|
|
13995
|
-
c.error(NOT_AUTHENTICATED_ERROR);
|
|
13996
|
-
}
|
|
13997
|
-
}
|
|
14612
|
+
import { Cli as Cli4, z as z5 } from "incur";
|
|
13998
14613
|
|
|
13999
14614
|
// src/commands/mpp/decode-view.tsx
|
|
14000
|
-
import { Box as
|
|
14001
|
-
import { jsx as
|
|
14615
|
+
import { Box as Box10, Text as Text12 } from "ink";
|
|
14616
|
+
import { jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
14002
14617
|
function DecodeChallengeView({
|
|
14003
14618
|
decoded
|
|
14004
14619
|
}) {
|
|
14005
|
-
return /* @__PURE__ */
|
|
14006
|
-
/* @__PURE__ */
|
|
14007
|
-
/* @__PURE__ */
|
|
14008
|
-
/* @__PURE__ */
|
|
14620
|
+
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", children: [
|
|
14621
|
+
/* @__PURE__ */ jsx14(Text12, { color: "green", children: "\u2713 Stripe challenge decoded" }),
|
|
14622
|
+
/* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
|
|
14623
|
+
/* @__PURE__ */ jsxs10(Text12, { children: [
|
|
14009
14624
|
"ID: ",
|
|
14010
|
-
/* @__PURE__ */
|
|
14625
|
+
/* @__PURE__ */ jsx14(Text12, { bold: true, children: decoded.id })
|
|
14011
14626
|
] }),
|
|
14012
|
-
/* @__PURE__ */
|
|
14627
|
+
/* @__PURE__ */ jsxs10(Text12, { children: [
|
|
14013
14628
|
"Realm: ",
|
|
14014
|
-
/* @__PURE__ */
|
|
14629
|
+
/* @__PURE__ */ jsx14(Text12, { bold: true, children: decoded.realm })
|
|
14015
14630
|
] }),
|
|
14016
|
-
/* @__PURE__ */
|
|
14631
|
+
/* @__PURE__ */ jsxs10(Text12, { children: [
|
|
14017
14632
|
"Network ID: ",
|
|
14018
|
-
/* @__PURE__ */
|
|
14633
|
+
/* @__PURE__ */ jsx14(Text12, { bold: true, children: decoded.network_id })
|
|
14019
14634
|
] }),
|
|
14020
|
-
/* @__PURE__ */
|
|
14021
|
-
/* @__PURE__ */
|
|
14635
|
+
/* @__PURE__ */ jsx14(Text12, { children: "Request JSON:" }),
|
|
14636
|
+
/* @__PURE__ */ jsx14(Text12, { children: JSON.stringify(decoded.request_json, null, 2) })
|
|
14022
14637
|
] })
|
|
14023
14638
|
] });
|
|
14024
14639
|
}
|
|
14025
14640
|
|
|
14026
14641
|
// src/commands/mpp/schema.ts
|
|
14027
|
-
import { z as
|
|
14028
|
-
var payOptions =
|
|
14029
|
-
spendRequestId:
|
|
14642
|
+
import { z as z4 } from "incur";
|
|
14643
|
+
var payOptions = z4.object({
|
|
14644
|
+
spendRequestId: z4.string().describe(
|
|
14030
14645
|
'Approved spend request ID with credential_type "shared_payment_token"'
|
|
14031
14646
|
),
|
|
14032
|
-
method:
|
|
14033
|
-
data:
|
|
14034
|
-
header:
|
|
14647
|
+
method: z4.string().optional().describe("HTTP method (default: GET, or POST if --data is provided)"),
|
|
14648
|
+
data: z4.string().optional().describe("Request body (implies POST if --method is not set)"),
|
|
14649
|
+
header: z4.array(z4.string()).default([]).describe('Request header in "Name: Value" format (repeatable)')
|
|
14035
14650
|
});
|
|
14036
|
-
var decodeOptions =
|
|
14037
|
-
challenge:
|
|
14651
|
+
var decodeOptions = z4.object({
|
|
14652
|
+
challenge: z4.string().describe(
|
|
14038
14653
|
"Raw WWW-Authenticate header value; may include multiple payment challenges"
|
|
14039
14654
|
)
|
|
14040
14655
|
});
|
|
14041
14656
|
|
|
14042
14657
|
// src/commands/mpp/index.tsx
|
|
14043
|
-
import { jsx as
|
|
14658
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
14044
14659
|
function createMppCli(repository, authStorage2, envAccessToken2) {
|
|
14045
|
-
const cli2 =
|
|
14660
|
+
const cli2 = Cli4.create("mpp", {
|
|
14046
14661
|
description: "Machine payment protocol (MPP) commands"
|
|
14047
14662
|
});
|
|
14048
14663
|
cli2.command("pay", {
|
|
14049
14664
|
description: "Complete a machine payment protocol (MPP) payment using an approved spend request",
|
|
14050
|
-
args:
|
|
14051
|
-
url:
|
|
14665
|
+
args: z5.object({
|
|
14666
|
+
url: z5.string().describe("URL to pay")
|
|
14052
14667
|
}),
|
|
14053
14668
|
options: payOptions,
|
|
14054
14669
|
alias: { method: "X", data: "d", header: "H" },
|
|
@@ -14063,7 +14678,7 @@ function createMppCli(repository, authStorage2, envAccessToken2) {
|
|
|
14063
14678
|
if (!c.agent && !c.formatExplicit) {
|
|
14064
14679
|
let capturedResult = null;
|
|
14065
14680
|
return renderInteractive(
|
|
14066
|
-
/* @__PURE__ */
|
|
14681
|
+
/* @__PURE__ */ jsx15(
|
|
14067
14682
|
MppPay,
|
|
14068
14683
|
{
|
|
14069
14684
|
url,
|
|
@@ -14102,7 +14717,7 @@ function createMppCli(repository, authStorage2, envAccessToken2) {
|
|
|
14102
14717
|
const decoded = decodeStripeChallenge(c.options.challenge);
|
|
14103
14718
|
if (!c.agent && !c.formatExplicit) {
|
|
14104
14719
|
return renderInteractive(
|
|
14105
|
-
/* @__PURE__ */
|
|
14720
|
+
/* @__PURE__ */ jsx15(DecodeChallengeView, { decoded }),
|
|
14106
14721
|
() => decoded
|
|
14107
14722
|
);
|
|
14108
14723
|
}
|
|
@@ -14113,12 +14728,12 @@ function createMppCli(repository, authStorage2, envAccessToken2) {
|
|
|
14113
14728
|
}
|
|
14114
14729
|
|
|
14115
14730
|
// src/commands/onboard/index.tsx
|
|
14116
|
-
import { Cli as
|
|
14731
|
+
import { Cli as Cli5 } from "incur";
|
|
14117
14732
|
|
|
14118
14733
|
// src/commands/onboard/onboard-runner.tsx
|
|
14119
|
-
import { Box as
|
|
14734
|
+
import { Box as Box11, Text as Text13, useApp as useApp2, useInput as useInput5 } from "ink";
|
|
14120
14735
|
import { useEffect as useEffect7, useRef as useRef4, useState as useState8 } from "react";
|
|
14121
|
-
import { jsx as
|
|
14736
|
+
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
14122
14737
|
var OnboardRunner = ({
|
|
14123
14738
|
authRepo: authRepo2,
|
|
14124
14739
|
spendRequestRepo: spendRequestRepo2,
|
|
@@ -14184,21 +14799,21 @@ var OnboardRunner = ({
|
|
|
14184
14799
|
const order = ["welcome", "auth", "payment-methods", "demo"];
|
|
14185
14800
|
return order.indexOf(phase) > order.indexOf(target);
|
|
14186
14801
|
};
|
|
14187
|
-
const prompt = (label = "Press [Enter] to continue") => /* @__PURE__ */
|
|
14802
|
+
const prompt = (label = "Press [Enter] to continue") => /* @__PURE__ */ jsxs11(Text13, { dimColor: true, children: [
|
|
14188
14803
|
"\n",
|
|
14189
14804
|
">",
|
|
14190
14805
|
" ",
|
|
14191
14806
|
label
|
|
14192
14807
|
] });
|
|
14193
|
-
return /* @__PURE__ */
|
|
14194
|
-
/* @__PURE__ */
|
|
14195
|
-
/* @__PURE__ */
|
|
14196
|
-
/* @__PURE__ */
|
|
14808
|
+
return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", gap: 1, children: [
|
|
14809
|
+
/* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
|
|
14810
|
+
/* @__PURE__ */ jsx16(Text13, { bold: true, children: ONBOARD.title }),
|
|
14811
|
+
/* @__PURE__ */ jsx16(Text13, { children: ONBOARD.subtitle })
|
|
14197
14812
|
] }),
|
|
14198
|
-
/* @__PURE__ */
|
|
14813
|
+
/* @__PURE__ */ jsx16(Box11, { flexDirection: "column", children: authSkipped || pastPhase("auth") ? /* @__PURE__ */ jsxs11(Text13, { color: "green", children: [
|
|
14199
14814
|
"\u2713 ",
|
|
14200
14815
|
authSkipped ? ONBOARD.auth.alreadyLoggedIn : ONBOARD.auth.authenticated
|
|
14201
|
-
] }) : phase === "auth" && !storage2.isAuthenticated() ? /* @__PURE__ */
|
|
14816
|
+
] }) : phase === "auth" && !storage2.isAuthenticated() ? /* @__PURE__ */ jsx16(
|
|
14202
14817
|
Login,
|
|
14203
14818
|
{
|
|
14204
14819
|
authResource: authRepo2,
|
|
@@ -14207,24 +14822,24 @@ var OnboardRunner = ({
|
|
|
14207
14822
|
onComplete: () => authResolver.current?.()
|
|
14208
14823
|
}
|
|
14209
14824
|
) : null }),
|
|
14210
|
-
pastPhase("auth") && /* @__PURE__ */
|
|
14211
|
-
phase === "payment-methods" && !pmMissing && /* @__PURE__ */
|
|
14212
|
-
pmMissing && /* @__PURE__ */
|
|
14213
|
-
/* @__PURE__ */
|
|
14214
|
-
/* @__PURE__ */
|
|
14825
|
+
pastPhase("auth") && /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
|
|
14826
|
+
phase === "payment-methods" && !pmMissing && /* @__PURE__ */ jsx16(Text13, { color: "cyan", children: ONBOARD.paymentMethods.loading }),
|
|
14827
|
+
pmMissing && /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
|
|
14828
|
+
/* @__PURE__ */ jsx16(Text13, { color: "yellow", children: ONBOARD.paymentMethods.missing }),
|
|
14829
|
+
/* @__PURE__ */ jsx16(Box11, { marginTop: 1, children: /* @__PURE__ */ jsxs11(Text13, { children: [
|
|
14215
14830
|
"Visit",
|
|
14216
14831
|
" ",
|
|
14217
|
-
/* @__PURE__ */
|
|
14832
|
+
/* @__PURE__ */ jsx16(Text13, { bold: true, color: "cyan", children: "app.link.com/wallet" }),
|
|
14218
14833
|
" ",
|
|
14219
14834
|
"to add a payment method, then press [Enter] to continue."
|
|
14220
14835
|
] }) }),
|
|
14221
14836
|
prompt(ONBOARD.paymentMethods.retryPrompt)
|
|
14222
14837
|
] }),
|
|
14223
|
-
pastPhase("payment-methods") && /* @__PURE__ */
|
|
14838
|
+
pastPhase("payment-methods") && /* @__PURE__ */ jsx16(Text13, { color: "green", children: "\u2713 Payment method found" })
|
|
14224
14839
|
] }),
|
|
14225
|
-
phase === "demo" && /* @__PURE__ */
|
|
14226
|
-
/* @__PURE__ */
|
|
14227
|
-
/* @__PURE__ */
|
|
14840
|
+
phase === "demo" && /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", children: [
|
|
14841
|
+
/* @__PURE__ */ jsx16(Text13, { dimColor: true, children: "\u2500\u2500\u2500" }),
|
|
14842
|
+
/* @__PURE__ */ jsx16(
|
|
14228
14843
|
DemoRunner,
|
|
14229
14844
|
{
|
|
14230
14845
|
authRepo: authRepo2,
|
|
@@ -14235,7 +14850,7 @@ var OnboardRunner = ({
|
|
|
14235
14850
|
}
|
|
14236
14851
|
)
|
|
14237
14852
|
] }),
|
|
14238
|
-
error && /* @__PURE__ */
|
|
14853
|
+
error && /* @__PURE__ */ jsxs11(Text13, { color: "red", children: [
|
|
14239
14854
|
"Error: ",
|
|
14240
14855
|
error
|
|
14241
14856
|
] })
|
|
@@ -14243,9 +14858,9 @@ var OnboardRunner = ({
|
|
|
14243
14858
|
};
|
|
14244
14859
|
|
|
14245
14860
|
// src/commands/onboard/index.tsx
|
|
14246
|
-
import { jsx as
|
|
14861
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
14247
14862
|
function createOnboardCli(authRepo2, spendRequestRepo2, createPaymentMethodsResource, authStorage2) {
|
|
14248
|
-
return
|
|
14863
|
+
return Cli5.create("onboard", {
|
|
14249
14864
|
description: "Guided setup: authenticate, verify payment methods, and demo both payment flows",
|
|
14250
14865
|
outputPolicy: "agent-only",
|
|
14251
14866
|
async run(c) {
|
|
@@ -14257,7 +14872,7 @@ function createOnboardCli(authRepo2, spendRequestRepo2, createPaymentMethodsReso
|
|
|
14257
14872
|
}
|
|
14258
14873
|
const paymentMethodsResource = createPaymentMethodsResource();
|
|
14259
14874
|
return renderInteractive(
|
|
14260
|
-
/* @__PURE__ */
|
|
14875
|
+
/* @__PURE__ */ jsx17(
|
|
14261
14876
|
OnboardRunner,
|
|
14262
14877
|
{
|
|
14263
14878
|
authRepo: authRepo2,
|
|
@@ -14275,11 +14890,11 @@ function createOnboardCli(authRepo2, spendRequestRepo2, createPaymentMethodsReso
|
|
|
14275
14890
|
}
|
|
14276
14891
|
|
|
14277
14892
|
// src/commands/payment-methods/index.tsx
|
|
14278
|
-
import { Cli as
|
|
14893
|
+
import { Cli as Cli6 } from "incur";
|
|
14279
14894
|
|
|
14280
14895
|
// src/commands/payment-methods/add.tsx
|
|
14281
|
-
import { Box as
|
|
14282
|
-
import { jsx as
|
|
14896
|
+
import { Box as Box12, Text as Text14, useApp as useApp3, useInput as useInput6 } from "ink";
|
|
14897
|
+
import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
14283
14898
|
var WALLET_URL = "https://app.link.com/wallet";
|
|
14284
14899
|
var AddPaymentMethod = () => {
|
|
14285
14900
|
const { exit } = useApp3();
|
|
@@ -14289,10 +14904,10 @@ var AddPaymentMethod = () => {
|
|
|
14289
14904
|
exit();
|
|
14290
14905
|
}
|
|
14291
14906
|
});
|
|
14292
|
-
return /* @__PURE__ */
|
|
14293
|
-
/* @__PURE__ */
|
|
14294
|
-
/* @__PURE__ */
|
|
14295
|
-
|
|
14907
|
+
return /* @__PURE__ */ jsxs12(Box12, { flexDirection: "column", paddingY: 1, children: [
|
|
14908
|
+
/* @__PURE__ */ jsx18(Box12, { marginBottom: 1, children: /* @__PURE__ */ jsx18(Text14, { bold: true, children: "Add Payment Method" }) }),
|
|
14909
|
+
/* @__PURE__ */ jsxs12(
|
|
14910
|
+
Box12,
|
|
14296
14911
|
{
|
|
14297
14912
|
flexDirection: "column",
|
|
14298
14913
|
borderStyle: "round",
|
|
@@ -14300,12 +14915,12 @@ var AddPaymentMethod = () => {
|
|
|
14300
14915
|
paddingX: 2,
|
|
14301
14916
|
paddingY: 1,
|
|
14302
14917
|
children: [
|
|
14303
|
-
/* @__PURE__ */
|
|
14918
|
+
/* @__PURE__ */ jsxs12(Text14, { children: [
|
|
14304
14919
|
"Open:",
|
|
14305
14920
|
" ",
|
|
14306
|
-
/* @__PURE__ */
|
|
14921
|
+
/* @__PURE__ */ jsx18(Text14, { bold: true, color: "cyan", children: WALLET_URL })
|
|
14307
14922
|
] }),
|
|
14308
|
-
/* @__PURE__ */
|
|
14923
|
+
/* @__PURE__ */ jsx18(Text14, { dimColor: true, children: "Press Enter to open in browser" })
|
|
14309
14924
|
]
|
|
14310
14925
|
}
|
|
14311
14926
|
)
|
|
@@ -14313,48 +14928,48 @@ var AddPaymentMethod = () => {
|
|
|
14313
14928
|
};
|
|
14314
14929
|
|
|
14315
14930
|
// src/commands/payment-methods/list.tsx
|
|
14316
|
-
import { Box as
|
|
14317
|
-
import
|
|
14318
|
-
import { useCallback as
|
|
14319
|
-
import { jsx as
|
|
14931
|
+
import { Box as Box13, Text as Text15 } from "ink";
|
|
14932
|
+
import Spinner5 from "ink-spinner";
|
|
14933
|
+
import { useCallback as useCallback4 } from "react";
|
|
14934
|
+
import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
14320
14935
|
var PaymentMethodsList = ({
|
|
14321
14936
|
resource,
|
|
14322
14937
|
onComplete
|
|
14323
14938
|
}) => {
|
|
14324
|
-
const action =
|
|
14939
|
+
const action = useCallback4(() => resource.listPaymentMethods(), [resource]);
|
|
14325
14940
|
const { status, data: methods, error } = useAsyncAction(action, onComplete);
|
|
14326
14941
|
if (status === "loading") {
|
|
14327
|
-
return /* @__PURE__ */
|
|
14328
|
-
/* @__PURE__ */
|
|
14942
|
+
return /* @__PURE__ */ jsx19(Box13, { children: /* @__PURE__ */ jsxs13(Text15, { color: "cyan", children: [
|
|
14943
|
+
/* @__PURE__ */ jsx19(Spinner5, { type: "dots" }),
|
|
14329
14944
|
" Loading payment methods..."
|
|
14330
14945
|
] }) });
|
|
14331
14946
|
}
|
|
14332
14947
|
if (status === "error") {
|
|
14333
|
-
return /* @__PURE__ */
|
|
14334
|
-
/* @__PURE__ */
|
|
14335
|
-
/* @__PURE__ */
|
|
14948
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", children: [
|
|
14949
|
+
/* @__PURE__ */ jsx19(Text15, { color: "red", children: "\u2717 Failed to load payment methods" }),
|
|
14950
|
+
/* @__PURE__ */ jsx19(Text15, { color: "red", children: error })
|
|
14336
14951
|
] });
|
|
14337
14952
|
}
|
|
14338
14953
|
if (!methods || methods.length === 0) {
|
|
14339
|
-
return /* @__PURE__ */
|
|
14954
|
+
return /* @__PURE__ */ jsx19(Box13, { children: /* @__PURE__ */ jsx19(Text15, { dimColor: true, children: "No payment methods found" }) });
|
|
14340
14955
|
}
|
|
14341
|
-
return /* @__PURE__ */
|
|
14342
|
-
/* @__PURE__ */
|
|
14343
|
-
/* @__PURE__ */
|
|
14956
|
+
return /* @__PURE__ */ jsxs13(Box13, { flexDirection: "column", children: [
|
|
14957
|
+
/* @__PURE__ */ jsx19(Text15, { bold: true, children: "Payment Methods" }),
|
|
14958
|
+
/* @__PURE__ */ jsx19(Box13, { flexDirection: "column", marginTop: 1, children: methods.map((pm) => {
|
|
14344
14959
|
const label = pm.card_details?.brand ?? pm.bank_account_details?.bank_name ?? "Bank account";
|
|
14345
14960
|
const last4 = pm.card_details?.last4 ?? pm.bank_account_details?.last4;
|
|
14346
14961
|
const suffix = pm.nickname ? `(${pm.nickname})` : "";
|
|
14347
14962
|
const agenticCap = pm.capabilities?.agentic_payments;
|
|
14348
14963
|
const ineligible = agenticCap && !agenticCap.eligible;
|
|
14349
|
-
return /* @__PURE__ */
|
|
14350
|
-
/* @__PURE__ */
|
|
14964
|
+
return /* @__PURE__ */ jsx19(Box13, { paddingX: 2, children: /* @__PURE__ */ jsxs13(Text15, { children: [
|
|
14965
|
+
/* @__PURE__ */ jsx19(Text15, { dimColor: true, children: pm.id }),
|
|
14351
14966
|
" ",
|
|
14352
14967
|
label,
|
|
14353
14968
|
" ****",
|
|
14354
14969
|
last4,
|
|
14355
14970
|
suffix ? ` ${suffix}` : "",
|
|
14356
|
-
pm.is_default ? /* @__PURE__ */
|
|
14357
|
-
ineligible ? /* @__PURE__ */
|
|
14971
|
+
pm.is_default ? /* @__PURE__ */ jsx19(Text15, { color: "green", children: " (default)" }) : "",
|
|
14972
|
+
ineligible ? /* @__PURE__ */ jsxs13(Text15, { dimColor: true, children: [
|
|
14358
14973
|
" ",
|
|
14359
14974
|
"agentic_payments: ineligible",
|
|
14360
14975
|
agenticCap.ineligibility_reasons?.length > 0 ? ` (${agenticCap.ineligibility_reasons.join(", ")})` : ""
|
|
@@ -14365,9 +14980,9 @@ var PaymentMethodsList = ({
|
|
|
14365
14980
|
};
|
|
14366
14981
|
|
|
14367
14982
|
// src/commands/payment-methods/index.tsx
|
|
14368
|
-
import { jsx as
|
|
14983
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
14369
14984
|
function createPaymentMethodsCli(createResource, authStorage2, envAccessToken2) {
|
|
14370
|
-
const cli2 =
|
|
14985
|
+
const cli2 = Cli6.create("payment-methods", {
|
|
14371
14986
|
description: "Payment methods management commands"
|
|
14372
14987
|
});
|
|
14373
14988
|
cli2.command("list", {
|
|
@@ -14378,7 +14993,7 @@ function createPaymentMethodsCli(createResource, authStorage2, envAccessToken2)
|
|
|
14378
14993
|
const resource = createResource();
|
|
14379
14994
|
if (!c.agent && !c.formatExplicit) {
|
|
14380
14995
|
return renderInteractive(
|
|
14381
|
-
/* @__PURE__ */
|
|
14996
|
+
/* @__PURE__ */ jsx20(PaymentMethodsList, { resource, onComplete: () => {
|
|
14382
14997
|
} }),
|
|
14383
14998
|
() => resource.listPaymentMethods()
|
|
14384
14999
|
);
|
|
@@ -14392,7 +15007,7 @@ function createPaymentMethodsCli(createResource, authStorage2, envAccessToken2)
|
|
|
14392
15007
|
middleware: [requireAuth(authStorage2, envAccessToken2)],
|
|
14393
15008
|
async run(c) {
|
|
14394
15009
|
if (!c.agent && !c.formatExplicit) {
|
|
14395
|
-
return renderInteractive(/* @__PURE__ */
|
|
15010
|
+
return renderInteractive(/* @__PURE__ */ jsx20(AddPaymentMethod, {}), () => ({
|
|
14396
15011
|
url: WALLET_URL
|
|
14397
15012
|
}));
|
|
14398
15013
|
}
|
|
@@ -14403,22 +15018,22 @@ function createPaymentMethodsCli(createResource, authStorage2, envAccessToken2)
|
|
|
14403
15018
|
}
|
|
14404
15019
|
|
|
14405
15020
|
// src/commands/report/index.tsx
|
|
14406
|
-
import { Cli as
|
|
15021
|
+
import { Cli as Cli7 } from "incur";
|
|
14407
15022
|
|
|
14408
15023
|
// src/commands/report/schema.ts
|
|
14409
|
-
import { z as
|
|
14410
|
-
var reportOptions =
|
|
14411
|
-
domain:
|
|
14412
|
-
outcome:
|
|
14413
|
-
spendRequestId:
|
|
14414
|
-
tag:
|
|
14415
|
-
step:
|
|
14416
|
-
freeformContext:
|
|
15024
|
+
import { z as z6 } from "incur";
|
|
15025
|
+
var reportOptions = z6.object({
|
|
15026
|
+
domain: z6.string().describe("Domain where the outcome occurred"),
|
|
15027
|
+
outcome: z6.enum(REPORT_OUTCOMES).describe("What happened: success, blocked, or abandoned"),
|
|
15028
|
+
spendRequestId: z6.string().describe("Spend request ID (lsrq_...)"),
|
|
15029
|
+
tag: z6.array(z6.enum(REPORT_TAGS)).optional().describe("Outcome tags (repeatable)"),
|
|
15030
|
+
step: z6.string().max(500).optional().describe("Where in the flow the agent was"),
|
|
15031
|
+
freeformContext: z6.string().max(500).optional().describe("Additional context (max 500 chars)")
|
|
14417
15032
|
});
|
|
14418
15033
|
|
|
14419
15034
|
// src/commands/report/index.tsx
|
|
14420
15035
|
function createReportCli(createResource, authStorage2, envAccessToken2) {
|
|
14421
|
-
const cli2 =
|
|
15036
|
+
const cli2 = Cli7.create("report", {
|
|
14422
15037
|
description: "Report the outcome of an agent action on a domain. Call after every purchase attempt.",
|
|
14423
15038
|
options: reportOptions,
|
|
14424
15039
|
outputPolicy: "agent-only",
|
|
@@ -14443,7 +15058,7 @@ function createReportCli(createResource, authStorage2, envAccessToken2) {
|
|
|
14443
15058
|
import {
|
|
14444
15059
|
createServer
|
|
14445
15060
|
} from "http";
|
|
14446
|
-
import { Cli as
|
|
15061
|
+
import { Cli as Cli8, z as z7 } from "incur";
|
|
14447
15062
|
async function nodeRequestToWebRequest(req, port) {
|
|
14448
15063
|
const body = await new Promise((resolve) => {
|
|
14449
15064
|
const chunks = [];
|
|
@@ -14469,10 +15084,10 @@ async function sendWebResponse(webRes, res) {
|
|
|
14469
15084
|
res.end(Buffer.from(buffer));
|
|
14470
15085
|
}
|
|
14471
15086
|
function createServeCli(rootCli) {
|
|
14472
|
-
return
|
|
15087
|
+
return Cli8.create("serve", {
|
|
14473
15088
|
description: "Start an HTTP server exposing link-cli as an MCP endpoint at /mcp",
|
|
14474
|
-
options:
|
|
14475
|
-
port:
|
|
15089
|
+
options: z7.object({
|
|
15090
|
+
port: z7.coerce.number().default(54321).describe("Port to listen on")
|
|
14476
15091
|
}),
|
|
14477
15092
|
async run(c) {
|
|
14478
15093
|
const { port } = c.options;
|
|
@@ -14517,13 +15132,13 @@ function createServeCli(rootCli) {
|
|
|
14517
15132
|
}
|
|
14518
15133
|
|
|
14519
15134
|
// src/commands/shipping-address/index.tsx
|
|
14520
|
-
import { Cli as
|
|
15135
|
+
import { Cli as Cli9 } from "incur";
|
|
14521
15136
|
|
|
14522
15137
|
// src/commands/shipping-address/list.tsx
|
|
14523
|
-
import { Box as
|
|
14524
|
-
import
|
|
14525
|
-
import { useCallback as
|
|
14526
|
-
import { jsx as
|
|
15138
|
+
import { Box as Box14, Text as Text16 } from "ink";
|
|
15139
|
+
import Spinner6 from "ink-spinner";
|
|
15140
|
+
import { useCallback as useCallback5 } from "react";
|
|
15141
|
+
import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
14527
15142
|
function formatStreetLine(address) {
|
|
14528
15143
|
const parts = [address.line_1, address.line_2].filter(Boolean);
|
|
14529
15144
|
return parts.length > 0 ? parts.join(", ") : null;
|
|
@@ -14555,7 +15170,7 @@ var ShippingAddressList = ({
|
|
|
14555
15170
|
resource,
|
|
14556
15171
|
onComplete
|
|
14557
15172
|
}) => {
|
|
14558
|
-
const action =
|
|
15173
|
+
const action = useCallback5(
|
|
14559
15174
|
() => resource.listShippingAddresses(),
|
|
14560
15175
|
[resource]
|
|
14561
15176
|
);
|
|
@@ -14565,40 +15180,40 @@ var ShippingAddressList = ({
|
|
|
14565
15180
|
error
|
|
14566
15181
|
} = useAsyncAction(action, onComplete);
|
|
14567
15182
|
if (status === "loading") {
|
|
14568
|
-
return /* @__PURE__ */
|
|
14569
|
-
/* @__PURE__ */
|
|
15183
|
+
return /* @__PURE__ */ jsx21(Box14, { children: /* @__PURE__ */ jsxs14(Text16, { color: "cyan", children: [
|
|
15184
|
+
/* @__PURE__ */ jsx21(Spinner6, { type: "dots" }),
|
|
14570
15185
|
" Loading shipping addresses..."
|
|
14571
15186
|
] }) });
|
|
14572
15187
|
}
|
|
14573
15188
|
if (status === "error") {
|
|
14574
|
-
return /* @__PURE__ */
|
|
14575
|
-
/* @__PURE__ */
|
|
14576
|
-
/* @__PURE__ */
|
|
15189
|
+
return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", children: [
|
|
15190
|
+
/* @__PURE__ */ jsx21(Text16, { color: "red", children: "\u2717 Failed to load shipping addresses" }),
|
|
15191
|
+
/* @__PURE__ */ jsx21(Text16, { color: "red", children: error })
|
|
14577
15192
|
] });
|
|
14578
15193
|
}
|
|
14579
15194
|
if (!shippingAddresses || shippingAddresses.length === 0) {
|
|
14580
|
-
return /* @__PURE__ */
|
|
15195
|
+
return /* @__PURE__ */ jsx21(Box14, { children: /* @__PURE__ */ jsx21(Text16, { dimColor: true, children: "No shipping addresses found" }) });
|
|
14581
15196
|
}
|
|
14582
|
-
return /* @__PURE__ */
|
|
14583
|
-
/* @__PURE__ */
|
|
14584
|
-
/* @__PURE__ */
|
|
15197
|
+
return /* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", children: [
|
|
15198
|
+
/* @__PURE__ */ jsx21(Text16, { bold: true, children: "Shipping Addresses" }),
|
|
15199
|
+
/* @__PURE__ */ jsx21(Box14, { flexDirection: "column", marginTop: 1, children: shippingAddresses.map((shippingAddress) => {
|
|
14585
15200
|
const addressName = shippingAddress.address?.name;
|
|
14586
15201
|
const nickname = shippingAddress.nickname ? ` (${shippingAddress.nickname})` : "";
|
|
14587
|
-
return /* @__PURE__ */
|
|
14588
|
-
|
|
15202
|
+
return /* @__PURE__ */ jsxs14(
|
|
15203
|
+
Box14,
|
|
14589
15204
|
{
|
|
14590
15205
|
flexDirection: "column",
|
|
14591
15206
|
paddingX: 2,
|
|
14592
15207
|
marginBottom: 1,
|
|
14593
15208
|
children: [
|
|
14594
|
-
/* @__PURE__ */
|
|
14595
|
-
/* @__PURE__ */
|
|
15209
|
+
/* @__PURE__ */ jsxs14(Text16, { children: [
|
|
15210
|
+
/* @__PURE__ */ jsx21(Text16, { dimColor: true, children: shippingAddress.id }),
|
|
14596
15211
|
nickname,
|
|
14597
|
-
shippingAddress.is_default ? /* @__PURE__ */
|
|
15212
|
+
shippingAddress.is_default ? /* @__PURE__ */ jsx21(Text16, { color: "green", children: " (default)" }) : null
|
|
14598
15213
|
] }),
|
|
14599
|
-
/* @__PURE__ */
|
|
14600
|
-
addressName ? /* @__PURE__ */
|
|
14601
|
-
formatAddressLines(shippingAddress).map((line) => /* @__PURE__ */
|
|
15214
|
+
/* @__PURE__ */ jsxs14(Box14, { flexDirection: "column", marginTop: 1, children: [
|
|
15215
|
+
addressName ? /* @__PURE__ */ jsx21(Text16, { bold: true, children: addressName }) : null,
|
|
15216
|
+
formatAddressLines(shippingAddress).map((line) => /* @__PURE__ */ jsx21(Text16, { children: line }, `${shippingAddress.id}:${line}`))
|
|
14602
15217
|
] })
|
|
14603
15218
|
]
|
|
14604
15219
|
},
|
|
@@ -14609,9 +15224,9 @@ var ShippingAddressList = ({
|
|
|
14609
15224
|
};
|
|
14610
15225
|
|
|
14611
15226
|
// src/commands/shipping-address/index.tsx
|
|
14612
|
-
import { jsx as
|
|
15227
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
14613
15228
|
function createShippingAddressCli(createResource, authStorage2, envAccessToken2) {
|
|
14614
|
-
const cli2 =
|
|
15229
|
+
const cli2 = Cli9.create("shipping-address", {
|
|
14615
15230
|
description: "Shipping address management commands"
|
|
14616
15231
|
});
|
|
14617
15232
|
cli2.command("list", {
|
|
@@ -14622,7 +15237,7 @@ function createShippingAddressCli(createResource, authStorage2, envAccessToken2)
|
|
|
14622
15237
|
const resource = createResource();
|
|
14623
15238
|
if (!c.agent && !c.formatExplicit) {
|
|
14624
15239
|
return renderInteractive(
|
|
14625
|
-
/* @__PURE__ */
|
|
15240
|
+
/* @__PURE__ */ jsx22(ShippingAddressList, { resource, onComplete: () => {
|
|
14626
15241
|
} }),
|
|
14627
15242
|
() => resource.listShippingAddresses()
|
|
14628
15243
|
);
|
|
@@ -14633,8 +15248,219 @@ function createShippingAddressCli(createResource, authStorage2, envAccessToken2)
|
|
|
14633
15248
|
return cli2;
|
|
14634
15249
|
}
|
|
14635
15250
|
|
|
15251
|
+
// src/commands/sources/index.tsx
|
|
15252
|
+
import { Cli as Cli10 } from "incur";
|
|
15253
|
+
|
|
15254
|
+
// src/commands/sources/list.tsx
|
|
15255
|
+
import { Box as Box15, Text as Text17 } from "ink";
|
|
15256
|
+
import Spinner7 from "ink-spinner";
|
|
15257
|
+
import { useCallback as useCallback6 } from "react";
|
|
15258
|
+
import { jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
15259
|
+
var COLUMN_GAP2 = " ";
|
|
15260
|
+
var HORIZONTAL_PADDING = 4;
|
|
15261
|
+
function truncateCell2(value, width) {
|
|
15262
|
+
if (value.length <= width) {
|
|
15263
|
+
return value;
|
|
15264
|
+
}
|
|
15265
|
+
if (width <= 3) {
|
|
15266
|
+
return value.slice(0, width);
|
|
15267
|
+
}
|
|
15268
|
+
return `${value.slice(0, width - 3)}...`;
|
|
15269
|
+
}
|
|
15270
|
+
function formatCell2(value, width) {
|
|
15271
|
+
return truncateCell2(value, width).padEnd(width);
|
|
15272
|
+
}
|
|
15273
|
+
function sourceId(source, index) {
|
|
15274
|
+
return typeof source.id === "string" && source.id.length > 0 ? source.id : `source-${index + 1}`;
|
|
15275
|
+
}
|
|
15276
|
+
function statusFromValue(value) {
|
|
15277
|
+
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
15278
|
+
const status = value.status;
|
|
15279
|
+
return typeof status === "string" ? status : null;
|
|
15280
|
+
}
|
|
15281
|
+
return null;
|
|
15282
|
+
}
|
|
15283
|
+
function formatCapabilities(source) {
|
|
15284
|
+
const capabilities = source.capabilities;
|
|
15285
|
+
if (!capabilities || typeof capabilities !== "object") {
|
|
15286
|
+
return "-";
|
|
15287
|
+
}
|
|
15288
|
+
const entries = Object.entries(capabilities).map(([capability, value]) => {
|
|
15289
|
+
const status = statusFromValue(value);
|
|
15290
|
+
return status ? `${capability}:${status}` : capability;
|
|
15291
|
+
}).sort();
|
|
15292
|
+
return entries.length > 0 ? entries.join(", ") : "-";
|
|
15293
|
+
}
|
|
15294
|
+
function formatExternalConnection(source) {
|
|
15295
|
+
const status = statusFromValue(source.external_connection);
|
|
15296
|
+
return status ?? "-";
|
|
15297
|
+
}
|
|
15298
|
+
function sourceRow(source, index) {
|
|
15299
|
+
const capabilities = formatCapabilities(source);
|
|
15300
|
+
const external = formatExternalConnection(source);
|
|
15301
|
+
return {
|
|
15302
|
+
key: sourceId(source, index),
|
|
15303
|
+
name: source.name ?? "Source",
|
|
15304
|
+
type: source.type ?? "-",
|
|
15305
|
+
id: sourceId(source, index),
|
|
15306
|
+
capabilities,
|
|
15307
|
+
external
|
|
15308
|
+
};
|
|
15309
|
+
}
|
|
15310
|
+
function tableColumns() {
|
|
15311
|
+
return [
|
|
15312
|
+
{ label: "Name", value: (row) => row.name, minWidth: 14, maxWidth: 24 },
|
|
15313
|
+
{ label: "Type", value: (row) => row.type, minWidth: 10, maxWidth: 14 },
|
|
15314
|
+
{ label: "ID", value: (row) => row.id, minWidth: 16, maxWidth: 48 },
|
|
15315
|
+
{
|
|
15316
|
+
label: "Capabilities",
|
|
15317
|
+
value: (row) => row.capabilities,
|
|
15318
|
+
minWidth: 8,
|
|
15319
|
+
maxWidth: 48
|
|
15320
|
+
},
|
|
15321
|
+
{
|
|
15322
|
+
label: "External connection status",
|
|
15323
|
+
value: (row) => row.external,
|
|
15324
|
+
minWidth: 8,
|
|
15325
|
+
maxWidth: 36
|
|
15326
|
+
}
|
|
15327
|
+
];
|
|
15328
|
+
}
|
|
15329
|
+
function distributeWidths(columns, availableWidth) {
|
|
15330
|
+
const gapWidth = COLUMN_GAP2.length * Math.max(0, columns.length - 1);
|
|
15331
|
+
const contentWidth2 = Math.max(columns.length, availableWidth - gapWidth);
|
|
15332
|
+
const widths = columns.map((column) => column.minWidth);
|
|
15333
|
+
let remaining = contentWidth2 - widths.reduce((total, width) => total + width, 0);
|
|
15334
|
+
while (remaining > 0) {
|
|
15335
|
+
let changed = false;
|
|
15336
|
+
for (let index = 0; index < columns.length && remaining > 0; index += 1) {
|
|
15337
|
+
if (widths[index] >= columns[index].maxWidth) {
|
|
15338
|
+
continue;
|
|
15339
|
+
}
|
|
15340
|
+
widths[index] += 1;
|
|
15341
|
+
remaining -= 1;
|
|
15342
|
+
changed = true;
|
|
15343
|
+
}
|
|
15344
|
+
if (!changed) {
|
|
15345
|
+
break;
|
|
15346
|
+
}
|
|
15347
|
+
}
|
|
15348
|
+
return widths;
|
|
15349
|
+
}
|
|
15350
|
+
function renderTableRows(rows, terminalWidth) {
|
|
15351
|
+
const columns = tableColumns();
|
|
15352
|
+
const availableWidth = contentWidth(terminalWidth);
|
|
15353
|
+
const widths = distributeWidths(columns, availableWidth);
|
|
15354
|
+
const headerRow = columns.map((column, index) => formatCell2(column.label, widths[index])).join(COLUMN_GAP2).slice(0, availableWidth);
|
|
15355
|
+
const separatorRow = "-".repeat(headerRow.length).slice(0, availableWidth);
|
|
15356
|
+
const bodyRows = rows.map(
|
|
15357
|
+
(row) => columns.map((column, index) => formatCell2(column.value(row), widths[index])).join(COLUMN_GAP2).slice(0, availableWidth)
|
|
15358
|
+
);
|
|
15359
|
+
return { headerRow, separatorRow, bodyRows };
|
|
15360
|
+
}
|
|
15361
|
+
function contentWidth(terminalWidth) {
|
|
15362
|
+
return Math.max(1, terminalWidth - HORIZONTAL_PADDING);
|
|
15363
|
+
}
|
|
15364
|
+
var SourcesList = ({
|
|
15365
|
+
resource,
|
|
15366
|
+
params,
|
|
15367
|
+
onComplete
|
|
15368
|
+
}) => {
|
|
15369
|
+
const action = useCallback6(
|
|
15370
|
+
() => resource.listSources(params),
|
|
15371
|
+
[resource, params]
|
|
15372
|
+
);
|
|
15373
|
+
const { status, data: page, error } = useAsyncAction(action, onComplete);
|
|
15374
|
+
const sources = page?.data ?? [];
|
|
15375
|
+
const nextCursor = page?.has_more && sources.length > 0 ? sources[sources.length - 1].id : null;
|
|
15376
|
+
const rows = sources.map(sourceRow);
|
|
15377
|
+
const terminalWidth = process.stdout.columns ?? 140;
|
|
15378
|
+
const { headerRow, separatorRow, bodyRows } = renderTableRows(
|
|
15379
|
+
rows,
|
|
15380
|
+
terminalWidth
|
|
15381
|
+
);
|
|
15382
|
+
if (status === "loading") {
|
|
15383
|
+
return /* @__PURE__ */ jsx23(Box15, { children: /* @__PURE__ */ jsxs15(Text17, { color: "cyan", children: [
|
|
15384
|
+
/* @__PURE__ */ jsx23(Spinner7, { type: "dots" }),
|
|
15385
|
+
" Loading sources..."
|
|
15386
|
+
] }) });
|
|
15387
|
+
}
|
|
15388
|
+
if (status === "error") {
|
|
15389
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", children: [
|
|
15390
|
+
/* @__PURE__ */ jsx23(Text17, { color: "red", children: "Failed to load sources" }),
|
|
15391
|
+
/* @__PURE__ */ jsx23(Text17, { color: "red", children: error })
|
|
15392
|
+
] });
|
|
15393
|
+
}
|
|
15394
|
+
if (sources.length === 0) {
|
|
15395
|
+
return /* @__PURE__ */ jsx23(Box15, { children: /* @__PURE__ */ jsx23(Text17, { dimColor: true, children: "No sources found" }) });
|
|
15396
|
+
}
|
|
15397
|
+
return /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", children: [
|
|
15398
|
+
/* @__PURE__ */ jsx23(Text17, { bold: true, children: "Sources" }),
|
|
15399
|
+
/* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
|
|
15400
|
+
/* @__PURE__ */ jsx23(Text17, { bold: true, children: headerRow }),
|
|
15401
|
+
/* @__PURE__ */ jsx23(Text17, { dimColor: true, children: separatorRow }),
|
|
15402
|
+
bodyRows.map((row, index) => /* @__PURE__ */ jsx23(Text17, { children: row }, rows[index].key))
|
|
15403
|
+
] }),
|
|
15404
|
+
page?.has_more !== void 0 ? /* @__PURE__ */ jsxs15(Box15, { flexDirection: "column", marginTop: 1, children: [
|
|
15405
|
+
/* @__PURE__ */ jsxs15(Text17, { dimColor: true, children: [
|
|
15406
|
+
"has_more: ",
|
|
15407
|
+
String(page.has_more)
|
|
15408
|
+
] }),
|
|
15409
|
+
typeof nextCursor === "string" && nextCursor.length > 0 ? /* @__PURE__ */ jsx23(Text17, { dimColor: true, children: `next page: --starting-after ${nextCursor}` }) : null
|
|
15410
|
+
] }) : null
|
|
15411
|
+
] });
|
|
15412
|
+
};
|
|
15413
|
+
|
|
15414
|
+
// src/commands/sources/schema.ts
|
|
15415
|
+
import { z as z8 } from "incur";
|
|
15416
|
+
var listOptions2 = z8.object({
|
|
15417
|
+
limit: z8.coerce.number().int().positive().max(100).optional().describe("Maximum number of sources to return (1-100)."),
|
|
15418
|
+
startingAfter: z8.string().optional().describe("Cursor: return sources after this source ID."),
|
|
15419
|
+
endingBefore: z8.string().optional().describe("Cursor: return sources before this source ID.")
|
|
15420
|
+
});
|
|
15421
|
+
|
|
15422
|
+
// src/commands/sources/index.tsx
|
|
15423
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
15424
|
+
function createSourcesCli(createResource, authStorage2, envAccessToken2) {
|
|
15425
|
+
const cli2 = Cli10.create("sources", {
|
|
15426
|
+
description: "List sources from your Link wallet"
|
|
15427
|
+
});
|
|
15428
|
+
cli2.command("list", {
|
|
15429
|
+
description: "List sources from your Link wallet",
|
|
15430
|
+
options: listOptions2,
|
|
15431
|
+
outputPolicy: "agent-only",
|
|
15432
|
+
middleware: [requireAuth(authStorage2, envAccessToken2)],
|
|
15433
|
+
async run(c) {
|
|
15434
|
+
const opts = c.options;
|
|
15435
|
+
const resource = createResource();
|
|
15436
|
+
const params = {};
|
|
15437
|
+
if (opts.limit !== void 0) params.limit = opts.limit;
|
|
15438
|
+
if (opts.startingAfter !== void 0)
|
|
15439
|
+
params.starting_after = opts.startingAfter;
|
|
15440
|
+
if (opts.endingBefore !== void 0)
|
|
15441
|
+
params.ending_before = opts.endingBefore;
|
|
15442
|
+
if (!c.agent && !c.formatExplicit) {
|
|
15443
|
+
return renderInteractive(
|
|
15444
|
+
/* @__PURE__ */ jsx24(
|
|
15445
|
+
SourcesList,
|
|
15446
|
+
{
|
|
15447
|
+
resource,
|
|
15448
|
+
params,
|
|
15449
|
+
onComplete: () => {
|
|
15450
|
+
}
|
|
15451
|
+
}
|
|
15452
|
+
),
|
|
15453
|
+
() => resource.listSources(params)
|
|
15454
|
+
);
|
|
15455
|
+
}
|
|
15456
|
+
return resource.listSources(params);
|
|
15457
|
+
}
|
|
15458
|
+
});
|
|
15459
|
+
return cli2;
|
|
15460
|
+
}
|
|
15461
|
+
|
|
14636
15462
|
// src/commands/spend-request/index.tsx
|
|
14637
|
-
import { Cli as
|
|
15463
|
+
import { Cli as Cli11, z as z11 } from "incur";
|
|
14638
15464
|
|
|
14639
15465
|
// src/utils/credential-output.ts
|
|
14640
15466
|
import { constants } from "fs";
|
|
@@ -14692,21 +15518,21 @@ async function writeCredentialFile(filePath, data, force) {
|
|
|
14692
15518
|
}
|
|
14693
15519
|
|
|
14694
15520
|
// src/utils/line-item-parser.ts
|
|
14695
|
-
import { z as
|
|
14696
|
-
var LineItemSchema =
|
|
14697
|
-
name:
|
|
14698
|
-
url:
|
|
14699
|
-
image_url:
|
|
14700
|
-
description:
|
|
14701
|
-
sku:
|
|
14702
|
-
quantity:
|
|
14703
|
-
unit_amount:
|
|
14704
|
-
product_url:
|
|
15521
|
+
import { z as z9 } from "zod";
|
|
15522
|
+
var LineItemSchema = z9.object({
|
|
15523
|
+
name: z9.string(),
|
|
15524
|
+
url: z9.string().optional(),
|
|
15525
|
+
image_url: z9.string().optional(),
|
|
15526
|
+
description: z9.string().optional(),
|
|
15527
|
+
sku: z9.string().optional(),
|
|
15528
|
+
quantity: z9.coerce.number().optional(),
|
|
15529
|
+
unit_amount: z9.coerce.number().optional(),
|
|
15530
|
+
product_url: z9.string().optional()
|
|
14705
15531
|
}).strict();
|
|
14706
|
-
var TotalSchema =
|
|
14707
|
-
type:
|
|
14708
|
-
display_text:
|
|
14709
|
-
amount:
|
|
15532
|
+
var TotalSchema = z9.object({
|
|
15533
|
+
type: z9.string(),
|
|
15534
|
+
display_text: z9.string(),
|
|
15535
|
+
amount: z9.coerce.number()
|
|
14710
15536
|
}).strict();
|
|
14711
15537
|
function parseKvString(raw) {
|
|
14712
15538
|
const result = {};
|
|
@@ -14736,7 +15562,7 @@ function parseLineItemFlag(raw) {
|
|
|
14736
15562
|
try {
|
|
14737
15563
|
return LineItemSchema.parse(obj);
|
|
14738
15564
|
} catch (err) {
|
|
14739
|
-
if (err instanceof
|
|
15565
|
+
if (err instanceof z9.ZodError)
|
|
14740
15566
|
throw formatZodError(err, "Line item", LineItemSchema);
|
|
14741
15567
|
throw err;
|
|
14742
15568
|
}
|
|
@@ -14746,65 +15572,65 @@ function parseTotalFlag(raw) {
|
|
|
14746
15572
|
try {
|
|
14747
15573
|
return TotalSchema.parse(obj);
|
|
14748
15574
|
} catch (err) {
|
|
14749
|
-
if (err instanceof
|
|
15575
|
+
if (err instanceof z9.ZodError)
|
|
14750
15576
|
throw formatZodError(err, "Total", TotalSchema);
|
|
14751
15577
|
throw err;
|
|
14752
15578
|
}
|
|
14753
15579
|
}
|
|
14754
15580
|
|
|
14755
15581
|
// src/commands/spend-request/cancel.tsx
|
|
14756
|
-
import { Box as
|
|
14757
|
-
import
|
|
14758
|
-
import { useCallback as
|
|
14759
|
-
import { jsx as
|
|
15582
|
+
import { Box as Box16, Text as Text18 } from "ink";
|
|
15583
|
+
import Spinner8 from "ink-spinner";
|
|
15584
|
+
import { useCallback as useCallback7 } from "react";
|
|
15585
|
+
import { jsx as jsx25, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
14760
15586
|
var CancelSpendRequest = ({
|
|
14761
15587
|
repository,
|
|
14762
15588
|
id,
|
|
14763
15589
|
onComplete
|
|
14764
15590
|
}) => {
|
|
14765
|
-
const action =
|
|
15591
|
+
const action = useCallback7(
|
|
14766
15592
|
() => repository.cancelSpendRequest(id),
|
|
14767
15593
|
[repository, id]
|
|
14768
15594
|
);
|
|
14769
15595
|
const { status, data: request, error } = useAsyncAction(action, onComplete);
|
|
14770
15596
|
if (status === "loading") {
|
|
14771
|
-
return /* @__PURE__ */
|
|
14772
|
-
/* @__PURE__ */
|
|
15597
|
+
return /* @__PURE__ */ jsx25(Box16, { children: /* @__PURE__ */ jsxs16(Text18, { color: "cyan", children: [
|
|
15598
|
+
/* @__PURE__ */ jsx25(Spinner8, { type: "dots" }),
|
|
14773
15599
|
" Canceling spend request ",
|
|
14774
15600
|
id,
|
|
14775
15601
|
"..."
|
|
14776
15602
|
] }) });
|
|
14777
15603
|
}
|
|
14778
15604
|
if (status === "error") {
|
|
14779
|
-
return /* @__PURE__ */
|
|
14780
|
-
/* @__PURE__ */
|
|
14781
|
-
/* @__PURE__ */
|
|
15605
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
|
|
15606
|
+
/* @__PURE__ */ jsx25(Text18, { color: "red", children: "\u2717 Failed to cancel spend request" }),
|
|
15607
|
+
/* @__PURE__ */ jsx25(Text18, { color: "red", children: error })
|
|
14782
15608
|
] });
|
|
14783
15609
|
}
|
|
14784
|
-
return /* @__PURE__ */
|
|
14785
|
-
/* @__PURE__ */
|
|
14786
|
-
/* @__PURE__ */
|
|
15610
|
+
return /* @__PURE__ */ jsxs16(Box16, { flexDirection: "column", children: [
|
|
15611
|
+
/* @__PURE__ */ jsx25(Text18, { color: "green", children: "\u2713 Spend request canceled" }),
|
|
15612
|
+
/* @__PURE__ */ jsx25(Box16, { flexDirection: "column", marginTop: 1, paddingX: 2, children: /* @__PURE__ */ jsxs16(Text18, { children: [
|
|
14787
15613
|
"ID: ",
|
|
14788
|
-
/* @__PURE__ */
|
|
15614
|
+
/* @__PURE__ */ jsx25(Text18, { bold: true, children: request?.id })
|
|
14789
15615
|
] }) })
|
|
14790
15616
|
] });
|
|
14791
15617
|
};
|
|
14792
15618
|
|
|
14793
15619
|
// src/commands/spend-request/create.tsx
|
|
14794
|
-
import { Box as
|
|
14795
|
-
import
|
|
14796
|
-
import { useCallback as
|
|
15620
|
+
import { Box as Box18, Text as Text20, useApp as useApp4 } from "ink";
|
|
15621
|
+
import Spinner10 from "ink-spinner";
|
|
15622
|
+
import { useCallback as useCallback8, useEffect as useEffect9, useState as useState9 } from "react";
|
|
14797
15623
|
|
|
14798
15624
|
// src/commands/spend-request/approval-waiting-view.tsx
|
|
14799
|
-
import { Box as
|
|
14800
|
-
import
|
|
14801
|
-
import { jsx as
|
|
15625
|
+
import { Box as Box17, Text as Text19 } from "ink";
|
|
15626
|
+
import Spinner9 from "ink-spinner";
|
|
15627
|
+
import { jsx as jsx26, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
14802
15628
|
var ApprovalWaitingView = ({
|
|
14803
15629
|
status,
|
|
14804
15630
|
approvalUrl
|
|
14805
|
-
}) => /* @__PURE__ */
|
|
14806
|
-
/* @__PURE__ */
|
|
14807
|
-
|
|
15631
|
+
}) => /* @__PURE__ */ jsxs17(Box17, { flexDirection: "column", paddingY: 1, children: [
|
|
15632
|
+
/* @__PURE__ */ jsxs17(
|
|
15633
|
+
Box17,
|
|
14808
15634
|
{
|
|
14809
15635
|
flexDirection: "column",
|
|
14810
15636
|
borderStyle: "round",
|
|
@@ -14812,20 +15638,20 @@ var ApprovalWaitingView = ({
|
|
|
14812
15638
|
paddingX: 2,
|
|
14813
15639
|
paddingY: 1,
|
|
14814
15640
|
children: [
|
|
14815
|
-
/* @__PURE__ */
|
|
15641
|
+
/* @__PURE__ */ jsxs17(Text19, { children: [
|
|
14816
15642
|
"Approve at:",
|
|
14817
15643
|
" ",
|
|
14818
|
-
/* @__PURE__ */
|
|
15644
|
+
/* @__PURE__ */ jsx26(Text19, { bold: true, color: "cyan", children: approvalUrl })
|
|
14819
15645
|
] }),
|
|
14820
|
-
/* @__PURE__ */
|
|
15646
|
+
/* @__PURE__ */ jsx26(Text19, { dimColor: true, children: "Press Enter to open in browser" })
|
|
14821
15647
|
]
|
|
14822
15648
|
}
|
|
14823
15649
|
),
|
|
14824
|
-
/* @__PURE__ */
|
|
14825
|
-
/* @__PURE__ */
|
|
14826
|
-
/* @__PURE__ */
|
|
15650
|
+
/* @__PURE__ */ jsx26(AppDownloadQrCodes, {}),
|
|
15651
|
+
/* @__PURE__ */ jsx26(Box17, { marginTop: 1, children: status === "polling" ? /* @__PURE__ */ jsxs17(Text19, { color: "cyan", children: [
|
|
15652
|
+
/* @__PURE__ */ jsx26(Spinner9, { type: "dots" }),
|
|
14827
15653
|
" Waiting for approval..."
|
|
14828
|
-
] }) : /* @__PURE__ */
|
|
15654
|
+
] }) : /* @__PURE__ */ jsx26(Text19, { dimColor: true, children: "Waiting..." }) })
|
|
14829
15655
|
] });
|
|
14830
15656
|
|
|
14831
15657
|
// src/commands/spend-request/use-approval-polling.ts
|
|
@@ -14894,7 +15720,7 @@ function useApprovalPolling({
|
|
|
14894
15720
|
}
|
|
14895
15721
|
|
|
14896
15722
|
// src/commands/spend-request/create.tsx
|
|
14897
|
-
import { Fragment as Fragment4, jsx as
|
|
15723
|
+
import { Fragment as Fragment4, jsx as jsx27, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
14898
15724
|
var CreateSpendRequest = ({
|
|
14899
15725
|
repository,
|
|
14900
15726
|
params,
|
|
@@ -14906,21 +15732,30 @@ var CreateSpendRequest = ({
|
|
|
14906
15732
|
const [status, setStatus] = useState9("creating");
|
|
14907
15733
|
const [request, setRequest] = useState9(null);
|
|
14908
15734
|
const [error, setError] = useState9("");
|
|
15735
|
+
const [verificationUrl, setVerificationUrl] = useState9("");
|
|
14909
15736
|
const [outputFilePath, setOutputFilePath] = useState9(null);
|
|
14910
15737
|
const [fileError, setFileError] = useState9("");
|
|
14911
15738
|
const approvalUrl = request?.approval_url ?? "";
|
|
14912
|
-
const
|
|
15739
|
+
const { exit } = useApp4();
|
|
15740
|
+
const completeAndExit = useCallback8(
|
|
15741
|
+
(result) => {
|
|
15742
|
+
onComplete(result);
|
|
15743
|
+
exit();
|
|
15744
|
+
},
|
|
15745
|
+
[onComplete, exit]
|
|
15746
|
+
);
|
|
15747
|
+
const onSuccess = useCallback8(
|
|
14913
15748
|
(result) => setRequest(result),
|
|
14914
15749
|
[]
|
|
14915
15750
|
);
|
|
14916
|
-
const onError =
|
|
15751
|
+
const onError = useCallback8((msg) => setError(msg), []);
|
|
14917
15752
|
useApprovalPolling({
|
|
14918
15753
|
status,
|
|
14919
15754
|
setStatus,
|
|
14920
15755
|
approvalUrl,
|
|
14921
15756
|
repository,
|
|
14922
15757
|
requestId: request?.id ?? null,
|
|
14923
|
-
onComplete,
|
|
15758
|
+
onComplete: completeAndExit,
|
|
14924
15759
|
onSuccess,
|
|
14925
15760
|
onError
|
|
14926
15761
|
});
|
|
@@ -14933,16 +15768,20 @@ var CreateSpendRequest = ({
|
|
|
14933
15768
|
setStatus("waiting");
|
|
14934
15769
|
} else {
|
|
14935
15770
|
setStatus("success");
|
|
14936
|
-
setTimeout(() =>
|
|
15771
|
+
setTimeout(() => completeAndExit(result), DISPLAY_DELAY_MS);
|
|
14937
15772
|
}
|
|
14938
15773
|
} catch (err) {
|
|
14939
15774
|
setError(err.message);
|
|
15775
|
+
if (err instanceof LinkApiError) {
|
|
15776
|
+
const url = err.details?.error?.verification_url;
|
|
15777
|
+
if (url) setVerificationUrl(url);
|
|
15778
|
+
}
|
|
14940
15779
|
setStatus("error");
|
|
14941
|
-
setTimeout(() =>
|
|
15780
|
+
setTimeout(() => completeAndExit(null), DISPLAY_DELAY_MS);
|
|
14942
15781
|
}
|
|
14943
15782
|
};
|
|
14944
15783
|
create();
|
|
14945
|
-
}, [repository, params, requestApproval,
|
|
15784
|
+
}, [repository, params, requestApproval, completeAndExit]);
|
|
14946
15785
|
useEffect9(() => {
|
|
14947
15786
|
if (status !== "success" || !outputFile || !request?.card) return;
|
|
14948
15787
|
const fileData = {
|
|
@@ -14956,101 +15795,105 @@ var CreateSpendRequest = ({
|
|
|
14956
15795
|
writeCredentialFile(outputFile, fileData, force ?? false).then((path7) => setOutputFilePath(path7)).catch((err) => setFileError(err.message));
|
|
14957
15796
|
}, [status, outputFile, force, request]);
|
|
14958
15797
|
if (status === "creating") {
|
|
14959
|
-
return /* @__PURE__ */
|
|
14960
|
-
/* @__PURE__ */
|
|
15798
|
+
return /* @__PURE__ */ jsx27(Box18, { children: /* @__PURE__ */ jsxs18(Text20, { color: "cyan", children: [
|
|
15799
|
+
/* @__PURE__ */ jsx27(Spinner10, { type: "dots" }),
|
|
14961
15800
|
" Creating spend request..."
|
|
14962
15801
|
] }) });
|
|
14963
15802
|
}
|
|
14964
15803
|
if (status === "error") {
|
|
14965
|
-
return /* @__PURE__ */
|
|
14966
|
-
/* @__PURE__ */
|
|
14967
|
-
/* @__PURE__ */
|
|
15804
|
+
return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
|
|
15805
|
+
/* @__PURE__ */ jsx27(Text20, { color: "red", children: "\u2717 Failed to create spend request" }),
|
|
15806
|
+
/* @__PURE__ */ jsx27(Text20, { color: "red", children: error }),
|
|
15807
|
+
verificationUrl && /* @__PURE__ */ jsxs18(Text20, { color: "red", children: [
|
|
15808
|
+
"Complete additional verification at: ",
|
|
15809
|
+
verificationUrl
|
|
15810
|
+
] })
|
|
14968
15811
|
] });
|
|
14969
15812
|
}
|
|
14970
15813
|
if (status === "success") {
|
|
14971
|
-
return /* @__PURE__ */
|
|
14972
|
-
/* @__PURE__ */
|
|
14973
|
-
/* @__PURE__ */
|
|
14974
|
-
/* @__PURE__ */
|
|
15814
|
+
return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", children: [
|
|
15815
|
+
/* @__PURE__ */ jsx27(Text20, { color: "green", children: "\u2713 Spend request created" }),
|
|
15816
|
+
/* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
|
|
15817
|
+
/* @__PURE__ */ jsxs18(Text20, { children: [
|
|
14975
15818
|
"ID: ",
|
|
14976
|
-
/* @__PURE__ */
|
|
15819
|
+
/* @__PURE__ */ jsx27(Text20, { bold: true, children: request?.id })
|
|
14977
15820
|
] }),
|
|
14978
|
-
/* @__PURE__ */
|
|
15821
|
+
/* @__PURE__ */ jsxs18(Text20, { children: [
|
|
14979
15822
|
"Status: ",
|
|
14980
|
-
/* @__PURE__ */
|
|
15823
|
+
/* @__PURE__ */ jsx27(Text20, { bold: true, children: request?.status })
|
|
14981
15824
|
] }),
|
|
14982
|
-
/* @__PURE__ */
|
|
15825
|
+
/* @__PURE__ */ jsxs18(Text20, { children: [
|
|
14983
15826
|
"Amount:",
|
|
14984
15827
|
" ",
|
|
14985
|
-
/* @__PURE__ */
|
|
15828
|
+
/* @__PURE__ */ jsx27(Text20, { bold: true, children: request?.amount != null ? `${request.amount} ${request.currency?.toUpperCase() ?? ""}`.trim() : "N/A" })
|
|
14986
15829
|
] }),
|
|
14987
|
-
/* @__PURE__ */
|
|
15830
|
+
/* @__PURE__ */ jsxs18(Text20, { children: [
|
|
14988
15831
|
"Merchant: ",
|
|
14989
|
-
/* @__PURE__ */
|
|
15832
|
+
/* @__PURE__ */ jsx27(Text20, { bold: true, children: request?.merchant_name })
|
|
14990
15833
|
] }),
|
|
14991
|
-
/* @__PURE__ */
|
|
15834
|
+
/* @__PURE__ */ jsxs18(Text20, { children: [
|
|
14992
15835
|
"Line Items:",
|
|
14993
15836
|
" ",
|
|
14994
|
-
/* @__PURE__ */
|
|
15837
|
+
/* @__PURE__ */ jsx27(Text20, { bold: true, children: request?.line_items.map((li) => li.name).join(", ") || "N/A" })
|
|
14995
15838
|
] }),
|
|
14996
|
-
request?.credential_type === "shared_payment_token" && request.shared_payment_token && /* @__PURE__ */
|
|
15839
|
+
request?.credential_type === "shared_payment_token" && request.shared_payment_token && /* @__PURE__ */ jsxs18(Text20, { children: [
|
|
14997
15840
|
"Token: ",
|
|
14998
|
-
/* @__PURE__ */
|
|
15841
|
+
/* @__PURE__ */ jsx27(Text20, { bold: true, children: request.shared_payment_token.id })
|
|
14999
15842
|
] })
|
|
15000
15843
|
] }),
|
|
15001
|
-
request?.card && !outputFile && /* @__PURE__ */
|
|
15002
|
-
/* @__PURE__ */
|
|
15003
|
-
/* @__PURE__ */
|
|
15844
|
+
request?.card && !outputFile && /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", marginTop: 1, children: [
|
|
15845
|
+
/* @__PURE__ */ jsx27(Text20, { bold: true, children: "Card Details:" }),
|
|
15846
|
+
/* @__PURE__ */ jsxs18(Text20, { children: [
|
|
15004
15847
|
" ",
|
|
15005
15848
|
"Number: ",
|
|
15006
|
-
/* @__PURE__ */
|
|
15849
|
+
/* @__PURE__ */ jsx27(Text20, { bold: true, children: request.card.number })
|
|
15007
15850
|
] }),
|
|
15008
|
-
/* @__PURE__ */
|
|
15851
|
+
/* @__PURE__ */ jsxs18(Text20, { children: [
|
|
15009
15852
|
" ",
|
|
15010
15853
|
"Brand: ",
|
|
15011
|
-
/* @__PURE__ */
|
|
15854
|
+
/* @__PURE__ */ jsx27(Text20, { bold: true, children: request.card.brand })
|
|
15012
15855
|
] }),
|
|
15013
|
-
/* @__PURE__ */
|
|
15856
|
+
/* @__PURE__ */ jsxs18(Text20, { children: [
|
|
15014
15857
|
" ",
|
|
15015
15858
|
"Expiry:",
|
|
15016
15859
|
" ",
|
|
15017
|
-
/* @__PURE__ */
|
|
15860
|
+
/* @__PURE__ */ jsxs18(Text20, { bold: true, children: [
|
|
15018
15861
|
String(request.card.exp_month).padStart(2, "0"),
|
|
15019
15862
|
"/",
|
|
15020
15863
|
request.card.exp_year
|
|
15021
15864
|
] })
|
|
15022
15865
|
] }),
|
|
15023
|
-
request.card.cvc && /* @__PURE__ */
|
|
15866
|
+
request.card.cvc && /* @__PURE__ */ jsxs18(Text20, { children: [
|
|
15024
15867
|
" ",
|
|
15025
15868
|
"CVC: ",
|
|
15026
|
-
/* @__PURE__ */
|
|
15869
|
+
/* @__PURE__ */ jsx27(Text20, { bold: true, children: request.card.cvc })
|
|
15027
15870
|
] }),
|
|
15028
|
-
request.card.valid_until && /* @__PURE__ */
|
|
15871
|
+
request.card.valid_until && /* @__PURE__ */ jsxs18(Text20, { children: [
|
|
15029
15872
|
" ",
|
|
15030
15873
|
"Valid Until: ",
|
|
15031
|
-
/* @__PURE__ */
|
|
15874
|
+
/* @__PURE__ */ jsx27(Text20, { bold: true, children: request.card.valid_until })
|
|
15032
15875
|
] })
|
|
15033
15876
|
] }),
|
|
15034
|
-
request?.card && outputFile && /* @__PURE__ */
|
|
15035
|
-
outputFilePath && /* @__PURE__ */
|
|
15877
|
+
request?.card && outputFile && /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", marginTop: 1, children: [
|
|
15878
|
+
outputFilePath && /* @__PURE__ */ jsxs18(Text20, { color: "green", children: [
|
|
15036
15879
|
"Card credentials written to ",
|
|
15037
|
-
/* @__PURE__ */
|
|
15880
|
+
/* @__PURE__ */ jsx27(Text20, { bold: true, children: outputFilePath })
|
|
15038
15881
|
] }),
|
|
15039
|
-
fileError && /* @__PURE__ */
|
|
15882
|
+
fileError && /* @__PURE__ */ jsxs18(Text20, { color: "red", children: [
|
|
15040
15883
|
"Failed to write card file: ",
|
|
15041
15884
|
fileError
|
|
15042
15885
|
] })
|
|
15043
15886
|
] }),
|
|
15044
|
-
/* @__PURE__ */
|
|
15887
|
+
/* @__PURE__ */ jsx27(AppDownloadQrCodes, {})
|
|
15045
15888
|
] });
|
|
15046
15889
|
}
|
|
15047
|
-
return /* @__PURE__ */
|
|
15048
|
-
/* @__PURE__ */
|
|
15890
|
+
return /* @__PURE__ */ jsxs18(Fragment4, { children: [
|
|
15891
|
+
/* @__PURE__ */ jsx27(Box18, { children: /* @__PURE__ */ jsxs18(Text20, { color: "green", children: [
|
|
15049
15892
|
"\u2713 Spend request created (ID: ",
|
|
15050
|
-
/* @__PURE__ */
|
|
15893
|
+
/* @__PURE__ */ jsx27(Text20, { bold: true, children: request?.id }),
|
|
15051
15894
|
")"
|
|
15052
15895
|
] }) }),
|
|
15053
|
-
/* @__PURE__ */
|
|
15896
|
+
/* @__PURE__ */ jsx27(
|
|
15054
15897
|
ApprovalWaitingView,
|
|
15055
15898
|
{
|
|
15056
15899
|
status,
|
|
@@ -15061,21 +15904,21 @@ var CreateSpendRequest = ({
|
|
|
15061
15904
|
};
|
|
15062
15905
|
|
|
15063
15906
|
// src/commands/spend-request/list.tsx
|
|
15064
|
-
import { Box as
|
|
15065
|
-
import
|
|
15066
|
-
import { useCallback as
|
|
15067
|
-
import { jsx as
|
|
15907
|
+
import { Box as Box19, Text as Text21, useApp as useApp5 } from "ink";
|
|
15908
|
+
import Spinner11 from "ink-spinner";
|
|
15909
|
+
import { useCallback as useCallback9 } from "react";
|
|
15910
|
+
import { jsx as jsx28, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
15068
15911
|
var SpendRequestList = ({
|
|
15069
15912
|
repository,
|
|
15070
15913
|
includeHistory = false,
|
|
15071
15914
|
onComplete
|
|
15072
15915
|
}) => {
|
|
15073
|
-
const { exit } =
|
|
15074
|
-
const action =
|
|
15916
|
+
const { exit } = useApp5();
|
|
15917
|
+
const action = useCallback9(
|
|
15075
15918
|
() => repository.listSpendRequests({ includeHistory }),
|
|
15076
15919
|
[repository, includeHistory]
|
|
15077
15920
|
);
|
|
15078
|
-
const wrappedOnComplete =
|
|
15921
|
+
const wrappedOnComplete = useCallback9(
|
|
15079
15922
|
(result) => {
|
|
15080
15923
|
onComplete(result);
|
|
15081
15924
|
exit();
|
|
@@ -15088,29 +15931,29 @@ var SpendRequestList = ({
|
|
|
15088
15931
|
error
|
|
15089
15932
|
} = useAsyncAction(action, wrappedOnComplete);
|
|
15090
15933
|
if (status === "loading") {
|
|
15091
|
-
return /* @__PURE__ */
|
|
15092
|
-
/* @__PURE__ */
|
|
15934
|
+
return /* @__PURE__ */ jsx28(Box19, { children: /* @__PURE__ */ jsxs19(Text21, { color: "cyan", children: [
|
|
15935
|
+
/* @__PURE__ */ jsx28(Spinner11, { type: "dots" }),
|
|
15093
15936
|
" Loading spend requests..."
|
|
15094
15937
|
] }) });
|
|
15095
15938
|
}
|
|
15096
15939
|
if (status === "error") {
|
|
15097
|
-
return /* @__PURE__ */
|
|
15098
|
-
/* @__PURE__ */
|
|
15099
|
-
/* @__PURE__ */
|
|
15940
|
+
return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", children: [
|
|
15941
|
+
/* @__PURE__ */ jsx28(Text21, { color: "red", children: "\u2717 Failed to load spend requests" }),
|
|
15942
|
+
/* @__PURE__ */ jsx28(Text21, { color: "red", children: error })
|
|
15100
15943
|
] });
|
|
15101
15944
|
}
|
|
15102
15945
|
if (!requests || requests.length === 0) {
|
|
15103
|
-
return /* @__PURE__ */
|
|
15946
|
+
return /* @__PURE__ */ jsx28(Box19, { children: /* @__PURE__ */ jsx28(Text21, { dimColor: true, children: includeHistory ? "No spend requests found" : "No active spend requests found" }) });
|
|
15104
15947
|
}
|
|
15105
|
-
return /* @__PURE__ */
|
|
15106
|
-
/* @__PURE__ */
|
|
15107
|
-
/* @__PURE__ */
|
|
15948
|
+
return /* @__PURE__ */ jsxs19(Box19, { flexDirection: "column", children: [
|
|
15949
|
+
/* @__PURE__ */ jsx28(Text21, { bold: true, children: includeHistory ? "All Spend Requests" : "Active Spend Requests" }),
|
|
15950
|
+
/* @__PURE__ */ jsx28(Box19, { flexDirection: "column", marginTop: 1, children: requests.map((sr) => {
|
|
15108
15951
|
const statusColor = sr.status === "approved" ? "green" : sr.status === "pending_approval" ? "yellow" : "white";
|
|
15109
15952
|
const amount = sr.amount != null ? `$${(sr.amount / 100).toFixed(2)} ${(sr.currency ?? "usd").toUpperCase()}` : "";
|
|
15110
|
-
return /* @__PURE__ */
|
|
15111
|
-
/* @__PURE__ */
|
|
15953
|
+
return /* @__PURE__ */ jsx28(Box19, { paddingX: 2, children: /* @__PURE__ */ jsxs19(Text21, { children: [
|
|
15954
|
+
/* @__PURE__ */ jsx28(Text21, { dimColor: true, children: sr.id }),
|
|
15112
15955
|
" ",
|
|
15113
|
-
/* @__PURE__ */
|
|
15956
|
+
/* @__PURE__ */ jsx28(Text21, { color: statusColor, children: sr.status }),
|
|
15114
15957
|
sr.merchant_name ? ` ${sr.merchant_name}` : "",
|
|
15115
15958
|
amount ? ` ${amount}` : ""
|
|
15116
15959
|
] }) }, sr.id);
|
|
@@ -15119,10 +15962,10 @@ var SpendRequestList = ({
|
|
|
15119
15962
|
};
|
|
15120
15963
|
|
|
15121
15964
|
// src/commands/spend-request/request-approval.tsx
|
|
15122
|
-
import { Box as
|
|
15123
|
-
import
|
|
15124
|
-
import { useCallback as
|
|
15125
|
-
import { jsx as
|
|
15965
|
+
import { Box as Box20, Text as Text22, useApp as useApp6 } from "ink";
|
|
15966
|
+
import Spinner12 from "ink-spinner";
|
|
15967
|
+
import { useCallback as useCallback10, useEffect as useEffect10, useState as useState10 } from "react";
|
|
15968
|
+
import { jsx as jsx29, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
15126
15969
|
var RequestApproval = ({
|
|
15127
15970
|
repository,
|
|
15128
15971
|
id,
|
|
@@ -15132,15 +15975,24 @@ var RequestApproval = ({
|
|
|
15132
15975
|
const [approvalUrl, setApprovalUrl] = useState10("");
|
|
15133
15976
|
const [result, setResult] = useState10(null);
|
|
15134
15977
|
const [error, setError] = useState10("");
|
|
15135
|
-
const
|
|
15136
|
-
const
|
|
15978
|
+
const [verificationUrl, setVerificationUrl] = useState10("");
|
|
15979
|
+
const { exit } = useApp6();
|
|
15980
|
+
const completeAndExit = useCallback10(
|
|
15981
|
+
(result2) => {
|
|
15982
|
+
onComplete(result2);
|
|
15983
|
+
exit();
|
|
15984
|
+
},
|
|
15985
|
+
[onComplete, exit]
|
|
15986
|
+
);
|
|
15987
|
+
const onSuccess = useCallback10((r) => setResult(r), []);
|
|
15988
|
+
const onError = useCallback10((msg) => setError(msg), []);
|
|
15137
15989
|
useApprovalPolling({
|
|
15138
15990
|
status,
|
|
15139
15991
|
setStatus,
|
|
15140
15992
|
approvalUrl,
|
|
15141
15993
|
repository,
|
|
15142
15994
|
requestId: id,
|
|
15143
|
-
onComplete,
|
|
15995
|
+
onComplete: completeAndExit,
|
|
15144
15996
|
onSuccess,
|
|
15145
15997
|
onError
|
|
15146
15998
|
});
|
|
@@ -15152,52 +16004,64 @@ var RequestApproval = ({
|
|
|
15152
16004
|
setStatus("waiting");
|
|
15153
16005
|
} catch (err) {
|
|
15154
16006
|
setError(err.message);
|
|
16007
|
+
if (err instanceof LinkApiError) {
|
|
16008
|
+
const url = err.details?.error?.verification_url;
|
|
16009
|
+
if (url) setVerificationUrl(url);
|
|
16010
|
+
}
|
|
15155
16011
|
setStatus("error");
|
|
16012
|
+
setTimeout(() => {
|
|
16013
|
+
onComplete(null);
|
|
16014
|
+
exit();
|
|
16015
|
+
}, DISPLAY_DELAY_MS);
|
|
15156
16016
|
}
|
|
15157
16017
|
};
|
|
15158
16018
|
request();
|
|
15159
|
-
}, [repository, id]);
|
|
16019
|
+
}, [repository, id, exit, onComplete]);
|
|
15160
16020
|
if (status === "requesting") {
|
|
15161
|
-
return /* @__PURE__ */
|
|
15162
|
-
/* @__PURE__ */
|
|
16021
|
+
return /* @__PURE__ */ jsx29(Box20, { children: /* @__PURE__ */ jsxs20(Text22, { color: "cyan", children: [
|
|
16022
|
+
/* @__PURE__ */ jsx29(Spinner12, { type: "dots" }),
|
|
15163
16023
|
" Requesting approval..."
|
|
15164
16024
|
] }) });
|
|
15165
16025
|
}
|
|
15166
16026
|
if (status === "error") {
|
|
15167
|
-
return /* @__PURE__ */
|
|
15168
|
-
/* @__PURE__ */
|
|
15169
|
-
/* @__PURE__ */
|
|
16027
|
+
return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", children: [
|
|
16028
|
+
/* @__PURE__ */ jsx29(Text22, { color: "red", children: "\u2717 Failed to request approval" }),
|
|
16029
|
+
/* @__PURE__ */ jsx29(Text22, { color: "red", children: error }),
|
|
16030
|
+
verificationUrl && /* @__PURE__ */ jsxs20(Text22, { color: "red", children: [
|
|
16031
|
+
"Complete additional verification at: ",
|
|
16032
|
+
verificationUrl
|
|
16033
|
+
] })
|
|
15170
16034
|
] });
|
|
15171
16035
|
}
|
|
15172
16036
|
if (status === "success") {
|
|
15173
|
-
return /* @__PURE__ */
|
|
15174
|
-
/* @__PURE__ */
|
|
15175
|
-
/* @__PURE__ */
|
|
15176
|
-
/* @__PURE__ */
|
|
16037
|
+
return /* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", children: [
|
|
16038
|
+
/* @__PURE__ */ jsx29(Text22, { color: "green", children: "\u2713 Approval completed" }),
|
|
16039
|
+
/* @__PURE__ */ jsxs20(Box20, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
|
|
16040
|
+
/* @__PURE__ */ jsxs20(Text22, { children: [
|
|
15177
16041
|
"ID: ",
|
|
15178
|
-
/* @__PURE__ */
|
|
16042
|
+
/* @__PURE__ */ jsx29(Text22, { bold: true, children: result?.id })
|
|
15179
16043
|
] }),
|
|
15180
|
-
/* @__PURE__ */
|
|
16044
|
+
/* @__PURE__ */ jsxs20(Text22, { children: [
|
|
15181
16045
|
"Status: ",
|
|
15182
|
-
/* @__PURE__ */
|
|
16046
|
+
/* @__PURE__ */ jsx29(Text22, { bold: true, children: result?.status })
|
|
15183
16047
|
] }),
|
|
15184
|
-
/* @__PURE__ */
|
|
16048
|
+
/* @__PURE__ */ jsxs20(Text22, { children: [
|
|
15185
16049
|
"Amount:",
|
|
15186
16050
|
" ",
|
|
15187
|
-
/* @__PURE__ */
|
|
16051
|
+
/* @__PURE__ */ jsx29(Text22, { bold: true, children: result?.amount != null ? `${result.amount} ${result.currency?.toUpperCase() ?? ""}`.trim() : "N/A" })
|
|
15188
16052
|
] }),
|
|
15189
|
-
/* @__PURE__ */
|
|
16053
|
+
/* @__PURE__ */ jsxs20(Text22, { children: [
|
|
15190
16054
|
"Merchant: ",
|
|
15191
|
-
/* @__PURE__ */
|
|
16055
|
+
/* @__PURE__ */ jsx29(Text22, { bold: true, children: result?.merchant_name })
|
|
15192
16056
|
] }),
|
|
15193
|
-
result?.credential_type === "shared_payment_token" && result.shared_payment_token && /* @__PURE__ */
|
|
16057
|
+
result?.credential_type === "shared_payment_token" && result.shared_payment_token && /* @__PURE__ */ jsxs20(Text22, { children: [
|
|
15194
16058
|
"Token: ",
|
|
15195
|
-
/* @__PURE__ */
|
|
16059
|
+
/* @__PURE__ */ jsx29(Text22, { bold: true, children: result.shared_payment_token.id })
|
|
15196
16060
|
] })
|
|
15197
16061
|
] })
|
|
15198
16062
|
] });
|
|
15199
16063
|
}
|
|
15200
|
-
return /* @__PURE__ */
|
|
16064
|
+
return /* @__PURE__ */ jsx29(
|
|
15201
16065
|
ApprovalWaitingView,
|
|
15202
16066
|
{
|
|
15203
16067
|
status,
|
|
@@ -15207,10 +16071,10 @@ var RequestApproval = ({
|
|
|
15207
16071
|
};
|
|
15208
16072
|
|
|
15209
16073
|
// src/commands/spend-request/retrieve.tsx
|
|
15210
|
-
import { Box as
|
|
15211
|
-
import
|
|
16074
|
+
import { Box as Box21, Text as Text23 } from "ink";
|
|
16075
|
+
import Spinner13 from "ink-spinner";
|
|
15212
16076
|
import { useEffect as useEffect11, useRef as useRef5, useState as useState11 } from "react";
|
|
15213
|
-
import { jsx as
|
|
16077
|
+
import { jsx as jsx30, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
15214
16078
|
var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
|
|
15215
16079
|
"approved",
|
|
15216
16080
|
"denied",
|
|
@@ -15334,121 +16198,121 @@ var RetrieveSpendRequest = ({
|
|
|
15334
16198
|
};
|
|
15335
16199
|
}, [phase, repository, id, include, timeout, onComplete]);
|
|
15336
16200
|
if (phase === "fetching") {
|
|
15337
|
-
return /* @__PURE__ */
|
|
15338
|
-
/* @__PURE__ */
|
|
16201
|
+
return /* @__PURE__ */ jsx30(Box21, { children: /* @__PURE__ */ jsxs21(Text23, { color: "cyan", children: [
|
|
16202
|
+
/* @__PURE__ */ jsx30(Spinner13, { type: "dots" }),
|
|
15339
16203
|
" Retrieving spend request ",
|
|
15340
16204
|
id,
|
|
15341
16205
|
"..."
|
|
15342
16206
|
] }) });
|
|
15343
16207
|
}
|
|
15344
16208
|
if (phase === "error") {
|
|
15345
|
-
return /* @__PURE__ */
|
|
16209
|
+
return /* @__PURE__ */ jsx30(Box21, { flexDirection: "column", children: /* @__PURE__ */ jsxs21(Text23, { color: "red", children: [
|
|
15346
16210
|
"\u2717 ",
|
|
15347
16211
|
error
|
|
15348
16212
|
] }) });
|
|
15349
16213
|
}
|
|
15350
16214
|
if (phase === "timeout") {
|
|
15351
|
-
return /* @__PURE__ */
|
|
15352
|
-
/* @__PURE__ */
|
|
16215
|
+
return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
|
|
16216
|
+
/* @__PURE__ */ jsxs21(Text23, { color: "yellow", children: [
|
|
15353
16217
|
"\u2717 Timed out waiting for approval after ",
|
|
15354
16218
|
timeout,
|
|
15355
16219
|
"s"
|
|
15356
16220
|
] }),
|
|
15357
|
-
request && /* @__PURE__ */
|
|
15358
|
-
/* @__PURE__ */
|
|
16221
|
+
request && /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
|
|
16222
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15359
16223
|
"ID: ",
|
|
15360
|
-
/* @__PURE__ */
|
|
16224
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: request.id })
|
|
15361
16225
|
] }),
|
|
15362
|
-
/* @__PURE__ */
|
|
16226
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15363
16227
|
"Status: ",
|
|
15364
|
-
/* @__PURE__ */
|
|
16228
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: request.status })
|
|
15365
16229
|
] })
|
|
15366
16230
|
] })
|
|
15367
16231
|
] });
|
|
15368
16232
|
}
|
|
15369
16233
|
if (phase === "polling") {
|
|
15370
|
-
return /* @__PURE__ */
|
|
15371
|
-
/* @__PURE__ */
|
|
15372
|
-
/* @__PURE__ */
|
|
16234
|
+
return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
|
|
16235
|
+
/* @__PURE__ */ jsx30(Box21, { children: /* @__PURE__ */ jsxs21(Text23, { color: "cyan", children: [
|
|
16236
|
+
/* @__PURE__ */ jsx30(Spinner13, { type: "dots" }),
|
|
15373
16237
|
" Awaiting approval... (",
|
|
15374
16238
|
elapsed,
|
|
15375
16239
|
"s elapsed)"
|
|
15376
16240
|
] }) }),
|
|
15377
|
-
request?.approval_url && /* @__PURE__ */
|
|
16241
|
+
request?.approval_url && /* @__PURE__ */ jsx30(Box21, { marginTop: 1, paddingX: 2, children: /* @__PURE__ */ jsxs21(Text23, { dimColor: true, children: [
|
|
15378
16242
|
"Approval URL: ",
|
|
15379
|
-
/* @__PURE__ */
|
|
16243
|
+
/* @__PURE__ */ jsx30(Text23, { color: "cyan", children: request.approval_url })
|
|
15380
16244
|
] }) })
|
|
15381
16245
|
] });
|
|
15382
16246
|
}
|
|
15383
16247
|
if (phase === "finalized") {
|
|
15384
16248
|
const psd = request?.payment_status_details;
|
|
15385
|
-
return /* @__PURE__ */
|
|
15386
|
-
/* @__PURE__ */
|
|
16249
|
+
return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
|
|
16250
|
+
/* @__PURE__ */ jsxs21(Text23, { color: "yellow", children: [
|
|
15387
16251
|
"Spend request reached terminal status: ",
|
|
15388
16252
|
request?.status
|
|
15389
16253
|
] }),
|
|
15390
|
-
/* @__PURE__ */
|
|
15391
|
-
/* @__PURE__ */
|
|
16254
|
+
/* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
|
|
16255
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15392
16256
|
"ID: ",
|
|
15393
|
-
/* @__PURE__ */
|
|
16257
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.id })
|
|
15394
16258
|
] }),
|
|
15395
|
-
/* @__PURE__ */
|
|
16259
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15396
16260
|
"Status: ",
|
|
15397
|
-
/* @__PURE__ */
|
|
16261
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.status })
|
|
15398
16262
|
] }),
|
|
15399
|
-
psd && /* @__PURE__ */
|
|
15400
|
-
/* @__PURE__ */
|
|
15401
|
-
/* @__PURE__ */
|
|
16263
|
+
psd && /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
|
|
16264
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: "Payment Details:" }),
|
|
16265
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15402
16266
|
" ",
|
|
15403
16267
|
"Outcome:",
|
|
15404
16268
|
" ",
|
|
15405
|
-
/* @__PURE__ */
|
|
16269
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, color: psd.outcome === "success" ? "green" : "red", children: psd.outcome })
|
|
15406
16270
|
] }),
|
|
15407
|
-
psd.code && /* @__PURE__ */
|
|
16271
|
+
psd.code && /* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15408
16272
|
" ",
|
|
15409
16273
|
"Code: ",
|
|
15410
|
-
/* @__PURE__ */
|
|
16274
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: psd.code })
|
|
15411
16275
|
] }),
|
|
15412
|
-
psd.decline_code && /* @__PURE__ */
|
|
16276
|
+
psd.decline_code && /* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15413
16277
|
" ",
|
|
15414
16278
|
"Decline Reason: ",
|
|
15415
|
-
/* @__PURE__ */
|
|
16279
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: psd.decline_code })
|
|
15416
16280
|
] }),
|
|
15417
|
-
/* @__PURE__ */
|
|
16281
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15418
16282
|
" ",
|
|
15419
16283
|
"Amount:",
|
|
15420
16284
|
" ",
|
|
15421
|
-
/* @__PURE__ */
|
|
16285
|
+
/* @__PURE__ */ jsxs21(Text23, { bold: true, children: [
|
|
15422
16286
|
psd.amount,
|
|
15423
16287
|
" ",
|
|
15424
16288
|
psd.currency
|
|
15425
16289
|
] })
|
|
15426
16290
|
] }),
|
|
15427
|
-
psd.created && /* @__PURE__ */
|
|
16291
|
+
psd.created && /* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15428
16292
|
" ",
|
|
15429
16293
|
"Charged At:",
|
|
15430
16294
|
" ",
|
|
15431
|
-
/* @__PURE__ */
|
|
16295
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: new Date(psd.created * 1e3).toISOString() })
|
|
15432
16296
|
] }),
|
|
15433
|
-
psd.refund_details && /* @__PURE__ */
|
|
15434
|
-
/* @__PURE__ */
|
|
16297
|
+
psd.refund_details && /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
|
|
16298
|
+
/* @__PURE__ */ jsxs21(Text23, { bold: true, children: [
|
|
15435
16299
|
" ",
|
|
15436
16300
|
"Refund:"
|
|
15437
16301
|
] }),
|
|
15438
|
-
/* @__PURE__ */
|
|
16302
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15439
16303
|
" ",
|
|
15440
16304
|
"Amount:",
|
|
15441
16305
|
" ",
|
|
15442
|
-
/* @__PURE__ */
|
|
16306
|
+
/* @__PURE__ */ jsxs21(Text23, { bold: true, children: [
|
|
15443
16307
|
psd.refund_details.amount,
|
|
15444
16308
|
" ",
|
|
15445
16309
|
psd.refund_details.currency
|
|
15446
16310
|
] })
|
|
15447
16311
|
] }),
|
|
15448
|
-
/* @__PURE__ */
|
|
16312
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15449
16313
|
" ",
|
|
15450
16314
|
"State: ",
|
|
15451
|
-
/* @__PURE__ */
|
|
16315
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: psd.refund_details.state })
|
|
15452
16316
|
] })
|
|
15453
16317
|
] })
|
|
15454
16318
|
] })
|
|
@@ -15456,71 +16320,71 @@ var RetrieveSpendRequest = ({
|
|
|
15456
16320
|
] });
|
|
15457
16321
|
}
|
|
15458
16322
|
if (phase === "declined") {
|
|
15459
|
-
return /* @__PURE__ */
|
|
15460
|
-
/* @__PURE__ */
|
|
15461
|
-
/* @__PURE__ */
|
|
15462
|
-
/* @__PURE__ */
|
|
16323
|
+
return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
|
|
16324
|
+
/* @__PURE__ */ jsx30(Text23, { color: "red", children: "\u2717 Spend request declined" }),
|
|
16325
|
+
/* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
|
|
16326
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15463
16327
|
"ID: ",
|
|
15464
|
-
/* @__PURE__ */
|
|
16328
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.id })
|
|
15465
16329
|
] }),
|
|
15466
|
-
/* @__PURE__ */
|
|
16330
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15467
16331
|
"Status:",
|
|
15468
16332
|
" ",
|
|
15469
|
-
/* @__PURE__ */
|
|
16333
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, color: "red", children: request?.status })
|
|
15470
16334
|
] }),
|
|
15471
|
-
/* @__PURE__ */
|
|
16335
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15472
16336
|
"Amount:",
|
|
15473
16337
|
" ",
|
|
15474
|
-
/* @__PURE__ */
|
|
16338
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.amount != null ? String(request.amount) : "N/A" })
|
|
15475
16339
|
] }),
|
|
15476
|
-
/* @__PURE__ */
|
|
16340
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15477
16341
|
"Merchant: ",
|
|
15478
|
-
/* @__PURE__ */
|
|
16342
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.merchant_name })
|
|
15479
16343
|
] })
|
|
15480
16344
|
] })
|
|
15481
16345
|
] });
|
|
15482
16346
|
}
|
|
15483
|
-
return /* @__PURE__ */
|
|
15484
|
-
/* @__PURE__ */
|
|
15485
|
-
/* @__PURE__ */
|
|
15486
|
-
/* @__PURE__ */
|
|
16347
|
+
return /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", children: [
|
|
16348
|
+
/* @__PURE__ */ jsx30(Text23, { color: "green", children: "\u2713 Spend request approved" }),
|
|
16349
|
+
/* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
|
|
16350
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15487
16351
|
"ID: ",
|
|
15488
|
-
/* @__PURE__ */
|
|
16352
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.id })
|
|
15489
16353
|
] }),
|
|
15490
|
-
/* @__PURE__ */
|
|
16354
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15491
16355
|
"Status:",
|
|
15492
16356
|
" ",
|
|
15493
|
-
/* @__PURE__ */
|
|
16357
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, color: "green", children: request?.status })
|
|
15494
16358
|
] }),
|
|
15495
|
-
/* @__PURE__ */
|
|
16359
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15496
16360
|
"Amount:",
|
|
15497
16361
|
" ",
|
|
15498
|
-
/* @__PURE__ */
|
|
16362
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.amount != null ? String(request.amount) : "N/A" })
|
|
15499
16363
|
] }),
|
|
15500
|
-
/* @__PURE__ */
|
|
16364
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15501
16365
|
"Merchant: ",
|
|
15502
|
-
/* @__PURE__ */
|
|
16366
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.merchant_name })
|
|
15503
16367
|
] }),
|
|
15504
|
-
/* @__PURE__ */
|
|
16368
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15505
16369
|
"Line Items:",
|
|
15506
16370
|
" ",
|
|
15507
|
-
/* @__PURE__ */
|
|
16371
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.line_items.map((li) => li.name).join(", ") })
|
|
15508
16372
|
] }),
|
|
15509
|
-
request?.link_pay_token && /* @__PURE__ */
|
|
15510
|
-
/* @__PURE__ */
|
|
15511
|
-
/* @__PURE__ */
|
|
16373
|
+
request?.link_pay_token && /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
|
|
16374
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: "Link Pay Token:" }),
|
|
16375
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15512
16376
|
" ",
|
|
15513
|
-
/* @__PURE__ */
|
|
16377
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: request.link_pay_token })
|
|
15514
16378
|
] })
|
|
15515
16379
|
] }),
|
|
15516
|
-
request?.payment_status_details && /* @__PURE__ */
|
|
15517
|
-
/* @__PURE__ */
|
|
15518
|
-
/* @__PURE__ */
|
|
16380
|
+
request?.payment_status_details && /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
|
|
16381
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: "Last Payment Attempt:" }),
|
|
16382
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15519
16383
|
" ",
|
|
15520
16384
|
"Outcome:",
|
|
15521
16385
|
" ",
|
|
15522
|
-
/* @__PURE__ */
|
|
15523
|
-
|
|
16386
|
+
/* @__PURE__ */ jsx30(
|
|
16387
|
+
Text23,
|
|
15524
16388
|
{
|
|
15525
16389
|
bold: true,
|
|
15526
16390
|
color: request.payment_status_details.outcome === "success" ? "green" : "red",
|
|
@@ -15528,79 +16392,79 @@ var RetrieveSpendRequest = ({
|
|
|
15528
16392
|
}
|
|
15529
16393
|
)
|
|
15530
16394
|
] }),
|
|
15531
|
-
request.payment_status_details.code && /* @__PURE__ */
|
|
16395
|
+
request.payment_status_details.code && /* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15532
16396
|
" ",
|
|
15533
16397
|
"Code:",
|
|
15534
16398
|
" ",
|
|
15535
|
-
/* @__PURE__ */
|
|
16399
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: request.payment_status_details.code })
|
|
15536
16400
|
] }),
|
|
15537
|
-
request.payment_status_details.decline_code && /* @__PURE__ */
|
|
16401
|
+
request.payment_status_details.decline_code && /* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15538
16402
|
" ",
|
|
15539
16403
|
"Decline Reason:",
|
|
15540
16404
|
" ",
|
|
15541
|
-
/* @__PURE__ */
|
|
16405
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: request.payment_status_details.decline_code })
|
|
15542
16406
|
] })
|
|
15543
16407
|
] }),
|
|
15544
|
-
request?.shared_payment_token && /* @__PURE__ */
|
|
15545
|
-
/* @__PURE__ */
|
|
16408
|
+
request?.shared_payment_token && /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
|
|
16409
|
+
/* @__PURE__ */ jsxs21(Text23, { bold: true, children: [
|
|
15546
16410
|
"\x1B]8;;https://docs.stripe.com/agentic-commerce/concepts/shared-payment-tokens\x07",
|
|
15547
16411
|
"Shared Payment Token",
|
|
15548
16412
|
"\x1B]8;;\x07",
|
|
15549
16413
|
":"
|
|
15550
16414
|
] }),
|
|
15551
|
-
/* @__PURE__ */
|
|
16415
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15552
16416
|
" ",
|
|
15553
16417
|
"Token: ",
|
|
15554
|
-
/* @__PURE__ */
|
|
16418
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: request.shared_payment_token.id })
|
|
15555
16419
|
] })
|
|
15556
16420
|
] }),
|
|
15557
|
-
request?.card && !outputFile && /* @__PURE__ */
|
|
15558
|
-
/* @__PURE__ */
|
|
15559
|
-
/* @__PURE__ */
|
|
16421
|
+
request?.card && !outputFile && /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
|
|
16422
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: "Card Details:" }),
|
|
16423
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15560
16424
|
" ",
|
|
15561
16425
|
"Number: ",
|
|
15562
|
-
/* @__PURE__ */
|
|
16426
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.card.number })
|
|
15563
16427
|
] }),
|
|
15564
|
-
/* @__PURE__ */
|
|
16428
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15565
16429
|
" ",
|
|
15566
16430
|
"Brand: ",
|
|
15567
|
-
/* @__PURE__ */
|
|
16431
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: request?.card.brand })
|
|
15568
16432
|
] }),
|
|
15569
|
-
/* @__PURE__ */
|
|
16433
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15570
16434
|
" ",
|
|
15571
16435
|
"Expiry:",
|
|
15572
16436
|
" ",
|
|
15573
|
-
/* @__PURE__ */
|
|
16437
|
+
/* @__PURE__ */ jsxs21(Text23, { bold: true, children: [
|
|
15574
16438
|
String(request?.card.exp_month).padStart(2, "0"),
|
|
15575
16439
|
"/",
|
|
15576
16440
|
request?.card.exp_year
|
|
15577
16441
|
] })
|
|
15578
16442
|
] }),
|
|
15579
|
-
request?.card.cvc && /* @__PURE__ */
|
|
16443
|
+
request?.card.cvc && /* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15580
16444
|
" ",
|
|
15581
16445
|
"CVC: ",
|
|
15582
|
-
/* @__PURE__ */
|
|
16446
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: request.card.cvc })
|
|
15583
16447
|
] }),
|
|
15584
|
-
request?.card.valid_until && /* @__PURE__ */
|
|
16448
|
+
request?.card.valid_until && /* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15585
16449
|
" ",
|
|
15586
16450
|
"Valid Until: ",
|
|
15587
|
-
/* @__PURE__ */
|
|
16451
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: request.card.valid_until })
|
|
15588
16452
|
] }),
|
|
15589
|
-
request?.card.billing_address && /* @__PURE__ */
|
|
15590
|
-
/* @__PURE__ */
|
|
15591
|
-
/* @__PURE__ */
|
|
16453
|
+
request?.card.billing_address && /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
|
|
16454
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: " Billing Address:" }),
|
|
16455
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15592
16456
|
" ",
|
|
15593
16457
|
request.card.billing_address.name
|
|
15594
16458
|
] }),
|
|
15595
|
-
/* @__PURE__ */
|
|
16459
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15596
16460
|
" ",
|
|
15597
16461
|
request.card.billing_address.line1
|
|
15598
16462
|
] }),
|
|
15599
|
-
request.card.billing_address.line2 && /* @__PURE__ */
|
|
16463
|
+
request.card.billing_address.line2 && /* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15600
16464
|
" ",
|
|
15601
16465
|
request.card.billing_address.line2
|
|
15602
16466
|
] }),
|
|
15603
|
-
/* @__PURE__ */
|
|
16467
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15604
16468
|
" ",
|
|
15605
16469
|
[
|
|
15606
16470
|
request.card.billing_address.city,
|
|
@@ -15608,18 +16472,18 @@ var RetrieveSpendRequest = ({
|
|
|
15608
16472
|
request.card.billing_address.postal_code
|
|
15609
16473
|
].filter(Boolean).join(", ")
|
|
15610
16474
|
] }),
|
|
15611
|
-
/* @__PURE__ */
|
|
16475
|
+
/* @__PURE__ */ jsxs21(Text23, { children: [
|
|
15612
16476
|
" ",
|
|
15613
16477
|
request.card.billing_address.country
|
|
15614
16478
|
] })
|
|
15615
16479
|
] })
|
|
15616
16480
|
] }),
|
|
15617
|
-
request?.card && outputFile && /* @__PURE__ */
|
|
15618
|
-
outputFilePath && /* @__PURE__ */
|
|
16481
|
+
request?.card && outputFile && /* @__PURE__ */ jsxs21(Box21, { flexDirection: "column", marginTop: 1, children: [
|
|
16482
|
+
outputFilePath && /* @__PURE__ */ jsxs21(Text23, { color: "green", children: [
|
|
15619
16483
|
"Card credentials written to ",
|
|
15620
|
-
/* @__PURE__ */
|
|
16484
|
+
/* @__PURE__ */ jsx30(Text23, { bold: true, children: outputFilePath })
|
|
15621
16485
|
] }),
|
|
15622
|
-
fileError && /* @__PURE__ */
|
|
16486
|
+
fileError && /* @__PURE__ */ jsxs21(Text23, { color: "red", children: [
|
|
15623
16487
|
"Failed to write card file: ",
|
|
15624
16488
|
fileError
|
|
15625
16489
|
] })
|
|
@@ -15629,140 +16493,143 @@ var RetrieveSpendRequest = ({
|
|
|
15629
16493
|
};
|
|
15630
16494
|
|
|
15631
16495
|
// src/commands/spend-request/schema.ts
|
|
15632
|
-
import { z as
|
|
15633
|
-
var createOptions =
|
|
15634
|
-
paymentMethodId:
|
|
15635
|
-
credentialType:
|
|
16496
|
+
import { z as z10 } from "incur";
|
|
16497
|
+
var createOptions = z10.object({
|
|
16498
|
+
paymentMethodId: z10.string().optional().describe("Payment method ID"),
|
|
16499
|
+
credentialType: z10.enum(["shared_payment_token", "card"]).default("card").describe(
|
|
15636
16500
|
'"card" for checkout forms/Stripe Elements; "shared_payment_token" for HTTP 402/machine payment flows'
|
|
15637
16501
|
),
|
|
15638
|
-
networkId:
|
|
16502
|
+
networkId: z10.string().optional().describe(
|
|
15639
16503
|
"Network ID (required for shared_payment_token) \u2014 use `link-cli mpp decode` to extract"
|
|
15640
16504
|
),
|
|
15641
|
-
amount:
|
|
15642
|
-
currency:
|
|
15643
|
-
merchantName:
|
|
16505
|
+
amount: z10.coerce.number().int().positive().max(5e5).describe("Amount in cents, max 500000 ($5,000.00)"),
|
|
16506
|
+
currency: z10.string().length(3).default("usd").describe("Currency code"),
|
|
16507
|
+
merchantName: z10.string().optional().describe(
|
|
15644
16508
|
"Merchant name (required for card; forbidden for shared_payment_token)"
|
|
15645
16509
|
),
|
|
15646
|
-
merchantUrl:
|
|
16510
|
+
merchantUrl: z10.string().optional().describe(
|
|
15647
16511
|
"Merchant URL (required for card; forbidden for shared_payment_token)"
|
|
15648
16512
|
),
|
|
15649
|
-
context:
|
|
16513
|
+
context: z10.string().min(100).describe(
|
|
15650
16514
|
"Min 100 chars \u2014 describe the purchase and rationale; the user reads this when approving"
|
|
15651
16515
|
),
|
|
15652
|
-
lineItem:
|
|
16516
|
+
lineItem: z10.array(z10.union([z10.string(), z10.record(z10.string(), z10.unknown())])).default([]).describe(
|
|
15653
16517
|
'Line item (repeatable, key:value format). Keys: name (required), quantity, unit_amount, description, sku, url, image_url, product_url. Example: "name:Shoes,unit_amount:5000,quantity:2"'
|
|
15654
16518
|
),
|
|
15655
|
-
total:
|
|
16519
|
+
total: z10.array(z10.union([z10.string(), z10.record(z10.string(), z10.unknown())])).default([]).describe(
|
|
15656
16520
|
'Total (repeatable, key:value format). Keys: type (required; one of: subtotal, tax, total, items_base_amount, items_discount, discount, fulfillment, shipping, fee, gift_wrap, tip, store_credit), display_text (required), amount (required). Example: "type:total,display_text:Total,amount:5000"'
|
|
15657
16521
|
),
|
|
15658
|
-
requestApproval:
|
|
15659
|
-
test:
|
|
16522
|
+
requestApproval: z10.boolean().default(true).describe("Request approval and poll until approved/denied/expired"),
|
|
16523
|
+
test: z10.boolean().default(false).describe(
|
|
15660
16524
|
"Use test mode (creates testmode credentials from test card data)"
|
|
15661
16525
|
),
|
|
15662
|
-
approve:
|
|
15663
|
-
outputFile:
|
|
16526
|
+
approve: z10.boolean().default(false).describe(""),
|
|
16527
|
+
outputFile: z10.string().optional().describe(
|
|
15664
16528
|
"Write full card credentials to this file path; stdout shows redacted card data only"
|
|
15665
16529
|
),
|
|
15666
|
-
force:
|
|
16530
|
+
force: z10.boolean().default(false).describe("Overwrite output file if it already exists"),
|
|
16531
|
+
approvalDetail: z10.union([z10.string(), z10.record(z10.string(), z10.unknown())]).optional().describe(
|
|
16532
|
+
"Approval details object (MCP/agent: pass as object; CLI: pass as JSON string). Required fields: approved_at (unix timestamp), approval_method (click|programmatic|voice), app_name, external_user_id. Optional: ip_address, user_agent, device_type (mobile|web), agent_log_id, external_user_name, external_session_id, authentication_method (biometric_face|biometric_fingerprint|passkey)."
|
|
16533
|
+
)
|
|
15667
16534
|
});
|
|
15668
|
-
var
|
|
15669
|
-
includeHistory:
|
|
16535
|
+
var listOptions3 = z10.object({
|
|
16536
|
+
includeHistory: z10.boolean().default(false).describe("Include expired and terminal spend requests")
|
|
15670
16537
|
});
|
|
15671
|
-
var retrieveOptions =
|
|
15672
|
-
timeout:
|
|
16538
|
+
var retrieveOptions = z10.object({
|
|
16539
|
+
timeout: z10.coerce.number().default(600).describe(
|
|
15673
16540
|
"Polling timeout in seconds. When reached during active polling, exits non-zero with POLLING_TIMEOUT. Default exceeds the server-side spend-request expiry so polling outlives the request itself."
|
|
15674
16541
|
),
|
|
15675
|
-
interval:
|
|
16542
|
+
interval: z10.coerce.number().default(0).describe(
|
|
15676
16543
|
"Poll interval in seconds. When > 0, polls until status is terminal, timeout is reached, or max attempts are exhausted."
|
|
15677
16544
|
),
|
|
15678
|
-
maxAttempts:
|
|
16545
|
+
maxAttempts: z10.coerce.number().default(0).describe(
|
|
15679
16546
|
"Max poll attempts. 0 = unlimited. Exhaustion during active polling exits non-zero with POLLING_TIMEOUT."
|
|
15680
16547
|
),
|
|
15681
|
-
include:
|
|
15682
|
-
outputFile:
|
|
16548
|
+
include: z10.array(z10.string()).default([]).describe("Include extra data (repeatable, e.g. --include card)"),
|
|
16549
|
+
outputFile: z10.string().optional().describe(
|
|
15683
16550
|
"Write full card credentials to this file path; stdout shows redacted card data only"
|
|
15684
16551
|
),
|
|
15685
|
-
force:
|
|
16552
|
+
force: z10.boolean().default(false).describe("Overwrite output file if it already exists")
|
|
15686
16553
|
});
|
|
15687
|
-
var updateOptions =
|
|
15688
|
-
paymentMethodId:
|
|
15689
|
-
amount:
|
|
15690
|
-
merchantUrl:
|
|
15691
|
-
profileId:
|
|
15692
|
-
merchantId:
|
|
15693
|
-
currency:
|
|
15694
|
-
lineItem:
|
|
16554
|
+
var updateOptions = z10.object({
|
|
16555
|
+
paymentMethodId: z10.string().optional().describe("Payment method ID"),
|
|
16556
|
+
amount: z10.coerce.number().optional().describe("Amount in cents"),
|
|
16557
|
+
merchantUrl: z10.string().optional().describe("Merchant URL"),
|
|
16558
|
+
profileId: z10.string().optional().describe("Profile ID"),
|
|
16559
|
+
merchantId: z10.string().optional().describe("Merchant ID"),
|
|
16560
|
+
currency: z10.string().optional().describe("Currency code"),
|
|
16561
|
+
lineItem: z10.array(z10.union([z10.string(), z10.record(z10.string(), z10.unknown())])).default([]).describe(
|
|
15695
16562
|
'Line item (repeatable, key:value format). Keys: name (required), quantity, unit_amount, description, sku, url, image_url, product_url. Example: "name:Shoes,unit_amount:5000,quantity:2"'
|
|
15696
16563
|
),
|
|
15697
|
-
total:
|
|
16564
|
+
total: z10.array(z10.union([z10.string(), z10.record(z10.string(), z10.unknown())])).default([]).describe(
|
|
15698
16565
|
'Total (repeatable, key:value format). Keys: type (required; one of: subtotal, tax, total, items_base_amount, items_discount, discount, fulfillment, shipping, fee, gift_wrap, tip, store_credit), display_text (required), amount (required). Example: "type:total,display_text:Total,amount:5000"'
|
|
15699
16566
|
)
|
|
15700
16567
|
});
|
|
15701
16568
|
|
|
15702
16569
|
// src/commands/spend-request/update.tsx
|
|
15703
|
-
import { Box as
|
|
15704
|
-
import
|
|
15705
|
-
import { useCallback as
|
|
15706
|
-
import { jsx as
|
|
16570
|
+
import { Box as Box22, Text as Text24 } from "ink";
|
|
16571
|
+
import Spinner14 from "ink-spinner";
|
|
16572
|
+
import { useCallback as useCallback11 } from "react";
|
|
16573
|
+
import { jsx as jsx31, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
15707
16574
|
var UpdateSpendRequest = ({
|
|
15708
16575
|
repository,
|
|
15709
16576
|
id,
|
|
15710
16577
|
params,
|
|
15711
16578
|
onComplete
|
|
15712
16579
|
}) => {
|
|
15713
|
-
const action =
|
|
16580
|
+
const action = useCallback11(
|
|
15714
16581
|
() => repository.updateSpendRequest(id, params),
|
|
15715
16582
|
[repository, id, params]
|
|
15716
16583
|
);
|
|
15717
16584
|
const { status, data: request, error } = useAsyncAction(action, onComplete);
|
|
15718
16585
|
if (status === "loading") {
|
|
15719
|
-
return /* @__PURE__ */
|
|
15720
|
-
/* @__PURE__ */
|
|
16586
|
+
return /* @__PURE__ */ jsx31(Box22, { children: /* @__PURE__ */ jsxs22(Text24, { color: "cyan", children: [
|
|
16587
|
+
/* @__PURE__ */ jsx31(Spinner14, { type: "dots" }),
|
|
15721
16588
|
" Updating spend request ",
|
|
15722
16589
|
id,
|
|
15723
16590
|
"..."
|
|
15724
16591
|
] }) });
|
|
15725
16592
|
}
|
|
15726
16593
|
if (status === "error") {
|
|
15727
|
-
return /* @__PURE__ */
|
|
15728
|
-
/* @__PURE__ */
|
|
15729
|
-
/* @__PURE__ */
|
|
16594
|
+
return /* @__PURE__ */ jsxs22(Box22, { flexDirection: "column", children: [
|
|
16595
|
+
/* @__PURE__ */ jsx31(Text24, { color: "red", children: "\u2717 Failed to update spend request" }),
|
|
16596
|
+
/* @__PURE__ */ jsx31(Text24, { color: "red", children: error })
|
|
15730
16597
|
] });
|
|
15731
16598
|
}
|
|
15732
|
-
return /* @__PURE__ */
|
|
15733
|
-
/* @__PURE__ */
|
|
15734
|
-
/* @__PURE__ */
|
|
15735
|
-
/* @__PURE__ */
|
|
16599
|
+
return /* @__PURE__ */ jsxs22(Box22, { flexDirection: "column", children: [
|
|
16600
|
+
/* @__PURE__ */ jsx31(Text24, { color: "green", children: "\u2713 Spend request updated" }),
|
|
16601
|
+
/* @__PURE__ */ jsxs22(Box22, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
|
|
16602
|
+
/* @__PURE__ */ jsxs22(Text24, { children: [
|
|
15736
16603
|
"ID: ",
|
|
15737
|
-
/* @__PURE__ */
|
|
16604
|
+
/* @__PURE__ */ jsx31(Text24, { bold: true, children: request?.id })
|
|
15738
16605
|
] }),
|
|
15739
|
-
/* @__PURE__ */
|
|
16606
|
+
/* @__PURE__ */ jsxs22(Text24, { children: [
|
|
15740
16607
|
"Status: ",
|
|
15741
|
-
/* @__PURE__ */
|
|
16608
|
+
/* @__PURE__ */ jsx31(Text24, { bold: true, children: request?.status })
|
|
15742
16609
|
] }),
|
|
15743
|
-
/* @__PURE__ */
|
|
16610
|
+
/* @__PURE__ */ jsxs22(Text24, { children: [
|
|
15744
16611
|
"Amount:",
|
|
15745
16612
|
" ",
|
|
15746
|
-
/* @__PURE__ */
|
|
16613
|
+
/* @__PURE__ */ jsx31(Text24, { bold: true, children: (() => {
|
|
15747
16614
|
const t = request?.totals.find((t2) => t2.type === "total");
|
|
15748
16615
|
return t ? String(t.amount) : "N/A";
|
|
15749
16616
|
})() })
|
|
15750
16617
|
] }),
|
|
15751
|
-
/* @__PURE__ */
|
|
16618
|
+
/* @__PURE__ */ jsxs22(Text24, { children: [
|
|
15752
16619
|
"Merchant: ",
|
|
15753
|
-
/* @__PURE__ */
|
|
16620
|
+
/* @__PURE__ */ jsx31(Text24, { bold: true, children: request?.merchant_name })
|
|
15754
16621
|
] }),
|
|
15755
|
-
/* @__PURE__ */
|
|
16622
|
+
/* @__PURE__ */ jsxs22(Text24, { children: [
|
|
15756
16623
|
"Line Items:",
|
|
15757
16624
|
" ",
|
|
15758
|
-
/* @__PURE__ */
|
|
16625
|
+
/* @__PURE__ */ jsx31(Text24, { bold: true, children: request?.line_items.map((li) => li.name).join(", ") })
|
|
15759
16626
|
] })
|
|
15760
16627
|
] })
|
|
15761
16628
|
] });
|
|
15762
16629
|
};
|
|
15763
16630
|
|
|
15764
16631
|
// src/commands/spend-request/index.tsx
|
|
15765
|
-
import { jsx as
|
|
16632
|
+
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
15766
16633
|
async function applyOutputFile(request, outputFile, force) {
|
|
15767
16634
|
if (!outputFile || !request.card) return request;
|
|
15768
16635
|
const fileData = {
|
|
@@ -15781,19 +16648,19 @@ async function applyOutputFile(request, outputFile, force) {
|
|
|
15781
16648
|
};
|
|
15782
16649
|
}
|
|
15783
16650
|
function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
|
|
15784
|
-
const cli2 =
|
|
16651
|
+
const cli2 = Cli11.create("spend-request", {
|
|
15785
16652
|
description: "Spend request management commands"
|
|
15786
16653
|
});
|
|
15787
16654
|
cli2.command("list", {
|
|
15788
16655
|
description: "List spend requests. By default returns only active requests (created, pending_approval, approved). Use --include-history to return all spend requests including expired and terminal states.",
|
|
15789
16656
|
outputPolicy: "agent-only",
|
|
15790
|
-
options:
|
|
16657
|
+
options: listOptions3,
|
|
15791
16658
|
middleware: [requireAuth(authStorage2, envAccessToken2)],
|
|
15792
16659
|
async run(c) {
|
|
15793
16660
|
const opts = { includeHistory: c.options.includeHistory ?? false };
|
|
15794
16661
|
if (!c.agent && !c.formatExplicit) {
|
|
15795
16662
|
return renderInteractive(
|
|
15796
|
-
/* @__PURE__ */
|
|
16663
|
+
/* @__PURE__ */ jsx32(
|
|
15797
16664
|
SpendRequestList,
|
|
15798
16665
|
{
|
|
15799
16666
|
repository,
|
|
@@ -15857,6 +16724,7 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
|
|
|
15857
16724
|
const totals = opts.total?.length ? opts.total.map(
|
|
15858
16725
|
(item) => typeof item === "string" ? parseTotalFlag(item) : item
|
|
15859
16726
|
) : void 0;
|
|
16727
|
+
const approvalDetails = opts.approvalDetail !== void 0 ? typeof opts.approvalDetail === "string" ? JSON.parse(opts.approvalDetail) : opts.approvalDetail : void 0;
|
|
15860
16728
|
const createParams = {
|
|
15861
16729
|
payment_details: opts.paymentMethodId,
|
|
15862
16730
|
credential_type: credentialType,
|
|
@@ -15870,14 +16738,15 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
|
|
|
15870
16738
|
totals,
|
|
15871
16739
|
request_approval: requestApproval || void 0,
|
|
15872
16740
|
test: opts.test ? true : void 0,
|
|
15873
|
-
approve: opts.approve ? true : void 0
|
|
16741
|
+
approve: opts.approve ? true : void 0,
|
|
16742
|
+
approval_details: approvalDetails
|
|
15874
16743
|
};
|
|
15875
16744
|
const outputFile = opts.outputFile;
|
|
15876
16745
|
const forceOverwrite = opts.force;
|
|
15877
16746
|
if (!c.agent && !c.formatExplicit) {
|
|
15878
|
-
let capturedResult =
|
|
16747
|
+
let capturedResult = void 0;
|
|
15879
16748
|
return renderInteractive(
|
|
15880
|
-
/* @__PURE__ */
|
|
16749
|
+
/* @__PURE__ */ jsx32(
|
|
15881
16750
|
CreateSpendRequest,
|
|
15882
16751
|
{
|
|
15883
16752
|
repository,
|
|
@@ -15891,13 +16760,28 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
|
|
|
15891
16760
|
}
|
|
15892
16761
|
),
|
|
15893
16762
|
() => {
|
|
15894
|
-
if (
|
|
16763
|
+
if (capturedResult === void 0)
|
|
15895
16764
|
throw new Error("Component exited without producing a result");
|
|
16765
|
+
if (capturedResult === null) process.exit(1);
|
|
15896
16766
|
return capturedResult;
|
|
15897
16767
|
}
|
|
15898
16768
|
);
|
|
15899
16769
|
}
|
|
15900
|
-
|
|
16770
|
+
let created;
|
|
16771
|
+
try {
|
|
16772
|
+
created = await repository.createSpendRequest(createParams);
|
|
16773
|
+
} catch (err) {
|
|
16774
|
+
if (err instanceof LinkApiError) {
|
|
16775
|
+
const apiErr = err.details;
|
|
16776
|
+
if (apiErr?.error?.verification_url) {
|
|
16777
|
+
return c.error({
|
|
16778
|
+
code: err.code,
|
|
16779
|
+
message: `${err.message} Verification URL: ${apiErr.error.verification_url}`
|
|
16780
|
+
});
|
|
16781
|
+
}
|
|
16782
|
+
}
|
|
16783
|
+
throw err;
|
|
16784
|
+
}
|
|
15901
16785
|
if (!requestApproval) {
|
|
15902
16786
|
try {
|
|
15903
16787
|
yield await applyOutputFile(created, outputFile, forceOverwrite);
|
|
@@ -15922,8 +16806,8 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
|
|
|
15922
16806
|
});
|
|
15923
16807
|
cli2.command("update", {
|
|
15924
16808
|
description: "Update a spend request",
|
|
15925
|
-
args:
|
|
15926
|
-
id:
|
|
16809
|
+
args: z11.object({
|
|
16810
|
+
id: z11.string().describe("Spend request ID")
|
|
15927
16811
|
}),
|
|
15928
16812
|
options: updateOptions,
|
|
15929
16813
|
outputPolicy: "agent-only",
|
|
@@ -15951,7 +16835,7 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
|
|
|
15951
16835
|
if (!c.agent && !c.formatExplicit) {
|
|
15952
16836
|
let capturedResult = null;
|
|
15953
16837
|
return renderInteractive(
|
|
15954
|
-
/* @__PURE__ */
|
|
16838
|
+
/* @__PURE__ */ jsx32(
|
|
15955
16839
|
UpdateSpendRequest,
|
|
15956
16840
|
{
|
|
15957
16841
|
repository,
|
|
@@ -15974,17 +16858,17 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
|
|
|
15974
16858
|
});
|
|
15975
16859
|
cli2.command("request-approval", {
|
|
15976
16860
|
description: "Request approval for a spend request",
|
|
15977
|
-
args:
|
|
15978
|
-
id:
|
|
16861
|
+
args: z11.object({
|
|
16862
|
+
id: z11.string().describe("Spend request ID")
|
|
15979
16863
|
}),
|
|
15980
16864
|
outputPolicy: "agent-only",
|
|
15981
16865
|
async *run(c) {
|
|
15982
16866
|
requireAuthGuard(c, authStorage2, envAccessToken2);
|
|
15983
16867
|
const id = c.args.id;
|
|
15984
16868
|
if (!c.agent && !c.formatExplicit) {
|
|
15985
|
-
let capturedResult =
|
|
16869
|
+
let capturedResult = void 0;
|
|
15986
16870
|
return renderInteractive(
|
|
15987
|
-
/* @__PURE__ */
|
|
16871
|
+
/* @__PURE__ */ jsx32(
|
|
15988
16872
|
RequestApproval,
|
|
15989
16873
|
{
|
|
15990
16874
|
repository,
|
|
@@ -15995,13 +16879,28 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
|
|
|
15995
16879
|
}
|
|
15996
16880
|
),
|
|
15997
16881
|
() => {
|
|
15998
|
-
if (
|
|
16882
|
+
if (capturedResult === void 0)
|
|
15999
16883
|
throw new Error("Component exited without producing a result");
|
|
16884
|
+
if (capturedResult === null) process.exit(1);
|
|
16000
16885
|
return capturedResult;
|
|
16001
16886
|
}
|
|
16002
16887
|
);
|
|
16003
16888
|
}
|
|
16004
|
-
|
|
16889
|
+
let approval;
|
|
16890
|
+
try {
|
|
16891
|
+
approval = await repository.requestApproval(id);
|
|
16892
|
+
} catch (err) {
|
|
16893
|
+
if (err instanceof LinkApiError) {
|
|
16894
|
+
const apiErr = err.details;
|
|
16895
|
+
if (apiErr?.error?.verification_url) {
|
|
16896
|
+
return c.error({
|
|
16897
|
+
code: err.code,
|
|
16898
|
+
message: `${err.message} Verification URL: ${apiErr.error.verification_url}`
|
|
16899
|
+
});
|
|
16900
|
+
}
|
|
16901
|
+
}
|
|
16902
|
+
throw err;
|
|
16903
|
+
}
|
|
16005
16904
|
yield {
|
|
16006
16905
|
...approval,
|
|
16007
16906
|
instruction: `Present the approval_url to the user and ask them to approve in the Link app. Then call \`spend-request retrieve ${id} --interval 2 --max-attempts 300\` to poll until approved. Do not wait for the user to reply \u2014 start polling immediately.`,
|
|
@@ -16014,8 +16913,8 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
|
|
|
16014
16913
|
});
|
|
16015
16914
|
cli2.command("retrieve", {
|
|
16016
16915
|
description: "Retrieve a spend request",
|
|
16017
|
-
args:
|
|
16018
|
-
id:
|
|
16916
|
+
args: z11.object({
|
|
16917
|
+
id: z11.string().describe("Spend request ID")
|
|
16019
16918
|
}),
|
|
16020
16919
|
options: retrieveOptions,
|
|
16021
16920
|
outputPolicy: "agent-only",
|
|
@@ -16033,7 +16932,7 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
|
|
|
16033
16932
|
if (!c.agent && !c.formatExplicit) {
|
|
16034
16933
|
let capturedResult = null;
|
|
16035
16934
|
return renderInteractive(
|
|
16036
|
-
/* @__PURE__ */
|
|
16935
|
+
/* @__PURE__ */ jsx32(
|
|
16037
16936
|
RetrieveSpendRequest,
|
|
16038
16937
|
{
|
|
16039
16938
|
repository,
|
|
@@ -16105,8 +17004,8 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
|
|
|
16105
17004
|
});
|
|
16106
17005
|
cli2.command("cancel", {
|
|
16107
17006
|
description: "Cancel a spend request",
|
|
16108
|
-
args:
|
|
16109
|
-
id:
|
|
17007
|
+
args: z11.object({
|
|
17008
|
+
id: z11.string().describe("Spend request ID")
|
|
16110
17009
|
}),
|
|
16111
17010
|
outputPolicy: "agent-only",
|
|
16112
17011
|
middleware: [requireAuth(authStorage2, envAccessToken2)],
|
|
@@ -16115,7 +17014,7 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
|
|
|
16115
17014
|
if (!c.agent && !c.formatExplicit) {
|
|
16116
17015
|
let capturedResult = null;
|
|
16117
17016
|
return renderInteractive(
|
|
16118
|
-
/* @__PURE__ */
|
|
17017
|
+
/* @__PURE__ */ jsx32(
|
|
16119
17018
|
CancelSpendRequest,
|
|
16120
17019
|
{
|
|
16121
17020
|
repository,
|
|
@@ -16138,55 +17037,221 @@ function createSpendRequestCli(repository, authStorage2, envAccessToken2) {
|
|
|
16138
17037
|
return cli2;
|
|
16139
17038
|
}
|
|
16140
17039
|
|
|
17040
|
+
// src/commands/transactions/index.tsx
|
|
17041
|
+
import { Cli as Cli12 } from "incur";
|
|
17042
|
+
|
|
17043
|
+
// src/commands/transactions/list.tsx
|
|
17044
|
+
import { Box as Box23, Text as Text25 } from "ink";
|
|
17045
|
+
import Spinner15 from "ink-spinner";
|
|
17046
|
+
import { useCallback as useCallback12 } from "react";
|
|
17047
|
+
import { jsx as jsx33, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
17048
|
+
var COLUMN_GAP3 = " ";
|
|
17049
|
+
var DATE_WIDTH = 10;
|
|
17050
|
+
var AMOUNT_WIDTH = 13;
|
|
17051
|
+
var STATUS_WIDTH = 10;
|
|
17052
|
+
var CATEGORY_WIDTH = 16;
|
|
17053
|
+
var MIN_DESCRIPTION_WIDTH = 16;
|
|
17054
|
+
var HORIZONTAL_PADDING2 = 4;
|
|
17055
|
+
function formatAmount(amount, currency) {
|
|
17056
|
+
const currencyCode = currency.toUpperCase();
|
|
17057
|
+
try {
|
|
17058
|
+
const formatter = new Intl.NumberFormat("en-US", {
|
|
17059
|
+
style: "currency",
|
|
17060
|
+
currency: currencyCode
|
|
17061
|
+
});
|
|
17062
|
+
const fractionDigits = formatter.resolvedOptions().maximumFractionDigits ?? 2;
|
|
17063
|
+
return formatter.format(amount / 10 ** fractionDigits);
|
|
17064
|
+
} catch {
|
|
17065
|
+
return `${amount} ${currency}`;
|
|
17066
|
+
}
|
|
17067
|
+
}
|
|
17068
|
+
function truncateCell3(value, width) {
|
|
17069
|
+
if (value.length <= width) {
|
|
17070
|
+
return value;
|
|
17071
|
+
}
|
|
17072
|
+
if (width <= 3) {
|
|
17073
|
+
return value.slice(0, width);
|
|
17074
|
+
}
|
|
17075
|
+
return `${value.slice(0, width - 3)}...`;
|
|
17076
|
+
}
|
|
17077
|
+
function formatCell3(value, width, align = "left") {
|
|
17078
|
+
const truncated = truncateCell3(value, width);
|
|
17079
|
+
return align === "right" ? truncated.padStart(width) : truncated.padEnd(width);
|
|
17080
|
+
}
|
|
17081
|
+
var TransactionsList = ({
|
|
17082
|
+
resource,
|
|
17083
|
+
params,
|
|
17084
|
+
onComplete
|
|
17085
|
+
}) => {
|
|
17086
|
+
const action = useCallback12(
|
|
17087
|
+
() => resource.listTransactions(params),
|
|
17088
|
+
[resource, params]
|
|
17089
|
+
);
|
|
17090
|
+
const { status, data: page, error } = useAsyncAction(action, onComplete);
|
|
17091
|
+
const transactions = page?.data ?? [];
|
|
17092
|
+
const nextCursor = page?.has_more && transactions.length > 0 ? transactions[transactions.length - 1].id : null;
|
|
17093
|
+
const terminalWidth = process.stdout.columns ?? 100;
|
|
17094
|
+
const descriptionWidth = Math.max(
|
|
17095
|
+
MIN_DESCRIPTION_WIDTH,
|
|
17096
|
+
terminalWidth - HORIZONTAL_PADDING2 - DATE_WIDTH - AMOUNT_WIDTH - STATUS_WIDTH - CATEGORY_WIDTH - COLUMN_GAP3.length * 4
|
|
17097
|
+
);
|
|
17098
|
+
const headerRow = [
|
|
17099
|
+
formatCell3("Date", DATE_WIDTH),
|
|
17100
|
+
formatCell3("Amount", AMOUNT_WIDTH, "right"),
|
|
17101
|
+
formatCell3("Status", STATUS_WIDTH),
|
|
17102
|
+
formatCell3("Category", CATEGORY_WIDTH),
|
|
17103
|
+
formatCell3("Description", descriptionWidth)
|
|
17104
|
+
].join(COLUMN_GAP3);
|
|
17105
|
+
const separatorRow = "-".repeat(headerRow.length);
|
|
17106
|
+
const rows = transactions.map(
|
|
17107
|
+
(txn) => [
|
|
17108
|
+
formatCell3(txn.created_date, DATE_WIDTH),
|
|
17109
|
+
formatCell3(formatAmount(txn.amount, txn.currency), AMOUNT_WIDTH, "right"),
|
|
17110
|
+
formatCell3(txn.status, STATUS_WIDTH),
|
|
17111
|
+
formatCell3(txn.category ?? "", CATEGORY_WIDTH),
|
|
17112
|
+
formatCell3(txn.description, descriptionWidth)
|
|
17113
|
+
].join(COLUMN_GAP3)
|
|
17114
|
+
);
|
|
17115
|
+
if (status === "loading") {
|
|
17116
|
+
return /* @__PURE__ */ jsx33(Box23, { children: /* @__PURE__ */ jsxs23(Text25, { color: "cyan", children: [
|
|
17117
|
+
/* @__PURE__ */ jsx33(Spinner15, { type: "dots" }),
|
|
17118
|
+
" Loading transactions..."
|
|
17119
|
+
] }) });
|
|
17120
|
+
}
|
|
17121
|
+
if (status === "error") {
|
|
17122
|
+
return /* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", children: [
|
|
17123
|
+
/* @__PURE__ */ jsx33(Text25, { color: "red", children: "Failed to load transactions" }),
|
|
17124
|
+
/* @__PURE__ */ jsx33(Text25, { color: "red", children: error })
|
|
17125
|
+
] });
|
|
17126
|
+
}
|
|
17127
|
+
if (transactions.length === 0) {
|
|
17128
|
+
return /* @__PURE__ */ jsx33(Box23, { children: /* @__PURE__ */ jsx33(Text25, { dimColor: true, children: "No transactions found" }) });
|
|
17129
|
+
}
|
|
17130
|
+
return /* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", children: [
|
|
17131
|
+
/* @__PURE__ */ jsx33(Text25, { bold: true, children: "Transactions" }),
|
|
17132
|
+
/* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
|
|
17133
|
+
/* @__PURE__ */ jsx33(Text25, { bold: true, children: headerRow }),
|
|
17134
|
+
/* @__PURE__ */ jsx33(Text25, { dimColor: true, children: separatorRow }),
|
|
17135
|
+
rows.map((row, index) => /* @__PURE__ */ jsx33(Text25, { children: row }, transactions[index].id))
|
|
17136
|
+
] }),
|
|
17137
|
+
page?.has_more !== void 0 ? /* @__PURE__ */ jsxs23(Box23, { flexDirection: "column", marginTop: 1, children: [
|
|
17138
|
+
/* @__PURE__ */ jsxs23(Text25, { dimColor: true, children: [
|
|
17139
|
+
"has_more: ",
|
|
17140
|
+
String(page.has_more)
|
|
17141
|
+
] }),
|
|
17142
|
+
nextCursor ? /* @__PURE__ */ jsx33(Text25, { dimColor: true, children: `next page: --starting-after ${nextCursor}` }) : null
|
|
17143
|
+
] }) : null
|
|
17144
|
+
] });
|
|
17145
|
+
};
|
|
17146
|
+
|
|
17147
|
+
// src/commands/transactions/schema.ts
|
|
17148
|
+
import { z as z12 } from "incur";
|
|
17149
|
+
var ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
|
|
17150
|
+
var listOptions4 = z12.object({
|
|
17151
|
+
limit: z12.coerce.number().int().positive().max(100).optional().describe("Maximum number of transactions to return (1-100)."),
|
|
17152
|
+
startingAfter: z12.string().optional().describe("Cursor: return transactions after this transaction ID."),
|
|
17153
|
+
endingBefore: z12.string().optional().describe("Cursor: return transactions before this transaction ID."),
|
|
17154
|
+
startDate: z12.string().regex(ISO_DATE_REGEX, "Date must be in YYYY-MM-DD format.").optional().describe("Only include transactions on or after this YYYY-MM-DD date."),
|
|
17155
|
+
endDate: z12.string().regex(ISO_DATE_REGEX, "Date must be in YYYY-MM-DD format.").optional().describe("Only include transactions on or before this YYYY-MM-DD date."),
|
|
17156
|
+
category: z12.string().optional().describe("Filter by transaction category."),
|
|
17157
|
+
origin: z12.enum(["link", "external_connection"]).optional().describe("Filter by transaction origin: link or external_connection."),
|
|
17158
|
+
source: z12.array(z12.string()).default([]).describe("Filter by source ID. Repeat to include multiple sources.")
|
|
17159
|
+
});
|
|
17160
|
+
|
|
17161
|
+
// src/commands/transactions/index.tsx
|
|
17162
|
+
import { jsx as jsx34 } from "react/jsx-runtime";
|
|
17163
|
+
function createTransactionsCli(createResource, authStorage2, envAccessToken2) {
|
|
17164
|
+
const cli2 = Cli12.create("transactions", {
|
|
17165
|
+
description: "List transactions from Link and external accounts"
|
|
17166
|
+
});
|
|
17167
|
+
cli2.command("list", {
|
|
17168
|
+
description: "List transactions from Link and external accounts, including non-Link activity",
|
|
17169
|
+
options: listOptions4,
|
|
17170
|
+
outputPolicy: "agent-only",
|
|
17171
|
+
middleware: [requireAuth(authStorage2, envAccessToken2)],
|
|
17172
|
+
async run(c) {
|
|
17173
|
+
const opts = c.options;
|
|
17174
|
+
const resource = createResource();
|
|
17175
|
+
const params = {};
|
|
17176
|
+
if (opts.limit !== void 0) params.limit = opts.limit;
|
|
17177
|
+
if (opts.startingAfter !== void 0)
|
|
17178
|
+
params.starting_after = opts.startingAfter;
|
|
17179
|
+
if (opts.endingBefore !== void 0)
|
|
17180
|
+
params.ending_before = opts.endingBefore;
|
|
17181
|
+
if (opts.startDate !== void 0) params.start_date = opts.startDate;
|
|
17182
|
+
if (opts.endDate !== void 0) params.end_date = opts.endDate;
|
|
17183
|
+
if (opts.category !== void 0) params.category = opts.category;
|
|
17184
|
+
if (opts.origin !== void 0) params.origin = opts.origin;
|
|
17185
|
+
if (opts.source.length > 0) params.sources = opts.source;
|
|
17186
|
+
if (!c.agent && !c.formatExplicit) {
|
|
17187
|
+
return renderInteractive(
|
|
17188
|
+
/* @__PURE__ */ jsx34(
|
|
17189
|
+
TransactionsList,
|
|
17190
|
+
{
|
|
17191
|
+
resource,
|
|
17192
|
+
params,
|
|
17193
|
+
onComplete: () => {
|
|
17194
|
+
}
|
|
17195
|
+
}
|
|
17196
|
+
),
|
|
17197
|
+
() => resource.listTransactions(params)
|
|
17198
|
+
);
|
|
17199
|
+
}
|
|
17200
|
+
return resource.listTransactions(params);
|
|
17201
|
+
}
|
|
17202
|
+
});
|
|
17203
|
+
return cli2;
|
|
17204
|
+
}
|
|
17205
|
+
|
|
16141
17206
|
// src/commands/user-info/index.tsx
|
|
16142
|
-
import { Cli as
|
|
17207
|
+
import { Cli as Cli13 } from "incur";
|
|
16143
17208
|
|
|
16144
17209
|
// src/commands/user-info/retrieve.tsx
|
|
16145
|
-
import { Box as
|
|
16146
|
-
import
|
|
16147
|
-
import { useCallback as
|
|
16148
|
-
import { jsx as
|
|
17210
|
+
import { Box as Box24, Text as Text26 } from "ink";
|
|
17211
|
+
import Spinner16 from "ink-spinner";
|
|
17212
|
+
import { useCallback as useCallback13 } from "react";
|
|
17213
|
+
import { jsx as jsx35, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
16149
17214
|
var UserInfoRetrieve = ({
|
|
16150
17215
|
resource,
|
|
16151
17216
|
onComplete
|
|
16152
17217
|
}) => {
|
|
16153
|
-
const action =
|
|
17218
|
+
const action = useCallback13(() => resource.retrieve(), [resource]);
|
|
16154
17219
|
const { status, data: userInfo, error } = useAsyncAction(action, onComplete);
|
|
16155
17220
|
if (status === "loading") {
|
|
16156
|
-
return /* @__PURE__ */
|
|
16157
|
-
/* @__PURE__ */
|
|
17221
|
+
return /* @__PURE__ */ jsx35(Box24, { children: /* @__PURE__ */ jsxs24(Text26, { color: "cyan", children: [
|
|
17222
|
+
/* @__PURE__ */ jsx35(Spinner16, { type: "dots" }),
|
|
16158
17223
|
" Loading user info..."
|
|
16159
17224
|
] }) });
|
|
16160
17225
|
}
|
|
16161
17226
|
if (status === "error") {
|
|
16162
|
-
return /* @__PURE__ */
|
|
16163
|
-
/* @__PURE__ */
|
|
16164
|
-
/* @__PURE__ */
|
|
17227
|
+
return /* @__PURE__ */ jsxs24(Box24, { flexDirection: "column", children: [
|
|
17228
|
+
/* @__PURE__ */ jsx35(Text26, { color: "red", children: "\u2717 Failed to load user info" }),
|
|
17229
|
+
/* @__PURE__ */ jsx35(Text26, { color: "red", children: error })
|
|
16165
17230
|
] });
|
|
16166
17231
|
}
|
|
16167
|
-
return /* @__PURE__ */
|
|
16168
|
-
/* @__PURE__ */
|
|
16169
|
-
/* @__PURE__ */
|
|
16170
|
-
/* @__PURE__ */
|
|
16171
|
-
/* @__PURE__ */
|
|
16172
|
-
userInfo?.email ?? /* @__PURE__ */
|
|
17232
|
+
return /* @__PURE__ */ jsxs24(Box24, { flexDirection: "column", children: [
|
|
17233
|
+
/* @__PURE__ */ jsx35(Text26, { bold: true, children: "User Info" }),
|
|
17234
|
+
/* @__PURE__ */ jsxs24(Box24, { flexDirection: "column", marginTop: 1, paddingX: 2, children: [
|
|
17235
|
+
/* @__PURE__ */ jsxs24(Text26, { children: [
|
|
17236
|
+
/* @__PURE__ */ jsx35(Text26, { dimColor: true, children: "Email: " }),
|
|
17237
|
+
userInfo?.email ?? /* @__PURE__ */ jsx35(Text26, { dimColor: true, children: "Not set" })
|
|
16173
17238
|
] }),
|
|
16174
|
-
/* @__PURE__ */
|
|
16175
|
-
/* @__PURE__ */
|
|
16176
|
-
userInfo?.name ?? /* @__PURE__ */
|
|
17239
|
+
/* @__PURE__ */ jsxs24(Text26, { children: [
|
|
17240
|
+
/* @__PURE__ */ jsx35(Text26, { dimColor: true, children: "Name: " }),
|
|
17241
|
+
userInfo?.name ?? /* @__PURE__ */ jsx35(Text26, { dimColor: true, children: "Not set" })
|
|
16177
17242
|
] }),
|
|
16178
|
-
/* @__PURE__ */
|
|
16179
|
-
/* @__PURE__ */
|
|
16180
|
-
userInfo?.phone ?? /* @__PURE__ */
|
|
17243
|
+
/* @__PURE__ */ jsxs24(Text26, { children: [
|
|
17244
|
+
/* @__PURE__ */ jsx35(Text26, { dimColor: true, children: "Phone: " }),
|
|
17245
|
+
userInfo?.phone ?? /* @__PURE__ */ jsx35(Text26, { dimColor: true, children: "Not set" })
|
|
16181
17246
|
] })
|
|
16182
17247
|
] })
|
|
16183
17248
|
] });
|
|
16184
17249
|
};
|
|
16185
17250
|
|
|
16186
17251
|
// src/commands/user-info/index.tsx
|
|
16187
|
-
import { jsx as
|
|
17252
|
+
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
16188
17253
|
function createUserInfoCli(createResource, authStorage2, envAccessToken2) {
|
|
16189
|
-
const cli2 =
|
|
17254
|
+
const cli2 = Cli13.create("user-info", {
|
|
16190
17255
|
description: "User information commands"
|
|
16191
17256
|
});
|
|
16192
17257
|
cli2.command("retrieve", {
|
|
@@ -16197,7 +17262,7 @@ function createUserInfoCli(createResource, authStorage2, envAccessToken2) {
|
|
|
16197
17262
|
const resource = createResource();
|
|
16198
17263
|
if (!c.agent && !c.formatExplicit) {
|
|
16199
17264
|
return renderInteractive(
|
|
16200
|
-
/* @__PURE__ */
|
|
17265
|
+
/* @__PURE__ */ jsx36(UserInfoRetrieve, { resource, onComplete: () => {
|
|
16201
17266
|
} }),
|
|
16202
17267
|
() => resource.retrieve()
|
|
16203
17268
|
);
|
|
@@ -16248,11 +17313,55 @@ function requireFetchImplementation2(config) {
|
|
|
16248
17313
|
|
|
16249
17314
|
// src/auth/auth-resource.ts
|
|
16250
17315
|
var CLIENT_ID = "lwlpk_U7Qy7ThG69STZk";
|
|
16251
|
-
var DEFAULT_SCOPE = "userinfo:read payment_methods.agentic";
|
|
16252
17316
|
function formatOAuthError(prefix, status, data, rawBody) {
|
|
16253
17317
|
const err = data;
|
|
16254
17318
|
return `${prefix} (${status}): ${err?.error_description ?? err?.error ?? (rawBody || "unknown error")}`;
|
|
16255
17319
|
}
|
|
17320
|
+
function appendAuthorizationDetailValue(params, key, value) {
|
|
17321
|
+
if (Array.isArray(value)) {
|
|
17322
|
+
for (const entry of value) {
|
|
17323
|
+
appendAuthorizationDetailValue(params, `${key}[]`, entry);
|
|
17324
|
+
}
|
|
17325
|
+
return;
|
|
17326
|
+
}
|
|
17327
|
+
if (value !== null && typeof value === "object") {
|
|
17328
|
+
for (const [entryKey, entryValue] of Object.entries(value)) {
|
|
17329
|
+
appendAuthorizationDetailValue(params, `${key}[${entryKey}]`, entryValue);
|
|
17330
|
+
}
|
|
17331
|
+
return;
|
|
17332
|
+
}
|
|
17333
|
+
params.append(key, String(value));
|
|
17334
|
+
}
|
|
17335
|
+
function buildDeviceCodeForm(clientName, options) {
|
|
17336
|
+
const connectionLabel = `${clientName} on ${hostname()}`;
|
|
17337
|
+
const params = new URLSearchParams({
|
|
17338
|
+
client_id: CLIENT_ID,
|
|
17339
|
+
scope: options.scope ?? DEFAULT_SCOPE,
|
|
17340
|
+
connection_label: connectionLabel,
|
|
17341
|
+
client_hint: clientName
|
|
17342
|
+
});
|
|
17343
|
+
const authorizationDetails = buildAuthorizationDetails(
|
|
17344
|
+
options.sourceActions,
|
|
17345
|
+
options.authorizationDetails
|
|
17346
|
+
);
|
|
17347
|
+
for (const detail of authorizationDetails) {
|
|
17348
|
+
appendAuthorizationDetailValue(params, "authorization_details[]", detail);
|
|
17349
|
+
}
|
|
17350
|
+
return params;
|
|
17351
|
+
}
|
|
17352
|
+
function serializeFormBody(params) {
|
|
17353
|
+
return params instanceof URLSearchParams ? params.toString() : new URLSearchParams(params).toString();
|
|
17354
|
+
}
|
|
17355
|
+
function serializeRedactedFormBody(params) {
|
|
17356
|
+
const redacted = new URLSearchParams(params);
|
|
17357
|
+
if (redacted.has("device_code")) {
|
|
17358
|
+
redacted.set("device_code", "<redacted>");
|
|
17359
|
+
}
|
|
17360
|
+
if (redacted.has("refresh_token")) {
|
|
17361
|
+
redacted.set("refresh_token", "<redacted>");
|
|
17362
|
+
}
|
|
17363
|
+
return redacted.toString();
|
|
17364
|
+
}
|
|
16256
17365
|
var LinkAuthResource = class {
|
|
16257
17366
|
config;
|
|
16258
17367
|
fetchImpl;
|
|
@@ -16262,12 +17371,9 @@ var LinkAuthResource = class {
|
|
|
16262
17371
|
}
|
|
16263
17372
|
async postForm(url, params) {
|
|
16264
17373
|
if (this.config.verbose) {
|
|
16265
|
-
const redacted = { ...params };
|
|
16266
|
-
if (redacted.device_code) redacted.device_code = "<redacted>";
|
|
16267
|
-
if (redacted.refresh_token) redacted.refresh_token = "<redacted>";
|
|
16268
17374
|
this.config.logger.debug(
|
|
16269
17375
|
`> POST ${url}
|
|
16270
|
-
${
|
|
17376
|
+
${serializeRedactedFormBody(params)}`
|
|
16271
17377
|
);
|
|
16272
17378
|
}
|
|
16273
17379
|
let response;
|
|
@@ -16278,7 +17384,7 @@ ${JSON.stringify(redacted, null, 2)}`
|
|
|
16278
17384
|
...this.config.defaultHeaders,
|
|
16279
17385
|
"Content-Type": "application/x-www-form-urlencoded"
|
|
16280
17386
|
},
|
|
16281
|
-
body:
|
|
17387
|
+
body: serializeFormBody(params)
|
|
16282
17388
|
});
|
|
16283
17389
|
} catch (error) {
|
|
16284
17390
|
throw new LinkTransportError(`Request failed: POST ${url}`, {
|
|
@@ -16300,16 +17406,12 @@ ${JSON.stringify(redacted, null, 2)}`
|
|
|
16300
17406
|
}
|
|
16301
17407
|
return { status: response.status, data, rawBody };
|
|
16302
17408
|
}
|
|
16303
|
-
async initiateDeviceAuth(
|
|
16304
|
-
const effectiveName = clientName ?? this.config.clientName;
|
|
17409
|
+
async initiateDeviceAuth(options = {}) {
|
|
17410
|
+
const effectiveName = options.clientName ?? this.config.clientName;
|
|
17411
|
+
const params = buildDeviceCodeForm(effectiveName, options);
|
|
16305
17412
|
const { status, data, rawBody } = await this.postForm(
|
|
16306
17413
|
`${this.config.authBaseUrl}/device/code`,
|
|
16307
|
-
|
|
16308
|
-
client_id: CLIENT_ID,
|
|
16309
|
-
scope: DEFAULT_SCOPE,
|
|
16310
|
-
connection_label: `${effectiveName} on ${hostname()}`,
|
|
16311
|
-
client_hint: effectiveName
|
|
16312
|
-
}
|
|
17414
|
+
params
|
|
16313
17415
|
);
|
|
16314
17416
|
if (status < 200 || status >= 300) {
|
|
16315
17417
|
throw new LinkApiError(
|
|
@@ -16488,6 +17590,9 @@ var ResourceFactory = class {
|
|
|
16488
17590
|
paymentMethodsResource;
|
|
16489
17591
|
shippingAddressResource;
|
|
16490
17592
|
userInfoResource;
|
|
17593
|
+
transactionsResource;
|
|
17594
|
+
sourcesResource;
|
|
17595
|
+
balancesResource;
|
|
16491
17596
|
webBotAuthResource;
|
|
16492
17597
|
reportResource;
|
|
16493
17598
|
constructor(options = {}) {
|
|
@@ -16602,6 +17707,48 @@ var ResourceFactory = class {
|
|
|
16602
17707
|
);
|
|
16603
17708
|
return this.userInfoResource;
|
|
16604
17709
|
}
|
|
17710
|
+
createTransactionsResource() {
|
|
17711
|
+
if (this.transactionsResource) {
|
|
17712
|
+
return this.transactionsResource;
|
|
17713
|
+
}
|
|
17714
|
+
const getAccessToken = this.createSdkAccessTokenProvider();
|
|
17715
|
+
this.transactionsResource = sanitizeResource(
|
|
17716
|
+
new TransactionsResource({
|
|
17717
|
+
verbose: this.verbose,
|
|
17718
|
+
defaultHeaders: this.defaultHeaders,
|
|
17719
|
+
getAccessToken
|
|
17720
|
+
})
|
|
17721
|
+
);
|
|
17722
|
+
return this.transactionsResource;
|
|
17723
|
+
}
|
|
17724
|
+
createSourcesResource() {
|
|
17725
|
+
if (this.sourcesResource) {
|
|
17726
|
+
return this.sourcesResource;
|
|
17727
|
+
}
|
|
17728
|
+
const getAccessToken = this.createSdkAccessTokenProvider();
|
|
17729
|
+
this.sourcesResource = sanitizeResource(
|
|
17730
|
+
new SourcesResource({
|
|
17731
|
+
verbose: this.verbose,
|
|
17732
|
+
defaultHeaders: this.defaultHeaders,
|
|
17733
|
+
getAccessToken
|
|
17734
|
+
})
|
|
17735
|
+
);
|
|
17736
|
+
return this.sourcesResource;
|
|
17737
|
+
}
|
|
17738
|
+
createBalancesResource() {
|
|
17739
|
+
if (this.balancesResource) {
|
|
17740
|
+
return this.balancesResource;
|
|
17741
|
+
}
|
|
17742
|
+
const getAccessToken = this.createSdkAccessTokenProvider();
|
|
17743
|
+
this.balancesResource = sanitizeResource(
|
|
17744
|
+
new BalancesResource({
|
|
17745
|
+
verbose: this.verbose,
|
|
17746
|
+
defaultHeaders: this.defaultHeaders,
|
|
17747
|
+
getAccessToken
|
|
17748
|
+
})
|
|
17749
|
+
);
|
|
17750
|
+
return this.balancesResource;
|
|
17751
|
+
}
|
|
16605
17752
|
createWebBotAuthResource() {
|
|
16606
17753
|
if (this.webBotAuthResource) {
|
|
16607
17754
|
return this.webBotAuthResource;
|
|
@@ -16703,12 +17850,16 @@ function cacheUpdateInfo(value, ttlMs = UPDATE_CACHE_TTL_MS) {
|
|
|
16703
17850
|
}
|
|
16704
17851
|
|
|
16705
17852
|
// src/cli.tsx
|
|
16706
|
-
var cliVersion = "0.
|
|
17853
|
+
var cliVersion = "0.9.0";
|
|
16707
17854
|
var cliName = "@stripe/link-cli";
|
|
16708
17855
|
var defaultHeaders = {
|
|
16709
17856
|
"User-Agent": `link-cli/${cliVersion}`
|
|
16710
17857
|
};
|
|
16711
|
-
var
|
|
17858
|
+
var verboseIndex = process.argv.indexOf("--verbose");
|
|
17859
|
+
var verbose = verboseIndex !== -1;
|
|
17860
|
+
if (verboseIndex !== -1) {
|
|
17861
|
+
process.argv.splice(verboseIndex, 1);
|
|
17862
|
+
}
|
|
16712
17863
|
var authFileIndex = process.argv.indexOf("--auth");
|
|
16713
17864
|
var credentialFilePath = authFileIndex !== -1 ? process.argv[authFileIndex + 1] : process.env.LINK_AUTH_FILE;
|
|
16714
17865
|
if (authFileIndex !== -1) {
|
|
@@ -16728,7 +17879,24 @@ var factory = new ResourceFactory({
|
|
|
16728
17879
|
});
|
|
16729
17880
|
var authRepo = factory.createAuthResource();
|
|
16730
17881
|
var spendRequestRepo = factory.createSpendRequestResource();
|
|
16731
|
-
var
|
|
17882
|
+
var requestedCommand = process.argv[2];
|
|
17883
|
+
var hiddenCli = requestedCommand === "transactions" ? createTransactionsCli(
|
|
17884
|
+
() => factory.createTransactionsResource(),
|
|
17885
|
+
authStorage,
|
|
17886
|
+
envAccessToken
|
|
17887
|
+
) : requestedCommand === "sources" ? createSourcesCli(
|
|
17888
|
+
() => factory.createSourcesResource(),
|
|
17889
|
+
authStorage,
|
|
17890
|
+
envAccessToken
|
|
17891
|
+
) : requestedCommand === "balances" ? createBalancesCli(
|
|
17892
|
+
() => factory.createBalancesResource(),
|
|
17893
|
+
authStorage,
|
|
17894
|
+
envAccessToken
|
|
17895
|
+
) : null;
|
|
17896
|
+
if (hiddenCli) {
|
|
17897
|
+
process.argv.splice(2, 1);
|
|
17898
|
+
}
|
|
17899
|
+
var cli = hiddenCli ?? Cli14.create("link-cli", {
|
|
16732
17900
|
description: "Create a secure, one-time payment credential from a Link wallet to let agents complete purchases on behalf of users.",
|
|
16733
17901
|
version: cliVersion
|
|
16734
17902
|
});
|
|
@@ -16745,58 +17913,60 @@ if (!isAgent && process.stdout.isTTY) {
|
|
|
16745
17913
|
process.stderr.write(renderInteractiveUpdateNotice(updateInfo));
|
|
16746
17914
|
}
|
|
16747
17915
|
}
|
|
16748
|
-
|
|
16749
|
-
|
|
16750
|
-
)
|
|
16751
|
-
|
|
16752
|
-
|
|
16753
|
-
)
|
|
16754
|
-
|
|
16755
|
-
|
|
16756
|
-
(
|
|
16757
|
-
|
|
16758
|
-
|
|
16759
|
-
|
|
16760
|
-
)
|
|
16761
|
-
|
|
16762
|
-
|
|
16763
|
-
(
|
|
16764
|
-
|
|
16765
|
-
|
|
16766
|
-
|
|
16767
|
-
)
|
|
16768
|
-
|
|
16769
|
-
|
|
16770
|
-
(
|
|
16771
|
-
|
|
16772
|
-
|
|
16773
|
-
|
|
16774
|
-
)
|
|
16775
|
-
|
|
16776
|
-
cli.command(
|
|
16777
|
-
|
|
16778
|
-
(
|
|
16779
|
-
|
|
16780
|
-
|
|
16781
|
-
|
|
16782
|
-
)
|
|
16783
|
-
|
|
16784
|
-
|
|
16785
|
-
|
|
16786
|
-
|
|
16787
|
-
|
|
16788
|
-
|
|
16789
|
-
|
|
16790
|
-
)
|
|
16791
|
-
|
|
16792
|
-
|
|
16793
|
-
|
|
16794
|
-
|
|
16795
|
-
|
|
16796
|
-
|
|
16797
|
-
|
|
16798
|
-
)
|
|
16799
|
-
|
|
17916
|
+
if (!hiddenCli) {
|
|
17917
|
+
cli.command(
|
|
17918
|
+
createAuthCli(authRepo, getUpdateInfo, authStorage, envAccessToken)
|
|
17919
|
+
);
|
|
17920
|
+
cli.command(
|
|
17921
|
+
createSpendRequestCli(spendRequestRepo, authStorage, envAccessToken)
|
|
17922
|
+
);
|
|
17923
|
+
cli.command(
|
|
17924
|
+
createPaymentMethodsCli(
|
|
17925
|
+
() => factory.createPaymentMethodsResource(),
|
|
17926
|
+
authStorage,
|
|
17927
|
+
envAccessToken
|
|
17928
|
+
)
|
|
17929
|
+
);
|
|
17930
|
+
cli.command(
|
|
17931
|
+
createShippingAddressCli(
|
|
17932
|
+
() => factory.createShippingAddressResource(),
|
|
17933
|
+
authStorage,
|
|
17934
|
+
envAccessToken
|
|
17935
|
+
)
|
|
17936
|
+
);
|
|
17937
|
+
cli.command(
|
|
17938
|
+
createUserInfoCli(
|
|
17939
|
+
() => factory.createUserInfoResource(),
|
|
17940
|
+
authStorage,
|
|
17941
|
+
envAccessToken
|
|
17942
|
+
)
|
|
17943
|
+
);
|
|
17944
|
+
cli.command(createMppCli(spendRequestRepo, authStorage, envAccessToken));
|
|
17945
|
+
cli.command(
|
|
17946
|
+
createReportCli(
|
|
17947
|
+
() => factory.createReportResource(),
|
|
17948
|
+
authStorage,
|
|
17949
|
+
envAccessToken
|
|
17950
|
+
)
|
|
17951
|
+
);
|
|
17952
|
+
cli.command(
|
|
17953
|
+
createDemoCli(
|
|
17954
|
+
authRepo,
|
|
17955
|
+
spendRequestRepo,
|
|
17956
|
+
() => factory.createPaymentMethodsResource(),
|
|
17957
|
+
authStorage
|
|
17958
|
+
)
|
|
17959
|
+
);
|
|
17960
|
+
cli.command(
|
|
17961
|
+
createOnboardCli(
|
|
17962
|
+
authRepo,
|
|
17963
|
+
spendRequestRepo,
|
|
17964
|
+
() => factory.createPaymentMethodsResource(),
|
|
17965
|
+
authStorage
|
|
17966
|
+
)
|
|
17967
|
+
);
|
|
17968
|
+
cli.command(createServeCli(cli));
|
|
17969
|
+
}
|
|
16800
17970
|
cli.serve();
|
|
16801
17971
|
var cli_default = cli;
|
|
16802
17972
|
export {
|