aliendrive-sdk 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 +132 -0
- package/aliendrive.d.ts +109 -0
- package/aliendrive.js +158 -0
- package/package.json +31 -0
package/README.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# aliendrive-sdk
|
|
2
|
+
|
|
3
|
+
Official Node.js SDK for the [AlienDrive](https://drive.moltenalien.com) API. S3-like interface for cloud file storage.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install aliendrive-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
const { AlienDrive } = require('aliendrive-sdk');
|
|
15
|
+
|
|
16
|
+
const drive = new AlienDrive({
|
|
17
|
+
endpoint: 'https://drive.moltenalien.com',
|
|
18
|
+
apiKey: 'mcd_your_api_key_here',
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
// Upload
|
|
22
|
+
await drive.putObject({
|
|
23
|
+
Key: 'photos/vacation.jpg',
|
|
24
|
+
Body: Buffer.from('...'),
|
|
25
|
+
ContentType: 'image/jpeg',
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// Download
|
|
29
|
+
const file = await drive.getObject({ Key: 'photos/vacation.jpg' });
|
|
30
|
+
console.log(file.Body); // Buffer
|
|
31
|
+
|
|
32
|
+
// List
|
|
33
|
+
const list = await drive.listObjects({ Prefix: 'photos/' });
|
|
34
|
+
console.log(list.Contents); // [{ Key, Size, ContentType, ... }]
|
|
35
|
+
|
|
36
|
+
// Delete
|
|
37
|
+
await drive.deleteObject({ Key: 'photos/vacation.jpg' });
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## API
|
|
41
|
+
|
|
42
|
+
### `new AlienDrive({ endpoint, apiKey })`
|
|
43
|
+
|
|
44
|
+
Create a client instance.
|
|
45
|
+
|
|
46
|
+
| Param | Type | Description |
|
|
47
|
+
|---|---|---|
|
|
48
|
+
| `endpoint` | `string` | API URL, e.g. `https://drive.moltenalien.com` |
|
|
49
|
+
| `apiKey` | `string` | Your API key (starts with `mcd_`) |
|
|
50
|
+
|
|
51
|
+
### `putObject({ Key, Body, ContentType? })`
|
|
52
|
+
|
|
53
|
+
Upload a file. Folders in the path are auto-created.
|
|
54
|
+
|
|
55
|
+
```javascript
|
|
56
|
+
await drive.putObject({
|
|
57
|
+
Key: 'reports/2026/q1.pdf',
|
|
58
|
+
Body: fs.readFileSync('q1.pdf'),
|
|
59
|
+
ContentType: 'application/pdf',
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### `getObject({ Key })`
|
|
64
|
+
|
|
65
|
+
Download a file. Returns `{ Body, ContentType, ContentLength, ETag, LastModified }`.
|
|
66
|
+
|
|
67
|
+
```javascript
|
|
68
|
+
const { Body } = await drive.getObject({ Key: 'reports/2026/q1.pdf' });
|
|
69
|
+
fs.writeFileSync('q1.pdf', Body);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### `headObject({ Key })`
|
|
73
|
+
|
|
74
|
+
Get file metadata without downloading.
|
|
75
|
+
|
|
76
|
+
```javascript
|
|
77
|
+
const meta = await drive.headObject({ Key: 'reports/2026/q1.pdf' });
|
|
78
|
+
console.log(meta.ContentLength); // file size in bytes
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### `listObjects({ Prefix?, MaxKeys? })`
|
|
82
|
+
|
|
83
|
+
List files and folders. Returns S3-compatible response with `Contents` and `CommonPrefixes`.
|
|
84
|
+
|
|
85
|
+
```javascript
|
|
86
|
+
const list = await drive.listObjects({ Prefix: 'reports/' });
|
|
87
|
+
list.Contents.forEach(f => console.log(f.Key, f.Size));
|
|
88
|
+
list.CommonPrefixes.forEach(f => console.log(f.Prefix)); // subfolders
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### `deleteObject({ Key })`
|
|
92
|
+
|
|
93
|
+
Delete a file. Returns `204` even if key doesn't exist (S3 behavior).
|
|
94
|
+
|
|
95
|
+
### `uploadFile(localPath, remotePath?)`
|
|
96
|
+
|
|
97
|
+
Convenience: upload a local file with auto-detected MIME type.
|
|
98
|
+
|
|
99
|
+
```javascript
|
|
100
|
+
await drive.uploadFile('./photo.jpg', 'photos/photo.jpg');
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### `downloadFile(remotePath, localPath)`
|
|
104
|
+
|
|
105
|
+
Convenience: download to a local file.
|
|
106
|
+
|
|
107
|
+
```javascript
|
|
108
|
+
await drive.downloadFile('photos/photo.jpg', './photo.jpg');
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## TypeScript
|
|
112
|
+
|
|
113
|
+
Full type definitions included. Works with both `require()` and TypeScript imports.
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import { AlienDrive } from 'aliendrive-sdk';
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Get an API Key
|
|
120
|
+
|
|
121
|
+
1. Sign up at [drive.moltenalien.com](https://drive.moltenalien.com)
|
|
122
|
+
2. Go to Settings
|
|
123
|
+
3. Create an API key
|
|
124
|
+
4. Copy it (shown only once)
|
|
125
|
+
|
|
126
|
+
## API Docs
|
|
127
|
+
|
|
128
|
+
Full API documentation at [drive.moltenalien.com/api-docs](https://drive.moltenalien.com/api-docs)
|
|
129
|
+
|
|
130
|
+
## License
|
|
131
|
+
|
|
132
|
+
MIT
|
package/aliendrive.d.ts
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
export interface AlienDriveConfig {
|
|
2
|
+
/** API endpoint, e.g. "https://drive.moltenalien.com" */
|
|
3
|
+
endpoint: string;
|
|
4
|
+
/** API key, e.g. "mcd_..." */
|
|
5
|
+
apiKey: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface PutObjectParams {
|
|
9
|
+
/** Object key/path, e.g. "Documents/report.pdf" */
|
|
10
|
+
Key: string;
|
|
11
|
+
/** File content */
|
|
12
|
+
Body: Buffer | string | ArrayBuffer | ReadableStream;
|
|
13
|
+
/** MIME type (default: "application/octet-stream") */
|
|
14
|
+
ContentType?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface PutObjectResult {
|
|
18
|
+
ETag: string;
|
|
19
|
+
Key: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface GetObjectParams {
|
|
23
|
+
/** Object key/path */
|
|
24
|
+
Key: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface GetObjectResult {
|
|
28
|
+
Body: Buffer;
|
|
29
|
+
ContentType: string;
|
|
30
|
+
ContentLength: number;
|
|
31
|
+
ETag: string;
|
|
32
|
+
LastModified: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface HeadObjectParams {
|
|
36
|
+
Key: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface HeadObjectResult {
|
|
40
|
+
ContentType: string | null;
|
|
41
|
+
ContentLength: number;
|
|
42
|
+
ETag: string | null;
|
|
43
|
+
LastModified: string | null;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface ListObjectsParams {
|
|
47
|
+
/** Filter by prefix, e.g. "Documents/" */
|
|
48
|
+
Prefix?: string;
|
|
49
|
+
/** Max results (default 1000) */
|
|
50
|
+
MaxKeys?: number;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface ListObjectsResult {
|
|
54
|
+
Name: string;
|
|
55
|
+
Prefix: string;
|
|
56
|
+
MaxKeys: number;
|
|
57
|
+
KeyCount: number;
|
|
58
|
+
Contents: Array<{
|
|
59
|
+
Key: string;
|
|
60
|
+
Size: number;
|
|
61
|
+
ContentType: string;
|
|
62
|
+
LastModified: string;
|
|
63
|
+
ETag: string;
|
|
64
|
+
}>;
|
|
65
|
+
CommonPrefixes: Array<{
|
|
66
|
+
Prefix: string;
|
|
67
|
+
}>;
|
|
68
|
+
IsTruncated: boolean;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface DeleteObjectParams {
|
|
72
|
+
Key: string;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface DeleteObjectResult {
|
|
76
|
+
DeleteMarker: boolean;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export interface UploadFileResult extends PutObjectResult {}
|
|
80
|
+
|
|
81
|
+
export interface DownloadFileResult {
|
|
82
|
+
size: number;
|
|
83
|
+
path: string;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export declare class AlienDrive {
|
|
87
|
+
constructor(config: AlienDriveConfig);
|
|
88
|
+
|
|
89
|
+
/** Upload a file (like S3 PutObject) */
|
|
90
|
+
putObject(params: PutObjectParams): Promise<PutObjectResult>;
|
|
91
|
+
|
|
92
|
+
/** Download a file (like S3 GetObject) */
|
|
93
|
+
getObject(params: GetObjectParams): Promise<GetObjectResult>;
|
|
94
|
+
|
|
95
|
+
/** Get file metadata (like S3 HeadObject) */
|
|
96
|
+
headObject(params: HeadObjectParams): Promise<HeadObjectResult>;
|
|
97
|
+
|
|
98
|
+
/** List objects at a prefix (like S3 ListObjectsV2) */
|
|
99
|
+
listObjects(params?: ListObjectsParams): Promise<ListObjectsResult>;
|
|
100
|
+
|
|
101
|
+
/** Delete a file (like S3 DeleteObject) */
|
|
102
|
+
deleteObject(params: DeleteObjectParams): Promise<DeleteObjectResult>;
|
|
103
|
+
|
|
104
|
+
/** Upload a local file by path */
|
|
105
|
+
uploadFile(localPath: string, remotePath?: string): Promise<UploadFileResult>;
|
|
106
|
+
|
|
107
|
+
/** Download to a local file */
|
|
108
|
+
downloadFile(remotePath: string, localPath: string): Promise<DownloadFileResult>;
|
|
109
|
+
}
|
package/aliendrive.js
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AlienDrive SDK — S3-like client for the AlienDrive API
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* const drive = new AlienDrive({ endpoint: 'https://drive.moltenalien.com', apiKey: 'mcd_...' });
|
|
6
|
+
* await drive.putObject({ Key: 'docs/file.txt', Body: Buffer.from('hello') });
|
|
7
|
+
* const data = await drive.getObject({ Key: 'docs/file.txt' });
|
|
8
|
+
* const list = await drive.listObjects({ Prefix: 'docs/' });
|
|
9
|
+
* await drive.deleteObject({ Key: 'docs/file.txt' });
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
class AlienDrive {
|
|
13
|
+
constructor({ endpoint, apiKey }) {
|
|
14
|
+
this.endpoint = endpoint.replace(/\/$/, '');
|
|
15
|
+
this.apiKey = apiKey;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async _fetch(path, opts = {}) {
|
|
19
|
+
const url = `${this.endpoint}${path}`;
|
|
20
|
+
const headers = { 'Authorization': `Bearer ${this.apiKey}`, ...opts.headers };
|
|
21
|
+
const res = await fetch(url, { ...opts, headers });
|
|
22
|
+
return res;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Upload a file — like S3 PutObject
|
|
27
|
+
* @param {Object} params
|
|
28
|
+
* @param {string} params.Key - e.g. "Documents/report.pdf"
|
|
29
|
+
* @param {Buffer|string|ReadableStream} params.Body - file content
|
|
30
|
+
* @param {string} [params.ContentType] - MIME type
|
|
31
|
+
*/
|
|
32
|
+
async putObject({ Key, Body, ContentType = 'application/octet-stream' }) {
|
|
33
|
+
const res = await this._fetch(`/api/v1/objects?key=${encodeURIComponent(Key)}`, {
|
|
34
|
+
method: 'PUT',
|
|
35
|
+
headers: { 'Content-Type': ContentType },
|
|
36
|
+
body: Body,
|
|
37
|
+
});
|
|
38
|
+
if (!res.ok) {
|
|
39
|
+
const err = await res.json().catch(() => ({ error: res.statusText }));
|
|
40
|
+
throw new Error(`PutObject failed (${res.status}): ${err.error}`);
|
|
41
|
+
}
|
|
42
|
+
return res.json();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Download a file — like S3 GetObject
|
|
47
|
+
* @param {Object} params
|
|
48
|
+
* @param {string} params.Key - e.g. "Documents/report.pdf"
|
|
49
|
+
* @returns {{ Body: Buffer, ContentType: string, ContentLength: number, ETag: string, LastModified: string }}
|
|
50
|
+
*/
|
|
51
|
+
async getObject({ Key }) {
|
|
52
|
+
const res = await this._fetch(`/api/v1/objects?key=${encodeURIComponent(Key)}`, {
|
|
53
|
+
redirect: 'follow',
|
|
54
|
+
});
|
|
55
|
+
if (!res.ok) {
|
|
56
|
+
throw new Error(`GetObject failed (${res.status}): NoSuchKey`);
|
|
57
|
+
}
|
|
58
|
+
const contentType = res.headers.get('content-type') || 'application/octet-stream';
|
|
59
|
+
const contentLength = parseInt(res.headers.get('content-length') || '0');
|
|
60
|
+
const etag = res.headers.get('etag') || '';
|
|
61
|
+
const lastModified = res.headers.get('last-modified') || '';
|
|
62
|
+
const buffer = Buffer.from(await res.arrayBuffer());
|
|
63
|
+
return {
|
|
64
|
+
Body: buffer,
|
|
65
|
+
ContentType: contentType,
|
|
66
|
+
ContentLength: contentLength,
|
|
67
|
+
ETag: etag,
|
|
68
|
+
LastModified: lastModified,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Get file metadata — like S3 HeadObject
|
|
74
|
+
* @param {Object} params
|
|
75
|
+
* @param {string} params.Key
|
|
76
|
+
*/
|
|
77
|
+
async headObject({ Key }) {
|
|
78
|
+
const res = await this._fetch(`/api/v1/objects?key=${encodeURIComponent(Key)}`, {
|
|
79
|
+
method: 'HEAD',
|
|
80
|
+
});
|
|
81
|
+
if (!res.ok) {
|
|
82
|
+
throw new Error(`HeadObject failed (${res.status}): NoSuchKey`);
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
ContentType: res.headers.get('content-type'),
|
|
86
|
+
ContentLength: parseInt(res.headers.get('content-length') || '0'),
|
|
87
|
+
ETag: res.headers.get('etag'),
|
|
88
|
+
LastModified: res.headers.get('last-modified'),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* List objects — like S3 ListObjectsV2
|
|
94
|
+
* @param {Object} [params]
|
|
95
|
+
* @param {string} [params.Prefix] - e.g. "Documents/"
|
|
96
|
+
* @param {number} [params.MaxKeys] - max results (default 1000)
|
|
97
|
+
*/
|
|
98
|
+
async listObjects({ Prefix = '', MaxKeys = 1000 } = {}) {
|
|
99
|
+
const params = new URLSearchParams();
|
|
100
|
+
if (Prefix) params.set('prefix', Prefix);
|
|
101
|
+
if (MaxKeys) params.set('maxKeys', String(MaxKeys));
|
|
102
|
+
const qs = params.toString();
|
|
103
|
+
|
|
104
|
+
const res = await this._fetch(`/api/v1/objects${qs ? '?' + qs : ''}`);
|
|
105
|
+
if (!res.ok) {
|
|
106
|
+
const err = await res.json().catch(() => ({ error: res.statusText }));
|
|
107
|
+
throw new Error(`ListObjects failed (${res.status}): ${err.error}`);
|
|
108
|
+
}
|
|
109
|
+
return res.json();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Delete a file — like S3 DeleteObject
|
|
114
|
+
* @param {Object} params
|
|
115
|
+
* @param {string} params.Key
|
|
116
|
+
*/
|
|
117
|
+
async deleteObject({ Key }) {
|
|
118
|
+
const res = await this._fetch(`/api/v1/objects?key=${encodeURIComponent(Key)}`, {
|
|
119
|
+
method: 'DELETE',
|
|
120
|
+
});
|
|
121
|
+
if (res.status !== 204 && !res.ok) {
|
|
122
|
+
throw new Error(`DeleteObject failed (${res.status})`);
|
|
123
|
+
}
|
|
124
|
+
return { DeleteMarker: true };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// ── Convenience methods ──
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Upload a local file
|
|
131
|
+
*/
|
|
132
|
+
async uploadFile(localPath, remotePath) {
|
|
133
|
+
const fs = require('fs');
|
|
134
|
+
const path = require('path');
|
|
135
|
+
const mime = {
|
|
136
|
+
'.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.png': 'image/png', '.gif': 'image/gif',
|
|
137
|
+
'.pdf': 'application/pdf', '.txt': 'text/plain', '.html': 'text/html',
|
|
138
|
+
'.json': 'application/json', '.xml': 'application/xml',
|
|
139
|
+
'.zip': 'application/zip', '.mp4': 'video/mp4', '.mp3': 'audio/mpeg',
|
|
140
|
+
};
|
|
141
|
+
const ext = path.extname(localPath).toLowerCase();
|
|
142
|
+
const body = fs.readFileSync(localPath);
|
|
143
|
+
const key = remotePath || path.basename(localPath);
|
|
144
|
+
return this.putObject({ Key: key, Body: body, ContentType: mime[ext] || 'application/octet-stream' });
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Download to a local file
|
|
149
|
+
*/
|
|
150
|
+
async downloadFile(remotePath, localPath) {
|
|
151
|
+
const fs = require('fs');
|
|
152
|
+
const data = await this.getObject({ Key: remotePath });
|
|
153
|
+
fs.writeFileSync(localPath, data.Body);
|
|
154
|
+
return { size: data.ContentLength, path: localPath };
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
module.exports = { AlienDrive };
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "aliendrive-sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Official Node.js SDK for the AlienDrive API — S3-like cloud storage",
|
|
5
|
+
"main": "aliendrive.js",
|
|
6
|
+
"types": "aliendrive.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"aliendrive.js",
|
|
9
|
+
"aliendrive.d.ts"
|
|
10
|
+
],
|
|
11
|
+
"keywords": [
|
|
12
|
+
"aliendrive",
|
|
13
|
+
"cloud-storage",
|
|
14
|
+
"s3",
|
|
15
|
+
"file-storage",
|
|
16
|
+
"object-storage",
|
|
17
|
+
"drive",
|
|
18
|
+
"api",
|
|
19
|
+
"sdk"
|
|
20
|
+
],
|
|
21
|
+
"author": "MoltenAlien",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/moltenalien/aliendrive-sdk"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://drive.moltenalien.com/api-docs",
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=18.0.0"
|
|
30
|
+
}
|
|
31
|
+
}
|