@inneropen/marvin-sdk 4.1.0 → 4.3.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/dist/{HttpClient-B_rEmJuO.d.cts → HttpClient-DXMNOPqu.d.cts} +17 -1
- package/dist/{HttpClient-B_rEmJuO.d.ts → HttpClient-DXMNOPqu.d.ts} +17 -1
- package/dist/{chunk-VS6R3V3K.js → chunk-KXI2FQSO.js} +50 -17
- package/dist/{chunk-DSVYCVQD.js → chunk-LTX3MAUE.js} +25 -0
- package/dist/{index-CX4jvPAA.d.cts → index-BEEbnrXV.d.cts} +481 -43
- package/dist/{index-CX4jvPAA.d.ts → index-BEEbnrXV.d.ts} +481 -43
- package/dist/index.cjs +75 -16
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +4 -2
- package/dist/{marvin-6keK-yvS.d.cts → marvin-CdsjwIyH.d.ts} +64 -35
- package/dist/{marvin-Cndwz82G.d.ts → marvin-gZtGa576.d.cts} +64 -35
- package/dist/platform.cjs +187 -3
- package/dist/platform.d.cts +190 -7
- package/dist/platform.d.ts +190 -7
- package/dist/platform.js +162 -4
- package/dist/publish.cjs +74 -16
- package/dist/publish.d.cts +4 -4
- package/dist/publish.d.ts +4 -4
- package/dist/publish.js +5 -3
- package/dist/types/index.d.cts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -79,6 +79,11 @@ interface RetryConfig {
|
|
|
79
79
|
*/
|
|
80
80
|
retryableStatuses: number[];
|
|
81
81
|
}
|
|
82
|
+
/** A successful binary read: the body's bytes and the server's content type. */
|
|
83
|
+
interface BinaryResponse {
|
|
84
|
+
data: Uint8Array;
|
|
85
|
+
contentType: string | null;
|
|
86
|
+
}
|
|
82
87
|
interface HttpClientConfig {
|
|
83
88
|
baseUrl: string;
|
|
84
89
|
auth: AuthStrategy;
|
|
@@ -158,6 +163,11 @@ declare class HttpClient {
|
|
|
158
163
|
* Still clamped to MAX_TIMEOUT.
|
|
159
164
|
*/
|
|
160
165
|
timeout?: number;
|
|
166
|
+
/**
|
|
167
|
+
* `'binary'` hands back a {@link BinaryResponse} (the raw bytes) instead of parsing JSON. Retries,
|
|
168
|
+
* redirects and errors behave exactly as for a JSON read.
|
|
169
|
+
*/
|
|
170
|
+
responseType?: 'json' | 'binary';
|
|
161
171
|
}, retryAttempt?: number): Promise<T>;
|
|
162
172
|
/**
|
|
163
173
|
* A successful response's JSON body, or `undefined` when there is none: 204/205, `content-length: 0`,
|
|
@@ -165,10 +175,16 @@ declare class HttpClient {
|
|
|
165
175
|
* JSON is a `MarvinApiError` naming the request — never a network error, and never retried.
|
|
166
176
|
*/
|
|
167
177
|
private readBody;
|
|
178
|
+
/** A successful response's bytes; a 204/205 is an empty array. A failed read is a network error. */
|
|
179
|
+
private readBinary;
|
|
168
180
|
/**
|
|
169
181
|
* GET request
|
|
170
182
|
*/
|
|
171
183
|
get<T>(endpoint: string, params?: Record<string, string | number | boolean | undefined>): Promise<T>;
|
|
184
|
+
/**
|
|
185
|
+
* GET a binary body (a file download). Follows redirects; retried like any GET.
|
|
186
|
+
*/
|
|
187
|
+
getBinary(endpoint: string, params?: Record<string, string | number | boolean | undefined>): Promise<BinaryResponse>;
|
|
172
188
|
/**
|
|
173
189
|
* POST request
|
|
174
190
|
*/
|
|
@@ -189,4 +205,4 @@ declare class HttpClient {
|
|
|
189
205
|
delete<T>(endpoint: string): Promise<T>;
|
|
190
206
|
}
|
|
191
207
|
|
|
192
|
-
export { type AuthStrategy as A, BearerTokenAuth as B, HttpClient as H, NoAuth as N, SessionAuth as S, type
|
|
208
|
+
export { type AuthStrategy as A, BearerTokenAuth as B, HttpClient as H, NoAuth as N, SessionAuth as S, type BinaryResponse as a, type HttpClientConfig as b };
|
|
@@ -79,6 +79,11 @@ interface RetryConfig {
|
|
|
79
79
|
*/
|
|
80
80
|
retryableStatuses: number[];
|
|
81
81
|
}
|
|
82
|
+
/** A successful binary read: the body's bytes and the server's content type. */
|
|
83
|
+
interface BinaryResponse {
|
|
84
|
+
data: Uint8Array;
|
|
85
|
+
contentType: string | null;
|
|
86
|
+
}
|
|
82
87
|
interface HttpClientConfig {
|
|
83
88
|
baseUrl: string;
|
|
84
89
|
auth: AuthStrategy;
|
|
@@ -158,6 +163,11 @@ declare class HttpClient {
|
|
|
158
163
|
* Still clamped to MAX_TIMEOUT.
|
|
159
164
|
*/
|
|
160
165
|
timeout?: number;
|
|
166
|
+
/**
|
|
167
|
+
* `'binary'` hands back a {@link BinaryResponse} (the raw bytes) instead of parsing JSON. Retries,
|
|
168
|
+
* redirects and errors behave exactly as for a JSON read.
|
|
169
|
+
*/
|
|
170
|
+
responseType?: 'json' | 'binary';
|
|
161
171
|
}, retryAttempt?: number): Promise<T>;
|
|
162
172
|
/**
|
|
163
173
|
* A successful response's JSON body, or `undefined` when there is none: 204/205, `content-length: 0`,
|
|
@@ -165,10 +175,16 @@ declare class HttpClient {
|
|
|
165
175
|
* JSON is a `MarvinApiError` naming the request — never a network error, and never retried.
|
|
166
176
|
*/
|
|
167
177
|
private readBody;
|
|
178
|
+
/** A successful response's bytes; a 204/205 is an empty array. A failed read is a network error. */
|
|
179
|
+
private readBinary;
|
|
168
180
|
/**
|
|
169
181
|
* GET request
|
|
170
182
|
*/
|
|
171
183
|
get<T>(endpoint: string, params?: Record<string, string | number | boolean | undefined>): Promise<T>;
|
|
184
|
+
/**
|
|
185
|
+
* GET a binary body (a file download). Follows redirects; retried like any GET.
|
|
186
|
+
*/
|
|
187
|
+
getBinary(endpoint: string, params?: Record<string, string | number | boolean | undefined>): Promise<BinaryResponse>;
|
|
172
188
|
/**
|
|
173
189
|
* POST request
|
|
174
190
|
*/
|
|
@@ -189,4 +205,4 @@ declare class HttpClient {
|
|
|
189
205
|
delete<T>(endpoint: string): Promise<T>;
|
|
190
206
|
}
|
|
191
207
|
|
|
192
|
-
export { type AuthStrategy as A, BearerTokenAuth as B, HttpClient as H, NoAuth as N, SessionAuth as S, type
|
|
208
|
+
export { type AuthStrategy as A, BearerTokenAuth as B, HttpClient as H, NoAuth as N, SessionAuth as S, type BinaryResponse as a, type HttpClientConfig as b };
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
__export,
|
|
7
7
|
init_core,
|
|
8
8
|
init_errors
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-LTX3MAUE.js";
|
|
10
10
|
|
|
11
11
|
// src/client/config.ts
|
|
12
12
|
var config_exports = {};
|
|
@@ -135,6 +135,12 @@ var init_config = __esm({
|
|
|
135
135
|
});
|
|
136
136
|
|
|
137
137
|
// src/entries/entry.ts
|
|
138
|
+
function isFullEntryData(raw) {
|
|
139
|
+
if (!raw || typeof raw !== "object") return false;
|
|
140
|
+
const record = raw;
|
|
141
|
+
if ("assetSlugs" in record || "resourceSlugs" in record) return false;
|
|
142
|
+
return Array.isArray(record.assets) || Array.isArray(record.resources);
|
|
143
|
+
}
|
|
138
144
|
var Entry;
|
|
139
145
|
var init_entry = __esm({
|
|
140
146
|
"src/entries/entry.ts"() {
|
|
@@ -314,6 +320,11 @@ var init_resource = __esm({
|
|
|
314
320
|
});
|
|
315
321
|
|
|
316
322
|
// src/entries/entries.ts
|
|
323
|
+
function csv(value) {
|
|
324
|
+
if (value === void 0) return void 0;
|
|
325
|
+
const joined = (Array.isArray(value) ? value : [value]).map((v) => v.trim()).filter(Boolean).join(",");
|
|
326
|
+
return joined || void 0;
|
|
327
|
+
}
|
|
317
328
|
function toListEntry(raw) {
|
|
318
329
|
const { collections, ...rest } = raw;
|
|
319
330
|
return {
|
|
@@ -337,19 +348,24 @@ var init_entries = __esm({
|
|
|
337
348
|
}
|
|
338
349
|
http;
|
|
339
350
|
workspaceSlug;
|
|
340
|
-
/**
|
|
341
|
-
* Get all published entries
|
|
342
|
-
*/
|
|
343
351
|
async list(options = {}) {
|
|
344
352
|
const queryString = this.http.buildQueryString({
|
|
345
353
|
entry_type: options.entryType,
|
|
346
354
|
collection: options.collection,
|
|
355
|
+
tag: csv(options.tag),
|
|
356
|
+
slug: csv(options.slug),
|
|
357
|
+
updated_since: options.updatedSince instanceof Date ? options.updatedSince.toISOString() : options.updatedSince,
|
|
347
358
|
limit: options.limit,
|
|
348
|
-
offset: options.offset
|
|
359
|
+
offset: options.offset,
|
|
360
|
+
expand: options.expand
|
|
349
361
|
});
|
|
350
362
|
const endpoint = `/api/publish/${this.workspaceSlug}/entries${queryString}`;
|
|
351
363
|
const response = await this.http.fetch(endpoint);
|
|
352
|
-
|
|
364
|
+
const data = response.data || [];
|
|
365
|
+
if (options.expand === "full" && data.every(isFullEntryData)) {
|
|
366
|
+
return data.map((entry) => new Entry(entry));
|
|
367
|
+
}
|
|
368
|
+
return data.map(toListEntry);
|
|
353
369
|
}
|
|
354
370
|
/**
|
|
355
371
|
* Get a single entry by slug
|
|
@@ -395,6 +411,7 @@ var init_collections = __esm({
|
|
|
395
411
|
"src/collections/collections.ts"() {
|
|
396
412
|
"use strict";
|
|
397
413
|
init_collection();
|
|
414
|
+
init_entry();
|
|
398
415
|
init_errors();
|
|
399
416
|
CollectionsModule = class {
|
|
400
417
|
constructor(http, workspaceSlug) {
|
|
@@ -427,18 +444,25 @@ var init_collections = __esm({
|
|
|
427
444
|
throw error;
|
|
428
445
|
}
|
|
429
446
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
447
|
+
async entries(slug, options = {}) {
|
|
448
|
+
if (options.expand !== "full") {
|
|
449
|
+
const collection = await this.get(slug);
|
|
450
|
+
return Array.isArray(collection) ? collection : collection.entries;
|
|
451
|
+
}
|
|
452
|
+
let data;
|
|
453
|
+
try {
|
|
454
|
+
data = await this.http.fetch(
|
|
455
|
+
`/api/publish/${this.workspaceSlug}/collections/${slug}?expand=full`
|
|
456
|
+
);
|
|
457
|
+
} catch (error) {
|
|
458
|
+
if (error instanceof MarvinNotFoundError) return [];
|
|
459
|
+
throw error;
|
|
440
460
|
}
|
|
441
|
-
|
|
461
|
+
const entries = data.entries ?? [];
|
|
462
|
+
if (entries.every(isFullEntryData)) {
|
|
463
|
+
return data.entries.map((entry) => new Entry(entry));
|
|
464
|
+
}
|
|
465
|
+
return new Collection(data).entries;
|
|
442
466
|
}
|
|
443
467
|
/**
|
|
444
468
|
* Try multiple collection slugs in fallback order.
|
|
@@ -498,6 +522,14 @@ var init_assets = __esm({
|
|
|
498
522
|
const endpoint = `/api/publish/${this.workspaceSlug}/assets/${slugOrId}`;
|
|
499
523
|
return this.http.fetch(endpoint);
|
|
500
524
|
}
|
|
525
|
+
/**
|
|
526
|
+
* Download a published asset's file by slug: its bytes and content type. The file route
|
|
527
|
+
* redirects to storage; the redirect is followed. Needs the `read:assets` permission.
|
|
528
|
+
*/
|
|
529
|
+
async download(slug) {
|
|
530
|
+
const validSlug = this.http.validatePathParam(slug, "asset slug");
|
|
531
|
+
return this.http.getBinary(`/api/publish/${this.workspaceSlug}/assets/${validSlug}/file`);
|
|
532
|
+
}
|
|
501
533
|
/**
|
|
502
534
|
* Convenience: Get all images
|
|
503
535
|
*/
|
|
@@ -888,6 +920,7 @@ export {
|
|
|
888
920
|
createConfigFromEnv,
|
|
889
921
|
config_exports,
|
|
890
922
|
init_config,
|
|
923
|
+
isFullEntryData,
|
|
891
924
|
Entry,
|
|
892
925
|
init_entry,
|
|
893
926
|
Collection,
|
|
@@ -383,6 +383,9 @@ var init_HttpClient = __esm({
|
|
|
383
383
|
errorText
|
|
384
384
|
);
|
|
385
385
|
}
|
|
386
|
+
if (options?.responseType === "binary") {
|
|
387
|
+
return await this.readBinary(response, method, endpoint);
|
|
388
|
+
}
|
|
386
389
|
const data = await this.readBody(response, method, endpoint);
|
|
387
390
|
if (this.debug && data !== void 0) {
|
|
388
391
|
const sanitized = this.sanitizeForLogging(data);
|
|
@@ -428,12 +431,34 @@ var init_HttpClient = __esm({
|
|
|
428
431
|
);
|
|
429
432
|
}
|
|
430
433
|
}
|
|
434
|
+
/** A successful response's bytes; a 204/205 is an empty array. A failed read is a network error. */
|
|
435
|
+
async readBinary(response, method, endpoint) {
|
|
436
|
+
const contentType = response.headers.get("content-type");
|
|
437
|
+
if (response.status === 204 || response.status === 205) {
|
|
438
|
+
return { data: new Uint8Array(0), contentType };
|
|
439
|
+
}
|
|
440
|
+
try {
|
|
441
|
+
return { data: new Uint8Array(await response.arrayBuffer()), contentType };
|
|
442
|
+
} catch (error) {
|
|
443
|
+
const cause = error instanceof Error ? error : void 0;
|
|
444
|
+
throw new MarvinNetworkError(
|
|
445
|
+
`Reading the ${response.status} response to ${method} ${endpoint} failed: ${cause?.message ?? String(error)}`,
|
|
446
|
+
cause
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
431
450
|
/**
|
|
432
451
|
* GET request
|
|
433
452
|
*/
|
|
434
453
|
async get(endpoint, params) {
|
|
435
454
|
return this.request("GET", endpoint, { params });
|
|
436
455
|
}
|
|
456
|
+
/**
|
|
457
|
+
* GET a binary body (a file download). Follows redirects; retried like any GET.
|
|
458
|
+
*/
|
|
459
|
+
async getBinary(endpoint, params) {
|
|
460
|
+
return this.request("GET", endpoint, { params, responseType: "binary" });
|
|
461
|
+
}
|
|
437
462
|
/**
|
|
438
463
|
* POST request
|
|
439
464
|
*/
|