@topolo/sdk 0.9.6 → 0.9.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -3574,9 +3574,15 @@ function slugify(value) {
3574
3574
  return String(value || "").trim().replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
3575
3575
  }
3576
3576
  function singularize(value) {
3577
+ const irregular = /* @__PURE__ */ new Map([
3578
+ ["analyses", "analysis"],
3579
+ ["buses", "bus"],
3580
+ ["statuses", "status"]
3581
+ ]);
3582
+ if (irregular.has(value)) return irregular.get(value);
3577
3583
  if (value.endsWith("ies") && value.length > 3) return `${value.slice(0, -3)}y`;
3578
- if (value.endsWith("sses")) return value.slice(0, -2);
3579
- if (value.endsWith("s") && !value.endsWith("ss")) return value.slice(0, -1);
3584
+ if (/(?:ches|shes|sses|xes|zes)$/.test(value)) return value.slice(0, -2);
3585
+ if (value.endsWith("s") && !/(?:ss|us|is)$/.test(value)) return value.slice(0, -1);
3580
3586
  return value || "resource";
3581
3587
  }
3582
3588
  function operationFor(action) {
@@ -3590,6 +3596,11 @@ function resourceFor(action) {
3590
3596
  const pathToken = String(action.path || "").split("/").filter((token) => token && token !== "api" && !token.startsWith("{")).find((token) => !OPERATION_TOKENS.has(slugify(token)));
3591
3597
  return singularize(slugify(pathToken || "resource").replaceAll("-", "_"));
3592
3598
  }
3599
+ function collectionFor(action, resource) {
3600
+ const named = String(action.name || "").split(/[._:-]+/).filter(Boolean).find((token) => !OPERATION_TOKENS.has(token));
3601
+ if (named) return slugify(named).replaceAll("-", "_");
3602
+ return resource.endsWith("s") ? resource : `${resource}s`;
3603
+ }
3593
3604
  function isConcreteOutputSchema(schema) {
3594
3605
  if (!isRecord3(schema)) return false;
3595
3606
  if (typeof schema.$ref === "string" && schema.$ref.trim()) return true;
@@ -3620,6 +3631,7 @@ function derivedOutputSchema(action) {
3620
3631
  "x-topolo-contract-precision": "structural"
3621
3632
  };
3622
3633
  if (operation === "list" || operation === "search") {
3634
+ const collection = collectionFor(action, resource);
3623
3635
  return {
3624
3636
  title: `${action.title || action.name} response`,
3625
3637
  description: `Collection response returned by ${action.name}. The service may return the collection directly or in an envelope.`,
@@ -3630,7 +3642,7 @@ function derivedOutputSchema(action) {
3630
3642
  properties: {
3631
3643
  data: { oneOf: [records, { type: "object", additionalProperties: true }] },
3632
3644
  items: records,
3633
- [resource.endsWith("s") ? resource : `${resource}s`]: records,
3645
+ [collection]: records,
3634
3646
  count: { type: "integer", minimum: 0 },
3635
3647
  nextCursor: { type: ["string", "null"] }
3636
3648
  },
package/dist/index.js CHANGED
@@ -3513,9 +3513,15 @@ function slugify(value) {
3513
3513
  return String(value || "").trim().replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
3514
3514
  }
3515
3515
  function singularize(value) {
3516
+ const irregular = /* @__PURE__ */ new Map([
3517
+ ["analyses", "analysis"],
3518
+ ["buses", "bus"],
3519
+ ["statuses", "status"]
3520
+ ]);
3521
+ if (irregular.has(value)) return irregular.get(value);
3516
3522
  if (value.endsWith("ies") && value.length > 3) return `${value.slice(0, -3)}y`;
3517
- if (value.endsWith("sses")) return value.slice(0, -2);
3518
- if (value.endsWith("s") && !value.endsWith("ss")) return value.slice(0, -1);
3523
+ if (/(?:ches|shes|sses|xes|zes)$/.test(value)) return value.slice(0, -2);
3524
+ if (value.endsWith("s") && !/(?:ss|us|is)$/.test(value)) return value.slice(0, -1);
3519
3525
  return value || "resource";
3520
3526
  }
3521
3527
  function operationFor(action) {
@@ -3529,6 +3535,11 @@ function resourceFor(action) {
3529
3535
  const pathToken = String(action.path || "").split("/").filter((token) => token && token !== "api" && !token.startsWith("{")).find((token) => !OPERATION_TOKENS.has(slugify(token)));
3530
3536
  return singularize(slugify(pathToken || "resource").replaceAll("-", "_"));
3531
3537
  }
3538
+ function collectionFor(action, resource) {
3539
+ const named = String(action.name || "").split(/[._:-]+/).filter(Boolean).find((token) => !OPERATION_TOKENS.has(token));
3540
+ if (named) return slugify(named).replaceAll("-", "_");
3541
+ return resource.endsWith("s") ? resource : `${resource}s`;
3542
+ }
3532
3543
  function isConcreteOutputSchema(schema) {
3533
3544
  if (!isRecord3(schema)) return false;
3534
3545
  if (typeof schema.$ref === "string" && schema.$ref.trim()) return true;
@@ -3559,6 +3570,7 @@ function derivedOutputSchema(action) {
3559
3570
  "x-topolo-contract-precision": "structural"
3560
3571
  };
3561
3572
  if (operation === "list" || operation === "search") {
3573
+ const collection = collectionFor(action, resource);
3562
3574
  return {
3563
3575
  title: `${action.title || action.name} response`,
3564
3576
  description: `Collection response returned by ${action.name}. The service may return the collection directly or in an envelope.`,
@@ -3569,7 +3581,7 @@ function derivedOutputSchema(action) {
3569
3581
  properties: {
3570
3582
  data: { oneOf: [records, { type: "object", additionalProperties: true }] },
3571
3583
  items: records,
3572
- [resource.endsWith("s") ? resource : `${resource}s`]: records,
3584
+ [collection]: records,
3573
3585
  count: { type: "integer", minimum: 0 },
3574
3586
  nextCursor: { type: ["string", "null"] }
3575
3587
  },
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@topolo/sdk",
3
- "version": "0.9.6",
4
- "topoloPublishedVersion": "0.9.6",
3
+ "version": "0.9.7",
4
+ "topoloPublishedVersion": "0.9.7",
5
5
  "description": "Typed client SDK for the Topolo platform. Used by TopoloCli, TopoloMCP, and third-party agents.",
6
6
  "type": "module",
7
7
  "main": "./dist/index.js",