@sarangkale66/pixxo-sdk-node 1.0.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 +107 -0
- package/dist/errors.d.ts +14 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +28 -0
- package/dist/errors.js.map +1 -0
- package/dist/folder.d.ts +10 -0
- package/dist/folder.d.ts.map +1 -0
- package/dist/folder.js +45 -0
- package/dist/folder.js.map +1 -0
- package/dist/http.d.ts +7 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +54 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/pixxo.d.ts +44 -0
- package/dist/pixxo.d.ts.map +1 -0
- package/dist/pixxo.js +161 -0
- package/dist/pixxo.js.map +1 -0
- package/dist/types.d.ts +112 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +4 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +24 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +144 -0
- package/dist/utils.js.map +1 -0
- package/package.json +33 -0
package/README.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Pixxo Node.js SDK
|
|
2
|
+
|
|
3
|
+
> Drop-in replacement for the [ImageKit Node.js SDK](https://github.com/imagekit-developer/imagekit-nodejs). Swap `import ImageKit from 'imagekit'` with `import Pixxo from 'pixxo'` — zero refactor required.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install pixxo
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import Pixxo from "pixxo";
|
|
15
|
+
import fs from "fs";
|
|
16
|
+
|
|
17
|
+
const pixxo = new Pixxo({
|
|
18
|
+
email: "you@example.com",
|
|
19
|
+
password: "your-password",
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const result = await pixxo.upload({
|
|
23
|
+
file: fs.readFileSync("receipt.pdf"),
|
|
24
|
+
fileName: "receipt.pdf",
|
|
25
|
+
folder: "/receipts",
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
console.log(result.url); // https://px.pixxo.io/…
|
|
29
|
+
console.log(result.fileId); // MongoDB ObjectId
|
|
30
|
+
console.log(result.name); // receipt.pdf
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Constructor Options
|
|
34
|
+
|
|
35
|
+
| Option | Type | Required | Default | Description |
|
|
36
|
+
|---|---|---|---|---|
|
|
37
|
+
| `email` | `string` | ✅ | — | Pixxo account email |
|
|
38
|
+
| `password` | `string` | ✅ | — | Pixxo account password |
|
|
39
|
+
| `baseUrl` | `string` | — | `https://api.pixxo.io` | API base URL |
|
|
40
|
+
| `cdnDomain` | `string` | — | `px.pixxo.io` | CDN domain for returned URLs |
|
|
41
|
+
| `maxRetries` | `number` | — | `2` | Retry attempts for S3 upload failures |
|
|
42
|
+
| `publicKey` | `string` | — | — | *Ignored* (ImageKit compat) |
|
|
43
|
+
| `privateKey` | `string` | — | — | *Ignored* (ImageKit compat) |
|
|
44
|
+
| `urlEndpoint` | `string` | — | — | *Ignored* (ImageKit compat) |
|
|
45
|
+
|
|
46
|
+
## `upload(options)`
|
|
47
|
+
|
|
48
|
+
### Options
|
|
49
|
+
|
|
50
|
+
| Option | Type | Required | Description |
|
|
51
|
+
|---|---|---|---|
|
|
52
|
+
| `file` | `Buffer \| string` | ✅ | Buffer, base64 string, or file path |
|
|
53
|
+
| `fileName` | `string` | ✅ | File name with extension |
|
|
54
|
+
| `folder` | `string` | — | Destination folder (e.g. `"/receipts"`) |
|
|
55
|
+
| `useUniqueFileName` | `boolean` | — | Append unique suffix (default: `true`) |
|
|
56
|
+
|
|
57
|
+
### Response
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
{
|
|
61
|
+
url: string; // CDN URL
|
|
62
|
+
fileId: string; // Pixxo asset ID
|
|
63
|
+
name: string; // Stored file name
|
|
64
|
+
fileType: string; // MIME type
|
|
65
|
+
size: number; // Size in bytes
|
|
66
|
+
folderId: string | null;
|
|
67
|
+
s3Key: string;
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Migration from ImageKit
|
|
72
|
+
|
|
73
|
+
```diff
|
|
74
|
+
- import ImageKit from "imagekit";
|
|
75
|
+
+ import Pixxo from "pixxo";
|
|
76
|
+
|
|
77
|
+
- const imagekit = new ImageKit({
|
|
78
|
+
- publicKey: "...",
|
|
79
|
+
- privateKey: "...",
|
|
80
|
+
- urlEndpoint: "...",
|
|
81
|
+
- });
|
|
82
|
+
+ const imagekit = new Pixxo({
|
|
83
|
+
+ email: "you@example.com",
|
|
84
|
+
+ password: "your-password",
|
|
85
|
+
+ });
|
|
86
|
+
|
|
87
|
+
// Everything else stays the same!
|
|
88
|
+
const result = await imagekit.upload({
|
|
89
|
+
file: buffer,
|
|
90
|
+
fileName: "photo.jpg",
|
|
91
|
+
folder: "/products",
|
|
92
|
+
});
|
|
93
|
+
console.log(result.url);
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Features
|
|
97
|
+
|
|
98
|
+
- **Token caching** — authenticates once, reuses token until expiry
|
|
99
|
+
- **Automatic retry** — exponential back-off for S3 upload failures
|
|
100
|
+
- **Recursive folder creation** — deeply nested paths just work
|
|
101
|
+
- **Multiple file input types** — Buffer, base64, file path
|
|
102
|
+
- **ImageKit-compatible response** — `url`, `fileId`, `name`
|
|
103
|
+
- **Zero dependencies** — uses native `fetch` (Node 18+)
|
|
104
|
+
|
|
105
|
+
## License
|
|
106
|
+
|
|
107
|
+
MIT
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom error class for Pixxo SDK errors.
|
|
3
|
+
* Provides HTTP status code + API response data when available.
|
|
4
|
+
*/
|
|
5
|
+
export declare class PixxoError extends Error {
|
|
6
|
+
readonly status: number;
|
|
7
|
+
readonly data: unknown;
|
|
8
|
+
constructor(message: string, status?: number, data?: unknown);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Type guard for PixxoError
|
|
12
|
+
*/
|
|
13
|
+
export declare function isPixxoError(err: unknown): err is PixxoError;
|
|
14
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,UAAW,SAAQ,KAAK;IACnC,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,IAAI,EAAE,OAAO,CAAC;gBAElB,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,MAAU,EAAE,IAAI,GAAE,OAAc;CAStE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,UAAU,CAE5D"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PixxoError = void 0;
|
|
4
|
+
exports.isPixxoError = isPixxoError;
|
|
5
|
+
/**
|
|
6
|
+
* Custom error class for Pixxo SDK errors.
|
|
7
|
+
* Provides HTTP status code + API response data when available.
|
|
8
|
+
*/
|
|
9
|
+
class PixxoError extends Error {
|
|
10
|
+
status;
|
|
11
|
+
data;
|
|
12
|
+
constructor(message, status = 0, data = null) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = "PixxoError";
|
|
15
|
+
this.status = status;
|
|
16
|
+
this.data = data;
|
|
17
|
+
// Maintain proper prototype chain (required for `instanceof`)
|
|
18
|
+
Object.setPrototypeOf(this, PixxoError.prototype);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.PixxoError = PixxoError;
|
|
22
|
+
/**
|
|
23
|
+
* Type guard for PixxoError
|
|
24
|
+
*/
|
|
25
|
+
function isPixxoError(err) {
|
|
26
|
+
return err instanceof PixxoError;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":";;;AAsBA,oCAEC;AAxBD;;;GAGG;AACH,MAAa,UAAW,SAAQ,KAAK;IACnB,MAAM,CAAS;IACf,IAAI,CAAU;IAE9B,YAAY,OAAe,EAAE,SAAiB,CAAC,EAAE,OAAgB,IAAI;QACnE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QAEjB,8DAA8D;QAC9D,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;CACF;AAbD,gCAaC;AAED;;GAEG;AACH,SAAgB,YAAY,CAAC,GAAY;IACvC,OAAO,GAAG,YAAY,UAAU,CAAC;AACnC,CAAC"}
|
package/dist/folder.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ensures the full folder path exists on the Pixxo backend,
|
|
3
|
+
* creating any missing segments along the way.
|
|
4
|
+
*
|
|
5
|
+
* On 409 (duplicate), it fetches the existing folder instead of failing.
|
|
6
|
+
*
|
|
7
|
+
* @returns The MongoDB `_id` of the deepest (leaf) folder.
|
|
8
|
+
*/
|
|
9
|
+
export declare function ensureFolderPath(baseUrl: string, folderPath: string, token: string): Promise<string>;
|
|
10
|
+
//# sourceMappingURL=folder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folder.d.ts","sourceRoot":"","sources":["../src/folder.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CAgDjB"}
|
package/dist/folder.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ensureFolderPath = ensureFolderPath;
|
|
4
|
+
const http_1 = require("./http");
|
|
5
|
+
const errors_1 = require("./errors");
|
|
6
|
+
/**
|
|
7
|
+
* Ensures the full folder path exists on the Pixxo backend,
|
|
8
|
+
* creating any missing segments along the way.
|
|
9
|
+
*
|
|
10
|
+
* On 409 (duplicate), it fetches the existing folder instead of failing.
|
|
11
|
+
*
|
|
12
|
+
* @returns The MongoDB `_id` of the deepest (leaf) folder.
|
|
13
|
+
*/
|
|
14
|
+
async function ensureFolderPath(baseUrl, folderPath, token) {
|
|
15
|
+
const segments = folderPath
|
|
16
|
+
.split("/")
|
|
17
|
+
.map((s) => s.trim())
|
|
18
|
+
.filter(Boolean);
|
|
19
|
+
if (segments.length === 0) {
|
|
20
|
+
throw new errors_1.PixxoError("Folder path cannot be empty");
|
|
21
|
+
}
|
|
22
|
+
let parentId = null;
|
|
23
|
+
for (const name of segments) {
|
|
24
|
+
try {
|
|
25
|
+
const data = await (0, http_1.postJSON)(`${baseUrl}/api/folders`, { name, parentId }, token);
|
|
26
|
+
parentId = data.data.folder._id;
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
if (err instanceof errors_1.PixxoError && err.status === 409) {
|
|
30
|
+
// Folder exists – look it up
|
|
31
|
+
const listData = await (0, http_1.getJSON)(`${baseUrl}/api/folders`, token, parentId ? { parentId } : {});
|
|
32
|
+
const existing = listData.data.folders.find((f) => f.name.toLowerCase() === name.toLowerCase());
|
|
33
|
+
if (!existing) {
|
|
34
|
+
throw new errors_1.PixxoError(`Folder "${name}" reportedly exists but could not be found in listing`);
|
|
35
|
+
}
|
|
36
|
+
parentId = existing._id;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
throw err;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return parentId;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=folder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"folder.js","sourceRoot":"","sources":["../src/folder.ts"],"names":[],"mappings":";;AAYA,4CAoDC;AAhED,iCAA2C;AAC3C,qCAAsC;AAGtC;;;;;;;GAOG;AACI,KAAK,UAAU,gBAAgB,CACpC,OAAe,EACf,UAAkB,EAClB,KAAa;IAEb,MAAM,QAAQ,GAAG,UAAU;SACxB,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,mBAAU,CAAC,6BAA6B,CAAC,CAAC;IACtD,CAAC;IAED,IAAI,QAAQ,GAAkB,IAAI,CAAC;IAEnC,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,IAAI,GAAyB,MAAM,IAAA,eAAQ,EAC/C,GAAG,OAAO,cAAc,EACxB,EAAE,IAAI,EAAE,QAAQ,EAAE,EAClB,KAAK,CACN,CAAC;YACF,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;QAClC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,mBAAU,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACpD,6BAA6B;gBAC7B,MAAM,QAAQ,GAAuB,MAAM,IAAA,cAAO,EAChD,GAAG,OAAO,cAAc,EACxB,KAAK,EACL,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAC7B,CAAC;gBAEF,MAAM,QAAQ,GACZ,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CACxB,CAAC,CAAiB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CACnE,CAAC;gBAEJ,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,MAAM,IAAI,mBAAU,CAClB,WAAW,IAAI,uDAAuD,CACvE,CAAC;gBACJ,CAAC;gBAED,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAkB,CAAC;AAC5B,CAAC"}
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function postJSON<T>(url: string, body: unknown, token?: string): Promise<T>;
|
|
2
|
+
export declare function getJSON<T>(url: string, token: string, params?: Record<string, string>): Promise<T>;
|
|
3
|
+
/**
|
|
4
|
+
* Upload a raw buffer to an S3 presigned URL via PUT.
|
|
5
|
+
*/
|
|
6
|
+
export declare function putS3(uploadUrl: string, buffer: Buffer, contentType: string): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAIA,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,OAAO,EACb,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,CAAC,CAAC,CAuBZ;AAED,wBAAsB,OAAO,CAAC,CAAC,EAC7B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GAClC,OAAO,CAAC,CAAC,CAAC,CAmBZ;AAED;;GAEG;AACH,wBAAsB,KAAK,CACzB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAiBf"}
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.postJSON = postJSON;
|
|
4
|
+
exports.getJSON = getJSON;
|
|
5
|
+
exports.putS3 = putS3;
|
|
6
|
+
const errors_1 = require("./errors");
|
|
7
|
+
// ─── Generic JSON helpers ──────────────────────────────────────────────────
|
|
8
|
+
async function postJSON(url, body, token) {
|
|
9
|
+
const headers = {
|
|
10
|
+
"Content-Type": "application/json",
|
|
11
|
+
};
|
|
12
|
+
if (token)
|
|
13
|
+
headers["Authorization"] = `Bearer ${token}`;
|
|
14
|
+
const res = await fetch(url, {
|
|
15
|
+
method: "POST",
|
|
16
|
+
headers,
|
|
17
|
+
body: JSON.stringify(body),
|
|
18
|
+
});
|
|
19
|
+
const data = (await res.json());
|
|
20
|
+
if (!res.ok) {
|
|
21
|
+
throw new errors_1.PixxoError(data?.error ?? `HTTP ${res.status}`, res.status, data);
|
|
22
|
+
}
|
|
23
|
+
return data;
|
|
24
|
+
}
|
|
25
|
+
async function getJSON(url, token, params = {}) {
|
|
26
|
+
const qs = new URLSearchParams(params).toString();
|
|
27
|
+
const fullUrl = qs ? `${url}?${qs}` : url;
|
|
28
|
+
const res = await fetch(fullUrl, {
|
|
29
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
30
|
+
});
|
|
31
|
+
const data = (await res.json());
|
|
32
|
+
if (!res.ok) {
|
|
33
|
+
throw new errors_1.PixxoError(data?.error ?? `HTTP ${res.status}`, res.status, data);
|
|
34
|
+
}
|
|
35
|
+
return data;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Upload a raw buffer to an S3 presigned URL via PUT.
|
|
39
|
+
*/
|
|
40
|
+
async function putS3(uploadUrl, buffer, contentType) {
|
|
41
|
+
const res = await fetch(uploadUrl, {
|
|
42
|
+
method: "PUT",
|
|
43
|
+
headers: {
|
|
44
|
+
"Content-Type": contentType,
|
|
45
|
+
"Content-Length": String(buffer.length),
|
|
46
|
+
},
|
|
47
|
+
body: buffer,
|
|
48
|
+
duplex: "half",
|
|
49
|
+
});
|
|
50
|
+
if (!res.ok) {
|
|
51
|
+
throw new errors_1.PixxoError(`S3 upload failed: ${res.status} ${res.statusText}`, res.status);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":";;AAIA,4BA2BC;AAED,0BAuBC;AAKD,sBAqBC;AAlFD,qCAAsC;AAEtC,8EAA8E;AAEvE,KAAK,UAAU,QAAQ,CAC5B,GAAW,EACX,IAAa,EACb,KAAc;IAEd,MAAM,OAAO,GAA2B;QACtC,cAAc,EAAE,kBAAkB;KACnC,CAAC;IACF,IAAI,KAAK;QAAE,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,KAAK,EAAE,CAAC;IAExD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC3B,MAAM,EAAE,MAAM;QACd,OAAO;QACP,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA2B,CAAC;IAE1D,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,mBAAU,CAClB,IAAI,EAAE,KAAK,IAAI,QAAQ,GAAG,CAAC,MAAM,EAAE,EACnC,GAAG,CAAC,MAAM,EACV,IAAI,CACL,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAEM,KAAK,UAAU,OAAO,CAC3B,GAAW,EACX,KAAa,EACb,SAAiC,EAAE;IAEnC,MAAM,EAAE,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;IAClD,MAAM,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IAE1C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE;QAC/B,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE;KAC9C,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA2B,CAAC;IAE1D,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,mBAAU,CAClB,IAAI,EAAE,KAAK,IAAI,QAAQ,GAAG,CAAC,MAAM,EAAE,EACnC,GAAG,CAAC,MAAM,EACV,IAAI,CACL,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,KAAK,CACzB,SAAiB,EACjB,MAAc,EACd,WAAmB;IAEnB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE;QACjC,MAAM,EAAE,KAAK;QACb,OAAO,EAAE;YACP,cAAc,EAAE,WAAW;YAC3B,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;SACxC;QACD,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,MAAe;KACT,CAAC,CAAC;IAElB,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,mBAAU,CAClB,qBAAqB,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,EACnD,GAAG,CAAC,MAAM,CACX,CAAC;IACJ,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pixxo Node.js SDK
|
|
3
|
+
*
|
|
4
|
+
* Drop‑in replacement for the ImageKit Node.js SDK.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* import Pixxo from "pixxo";
|
|
9
|
+
*
|
|
10
|
+
* const pixxo = new Pixxo({
|
|
11
|
+
* email: "user@example.com",
|
|
12
|
+
* password: "secret",
|
|
13
|
+
* });
|
|
14
|
+
*
|
|
15
|
+
* const res = await pixxo.upload({
|
|
16
|
+
* file: fs.readFileSync("photo.jpg"),
|
|
17
|
+
* fileName: "photo.jpg",
|
|
18
|
+
* folder: "/products",
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* console.log(res.url); // https://px.pixxo.io/…
|
|
22
|
+
* console.log(res.fileId); // Mongo ObjectId
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @module pixxo
|
|
26
|
+
*/
|
|
27
|
+
export { default } from "./pixxo";
|
|
28
|
+
export { default as Pixxo } from "./pixxo";
|
|
29
|
+
export type { PixxoConfig, UploadOptions, UploadResponse } from "./types";
|
|
30
|
+
export { PixxoError, isPixxoError } from "./errors";
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,SAAS,CAAC;AAG3C,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pixxo Node.js SDK
|
|
4
|
+
*
|
|
5
|
+
* Drop‑in replacement for the ImageKit Node.js SDK.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import Pixxo from "pixxo";
|
|
10
|
+
*
|
|
11
|
+
* const pixxo = new Pixxo({
|
|
12
|
+
* email: "user@example.com",
|
|
13
|
+
* password: "secret",
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* const res = await pixxo.upload({
|
|
17
|
+
* file: fs.readFileSync("photo.jpg"),
|
|
18
|
+
* fileName: "photo.jpg",
|
|
19
|
+
* folder: "/products",
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* console.log(res.url); // https://px.pixxo.io/…
|
|
23
|
+
* console.log(res.fileId); // Mongo ObjectId
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @module pixxo
|
|
27
|
+
*/
|
|
28
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
29
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
30
|
+
};
|
|
31
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
+
exports.isPixxoError = exports.PixxoError = exports.Pixxo = exports.default = void 0;
|
|
33
|
+
var pixxo_1 = require("./pixxo");
|
|
34
|
+
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(pixxo_1).default; } });
|
|
35
|
+
var pixxo_2 = require("./pixxo");
|
|
36
|
+
Object.defineProperty(exports, "Pixxo", { enumerable: true, get: function () { return __importDefault(pixxo_2).default; } });
|
|
37
|
+
var errors_1 = require("./errors");
|
|
38
|
+
Object.defineProperty(exports, "PixxoError", { enumerable: true, get: function () { return errors_1.PixxoError; } });
|
|
39
|
+
Object.defineProperty(exports, "isPixxoError", { enumerable: true, get: function () { return errors_1.isPixxoError; } });
|
|
40
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;;;;;;AAEH,iCAAkC;AAAzB,iHAAA,OAAO,OAAA;AAChB,iCAA2C;AAAlC,+GAAA,OAAO,OAAS;AAIzB,mCAAoD;AAA3C,oGAAA,UAAU,OAAA;AAAE,sGAAA,YAAY,OAAA"}
|
package/dist/pixxo.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { PixxoConfig, UploadOptions, UploadResponse } from "./types";
|
|
2
|
+
declare class Pixxo {
|
|
3
|
+
private readonly email;
|
|
4
|
+
private readonly password;
|
|
5
|
+
private readonly baseUrl;
|
|
6
|
+
private readonly cdnDomain;
|
|
7
|
+
private readonly maxRetries;
|
|
8
|
+
/** Cached JWT token */
|
|
9
|
+
private token;
|
|
10
|
+
/** Timestamp (ms) when the cached token expires */
|
|
11
|
+
private tokenExpiry;
|
|
12
|
+
constructor(config: PixxoConfig);
|
|
13
|
+
/**
|
|
14
|
+
* Get a valid JWT token, re‑authenticating only when needed.
|
|
15
|
+
*/
|
|
16
|
+
private getToken;
|
|
17
|
+
/**
|
|
18
|
+
* Upload a file to Pixxo.
|
|
19
|
+
*
|
|
20
|
+
* Drop‑in replacement for `ImageKit.upload()`.
|
|
21
|
+
*
|
|
22
|
+
* ```ts
|
|
23
|
+
* const res = await pixxo.upload({
|
|
24
|
+
* file: fs.readFileSync("receipt.pdf"),
|
|
25
|
+
* fileName: "receipt.pdf",
|
|
26
|
+
* folder: "/receipts",
|
|
27
|
+
* });
|
|
28
|
+
* console.log(res.url);
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
upload(options: UploadOptions): Promise<UploadResponse>;
|
|
32
|
+
private uploadWithRetry;
|
|
33
|
+
/**
|
|
34
|
+
* Replace the CloudFront origin domain with the custom CDN domain.
|
|
35
|
+
*/
|
|
36
|
+
private rewriteCdnUrl;
|
|
37
|
+
/**
|
|
38
|
+
* Build a CDN URL from an S3 key (fallback when the asset response
|
|
39
|
+
* doesn't provide a CloudFront URL, e.g. on 409).
|
|
40
|
+
*/
|
|
41
|
+
private buildCdnUrl;
|
|
42
|
+
}
|
|
43
|
+
export default Pixxo;
|
|
44
|
+
//# sourceMappingURL=pixxo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pixxo.d.ts","sourceRoot":"","sources":["../src/pixxo.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAGV,WAAW,EACX,aAAa,EACb,cAAc,EAEf,MAAM,SAAS,CAAC;AAajB,cAAM,KAAK;IACT,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IAEpC,uBAAuB;IACvB,OAAO,CAAC,KAAK,CAAuB;IACpC,mDAAmD;IACnD,OAAO,CAAC,WAAW,CAAa;gBAEpB,MAAM,EAAE,WAAW;IAa/B;;OAEG;YACW,QAAQ;IAuBtB;;;;;;;;;;;;;OAaG;IACG,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;YAgF/C,eAAe;IAyB7B;;OAEG;IACH,OAAO,CAAC,aAAa;IAIrB;;;OAGG;IACH,OAAO,CAAC,WAAW;CAGpB;AAED,eAAe,KAAK,CAAC"}
|
package/dist/pixxo.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const http_1 = require("./http");
|
|
4
|
+
const errors_1 = require("./errors");
|
|
5
|
+
const folder_1 = require("./folder");
|
|
6
|
+
const utils_1 = require("./utils");
|
|
7
|
+
// ─── Constants ─────────────────────────────────────────────────────────────
|
|
8
|
+
const DEFAULT_BASE_URL = "https://api.pixxo.io";
|
|
9
|
+
const DEFAULT_CDN_DOMAIN = "px.pixxo.io";
|
|
10
|
+
const CLOUDFRONT_ORIGIN = "d10i6f9i6i5qro.cloudfront.net";
|
|
11
|
+
const TOKEN_SAFETY_MARGIN_MS = 5 * 60 * 1000; // refresh 5 min before expiry
|
|
12
|
+
const DEFAULT_TOKEN_LIFETIME_MS = 24 * 60 * 60 * 1000; // assume 24h if unknown
|
|
13
|
+
const DEFAULT_MAX_RETRIES = 2;
|
|
14
|
+
// ─── Pixxo SDK ─────────────────────────────────────────────────────────────
|
|
15
|
+
class Pixxo {
|
|
16
|
+
email;
|
|
17
|
+
password;
|
|
18
|
+
baseUrl;
|
|
19
|
+
cdnDomain;
|
|
20
|
+
maxRetries;
|
|
21
|
+
/** Cached JWT token */
|
|
22
|
+
token = null;
|
|
23
|
+
/** Timestamp (ms) when the cached token expires */
|
|
24
|
+
tokenExpiry = 0;
|
|
25
|
+
constructor(config) {
|
|
26
|
+
if (!config.email)
|
|
27
|
+
throw new errors_1.PixxoError("email is required");
|
|
28
|
+
if (!config.password)
|
|
29
|
+
throw new errors_1.PixxoError("password is required");
|
|
30
|
+
this.email = config.email;
|
|
31
|
+
this.password = config.password;
|
|
32
|
+
this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
33
|
+
this.cdnDomain = config.cdnDomain ?? DEFAULT_CDN_DOMAIN;
|
|
34
|
+
this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
35
|
+
}
|
|
36
|
+
// ── Authentication ─────────────────────────────────────────────────────
|
|
37
|
+
/**
|
|
38
|
+
* Get a valid JWT token, re‑authenticating only when needed.
|
|
39
|
+
*/
|
|
40
|
+
async getToken() {
|
|
41
|
+
if (this.token && Date.now() < this.tokenExpiry) {
|
|
42
|
+
return this.token;
|
|
43
|
+
}
|
|
44
|
+
const res = await (0, http_1.postJSON)(`${this.baseUrl}/api/auth/login`, { email: this.email, password: this.password });
|
|
45
|
+
const token = res?.data?.token ?? res?.token;
|
|
46
|
+
if (!token) {
|
|
47
|
+
throw new errors_1.PixxoError("Login succeeded but no token was returned");
|
|
48
|
+
}
|
|
49
|
+
this.token = token;
|
|
50
|
+
this.tokenExpiry = Date.now() + DEFAULT_TOKEN_LIFETIME_MS - TOKEN_SAFETY_MARGIN_MS;
|
|
51
|
+
return token;
|
|
52
|
+
}
|
|
53
|
+
// ── Upload ─────────────────────────────────────────────────────────────
|
|
54
|
+
/**
|
|
55
|
+
* Upload a file to Pixxo.
|
|
56
|
+
*
|
|
57
|
+
* Drop‑in replacement for `ImageKit.upload()`.
|
|
58
|
+
*
|
|
59
|
+
* ```ts
|
|
60
|
+
* const res = await pixxo.upload({
|
|
61
|
+
* file: fs.readFileSync("receipt.pdf"),
|
|
62
|
+
* fileName: "receipt.pdf",
|
|
63
|
+
* folder: "/receipts",
|
|
64
|
+
* });
|
|
65
|
+
* console.log(res.url);
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
async upload(options) {
|
|
69
|
+
// ── Resolve file ─────────────────────────────────────────────────
|
|
70
|
+
const buffer = (0, utils_1.resolveFileToBuffer)(options.file);
|
|
71
|
+
const fileName = options.fileName;
|
|
72
|
+
const fileType = (0, utils_1.getMimeType)(fileName);
|
|
73
|
+
const fileSize = buffer.length;
|
|
74
|
+
// ── Normalise folder ─────────────────────────────────────────────
|
|
75
|
+
const folderPath = (0, utils_1.normalizeFolderPath)(options.folder);
|
|
76
|
+
// ── Authenticate ─────────────────────────────────────────────────
|
|
77
|
+
const token = await this.getToken();
|
|
78
|
+
// ── Ensure folder + get presigned URL (parallel) ─────────────────
|
|
79
|
+
const folderPromise = folderPath
|
|
80
|
+
? (0, folder_1.ensureFolderPath)(this.baseUrl, folderPath, token)
|
|
81
|
+
: Promise.resolve(null);
|
|
82
|
+
const uploadUrlPromise = (0, http_1.postJSON)(`${this.baseUrl}/api/assets/upload-url`, {
|
|
83
|
+
fileName,
|
|
84
|
+
fileType,
|
|
85
|
+
fileSize,
|
|
86
|
+
folder: folderPath || undefined,
|
|
87
|
+
customFileName: options.useUniqueFileName === false ? fileName : undefined,
|
|
88
|
+
}, token);
|
|
89
|
+
const [folderId, uploadUrlData] = await Promise.all([
|
|
90
|
+
folderPromise,
|
|
91
|
+
uploadUrlPromise,
|
|
92
|
+
]);
|
|
93
|
+
const { uploadUrl, s3Key, s3Bucket } = uploadUrlData.data;
|
|
94
|
+
// ── Upload to S3 with retry ──────────────────────────────────────
|
|
95
|
+
await this.uploadWithRetry(uploadUrl, buffer, fileType);
|
|
96
|
+
// ── Register asset in backend ────────────────────────────────────
|
|
97
|
+
let asset;
|
|
98
|
+
try {
|
|
99
|
+
asset = await (0, http_1.postJSON)(`${this.baseUrl}/api/assets`, { fileName, fileType, fileSize, s3Key, s3Bucket, folderId }, token);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
// 409 = asset already exists – treat as success for idempotency
|
|
103
|
+
if (err instanceof errors_1.PixxoError && err.status === 409) {
|
|
104
|
+
return {
|
|
105
|
+
url: this.buildCdnUrl(s3Key),
|
|
106
|
+
fileId: "",
|
|
107
|
+
name: fileName,
|
|
108
|
+
fileType,
|
|
109
|
+
size: fileSize,
|
|
110
|
+
folderId,
|
|
111
|
+
s3Key,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
throw err;
|
|
115
|
+
}
|
|
116
|
+
const created = asset.data.asset;
|
|
117
|
+
return {
|
|
118
|
+
url: this.rewriteCdnUrl(created.cloudfrontUrl),
|
|
119
|
+
fileId: created._id,
|
|
120
|
+
name: created.name,
|
|
121
|
+
fileType: created.type,
|
|
122
|
+
size: created.sizeBytes,
|
|
123
|
+
folderId: created.folderId,
|
|
124
|
+
s3Key: created.s3Key,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
// ── Retry helper ───────────────────────────────────────────────────────
|
|
128
|
+
async uploadWithRetry(uploadUrl, buffer, contentType) {
|
|
129
|
+
let lastError;
|
|
130
|
+
for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
|
|
131
|
+
try {
|
|
132
|
+
await (0, http_1.putS3)(uploadUrl, buffer, contentType);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
lastError = err;
|
|
137
|
+
if (attempt < this.maxRetries) {
|
|
138
|
+
// Exponential back-off: 500ms, 1s, 2s …
|
|
139
|
+
await (0, utils_1.sleep)(500 * Math.pow(2, attempt));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
throw lastError;
|
|
144
|
+
}
|
|
145
|
+
// ── URL helpers ────────────────────────────────────────────────────────
|
|
146
|
+
/**
|
|
147
|
+
* Replace the CloudFront origin domain with the custom CDN domain.
|
|
148
|
+
*/
|
|
149
|
+
rewriteCdnUrl(cloudfrontUrl) {
|
|
150
|
+
return cloudfrontUrl.replace(CLOUDFRONT_ORIGIN, this.cdnDomain);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Build a CDN URL from an S3 key (fallback when the asset response
|
|
154
|
+
* doesn't provide a CloudFront URL, e.g. on 409).
|
|
155
|
+
*/
|
|
156
|
+
buildCdnUrl(s3Key) {
|
|
157
|
+
return `https://${this.cdnDomain}/${s3Key}`;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
exports.default = Pixxo;
|
|
161
|
+
//# sourceMappingURL=pixxo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pixxo.js","sourceRoot":"","sources":["../src/pixxo.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for the Pixxo SDK.
|
|
3
|
+
*
|
|
4
|
+
* `publicKey` and `privateKey` are accepted for ImageKit compatibility
|
|
5
|
+
* but are NOT used by the Pixxo backend – they are silently ignored.
|
|
6
|
+
*/
|
|
7
|
+
export interface PixxoConfig {
|
|
8
|
+
email: string;
|
|
9
|
+
password: string;
|
|
10
|
+
/** Override API base URL (default: https://api.pixxo.io) */
|
|
11
|
+
baseUrl?: string;
|
|
12
|
+
/** Override CDN domain for returned URLs (default: px.pixxo.io) */
|
|
13
|
+
cdnDomain?: string;
|
|
14
|
+
/** Max retry attempts for upload failures (default: 2) */
|
|
15
|
+
maxRetries?: number;
|
|
16
|
+
publicKey?: string;
|
|
17
|
+
privateKey?: string;
|
|
18
|
+
urlEndpoint?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface UploadOptions {
|
|
21
|
+
/**
|
|
22
|
+
* The file to upload.
|
|
23
|
+
* - `Buffer` – raw bytes
|
|
24
|
+
* - `string` – base64‑encoded data **or** an absolute/relative file path
|
|
25
|
+
*/
|
|
26
|
+
file: Buffer | string;
|
|
27
|
+
/** Desired file name including extension */
|
|
28
|
+
fileName: string;
|
|
29
|
+
/**
|
|
30
|
+
* Destination folder path (ImageKit style, with leading slash).
|
|
31
|
+
* e.g. `"/receipts"` or `"/products/images"`
|
|
32
|
+
*
|
|
33
|
+
* Internally normalised to Pixxo format (no leading slash).
|
|
34
|
+
*/
|
|
35
|
+
folder?: string;
|
|
36
|
+
/** Whether to append a unique suffix to the file name (default: true) */
|
|
37
|
+
useUniqueFileName?: boolean;
|
|
38
|
+
/** Optional tags – accepted for ImageKit compat, currently ignored */
|
|
39
|
+
tags?: string[];
|
|
40
|
+
/** Any extra metadata – forwarded if supported */
|
|
41
|
+
[key: string]: unknown;
|
|
42
|
+
}
|
|
43
|
+
export interface UploadResponse {
|
|
44
|
+
/** Public CDN URL of the uploaded asset */
|
|
45
|
+
url: string;
|
|
46
|
+
/** Pixxo asset ID (maps to ImageKit's `fileId`) */
|
|
47
|
+
fileId: string;
|
|
48
|
+
/** File name as stored */
|
|
49
|
+
name: string;
|
|
50
|
+
/** MIME type */
|
|
51
|
+
fileType: string;
|
|
52
|
+
/** Size in bytes */
|
|
53
|
+
size: number;
|
|
54
|
+
/** Folder ID in Pixxo (if any) */
|
|
55
|
+
folderId: string | null;
|
|
56
|
+
/** Raw S3 key */
|
|
57
|
+
s3Key: string;
|
|
58
|
+
}
|
|
59
|
+
export interface LoginResponse {
|
|
60
|
+
success: boolean;
|
|
61
|
+
message?: string;
|
|
62
|
+
data?: {
|
|
63
|
+
user?: Record<string, unknown>;
|
|
64
|
+
token?: string;
|
|
65
|
+
};
|
|
66
|
+
token?: string;
|
|
67
|
+
}
|
|
68
|
+
export interface FolderDocument {
|
|
69
|
+
_id: string;
|
|
70
|
+
name: string;
|
|
71
|
+
parentId: string | null;
|
|
72
|
+
path?: string[];
|
|
73
|
+
}
|
|
74
|
+
export interface FolderCreateResponse {
|
|
75
|
+
success: boolean;
|
|
76
|
+
data: {
|
|
77
|
+
folder: FolderDocument;
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
export interface FolderListResponse {
|
|
81
|
+
success: boolean;
|
|
82
|
+
data: {
|
|
83
|
+
folders: FolderDocument[];
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
export interface UploadUrlResponse {
|
|
87
|
+
success: boolean;
|
|
88
|
+
data: {
|
|
89
|
+
uploadUrl: string;
|
|
90
|
+
s3Key: string;
|
|
91
|
+
s3Bucket: string;
|
|
92
|
+
expiresIn: number;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
export interface AssetDocument {
|
|
96
|
+
_id: string;
|
|
97
|
+
name: string;
|
|
98
|
+
type: string;
|
|
99
|
+
s3Key: string;
|
|
100
|
+
s3Bucket: string;
|
|
101
|
+
folderId: string | null;
|
|
102
|
+
cloudfrontUrl: string;
|
|
103
|
+
sizeBytes: number;
|
|
104
|
+
metadata?: Record<string, unknown>;
|
|
105
|
+
}
|
|
106
|
+
export interface AssetCreateResponse {
|
|
107
|
+
success: boolean;
|
|
108
|
+
data: {
|
|
109
|
+
asset: AssetDocument;
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA,8EAA8E"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Infer MIME type from file name / extension. Falls back to
|
|
3
|
+
* `application/octet-stream` for unknown extensions.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getMimeType(fileName: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* Resolve the `file` parameter from an upload call into a `Buffer`.
|
|
8
|
+
*
|
|
9
|
+
* Accepts:
|
|
10
|
+
* - `Buffer` → returned as-is
|
|
11
|
+
* - base64 string → decoded
|
|
12
|
+
* - file path → read from disk
|
|
13
|
+
*/
|
|
14
|
+
export declare function resolveFileToBuffer(file: Buffer | string): Buffer;
|
|
15
|
+
/**
|
|
16
|
+
* Convert ImageKit‑style folder (`/receipts`) to Pixxo style (`receipts`).
|
|
17
|
+
* Also trims trailing slashes and collapses duplicate slashes.
|
|
18
|
+
*/
|
|
19
|
+
export declare function normalizeFolderPath(folder?: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Simple async sleep.
|
|
22
|
+
*/
|
|
23
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
24
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AA8CA;;;GAGG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGpD;AAcD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAkBjE;AAID;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAM3D;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getMimeType = getMimeType;
|
|
37
|
+
exports.resolveFileToBuffer = resolveFileToBuffer;
|
|
38
|
+
exports.normalizeFolderPath = normalizeFolderPath;
|
|
39
|
+
exports.sleep = sleep;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
// ─── MIME type detection (lightweight, no dependencies) ────────────────────
|
|
43
|
+
const MIME_MAP = {
|
|
44
|
+
".jpg": "image/jpeg",
|
|
45
|
+
".jpeg": "image/jpeg",
|
|
46
|
+
".png": "image/png",
|
|
47
|
+
".gif": "image/gif",
|
|
48
|
+
".webp": "image/webp",
|
|
49
|
+
".avif": "image/avif",
|
|
50
|
+
".svg": "image/svg+xml",
|
|
51
|
+
".bmp": "image/bmp",
|
|
52
|
+
".ico": "image/x-icon",
|
|
53
|
+
".tiff": "image/tiff",
|
|
54
|
+
".tif": "image/tiff",
|
|
55
|
+
".pdf": "application/pdf",
|
|
56
|
+
".json": "application/json",
|
|
57
|
+
".xml": "application/xml",
|
|
58
|
+
".csv": "text/csv",
|
|
59
|
+
".txt": "text/plain",
|
|
60
|
+
".html": "text/html",
|
|
61
|
+
".css": "text/css",
|
|
62
|
+
".js": "application/javascript",
|
|
63
|
+
".mp4": "video/mp4",
|
|
64
|
+
".webm": "video/webm",
|
|
65
|
+
".mov": "video/quicktime",
|
|
66
|
+
".avi": "video/x-msvideo",
|
|
67
|
+
".mp3": "audio/mpeg",
|
|
68
|
+
".wav": "audio/wav",
|
|
69
|
+
".ogg": "audio/ogg",
|
|
70
|
+
".zip": "application/zip",
|
|
71
|
+
".gz": "application/gzip",
|
|
72
|
+
".tar": "application/x-tar",
|
|
73
|
+
".doc": "application/msword",
|
|
74
|
+
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
75
|
+
".xls": "application/vnd.ms-excel",
|
|
76
|
+
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
77
|
+
".ppt": "application/vnd.ms-powerpoint",
|
|
78
|
+
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Infer MIME type from file name / extension. Falls back to
|
|
82
|
+
* `application/octet-stream` for unknown extensions.
|
|
83
|
+
*/
|
|
84
|
+
function getMimeType(fileName) {
|
|
85
|
+
const ext = path.extname(fileName).toLowerCase();
|
|
86
|
+
return MIME_MAP[ext] ?? "application/octet-stream";
|
|
87
|
+
}
|
|
88
|
+
// ─── File resolution ───────────────────────────────────────────────────────
|
|
89
|
+
/**
|
|
90
|
+
* Determines whether a string looks like base64‑encoded data.
|
|
91
|
+
* Heuristic: length ≥ 64, matches base64 charset, no path separators.
|
|
92
|
+
*/
|
|
93
|
+
function isBase64(str) {
|
|
94
|
+
if (str.length < 64)
|
|
95
|
+
return false;
|
|
96
|
+
if (str.includes("/") && str.includes("."))
|
|
97
|
+
return false; // likely a path
|
|
98
|
+
return /^[A-Za-z0-9+/\r\n]+=*$/.test(str);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Resolve the `file` parameter from an upload call into a `Buffer`.
|
|
102
|
+
*
|
|
103
|
+
* Accepts:
|
|
104
|
+
* - `Buffer` → returned as-is
|
|
105
|
+
* - base64 string → decoded
|
|
106
|
+
* - file path → read from disk
|
|
107
|
+
*/
|
|
108
|
+
function resolveFileToBuffer(file) {
|
|
109
|
+
if (Buffer.isBuffer(file))
|
|
110
|
+
return file;
|
|
111
|
+
if (typeof file === "string") {
|
|
112
|
+
// Check base64 first
|
|
113
|
+
if (isBase64(file)) {
|
|
114
|
+
return Buffer.from(file, "base64");
|
|
115
|
+
}
|
|
116
|
+
// Treat as file path
|
|
117
|
+
const resolved = path.resolve(file);
|
|
118
|
+
if (!fs.existsSync(resolved)) {
|
|
119
|
+
throw new Error(`File not found: ${resolved}`);
|
|
120
|
+
}
|
|
121
|
+
return fs.readFileSync(resolved);
|
|
122
|
+
}
|
|
123
|
+
throw new Error("Invalid file: expected Buffer, base64 string, or file path");
|
|
124
|
+
}
|
|
125
|
+
// ─── Folder path normalisation ─────────────────────────────────────────────
|
|
126
|
+
/**
|
|
127
|
+
* Convert ImageKit‑style folder (`/receipts`) to Pixxo style (`receipts`).
|
|
128
|
+
* Also trims trailing slashes and collapses duplicate slashes.
|
|
129
|
+
*/
|
|
130
|
+
function normalizeFolderPath(folder) {
|
|
131
|
+
if (!folder)
|
|
132
|
+
return "";
|
|
133
|
+
return folder
|
|
134
|
+
.replace(/\/+/g, "/") // collapse duplicates
|
|
135
|
+
.replace(/^\//, "") // strip leading slash
|
|
136
|
+
.replace(/\/$/, ""); // strip trailing slash
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Simple async sleep.
|
|
140
|
+
*/
|
|
141
|
+
function sleep(ms) {
|
|
142
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sarangkale66/pixxo-sdk-node",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Pixxo Node.js SDK — drop-in replacement for ImageKit SDK",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"prepublishOnly": "npm run build",
|
|
13
|
+
"typecheck": "tsc --noEmit"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"pixxo",
|
|
17
|
+
"imagekit",
|
|
18
|
+
"image",
|
|
19
|
+
"upload",
|
|
20
|
+
"cdn",
|
|
21
|
+
"asset-management",
|
|
22
|
+
"s3"
|
|
23
|
+
],
|
|
24
|
+
"author": "",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/node": "^20.12.0",
|
|
28
|
+
"typescript": "^5.4.5"
|
|
29
|
+
},
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=18.0.0"
|
|
32
|
+
}
|
|
33
|
+
}
|