@secondlayer/sdk 6.15.0 → 6.17.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.
@@ -23,6 +23,22 @@ class VersionConflictError extends ApiError {
23
23
  }
24
24
  }
25
25
 
26
+ class ByoBreakingChangeError extends ApiError {
27
+ details;
28
+ constructor(message, details) {
29
+ super(422, message, details, "BYO_BREAKING_CHANGE");
30
+ this.name = "ByoBreakingChangeError";
31
+ this.details = details;
32
+ }
33
+ }
34
+ function isByoBreakingDetails(x) {
35
+ if (!x || typeof x !== "object")
36
+ return false;
37
+ const d = x;
38
+ const plan = d.plan;
39
+ return Array.isArray(d.reasons) && !!plan && typeof plan === "object" && typeof plan.dropStatement === "string";
40
+ }
41
+
26
42
  // src/base.ts
27
43
  var DEFAULT_BASE_URL = "https://api.secondlayer.tools";
28
44
  function buildQuery(params) {
@@ -123,6 +139,9 @@ class BaseClient {
123
139
  if (errorBody)
124
140
  message = errorBody;
125
141
  }
142
+ if (response.status === 422 && code === "BYO_BREAKING_CHANGE" && parsedBody && typeof parsedBody === "object" && isByoBreakingDetails(parsedBody.details)) {
143
+ throw new ByoBreakingChangeError(message, parsedBody.details);
144
+ }
126
145
  throw new ApiError(response.status, message, parsedBody, code);
127
146
  }
128
147
  return response;
@@ -376,6 +395,12 @@ class ApiKeys extends BaseClient {
376
395
  name: params.name
377
396
  });
378
397
  }
398
+ list() {
399
+ return this.request("GET", "/api/keys");
400
+ }
401
+ revoke(id) {
402
+ return this.request("DELETE", `/api/keys/${id}`);
403
+ }
379
404
  }
380
405
 
381
406
  // src/contracts/client.ts
@@ -422,20 +447,35 @@ var CURSOR_SLUGS = {
422
447
  rowKey: "events"
423
448
  }
424
449
  };
