@siglume/api-sdk 0.10.6 → 0.10.8
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 +99 -91
- package/dist/bin/siglume.cjs +336 -10
- package/dist/bin/siglume.cjs.map +1 -1
- package/dist/bin/siglume.js +336 -10
- package/dist/bin/siglume.js.map +1 -1
- package/dist/cli/index.cjs +336 -10
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.d.cts +82 -0
- package/dist/cli/index.d.ts +82 -0
- package/dist/cli/index.js +336 -10
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +243 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +103 -1
- package/dist/index.d.ts +103 -1
- package/dist/index.js +243 -1
- package/dist/index.js.map +1 -1
- package/package.json +58 -58
package/dist/cli/index.js
CHANGED
|
@@ -1226,6 +1226,56 @@ var init_operations = __esm({
|
|
|
1226
1226
|
});
|
|
1227
1227
|
|
|
1228
1228
|
// src/client.ts
|
|
1229
|
+
function validateManifestPersistenceContract(payload) {
|
|
1230
|
+
const vertical = String(payload.store_vertical ?? "").trim().toLowerCase();
|
|
1231
|
+
const persistence = payload.persistence;
|
|
1232
|
+
if (persistence === void 0 || persistence === null) {
|
|
1233
|
+
return;
|
|
1234
|
+
}
|
|
1235
|
+
if (!isRecord(persistence)) {
|
|
1236
|
+
throw new SiglumeClientError("AppManifest.persistence must be an object.");
|
|
1237
|
+
}
|
|
1238
|
+
const mode = String(persistence.mode ?? (vertical === "game" ? "platform" : "none")).trim().toLowerCase();
|
|
1239
|
+
if (!["none", "local", "platform", "developer_server"].includes(mode)) {
|
|
1240
|
+
throw new SiglumeClientError(
|
|
1241
|
+
"AppManifest.persistence.mode must be one of: none, local, platform, developer_server."
|
|
1242
|
+
);
|
|
1243
|
+
}
|
|
1244
|
+
const schema = persistence.save_data_schema;
|
|
1245
|
+
if (vertical === "game" && mode !== "none" && schema === void 0) {
|
|
1246
|
+
throw new SiglumeClientError(
|
|
1247
|
+
"AppManifest.persistence.save_data_schema is required when store_vertical='game' and persistence.mode is not 'none'."
|
|
1248
|
+
);
|
|
1249
|
+
}
|
|
1250
|
+
if (schema !== void 0) {
|
|
1251
|
+
validateSaveDataSchema(schema, "AppManifest.persistence.save_data_schema");
|
|
1252
|
+
}
|
|
1253
|
+
}
|
|
1254
|
+
function validateSaveDataSchema(schema, fieldName) {
|
|
1255
|
+
if (!isRecord(schema)) {
|
|
1256
|
+
throw new SiglumeClientError(`${fieldName} must be a JSON Schema object.`);
|
|
1257
|
+
}
|
|
1258
|
+
const schemaSize = new TextEncoder().encode(JSON.stringify(schema)).length;
|
|
1259
|
+
if (schemaSize > 8192) {
|
|
1260
|
+
throw new SiglumeClientError(`${fieldName} must be at most 8192 bytes.`);
|
|
1261
|
+
}
|
|
1262
|
+
if (schema.type !== "object") {
|
|
1263
|
+
throw new SiglumeClientError(`${fieldName}.type must be 'object'.`);
|
|
1264
|
+
}
|
|
1265
|
+
const properties = schema.properties;
|
|
1266
|
+
if (!isRecord(properties) || Object.keys(properties).length === 0) {
|
|
1267
|
+
throw new SiglumeClientError(`${fieldName}.properties must be a non-empty object.`);
|
|
1268
|
+
}
|
|
1269
|
+
if (schema.required !== void 0) {
|
|
1270
|
+
if (!Array.isArray(schema.required) || !schema.required.every((item) => typeof item === "string")) {
|
|
1271
|
+
throw new SiglumeClientError(`${fieldName}.required must be an array of strings when provided.`);
|
|
1272
|
+
}
|
|
1273
|
+
const missing = schema.required.filter((item) => !(item in properties));
|
|
1274
|
+
if (missing.length > 0) {
|
|
1275
|
+
throw new SiglumeClientError(`${fieldName}.required references undefined properties: ${missing.join(", ")}.`);
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1229
1279
|
function buildToolManualQualityReport(payload) {
|
|
1230
1280
|
const qualityBlock = isRecord(payload.quality) ? payload.quality : payload;
|
|
1231
1281
|
const issues = [];
|
|
@@ -1300,6 +1350,8 @@ function buildUrl(baseUrl, path, params) {
|
|
|
1300
1350
|
return url.toString();
|
|
1301
1351
|
}
|
|
1302
1352
|
function parseListing(data) {
|
|
1353
|
+
const metadata = isRecord(data.metadata) ? data.metadata : {};
|
|
1354
|
+
const persistence = isRecord(data.persistence) ? data.persistence : isRecord(metadata.persistence) ? metadata.persistence : {};
|
|
1303
1355
|
return {
|
|
1304
1356
|
listing_id: String(data.listing_id ?? data.id ?? ""),
|
|
1305
1357
|
capability_key: String(data.capability_key ?? ""),
|
|
@@ -1313,6 +1365,8 @@ function parseListing(data) {
|
|
|
1313
1365
|
price_model: stringOrNull(data.price_model),
|
|
1314
1366
|
price_value_minor: Number(data.price_value_minor ?? 0),
|
|
1315
1367
|
currency: String(data.currency ?? "USD"),
|
|
1368
|
+
allow_free_trial: Boolean(data.allow_free_trial ?? false),
|
|
1369
|
+
free_trial_duration_days: Number(data.free_trial_duration_days ?? 30),
|
|
1316
1370
|
short_description: stringOrNull(data.short_description),
|
|
1317
1371
|
description: stringOrNull(data.description),
|
|
1318
1372
|
docs_url: stringOrNull(data.docs_url),
|
|
@@ -1320,14 +1374,59 @@ function parseListing(data) {
|
|
|
1320
1374
|
seller_display_name: stringOrNull(data.seller_display_name),
|
|
1321
1375
|
seller_homepage_url: stringOrNull(data.seller_homepage_url),
|
|
1322
1376
|
seller_social_url: stringOrNull(data.seller_social_url),
|
|
1377
|
+
publisher_type: stringOrNull(data.publisher_type),
|
|
1378
|
+
publisher_company_id: stringOrNull(data.publisher_company_id),
|
|
1379
|
+
company_id: stringOrNull(data.company_id),
|
|
1380
|
+
company_name: stringOrNull(data.company_name),
|
|
1381
|
+
company_publish_status: stringOrNull(data.company_publish_status),
|
|
1382
|
+
company_terms_version: stringOrNull(data.company_terms_version),
|
|
1323
1383
|
review_status: stringOrNull(data.review_status),
|
|
1324
1384
|
review_note: stringOrNull(data.review_note),
|
|
1325
1385
|
submission_blockers: Array.isArray(data.submission_blockers) ? data.submission_blockers.filter((item) => typeof item === "string") : [],
|
|
1386
|
+
persistence: { ...persistence },
|
|
1326
1387
|
created_at: stringOrNull(data.created_at),
|
|
1327
1388
|
updated_at: stringOrNull(data.updated_at),
|
|
1328
1389
|
raw: { ...data }
|
|
1329
1390
|
};
|
|
1330
1391
|
}
|
|
1392
|
+
function parseCompanyPublisher(data) {
|
|
1393
|
+
const wallets = Array.isArray(data.settlement_wallets) ? data.settlement_wallets.filter((item) => isRecord(item)) : [];
|
|
1394
|
+
return {
|
|
1395
|
+
company_id: String(data.company_id ?? data.id ?? ""),
|
|
1396
|
+
name: String(data.name ?? ""),
|
|
1397
|
+
status: String(data.status ?? ""),
|
|
1398
|
+
description: stringOrNull(data.description),
|
|
1399
|
+
is_founder: Boolean(data.is_founder ?? false),
|
|
1400
|
+
membership_role: stringOrNull(data.membership_role),
|
|
1401
|
+
membership_status: stringOrNull(data.membership_status),
|
|
1402
|
+
can_publish: Boolean(data.can_publish ?? true),
|
|
1403
|
+
can_approve: Boolean(data.can_approve ?? false),
|
|
1404
|
+
approval_required: Boolean(data.approval_required ?? false),
|
|
1405
|
+
paid_listing_allowed: Boolean(data.paid_listing_allowed ?? false),
|
|
1406
|
+
disabled_reasons: Array.isArray(data.disabled_reasons) ? data.disabled_reasons.filter((item) => typeof item === "string") : [],
|
|
1407
|
+
company_terms_version: stringOrNull(data.company_terms_version),
|
|
1408
|
+
active_listing_count: Number(data.active_listing_count ?? 0),
|
|
1409
|
+
pending_approval_count: Number(data.pending_approval_count ?? 0),
|
|
1410
|
+
settlement_wallet_ready: Boolean(data.settlement_wallet_ready ?? false),
|
|
1411
|
+
settlement_wallets: wallets.map((item) => ({ ...item })),
|
|
1412
|
+
raw: { ...data }
|
|
1413
|
+
};
|
|
1414
|
+
}
|
|
1415
|
+
function parseCapabilitySaveState(data) {
|
|
1416
|
+
return {
|
|
1417
|
+
capability_key: String(data.capability_key ?? ""),
|
|
1418
|
+
save_key: String(data.save_key ?? ""),
|
|
1419
|
+
schema_version: String(data.schema_version ?? "1"),
|
|
1420
|
+
revision: Number(data.revision ?? 0),
|
|
1421
|
+
payload: toRecord(data.payload),
|
|
1422
|
+
metadata: toRecord(data.metadata),
|
|
1423
|
+
checksum: stringOrNull(data.checksum),
|
|
1424
|
+
updated_at: stringOrNull(data.updated_at),
|
|
1425
|
+
created_at: stringOrNull(data.created_at),
|
|
1426
|
+
exists: Boolean(data.exists ?? false),
|
|
1427
|
+
raw: { ...data }
|
|
1428
|
+
};
|
|
1429
|
+
}
|
|
1331
1430
|
function parseBundleMember(data) {
|
|
1332
1431
|
return {
|
|
1333
1432
|
capability_listing_id: String(data.capability_listing_id ?? ""),
|
|
@@ -2507,17 +2606,23 @@ var init_client = __esm({
|
|
|
2507
2606
|
"support_contact",
|
|
2508
2607
|
"seller_homepage_url",
|
|
2509
2608
|
"seller_social_url",
|
|
2609
|
+
"publisher_type",
|
|
2610
|
+
"company_id",
|
|
2611
|
+
"publisher_company_id",
|
|
2510
2612
|
"store_vertical",
|
|
2511
2613
|
"jurisdiction",
|
|
2512
2614
|
"price_model",
|
|
2513
2615
|
"price_value_minor",
|
|
2514
2616
|
"currency",
|
|
2617
|
+
"allow_free_trial",
|
|
2618
|
+
"free_trial_duration_days",
|
|
2515
2619
|
"permission_class",
|
|
2516
2620
|
"approval_mode",
|
|
2517
2621
|
"dry_run_supported",
|
|
2518
2622
|
"required_connected_accounts",
|
|
2519
2623
|
"permission_scopes",
|
|
2520
|
-
"compatibility_tags"
|
|
2624
|
+
"compatibility_tags",
|
|
2625
|
+
"persistence"
|
|
2521
2626
|
]) {
|
|
2522
2627
|
const value = manifestPayload[fieldName];
|
|
2523
2628
|
if (value !== void 0 && value !== null) {
|
|
@@ -2539,6 +2644,44 @@ var init_client = __esm({
|
|
|
2539
2644
|
throw new SiglumeClientError(`AppManifest.currency must be 'USD' or 'JPY'. Got ${String(payload.currency)}.`);
|
|
2540
2645
|
}
|
|
2541
2646
|
payload.currency = currency;
|
|
2647
|
+
if (payload.allow_free_trial === void 0 || payload.allow_free_trial === null) {
|
|
2648
|
+
throw new SiglumeClientError(
|
|
2649
|
+
"AppManifest.allow_free_trial is required. Pass true to offer a Plus/Pro buyer free trial or false to disable trials."
|
|
2650
|
+
);
|
|
2651
|
+
}
|
|
2652
|
+
if (Boolean(payload.allow_free_trial)) {
|
|
2653
|
+
const duration = payload.free_trial_duration_days ?? 30;
|
|
2654
|
+
if (typeof duration !== "number" || !Number.isInteger(duration)) {
|
|
2655
|
+
throw new SiglumeClientError(
|
|
2656
|
+
"AppManifest.free_trial_duration_days must be an integer when allow_free_trial=true."
|
|
2657
|
+
);
|
|
2658
|
+
}
|
|
2659
|
+
if (duration < 1 || duration > 90) {
|
|
2660
|
+
throw new SiglumeClientError(
|
|
2661
|
+
`AppManifest.free_trial_duration_days must be between 1 and 90 when allow_free_trial=true, got: ${duration}.`
|
|
2662
|
+
);
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2665
|
+
const explicitPublisherType = payload.publisher_type !== void 0 && payload.publisher_type !== null;
|
|
2666
|
+
const companyId = String(payload.company_id ?? "").trim() || String(payload.publisher_company_id ?? "").trim();
|
|
2667
|
+
const publisherType = String(payload.publisher_type ?? "user").trim().toLowerCase();
|
|
2668
|
+
if (publisherType !== "user" && publisherType !== "company") {
|
|
2669
|
+
throw new SiglumeClientError("AppManifest.publisher_type must be 'user' or 'company'.");
|
|
2670
|
+
}
|
|
2671
|
+
if (publisherType === "company" && !companyId) {
|
|
2672
|
+
throw new SiglumeClientError("AppManifest.company_id is required when publisher_type='company'.");
|
|
2673
|
+
}
|
|
2674
|
+
if (publisherType === "user" && companyId) {
|
|
2675
|
+
throw new SiglumeClientError("AppManifest.company_id cannot be combined with publisher_type='user'.");
|
|
2676
|
+
}
|
|
2677
|
+
if (explicitPublisherType || companyId) {
|
|
2678
|
+
payload.publisher_type = publisherType;
|
|
2679
|
+
}
|
|
2680
|
+
if (companyId) {
|
|
2681
|
+
payload.company_id = companyId;
|
|
2682
|
+
payload.publisher_company_id = companyId;
|
|
2683
|
+
}
|
|
2684
|
+
validateManifestPersistenceContract(payload);
|
|
2542
2685
|
if (payload.manifest && typeof payload.manifest === "object") {
|
|
2543
2686
|
delete payload.manifest.version;
|
|
2544
2687
|
}
|
|
@@ -2646,6 +2789,45 @@ var init_client = __esm({
|
|
|
2646
2789
|
const [data] = await this.request("GET", `/market/capabilities/${listing_id}`);
|
|
2647
2790
|
return parseListing(data);
|
|
2648
2791
|
}
|
|
2792
|
+
async list_company_publishers() {
|
|
2793
|
+
const [data] = await this.request("GET", "/market/company-publishers");
|
|
2794
|
+
return Array.isArray(data.items) ? data.items.filter((item) => isRecord(item)).map(parseCompanyPublisher) : [];
|
|
2795
|
+
}
|
|
2796
|
+
async request_company_publish_approval(listing_id, note) {
|
|
2797
|
+
const [data] = await this.request("POST", `/market/capabilities/${listing_id}/company-publish-approval`, {
|
|
2798
|
+
json_body: note ? { note } : {}
|
|
2799
|
+
});
|
|
2800
|
+
return parseListing(data);
|
|
2801
|
+
}
|
|
2802
|
+
async decide_company_publish_approval(listing_id, options) {
|
|
2803
|
+
const [data] = await this.request("POST", `/market/capabilities/${listing_id}/company-publish-approval/decision`, {
|
|
2804
|
+
json_body: {
|
|
2805
|
+
decision: options.decision,
|
|
2806
|
+
...options.reason ? { reason: options.reason } : {}
|
|
2807
|
+
}
|
|
2808
|
+
});
|
|
2809
|
+
return parseListing(data);
|
|
2810
|
+
}
|
|
2811
|
+
async get_capability_state(capability_key, save_key = "default") {
|
|
2812
|
+
const [data] = await this.request("GET", `/market/capability-state/${capability_key}/${save_key}`);
|
|
2813
|
+
return parseCapabilitySaveState(data);
|
|
2814
|
+
}
|
|
2815
|
+
async put_capability_state(capability_key, save_key = "default", payload = {}, options = {}) {
|
|
2816
|
+
const body = {
|
|
2817
|
+
payload: toRecord(payload),
|
|
2818
|
+
schema_version: options.schema_version ?? "1",
|
|
2819
|
+
metadata: toRecord(options.metadata)
|
|
2820
|
+
};
|
|
2821
|
+
if (options.expected_revision !== void 0 && options.expected_revision !== null) {
|
|
2822
|
+
body.expected_revision = Math.trunc(options.expected_revision);
|
|
2823
|
+
}
|
|
2824
|
+
const [data] = await this.request("PUT", `/market/capability-state/${capability_key}/${save_key}`, { json_body: body });
|
|
2825
|
+
return parseCapabilitySaveState(data);
|
|
2826
|
+
}
|
|
2827
|
+
async delete_capability_state(capability_key, save_key = "default") {
|
|
2828
|
+
const [data] = await this.request("DELETE", `/market/capability-state/${capability_key}/${save_key}`);
|
|
2829
|
+
return parseCapabilitySaveState(data);
|
|
2830
|
+
}
|
|
2649
2831
|
// ----- Capability bundles (v0.7 track 2) ---------------------------------
|
|
2650
2832
|
async list_bundles(options = {}) {
|
|
2651
2833
|
const params = {
|
|
@@ -5114,10 +5296,14 @@ function appendValueChange(changes, emittedKeys, level, key, oldValue, newValue,
|
|
|
5114
5296
|
}
|
|
5115
5297
|
function normalizeManifest(value) {
|
|
5116
5298
|
const payload = coerceMapping(value, "manifest");
|
|
5299
|
+
const rawDuration = payload.free_trial_duration_days;
|
|
5300
|
+
const duration = rawDuration === void 0 || rawDuration === null ? 30 : Number(rawDuration);
|
|
5117
5301
|
return {
|
|
5118
5302
|
...payload,
|
|
5119
5303
|
price_model: payload.price_model ?? "free",
|
|
5120
5304
|
currency: payload.currency ?? "USD",
|
|
5305
|
+
allow_free_trial: Boolean(payload.allow_free_trial ?? false),
|
|
5306
|
+
free_trial_duration_days: Number.isFinite(duration) ? Math.trunc(duration) : 30,
|
|
5121
5307
|
// AppManifest defaults permission_class to "read-only" (hyphen form,
|
|
5122
5308
|
// PermissionClass.READ_ONLY). Without this default, a legacy / minimal
|
|
5123
5309
|
// manifest without permission_class compared against an upgraded one
|
|
@@ -7236,7 +7422,12 @@ function ensureManifestPublisherIdentity(project) {
|
|
|
7236
7422
|
const sellerHomepageUrl = String(manifestPayload.seller_homepage_url ?? "").trim();
|
|
7237
7423
|
const sellerSocialUrl = String(manifestPayload.seller_social_url ?? "").trim();
|
|
7238
7424
|
const jurisdiction = String(manifestPayload.jurisdiction ?? "").trim();
|
|
7425
|
+
const companyId = String(manifestPayload.company_id ?? "").trim() || String(manifestPayload.publisher_company_id ?? "").trim();
|
|
7426
|
+
const publisherType = String(manifestPayload.publisher_type ?? "user").trim().toLowerCase();
|
|
7239
7427
|
const issues = [];
|
|
7428
|
+
if (companyId && publisherType !== "company") {
|
|
7429
|
+
issues.push('manifest.company_id requires manifest.publisher_type to be "company"');
|
|
7430
|
+
}
|
|
7240
7431
|
if (!docsUrl) {
|
|
7241
7432
|
issues.push("manifest.docs_url is required");
|
|
7242
7433
|
} else if (looksLikePlaceholder(docsUrl)) {
|
|
@@ -7382,25 +7573,110 @@ ${errors.map((error) => `- ${error}`).join("\n")}`
|
|
|
7382
7573
|
}
|
|
7383
7574
|
return preflight;
|
|
7384
7575
|
}
|
|
7576
|
+
function companyNameSlug(value) {
|
|
7577
|
+
return value.normalize("NFKD").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
7578
|
+
}
|
|
7385
7579
|
async function runRegistration(path = ".", options = {}, deps = {}) {
|
|
7386
7580
|
const project = await loadProject(path);
|
|
7581
|
+
let requestedCompanyId = String(options.company_id ?? "").trim();
|
|
7582
|
+
const requestedCompanySlug = String(options.company_slug ?? "").trim();
|
|
7583
|
+
let companyPublisherCandidates = null;
|
|
7584
|
+
if (requestedCompanySlug) {
|
|
7585
|
+
if (requestedCompanyId) {
|
|
7586
|
+
throw new SiglumeProjectError("--company and --company-slug cannot be combined.");
|
|
7587
|
+
}
|
|
7588
|
+
const slug = companyNameSlug(requestedCompanySlug);
|
|
7589
|
+
if (!slug && requestedCompanySlug !== requestedCompanyId) {
|
|
7590
|
+
throw new SiglumeProjectError(`Company slug ${requestedCompanySlug} is not slug-compatible; use --company <company_id> instead.`);
|
|
7591
|
+
}
|
|
7592
|
+
}
|
|
7593
|
+
if (requestedCompanyId) {
|
|
7594
|
+
project.manifest = {
|
|
7595
|
+
...project.manifest,
|
|
7596
|
+
publisher_type: "company",
|
|
7597
|
+
company_id: requestedCompanyId,
|
|
7598
|
+
publisher_company_id: requestedCompanyId
|
|
7599
|
+
};
|
|
7600
|
+
}
|
|
7387
7601
|
ensureExplicitToolManual(project);
|
|
7388
7602
|
ensureManifestPublisherIdentity(project);
|
|
7389
7603
|
ensureRuntimeValidationReady(project);
|
|
7390
7604
|
ensureRequiredOauthCredentials(project);
|
|
7391
7605
|
const canonicalOauthCredentials = canonicalOauthCredentialsPayload(project.oauth_credentials);
|
|
7392
7606
|
const client = await createClient(deps);
|
|
7607
|
+
if (requestedCompanySlug) {
|
|
7608
|
+
const slug = companyNameSlug(requestedCompanySlug);
|
|
7609
|
+
companyPublisherCandidates = await client.list_company_publishers();
|
|
7610
|
+
const matches = companyPublisherCandidates.filter(
|
|
7611
|
+
(item) => companyNameSlug(item.name || item.company_id) === slug || item.company_id === requestedCompanySlug
|
|
7612
|
+
);
|
|
7613
|
+
if (matches.length === 0) {
|
|
7614
|
+
throw new SiglumeProjectError(`Company slug ${requestedCompanySlug} is not available to this API key.`);
|
|
7615
|
+
}
|
|
7616
|
+
if (matches.length > 1) {
|
|
7617
|
+
throw new SiglumeProjectError(`Company slug ${requestedCompanySlug} is ambiguous; use --company <company_id> instead.`);
|
|
7618
|
+
}
|
|
7619
|
+
const match = matches[0];
|
|
7620
|
+
if (!match) {
|
|
7621
|
+
throw new SiglumeProjectError(`Company slug ${requestedCompanySlug} is not available to this API key.`);
|
|
7622
|
+
}
|
|
7623
|
+
if (match.can_publish === false) {
|
|
7624
|
+
const disabledReasons = match.disabled_reasons ?? [];
|
|
7625
|
+
const reasons = disabledReasons.length > 0 ? disabledReasons.join(", ") : "company publisher is disabled";
|
|
7626
|
+
throw new SiglumeProjectError(`Company ${match.company_id} cannot publish: ${reasons}.`);
|
|
7627
|
+
}
|
|
7628
|
+
requestedCompanyId = match.company_id;
|
|
7629
|
+
project.manifest = {
|
|
7630
|
+
...project.manifest,
|
|
7631
|
+
publisher_type: "company",
|
|
7632
|
+
company_id: requestedCompanyId,
|
|
7633
|
+
publisher_company_id: requestedCompanyId
|
|
7634
|
+
};
|
|
7635
|
+
}
|
|
7393
7636
|
const preflight = await registrationPreflight(project, client);
|
|
7637
|
+
let companyPublisherPreflight = null;
|
|
7638
|
+
const companyId = String(project.manifest.company_id ?? "").trim() || String(project.manifest.publisher_company_id ?? "").trim();
|
|
7639
|
+
const publisherType = String(project.manifest.publisher_type ?? "user").toLowerCase();
|
|
7640
|
+
if (publisherType === "company") {
|
|
7641
|
+
if (!companyId) {
|
|
7642
|
+
throw new SiglumeProjectError("Company registration requires --company <company_id> or manifest.company_id.");
|
|
7643
|
+
}
|
|
7644
|
+
const companies = companyPublisherCandidates ?? await client.list_company_publishers();
|
|
7645
|
+
companyPublisherCandidates = companies;
|
|
7646
|
+
const company = companies.find((item) => item.company_id === companyId);
|
|
7647
|
+
if (!company) {
|
|
7648
|
+
throw new SiglumeProjectError(`Company ${companyId} is not available to this API key.`);
|
|
7649
|
+
}
|
|
7650
|
+
if (company.can_publish === false) {
|
|
7651
|
+
const disabledReasons = company.disabled_reasons ?? [];
|
|
7652
|
+
const reasons = disabledReasons.length > 0 ? disabledReasons.join(", ") : "company publisher is disabled";
|
|
7653
|
+
throw new SiglumeProjectError(`Company ${companyId} cannot publish: ${reasons}.`);
|
|
7654
|
+
}
|
|
7655
|
+
companyPublisherPreflight = company;
|
|
7656
|
+
}
|
|
7394
7657
|
let developerPortalPreflight = null;
|
|
7395
7658
|
if (String(project.manifest.price_model ?? "free").toLowerCase() !== "free") {
|
|
7396
|
-
|
|
7397
|
-
|
|
7398
|
-
|
|
7399
|
-
|
|
7400
|
-
|
|
7401
|
-
)
|
|
7659
|
+
if (publisherType === "company") {
|
|
7660
|
+
const company = companyPublisherPreflight;
|
|
7661
|
+
if (!company) {
|
|
7662
|
+
throw new SiglumeProjectError(`Company ${companyId} is not available to this API key.`);
|
|
7663
|
+
}
|
|
7664
|
+
if (company.settlement_wallet_ready !== true) {
|
|
7665
|
+
throw new SiglumeProjectError(
|
|
7666
|
+
`Paid company registration requires a verified company settlement wallet for ${company.name}. Open the company settings and complete settlement readiness before registering.`
|
|
7667
|
+
);
|
|
7668
|
+
}
|
|
7669
|
+
developerPortalPreflight = { company_publisher: toJsonable(company) };
|
|
7670
|
+
} else {
|
|
7671
|
+
const portal = await client.get_developer_portal();
|
|
7672
|
+
const verifiedDestination = portal.payout_readiness?.verified_destination;
|
|
7673
|
+
if (verifiedDestination !== true) {
|
|
7674
|
+
throw new SiglumeProjectError(
|
|
7675
|
+
"Paid API registration requires a verified Polygon payout destination. Open https://siglume.com/owner/credits/payout and confirm the embedded-wallet payout token, or call GET /v1/market/developer/portal until payout_readiness.verified_destination is true."
|
|
7676
|
+
);
|
|
7677
|
+
}
|
|
7678
|
+
developerPortalPreflight = toJsonable(portal);
|
|
7402
7679
|
}
|
|
7403
|
-
developerPortalPreflight = toJsonable(portal);
|
|
7404
7680
|
}
|
|
7405
7681
|
const receipt = await client.auto_register(project.manifest, project.tool_manual, {
|
|
7406
7682
|
runtime_validation: project.runtime_validation,
|
|
@@ -7473,6 +7749,14 @@ async function getUsageReport(options, deps = {}) {
|
|
|
7473
7749
|
count: items.length
|
|
7474
7750
|
};
|
|
7475
7751
|
}
|
|
7752
|
+
async function listCompanyPublishersReport(deps = {}) {
|
|
7753
|
+
const client = await createClient(deps);
|
|
7754
|
+
const companies = await client.list_company_publishers();
|
|
7755
|
+
return {
|
|
7756
|
+
companies: companies.map((item) => toJsonable(item)),
|
|
7757
|
+
count: companies.length
|
|
7758
|
+
};
|
|
7759
|
+
}
|
|
7476
7760
|
async function diffJsonFiles(oldPath, newPath) {
|
|
7477
7761
|
const oldPayload = await loadJsonDocument(oldPath);
|
|
7478
7762
|
const newPayload = await loadJsonDocument(newPath);
|
|
@@ -7669,6 +7953,7 @@ function buildOperationManifest(operation, capability_key_override) {
|
|
|
7669
7953
|
required_connected_accounts: [],
|
|
7670
7954
|
price_model: PriceModel.FREE,
|
|
7671
7955
|
currency: "USD",
|
|
7956
|
+
allow_free_trial: false,
|
|
7672
7957
|
jurisdiction: "US",
|
|
7673
7958
|
short_description: operation.summary,
|
|
7674
7959
|
docs_url: "https://example.com/docs",
|
|
@@ -7747,6 +8032,7 @@ function operationAdapterSource(operation, manifest) {
|
|
|
7747
8032
|
" required_connected_accounts: [],",
|
|
7748
8033
|
" price_model: PriceModel.FREE,",
|
|
7749
8034
|
" currency: 'USD' as const,",
|
|
8035
|
+
" allow_free_trial: false,",
|
|
7750
8036
|
` jurisdiction: ${JSON.stringify(manifest.jurisdiction)},`,
|
|
7751
8037
|
` short_description: ${JSON.stringify(manifest.short_description ?? "")},`,
|
|
7752
8038
|
` support_contact: ${JSON.stringify(manifest.support_contact ?? "")},`,
|
|
@@ -8427,6 +8713,7 @@ function fallbackTemplateSource(template) {
|
|
|
8427
8713
|
" required_connected_accounts: [],",
|
|
8428
8714
|
" price_model: PriceModel.FREE,",
|
|
8429
8715
|
" currency: 'USD' as const,",
|
|
8716
|
+
" allow_free_trial: false,",
|
|
8430
8717
|
' jurisdiction: "US",',
|
|
8431
8718
|
' short_description: "Starter template generated by siglume init.",',
|
|
8432
8719
|
' support_contact: "support@example.com",',
|
|
@@ -8481,6 +8768,7 @@ function starterManifest(template) {
|
|
|
8481
8768
|
required_connected_accounts: [],
|
|
8482
8769
|
price_model: "free",
|
|
8483
8770
|
currency: "USD",
|
|
8771
|
+
allow_free_trial: false,
|
|
8484
8772
|
jurisdiction: "US",
|
|
8485
8773
|
short_description: "Starter template generated by siglume init.",
|
|
8486
8774
|
support_contact: "support@example.com",
|
|
@@ -8555,6 +8843,24 @@ function renderOperationTable(operations) {
|
|
|
8555
8843
|
...rows.map((row) => row.map((cell, index) => cell.padEnd(widths[index] ?? cell.length)).join(" "))
|
|
8556
8844
|
];
|
|
8557
8845
|
}
|
|
8846
|
+
function renderCompanyTable(companies) {
|
|
8847
|
+
const rows = companies.map((item) => [
|
|
8848
|
+
String(item.company_id ?? item.id ?? ""),
|
|
8849
|
+
String(item.name ?? ""),
|
|
8850
|
+
String(item.membership_role ?? (item.is_founder ? "founder" : "")),
|
|
8851
|
+
String(item.settlement_wallet_ready === true ? "ready" : "not_ready"),
|
|
8852
|
+
String(item.pending_approval_count ?? 0)
|
|
8853
|
+
]);
|
|
8854
|
+
const headers = ["company_id", "name", "role", "settlement", "pending"];
|
|
8855
|
+
const widths = headers.map(
|
|
8856
|
+
(header, index) => Math.max(header.length, ...rows.map((row) => row[index]?.length ?? 0))
|
|
8857
|
+
);
|
|
8858
|
+
return [
|
|
8859
|
+
headers.map((header, index) => header.padEnd(widths[index] ?? header.length)).join(" "),
|
|
8860
|
+
widths.map((width) => "-".repeat(width)).join(" "),
|
|
8861
|
+
...rows.map((row) => row.map((cell, index) => cell.padEnd(widths[index] ?? cell.length)).join(" "))
|
|
8862
|
+
];
|
|
8863
|
+
}
|
|
8558
8864
|
async function runCli(argv, deps = {}) {
|
|
8559
8865
|
const stdout = deps.stdout;
|
|
8560
8866
|
const stderr = deps.stderr ?? console.error;
|
|
@@ -8711,7 +9017,21 @@ async function runCli(argv, deps = {}) {
|
|
|
8711
9017
|
if (report.runtime_validation_path) emit(stdout, `runtime_validation_path: ${String(report.runtime_validation_path)}`);
|
|
8712
9018
|
if (report.oauth_credentials_path) emit(stdout, `oauth_credentials_path: ${String(report.oauth_credentials_path)}`);
|
|
8713
9019
|
});
|
|
8714
|
-
program.command("
|
|
9020
|
+
program.command("companies").description("List Siglume companies available for company-name publishing.").option("--json", "emit machine-readable JSON", false).action(async (options) => {
|
|
9021
|
+
const report = await listCompanyPublishersReport(deps);
|
|
9022
|
+
if (options.json) {
|
|
9023
|
+
emit(stdout, renderJson(report));
|
|
9024
|
+
return;
|
|
9025
|
+
}
|
|
9026
|
+
const companies = Array.isArray(report.companies) ? report.companies.filter((item) => Boolean(item && typeof item === "object")) : [];
|
|
9027
|
+
if (companies.length === 0) {
|
|
9028
|
+
emit(stdout, "No company publishers available for this API key.");
|
|
9029
|
+
return;
|
|
9030
|
+
}
|
|
9031
|
+
emit(stdout, "Company publishers");
|
|
9032
|
+
renderCompanyTable(companies).forEach((line) => emit(stdout, line));
|
|
9033
|
+
});
|
|
9034
|
+
program.command("register").option("--confirm", "explicitly confirm the registration; this is the default unless --draft-only is set", false).option("--draft-only", "create or refresh the draft without confirming publication", false).option("--submit-review", "legacy alias: publish immediately if your environment still routes through submit-review", false).option("--company <companyId>", "publish under a Siglume company name; revenue is split equally among active members", "").option("--company-slug <slug>", "publish under a Siglume company by matching the slugified company name", "").option("--json", "emit machine-readable JSON", false).argument("[path]", ".", "project path").action(async (path, options) => {
|
|
8715
9035
|
const draftOnly = Boolean(options.draftOnly);
|
|
8716
9036
|
if (draftOnly && options.confirm) {
|
|
8717
9037
|
throw new SiglumeProjectError("--draft-only cannot be combined with --confirm.");
|
|
@@ -8720,7 +9040,13 @@ async function runCli(argv, deps = {}) {
|
|
|
8720
9040
|
throw new SiglumeProjectError("--draft-only cannot be combined with --submit-review.");
|
|
8721
9041
|
}
|
|
8722
9042
|
const shouldConfirm = Boolean(options.confirm) || !draftOnly && !options.submitReview;
|
|
8723
|
-
const report = await runRegistration(path, {
|
|
9043
|
+
const report = await runRegistration(path, {
|
|
9044
|
+
confirm: shouldConfirm,
|
|
9045
|
+
draft_only: draftOnly,
|
|
9046
|
+
submit_review: options.submitReview,
|
|
9047
|
+
company_id: options.company,
|
|
9048
|
+
company_slug: options.companySlug
|
|
9049
|
+
}, deps);
|
|
8724
9050
|
if (options.json) {
|
|
8725
9051
|
emit(stdout, renderJson(report));
|
|
8726
9052
|
} else {
|