@printhive/api 0.3.2 → 0.4.1
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 +13 -0
- package/README.md +146 -5
- package/dist/{chunk-YZJ5H32X.js → chunk-GOUMDFJR.js} +13520 -6769
- package/dist/{errors-GNC6X3MK.js → errors-4M56UUFV.js} +1 -1
- package/dist/index.cjs +15054 -8248
- package/dist/index.d.cts +1167 -151
- package/dist/index.d.ts +1167 -151
- package/dist/index.js +123 -63
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.1
|
|
4
|
+
|
|
5
|
+
- Document print-job creation's 503 `catalog_store_failed` response, including optional per-slot failure details, in the generated OpenAPI contract. Runtime behavior is unchanged.
|
|
6
|
+
- Global filament search results now have `acceptedByCreate: true` when the organization's global-filament setting and shared catalog admission allow creation. Disabled global IDs remain unavailable to create and are excluded from search. Search and create use one admission operation.
|
|
7
|
+
- Accept enabled global filament IDs on print-job creation and normalize single-color catalog choices with the shared material color rules. Reject ambiguous colors and failed setting reads. Return `merged_into` on merged-filament slot errors. Existing catalog CRUD routes can still return merge tombstones.
|
|
8
|
+
|
|
9
|
+
## 0.4.0
|
|
10
|
+
|
|
11
|
+
- Add typed `printers.search` and `filaments.search`, with bounded integer pagination and catalog `filamentId` values.
|
|
12
|
+
- Reuse the web palette printer matcher and the filament picker ranking through narrow partner routes.
|
|
13
|
+
- Add `acceptedByCreate` for the catalog admission rules in 0.4.0. At that release, global, unsynced, and invalid-color rows were flagged false. Global support is added in 0.4.1.
|
|
14
|
+
- Require Read scope on the existing `/v1/search` and `/v1/materials/command-search` API-key routes. Empty-scope keys receive 403.
|
|
15
|
+
|
|
3
16
|
## 0.3.2
|
|
4
17
|
|
|
5
18
|
- Add `printJobs.get` for live job polling after creation, including the API's waiting-reason snapshot.
|
package/README.md
CHANGED
|
@@ -28,11 +28,27 @@ const created = await hive.printJobs.waitUntilCreated(request.requestId);
|
|
|
28
28
|
console.log(created.job);
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
`printJobs.create` sends multipart to `/v1/print-jobs/create` for a file path or `Uint8Array` plus `filename`. `plate` and typed `filaments` are required; `targetSlot` is optional. Other inputs include `printer_id`, `name`, `externalId`, `release`, `on_filament_mismatch`, and existing `print_options`. This method reads file paths into memory, copies byte inputs, and can retry the multipart body safely. It returns the server's `202` request fields plus `idempotencyKey`. Persist your own key before calling when retries must survive process restarts. Changed metadata or bytes with the same key conflict.
|
|
31
|
+
`printJobs.create` sends multipart to `/v1/print-jobs/create` for a file path or `Uint8Array` plus `filename`. `plate` and typed `filaments` are required; `targetSlot` is optional. Other inputs include `printer_id`, `name`, `externalId`, `release`, `acceptEngineSettingUpdates`, `on_filament_mismatch`, and existing `print_options`. This method reads file paths into memory, copies byte inputs, and can retry the multipart body safely. It returns the server's `202` request fields plus `idempotencyKey`. Persist your own key before calling when retries must survive process restarts. Changed metadata or bytes with the same key conflict.
|
|
32
32
|
|
|
33
33
|
For an existing artifact, `printJobs.create({ name, model_file_id, ... })` sends JSON and returns the existing `201` response with `job` and eligibility fields plus `idempotencyKey`. The client generates an idempotency key once per call if omitted.
|
|
34
34
|
|
|
35
|
-
`printJobs.getCreateRequest(requestId)` reads the current receipt. `waitUntilCreated(requestId, { intervalMs?, timeoutMs?, signal? })` polls while `preparing`, defaults to a 120-second total deadline, and returns when `created`, including a retained receipt with `job: null` after the job was deleted. `PrintJobCreateStoppedError.request` exposes a `held`, `failed`, or `cancelled` receipt, including its required actions or failure reasons. It does not authorize a held request automatically.
|
|
35
|
+
`printJobs.getCreateRequest(requestId)` reads the current receipt. `waitUntilCreated(requestId, { intervalMs?, timeoutMs?, signal? })` polls while `preparing`, defaults to a 120-second total deadline, and returns when `created`, including a retained receipt with `job: null` after the job was deleted. `PrintJobCreateStoppedError.request` exposes a `held`, `failed`, or `cancelled` receipt, including its required actions or failure reasons. It does not authorize a held request automatically.
|
|
36
|
+
|
|
37
|
+
## Source preparation opt-ins
|
|
38
|
+
|
|
39
|
+
The opt-ins grant separate permissions. `acceptEngineSettingUpdates` permits eligible stock-setting updates; it does not permit an unqualified printer conversion. The separate `allowUnqualifiedConversion` control is being added in [#5083](https://github.com/PrintHive/hive/pull/5083) and is unavailable until that PR merges. Its conversion consent does not approve customised engine-setting changes. When both controls are available, a request can enable both; each still applies its own checks.
|
|
40
|
+
|
|
41
|
+
`acceptEngineSettingUpdates` has OpenAPI `default: false` for JSON and multipart creates. For source preparation, `true` accepts engine changes only to settings absent from the source's `different_settings_to_system` customisation list and backed by nonempty `inherits_group` entries for their presets. Missing diff metadata, a missing diff entry, or missing or empty preset inheritance makes the setting customised and it holds. An empty diff entry counts as stock only with inheritance evidence. Empty source setting values do not exempt customised settings. Accepted changes appear in the prepared plate's `lineage.acceptedEngineSettingChanges`.
|
|
42
|
+
|
|
43
|
+
An engine review hold includes `changes`, `sourceRelease`, and `engineRelease`, alongside the existing `detail`. Each change has `key`, `sourceValue`, `engineValue`, and `slots`. Array values identify changed slots using one-based source slot numbers. Scalar settings have an empty `slots` array. A setting removed by the engine has `engineValue: null`.
|
|
44
|
+
|
|
45
|
+
Call `printJobs.approveReview(requestId, { changes, sourceRelease, engineRelease })` with the reported values to re-slice. This requires `control` scope. It returns `{ approved: true }` with HTTP 202. Repeating the same approval returns 202 while that submitted review still covers the current pending or ready slice, without starting another slice. This includes Cloud Slice retries that change the slice ID while retaining the plate's approval. A stale or mismatched review returns HTTP 409 `review_conflict`. Approval accepts those changes for those releases, including customised settings. The create-time stock opt-in continues to accept eligible stock changes after approval. Other changes hold again. Poll the receipt again after approval.
|
|
46
|
+
|
|
47
|
+
For `release: "manual"` requests held by an engine review or another preparation reason, `/release` now returns HTTP 409 `manual_release_not_available` instead of 202. It keeps the holds and does not authorize manual release. Resolve the preparation holds first, then call `/release` when the only hold is `manual_release_required`.
|
|
48
|
+
|
|
49
|
+
Use the HTTP release/cancel operations described in the [integration reference](../../docs/integrations/printie/planned-production.md) when needed.
|
|
50
|
+
|
|
51
|
+
## Observe created jobs
|
|
36
52
|
|
|
37
53
|
`printJobs.get(jobId, signal?)` reads `GET /v1/print-jobs/{id}` and returns the inner job snapshot. It requires a positive safe-integer ID. After a create receipt reaches `created` with a non-null job, read that job separately to observe its current status and `print_options.filament_waiting_reasons`. A created job may still wait for materials or printer readiness. Keep polling the live job rather than treating its creation receipt as a current material assessment. A deleted or inaccessible job returns the API's error; the retained create receipt does not recreate it.
|
|
38
54
|
|
|
@@ -143,9 +159,9 @@ Only 429, 503, and network failures retry. Permanent `preparation_disabled` neve
|
|
|
143
159
|
|
|
144
160
|
## Coverage and contract maintenance
|
|
145
161
|
|
|
146
|
-
The current source covers creation and request polling under `/v1/print-jobs/create`, customer printer list and detail reads at `/v1/printers` and `/v1/printers/{id}`, plus preparation creation, reads, polling and download metadata, uploads, source reads and polling, external-id model lookup, and source-file listing under `/v1/partner-production/`. It offers no generic request method for other routes.
|
|
162
|
+
The current source covers creation and request polling under `/v1/print-jobs/create`, partner printer and filament search at `/v1/printers/search` and `/v1/filaments/search`, customer printer list and detail reads at `/v1/printers` and `/v1/printers/{id}`, plus preparation creation, reads, polling and download metadata, uploads, source reads and polling, external-id model lookup, and source-file listing under `/v1/partner-production/`. It offers no generic request method for other routes.
|
|
147
163
|
|
|
148
|
-
`apps/api/scripts/export-openapi.ts` builds a schema-only Fastify app from the real printer, file-compatibility, print-job, and partner route plugins, without listening, worker startup, database calls, or queue startup. It uses stub environment values. This intentionally exports authenticated partner routes directly. The Swagger UI's public-operation filter would remove them, and generic error enrichment would lose partner restriction details.
|
|
164
|
+
`apps/api/scripts/export-openapi.ts` builds a schema-only Fastify app from the real partner search, printer, file-compatibility, print-job, and partner route plugins, without listening, worker startup, database calls, or queue startup. It uses stub environment values. This intentionally exports authenticated partner routes directly. The Swagger UI's public-operation filter would remove them, and generic error enrichment would lose partner restriction details.
|
|
149
165
|
|
|
150
166
|
`bun run generate` filters that export by the prefix list in `scripts/contracts.mjs`, commits `openapi.json`, and generates TypeScript types and standalone response validators. AJV compiles the validators during development; the build bundles their small runtime helpers. `openapi-typescript` is a development dependency because it generates OpenAPI 3 union types without adding runtime dependencies. `bun run check:drift` reexports and compares the snapshot. Types and standalone validators regenerate in ignored `.temp` build output on every check. `bun run test` builds the distribution and runs its HTTP tests against `dist`, including in the release workflow. `api-client-check.yml` also runs when API or client sources change, so drift checks do not depend on Turbo selecting the client as affected.
|
|
151
167
|
|
|
@@ -222,4 +238,129 @@ All operations enforce organization ownership. Returned rows include `id`, `sku`
|
|
|
222
238
|
Errors include 400 `invalid_catalog_input`, 400 `conflicting_color_hex`, 403 `API_KEY_SCOPE_REQUIRED`,
|
|
223
239
|
404 `catalog_filament_not_found`, 409 `catalog_conflict` for uniqueness conflicts,
|
|
224
240
|
and 500 `catalog_store_failed`. Invalid bodies return the API validation error.
|
|
225
|
-
|
|
241
|
+
Pass the returned `id` as `filaments[].filamentId` in JSON or multipart print-job
|
|
242
|
+
creation. A slot can contain only `{ sourceSlot, filamentId }`, plus an optional
|
|
243
|
+
`targetSlot`. Hive derives material and color from the catalog row.
|
|
244
|
+
Explicit `material` and `color` must agree with the row. Material comparisons
|
|
245
|
+
ignore case, and colors accept a leading `#` and either case.
|
|
246
|
+
|
|
247
|
+
Create also accepts global filament IDs. Global filaments are platform-managed
|
|
248
|
+
`materials` rows with no organization owner. Search reports their
|
|
249
|
+
`organization_id` as `"global"`. The organization's `materials.global_filaments_enabled`
|
|
250
|
+
setting must be enabled. The setting defaults to enabled when absent, as in the
|
|
251
|
+
web material picker and Smart Queue. Organization-owned rows still require a
|
|
252
|
+
`partner-catalog:` import source. Other organization materials are not admitted
|
|
253
|
+
through this catalog contract.
|
|
254
|
+
|
|
255
|
+
A contradiction returns 422 `filament_catalog_conflict` with the `sourceSlot` in
|
|
256
|
+
`filaments[]`. An unknown or foreign catalog ID, a merge tombstone, an organization
|
|
257
|
+
row outside the partner catalog, or a global ID when globals are disabled returns 422
|
|
258
|
+
`catalog_filament_not_found` with the slot. Catalog rows without a material or a
|
|
259
|
+
readable color return 422 `invalid_catalog_filament`. The material must be at most
|
|
260
|
+
100 characters. Hive reads `metadata.colors`, falling back to `color`, and normalizes
|
|
261
|
+
named colors and 8-digit hex colors to `#RRGGBB`. Multiple distinct colors, unreadable
|
|
262
|
+
colors, or disagreement between `metadata.colors` and `color` are rejected. Duplicate
|
|
263
|
+
representations of the same RGB color are accepted; alpha is discarded.
|
|
264
|
+
|
|
265
|
+
For an accessible merge tombstone, the slot error includes `merged_into`, the
|
|
266
|
+
replacement material ID. A setting read error returns 503 `catalog_store_failed`;
|
|
267
|
+
only a missing setting defaults to enabled.
|
|
268
|
+
|
|
269
|
+
Stored requirements, waiting reasons, and load-step requirements retain
|
|
270
|
+
`filamentId`, `brand`, `name`, `colorName`, `material`, and `colorHex`. Catalog
|
|
271
|
+
identity is a snapshot. Multipart retries reuse the first saved catalog snapshot,
|
|
272
|
+
even if the catalog changes. Matching still uses material and color proximity.
|
|
273
|
+
Requests and stored jobs without `filamentId` keep their existing shape.
|
|
274
|
+
Catalog diameter is intentionally outside the typed requirement snapshot. Global,
|
|
275
|
+
partner-catalog, and manual requirements continue to match by material and color;
|
|
276
|
+
this change does not add an exact-product or filament-diameter constraint.
|
|
277
|
+
|
|
278
|
+
Catalog validation errors in JSON or multipart creation do not reserve a new
|
|
279
|
+
idempotency key or `externalId`. For JSON requests that include `filamentId`,
|
|
280
|
+
the same applies to every other validation error that Hive returns
|
|
281
|
+
before it accepts the request. Correct the request, or add the missing catalog
|
|
282
|
+
entry, and retry with the same identity. Existing created or failed receipts
|
|
283
|
+
replay before a new catalog lookup. Once Hive accepts the request, changes to
|
|
284
|
+
its submitted fields or uploaded bytes return 409. Requests without `filamentId`
|
|
285
|
+
keep their existing receipt behavior.
|
|
286
|
+
Filament search returns catalog IDs and `acceptedByCreate`. A result with
|
|
287
|
+
`acceptedByCreate: true` satisfies the current catalog admission checks for
|
|
288
|
+
print-job filament requirements. Other create admission checks still apply.
|
|
289
|
+
|
|
290
|
+
## Search printers and filaments
|
|
291
|
+
|
|
292
|
+
Both methods require an organization API key with the `read` tier or higher.
|
|
293
|
+
The API derives organization ownership from the authenticated key.
|
|
294
|
+
|
|
295
|
+
The existing `GET /v1/search` and `GET /v1/materials/command-search` routes
|
|
296
|
+
also require the `read` tier or higher for API keys. Empty-scope API keys now
|
|
297
|
+
receive 403 on those routes. JWT authentication keeps its existing membership
|
|
298
|
+
checks.
|
|
299
|
+
|
|
300
|
+
```ts
|
|
301
|
+
const printerPage = await hive.printers.search({ query: "Boo P1S", limit: 10 });
|
|
302
|
+
const filamentPage = await hive.filaments.search({
|
|
303
|
+
query: "black PETG",
|
|
304
|
+
limit: 20,
|
|
305
|
+
});
|
|
306
|
+
const redFilaments = await hive.filaments.search({ query: "bambu red" });
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
| Method | Return type | API route |
|
|
310
|
+
| ------------------------------------------------------- | ----------------------------- | -------------------------------- |
|
|
311
|
+
| `printers.search({ query, limit?, offset?, signal? })` | `Promise<PrinterSearchPage>` | `GET /v1/printers/search?q=...` |
|
|
312
|
+
| `filaments.search({ query, limit?, offset?, signal? })` | `Promise<FilamentSearchPage>` | `GET /v1/filaments/search?q=...` |
|
|
313
|
+
|
|
314
|
+
`SearchOptions` contains the string `query`, optional integer `limit` and
|
|
315
|
+
`offset`, and an optional `AbortSignal`. Both methods return one page and use
|
|
316
|
+
the client's normal GET retry policy. Invalid response shapes throw `TypeError`.
|
|
317
|
+
Missing authentication returns 401. Insufficient API-key scope returns 403.
|
|
318
|
+
Fractional or out-of-range pagination returns 400. `limit` accepts 1–50, with
|
|
319
|
+
default 20. `offset` accepts 0–10,000, with default 0.
|
|
320
|
+
|
|
321
|
+
`PrinterSearchPage` contains `printers`, `total`, and `query`. Each
|
|
322
|
+
`PrinterSearchResult` includes `id`, name, model, serial, status, location,
|
|
323
|
+
`score`, and `match`. The API reads organization-scoped stored observations
|
|
324
|
+
and uses the same shared candidate builder and ranking code as the web
|
|
325
|
+
palette. Queries contain 1–256 characters. Ranking happens before pagination.
|
|
326
|
+
Each request reads every organization printer in batches of up to 1,000 before
|
|
327
|
+
ranking and pagination. These reads have no per-organization cache. Large
|
|
328
|
+
fleets and frequent queries therefore increase database read work. The SDK
|
|
329
|
+
does not debounce or cache requests.
|
|
330
|
+
|
|
331
|
+
No printer search index is involved, and no printer is contacted. Printer `id`
|
|
332
|
+
is the identity for explicit printer placement. Search does not guarantee
|
|
333
|
+
readiness; `printers.get(id)` returns stored printer details.
|
|
334
|
+
|
|
335
|
+
`FilamentSearchPage` contains `filaments`, `total`, `hasMore`, `matchMode`, and
|
|
336
|
+
`originalQuery`. Each `FilamentSearchResult` includes `id`, `filamentId`, name,
|
|
337
|
+
brand, material type, color, diameter, category, organization, and optional SKU.
|
|
338
|
+
`filamentId` equals the catalog material row's `id`. It is not an inventory item
|
|
339
|
+
ID. `acceptedByCreate` reports whether the row satisfies the same catalog
|
|
340
|
+
admission operation used by creation, including the organization's global-filament
|
|
341
|
+
setting, ownership, material, and normalized color checks. It does not promise that a print job
|
|
342
|
+
passes file, plate, target, or dispatch admission.
|
|
343
|
+
|
|
344
|
+
Filament search reuses the web Material Command Search picker, including its
|
|
345
|
+
ranked database query and the organization's global-filament setting. It can
|
|
346
|
+
return organization filaments and enabled global catalog filaments. Global
|
|
347
|
+
rows have `organization_id: "global"`. In SDK 0.4.1, eligible global rows have
|
|
348
|
+
`acceptedByCreate: true` and their IDs can be used in `filaments[].filamentId` on
|
|
349
|
+
`POST /v1/print-jobs/create`. When globals are disabled, search excludes those
|
|
350
|
+
rows and creation rejects their IDs with `catalog_filament_not_found`.
|
|
351
|
+
|
|
352
|
+
Organization-owned rows require `partner-catalog:` provenance. Unsynced rows,
|
|
353
|
+
merge tombstones, rows without a usable material or color, and rows with ambiguous
|
|
354
|
+
or conflicting colors have `acceptedByCreate: false` when returned by search.
|
|
355
|
+
The material must be at most 100 characters, and the color must normalize to one
|
|
356
|
+
RGB hex value under the shared material color rules. Named and 8-digit colors
|
|
357
|
+
are supported. Search does not otherwise filter out ineligible catalog rows.
|
|
358
|
+
An admission-setting read error returns 503; only a missing setting defaults to
|
|
359
|
+
enabled.
|
|
360
|
+
|
|
361
|
+
Queries contain at most 100 characters. An empty query browses the catalog.
|
|
362
|
+
Set the next offset to the previous offset plus the returned filament count
|
|
363
|
+
while `hasMore` is true. When no strict filament match exists, the picker
|
|
364
|
+
returns a broader catalog page with `matchMode: "broadened"` and retains the
|
|
365
|
+
sanitized `originalQuery`. Callers can display that distinction and ask users
|
|
366
|
+
to choose a filament. Neither search method selects a result or creates a job.
|