@secondlayer/sdk 0.4.1 → 0.6.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.
- package/README.md +97 -0
- package/dist/index.d.ts +25 -25
- package/dist/index.js +37 -30
- package/dist/index.js.map +9 -9
- package/dist/streams/index.js +10 -7
- package/dist/streams/index.js.map +4 -4
- package/dist/{views → subgraphs}/index.d.ts +25 -25
- package/dist/{views → subgraphs}/index.js +37 -30
- package/dist/subgraphs/index.js.map +16 -0
- package/package.json +10 -6
- package/dist/views/index.js.map +0 -16
package/README.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# @secondlayer/sdk
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for the Second Layer API.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @secondlayer/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { SecondLayer } from "@secondlayer/sdk";
|
|
15
|
+
|
|
16
|
+
const sl = new SecondLayer({
|
|
17
|
+
apiKey: "sk-sl_...", // or session token
|
|
18
|
+
baseUrl: "https://api.secondlayer.tools", // default
|
|
19
|
+
});
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Contracts
|
|
23
|
+
|
|
24
|
+
Search, inspect, and fetch ABIs for on-chain contracts.
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
// Search by name
|
|
28
|
+
const { contracts, total } = await sl.contracts.search("bns", { limit: 10, offset: 0 });
|
|
29
|
+
|
|
30
|
+
// Get contract detail
|
|
31
|
+
const contract = await sl.contracts.get("SP000000000000000000002Q6VF78.bns");
|
|
32
|
+
// { contractId, name, deployer, deployBlock, deployTxId, callCount, lastCalledAt, abi, ... }
|
|
33
|
+
|
|
34
|
+
// Fetch ABI (lazy-cached from Stacks node)
|
|
35
|
+
const abi = await sl.contracts.getAbi("SP000000000000000000002Q6VF78.bns");
|
|
36
|
+
// { functions: [...], maps: [...], variables: [...], ... }
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Streams
|
|
40
|
+
|
|
41
|
+
Manage real-time event streams with webhook delivery.
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
// Create
|
|
45
|
+
const { stream, webhookSecret } = await sl.streams.create({
|
|
46
|
+
name: "my-stream",
|
|
47
|
+
webhookUrl: "https://example.com/webhook",
|
|
48
|
+
filters: { type: "contract_call", contract_id: "SP...token" },
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// List
|
|
52
|
+
const { streams, total } = await sl.streams.list({ status: "active" });
|
|
53
|
+
|
|
54
|
+
// Get / Update / Delete
|
|
55
|
+
const stream = await sl.streams.get("stream-id");
|
|
56
|
+
await sl.streams.update("stream-id", { name: "renamed" });
|
|
57
|
+
await sl.streams.delete("stream-id");
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Views
|
|
61
|
+
|
|
62
|
+
Deploy and query materialized views.
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
// List
|
|
66
|
+
const { data } = await sl.views.list();
|
|
67
|
+
|
|
68
|
+
// Get
|
|
69
|
+
const view = await sl.views.get("my-view");
|
|
70
|
+
|
|
71
|
+
// Query table
|
|
72
|
+
const rows = await sl.views.queryTable("my-view", "transfers", {
|
|
73
|
+
sort: "block_height",
|
|
74
|
+
order: "desc",
|
|
75
|
+
limit: 50,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// Typed client (with defineView schema)
|
|
79
|
+
import myView from "./views/my-view";
|
|
80
|
+
const client = sl.views.typed(myView);
|
|
81
|
+
const rows = await client.transfers.findMany({ where: { sender: "SP..." } });
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Error Handling
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import { ApiError } from "@secondlayer/sdk";
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
await sl.contracts.get("nonexistent");
|
|
91
|
+
} catch (err) {
|
|
92
|
+
if (err instanceof ApiError) {
|
|
93
|
+
console.log(err.status); // 404
|
|
94
|
+
console.log(err.message); // "Contract not found"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
```
|
package/dist/index.d.ts
CHANGED
|
@@ -54,14 +54,14 @@ declare class Streams extends BaseClient {
|
|
|
54
54
|
pauseAll(): Promise<BulkPauseResponse>;
|
|
55
55
|
resumeAll(): Promise<BulkResumeResponse>;
|
|
56
56
|
}
|
|
57
|
-
import {
|
|
58
|
-
import {
|
|
59
|
-
import {
|
|
60
|
-
declare class
|
|
57
|
+
import { SubgraphSummary, SubgraphDetail, SubgraphQueryParams, ReindexResponse } from "@secondlayer/shared/schemas";
|
|
58
|
+
import { DeploySubgraphRequest, DeploySubgraphResponse } from "@secondlayer/shared/schemas/subgraphs";
|
|
59
|
+
import { InferSubgraphClient } from "@secondlayer/subgraphs";
|
|
60
|
+
declare class Subgraphs extends BaseClient {
|
|
61
61
|
list(): Promise<{
|
|
62
|
-
data:
|
|
62
|
+
data: SubgraphSummary[]
|
|
63
63
|
}>;
|
|
64
|
-
get(name: string): Promise<
|
|
64
|
+
get(name: string): Promise<SubgraphDetail>;
|
|
65
65
|
reindex(name: string, options?: {
|
|
66
66
|
fromBlock?: number
|
|
67
67
|
toBlock?: number
|
|
@@ -69,55 +69,55 @@ declare class Views extends BaseClient {
|
|
|
69
69
|
delete(name: string): Promise<{
|
|
70
70
|
message: string
|
|
71
71
|
}>;
|
|
72
|
-
deploy(data:
|
|
73
|
-
queryTable(name: string, table: string, params?:
|
|
74
|
-
queryTableCount(name: string, table: string, params?:
|
|
72
|
+
deploy(data: DeploySubgraphRequest): Promise<DeploySubgraphResponse>;
|
|
73
|
+
queryTable(name: string, table: string, params?: SubgraphQueryParams): Promise<unknown[]>;
|
|
74
|
+
queryTableCount(name: string, table: string, params?: SubgraphQueryParams): Promise<{
|
|
75
75
|
count: number
|
|
76
76
|
}>;
|
|
77
77
|
/**
|
|
78
|
-
* Returns a typed client for a
|
|
79
|
-
* Row types are inferred from the
|
|
78
|
+
* Returns a typed client for a subgraph defined with `defineSubgraph()`.
|
|
79
|
+
* Row types are inferred from the subgraph's schema literal types.
|
|
80
80
|
*
|
|
81
81
|
* @example
|
|
82
82
|
* ```ts
|
|
83
|
-
* import
|
|
84
|
-
* const client = sl.
|
|
83
|
+
* import mySubgraph from './subgraphs/my-token-subgraph'
|
|
84
|
+
* const client = sl.subgraphs.typed(mySubgraph)
|
|
85
85
|
* const rows = await client.transfers.findMany({ where: { sender: 'SP...' } })
|
|
86
|
-
* // rows: InferTableRow<typeof
|
|
86
|
+
* // rows: InferTableRow<typeof mySubgraph.schema.transfers>[]
|
|
87
87
|
* ```
|
|
88
88
|
*/
|
|
89
89
|
typed<T extends {
|
|
90
90
|
name: string
|
|
91
91
|
schema: Record<string, unknown>
|
|
92
|
-
}>(def: T):
|
|
92
|
+
}>(def: T): InferSubgraphClient<T>;
|
|
93
93
|
private createTableClient;
|
|
94
94
|
}
|
|
95
|
-
import {
|
|
95
|
+
import { InferSubgraphClient as InferSubgraphClient2 } from "@secondlayer/subgraphs";
|
|
96
96
|
import { QueueStats } from "@secondlayer/shared/types";
|
|
97
97
|
declare class SecondLayer extends BaseClient {
|
|
98
98
|
readonly streams: Streams;
|
|
99
|
-
readonly
|
|
99
|
+
readonly subgraphs: Subgraphs;
|
|
100
100
|
constructor(options?: Partial<SecondLayerOptions>);
|
|
101
101
|
getQueueStats(): Promise<QueueStats>;
|
|
102
102
|
}
|
|
103
103
|
/**
|
|
104
|
-
* Returns a typed client for a
|
|
104
|
+
* Returns a typed client for a subgraph defined with `defineSubgraph()`.
|
|
105
105
|
*
|
|
106
|
-
* Accepts a plain options object, a `SecondLayer` instance, or a `
|
|
106
|
+
* Accepts a plain options object, a `SecondLayer` instance, or a `Subgraphs` instance.
|
|
107
107
|
*
|
|
108
108
|
* @example
|
|
109
109
|
* ```ts
|
|
110
|
-
* import
|
|
111
|
-
* import {
|
|
110
|
+
* import mySubgraph from './subgraphs/my-subgraph'
|
|
111
|
+
* import { getSubgraph } from '@secondlayer/sdk'
|
|
112
112
|
*
|
|
113
|
-
* const client =
|
|
113
|
+
* const client = getSubgraph(mySubgraph, { apiKey: 'sl_...' })
|
|
114
114
|
* const rows = await client.transfers.findMany({ where: { sender: 'SP...' } })
|
|
115
115
|
* ```
|
|
116
116
|
*/
|
|
117
|
-
declare function
|
|
117
|
+
declare function getSubgraph<T extends {
|
|
118
118
|
name: string
|
|
119
119
|
schema: Record<string, unknown>
|
|
120
|
-
}>(def: T, options?: Partial<SecondLayerOptions> | SecondLayer |
|
|
120
|
+
}>(def: T, options?: Partial<SecondLayerOptions> | SecondLayer | Subgraphs): InferSubgraphClient2<T>;
|
|
121
121
|
/**
|
|
122
122
|
* Error thrown by {@link SecondLayer} when an API request fails.
|
|
123
123
|
* Includes the HTTP status code for programmatic error handling.
|
|
@@ -138,4 +138,4 @@ declare class ApiError extends Error {
|
|
|
138
138
|
status: number;
|
|
139
139
|
constructor(status: number, message: string);
|
|
140
140
|
}
|
|
141
|
-
export {
|
|
141
|
+
export { getSubgraph, Subgraphs, Streams, SecondLayerOptions, SecondLayer, ApiError };
|
package/dist/index.js
CHANGED
|
@@ -54,7 +54,12 @@ class BaseClient {
|
|
|
54
54
|
let message = `HTTP ${response.status}`;
|
|
55
55
|
try {
|
|
56
56
|
const json = JSON.parse(errorBody);
|
|
57
|
-
|
|
57
|
+
const err = json.error ?? json.message;
|
|
58
|
+
if (typeof err === "string") {
|
|
59
|
+
message = err;
|
|
60
|
+
} else if (err && typeof err === "object") {
|
|
61
|
+
message = JSON.stringify(err);
|
|
62
|
+
}
|
|
58
63
|
} catch {
|
|
59
64
|
if (errorBody)
|
|
60
65
|
message = errorBody;
|
|
@@ -79,8 +84,7 @@ class Streams extends BaseClient {
|
|
|
79
84
|
return partialId;
|
|
80
85
|
}
|
|
81
86
|
const { streams } = await this.list();
|
|
82
|
-
const
|
|
83
|
-
const matches = typedStreams.filter((s) => s.id.startsWith(partialId));
|
|
87
|
+
const matches = streams.filter((s) => s.id.startsWith(partialId));
|
|
84
88
|
if (matches.length === 0) {
|
|
85
89
|
throw new ApiError(404, `No stream found matching "${partialId}"`);
|
|
86
90
|
}
|
|
@@ -97,8 +101,7 @@ class Streams extends BaseClient {
|
|
|
97
101
|
}
|
|
98
102
|
async updateByName(name, data) {
|
|
99
103
|
const { streams } = await this.list();
|
|
100
|
-
const
|
|
101
|
-
const existing = typedStreams.find((s) => s.name === name);
|
|
104
|
+
const existing = streams.find((s) => s.name === name);
|
|
102
105
|
if (!existing) {
|
|
103
106
|
throw new ApiError(404, `Stream with name "${name}" not found`);
|
|
104
107
|
}
|
|
@@ -129,7 +132,7 @@ class Streams extends BaseClient {
|
|
|
129
132
|
}
|
|
130
133
|
async listDeliveries(id, params) {
|
|
131
134
|
const qs = new URLSearchParams;
|
|
132
|
-
if (params?.limit)
|
|
135
|
+
if (params?.limit !== undefined)
|
|
133
136
|
qs.set("limit", String(params.limit));
|
|
134
137
|
if (params?.status)
|
|
135
138
|
qs.set("status", params.status);
|
|
@@ -147,7 +150,7 @@ class Streams extends BaseClient {
|
|
|
147
150
|
return this.request("POST", "/api/streams/resume");
|
|
148
151
|
}
|
|
149
152
|
}
|
|
150
|
-
// src/
|
|
153
|
+
// src/subgraphs/serialize.ts
|
|
151
154
|
var SYSTEM_COLUMN_MAP = {
|
|
152
155
|
_blockHeight: "_block_height",
|
|
153
156
|
_txId: "_tx_id",
|
|
@@ -188,8 +191,8 @@ function resolveOrderByColumn(col) {
|
|
|
188
191
|
return resolveColumn(col);
|
|
189
192
|
}
|
|
190
193
|
|
|
191
|
-
// src/
|
|
192
|
-
function
|
|
194
|
+
// src/subgraphs/client.ts
|
|
195
|
+
function buildSubgraphQueryString(params) {
|
|
193
196
|
const qs = new URLSearchParams;
|
|
194
197
|
if (params.sort)
|
|
195
198
|
qs.set("_sort", params.sort);
|
|
@@ -210,27 +213,27 @@ function buildViewQueryString(params) {
|
|
|
210
213
|
return str ? `?${str}` : "";
|
|
211
214
|
}
|
|
212
215
|
|
|
213
|
-
class
|
|
216
|
+
class Subgraphs extends BaseClient {
|
|
214
217
|
async list() {
|
|
215
|
-
return this.request("GET", "/api/
|
|
218
|
+
return this.request("GET", "/api/subgraphs");
|
|
216
219
|
}
|
|
217
220
|
async get(name) {
|
|
218
|
-
return this.request("GET", `/api/
|
|
221
|
+
return this.request("GET", `/api/subgraphs/${name}`);
|
|
219
222
|
}
|
|
220
223
|
async reindex(name, options) {
|
|
221
|
-
return this.request("POST", `/api/
|
|
224
|
+
return this.request("POST", `/api/subgraphs/${name}/reindex`, options);
|
|
222
225
|
}
|
|
223
226
|
async delete(name) {
|
|
224
|
-
return this.request("DELETE", `/api/
|
|
227
|
+
return this.request("DELETE", `/api/subgraphs/${name}`);
|
|
225
228
|
}
|
|
226
229
|
async deploy(data) {
|
|
227
|
-
return this.request("POST", "/api/
|
|
230
|
+
return this.request("POST", "/api/subgraphs", data);
|
|
228
231
|
}
|
|
229
232
|
async queryTable(name, table, params = {}) {
|
|
230
|
-
return this.request("GET", `/api/
|
|
233
|
+
return this.request("GET", `/api/subgraphs/${name}/${table}${buildSubgraphQueryString(params)}`);
|
|
231
234
|
}
|
|
232
235
|
async queryTableCount(name, table, params = {}) {
|
|
233
|
-
return this.request("GET", `/api/
|
|
236
|
+
return this.request("GET", `/api/subgraphs/${name}/${table}/count${buildSubgraphQueryString(params)}`);
|
|
234
237
|
}
|
|
235
238
|
typed(def) {
|
|
236
239
|
const result = {};
|
|
@@ -239,7 +242,7 @@ class Views extends BaseClient {
|
|
|
239
242
|
}
|
|
240
243
|
return result;
|
|
241
244
|
}
|
|
242
|
-
createTableClient(
|
|
245
|
+
createTableClient(subgraphName, tableName) {
|
|
243
246
|
const self = this;
|
|
244
247
|
return {
|
|
245
248
|
async findMany(options = {}) {
|
|
@@ -249,6 +252,10 @@ class Views extends BaseClient {
|
|
|
249
252
|
if (options.orderBy) {
|
|
250
253
|
const entries = Object.entries(options.orderBy);
|
|
251
254
|
if (entries.length > 0) {
|
|
255
|
+
if (entries.length > 1) {
|
|
256
|
+
const extra = entries.slice(1).map(([col2]) => col2).join(", ");
|
|
257
|
+
throw new Error(`orderBy supports only one column; remove extra keys: ${extra}`);
|
|
258
|
+
}
|
|
252
259
|
const [col, dir] = entries[0];
|
|
253
260
|
sort = resolveOrderByColumn(col);
|
|
254
261
|
order = dir ?? "asc";
|
|
@@ -262,11 +269,11 @@ class Views extends BaseClient {
|
|
|
262
269
|
fields: options.fields?.join(","),
|
|
263
270
|
filters
|
|
264
271
|
};
|
|
265
|
-
return self.queryTable(
|
|
272
|
+
return self.queryTable(subgraphName, tableName, params);
|
|
266
273
|
},
|
|
267
274
|
async count(where) {
|
|
268
275
|
const filters = where ? serializeWhere(where) : undefined;
|
|
269
|
-
const result = await self.queryTableCount(
|
|
276
|
+
const result = await self.queryTableCount(subgraphName, tableName, { filters });
|
|
270
277
|
return result.count;
|
|
271
278
|
}
|
|
272
279
|
};
|
|
@@ -275,11 +282,11 @@ class Views extends BaseClient {
|
|
|
275
282
|
// src/client.ts
|
|
276
283
|
class SecondLayer extends BaseClient {
|
|
277
284
|
streams;
|
|
278
|
-
|
|
285
|
+
subgraphs;
|
|
279
286
|
constructor(options = {}) {
|
|
280
287
|
super(options);
|
|
281
288
|
this.streams = new Streams(options);
|
|
282
|
-
this.
|
|
289
|
+
this.subgraphs = new Subgraphs(options);
|
|
283
290
|
}
|
|
284
291
|
async getQueueStats() {
|
|
285
292
|
const status = await this.request("GET", "/status");
|
|
@@ -287,23 +294,23 @@ class SecondLayer extends BaseClient {
|
|
|
287
294
|
}
|
|
288
295
|
}
|
|
289
296
|
|
|
290
|
-
// src/
|
|
291
|
-
function
|
|
292
|
-
if (options instanceof
|
|
297
|
+
// src/subgraphs/get-subgraph.ts
|
|
298
|
+
function getSubgraph(def, options = {}) {
|
|
299
|
+
if (options instanceof Subgraphs) {
|
|
293
300
|
return options.typed(def);
|
|
294
301
|
}
|
|
295
302
|
if (options instanceof SecondLayer) {
|
|
296
|
-
return options.
|
|
303
|
+
return options.subgraphs.typed(def);
|
|
297
304
|
}
|
|
298
|
-
return new
|
|
305
|
+
return new Subgraphs(options).typed(def);
|
|
299
306
|
}
|
|
300
307
|
export {
|
|
301
|
-
|
|
302
|
-
|
|
308
|
+
getSubgraph,
|
|
309
|
+
Subgraphs,
|
|
303
310
|
Streams,
|
|
304
311
|
SecondLayer,
|
|
305
312
|
ApiError
|
|
306
313
|
};
|
|
307
314
|
|
|
308
|
-
//# debugId=
|
|
315
|
+
//# debugId=90B4B3D52C6B85BE64756E2164756E21
|
|
309
316
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/errors.ts", "../src/base.ts", "../src/streams/client.ts", "../src/
|
|
3
|
+
"sources": ["../src/errors.ts", "../src/base.ts", "../src/streams/client.ts", "../src/subgraphs/serialize.ts", "../src/subgraphs/client.ts", "../src/client.ts", "../src/subgraphs/get-subgraph.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"/**\n * Error thrown by {@link SecondLayer} when an API request fails.\n * Includes the HTTP status code for programmatic error handling.\n *\n * @example\n * ```ts\n * try {\n * await client.streams.get(\"abc123\");\n * } catch (err) {\n * if (err instanceof ApiError && err.status === 404) {\n * console.log(\"Stream not found\");\n * }\n * }\n * ```\n */\nexport class ApiError extends Error {\n constructor(\n /** HTTP status code (0 for network errors). */\n public status: number,\n message: string\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n}\n",
|
|
6
|
-
"import { ApiError } from \"./errors.ts\";\n\nexport interface SecondLayerOptions {\n /** Base URL of the Secondlayer API (trailing slashes are stripped). */\n baseUrl: string;\n /** Bearer token for authenticated requests. */\n apiKey?: string;\n}\n\nconst DEFAULT_BASE_URL = \"https://api.secondlayer.tools\";\n\nexport abstract class BaseClient {\n protected baseUrl: string;\n protected apiKey?: string;\n\n constructor(options: Partial<SecondLayerOptions> = {}) {\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.apiKey = options.apiKey;\n }\n\n static authHeaders(apiKey?: string): Record<string, string> {\n const headers: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (apiKey) {\n headers[\"Authorization\"] = `Bearer ${apiKey}`;\n }\n return headers;\n }\n\n protected async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const headers = BaseClient.authHeaders(this.apiKey);\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n } catch {\n throw new ApiError(0, `Cannot reach API at ${this.baseUrl}. Check your connection or try again.`);\n }\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new ApiError(401, \"API key invalid or expired.\");\n }\n\n if (response.status === 429) {\n const retryAfter = response.headers.get(\"Retry-After\");\n const msg = retryAfter\n ? `Rate limited. Wait ${retryAfter} seconds.`\n : \"Rate limited. Try again later.\";\n throw new ApiError(429, msg);\n }\n\n if (response.status >= 500) {\n throw new ApiError(response.status, `Server error. Try again or check status at ${this.baseUrl}/health`);\n }\n\n const errorBody = await response.text();\n let message = `HTTP ${response.status}`;\n try {\n const json = JSON.parse(errorBody);\n
|
|
7
|
-
"import type {\n CreateStream,\n UpdateStream,\n StreamResponse,\n CreateStreamResponse,\n ListStreamsResponse,\n BulkPauseResponse,\n BulkResumeResponse,\n} from \"@secondlayer/shared/schemas\";\nimport { ApiError } from \"../errors.ts\";\nimport { BaseClient } from \"../base.ts\";\n\nexport interface DeliverySummary {\n id: string;\n blockHeight: number;\n status: string;\n statusCode: number | null;\n responseTimeMs: number | null;\n attempts: number;\n error: string | null;\n createdAt: string;\n}\n\nexport interface DeliveryDetail extends DeliverySummary {\n payload: unknown;\n}\n\nexport interface DeliveriesResponse {\n deliveries: DeliverySummary[];\n}\n\nexport class Streams extends BaseClient {\n private async requestWithStreamId<T>(\n method: string,\n pathTemplate: (id: string) => string,\n id: string,\n body?: unknown\n ): Promise<T> {\n const fullId = await this.resolveStreamId(id);\n return this.request<T>(method, pathTemplate(fullId), body);\n }\n\n async resolveStreamId(partialId: string): Promise<string> {\n if (partialId.length === 36 && partialId.includes(\"-\")) {\n return partialId;\n }\n\n const { streams } = await this.list();\n const
|
|
8
|
-
"/**\n * Maps camelCase system column names (with or without `_` prefix) to the\n * actual snake_case DB column names used in query params.\n */\nconst SYSTEM_COLUMN_MAP: Record<string, string> = {\n // underscore-prefixed camelCase (canonical row shape)\n _blockHeight: \"_block_height\",\n _txId: \"_tx_id\",\n _createdAt: \"_created_at\",\n _id: \"_id\",\n // no-prefix aliases\n blockHeight: \"_block_height\",\n txId: \"_tx_id\",\n createdAt: \"_created_at\",\n id: \"_id\",\n};\n\nfunction resolveColumn(col: string): string {\n return SYSTEM_COLUMN_MAP[col] ?? col;\n}\n\n/**\n * Serializes a WhereInput object into the flat filter map expected by\n *
|
|
9
|
-
"import type {\n
|
|
10
|
-
"import type { QueueStats } from \"@secondlayer/shared/types\";\nimport { BaseClient } from \"./base.ts\";\nimport type { SecondLayerOptions } from \"./base.ts\";\nimport { Streams } from \"./streams/client.ts\";\nimport {
|
|
11
|
-
"import type {
|
|
6
|
+
"import { ApiError } from \"./errors.ts\";\n\nexport interface SecondLayerOptions {\n /** Base URL of the Secondlayer API (trailing slashes are stripped). */\n baseUrl: string;\n /** Bearer token for authenticated requests. */\n apiKey?: string;\n}\n\nconst DEFAULT_BASE_URL = \"https://api.secondlayer.tools\";\n\nexport abstract class BaseClient {\n protected baseUrl: string;\n protected apiKey?: string;\n\n constructor(options: Partial<SecondLayerOptions> = {}) {\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.apiKey = options.apiKey;\n }\n\n static authHeaders(apiKey?: string): Record<string, string> {\n const headers: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (apiKey) {\n headers[\"Authorization\"] = `Bearer ${apiKey}`;\n }\n return headers;\n }\n\n protected async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const headers = BaseClient.authHeaders(this.apiKey);\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n } catch {\n throw new ApiError(0, `Cannot reach API at ${this.baseUrl}. Check your connection or try again.`);\n }\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new ApiError(401, \"API key invalid or expired.\");\n }\n\n if (response.status === 429) {\n const retryAfter = response.headers.get(\"Retry-After\");\n const msg = retryAfter\n ? `Rate limited. Wait ${retryAfter} seconds.`\n : \"Rate limited. Try again later.\";\n throw new ApiError(429, msg);\n }\n\n if (response.status >= 500) {\n throw new ApiError(response.status, `Server error. Try again or check status at ${this.baseUrl}/health`);\n }\n\n const errorBody = await response.text();\n let message = `HTTP ${response.status}`;\n try {\n const json = JSON.parse(errorBody);\n const err = json.error ?? json.message;\n if (typeof err === \"string\") {\n message = err;\n } else if (err && typeof err === \"object\") {\n message = JSON.stringify(err);\n }\n } catch {\n if (errorBody) message = errorBody;\n }\n throw new ApiError(response.status, message);\n }\n\n if (response.status === 204) {\n return undefined as T;\n }\n\n return response.json() as Promise<T>;\n }\n}\n",
|
|
7
|
+
"import type {\n CreateStream,\n UpdateStream,\n StreamResponse,\n CreateStreamResponse,\n ListStreamsResponse,\n BulkPauseResponse,\n BulkResumeResponse,\n} from \"@secondlayer/shared/schemas\";\nimport { ApiError } from \"../errors.ts\";\nimport { BaseClient } from \"../base.ts\";\n\nexport interface DeliverySummary {\n id: string;\n blockHeight: number;\n status: string;\n statusCode: number | null;\n responseTimeMs: number | null;\n attempts: number;\n error: string | null;\n createdAt: string;\n}\n\nexport interface DeliveryDetail extends DeliverySummary {\n payload: unknown;\n}\n\nexport interface DeliveriesResponse {\n deliveries: DeliverySummary[];\n}\n\nexport class Streams extends BaseClient {\n private async requestWithStreamId<T>(\n method: string,\n pathTemplate: (id: string) => string,\n id: string,\n body?: unknown\n ): Promise<T> {\n const fullId = await this.resolveStreamId(id);\n return this.request<T>(method, pathTemplate(fullId), body);\n }\n\n async resolveStreamId(partialId: string): Promise<string> {\n if (partialId.length === 36 && partialId.includes(\"-\")) {\n return partialId;\n }\n\n const { streams } = await this.list();\n const matches = streams.filter((s) => s.id.startsWith(partialId));\n\n if (matches.length === 0) {\n throw new ApiError(404, `No stream found matching \"${partialId}\"`);\n }\n if (matches.length > 1) {\n throw new ApiError(400, `Multiple streams match \"${partialId}\": ${matches.map((s) => s.id.slice(0, 8)).join(\", \")}`);\n }\n\n return matches[0]!.id;\n }\n\n async create(data: CreateStream): Promise<CreateStreamResponse> {\n return this.request<CreateStreamResponse>(\"POST\", \"/api/streams\", data);\n }\n\n async update(id: string, data: UpdateStream): Promise<StreamResponse> {\n return this.requestWithStreamId(\"PATCH\", (id) => `/api/streams/${id}`, id, data);\n }\n\n async updateByName(name: string, data: CreateStream): Promise<StreamResponse> {\n const { streams } = await this.list();\n const existing = streams.find((s) => s.name === name);\n if (!existing) {\n throw new ApiError(404, `Stream with name \"${name}\" not found`);\n }\n return this.update(existing.id, data);\n }\n\n async list(params?: { status?: string }): Promise<ListStreamsResponse> {\n const searchParams = new URLSearchParams();\n if (params?.status) searchParams.set(\"status\", params.status);\n const query = searchParams.toString();\n const path = query ? `/api/streams?${query}` : \"/api/streams\";\n return this.request<ListStreamsResponse>(\"GET\", path);\n }\n\n async get(id: string): Promise<StreamResponse> {\n return this.requestWithStreamId(\"GET\", (id) => `/api/streams/${id}`, id);\n }\n\n async delete(id: string): Promise<void> {\n return this.requestWithStreamId(\"DELETE\", (id) => `/api/streams/${id}`, id);\n }\n\n async enable(id: string): Promise<StreamResponse> {\n return this.requestWithStreamId(\"POST\", (id) => `/api/streams/${id}/enable`, id);\n }\n\n async disable(id: string): Promise<StreamResponse> {\n return this.requestWithStreamId(\"POST\", (id) => `/api/streams/${id}/disable`, id);\n }\n\n async rotateSecret(id: string): Promise<{ secret: string }> {\n return this.requestWithStreamId(\"POST\", (id) => `/api/streams/${id}/rotate-secret`, id);\n }\n\n // ── Deliveries ─────────────────────────────────────────────────────\n\n /** List recent deliveries for a stream. */\n async listDeliveries(id: string, params?: { limit?: number; status?: string }): Promise<DeliveriesResponse> {\n const qs = new URLSearchParams();\n if (params?.limit !== undefined) qs.set(\"limit\", String(params.limit));\n if (params?.status) qs.set(\"status\", params.status);\n const query = qs.toString();\n return this.requestWithStreamId(\"GET\", (id) => `/api/streams/${id}/deliveries${query ? `?${query}` : \"\"}`, id);\n }\n\n /** Get a single delivery with full payload. */\n async getDelivery(streamId: string, deliveryId: string): Promise<DeliveryDetail> {\n const fullId = await this.resolveStreamId(streamId);\n return this.request<DeliveryDetail>(\"GET\", `/api/streams/${fullId}/deliveries/${deliveryId}`);\n }\n\n async pauseAll(): Promise<BulkPauseResponse> {\n return this.request<BulkPauseResponse>(\"POST\", \"/api/streams/pause\");\n }\n\n async resumeAll(): Promise<BulkResumeResponse> {\n return this.request<BulkResumeResponse>(\"POST\", \"/api/streams/resume\");\n }\n}\n",
|
|
8
|
+
"/**\n * Maps camelCase system column names (with or without `_` prefix) to the\n * actual snake_case DB column names used in query params.\n */\nconst SYSTEM_COLUMN_MAP: Record<string, string> = {\n // underscore-prefixed camelCase (canonical row shape)\n _blockHeight: \"_block_height\",\n _txId: \"_tx_id\",\n _createdAt: \"_created_at\",\n _id: \"_id\",\n // no-prefix aliases\n blockHeight: \"_block_height\",\n txId: \"_tx_id\",\n createdAt: \"_created_at\",\n id: \"_id\",\n};\n\nfunction resolveColumn(col: string): string {\n return SYSTEM_COLUMN_MAP[col] ?? col;\n}\n\n/**\n * Serializes a WhereInput object into the flat filter map expected by\n * SubgraphQueryParams.filters (and the REST API query string).\n *\n * Scalar values → `{ column: \"value\" }`\n * Comparison objects → `{ \"column.gte\": \"100\", \"column.lt\": \"200\" }`\n * System column aliases → `blockHeight` / `_blockHeight` both → `_block_height`\n */\nexport function serializeWhere(\n where: Record<string, unknown>,\n): Record<string, string> {\n const filters: Record<string, string> = {};\n\n for (const [column, value] of Object.entries(where)) {\n if (value === null || value === undefined) continue;\n\n const col = resolveColumn(column);\n\n if (typeof value === \"object\" && !Array.isArray(value)) {\n const ops = value as Record<string, unknown>;\n for (const [op, opValue] of Object.entries(ops)) {\n if (opValue === null || opValue === undefined) continue;\n if (op === \"eq\") {\n filters[col] = String(opValue);\n } else if ([\"neq\", \"gt\", \"gte\", \"lt\", \"lte\"].includes(op)) {\n filters[`${col}.${op}`] = String(opValue);\n }\n }\n } else {\n filters[col] = String(value);\n }\n }\n\n return filters;\n}\n\n/**\n * Resolves an orderBy column name (either alias or canonical) to the DB column name.\n */\nexport function resolveOrderByColumn(col: string): string {\n return resolveColumn(col);\n}\n",
|
|
9
|
+
"import type {\n SubgraphSummary,\n SubgraphDetail,\n SubgraphQueryParams,\n ReindexResponse,\n} from \"@secondlayer/shared/schemas\";\nimport type { DeploySubgraphRequest, DeploySubgraphResponse } from \"@secondlayer/shared/schemas/subgraphs\";\nimport type {\n InferSubgraphClient,\n FindManyOptions,\n WhereInput,\n} from \"@secondlayer/subgraphs\";\nimport { BaseClient } from \"../base.ts\";\nimport { serializeWhere, resolveOrderByColumn } from \"./serialize.ts\";\n\nfunction buildSubgraphQueryString(params: SubgraphQueryParams): string {\n const qs = new URLSearchParams();\n if (params.sort) qs.set(\"_sort\", params.sort);\n if (params.order) qs.set(\"_order\", params.order);\n if (params.limit !== undefined) qs.set(\"_limit\", String(params.limit));\n if (params.offset !== undefined) qs.set(\"_offset\", String(params.offset));\n if (params.fields) qs.set(\"_fields\", params.fields);\n if (params.filters) {\n for (const [key, value] of Object.entries(params.filters)) {\n qs.set(key, String(value));\n }\n }\n const str = qs.toString();\n return str ? `?${str}` : \"\";\n}\n\nexport class Subgraphs extends BaseClient {\n async list(): Promise<{ data: SubgraphSummary[] }> {\n return this.request<{ data: SubgraphSummary[] }>(\"GET\", \"/api/subgraphs\");\n }\n\n async get(name: string): Promise<SubgraphDetail> {\n return this.request<SubgraphDetail>(\"GET\", `/api/subgraphs/${name}`);\n }\n\n async reindex(name: string, options?: { fromBlock?: number; toBlock?: number }): Promise<ReindexResponse> {\n return this.request<ReindexResponse>(\"POST\", `/api/subgraphs/${name}/reindex`, options);\n }\n\n async delete(name: string): Promise<{ message: string }> {\n return this.request<{ message: string }>(\"DELETE\", `/api/subgraphs/${name}`);\n }\n\n async deploy(data: DeploySubgraphRequest): Promise<DeploySubgraphResponse> {\n return this.request<DeploySubgraphResponse>(\"POST\", \"/api/subgraphs\", data);\n }\n\n async queryTable(name: string, table: string, params: SubgraphQueryParams = {}): Promise<unknown[]> {\n return this.request<unknown[]>(\"GET\", `/api/subgraphs/${name}/${table}${buildSubgraphQueryString(params)}`);\n }\n\n async queryTableCount(name: string, table: string, params: SubgraphQueryParams = {}): Promise<{ count: number }> {\n return this.request<{ count: number }>(\"GET\", `/api/subgraphs/${name}/${table}/count${buildSubgraphQueryString(params)}`);\n }\n\n /**\n * Returns a typed client for a subgraph defined with `defineSubgraph()`.\n * Row types are inferred from the subgraph's schema literal types.\n *\n * @example\n * ```ts\n * import mySubgraph from './subgraphs/my-token-subgraph'\n * const client = sl.subgraphs.typed(mySubgraph)\n * const rows = await client.transfers.findMany({ where: { sender: 'SP...' } })\n * // rows: InferTableRow<typeof mySubgraph.schema.transfers>[]\n * ```\n */\n typed<T extends { name: string; schema: Record<string, unknown> }>(\n def: T,\n ): InferSubgraphClient<T> {\n const result: Record<string, unknown> = {};\n\n for (const tableName of Object.keys(def.schema)) {\n result[tableName] = this.createTableClient(def.name, tableName);\n }\n\n return result as InferSubgraphClient<T>;\n }\n\n private createTableClient(subgraphName: string, tableName: string) {\n const self = this;\n\n return {\n async findMany<TRow>(options: FindManyOptions<TRow> = {}): Promise<TRow[]> {\n const filters = options.where\n ? serializeWhere(options.where as Record<string, unknown>)\n : undefined;\n\n let sort: string | undefined;\n let order: string | undefined;\n if (options.orderBy) {\n const entries = Object.entries(options.orderBy) as [string, \"asc\" | \"desc\"][];\n if (entries.length > 0) {\n if (entries.length > 1) {\n const extra = entries.slice(1).map(([col]) => col).join(\", \");\n throw new Error(`orderBy supports only one column; remove extra keys: ${extra}`);\n }\n const [col, dir] = entries[0]!;\n sort = resolveOrderByColumn(col);\n order = dir ?? \"asc\";\n }\n }\n\n const params: SubgraphQueryParams = {\n sort,\n order,\n limit: options.limit,\n offset: options.offset,\n fields: options.fields?.join(\",\"),\n filters,\n };\n\n return self.queryTable(subgraphName, tableName, params) as Promise<TRow[]>;\n },\n\n async count<TRow>(where?: WhereInput<TRow>): Promise<number> {\n const filters = where\n ? serializeWhere(where as Record<string, unknown>)\n : undefined;\n\n const result = await self.queryTableCount(subgraphName, tableName, { filters });\n return result.count;\n },\n };\n }\n}\n",
|
|
10
|
+
"import type { QueueStats } from \"@secondlayer/shared/types\";\nimport { BaseClient } from \"./base.ts\";\nimport type { SecondLayerOptions } from \"./base.ts\";\nimport { Streams } from \"./streams/client.ts\";\nimport { Subgraphs } from \"./subgraphs/client.ts\";\n\nexport class SecondLayer extends BaseClient {\n readonly streams: Streams;\n readonly subgraphs: Subgraphs;\n\n constructor(options: Partial<SecondLayerOptions> = {}) {\n super(options);\n this.streams = new Streams(options);\n this.subgraphs = new Subgraphs(options);\n }\n\n async getQueueStats(): Promise<QueueStats> {\n const status = await this.request<{ queue: QueueStats }>(\"GET\", \"/status\");\n return status.queue;\n }\n}\n",
|
|
11
|
+
"import type { InferSubgraphClient } from \"@secondlayer/subgraphs\";\nimport type { SecondLayerOptions } from \"../base.ts\";\nimport { SecondLayer } from \"../client.ts\";\nimport { Subgraphs } from \"./client.ts\";\n\n/**\n * Returns a typed client for a subgraph defined with `defineSubgraph()`.\n *\n * Accepts a plain options object, a `SecondLayer` instance, or a `Subgraphs` instance.\n *\n * @example\n * ```ts\n * import mySubgraph from './subgraphs/my-subgraph'\n * import { getSubgraph } from '@secondlayer/sdk'\n *\n * const client = getSubgraph(mySubgraph, { apiKey: 'sl_...' })\n * const rows = await client.transfers.findMany({ where: { sender: 'SP...' } })\n * ```\n */\nexport function getSubgraph<T extends { name: string; schema: Record<string, unknown> }>(\n def: T,\n options: Partial<SecondLayerOptions> | SecondLayer | Subgraphs = {},\n): InferSubgraphClient<T> {\n if (options instanceof Subgraphs) {\n return options.typed(def);\n }\n if (options instanceof SecondLayer) {\n return options.subgraphs.typed(def);\n }\n return new Subgraphs(options).typed(def);\n}\n"
|
|
12
12
|
],
|
|
13
|
-
"mappings": ";AAeO,MAAM,iBAAiB,MAAM;AAAA,EAGzB;AAAA,EAFT,WAAW,CAEF,QACP,SACA;AAAA,IACA,MAAM,OAAO;AAAA,IAHN;AAAA,IAIP,KAAK,OAAO;AAAA;AAEhB;;;ACfA,IAAM,mBAAmB;AAAA;AAElB,MAAe,WAAW;AAAA,EACrB;AAAA,EACA;AAAA,EAEV,WAAW,CAAC,UAAuC,CAAC,GAAG;AAAA,IACrD,KAAK,WAAW,QAAQ,WAAW,kBAAkB,QAAQ,QAAQ,EAAE;AAAA,IACvE,KAAK,SAAS,QAAQ;AAAA;AAAA,SAGjB,WAAW,CAAC,QAAyC;AAAA,IAC1D,MAAM,UAAkC,EAAE,gBAAgB,mBAAmB;AAAA,IAC7E,IAAI,QAAQ;AAAA,MACV,QAAQ,mBAAmB,UAAU;AAAA,IACvC;AAAA,IACA,OAAO;AAAA;AAAA,OAGO,QAAU,CAAC,QAAgB,MAAc,MAA4B;AAAA,IACnF,MAAM,MAAM,GAAG,KAAK,UAAU;AAAA,IAC9B,MAAM,UAAU,WAAW,YAAY,KAAK,MAAM;AAAA,IAElD,IAAI;AAAA,IACJ,IAAI;AAAA,MACF,WAAW,MAAM,MAAM,KAAK;AAAA,QAC1B;AAAA,QACA;AAAA,QACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,MACtC,CAAC;AAAA,MACD,MAAM;AAAA,MACN,MAAM,IAAI,SAAS,GAAG,uBAAuB,KAAK,8CAA8C;AAAA;AAAA,IAGlG,IAAI,CAAC,SAAS,IAAI;AAAA,MAChB,IAAI,SAAS,WAAW,KAAK;AAAA,QAC3B,MAAM,IAAI,SAAS,KAAK,6BAA6B;AAAA,MACvD;AAAA,MAEA,IAAI,SAAS,WAAW,KAAK;AAAA,QAC3B,MAAM,aAAa,SAAS,QAAQ,IAAI,aAAa;AAAA,QACrD,MAAM,MAAM,aACR,sBAAsB,wBACtB;AAAA,QACJ,MAAM,IAAI,SAAS,KAAK,GAAG;AAAA,MAC7B;AAAA,MAEA,IAAI,SAAS,UAAU,KAAK;AAAA,QAC1B,MAAM,IAAI,SAAS,SAAS,QAAQ,8CAA8C,KAAK,gBAAgB;AAAA,MACzG;AAAA,MAEA,MAAM,YAAY,MAAM,SAAS,KAAK;AAAA,MACtC,IAAI,UAAU,QAAQ,SAAS;AAAA,MAC/B,IAAI;AAAA,QACF,MAAM,OAAO,KAAK,MAAM,SAAS;AAAA,QACjC,
|
|
14
|
-
"debugId": "
|
|
13
|
+
"mappings": "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",
|
|
14
|
+
"debugId": "90B4B3D52C6B85BE64756E2164756E21",
|
|
15
15
|
"names": []
|
|
16
16
|
}
|
package/dist/streams/index.js
CHANGED
|
@@ -54,7 +54,12 @@ class BaseClient {
|
|
|
54
54
|
let message = `HTTP ${response.status}`;
|
|
55
55
|
try {
|
|
56
56
|
const json = JSON.parse(errorBody);
|
|
57
|
-
|
|
57
|
+
const err = json.error ?? json.message;
|
|
58
|
+
if (typeof err === "string") {
|
|
59
|
+
message = err;
|
|
60
|
+
} else if (err && typeof err === "object") {
|
|
61
|
+
message = JSON.stringify(err);
|
|
62
|
+
}
|
|
58
63
|
} catch {
|
|
59
64
|
if (errorBody)
|
|
60
65
|
message = errorBody;
|
|
@@ -79,8 +84,7 @@ class Streams extends BaseClient {
|
|
|
79
84
|
return partialId;
|
|
80
85
|
}
|
|
81
86
|
const { streams } = await this.list();
|
|
82
|
-
const
|
|
83
|
-
const matches = typedStreams.filter((s) => s.id.startsWith(partialId));
|
|
87
|
+
const matches = streams.filter((s) => s.id.startsWith(partialId));
|
|
84
88
|
if (matches.length === 0) {
|
|
85
89
|
throw new ApiError(404, `No stream found matching "${partialId}"`);
|
|
86
90
|
}
|
|
@@ -97,8 +101,7 @@ class Streams extends BaseClient {
|
|
|
97
101
|
}
|
|
98
102
|
async updateByName(name, data) {
|
|
99
103
|
const { streams } = await this.list();
|
|
100
|
-
const
|
|
101
|
-
const existing = typedStreams.find((s) => s.name === name);
|
|
104
|
+
const existing = streams.find((s) => s.name === name);
|
|
102
105
|
if (!existing) {
|
|
103
106
|
throw new ApiError(404, `Stream with name "${name}" not found`);
|
|
104
107
|
}
|
|
@@ -129,7 +132,7 @@ class Streams extends BaseClient {
|
|
|
129
132
|
}
|
|
130
133
|
async listDeliveries(id, params) {
|
|
131
134
|
const qs = new URLSearchParams;
|
|
132
|
-
if (params?.limit)
|
|
135
|
+
if (params?.limit !== undefined)
|
|
133
136
|
qs.set("limit", String(params.limit));
|
|
134
137
|
if (params?.status)
|
|
135
138
|
qs.set("status", params.status);
|
|
@@ -151,5 +154,5 @@ export {
|
|
|
151
154
|
Streams
|
|
152
155
|
};
|
|
153
156
|
|
|
154
|
-
//# debugId=
|
|
157
|
+
//# debugId=230A3690DE682D2364756E2164756E21
|
|
155
158
|
//# sourceMappingURL=index.js.map
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
"sources": ["../src/errors.ts", "../src/base.ts", "../src/streams/client.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"/**\n * Error thrown by {@link SecondLayer} when an API request fails.\n * Includes the HTTP status code for programmatic error handling.\n *\n * @example\n * ```ts\n * try {\n * await client.streams.get(\"abc123\");\n * } catch (err) {\n * if (err instanceof ApiError && err.status === 404) {\n * console.log(\"Stream not found\");\n * }\n * }\n * ```\n */\nexport class ApiError extends Error {\n constructor(\n /** HTTP status code (0 for network errors). */\n public status: number,\n message: string\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n}\n",
|
|
6
|
-
"import { ApiError } from \"./errors.ts\";\n\nexport interface SecondLayerOptions {\n /** Base URL of the Secondlayer API (trailing slashes are stripped). */\n baseUrl: string;\n /** Bearer token for authenticated requests. */\n apiKey?: string;\n}\n\nconst DEFAULT_BASE_URL = \"https://api.secondlayer.tools\";\n\nexport abstract class BaseClient {\n protected baseUrl: string;\n protected apiKey?: string;\n\n constructor(options: Partial<SecondLayerOptions> = {}) {\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.apiKey = options.apiKey;\n }\n\n static authHeaders(apiKey?: string): Record<string, string> {\n const headers: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (apiKey) {\n headers[\"Authorization\"] = `Bearer ${apiKey}`;\n }\n return headers;\n }\n\n protected async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const headers = BaseClient.authHeaders(this.apiKey);\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n } catch {\n throw new ApiError(0, `Cannot reach API at ${this.baseUrl}. Check your connection or try again.`);\n }\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new ApiError(401, \"API key invalid or expired.\");\n }\n\n if (response.status === 429) {\n const retryAfter = response.headers.get(\"Retry-After\");\n const msg = retryAfter\n ? `Rate limited. Wait ${retryAfter} seconds.`\n : \"Rate limited. Try again later.\";\n throw new ApiError(429, msg);\n }\n\n if (response.status >= 500) {\n throw new ApiError(response.status, `Server error. Try again or check status at ${this.baseUrl}/health`);\n }\n\n const errorBody = await response.text();\n let message = `HTTP ${response.status}`;\n try {\n const json = JSON.parse(errorBody);\n
|
|
7
|
-
"import type {\n CreateStream,\n UpdateStream,\n StreamResponse,\n CreateStreamResponse,\n ListStreamsResponse,\n BulkPauseResponse,\n BulkResumeResponse,\n} from \"@secondlayer/shared/schemas\";\nimport { ApiError } from \"../errors.ts\";\nimport { BaseClient } from \"../base.ts\";\n\nexport interface DeliverySummary {\n id: string;\n blockHeight: number;\n status: string;\n statusCode: number | null;\n responseTimeMs: number | null;\n attempts: number;\n error: string | null;\n createdAt: string;\n}\n\nexport interface DeliveryDetail extends DeliverySummary {\n payload: unknown;\n}\n\nexport interface DeliveriesResponse {\n deliveries: DeliverySummary[];\n}\n\nexport class Streams extends BaseClient {\n private async requestWithStreamId<T>(\n method: string,\n pathTemplate: (id: string) => string,\n id: string,\n body?: unknown\n ): Promise<T> {\n const fullId = await this.resolveStreamId(id);\n return this.request<T>(method, pathTemplate(fullId), body);\n }\n\n async resolveStreamId(partialId: string): Promise<string> {\n if (partialId.length === 36 && partialId.includes(\"-\")) {\n return partialId;\n }\n\n const { streams } = await this.list();\n const
|
|
6
|
+
"import { ApiError } from \"./errors.ts\";\n\nexport interface SecondLayerOptions {\n /** Base URL of the Secondlayer API (trailing slashes are stripped). */\n baseUrl: string;\n /** Bearer token for authenticated requests. */\n apiKey?: string;\n}\n\nconst DEFAULT_BASE_URL = \"https://api.secondlayer.tools\";\n\nexport abstract class BaseClient {\n protected baseUrl: string;\n protected apiKey?: string;\n\n constructor(options: Partial<SecondLayerOptions> = {}) {\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.apiKey = options.apiKey;\n }\n\n static authHeaders(apiKey?: string): Record<string, string> {\n const headers: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (apiKey) {\n headers[\"Authorization\"] = `Bearer ${apiKey}`;\n }\n return headers;\n }\n\n protected async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const headers = BaseClient.authHeaders(this.apiKey);\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n } catch {\n throw new ApiError(0, `Cannot reach API at ${this.baseUrl}. Check your connection or try again.`);\n }\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new ApiError(401, \"API key invalid or expired.\");\n }\n\n if (response.status === 429) {\n const retryAfter = response.headers.get(\"Retry-After\");\n const msg = retryAfter\n ? `Rate limited. Wait ${retryAfter} seconds.`\n : \"Rate limited. Try again later.\";\n throw new ApiError(429, msg);\n }\n\n if (response.status >= 500) {\n throw new ApiError(response.status, `Server error. Try again or check status at ${this.baseUrl}/health`);\n }\n\n const errorBody = await response.text();\n let message = `HTTP ${response.status}`;\n try {\n const json = JSON.parse(errorBody);\n const err = json.error ?? json.message;\n if (typeof err === \"string\") {\n message = err;\n } else if (err && typeof err === \"object\") {\n message = JSON.stringify(err);\n }\n } catch {\n if (errorBody) message = errorBody;\n }\n throw new ApiError(response.status, message);\n }\n\n if (response.status === 204) {\n return undefined as T;\n }\n\n return response.json() as Promise<T>;\n }\n}\n",
|
|
7
|
+
"import type {\n CreateStream,\n UpdateStream,\n StreamResponse,\n CreateStreamResponse,\n ListStreamsResponse,\n BulkPauseResponse,\n BulkResumeResponse,\n} from \"@secondlayer/shared/schemas\";\nimport { ApiError } from \"../errors.ts\";\nimport { BaseClient } from \"../base.ts\";\n\nexport interface DeliverySummary {\n id: string;\n blockHeight: number;\n status: string;\n statusCode: number | null;\n responseTimeMs: number | null;\n attempts: number;\n error: string | null;\n createdAt: string;\n}\n\nexport interface DeliveryDetail extends DeliverySummary {\n payload: unknown;\n}\n\nexport interface DeliveriesResponse {\n deliveries: DeliverySummary[];\n}\n\nexport class Streams extends BaseClient {\n private async requestWithStreamId<T>(\n method: string,\n pathTemplate: (id: string) => string,\n id: string,\n body?: unknown\n ): Promise<T> {\n const fullId = await this.resolveStreamId(id);\n return this.request<T>(method, pathTemplate(fullId), body);\n }\n\n async resolveStreamId(partialId: string): Promise<string> {\n if (partialId.length === 36 && partialId.includes(\"-\")) {\n return partialId;\n }\n\n const { streams } = await this.list();\n const matches = streams.filter((s) => s.id.startsWith(partialId));\n\n if (matches.length === 0) {\n throw new ApiError(404, `No stream found matching \"${partialId}\"`);\n }\n if (matches.length > 1) {\n throw new ApiError(400, `Multiple streams match \"${partialId}\": ${matches.map((s) => s.id.slice(0, 8)).join(\", \")}`);\n }\n\n return matches[0]!.id;\n }\n\n async create(data: CreateStream): Promise<CreateStreamResponse> {\n return this.request<CreateStreamResponse>(\"POST\", \"/api/streams\", data);\n }\n\n async update(id: string, data: UpdateStream): Promise<StreamResponse> {\n return this.requestWithStreamId(\"PATCH\", (id) => `/api/streams/${id}`, id, data);\n }\n\n async updateByName(name: string, data: CreateStream): Promise<StreamResponse> {\n const { streams } = await this.list();\n const existing = streams.find((s) => s.name === name);\n if (!existing) {\n throw new ApiError(404, `Stream with name \"${name}\" not found`);\n }\n return this.update(existing.id, data);\n }\n\n async list(params?: { status?: string }): Promise<ListStreamsResponse> {\n const searchParams = new URLSearchParams();\n if (params?.status) searchParams.set(\"status\", params.status);\n const query = searchParams.toString();\n const path = query ? `/api/streams?${query}` : \"/api/streams\";\n return this.request<ListStreamsResponse>(\"GET\", path);\n }\n\n async get(id: string): Promise<StreamResponse> {\n return this.requestWithStreamId(\"GET\", (id) => `/api/streams/${id}`, id);\n }\n\n async delete(id: string): Promise<void> {\n return this.requestWithStreamId(\"DELETE\", (id) => `/api/streams/${id}`, id);\n }\n\n async enable(id: string): Promise<StreamResponse> {\n return this.requestWithStreamId(\"POST\", (id) => `/api/streams/${id}/enable`, id);\n }\n\n async disable(id: string): Promise<StreamResponse> {\n return this.requestWithStreamId(\"POST\", (id) => `/api/streams/${id}/disable`, id);\n }\n\n async rotateSecret(id: string): Promise<{ secret: string }> {\n return this.requestWithStreamId(\"POST\", (id) => `/api/streams/${id}/rotate-secret`, id);\n }\n\n // ── Deliveries ─────────────────────────────────────────────────────\n\n /** List recent deliveries for a stream. */\n async listDeliveries(id: string, params?: { limit?: number; status?: string }): Promise<DeliveriesResponse> {\n const qs = new URLSearchParams();\n if (params?.limit !== undefined) qs.set(\"limit\", String(params.limit));\n if (params?.status) qs.set(\"status\", params.status);\n const query = qs.toString();\n return this.requestWithStreamId(\"GET\", (id) => `/api/streams/${id}/deliveries${query ? `?${query}` : \"\"}`, id);\n }\n\n /** Get a single delivery with full payload. */\n async getDelivery(streamId: string, deliveryId: string): Promise<DeliveryDetail> {\n const fullId = await this.resolveStreamId(streamId);\n return this.request<DeliveryDetail>(\"GET\", `/api/streams/${fullId}/deliveries/${deliveryId}`);\n }\n\n async pauseAll(): Promise<BulkPauseResponse> {\n return this.request<BulkPauseResponse>(\"POST\", \"/api/streams/pause\");\n }\n\n async resumeAll(): Promise<BulkResumeResponse> {\n return this.request<BulkResumeResponse>(\"POST\", \"/api/streams/resume\");\n }\n}\n"
|
|
8
8
|
],
|
|
9
|
-
"mappings": ";AAeO,MAAM,iBAAiB,MAAM;AAAA,EAGzB;AAAA,EAFT,WAAW,CAEF,QACP,SACA;AAAA,IACA,MAAM,OAAO;AAAA,IAHN;AAAA,IAIP,KAAK,OAAO;AAAA;AAEhB;;;ACfA,IAAM,mBAAmB;AAAA;AAElB,MAAe,WAAW;AAAA,EACrB;AAAA,EACA;AAAA,EAEV,WAAW,CAAC,UAAuC,CAAC,GAAG;AAAA,IACrD,KAAK,WAAW,QAAQ,WAAW,kBAAkB,QAAQ,QAAQ,EAAE;AAAA,IACvE,KAAK,SAAS,QAAQ;AAAA;AAAA,SAGjB,WAAW,CAAC,QAAyC;AAAA,IAC1D,MAAM,UAAkC,EAAE,gBAAgB,mBAAmB;AAAA,IAC7E,IAAI,QAAQ;AAAA,MACV,QAAQ,mBAAmB,UAAU;AAAA,IACvC;AAAA,IACA,OAAO;AAAA;AAAA,OAGO,QAAU,CAAC,QAAgB,MAAc,MAA4B;AAAA,IACnF,MAAM,MAAM,GAAG,KAAK,UAAU;AAAA,IAC9B,MAAM,UAAU,WAAW,YAAY,KAAK,MAAM;AAAA,IAElD,IAAI;AAAA,IACJ,IAAI;AAAA,MACF,WAAW,MAAM,MAAM,KAAK;AAAA,QAC1B;AAAA,QACA;AAAA,QACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,MACtC,CAAC;AAAA,MACD,MAAM;AAAA,MACN,MAAM,IAAI,SAAS,GAAG,uBAAuB,KAAK,8CAA8C;AAAA;AAAA,IAGlG,IAAI,CAAC,SAAS,IAAI;AAAA,MAChB,IAAI,SAAS,WAAW,KAAK;AAAA,QAC3B,MAAM,IAAI,SAAS,KAAK,6BAA6B;AAAA,MACvD;AAAA,MAEA,IAAI,SAAS,WAAW,KAAK;AAAA,QAC3B,MAAM,aAAa,SAAS,QAAQ,IAAI,aAAa;AAAA,QACrD,MAAM,MAAM,aACR,sBAAsB,wBACtB;AAAA,QACJ,MAAM,IAAI,SAAS,KAAK,GAAG;AAAA,MAC7B;AAAA,MAEA,IAAI,SAAS,UAAU,KAAK;AAAA,QAC1B,MAAM,IAAI,SAAS,SAAS,QAAQ,8CAA8C,KAAK,gBAAgB;AAAA,MACzG;AAAA,MAEA,MAAM,YAAY,MAAM,SAAS,KAAK;AAAA,MACtC,IAAI,UAAU,QAAQ,SAAS;AAAA,MAC/B,IAAI;AAAA,QACF,MAAM,OAAO,KAAK,MAAM,SAAS;AAAA,QACjC,
|
|
10
|
-
"debugId": "
|
|
9
|
+
"mappings": ";AAeO,MAAM,iBAAiB,MAAM;AAAA,EAGzB;AAAA,EAFT,WAAW,CAEF,QACP,SACA;AAAA,IACA,MAAM,OAAO;AAAA,IAHN;AAAA,IAIP,KAAK,OAAO;AAAA;AAEhB;;;ACfA,IAAM,mBAAmB;AAAA;AAElB,MAAe,WAAW;AAAA,EACrB;AAAA,EACA;AAAA,EAEV,WAAW,CAAC,UAAuC,CAAC,GAAG;AAAA,IACrD,KAAK,WAAW,QAAQ,WAAW,kBAAkB,QAAQ,QAAQ,EAAE;AAAA,IACvE,KAAK,SAAS,QAAQ;AAAA;AAAA,SAGjB,WAAW,CAAC,QAAyC;AAAA,IAC1D,MAAM,UAAkC,EAAE,gBAAgB,mBAAmB;AAAA,IAC7E,IAAI,QAAQ;AAAA,MACV,QAAQ,mBAAmB,UAAU;AAAA,IACvC;AAAA,IACA,OAAO;AAAA;AAAA,OAGO,QAAU,CAAC,QAAgB,MAAc,MAA4B;AAAA,IACnF,MAAM,MAAM,GAAG,KAAK,UAAU;AAAA,IAC9B,MAAM,UAAU,WAAW,YAAY,KAAK,MAAM;AAAA,IAElD,IAAI;AAAA,IACJ,IAAI;AAAA,MACF,WAAW,MAAM,MAAM,KAAK;AAAA,QAC1B;AAAA,QACA;AAAA,QACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,MACtC,CAAC;AAAA,MACD,MAAM;AAAA,MACN,MAAM,IAAI,SAAS,GAAG,uBAAuB,KAAK,8CAA8C;AAAA;AAAA,IAGlG,IAAI,CAAC,SAAS,IAAI;AAAA,MAChB,IAAI,SAAS,WAAW,KAAK;AAAA,QAC3B,MAAM,IAAI,SAAS,KAAK,6BAA6B;AAAA,MACvD;AAAA,MAEA,IAAI,SAAS,WAAW,KAAK;AAAA,QAC3B,MAAM,aAAa,SAAS,QAAQ,IAAI,aAAa;AAAA,QACrD,MAAM,MAAM,aACR,sBAAsB,wBACtB;AAAA,QACJ,MAAM,IAAI,SAAS,KAAK,GAAG;AAAA,MAC7B;AAAA,MAEA,IAAI,SAAS,UAAU,KAAK;AAAA,QAC1B,MAAM,IAAI,SAAS,SAAS,QAAQ,8CAA8C,KAAK,gBAAgB;AAAA,MACzG;AAAA,MAEA,MAAM,YAAY,MAAM,SAAS,KAAK;AAAA,MACtC,IAAI,UAAU,QAAQ,SAAS;AAAA,MAC/B,IAAI;AAAA,QACF,MAAM,OAAO,KAAK,MAAM,SAAS;AAAA,QACjC,MAAM,MAAM,KAAK,SAAS,KAAK;AAAA,QAC/B,IAAI,OAAO,QAAQ,UAAU;AAAA,UAC3B,UAAU;AAAA,QACZ,EAAO,SAAI,OAAO,OAAO,QAAQ,UAAU;AAAA,UACzC,UAAU,KAAK,UAAU,GAAG;AAAA,QAC9B;AAAA,QACA,MAAM;AAAA,QACN,IAAI;AAAA,UAAW,UAAU;AAAA;AAAA,MAE3B,MAAM,IAAI,SAAS,SAAS,QAAQ,OAAO;AAAA,IAC7C;AAAA,IAEA,IAAI,SAAS,WAAW,KAAK;AAAA,MAC3B;AAAA,IACF;AAAA,IAEA,OAAO,SAAS,KAAK;AAAA;AAEzB;;;ACnDO,MAAM,gBAAgB,WAAW;AAAA,OACxB,oBAAsB,CAClC,QACA,cACA,IACA,MACY;AAAA,IACZ,MAAM,SAAS,MAAM,KAAK,gBAAgB,EAAE;AAAA,IAC5C,OAAO,KAAK,QAAW,QAAQ,aAAa,MAAM,GAAG,IAAI;AAAA;AAAA,OAGrD,gBAAe,CAAC,WAAoC;AAAA,IACxD,IAAI,UAAU,WAAW,MAAM,UAAU,SAAS,GAAG,GAAG;AAAA,MACtD,OAAO;AAAA,IACT;AAAA,IAEA,QAAQ,YAAY,MAAM,KAAK,KAAK;AAAA,IACpC,MAAM,UAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,GAAG,WAAW,SAAS,CAAC;AAAA,IAEhE,IAAI,QAAQ,WAAW,GAAG;AAAA,MACxB,MAAM,IAAI,SAAS,KAAK,6BAA6B,YAAY;AAAA,IACnE;AAAA,IACA,IAAI,QAAQ,SAAS,GAAG;AAAA,MACtB,MAAM,IAAI,SAAS,KAAK,2BAA2B,eAAe,QAAQ,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,CAAC,EAAE,KAAK,IAAI,GAAG;AAAA,IACrH;AAAA,IAEA,OAAO,QAAQ,GAAI;AAAA;AAAA,OAGf,OAAM,CAAC,MAAmD;AAAA,IAC9D,OAAO,KAAK,QAA8B,QAAQ,gBAAgB,IAAI;AAAA;AAAA,OAGlE,OAAM,CAAC,IAAY,MAA6C;AAAA,IACpE,OAAO,KAAK,oBAAoB,SAAS,CAAC,QAAO,gBAAgB,OAAM,IAAI,IAAI;AAAA;AAAA,OAG3E,aAAY,CAAC,MAAc,MAA6C;AAAA,IAC5E,QAAQ,YAAY,MAAM,KAAK,KAAK;AAAA,IACpC,MAAM,WAAW,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAAA,IACpD,IAAI,CAAC,UAAU;AAAA,MACb,MAAM,IAAI,SAAS,KAAK,qBAAqB,iBAAiB;AAAA,IAChE;AAAA,IACA,OAAO,KAAK,OAAO,SAAS,IAAI,IAAI;AAAA;AAAA,OAGhC,KAAI,CAAC,QAA4D;AAAA,IACrE,MAAM,eAAe,IAAI;AAAA,IACzB,IAAI,QAAQ;AAAA,MAAQ,aAAa,IAAI,UAAU,OAAO,MAAM;AAAA,IAC5D,MAAM,QAAQ,aAAa,SAAS;AAAA,IACpC,MAAM,OAAO,QAAQ,gBAAgB,UAAU;AAAA,IAC/C,OAAO,KAAK,QAA6B,OAAO,IAAI;AAAA;AAAA,OAGhD,IAAG,CAAC,IAAqC;AAAA,IAC7C,OAAO,KAAK,oBAAoB,OAAO,CAAC,QAAO,gBAAgB,OAAM,EAAE;AAAA;AAAA,OAGnE,OAAM,CAAC,IAA2B;AAAA,IACtC,OAAO,KAAK,oBAAoB,UAAU,CAAC,QAAO,gBAAgB,OAAM,EAAE;AAAA;AAAA,OAGtE,OAAM,CAAC,IAAqC;AAAA,IAChD,OAAO,KAAK,oBAAoB,QAAQ,CAAC,QAAO,gBAAgB,cAAa,EAAE;AAAA;AAAA,OAG3E,QAAO,CAAC,IAAqC;AAAA,IACjD,OAAO,KAAK,oBAAoB,QAAQ,CAAC,QAAO,gBAAgB,eAAc,EAAE;AAAA;AAAA,OAG5E,aAAY,CAAC,IAAyC;AAAA,IAC1D,OAAO,KAAK,oBAAoB,QAAQ,CAAC,QAAO,gBAAgB,qBAAoB,EAAE;AAAA;AAAA,OAMlF,eAAc,CAAC,IAAY,QAA2E;AAAA,IAC1G,MAAM,KAAK,IAAI;AAAA,IACf,IAAI,QAAQ,UAAU;AAAA,MAAW,GAAG,IAAI,SAAS,OAAO,OAAO,KAAK,CAAC;AAAA,IACrE,IAAI,QAAQ;AAAA,MAAQ,GAAG,IAAI,UAAU,OAAO,MAAM;AAAA,IAClD,MAAM,QAAQ,GAAG,SAAS;AAAA,IAC1B,OAAO,KAAK,oBAAoB,OAAO,CAAC,QAAO,gBAAgB,iBAAgB,QAAQ,IAAI,UAAU,MAAM,EAAE;AAAA;AAAA,OAIzG,YAAW,CAAC,UAAkB,YAA6C;AAAA,IAC/E,MAAM,SAAS,MAAM,KAAK,gBAAgB,QAAQ;AAAA,IAClD,OAAO,KAAK,QAAwB,OAAO,gBAAgB,qBAAqB,YAAY;AAAA;AAAA,OAGxF,SAAQ,GAA+B;AAAA,IAC3C,OAAO,KAAK,QAA2B,QAAQ,oBAAoB;AAAA;AAAA,OAG/D,UAAS,GAAgC;AAAA,IAC7C,OAAO,KAAK,QAA4B,QAAQ,qBAAqB;AAAA;AAEzE;",
|
|
10
|
+
"debugId": "230A3690DE682D2364756E2164756E21",
|
|
11
11
|
"names": []
|
|
12
12
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { SubgraphSummary, SubgraphDetail, SubgraphQueryParams, ReindexResponse } from "@secondlayer/shared/schemas";
|
|
2
|
+
import { DeploySubgraphRequest, DeploySubgraphResponse } from "@secondlayer/shared/schemas/subgraphs";
|
|
3
|
+
import { InferSubgraphClient } from "@secondlayer/subgraphs";
|
|
4
4
|
interface SecondLayerOptions {
|
|
5
5
|
/** Base URL of the Secondlayer API (trailing slashes are stripped). */
|
|
6
6
|
baseUrl: string;
|
|
@@ -14,11 +14,11 @@ declare abstract class BaseClient {
|
|
|
14
14
|
static authHeaders(apiKey?: string): Record<string, string>;
|
|
15
15
|
protected request<T>(method: string, path: string, body?: unknown): Promise<T>;
|
|
16
16
|
}
|
|
17
|
-
declare class
|
|
17
|
+
declare class Subgraphs extends BaseClient {
|
|
18
18
|
list(): Promise<{
|
|
19
|
-
data:
|
|
19
|
+
data: SubgraphSummary[]
|
|
20
20
|
}>;
|
|
21
|
-
get(name: string): Promise<
|
|
21
|
+
get(name: string): Promise<SubgraphDetail>;
|
|
22
22
|
reindex(name: string, options?: {
|
|
23
23
|
fromBlock?: number
|
|
24
24
|
toBlock?: number
|
|
@@ -26,30 +26,30 @@ declare class Views extends BaseClient {
|
|
|
26
26
|
delete(name: string): Promise<{
|
|
27
27
|
message: string
|
|
28
28
|
}>;
|
|
29
|
-
deploy(data:
|
|
30
|
-
queryTable(name: string, table: string, params?:
|
|
31
|
-
queryTableCount(name: string, table: string, params?:
|
|
29
|
+
deploy(data: DeploySubgraphRequest): Promise<DeploySubgraphResponse>;
|
|
30
|
+
queryTable(name: string, table: string, params?: SubgraphQueryParams): Promise<unknown[]>;
|
|
31
|
+
queryTableCount(name: string, table: string, params?: SubgraphQueryParams): Promise<{
|
|
32
32
|
count: number
|
|
33
33
|
}>;
|
|
34
34
|
/**
|
|
35
|
-
* Returns a typed client for a
|
|
36
|
-
* Row types are inferred from the
|
|
35
|
+
* Returns a typed client for a subgraph defined with `defineSubgraph()`.
|
|
36
|
+
* Row types are inferred from the subgraph's schema literal types.
|
|
37
37
|
*
|
|
38
38
|
* @example
|
|
39
39
|
* ```ts
|
|
40
|
-
* import
|
|
41
|
-
* const client = sl.
|
|
40
|
+
* import mySubgraph from './subgraphs/my-token-subgraph'
|
|
41
|
+
* const client = sl.subgraphs.typed(mySubgraph)
|
|
42
42
|
* const rows = await client.transfers.findMany({ where: { sender: 'SP...' } })
|
|
43
|
-
* // rows: InferTableRow<typeof
|
|
43
|
+
* // rows: InferTableRow<typeof mySubgraph.schema.transfers>[]
|
|
44
44
|
* ```
|
|
45
45
|
*/
|
|
46
46
|
typed<T extends {
|
|
47
47
|
name: string
|
|
48
48
|
schema: Record<string, unknown>
|
|
49
|
-
}>(def: T):
|
|
49
|
+
}>(def: T): InferSubgraphClient<T>;
|
|
50
50
|
private createTableClient;
|
|
51
51
|
}
|
|
52
|
-
import {
|
|
52
|
+
import { InferSubgraphClient as InferSubgraphClient2 } from "@secondlayer/subgraphs";
|
|
53
53
|
import { QueueStats } from "@secondlayer/shared/types";
|
|
54
54
|
import { CreateStream, UpdateStream, StreamResponse, CreateStreamResponse, ListStreamsResponse, BulkPauseResponse, BulkResumeResponse } from "@secondlayer/shared/schemas";
|
|
55
55
|
interface DeliverySummary {
|
|
@@ -96,26 +96,26 @@ declare class Streams extends BaseClient {
|
|
|
96
96
|
}
|
|
97
97
|
declare class SecondLayer extends BaseClient {
|
|
98
98
|
readonly streams: Streams;
|
|
99
|
-
readonly
|
|
99
|
+
readonly subgraphs: Subgraphs;
|
|
100
100
|
constructor(options?: Partial<SecondLayerOptions>);
|
|
101
101
|
getQueueStats(): Promise<QueueStats>;
|
|
102
102
|
}
|
|
103
103
|
/**
|
|
104
|
-
* Returns a typed client for a
|
|
104
|
+
* Returns a typed client for a subgraph defined with `defineSubgraph()`.
|
|
105
105
|
*
|
|
106
|
-
* Accepts a plain options object, a `SecondLayer` instance, or a `
|
|
106
|
+
* Accepts a plain options object, a `SecondLayer` instance, or a `Subgraphs` instance.
|
|
107
107
|
*
|
|
108
108
|
* @example
|
|
109
109
|
* ```ts
|
|
110
|
-
* import
|
|
111
|
-
* import {
|
|
110
|
+
* import mySubgraph from './subgraphs/my-subgraph'
|
|
111
|
+
* import { getSubgraph } from '@secondlayer/sdk'
|
|
112
112
|
*
|
|
113
|
-
* const client =
|
|
113
|
+
* const client = getSubgraph(mySubgraph, { apiKey: 'sl_...' })
|
|
114
114
|
* const rows = await client.transfers.findMany({ where: { sender: 'SP...' } })
|
|
115
115
|
* ```
|
|
116
116
|
*/
|
|
117
|
-
declare function
|
|
117
|
+
declare function getSubgraph<T extends {
|
|
118
118
|
name: string
|
|
119
119
|
schema: Record<string, unknown>
|
|
120
|
-
}>(def: T, options?: Partial<SecondLayerOptions> | SecondLayer |
|
|
121
|
-
export {
|
|
120
|
+
}>(def: T, options?: Partial<SecondLayerOptions> | SecondLayer | Subgraphs): InferSubgraphClient2<T>;
|
|
121
|
+
export { getSubgraph, Subgraphs, SecondLayerOptions };
|
|
@@ -54,7 +54,12 @@ class BaseClient {
|
|
|
54
54
|
let message = `HTTP ${response.status}`;
|
|
55
55
|
try {
|
|
56
56
|
const json = JSON.parse(errorBody);
|
|
57
|
-
|
|
57
|
+
const err = json.error ?? json.message;
|
|
58
|
+
if (typeof err === "string") {
|
|
59
|
+
message = err;
|
|
60
|
+
} else if (err && typeof err === "object") {
|
|
61
|
+
message = JSON.stringify(err);
|
|
62
|
+
}
|
|
58
63
|
} catch {
|
|
59
64
|
if (errorBody)
|
|
60
65
|
message = errorBody;
|
|
@@ -68,7 +73,7 @@ class BaseClient {
|
|
|
68
73
|
}
|
|
69
74
|
}
|
|
70
75
|
|
|
71
|
-
// src/
|
|
76
|
+
// src/subgraphs/serialize.ts
|
|
72
77
|
var SYSTEM_COLUMN_MAP = {
|
|
73
78
|
_blockHeight: "_block_height",
|
|
74
79
|
_txId: "_tx_id",
|
|
@@ -109,8 +114,8 @@ function resolveOrderByColumn(col) {
|
|
|
109
114
|
return resolveColumn(col);
|
|
110
115
|
}
|
|
111
116
|
|
|
112
|
-
// src/
|
|
113
|
-
function
|
|
117
|
+
// src/subgraphs/client.ts
|
|
118
|
+
function buildSubgraphQueryString(params) {
|
|
114
119
|
const qs = new URLSearchParams;
|
|
115
120
|
if (params.sort)
|
|
116
121
|
qs.set("_sort", params.sort);
|
|
@@ -131,27 +136,27 @@ function buildViewQueryString(params) {
|
|
|
131
136
|
return str ? `?${str}` : "";
|
|
132
137
|
}
|
|
133
138
|
|
|
134
|
-
class
|
|
139
|
+
class Subgraphs extends BaseClient {
|
|
135
140
|
async list() {
|
|
136
|
-
return this.request("GET", "/api/
|
|
141
|
+
return this.request("GET", "/api/subgraphs");
|
|
137
142
|
}
|
|
138
143
|
async get(name) {
|
|
139
|
-
return this.request("GET", `/api/
|
|
144
|
+
return this.request("GET", `/api/subgraphs/${name}`);
|
|
140
145
|
}
|
|
141
146
|
async reindex(name, options) {
|
|
142
|
-
return this.request("POST", `/api/
|
|
147
|
+
return this.request("POST", `/api/subgraphs/${name}/reindex`, options);
|
|
143
148
|
}
|
|
144
149
|
async delete(name) {
|
|
145
|
-
return this.request("DELETE", `/api/
|
|
150
|
+
return this.request("DELETE", `/api/subgraphs/${name}`);
|
|
146
151
|
}
|
|
147
152
|
async deploy(data) {
|
|
148
|
-
return this.request("POST", "/api/
|
|
153
|
+
return this.request("POST", "/api/subgraphs", data);
|
|
149
154
|
}
|
|
150
155
|
async queryTable(name, table, params = {}) {
|
|
151
|
-
return this.request("GET", `/api/
|
|
156
|
+
return this.request("GET", `/api/subgraphs/${name}/${table}${buildSubgraphQueryString(params)}`);
|
|
152
157
|
}
|
|
153
158
|
async queryTableCount(name, table, params = {}) {
|
|
154
|
-
return this.request("GET", `/api/
|
|
159
|
+
return this.request("GET", `/api/subgraphs/${name}/${table}/count${buildSubgraphQueryString(params)}`);
|
|
155
160
|
}
|
|
156
161
|
typed(def) {
|
|
157
162
|
const result = {};
|
|
@@ -160,7 +165,7 @@ class Views extends BaseClient {
|
|
|
160
165
|
}
|
|
161
166
|
return result;
|
|
162
167
|
}
|
|
163
|
-
createTableClient(
|
|
168
|
+
createTableClient(subgraphName, tableName) {
|
|
164
169
|
const self = this;
|
|
165
170
|
return {
|
|
166
171
|
async findMany(options = {}) {
|
|
@@ -170,6 +175,10 @@ class Views extends BaseClient {
|
|
|
170
175
|
if (options.orderBy) {
|
|
171
176
|
const entries = Object.entries(options.orderBy);
|
|
172
177
|
if (entries.length > 0) {
|
|
178
|
+
if (entries.length > 1) {
|
|
179
|
+
const extra = entries.slice(1).map(([col2]) => col2).join(", ");
|
|
180
|
+
throw new Error(`orderBy supports only one column; remove extra keys: ${extra}`);
|
|
181
|
+
}
|
|
173
182
|
const [col, dir] = entries[0];
|
|
174
183
|
sort = resolveOrderByColumn(col);
|
|
175
184
|
order = dir ?? "asc";
|
|
@@ -183,11 +192,11 @@ class Views extends BaseClient {
|
|
|
183
192
|
fields: options.fields?.join(","),
|
|
184
193
|
filters
|
|
185
194
|
};
|
|
186
|
-
return self.queryTable(
|
|
195
|
+
return self.queryTable(subgraphName, tableName, params);
|
|
187
196
|
},
|
|
188
197
|
async count(where) {
|
|
189
198
|
const filters = where ? serializeWhere(where) : undefined;
|
|
190
|
-
const result = await self.queryTableCount(
|
|
199
|
+
const result = await self.queryTableCount(subgraphName, tableName, { filters });
|
|
191
200
|
return result.count;
|
|
192
201
|
}
|
|
193
202
|
};
|
|
@@ -204,8 +213,7 @@ class Streams extends BaseClient {
|
|
|
204
213
|
return partialId;
|
|
205
214
|
}
|
|
206
215
|
const { streams } = await this.list();
|
|
207
|
-
const
|
|
208
|
-
const matches = typedStreams.filter((s) => s.id.startsWith(partialId));
|
|
216
|
+
const matches = streams.filter((s) => s.id.startsWith(partialId));
|
|
209
217
|
if (matches.length === 0) {
|
|
210
218
|
throw new ApiError(404, `No stream found matching "${partialId}"`);
|
|
211
219
|
}
|
|
@@ -222,8 +230,7 @@ class Streams extends BaseClient {
|
|
|
222
230
|
}
|
|
223
231
|
async updateByName(name, data) {
|
|
224
232
|
const { streams } = await this.list();
|
|
225
|
-
const
|
|
226
|
-
const existing = typedStreams.find((s) => s.name === name);
|
|
233
|
+
const existing = streams.find((s) => s.name === name);
|
|
227
234
|
if (!existing) {
|
|
228
235
|
throw new ApiError(404, `Stream with name "${name}" not found`);
|
|
229
236
|
}
|
|
@@ -254,7 +261,7 @@ class Streams extends BaseClient {
|
|
|
254
261
|
}
|
|
255
262
|
async listDeliveries(id, params) {
|
|
256
263
|
const qs = new URLSearchParams;
|
|
257
|
-
if (params?.limit)
|
|
264
|
+
if (params?.limit !== undefined)
|
|
258
265
|
qs.set("limit", String(params.limit));
|
|
259
266
|
if (params?.status)
|
|
260
267
|
qs.set("status", params.status);
|
|
@@ -276,11 +283,11 @@ class Streams extends BaseClient {
|
|
|
276
283
|
// src/client.ts
|
|
277
284
|
class SecondLayer extends BaseClient {
|
|
278
285
|
streams;
|
|
279
|
-
|
|
286
|
+
subgraphs;
|
|
280
287
|
constructor(options = {}) {
|
|
281
288
|
super(options);
|
|
282
289
|
this.streams = new Streams(options);
|
|
283
|
-
this.
|
|
290
|
+
this.subgraphs = new Subgraphs(options);
|
|
284
291
|
}
|
|
285
292
|
async getQueueStats() {
|
|
286
293
|
const status = await this.request("GET", "/status");
|
|
@@ -288,20 +295,20 @@ class SecondLayer extends BaseClient {
|
|
|
288
295
|
}
|
|
289
296
|
}
|
|
290
297
|
|
|
291
|
-
// src/
|
|
292
|
-
function
|
|
293
|
-
if (options instanceof
|
|
298
|
+
// src/subgraphs/get-subgraph.ts
|
|
299
|
+
function getSubgraph(def, options = {}) {
|
|
300
|
+
if (options instanceof Subgraphs) {
|
|
294
301
|
return options.typed(def);
|
|
295
302
|
}
|
|
296
303
|
if (options instanceof SecondLayer) {
|
|
297
|
-
return options.
|
|
304
|
+
return options.subgraphs.typed(def);
|
|
298
305
|
}
|
|
299
|
-
return new
|
|
306
|
+
return new Subgraphs(options).typed(def);
|
|
300
307
|
}
|
|
301
308
|
export {
|
|
302
|
-
|
|
303
|
-
|
|
309
|
+
getSubgraph,
|
|
310
|
+
Subgraphs
|
|
304
311
|
};
|
|
305
312
|
|
|
306
|
-
//# debugId=
|
|
313
|
+
//# debugId=01969F6E72DC6CF664756E2164756E21
|
|
307
314
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/errors.ts", "../src/base.ts", "../src/subgraphs/serialize.ts", "../src/subgraphs/client.ts", "../src/streams/client.ts", "../src/client.ts", "../src/subgraphs/get-subgraph.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"/**\n * Error thrown by {@link SecondLayer} when an API request fails.\n * Includes the HTTP status code for programmatic error handling.\n *\n * @example\n * ```ts\n * try {\n * await client.streams.get(\"abc123\");\n * } catch (err) {\n * if (err instanceof ApiError && err.status === 404) {\n * console.log(\"Stream not found\");\n * }\n * }\n * ```\n */\nexport class ApiError extends Error {\n constructor(\n /** HTTP status code (0 for network errors). */\n public status: number,\n message: string\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n}\n",
|
|
6
|
+
"import { ApiError } from \"./errors.ts\";\n\nexport interface SecondLayerOptions {\n /** Base URL of the Secondlayer API (trailing slashes are stripped). */\n baseUrl: string;\n /** Bearer token for authenticated requests. */\n apiKey?: string;\n}\n\nconst DEFAULT_BASE_URL = \"https://api.secondlayer.tools\";\n\nexport abstract class BaseClient {\n protected baseUrl: string;\n protected apiKey?: string;\n\n constructor(options: Partial<SecondLayerOptions> = {}) {\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.apiKey = options.apiKey;\n }\n\n static authHeaders(apiKey?: string): Record<string, string> {\n const headers: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (apiKey) {\n headers[\"Authorization\"] = `Bearer ${apiKey}`;\n }\n return headers;\n }\n\n protected async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const headers = BaseClient.authHeaders(this.apiKey);\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n } catch {\n throw new ApiError(0, `Cannot reach API at ${this.baseUrl}. Check your connection or try again.`);\n }\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new ApiError(401, \"API key invalid or expired.\");\n }\n\n if (response.status === 429) {\n const retryAfter = response.headers.get(\"Retry-After\");\n const msg = retryAfter\n ? `Rate limited. Wait ${retryAfter} seconds.`\n : \"Rate limited. Try again later.\";\n throw new ApiError(429, msg);\n }\n\n if (response.status >= 500) {\n throw new ApiError(response.status, `Server error. Try again or check status at ${this.baseUrl}/health`);\n }\n\n const errorBody = await response.text();\n let message = `HTTP ${response.status}`;\n try {\n const json = JSON.parse(errorBody);\n const err = json.error ?? json.message;\n if (typeof err === \"string\") {\n message = err;\n } else if (err && typeof err === \"object\") {\n message = JSON.stringify(err);\n }\n } catch {\n if (errorBody) message = errorBody;\n }\n throw new ApiError(response.status, message);\n }\n\n if (response.status === 204) {\n return undefined as T;\n }\n\n return response.json() as Promise<T>;\n }\n}\n",
|
|
7
|
+
"/**\n * Maps camelCase system column names (with or without `_` prefix) to the\n * actual snake_case DB column names used in query params.\n */\nconst SYSTEM_COLUMN_MAP: Record<string, string> = {\n // underscore-prefixed camelCase (canonical row shape)\n _blockHeight: \"_block_height\",\n _txId: \"_tx_id\",\n _createdAt: \"_created_at\",\n _id: \"_id\",\n // no-prefix aliases\n blockHeight: \"_block_height\",\n txId: \"_tx_id\",\n createdAt: \"_created_at\",\n id: \"_id\",\n};\n\nfunction resolveColumn(col: string): string {\n return SYSTEM_COLUMN_MAP[col] ?? col;\n}\n\n/**\n * Serializes a WhereInput object into the flat filter map expected by\n * SubgraphQueryParams.filters (and the REST API query string).\n *\n * Scalar values → `{ column: \"value\" }`\n * Comparison objects → `{ \"column.gte\": \"100\", \"column.lt\": \"200\" }`\n * System column aliases → `blockHeight` / `_blockHeight` both → `_block_height`\n */\nexport function serializeWhere(\n where: Record<string, unknown>,\n): Record<string, string> {\n const filters: Record<string, string> = {};\n\n for (const [column, value] of Object.entries(where)) {\n if (value === null || value === undefined) continue;\n\n const col = resolveColumn(column);\n\n if (typeof value === \"object\" && !Array.isArray(value)) {\n const ops = value as Record<string, unknown>;\n for (const [op, opValue] of Object.entries(ops)) {\n if (opValue === null || opValue === undefined) continue;\n if (op === \"eq\") {\n filters[col] = String(opValue);\n } else if ([\"neq\", \"gt\", \"gte\", \"lt\", \"lte\"].includes(op)) {\n filters[`${col}.${op}`] = String(opValue);\n }\n }\n } else {\n filters[col] = String(value);\n }\n }\n\n return filters;\n}\n\n/**\n * Resolves an orderBy column name (either alias or canonical) to the DB column name.\n */\nexport function resolveOrderByColumn(col: string): string {\n return resolveColumn(col);\n}\n",
|
|
8
|
+
"import type {\n SubgraphSummary,\n SubgraphDetail,\n SubgraphQueryParams,\n ReindexResponse,\n} from \"@secondlayer/shared/schemas\";\nimport type { DeploySubgraphRequest, DeploySubgraphResponse } from \"@secondlayer/shared/schemas/subgraphs\";\nimport type {\n InferSubgraphClient,\n FindManyOptions,\n WhereInput,\n} from \"@secondlayer/subgraphs\";\nimport { BaseClient } from \"../base.ts\";\nimport { serializeWhere, resolveOrderByColumn } from \"./serialize.ts\";\n\nfunction buildSubgraphQueryString(params: SubgraphQueryParams): string {\n const qs = new URLSearchParams();\n if (params.sort) qs.set(\"_sort\", params.sort);\n if (params.order) qs.set(\"_order\", params.order);\n if (params.limit !== undefined) qs.set(\"_limit\", String(params.limit));\n if (params.offset !== undefined) qs.set(\"_offset\", String(params.offset));\n if (params.fields) qs.set(\"_fields\", params.fields);\n if (params.filters) {\n for (const [key, value] of Object.entries(params.filters)) {\n qs.set(key, String(value));\n }\n }\n const str = qs.toString();\n return str ? `?${str}` : \"\";\n}\n\nexport class Subgraphs extends BaseClient {\n async list(): Promise<{ data: SubgraphSummary[] }> {\n return this.request<{ data: SubgraphSummary[] }>(\"GET\", \"/api/subgraphs\");\n }\n\n async get(name: string): Promise<SubgraphDetail> {\n return this.request<SubgraphDetail>(\"GET\", `/api/subgraphs/${name}`);\n }\n\n async reindex(name: string, options?: { fromBlock?: number; toBlock?: number }): Promise<ReindexResponse> {\n return this.request<ReindexResponse>(\"POST\", `/api/subgraphs/${name}/reindex`, options);\n }\n\n async delete(name: string): Promise<{ message: string }> {\n return this.request<{ message: string }>(\"DELETE\", `/api/subgraphs/${name}`);\n }\n\n async deploy(data: DeploySubgraphRequest): Promise<DeploySubgraphResponse> {\n return this.request<DeploySubgraphResponse>(\"POST\", \"/api/subgraphs\", data);\n }\n\n async queryTable(name: string, table: string, params: SubgraphQueryParams = {}): Promise<unknown[]> {\n return this.request<unknown[]>(\"GET\", `/api/subgraphs/${name}/${table}${buildSubgraphQueryString(params)}`);\n }\n\n async queryTableCount(name: string, table: string, params: SubgraphQueryParams = {}): Promise<{ count: number }> {\n return this.request<{ count: number }>(\"GET\", `/api/subgraphs/${name}/${table}/count${buildSubgraphQueryString(params)}`);\n }\n\n /**\n * Returns a typed client for a subgraph defined with `defineSubgraph()`.\n * Row types are inferred from the subgraph's schema literal types.\n *\n * @example\n * ```ts\n * import mySubgraph from './subgraphs/my-token-subgraph'\n * const client = sl.subgraphs.typed(mySubgraph)\n * const rows = await client.transfers.findMany({ where: { sender: 'SP...' } })\n * // rows: InferTableRow<typeof mySubgraph.schema.transfers>[]\n * ```\n */\n typed<T extends { name: string; schema: Record<string, unknown> }>(\n def: T,\n ): InferSubgraphClient<T> {\n const result: Record<string, unknown> = {};\n\n for (const tableName of Object.keys(def.schema)) {\n result[tableName] = this.createTableClient(def.name, tableName);\n }\n\n return result as InferSubgraphClient<T>;\n }\n\n private createTableClient(subgraphName: string, tableName: string) {\n const self = this;\n\n return {\n async findMany<TRow>(options: FindManyOptions<TRow> = {}): Promise<TRow[]> {\n const filters = options.where\n ? serializeWhere(options.where as Record<string, unknown>)\n : undefined;\n\n let sort: string | undefined;\n let order: string | undefined;\n if (options.orderBy) {\n const entries = Object.entries(options.orderBy) as [string, \"asc\" | \"desc\"][];\n if (entries.length > 0) {\n if (entries.length > 1) {\n const extra = entries.slice(1).map(([col]) => col).join(\", \");\n throw new Error(`orderBy supports only one column; remove extra keys: ${extra}`);\n }\n const [col, dir] = entries[0]!;\n sort = resolveOrderByColumn(col);\n order = dir ?? \"asc\";\n }\n }\n\n const params: SubgraphQueryParams = {\n sort,\n order,\n limit: options.limit,\n offset: options.offset,\n fields: options.fields?.join(\",\"),\n filters,\n };\n\n return self.queryTable(subgraphName, tableName, params) as Promise<TRow[]>;\n },\n\n async count<TRow>(where?: WhereInput<TRow>): Promise<number> {\n const filters = where\n ? serializeWhere(where as Record<string, unknown>)\n : undefined;\n\n const result = await self.queryTableCount(subgraphName, tableName, { filters });\n return result.count;\n },\n };\n }\n}\n",
|
|
9
|
+
"import type {\n CreateStream,\n UpdateStream,\n StreamResponse,\n CreateStreamResponse,\n ListStreamsResponse,\n BulkPauseResponse,\n BulkResumeResponse,\n} from \"@secondlayer/shared/schemas\";\nimport { ApiError } from \"../errors.ts\";\nimport { BaseClient } from \"../base.ts\";\n\nexport interface DeliverySummary {\n id: string;\n blockHeight: number;\n status: string;\n statusCode: number | null;\n responseTimeMs: number | null;\n attempts: number;\n error: string | null;\n createdAt: string;\n}\n\nexport interface DeliveryDetail extends DeliverySummary {\n payload: unknown;\n}\n\nexport interface DeliveriesResponse {\n deliveries: DeliverySummary[];\n}\n\nexport class Streams extends BaseClient {\n private async requestWithStreamId<T>(\n method: string,\n pathTemplate: (id: string) => string,\n id: string,\n body?: unknown\n ): Promise<T> {\n const fullId = await this.resolveStreamId(id);\n return this.request<T>(method, pathTemplate(fullId), body);\n }\n\n async resolveStreamId(partialId: string): Promise<string> {\n if (partialId.length === 36 && partialId.includes(\"-\")) {\n return partialId;\n }\n\n const { streams } = await this.list();\n const matches = streams.filter((s) => s.id.startsWith(partialId));\n\n if (matches.length === 0) {\n throw new ApiError(404, `No stream found matching \"${partialId}\"`);\n }\n if (matches.length > 1) {\n throw new ApiError(400, `Multiple streams match \"${partialId}\": ${matches.map((s) => s.id.slice(0, 8)).join(\", \")}`);\n }\n\n return matches[0]!.id;\n }\n\n async create(data: CreateStream): Promise<CreateStreamResponse> {\n return this.request<CreateStreamResponse>(\"POST\", \"/api/streams\", data);\n }\n\n async update(id: string, data: UpdateStream): Promise<StreamResponse> {\n return this.requestWithStreamId(\"PATCH\", (id) => `/api/streams/${id}`, id, data);\n }\n\n async updateByName(name: string, data: CreateStream): Promise<StreamResponse> {\n const { streams } = await this.list();\n const existing = streams.find((s) => s.name === name);\n if (!existing) {\n throw new ApiError(404, `Stream with name \"${name}\" not found`);\n }\n return this.update(existing.id, data);\n }\n\n async list(params?: { status?: string }): Promise<ListStreamsResponse> {\n const searchParams = new URLSearchParams();\n if (params?.status) searchParams.set(\"status\", params.status);\n const query = searchParams.toString();\n const path = query ? `/api/streams?${query}` : \"/api/streams\";\n return this.request<ListStreamsResponse>(\"GET\", path);\n }\n\n async get(id: string): Promise<StreamResponse> {\n return this.requestWithStreamId(\"GET\", (id) => `/api/streams/${id}`, id);\n }\n\n async delete(id: string): Promise<void> {\n return this.requestWithStreamId(\"DELETE\", (id) => `/api/streams/${id}`, id);\n }\n\n async enable(id: string): Promise<StreamResponse> {\n return this.requestWithStreamId(\"POST\", (id) => `/api/streams/${id}/enable`, id);\n }\n\n async disable(id: string): Promise<StreamResponse> {\n return this.requestWithStreamId(\"POST\", (id) => `/api/streams/${id}/disable`, id);\n }\n\n async rotateSecret(id: string): Promise<{ secret: string }> {\n return this.requestWithStreamId(\"POST\", (id) => `/api/streams/${id}/rotate-secret`, id);\n }\n\n // ── Deliveries ─────────────────────────────────────────────────────\n\n /** List recent deliveries for a stream. */\n async listDeliveries(id: string, params?: { limit?: number; status?: string }): Promise<DeliveriesResponse> {\n const qs = new URLSearchParams();\n if (params?.limit !== undefined) qs.set(\"limit\", String(params.limit));\n if (params?.status) qs.set(\"status\", params.status);\n const query = qs.toString();\n return this.requestWithStreamId(\"GET\", (id) => `/api/streams/${id}/deliveries${query ? `?${query}` : \"\"}`, id);\n }\n\n /** Get a single delivery with full payload. */\n async getDelivery(streamId: string, deliveryId: string): Promise<DeliveryDetail> {\n const fullId = await this.resolveStreamId(streamId);\n return this.request<DeliveryDetail>(\"GET\", `/api/streams/${fullId}/deliveries/${deliveryId}`);\n }\n\n async pauseAll(): Promise<BulkPauseResponse> {\n return this.request<BulkPauseResponse>(\"POST\", \"/api/streams/pause\");\n }\n\n async resumeAll(): Promise<BulkResumeResponse> {\n return this.request<BulkResumeResponse>(\"POST\", \"/api/streams/resume\");\n }\n}\n",
|
|
10
|
+
"import type { QueueStats } from \"@secondlayer/shared/types\";\nimport { BaseClient } from \"./base.ts\";\nimport type { SecondLayerOptions } from \"./base.ts\";\nimport { Streams } from \"./streams/client.ts\";\nimport { Subgraphs } from \"./subgraphs/client.ts\";\n\nexport class SecondLayer extends BaseClient {\n readonly streams: Streams;\n readonly subgraphs: Subgraphs;\n\n constructor(options: Partial<SecondLayerOptions> = {}) {\n super(options);\n this.streams = new Streams(options);\n this.subgraphs = new Subgraphs(options);\n }\n\n async getQueueStats(): Promise<QueueStats> {\n const status = await this.request<{ queue: QueueStats }>(\"GET\", \"/status\");\n return status.queue;\n }\n}\n",
|
|
11
|
+
"import type { InferSubgraphClient } from \"@secondlayer/subgraphs\";\nimport type { SecondLayerOptions } from \"../base.ts\";\nimport { SecondLayer } from \"../client.ts\";\nimport { Subgraphs } from \"./client.ts\";\n\n/**\n * Returns a typed client for a subgraph defined with `defineSubgraph()`.\n *\n * Accepts a plain options object, a `SecondLayer` instance, or a `Subgraphs` instance.\n *\n * @example\n * ```ts\n * import mySubgraph from './subgraphs/my-subgraph'\n * import { getSubgraph } from '@secondlayer/sdk'\n *\n * const client = getSubgraph(mySubgraph, { apiKey: 'sl_...' })\n * const rows = await client.transfers.findMany({ where: { sender: 'SP...' } })\n * ```\n */\nexport function getSubgraph<T extends { name: string; schema: Record<string, unknown> }>(\n def: T,\n options: Partial<SecondLayerOptions> | SecondLayer | Subgraphs = {},\n): InferSubgraphClient<T> {\n if (options instanceof Subgraphs) {\n return options.typed(def);\n }\n if (options instanceof SecondLayer) {\n return options.subgraphs.typed(def);\n }\n return new Subgraphs(options).typed(def);\n}\n"
|
|
12
|
+
],
|
|
13
|
+
"mappings": "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",
|
|
14
|
+
"debugId": "01969F6E72DC6CF664756E2164756E21",
|
|
15
|
+
"names": []
|
|
16
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@secondlayer/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -13,9 +13,13 @@
|
|
|
13
13
|
"types": "./dist/streams/index.d.ts",
|
|
14
14
|
"import": "./dist/streams/index.js"
|
|
15
15
|
},
|
|
16
|
-
"./
|
|
17
|
-
"types": "./dist/
|
|
18
|
-
"import": "./dist/
|
|
16
|
+
"./subgraphs": {
|
|
17
|
+
"types": "./dist/subgraphs/index.d.ts",
|
|
18
|
+
"import": "./dist/subgraphs/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./contracts": {
|
|
21
|
+
"types": "./dist/contracts/index.d.ts",
|
|
22
|
+
"import": "./dist/contracts/index.js"
|
|
19
23
|
}
|
|
20
24
|
},
|
|
21
25
|
"files": [
|
|
@@ -29,8 +33,8 @@
|
|
|
29
33
|
"prepublishOnly": "bun run build"
|
|
30
34
|
},
|
|
31
35
|
"dependencies": {
|
|
32
|
-
"@secondlayer/shared": "^0.
|
|
33
|
-
"@secondlayer/
|
|
36
|
+
"@secondlayer/shared": "^0.5.0",
|
|
37
|
+
"@secondlayer/subgraphs": "^0.5.0"
|
|
34
38
|
},
|
|
35
39
|
"devDependencies": {
|
|
36
40
|
"@types/bun": "latest",
|
package/dist/views/index.js.map
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../src/errors.ts", "../src/base.ts", "../src/views/serialize.ts", "../src/views/client.ts", "../src/streams/client.ts", "../src/client.ts", "../src/views/get-view.ts"],
|
|
4
|
-
"sourcesContent": [
|
|
5
|
-
"/**\n * Error thrown by {@link SecondLayer} when an API request fails.\n * Includes the HTTP status code for programmatic error handling.\n *\n * @example\n * ```ts\n * try {\n * await client.streams.get(\"abc123\");\n * } catch (err) {\n * if (err instanceof ApiError && err.status === 404) {\n * console.log(\"Stream not found\");\n * }\n * }\n * ```\n */\nexport class ApiError extends Error {\n constructor(\n /** HTTP status code (0 for network errors). */\n public status: number,\n message: string\n ) {\n super(message);\n this.name = \"ApiError\";\n }\n}\n",
|
|
6
|
-
"import { ApiError } from \"./errors.ts\";\n\nexport interface SecondLayerOptions {\n /** Base URL of the Secondlayer API (trailing slashes are stripped). */\n baseUrl: string;\n /** Bearer token for authenticated requests. */\n apiKey?: string;\n}\n\nconst DEFAULT_BASE_URL = \"https://api.secondlayer.tools\";\n\nexport abstract class BaseClient {\n protected baseUrl: string;\n protected apiKey?: string;\n\n constructor(options: Partial<SecondLayerOptions> = {}) {\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n this.apiKey = options.apiKey;\n }\n\n static authHeaders(apiKey?: string): Record<string, string> {\n const headers: Record<string, string> = { \"Content-Type\": \"application/json\" };\n if (apiKey) {\n headers[\"Authorization\"] = `Bearer ${apiKey}`;\n }\n return headers;\n }\n\n protected async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n const headers = BaseClient.authHeaders(this.apiKey);\n\n let response: Response;\n try {\n response = await fetch(url, {\n method,\n headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n } catch {\n throw new ApiError(0, `Cannot reach API at ${this.baseUrl}. Check your connection or try again.`);\n }\n\n if (!response.ok) {\n if (response.status === 401) {\n throw new ApiError(401, \"API key invalid or expired.\");\n }\n\n if (response.status === 429) {\n const retryAfter = response.headers.get(\"Retry-After\");\n const msg = retryAfter\n ? `Rate limited. Wait ${retryAfter} seconds.`\n : \"Rate limited. Try again later.\";\n throw new ApiError(429, msg);\n }\n\n if (response.status >= 500) {\n throw new ApiError(response.status, `Server error. Try again or check status at ${this.baseUrl}/health`);\n }\n\n const errorBody = await response.text();\n let message = `HTTP ${response.status}`;\n try {\n const json = JSON.parse(errorBody);\n message = json.error || json.message || message;\n } catch {\n if (errorBody) message = errorBody;\n }\n throw new ApiError(response.status, message);\n }\n\n if (response.status === 204) {\n return undefined as T;\n }\n\n return response.json() as Promise<T>;\n }\n}\n",
|
|
7
|
-
"/**\n * Maps camelCase system column names (with or without `_` prefix) to the\n * actual snake_case DB column names used in query params.\n */\nconst SYSTEM_COLUMN_MAP: Record<string, string> = {\n // underscore-prefixed camelCase (canonical row shape)\n _blockHeight: \"_block_height\",\n _txId: \"_tx_id\",\n _createdAt: \"_created_at\",\n _id: \"_id\",\n // no-prefix aliases\n blockHeight: \"_block_height\",\n txId: \"_tx_id\",\n createdAt: \"_created_at\",\n id: \"_id\",\n};\n\nfunction resolveColumn(col: string): string {\n return SYSTEM_COLUMN_MAP[col] ?? col;\n}\n\n/**\n * Serializes a WhereInput object into the flat filter map expected by\n * ViewQueryParams.filters (and the REST API query string).\n *\n * Scalar values → `{ column: \"value\" }`\n * Comparison objects → `{ \"column.gte\": \"100\", \"column.lt\": \"200\" }`\n * System column aliases → `blockHeight` / `_blockHeight` both → `_block_height`\n */\nexport function serializeWhere(\n where: Record<string, unknown>,\n): Record<string, string> {\n const filters: Record<string, string> = {};\n\n for (const [column, value] of Object.entries(where)) {\n if (value === null || value === undefined) continue;\n\n const col = resolveColumn(column);\n\n if (typeof value === \"object\" && !Array.isArray(value)) {\n const ops = value as Record<string, unknown>;\n for (const [op, opValue] of Object.entries(ops)) {\n if (opValue === null || opValue === undefined) continue;\n if (op === \"eq\") {\n filters[col] = String(opValue);\n } else if ([\"neq\", \"gt\", \"gte\", \"lt\", \"lte\"].includes(op)) {\n filters[`${col}.${op}`] = String(opValue);\n }\n }\n } else {\n filters[col] = String(value);\n }\n }\n\n return filters;\n}\n\n/**\n * Resolves an orderBy column name (either alias or canonical) to the DB column name.\n */\nexport function resolveOrderByColumn(col: string): string {\n return resolveColumn(col);\n}\n",
|
|
8
|
-
"import type {\n ViewSummary,\n ViewDetail,\n ViewQueryParams,\n ReindexResponse,\n} from \"@secondlayer/shared/schemas\";\nimport type { DeployViewRequest, DeployViewResponse } from \"@secondlayer/shared/schemas/views\";\nimport type {\n InferViewClient,\n FindManyOptions,\n WhereInput,\n} from \"@secondlayer/views\";\nimport { BaseClient } from \"../base.ts\";\nimport { serializeWhere, resolveOrderByColumn } from \"./serialize.ts\";\n\nfunction buildViewQueryString(params: ViewQueryParams): string {\n const qs = new URLSearchParams();\n if (params.sort) qs.set(\"_sort\", params.sort);\n if (params.order) qs.set(\"_order\", params.order);\n if (params.limit !== undefined) qs.set(\"_limit\", String(params.limit));\n if (params.offset !== undefined) qs.set(\"_offset\", String(params.offset));\n if (params.fields) qs.set(\"_fields\", params.fields);\n if (params.filters) {\n for (const [key, value] of Object.entries(params.filters)) {\n qs.set(key, String(value));\n }\n }\n const str = qs.toString();\n return str ? `?${str}` : \"\";\n}\n\nexport class Views extends BaseClient {\n async list(): Promise<{ data: ViewSummary[] }> {\n return this.request<{ data: ViewSummary[] }>(\"GET\", \"/api/views\");\n }\n\n async get(name: string): Promise<ViewDetail> {\n return this.request<ViewDetail>(\"GET\", `/api/views/${name}`);\n }\n\n async reindex(name: string, options?: { fromBlock?: number; toBlock?: number }): Promise<ReindexResponse> {\n return this.request<ReindexResponse>(\"POST\", `/api/views/${name}/reindex`, options);\n }\n\n async delete(name: string): Promise<{ message: string }> {\n return this.request<{ message: string }>(\"DELETE\", `/api/views/${name}`);\n }\n\n async deploy(data: DeployViewRequest): Promise<DeployViewResponse> {\n return this.request<DeployViewResponse>(\"POST\", \"/api/views\", data);\n }\n\n async queryTable(name: string, table: string, params: ViewQueryParams = {}): Promise<unknown[]> {\n return this.request<unknown[]>(\"GET\", `/api/views/${name}/${table}${buildViewQueryString(params)}`);\n }\n\n async queryTableCount(name: string, table: string, params: ViewQueryParams = {}): Promise<{ count: number }> {\n return this.request<{ count: number }>(\"GET\", `/api/views/${name}/${table}/count${buildViewQueryString(params)}`);\n }\n\n /**\n * Returns a typed client for a view defined with `defineView()`.\n * Row types are inferred from the view's schema literal types.\n *\n * @example\n * ```ts\n * import myView from './views/my-token-view'\n * const client = sl.views.typed(myView)\n * const rows = await client.transfers.findMany({ where: { sender: 'SP...' } })\n * // rows: InferTableRow<typeof myView.schema.transfers>[]\n * ```\n */\n typed<T extends { name: string; schema: Record<string, unknown> }>(\n def: T,\n ): InferViewClient<T> {\n const result: Record<string, unknown> = {};\n\n for (const tableName of Object.keys(def.schema)) {\n result[tableName] = this.createTableClient(def.name, tableName);\n }\n\n return result as InferViewClient<T>;\n }\n\n private createTableClient(viewName: string, tableName: string) {\n const self = this;\n\n return {\n async findMany<TRow>(options: FindManyOptions<TRow> = {}): Promise<TRow[]> {\n const filters = options.where\n ? serializeWhere(options.where as Record<string, unknown>)\n : undefined;\n\n let sort: string | undefined;\n let order: string | undefined;\n if (options.orderBy) {\n const entries = Object.entries(options.orderBy);\n if (entries.length > 0) {\n const [col, dir] = entries[0]!;\n sort = resolveOrderByColumn(col);\n order = (dir as unknown as string | undefined) ?? \"asc\";\n }\n }\n\n const params: ViewQueryParams = {\n sort,\n order,\n limit: options.limit,\n offset: options.offset,\n fields: options.fields?.join(\",\"),\n filters,\n };\n\n return self.queryTable(viewName, tableName, params) as Promise<TRow[]>;\n },\n\n async count<TRow>(where?: WhereInput<TRow>): Promise<number> {\n const filters = where\n ? serializeWhere(where as Record<string, unknown>)\n : undefined;\n\n const result = await self.queryTableCount(viewName, tableName, { filters });\n return result.count;\n },\n };\n }\n}\n",
|
|
9
|
-
"import type {\n CreateStream,\n UpdateStream,\n StreamResponse,\n CreateStreamResponse,\n ListStreamsResponse,\n BulkPauseResponse,\n BulkResumeResponse,\n} from \"@secondlayer/shared/schemas\";\nimport { ApiError } from \"../errors.ts\";\nimport { BaseClient } from \"../base.ts\";\n\nexport interface DeliverySummary {\n id: string;\n blockHeight: number;\n status: string;\n statusCode: number | null;\n responseTimeMs: number | null;\n attempts: number;\n error: string | null;\n createdAt: string;\n}\n\nexport interface DeliveryDetail extends DeliverySummary {\n payload: unknown;\n}\n\nexport interface DeliveriesResponse {\n deliveries: DeliverySummary[];\n}\n\nexport class Streams extends BaseClient {\n private async requestWithStreamId<T>(\n method: string,\n pathTemplate: (id: string) => string,\n id: string,\n body?: unknown\n ): Promise<T> {\n const fullId = await this.resolveStreamId(id);\n return this.request<T>(method, pathTemplate(fullId), body);\n }\n\n async resolveStreamId(partialId: string): Promise<string> {\n if (partialId.length === 36 && partialId.includes(\"-\")) {\n return partialId;\n }\n\n const { streams } = await this.list();\n const typedStreams = streams as { id: string }[];\n const matches = typedStreams.filter((s) => s.id.startsWith(partialId));\n\n if (matches.length === 0) {\n throw new ApiError(404, `No stream found matching \"${partialId}\"`);\n }\n if (matches.length > 1) {\n throw new ApiError(400, `Multiple streams match \"${partialId}\": ${matches.map((s) => s.id.slice(0, 8)).join(\", \")}`);\n }\n\n return matches[0]!.id;\n }\n\n async create(data: CreateStream): Promise<CreateStreamResponse> {\n return this.request<CreateStreamResponse>(\"POST\", \"/api/streams\", data);\n }\n\n async update(id: string, data: UpdateStream): Promise<StreamResponse> {\n return this.requestWithStreamId(\"PATCH\", (id) => `/api/streams/${id}`, id, data);\n }\n\n async updateByName(name: string, data: CreateStream): Promise<StreamResponse> {\n const { streams } = await this.list();\n const typedStreams = streams as { id: string; name: string }[];\n const existing = typedStreams.find((s) => s.name === name);\n if (!existing) {\n throw new ApiError(404, `Stream with name \"${name}\" not found`);\n }\n return this.update(existing.id, data);\n }\n\n async list(params?: { status?: string }): Promise<ListStreamsResponse> {\n const searchParams = new URLSearchParams();\n if (params?.status) searchParams.set(\"status\", params.status);\n const query = searchParams.toString();\n const path = query ? `/api/streams?${query}` : \"/api/streams\";\n return this.request<ListStreamsResponse>(\"GET\", path);\n }\n\n async get(id: string): Promise<StreamResponse> {\n return this.requestWithStreamId(\"GET\", (id) => `/api/streams/${id}`, id);\n }\n\n async delete(id: string): Promise<void> {\n return this.requestWithStreamId(\"DELETE\", (id) => `/api/streams/${id}`, id);\n }\n\n async enable(id: string): Promise<StreamResponse> {\n return this.requestWithStreamId(\"POST\", (id) => `/api/streams/${id}/enable`, id);\n }\n\n async disable(id: string): Promise<StreamResponse> {\n return this.requestWithStreamId(\"POST\", (id) => `/api/streams/${id}/disable`, id);\n }\n\n async rotateSecret(id: string): Promise<{ secret: string }> {\n return this.requestWithStreamId(\"POST\", (id) => `/api/streams/${id}/rotate-secret`, id);\n }\n\n // ── Deliveries ─────────────────────────────────────────────────────\n\n /** List recent deliveries for a stream. */\n async listDeliveries(id: string, params?: { limit?: number; status?: string }): Promise<DeliveriesResponse> {\n const qs = new URLSearchParams();\n if (params?.limit) qs.set(\"limit\", String(params.limit));\n if (params?.status) qs.set(\"status\", params.status);\n const query = qs.toString();\n return this.requestWithStreamId(\"GET\", (id) => `/api/streams/${id}/deliveries${query ? `?${query}` : \"\"}`, id);\n }\n\n /** Get a single delivery with full payload. */\n async getDelivery(streamId: string, deliveryId: string): Promise<DeliveryDetail> {\n const fullId = await this.resolveStreamId(streamId);\n return this.request<DeliveryDetail>(\"GET\", `/api/streams/${fullId}/deliveries/${deliveryId}`);\n }\n\n async pauseAll(): Promise<BulkPauseResponse> {\n return this.request<BulkPauseResponse>(\"POST\", \"/api/streams/pause\");\n }\n\n async resumeAll(): Promise<BulkResumeResponse> {\n return this.request<BulkResumeResponse>(\"POST\", \"/api/streams/resume\");\n }\n}\n",
|
|
10
|
-
"import type { QueueStats } from \"@secondlayer/shared/types\";\nimport { BaseClient } from \"./base.ts\";\nimport type { SecondLayerOptions } from \"./base.ts\";\nimport { Streams } from \"./streams/client.ts\";\nimport { Views } from \"./views/client.ts\";\n\nexport class SecondLayer extends BaseClient {\n readonly streams: Streams;\n readonly views: Views;\n\n constructor(options: Partial<SecondLayerOptions> = {}) {\n super(options);\n this.streams = new Streams(options);\n this.views = new Views(options);\n }\n\n async getQueueStats(): Promise<QueueStats> {\n const status = await this.request<{ queue: QueueStats }>(\"GET\", \"/status\");\n return status.queue;\n }\n}\n",
|
|
11
|
-
"import type { InferViewClient } from \"@secondlayer/views\";\nimport type { SecondLayerOptions } from \"../base.ts\";\nimport { SecondLayer } from \"../client.ts\";\nimport { Views } from \"./client.ts\";\n\n/**\n * Returns a typed client for a view defined with `defineView()`.\n *\n * Accepts a plain options object, a `SecondLayer` instance, or a `Views` instance.\n *\n * @example\n * ```ts\n * import myView from './views/my-view'\n * import { getView } from '@secondlayer/sdk'\n *\n * const client = getView(myView, { apiKey: 'sl_...' })\n * const rows = await client.transfers.findMany({ where: { sender: 'SP...' } })\n * ```\n */\nexport function getView<T extends { name: string; schema: Record<string, unknown> }>(\n def: T,\n options: Partial<SecondLayerOptions> | SecondLayer | Views = {},\n): InferViewClient<T> {\n if (options instanceof Views) {\n return options.typed(def);\n }\n if (options instanceof SecondLayer) {\n return options.views.typed(def);\n }\n return new Views(options).typed(def);\n}\n"
|
|
12
|
-
],
|
|
13
|
-
"mappings": ";AAeO,MAAM,iBAAiB,MAAM;AAAA,EAGzB;AAAA,EAFT,WAAW,CAEF,QACP,SACA;AAAA,IACA,MAAM,OAAO;AAAA,IAHN;AAAA,IAIP,KAAK,OAAO;AAAA;AAEhB;;;ACfA,IAAM,mBAAmB;AAAA;AAElB,MAAe,WAAW;AAAA,EACrB;AAAA,EACA;AAAA,EAEV,WAAW,CAAC,UAAuC,CAAC,GAAG;AAAA,IACrD,KAAK,WAAW,QAAQ,WAAW,kBAAkB,QAAQ,QAAQ,EAAE;AAAA,IACvE,KAAK,SAAS,QAAQ;AAAA;AAAA,SAGjB,WAAW,CAAC,QAAyC;AAAA,IAC1D,MAAM,UAAkC,EAAE,gBAAgB,mBAAmB;AAAA,IAC7E,IAAI,QAAQ;AAAA,MACV,QAAQ,mBAAmB,UAAU;AAAA,IACvC;AAAA,IACA,OAAO;AAAA;AAAA,OAGO,QAAU,CAAC,QAAgB,MAAc,MAA4B;AAAA,IACnF,MAAM,MAAM,GAAG,KAAK,UAAU;AAAA,IAC9B,MAAM,UAAU,WAAW,YAAY,KAAK,MAAM;AAAA,IAElD,IAAI;AAAA,IACJ,IAAI;AAAA,MACF,WAAW,MAAM,MAAM,KAAK;AAAA,QAC1B;AAAA,QACA;AAAA,QACA,MAAM,OAAO,KAAK,UAAU,IAAI,IAAI;AAAA,MACtC,CAAC;AAAA,MACD,MAAM;AAAA,MACN,MAAM,IAAI,SAAS,GAAG,uBAAuB,KAAK,8CAA8C;AAAA;AAAA,IAGlG,IAAI,CAAC,SAAS,IAAI;AAAA,MAChB,IAAI,SAAS,WAAW,KAAK;AAAA,QAC3B,MAAM,IAAI,SAAS,KAAK,6BAA6B;AAAA,MACvD;AAAA,MAEA,IAAI,SAAS,WAAW,KAAK;AAAA,QAC3B,MAAM,aAAa,SAAS,QAAQ,IAAI,aAAa;AAAA,QACrD,MAAM,MAAM,aACR,sBAAsB,wBACtB;AAAA,QACJ,MAAM,IAAI,SAAS,KAAK,GAAG;AAAA,MAC7B;AAAA,MAEA,IAAI,SAAS,UAAU,KAAK;AAAA,QAC1B,MAAM,IAAI,SAAS,SAAS,QAAQ,8CAA8C,KAAK,gBAAgB;AAAA,MACzG;AAAA,MAEA,MAAM,YAAY,MAAM,SAAS,KAAK;AAAA,MACtC,IAAI,UAAU,QAAQ,SAAS;AAAA,MAC/B,IAAI;AAAA,QACF,MAAM,OAAO,KAAK,MAAM,SAAS;AAAA,QACjC,UAAU,KAAK,SAAS,KAAK,WAAW;AAAA,QACxC,MAAM;AAAA,QACN,IAAI;AAAA,UAAW,UAAU;AAAA;AAAA,MAE3B,MAAM,IAAI,SAAS,SAAS,QAAQ,OAAO;AAAA,IAC7C;AAAA,IAEA,IAAI,SAAS,WAAW,KAAK;AAAA,MAC3B;AAAA,IACF;AAAA,IAEA,OAAO,SAAS,KAAK;AAAA;AAEzB;;;ACzEA,IAAM,oBAA4C;AAAA,EAEhD,cAAc;AAAA,EACd,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,KAAK;AAAA,EAEL,aAAa;AAAA,EACb,MAAM;AAAA,EACN,WAAW;AAAA,EACX,IAAI;AACN;AAEA,SAAS,aAAa,CAAC,KAAqB;AAAA,EAC1C,OAAO,kBAAkB,QAAQ;AAAA;AAW5B,SAAS,cAAc,CAC5B,OACwB;AAAA,EACxB,MAAM,UAAkC,CAAC;AAAA,EAEzC,YAAY,QAAQ,UAAU,OAAO,QAAQ,KAAK,GAAG;AAAA,IACnD,IAAI,UAAU,QAAQ,UAAU;AAAA,MAAW;AAAA,IAE3C,MAAM,MAAM,cAAc,MAAM;AAAA,IAEhC,IAAI,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AAAA,MACtD,MAAM,MAAM;AAAA,MACZ,YAAY,IAAI,YAAY,OAAO,QAAQ,GAAG,GAAG;AAAA,QAC/C,IAAI,YAAY,QAAQ,YAAY;AAAA,UAAW;AAAA,QAC/C,IAAI,OAAO,MAAM;AAAA,UACf,QAAQ,OAAO,OAAO,OAAO;AAAA,QAC/B,EAAO,SAAI,CAAC,OAAO,MAAM,OAAO,MAAM,KAAK,EAAE,SAAS,EAAE,GAAG;AAAA,UACzD,QAAQ,GAAG,OAAO,QAAQ,OAAO,OAAO;AAAA,QAC1C;AAAA,MACF;AAAA,IACF,EAAO;AAAA,MACL,QAAQ,OAAO,OAAO,KAAK;AAAA;AAAA,EAE/B;AAAA,EAEA,OAAO;AAAA;AAMF,SAAS,oBAAoB,CAAC,KAAqB;AAAA,EACxD,OAAO,cAAc,GAAG;AAAA;;;AC9C1B,SAAS,oBAAoB,CAAC,QAAiC;AAAA,EAC7D,MAAM,KAAK,IAAI;AAAA,EACf,IAAI,OAAO;AAAA,IAAM,GAAG,IAAI,SAAS,OAAO,IAAI;AAAA,EAC5C,IAAI,OAAO;AAAA,IAAO,GAAG,IAAI,UAAU,OAAO,KAAK;AAAA,EAC/C,IAAI,OAAO,UAAU;AAAA,IAAW,GAAG,IAAI,UAAU,OAAO,OAAO,KAAK,CAAC;AAAA,EACrE,IAAI,OAAO,WAAW;AAAA,IAAW,GAAG,IAAI,WAAW,OAAO,OAAO,MAAM,CAAC;AAAA,EACxE,IAAI,OAAO;AAAA,IAAQ,GAAG,IAAI,WAAW,OAAO,MAAM;AAAA,EAClD,IAAI,OAAO,SAAS;AAAA,IAClB,YAAY,KAAK,UAAU,OAAO,QAAQ,OAAO,OAAO,GAAG;AAAA,MACzD,GAAG,IAAI,KAAK,OAAO,KAAK,CAAC;AAAA,IAC3B;AAAA,EACF;AAAA,EACA,MAAM,MAAM,GAAG,SAAS;AAAA,EACxB,OAAO,MAAM,IAAI,QAAQ;AAAA;AAAA;AAGpB,MAAM,cAAc,WAAW;AAAA,OAC9B,KAAI,GAAqC;AAAA,IAC7C,OAAO,KAAK,QAAiC,OAAO,YAAY;AAAA;AAAA,OAG5D,IAAG,CAAC,MAAmC;AAAA,IAC3C,OAAO,KAAK,QAAoB,OAAO,cAAc,MAAM;AAAA;AAAA,OAGvD,QAAO,CAAC,MAAc,SAA8E;AAAA,IACxG,OAAO,KAAK,QAAyB,QAAQ,cAAc,gBAAgB,OAAO;AAAA;AAAA,OAG9E,OAAM,CAAC,MAA4C;AAAA,IACvD,OAAO,KAAK,QAA6B,UAAU,cAAc,MAAM;AAAA;AAAA,OAGnE,OAAM,CAAC,MAAsD;AAAA,IACjE,OAAO,KAAK,QAA4B,QAAQ,cAAc,IAAI;AAAA;AAAA,OAG9D,WAAU,CAAC,MAAc,OAAe,SAA0B,CAAC,GAAuB;AAAA,IAC9F,OAAO,KAAK,QAAmB,OAAO,cAAc,QAAQ,QAAQ,qBAAqB,MAAM,GAAG;AAAA;AAAA,OAG9F,gBAAe,CAAC,MAAc,OAAe,SAA0B,CAAC,GAA+B;AAAA,IAC3G,OAAO,KAAK,QAA2B,OAAO,cAAc,QAAQ,cAAc,qBAAqB,MAAM,GAAG;AAAA;AAAA,EAelH,KAAkE,CAChE,KACoB;AAAA,IACpB,MAAM,SAAkC,CAAC;AAAA,IAEzC,WAAW,aAAa,OAAO,KAAK,IAAI,MAAM,GAAG;AAAA,MAC/C,OAAO,aAAa,KAAK,kBAAkB,IAAI,MAAM,SAAS;AAAA,IAChE;AAAA,IAEA,OAAO;AAAA;AAAA,EAGD,iBAAiB,CAAC,UAAkB,WAAmB;AAAA,IAC7D,MAAM,OAAO;AAAA,IAEb,OAAO;AAAA,WACC,SAAc,CAAC,UAAiC,CAAC,GAAoB;AAAA,QACzE,MAAM,UAAU,QAAQ,QACpB,eAAe,QAAQ,KAAgC,IACvD;AAAA,QAEJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI,QAAQ,SAAS;AAAA,UACnB,MAAM,UAAU,OAAO,QAAQ,QAAQ,OAAO;AAAA,UAC9C,IAAI,QAAQ,SAAS,GAAG;AAAA,YACtB,OAAO,KAAK,OAAO,QAAQ;AAAA,YAC3B,OAAO,qBAAqB,GAAG;AAAA,YAC/B,QAAS,OAAyC;AAAA,UACpD;AAAA,QACF;AAAA,QAEA,MAAM,SAA0B;AAAA,UAC9B;AAAA,UACA;AAAA,UACA,OAAO,QAAQ;AAAA,UACf,QAAQ,QAAQ;AAAA,UAChB,QAAQ,QAAQ,QAAQ,KAAK,GAAG;AAAA,UAChC;AAAA,QACF;AAAA,QAEA,OAAO,KAAK,WAAW,UAAU,WAAW,MAAM;AAAA;AAAA,WAG9C,MAAW,CAAC,OAA2C;AAAA,QAC3D,MAAM,UAAU,QACZ,eAAe,KAAgC,IAC/C;AAAA,QAEJ,MAAM,SAAS,MAAM,KAAK,gBAAgB,UAAU,WAAW,EAAE,QAAQ,CAAC;AAAA,QAC1E,OAAO,OAAO;AAAA;AAAA,IAElB;AAAA;AAEJ;;AC/FO,MAAM,gBAAgB,WAAW;AAAA,OACxB,oBAAsB,CAClC,QACA,cACA,IACA,MACY;AAAA,IACZ,MAAM,SAAS,MAAM,KAAK,gBAAgB,EAAE;AAAA,IAC5C,OAAO,KAAK,QAAW,QAAQ,aAAa,MAAM,GAAG,IAAI;AAAA;AAAA,OAGrD,gBAAe,CAAC,WAAoC;AAAA,IACxD,IAAI,UAAU,WAAW,MAAM,UAAU,SAAS,GAAG,GAAG;AAAA,MACtD,OAAO;AAAA,IACT;AAAA,IAEA,QAAQ,YAAY,MAAM,KAAK,KAAK;AAAA,IACpC,MAAM,eAAe;AAAA,IACrB,MAAM,UAAU,aAAa,OAAO,CAAC,MAAM,EAAE,GAAG,WAAW,SAAS,CAAC;AAAA,IAErE,IAAI,QAAQ,WAAW,GAAG;AAAA,MACxB,MAAM,IAAI,SAAS,KAAK,6BAA6B,YAAY;AAAA,IACnE;AAAA,IACA,IAAI,QAAQ,SAAS,GAAG;AAAA,MACtB,MAAM,IAAI,SAAS,KAAK,2BAA2B,eAAe,QAAQ,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,CAAC,EAAE,KAAK,IAAI,GAAG;AAAA,IACrH;AAAA,IAEA,OAAO,QAAQ,GAAI;AAAA;AAAA,OAGf,OAAM,CAAC,MAAmD;AAAA,IAC9D,OAAO,KAAK,QAA8B,QAAQ,gBAAgB,IAAI;AAAA;AAAA,OAGlE,OAAM,CAAC,IAAY,MAA6C;AAAA,IACpE,OAAO,KAAK,oBAAoB,SAAS,CAAC,QAAO,gBAAgB,OAAM,IAAI,IAAI;AAAA;AAAA,OAG3E,aAAY,CAAC,MAAc,MAA6C;AAAA,IAC5E,QAAQ,YAAY,MAAM,KAAK,KAAK;AAAA,IACpC,MAAM,eAAe;AAAA,IACrB,MAAM,WAAW,aAAa,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAAA,IACzD,IAAI,CAAC,UAAU;AAAA,MACb,MAAM,IAAI,SAAS,KAAK,qBAAqB,iBAAiB;AAAA,IAChE;AAAA,IACA,OAAO,KAAK,OAAO,SAAS,IAAI,IAAI;AAAA;AAAA,OAGhC,KAAI,CAAC,QAA4D;AAAA,IACrE,MAAM,eAAe,IAAI;AAAA,IACzB,IAAI,QAAQ;AAAA,MAAQ,aAAa,IAAI,UAAU,OAAO,MAAM;AAAA,IAC5D,MAAM,QAAQ,aAAa,SAAS;AAAA,IACpC,MAAM,OAAO,QAAQ,gBAAgB,UAAU;AAAA,IAC/C,OAAO,KAAK,QAA6B,OAAO,IAAI;AAAA;AAAA,OAGhD,IAAG,CAAC,IAAqC;AAAA,IAC7C,OAAO,KAAK,oBAAoB,OAAO,CAAC,QAAO,gBAAgB,OAAM,EAAE;AAAA;AAAA,OAGnE,OAAM,CAAC,IAA2B;AAAA,IACtC,OAAO,KAAK,oBAAoB,UAAU,CAAC,QAAO,gBAAgB,OAAM,EAAE;AAAA;AAAA,OAGtE,OAAM,CAAC,IAAqC;AAAA,IAChD,OAAO,KAAK,oBAAoB,QAAQ,CAAC,QAAO,gBAAgB,cAAa,EAAE;AAAA;AAAA,OAG3E,QAAO,CAAC,IAAqC;AAAA,IACjD,OAAO,KAAK,oBAAoB,QAAQ,CAAC,QAAO,gBAAgB,eAAc,EAAE;AAAA;AAAA,OAG5E,aAAY,CAAC,IAAyC;AAAA,IAC1D,OAAO,KAAK,oBAAoB,QAAQ,CAAC,QAAO,gBAAgB,qBAAoB,EAAE;AAAA;AAAA,OAMlF,eAAc,CAAC,IAAY,QAA2E;AAAA,IAC1G,MAAM,KAAK,IAAI;AAAA,IACf,IAAI,QAAQ;AAAA,MAAO,GAAG,IAAI,SAAS,OAAO,OAAO,KAAK,CAAC;AAAA,IACvD,IAAI,QAAQ;AAAA,MAAQ,GAAG,IAAI,UAAU,OAAO,MAAM;AAAA,IAClD,MAAM,QAAQ,GAAG,SAAS;AAAA,IAC1B,OAAO,KAAK,oBAAoB,OAAO,CAAC,QAAO,gBAAgB,iBAAgB,QAAQ,IAAI,UAAU,MAAM,EAAE;AAAA;AAAA,OAIzG,YAAW,CAAC,UAAkB,YAA6C;AAAA,IAC/E,MAAM,SAAS,MAAM,KAAK,gBAAgB,QAAQ;AAAA,IAClD,OAAO,KAAK,QAAwB,OAAO,gBAAgB,qBAAqB,YAAY;AAAA;AAAA,OAGxF,SAAQ,GAA+B;AAAA,IAC3C,OAAO,KAAK,QAA2B,QAAQ,oBAAoB;AAAA;AAAA,OAG/D,UAAS,GAAgC;AAAA,IAC7C,OAAO,KAAK,QAA4B,QAAQ,qBAAqB;AAAA;AAEzE;;;AC7HO,MAAM,oBAAoB,WAAW;AAAA,EACjC;AAAA,EACA;AAAA,EAET,WAAW,CAAC,UAAuC,CAAC,GAAG;AAAA,IACrD,MAAM,OAAO;AAAA,IACb,KAAK,UAAU,IAAI,QAAQ,OAAO;AAAA,IAClC,KAAK,QAAQ,IAAI,MAAM,OAAO;AAAA;AAAA,OAG1B,cAAa,GAAwB;AAAA,IACzC,MAAM,SAAS,MAAM,KAAK,QAA+B,OAAO,SAAS;AAAA,IACzE,OAAO,OAAO;AAAA;AAElB;;;ACDO,SAAS,OAAoE,CAClF,KACA,UAA6D,CAAC,GAC1C;AAAA,EACpB,IAAI,mBAAmB,OAAO;AAAA,IAC5B,OAAO,QAAQ,MAAM,GAAG;AAAA,EAC1B;AAAA,EACA,IAAI,mBAAmB,aAAa;AAAA,IAClC,OAAO,QAAQ,MAAM,MAAM,GAAG;AAAA,EAChC;AAAA,EACA,OAAO,IAAI,MAAM,OAAO,EAAE,MAAM,GAAG;AAAA;",
|
|
14
|
-
"debugId": "77950829DF762B1564756E2164756E21",
|
|
15
|
-
"names": []
|
|
16
|
-
}
|