@letsping/sdk 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,128 @@
1
+ # @letsping/sdk
2
+
3
+ The official Node.js/TypeScript SDK for [LetsPing](https://letsping.co).
4
+
5
+ LetsPing is the Human-in-the-Loop control plane for autonomous agents — the durable state layer that pauses execution before sensitive actions, persists encrypted agent state, and resumes only after explicit human approval (or rejection/correction).
6
+
7
+ ## Requirements
8
+
9
+ - Node.js 18+
10
+ - TypeScript 5+ (recommended)
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ npm install @letsping/sdk
16
+ ```
17
+
18
+ ## Usage
19
+
20
+ ### Blocking Request (`ask`)
21
+
22
+ Execution suspends until the request is approved, rejected, or times out.
23
+
24
+ ```typescript
25
+ import { LetsPing } from "@letsping/sdk";
26
+
27
+ const lp = new LetsPing(process.env.LETSPING_API_KEY!);
28
+
29
+ async function processRefund(userId: string, amount: number) {
30
+ try {
31
+ const decision = await lp.ask({
32
+ service: "billing-service",
33
+ action: "refund_user",
34
+ priority: "high",
35
+ payload: { userId, amount },
36
+
37
+ // Optional: JSON Schema to render an editable form in the dashboard
38
+ // (If using Zod: convert via zodToJsonSchema(mySchema))
39
+ schema: {
40
+ type: "object",
41
+ properties: {
42
+ amount: { type: "number", maximum: 5000 }
43
+ },
44
+ required: ["amount"]
45
+ },
46
+
47
+ // Optional override (default: 24 hours)
48
+ timeoutMs: 30 * 60 * 1000, // 30 minutes
49
+ });
50
+
51
+ if (decision.status === "APPROVED") {
52
+ // Prefer patched_payload if human edited values
53
+ const data = decision.patched_payload ?? decision.payload;
54
+ await stripe.refunds.create({
55
+ charge: data.userId,
56
+ amount: Math.round(data.amount * 100),
57
+ });
58
+ console.log("Refund executed");
59
+ } else {
60
+ console.log(`Refund ${decision.status.toLowerCase()} by operator`);
61
+ }
62
+ } catch (error) {
63
+ console.error("Approval failed or timed out:", error);
64
+ }
65
+ }
66
+ ```
67
+
68
+ ### Non-Blocking Request (`defer`)
69
+
70
+ Queues the request immediately and returns; ideal for serverless or event-driven flows.
71
+
72
+ ```typescript
73
+ const { id } = await lp.defer({
74
+ service: "notification-agent",
75
+ action: "send_email",
76
+ payload: {
77
+ to: "user@example.com",
78
+ subject: "Your invoice is ready",
79
+ amount: 249.99
80
+ },
81
+ priority: "medium"
82
+ });
83
+
84
+ console.log(`Approval request queued → ${id}`);
85
+ ```
86
+
87
+ ## API Reference
88
+
89
+ ### `new LetsPing(apiKey, options?)`
90
+
91
+ - `apiKey` (string) — **required** — Service Role or Project API key from LetsPing dashboard
92
+ - `options.baseUrl` (string) — optional — Override endpoint (self-hosted / staging)
93
+
94
+ ### `lp.ask(options): Promise<Decision>`
95
+
96
+ Blocks until resolved (approve / reject / timeout).
97
+
98
+ | Property | Type | Description |
99
+ |--------------|---------------------------------|-----------------------------------------------------------------------------|
100
+ | `service` | `string` | Service / module identifier (e.g. "billing", "compliance") |
101
+ | `action` | `string` | Action name (e.g. "refund", "transfer_funds") |
102
+ | `payload` | `Record<string, any>` | Context passed to human operator (and returned in Decision) |
103
+ | `priority` | `"low" \| "medium" \| "high" \| "critical"` | Routing priority in dashboard |
104
+ | `schema` | `object` | JSON Schema (draft 07) — generates editable form in dashboard |
105
+ | `timeoutMs` | `number` | Max wait time (default: 86_400_000 ms = 24 hours) |
106
+
107
+ ### `lp.defer(options): Promise<{ id: string }>`
108
+
109
+ Fire-and-forget: queues request and returns request ID immediately. Same options shape as `ask`.
110
+
111
+ ### Decision Type
112
+
113
+ ```typescript
114
+ interface Decision {
115
+ status: "APPROVED" | "REJECTED";
116
+ payload: Record<string, any>; // Original payload sent by agent
117
+ patched_payload?: Record<string, any>; // Human-edited values (if modified)
118
+ metadata: {
119
+ actor_id: string; // ID/email of the approving/rejecting human
120
+ resolved_at: string; // ISO 8601 timestamp
121
+ };
122
+ }
123
+ ```
124
+
125
+ For full documentation, request schema examples, error codes, and dashboard integration see:
126
+ https://letsping.co/docs#sdk
127
+
128
+ Deploy agents with confidence.
@@ -0,0 +1,37 @@
1
+ type Priority = "low" | "medium" | "high" | "critical";
2
+ interface RequestOptions {
3
+ service: string;
4
+ action: string;
5
+ payload: Record<string, any>;
6
+ priority?: Priority;
7
+ schema?: Record<string, any>;
8
+ timeoutMs?: number;
9
+ }
10
+ interface Decision {
11
+ status: "APPROVED" | "REJECTED";
12
+ payload: any;
13
+ patched_payload?: any;
14
+ metadata?: {
15
+ resolved_at: string;
16
+ actor_id: string;
17
+ method?: string;
18
+ };
19
+ }
20
+ declare class LetsPingError extends Error {
21
+ status?: number | undefined;
22
+ constructor(message: string, status?: number | undefined);
23
+ }
24
+ declare class LetsPing {
25
+ private readonly apiKey;
26
+ private readonly baseUrl;
27
+ constructor(apiKey?: string, options?: {
28
+ baseUrl?: string;
29
+ });
30
+ ask(options: RequestOptions): Promise<Decision>;
31
+ defer(options: RequestOptions): Promise<{
32
+ id: string;
33
+ }>;
34
+ private request;
35
+ }
36
+
37
+ export { type Decision, LetsPing, LetsPingError, type Priority, type RequestOptions };
@@ -0,0 +1,37 @@
1
+ type Priority = "low" | "medium" | "high" | "critical";
2
+ interface RequestOptions {
3
+ service: string;
4
+ action: string;
5
+ payload: Record<string, any>;
6
+ priority?: Priority;
7
+ schema?: Record<string, any>;
8
+ timeoutMs?: number;
9
+ }
10
+ interface Decision {
11
+ status: "APPROVED" | "REJECTED";
12
+ payload: any;
13
+ patched_payload?: any;
14
+ metadata?: {
15
+ resolved_at: string;
16
+ actor_id: string;
17
+ method?: string;
18
+ };
19
+ }
20
+ declare class LetsPingError extends Error {
21
+ status?: number | undefined;
22
+ constructor(message: string, status?: number | undefined);
23
+ }
24
+ declare class LetsPing {
25
+ private readonly apiKey;
26
+ private readonly baseUrl;
27
+ constructor(apiKey?: string, options?: {
28
+ baseUrl?: string;
29
+ });
30
+ ask(options: RequestOptions): Promise<Decision>;
31
+ defer(options: RequestOptions): Promise<{
32
+ id: string;
33
+ }>;
34
+ private request;
35
+ }
36
+
37
+ export { type Decision, LetsPing, LetsPingError, type Priority, type RequestOptions };
package/dist/index.js ADDED
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ LetsPing: () => LetsPing,
24
+ LetsPingError: () => LetsPingError
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+ var LetsPingError = class extends Error {
28
+ constructor(message, status) {
29
+ super(message);
30
+ this.status = status;
31
+ this.name = "LetsPingError";
32
+ }
33
+ };
34
+ var LetsPing = class {
35
+ constructor(apiKey, options) {
36
+ const key = apiKey || process.env.LETSPING_API_KEY;
37
+ if (!key) throw new Error("LetsPing: API Key is required. Pass it to the constructor or set LETSPING_API_KEY env var.");
38
+ this.apiKey = key;
39
+ this.baseUrl = options?.baseUrl || "https://letsping.co/api";
40
+ }
41
+ async ask(options) {
42
+ if (options.schema && options.schema._def) {
43
+ throw new LetsPingError("LetsPing Error: Raw Zod schema detected. You must convert it to JSON Schema (e.g. using 'zod-to-json-schema') before passing it to the SDK.");
44
+ }
45
+ const { id } = await this.request("POST", "/ingest", {
46
+ service: options.service,
47
+ action: options.action,
48
+ payload: options.payload,
49
+ priority: options.priority || "medium",
50
+ schema: options.schema,
51
+ metadata: {
52
+ role: options.role,
53
+ sdk: "node"
54
+ }
55
+ });
56
+ const timeout = options.timeoutMs || 24 * 60 * 60 * 1e3;
57
+ const start = Date.now();
58
+ let delay = 1e3;
59
+ const maxDelay = 1e4;
60
+ while (Date.now() - start < timeout) {
61
+ try {
62
+ const check = await this.request("GET", `/status/${id}`);
63
+ if (check.status === "APPROVED" || check.status === "REJECTED") {
64
+ return {
65
+ status: check.status,
66
+ payload: options.payload,
67
+ patched_payload: check.patched_payload || options.payload,
68
+ metadata: {
69
+ resolved_at: check.resolved_at,
70
+ actor_id: check.actor_id
71
+ }
72
+ };
73
+ }
74
+ } catch (e) {
75
+ const status = e.status;
76
+ if (status && status >= 400 && status < 500 && status !== 404 && status !== 429) {
77
+ throw e;
78
+ }
79
+ }
80
+ const jitter = Math.random() * 200;
81
+ await new Promise((r) => setTimeout(r, delay + jitter));
82
+ delay = Math.min(delay * 1.5, maxDelay);
83
+ }
84
+ throw new LetsPingError(`Request ${id} timed out waiting for approval.`);
85
+ }
86
+ async defer(options) {
87
+ return this.request("POST", "/ingest", options);
88
+ }
89
+ async request(method, path, body) {
90
+ const headers = {
91
+ "Authorization": `Bearer ${this.apiKey}`,
92
+ "Content-Type": "application/json",
93
+ "User-Agent": "letsping-node/0.1.2"
94
+ };
95
+ try {
96
+ const response = await fetch(`${this.baseUrl}${path}`, {
97
+ method,
98
+ headers,
99
+ body: body ? JSON.stringify(body) : void 0
100
+ });
101
+ if (!response.ok) {
102
+ const errorText = await response.text();
103
+ let message = errorText;
104
+ try {
105
+ const json = JSON.parse(errorText);
106
+ if (json.message) message = json.message;
107
+ } catch {
108
+ }
109
+ throw new LetsPingError(`API Error [${response.status}]: ${message}`, response.status);
110
+ }
111
+ return response.json();
112
+ } catch (e) {
113
+ if (e instanceof LetsPingError) throw e;
114
+ throw new LetsPingError(`Network Error: ${e.message}`);
115
+ }
116
+ }
117
+ tool(service, action, priority = "medium") {
118
+ return async (context) => {
119
+ let payload;
120
+ try {
121
+ if (typeof context === "string") {
122
+ try {
123
+ payload = JSON.parse(context);
124
+ } catch {
125
+ payload = { raw_context: context };
126
+ }
127
+ } else if (typeof context === "object" && context !== null) {
128
+ payload = context;
129
+ } else {
130
+ payload = { raw_context: String(context) };
131
+ }
132
+ const result = await this.ask({
133
+ service,
134
+ action,
135
+ payload,
136
+ priority
137
+ });
138
+ if (result.status === "REJECTED") {
139
+ return `STOP: Action Rejected by Human.`;
140
+ }
141
+ const finalPayload = result.patched_payload || result.payload;
142
+ return JSON.stringify(finalPayload);
143
+ } catch (e) {
144
+ return `ERROR: System Failure: ${e.message}`;
145
+ }
146
+ };
147
+ }
148
+ };
149
+ // Annotate the CommonJS export names for ESM import in node:
150
+ 0 && (module.exports = {
151
+ LetsPing,
152
+ LetsPingError
153
+ });
154
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export type Priority = \"low\" | \"medium\" | \"high\" | \"critical\";\r\n\r\n/**\r\n * Options for configuring a LetsPing approval request.\r\n */\r\nexport interface RequestOptions {\r\n /** Name of the agent or service (e.g., \"billing-agent\") */\r\n service: string;\r\n /** Specific action being requested (e.g., \"refund_user\") */\r\n action: string;\r\n /** The data payload to be reviewed by the human */\r\n payload: Record<string, any>;\r\n /** Urgency level affecting notification routing (default: \"medium\") */\r\n priority?: Priority;\r\n /** JSON Schema (Draft 7) for rendering a structured form in the dashboard */\r\n schema?: Record<string, any>;\r\n /** Maximum time to wait for approval in milliseconds (default: 24h) */\r\n timeoutMs?: number;\r\n /** (Enterprise) Specific role required for approval (e.g., \"finance\") */\r\n role?: string;\r\n}\r\n\r\n/**\r\n * The result of a human approval decision.\r\n */\r\nexport interface Decision {\r\n status: \"APPROVED\" | \"REJECTED\";\r\n /** The original payload submitted */\r\n payload: any;\r\n /** The modified payload if the human edited values during approval */\r\n patched_payload?: any;\r\n metadata?: {\r\n resolved_at: string;\r\n actor_id: string;\r\n method?: string;\r\n };\r\n}\r\n\r\nexport class LetsPingError extends Error {\r\n constructor(message: string, public status?: number) {\r\n super(message);\r\n this.name = \"LetsPingError\";\r\n }\r\n}\r\n\r\nexport class LetsPing {\r\n private readonly apiKey: string;\r\n private readonly baseUrl: string;\r\n\r\n constructor(apiKey?: string, options?: { baseUrl?: string }) {\r\n const key = apiKey || process.env.LETSPING_API_KEY;\r\n if (!key) throw new Error(\"LetsPing: API Key is required. Pass it to the constructor or set LETSPING_API_KEY env var.\");\r\n\r\n this.apiKey = key;\r\n this.baseUrl = options?.baseUrl || \"https://letsping.co/api\";\r\n }\r\n\r\n async ask(options: RequestOptions): Promise<Decision> {\r\n if (options.schema && (options.schema as any)._def) {\r\n throw new LetsPingError(\"LetsPing Error: Raw Zod schema detected. You must convert it to JSON Schema (e.g. using 'zod-to-json-schema') before passing it to the SDK.\");\r\n }\r\n\r\n const { id } = await this.request<{ id: string }>(\"POST\", \"/ingest\", {\r\n service: options.service,\r\n action: options.action,\r\n payload: options.payload,\r\n priority: options.priority || \"medium\",\r\n schema: options.schema,\r\n metadata: {\r\n role: options.role,\r\n sdk: \"node\"\r\n }\r\n });\r\n\r\n const timeout = options.timeoutMs || 24 * 60 * 60 * 1000;\r\n const start = Date.now();\r\n let delay = 1000;\r\n const maxDelay = 10000;\r\n\r\n while (Date.now() - start < timeout) {\r\n try {\r\n const check = await this.request<any>(\"GET\", `/status/${id}`);\r\n\r\n if (check.status === \"APPROVED\" || check.status === \"REJECTED\") {\r\n return {\r\n status: check.status,\r\n payload: options.payload,\r\n patched_payload: check.patched_payload || options.payload,\r\n metadata: {\r\n resolved_at: check.resolved_at,\r\n actor_id: check.actor_id\r\n }\r\n };\r\n }\r\n } catch (e: any) {\r\n // Retry on:\r\n // 1. Network errors (status is undefined)\r\n // 2. 404 (not found yet)\r\n // 3. 429 (rate limit)\r\n // 4. 5xx (server error)\r\n // Fail on: 400, 401, 403 (client errors)\r\n const status = e.status;\r\n if (status && status >= 400 && status < 500 && status !== 404 && status !== 429) {\r\n throw e;\r\n }\r\n }\r\n\r\n const jitter = Math.random() * 200;\r\n await new Promise(r => setTimeout(r, delay + jitter));\r\n delay = Math.min(delay * 1.5, maxDelay);\r\n }\r\n\r\n throw new LetsPingError(`Request ${id} timed out waiting for approval.`);\r\n }\r\n\r\n async defer(options: RequestOptions): Promise<{ id: string }> {\r\n return this.request<{ id: string }>(\"POST\", \"/ingest\", options);\r\n }\r\n\r\n private async request<T>(method: string, path: string, body?: any): Promise<T> {\r\n // Shared headers\r\n const headers: Record<string, string> = {\r\n \"Authorization\": `Bearer ${this.apiKey}`,\r\n \"Content-Type\": \"application/json\",\r\n \"User-Agent\": \"letsping-node/0.1.2\"\r\n };\r\n\r\n try {\r\n const response = await fetch(`${this.baseUrl}${path}`, {\r\n method,\r\n headers,\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n // Try parsing JSON error message\r\n let message = errorText;\r\n try {\r\n const json = JSON.parse(errorText);\r\n if (json.message) message = json.message;\r\n } catch { }\r\n\r\n throw new LetsPingError(`API Error [${response.status}]: ${message}`, response.status);\r\n }\r\n\r\n return response.json() as Promise<T>;\r\n } catch (e: any) {\r\n if (e instanceof LetsPingError) throw e;\r\n // Fetch/Network errors\r\n throw new LetsPingError(`Network Error: ${e.message}`);\r\n }\r\n }\r\n tool(service: string, action: string, priority: Priority = \"medium\"): (context: string | Record<string, any>) => Promise<string> {\r\n return async (context: string | Record<string, any>): Promise<string> => {\r\n let payload: Record<string, any>;\r\n try {\r\n if (typeof context === 'string') {\r\n try {\r\n payload = JSON.parse(context);\r\n } catch {\r\n payload = { raw_context: context };\r\n }\r\n } else if (typeof context === 'object' && context !== null) {\r\n payload = context;\r\n } else {\r\n // Handle numbers, booleans, undefined, etc.\r\n payload = { raw_context: String(context) };\r\n }\r\n\r\n const result = await this.ask({\r\n service,\r\n action,\r\n payload,\r\n priority\r\n });\r\n\r\n if (result.status === \"REJECTED\") {\r\n return `STOP: Action Rejected by Human.`;\r\n }\r\n\r\n const finalPayload = result.patched_payload || result.payload;\r\n return JSON.stringify(finalPayload);\r\n } catch (e: any) {\r\n return `ERROR: System Failure: ${e.message}`;\r\n }\r\n };\r\n }\r\n}"],"mappings":"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","names":[]}
package/dist/index.mjs ADDED
@@ -0,0 +1,128 @@
1
+ // src/index.ts
2
+ var LetsPingError = class extends Error {
3
+ constructor(message, status) {
4
+ super(message);
5
+ this.status = status;
6
+ this.name = "LetsPingError";
7
+ }
8
+ };
9
+ var LetsPing = class {
10
+ constructor(apiKey, options) {
11
+ const key = apiKey || process.env.LETSPING_API_KEY;
12
+ if (!key) throw new Error("LetsPing: API Key is required. Pass it to the constructor or set LETSPING_API_KEY env var.");
13
+ this.apiKey = key;
14
+ this.baseUrl = options?.baseUrl || "https://letsping.co/api";
15
+ }
16
+ async ask(options) {
17
+ if (options.schema && options.schema._def) {
18
+ throw new LetsPingError("LetsPing Error: Raw Zod schema detected. You must convert it to JSON Schema (e.g. using 'zod-to-json-schema') before passing it to the SDK.");
19
+ }
20
+ const { id } = await this.request("POST", "/ingest", {
21
+ service: options.service,
22
+ action: options.action,
23
+ payload: options.payload,
24
+ priority: options.priority || "medium",
25
+ schema: options.schema,
26
+ metadata: {
27
+ role: options.role,
28
+ sdk: "node"
29
+ }
30
+ });
31
+ const timeout = options.timeoutMs || 24 * 60 * 60 * 1e3;
32
+ const start = Date.now();
33
+ let delay = 1e3;
34
+ const maxDelay = 1e4;
35
+ while (Date.now() - start < timeout) {
36
+ try {
37
+ const check = await this.request("GET", `/status/${id}`);
38
+ if (check.status === "APPROVED" || check.status === "REJECTED") {
39
+ return {
40
+ status: check.status,
41
+ payload: options.payload,
42
+ patched_payload: check.patched_payload || options.payload,
43
+ metadata: {
44
+ resolved_at: check.resolved_at,
45
+ actor_id: check.actor_id
46
+ }
47
+ };
48
+ }
49
+ } catch (e) {
50
+ const status = e.status;
51
+ if (status && status >= 400 && status < 500 && status !== 404 && status !== 429) {
52
+ throw e;
53
+ }
54
+ }
55
+ const jitter = Math.random() * 200;
56
+ await new Promise((r) => setTimeout(r, delay + jitter));
57
+ delay = Math.min(delay * 1.5, maxDelay);
58
+ }
59
+ throw new LetsPingError(`Request ${id} timed out waiting for approval.`);
60
+ }
61
+ async defer(options) {
62
+ return this.request("POST", "/ingest", options);
63
+ }
64
+ async request(method, path, body) {
65
+ const headers = {
66
+ "Authorization": `Bearer ${this.apiKey}`,
67
+ "Content-Type": "application/json",
68
+ "User-Agent": "letsping-node/0.1.2"
69
+ };
70
+ try {
71
+ const response = await fetch(`${this.baseUrl}${path}`, {
72
+ method,
73
+ headers,
74
+ body: body ? JSON.stringify(body) : void 0
75
+ });
76
+ if (!response.ok) {
77
+ const errorText = await response.text();
78
+ let message = errorText;
79
+ try {
80
+ const json = JSON.parse(errorText);
81
+ if (json.message) message = json.message;
82
+ } catch {
83
+ }
84
+ throw new LetsPingError(`API Error [${response.status}]: ${message}`, response.status);
85
+ }
86
+ return response.json();
87
+ } catch (e) {
88
+ if (e instanceof LetsPingError) throw e;
89
+ throw new LetsPingError(`Network Error: ${e.message}`);
90
+ }
91
+ }
92
+ tool(service, action, priority = "medium") {
93
+ return async (context) => {
94
+ let payload;
95
+ try {
96
+ if (typeof context === "string") {
97
+ try {
98
+ payload = JSON.parse(context);
99
+ } catch {
100
+ payload = { raw_context: context };
101
+ }
102
+ } else if (typeof context === "object" && context !== null) {
103
+ payload = context;
104
+ } else {
105
+ payload = { raw_context: String(context) };
106
+ }
107
+ const result = await this.ask({
108
+ service,
109
+ action,
110
+ payload,
111
+ priority
112
+ });
113
+ if (result.status === "REJECTED") {
114
+ return `STOP: Action Rejected by Human.`;
115
+ }
116
+ const finalPayload = result.patched_payload || result.payload;
117
+ return JSON.stringify(finalPayload);
118
+ } catch (e) {
119
+ return `ERROR: System Failure: ${e.message}`;
120
+ }
121
+ };
122
+ }
123
+ };
124
+ export {
125
+ LetsPing,
126
+ LetsPingError
127
+ };
128
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export type Priority = \"low\" | \"medium\" | \"high\" | \"critical\";\r\n\r\n/**\r\n * Options for configuring a LetsPing approval request.\r\n */\r\nexport interface RequestOptions {\r\n /** Name of the agent or service (e.g., \"billing-agent\") */\r\n service: string;\r\n /** Specific action being requested (e.g., \"refund_user\") */\r\n action: string;\r\n /** The data payload to be reviewed by the human */\r\n payload: Record<string, any>;\r\n /** Urgency level affecting notification routing (default: \"medium\") */\r\n priority?: Priority;\r\n /** JSON Schema (Draft 7) for rendering a structured form in the dashboard */\r\n schema?: Record<string, any>;\r\n /** Maximum time to wait for approval in milliseconds (default: 24h) */\r\n timeoutMs?: number;\r\n /** (Enterprise) Specific role required for approval (e.g., \"finance\") */\r\n role?: string;\r\n}\r\n\r\n/**\r\n * The result of a human approval decision.\r\n */\r\nexport interface Decision {\r\n status: \"APPROVED\" | \"REJECTED\";\r\n /** The original payload submitted */\r\n payload: any;\r\n /** The modified payload if the human edited values during approval */\r\n patched_payload?: any;\r\n metadata?: {\r\n resolved_at: string;\r\n actor_id: string;\r\n method?: string;\r\n };\r\n}\r\n\r\nexport class LetsPingError extends Error {\r\n constructor(message: string, public status?: number) {\r\n super(message);\r\n this.name = \"LetsPingError\";\r\n }\r\n}\r\n\r\nexport class LetsPing {\r\n private readonly apiKey: string;\r\n private readonly baseUrl: string;\r\n\r\n constructor(apiKey?: string, options?: { baseUrl?: string }) {\r\n const key = apiKey || process.env.LETSPING_API_KEY;\r\n if (!key) throw new Error(\"LetsPing: API Key is required. Pass it to the constructor or set LETSPING_API_KEY env var.\");\r\n\r\n this.apiKey = key;\r\n this.baseUrl = options?.baseUrl || \"https://letsping.co/api\";\r\n }\r\n\r\n async ask(options: RequestOptions): Promise<Decision> {\r\n if (options.schema && (options.schema as any)._def) {\r\n throw new LetsPingError(\"LetsPing Error: Raw Zod schema detected. You must convert it to JSON Schema (e.g. using 'zod-to-json-schema') before passing it to the SDK.\");\r\n }\r\n\r\n const { id } = await this.request<{ id: string }>(\"POST\", \"/ingest\", {\r\n service: options.service,\r\n action: options.action,\r\n payload: options.payload,\r\n priority: options.priority || \"medium\",\r\n schema: options.schema,\r\n metadata: {\r\n role: options.role,\r\n sdk: \"node\"\r\n }\r\n });\r\n\r\n const timeout = options.timeoutMs || 24 * 60 * 60 * 1000;\r\n const start = Date.now();\r\n let delay = 1000;\r\n const maxDelay = 10000;\r\n\r\n while (Date.now() - start < timeout) {\r\n try {\r\n const check = await this.request<any>(\"GET\", `/status/${id}`);\r\n\r\n if (check.status === \"APPROVED\" || check.status === \"REJECTED\") {\r\n return {\r\n status: check.status,\r\n payload: options.payload,\r\n patched_payload: check.patched_payload || options.payload,\r\n metadata: {\r\n resolved_at: check.resolved_at,\r\n actor_id: check.actor_id\r\n }\r\n };\r\n }\r\n } catch (e: any) {\r\n // Retry on:\r\n // 1. Network errors (status is undefined)\r\n // 2. 404 (not found yet)\r\n // 3. 429 (rate limit)\r\n // 4. 5xx (server error)\r\n // Fail on: 400, 401, 403 (client errors)\r\n const status = e.status;\r\n if (status && status >= 400 && status < 500 && status !== 404 && status !== 429) {\r\n throw e;\r\n }\r\n }\r\n\r\n const jitter = Math.random() * 200;\r\n await new Promise(r => setTimeout(r, delay + jitter));\r\n delay = Math.min(delay * 1.5, maxDelay);\r\n }\r\n\r\n throw new LetsPingError(`Request ${id} timed out waiting for approval.`);\r\n }\r\n\r\n async defer(options: RequestOptions): Promise<{ id: string }> {\r\n return this.request<{ id: string }>(\"POST\", \"/ingest\", options);\r\n }\r\n\r\n private async request<T>(method: string, path: string, body?: any): Promise<T> {\r\n // Shared headers\r\n const headers: Record<string, string> = {\r\n \"Authorization\": `Bearer ${this.apiKey}`,\r\n \"Content-Type\": \"application/json\",\r\n \"User-Agent\": \"letsping-node/0.1.2\"\r\n };\r\n\r\n try {\r\n const response = await fetch(`${this.baseUrl}${path}`, {\r\n method,\r\n headers,\r\n body: body ? JSON.stringify(body) : undefined,\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n // Try parsing JSON error message\r\n let message = errorText;\r\n try {\r\n const json = JSON.parse(errorText);\r\n if (json.message) message = json.message;\r\n } catch { }\r\n\r\n throw new LetsPingError(`API Error [${response.status}]: ${message}`, response.status);\r\n }\r\n\r\n return response.json() as Promise<T>;\r\n } catch (e: any) {\r\n if (e instanceof LetsPingError) throw e;\r\n // Fetch/Network errors\r\n throw new LetsPingError(`Network Error: ${e.message}`);\r\n }\r\n }\r\n tool(service: string, action: string, priority: Priority = \"medium\"): (context: string | Record<string, any>) => Promise<string> {\r\n return async (context: string | Record<string, any>): Promise<string> => {\r\n let payload: Record<string, any>;\r\n try {\r\n if (typeof context === 'string') {\r\n try {\r\n payload = JSON.parse(context);\r\n } catch {\r\n payload = { raw_context: context };\r\n }\r\n } else if (typeof context === 'object' && context !== null) {\r\n payload = context;\r\n } else {\r\n // Handle numbers, booleans, undefined, etc.\r\n payload = { raw_context: String(context) };\r\n }\r\n\r\n const result = await this.ask({\r\n service,\r\n action,\r\n payload,\r\n priority\r\n });\r\n\r\n if (result.status === \"REJECTED\") {\r\n return `STOP: Action Rejected by Human.`;\r\n }\r\n\r\n const finalPayload = result.patched_payload || result.payload;\r\n return JSON.stringify(finalPayload);\r\n } catch (e: any) {\r\n return `ERROR: System Failure: ${e.message}`;\r\n }\r\n };\r\n }\r\n}"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letsping/sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "The Human-in-the-Loop SDK for Autonomous Agents",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -20,8 +20,8 @@
20
20
  "dependencies": {},
21
21
  "devDependencies": {
22
22
  "tsup": "^8.0.0",
23
- "typescript": "^5.0.0",
24
- "@types/node": "^20.0.0"
23
+ "typescript": "^5.7.2",
24
+ "@types/node": "^22.0.0"
25
25
  },
26
26
  "publishConfig": {
27
27
  "access": "public"
package/src/index.d.ts ADDED
@@ -0,0 +1,35 @@
1
+ export type Priority = "low" | "medium" | "high" | "critical";
2
+ export interface RequestOptions {
3
+ service: string;
4
+ action: string;
5
+ payload: Record<string, any>;
6
+ priority?: Priority;
7
+ schema?: Record<string, any>;
8
+ timeoutMs?: number;
9
+ }
10
+ export interface Decision {
11
+ status: "APPROVED" | "REJECTED";
12
+ payload: any;
13
+ patched_payload?: any;
14
+ metadata?: {
15
+ resolved_at: string;
16
+ actor_id: string;
17
+ method?: string;
18
+ };
19
+ }
20
+ export declare class LetsPingError extends Error {
21
+ status?: number | undefined;
22
+ constructor(message: string, status?: number | undefined);
23
+ }
24
+ export declare class LetsPing {
25
+ private readonly apiKey;
26
+ private readonly baseUrl;
27
+ constructor(apiKey?: string, options?: {
28
+ baseUrl?: string;
29
+ });
30
+ ask(options: RequestOptions): Promise<Decision>;
31
+ defer(options: RequestOptions): Promise<{
32
+ id: string;
33
+ }>;
34
+ private request;
35
+ }
package/src/index.ts CHANGED
@@ -1,21 +1,33 @@
1
1
  export type Priority = "low" | "medium" | "high" | "critical";
2
2
 
3
+ /**
4
+ * Options for configuring a LetsPing approval request.
5
+ */
3
6
  export interface RequestOptions {
7
+ /** Name of the agent or service (e.g., "billing-agent") */
4
8
  service: string;
9
+ /** Specific action being requested (e.g., "refund_user") */
5
10
  action: string;
11
+ /** The data payload to be reviewed by the human */
6
12
  payload: Record<string, any>;
13
+ /** Urgency level affecting notification routing (default: "medium") */
7
14
  priority?: Priority;
8
- /**
9
- * JSON Schema object defining the structure of the payload for the Human UI.
10
- * Note: If using Zod, use `zod-to-json-schema` before passing it here.
11
- */
15
+ /** JSON Schema (Draft 7) for rendering a structured form in the dashboard */
12
16
  schema?: Record<string, any>;
17
+ /** Maximum time to wait for approval in milliseconds (default: 24h) */
13
18
  timeoutMs?: number;
19
+ /** (Enterprise) Specific role required for approval (e.g., "finance") */
20
+ role?: string;
14
21
  }
15
22
 
23
+ /**
24
+ * The result of a human approval decision.
25
+ */
16
26
  export interface Decision {
17
27
  status: "APPROVED" | "REJECTED";
28
+ /** The original payload submitted */
18
29
  payload: any;
30
+ /** The modified payload if the human edited values during approval */
19
31
  patched_payload?: any;
20
32
  metadata?: {
21
33
  resolved_at: string;
@@ -44,9 +56,8 @@ export class LetsPing {
44
56
  }
45
57
 
46
58
  async ask(options: RequestOptions): Promise<Decision> {
47
- // Warn if a raw Zod object is passed, as it serializes to {}
48
59
  if (options.schema && (options.schema as any)._def) {
49
- console.warn("\x1b[33m%s\x1b[0m", "⚠️ LetsPing Warning: It looks like you passed a raw Zod object to 'schema'. This will result in an empty form. Please convert it to JSON Schema first (e.g. using 'zod-to-json-schema').");
60
+ throw new LetsPingError("LetsPing Error: Raw Zod schema detected. You must convert it to JSON Schema (e.g. using 'zod-to-json-schema') before passing it to the SDK.");
50
61
  }
51
62
 
52
63
  const { id } = await this.request<{ id: string }>("POST", "/ingest", {
@@ -54,7 +65,11 @@ export class LetsPing {
54
65
  action: options.action,
55
66
  payload: options.payload,
56
67
  priority: options.priority || "medium",
57
- schema: options.schema
68
+ schema: options.schema,
69
+ metadata: {
70
+ role: options.role,
71
+ sdk: "node"
72
+ }
58
73
  });
59
74
 
60
75
  const timeout = options.timeoutMs || 24 * 60 * 60 * 1000;
@@ -78,8 +93,16 @@ export class LetsPing {
78
93
  };
79
94
  }
80
95
  } catch (e: any) {
81
- // Ignore 404 (pending) and 429 (rate limit), throw everything else
82
- if (e.status !== 404 && e.status !== 429) throw e;
96
+ // Retry on:
97
+ // 1. Network errors (status is undefined)
98
+ // 2. 404 (not found yet)
99
+ // 3. 429 (rate limit)
100
+ // 4. 5xx (server error)
101
+ // Fail on: 400, 401, 403 (client errors)
102
+ const status = e.status;
103
+ if (status && status >= 400 && status < 500 && status !== 404 && status !== 429) {
104
+ throw e;
105
+ }
83
106
  }
84
107
 
85
108
  const jitter = Math.random() * 200;
@@ -95,10 +118,11 @@ export class LetsPing {
95
118
  }
96
119
 
97
120
  private async request<T>(method: string, path: string, body?: any): Promise<T> {
121
+ // Shared headers
98
122
  const headers: Record<string, string> = {
99
123
  "Authorization": `Bearer ${this.apiKey}`,
100
124
  "Content-Type": "application/json",
101
- "User-Agent": "letsping-node/0.1.0"
125
+ "User-Agent": "letsping-node/0.1.2"
102
126
  };
103
127
 
104
128
  try {
@@ -110,13 +134,56 @@ export class LetsPing {
110
134
 
111
135
  if (!response.ok) {
112
136
  const errorText = await response.text();
113
- throw new LetsPingError(`LetsPing API Error [${response.status}]: ${errorText}`, response.status);
137
+ // Try parsing JSON error message
138
+ let message = errorText;
139
+ try {
140
+ const json = JSON.parse(errorText);
141
+ if (json.message) message = json.message;
142
+ } catch { }
143
+
144
+ throw new LetsPingError(`API Error [${response.status}]: ${message}`, response.status);
114
145
  }
115
146
 
116
147
  return response.json() as Promise<T>;
117
148
  } catch (e: any) {
118
149
  if (e instanceof LetsPingError) throw e;
150
+ // Fetch/Network errors
119
151
  throw new LetsPingError(`Network Error: ${e.message}`);
120
152
  }
121
153
  }
154
+ tool(service: string, action: string, priority: Priority = "medium"): (context: string | Record<string, any>) => Promise<string> {
155
+ return async (context: string | Record<string, any>): Promise<string> => {
156
+ let payload: Record<string, any>;
157
+ try {
158
+ if (typeof context === 'string') {
159
+ try {
160
+ payload = JSON.parse(context);
161
+ } catch {
162
+ payload = { raw_context: context };
163
+ }
164
+ } else if (typeof context === 'object' && context !== null) {
165
+ payload = context;
166
+ } else {
167
+ // Handle numbers, booleans, undefined, etc.
168
+ payload = { raw_context: String(context) };
169
+ }
170
+
171
+ const result = await this.ask({
172
+ service,
173
+ action,
174
+ payload,
175
+ priority
176
+ });
177
+
178
+ if (result.status === "REJECTED") {
179
+ return `STOP: Action Rejected by Human.`;
180
+ }
181
+
182
+ const finalPayload = result.patched_payload || result.payload;
183
+ return JSON.stringify(finalPayload);
184
+ } catch (e: any) {
185
+ return `ERROR: System Failure: ${e.message}`;
186
+ }
187
+ };
188
+ }
122
189
  }
package/tsc_error.log ADDED
@@ -0,0 +1,213 @@
1
+ npm warn Unknown user config "email". This will stop working in the next major version of npm.
2
+ ../../node_modules/@types/node/globals.d.ts(95,18): error TS1005: '>' expected.
3
+ ../../node_modules/@types/node/globals.d.ts(95,27): error TS1005: ')' expected.
4
+ ../../node_modules/@types/node/globals.d.ts(96,18): error TS1005: '>' expected.
5
+ ../../node_modules/@types/node/globals.d.ts(96,27): error TS1005: ';' expected.
6
+ ../../node_modules/@types/node/globals.d.ts(97,31): error TS1005: '>' expected.
7
+ ../../node_modules/@types/node/globals.d.ts(97,35): error TS1005: ';' expected.
8
+ ../../node_modules/@types/node/globals.d.ts(97,43): error TS1161: Unterminated regular expression literal.
9
+ ../../node_modules/@types/node/globals.d.ts(98,22): error TS1161: Unterminated regular expression literal.
10
+ ../../node_modules/@types/node/globals.d.ts(99,27): error TS1005: ';' expected.
11
+ ../../node_modules/@types/node/globals.d.ts(100,29): error TS1005: '>' expected.
12
+ ../../node_modules/@types/node/globals.d.ts(100,38): error TS1005: ';' expected.
13
+ ../../node_modules/@types/node/globals.d.ts(100,97): error TS1005: ';' expected.
14
+ ../../node_modules/@types/node/globals.d.ts(100,107): error TS1161: Unterminated regular expression literal.
15
+ ../../node_modules/@types/node/globals.d.ts(101,33): error TS1005: ';' expected.
16
+ ../../node_modules/@types/node/globals.d.ts(102,38): error TS1005: ';' expected.
17
+ ../../node_modules/@types/node/globals.d.ts(102,46): error TS1228: A type predicate is only allowed in return type position for functions and methods.
18
+ ../../node_modules/@types/node/globals.d.ts(102,49): error TS1434: Unexpected keyword or identifier.
19
+ ../../node_modules/@types/node/globals.d.ts(102,53): error TS1128: Declaration or statement expected.
20
+ ../../node_modules/@types/node/globals.d.ts(102,68): error TS1005: '(' expected.
21
+ ../../node_modules/@types/node/globals.d.ts(102,83): error TS1005: ')' expected.
22
+ ../../node_modules/@types/node/globals.d.ts(102,105): error TS1005: ';' expected.
23
+ ../../node_modules/@types/node/globals.d.ts(102,112): error TS1434: Unexpected keyword or identifier.
24
+ ../../node_modules/@types/node/globals.d.ts(102,117): error TS1434: Unexpected keyword or identifier.
25
+ ../../node_modules/@types/node/globals.d.ts(103,21): error TS1003: Identifier expected.
26
+ ../../node_modules/@types/node/globals.d.ts(103,22): error TS1161: Unterminated regular expression literal.
27
+ ../../node_modules/@types/node/globals.d.ts(104,38): error TS1161: Unterminated regular expression literal.
28
+ ../../node_modules/@types/node/globals.d.ts(109,20): error TS1005: ';' expected.
29
+ ../../node_modules/@types/node/globals.d.ts(110,18): error TS1161: Unterminated regular expression literal.
30
+ ../../node_modules/@types/node/globals.d.ts(111,18): error TS1161: Unterminated regular expression literal.
31
+ ../../node_modules/@types/node/globals.d.ts(112,9): error TS1128: Declaration or statement expected.
32
+ ../../node_modules/@types/node/globals.d.ts(116,14): error TS1005: '>' expected.
33
+ ../../node_modules/@types/node/globals.d.ts(116,23): error TS1005: ')' expected.
34
+ ../../node_modules/@types/node/globals.d.ts(117,14): error TS1005: '>' expected.
35
+ ../../node_modules/@types/node/globals.d.ts(117,23): error TS1005: ';' expected.
36
+ ../../node_modules/@types/node/globals.d.ts(118,19): error TS1005: '>' expected.
37
+ ../../node_modules/@types/node/globals.d.ts(118,23): error TS1005: ';' expected.
38
+ ../../node_modules/@types/node/globals.d.ts(118,49): error TS1005: ';' expected.
39
+ ../../node_modules/@types/node/globals.d.ts(119,28): error TS1005: '>' expected.
40
+ ../../node_modules/@types/node/globals.d.ts(119,32): error TS1005: ';' expected.
41
+ ../../node_modules/@types/node/globals.d.ts(119,40): error TS1161: Unterminated regular expression literal.
42
+ ../../node_modules/@types/node/globals.d.ts(120,22): error TS1161: Unterminated regular expression literal.
43
+ ../../node_modules/@types/node/globals.d.ts(121,22): error TS1161: Unterminated regular expression literal.
44
+ ../../node_modules/@types/node/globals.d.ts(123,27): error TS1005: ';' expected.
45
+ ../../node_modules/@types/node/globals.d.ts(124,30): error TS1005: '>' expected.
46
+ ../../node_modules/@types/node/globals.d.ts(124,39): error TS1005: ';' expected.
47
+ ../../node_modules/@types/node/globals.d.ts(124,154): error TS1109: Expression expected.
48
+ ../../node_modules/@types/node/globals.d.ts(126,36): error TS1005: ',' expected.
49
+ ../../node_modules/@types/node/globals.d.ts(127,38): error TS1005: '>' expected.
50
+ ../../node_modules/@types/node/globals.d.ts(127,47): error TS1005: ')' expected.
51
+ ../../node_modules/@types/node/globals.d.ts(128,42): error TS1005: '>' expected.
52
+ ../../node_modules/@types/node/globals.d.ts(128,51): error TS1005: ';' expected.
53
+ ../../node_modules/@types/node/globals.d.ts(129,54): error TS1005: '>' expected.
54
+ ../../node_modules/@types/node/globals.d.ts(129,58): error TS1005: ';' expected.
55
+ ../../node_modules/@types/node/globals.d.ts(129,66): error TS1161: Unterminated regular expression literal.
56
+ ../../node_modules/@types/node/globals.d.ts(130,46): error TS1161: Unterminated regular expression literal.
57
+ ../../node_modules/@types/node/globals.d.ts(132,51): error TS1005: ';' expected.
58
+ ../../node_modules/@types/node/globals.d.ts(133,53): error TS1005: '>' expected.
59
+ ../../node_modules/@types/node/globals.d.ts(133,62): error TS1005: ';' expected.
60
+ ../../node_modules/@types/node/globals.d.ts(133,103): error TS1005: ';' expected.
61
+ ../../node_modules/@types/node/globals.d.ts(133,112): error TS1005: ';' expected.
62
+ ../../node_modules/@types/node/globals.d.ts(133,126): error TS1161: Unterminated regular expression literal.
63
+ ../../node_modules/@types/node/globals.d.ts(134,57): error TS1005: ';' expected.
64
+ ../../node_modules/@types/node/globals.d.ts(135,65): error TS1005: ';' expected.
65
+ ../../node_modules/@types/node/globals.d.ts(135,70): error TS1435: Unknown keyword or identifier. Did you mean 'get'?
66
+ ../../node_modules/@types/node/globals.d.ts(135,76): error TS1434: Unexpected keyword or identifier.
67
+ ../../node_modules/@types/node/globals.d.ts(135,86): error TS1434: Unexpected keyword or identifier.
68
+ ../../node_modules/@types/node/globals.d.ts(135,90): error TS1434: Unexpected keyword or identifier.
69
+ ../../node_modules/@types/node/globals.d.ts(135,94): error TS1434: Unexpected keyword or identifier.
70
+ ../../node_modules/@types/node/globals.d.ts(135,99): error TS1434: Unexpected keyword or identifier.
71
+ ../../node_modules/@types/node/globals.d.ts(135,102): error TS1434: Unexpected keyword or identifier.
72
+ ../../node_modules/@types/node/globals.d.ts(135,112): error TS1434: Unexpected keyword or identifier.
73
+ ../../node_modules/@types/node/globals.d.ts(135,114): error TS1434: Unexpected keyword or identifier.
74
+ ../../node_modules/@types/node/globals.d.ts(135,124): error TS1434: Unexpected keyword or identifier.
75
+ ../../node_modules/@types/node/globals.d.ts(135,138): error TS1434: Unexpected keyword or identifier.
76
+ ../../node_modules/@types/node/globals.d.ts(135,143): error TS1434: Unexpected keyword or identifier.
77
+ ../../node_modules/@types/node/globals.d.ts(136,29): error TS1003: Identifier expected.
78
+ ../../node_modules/@types/node/globals.d.ts(136,30): error TS1161: Unterminated regular expression literal.
79
+ ../../node_modules/@types/node/globals.d.ts(137,62): error TS1161: Unterminated regular expression literal.
80
+ ../../node_modules/@types/node/globals.d.ts(141,18): error TS1005: '>' expected.
81
+ ../../node_modules/@types/node/globals.d.ts(141,27): error TS1005: ')' expected.
82
+ ../../node_modules/@types/node/globals.d.ts(142,30): error TS1005: '>' expected.
83
+ ../../node_modules/@types/node/globals.d.ts(142,34): error TS1005: ';' expected.
84
+ ../../node_modules/@types/node/globals.d.ts(142,66): error TS1109: Expression expected.
85
+ ../../node_modules/@types/node/globals.d.ts(143,38): error TS1161: Unterminated regular expression literal.
86
+ ../../node_modules/@types/node/globals.d.ts(144,22): error TS1161: Unterminated regular expression literal.
87
+ ../../node_modules/@types/node/globals.d.ts(145,25): error TS1128: Declaration or statement expected.
88
+ ../../node_modules/@types/node/globals.d.ts(149,29): error TS1005: '>' expected.
89
+ ../../node_modules/@types/node/globals.d.ts(149,36): error TS1005: ';' expected.
90
+ ../../node_modules/@types/node/globals.d.ts(153,30): error TS1005: ',' expected.
91
+ ../../node_modules/@types/node/globals.d.ts(153,44): error TS1005: ',' expected.
92
+ ../../node_modules/@types/node/globals.d.ts(153,71): error TS1005: ',' expected.
93
+ ../../node_modules/@types/node/globals.d.ts(153,72): error TS1109: Expression expected.
94
+ ../../node_modules/@types/node/globals.d.ts(153,74): error TS1109: Expression expected.
95
+ ../../node_modules/@types/node/globals.d.ts(155,2): error TS1110: Type expected.
96
+ ../../node_modules/@types/node/globals.d.ts(156,6): error TS1161: Unterminated regular expression literal.
97
+ ../../node_modules/@types/node/globals.d.ts(157,17): error TS1128: Declaration or statement expected.
98
+ ../../node_modules/@types/node/globals.d.ts(157,18): error TS1128: Declaration or statement expected.
99
+ ../../node_modules/@types/node/globals.d.ts(161,14): error TS1005: '>' expected.
100
+ ../../node_modules/@types/node/globals.d.ts(161,23): error TS1005: ')' expected.
101
+ ../../node_modules/@types/node/globals.d.ts(162,18): error TS1005: '>' expected.
102
+ ../../node_modules/@types/node/globals.d.ts(162,27): error TS1005: ';' expected.
103
+ ../../node_modules/@types/node/globals.d.ts(163,21): error TS1005: '>' expected.
104
+ ../../node_modules/@types/node/globals.d.ts(163,30): error TS1005: ';' expected.
105
+ ../../node_modules/@types/node/globals.d.ts(163,69): error TS1005: ';' expected.
106
+ ../../node_modules/@types/node/globals.d.ts(163,78): error TS1161: Unterminated regular expression literal.
107
+ ../../node_modules/@types/node/globals.d.ts(164,25): error TS1005: ';' expected.
108
+ ../../node_modules/@types/node/globals.d.ts(164,68): error TS1005: ';' expected.
109
+ ../../node_modules/@types/node/globals.d.ts(164,73): error TS1434: Unexpected keyword or identifier.
110
+ ../../node_modules/@types/node/globals.d.ts(164,98): error TS1005: ',' expected.
111
+ ../../node_modules/@types/node/globals.d.ts(164,112): error TS1351: An identifier or keyword cannot immediately follow a numeric literal.
112
+ ../../node_modules/@types/node/globals.d.ts(164,122): error TS1005: ';' expected.
113
+ ../../node_modules/@types/node/globals.d.ts(164,126): error TS1434: Unexpected keyword or identifier.
114
+ ../../node_modules/@types/node/globals.d.ts(164,131): error TS1434: Unexpected keyword or identifier.
115
+ ../../node_modules/@types/node/globals.d.ts(164,135): error TS1434: Unexpected keyword or identifier.
116
+ ../../node_modules/@types/node/globals.d.ts(164,146): error TS1003: Identifier expected.
117
+ ../../node_modules/@types/node/globals.d.ts(164,147): error TS1161: Unterminated regular expression literal.
118
+ ../../node_modules/@types/node/globals.d.ts(165,26): error TS1161: Unterminated regular expression literal.
119
+ ../../node_modules/@types/node/globals.d.ts(167,31): error TS1005: ';' expected.
120
+ ../../node_modules/@types/node/globals.d.ts(168,34): error TS1005: '>' expected.
121
+ ../../node_modules/@types/node/globals.d.ts(168,43): error TS1005: ';' expected.
122
+ ../../node_modules/@types/node/globals.d.ts(170,37): error TS1005: '>' expected.
123
+ ../../node_modules/@types/node/globals.d.ts(170,42): error TS1005: ';' expected.
124
+ ../../node_modules/@types/node/globals.d.ts(171,17): error TS1005: ':' expected.
125
+ ../../node_modules/@types/node/globals.d.ts(173,21): error TS1005: ':' expected.
126
+ ../../node_modules/@types/node/globals.d.ts(174,10): error TS1109: Expression expected.
127
+ ../../node_modules/@types/node/globals.d.ts(175,10): error TS1110: Type expected.
128
+ ../../node_modules/@types/node/globals.d.ts(176,10): error TS1161: Unterminated regular expression literal.
129
+ ../../node_modules/@types/node/globals.d.ts(178,15): error TS1005: ';' expected.
130
+ ../../node_modules/@types/node/globals.d.ts(179,18): error TS1005: '>' expected.
131
+ ../../node_modules/@types/node/globals.d.ts(179,27): error TS1005: ';' expected.
132
+ ../../node_modules/@types/node/globals.d.ts(180,23): error TS1005: '>' expected.
133
+ ../../node_modules/@types/node/globals.d.ts(180,32): error TS1005: ';' expected.
134
+ ../../node_modules/@types/node/globals.d.ts(180,106): error TS1005: ';' expected.
135
+ ../../node_modules/@types/node/globals.d.ts(180,117): error TS1161: Unterminated regular expression literal.
136
+ ../../node_modules/@types/node/globals.d.ts(181,22): error TS1161: Unterminated regular expression literal.
137
+ ../../node_modules/@types/node/globals.d.ts(183,27): error TS1005: ';' expected.
138
+ ../../node_modules/@types/node/globals.d.ts(184,31): error TS1005: '>' expected.
139
+ ../../node_modules/@types/node/globals.d.ts(184,40): error TS1005: ';' expected.
140
+ ../../node_modules/@types/node/globals.d.ts(186,30): error TS1161: Unterminated regular expression literal.
141
+ ../../node_modules/@types/node/globals.d.ts(191,15): error TS1005: '>' expected.
142
+ ../../node_modules/@types/node/globals.d.ts(191,19): error TS1005: ';' expected.
143
+ ../../node_modules/@types/node/globals.d.ts(191,27): error TS1161: Unterminated regular expression literal.
144
+ ../../node_modules/@types/node/globals.d.ts(192,14): error TS1161: Unterminated regular expression literal.
145
+ ../../node_modules/@types/node/globals.d.ts(193,14): error TS1161: Unterminated regular expression literal.
146
+ ../../node_modules/@types/node/globals.d.ts(194,14): error TS1161: Unterminated regular expression literal.
147
+ ../../node_modules/@types/node/globals.d.ts(197,16): error TS1136: Property assignment expected.
148
+ ../../node_modules/@types/node/globals.d.ts(197,19): error TS1005: ';' expected.
149
+ ../../node_modules/@types/node/globals.d.ts(202,6): error TS1161: Unterminated regular expression literal.
150
+ ../../node_modules/@types/node/globals.d.ts(203,6): error TS1161: Unterminated regular expression literal.
151
+ ../../node_modules/@types/node/globals.d.ts(204,17): error TS1128: Declaration or statement expected.
152
+ ../../node_modules/@types/node/globals.d.ts(204,18): error TS1128: Declaration or statement expected.
153
+ ../../node_modules/@types/node/globals.d.ts(208,14): error TS1005: '>' expected.
154
+ ../../node_modules/@types/node/globals.d.ts(208,23): error TS1005: ')' expected.
155
+ ../../node_modules/@types/node/globals.d.ts(209,18): error TS1005: '>' expected.
156
+ ../../node_modules/@types/node/globals.d.ts(209,27): error TS1005: ';' expected.
157
+ ../../node_modules/@types/node/globals.d.ts(210,21): error TS1005: '>' expected.
158
+ ../../node_modules/@types/node/globals.d.ts(210,30): error TS1005: ';' expected.
159
+ ../../node_modules/@types/node/globals.d.ts(210,71): error TS1005: ';' expected.
160
+ ../../node_modules/@types/node/globals.d.ts(210,83): error TS1161: Unterminated regular expression literal.
161
+ ../../node_modules/@types/node/globals.d.ts(211,25): error TS1005: ';' expected.
162
+ ../../node_modules/@types/node/globals.d.ts(211,69): error TS1005: ';' expected.
163
+ ../../node_modules/@types/node/globals.d.ts(211,83): error TS1005: ';' expected.
164
+ ../../node_modules/@types/node/globals.d.ts(211,88): error TS1434: Unexpected keyword or identifier.
165
+ ../../node_modules/@types/node/globals.d.ts(211,93): error TS1434: Unexpected keyword or identifier.
166
+ ../../node_modules/@types/node/globals.d.ts(211,98): error TS1434: Unexpected keyword or identifier.
167
+ ../../node_modules/@types/node/globals.d.ts(211,112): error TS1434: Unexpected keyword or identifier.
168
+ ../../node_modules/@types/node/globals.d.ts(211,116): error TS1434: Unexpected keyword or identifier.
169
+ ../../node_modules/@types/node/globals.d.ts(211,119): error TS1434: Unexpected keyword or identifier.
170
+ ../../node_modules/@types/node/globals.d.ts(211,133): error TS1003: Identifier expected.
171
+ ../../node_modules/@types/node/globals.d.ts(211,134): error TS1161: Unterminated regular expression literal.
172
+ ../../node_modules/@types/node/globals.d.ts(212,26): error TS1161: Unterminated regular expression literal.
173
+ ../../node_modules/@types/node/globals.d.ts(214,31): error TS1005: ';' expected.
174
+ ../../node_modules/@types/node/globals.d.ts(216,33): error TS1005: '>' expected.
175
+ ../../node_modules/@types/node/globals.d.ts(220,20): error TS1005: ':' expected.
176
+ ../../node_modules/@types/node/globals.d.ts(222,17): error TS1136: Property assignment expected.
177
+ ../../node_modules/@types/node/globals.d.ts(222,21): error TS1005: ';' expected.
178
+ ../../node_modules/@types/node/globals.d.ts(226,6): error TS1109: Expression expected.
179
+ ../../node_modules/@types/node/globals.d.ts(227,6): error TS1110: Type expected.
180
+ ../../node_modules/@types/node/globals.d.ts(231,14): error TS1005: '>' expected.
181
+ ../../node_modules/@types/node/globals.d.ts(231,23): error TS1005: ')' expected.
182
+ ../../node_modules/@types/node/globals.d.ts(232,26): error TS1005: '>' expected.
183
+ ../../node_modules/@types/node/globals.d.ts(232,30): error TS1005: ';' expected.
184
+ ../../node_modules/@types/node/globals.d.ts(232,38): error TS1161: Unterminated regular expression literal.
185
+ ../../node_modules/@types/node/globals.d.ts(233,18): error TS1161: Unterminated regular expression literal.
186
+ ../../node_modules/@types/node/globals.d.ts(234,25): error TS1128: Declaration or statement expected.
187
+ ../../node_modules/@types/node/globals.d.ts(237,6): error TS1005: '>' expected.
188
+ ../../node_modules/@types/node/globals.d.ts(237,15): error TS1005: ';' expected.
189
+ ../../node_modules/@types/node/globals.d.ts(239,33): error TS1005: '>' expected.
190
+ ../../node_modules/@types/node/globals.d.ts(239,40): error TS1005: ';' expected.
191
+ ../../node_modules/@types/node/globals.d.ts(240,24): error TS1005: ',' expected.
192
+ ../../node_modules/@types/node/globals.d.ts(240,50): error TS1128: Declaration or statement expected.
193
+ ../../node_modules/@types/node/globals.d.ts(243,26): error TS1005: ',' expected.
194
+ ../../node_modules/@types/node/globals.d.ts(243,40): error TS1005: ',' expected.
195
+ ../../node_modules/@types/node/globals.d.ts(243,67): error TS1005: ',' expected.
196
+ ../../node_modules/@types/node/globals.d.ts(243,68): error TS1109: Expression expected.
197
+ ../../node_modules/@types/node/globals.d.ts(243,70): error TS1109: Expression expected.
198
+ ../../node_modules/@types/node/globals.d.ts(243,91): error TS1128: Declaration or statement expected.
199
+ ../../node_modules/@types/node/globals.d.ts(244,2): error TS1110: Type expected.
200
+ ../../node_modules/@types/node/globals.d.ts(247,12): error TS1136: Property assignment expected.
201
+ ../../node_modules/@types/node/globals.d.ts(247,15): error TS1005: ';' expected.
202
+ ../../node_modules/@types/node/globals.d.ts(247,33): error TS1128: Declaration or statement expected.
203
+ ../../node_modules/@types/node/globals.d.ts(250,10): error TS1005: ';' expected.
204
+ ../../node_modules/@types/node/globals.d.ts(250,13): error TS1434: Unexpected keyword or identifier.
205
+ ../../node_modules/@types/node/globals.d.ts(251,10): error TS1161: Unterminated regular expression literal.
206
+ ../../node_modules/@types/node/globals.d.ts(252,10): error TS1161: Unterminated regular expression literal.
207
+ ../../node_modules/@types/node/globals.d.ts(253,10): error TS1161: Unterminated regular expression literal.
208
+ ../../node_modules/@types/node/globals.d.ts(254,17): error TS1128: Declaration or statement expected.
209
+ ../../node_modules/@types/node/globals.d.ts(254,18): error TS1128: Declaration or statement expected.
210
+ ../../node_modules/@types/node/globals.d.ts(255,2): error TS1110: Type expected.
211
+ ../../node_modules/@types/node/globals.d.ts(256,6): error TS1161: Unterminated regular expression literal.
212
+ ../../node_modules/@types/node/globals.d.ts(257,5): error TS1128: Declaration or statement expected.
213
+ ../../node_modules/@types/node/globals.d.ts(258,1): error TS1128: Declaration or statement expected.
package/tsconfig.json CHANGED
@@ -8,7 +8,14 @@
8
8
  "esModuleInterop": true,
9
9
  "skipLibCheck": true,
10
10
  "forceConsistentCasingInFileNames": true,
11
- "baseUrl": "."
11
+ "baseUrl": ".",
12
+ "lib": [
13
+ "ES2020",
14
+ "DOM"
15
+ ],
16
+ "types": [
17
+ "node"
18
+ ]
12
19
  },
13
20
  "include": [
14
21
  "src"