@topolo/sdk 0.14.1 → 0.14.2

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.
@@ -110,6 +110,7 @@ var ERROR_CODE_PATTERN = /^[a-z][a-z0-9_]{0,63}$/;
110
110
  var TOPOLO_REQUEST_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
111
111
  var CLOUDFLARE_RAY_ID_PATTERN = /^[0-9a-f]{16}-[A-Z]{3}$/;
112
112
  var PERMISSION_PATTERN = /^[a-z][a-z0-9_-]{0,63}(?:\.[a-z][a-z0-9_-]{0,63})*:(?:[a-z][a-z0-9_-]{0,63}|\*)$/;
113
+ var PUBLIC_FIELD_PATH_PATTERN = /^[$.a-z0-9_[\]-]{1,160}$/i;
113
114
  var RETRY_AFTER_DATE_PATTERN = /^(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun), \d{2} (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{4} \d{2}:\d{2}:\d{2} GMT$/;
114
115
  var PUBLIC_DETAIL_SOURCES = /* @__PURE__ */ new Set([
115
116
  "api_key_introspection",
@@ -195,7 +196,11 @@ function extractTopoloServiceErrorDetails(body) {
195
196
  if (candidate === void 0) candidate = nestedRecord.details ?? nestedRecord;
196
197
  }
197
198
  if (candidate === void 0) candidate = record;
198
- if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) return void 0;
199
+ if (Array.isArray(candidate)) {
200
+ const paths = canonicalTopoloValidationPaths(candidate);
201
+ return paths.length ? { paths } : void 0;
202
+ }
203
+ if (!candidate || typeof candidate !== "object") return void 0;
199
204
  const source = candidate;
200
205
  const safe = {};
201
206
  for (const [key, value] of Object.entries(source)) {
@@ -232,12 +237,42 @@ function extractTopoloServiceErrorDetails(body) {
232
237
  continue;
233
238
  }
234
239
  if (["missingFields", "fields", "paths"].includes(key) && Array.isArray(value)) {
235
- const paths = value.filter((item) => typeof item === "string" && /^[$.a-z0-9_[\]-]{1,160}$/i.test(item));
240
+ const paths = value.filter((item) => typeof item === "string" && PUBLIC_FIELD_PATH_PATTERN.test(item));
236
241
  if (paths.length) safe[key] = paths;
237
242
  }
238
243
  }
239
244
  return Object.keys(safe).length ? safe : void 0;
240
245
  }
246
+ function canonicalTopoloValidationPaths(issues) {
247
+ const paths = [];
248
+ for (const issue of issues) {
249
+ if (!issue || typeof issue !== "object" || Array.isArray(issue)) continue;
250
+ const record = issue;
251
+ const path = canonicalTopoloValidationPath(record.field) ?? canonicalTopoloValidationPath(record.path);
252
+ if (path && !paths.includes(path)) paths.push(path);
253
+ if (paths.length === 32) break;
254
+ }
255
+ return paths;
256
+ }
257
+ function canonicalTopoloValidationPath(value) {
258
+ if (typeof value === "string") {
259
+ const path2 = value.trim();
260
+ return PUBLIC_FIELD_PATH_PATTERN.test(path2) ? path2 : void 0;
261
+ }
262
+ if (!Array.isArray(value) || value.length === 0 || value.length > 32) return void 0;
263
+ const segments = value.map((segment) => {
264
+ if (typeof segment === "number" && Number.isSafeInteger(segment) && segment >= 0) {
265
+ return String(segment);
266
+ }
267
+ if (typeof segment === "string" && /^[a-z0-9_$-]{1,80}$/i.test(segment)) {
268
+ return segment;
269
+ }
270
+ return null;
271
+ });
272
+ if (segments.includes(null)) return void 0;
273
+ const path = segments.join(".");
274
+ return PUBLIC_FIELD_PATH_PATTERN.test(path) ? path : void 0;
275
+ }
241
276
  var TopoloHttpError = class extends TopoloSdkError {
242
277
  status;
243
278
  body;
@@ -63,6 +63,7 @@ var ERROR_CODE_PATTERN = /^[a-z][a-z0-9_]{0,63}$/;
63
63
  var TOPOLO_REQUEST_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
64
64
  var CLOUDFLARE_RAY_ID_PATTERN = /^[0-9a-f]{16}-[A-Z]{3}$/;
65
65
  var PERMISSION_PATTERN = /^[a-z][a-z0-9_-]{0,63}(?:\.[a-z][a-z0-9_-]{0,63})*:(?:[a-z][a-z0-9_-]{0,63}|\*)$/;
66
+ var PUBLIC_FIELD_PATH_PATTERN = /^[$.a-z0-9_[\]-]{1,160}$/i;
66
67
  var RETRY_AFTER_DATE_PATTERN = /^(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun), \d{2} (?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{4} \d{2}:\d{2}:\d{2} GMT$/;
67
68
  var PUBLIC_DETAIL_SOURCES = /* @__PURE__ */ new Set([
68
69
  "api_key_introspection",
@@ -148,7 +149,11 @@ function extractTopoloServiceErrorDetails(body) {
148
149
  if (candidate === void 0) candidate = nestedRecord.details ?? nestedRecord;
149
150
  }
150
151
  if (candidate === void 0) candidate = record;
151
- if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) return void 0;
152
+ if (Array.isArray(candidate)) {
153
+ const paths = canonicalTopoloValidationPaths(candidate);
154
+ return paths.length ? { paths } : void 0;
155
+ }
156
+ if (!candidate || typeof candidate !== "object") return void 0;
152
157
  const source = candidate;
153
158
  const safe = {};
154
159
  for (const [key, value] of Object.entries(source)) {
@@ -185,12 +190,42 @@ function extractTopoloServiceErrorDetails(body) {
185
190
  continue;
186
191
  }
187
192
  if (["missingFields", "fields", "paths"].includes(key) && Array.isArray(value)) {
188
- const paths = value.filter((item) => typeof item === "string" && /^[$.a-z0-9_[\]-]{1,160}$/i.test(item));
193
+ const paths = value.filter((item) => typeof item === "string" && PUBLIC_FIELD_PATH_PATTERN.test(item));
189
194
  if (paths.length) safe[key] = paths;
190
195
  }
191
196
  }
192
197
  return Object.keys(safe).length ? safe : void 0;
193
198
  }
199
+ function canonicalTopoloValidationPaths(issues) {
200
+ const paths = [];
201
+ for (const issue of issues) {
202
+ if (!issue || typeof issue !== "object" || Array.isArray(issue)) continue;
203
+ const record = issue;
204
+ const path = canonicalTopoloValidationPath(record.field) ?? canonicalTopoloValidationPath(record.path);
205
+ if (path && !paths.includes(path)) paths.push(path);
206
+ if (paths.length === 32) break;
207
+ }
208
+ return paths;
209
+ }
210
+ function canonicalTopoloValidationPath(value) {
211
+ if (typeof value === "string") {
212
+ const path2 = value.trim();
213
+ return PUBLIC_FIELD_PATH_PATTERN.test(path2) ? path2 : void 0;
214
+ }
215
+ if (!Array.isArray(value) || value.length === 0 || value.length > 32) return void 0;
216
+ const segments = value.map((segment) => {
217
+ if (typeof segment === "number" && Number.isSafeInteger(segment) && segment >= 0) {
218
+ return String(segment);
219
+ }
220
+ if (typeof segment === "string" && /^[a-z0-9_$-]{1,80}$/i.test(segment)) {
221
+ return segment;
222
+ }
223
+ return null;
224
+ });
225
+ if (segments.includes(null)) return void 0;
226
+ const path = segments.join(".");
227
+ return PUBLIC_FIELD_PATH_PATTERN.test(path) ? path : void 0;
228
+ }
194
229
  var TopoloHttpError = class extends TopoloSdkError {
195
230
  status;
196
231
  body;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@topolo/sdk",
3
- "version": "0.14.1",
4
- "topoloPublishedVersion": "0.14.1",
3
+ "version": "0.14.2",
4
+ "topoloPublishedVersion": "0.14.2",
5
5
  "description": "Typed client SDK for the Topolo platform. Used by TopoloCli, TopoloMCP, and third-party agents.",
6
6
  "license": "UNLICENSED",
7
7
  "author": "Topolo",