waitkit 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/{index-BinqFLs8.d.cts → index-3alZWsam.d.cts} +1 -1
- package/dist/{index-BinqFLs8.d.ts → index-3alZWsam.d.ts} +1 -1
- package/dist/index.cjs +19 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +19 -3
- package/dist/index.js.map +1 -1
- package/dist/react.d.cts +1 -1
- package/dist/react.d.ts +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -62,6 +62,8 @@ function WaitlistForm() {
|
|
|
62
62
|
| `baseUrl` | `string` | `https://waitkit.dev` | API base URL |
|
|
63
63
|
| `source` | `string` | `landing-page` | Default source for all signups |
|
|
64
64
|
|
|
65
|
+
> **Browser-only:** `wk.subscribers.create()` must be called from the browser (it throws if called in a server environment). Call it from an event handler, `useEffect`, or any `"use client"` code path. `wk.subscribers.count()` is safe to call server-side.
|
|
66
|
+
|
|
65
67
|
### `wk.subscribers.create(options)`
|
|
66
68
|
|
|
67
69
|
| Param | Type | Required | Description |
|
|
@@ -36,7 +36,7 @@ declare class SubscribersResource {
|
|
|
36
36
|
count(projectSlug?: string): Promise<number>;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
declare const DEFAULT_BASE_URL = "https://waitkit.dev";
|
|
39
|
+
declare const DEFAULT_BASE_URL = "https://api.waitkit.dev";
|
|
40
40
|
declare class WaitKit {
|
|
41
41
|
subscribers: SubscribersResource;
|
|
42
42
|
private client;
|
|
@@ -36,7 +36,7 @@ declare class SubscribersResource {
|
|
|
36
36
|
count(projectSlug?: string): Promise<number>;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
declare const DEFAULT_BASE_URL = "https://waitkit.dev";
|
|
39
|
+
declare const DEFAULT_BASE_URL = "https://api.waitkit.dev";
|
|
40
40
|
declare class WaitKit {
|
|
41
41
|
subscribers: SubscribersResource;
|
|
42
42
|
private client;
|
package/dist/index.cjs
CHANGED
|
@@ -94,9 +94,25 @@ var SubscribersResource = class {
|
|
|
94
94
|
return { Authorization: `Bearer ${this.apiKey}` };
|
|
95
95
|
}
|
|
96
96
|
async create(options) {
|
|
97
|
+
if (typeof window === "undefined") {
|
|
98
|
+
throw new WaitKitError(
|
|
99
|
+
`WaitKit: subscribers.create() can only be called from the browser.
|
|
100
|
+
|
|
101
|
+
A server-side call was detected (window is undefined). The join endpoint collects
|
|
102
|
+
signups directly in the browser; calling it from a server (Next.js Server Component,
|
|
103
|
+
Server Action, Route Handler, or Node.js) would expose your API key.
|
|
104
|
+
|
|
105
|
+
To fix this:
|
|
106
|
+
- Add "use client" at the top of the file, or
|
|
107
|
+
- Call wk.subscribers.create() from an event handler or useEffect (client-only), or
|
|
108
|
+
- In Next.js, keep the key in a NEXT_PUBLIC_* env var so it only reaches the browser.
|
|
109
|
+
|
|
110
|
+
wk.subscribers.count() is safe to call server-side.`
|
|
111
|
+
);
|
|
112
|
+
}
|
|
97
113
|
const data = await this.client.request(
|
|
98
114
|
"POST",
|
|
99
|
-
`/
|
|
115
|
+
`/v1/waitlist/${this.projectSlug}/join`,
|
|
100
116
|
{
|
|
101
117
|
headers: this.headers,
|
|
102
118
|
body: {
|
|
@@ -114,7 +130,7 @@ var SubscribersResource = class {
|
|
|
114
130
|
const slug = projectSlug ?? this.projectSlug;
|
|
115
131
|
const data = await this.client.request(
|
|
116
132
|
"GET",
|
|
117
|
-
`/
|
|
133
|
+
`/v1/waitlist/${slug}/count`,
|
|
118
134
|
{ headers: this.headers }
|
|
119
135
|
);
|
|
120
136
|
return data.count;
|
|
@@ -122,7 +138,7 @@ var SubscribersResource = class {
|
|
|
122
138
|
};
|
|
123
139
|
|
|
124
140
|
// src/index.ts
|
|
125
|
-
var DEFAULT_BASE_URL = "https://waitkit.dev";
|
|
141
|
+
var DEFAULT_BASE_URL = "https://api.waitkit.dev";
|
|
126
142
|
var WaitKit = class {
|
|
127
143
|
subscribers;
|
|
128
144
|
client;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/client.ts","../src/resources/subscribers.ts"],"sourcesContent":["import { HttpClient } from \"./client\";\nimport { SubscribersResource } from \"./resources/subscribers\";\nimport type { WaitKitConfig } from \"./types\";\n\nexport const DEFAULT_BASE_URL = \"https://waitkit.dev\";\n\nexport class WaitKit {\n subscribers: SubscribersResource;\n private client: HttpClient;\n private apiKey: string;\n private projectSlug: string;\n\n constructor(config: WaitKitConfig) {\n this.apiKey = config.apiKey;\n this.projectSlug = config.projectSlug;\n this.client = new HttpClient(config.baseUrl ?? DEFAULT_BASE_URL);\n this.subscribers = new SubscribersResource(\n this.client,\n this.apiKey,\n this.projectSlug,\n config.source,\n );\n }\n}\n","import type { ErrorResponse } from \"./types\";\n\nexport class WaitKitError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n public issues?: Array<{ path: string; message: string }>,\n ) {\n super(message);\n this.name = \"WaitKitError\";\n }\n\n static fromResponse(res: ErrorResponse): WaitKitError {\n return new WaitKitError(res.message, res.statusCode, res.issues);\n }\n}\n","import type { ApiResponse, ErrorResponse, SuccessResponse } from \"./types\";\nimport { WaitKitError } from \"./errors\";\n\nexport class HttpClient {\n private baseUrl: string;\n\n constructor(baseUrl: string) {\n this.baseUrl = baseUrl.replace(/\\/+$/, \"\");\n }\n\n async request<T>(\n method: string,\n path: string,\n options: {\n headers?: Record<string, string>;\n body?: unknown;\n query?: Record<string, string | number | undefined>;\n } = {},\n ): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`);\n\n if (options.query) {\n for (const [key, value] of Object.entries(options.query)) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n const res = await fetch(url.toString(), {\n method,\n headers: {\n \"Content-Type\": \"application/json\",\n ...options.headers,\n },\n body: options.body ? JSON.stringify(options.body) : undefined,\n });\n\n const json: ApiResponse<T> = await res.json();\n\n if (!res.ok || json.status === \"error\") {\n const err = json as ErrorResponse;\n throw WaitKitError.fromResponse(err);\n }\n\n return (json as SuccessResponse<T>).data;\n }\n}\n","import { HttpClient } from \"../client\";\nimport type { JoinOptions, JoinResult } from \"../types\";\n\nconst DEFAULT_SOURCE = \"landing-page\";\n\nfunction getSourceFromUrl(): string | null {\n if (typeof window === \"undefined\") return null;\n const params = new URLSearchParams(window.location.search);\n return params.get(\"source\") || params.get(\"s\") || null;\n}\n\nexport class SubscribersResource {\n private client: HttpClient;\n private apiKey: string;\n private projectSlug: string;\n private defaultSource: string;\n\n constructor(\n client: HttpClient,\n apiKey: string,\n projectSlug: string,\n defaultSource?: string,\n ) {\n this.client = client;\n this.apiKey = apiKey;\n this.projectSlug = projectSlug;\n this.defaultSource = defaultSource ?? DEFAULT_SOURCE;\n }\n\n private get headers() {\n return { Authorization: `Bearer ${this.apiKey}` };\n }\n\n async create(options: JoinOptions): Promise<JoinResult> {\n const data = await this.client.request<{ email: string }>(\n \"POST\",\n `/
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/client.ts","../src/resources/subscribers.ts"],"sourcesContent":["import { HttpClient } from \"./client\";\nimport { SubscribersResource } from \"./resources/subscribers\";\nimport type { WaitKitConfig } from \"./types\";\n\nexport const DEFAULT_BASE_URL = \"https://api.waitkit.dev\";\n\nexport class WaitKit {\n subscribers: SubscribersResource;\n private client: HttpClient;\n private apiKey: string;\n private projectSlug: string;\n\n constructor(config: WaitKitConfig) {\n this.apiKey = config.apiKey;\n this.projectSlug = config.projectSlug;\n this.client = new HttpClient(config.baseUrl ?? DEFAULT_BASE_URL);\n this.subscribers = new SubscribersResource(\n this.client,\n this.apiKey,\n this.projectSlug,\n config.source,\n );\n }\n}\n","import type { ErrorResponse } from \"./types\";\n\nexport class WaitKitError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n public issues?: Array<{ path: string; message: string }>,\n ) {\n super(message);\n this.name = \"WaitKitError\";\n }\n\n static fromResponse(res: ErrorResponse): WaitKitError {\n return new WaitKitError(res.message, res.statusCode, res.issues);\n }\n}\n","import type { ApiResponse, ErrorResponse, SuccessResponse } from \"./types\";\nimport { WaitKitError } from \"./errors\";\n\nexport class HttpClient {\n private baseUrl: string;\n\n constructor(baseUrl: string) {\n this.baseUrl = baseUrl.replace(/\\/+$/, \"\");\n }\n\n async request<T>(\n method: string,\n path: string,\n options: {\n headers?: Record<string, string>;\n body?: unknown;\n query?: Record<string, string | number | undefined>;\n } = {},\n ): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`);\n\n if (options.query) {\n for (const [key, value] of Object.entries(options.query)) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n const res = await fetch(url.toString(), {\n method,\n headers: {\n \"Content-Type\": \"application/json\",\n ...options.headers,\n },\n body: options.body ? JSON.stringify(options.body) : undefined,\n });\n\n const json: ApiResponse<T> = await res.json();\n\n if (!res.ok || json.status === \"error\") {\n const err = json as ErrorResponse;\n throw WaitKitError.fromResponse(err);\n }\n\n return (json as SuccessResponse<T>).data;\n }\n}\n","import { HttpClient } from \"../client\";\nimport { WaitKitError } from \"../errors\";\nimport type { JoinOptions, JoinResult } from \"../types\";\n\nconst DEFAULT_SOURCE = \"landing-page\";\n\nfunction getSourceFromUrl(): string | null {\n if (typeof window === \"undefined\") return null;\n const params = new URLSearchParams(window.location.search);\n return params.get(\"source\") || params.get(\"s\") || null;\n}\n\nexport class SubscribersResource {\n private client: HttpClient;\n private apiKey: string;\n private projectSlug: string;\n private defaultSource: string;\n\n constructor(\n client: HttpClient,\n apiKey: string,\n projectSlug: string,\n defaultSource?: string,\n ) {\n this.client = client;\n this.apiKey = apiKey;\n this.projectSlug = projectSlug;\n this.defaultSource = defaultSource ?? DEFAULT_SOURCE;\n }\n\n private get headers() {\n return { Authorization: `Bearer ${this.apiKey}` };\n }\n\n async create(options: JoinOptions): Promise<JoinResult> {\n if (typeof window === \"undefined\") {\n throw new WaitKitError(\n `WaitKit: subscribers.create() can only be called from the browser.\n\nA server-side call was detected (window is undefined). The join endpoint collects\nsignups directly in the browser; calling it from a server (Next.js Server Component,\nServer Action, Route Handler, or Node.js) would expose your API key.\n\nTo fix this:\n- Add \"use client\" at the top of the file, or\n- Call wk.subscribers.create() from an event handler or useEffect (client-only), or\n- In Next.js, keep the key in a NEXT_PUBLIC_* env var so it only reaches the browser.\n\nwk.subscribers.count() is safe to call server-side.`,\n );\n }\n\n const data = await this.client.request<{ email: string }>(\n \"POST\",\n `/v1/waitlist/${this.projectSlug}/join`,\n {\n headers: this.headers,\n body: {\n ...options,\n source: options.source ?? getSourceFromUrl() ?? this.defaultSource,\n },\n },\n );\n\n return {\n message: \"Thank you for joining the waitlist!\",\n email: data.email,\n };\n }\n\n async count(projectSlug?: string): Promise<number> {\n const slug = projectSlug ?? this.projectSlug;\n const data = await this.client.request<{ count: number }>(\n \"GET\",\n `/v1/waitlist/${slug}/count`,\n { headers: this.headers },\n );\n\n return data.count;\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { D as DEFAULT_BASE_URL, W as WaitKit } from './index-
|
|
1
|
+
export { D as DEFAULT_BASE_URL, W as WaitKit } from './index-3alZWsam.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { D as DEFAULT_BASE_URL, W as WaitKit } from './index-
|
|
1
|
+
export { D as DEFAULT_BASE_URL, W as WaitKit } from './index-3alZWsam.js';
|
package/dist/index.js
CHANGED
|
@@ -67,9 +67,25 @@ var SubscribersResource = class {
|
|
|
67
67
|
return { Authorization: `Bearer ${this.apiKey}` };
|
|
68
68
|
}
|
|
69
69
|
async create(options) {
|
|
70
|
+
if (typeof window === "undefined") {
|
|
71
|
+
throw new WaitKitError(
|
|
72
|
+
`WaitKit: subscribers.create() can only be called from the browser.
|
|
73
|
+
|
|
74
|
+
A server-side call was detected (window is undefined). The join endpoint collects
|
|
75
|
+
signups directly in the browser; calling it from a server (Next.js Server Component,
|
|
76
|
+
Server Action, Route Handler, or Node.js) would expose your API key.
|
|
77
|
+
|
|
78
|
+
To fix this:
|
|
79
|
+
- Add "use client" at the top of the file, or
|
|
80
|
+
- Call wk.subscribers.create() from an event handler or useEffect (client-only), or
|
|
81
|
+
- In Next.js, keep the key in a NEXT_PUBLIC_* env var so it only reaches the browser.
|
|
82
|
+
|
|
83
|
+
wk.subscribers.count() is safe to call server-side.`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
70
86
|
const data = await this.client.request(
|
|
71
87
|
"POST",
|
|
72
|
-
`/
|
|
88
|
+
`/v1/waitlist/${this.projectSlug}/join`,
|
|
73
89
|
{
|
|
74
90
|
headers: this.headers,
|
|
75
91
|
body: {
|
|
@@ -87,7 +103,7 @@ var SubscribersResource = class {
|
|
|
87
103
|
const slug = projectSlug ?? this.projectSlug;
|
|
88
104
|
const data = await this.client.request(
|
|
89
105
|
"GET",
|
|
90
|
-
`/
|
|
106
|
+
`/v1/waitlist/${slug}/count`,
|
|
91
107
|
{ headers: this.headers }
|
|
92
108
|
);
|
|
93
109
|
return data.count;
|
|
@@ -95,7 +111,7 @@ var SubscribersResource = class {
|
|
|
95
111
|
};
|
|
96
112
|
|
|
97
113
|
// src/index.ts
|
|
98
|
-
var DEFAULT_BASE_URL = "https://waitkit.dev";
|
|
114
|
+
var DEFAULT_BASE_URL = "https://api.waitkit.dev";
|
|
99
115
|
var WaitKit = class {
|
|
100
116
|
subscribers;
|
|
101
117
|
client;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/resources/subscribers.ts","../src/index.ts"],"sourcesContent":["import type { ErrorResponse } from \"./types\";\n\nexport class WaitKitError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n public issues?: Array<{ path: string; message: string }>,\n ) {\n super(message);\n this.name = \"WaitKitError\";\n }\n\n static fromResponse(res: ErrorResponse): WaitKitError {\n return new WaitKitError(res.message, res.statusCode, res.issues);\n }\n}\n","import type { ApiResponse, ErrorResponse, SuccessResponse } from \"./types\";\nimport { WaitKitError } from \"./errors\";\n\nexport class HttpClient {\n private baseUrl: string;\n\n constructor(baseUrl: string) {\n this.baseUrl = baseUrl.replace(/\\/+$/, \"\");\n }\n\n async request<T>(\n method: string,\n path: string,\n options: {\n headers?: Record<string, string>;\n body?: unknown;\n query?: Record<string, string | number | undefined>;\n } = {},\n ): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`);\n\n if (options.query) {\n for (const [key, value] of Object.entries(options.query)) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n const res = await fetch(url.toString(), {\n method,\n headers: {\n \"Content-Type\": \"application/json\",\n ...options.headers,\n },\n body: options.body ? JSON.stringify(options.body) : undefined,\n });\n\n const json: ApiResponse<T> = await res.json();\n\n if (!res.ok || json.status === \"error\") {\n const err = json as ErrorResponse;\n throw WaitKitError.fromResponse(err);\n }\n\n return (json as SuccessResponse<T>).data;\n }\n}\n","import { HttpClient } from \"../client\";\nimport type { JoinOptions, JoinResult } from \"../types\";\n\nconst DEFAULT_SOURCE = \"landing-page\";\n\nfunction getSourceFromUrl(): string | null {\n if (typeof window === \"undefined\") return null;\n const params = new URLSearchParams(window.location.search);\n return params.get(\"source\") || params.get(\"s\") || null;\n}\n\nexport class SubscribersResource {\n private client: HttpClient;\n private apiKey: string;\n private projectSlug: string;\n private defaultSource: string;\n\n constructor(\n client: HttpClient,\n apiKey: string,\n projectSlug: string,\n defaultSource?: string,\n ) {\n this.client = client;\n this.apiKey = apiKey;\n this.projectSlug = projectSlug;\n this.defaultSource = defaultSource ?? DEFAULT_SOURCE;\n }\n\n private get headers() {\n return { Authorization: `Bearer ${this.apiKey}` };\n }\n\n async create(options: JoinOptions): Promise<JoinResult> {\n const data = await this.client.request<{ email: string }>(\n \"POST\",\n `/
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/client.ts","../src/resources/subscribers.ts","../src/index.ts"],"sourcesContent":["import type { ErrorResponse } from \"./types\";\n\nexport class WaitKitError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n public issues?: Array<{ path: string; message: string }>,\n ) {\n super(message);\n this.name = \"WaitKitError\";\n }\n\n static fromResponse(res: ErrorResponse): WaitKitError {\n return new WaitKitError(res.message, res.statusCode, res.issues);\n }\n}\n","import type { ApiResponse, ErrorResponse, SuccessResponse } from \"./types\";\nimport { WaitKitError } from \"./errors\";\n\nexport class HttpClient {\n private baseUrl: string;\n\n constructor(baseUrl: string) {\n this.baseUrl = baseUrl.replace(/\\/+$/, \"\");\n }\n\n async request<T>(\n method: string,\n path: string,\n options: {\n headers?: Record<string, string>;\n body?: unknown;\n query?: Record<string, string | number | undefined>;\n } = {},\n ): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`);\n\n if (options.query) {\n for (const [key, value] of Object.entries(options.query)) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n const res = await fetch(url.toString(), {\n method,\n headers: {\n \"Content-Type\": \"application/json\",\n ...options.headers,\n },\n body: options.body ? JSON.stringify(options.body) : undefined,\n });\n\n const json: ApiResponse<T> = await res.json();\n\n if (!res.ok || json.status === \"error\") {\n const err = json as ErrorResponse;\n throw WaitKitError.fromResponse(err);\n }\n\n return (json as SuccessResponse<T>).data;\n }\n}\n","import { HttpClient } from \"../client\";\nimport { WaitKitError } from \"../errors\";\nimport type { JoinOptions, JoinResult } from \"../types\";\n\nconst DEFAULT_SOURCE = \"landing-page\";\n\nfunction getSourceFromUrl(): string | null {\n if (typeof window === \"undefined\") return null;\n const params = new URLSearchParams(window.location.search);\n return params.get(\"source\") || params.get(\"s\") || null;\n}\n\nexport class SubscribersResource {\n private client: HttpClient;\n private apiKey: string;\n private projectSlug: string;\n private defaultSource: string;\n\n constructor(\n client: HttpClient,\n apiKey: string,\n projectSlug: string,\n defaultSource?: string,\n ) {\n this.client = client;\n this.apiKey = apiKey;\n this.projectSlug = projectSlug;\n this.defaultSource = defaultSource ?? DEFAULT_SOURCE;\n }\n\n private get headers() {\n return { Authorization: `Bearer ${this.apiKey}` };\n }\n\n async create(options: JoinOptions): Promise<JoinResult> {\n if (typeof window === \"undefined\") {\n throw new WaitKitError(\n `WaitKit: subscribers.create() can only be called from the browser.\n\nA server-side call was detected (window is undefined). The join endpoint collects\nsignups directly in the browser; calling it from a server (Next.js Server Component,\nServer Action, Route Handler, or Node.js) would expose your API key.\n\nTo fix this:\n- Add \"use client\" at the top of the file, or\n- Call wk.subscribers.create() from an event handler or useEffect (client-only), or\n- In Next.js, keep the key in a NEXT_PUBLIC_* env var so it only reaches the browser.\n\nwk.subscribers.count() is safe to call server-side.`,\n );\n }\n\n const data = await this.client.request<{ email: string }>(\n \"POST\",\n `/v1/waitlist/${this.projectSlug}/join`,\n {\n headers: this.headers,\n body: {\n ...options,\n source: options.source ?? getSourceFromUrl() ?? this.defaultSource,\n },\n },\n );\n\n return {\n message: \"Thank you for joining the waitlist!\",\n email: data.email,\n };\n }\n\n async count(projectSlug?: string): Promise<number> {\n const slug = projectSlug ?? this.projectSlug;\n const data = await this.client.request<{ count: number }>(\n \"GET\",\n `/v1/waitlist/${slug}/count`,\n { headers: this.headers },\n );\n\n return data.count;\n }\n}\n","import { HttpClient } from \"./client\";\nimport { SubscribersResource } from \"./resources/subscribers\";\nimport type { WaitKitConfig } from \"./types\";\n\nexport const DEFAULT_BASE_URL = \"https://api.waitkit.dev\";\n\nexport class WaitKit {\n subscribers: SubscribersResource;\n private client: HttpClient;\n private apiKey: string;\n private projectSlug: string;\n\n constructor(config: WaitKitConfig) {\n this.apiKey = config.apiKey;\n this.projectSlug = config.projectSlug;\n this.client = new HttpClient(config.baseUrl ?? DEFAULT_BASE_URL);\n this.subscribers = new SubscribersResource(\n this.client,\n this.apiKey,\n this.projectSlug,\n config.source,\n );\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/react.d.cts
CHANGED
package/dist/react.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "waitkit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "WaitKit SDK — waitlist infrastructure for your app",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"waitkit",
|
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
"subscribers"
|
|
13
13
|
],
|
|
14
14
|
"license": "ISC",
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
15
18
|
"author": {
|
|
16
19
|
"name": "ubeyidah",
|
|
17
20
|
"url": "https://github.com/ubeyidah"
|
|
@@ -41,9 +44,6 @@
|
|
|
41
44
|
"main": "./dist/index.cjs",
|
|
42
45
|
"module": "./dist/index.js",
|
|
43
46
|
"types": "./dist/index.d.ts",
|
|
44
|
-
"files": [
|
|
45
|
-
"dist"
|
|
46
|
-
],
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"react": "^18.0.0 || ^19.0.0"
|
|
49
49
|
},
|