@secondlayer/sdk 0.4.0 → 0.5.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.js +15 -8
- package/dist/index.js.map +5 -5
- package/dist/streams/index.js +10 -7
- package/dist/streams/index.js.map +4 -4
- package/dist/views/index.js +15 -8
- package/dist/views/index.js.map +5 -5
- package/package.json +7 -3
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.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);
|
|
@@ -203,7 +206,7 @@ function buildViewQueryString(params) {
|
|
|
203
206
|
qs.set("_fields", params.fields);
|
|
204
207
|
if (params.filters) {
|
|
205
208
|
for (const [key, value] of Object.entries(params.filters)) {
|
|
206
|
-
qs.set(key, value);
|
|
209
|
+
qs.set(key, String(value));
|
|
207
210
|
}
|
|
208
211
|
}
|
|
209
212
|
const str = qs.toString();
|
|
@@ -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";
|
|
@@ -305,5 +312,5 @@ export {
|
|
|
305
312
|
ApiError
|
|
306
313
|
};
|
|
307
314
|
|
|
308
|
-
//# debugId=
|
|
315
|
+
//# debugId=6A5C74B2B94FA0CF64756E2164756E21
|
|
309
316
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
"sources": ["../src/errors.ts", "../src/base.ts", "../src/streams/client.ts", "../src/views/serialize.ts", "../src/views/client.ts", "../src/client.ts", "../src/views/get-view.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
|
"/**\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",
|
|
9
|
-
"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, 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 =
|
|
9
|
+
"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) 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: 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",
|
|
10
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
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
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": ";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;;AC7HA,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,IAAI,QAAQ,SAAS,GAAG;AAAA,cACtB,MAAM,QAAQ,QAAQ,MAAM,CAAC,EAAE,IAAI,EAAE,UAAS,IAAG,EAAE,KAAK,IAAI;AAAA,cAC5D,MAAM,IAAI,MAAM,wDAAwD,OAAO;AAAA,YACjF;AAAA,YACA,OAAO,KAAK,OAAO,QAAQ;AAAA,YAC3B,OAAO,qBAAqB,GAAG;AAAA,YAC/B,QAAQ,OAAO;AAAA,UACjB;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;;AC5HO,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": "6A5C74B2B94FA0CF64756E2164756E21",
|
|
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": "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",
|
|
10
|
+
"debugId": "230A3690DE682D2364756E2164756E21",
|
|
11
11
|
"names": []
|
|
12
12
|
}
|
package/dist/views/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;
|
|
@@ -124,7 +129,7 @@ function buildViewQueryString(params) {
|
|
|
124
129
|
qs.set("_fields", params.fields);
|
|
125
130
|
if (params.filters) {
|
|
126
131
|
for (const [key, value] of Object.entries(params.filters)) {
|
|
127
|
-
qs.set(key, value);
|
|
132
|
+
qs.set(key, String(value));
|
|
128
133
|
}
|
|
129
134
|
}
|
|
130
135
|
const str = qs.toString();
|
|
@@ -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";
|
|
@@ -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);
|
|
@@ -303,5 +310,5 @@ export {
|
|
|
303
310
|
Views
|
|
304
311
|
};
|
|
305
312
|
|
|
306
|
-
//# debugId=
|
|
313
|
+
//# debugId=A30DD0EC2223779564756E2164756E21
|
|
307
314
|
//# sourceMappingURL=index.js.map
|
package/dist/views/index.js.map
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
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
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
|
|
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
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, 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 =
|
|
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
|
|
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) 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: 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 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
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
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
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": "A30DD0EC2223779564756E2164756E21",
|
|
15
15
|
"names": []
|
|
16
16
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@secondlayer/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -16,6 +16,10 @@
|
|
|
16
16
|
"./views": {
|
|
17
17
|
"types": "./dist/views/index.d.ts",
|
|
18
18
|
"import": "./dist/views/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/views": "^0.
|
|
36
|
+
"@secondlayer/shared": "^0.4.0",
|
|
37
|
+
"@secondlayer/views": "^0.3.0"
|
|
34
38
|
},
|
|
35
39
|
"devDependencies": {
|
|
36
40
|
"@types/bun": "latest",
|