@bluepic/embed 0.4.0-next.167 → 0.4.0-next.168
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/bluepic-embed.iife.js +197 -191
- package/dist/bluepic-embed.umd.js +200 -194
- package/dist/components/BxTable.vue.d.ts +2 -0
- package/dist/components/TemplateEditor/BatchCell.vue.d.ts +18 -0
- package/dist/components/TemplateEditor/BatchEditor.vue.d.ts +258 -0
- package/dist/components/TemplateEditor/BatchExportPopup.vue.d.ts +66 -0
- package/dist/components/TemplateEditor/BatchImportPopup.vue.d.ts +25 -0
- package/dist/components/TemplateEditor/BxTemplateEditor.vue.d.ts +28 -0
- package/dist/components/fields/ImageEdit.vue.d.ts +6 -0
- package/dist/embed/embed.d.ts +56 -4
- package/dist/main.cjs +112 -106
- package/dist/main.mjs +27971 -25694
- package/dist/style.css +1 -1
- package/dist/util/batch/csv.d.ts +58 -0
- package/dist/util/batch/export.d.ts +77 -0
- package/dist/util/batch/fields.d.ts +22 -0
- package/dist/util/batch/parseCSV.d.ts +72 -0
- package/dist/util/batch/useBatchRows.d.ts +67 -0
- package/dist/util/export.d.ts +3 -0
- package/package.json +1 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Studio } from '@bluepic/types';
|
|
2
|
+
import type { BatchRow } from './useBatchRows';
|
|
3
|
+
import { type BatchColumnField } from './fields';
|
|
4
|
+
/** The formats a CSV result link can point at, plus the prepopulated editor link. */
|
|
5
|
+
export type BatchCsvFormat = Studio.UrlRenderFormat | 'template-link';
|
|
6
|
+
/** Header of the result column. Stable: re-imports recognise and ignore it. */
|
|
7
|
+
export declare const BATCH_CSV_RESULT_COLUMN = "bluepic_result";
|
|
8
|
+
export interface BatchCsvOptions {
|
|
9
|
+
format: BatchCsvFormat;
|
|
10
|
+
/** `https://image.bluepic.io` / `https://image-staging.bluepic.io` (no trailing slash). */
|
|
11
|
+
urlRenderBaseUrl: string;
|
|
12
|
+
templateId: string;
|
|
13
|
+
/** Readable URL form when both are known: `/<orgSlug>/<alias>.<ext>`. */
|
|
14
|
+
orgSlug?: string;
|
|
15
|
+
templateAlias?: string | null;
|
|
16
|
+
/** Multi-canvas: the canvas the editor shows — becomes the extra path segment. */
|
|
17
|
+
canvasId?: string;
|
|
18
|
+
/** The editor's own URL without query (`https://template.bluepic.io/<slug>/<templateId>[/<canvas>]`). */
|
|
19
|
+
templateLinkBaseUrl: string;
|
|
20
|
+
/** `,` (default) or `;` for spreadsheets in `;` locales. */
|
|
21
|
+
delimiter?: ',' | ';';
|
|
22
|
+
}
|
|
23
|
+
export interface BatchCsvResult {
|
|
24
|
+
csv: string;
|
|
25
|
+
/** The per-row result links, in row order. */
|
|
26
|
+
links: string[];
|
|
27
|
+
/** Rows whose URL-render query exceeds the API's byte budget (1-based indices). */
|
|
28
|
+
overBudget: number[];
|
|
29
|
+
/** `bluepic_result` header + one binding key per data column. */
|
|
30
|
+
header: string[];
|
|
31
|
+
}
|
|
32
|
+
/** A binding value as a CSV cell: image objects become their src, other objects JSON. */
|
|
33
|
+
export declare function cellValue(value: unknown): string;
|
|
34
|
+
/** Path of the render URL: alias form when the team + alias are known, else the id form. */
|
|
35
|
+
export declare function urlRenderPath(opts: Pick<BatchCsvOptions, 'templateId' | 'orgSlug' | 'templateAlias' | 'canvasId'>, ext: string): string;
|
|
36
|
+
/** The result link for one row, or null when the format has no link (never happens today). */
|
|
37
|
+
export declare function buildResultLink(row: BatchRow, columns: BatchColumnField[], opts: BatchCsvOptions): {
|
|
38
|
+
url: string;
|
|
39
|
+
overBudget: boolean;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* The batch as a spreadsheet: one column per binding key (so a re-import maps
|
|
43
|
+
* 1:1), image values flattened to their src, and a last column with the
|
|
44
|
+
* result link per row. UTF-8 with BOM so Excel opens it correctly.
|
|
45
|
+
*/
|
|
46
|
+
export declare function buildBatchCsv(rows: BatchRow[], columns: BatchColumnField[], opts: BatchCsvOptions): BatchCsvResult;
|
|
47
|
+
export interface PrewarmProgress {
|
|
48
|
+
done: number;
|
|
49
|
+
total: number;
|
|
50
|
+
failed: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Request every link once so the render lands in the API's cache (and is
|
|
54
|
+
* billed) now, not when a recipient first opens the sheet. Videos one at a
|
|
55
|
+
* time, images four at a time. `no-cors`: we only need the request to happen,
|
|
56
|
+
* not to read the bytes.
|
|
57
|
+
*/
|
|
58
|
+
export declare function prewarmLinks(links: string[], isVideo: boolean, onProgress?: (progress: PrewarmProgress) => void, signal?: AbortSignal): Promise<PrewarmProgress>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { Template } from '@bluepic/types';
|
|
2
|
+
import { imageFormats, videoFormats, type RenderRemoteOptions, type RenderRemoteVideoOptions } from '../export';
|
|
3
|
+
import type { BatchRow } from './useBatchRows';
|
|
4
|
+
export type BatchImageFormat = keyof typeof imageFormats;
|
|
5
|
+
export type BatchVideoFormat = keyof typeof videoFormats;
|
|
6
|
+
export type BatchFileFormat = BatchImageFormat | BatchVideoFormat;
|
|
7
|
+
/** How exported files are named: by their 1-based index, or by a Text binding's value. */
|
|
8
|
+
export type BatchNaming = {
|
|
9
|
+
kind: 'index';
|
|
10
|
+
} | {
|
|
11
|
+
kind: 'binding';
|
|
12
|
+
key: string;
|
|
13
|
+
};
|
|
14
|
+
export interface BatchFileExportContext {
|
|
15
|
+
serial: Template.Serial;
|
|
16
|
+
campaignId: number;
|
|
17
|
+
templateId: string;
|
|
18
|
+
canvasId?: string;
|
|
19
|
+
/** Template name — the zip name and the index-naming prefix. */
|
|
20
|
+
name: string;
|
|
21
|
+
remoteOptions: RenderRemoteOptions;
|
|
22
|
+
remoteVideoOptions: RenderRemoteVideoOptions;
|
|
23
|
+
/**
|
|
24
|
+
* Called once per successfully rendered row with that row's data. The
|
|
25
|
+
* editor binds it to its per-output credit consumer, so each row is charged
|
|
26
|
+
* exactly once per session (and never twice for the same content).
|
|
27
|
+
*/
|
|
28
|
+
consumeOutput: (data: Record<string, unknown>) => Promise<void>;
|
|
29
|
+
/** Cooperative cancellation: checked before every row starts. */
|
|
30
|
+
signal?: AbortSignal;
|
|
31
|
+
}
|
|
32
|
+
export interface BatchExportProgress {
|
|
33
|
+
/** Rows finished (rendered + consumed). */
|
|
34
|
+
done: number;
|
|
35
|
+
total: number;
|
|
36
|
+
/** 0..1 progress inside the row being rendered (videos stream it; images jump). */
|
|
37
|
+
current: number;
|
|
38
|
+
/** 1-based index of the row being rendered. */
|
|
39
|
+
currentIndex: number;
|
|
40
|
+
}
|
|
41
|
+
export interface BatchFileExportResult {
|
|
42
|
+
/** One blob per exported file (a multi-frame template yields several per row). */
|
|
43
|
+
files: {
|
|
44
|
+
name: string;
|
|
45
|
+
blob: Blob;
|
|
46
|
+
}[];
|
|
47
|
+
/** The zip (or the single file) ready to hand out, plus its file name. */
|
|
48
|
+
output: {
|
|
49
|
+
blob: Blob;
|
|
50
|
+
fileName: string;
|
|
51
|
+
};
|
|
52
|
+
cancelled: boolean;
|
|
53
|
+
}
|
|
54
|
+
/** Image rows render four at a time, videos strictly one after the other (decision 2026-09-02). */
|
|
55
|
+
export declare const BATCH_IMAGE_CONCURRENCY = 4;
|
|
56
|
+
export declare const BATCH_VIDEO_CONCURRENCY = 1;
|
|
57
|
+
/** A file-system-safe base name from a binding value; empty when nothing usable remains. */
|
|
58
|
+
export declare function sanitizeFileName(value: unknown): string;
|
|
59
|
+
/** Base names for every row, unique (`name`, `name_2`, `name_3`, …). */
|
|
60
|
+
export declare function batchFileBaseNames(rows: BatchRow[], naming: BatchNaming, prefix: string): string[];
|
|
61
|
+
/**
|
|
62
|
+
* Render every row server-side and pack the results.
|
|
63
|
+
*
|
|
64
|
+
* Images go through the campaign render endpoint (which does not charge — the
|
|
65
|
+
* per-row `consumeOutput` does), videos through the video render service.
|
|
66
|
+
* Rows are rendered in order; a failed row aborts the export with its error
|
|
67
|
+
* so nothing half-billed slips through silently.
|
|
68
|
+
*/
|
|
69
|
+
export declare function exportBatchFiles(rows: BatchRow[], format: BatchFileFormat, naming: BatchNaming, ctx: BatchFileExportContext, onProgress?: (progress: BatchExportProgress) => void): Promise<BatchFileExportResult>;
|
|
70
|
+
/** One file stays a file; several become a zip named after the template. */
|
|
71
|
+
export declare function packFiles(files: {
|
|
72
|
+
name: string;
|
|
73
|
+
blob: Blob;
|
|
74
|
+
}[], zipBaseName: string): Promise<{
|
|
75
|
+
blob: Blob;
|
|
76
|
+
fileName: string;
|
|
77
|
+
}>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { BluepicField, Template } from '@bluepic/types';
|
|
2
|
+
/** A field as a batch-table column: the field plus where it came from. */
|
|
3
|
+
export interface BatchColumnField {
|
|
4
|
+
field: BluepicField;
|
|
5
|
+
/** Stable key for the column (the field's first binding, else its index path). */
|
|
6
|
+
key: string;
|
|
7
|
+
/** Group breadcrumb the field lives in, for the header caption. */
|
|
8
|
+
groupPath: string[];
|
|
9
|
+
/** 1-based slide the field belongs to on multi-slide templates, else undefined. */
|
|
10
|
+
slide?: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Every value-bearing field of a serial as a flat column list. Groups are
|
|
14
|
+
* flattened (their children become columns, the group's description is kept
|
|
15
|
+
* as a breadcrumb); instructions are dropped.
|
|
16
|
+
*/
|
|
17
|
+
export declare function flattenBatchFields(serial: Template.Serial | undefined): BatchColumnField[];
|
|
18
|
+
/** The binding keys a field writes, in model order. */
|
|
19
|
+
export declare function bindingKeysOf(field: BluepicField): string[];
|
|
20
|
+
export declare function isImageField(field: BluepicField): boolean;
|
|
21
|
+
/** A Text binding a file name / CSV column can be derived from. */
|
|
22
|
+
export declare function isTextField(field: BluepicField): boolean;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export type LocaleConfig = 'de' | 'en' | 'auto';
|
|
2
|
+
export type CSVDelimiter = ',' | ';' | 'auto';
|
|
3
|
+
type StringDescriptor = {
|
|
4
|
+
type: 'string';
|
|
5
|
+
value: string;
|
|
6
|
+
};
|
|
7
|
+
type NumberDescriptor = {
|
|
8
|
+
type: 'number';
|
|
9
|
+
value: number;
|
|
10
|
+
unit?: string;
|
|
11
|
+
};
|
|
12
|
+
type BooleanDescriptor = {
|
|
13
|
+
type: 'boolean';
|
|
14
|
+
value: boolean;
|
|
15
|
+
};
|
|
16
|
+
type DateDescriptor = {
|
|
17
|
+
type: 'date';
|
|
18
|
+
value: Date;
|
|
19
|
+
format: string;
|
|
20
|
+
};
|
|
21
|
+
type URLDescriptor = {
|
|
22
|
+
type: 'url';
|
|
23
|
+
value: string;
|
|
24
|
+
protocol: string;
|
|
25
|
+
};
|
|
26
|
+
type ColorDescriptor = {
|
|
27
|
+
type: 'color';
|
|
28
|
+
value: string;
|
|
29
|
+
rgb: {
|
|
30
|
+
r: number;
|
|
31
|
+
g: number;
|
|
32
|
+
b: number;
|
|
33
|
+
};
|
|
34
|
+
hex: string;
|
|
35
|
+
hsl: {
|
|
36
|
+
h: number;
|
|
37
|
+
s: number;
|
|
38
|
+
l: number;
|
|
39
|
+
};
|
|
40
|
+
alpha: number;
|
|
41
|
+
format: 'hex' | 'rgb' | 'rgba' | 'hsl' | 'hsla' | 'name' | 'keyword';
|
|
42
|
+
};
|
|
43
|
+
type JSONObjectDescriptor = {
|
|
44
|
+
type: 'json-object';
|
|
45
|
+
value: Record<string, unknown>;
|
|
46
|
+
};
|
|
47
|
+
type JSONArrayDescriptor = {
|
|
48
|
+
type: 'json-array';
|
|
49
|
+
value: unknown[];
|
|
50
|
+
};
|
|
51
|
+
type NullDescriptor = {
|
|
52
|
+
type: 'null';
|
|
53
|
+
value: null;
|
|
54
|
+
};
|
|
55
|
+
export type CellDescriptor = StringDescriptor | NumberDescriptor | BooleanDescriptor | DateDescriptor | URLDescriptor | ColorDescriptor | JSONObjectDescriptor | JSONArrayDescriptor | NullDescriptor;
|
|
56
|
+
export type InferredTable = CellDescriptor[][];
|
|
57
|
+
export declare function isString(cell: CellDescriptor): cell is StringDescriptor;
|
|
58
|
+
export declare function isNumber(cell: CellDescriptor): cell is NumberDescriptor;
|
|
59
|
+
export declare function isBoolean(cell: CellDescriptor): cell is BooleanDescriptor;
|
|
60
|
+
export declare function isDate(cell: CellDescriptor): cell is DateDescriptor;
|
|
61
|
+
export declare function isURL(cell: CellDescriptor): cell is URLDescriptor;
|
|
62
|
+
export declare function isColor(cell: CellDescriptor): cell is ColorDescriptor;
|
|
63
|
+
export declare function isJSONObject(cell: CellDescriptor): cell is JSONObjectDescriptor;
|
|
64
|
+
export declare function isJSONArray(cell: CellDescriptor): cell is JSONArrayDescriptor;
|
|
65
|
+
export declare function isNull(cell: CellDescriptor): cell is NullDescriptor;
|
|
66
|
+
export declare function exampleUsage(inferredTable: InferredTable): void;
|
|
67
|
+
export declare function inferredCellToString(cell: CellDescriptor): string;
|
|
68
|
+
export declare function heuristicInferTable(rawTable: string[][], locale: LocaleConfig): InferredTable;
|
|
69
|
+
export declare function detectCSVDelimiter(raw: string): ',' | ';';
|
|
70
|
+
export declare function parseCSVRaw(raw: string, delimiter?: ',' | ';'): string[][];
|
|
71
|
+
export declare function parseCSV(raw: string, locale: LocaleConfig, delimiter?: CSVDelimiter): InferredTable;
|
|
72
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { type Ref } from 'vue';
|
|
2
|
+
/**
|
|
3
|
+
* Batch editor data model.
|
|
4
|
+
*
|
|
5
|
+
* A row is one set of binding values — exactly the object the live template
|
|
6
|
+
* and the renderer consume as `data` — plus a stable id. Ids (not indices) are
|
|
7
|
+
* what selection and the active row point at, so deleting or reordering rows
|
|
8
|
+
* never shifts the meaning of "row 3 is selected".
|
|
9
|
+
*/
|
|
10
|
+
export interface BatchRow {
|
|
11
|
+
id: string;
|
|
12
|
+
data: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
/** Hard cap on rows per batch (decision 2026-09-02). */
|
|
15
|
+
export declare const BATCH_MAX_ROWS = 1024;
|
|
16
|
+
export interface UseBatchRowsOptions {
|
|
17
|
+
/** The bindings every row starts from (`serial.bindings`). */
|
|
18
|
+
seed: () => Record<string, unknown>;
|
|
19
|
+
/**
|
|
20
|
+
* sessionStorage key. Rows survive a reload / a canvas switch (the editor
|
|
21
|
+
* re-mounts per canvas) under it. Undefined = no persistence.
|
|
22
|
+
*/
|
|
23
|
+
storageKey: Ref<string | undefined>;
|
|
24
|
+
/** Rows the host hands in (`v-model:batchRows`); take precedence over storage. */
|
|
25
|
+
initial?: BatchRow[];
|
|
26
|
+
}
|
|
27
|
+
export declare function useBatchRows(opts: UseBatchRowsOptions): {
|
|
28
|
+
rows: Ref<{
|
|
29
|
+
id: string;
|
|
30
|
+
data: Record<string, unknown>;
|
|
31
|
+
}[], BatchRow[] | {
|
|
32
|
+
id: string;
|
|
33
|
+
data: Record<string, unknown>;
|
|
34
|
+
}[]>;
|
|
35
|
+
activeRowId: Ref<string, string>;
|
|
36
|
+
activeIndex: import("vue").ComputedRef<number>;
|
|
37
|
+
activeRow: import("vue").ComputedRef<{
|
|
38
|
+
id: string;
|
|
39
|
+
data: Record<string, unknown>;
|
|
40
|
+
}>;
|
|
41
|
+
selectedIds: Ref<Set<string> & Omit<Set<string>, keyof Set<any>>, Set<string> | (Set<string> & Omit<Set<string>, keyof Set<any>>)>;
|
|
42
|
+
selectedRows: import("vue").ComputedRef<{
|
|
43
|
+
id: string;
|
|
44
|
+
data: Record<string, unknown>;
|
|
45
|
+
}[]>;
|
|
46
|
+
targetRows: import("vue").ComputedRef<{
|
|
47
|
+
id: string;
|
|
48
|
+
data: Record<string, unknown>;
|
|
49
|
+
}[]>;
|
|
50
|
+
allSelected: import("vue").ComputedRef<boolean>;
|
|
51
|
+
atCapacity: import("vue").ComputedRef<boolean>;
|
|
52
|
+
setActive: (id: string) => void;
|
|
53
|
+
activateOffset: (delta: number) => void;
|
|
54
|
+
addRow: (sourceId?: string) => BatchRow | undefined;
|
|
55
|
+
removeRows: (ids: string[]) => void;
|
|
56
|
+
moveRow: (id: string, delta: -1 | 1) => void;
|
|
57
|
+
toggleSelected: (id: string, on?: boolean) => void;
|
|
58
|
+
selectAll: (on: boolean) => void;
|
|
59
|
+
ensureRowsFrom: (fromIndex: number, count: number) => BatchRow[];
|
|
60
|
+
importRows: (datasets: Record<string, unknown>[], mode: "append" | "replace") => {
|
|
61
|
+
imported: number;
|
|
62
|
+
dropped: number;
|
|
63
|
+
};
|
|
64
|
+
replaceAll: (next: BatchRow[]) => void;
|
|
65
|
+
makeRow: (data?: Record<string, unknown>) => BatchRow;
|
|
66
|
+
};
|
|
67
|
+
export type BatchRowsModel = ReturnType<typeof useBatchRows>;
|
package/dist/util/export.d.ts
CHANGED
|
@@ -78,6 +78,9 @@ campaignCaption?: Ref<string | undefined>,
|
|
|
78
78
|
*/
|
|
79
79
|
canvasId?: Ref<string | undefined>): {
|
|
80
80
|
triggerExport: () => Promise<void>;
|
|
81
|
+
consumeOutputFor: (rowData: {
|
|
82
|
+
[k: string]: unknown;
|
|
83
|
+
}) => Promise<void>;
|
|
81
84
|
preCacheLocalRender: () => Promise<void>;
|
|
82
85
|
rendering: Ref<boolean, boolean>;
|
|
83
86
|
videoRenderingProgress: Ref<number | undefined, number | undefined>;
|