@plumix/plugin-media 0.1.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/LICENSE +21 -0
- package/README.md +211 -0
- package/dist/admin/FocalPointField.d.ts +22 -0
- package/dist/admin/FocalPointField.d.ts.map +1 -0
- package/dist/admin/FocalPointField.js +71 -0
- package/dist/admin/FocalPointField.js.map +1 -0
- package/dist/admin/MediaLibrary.d.ts +43 -0
- package/dist/admin/MediaLibrary.d.ts.map +1 -0
- package/dist/admin/MediaLibrary.js +698 -0
- package/dist/admin/MediaLibrary.js.map +1 -0
- package/dist/admin/MediaListPickerField.d.ts +14 -0
- package/dist/admin/MediaListPickerField.d.ts.map +1 -0
- package/dist/admin/MediaListPickerField.js +161 -0
- package/dist/admin/MediaListPickerField.js.map +1 -0
- package/dist/admin/MediaPickerField.d.ts +25 -0
- package/dist/admin/MediaPickerField.d.ts.map +1 -0
- package/dist/admin/MediaPickerField.js +82 -0
- package/dist/admin/MediaPickerField.js.map +1 -0
- package/dist/admin/MediaUrlField.d.ts +14 -0
- package/dist/admin/MediaUrlField.d.ts.map +1 -0
- package/dist/admin/MediaUrlField.js +29 -0
- package/dist/admin/MediaUrlField.js.map +1 -0
- package/dist/admin/index.d.ts +11 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +49 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/messages.d.ts +24 -0
- package/dist/admin/messages.d.ts.map +1 -0
- package/dist/admin/messages.js +28 -0
- package/dist/admin/messages.js.map +1 -0
- package/dist/blocks/file/index.d.ts +2 -0
- package/dist/blocks/file/index.d.ts.map +1 -0
- package/dist/blocks/file/index.js +109 -0
- package/dist/blocks/file/index.js.map +1 -0
- package/dist/blocks/file/normalize.d.ts +10 -0
- package/dist/blocks/file/normalize.d.ts.map +1 -0
- package/dist/blocks/file/normalize.js +45 -0
- package/dist/blocks/file/normalize.js.map +1 -0
- package/dist/blocks/image/index.d.ts +2 -0
- package/dist/blocks/image/index.d.ts.map +1 -0
- package/dist/blocks/image/index.js +141 -0
- package/dist/blocks/image/index.js.map +1 -0
- package/dist/blocks/image/normalize.d.ts +7 -0
- package/dist/blocks/image/normalize.d.ts.map +1 -0
- package/dist/blocks/image/normalize.js +20 -0
- package/dist/blocks/image/normalize.js.map +1 -0
- package/dist/blocks.d.ts +2 -0
- package/dist/blocks.d.ts.map +1 -0
- package/dist/blocks.js +6 -0
- package/dist/blocks.js.map +1 -0
- package/dist/builder.d.ts +80 -0
- package/dist/builder.d.ts.map +1 -0
- package/dist/builder.js +61 -0
- package/dist/builder.js.map +1 -0
- package/dist/fields.d.ts +3 -0
- package/dist/fields.d.ts.map +1 -0
- package/dist/fields.js +7 -0
- package/dist/fields.js.map +1 -0
- package/dist/image-dimensions.d.ts +7 -0
- package/dist/image-dimensions.d.ts.map +1 -0
- package/dist/image-dimensions.js +142 -0
- package/dist/image-dimensions.js.map +1 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +216 -0
- package/dist/index.js.map +1 -0
- package/dist/lookup.d.ts +43 -0
- package/dist/lookup.d.ts.map +1 -0
- package/dist/lookup.js +154 -0
- package/dist/lookup.js.map +1 -0
- package/dist/magic-bytes.d.ts +4 -0
- package/dist/magic-bytes.d.ts.map +1 -0
- package/dist/magic-bytes.js +107 -0
- package/dist/magic-bytes.js.map +1 -0
- package/dist/mcp-tools.d.ts +10 -0
- package/dist/mcp-tools.d.ts.map +1 -0
- package/dist/mcp-tools.js +43 -0
- package/dist/mcp-tools.js.map +1 -0
- package/dist/media-blocks.d.ts +3 -0
- package/dist/media-blocks.d.ts.map +1 -0
- package/dist/media-blocks.js +10 -0
- package/dist/media-blocks.js.map +1 -0
- package/dist/meta.d.ts +12 -0
- package/dist/meta.d.ts.map +1 -0
- package/dist/meta.js +20 -0
- package/dist/meta.js.map +1 -0
- package/dist/mime.d.ts +3 -0
- package/dist/mime.d.ts.map +1 -0
- package/dist/mime.js +58 -0
- package/dist/mime.js.map +1 -0
- package/dist/read-service.d.ts +66 -0
- package/dist/read-service.d.ts.map +1 -0
- package/dist/read-service.js +156 -0
- package/dist/read-service.js.map +1 -0
- package/dist/rpc.d.ts +7 -0
- package/dist/rpc.d.ts.map +1 -0
- package/dist/rpc.js +352 -0
- package/dist/rpc.js.map +1 -0
- package/dist/serve-route.d.ts +19 -0
- package/dist/serve-route.d.ts.map +1 -0
- package/dist/serve-route.js +122 -0
- package/dist/serve-route.js.map +1 -0
- package/dist/upload-route.d.ts +17 -0
- package/dist/upload-route.d.ts.map +1 -0
- package/dist/upload-route.js +106 -0
- package/dist/upload-route.js.map +1 -0
- package/package.json +97 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
// Intrinsic pixel-dimension probe for the raster image formats the media
|
|
2
|
+
// plugin accepts. Runs at confirm time on the same leading bytes we read for
|
|
3
|
+
// the magic-byte sniff, so uploaded images carry width/height without a
|
|
4
|
+
// separate decode pass. Returns null whenever dimensions can't be determined
|
|
5
|
+
// — a vector format (SVG), an unknown mime, or a sample too short to reach the
|
|
6
|
+
// header — and callers treat that as "no dimensions" rather than an error.
|
|
7
|
+
// Bytes to read for the dimension probe. Larger than the magic-byte sample
|
|
8
|
+
// because a JPEG's SOF marker can sit past a big APP1/EXIF block; 64 KiB
|
|
9
|
+
// covers the header region of the formats we probe without reading whole files.
|
|
10
|
+
export const DIMENSION_SAMPLE_SIZE = 65536;
|
|
11
|
+
function readPng(v) {
|
|
12
|
+
// Signature (8) + IHDR length (4) + "IHDR" (4), then width/height as BE u32.
|
|
13
|
+
if (v.byteLength < 24)
|
|
14
|
+
return null;
|
|
15
|
+
return { width: v.getUint32(16), height: v.getUint32(20) };
|
|
16
|
+
}
|
|
17
|
+
function readGif(v) {
|
|
18
|
+
// "GIF87a"/"GIF89a" (6), then width/height as LE u16 in the screen descriptor.
|
|
19
|
+
if (v.byteLength < 10)
|
|
20
|
+
return null;
|
|
21
|
+
return { width: v.getUint16(6, true), height: v.getUint16(8, true) };
|
|
22
|
+
}
|
|
23
|
+
// Start-Of-Frame markers carry the frame dimensions. Excludes 0xC4 (DHT),
|
|
24
|
+
// 0xC8 (JPG), 0xCC (DAC), which share the 0xCn range but aren't frame headers.
|
|
25
|
+
function isSofMarker(marker) {
|
|
26
|
+
return (marker >= 0xc0 &&
|
|
27
|
+
marker <= 0xcf &&
|
|
28
|
+
marker !== 0xc4 &&
|
|
29
|
+
marker !== 0xc8 &&
|
|
30
|
+
marker !== 0xcc);
|
|
31
|
+
}
|
|
32
|
+
function readJpeg(v) {
|
|
33
|
+
const len = v.byteLength;
|
|
34
|
+
if (len < 2 || v.getUint8(0) !== 0xff || v.getUint8(1) !== 0xd8)
|
|
35
|
+
return null;
|
|
36
|
+
let pos = 2;
|
|
37
|
+
while (pos + 1 < len) {
|
|
38
|
+
if (v.getUint8(pos) !== 0xff || v.getUint8(pos + 1) === 0xff) {
|
|
39
|
+
pos++; // stray fill byte or padding before the next marker
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const marker = v.getUint8(pos + 1);
|
|
43
|
+
pos += 2;
|
|
44
|
+
// Standalone markers (SOI/EOI/TEM/RSTn) carry no length segment.
|
|
45
|
+
if (marker === 0xd8 || marker === 0xd9 || marker === 0x01)
|
|
46
|
+
continue;
|
|
47
|
+
if (marker >= 0xd0 && marker <= 0xd7)
|
|
48
|
+
continue;
|
|
49
|
+
if (pos + 1 >= len)
|
|
50
|
+
return null;
|
|
51
|
+
if (isSofMarker(marker)) {
|
|
52
|
+
// length(2), precision(1), then height/width as BE u16.
|
|
53
|
+
if (pos + 6 >= len)
|
|
54
|
+
return null;
|
|
55
|
+
return { width: v.getUint16(pos + 5), height: v.getUint16(pos + 3) };
|
|
56
|
+
}
|
|
57
|
+
const segLen = v.getUint16(pos);
|
|
58
|
+
if (segLen < 2)
|
|
59
|
+
return null;
|
|
60
|
+
pos += segLen;
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
function fourccAt(v, offset) {
|
|
65
|
+
return String.fromCharCode(v.getUint8(offset), v.getUint8(offset + 1), v.getUint8(offset + 2), v.getUint8(offset + 3));
|
|
66
|
+
}
|
|
67
|
+
function readWebp(v) {
|
|
68
|
+
// RIFF(4) + size(4) + "WEBP"(4), then a variant chunk whose fourcc at
|
|
69
|
+
// offset 12 selects the dimension layout.
|
|
70
|
+
if (v.byteLength < 16)
|
|
71
|
+
return null;
|
|
72
|
+
const fourcc = fourccAt(v, 12);
|
|
73
|
+
if (fourcc === "VP8X") {
|
|
74
|
+
// flags(1) + reserved(3), then canvas (width-1)/(height-1) as LE u24.
|
|
75
|
+
if (v.byteLength < 30)
|
|
76
|
+
return null;
|
|
77
|
+
const w = v.getUint16(24, true) | (v.getUint8(26) << 16);
|
|
78
|
+
const h = v.getUint16(27, true) | (v.getUint8(29) << 16);
|
|
79
|
+
return { width: w + 1, height: h + 1 };
|
|
80
|
+
}
|
|
81
|
+
if (fourcc === "VP8 ") {
|
|
82
|
+
// frame tag(3) + start code 0x9d012a(3), then 14-bit width/height as LE u16.
|
|
83
|
+
// Require the start code so a non-key-frame or corrupt chunk yields null
|
|
84
|
+
// rather than a masked-but-meaningless number.
|
|
85
|
+
if (v.byteLength < 30 ||
|
|
86
|
+
v.getUint8(23) !== 0x9d ||
|
|
87
|
+
v.getUint8(24) !== 0x01 ||
|
|
88
|
+
v.getUint8(25) !== 0x2a) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
width: v.getUint16(26, true) & 0x3fff,
|
|
93
|
+
height: v.getUint16(28, true) & 0x3fff,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
if (fourcc === "VP8L") {
|
|
97
|
+
// 0x2f signature at 20, then 14-bit (width-1)/(height-1) bit-packed.
|
|
98
|
+
if (v.byteLength < 25 || v.getUint8(20) !== 0x2f)
|
|
99
|
+
return null;
|
|
100
|
+
const bits = v.getUint32(21, true);
|
|
101
|
+
return {
|
|
102
|
+
width: (bits & 0x3fff) + 1,
|
|
103
|
+
height: ((bits >>> 14) & 0x3fff) + 1,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
function readAvif(v) {
|
|
109
|
+
// ISOBMFF nests the ImageSpatialExtents box (`ispe`) several boxes deep;
|
|
110
|
+
// scan for its fourcc rather than walking the box tree, then read the BE
|
|
111
|
+
// u32 width/height that follow the 4-byte version/flags field. Require the
|
|
112
|
+
// preceding u32 to be the fixed 20-byte box size (size(4) + type(4) +
|
|
113
|
+
// version/flags(4) + w(4) + h(4)) so a stray `ispe` in some other box's
|
|
114
|
+
// payload can't be mistaken for a real spatial-extents box.
|
|
115
|
+
for (let i = 4; i + 16 <= v.byteLength; i++) {
|
|
116
|
+
if (fourccAt(v, i) === "ispe" && v.getUint32(i - 4) === 0x14) {
|
|
117
|
+
const width = v.getUint32(i + 8);
|
|
118
|
+
const height = v.getUint32(i + 12);
|
|
119
|
+
if (width > 0 && height > 0)
|
|
120
|
+
return { width, height };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
export function readImageDimensions(bytes, mime) {
|
|
126
|
+
const v = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
127
|
+
switch (mime) {
|
|
128
|
+
case "image/png":
|
|
129
|
+
return readPng(v);
|
|
130
|
+
case "image/gif":
|
|
131
|
+
return readGif(v);
|
|
132
|
+
case "image/jpeg":
|
|
133
|
+
return readJpeg(v);
|
|
134
|
+
case "image/webp":
|
|
135
|
+
return readWebp(v);
|
|
136
|
+
case "image/avif":
|
|
137
|
+
return readAvif(v);
|
|
138
|
+
default:
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=image-dimensions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"image-dimensions.js","sourceRoot":"","sources":["../src/image-dimensions.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { PluginDescriptor } from "plumix/plugin";
|
|
2
|
+
import { DEFAULT_ACCEPTED_TYPES } from "./mime.js";
|
|
3
|
+
export type { MediaFieldScope } from "./lookup.js";
|
|
4
|
+
export { DEFAULT_ACCEPTED_TYPES };
|
|
5
|
+
/** Default max upload size — 25 MiB. */
|
|
6
|
+
export declare const DEFAULT_MAX_UPLOAD_SIZE: number;
|
|
7
|
+
export { mediaBlocks } from "./media-blocks.js";
|
|
8
|
+
interface MediaPluginOptions {
|
|
9
|
+
/**
|
|
10
|
+
* MIME types accepted by `media.createUploadUrl`. The browser sends a
|
|
11
|
+
* proposed `contentType`; anything outside the allowlist is rejected
|
|
12
|
+
* before a presigned URL is minted. Defaults to {@link DEFAULT_ACCEPTED_TYPES}.
|
|
13
|
+
*/
|
|
14
|
+
readonly acceptedTypes?: readonly string[];
|
|
15
|
+
/**
|
|
16
|
+
* Maximum upload size in bytes. The browser-declared `size` in
|
|
17
|
+
* `media.createUploadUrl` is rejected up front if it exceeds this
|
|
18
|
+
* cap, the value is signed into presigned PUTs as `Content-Length`,
|
|
19
|
+
* and the worker-routed upload counts actual bytes streamed and
|
|
20
|
+
* aborts past the cap. Defaults to 25 MiB.
|
|
21
|
+
*/
|
|
22
|
+
readonly maxUploadSize?: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Media plugin — registers the `media` entry type, the `media.*` RPC
|
|
26
|
+
* router, and the admin Media Library page.
|
|
27
|
+
*
|
|
28
|
+
* Uploads use the two-phase signed-URL flow:
|
|
29
|
+
*
|
|
30
|
+
* 1. `media.createUploadUrl({ filename, contentType, size })` →
|
|
31
|
+
* creates a `draft` entry, returns a presigned PUT URL the browser
|
|
32
|
+
* uses to upload bytes directly to storage.
|
|
33
|
+
* 2. `media.confirm({ id })` → flips the entry from `draft` to
|
|
34
|
+
* `published` once the browser-PUT succeeded.
|
|
35
|
+
*
|
|
36
|
+
* Bytes never traverse the worker. Requires a storage adapter whose
|
|
37
|
+
* `presignPut` is implemented (e.g. `r2({ s3: { ... } })`).
|
|
38
|
+
*
|
|
39
|
+
* Pairs with `imageDelivery:` for on-the-fly resizing.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* import { media } from "@plumix/plugin-media";
|
|
44
|
+
*
|
|
45
|
+
* plumix({
|
|
46
|
+
* storage: r2({
|
|
47
|
+
* binding: "MEDIA",
|
|
48
|
+
* publicUrlBase: "https://media.example.com",
|
|
49
|
+
* s3: {
|
|
50
|
+
* bucket: "plumix-media",
|
|
51
|
+
* accountId: env.CF_ACCOUNT_ID,
|
|
52
|
+
* accessKeyId: env.R2_ACCESS_KEY_ID,
|
|
53
|
+
* secretAccessKey: env.R2_SECRET_ACCESS_KEY,
|
|
54
|
+
* },
|
|
55
|
+
* }),
|
|
56
|
+
* imageDelivery: images({ zone: "media.example.com" }),
|
|
57
|
+
* plugins: [media()],
|
|
58
|
+
* });
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export declare function media(options?: MediaPluginOptions): PluginDescriptor<undefined>;
|
|
62
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAOvE,OAAO,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAKnD,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,OAAO,EAAE,sBAAsB,EAAE,CAAC;AAElC,wCAAwC;AACxC,eAAO,MAAM,uBAAuB,QAAmB,CAAC;AAgExD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,UAAU,kBAAkB;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C;;;;;;OAMG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAYD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,KAAK,CACnB,OAAO,GAAE,kBAAuB,GAC/B,gBAAgB,CAAC,SAAS,CAAC,CA8G7B"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { definePlugin } from "plumix/plugin";
|
|
2
|
+
import { fileBlock } from "./blocks/file/index.js";
|
|
3
|
+
import { imageBlock } from "./blocks/image/index.js";
|
|
4
|
+
import { mediaLookupAdapter } from "./lookup.js";
|
|
5
|
+
import { mediaGetTool, mediaListTool } from "./mcp-tools.js";
|
|
6
|
+
import { DEFAULT_ACCEPTED_TYPES } from "./mime.js";
|
|
7
|
+
import { createMediaRouter } from "./rpc.js";
|
|
8
|
+
import { handleMediaServe } from "./serve-route.js";
|
|
9
|
+
import { handleWorkerUpload } from "./upload-route.js";
|
|
10
|
+
export { DEFAULT_ACCEPTED_TYPES };
|
|
11
|
+
/** Default max upload size — 25 MiB. */
|
|
12
|
+
export const DEFAULT_MAX_UPLOAD_SIZE = 25 * 1024 * 1024;
|
|
13
|
+
// Per-entity label table; `satisfies EntryTypeLabels` catches typo-
|
|
14
|
+
// renames at compile time. See `plugin-pages/src/index.ts` for the
|
|
15
|
+
// "no Babel macro server-side" rationale on the literal `{id,message}`
|
|
16
|
+
// shape.
|
|
17
|
+
const MEDIA_LABELS = {
|
|
18
|
+
singular: { id: "plugin.media.media.singular", message: "Asset" },
|
|
19
|
+
plural: { id: "plugin.media.media.plural", message: "Media" },
|
|
20
|
+
addNew: { id: "plugin.media.media.addNew", message: "Add New" },
|
|
21
|
+
addNewItem: {
|
|
22
|
+
id: "plugin.media.media.addNewItem",
|
|
23
|
+
message: "Upload Media",
|
|
24
|
+
},
|
|
25
|
+
editItem: {
|
|
26
|
+
id: "plugin.media.media.editItem",
|
|
27
|
+
message: "Edit Media",
|
|
28
|
+
},
|
|
29
|
+
newItem: {
|
|
30
|
+
id: "plugin.media.media.newItem",
|
|
31
|
+
message: "New Media",
|
|
32
|
+
},
|
|
33
|
+
viewItem: {
|
|
34
|
+
id: "plugin.media.media.viewItem",
|
|
35
|
+
message: "View Media",
|
|
36
|
+
},
|
|
37
|
+
searchItems: {
|
|
38
|
+
id: "plugin.media.media.searchItems",
|
|
39
|
+
message: "Search media…",
|
|
40
|
+
},
|
|
41
|
+
notFound: {
|
|
42
|
+
id: "plugin.media.media.notFound",
|
|
43
|
+
message: "No media yet",
|
|
44
|
+
},
|
|
45
|
+
notFoundInTrash: {
|
|
46
|
+
id: "plugin.media.media.notFoundInTrash",
|
|
47
|
+
message: "Trash is empty",
|
|
48
|
+
},
|
|
49
|
+
allItems: {
|
|
50
|
+
id: "plugin.media.media.allItems",
|
|
51
|
+
message: "All Media",
|
|
52
|
+
},
|
|
53
|
+
untitledItem: {
|
|
54
|
+
id: "plugin.media.media.untitledItem",
|
|
55
|
+
message: "Untitled Media",
|
|
56
|
+
},
|
|
57
|
+
moveToTrash: {
|
|
58
|
+
id: "plugin.media.media.moveToTrash",
|
|
59
|
+
message: "Move media to trash?",
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
// Admin-page chrome (separate from per-type labels because the
|
|
63
|
+
// "Media Library" page heading isn't an entry-type label).
|
|
64
|
+
const MEDIA_LIBRARY_LABEL = {
|
|
65
|
+
id: "plugin.media.adminPage.title",
|
|
66
|
+
message: "Media Library",
|
|
67
|
+
};
|
|
68
|
+
const LIBRARY_GROUP_LABEL = {
|
|
69
|
+
id: "core.adminNav.library",
|
|
70
|
+
message: "Library",
|
|
71
|
+
};
|
|
72
|
+
// Re-export the canonical list from `media-blocks.ts` (server-clean).
|
|
73
|
+
export { mediaBlocks } from "./media-blocks.js";
|
|
74
|
+
/**
|
|
75
|
+
* Lexical path the plumix vite plugin uses to locate this package's admin
|
|
76
|
+
* chunk. Stays inside the consumer's project tree (`node_modules/...`) so
|
|
77
|
+
* the build-time containment check passes; esbuild follows the symlink to
|
|
78
|
+
* the workspace source under the hood. Override `adminEntry` in
|
|
79
|
+
* `definePlugin` if your install layout differs (e.g. pnpm hoisting tweaks).
|
|
80
|
+
*/
|
|
81
|
+
const ADMIN_ENTRY_PATH = "node_modules/@plumix/plugin-media/dist/admin/index.js";
|
|
82
|
+
/**
|
|
83
|
+
* Media plugin — registers the `media` entry type, the `media.*` RPC
|
|
84
|
+
* router, and the admin Media Library page.
|
|
85
|
+
*
|
|
86
|
+
* Uploads use the two-phase signed-URL flow:
|
|
87
|
+
*
|
|
88
|
+
* 1. `media.createUploadUrl({ filename, contentType, size })` →
|
|
89
|
+
* creates a `draft` entry, returns a presigned PUT URL the browser
|
|
90
|
+
* uses to upload bytes directly to storage.
|
|
91
|
+
* 2. `media.confirm({ id })` → flips the entry from `draft` to
|
|
92
|
+
* `published` once the browser-PUT succeeded.
|
|
93
|
+
*
|
|
94
|
+
* Bytes never traverse the worker. Requires a storage adapter whose
|
|
95
|
+
* `presignPut` is implemented (e.g. `r2({ s3: { ... } })`).
|
|
96
|
+
*
|
|
97
|
+
* Pairs with `imageDelivery:` for on-the-fly resizing.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```ts
|
|
101
|
+
* import { media } from "@plumix/plugin-media";
|
|
102
|
+
*
|
|
103
|
+
* plumix({
|
|
104
|
+
* storage: r2({
|
|
105
|
+
* binding: "MEDIA",
|
|
106
|
+
* publicUrlBase: "https://media.example.com",
|
|
107
|
+
* s3: {
|
|
108
|
+
* bucket: "plumix-media",
|
|
109
|
+
* accountId: env.CF_ACCOUNT_ID,
|
|
110
|
+
* accessKeyId: env.R2_ACCESS_KEY_ID,
|
|
111
|
+
* secretAccessKey: env.R2_SECRET_ACCESS_KEY,
|
|
112
|
+
* },
|
|
113
|
+
* }),
|
|
114
|
+
* imageDelivery: images({ zone: "media.example.com" }),
|
|
115
|
+
* plugins: [media()],
|
|
116
|
+
* });
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
export function media(options = {}) {
|
|
120
|
+
const acceptedTypes = options.acceptedTypes ?? DEFAULT_ACCEPTED_TYPES;
|
|
121
|
+
const maxUploadSize = options.maxUploadSize ?? DEFAULT_MAX_UPLOAD_SIZE;
|
|
122
|
+
return definePlugin("media", (ctx) => {
|
|
123
|
+
// Media blocks contributed under the `media/` namespace. Order is
|
|
124
|
+
// just for readability; the registry is keyed by name.
|
|
125
|
+
ctx.registerBlock(imageBlock);
|
|
126
|
+
ctx.registerBlock(fileBlock);
|
|
127
|
+
ctx.registerEntryType("media", {
|
|
128
|
+
label: MEDIA_LABELS.plural,
|
|
129
|
+
labels: MEDIA_LABELS,
|
|
130
|
+
description: "Uploaded files — images, video, documents",
|
|
131
|
+
supports: ["title", "excerpt"],
|
|
132
|
+
// `isPublic: false` cascades to `showUI: false` and
|
|
133
|
+
// `showInSidebar: false`. Both are load-bearing here:
|
|
134
|
+
// the plugin renders its own admin page (registered below)
|
|
135
|
+
// — we don't want the generic entries list, sidebar item,
|
|
136
|
+
// or dashboard quick-card auto-registered too.
|
|
137
|
+
isPublic: false,
|
|
138
|
+
excludeFromGenericRpc: false,
|
|
139
|
+
hasArchive: false,
|
|
140
|
+
menuIcon: "image",
|
|
141
|
+
});
|
|
142
|
+
ctx.registerRpcRouter(createMediaRouter({ acceptedTypes, maxUploadSize }));
|
|
143
|
+
// Media's own MCP read tools, contributed through the plugin seam —
|
|
144
|
+
// they ship from the plugin that owns media, not core.
|
|
145
|
+
ctx.registerMcpTool(mediaListTool);
|
|
146
|
+
ctx.registerMcpTool(mediaGetTool);
|
|
147
|
+
// Reference-field surface: any `media({ ... })` field calls
|
|
148
|
+
// through `lookup.list({ kind: "media", ids })` for write
|
|
149
|
+
// validation + read-time orphan filter, and through the same
|
|
150
|
+
// RPC for picker label resolution. Capability matches the
|
|
151
|
+
// existing media library page gate.
|
|
152
|
+
ctx.registerLookupAdapter({
|
|
153
|
+
kind: "media",
|
|
154
|
+
adapter: mediaLookupAdapter,
|
|
155
|
+
capability: "entry:media:read",
|
|
156
|
+
});
|
|
157
|
+
// Worker-routed upload fallback. `media.createUploadUrl` returns
|
|
158
|
+
// this URL when `storage.presignPut` isn't configured (e.g. the
|
|
159
|
+
// R2 binding is attached but no S3 credentials are wired up). The
|
|
160
|
+
// browser PUTs bytes here, the dispatcher authenticates the
|
|
161
|
+
// session, and the handler streams them through to storage.
|
|
162
|
+
ctx.registerRoute({
|
|
163
|
+
method: "PUT",
|
|
164
|
+
path: "/upload/*",
|
|
165
|
+
auth: "authenticated",
|
|
166
|
+
handler: handleWorkerUpload,
|
|
167
|
+
});
|
|
168
|
+
// Worker-proxied media serve. When the storage adapter has no
|
|
169
|
+
// public URL base (private bucket without a custom domain),
|
|
170
|
+
// `r2.url()` returns a relative URL pointing here. Public so
|
|
171
|
+
// published media can be embedded in pages/posts.
|
|
172
|
+
ctx.registerRoute({
|
|
173
|
+
method: "GET",
|
|
174
|
+
path: "/serve/*",
|
|
175
|
+
auth: "public",
|
|
176
|
+
handler: handleMediaServe,
|
|
177
|
+
});
|
|
178
|
+
ctx.registerAdminPage({
|
|
179
|
+
path: "/media",
|
|
180
|
+
title: MEDIA_LIBRARY_LABEL,
|
|
181
|
+
capability: "entry:media:read",
|
|
182
|
+
nav: {
|
|
183
|
+
// Own group between Entries (priority 100) and Taxonomies
|
|
184
|
+
// (priority 200). Media isn't a content surface like Posts/
|
|
185
|
+
// Pages — putting it under "Entries" reads as nesting, which
|
|
186
|
+
// doesn't match the WordPress mental model.
|
|
187
|
+
group: {
|
|
188
|
+
id: "library",
|
|
189
|
+
label: LIBRARY_GROUP_LABEL,
|
|
190
|
+
priority: 150,
|
|
191
|
+
},
|
|
192
|
+
label: MEDIA_LIBRARY_LABEL,
|
|
193
|
+
order: 50,
|
|
194
|
+
keywords: [
|
|
195
|
+
{ id: "plugin.media.keyword.images", message: "images" },
|
|
196
|
+
{ id: "plugin.media.keyword.files", message: "files" },
|
|
197
|
+
{ id: "plugin.media.keyword.uploads", message: "uploads" },
|
|
198
|
+
{ id: "plugin.media.keyword.photos", message: "photos" },
|
|
199
|
+
{ id: "plugin.media.keyword.assets", message: "assets" },
|
|
200
|
+
],
|
|
201
|
+
},
|
|
202
|
+
component: "MediaLibrary",
|
|
203
|
+
});
|
|
204
|
+
}, {
|
|
205
|
+
adminEntry: ADMIN_ENTRY_PATH,
|
|
206
|
+
// Browser-safe block specs for the editor canvas (the iframe ships no
|
|
207
|
+
// server code). Mirrors the `ctx.registerBlock` calls above.
|
|
208
|
+
editorBlocksModule: "@plumix/plugin-media/blocks",
|
|
209
|
+
i18n: {
|
|
210
|
+
sourceLocale: "en",
|
|
211
|
+
locales: ["en"],
|
|
212
|
+
catalogPath: "./locales",
|
|
213
|
+
},
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/lookup.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { LookupAdapter } from "plumix/plugin";
|
|
2
|
+
/**
|
|
3
|
+
* Public scope shape for the `media` reference field. Carried on the
|
|
4
|
+
* field's `referenceTarget.scope`; the media `LookupAdapter` consumes
|
|
5
|
+
* it for write-time validation, picker filtering, and read-time
|
|
6
|
+
* orphan resolution.
|
|
7
|
+
*
|
|
8
|
+
* `accept` is either a single MIME prefix string (`"image/"` matches
|
|
9
|
+
* `image/png`, `image/jpeg`, …) or a readonly array of exact MIME
|
|
10
|
+
* matches. Drop HTML's `image/*` wildcard syntax — the trailing slash
|
|
11
|
+
* already conveys "category" and avoids the `image/*` vs `image/`
|
|
12
|
+
* ambiguity.
|
|
13
|
+
*/
|
|
14
|
+
export interface MediaFieldScope {
|
|
15
|
+
readonly accept?: string | readonly string[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Server-side adapter for the `media` reference field. Storage is the
|
|
19
|
+
* cached-object shape (`{ id, mime, filename }`) — the meta pipeline
|
|
20
|
+
* pulls `cached` from `LookupResult` and merges it into the stored
|
|
21
|
+
* value on every write so reads render thumbnails without an extra
|
|
22
|
+
* resolve round-trip.
|
|
23
|
+
*
|
|
24
|
+
* Queries:
|
|
25
|
+
* - `list({ ids })`: PK lookup via `inArray(entries.id, …)` + the
|
|
26
|
+
* `entries_type_status_published_idx` partition. SQLite picks the
|
|
27
|
+
* PK as the most selective; the type+status filter is post-applied
|
|
28
|
+
* to a small rowset.
|
|
29
|
+
* - `list({ query })`: leverages `entries_type_status_published_idx`
|
|
30
|
+
* for the `(type, status)` prefix; ordered by `desc(publishedAt)`
|
|
31
|
+
* matches the index's third column (no extra sort).
|
|
32
|
+
* - MIME `accept` filter: post-filter in JS against the meta JSON.
|
|
33
|
+
* The narrowed rowset (type+status or PK) keeps this tractable
|
|
34
|
+
* without a generated column.
|
|
35
|
+
*
|
|
36
|
+
* Drafts and trashed media are invisible to the picker — only
|
|
37
|
+
* `status = "published"` rows surface. A draft media entry exists
|
|
38
|
+
* between `media.createUploadUrl` (writes a draft row) and
|
|
39
|
+
* `media.confirm` (flips to published) — referencing one would point
|
|
40
|
+
* at an asset whose bytes haven't been verified.
|
|
41
|
+
*/
|
|
42
|
+
export declare const mediaLookupAdapter: LookupAdapter<MediaFieldScope>;
|
|
43
|
+
//# sourceMappingURL=lookup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lookup.d.ts","sourceRoot":"","sources":["../src/lookup.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAqB,MAAM,eAAe,CAAC;AAgBtE;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;CAC9C;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,kBAAkB,EAAE,aAAa,CAAC,eAAe,CA4D7D,CAAC"}
|
package/dist/lookup.js
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { and, desc, entries, eq, inArray, like, sql } from "plumix/plugin";
|
|
2
|
+
import { parseMediaMeta } from "./meta.js";
|
|
3
|
+
const MEDIA_ENTRY_TYPE = "media";
|
|
4
|
+
const DEFAULT_LIST_LIMIT = 24;
|
|
5
|
+
const MAX_LIST_LIMIT = 100;
|
|
6
|
+
const MEDIA_ROW_COLUMNS = {
|
|
7
|
+
id: entries.id,
|
|
8
|
+
title: entries.title,
|
|
9
|
+
meta: entries.meta,
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Server-side adapter for the `media` reference field. Storage is the
|
|
13
|
+
* cached-object shape (`{ id, mime, filename }`) — the meta pipeline
|
|
14
|
+
* pulls `cached` from `LookupResult` and merges it into the stored
|
|
15
|
+
* value on every write so reads render thumbnails without an extra
|
|
16
|
+
* resolve round-trip.
|
|
17
|
+
*
|
|
18
|
+
* Queries:
|
|
19
|
+
* - `list({ ids })`: PK lookup via `inArray(entries.id, …)` + the
|
|
20
|
+
* `entries_type_status_published_idx` partition. SQLite picks the
|
|
21
|
+
* PK as the most selective; the type+status filter is post-applied
|
|
22
|
+
* to a small rowset.
|
|
23
|
+
* - `list({ query })`: leverages `entries_type_status_published_idx`
|
|
24
|
+
* for the `(type, status)` prefix; ordered by `desc(publishedAt)`
|
|
25
|
+
* matches the index's third column (no extra sort).
|
|
26
|
+
* - MIME `accept` filter: post-filter in JS against the meta JSON.
|
|
27
|
+
* The narrowed rowset (type+status or PK) keeps this tractable
|
|
28
|
+
* without a generated column.
|
|
29
|
+
*
|
|
30
|
+
* Drafts and trashed media are invisible to the picker — only
|
|
31
|
+
* `status = "published"` rows surface. A draft media entry exists
|
|
32
|
+
* between `media.createUploadUrl` (writes a draft row) and
|
|
33
|
+
* `media.confirm` (flips to published) — referencing one would point
|
|
34
|
+
* at an asset whose bytes haven't been verified.
|
|
35
|
+
*/
|
|
36
|
+
export const mediaLookupAdapter = {
|
|
37
|
+
async list(ctx, options) {
|
|
38
|
+
const conditions = [
|
|
39
|
+
eq(entries.type, MEDIA_ENTRY_TYPE),
|
|
40
|
+
eq(entries.status, "published"),
|
|
41
|
+
];
|
|
42
|
+
const acceptCondition = buildAcceptCondition(options.scope?.accept);
|
|
43
|
+
if (acceptCondition)
|
|
44
|
+
conditions.push(acceptCondition);
|
|
45
|
+
let limit;
|
|
46
|
+
if (options.ids !== undefined) {
|
|
47
|
+
const numericIds = options.ids
|
|
48
|
+
.map((id) => parseMediaId(id))
|
|
49
|
+
.filter((id) => id !== null);
|
|
50
|
+
if (numericIds.length === 0)
|
|
51
|
+
return [];
|
|
52
|
+
conditions.push(inArray(entries.id, numericIds));
|
|
53
|
+
limit = numericIds.length;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
const trimmedQuery = options.query?.trim();
|
|
57
|
+
if (trimmedQuery) {
|
|
58
|
+
conditions.push(like(entries.title, `%${trimmedQuery}%`));
|
|
59
|
+
}
|
|
60
|
+
limit = clampLimit(options.limit);
|
|
61
|
+
}
|
|
62
|
+
const rows = await ctx.db
|
|
63
|
+
.select(MEDIA_ROW_COLUMNS)
|
|
64
|
+
.from(entries)
|
|
65
|
+
.where(and(...conditions))
|
|
66
|
+
.orderBy(desc(entries.publishedAt), desc(entries.id))
|
|
67
|
+
.limit(limit);
|
|
68
|
+
const results = [];
|
|
69
|
+
for (const row of rows) {
|
|
70
|
+
const meta = parseMediaMeta(row.meta);
|
|
71
|
+
if (!meta)
|
|
72
|
+
continue;
|
|
73
|
+
results.push(toLookupResult(row.id, row.title, meta.mime));
|
|
74
|
+
}
|
|
75
|
+
return results;
|
|
76
|
+
},
|
|
77
|
+
async resolve(ctx, id, scope) {
|
|
78
|
+
const numericId = parseMediaId(id);
|
|
79
|
+
if (numericId === null)
|
|
80
|
+
return null;
|
|
81
|
+
const conditions = [
|
|
82
|
+
eq(entries.id, numericId),
|
|
83
|
+
eq(entries.type, MEDIA_ENTRY_TYPE),
|
|
84
|
+
eq(entries.status, "published"),
|
|
85
|
+
];
|
|
86
|
+
const acceptCondition = buildAcceptCondition(scope?.accept);
|
|
87
|
+
if (acceptCondition)
|
|
88
|
+
conditions.push(acceptCondition);
|
|
89
|
+
const [row] = await ctx.db
|
|
90
|
+
.select(MEDIA_ROW_COLUMNS)
|
|
91
|
+
.from(entries)
|
|
92
|
+
.where(and(...conditions))
|
|
93
|
+
.limit(1);
|
|
94
|
+
if (!row)
|
|
95
|
+
return null;
|
|
96
|
+
const meta = parseMediaMeta(row.meta);
|
|
97
|
+
if (!meta)
|
|
98
|
+
return null;
|
|
99
|
+
return toLookupResult(row.id, row.title, meta.mime);
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
function parseMediaId(id) {
|
|
103
|
+
if (!/^[1-9]\d{0,15}$/.test(id))
|
|
104
|
+
return null;
|
|
105
|
+
const parsed = Number(id);
|
|
106
|
+
return Number.isSafeInteger(parsed) ? parsed : null;
|
|
107
|
+
}
|
|
108
|
+
function clampLimit(requested) {
|
|
109
|
+
if (requested === undefined)
|
|
110
|
+
return DEFAULT_LIST_LIMIT;
|
|
111
|
+
if (!Number.isFinite(requested) || requested <= 0)
|
|
112
|
+
return DEFAULT_LIST_LIMIT;
|
|
113
|
+
return Math.min(Math.floor(requested), MAX_LIST_LIMIT);
|
|
114
|
+
}
|
|
115
|
+
// Translate the `accept` scope into a SQL predicate against the
|
|
116
|
+
// extracted JSON `mime` field. Pushing the filter into SQL means the
|
|
117
|
+
// browse path's LIMIT clause counts only rows that pass the accept
|
|
118
|
+
// filter — post-filtering in JS would silently under-fill the picker
|
|
119
|
+
// grid for fields whose accept rejects a chunk of the recent uploads.
|
|
120
|
+
//
|
|
121
|
+
// `meta.mime` isn't indexed (no generated column), but the type+status
|
|
122
|
+
// filter has already narrowed the rowset before this predicate is
|
|
123
|
+
// applied, so the cost is bounded. Real MIME strings don't contain
|
|
124
|
+
// `%`/`_`, and plugin-supplied prefixes are trusted (set at field-
|
|
125
|
+
// build time, not user input), so no LIKE escaping needed.
|
|
126
|
+
function buildAcceptCondition(accept) {
|
|
127
|
+
if (accept === undefined)
|
|
128
|
+
return undefined;
|
|
129
|
+
const mimeExpr = sql `json_extract(${entries.meta}, '$.mime')`;
|
|
130
|
+
if (typeof accept === "string") {
|
|
131
|
+
if (accept === "")
|
|
132
|
+
return undefined;
|
|
133
|
+
return like(mimeExpr, `${accept}%`);
|
|
134
|
+
}
|
|
135
|
+
if (accept.length === 0)
|
|
136
|
+
return undefined;
|
|
137
|
+
return inArray(mimeExpr, accept);
|
|
138
|
+
}
|
|
139
|
+
function toLookupResult(id, title, mime) {
|
|
140
|
+
// Mirror the entry adapter's `null` contract for empty/whitespace
|
|
141
|
+
// titles so admin pickers render a localized "Untitled" descriptor
|
|
142
|
+
// rather than an empty `<p>`. `cached.filename` keeps the raw value
|
|
143
|
+
// (deletion-resilient consumers may still want the original token).
|
|
144
|
+
const trimmedTitle = title.trim();
|
|
145
|
+
const label = trimmedTitle !== "" ? trimmedTitle : null;
|
|
146
|
+
return {
|
|
147
|
+
id: String(id),
|
|
148
|
+
label,
|
|
149
|
+
targetType: MEDIA_ENTRY_TYPE,
|
|
150
|
+
subtitle: mime,
|
|
151
|
+
cached: { mime, filename: title },
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=lookup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lookup.js","sourceRoot":"","sources":["../src/lookup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"magic-bytes.d.ts","sourceRoot":"","sources":["../src/magic-bytes.ts"],"names":[],"mappings":"AAgIA,mEAAmE;AACnE,eAAO,MAAM,sBAAsB,KAAK,CAAC;AAEzC,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAI7E"}
|