@plung/sdk 0.2.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/CHANGELOG.md ADDED
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ ## v0.2.0 - 2026-04-05
4
+
5
+ - Renamed the published SDK package from `trimz` to `@plung/sdk`.
6
+ - Updated the default production API base URL to `https://api.plung.co`.
7
+ - Updated SDK examples and short-link fixtures to use `https://plu.ng/...`.
8
+ - Updated release tooling and package metadata for the Plung org-scoped npm package.
9
+
10
+ ## v0.1.0 - 2026-03-27
11
+
12
+ - Added `links.create()` for single-link creation with typed `{ data, meta }` responses.
13
+ - Added `links.batchCreate()` with partial-success support and typed `{ data, meta }` responses.
14
+ - Added `qr.get()` for QR code retrieval with binary data, content type metadata, and response metadata.
15
+ - Added `analytics.get()` for typed link statistics retrieval.
16
+ - Added typed error classes for authentication, validation, not found, gone, forbidden, and rate-limit failures.
package/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # Plung TypeScript SDK
2
+
3
+ Official TypeScript SDK for the Plung API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @plung/sdk
9
+ ```
10
+
11
+ ## Quick start
12
+
13
+ ```ts
14
+ import { PlungClient } from '@plung/sdk';
15
+
16
+ const client = new PlungClient(process.env.PLUNG_API_KEY!);
17
+
18
+ const { data, meta } = await client.links.create({
19
+ url: 'https://example.com',
20
+ });
21
+
22
+ console.log(data.shortUrl);
23
+ console.log(meta.rateLimit.remaining);
24
+ ```
25
+
26
+ Example response shape:
27
+
28
+ ```ts
29
+ {
30
+ data: {
31
+ shortUrl: 'https://plu.ng/hello-world',
32
+ shortCode: 'hello-world',
33
+ url: 'https://example.com',
34
+ createdAt: '2026-03-27T00:00:00.000Z'
35
+ },
36
+ meta: {
37
+ apiKeyName: 'primary',
38
+ rateLimit: {
39
+ limit: 100,
40
+ remaining: 99,
41
+ reset: 1710000000
42
+ },
43
+ plan: 'PRO',
44
+ usage: {
45
+ apiCallsUsed: 1,
46
+ apiCallsLimit: 1000,
47
+ apiCallsRemaining: 999,
48
+ reset: 1775001600
49
+ }
50
+ }
51
+ }
52
+ ```
53
+
54
+ ## Available methods
55
+
56
+ | Resource | Method | Signature |
57
+ | --- | --- | --- |
58
+ | Links | `links.create` | `(input: CreateLinkInput) => Promise<PlungResponse<Link>>` |
59
+ | Links | `links.batchCreate` | `(items: CreateLinkInput[]) => Promise<PlungResponse<BatchCreateResponse>>` |
60
+ | QR | `qr.get` | `(shortCode: string, options?: QrOptions) => Promise<QrResponse>` |
61
+ | Analytics | `analytics.get` | `(shortCode: string) => Promise<PlungResponse<LinkStats>>` |
62
+
63
+ ## Error handling
64
+
65
+ ```ts
66
+ import {
67
+ PlungAuthError,
68
+ PlungRateLimitError,
69
+ PlungValidationError,
70
+ PlungClient,
71
+ } from '@plung/sdk';
72
+
73
+ const client = new PlungClient(process.env.PLUNG_API_KEY!);
74
+
75
+ try {
76
+ await client.links.create({ url: 'not-a-valid-url' });
77
+ } catch (error) {
78
+ if (error instanceof PlungValidationError) {
79
+ console.log('Validation failed:', error.message);
80
+ } else if (error instanceof PlungAuthError) {
81
+ console.log('Authentication failed:', error.message);
82
+ } else if (error instanceof PlungRateLimitError) {
83
+ console.log('Rate limited:', error.retryAfter);
84
+ }
85
+ }
86
+ ```
87
+
88
+ ## Response metadata
89
+
90
+ Every successful SDK response includes a `meta` object.
91
+
92
+ - `meta.apiKeyName`: API key label returned by the backend, when available.
93
+ - `meta.rateLimit.limit`: Current rate-limit ceiling for the authenticated key.
94
+ - `meta.rateLimit.remaining`: Remaining requests in the current rate-limit window.
95
+ - `meta.rateLimit.reset`: Unix timestamp in seconds for the rate-limit reset time.
96
+ - `meta.plan`: Current Plung plan identifier returned by the backend.
97
+ - `meta.usage.apiCallsUsed`: API calls already used in the current billing period.
98
+ - `meta.usage.apiCallsLimit`: API call limit for the current billing period, when finite.
99
+ - `meta.usage.apiCallsRemaining`: Remaining API calls for the current billing period, when finite.
100
+ - `meta.usage.reset`: Unix timestamp in seconds for the next usage reset time.
101
+
102
+ ## Requirements
103
+
104
+ - Node `>=24.14.1`
@@ -0,0 +1,128 @@
1
+ import { AxiosInstance } from 'axios';
2
+
3
+ interface CreateLinkInput {
4
+ url: string;
5
+ alias?: string;
6
+ password?: string;
7
+ expiresIn?: number;
8
+ maxClicks?: number;
9
+ }
10
+ interface Link {
11
+ shortUrl: string;
12
+ shortCode: string;
13
+ url: string;
14
+ createdAt: string;
15
+ alias?: string;
16
+ expiresAt?: string;
17
+ maxClicks?: number;
18
+ }
19
+ interface BatchCreateResult {
20
+ index: number;
21
+ success: boolean;
22
+ shortUrl?: string;
23
+ shortCode?: string;
24
+ url?: string;
25
+ alias?: string;
26
+ expiresAt?: string;
27
+ maxClicks?: number;
28
+ error?: string;
29
+ }
30
+ interface BatchCreateResponse {
31
+ results: BatchCreateResult[];
32
+ }
33
+
34
+ interface LinkStats {
35
+ shortCode: string;
36
+ url: string;
37
+ clickCount: number;
38
+ createdAt: string;
39
+ lastAccessed?: string | null;
40
+ expiresAt?: string | null;
41
+ maxClicks?: number | null;
42
+ }
43
+
44
+ interface PlungMeta {
45
+ apiKeyName?: string;
46
+ rateLimit: {
47
+ limit?: number;
48
+ remaining?: number;
49
+ reset?: number;
50
+ };
51
+ plan?: string;
52
+ usage: {
53
+ apiCallsUsed?: number;
54
+ apiCallsLimit?: number;
55
+ apiCallsRemaining?: number;
56
+ reset?: number;
57
+ };
58
+ }
59
+ interface PlungResponse<T> {
60
+ data: T;
61
+ meta: PlungMeta;
62
+ }
63
+ type QrFormat = 'png' | 'svg';
64
+ interface QrOptions {
65
+ format?: QrFormat;
66
+ size?: number;
67
+ }
68
+ interface QrResponse {
69
+ data: ArrayBuffer;
70
+ contentType: 'image/png' | 'image/svg+xml';
71
+ meta: PlungMeta;
72
+ }
73
+
74
+ declare class AnalyticsResource {
75
+ private readonly http;
76
+ constructor(http: AxiosInstance);
77
+ get(shortCode: string): Promise<PlungResponse<LinkStats>>;
78
+ }
79
+
80
+ declare class LinksResource {
81
+ private readonly http;
82
+ constructor(http: AxiosInstance);
83
+ create(input: CreateLinkInput): Promise<PlungResponse<Link>>;
84
+ batchCreate(items: CreateLinkInput[]): Promise<PlungResponse<BatchCreateResponse>>;
85
+ }
86
+
87
+ declare class QrResource {
88
+ private readonly http;
89
+ constructor(http: AxiosInstance);
90
+ get(shortCode: string, options?: QrOptions): Promise<QrResponse>;
91
+ }
92
+
93
+ declare class PlungClient {
94
+ readonly links: LinksResource;
95
+ readonly qr: QrResource;
96
+ readonly analytics: AnalyticsResource;
97
+ private readonly http;
98
+ constructor(apiKey: string, options?: {
99
+ baseURL?: string;
100
+ timeout?: number;
101
+ });
102
+ }
103
+
104
+ declare class PlungError extends Error {
105
+ readonly statusCode: number;
106
+ constructor(message: string, statusCode: number);
107
+ }
108
+ declare class PlungAuthError extends PlungError {
109
+ constructor(message?: string);
110
+ }
111
+ declare class PlungForbiddenError extends PlungError {
112
+ constructor(message?: string);
113
+ }
114
+ declare class PlungNotFoundError extends PlungError {
115
+ constructor(message?: string);
116
+ }
117
+ declare class PlungGoneError extends PlungError {
118
+ constructor(message?: string);
119
+ }
120
+ declare class PlungRateLimitError extends PlungError {
121
+ readonly retryAfter?: number;
122
+ constructor(message?: string, retryAfter?: number);
123
+ }
124
+ declare class PlungValidationError extends PlungError {
125
+ constructor(message?: string);
126
+ }
127
+
128
+ export { AnalyticsResource, type BatchCreateResponse, type BatchCreateResult, type CreateLinkInput, type Link, type LinkStats, LinksResource, PlungAuthError, PlungClient, PlungError, PlungForbiddenError, PlungGoneError, type PlungMeta, PlungNotFoundError, PlungRateLimitError, type PlungResponse, PlungValidationError, type QrFormat, type QrOptions, QrResource, type QrResponse };
package/dist/index.js ADDED
@@ -0,0 +1,401 @@
1
+ import axios, { AxiosHeaders } from 'axios';
2
+
3
+ // src/http/axios.ts
4
+
5
+ // src/errors/index.ts
6
+ var PlungError = class extends Error {
7
+ statusCode;
8
+ constructor(message, statusCode) {
9
+ super(message);
10
+ this.name = new.target.name;
11
+ this.message = message;
12
+ this.statusCode = statusCode;
13
+ Object.setPrototypeOf(this, new.target.prototype);
14
+ }
15
+ };
16
+ var PlungAuthError = class extends PlungError {
17
+ constructor(message = "Authentication failed") {
18
+ super(message, 401);
19
+ }
20
+ };
21
+ var PlungForbiddenError = class extends PlungError {
22
+ constructor(message = "Forbidden") {
23
+ super(message, 403);
24
+ }
25
+ };
26
+ var PlungNotFoundError = class extends PlungError {
27
+ constructor(message = "Not found") {
28
+ super(message, 404);
29
+ }
30
+ };
31
+ var PlungGoneError = class extends PlungError {
32
+ constructor(message = "Resource is no longer available") {
33
+ super(message, 410);
34
+ }
35
+ };
36
+ var PlungRateLimitError = class extends PlungError {
37
+ retryAfter;
38
+ constructor(message = "Rate limit exceeded", retryAfter) {
39
+ super(message, 429);
40
+ if (retryAfter !== void 0) {
41
+ this.retryAfter = retryAfter;
42
+ }
43
+ }
44
+ };
45
+ var PlungValidationError = class extends PlungError {
46
+ constructor(message = "Validation failed") {
47
+ super(message, 400);
48
+ }
49
+ };
50
+
51
+ // src/http/axios.ts
52
+ var DEFAULT_BASE_URL = "https://api.plung.co";
53
+ var DEFAULT_TIMEOUT = 1e4;
54
+ function getHeaderValue(response, headerName) {
55
+ const responseHeaders = response.headers;
56
+ const getter = responseHeaders.get;
57
+ const valueFromGetter = typeof getter === "function" ? getter.call(response.headers, headerName) : void 0;
58
+ const value = valueFromGetter ?? responseHeaders[headerName] ?? responseHeaders[headerName.toLowerCase()];
59
+ if (Array.isArray(value)) {
60
+ return value.find((item) => typeof item === "string");
61
+ }
62
+ return typeof value === "string" ? value : void 0;
63
+ }
64
+ function parseNumberHeader(response, headerName) {
65
+ const value = getHeaderValue(response, headerName);
66
+ if (!value) {
67
+ return void 0;
68
+ }
69
+ const parsed = Number.parseInt(value, 10);
70
+ return Number.isNaN(parsed) ? void 0 : parsed;
71
+ }
72
+ function parseMetadata(response) {
73
+ const metadata = {};
74
+ const apiKeyName = getHeaderValue(response, "x-api-key-name");
75
+ if (apiKeyName) {
76
+ metadata.apiKeyName = apiKeyName;
77
+ }
78
+ const rateLimitLimit = parseNumberHeader(response, "x-ratelimit-limit");
79
+ if (rateLimitLimit !== void 0) {
80
+ metadata.rateLimitLimit = rateLimitLimit;
81
+ }
82
+ const rateLimitRemaining = parseNumberHeader(
83
+ response,
84
+ "x-ratelimit-remaining"
85
+ );
86
+ if (rateLimitRemaining !== void 0) {
87
+ metadata.rateLimitRemaining = rateLimitRemaining;
88
+ }
89
+ const rateLimitReset = parseNumberHeader(response, "x-ratelimit-reset");
90
+ if (rateLimitReset !== void 0) {
91
+ metadata.rateLimitReset = rateLimitReset;
92
+ }
93
+ const plan = getHeaderValue(response, "x-plan");
94
+ if (plan) {
95
+ metadata.plan = plan;
96
+ }
97
+ const usageApiCallsUsed = parseNumberHeader(
98
+ response,
99
+ "x-usage-apicalls-used"
100
+ );
101
+ if (usageApiCallsUsed !== void 0) {
102
+ metadata.usageApiCallsUsed = usageApiCallsUsed;
103
+ }
104
+ const usageApiCallsLimit = parseNumberHeader(
105
+ response,
106
+ "x-usage-apicalls-limit"
107
+ );
108
+ if (usageApiCallsLimit !== void 0) {
109
+ metadata.usageApiCallsLimit = usageApiCallsLimit;
110
+ }
111
+ const usageApiCallsRemaining = parseNumberHeader(
112
+ response,
113
+ "x-usage-apicalls-remaining"
114
+ );
115
+ if (usageApiCallsRemaining !== void 0) {
116
+ metadata.usageApiCallsRemaining = usageApiCallsRemaining;
117
+ }
118
+ const usageReset = getHeaderValue(response, "x-usage-reset");
119
+ if (usageReset) {
120
+ metadata.usageReset = usageReset;
121
+ }
122
+ return metadata;
123
+ }
124
+ function attachMetadata(response) {
125
+ return Object.assign(response, {
126
+ metadata: parseMetadata(response)
127
+ });
128
+ }
129
+ function normalizeErrorMessage(error) {
130
+ const fallbackMessage = error.response?.statusText?.trim() || "Request failed";
131
+ const responseData = error.response?.data;
132
+ if (!responseData || typeof responseData !== "object") {
133
+ return fallbackMessage;
134
+ }
135
+ const message = responseData.message;
136
+ if (typeof message === "string" && message.trim() !== "") {
137
+ return message;
138
+ }
139
+ if (Array.isArray(message)) {
140
+ const messages = message.filter(
141
+ (item) => typeof item === "string" && item.trim() !== ""
142
+ );
143
+ if (messages.length > 0) {
144
+ return messages.join("; ");
145
+ }
146
+ }
147
+ return fallbackMessage;
148
+ }
149
+ function parseRetryAfter(error) {
150
+ const response = error.response;
151
+ if (!response) {
152
+ return void 0;
153
+ }
154
+ const value = getHeaderValue(response, "retry-after");
155
+ if (!value) {
156
+ return void 0;
157
+ }
158
+ const seconds = Number.parseInt(value, 10);
159
+ if (!Number.isNaN(seconds)) {
160
+ return seconds;
161
+ }
162
+ const retryDate = Date.parse(value);
163
+ if (Number.isNaN(retryDate)) {
164
+ return void 0;
165
+ }
166
+ return Math.max(0, Math.ceil((retryDate - Date.now()) / 1e3));
167
+ }
168
+ function mapHttpError(error) {
169
+ const response = error.response;
170
+ if (!response) {
171
+ return error;
172
+ }
173
+ const message = normalizeErrorMessage(error);
174
+ switch (response.status) {
175
+ case 400:
176
+ return new PlungValidationError(message);
177
+ case 401:
178
+ return new PlungAuthError(message);
179
+ case 403:
180
+ return new PlungForbiddenError(message);
181
+ case 404:
182
+ return new PlungNotFoundError(message);
183
+ case 410:
184
+ return new PlungGoneError(message);
185
+ case 429:
186
+ return new PlungRateLimitError(message, parseRetryAfter(error));
187
+ default:
188
+ return new PlungError(message, response.status);
189
+ }
190
+ }
191
+ function createAxios(apiKey, options = {}) {
192
+ const instance = axios.create({
193
+ baseURL: options.baseURL ?? DEFAULT_BASE_URL,
194
+ timeout: options.timeout ?? DEFAULT_TIMEOUT
195
+ });
196
+ instance.interceptors.request.use((config) => {
197
+ const headers = AxiosHeaders.from(config.headers);
198
+ headers.set("Authorization", `Bearer ${apiKey}`);
199
+ config.headers = headers;
200
+ return config;
201
+ });
202
+ instance.interceptors.response.use(
203
+ (response) => attachMetadata(response),
204
+ (error) => {
205
+ if (!axios.isAxiosError(error)) {
206
+ return Promise.reject(error);
207
+ }
208
+ return Promise.reject(mapHttpError(error));
209
+ }
210
+ );
211
+ return instance;
212
+ }
213
+
214
+ // src/resources/analytics.ts
215
+ function toEpochSeconds(value) {
216
+ if (!value) {
217
+ return void 0;
218
+ }
219
+ const parsed = Date.parse(value);
220
+ if (Number.isNaN(parsed)) {
221
+ return void 0;
222
+ }
223
+ return Math.floor(parsed / 1e3);
224
+ }
225
+ function mapMeta(metadata) {
226
+ const usageReset = toEpochSeconds(metadata.usageReset);
227
+ return {
228
+ ...metadata.apiKeyName ? { apiKeyName: metadata.apiKeyName } : {},
229
+ rateLimit: {
230
+ ...metadata.rateLimitLimit !== void 0 ? { limit: metadata.rateLimitLimit } : {},
231
+ ...metadata.rateLimitRemaining !== void 0 ? { remaining: metadata.rateLimitRemaining } : {},
232
+ ...metadata.rateLimitReset !== void 0 ? { reset: metadata.rateLimitReset } : {}
233
+ },
234
+ ...metadata.plan ? { plan: metadata.plan } : {},
235
+ usage: {
236
+ ...metadata.usageApiCallsUsed !== void 0 ? { apiCallsUsed: metadata.usageApiCallsUsed } : {},
237
+ ...metadata.usageApiCallsLimit !== void 0 ? { apiCallsLimit: metadata.usageApiCallsLimit } : {},
238
+ ...metadata.usageApiCallsRemaining !== void 0 ? { apiCallsRemaining: metadata.usageApiCallsRemaining } : {},
239
+ ...usageReset !== void 0 ? { reset: usageReset } : {}
240
+ }
241
+ };
242
+ }
243
+ var AnalyticsResource = class {
244
+ constructor(http) {
245
+ this.http = http;
246
+ }
247
+ async get(shortCode) {
248
+ const response = await this.http.get(`/v2/stats/${shortCode}`);
249
+ return {
250
+ data: response.data,
251
+ meta: mapMeta(response.metadata)
252
+ };
253
+ }
254
+ };
255
+
256
+ // src/resources/links.ts
257
+ function toEpochSeconds2(value) {
258
+ if (!value) {
259
+ return void 0;
260
+ }
261
+ const parsed = Date.parse(value);
262
+ if (Number.isNaN(parsed)) {
263
+ return void 0;
264
+ }
265
+ return Math.floor(parsed / 1e3);
266
+ }
267
+ function mapMeta2(metadata) {
268
+ const usageReset = toEpochSeconds2(metadata.usageReset);
269
+ return {
270
+ ...metadata.apiKeyName ? { apiKeyName: metadata.apiKeyName } : {},
271
+ rateLimit: {
272
+ ...metadata.rateLimitLimit !== void 0 ? { limit: metadata.rateLimitLimit } : {},
273
+ ...metadata.rateLimitRemaining !== void 0 ? { remaining: metadata.rateLimitRemaining } : {},
274
+ ...metadata.rateLimitReset !== void 0 ? { reset: metadata.rateLimitReset } : {}
275
+ },
276
+ ...metadata.plan ? { plan: metadata.plan } : {},
277
+ usage: {
278
+ ...metadata.usageApiCallsUsed !== void 0 ? { apiCallsUsed: metadata.usageApiCallsUsed } : {},
279
+ ...metadata.usageApiCallsLimit !== void 0 ? { apiCallsLimit: metadata.usageApiCallsLimit } : {},
280
+ ...metadata.usageApiCallsRemaining !== void 0 ? { apiCallsRemaining: metadata.usageApiCallsRemaining } : {},
281
+ ...usageReset !== void 0 ? { reset: usageReset } : {}
282
+ }
283
+ };
284
+ }
285
+ var LinksResource = class {
286
+ constructor(http) {
287
+ this.http = http;
288
+ }
289
+ async create(input) {
290
+ const response = await this.http.post("/v2/shorten", input);
291
+ return {
292
+ data: response.data,
293
+ meta: mapMeta2(response.metadata)
294
+ };
295
+ }
296
+ async batchCreate(items) {
297
+ const response = await this.http.post("/v2/shorten/batch", { urls: items });
298
+ return {
299
+ data: response.data,
300
+ meta: mapMeta2(response.metadata)
301
+ };
302
+ }
303
+ };
304
+
305
+ // src/resources/qr.ts
306
+ function toEpochSeconds3(value) {
307
+ if (!value) {
308
+ return void 0;
309
+ }
310
+ const parsed = Date.parse(value);
311
+ if (Number.isNaN(parsed)) {
312
+ return void 0;
313
+ }
314
+ return Math.floor(parsed / 1e3);
315
+ }
316
+ function mapMeta3(metadata) {
317
+ const usageReset = toEpochSeconds3(metadata.usageReset);
318
+ return {
319
+ ...metadata.apiKeyName ? { apiKeyName: metadata.apiKeyName } : {},
320
+ rateLimit: {
321
+ ...metadata.rateLimitLimit !== void 0 ? { limit: metadata.rateLimitLimit } : {},
322
+ ...metadata.rateLimitRemaining !== void 0 ? { remaining: metadata.rateLimitRemaining } : {},
323
+ ...metadata.rateLimitReset !== void 0 ? { reset: metadata.rateLimitReset } : {}
324
+ },
325
+ ...metadata.plan ? { plan: metadata.plan } : {},
326
+ usage: {
327
+ ...metadata.usageApiCallsUsed !== void 0 ? { apiCallsUsed: metadata.usageApiCallsUsed } : {},
328
+ ...metadata.usageApiCallsLimit !== void 0 ? { apiCallsLimit: metadata.usageApiCallsLimit } : {},
329
+ ...metadata.usageApiCallsRemaining !== void 0 ? { apiCallsRemaining: metadata.usageApiCallsRemaining } : {},
330
+ ...usageReset !== void 0 ? { reset: usageReset } : {}
331
+ }
332
+ };
333
+ }
334
+ function getHeaderValue2(response, headerName) {
335
+ const responseHeaders = response.headers;
336
+ const getter = responseHeaders.get;
337
+ const valueFromGetter = typeof getter === "function" ? getter.call(response.headers, headerName) : void 0;
338
+ const value = valueFromGetter ?? responseHeaders[headerName] ?? responseHeaders[headerName.toLowerCase()];
339
+ if (Array.isArray(value)) {
340
+ return value.find((item) => typeof item === "string");
341
+ }
342
+ return typeof value === "string" ? value : void 0;
343
+ }
344
+ function normalizeContentType(value) {
345
+ const normalized = value?.toLowerCase();
346
+ if (normalized?.includes("image/svg+xml")) {
347
+ return "image/svg+xml";
348
+ }
349
+ if (normalized?.includes("image/png")) {
350
+ return "image/png";
351
+ }
352
+ return "image/png";
353
+ }
354
+ function toArrayBuffer(data) {
355
+ if (data instanceof ArrayBuffer) {
356
+ return data;
357
+ }
358
+ if (ArrayBuffer.isView(data)) {
359
+ const bytes = new Uint8Array(data.byteLength);
360
+ bytes.set(new Uint8Array(data.buffer, data.byteOffset, data.byteLength));
361
+ return bytes.buffer;
362
+ }
363
+ throw new TypeError("Unexpected QR response body type");
364
+ }
365
+ var QrResource = class {
366
+ constructor(http) {
367
+ this.http = http;
368
+ }
369
+ async get(shortCode, options = {}) {
370
+ const response = await this.http.get(`/v2/qr/${shortCode}`, {
371
+ params: {
372
+ ...options.format !== void 0 ? { format: options.format } : {},
373
+ ...options.size !== void 0 ? { size: options.size } : {}
374
+ },
375
+ responseType: "arraybuffer"
376
+ });
377
+ return {
378
+ data: toArrayBuffer(response.data),
379
+ contentType: normalizeContentType(getHeaderValue2(response, "content-type")),
380
+ meta: mapMeta3(response.metadata)
381
+ };
382
+ }
383
+ };
384
+
385
+ // src/client.ts
386
+ var PlungClient = class {
387
+ links;
388
+ qr;
389
+ analytics;
390
+ http;
391
+ constructor(apiKey, options = {}) {
392
+ this.http = createAxios(apiKey, options);
393
+ this.links = new LinksResource(this.http);
394
+ this.qr = new QrResource(this.http);
395
+ this.analytics = new AnalyticsResource(this.http);
396
+ }
397
+ };
398
+
399
+ export { AnalyticsResource, LinksResource, PlungAuthError, PlungClient, PlungError, PlungForbiddenError, PlungGoneError, PlungNotFoundError, PlungRateLimitError, PlungValidationError, QrResource };
400
+ //# sourceMappingURL=index.js.map
401
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors/index.ts","../src/http/axios.ts","../src/resources/analytics.ts","../src/resources/links.ts","../src/resources/qr.ts","../src/client.ts"],"names":["toEpochSeconds","mapMeta","getHeaderValue"],"mappings":"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","file":"index.js","sourcesContent":["export class PlungError extends Error {\n public readonly statusCode: number;\n\n constructor(message: string, statusCode: number) {\n super(message);\n\n this.name = new.target.name;\n this.message = message;\n this.statusCode = statusCode;\n\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class PlungAuthError extends PlungError {\n constructor(message = 'Authentication failed') {\n super(message, 401);\n }\n}\n\nexport class PlungForbiddenError extends PlungError {\n constructor(message = 'Forbidden') {\n super(message, 403);\n }\n}\n\nexport class PlungNotFoundError extends PlungError {\n constructor(message = 'Not found') {\n super(message, 404);\n }\n}\n\nexport class PlungGoneError extends PlungError {\n constructor(message = 'Resource is no longer available') {\n super(message, 410);\n }\n}\n\nexport class PlungRateLimitError extends PlungError {\n public readonly retryAfter?: number;\n\n constructor(message = 'Rate limit exceeded', retryAfter?: number) {\n super(message, 429);\n\n if (retryAfter !== undefined) {\n this.retryAfter = retryAfter;\n }\n }\n}\n\nexport class PlungValidationError extends PlungError {\n constructor(message = 'Validation failed') {\n super(message, 400);\n }\n}\n","import axios, {\n AxiosHeaders,\n type AxiosError,\n type AxiosInstance,\n type AxiosResponse,\n} from 'axios';\n\nimport {\n PlungAuthError,\n PlungError,\n PlungForbiddenError,\n PlungGoneError,\n PlungNotFoundError,\n PlungRateLimitError,\n PlungValidationError,\n} from '../errors/index.js';\n\nconst DEFAULT_BASE_URL = 'https://api.plung.co';\nconst DEFAULT_TIMEOUT = 10_000;\n\nexport interface CreateAxiosOptions {\n baseURL?: string;\n timeout?: number;\n}\n\nexport interface PlungResponseMeta {\n apiKeyName?: string;\n rateLimitLimit?: number;\n rateLimitRemaining?: number;\n rateLimitReset?: number;\n plan?: string;\n usageApiCallsUsed?: number;\n usageApiCallsLimit?: number;\n usageApiCallsRemaining?: number;\n usageReset?: string;\n}\n\nexport interface PlungResponse<T> {\n data: T;\n meta: PlungResponseMeta;\n}\n\nexport type PlungAxiosResponse<T = unknown, D = unknown> = AxiosResponse<T, D> & {\n metadata: PlungResponseMeta;\n};\n\nfunction getHeaderValue(\n response: AxiosResponse<unknown>,\n headerName: string,\n): string | undefined {\n const responseHeaders = response.headers as Record<string, unknown>;\n const getter = responseHeaders.get;\n\n const valueFromGetter =\n typeof getter === 'function'\n ? getter.call(response.headers, headerName)\n : undefined;\n\n const value =\n valueFromGetter ??\n responseHeaders[headerName] ??\n responseHeaders[headerName.toLowerCase()];\n\n if (Array.isArray(value)) {\n return value.find((item): item is string => typeof item === 'string');\n }\n\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction parseNumberHeader(\n response: AxiosResponse<unknown>,\n headerName: string,\n): number | undefined {\n const value = getHeaderValue(response, headerName);\n\n if (!value) {\n return undefined;\n }\n\n const parsed = Number.parseInt(value, 10);\n\n return Number.isNaN(parsed) ? undefined : parsed;\n}\n\nfunction parseMetadata(response: AxiosResponse<unknown>): PlungResponseMeta {\n const metadata: PlungResponseMeta = {};\n\n const apiKeyName = getHeaderValue(response, 'x-api-key-name');\n if (apiKeyName) {\n metadata.apiKeyName = apiKeyName;\n }\n\n const rateLimitLimit = parseNumberHeader(response, 'x-ratelimit-limit');\n if (rateLimitLimit !== undefined) {\n metadata.rateLimitLimit = rateLimitLimit;\n }\n\n const rateLimitRemaining = parseNumberHeader(\n response,\n 'x-ratelimit-remaining',\n );\n if (rateLimitRemaining !== undefined) {\n metadata.rateLimitRemaining = rateLimitRemaining;\n }\n\n const rateLimitReset = parseNumberHeader(response, 'x-ratelimit-reset');\n if (rateLimitReset !== undefined) {\n metadata.rateLimitReset = rateLimitReset;\n }\n\n const plan = getHeaderValue(response, 'x-plan');\n if (plan) {\n metadata.plan = plan;\n }\n\n const usageApiCallsUsed = parseNumberHeader(\n response,\n 'x-usage-apicalls-used',\n );\n if (usageApiCallsUsed !== undefined) {\n metadata.usageApiCallsUsed = usageApiCallsUsed;\n }\n\n const usageApiCallsLimit = parseNumberHeader(\n response,\n 'x-usage-apicalls-limit',\n );\n if (usageApiCallsLimit !== undefined) {\n metadata.usageApiCallsLimit = usageApiCallsLimit;\n }\n\n const usageApiCallsRemaining = parseNumberHeader(\n response,\n 'x-usage-apicalls-remaining',\n );\n if (usageApiCallsRemaining !== undefined) {\n metadata.usageApiCallsRemaining = usageApiCallsRemaining;\n }\n\n const usageReset = getHeaderValue(response, 'x-usage-reset');\n if (usageReset) {\n metadata.usageReset = usageReset;\n }\n\n return metadata;\n}\n\nfunction attachMetadata<T, D>(response: AxiosResponse<T, D>): PlungAxiosResponse<T, D> {\n return Object.assign(response, {\n metadata: parseMetadata(response as AxiosResponse<unknown>),\n });\n}\n\nfunction normalizeErrorMessage(error: AxiosError): string {\n const fallbackMessage = error.response?.statusText?.trim() || 'Request failed';\n const responseData = error.response?.data;\n\n if (!responseData || typeof responseData !== 'object') {\n return fallbackMessage;\n }\n\n const message = (responseData as { message?: unknown }).message;\n\n if (typeof message === 'string' && message.trim() !== '') {\n return message;\n }\n\n if (Array.isArray(message)) {\n const messages = message.filter(\n (item): item is string => typeof item === 'string' && item.trim() !== '',\n );\n\n if (messages.length > 0) {\n return messages.join('; ');\n }\n }\n\n return fallbackMessage;\n}\n\nfunction parseRetryAfter(error: AxiosError): number | undefined {\n const response = error.response;\n\n if (!response) {\n return undefined;\n }\n\n const value = getHeaderValue(response, 'retry-after');\n\n if (!value) {\n return undefined;\n }\n\n const seconds = Number.parseInt(value, 10);\n if (!Number.isNaN(seconds)) {\n return seconds;\n }\n\n const retryDate = Date.parse(value);\n if (Number.isNaN(retryDate)) {\n return undefined;\n }\n\n return Math.max(0, Math.ceil((retryDate - Date.now()) / 1000));\n}\n\nfunction mapHttpError(error: AxiosError): Error {\n const response = error.response;\n\n if (!response) {\n return error;\n }\n\n const message = normalizeErrorMessage(error);\n\n switch (response.status) {\n case 400:\n return new PlungValidationError(message);\n case 401:\n return new PlungAuthError(message);\n case 403:\n return new PlungForbiddenError(message);\n case 404:\n return new PlungNotFoundError(message);\n case 410:\n return new PlungGoneError(message);\n case 429:\n return new PlungRateLimitError(message, parseRetryAfter(error));\n default:\n return new PlungError(message, response.status);\n }\n}\n\nexport default function createAxios(\n apiKey: string,\n options: CreateAxiosOptions = {},\n): AxiosInstance {\n const instance = axios.create({\n baseURL: options.baseURL ?? DEFAULT_BASE_URL,\n timeout: options.timeout ?? DEFAULT_TIMEOUT,\n });\n\n instance.interceptors.request.use((config) => {\n const headers = AxiosHeaders.from(config.headers);\n headers.set('Authorization', `Bearer ${apiKey}`);\n config.headers = headers;\n\n return config;\n });\n\n instance.interceptors.response.use(\n (response) => attachMetadata(response),\n (error: unknown) => {\n if (!axios.isAxiosError(error)) {\n return Promise.reject(error);\n }\n\n return Promise.reject(mapHttpError(error));\n },\n );\n\n return instance;\n}\n","import type { AxiosInstance } from 'axios';\n\nimport type {\n PlungAxiosResponse as InternalPlungAxiosResponse,\n PlungResponseMeta as InternalPlungResponseMeta,\n} from '../http/axios.js';\nimport type { LinkStats, PlungMeta, PlungResponse } from '../types/index.js';\n\nfunction toEpochSeconds(value: string | undefined): number | undefined {\n if (!value) {\n return undefined;\n }\n\n const parsed = Date.parse(value);\n\n if (Number.isNaN(parsed)) {\n return undefined;\n }\n\n return Math.floor(parsed / 1000);\n}\n\nfunction mapMeta(metadata: InternalPlungResponseMeta): PlungMeta {\n const usageReset = toEpochSeconds(metadata.usageReset);\n\n return {\n ...(metadata.apiKeyName ? { apiKeyName: metadata.apiKeyName } : {}),\n rateLimit: {\n ...(metadata.rateLimitLimit !== undefined\n ? { limit: metadata.rateLimitLimit }\n : {}),\n ...(metadata.rateLimitRemaining !== undefined\n ? { remaining: metadata.rateLimitRemaining }\n : {}),\n ...(metadata.rateLimitReset !== undefined\n ? { reset: metadata.rateLimitReset }\n : {}),\n },\n ...(metadata.plan ? { plan: metadata.plan } : {}),\n usage: {\n ...(metadata.usageApiCallsUsed !== undefined\n ? { apiCallsUsed: metadata.usageApiCallsUsed }\n : {}),\n ...(metadata.usageApiCallsLimit !== undefined\n ? { apiCallsLimit: metadata.usageApiCallsLimit }\n : {}),\n ...(metadata.usageApiCallsRemaining !== undefined\n ? { apiCallsRemaining: metadata.usageApiCallsRemaining }\n : {}),\n ...(usageReset !== undefined ? { reset: usageReset } : {}),\n },\n };\n}\n\nexport class AnalyticsResource {\n constructor(private readonly http: AxiosInstance) {}\n\n async get(shortCode: string): Promise<PlungResponse<LinkStats>> {\n const response = await this.http.get<\n LinkStats,\n InternalPlungAxiosResponse<LinkStats>\n >(`/v2/stats/${shortCode}`);\n\n return {\n data: response.data,\n meta: mapMeta(response.metadata),\n };\n }\n}\n\nexport default AnalyticsResource;\n","import type { AxiosInstance } from 'axios';\n\nimport type {\n PlungAxiosResponse as InternalPlungAxiosResponse,\n PlungResponseMeta as InternalPlungResponseMeta,\n} from '../http/axios.js';\nimport type {\n BatchCreateResponse,\n CreateLinkInput,\n Link,\n PlungMeta,\n PlungResponse,\n} from '../types/index.js';\n\nfunction toEpochSeconds(value: string | undefined): number | undefined {\n if (!value) {\n return undefined;\n }\n\n const parsed = Date.parse(value);\n\n if (Number.isNaN(parsed)) {\n return undefined;\n }\n\n return Math.floor(parsed / 1000);\n}\n\nfunction mapMeta(metadata: InternalPlungResponseMeta): PlungMeta {\n const usageReset = toEpochSeconds(metadata.usageReset);\n\n return {\n ...(metadata.apiKeyName ? { apiKeyName: metadata.apiKeyName } : {}),\n rateLimit: {\n ...(metadata.rateLimitLimit !== undefined\n ? { limit: metadata.rateLimitLimit }\n : {}),\n ...(metadata.rateLimitRemaining !== undefined\n ? { remaining: metadata.rateLimitRemaining }\n : {}),\n ...(metadata.rateLimitReset !== undefined\n ? { reset: metadata.rateLimitReset }\n : {}),\n },\n ...(metadata.plan ? { plan: metadata.plan } : {}),\n usage: {\n ...(metadata.usageApiCallsUsed !== undefined\n ? { apiCallsUsed: metadata.usageApiCallsUsed }\n : {}),\n ...(metadata.usageApiCallsLimit !== undefined\n ? { apiCallsLimit: metadata.usageApiCallsLimit }\n : {}),\n ...(metadata.usageApiCallsRemaining !== undefined\n ? { apiCallsRemaining: metadata.usageApiCallsRemaining }\n : {}),\n ...(usageReset !== undefined ? { reset: usageReset } : {}),\n },\n };\n}\n\nexport class LinksResource {\n constructor(private readonly http: AxiosInstance) {}\n\n async create(input: CreateLinkInput): Promise<PlungResponse<Link>> {\n const response = await this.http.post<\n Link,\n InternalPlungAxiosResponse<Link>,\n CreateLinkInput\n >('/v2/shorten', input);\n\n return {\n data: response.data,\n meta: mapMeta(response.metadata),\n };\n }\n\n async batchCreate(\n items: CreateLinkInput[],\n ): Promise<PlungResponse<BatchCreateResponse>> {\n const response = await this.http.post<\n BatchCreateResponse,\n InternalPlungAxiosResponse<BatchCreateResponse>,\n { urls: CreateLinkInput[] }\n >('/v2/shorten/batch', { urls: items });\n\n return {\n data: response.data,\n meta: mapMeta(response.metadata),\n };\n }\n}\n\nexport default LinksResource;\n","import type { AxiosInstance, AxiosResponse } from 'axios';\n\nimport type {\n PlungAxiosResponse as InternalPlungAxiosResponse,\n PlungResponseMeta as InternalPlungResponseMeta,\n} from '../http/axios.js';\nimport type { QrOptions, QrResponse, PlungMeta } from '../types/index.js';\n\nfunction toEpochSeconds(value: string | undefined): number | undefined {\n if (!value) {\n return undefined;\n }\n\n const parsed = Date.parse(value);\n\n if (Number.isNaN(parsed)) {\n return undefined;\n }\n\n return Math.floor(parsed / 1000);\n}\n\nfunction mapMeta(metadata: InternalPlungResponseMeta): PlungMeta {\n const usageReset = toEpochSeconds(metadata.usageReset);\n\n return {\n ...(metadata.apiKeyName ? { apiKeyName: metadata.apiKeyName } : {}),\n rateLimit: {\n ...(metadata.rateLimitLimit !== undefined\n ? { limit: metadata.rateLimitLimit }\n : {}),\n ...(metadata.rateLimitRemaining !== undefined\n ? { remaining: metadata.rateLimitRemaining }\n : {}),\n ...(metadata.rateLimitReset !== undefined\n ? { reset: metadata.rateLimitReset }\n : {}),\n },\n ...(metadata.plan ? { plan: metadata.plan } : {}),\n usage: {\n ...(metadata.usageApiCallsUsed !== undefined\n ? { apiCallsUsed: metadata.usageApiCallsUsed }\n : {}),\n ...(metadata.usageApiCallsLimit !== undefined\n ? { apiCallsLimit: metadata.usageApiCallsLimit }\n : {}),\n ...(metadata.usageApiCallsRemaining !== undefined\n ? { apiCallsRemaining: metadata.usageApiCallsRemaining }\n : {}),\n ...(usageReset !== undefined ? { reset: usageReset } : {}),\n },\n };\n}\n\nfunction getHeaderValue(\n response: AxiosResponse<unknown>,\n headerName: string,\n): string | undefined {\n const responseHeaders = response.headers as Record<string, unknown>;\n const getter = responseHeaders.get;\n\n const valueFromGetter =\n typeof getter === 'function'\n ? getter.call(response.headers, headerName)\n : undefined;\n\n const value =\n valueFromGetter ??\n responseHeaders[headerName] ??\n responseHeaders[headerName.toLowerCase()];\n\n if (Array.isArray(value)) {\n return value.find((item): item is string => typeof item === 'string');\n }\n\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction normalizeContentType(\n value: string | undefined,\n): 'image/png' | 'image/svg+xml' {\n const normalized = value?.toLowerCase();\n\n if (normalized?.includes('image/svg+xml')) {\n return 'image/svg+xml';\n }\n\n if (normalized?.includes('image/png')) {\n return 'image/png';\n }\n\n return 'image/png';\n}\n\nfunction toArrayBuffer(data: ArrayBuffer | ArrayBufferView): ArrayBuffer {\n if (data instanceof ArrayBuffer) {\n return data;\n }\n\n if (ArrayBuffer.isView(data)) {\n const bytes = new Uint8Array(data.byteLength);\n bytes.set(new Uint8Array(data.buffer, data.byteOffset, data.byteLength));\n\n return bytes.buffer;\n }\n\n throw new TypeError('Unexpected QR response body type');\n}\n\nexport class QrResource {\n constructor(private readonly http: AxiosInstance) {}\n\n async get(shortCode: string, options: QrOptions = {}): Promise<QrResponse> {\n const response = await this.http.get<\n ArrayBuffer | ArrayBufferView,\n InternalPlungAxiosResponse<ArrayBuffer | ArrayBufferView>\n >(`/v2/qr/${shortCode}`, {\n params: {\n ...(options.format !== undefined ? { format: options.format } : {}),\n ...(options.size !== undefined ? { size: options.size } : {}),\n },\n responseType: 'arraybuffer',\n });\n\n return {\n data: toArrayBuffer(response.data),\n contentType: normalizeContentType(getHeaderValue(response, 'content-type')),\n meta: mapMeta(response.metadata),\n };\n }\n}\n\nexport default QrResource;\n","import type { AxiosInstance } from 'axios';\n\nimport createAxios from './http/axios.js';\nimport { AnalyticsResource } from './resources/analytics.js';\nimport { LinksResource } from './resources/links.js';\nimport { QrResource } from './resources/qr.js';\n\nexport class PlungClient {\n public readonly links: LinksResource;\n public readonly qr: QrResource;\n public readonly analytics: AnalyticsResource;\n\n private readonly http: AxiosInstance;\n\n constructor(\n apiKey: string,\n options: {\n baseURL?: string;\n timeout?: number;\n } = {},\n ) {\n this.http = createAxios(apiKey, options);\n this.links = new LinksResource(this.http);\n this.qr = new QrResource(this.http);\n this.analytics = new AnalyticsResource(this.http);\n }\n}\n\nexport default PlungClient;\n"]}
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@plung/sdk",
3
+ "version": "0.2.0",
4
+ "description": "Official TypeScript SDK for the Plung API",
5
+ "author": "Plung",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "sideEffects": false,
9
+ "engines": {
10
+ "node": ">=24.14.1"
11
+ },
12
+ "packageManager": "pnpm@10.33.0",
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "import": "./dist/index.js"
20
+ }
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "README.md",
25
+ "CHANGELOG.md"
26
+ ],
27
+ "scripts": {
28
+ "build": "tsup --config tsup.config.ts",
29
+ "lint": "eslint src tests examples scripts tsup.config.ts",
30
+ "lint:fix": "eslint src tests examples scripts tsup.config.ts --fix",
31
+ "typecheck": "tsc -p tsconfig.json --noEmit",
32
+ "test": "vitest run",
33
+ "test:watch": "vitest",
34
+ "release": "env TMPDIR=/tmp tsx scripts/publish.ts"
35
+ },
36
+ "dependencies": {
37
+ "axios": "^1.13.6"
38
+ },
39
+ "devDependencies": {
40
+ "@eslint/js": "^10.0.1",
41
+ "@types/node": "^24.0.0",
42
+ "eslint": "^10.1.0",
43
+ "globals": "^17.4.0",
44
+ "tsup": "^8.5.1",
45
+ "tsx": "^4.21.0",
46
+ "typescript": "^6.0.2",
47
+ "typescript-eslint": "^8.57.2",
48
+ "vitest": "^4.1.2"
49
+ }
50
+ }