disk 0.7.1 → 0.8.8
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/{LICENSE.md → LICENSE} +10 -9
- package/README.md +111 -78
- package/dist/cli.js +573 -0
- package/dist/index.cjs +421 -0
- package/dist/index.d.cts +1144 -0
- package/dist/index.d.ts +1144 -0
- package/dist/index.js +372 -0
- package/package.json +41 -37
- package/lib/disk.js +0 -379
- package/lib/partition.js +0 -117
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
Archil: () => Archil,
|
|
34
|
+
ArchilApiError: () => ArchilApiError,
|
|
35
|
+
Disk: () => Disk,
|
|
36
|
+
Disks: () => Disks,
|
|
37
|
+
Tokens: () => Tokens,
|
|
38
|
+
configure: () => configure,
|
|
39
|
+
createApiKey: () => createApiKey,
|
|
40
|
+
createDisk: () => createDisk,
|
|
41
|
+
deleteApiKey: () => deleteApiKey,
|
|
42
|
+
getDisk: () => getDisk,
|
|
43
|
+
listApiKeys: () => listApiKeys,
|
|
44
|
+
listDisks: () => listDisks
|
|
45
|
+
});
|
|
46
|
+
module.exports = __toCommonJS(index_exports);
|
|
47
|
+
|
|
48
|
+
// src/client.ts
|
|
49
|
+
var import_openapi_fetch = __toESM(require("openapi-fetch"), 1);
|
|
50
|
+
|
|
51
|
+
// src/errors.ts
|
|
52
|
+
var ArchilApiError = class extends Error {
|
|
53
|
+
status;
|
|
54
|
+
code;
|
|
55
|
+
constructor(message, status, code) {
|
|
56
|
+
super(message);
|
|
57
|
+
this.name = "ArchilApiError";
|
|
58
|
+
this.status = status;
|
|
59
|
+
this.code = code;
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// src/regions.ts
|
|
64
|
+
var REGION_URLS = {
|
|
65
|
+
"aws-us-east-1": "https://control.green.us-east-1.aws.prod.archil.com",
|
|
66
|
+
"aws-us-west-2": "https://control.green.us-west-2.aws.prod.archil.com",
|
|
67
|
+
"aws-eu-west-1": "https://control.green.eu-west-1.aws.prod.archil.com",
|
|
68
|
+
"gcp-us-central1": "https://control.blue.us-central1.gcp.prod.archil.com"
|
|
69
|
+
};
|
|
70
|
+
function resolveBaseUrl(region) {
|
|
71
|
+
const url = REGION_URLS[region];
|
|
72
|
+
if (!url) {
|
|
73
|
+
throw new Error(
|
|
74
|
+
`Unknown region "${region}". Valid regions: ${Object.keys(REGION_URLS).join(", ")}`
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
return url;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// src/client.ts
|
|
81
|
+
function createApiClient(opts) {
|
|
82
|
+
const baseUrl = opts.baseUrl ?? resolveBaseUrl(opts.region);
|
|
83
|
+
return (0, import_openapi_fetch.default)({
|
|
84
|
+
baseUrl,
|
|
85
|
+
headers: {
|
|
86
|
+
Authorization: `key-${opts.apiKey.replace(/^key-/, "")}`
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
async function unwrap(promise) {
|
|
91
|
+
const { data: body, error, response } = await promise;
|
|
92
|
+
if (error || !body) {
|
|
93
|
+
const errBody = error;
|
|
94
|
+
throw new ArchilApiError(
|
|
95
|
+
errBody?.error ?? `API request failed with status ${response.status}`,
|
|
96
|
+
response.status
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
if (!body.success) {
|
|
100
|
+
throw new ArchilApiError(
|
|
101
|
+
body.error ?? "Unknown API error",
|
|
102
|
+
response.status
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
return body.data;
|
|
106
|
+
}
|
|
107
|
+
async function unwrapEmpty(promise) {
|
|
108
|
+
const { data: body, error, response } = await promise;
|
|
109
|
+
if (error || !body) {
|
|
110
|
+
const errBody = error;
|
|
111
|
+
throw new ArchilApiError(
|
|
112
|
+
errBody?.error ?? `API request failed with status ${response.status}`,
|
|
113
|
+
response.status
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
if (!body.success) {
|
|
117
|
+
throw new ArchilApiError(
|
|
118
|
+
body.error ?? "Unknown API error",
|
|
119
|
+
response.status
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// src/disk.ts
|
|
125
|
+
var import_node_module = require("module");
|
|
126
|
+
var import_node_url = require("url");
|
|
127
|
+
var import_meta = {};
|
|
128
|
+
var Disk = class {
|
|
129
|
+
id;
|
|
130
|
+
name;
|
|
131
|
+
organization;
|
|
132
|
+
status;
|
|
133
|
+
provider;
|
|
134
|
+
region;
|
|
135
|
+
createdAt;
|
|
136
|
+
fsHandlerStatus;
|
|
137
|
+
lastAccessed;
|
|
138
|
+
dataSize;
|
|
139
|
+
monthlyUsage;
|
|
140
|
+
mounts;
|
|
141
|
+
metrics;
|
|
142
|
+
connectedClients;
|
|
143
|
+
authorizedUsers;
|
|
144
|
+
/** @internal */
|
|
145
|
+
_client;
|
|
146
|
+
/** @internal */
|
|
147
|
+
_archilRegion;
|
|
148
|
+
/** @internal */
|
|
149
|
+
constructor(data, client, archilRegion) {
|
|
150
|
+
this.id = data.id;
|
|
151
|
+
this.name = data.name;
|
|
152
|
+
this.organization = data.organization;
|
|
153
|
+
this.status = data.status;
|
|
154
|
+
this.provider = data.provider;
|
|
155
|
+
this.region = data.region;
|
|
156
|
+
this.createdAt = data.createdAt;
|
|
157
|
+
this.fsHandlerStatus = data.fsHandlerStatus;
|
|
158
|
+
this.lastAccessed = data.lastAccessed;
|
|
159
|
+
this.dataSize = data.dataSize;
|
|
160
|
+
this.monthlyUsage = data.monthlyUsage;
|
|
161
|
+
this.mounts = data.mounts;
|
|
162
|
+
this.metrics = data.metrics;
|
|
163
|
+
this.connectedClients = data.connectedClients;
|
|
164
|
+
this.authorizedUsers = data.authorizedUsers;
|
|
165
|
+
this._client = client;
|
|
166
|
+
this._archilRegion = archilRegion;
|
|
167
|
+
}
|
|
168
|
+
toJSON() {
|
|
169
|
+
return {
|
|
170
|
+
id: this.id,
|
|
171
|
+
name: this.name,
|
|
172
|
+
organization: this.organization,
|
|
173
|
+
status: this.status,
|
|
174
|
+
provider: this.provider,
|
|
175
|
+
region: this.region,
|
|
176
|
+
createdAt: this.createdAt,
|
|
177
|
+
fsHandlerStatus: this.fsHandlerStatus,
|
|
178
|
+
lastAccessed: this.lastAccessed,
|
|
179
|
+
dataSize: this.dataSize,
|
|
180
|
+
monthlyUsage: this.monthlyUsage,
|
|
181
|
+
mounts: this.mounts,
|
|
182
|
+
metrics: this.metrics,
|
|
183
|
+
connectedClients: this.connectedClients,
|
|
184
|
+
authorizedUsers: this.authorizedUsers
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
async addUser(user) {
|
|
188
|
+
return unwrap(
|
|
189
|
+
this._client.POST("/api/disks/{id}/users", {
|
|
190
|
+
params: { path: { id: this.id } },
|
|
191
|
+
body: user
|
|
192
|
+
})
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
async removeUser(userType, identifier) {
|
|
196
|
+
await unwrapEmpty(
|
|
197
|
+
this._client.DELETE("/api/disks/{id}/users/{userType}", {
|
|
198
|
+
params: {
|
|
199
|
+
path: { id: this.id, userType },
|
|
200
|
+
query: { identifier }
|
|
201
|
+
}
|
|
202
|
+
})
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
async createToken(nickname) {
|
|
206
|
+
const user = await unwrap(
|
|
207
|
+
this._client.POST("/api/disks/{id}/users", {
|
|
208
|
+
params: { path: { id: this.id } },
|
|
209
|
+
body: { type: "token", nickname }
|
|
210
|
+
})
|
|
211
|
+
);
|
|
212
|
+
if (!user.token || !user.identifier) {
|
|
213
|
+
throw new Error("Server did not return a generated token");
|
|
214
|
+
}
|
|
215
|
+
return user;
|
|
216
|
+
}
|
|
217
|
+
async removeTokenUser(identifier) {
|
|
218
|
+
await this.removeUser("token", identifier);
|
|
219
|
+
}
|
|
220
|
+
async delete() {
|
|
221
|
+
await unwrapEmpty(
|
|
222
|
+
this._client.DELETE("/api/disks/{id}", {
|
|
223
|
+
params: { path: { id: this.id } }
|
|
224
|
+
})
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Execute a command in a container with this disk mounted.
|
|
229
|
+
* Blocks until the command completes and returns stdout, stderr, and exit code.
|
|
230
|
+
*/
|
|
231
|
+
async exec(command) {
|
|
232
|
+
return unwrap(
|
|
233
|
+
this._client.POST("/api/disks/{id}/exec", {
|
|
234
|
+
params: { path: { id: this.id } },
|
|
235
|
+
body: { command }
|
|
236
|
+
})
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Connect to this disk's data plane via the native ArchilClient.
|
|
241
|
+
*
|
|
242
|
+
* Requires the native module to be available (platform-specific .node binary).
|
|
243
|
+
*/
|
|
244
|
+
async mount(opts) {
|
|
245
|
+
let ArchilClient;
|
|
246
|
+
try {
|
|
247
|
+
const base = typeof import_meta !== "undefined" && import_meta.url ? import_meta.url : (0, import_node_url.pathToFileURL)(__filename).href;
|
|
248
|
+
const nativeRequire = (0, import_node_module.createRequire)(base);
|
|
249
|
+
const native = nativeRequire("@archildata/native");
|
|
250
|
+
ArchilClient = native.ArchilClient;
|
|
251
|
+
} catch {
|
|
252
|
+
throw new Error(
|
|
253
|
+
"Native client not available. Install @archildata/native (platform-specific binary) or use ArchilClient.connect() directly."
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
return ArchilClient.connect({
|
|
257
|
+
region: this._archilRegion,
|
|
258
|
+
diskName: `${this.organization}/${this.name}`,
|
|
259
|
+
authToken: opts?.authToken,
|
|
260
|
+
logLevel: opts?.logLevel,
|
|
261
|
+
serverAddress: opts?.serverAddress,
|
|
262
|
+
insecure: opts?.insecure
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
// src/disks.ts
|
|
268
|
+
var Disks = class {
|
|
269
|
+
/** @internal */
|
|
270
|
+
_client;
|
|
271
|
+
/** @internal */
|
|
272
|
+
_region;
|
|
273
|
+
/** @internal */
|
|
274
|
+
constructor(client, region) {
|
|
275
|
+
this._client = client;
|
|
276
|
+
this._region = region;
|
|
277
|
+
}
|
|
278
|
+
async list(opts) {
|
|
279
|
+
const data = await unwrap(
|
|
280
|
+
this._client.GET("/api/disks", {
|
|
281
|
+
params: { query: { limit: opts?.limit, cursor: opts?.cursor } }
|
|
282
|
+
})
|
|
283
|
+
);
|
|
284
|
+
return data.map(
|
|
285
|
+
(d) => new Disk(d, this._client, this._region)
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
async get(id) {
|
|
289
|
+
const data = await unwrap(
|
|
290
|
+
this._client.GET("/api/disks/{id}", {
|
|
291
|
+
params: { path: { id } }
|
|
292
|
+
})
|
|
293
|
+
);
|
|
294
|
+
return new Disk(data, this._client, this._region);
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Create a new disk with an auto-generated mount token.
|
|
298
|
+
*
|
|
299
|
+
* Returns the Disk, the one-time token (save it — it cannot be retrieved
|
|
300
|
+
* again), and the token identifier for later management.
|
|
301
|
+
*/
|
|
302
|
+
async create(req) {
|
|
303
|
+
const created = await unwrap(
|
|
304
|
+
this._client.POST("/api/disks", { body: req })
|
|
305
|
+
);
|
|
306
|
+
const resp = created;
|
|
307
|
+
if (!resp.diskId) {
|
|
308
|
+
throw new Error("API returned success but no diskId");
|
|
309
|
+
}
|
|
310
|
+
const authorizedUsers = resp.authorizedUsers ?? [];
|
|
311
|
+
const tokenUser = authorizedUsers.find((u) => u.token);
|
|
312
|
+
const disk = await this.get(resp.diskId);
|
|
313
|
+
return {
|
|
314
|
+
disk,
|
|
315
|
+
token: tokenUser?.token ?? null,
|
|
316
|
+
tokenIdentifier: tokenUser?.identifier ?? null,
|
|
317
|
+
authorizedUsers
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// src/tokens.ts
|
|
323
|
+
var Tokens = class {
|
|
324
|
+
/** @internal */
|
|
325
|
+
_client;
|
|
326
|
+
/** @internal */
|
|
327
|
+
constructor(client) {
|
|
328
|
+
this._client = client;
|
|
329
|
+
}
|
|
330
|
+
async list(opts) {
|
|
331
|
+
const data = await unwrap(
|
|
332
|
+
this._client.GET("/api/tokens", {
|
|
333
|
+
params: { query: { limit: opts?.limit, cursor: opts?.cursor } }
|
|
334
|
+
})
|
|
335
|
+
);
|
|
336
|
+
return data.tokens ?? [];
|
|
337
|
+
}
|
|
338
|
+
async create(req) {
|
|
339
|
+
const data = await unwrap(
|
|
340
|
+
this._client.POST("/api/tokens", { body: req })
|
|
341
|
+
);
|
|
342
|
+
return data;
|
|
343
|
+
}
|
|
344
|
+
async delete(id) {
|
|
345
|
+
await unwrapEmpty(
|
|
346
|
+
this._client.DELETE("/api/tokens/{id}", {
|
|
347
|
+
params: { path: { id } }
|
|
348
|
+
})
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
// src/archil.ts
|
|
354
|
+
var Archil = class {
|
|
355
|
+
disks;
|
|
356
|
+
tokens;
|
|
357
|
+
constructor(opts = {}) {
|
|
358
|
+
const apiKey = opts.apiKey ?? process.env.ARCHIL_API_KEY;
|
|
359
|
+
const region = opts.region ?? process.env.ARCHIL_REGION;
|
|
360
|
+
if (!apiKey) {
|
|
361
|
+
throw new Error("Missing API key: pass apiKey in options or set ARCHIL_API_KEY environment variable");
|
|
362
|
+
}
|
|
363
|
+
if (!region) {
|
|
364
|
+
throw new Error("Missing region: pass region in options or set ARCHIL_REGION environment variable");
|
|
365
|
+
}
|
|
366
|
+
const client = createApiClient({
|
|
367
|
+
apiKey,
|
|
368
|
+
region,
|
|
369
|
+
baseUrl: opts.baseUrl
|
|
370
|
+
});
|
|
371
|
+
this.disks = new Disks(client, region);
|
|
372
|
+
this.tokens = new Tokens(client);
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
// src/index.ts
|
|
377
|
+
var _options;
|
|
378
|
+
var _instance;
|
|
379
|
+
function configure(options) {
|
|
380
|
+
_options = options;
|
|
381
|
+
_instance = void 0;
|
|
382
|
+
}
|
|
383
|
+
function archil() {
|
|
384
|
+
if (!_instance) {
|
|
385
|
+
_instance = new Archil(_options);
|
|
386
|
+
}
|
|
387
|
+
return _instance;
|
|
388
|
+
}
|
|
389
|
+
function createDisk(req) {
|
|
390
|
+
return archil().disks.create(req);
|
|
391
|
+
}
|
|
392
|
+
function listDisks(opts) {
|
|
393
|
+
return archil().disks.list(opts);
|
|
394
|
+
}
|
|
395
|
+
function getDisk(id) {
|
|
396
|
+
return archil().disks.get(id);
|
|
397
|
+
}
|
|
398
|
+
function listApiKeys(opts) {
|
|
399
|
+
return archil().tokens.list(opts);
|
|
400
|
+
}
|
|
401
|
+
function createApiKey(req) {
|
|
402
|
+
return archil().tokens.create(req);
|
|
403
|
+
}
|
|
404
|
+
function deleteApiKey(id) {
|
|
405
|
+
return archil().tokens.delete(id);
|
|
406
|
+
}
|
|
407
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
408
|
+
0 && (module.exports = {
|
|
409
|
+
Archil,
|
|
410
|
+
ArchilApiError,
|
|
411
|
+
Disk,
|
|
412
|
+
Disks,
|
|
413
|
+
Tokens,
|
|
414
|
+
configure,
|
|
415
|
+
createApiKey,
|
|
416
|
+
createDisk,
|
|
417
|
+
deleteApiKey,
|
|
418
|
+
getDisk,
|
|
419
|
+
listApiKeys,
|
|
420
|
+
listDisks
|
|
421
|
+
});
|