@printhive/api 0.1.0 → 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 +7 -0
- package/README.md +60 -6
- package/dist/{chunk-TGPYH7CV.js → chunk-7UULMDS5.js} +4199 -2437
- package/dist/{errors-LHFABGGG.js → errors-TJFN2M7S.js} +1 -1
- package/dist/index.cjs +4323 -2433
- package/dist/index.d.cts +757 -1
- package/dist/index.d.ts +757 -1
- package/dist/index.js +142 -11
- package/package.json +7 -2
package/dist/index.js
CHANGED
|
@@ -3,10 +3,14 @@ import {
|
|
|
3
3
|
PrintHiveNetworkError,
|
|
4
4
|
apiError,
|
|
5
5
|
apiKey,
|
|
6
|
+
createRequest,
|
|
6
7
|
model,
|
|
7
8
|
page,
|
|
9
|
+
printJob,
|
|
10
|
+
printer,
|
|
11
|
+
printers,
|
|
8
12
|
source
|
|
9
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-7UULMDS5.js";
|
|
10
14
|
|
|
11
15
|
// src/transport.ts
|
|
12
16
|
var MAX_RETRY_AFTER_MS = 6e4;
|
|
@@ -29,6 +33,14 @@ async function pause(ms, signal) {
|
|
|
29
33
|
signal?.addEventListener("abort", abort, { once: true });
|
|
30
34
|
});
|
|
31
35
|
}
|
|
36
|
+
function postHeaders(request) {
|
|
37
|
+
const headers = new Headers({ "idempotency-key": request.idempotencyKey });
|
|
38
|
+
if (request.contentType !== null)
|
|
39
|
+
headers.set("content-type", request.contentType ?? "model/3mf");
|
|
40
|
+
if (request.size !== void 0)
|
|
41
|
+
headers.set("content-length", String(request.size));
|
|
42
|
+
return headers;
|
|
43
|
+
}
|
|
32
44
|
var Transport = class {
|
|
33
45
|
options;
|
|
34
46
|
constructor(options) {
|
|
@@ -76,9 +88,8 @@ var Transport = class {
|
|
|
76
88
|
redirect: "error"
|
|
77
89
|
};
|
|
78
90
|
if (request.method === "POST") {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
headers.set("idempotency-key", request.idempotencyKey);
|
|
91
|
+
for (const [name, value] of postHeaders(request))
|
|
92
|
+
headers.set(name, value);
|
|
82
93
|
init.body = await request.body();
|
|
83
94
|
init.duplex = "half";
|
|
84
95
|
}
|
|
@@ -114,7 +125,14 @@ function retryDelay(failure, replayable, attempt, maxRetries) {
|
|
|
114
125
|
return Math.max(backoff, retryAfterMs);
|
|
115
126
|
}
|
|
116
127
|
|
|
117
|
-
// src/
|
|
128
|
+
// src/print-jobs.ts
|
|
129
|
+
var PrintJobCreateStoppedError = class extends Error {
|
|
130
|
+
constructor(request) {
|
|
131
|
+
super(`Print job creation ${request.status}`);
|
|
132
|
+
this.request = request;
|
|
133
|
+
this.name = "PrintJobCreateStoppedError";
|
|
134
|
+
}
|
|
135
|
+
};
|
|
118
136
|
async function decode(response, validate) {
|
|
119
137
|
const value = await response.json().catch((error) => {
|
|
120
138
|
if (error instanceof SyntaxError)
|
|
@@ -124,6 +142,97 @@ async function decode(response, validate) {
|
|
|
124
142
|
if (!validate(value)) throw new TypeError("Invalid Print Hive API response");
|
|
125
143
|
return value;
|
|
126
144
|
}
|
|
145
|
+
var PrintJobs = class {
|
|
146
|
+
constructor(transport) {
|
|
147
|
+
this.transport = transport;
|
|
148
|
+
}
|
|
149
|
+
async create(input) {
|
|
150
|
+
const { idempotencyKey: suppliedKey, ...bodyInput } = input;
|
|
151
|
+
const idempotencyKey = suppliedKey ?? crypto.randomUUID();
|
|
152
|
+
if ("file" in bodyInput) {
|
|
153
|
+
const { file, filename, ...metadata } = bodyInput;
|
|
154
|
+
const bytes = file instanceof Uint8Array ? new Uint8Array(file) : new Uint8Array(
|
|
155
|
+
await (await import("fs/promises")).readFile(file)
|
|
156
|
+
);
|
|
157
|
+
const response2 = await this.transport.request({
|
|
158
|
+
method: "POST",
|
|
159
|
+
path: "/v1/print-jobs/create",
|
|
160
|
+
idempotencyKey,
|
|
161
|
+
replayable: true,
|
|
162
|
+
contentType: null,
|
|
163
|
+
body: async () => {
|
|
164
|
+
const form = new FormData();
|
|
165
|
+
for (const [field, value] of Object.entries({
|
|
166
|
+
name: metadata.name,
|
|
167
|
+
printer_id: metadata.printer_id,
|
|
168
|
+
on_filament_mismatch: metadata.on_filament_mismatch,
|
|
169
|
+
externalId: metadata.externalId,
|
|
170
|
+
release: metadata.release
|
|
171
|
+
})) {
|
|
172
|
+
if (value !== void 0) form.set(field, value);
|
|
173
|
+
}
|
|
174
|
+
form.set("plate", String(metadata.plate));
|
|
175
|
+
form.set("filaments", JSON.stringify(metadata.filaments));
|
|
176
|
+
if (metadata.print_options !== void 0)
|
|
177
|
+
form.set("print_options", JSON.stringify(metadata.print_options));
|
|
178
|
+
form.set("file", new Blob([bytes]), filename);
|
|
179
|
+
return form;
|
|
180
|
+
},
|
|
181
|
+
decode: (response3) => decode(response3, createRequest)
|
|
182
|
+
});
|
|
183
|
+
return { ...response2, idempotencyKey };
|
|
184
|
+
}
|
|
185
|
+
const response = await this.transport.request({
|
|
186
|
+
method: "POST",
|
|
187
|
+
path: "/v1/print-jobs/create",
|
|
188
|
+
idempotencyKey,
|
|
189
|
+
replayable: true,
|
|
190
|
+
contentType: "application/json",
|
|
191
|
+
body: async () => JSON.stringify(bodyInput),
|
|
192
|
+
decode: (response2) => decode(response2, printJob)
|
|
193
|
+
});
|
|
194
|
+
return { ...response, idempotencyKey };
|
|
195
|
+
}
|
|
196
|
+
getCreateRequest(requestId, signal) {
|
|
197
|
+
return this.transport.request({
|
|
198
|
+
method: "GET",
|
|
199
|
+
path: `/v1/print-jobs/create-requests/${encodeURIComponent(requestId)}`,
|
|
200
|
+
signal,
|
|
201
|
+
decode: (response) => decode(response, createRequest)
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
async waitUntilCreated(requestId, options = {}) {
|
|
205
|
+
const interval = positive(options.intervalMs ?? 1e3, "intervalMs");
|
|
206
|
+
const deadline = AbortSignal.timeout(
|
|
207
|
+
positive(options.timeoutMs ?? 12e4, "timeoutMs")
|
|
208
|
+
);
|
|
209
|
+
const signal = options.signal ? AbortSignal.any([options.signal, deadline]) : deadline;
|
|
210
|
+
try {
|
|
211
|
+
for (; ; ) {
|
|
212
|
+
const request = await this.getCreateRequest(requestId, signal);
|
|
213
|
+
if (request.status === "created") return request;
|
|
214
|
+
if (request.status !== "preparing")
|
|
215
|
+
throw new PrintJobCreateStoppedError(request);
|
|
216
|
+
await pause(interval, signal);
|
|
217
|
+
}
|
|
218
|
+
} catch (error) {
|
|
219
|
+
if (deadline.aborted && !options.signal?.aborted)
|
|
220
|
+
throw new PrintHiveNetworkError("timeout");
|
|
221
|
+
throw error;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
// src/index.ts
|
|
227
|
+
async function decode2(response, validate) {
|
|
228
|
+
const value = await response.json().catch((error) => {
|
|
229
|
+
if (error instanceof SyntaxError)
|
|
230
|
+
throw new TypeError("Invalid Print Hive API response");
|
|
231
|
+
throw error;
|
|
232
|
+
});
|
|
233
|
+
if (!validate(value)) throw new TypeError("Invalid Print Hive API response");
|
|
234
|
+
return value;
|
|
235
|
+
}
|
|
127
236
|
function isPath(file) {
|
|
128
237
|
return !(file instanceof Uint8Array) && !(file instanceof ReadableStream);
|
|
129
238
|
}
|
|
@@ -131,14 +240,35 @@ var prefix = "/v1/partner-production";
|
|
|
131
240
|
var PrintHive = class {
|
|
132
241
|
partnerSources;
|
|
133
242
|
models;
|
|
243
|
+
printers;
|
|
244
|
+
printJobs;
|
|
134
245
|
constructor(options) {
|
|
135
246
|
const transport = new Transport(options);
|
|
247
|
+
this.printJobs = new PrintJobs(transport);
|
|
136
248
|
const get = (sourceId, signal) => transport.request({
|
|
137
|
-
decode: (response) =>
|
|
249
|
+
decode: (response) => decode2(response, source),
|
|
138
250
|
method: "GET",
|
|
139
251
|
path: `${prefix}/uploads/${encodeURIComponent(sourceId)}`,
|
|
140
252
|
signal
|
|
141
253
|
});
|
|
254
|
+
this.printers = {
|
|
255
|
+
list: (input = {}) => {
|
|
256
|
+
const query = new URLSearchParams();
|
|
257
|
+
if (input.limit !== void 0) query.set("limit", String(input.limit));
|
|
258
|
+
if (input.cursor !== void 0) query.set("cursor", input.cursor);
|
|
259
|
+
return transport.request({
|
|
260
|
+
decode: (response) => decode2(response, printers),
|
|
261
|
+
method: "GET",
|
|
262
|
+
path: "/v1/printers",
|
|
263
|
+
query
|
|
264
|
+
});
|
|
265
|
+
},
|
|
266
|
+
get: (id) => transport.request({
|
|
267
|
+
decode: (response) => decode2(response, printer),
|
|
268
|
+
method: "GET",
|
|
269
|
+
path: `/v1/printers/${encodeURIComponent(id)}`
|
|
270
|
+
})
|
|
271
|
+
};
|
|
142
272
|
this.partnerSources = {
|
|
143
273
|
get,
|
|
144
274
|
async upload(input) {
|
|
@@ -172,7 +302,7 @@ var PrintHive = class {
|
|
|
172
302
|
if (!Number.isSafeInteger(size) || size < 0)
|
|
173
303
|
throw new RangeError("size must be a nonnegative safe integer");
|
|
174
304
|
const source2 = await transport.request({
|
|
175
|
-
decode: (response) =>
|
|
305
|
+
decode: (response) => decode2(response, source),
|
|
176
306
|
method: "POST",
|
|
177
307
|
path: `${prefix}/uploads`,
|
|
178
308
|
query,
|
|
@@ -198,7 +328,7 @@ var PrintHive = class {
|
|
|
198
328
|
}
|
|
199
329
|
} catch (error) {
|
|
200
330
|
if (deadline.aborted && !options2.signal?.aborted) {
|
|
201
|
-
const { PrintHiveNetworkError: PrintHiveNetworkError2 } = await import("./errors-
|
|
331
|
+
const { PrintHiveNetworkError: PrintHiveNetworkError2 } = await import("./errors-TJFN2M7S.js");
|
|
202
332
|
throw new PrintHiveNetworkError2("timeout");
|
|
203
333
|
}
|
|
204
334
|
throw error;
|
|
@@ -207,7 +337,7 @@ var PrintHive = class {
|
|
|
207
337
|
};
|
|
208
338
|
this.models = {
|
|
209
339
|
findByExternalId: (externalId) => transport.request({
|
|
210
|
-
decode: (response) =>
|
|
340
|
+
decode: (response) => decode2(response, model),
|
|
211
341
|
method: "GET",
|
|
212
342
|
path: `${prefix}/models`,
|
|
213
343
|
query: new URLSearchParams({ externalId })
|
|
@@ -218,7 +348,7 @@ var PrintHive = class {
|
|
|
218
348
|
const query = new URLSearchParams();
|
|
219
349
|
if (cursor !== null) query.set("cursor", cursor);
|
|
220
350
|
const page2 = await transport.request({
|
|
221
|
-
decode: (response) =>
|
|
351
|
+
decode: (response) => decode2(response, page),
|
|
222
352
|
method: "GET",
|
|
223
353
|
path: `${prefix}/models/${encodeURIComponent(modelId)}/files`,
|
|
224
354
|
query
|
|
@@ -233,5 +363,6 @@ var PrintHive = class {
|
|
|
233
363
|
export {
|
|
234
364
|
PrintHive,
|
|
235
365
|
PrintHiveApiError,
|
|
236
|
-
PrintHiveNetworkError
|
|
366
|
+
PrintHiveNetworkError,
|
|
367
|
+
PrintJobCreateStoppedError
|
|
237
368
|
};
|
package/package.json
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@printhive/api",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
|
-
"description": "Print Hive
|
|
6
|
+
"description": "Print Hive REST API client",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/PrintHive/hive.git",
|
|
10
|
+
"directory": "packages/api-client"
|
|
11
|
+
},
|
|
7
12
|
"main": "./dist/index.cjs",
|
|
8
13
|
"module": "./dist/index.js",
|
|
9
14
|
"types": "./dist/index.d.ts",
|