@dalgoridim/headless-cms 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 +10 -0
- package/README.md +178 -0
- package/dist/adapters/firestore/index.cjs +152 -0
- package/dist/adapters/firestore/index.cjs.map +1 -0
- package/dist/adapters/firestore/index.d.cts +39 -0
- package/dist/adapters/firestore/index.d.ts +39 -0
- package/dist/adapters/firestore/index.js +120 -0
- package/dist/adapters/firestore/index.js.map +1 -0
- package/dist/adapters/postgres/index.cjs +299 -0
- package/dist/adapters/postgres/index.cjs.map +1 -0
- package/dist/adapters/postgres/index.d.cts +59 -0
- package/dist/adapters/postgres/index.d.ts +59 -0
- package/dist/adapters/postgres/index.js +277 -0
- package/dist/adapters/postgres/index.js.map +1 -0
- package/dist/auth/firebase/client/index.cjs +153 -0
- package/dist/auth/firebase/client/index.cjs.map +1 -0
- package/dist/auth/firebase/client/index.d.cts +29 -0
- package/dist/auth/firebase/client/index.d.ts +29 -0
- package/dist/auth/firebase/client/index.js +138 -0
- package/dist/auth/firebase/client/index.js.map +1 -0
- package/dist/auth/firebase/index.cjs +81 -0
- package/dist/auth/firebase/index.cjs.map +1 -0
- package/dist/auth/firebase/index.d.cts +23 -0
- package/dist/auth/firebase/index.d.ts +23 -0
- package/dist/auth/firebase/index.js +46 -0
- package/dist/auth/firebase/index.js.map +1 -0
- package/dist/auth/nextauth/index.cjs +51 -0
- package/dist/auth/nextauth/index.cjs.map +1 -0
- package/dist/auth/nextauth/index.d.cts +30 -0
- package/dist/auth/nextauth/index.d.ts +30 -0
- package/dist/auth/nextauth/index.js +25 -0
- package/dist/auth/nextauth/index.js.map +1 -0
- package/dist/client/index.cjs +1018 -0
- package/dist/client/index.cjs.map +1 -0
- package/dist/client/index.d.cts +96 -0
- package/dist/client/index.d.ts +96 -0
- package/dist/client/index.js +994 -0
- package/dist/client/index.js.map +1 -0
- package/dist/index.cjs +19 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +122 -0
- package/dist/index.d.ts +122 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -0
- package/dist/server/index.cjs +128 -0
- package/dist/server/index.cjs.map +1 -0
- package/dist/server/index.d.cts +52 -0
- package/dist/server/index.d.ts +52 -0
- package/dist/server/index.js +99 -0
- package/dist/server/index.js.map +1 -0
- package/dist/storage/cloudinary/index.cjs +55 -0
- package/dist/storage/cloudinary/index.cjs.map +1 -0
- package/dist/storage/cloudinary/index.d.cts +17 -0
- package/dist/storage/cloudinary/index.d.ts +17 -0
- package/dist/storage/cloudinary/index.js +30 -0
- package/dist/storage/cloudinary/index.js.map +1 -0
- package/dist/storage/cloudinary/server.cjs +56 -0
- package/dist/storage/cloudinary/server.cjs.map +1 -0
- package/dist/storage/cloudinary/server.d.cts +16 -0
- package/dist/storage/cloudinary/server.d.ts +16 -0
- package/dist/storage/cloudinary/server.js +31 -0
- package/dist/storage/cloudinary/server.js.map +1 -0
- package/dist/storage/local/index.cjs +44 -0
- package/dist/storage/local/index.cjs.map +1 -0
- package/dist/storage/local/index.d.cts +15 -0
- package/dist/storage/local/index.d.ts +15 -0
- package/dist/storage/local/index.js +19 -0
- package/dist/storage/local/index.js.map +1 -0
- package/dist/storage/local/server.cjs +61 -0
- package/dist/storage/local/server.cjs.map +1 -0
- package/dist/storage/local/server.d.cts +16 -0
- package/dist/storage/local/server.d.ts +16 -0
- package/dist/storage/local/server.js +26 -0
- package/dist/storage/local/server.js.map +1 -0
- package/dist/storage/s3/index.cjs +52 -0
- package/dist/storage/s3/index.cjs.map +1 -0
- package/dist/storage/s3/index.d.cts +14 -0
- package/dist/storage/s3/index.d.ts +14 -0
- package/dist/storage/s3/index.js +27 -0
- package/dist/storage/s3/index.js.map +1 -0
- package/dist/storage/s3/server.cjs +61 -0
- package/dist/storage/s3/server.cjs.map +1 -0
- package/dist/storage/s3/server.d.cts +19 -0
- package/dist/storage/s3/server.d.ts +19 -0
- package/dist/storage/s3/server.js +36 -0
- package/dist/storage/s3/server.js.map +1 -0
- package/package.json +165 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { DataAdapter, AuthAdapter, ServerStorageAdapter, AuthIdentity } from '../index.js';
|
|
2
|
+
export { ClientStorageAdapter, NestedSections, Query, Section, StorageAdapter } from '../index.js';
|
|
3
|
+
|
|
4
|
+
interface CmsHandlersDeps {
|
|
5
|
+
data: DataAdapter;
|
|
6
|
+
auth: AuthAdapter;
|
|
7
|
+
storage?: ServerStorageAdapter;
|
|
8
|
+
}
|
|
9
|
+
/** Next.js App Router passes dynamic params as a promise. */
|
|
10
|
+
type RouteContext = {
|
|
11
|
+
params: Promise<{
|
|
12
|
+
collection: string;
|
|
13
|
+
id: string;
|
|
14
|
+
}>;
|
|
15
|
+
};
|
|
16
|
+
type RouteHandler = (req: Request, ctx: RouteContext) => Promise<Response>;
|
|
17
|
+
type SignHandler = (req: Request) => Promise<Response>;
|
|
18
|
+
/**
|
|
19
|
+
* Builds the generic admin CRUD handlers, replacing a hand-written
|
|
20
|
+
* `/api/admin/[collection]/[id]/route.ts`. Mount like:
|
|
21
|
+
*
|
|
22
|
+
* ```ts
|
|
23
|
+
* // app/api/admin/[collection]/[id]/route.ts
|
|
24
|
+
* export const { GET, PATCH, PUT, DELETE } = createCmsHandlers({ data, auth });
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* If a `storage` adapter with a `sign` method is provided, also mount its sign
|
|
28
|
+
* handler at e.g. `app/api/admin/sign/route.ts`:
|
|
29
|
+
*
|
|
30
|
+
* ```ts
|
|
31
|
+
* export const POST = createCmsHandlers({ data, auth, storage }).sign;
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
declare function createCmsHandlers(deps: CmsHandlersDeps): {
|
|
35
|
+
GET: RouteHandler;
|
|
36
|
+
PATCH: RouteHandler;
|
|
37
|
+
PUT: RouteHandler;
|
|
38
|
+
DELETE: RouteHandler;
|
|
39
|
+
sign: SignHandler;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/** Thrown when a request fails the admin gate; carried up to the route handler. */
|
|
43
|
+
declare class UnauthorizedError extends Error {
|
|
44
|
+
constructor(message?: string);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Wraps an {@link AuthAdapter} into a reusable server gate. Throws
|
|
48
|
+
* {@link UnauthorizedError} unless the request resolves to an admin identity.
|
|
49
|
+
*/
|
|
50
|
+
declare function createAdminGate(auth: AuthAdapter): (req: Request) => Promise<AuthIdentity>;
|
|
51
|
+
|
|
52
|
+
export { AuthAdapter, AuthIdentity, type CmsHandlersDeps, DataAdapter, ServerStorageAdapter, UnauthorizedError, createAdminGate, createCmsHandlers };
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// src/server/createAdminGate.ts
|
|
2
|
+
var UnauthorizedError = class extends Error {
|
|
3
|
+
constructor(message = "Unauthorized") {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = "UnauthorizedError";
|
|
6
|
+
}
|
|
7
|
+
};
|
|
8
|
+
function createAdminGate(auth) {
|
|
9
|
+
return async function requireAdmin(req) {
|
|
10
|
+
const identity = await auth.verifyRequest(req);
|
|
11
|
+
if (!identity || !identity.isAdmin) {
|
|
12
|
+
throw new UnauthorizedError(
|
|
13
|
+
identity ? "Forbidden - Not an authorized admin" : "Unauthorized"
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
return identity;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// src/server/createCmsHandlers.ts
|
|
21
|
+
function json(body, status = 200) {
|
|
22
|
+
return new Response(JSON.stringify(body), {
|
|
23
|
+
status,
|
|
24
|
+
headers: { "Content-Type": "application/json" }
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
function errorResponse(error) {
|
|
28
|
+
if (error instanceof UnauthorizedError && error.message === "Unauthorized") {
|
|
29
|
+
return json({ error: "Unauthorized", logout: true }, 401);
|
|
30
|
+
}
|
|
31
|
+
const message = error instanceof Error ? error.message : "Request failed";
|
|
32
|
+
return json({ error: message }, 403);
|
|
33
|
+
}
|
|
34
|
+
function createCmsHandlers(deps) {
|
|
35
|
+
const { data, auth, storage } = deps;
|
|
36
|
+
const requireAdmin = createAdminGate(auth);
|
|
37
|
+
const GET = async (req, ctx) => {
|
|
38
|
+
try {
|
|
39
|
+
await requireAdmin(req);
|
|
40
|
+
const { collection, id } = await ctx.params;
|
|
41
|
+
const doc = await data.fetchById(collection, id);
|
|
42
|
+
if (!doc) return json({ error: "Document not found" }, 404);
|
|
43
|
+
return json(doc);
|
|
44
|
+
} catch (error) {
|
|
45
|
+
return errorResponse(error);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const PATCH = async (req, ctx) => {
|
|
49
|
+
try {
|
|
50
|
+
await requireAdmin(req);
|
|
51
|
+
const { collection, id } = await ctx.params;
|
|
52
|
+
const body = await req.json();
|
|
53
|
+
await data.update(collection, id, body);
|
|
54
|
+
return json({ ok: true });
|
|
55
|
+
} catch (error) {
|
|
56
|
+
return errorResponse(error);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const PUT = async (req, ctx) => {
|
|
60
|
+
try {
|
|
61
|
+
await requireAdmin(req);
|
|
62
|
+
const { collection, id } = await ctx.params;
|
|
63
|
+
const body = await req.json();
|
|
64
|
+
await data.upsert(collection, id, body);
|
|
65
|
+
return json({ ok: true });
|
|
66
|
+
} catch (error) {
|
|
67
|
+
return errorResponse(error);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const DELETE = async (req, ctx) => {
|
|
71
|
+
try {
|
|
72
|
+
await requireAdmin(req);
|
|
73
|
+
const { collection, id } = await ctx.params;
|
|
74
|
+
await data.delete(collection, id);
|
|
75
|
+
return json({ ok: true });
|
|
76
|
+
} catch (error) {
|
|
77
|
+
return errorResponse(error);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
const sign = async (req) => {
|
|
81
|
+
try {
|
|
82
|
+
await requireAdmin(req);
|
|
83
|
+
if (!(storage == null ? void 0 : storage.sign)) {
|
|
84
|
+
return json({ error: "No storage adapter with sign() configured" }, 404);
|
|
85
|
+
}
|
|
86
|
+
const result = await storage.sign(req);
|
|
87
|
+
return json(result);
|
|
88
|
+
} catch (error) {
|
|
89
|
+
return errorResponse(error);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
return { GET, PATCH, PUT, DELETE, sign };
|
|
93
|
+
}
|
|
94
|
+
export {
|
|
95
|
+
UnauthorizedError,
|
|
96
|
+
createAdminGate,
|
|
97
|
+
createCmsHandlers
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/server/createAdminGate.ts","../../src/server/createCmsHandlers.ts"],"sourcesContent":["import type { AuthAdapter, AuthIdentity } from \"../types\";\n\n/** Thrown when a request fails the admin gate; carried up to the route handler. */\nexport class UnauthorizedError extends Error {\n constructor(message = \"Unauthorized\") {\n super(message);\n this.name = \"UnauthorizedError\";\n }\n}\n\n/**\n * Wraps an {@link AuthAdapter} into a reusable server gate. Throws\n * {@link UnauthorizedError} unless the request resolves to an admin identity.\n */\nexport function createAdminGate(auth: AuthAdapter) {\n return async function requireAdmin(req: Request): Promise<AuthIdentity> {\n const identity = await auth.verifyRequest(req);\n if (!identity || !identity.isAdmin) {\n throw new UnauthorizedError(\n identity ? \"Forbidden - Not an authorized admin\" : \"Unauthorized\",\n );\n }\n return identity;\n };\n}\n","import type { DataAdapter, AuthAdapter, ServerStorageAdapter } from \"../types\";\nimport { createAdminGate, UnauthorizedError } from \"./createAdminGate\";\n\nexport interface CmsHandlersDeps {\n data: DataAdapter;\n auth: AuthAdapter;\n storage?: ServerStorageAdapter;\n}\n\n/** Next.js App Router passes dynamic params as a promise. */\ntype RouteContext = {\n params: Promise<{ collection: string; id: string }>;\n};\n\ntype RouteHandler = (req: Request, ctx: RouteContext) => Promise<Response>;\ntype SignHandler = (req: Request) => Promise<Response>;\n\nfunction json(body: unknown, status = 200): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: { \"Content-Type\": \"application/json\" },\n });\n}\n\n/**\n * Translate any thrown error into a response. Auth failures return 401 with\n * `{ logout: true }` so a client interceptor can force sign-out.\n */\nfunction errorResponse(error: unknown): Response {\n if (error instanceof UnauthorizedError && error.message === \"Unauthorized\") {\n return json({ error: \"Unauthorized\", logout: true }, 401);\n }\n const message = error instanceof Error ? error.message : \"Request failed\";\n return json({ error: message }, 403);\n}\n\n/**\n * Builds the generic admin CRUD handlers, replacing a hand-written\n * `/api/admin/[collection]/[id]/route.ts`. Mount like:\n *\n * ```ts\n * // app/api/admin/[collection]/[id]/route.ts\n * export const { GET, PATCH, PUT, DELETE } = createCmsHandlers({ data, auth });\n * ```\n *\n * If a `storage` adapter with a `sign` method is provided, also mount its sign\n * handler at e.g. `app/api/admin/sign/route.ts`:\n *\n * ```ts\n * export const POST = createCmsHandlers({ data, auth, storage }).sign;\n * ```\n */\nexport function createCmsHandlers(deps: CmsHandlersDeps): {\n GET: RouteHandler;\n PATCH: RouteHandler;\n PUT: RouteHandler;\n DELETE: RouteHandler;\n sign: SignHandler;\n} {\n const { data, auth, storage } = deps;\n const requireAdmin = createAdminGate(auth);\n\n const GET: RouteHandler = async (req, ctx) => {\n try {\n await requireAdmin(req);\n const { collection, id } = await ctx.params;\n const doc = await data.fetchById(collection, id);\n if (!doc) return json({ error: \"Document not found\" }, 404);\n return json(doc);\n } catch (error) {\n return errorResponse(error);\n }\n };\n\n const PATCH: RouteHandler = async (req, ctx) => {\n try {\n await requireAdmin(req);\n const { collection, id } = await ctx.params;\n const body = await req.json();\n await data.update(collection, id, body);\n return json({ ok: true });\n } catch (error) {\n return errorResponse(error);\n }\n };\n\n const PUT: RouteHandler = async (req, ctx) => {\n try {\n await requireAdmin(req);\n const { collection, id } = await ctx.params;\n const body = await req.json();\n await data.upsert(collection, id, body);\n return json({ ok: true });\n } catch (error) {\n return errorResponse(error);\n }\n };\n\n const DELETE: RouteHandler = async (req, ctx) => {\n try {\n await requireAdmin(req);\n const { collection, id } = await ctx.params;\n await data.delete(collection, id);\n return json({ ok: true });\n } catch (error) {\n return errorResponse(error);\n }\n };\n\n const sign: SignHandler = async (req) => {\n try {\n await requireAdmin(req);\n if (!storage?.sign) {\n return json({ error: \"No storage adapter with sign() configured\" }, 404);\n }\n const result = await storage.sign(req);\n return json(result);\n } catch (error) {\n return errorResponse(error);\n }\n };\n\n return { GET, PATCH, PUT, DELETE, sign };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/storage/cloudinary/index.ts
|
|
21
|
+
var cloudinary_exports = {};
|
|
22
|
+
__export(cloudinary_exports, {
|
|
23
|
+
cloudinaryStorage: () => cloudinaryStorage
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(cloudinary_exports);
|
|
26
|
+
function cloudinaryStorage(config = {}) {
|
|
27
|
+
var _a, _b;
|
|
28
|
+
const folder = (_a = config.folder) != null ? _a : "uploads";
|
|
29
|
+
const signEndpoint = (_b = config.signEndpoint) != null ? _b : "/api/admin/sign";
|
|
30
|
+
return {
|
|
31
|
+
async upload(file) {
|
|
32
|
+
const signRes = await fetch(signEndpoint, { method: "POST" });
|
|
33
|
+
if (!signRes.ok) throw new Error("Failed to get upload signature");
|
|
34
|
+
const { timestamp, signature, cloudName, apiKey } = await signRes.json();
|
|
35
|
+
const formData = new FormData();
|
|
36
|
+
formData.append("file", file);
|
|
37
|
+
formData.append("api_key", apiKey);
|
|
38
|
+
formData.append("timestamp", String(timestamp));
|
|
39
|
+
formData.append("signature", signature);
|
|
40
|
+
formData.append("folder", folder);
|
|
41
|
+
const uploadRes = await fetch(
|
|
42
|
+
`https://api.cloudinary.com/v1_1/${cloudName}/auto/upload`,
|
|
43
|
+
{ method: "POST", body: formData }
|
|
44
|
+
);
|
|
45
|
+
if (!uploadRes.ok) throw new Error("Cloudinary upload failed");
|
|
46
|
+
const data = await uploadRes.json();
|
|
47
|
+
return { url: data.secure_url };
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
52
|
+
0 && (module.exports = {
|
|
53
|
+
cloudinaryStorage
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/storage/cloudinary/index.ts"],"sourcesContent":["import type { ClientStorageAdapter } from \"../../types\";\n\nexport interface CloudinaryClientConfig {\n /** Upload folder. Must match the folder the server signs. Default `uploads`. */\n folder?: string;\n /** Endpoint that returns a signature. Default `/api/admin/sign`. */\n signEndpoint?: string;\n}\n\n/**\n * Cloudinary client storage: fetches a signature from the server, then posts the\n * file straight to Cloudinary. Pure `fetch` — no server dependencies, safe in\n * client components. The matching server signer lives at\n * `@dalgoridim/headless-cms/storage/cloudinary/server`.\n */\nexport function cloudinaryStorage(\n config: CloudinaryClientConfig = {},\n): ClientStorageAdapter {\n const folder = config.folder ?? \"uploads\";\n const signEndpoint = config.signEndpoint ?? \"/api/admin/sign\";\n\n return {\n async upload(file: File) {\n const signRes = await fetch(signEndpoint, { method: \"POST\" });\n if (!signRes.ok) throw new Error(\"Failed to get upload signature\");\n const { timestamp, signature, cloudName, apiKey } = await signRes.json();\n\n const formData = new FormData();\n formData.append(\"file\", file);\n formData.append(\"api_key\", apiKey);\n formData.append(\"timestamp\", String(timestamp));\n formData.append(\"signature\", signature);\n formData.append(\"folder\", folder);\n\n const uploadRes = await fetch(\n `https://api.cloudinary.com/v1_1/${cloudName}/auto/upload`,\n { method: \"POST\", body: formData },\n );\n if (!uploadRes.ok) throw new Error(\"Cloudinary upload failed\");\n const data = await uploadRes.json();\n return { url: data.secure_url as string };\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAeO,SAAS,kBACd,SAAiC,CAAC,GACZ;AAjBxB;AAkBE,QAAM,UAAS,YAAO,WAAP,YAAiB;AAChC,QAAM,gBAAe,YAAO,iBAAP,YAAuB;AAE5C,SAAO;AAAA,IACL,MAAM,OAAO,MAAY;AACvB,YAAM,UAAU,MAAM,MAAM,cAAc,EAAE,QAAQ,OAAO,CAAC;AAC5D,UAAI,CAAC,QAAQ,GAAI,OAAM,IAAI,MAAM,gCAAgC;AACjE,YAAM,EAAE,WAAW,WAAW,WAAW,OAAO,IAAI,MAAM,QAAQ,KAAK;AAEvE,YAAM,WAAW,IAAI,SAAS;AAC9B,eAAS,OAAO,QAAQ,IAAI;AAC5B,eAAS,OAAO,WAAW,MAAM;AACjC,eAAS,OAAO,aAAa,OAAO,SAAS,CAAC;AAC9C,eAAS,OAAO,aAAa,SAAS;AACtC,eAAS,OAAO,UAAU,MAAM;AAEhC,YAAM,YAAY,MAAM;AAAA,QACtB,mCAAmC,SAAS;AAAA,QAC5C,EAAE,QAAQ,QAAQ,MAAM,SAAS;AAAA,MACnC;AACA,UAAI,CAAC,UAAU,GAAI,OAAM,IAAI,MAAM,0BAA0B;AAC7D,YAAM,OAAO,MAAM,UAAU,KAAK;AAClC,aAAO,EAAE,KAAK,KAAK,WAAqB;AAAA,IAC1C;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ClientStorageAdapter } from '../../index.cjs';
|
|
2
|
+
|
|
3
|
+
interface CloudinaryClientConfig {
|
|
4
|
+
/** Upload folder. Must match the folder the server signs. Default `uploads`. */
|
|
5
|
+
folder?: string;
|
|
6
|
+
/** Endpoint that returns a signature. Default `/api/admin/sign`. */
|
|
7
|
+
signEndpoint?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Cloudinary client storage: fetches a signature from the server, then posts the
|
|
11
|
+
* file straight to Cloudinary. Pure `fetch` — no server dependencies, safe in
|
|
12
|
+
* client components. The matching server signer lives at
|
|
13
|
+
* `@dalgoridim/headless-cms/storage/cloudinary/server`.
|
|
14
|
+
*/
|
|
15
|
+
declare function cloudinaryStorage(config?: CloudinaryClientConfig): ClientStorageAdapter;
|
|
16
|
+
|
|
17
|
+
export { type CloudinaryClientConfig, cloudinaryStorage };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ClientStorageAdapter } from '../../index.js';
|
|
2
|
+
|
|
3
|
+
interface CloudinaryClientConfig {
|
|
4
|
+
/** Upload folder. Must match the folder the server signs. Default `uploads`. */
|
|
5
|
+
folder?: string;
|
|
6
|
+
/** Endpoint that returns a signature. Default `/api/admin/sign`. */
|
|
7
|
+
signEndpoint?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Cloudinary client storage: fetches a signature from the server, then posts the
|
|
11
|
+
* file straight to Cloudinary. Pure `fetch` — no server dependencies, safe in
|
|
12
|
+
* client components. The matching server signer lives at
|
|
13
|
+
* `@dalgoridim/headless-cms/storage/cloudinary/server`.
|
|
14
|
+
*/
|
|
15
|
+
declare function cloudinaryStorage(config?: CloudinaryClientConfig): ClientStorageAdapter;
|
|
16
|
+
|
|
17
|
+
export { type CloudinaryClientConfig, cloudinaryStorage };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// src/storage/cloudinary/index.ts
|
|
2
|
+
function cloudinaryStorage(config = {}) {
|
|
3
|
+
var _a, _b;
|
|
4
|
+
const folder = (_a = config.folder) != null ? _a : "uploads";
|
|
5
|
+
const signEndpoint = (_b = config.signEndpoint) != null ? _b : "/api/admin/sign";
|
|
6
|
+
return {
|
|
7
|
+
async upload(file) {
|
|
8
|
+
const signRes = await fetch(signEndpoint, { method: "POST" });
|
|
9
|
+
if (!signRes.ok) throw new Error("Failed to get upload signature");
|
|
10
|
+
const { timestamp, signature, cloudName, apiKey } = await signRes.json();
|
|
11
|
+
const formData = new FormData();
|
|
12
|
+
formData.append("file", file);
|
|
13
|
+
formData.append("api_key", apiKey);
|
|
14
|
+
formData.append("timestamp", String(timestamp));
|
|
15
|
+
formData.append("signature", signature);
|
|
16
|
+
formData.append("folder", folder);
|
|
17
|
+
const uploadRes = await fetch(
|
|
18
|
+
`https://api.cloudinary.com/v1_1/${cloudName}/auto/upload`,
|
|
19
|
+
{ method: "POST", body: formData }
|
|
20
|
+
);
|
|
21
|
+
if (!uploadRes.ok) throw new Error("Cloudinary upload failed");
|
|
22
|
+
const data = await uploadRes.json();
|
|
23
|
+
return { url: data.secure_url };
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export {
|
|
28
|
+
cloudinaryStorage
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/storage/cloudinary/index.ts"],"sourcesContent":["import type { ClientStorageAdapter } from \"../../types\";\n\nexport interface CloudinaryClientConfig {\n /** Upload folder. Must match the folder the server signs. Default `uploads`. */\n folder?: string;\n /** Endpoint that returns a signature. Default `/api/admin/sign`. */\n signEndpoint?: string;\n}\n\n/**\n * Cloudinary client storage: fetches a signature from the server, then posts the\n * file straight to Cloudinary. Pure `fetch` — no server dependencies, safe in\n * client components. The matching server signer lives at\n * `@dalgoridim/headless-cms/storage/cloudinary/server`.\n */\nexport function cloudinaryStorage(\n config: CloudinaryClientConfig = {},\n): ClientStorageAdapter {\n const folder = config.folder ?? \"uploads\";\n const signEndpoint = config.signEndpoint ?? \"/api/admin/sign\";\n\n return {\n async upload(file: File) {\n const signRes = await fetch(signEndpoint, { method: \"POST\" });\n if (!signRes.ok) throw new Error(\"Failed to get upload signature\");\n const { timestamp, signature, cloudName, apiKey } = await signRes.json();\n\n const formData = new FormData();\n formData.append(\"file\", file);\n formData.append(\"api_key\", apiKey);\n formData.append(\"timestamp\", String(timestamp));\n formData.append(\"signature\", signature);\n formData.append(\"folder\", folder);\n\n const uploadRes = await fetch(\n `https://api.cloudinary.com/v1_1/${cloudName}/auto/upload`,\n { method: \"POST\", body: formData },\n );\n if (!uploadRes.ok) throw new Error(\"Cloudinary upload failed\");\n const data = await uploadRes.json();\n return { url: data.secure_url as string };\n },\n };\n}\n"],"mappings":";AAeO,SAAS,kBACd,SAAiC,CAAC,GACZ;AAjBxB;AAkBE,QAAM,UAAS,YAAO,WAAP,YAAiB;AAChC,QAAM,gBAAe,YAAO,iBAAP,YAAuB;AAE5C,SAAO;AAAA,IACL,MAAM,OAAO,MAAY;AACvB,YAAM,UAAU,MAAM,MAAM,cAAc,EAAE,QAAQ,OAAO,CAAC;AAC5D,UAAI,CAAC,QAAQ,GAAI,OAAM,IAAI,MAAM,gCAAgC;AACjE,YAAM,EAAE,WAAW,WAAW,WAAW,OAAO,IAAI,MAAM,QAAQ,KAAK;AAEvE,YAAM,WAAW,IAAI,SAAS;AAC9B,eAAS,OAAO,QAAQ,IAAI;AAC5B,eAAS,OAAO,WAAW,MAAM;AACjC,eAAS,OAAO,aAAa,OAAO,SAAS,CAAC;AAC9C,eAAS,OAAO,aAAa,SAAS;AACtC,eAAS,OAAO,UAAU,MAAM;AAEhC,YAAM,YAAY,MAAM;AAAA,QACtB,mCAAmC,SAAS;AAAA,QAC5C,EAAE,QAAQ,QAAQ,MAAM,SAAS;AAAA,MACnC;AACA,UAAI,CAAC,UAAU,GAAI,OAAM,IAAI,MAAM,0BAA0B;AAC7D,YAAM,OAAO,MAAM,UAAU,KAAK;AAClC,aAAO,EAAE,KAAK,KAAK,WAAqB;AAAA,IAC1C;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/storage/cloudinary/server.ts
|
|
21
|
+
var server_exports = {};
|
|
22
|
+
__export(server_exports, {
|
|
23
|
+
cloudinarySign: () => cloudinarySign
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(server_exports);
|
|
26
|
+
var import_cloudinary = require("cloudinary");
|
|
27
|
+
function cloudinarySign(config = {}) {
|
|
28
|
+
var _a;
|
|
29
|
+
const folder = (_a = config.folder) != null ? _a : "uploads";
|
|
30
|
+
return {
|
|
31
|
+
async sign() {
|
|
32
|
+
import_cloudinary.v2.config({
|
|
33
|
+
cloud_name: config.cloudName,
|
|
34
|
+
api_key: config.apiKey,
|
|
35
|
+
api_secret: config.apiSecret
|
|
36
|
+
});
|
|
37
|
+
const timestamp = Math.floor(Date.now() / 1e3);
|
|
38
|
+
const signature = import_cloudinary.v2.utils.api_sign_request(
|
|
39
|
+
{ timestamp, folder },
|
|
40
|
+
config.apiSecret
|
|
41
|
+
);
|
|
42
|
+
return {
|
|
43
|
+
timestamp,
|
|
44
|
+
signature,
|
|
45
|
+
folder,
|
|
46
|
+
cloudName: config.cloudName,
|
|
47
|
+
apiKey: config.apiKey
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
53
|
+
0 && (module.exports = {
|
|
54
|
+
cloudinarySign
|
|
55
|
+
});
|
|
56
|
+
//# sourceMappingURL=server.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/storage/cloudinary/server.ts"],"sourcesContent":["import { v2 as cloudinary } from \"cloudinary\";\nimport type { ServerStorageAdapter } from \"../../types\";\n\nexport interface CloudinaryServerConfig {\n cloudName?: string;\n apiKey?: string;\n apiSecret?: string;\n /** Upload folder. Must match the client's folder. Default `uploads`. */\n folder?: string;\n}\n\n/**\n * Cloudinary server signer. Mount its `sign` via `createCmsHandlers`. Imports the\n * Cloudinary SDK statically, so only ever import this from server code.\n */\nexport function cloudinarySign(\n config: CloudinaryServerConfig = {},\n): ServerStorageAdapter {\n const folder = config.folder ?? \"uploads\";\n\n return {\n async sign() {\n cloudinary.config({\n cloud_name: config.cloudName,\n api_key: config.apiKey,\n api_secret: config.apiSecret,\n });\n const timestamp = Math.floor(Date.now() / 1000);\n const signature = cloudinary.utils.api_sign_request(\n { timestamp, folder },\n config.apiSecret!,\n );\n return {\n timestamp,\n signature,\n folder,\n cloudName: config.cloudName,\n apiKey: config.apiKey,\n };\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAAiC;AAe1B,SAAS,eACd,SAAiC,CAAC,GACZ;AAjBxB;AAkBE,QAAM,UAAS,YAAO,WAAP,YAAiB;AAEhC,SAAO;AAAA,IACL,MAAM,OAAO;AACX,wBAAAA,GAAW,OAAO;AAAA,QAChB,YAAY,OAAO;AAAA,QACnB,SAAS,OAAO;AAAA,QAChB,YAAY,OAAO;AAAA,MACrB,CAAC;AACD,YAAM,YAAY,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAC9C,YAAM,YAAY,kBAAAA,GAAW,MAAM;AAAA,QACjC,EAAE,WAAW,OAAO;AAAA,QACpB,OAAO;AAAA,MACT;AACA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW,OAAO;AAAA,QAClB,QAAQ,OAAO;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACF;","names":["cloudinary"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ServerStorageAdapter } from '../../index.cjs';
|
|
2
|
+
|
|
3
|
+
interface CloudinaryServerConfig {
|
|
4
|
+
cloudName?: string;
|
|
5
|
+
apiKey?: string;
|
|
6
|
+
apiSecret?: string;
|
|
7
|
+
/** Upload folder. Must match the client's folder. Default `uploads`. */
|
|
8
|
+
folder?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Cloudinary server signer. Mount its `sign` via `createCmsHandlers`. Imports the
|
|
12
|
+
* Cloudinary SDK statically, so only ever import this from server code.
|
|
13
|
+
*/
|
|
14
|
+
declare function cloudinarySign(config?: CloudinaryServerConfig): ServerStorageAdapter;
|
|
15
|
+
|
|
16
|
+
export { type CloudinaryServerConfig, cloudinarySign };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ServerStorageAdapter } from '../../index.js';
|
|
2
|
+
|
|
3
|
+
interface CloudinaryServerConfig {
|
|
4
|
+
cloudName?: string;
|
|
5
|
+
apiKey?: string;
|
|
6
|
+
apiSecret?: string;
|
|
7
|
+
/** Upload folder. Must match the client's folder. Default `uploads`. */
|
|
8
|
+
folder?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Cloudinary server signer. Mount its `sign` via `createCmsHandlers`. Imports the
|
|
12
|
+
* Cloudinary SDK statically, so only ever import this from server code.
|
|
13
|
+
*/
|
|
14
|
+
declare function cloudinarySign(config?: CloudinaryServerConfig): ServerStorageAdapter;
|
|
15
|
+
|
|
16
|
+
export { type CloudinaryServerConfig, cloudinarySign };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// src/storage/cloudinary/server.ts
|
|
2
|
+
import { v2 as cloudinary } from "cloudinary";
|
|
3
|
+
function cloudinarySign(config = {}) {
|
|
4
|
+
var _a;
|
|
5
|
+
const folder = (_a = config.folder) != null ? _a : "uploads";
|
|
6
|
+
return {
|
|
7
|
+
async sign() {
|
|
8
|
+
cloudinary.config({
|
|
9
|
+
cloud_name: config.cloudName,
|
|
10
|
+
api_key: config.apiKey,
|
|
11
|
+
api_secret: config.apiSecret
|
|
12
|
+
});
|
|
13
|
+
const timestamp = Math.floor(Date.now() / 1e3);
|
|
14
|
+
const signature = cloudinary.utils.api_sign_request(
|
|
15
|
+
{ timestamp, folder },
|
|
16
|
+
config.apiSecret
|
|
17
|
+
);
|
|
18
|
+
return {
|
|
19
|
+
timestamp,
|
|
20
|
+
signature,
|
|
21
|
+
folder,
|
|
22
|
+
cloudName: config.cloudName,
|
|
23
|
+
apiKey: config.apiKey
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
cloudinarySign
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/storage/cloudinary/server.ts"],"sourcesContent":["import { v2 as cloudinary } from \"cloudinary\";\nimport type { ServerStorageAdapter } from \"../../types\";\n\nexport interface CloudinaryServerConfig {\n cloudName?: string;\n apiKey?: string;\n apiSecret?: string;\n /** Upload folder. Must match the client's folder. Default `uploads`. */\n folder?: string;\n}\n\n/**\n * Cloudinary server signer. Mount its `sign` via `createCmsHandlers`. Imports the\n * Cloudinary SDK statically, so only ever import this from server code.\n */\nexport function cloudinarySign(\n config: CloudinaryServerConfig = {},\n): ServerStorageAdapter {\n const folder = config.folder ?? \"uploads\";\n\n return {\n async sign() {\n cloudinary.config({\n cloud_name: config.cloudName,\n api_key: config.apiKey,\n api_secret: config.apiSecret,\n });\n const timestamp = Math.floor(Date.now() / 1000);\n const signature = cloudinary.utils.api_sign_request(\n { timestamp, folder },\n config.apiSecret!,\n );\n return {\n timestamp,\n signature,\n folder,\n cloudName: config.cloudName,\n apiKey: config.apiKey,\n };\n },\n };\n}\n"],"mappings":";AAAA,SAAS,MAAM,kBAAkB;AAe1B,SAAS,eACd,SAAiC,CAAC,GACZ;AAjBxB;AAkBE,QAAM,UAAS,YAAO,WAAP,YAAiB;AAEhC,SAAO;AAAA,IACL,MAAM,OAAO;AACX,iBAAW,OAAO;AAAA,QAChB,YAAY,OAAO;AAAA,QACnB,SAAS,OAAO;AAAA,QAChB,YAAY,OAAO;AAAA,MACrB,CAAC;AACD,YAAM,YAAY,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AAC9C,YAAM,YAAY,WAAW,MAAM;AAAA,QACjC,EAAE,WAAW,OAAO;AAAA,QACpB,OAAO;AAAA,MACT;AACA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW,OAAO;AAAA,QAClB,QAAQ,OAAO;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/storage/local/index.ts
|
|
21
|
+
var local_exports = {};
|
|
22
|
+
__export(local_exports, {
|
|
23
|
+
localStorage: () => localStorage
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(local_exports);
|
|
26
|
+
function localStorage(config = {}) {
|
|
27
|
+
var _a;
|
|
28
|
+
const signEndpoint = (_a = config.signEndpoint) != null ? _a : "/api/admin/sign";
|
|
29
|
+
return {
|
|
30
|
+
async upload(file) {
|
|
31
|
+
const formData = new FormData();
|
|
32
|
+
formData.append("file", file);
|
|
33
|
+
const res = await fetch(signEndpoint, { method: "POST", body: formData });
|
|
34
|
+
if (!res.ok) throw new Error("Local upload failed");
|
|
35
|
+
const { url } = await res.json();
|
|
36
|
+
return { url };
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
41
|
+
0 && (module.exports = {
|
|
42
|
+
localStorage
|
|
43
|
+
});
|
|
44
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/storage/local/index.ts"],"sourcesContent":["import type { ClientStorageAdapter } from \"../../types\";\n\nexport interface LocalClientConfig {\n /** Endpoint that accepts the upload. Default `/api/admin/sign`. */\n signEndpoint?: string;\n}\n\n/**\n * Local-filesystem client storage: posts the file to the server, which writes it\n * to disk and returns the public URL. Pure `fetch` — safe in client components.\n * The matching server handler lives at\n * `@dalgoridim/headless-cms/storage/local/server`.\n */\nexport function localStorage(\n config: LocalClientConfig = {},\n): ClientStorageAdapter {\n const signEndpoint = config.signEndpoint ?? \"/api/admin/sign\";\n\n return {\n async upload(file: File) {\n const formData = new FormData();\n formData.append(\"file\", file);\n const res = await fetch(signEndpoint, { method: \"POST\", body: formData });\n if (!res.ok) throw new Error(\"Local upload failed\");\n const { url } = await res.json();\n return { url: url as string };\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAaO,SAAS,aACd,SAA4B,CAAC,GACP;AAfxB;AAgBE,QAAM,gBAAe,YAAO,iBAAP,YAAuB;AAE5C,SAAO;AAAA,IACL,MAAM,OAAO,MAAY;AACvB,YAAM,WAAW,IAAI,SAAS;AAC9B,eAAS,OAAO,QAAQ,IAAI;AAC5B,YAAM,MAAM,MAAM,MAAM,cAAc,EAAE,QAAQ,QAAQ,MAAM,SAAS,CAAC;AACxE,UAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,qBAAqB;AAClD,YAAM,EAAE,IAAI,IAAI,MAAM,IAAI,KAAK;AAC/B,aAAO,EAAE,IAAmB;AAAA,IAC9B;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ClientStorageAdapter } from '../../index.cjs';
|
|
2
|
+
|
|
3
|
+
interface LocalClientConfig {
|
|
4
|
+
/** Endpoint that accepts the upload. Default `/api/admin/sign`. */
|
|
5
|
+
signEndpoint?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Local-filesystem client storage: posts the file to the server, which writes it
|
|
9
|
+
* to disk and returns the public URL. Pure `fetch` — safe in client components.
|
|
10
|
+
* The matching server handler lives at
|
|
11
|
+
* `@dalgoridim/headless-cms/storage/local/server`.
|
|
12
|
+
*/
|
|
13
|
+
declare function localStorage(config?: LocalClientConfig): ClientStorageAdapter;
|
|
14
|
+
|
|
15
|
+
export { type LocalClientConfig, localStorage };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ClientStorageAdapter } from '../../index.js';
|
|
2
|
+
|
|
3
|
+
interface LocalClientConfig {
|
|
4
|
+
/** Endpoint that accepts the upload. Default `/api/admin/sign`. */
|
|
5
|
+
signEndpoint?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Local-filesystem client storage: posts the file to the server, which writes it
|
|
9
|
+
* to disk and returns the public URL. Pure `fetch` — safe in client components.
|
|
10
|
+
* The matching server handler lives at
|
|
11
|
+
* `@dalgoridim/headless-cms/storage/local/server`.
|
|
12
|
+
*/
|
|
13
|
+
declare function localStorage(config?: LocalClientConfig): ClientStorageAdapter;
|
|
14
|
+
|
|
15
|
+
export { type LocalClientConfig, localStorage };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// src/storage/local/index.ts
|
|
2
|
+
function localStorage(config = {}) {
|
|
3
|
+
var _a;
|
|
4
|
+
const signEndpoint = (_a = config.signEndpoint) != null ? _a : "/api/admin/sign";
|
|
5
|
+
return {
|
|
6
|
+
async upload(file) {
|
|
7
|
+
const formData = new FormData();
|
|
8
|
+
formData.append("file", file);
|
|
9
|
+
const res = await fetch(signEndpoint, { method: "POST", body: formData });
|
|
10
|
+
if (!res.ok) throw new Error("Local upload failed");
|
|
11
|
+
const { url } = await res.json();
|
|
12
|
+
return { url };
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export {
|
|
17
|
+
localStorage
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/storage/local/index.ts"],"sourcesContent":["import type { ClientStorageAdapter } from \"../../types\";\n\nexport interface LocalClientConfig {\n /** Endpoint that accepts the upload. Default `/api/admin/sign`. */\n signEndpoint?: string;\n}\n\n/**\n * Local-filesystem client storage: posts the file to the server, which writes it\n * to disk and returns the public URL. Pure `fetch` — safe in client components.\n * The matching server handler lives at\n * `@dalgoridim/headless-cms/storage/local/server`.\n */\nexport function localStorage(\n config: LocalClientConfig = {},\n): ClientStorageAdapter {\n const signEndpoint = config.signEndpoint ?? \"/api/admin/sign\";\n\n return {\n async upload(file: File) {\n const formData = new FormData();\n formData.append(\"file\", file);\n const res = await fetch(signEndpoint, { method: \"POST\", body: formData });\n if (!res.ok) throw new Error(\"Local upload failed\");\n const { url } = await res.json();\n return { url: url as string };\n },\n };\n}\n"],"mappings":";AAaO,SAAS,aACd,SAA4B,CAAC,GACP;AAfxB;AAgBE,QAAM,gBAAe,YAAO,iBAAP,YAAuB;AAE5C,SAAO;AAAA,IACL,MAAM,OAAO,MAAY;AACvB,YAAM,WAAW,IAAI,SAAS;AAC9B,eAAS,OAAO,QAAQ,IAAI;AAC5B,YAAM,MAAM,MAAM,MAAM,cAAc,EAAE,QAAQ,QAAQ,MAAM,SAAS,CAAC;AACxE,UAAI,CAAC,IAAI,GAAI,OAAM,IAAI,MAAM,qBAAqB;AAClD,YAAM,EAAE,IAAI,IAAI,MAAM,IAAI,KAAK;AAC/B,aAAO,EAAE,IAAmB;AAAA,IAC9B;AAAA,EACF;AACF;","names":[]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/storage/local/server.ts
|
|
31
|
+
var server_exports = {};
|
|
32
|
+
__export(server_exports, {
|
|
33
|
+
localSign: () => localSign
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(server_exports);
|
|
36
|
+
var import_promises = require("fs/promises");
|
|
37
|
+
var import_node_path = __toESM(require("path"), 1);
|
|
38
|
+
function localSign(config = {}) {
|
|
39
|
+
var _a, _b;
|
|
40
|
+
const uploadDir = (_a = config.uploadDir) != null ? _a : "public/uploads";
|
|
41
|
+
const publicPath = ((_b = config.publicPath) != null ? _b : "/uploads").replace(/\/$/, "");
|
|
42
|
+
return {
|
|
43
|
+
async sign(req) {
|
|
44
|
+
const form = await req.formData();
|
|
45
|
+
const file = form.get("file");
|
|
46
|
+
if (!(file instanceof File)) throw new Error("No file provided");
|
|
47
|
+
const safeName = file.name.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
48
|
+
const fileName = `${Date.now()}-${safeName}`;
|
|
49
|
+
const absDir = import_node_path.default.resolve(process.cwd(), uploadDir);
|
|
50
|
+
await (0, import_promises.mkdir)(absDir, { recursive: true });
|
|
51
|
+
const buffer = Buffer.from(await file.arrayBuffer());
|
|
52
|
+
await (0, import_promises.writeFile)(import_node_path.default.join(absDir, fileName), buffer);
|
|
53
|
+
return { url: `${publicPath}/${fileName}` };
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
58
|
+
0 && (module.exports = {
|
|
59
|
+
localSign
|
|
60
|
+
});
|
|
61
|
+
//# sourceMappingURL=server.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/storage/local/server.ts"],"sourcesContent":["import { mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { ServerStorageAdapter } from \"../../types\";\n\nexport interface LocalServerConfig {\n /** Directory to write uploads into. Default `public/uploads`. */\n uploadDir?: string;\n /** Public URL path the directory is served from. Default `/uploads`. */\n publicPath?: string;\n}\n\n/**\n * Local-filesystem server handler: receives the multipart file, writes it to\n * disk, and returns its public URL. Mount its `sign` via `createCmsHandlers`.\n * Server-only (uses Node `fs`).\n */\nexport function localSign(config: LocalServerConfig = {}): ServerStorageAdapter {\n const uploadDir = config.uploadDir ?? \"public/uploads\";\n const publicPath = (config.publicPath ?? \"/uploads\").replace(/\\/$/, \"\");\n\n return {\n async sign(req: Request) {\n const form = await req.formData();\n const file = form.get(\"file\");\n if (!(file instanceof File)) throw new Error(\"No file provided\");\n\n const safeName = file.name.replace(/[^a-zA-Z0-9._-]/g, \"_\");\n const fileName = `${Date.now()}-${safeName}`;\n const absDir = path.resolve(process.cwd(), uploadDir);\n await mkdir(absDir, { recursive: true });\n\n const buffer = Buffer.from(await file.arrayBuffer());\n await writeFile(path.join(absDir, fileName), buffer);\n\n return { url: `${publicPath}/${fileName}` };\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAiC;AACjC,uBAAiB;AAeV,SAAS,UAAU,SAA4B,CAAC,GAAyB;AAhBhF;AAiBE,QAAM,aAAY,YAAO,cAAP,YAAoB;AACtC,QAAM,eAAc,YAAO,eAAP,YAAqB,YAAY,QAAQ,OAAO,EAAE;AAEtE,SAAO;AAAA,IACL,MAAM,KAAK,KAAc;AACvB,YAAM,OAAO,MAAM,IAAI,SAAS;AAChC,YAAM,OAAO,KAAK,IAAI,MAAM;AAC5B,UAAI,EAAE,gBAAgB,MAAO,OAAM,IAAI,MAAM,kBAAkB;AAE/D,YAAM,WAAW,KAAK,KAAK,QAAQ,oBAAoB,GAAG;AAC1D,YAAM,WAAW,GAAG,KAAK,IAAI,CAAC,IAAI,QAAQ;AAC1C,YAAM,SAAS,iBAAAA,QAAK,QAAQ,QAAQ,IAAI,GAAG,SAAS;AACpD,gBAAM,uBAAM,QAAQ,EAAE,WAAW,KAAK,CAAC;AAEvC,YAAM,SAAS,OAAO,KAAK,MAAM,KAAK,YAAY,CAAC;AACnD,gBAAM,2BAAU,iBAAAA,QAAK,KAAK,QAAQ,QAAQ,GAAG,MAAM;AAEnD,aAAO,EAAE,KAAK,GAAG,UAAU,IAAI,QAAQ,GAAG;AAAA,IAC5C;AAAA,EACF;AACF;","names":["path"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ServerStorageAdapter } from '../../index.cjs';
|
|
2
|
+
|
|
3
|
+
interface LocalServerConfig {
|
|
4
|
+
/** Directory to write uploads into. Default `public/uploads`. */
|
|
5
|
+
uploadDir?: string;
|
|
6
|
+
/** Public URL path the directory is served from. Default `/uploads`. */
|
|
7
|
+
publicPath?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Local-filesystem server handler: receives the multipart file, writes it to
|
|
11
|
+
* disk, and returns its public URL. Mount its `sign` via `createCmsHandlers`.
|
|
12
|
+
* Server-only (uses Node `fs`).
|
|
13
|
+
*/
|
|
14
|
+
declare function localSign(config?: LocalServerConfig): ServerStorageAdapter;
|
|
15
|
+
|
|
16
|
+
export { type LocalServerConfig, localSign };
|