450
+ function catalogPathTail(path) {
451
+ return path.replace(/^\/?v1\/datasets\//, "").replace(/^\/+/, "");
452
+ }
425
453
 
426
454
  class Datasets extends BaseClient {
455
+ catalogPromise;
427
456
  constructor(options = {}) {
428
457
  super(options);
429
458
  }
430
459
  listDatasets() {
431
460
  return this.request("GET", "/v1/datasets");
432
461
  }
462
+ async get(slug, params = {}) {
463
+ const { path, rowKey } = await this.resolveDataset(slug);
464
+ const env = await this.requestPath(path, this.paramsToQuery(params));
465
+ const value = env[rowKey];
466
+ const rows = Array.isArray(value) ? value : value == null ? [] : [value];
467
+ return {
468
+ rows,
469
+ next_cursor: env.next_cursor ?? null,
470
+ tip: env.tip
471
+ };
472
+ }
433
473
  async query(slug, params = {}) {
434
474
  const d = CURSOR_SLUGS[slug];
435
475
  if (!d) {
436
476
  throw new Error(`unknown cursor dataset "${slug}" (use one of: ${Object.keys(CURSOR_SLUGS).join(", ")})`);
437
477
  }
438
- const env = await this.get(d.path, this.paramsToQuery(params));
478
+ const env = await this.requestPath(d.path, this.paramsToQuery(params));
439
479
  return {
440
480
  rows: env[d.rowKey] ?? [],
441
481
  next_cursor: env.next_cursor ?? null,
@@ -452,7 +492,7 @@ class Datasets extends BaseClient {
452
492
  bnsNamespaceEvents = this.cursorDataset("bns/namespace-events", "events");
453
493
  bnsMarketplaceEvents = this.cursorDataset("bns/marketplace-events", "events");
454
494
  bnsNames(params = {}) {
455
- return this.get("bns/names", buildQuery({
495
+ return this.requestPath("bns/names", buildQuery({
456
496
  namespace: params.namespace,
457
497
  owner: params.owner,
458
498
  limit: params.limit,
@@ -460,17 +500,40 @@ class Datasets extends BaseClient {
460
500
  }));
461
501
  }
462
502
  bnsNamespaces() {
463
- return this.get("bns/namespaces", "");
503
+ return this.requestPath("bns/namespaces", "");
464
504
  }
465
505
  bnsResolve(fqn) {
466
- return this.get("bns/resolve", buildQuery({ fqn }));
506
+ return this.requestPath("bns/resolve", buildQuery({ fqn }));
467
507
  }
468
508
  networkHealth() {
469
- return this.get("network-health/summary", "");
509
+ return this.requestPath("network-health/summary", "");
470
510
  }
471
- get(path, query) {
511
+ requestPath(path, query) {
472
512
  return this.request("GET", `/v1/datasets/${path}${query}`);
473
513
  }
514
+ async resolveDataset(slug) {
515
+ const cursor = CURSOR_SLUGS[slug];
516
+ if (cursor)
517
+ return { path: cursor.path, rowKey: cursor.rowKey };
518
+ const families = await this.loadCatalog();
519
+ const tail = catalogPathTail(slug);
520
+ const match = families.find((f) => f.family === slug || catalogPathTail(f.path) === tail);
521
+ if (!match) {
522
+ throw new Error(`unknown dataset "${slug}" (available: ${families.map((f) => f.family).join(", ")})`);
523
+ }
524
+ return { path: catalogPathTail(match.path), rowKey: match.row_key };
525
+ }
526
+ loadCatalog() {
527
+ this.catalogPromise ??= (async () => {
528
+ const raw = await this.listDatasets();
529
+ const families = raw.families;
530
+ if (!Array.isArray(families)) {
531
+ throw new Error("dataset catalog response missing families[]");
532
+ }
533
+ return families;
534
+ })();
535
+ return this.catalogPromise;
536
+ }
474
537
  paramsToQuery(params) {
475
538
  const mapped = {};
476
539
  for (const [k, v] of Object.entries(params)) {
@@ -482,7 +545,7 @@ class Datasets extends BaseClient {
482
545
  }
483
546
  cursorDataset(path, rowKey) {
484
547
  const list = async (params = {}) => {
485
- const envelope = await this.get(path, this.paramsToQuery(params));
548
+ const envelope = await this.requestPath(path, this.paramsToQuery(params));
486
549
  return {
487
550
  rows: envelope[rowKey] ?? [],
488
551
  next_cursor: envelope.next_cursor ?? null,
@@ -925,6 +988,31 @@ class Index extends BaseClient {
925
988
  }
926
989
  }
927
990
 
991
+ // src/projects/client.ts
992
+ class Projects extends BaseClient {
993
+ constructor(options = {}) {
994
+ super(options);
995
+ }
996
+ list() {
997
+ return this.request("GET", "/api/projects");
998
+ }
999
+ get(slug) {
1000
+ return this.request("GET", `/api/projects/${slug}`);
1001
+ }
1002
+ create(params) {
1003
+ return this.request("POST", "/api/projects", params);
1004
+ }
1005
+ update(slug, patch) {
1006
+ return this.request("PATCH", `/api/projects/${slug}`, patch);
1007
+ }
1008
+ delete(slug) {
1009
+ return this.request("DELETE", `/api/projects/${slug}`);
1010
+ }
1011
+ team(slug) {
1012
+ return this.request("GET", `/api/projects/${slug}/team`);
1013
+ }
1014
+ }
1015
+
928
1016
  // src/streams/client.ts
929
1017
  import { ed25519 as ed255192 } from "@secondlayer/shared";
930
1018
 
@@ -1603,6 +1691,7 @@ class SecondLayer extends BaseClient {
1603
1691
  subgraphs;
1604
1692
  subscriptions;
1605
1693
  apiKeys;
1694
+ projects;
1606
1695
  constructor(options = {}) {
1607
1696
  super(options);
1608
1697
  this.streams = createStreamsClient({
@@ -1616,15 +1705,26 @@ class SecondLayer extends BaseClient {
1616
1705
  this.subgraphs = new Subgraphs(options);
1617
1706
  this.subscriptions = new Subscriptions(options);
1618
1707
  this.apiKeys = new ApiKeys(options);
1708
+ this.projects = new Projects(options);
1619
1709
  }
1620
1710
  async context() {
1621
1711
  const safe = (p) => p.then((v) => v).catch(() => null);
1622
- const [account, streamsTip, indexEnv, subgraphsRes, subscriptionsRes] = await Promise.all([
1712
+ const [
1713
+ account,
1714
+ streamsTip,
1715
+ indexEnv,
1716
+ subgraphsRes,
1717
+ subscriptionsRes,
1718
+ projectsRes,
1719
+ apiKeysRes
1720
+ ] = await Promise.all([
1623
1721
  safe(this.request("GET", "/api/accounts/me")),
1624
1722
  safe(this.streams.tip()),
1625
1723
  safe(this.index.canonical.list({ limit: 1 })),
1626
1724
  safe(this.subgraphs.list()),
1627
- safe(this.subscriptions.list())
1725
+ safe(this.subscriptions.list()),
1726
+ safe(this.projects.list()),
1727
+ safe(this.apiKeys.list())
1628
1728
  ]);
1629
1729
  const subgraphs = subgraphsRes?.data ?? null;
1630
1730
  let subscriptions = null;
@@ -1650,12 +1750,25 @@ class SecondLayer extends BaseClient {
1650
1750
  }));
1651
1751
  activeOperations = probed.filter((o) => o !== null);
1652
1752
  }
1753
+ const projects = projectsRes ? projectsRes.projects.map((p) => ({
1754
+ name: p.name,
1755
+ slug: p.slug,
1756
+ network: p.network
1757
+ })) : null;
1758
+ const apiKeys = apiKeysRes ? apiKeysRes.keys.map((k) => ({
1759
+ prefix: k.prefix,
1760
+ name: k.name,
1761
+ status: k.status,
1762
+ product: k.product
1763
+ })) : null;
1653
1764
  return {
1654
1765
  account,
1655
1766
  streamsTip,
1656
1767
  indexTip: indexEnv?.tip ?? null,
1657
1768
  subgraphs,
1658
1769
  subscriptions,
1770
+ projects,
1771
+ apiKeys,
1659
1772
  activeOperations
1660
1773
  };
1661
1774
  }
@@ -1676,5 +1789,5 @@ export {
1676
1789
  Subgraphs
1677
1790
  };
1678
1791
 
1679
- //# debugId=5ECE26F86F9604DA64756E2164756E21
1792
+ //# debugId=9A541BEB19FD0E7964756E2164756E21
1680
1793
  //# sourceMappingURL=index.js.map