@siglume/api-sdk 1.0.0 → 1.1.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 +51 -0
- package/dist/bin/siglume.cjs +189 -49
- package/dist/bin/siglume.cjs.map +1 -1
- package/dist/bin/siglume.js +189 -49
- package/dist/bin/siglume.js.map +1 -1
- package/dist/cli/index.cjs +189 -49
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +24 -0
- package/dist/cli/index.d.ts +24 -0
- package/dist/cli/index.js +189 -49
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +211 -69
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -2
- package/dist/index.d.ts +27 -2
- package/dist/index.js +211 -69
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.d.cts
CHANGED
|
@@ -178,6 +178,7 @@ interface AppManifest {
|
|
|
178
178
|
permission_scopes?: string[];
|
|
179
179
|
price_model?: PriceModel;
|
|
180
180
|
price_value_minor?: number;
|
|
181
|
+
pricing_plan?: PricingPlan;
|
|
181
182
|
currency: ListingCurrency;
|
|
182
183
|
allow_free_trial: boolean;
|
|
183
184
|
free_trial_duration_days?: number;
|
|
@@ -261,6 +262,28 @@ interface EnvelopeMeta {
|
|
|
261
262
|
request_id?: string | null;
|
|
262
263
|
trace_id?: string | null;
|
|
263
264
|
}
|
|
265
|
+
interface PricingPlanItem {
|
|
266
|
+
key?: string | null;
|
|
267
|
+
label?: string | null;
|
|
268
|
+
price_minor?: number | null;
|
|
269
|
+
amount_minor?: number | null;
|
|
270
|
+
currency?: string | null;
|
|
271
|
+
unit_label?: string | null;
|
|
272
|
+
description?: string | null;
|
|
273
|
+
conditions?: unknown;
|
|
274
|
+
receipt_code?: string | null;
|
|
275
|
+
}
|
|
276
|
+
interface PricingPlan {
|
|
277
|
+
billing_model?: string | null;
|
|
278
|
+
display_name?: string | null;
|
|
279
|
+
summary?: string | null;
|
|
280
|
+
description?: string | null;
|
|
281
|
+
currency?: string | null;
|
|
282
|
+
unit_label?: string | null;
|
|
283
|
+
free_upfront_invocation?: boolean | null;
|
|
284
|
+
fallback_note?: string | null;
|
|
285
|
+
items?: PricingPlanItem[];
|
|
286
|
+
}
|
|
264
287
|
interface CursorPage<T> {
|
|
265
288
|
items: T[];
|
|
266
289
|
next_cursor?: string | null;
|
|
@@ -282,6 +305,7 @@ interface AppListingRecord {
|
|
|
282
305
|
dry_run_supported: boolean;
|
|
283
306
|
price_model?: string | null;
|
|
284
307
|
price_value_minor: number;
|
|
308
|
+
pricing_plan?: PricingPlan | null;
|
|
285
309
|
currency: string;
|
|
286
310
|
allow_free_trial: boolean;
|
|
287
311
|
free_trial_duration_days: number;
|
package/dist/cli/index.d.ts
CHANGED
|
@@ -178,6 +178,7 @@ interface AppManifest {
|
|
|
178
178
|
permission_scopes?: string[];
|
|
179
179
|
price_model?: PriceModel;
|
|
180
180
|
price_value_minor?: number;
|
|
181
|
+
pricing_plan?: PricingPlan;
|
|
181
182
|
currency: ListingCurrency;
|
|
182
183
|
allow_free_trial: boolean;
|
|
183
184
|
free_trial_duration_days?: number;
|
|
@@ -261,6 +262,28 @@ interface EnvelopeMeta {
|
|
|
261
262
|
request_id?: string | null;
|
|
262
263
|
trace_id?: string | null;
|
|
263
264
|
}
|
|
265
|
+
interface PricingPlanItem {
|
|
266
|
+
key?: string | null;
|
|
267
|
+
label?: string | null;
|
|
268
|
+
price_minor?: number | null;
|
|
269
|
+
amount_minor?: number | null;
|
|
270
|
+
currency?: string | null;
|
|
271
|
+
unit_label?: string | null;
|
|
272
|
+
description?: string | null;
|
|
273
|
+
conditions?: unknown;
|
|
274
|
+
receipt_code?: string | null;
|
|
275
|
+
}
|
|
276
|
+
interface PricingPlan {
|
|
277
|
+
billing_model?: string | null;
|
|
278
|
+
display_name?: string | null;
|
|
279
|
+
summary?: string | null;
|
|
280
|
+
description?: string | null;
|
|
281
|
+
currency?: string | null;
|
|
282
|
+
unit_label?: string | null;
|
|
283
|
+
free_upfront_invocation?: boolean | null;
|
|
284
|
+
fallback_note?: string | null;
|
|
285
|
+
items?: PricingPlanItem[];
|
|
286
|
+
}
|
|
264
287
|
interface CursorPage<T> {
|
|
265
288
|
items: T[];
|
|
266
289
|
next_cursor?: string | null;
|
|
@@ -282,6 +305,7 @@ interface AppListingRecord {
|
|
|
282
305
|
dry_run_supported: boolean;
|
|
283
306
|
price_model?: string | null;
|
|
284
307
|
price_value_minor: number;
|
|
308
|
+
pricing_plan?: PricingPlan | null;
|
|
285
309
|
currency: string;
|
|
286
310
|
allow_free_trial: boolean;
|
|
287
311
|
free_trial_duration_days: number;
|
package/dist/cli/index.js
CHANGED
|
@@ -155,6 +155,61 @@ var init_utils = __esm({
|
|
|
155
155
|
}
|
|
156
156
|
});
|
|
157
157
|
|
|
158
|
+
// src/types.ts
|
|
159
|
+
var PermissionClass, ApprovalMode, Environment, PriceModel, AppCategory, MINIMUM_JPY_OPERATION_PRICE_MINOR, ToolManualPermissionClass, SettlementMode;
|
|
160
|
+
var init_types = __esm({
|
|
161
|
+
"src/types.ts"() {
|
|
162
|
+
"use strict";
|
|
163
|
+
PermissionClass = {
|
|
164
|
+
READ_ONLY: "read-only",
|
|
165
|
+
ACTION: "action",
|
|
166
|
+
PAYMENT: "payment",
|
|
167
|
+
/** @deprecated Use READ_ONLY. Behaves identically. */
|
|
168
|
+
RECOMMENDATION: "recommendation"
|
|
169
|
+
};
|
|
170
|
+
ApprovalMode = {
|
|
171
|
+
AUTO: "auto",
|
|
172
|
+
BUDGET_BOUNDED: "budget-bounded",
|
|
173
|
+
ALWAYS_ASK: "always-ask",
|
|
174
|
+
DENY: "deny"
|
|
175
|
+
};
|
|
176
|
+
Environment = {
|
|
177
|
+
SANDBOX: "sandbox",
|
|
178
|
+
LIVE: "live"
|
|
179
|
+
};
|
|
180
|
+
PriceModel = {
|
|
181
|
+
FREE: "free",
|
|
182
|
+
SUBSCRIPTION: "subscription",
|
|
183
|
+
ONE_TIME: "one_time",
|
|
184
|
+
BUNDLE: "bundle",
|
|
185
|
+
USAGE_BASED: "usage_based",
|
|
186
|
+
PER_ACTION: "per_action"
|
|
187
|
+
};
|
|
188
|
+
AppCategory = {
|
|
189
|
+
COMMERCE: "commerce",
|
|
190
|
+
BOOKING: "booking",
|
|
191
|
+
CRM: "crm",
|
|
192
|
+
FINANCE: "finance",
|
|
193
|
+
DOCUMENT: "document",
|
|
194
|
+
COMMUNICATION: "communication",
|
|
195
|
+
MONITORING: "monitoring",
|
|
196
|
+
OTHER: "other"
|
|
197
|
+
};
|
|
198
|
+
MINIMUM_JPY_OPERATION_PRICE_MINOR = 15;
|
|
199
|
+
ToolManualPermissionClass = {
|
|
200
|
+
READ_ONLY: "read_only",
|
|
201
|
+
ACTION: "action",
|
|
202
|
+
PAYMENT: "payment"
|
|
203
|
+
};
|
|
204
|
+
SettlementMode = {
|
|
205
|
+
STRIPE_CHECKOUT: "stripe_checkout",
|
|
206
|
+
STRIPE_PAYMENT_INTENT: "stripe_payment_intent",
|
|
207
|
+
POLYGON_MANDATE: "polygon_mandate",
|
|
208
|
+
EMBEDDED_WALLET_CHARGE: "embedded_wallet_charge"
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
|
|
158
213
|
// src/webhooks.ts
|
|
159
214
|
function isRecord2(value) {
|
|
160
215
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -1276,6 +1331,58 @@ function validateSaveDataSchema(schema, fieldName) {
|
|
|
1276
1331
|
}
|
|
1277
1332
|
}
|
|
1278
1333
|
}
|
|
1334
|
+
function validatePricingPlanFloor(plan, defaultCurrency) {
|
|
1335
|
+
if (plan === void 0 || plan === null) {
|
|
1336
|
+
return;
|
|
1337
|
+
}
|
|
1338
|
+
if (!isRecord(plan)) {
|
|
1339
|
+
throw new SiglumeClientError("AppManifest.pricing_plan must be an object when provided.");
|
|
1340
|
+
}
|
|
1341
|
+
const items = plan.items;
|
|
1342
|
+
if (items === void 0 || items === null) {
|
|
1343
|
+
return;
|
|
1344
|
+
}
|
|
1345
|
+
if (!Array.isArray(items)) {
|
|
1346
|
+
throw new SiglumeClientError("AppManifest.pricing_plan.items must be an array when provided.");
|
|
1347
|
+
}
|
|
1348
|
+
const planCurrency = String(plan.currency ?? defaultCurrency ?? "").trim().toUpperCase();
|
|
1349
|
+
const seenKeys = /* @__PURE__ */ new Set();
|
|
1350
|
+
items.forEach((item, index) => {
|
|
1351
|
+
if (!isRecord(item)) {
|
|
1352
|
+
throw new SiglumeClientError(`AppManifest.pricing_plan.items[${index}] must be an object.`);
|
|
1353
|
+
}
|
|
1354
|
+
const itemKey = String(
|
|
1355
|
+
item.key ?? item.operation ?? item.operation_key ?? item.request_type ?? item.receipt_code ?? item.action ?? ""
|
|
1356
|
+
).trim();
|
|
1357
|
+
if (!itemKey) {
|
|
1358
|
+
throw new SiglumeClientError(`AppManifest.pricing_plan.items[${index}].key is required.`);
|
|
1359
|
+
}
|
|
1360
|
+
if (seenKeys.has(itemKey)) {
|
|
1361
|
+
throw new SiglumeClientError(`AppManifest.pricing_plan.items[${index}].key duplicates ${itemKey}.`);
|
|
1362
|
+
}
|
|
1363
|
+
seenKeys.add(itemKey);
|
|
1364
|
+
const amountRaw = item.price_minor ?? item.amount_minor ?? item.cost_minor ?? item.value_minor;
|
|
1365
|
+
if (amountRaw === void 0 || amountRaw === null) {
|
|
1366
|
+
throw new SiglumeClientError(`AppManifest.pricing_plan.items[${index}].price_minor is required.`);
|
|
1367
|
+
}
|
|
1368
|
+
const amountMinor = typeof amountRaw === "number" ? amountRaw : typeof amountRaw === "string" && amountRaw.trim() ? Number(amountRaw) : NaN;
|
|
1369
|
+
if (!Number.isInteger(amountMinor)) {
|
|
1370
|
+
throw new SiglumeClientError(`AppManifest.pricing_plan.items[${index}].price_minor must be an integer.`);
|
|
1371
|
+
}
|
|
1372
|
+
if (amountMinor < 0) {
|
|
1373
|
+
throw new SiglumeClientError(`AppManifest.pricing_plan.items[${index}].price_minor must be zero or positive.`);
|
|
1374
|
+
}
|
|
1375
|
+
const currency = String(item.currency ?? planCurrency ?? defaultCurrency ?? "").trim().toUpperCase();
|
|
1376
|
+
if (MINIMUM_JPY_OPERATION_PRICE_CURRENCIES.has(currency) && amountMinor > 0 && amountMinor < MINIMUM_JPY_OPERATION_PRICE_MINOR) {
|
|
1377
|
+
throw new SiglumeClientError(
|
|
1378
|
+
`AppManifest.pricing_plan.items[${index}].price_minor must be 0 or at least ${MINIMUM_JPY_OPERATION_PRICE_MINOR} for JPY/JPYC operation billing.`
|
|
1379
|
+
);
|
|
1380
|
+
}
|
|
1381
|
+
});
|
|
1382
|
+
}
|
|
1383
|
+
function pricingPlanHasItems(plan) {
|
|
1384
|
+
return isRecord(plan) && Array.isArray(plan.items) && plan.items.length > 0;
|
|
1385
|
+
}
|
|
1279
1386
|
function buildToolManualQualityReport(payload) {
|
|
1280
1387
|
const qualityBlock = isRecord(payload.quality) ? payload.quality : payload;
|
|
1281
1388
|
const issues = [];
|
|
@@ -1351,6 +1458,7 @@ function buildUrl(baseUrl, path, params) {
|
|
|
1351
1458
|
}
|
|
1352
1459
|
function parseListing(data) {
|
|
1353
1460
|
const metadata = isRecord(data.metadata) ? data.metadata : {};
|
|
1461
|
+
const pricing_plan = isRecord(data.pricing_plan) ? data.pricing_plan : isRecord(metadata.pricing_plan) ? metadata.pricing_plan : null;
|
|
1354
1462
|
const persistence = isRecord(data.persistence) ? data.persistence : isRecord(metadata.persistence) ? metadata.persistence : {};
|
|
1355
1463
|
return {
|
|
1356
1464
|
listing_id: String(data.listing_id ?? data.id ?? ""),
|
|
@@ -1364,6 +1472,7 @@ function parseListing(data) {
|
|
|
1364
1472
|
dry_run_supported: Boolean(data.dry_run_supported ?? false),
|
|
1365
1473
|
price_model: stringOrNull(data.price_model),
|
|
1366
1474
|
price_value_minor: Number(data.price_value_minor ?? 0),
|
|
1475
|
+
pricing_plan,
|
|
1367
1476
|
currency: String(data.currency ?? "USD"),
|
|
1368
1477
|
allow_free_trial: Boolean(data.allow_free_trial ?? false),
|
|
1369
1478
|
free_trial_duration_days: Number(data.free_trial_duration_days ?? 30),
|
|
@@ -2461,10 +2570,11 @@ function cloneJsonLike(value) {
|
|
|
2461
2570
|
}
|
|
2462
2571
|
return value;
|
|
2463
2572
|
}
|
|
2464
|
-
var DEFAULT_SIGLUME_API_BASE, RETRYABLE_STATUS_CODES, CursorPageResult, SiglumeClient;
|
|
2573
|
+
var DEFAULT_SIGLUME_API_BASE, RETRYABLE_STATUS_CODES, MINIMUM_JPY_OPERATION_PRICE_CURRENCIES, CursorPageResult, SiglumeClient;
|
|
2465
2574
|
var init_client = __esm({
|
|
2466
2575
|
"src/client.ts"() {
|
|
2467
2576
|
"use strict";
|
|
2577
|
+
init_types();
|
|
2468
2578
|
init_errors();
|
|
2469
2579
|
init_webhooks();
|
|
2470
2580
|
init_web3();
|
|
@@ -2472,6 +2582,7 @@ var init_client = __esm({
|
|
|
2472
2582
|
init_utils();
|
|
2473
2583
|
DEFAULT_SIGLUME_API_BASE = "https://siglume.com/v1";
|
|
2474
2584
|
RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
2585
|
+
MINIMUM_JPY_OPERATION_PRICE_CURRENCIES = /* @__PURE__ */ new Set(["JPY", "JPYC"]);
|
|
2475
2586
|
CursorPageResult = class {
|
|
2476
2587
|
items;
|
|
2477
2588
|
next_cursor;
|
|
@@ -2579,6 +2690,7 @@ var init_client = __esm({
|
|
|
2579
2690
|
"jurisdiction",
|
|
2580
2691
|
"price_model",
|
|
2581
2692
|
"price_value_minor",
|
|
2693
|
+
"pricing_plan",
|
|
2582
2694
|
"currency",
|
|
2583
2695
|
"allow_free_trial",
|
|
2584
2696
|
"free_trial_duration_days",
|
|
@@ -2595,6 +2707,9 @@ var init_client = __esm({
|
|
|
2595
2707
|
payload[fieldName] = value;
|
|
2596
2708
|
}
|
|
2597
2709
|
}
|
|
2710
|
+
if (payload.pricing_plan !== void 0 && (typeof payload.pricing_plan !== "object" || Array.isArray(payload.pricing_plan))) {
|
|
2711
|
+
throw new SiglumeClientError("AppManifest.pricing_plan must be an object when provided.");
|
|
2712
|
+
}
|
|
2598
2713
|
if (payload.store_vertical === void 0 || payload.store_vertical === null) {
|
|
2599
2714
|
throw new SiglumeClientError(
|
|
2600
2715
|
"AppManifest.store_vertical is required. Choose 'api' for normal API Store listings or 'game' for API games."
|
|
@@ -2610,6 +2725,13 @@ var init_client = __esm({
|
|
|
2610
2725
|
throw new SiglumeClientError(`AppManifest.currency must be 'USD' or 'JPY'. Got ${String(payload.currency)}.`);
|
|
2611
2726
|
}
|
|
2612
2727
|
payload.currency = currency;
|
|
2728
|
+
if (payload.pricing_plan !== void 0) {
|
|
2729
|
+
validatePricingPlanFloor(payload.pricing_plan, currency);
|
|
2730
|
+
}
|
|
2731
|
+
const priceModel = String(payload.price_model ?? "free").trim().toLowerCase();
|
|
2732
|
+
if ((priceModel === "usage_based" || priceModel === "per_action") && !pricingPlanHasItems(payload.pricing_plan)) {
|
|
2733
|
+
throw new SiglumeClientError("AppManifest.pricing_plan.items is required for usage_based/per_action pricing.");
|
|
2734
|
+
}
|
|
2613
2735
|
if (payload.allow_free_trial === void 0 || payload.allow_free_trial === null) {
|
|
2614
2736
|
throw new SiglumeClientError(
|
|
2615
2737
|
"AppManifest.allow_free_trial is required. Pass true to offer a Plus/Pro buyer free trial or false to disable trials."
|
|
@@ -5284,53 +5406,8 @@ function stableValue(value) {
|
|
|
5284
5406
|
return value;
|
|
5285
5407
|
}
|
|
5286
5408
|
|
|
5287
|
-
// src/
|
|
5288
|
-
|
|
5289
|
-
READ_ONLY: "read-only",
|
|
5290
|
-
ACTION: "action",
|
|
5291
|
-
PAYMENT: "payment",
|
|
5292
|
-
/** @deprecated Use READ_ONLY. Behaves identically. */
|
|
5293
|
-
RECOMMENDATION: "recommendation"
|
|
5294
|
-
};
|
|
5295
|
-
var ApprovalMode = {
|
|
5296
|
-
AUTO: "auto",
|
|
5297
|
-
BUDGET_BOUNDED: "budget-bounded",
|
|
5298
|
-
ALWAYS_ASK: "always-ask",
|
|
5299
|
-
DENY: "deny"
|
|
5300
|
-
};
|
|
5301
|
-
var Environment = {
|
|
5302
|
-
SANDBOX: "sandbox",
|
|
5303
|
-
LIVE: "live"
|
|
5304
|
-
};
|
|
5305
|
-
var PriceModel = {
|
|
5306
|
-
FREE: "free",
|
|
5307
|
-
SUBSCRIPTION: "subscription",
|
|
5308
|
-
ONE_TIME: "one_time",
|
|
5309
|
-
BUNDLE: "bundle",
|
|
5310
|
-
USAGE_BASED: "usage_based",
|
|
5311
|
-
PER_ACTION: "per_action"
|
|
5312
|
-
};
|
|
5313
|
-
var AppCategory = {
|
|
5314
|
-
COMMERCE: "commerce",
|
|
5315
|
-
BOOKING: "booking",
|
|
5316
|
-
CRM: "crm",
|
|
5317
|
-
FINANCE: "finance",
|
|
5318
|
-
DOCUMENT: "document",
|
|
5319
|
-
COMMUNICATION: "communication",
|
|
5320
|
-
MONITORING: "monitoring",
|
|
5321
|
-
OTHER: "other"
|
|
5322
|
-
};
|
|
5323
|
-
var ToolManualPermissionClass = {
|
|
5324
|
-
READ_ONLY: "read_only",
|
|
5325
|
-
ACTION: "action",
|
|
5326
|
-
PAYMENT: "payment"
|
|
5327
|
-
};
|
|
5328
|
-
var SettlementMode = {
|
|
5329
|
-
STRIPE_CHECKOUT: "stripe_checkout",
|
|
5330
|
-
STRIPE_PAYMENT_INTENT: "stripe_payment_intent",
|
|
5331
|
-
POLYGON_MANDATE: "polygon_mandate",
|
|
5332
|
-
EMBEDDED_WALLET_CHARGE: "embedded_wallet_charge"
|
|
5333
|
-
};
|
|
5409
|
+
// src/runtime.ts
|
|
5410
|
+
init_types();
|
|
5334
5411
|
|
|
5335
5412
|
// src/testing/recorder.ts
|
|
5336
5413
|
var CASSETTE_VERSION = 1;
|
|
@@ -5722,6 +5799,7 @@ Actual: ${requestSignature(requestRecord, ignoreBodyFields)}`
|
|
|
5722
5799
|
};
|
|
5723
5800
|
|
|
5724
5801
|
// src/tool-manual-validator.ts
|
|
5802
|
+
init_types();
|
|
5725
5803
|
init_utils();
|
|
5726
5804
|
var JURISDICTION_PATTERN = /^[A-Z]{2}(-[A-Z0-9]{1,3})?$/;
|
|
5727
5805
|
var TOOL_NAME_RE = /^[A-Za-z0-9_]{3,64}$/;
|
|
@@ -5993,6 +6071,64 @@ function validate_tool_manual(manualInput) {
|
|
|
5993
6071
|
// src/runtime.ts
|
|
5994
6072
|
init_web3();
|
|
5995
6073
|
var CAPABILITY_KEY_RE = /^[a-z0-9][a-z0-9-]*[a-z0-9]$/;
|
|
6074
|
+
var MINIMUM_JPY_OPERATION_PRICE_CURRENCIES2 = /* @__PURE__ */ new Set(["JPY", "JPYC"]);
|
|
6075
|
+
function pricingPlanFloorIssues(plan, defaultCurrency) {
|
|
6076
|
+
const issues = [];
|
|
6077
|
+
if (plan === void 0 || plan === null) {
|
|
6078
|
+
return issues;
|
|
6079
|
+
}
|
|
6080
|
+
if (typeof plan !== "object" || Array.isArray(plan)) {
|
|
6081
|
+
return ["pricing_plan must be an object when provided"];
|
|
6082
|
+
}
|
|
6083
|
+
const record = plan;
|
|
6084
|
+
const items = record.items;
|
|
6085
|
+
if (items === void 0 || items === null) {
|
|
6086
|
+
return issues;
|
|
6087
|
+
}
|
|
6088
|
+
if (!Array.isArray(items)) {
|
|
6089
|
+
return ["pricing_plan.items must be an array when provided"];
|
|
6090
|
+
}
|
|
6091
|
+
const planCurrency = String(record.currency ?? defaultCurrency ?? "").trim().toUpperCase();
|
|
6092
|
+
const seenKeys = /* @__PURE__ */ new Set();
|
|
6093
|
+
items.forEach((item, index) => {
|
|
6094
|
+
if (typeof item !== "object" || item === null || Array.isArray(item)) {
|
|
6095
|
+
issues.push(`pricing_plan.items[${index}] must be an object`);
|
|
6096
|
+
return;
|
|
6097
|
+
}
|
|
6098
|
+
const itemRecord = item;
|
|
6099
|
+
const itemKey = String(
|
|
6100
|
+
itemRecord.key ?? itemRecord.operation ?? itemRecord.operation_key ?? itemRecord.request_type ?? itemRecord.receipt_code ?? itemRecord.action ?? ""
|
|
6101
|
+
).trim();
|
|
6102
|
+
if (!itemKey) {
|
|
6103
|
+
issues.push(`pricing_plan.items[${index}].key is required`);
|
|
6104
|
+
} else if (seenKeys.has(itemKey)) {
|
|
6105
|
+
issues.push(`pricing_plan.items[${index}].key duplicates ${itemKey}`);
|
|
6106
|
+
} else {
|
|
6107
|
+
seenKeys.add(itemKey);
|
|
6108
|
+
}
|
|
6109
|
+
const amountRaw = itemRecord.price_minor ?? itemRecord.amount_minor ?? itemRecord.cost_minor ?? itemRecord.value_minor;
|
|
6110
|
+
if (amountRaw === void 0 || amountRaw === null) {
|
|
6111
|
+
issues.push(`pricing_plan.items[${index}].price_minor is required`);
|
|
6112
|
+
return;
|
|
6113
|
+
}
|
|
6114
|
+
const amountMinor = typeof amountRaw === "number" ? amountRaw : typeof amountRaw === "string" && amountRaw.trim() ? Number(amountRaw) : NaN;
|
|
6115
|
+
if (!Number.isInteger(amountMinor)) {
|
|
6116
|
+
issues.push(`pricing_plan.items[${index}].price_minor must be an integer`);
|
|
6117
|
+
return;
|
|
6118
|
+
}
|
|
6119
|
+
if (amountMinor < 0) {
|
|
6120
|
+
issues.push(`pricing_plan.items[${index}].price_minor must be zero or positive`);
|
|
6121
|
+
return;
|
|
6122
|
+
}
|
|
6123
|
+
const currency = String(itemRecord.currency ?? planCurrency ?? defaultCurrency ?? "").trim().toUpperCase();
|
|
6124
|
+
if (MINIMUM_JPY_OPERATION_PRICE_CURRENCIES2.has(currency) && amountMinor > 0 && amountMinor < MINIMUM_JPY_OPERATION_PRICE_MINOR) {
|
|
6125
|
+
issues.push(
|
|
6126
|
+
`pricing_plan.items[${index}].price_minor must be 0 or at least ${MINIMUM_JPY_OPERATION_PRICE_MINOR} for JPY/JPYC operation billing`
|
|
6127
|
+
);
|
|
6128
|
+
}
|
|
6129
|
+
});
|
|
6130
|
+
return issues;
|
|
6131
|
+
}
|
|
5996
6132
|
function normalizeExecutionResult(result, executionKind) {
|
|
5997
6133
|
return {
|
|
5998
6134
|
success: Boolean(result.success),
|
|
@@ -6080,6 +6216,10 @@ var AppTestHarness = class {
|
|
|
6080
6216
|
if (!manifest.example_prompts || manifest.example_prompts.length === 0) {
|
|
6081
6217
|
issues.push("at least one example_prompt is recommended");
|
|
6082
6218
|
}
|
|
6219
|
+
issues.push(...pricingPlanFloorIssues(manifest.pricing_plan, String(manifest.currency ?? "USD")));
|
|
6220
|
+
if ((manifest.price_model === PriceModel.USAGE_BASED || manifest.price_model === PriceModel.PER_ACTION) && (!manifest.pricing_plan || !Array.isArray(manifest.pricing_plan.items) || manifest.pricing_plan.items.length === 0)) {
|
|
6221
|
+
issues.push("pricing_plan.items is required for usage_based/per_action pricing");
|
|
6222
|
+
}
|
|
6083
6223
|
if (manifest.permission_class === PermissionClass.ACTION || manifest.permission_class === PermissionClass.PAYMENT) {
|
|
6084
6224
|
if (!manifest.dry_run_supported) {
|
|
6085
6225
|
issues.push("action/payment apps should support dry_run");
|
|
@@ -6155,7 +6295,7 @@ var AppTestHarness = class {
|
|
|
6155
6295
|
};
|
|
6156
6296
|
}
|
|
6157
6297
|
return {
|
|
6158
|
-
experimental:
|
|
6298
|
+
experimental: false,
|
|
6159
6299
|
usage_record,
|
|
6160
6300
|
invoice_line_preview
|
|
6161
6301
|
};
|