@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/bin/siglume.cjs
CHANGED
|
@@ -1247,6 +1247,56 @@ var init_operations = __esm({
|
|
|
1247
1247
|
});
|
|
1248
1248
|
|
|
1249
1249
|
// src/client.ts
|
|
1250
|
+
function validateManifestPersistenceContract(payload) {
|
|
1251
|
+
const vertical = String(payload.store_vertical ?? "").trim().toLowerCase();
|
|
1252
|
+
const persistence = payload.persistence;
|
|
1253
|
+
if (persistence === void 0 || persistence === null) {
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
1256
|
+
if (!isRecord(persistence)) {
|
|
1257
|
+
throw new SiglumeClientError("AppManifest.persistence must be an object.");
|
|
1258
|
+
}
|
|
1259
|
+
const mode = String(persistence.mode ?? (vertical === "game" ? "platform" : "none")).trim().toLowerCase();
|
|
1260
|
+
if (!["none", "local", "platform", "developer_server"].includes(mode)) {
|
|
1261
|
+
throw new SiglumeClientError(
|
|
1262
|
+
"AppManifest.persistence.mode must be one of: none, local, platform, developer_server."
|
|
1263
|
+
);
|
|
1264
|
+
}
|
|
1265
|
+
const schema = persistence.save_data_schema;
|
|
1266
|
+
if (vertical === "game" && mode !== "none" && schema === void 0) {
|
|
1267
|
+
throw new SiglumeClientError(
|
|
1268
|
+
"AppManifest.persistence.save_data_schema is required when store_vertical='game' and persistence.mode is not 'none'."
|
|
1269
|
+
);
|
|
1270
|
+
}
|
|
1271
|
+
if (schema !== void 0) {
|
|
1272
|
+
validateSaveDataSchema(schema, "AppManifest.persistence.save_data_schema");
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
function validateSaveDataSchema(schema, fieldName) {
|
|
1276
|
+
if (!isRecord(schema)) {
|
|
1277
|
+
throw new SiglumeClientError(`${fieldName} must be a JSON Schema object.`);
|
|
1278
|
+
}
|
|
1279
|
+
const schemaSize = new TextEncoder().encode(JSON.stringify(schema)).length;
|
|
1280
|
+
if (schemaSize > 8192) {
|
|
1281
|
+
throw new SiglumeClientError(`${fieldName} must be at most 8192 bytes.`);
|
|
1282
|
+
}
|
|
1283
|
+
if (schema.type !== "object") {
|
|
1284
|
+
throw new SiglumeClientError(`${fieldName}.type must be 'object'.`);
|
|
1285
|
+
}
|
|
1286
|
+
const properties = schema.properties;
|
|
1287
|
+
if (!isRecord(properties) || Object.keys(properties).length === 0) {
|
|
1288
|
+
throw new SiglumeClientError(`${fieldName}.properties must be a non-empty object.`);
|
|
1289
|
+
}
|
|
1290
|
+
if (schema.required !== void 0) {
|
|
1291
|
+
if (!Array.isArray(schema.required) || !schema.required.every((item) => typeof item === "string")) {
|
|
1292
|
+
throw new SiglumeClientError(`${fieldName}.required must be an array of strings when provided.`);
|
|
1293
|
+
}
|
|
1294
|
+
const missing = schema.required.filter((item) => !(item in properties));
|
|
1295
|
+
if (missing.length > 0) {
|
|
1296
|
+
throw new SiglumeClientError(`${fieldName}.required references undefined properties: ${missing.join(", ")}.`);
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1250
1300
|
function buildToolManualQualityReport(payload) {
|
|
1251
1301
|
const qualityBlock = isRecord(payload.quality) ? payload.quality : payload;
|
|
1252
1302
|
const issues = [];
|
|
@@ -1321,6 +1371,8 @@ function buildUrl(baseUrl, path, params) {
|
|
|
1321
1371
|
return url.toString();
|
|
1322
1372
|
}
|
|
1323
1373
|
function parseListing(data) {
|
|
1374
|
+
const metadata = isRecord(data.metadata) ? data.metadata : {};
|
|
1375
|
+
const persistence = isRecord(data.persistence) ? data.persistence : isRecord(metadata.persistence) ? metadata.persistence : {};
|
|
1324
1376
|
return {
|
|
1325
1377
|
listing_id: String(data.listing_id ?? data.id ?? ""),
|
|
1326
1378
|
capability_key: String(data.capability_key ?? ""),
|
|
@@ -1334,6 +1386,8 @@ function parseListing(data) {
|
|
|
1334
1386
|
price_model: stringOrNull(data.price_model),
|
|
1335
1387
|
price_value_minor: Number(data.price_value_minor ?? 0),
|
|
1336
1388
|
currency: String(data.currency ?? "USD"),
|
|
1389
|
+
allow_free_trial: Boolean(data.allow_free_trial ?? false),
|
|
1390
|
+
free_trial_duration_days: Number(data.free_trial_duration_days ?? 30),
|
|
1337
1391
|
short_description: stringOrNull(data.short_description),
|
|
1338
1392
|
description: stringOrNull(data.description),
|
|
1339
1393
|
docs_url: stringOrNull(data.docs_url),
|
|
@@ -1341,14 +1395,59 @@ function parseListing(data) {
|
|
|
1341
1395
|
seller_display_name: stringOrNull(data.seller_display_name),
|
|
1342
1396
|
seller_homepage_url: stringOrNull(data.seller_homepage_url),
|
|
1343
1397
|
seller_social_url: stringOrNull(data.seller_social_url),
|
|
1398
|
+
publisher_type: stringOrNull(data.publisher_type),
|
|
1399
|
+
publisher_company_id: stringOrNull(data.publisher_company_id),
|
|
1400
|
+
company_id: stringOrNull(data.company_id),
|
|
1401
|
+
company_name: stringOrNull(data.company_name),
|
|
1402
|
+
company_publish_status: stringOrNull(data.company_publish_status),
|
|
1403
|
+
company_terms_version: stringOrNull(data.company_terms_version),
|
|
1344
1404
|
review_status: stringOrNull(data.review_status),
|
|
1345
1405
|
review_note: stringOrNull(data.review_note),
|
|
1346
1406
|
submission_blockers: Array.isArray(data.submission_blockers) ? data.submission_blockers.filter((item) => typeof item === "string") : [],
|
|
1407
|
+
persistence: { ...persistence },
|
|
1347
1408
|
created_at: stringOrNull(data.created_at),
|
|
1348
1409
|
updated_at: stringOrNull(data.updated_at),
|
|
1349
1410
|
raw: { ...data }
|
|
1350
1411
|
};
|
|
1351
1412
|
}
|
|
1413
|
+
function parseCompanyPublisher(data) {
|
|
1414
|
+
const wallets = Array.isArray(data.settlement_wallets) ? data.settlement_wallets.filter((item) => isRecord(item)) : [];
|
|
1415
|
+
return {
|
|
1416
|
+
company_id: String(data.company_id ?? data.id ?? ""),
|
|
1417
|
+
name: String(data.name ?? ""),
|
|
1418
|
+
status: String(data.status ?? ""),
|
|
1419
|
+
description: stringOrNull(data.description),
|
|
1420
|
+
is_founder: Boolean(data.is_founder ?? false),
|
|
1421
|
+
membership_role: stringOrNull(data.membership_role),
|
|
1422
|
+
membership_status: stringOrNull(data.membership_status),
|
|
1423
|
+
can_publish: Boolean(data.can_publish ?? true),
|
|
1424
|
+
can_approve: Boolean(data.can_approve ?? false),
|
|
1425
|
+
approval_required: Boolean(data.approval_required ?? false),
|
|
1426
|
+
paid_listing_allowed: Boolean(data.paid_listing_allowed ?? false),
|
|
1427
|
+
disabled_reasons: Array.isArray(data.disabled_reasons) ? data.disabled_reasons.filter((item) => typeof item === "string") : [],
|
|
1428
|
+
company_terms_version: stringOrNull(data.company_terms_version),
|
|
1429
|
+
active_listing_count: Number(data.active_listing_count ?? 0),
|
|
1430
|
+
pending_approval_count: Number(data.pending_approval_count ?? 0),
|
|
1431
|
+
settlement_wallet_ready: Boolean(data.settlement_wallet_ready ?? false),
|
|
1432
|
+
settlement_wallets: wallets.map((item) => ({ ...item })),
|
|
1433
|
+
raw: { ...data }
|
|
1434
|
+
};
|
|
1435
|
+
}
|
|
1436
|
+
function parseCapabilitySaveState(data) {
|
|
1437
|
+
return {
|
|
1438
|
+
capability_key: String(data.capability_key ?? ""),
|
|
1439
|
+
save_key: String(data.save_key ?? ""),
|
|
1440
|
+
schema_version: String(data.schema_version ?? "1"),
|
|
1441
|
+
revision: Number(data.revision ?? 0),
|
|
1442
|
+
payload: toRecord(data.payload),
|
|
1443
|
+
metadata: toRecord(data.metadata),
|
|
1444
|
+
checksum: stringOrNull(data.checksum),
|
|
1445
|
+
updated_at: stringOrNull(data.updated_at),
|
|
1446
|
+
created_at: stringOrNull(data.created_at),
|
|
1447
|
+
exists: Boolean(data.exists ?? false),
|
|
1448
|
+
raw: { ...data }
|
|
1449
|
+
};
|
|
1450
|
+
}
|
|
1352
1451
|
function parseBundleMember(data) {
|
|
1353
1452
|
return {
|
|
1354
1453
|
capability_listing_id: String(data.capability_listing_id ?? ""),
|
|
@@ -2528,17 +2627,23 @@ var init_client = __esm({
|
|
|
2528
2627
|
"support_contact",
|
|
2529
2628
|
"seller_homepage_url",
|
|
2530
2629
|
"seller_social_url",
|
|
2630
|
+
"publisher_type",
|
|
2631
|
+
"company_id",
|
|
2632
|
+
"publisher_company_id",
|
|
2531
2633
|
"store_vertical",
|
|
2532
2634
|
"jurisdiction",
|
|
2533
2635
|
"price_model",
|
|
2534
2636
|
"price_value_minor",
|
|
2535
2637
|
"currency",
|
|
2638
|
+
"allow_free_trial",
|
|
2639
|
+
"free_trial_duration_days",
|
|
2536
2640
|
"permission_class",
|
|
2537
2641
|
"approval_mode",
|
|
2538
2642
|
"dry_run_supported",
|
|
2539
2643
|
"required_connected_accounts",
|
|
2540
2644
|
"permission_scopes",
|
|
2541
|
-
"compatibility_tags"
|
|
2645
|
+
"compatibility_tags",
|
|
2646
|
+
"persistence"
|
|
2542
2647
|
]) {
|
|
2543
2648
|
const value = manifestPayload[fieldName];
|
|
2544
2649
|
if (value !== void 0 && value !== null) {
|
|
@@ -2560,6 +2665,44 @@ var init_client = __esm({
|
|
|
2560
2665
|
throw new SiglumeClientError(`AppManifest.currency must be 'USD' or 'JPY'. Got ${String(payload.currency)}.`);
|
|
2561
2666
|
}
|
|
2562
2667
|
payload.currency = currency;
|
|
2668
|
+
if (payload.allow_free_trial === void 0 || payload.allow_free_trial === null) {
|
|
2669
|
+
throw new SiglumeClientError(
|
|
2670
|
+
"AppManifest.allow_free_trial is required. Pass true to offer a Plus/Pro buyer free trial or false to disable trials."
|
|
2671
|
+
);
|
|
2672
|
+
}
|
|
2673
|
+
if (Boolean(payload.allow_free_trial)) {
|
|
2674
|
+
const duration = payload.free_trial_duration_days ?? 30;
|
|
2675
|
+
if (typeof duration !== "number" || !Number.isInteger(duration)) {
|
|
2676
|
+
throw new SiglumeClientError(
|
|
2677
|
+
"AppManifest.free_trial_duration_days must be an integer when allow_free_trial=true."
|
|
2678
|
+
);
|
|
2679
|
+
}
|
|
2680
|
+
if (duration < 1 || duration > 90) {
|
|
2681
|
+
throw new SiglumeClientError(
|
|
2682
|
+
`AppManifest.free_trial_duration_days must be between 1 and 90 when allow_free_trial=true, got: ${duration}.`
|
|
2683
|
+
);
|
|
2684
|
+
}
|
|
2685
|
+
}
|
|
2686
|
+
const explicitPublisherType = payload.publisher_type !== void 0 && payload.publisher_type !== null;
|
|
2687
|
+
const companyId = String(payload.company_id ?? "").trim() || String(payload.publisher_company_id ?? "").trim();
|
|
2688
|
+
const publisherType = String(payload.publisher_type ?? "user").trim().toLowerCase();
|
|
2689
|
+
if (publisherType !== "user" && publisherType !== "company") {
|
|
2690
|
+
throw new SiglumeClientError("AppManifest.publisher_type must be 'user' or 'company'.");
|
|
2691
|
+
}
|
|
2692
|
+
if (publisherType === "company" && !companyId) {
|
|
2693
|
+
throw new SiglumeClientError("AppManifest.company_id is required when publisher_type='company'.");
|
|
2694
|
+
}
|
|
2695
|
+
if (publisherType === "user" && companyId) {
|
|
2696
|
+
throw new SiglumeClientError("AppManifest.company_id cannot be combined with publisher_type='user'.");
|
|
2697
|
+
}
|
|
2698
|
+
if (explicitPublisherType || companyId) {
|
|
2699
|
+
payload.publisher_type = publisherType;
|
|
2700
|
+
}
|
|
2701
|
+
if (companyId) {
|
|
2702
|
+
payload.company_id = companyId;
|
|
2703
|
+
payload.publisher_company_id = companyId;
|
|
2704
|
+
}
|
|
2705
|
+
validateManifestPersistenceContract(payload);
|
|
2563
2706
|
if (payload.manifest && typeof payload.manifest === "object") {
|
|
2564
2707
|
delete payload.manifest.version;
|
|
2565
2708
|
}
|
|
@@ -2667,6 +2810,45 @@ var init_client = __esm({
|
|
|
2667
2810
|
const [data] = await this.request("GET", `/market/capabilities/${listing_id}`);
|
|
2668
2811
|
return parseListing(data);
|
|
2669
2812
|
}
|
|
2813
|
+
async list_company_publishers() {
|
|
2814
|
+
const [data] = await this.request("GET", "/market/company-publishers");
|
|
2815
|
+
return Array.isArray(data.items) ? data.items.filter((item) => isRecord(item)).map(parseCompanyPublisher) : [];
|
|
2816
|
+
}
|
|
2817
|
+
async request_company_publish_approval(listing_id, note) {
|
|
2818
|
+
const [data] = await this.request("POST", `/market/capabilities/${listing_id}/company-publish-approval`, {
|
|
2819
|
+
json_body: note ? { note } : {}
|
|
2820
|
+
});
|
|
2821
|
+
return parseListing(data);
|
|
2822
|
+
}
|
|
2823
|
+
async decide_company_publish_approval(listing_id, options) {
|
|
2824
|
+
const [data] = await this.request("POST", `/market/capabilities/${listing_id}/company-publish-approval/decision`, {
|
|
2825
|
+
json_body: {
|
|
2826
|
+
decision: options.decision,
|
|
2827
|
+
...options.reason ? { reason: options.reason } : {}
|
|
2828
|
+
}
|
|
2829
|
+
});
|
|
2830
|
+
return parseListing(data);
|
|
2831
|
+
}
|
|
2832
|
+
async get_capability_state(capability_key, save_key = "default") {
|
|
2833
|
+
const [data] = await this.request("GET", `/market/capability-state/${capability_key}/${save_key}`);
|
|
2834
|
+
return parseCapabilitySaveState(data);
|
|
2835
|
+
}
|
|
2836
|
+
async put_capability_state(capability_key, save_key = "default", payload = {}, options = {}) {
|
|
2837
|
+
const body = {
|
|
2838
|
+
payload: toRecord(payload),
|
|
2839
|
+
schema_version: options.schema_version ?? "1",
|
|
2840
|
+
metadata: toRecord(options.metadata)
|
|
2841
|
+
};
|
|
2842
|
+
if (options.expected_revision !== void 0 && options.expected_revision !== null) {
|
|
2843
|
+
body.expected_revision = Math.trunc(options.expected_revision);
|
|
2844
|
+
}
|
|
2845
|
+
const [data] = await this.request("PUT", `/market/capability-state/${capability_key}/${save_key}`, { json_body: body });
|
|
2846
|
+
return parseCapabilitySaveState(data);
|
|
2847
|
+
}
|
|
2848
|
+
async delete_capability_state(capability_key, save_key = "default") {
|
|
2849
|
+
const [data] = await this.request("DELETE", `/market/capability-state/${capability_key}/${save_key}`);
|
|
2850
|
+
return parseCapabilitySaveState(data);
|
|
2851
|
+
}
|
|
2670
2852
|
// ----- Capability bundles (v0.7 track 2) ---------------------------------
|
|
2671
2853
|
async list_bundles(options = {}) {
|
|
2672
2854
|
const params = {
|
|
@@ -5135,10 +5317,14 @@ function appendValueChange(changes, emittedKeys, level, key, oldValue, newValue,
|
|
|
5135
5317
|
}
|
|
5136
5318
|
function normalizeManifest(value) {
|
|
5137
5319
|
const payload = coerceMapping(value, "manifest");
|
|
5320
|
+
const rawDuration = payload.free_trial_duration_days;
|
|
5321
|
+
const duration = rawDuration === void 0 || rawDuration === null ? 30 : Number(rawDuration);
|
|
5138
5322
|
return {
|
|
5139
5323
|
...payload,
|
|
5140
5324
|
price_model: payload.price_model ?? "free",
|
|
5141
5325
|
currency: payload.currency ?? "USD",
|
|
5326
|
+
allow_free_trial: Boolean(payload.allow_free_trial ?? false),
|
|
5327
|
+
free_trial_duration_days: Number.isFinite(duration) ? Math.trunc(duration) : 30,
|
|
5142
5328
|
// AppManifest defaults permission_class to "read-only" (hyphen form,
|
|
5143
5329
|
// PermissionClass.READ_ONLY). Without this default, a legacy / minimal
|
|
5144
5330
|
// manifest without permission_class compared against an upgraded one
|
|
@@ -7257,7 +7443,12 @@ function ensureManifestPublisherIdentity(project) {
|
|
|
7257
7443
|
const sellerHomepageUrl = String(manifestPayload.seller_homepage_url ?? "").trim();
|
|
7258
7444
|
const sellerSocialUrl = String(manifestPayload.seller_social_url ?? "").trim();
|
|
7259
7445
|
const jurisdiction = String(manifestPayload.jurisdiction ?? "").trim();
|
|
7446
|
+
const companyId = String(manifestPayload.company_id ?? "").trim() || String(manifestPayload.publisher_company_id ?? "").trim();
|
|
7447
|
+
const publisherType = String(manifestPayload.publisher_type ?? "user").trim().toLowerCase();
|
|
7260
7448
|
const issues = [];
|
|
7449
|
+
if (companyId && publisherType !== "company") {
|
|
7450
|
+
issues.push('manifest.company_id requires manifest.publisher_type to be "company"');
|
|
7451
|
+
}
|
|
7261
7452
|
if (!docsUrl) {
|
|
7262
7453
|
issues.push("manifest.docs_url is required");
|
|
7263
7454
|
} else if (looksLikePlaceholder(docsUrl)) {
|
|
@@ -7403,25 +7594,110 @@ ${errors.map((error) => `- ${error}`).join("\n")}`
|
|
|
7403
7594
|
}
|
|
7404
7595
|
return preflight;
|
|
7405
7596
|
}
|
|
7597
|
+
function companyNameSlug(value) {
|
|
7598
|
+
return value.normalize("NFKD").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
7599
|
+
}
|
|
7406
7600
|
async function runRegistration(path = ".", options = {}, deps = {}) {
|
|
7407
7601
|
const project = await loadProject(path);
|
|
7602
|
+
let requestedCompanyId = String(options.company_id ?? "").trim();
|
|
7603
|
+
const requestedCompanySlug = String(options.company_slug ?? "").trim();
|
|
7604
|
+
let companyPublisherCandidates = null;
|
|
7605
|
+
if (requestedCompanySlug) {
|
|
7606
|
+
if (requestedCompanyId) {
|
|
7607
|
+
throw new SiglumeProjectError("--company and --company-slug cannot be combined.");
|
|
7608
|
+
}
|
|
7609
|
+
const slug = companyNameSlug(requestedCompanySlug);
|
|
7610
|
+
if (!slug && requestedCompanySlug !== requestedCompanyId) {
|
|
7611
|
+
throw new SiglumeProjectError(`Company slug ${requestedCompanySlug} is not slug-compatible; use --company <company_id> instead.`);
|
|
7612
|
+
}
|
|
7613
|
+
}
|
|
7614
|
+
if (requestedCompanyId) {
|
|
7615
|
+
project.manifest = {
|
|
7616
|
+
...project.manifest,
|
|
7617
|
+
publisher_type: "company",
|
|
7618
|
+
company_id: requestedCompanyId,
|
|
7619
|
+
publisher_company_id: requestedCompanyId
|
|
7620
|
+
};
|
|
7621
|
+
}
|
|
7408
7622
|
ensureExplicitToolManual(project);
|
|
7409
7623
|
ensureManifestPublisherIdentity(project);
|
|
7410
7624
|
ensureRuntimeValidationReady(project);
|
|
7411
7625
|
ensureRequiredOauthCredentials(project);
|
|
7412
7626
|
const canonicalOauthCredentials = canonicalOauthCredentialsPayload(project.oauth_credentials);
|
|
7413
7627
|
const client = await createClient(deps);
|
|
7628
|
+
if (requestedCompanySlug) {
|
|
7629
|
+
const slug = companyNameSlug(requestedCompanySlug);
|
|
7630
|
+
companyPublisherCandidates = await client.list_company_publishers();
|
|
7631
|
+
const matches = companyPublisherCandidates.filter(
|
|
7632
|
+
(item) => companyNameSlug(item.name || item.company_id) === slug || item.company_id === requestedCompanySlug
|
|
7633
|
+
);
|
|
7634
|
+
if (matches.length === 0) {
|
|
7635
|
+
throw new SiglumeProjectError(`Company slug ${requestedCompanySlug} is not available to this API key.`);
|
|
7636
|
+
}
|
|
7637
|
+
if (matches.length > 1) {
|
|
7638
|
+
throw new SiglumeProjectError(`Company slug ${requestedCompanySlug} is ambiguous; use --company <company_id> instead.`);
|
|
7639
|
+
}
|
|
7640
|
+
const match = matches[0];
|
|
7641
|
+
if (!match) {
|
|
7642
|
+
throw new SiglumeProjectError(`Company slug ${requestedCompanySlug} is not available to this API key.`);
|
|
7643
|
+
}
|
|
7644
|
+
if (match.can_publish === false) {
|
|
7645
|
+
const disabledReasons = match.disabled_reasons ?? [];
|
|
7646
|
+
const reasons = disabledReasons.length > 0 ? disabledReasons.join(", ") : "company publisher is disabled";
|
|
7647
|
+
throw new SiglumeProjectError(`Company ${match.company_id} cannot publish: ${reasons}.`);
|
|
7648
|
+
}
|
|
7649
|
+
requestedCompanyId = match.company_id;
|
|
7650
|
+
project.manifest = {
|
|
7651
|
+
...project.manifest,
|
|
7652
|
+
publisher_type: "company",
|
|
7653
|
+
company_id: requestedCompanyId,
|
|
7654
|
+
publisher_company_id: requestedCompanyId
|
|
7655
|
+
};
|
|
7656
|
+
}
|
|
7414
7657
|
const preflight = await registrationPreflight(project, client);
|
|
7658
|
+
let companyPublisherPreflight = null;
|
|
7659
|
+
const companyId = String(project.manifest.company_id ?? "").trim() || String(project.manifest.publisher_company_id ?? "").trim();
|
|
7660
|
+
const publisherType = String(project.manifest.publisher_type ?? "user").toLowerCase();
|
|
7661
|
+
if (publisherType === "company") {
|
|
7662
|
+
if (!companyId) {
|
|
7663
|
+
throw new SiglumeProjectError("Company registration requires --company <company_id> or manifest.company_id.");
|
|
7664
|
+
}
|
|
7665
|
+
const companies = companyPublisherCandidates ?? await client.list_company_publishers();
|
|
7666
|
+
companyPublisherCandidates = companies;
|
|
7667
|
+
const company = companies.find((item) => item.company_id === companyId);
|
|
7668
|
+
if (!company) {
|
|
7669
|
+
throw new SiglumeProjectError(`Company ${companyId} is not available to this API key.`);
|
|
7670
|
+
}
|
|
7671
|
+
if (company.can_publish === false) {
|
|
7672
|
+
const disabledReasons = company.disabled_reasons ?? [];
|
|
7673
|
+
const reasons = disabledReasons.length > 0 ? disabledReasons.join(", ") : "company publisher is disabled";
|
|
7674
|
+
throw new SiglumeProjectError(`Company ${companyId} cannot publish: ${reasons}.`);
|
|
7675
|
+
}
|
|
7676
|
+
companyPublisherPreflight = company;
|
|
7677
|
+
}
|
|
7415
7678
|
let developerPortalPreflight = null;
|
|
7416
7679
|
if (String(project.manifest.price_model ?? "free").toLowerCase() !== "free") {
|
|
7417
|
-
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
)
|
|
7680
|
+
if (publisherType === "company") {
|
|
7681
|
+
const company = companyPublisherPreflight;
|
|
7682
|
+
if (!company) {
|
|
7683
|
+
throw new SiglumeProjectError(`Company ${companyId} is not available to this API key.`);
|
|
7684
|
+
}
|
|
7685
|
+
if (company.settlement_wallet_ready !== true) {
|
|
7686
|
+
throw new SiglumeProjectError(
|
|
7687
|
+
`Paid company registration requires a verified company settlement wallet for ${company.name}. Open the company settings and complete settlement readiness before registering.`
|
|
7688
|
+
);
|
|
7689
|
+
}
|
|
7690
|
+
developerPortalPreflight = { company_publisher: toJsonable(company) };
|
|
7691
|
+
} else {
|
|
7692
|
+
const portal = await client.get_developer_portal();
|
|
7693
|
+
const verifiedDestination = portal.payout_readiness?.verified_destination;
|
|
7694
|
+
if (verifiedDestination !== true) {
|
|
7695
|
+
throw new SiglumeProjectError(
|
|
7696
|
+
"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."
|
|
7697
|
+
);
|
|
7698
|
+
}
|
|
7699
|
+
developerPortalPreflight = toJsonable(portal);
|
|
7423
7700
|
}
|
|
7424
|
-
developerPortalPreflight = toJsonable(portal);
|
|
7425
7701
|
}
|
|
7426
7702
|
const receipt = await client.auto_register(project.manifest, project.tool_manual, {
|
|
7427
7703
|
runtime_validation: project.runtime_validation,
|
|
@@ -7494,6 +7770,14 @@ async function getUsageReport(options, deps = {}) {
|
|
|
7494
7770
|
count: items.length
|
|
7495
7771
|
};
|
|
7496
7772
|
}
|
|
7773
|
+
async function listCompanyPublishersReport(deps = {}) {
|
|
7774
|
+
const client = await createClient(deps);
|
|
7775
|
+
const companies = await client.list_company_publishers();
|
|
7776
|
+
return {
|
|
7777
|
+
companies: companies.map((item) => toJsonable(item)),
|
|
7778
|
+
count: companies.length
|
|
7779
|
+
};
|
|
7780
|
+
}
|
|
7497
7781
|
async function diffJsonFiles(oldPath, newPath) {
|
|
7498
7782
|
const oldPayload = await loadJsonDocument(oldPath);
|
|
7499
7783
|
const newPayload = await loadJsonDocument(newPath);
|
|
@@ -7690,6 +7974,7 @@ function buildOperationManifest(operation, capability_key_override) {
|
|
|
7690
7974
|
required_connected_accounts: [],
|
|
7691
7975
|
price_model: PriceModel.FREE,
|
|
7692
7976
|
currency: "USD",
|
|
7977
|
+
allow_free_trial: false,
|
|
7693
7978
|
jurisdiction: "US",
|
|
7694
7979
|
short_description: operation.summary,
|
|
7695
7980
|
docs_url: "https://example.com/docs",
|
|
@@ -7768,6 +8053,7 @@ function operationAdapterSource(operation, manifest) {
|
|
|
7768
8053
|
" required_connected_accounts: [],",
|
|
7769
8054
|
" price_model: PriceModel.FREE,",
|
|
7770
8055
|
" currency: 'USD' as const,",
|
|
8056
|
+
" allow_free_trial: false,",
|
|
7771
8057
|
` jurisdiction: ${JSON.stringify(manifest.jurisdiction)},`,
|
|
7772
8058
|
` short_description: ${JSON.stringify(manifest.short_description ?? "")},`,
|
|
7773
8059
|
` support_contact: ${JSON.stringify(manifest.support_contact ?? "")},`,
|
|
@@ -8448,6 +8734,7 @@ function fallbackTemplateSource(template) {
|
|
|
8448
8734
|
" required_connected_accounts: [],",
|
|
8449
8735
|
" price_model: PriceModel.FREE,",
|
|
8450
8736
|
" currency: 'USD' as const,",
|
|
8737
|
+
" allow_free_trial: false,",
|
|
8451
8738
|
' jurisdiction: "US",',
|
|
8452
8739
|
' short_description: "Starter template generated by siglume init.",',
|
|
8453
8740
|
' support_contact: "support@example.com",',
|
|
@@ -8502,6 +8789,7 @@ function starterManifest(template) {
|
|
|
8502
8789
|
required_connected_accounts: [],
|
|
8503
8790
|
price_model: "free",
|
|
8504
8791
|
currency: "USD",
|
|
8792
|
+
allow_free_trial: false,
|
|
8505
8793
|
jurisdiction: "US",
|
|
8506
8794
|
short_description: "Starter template generated by siglume init.",
|
|
8507
8795
|
support_contact: "support@example.com",
|
|
@@ -8576,6 +8864,24 @@ function renderOperationTable(operations) {
|
|
|
8576
8864
|
...rows.map((row) => row.map((cell, index) => cell.padEnd(widths[index] ?? cell.length)).join(" "))
|
|
8577
8865
|
];
|
|
8578
8866
|
}
|
|
8867
|
+
function renderCompanyTable(companies) {
|
|
8868
|
+
const rows = companies.map((item) => [
|
|
8869
|
+
String(item.company_id ?? item.id ?? ""),
|
|
8870
|
+
String(item.name ?? ""),
|
|
8871
|
+
String(item.membership_role ?? (item.is_founder ? "founder" : "")),
|
|
8872
|
+
String(item.settlement_wallet_ready === true ? "ready" : "not_ready"),
|
|
8873
|
+
String(item.pending_approval_count ?? 0)
|
|
8874
|
+
]);
|
|
8875
|
+
const headers = ["company_id", "name", "role", "settlement", "pending"];
|
|
8876
|
+
const widths = headers.map(
|
|
8877
|
+
(header, index) => Math.max(header.length, ...rows.map((row) => row[index]?.length ?? 0))
|
|
8878
|
+
);
|
|
8879
|
+
return [
|
|
8880
|
+
headers.map((header, index) => header.padEnd(widths[index] ?? header.length)).join(" "),
|
|
8881
|
+
widths.map((width) => "-".repeat(width)).join(" "),
|
|
8882
|
+
...rows.map((row) => row.map((cell, index) => cell.padEnd(widths[index] ?? cell.length)).join(" "))
|
|
8883
|
+
];
|
|
8884
|
+
}
|
|
8579
8885
|
async function runCli(argv, deps = {}) {
|
|
8580
8886
|
const stdout = deps.stdout;
|
|
8581
8887
|
const stderr = deps.stderr ?? console.error;
|
|
@@ -8732,7 +9038,21 @@ async function runCli(argv, deps = {}) {
|
|
|
8732
9038
|
if (report.runtime_validation_path) emit(stdout, `runtime_validation_path: ${String(report.runtime_validation_path)}`);
|
|
8733
9039
|
if (report.oauth_credentials_path) emit(stdout, `oauth_credentials_path: ${String(report.oauth_credentials_path)}`);
|
|
8734
9040
|
});
|
|
8735
|
-
program.command("
|
|
9041
|
+
program.command("companies").description("List Siglume companies available for company-name publishing.").option("--json", "emit machine-readable JSON", false).action(async (options) => {
|
|
9042
|
+
const report = await listCompanyPublishersReport(deps);
|
|
9043
|
+
if (options.json) {
|
|
9044
|
+
emit(stdout, renderJson(report));
|
|
9045
|
+
return;
|
|
9046
|
+
}
|
|
9047
|
+
const companies = Array.isArray(report.companies) ? report.companies.filter((item) => Boolean(item && typeof item === "object")) : [];
|
|
9048
|
+
if (companies.length === 0) {
|
|
9049
|
+
emit(stdout, "No company publishers available for this API key.");
|
|
9050
|
+
return;
|
|
9051
|
+
}
|
|
9052
|
+
emit(stdout, "Company publishers");
|
|
9053
|
+
renderCompanyTable(companies).forEach((line) => emit(stdout, line));
|
|
9054
|
+
});
|
|
9055
|
+
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) => {
|
|
8736
9056
|
const draftOnly = Boolean(options.draftOnly);
|
|
8737
9057
|
if (draftOnly && options.confirm) {
|
|
8738
9058
|
throw new SiglumeProjectError("--draft-only cannot be combined with --confirm.");
|
|
@@ -8741,7 +9061,13 @@ async function runCli(argv, deps = {}) {
|
|
|
8741
9061
|
throw new SiglumeProjectError("--draft-only cannot be combined with --submit-review.");
|
|
8742
9062
|
}
|
|
8743
9063
|
const shouldConfirm = Boolean(options.confirm) || !draftOnly && !options.submitReview;
|
|
8744
|
-
const report = await runRegistration(path, {
|
|
9064
|
+
const report = await runRegistration(path, {
|
|
9065
|
+
confirm: shouldConfirm,
|
|
9066
|
+
draft_only: draftOnly,
|
|
9067
|
+
submit_review: options.submitReview,
|
|
9068
|
+
company_id: options.company,
|
|
9069
|
+
company_slug: options.companySlug
|
|
9070
|
+
}, deps);
|
|
8745
9071
|
if (options.json) {
|
|
8746
9072
|
emit(stdout, renderJson(report));
|
|
8747
9073
|
} else {
|