@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.
Files changed (87) hide show
  1. package/LICENSE +10 -0
  2. package/README.md +178 -0
  3. package/dist/adapters/firestore/index.cjs +152 -0
  4. package/dist/adapters/firestore/index.cjs.map +1 -0
  5. package/dist/adapters/firestore/index.d.cts +39 -0
  6. package/dist/adapters/firestore/index.d.ts +39 -0
  7. package/dist/adapters/firestore/index.js +120 -0
  8. package/dist/adapters/firestore/index.js.map +1 -0
  9. package/dist/adapters/postgres/index.cjs +299 -0
  10. package/dist/adapters/postgres/index.cjs.map +1 -0
  11. package/dist/adapters/postgres/index.d.cts +59 -0
  12. package/dist/adapters/postgres/index.d.ts +59 -0
  13. package/dist/adapters/postgres/index.js +277 -0
  14. package/dist/adapters/postgres/index.js.map +1 -0
  15. package/dist/auth/firebase/client/index.cjs +153 -0
  16. package/dist/auth/firebase/client/index.cjs.map +1 -0
  17. package/dist/auth/firebase/client/index.d.cts +29 -0
  18. package/dist/auth/firebase/client/index.d.ts +29 -0
  19. package/dist/auth/firebase/client/index.js +138 -0
  20. package/dist/auth/firebase/client/index.js.map +1 -0
  21. package/dist/auth/firebase/index.cjs +81 -0
  22. package/dist/auth/firebase/index.cjs.map +1 -0
  23. package/dist/auth/firebase/index.d.cts +23 -0
  24. package/dist/auth/firebase/index.d.ts +23 -0
  25. package/dist/auth/firebase/index.js +46 -0
  26. package/dist/auth/firebase/index.js.map +1 -0
  27. package/dist/auth/nextauth/index.cjs +51 -0
  28. package/dist/auth/nextauth/index.cjs.map +1 -0
  29. package/dist/auth/nextauth/index.d.cts +30 -0
  30. package/dist/auth/nextauth/index.d.ts +30 -0
  31. package/dist/auth/nextauth/index.js +25 -0
  32. package/dist/auth/nextauth/index.js.map +1 -0
  33. package/dist/client/index.cjs +1018 -0
  34. package/dist/client/index.cjs.map +1 -0
  35. package/dist/client/index.d.cts +96 -0
  36. package/dist/client/index.d.ts +96 -0
  37. package/dist/client/index.js +994 -0
  38. package/dist/client/index.js.map +1 -0
  39. package/dist/index.cjs +19 -0
  40. package/dist/index.cjs.map +1 -0
  41. package/dist/index.d.cts +122 -0
  42. package/dist/index.d.ts +122 -0
  43. package/dist/index.js +1 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/server/index.cjs +128 -0
  46. package/dist/server/index.cjs.map +1 -0
  47. package/dist/server/index.d.cts +52 -0
  48. package/dist/server/index.d.ts +52 -0
  49. package/dist/server/index.js +99 -0
  50. package/dist/server/index.js.map +1 -0
  51. package/dist/storage/cloudinary/index.cjs +55 -0
  52. package/dist/storage/cloudinary/index.cjs.map +1 -0
  53. package/dist/storage/cloudinary/index.d.cts +17 -0
  54. package/dist/storage/cloudinary/index.d.ts +17 -0
  55. package/dist/storage/cloudinary/index.js +30 -0
  56. package/dist/storage/cloudinary/index.js.map +1 -0
  57. package/dist/storage/cloudinary/server.cjs +56 -0
  58. package/dist/storage/cloudinary/server.cjs.map +1 -0
  59. package/dist/storage/cloudinary/server.d.cts +16 -0
  60. package/dist/storage/cloudinary/server.d.ts +16 -0
  61. package/dist/storage/cloudinary/server.js +31 -0
  62. package/dist/storage/cloudinary/server.js.map +1 -0
  63. package/dist/storage/local/index.cjs +44 -0
  64. package/dist/storage/local/index.cjs.map +1 -0
  65. package/dist/storage/local/index.d.cts +15 -0
  66. package/dist/storage/local/index.d.ts +15 -0
  67. package/dist/storage/local/index.js +19 -0
  68. package/dist/storage/local/index.js.map +1 -0
  69. package/dist/storage/local/server.cjs +61 -0
  70. package/dist/storage/local/server.cjs.map +1 -0
  71. package/dist/storage/local/server.d.cts +16 -0
  72. package/dist/storage/local/server.d.ts +16 -0
  73. package/dist/storage/local/server.js +26 -0
  74. package/dist/storage/local/server.js.map +1 -0
  75. package/dist/storage/s3/index.cjs +52 -0
  76. package/dist/storage/s3/index.cjs.map +1 -0
  77. package/dist/storage/s3/index.d.cts +14 -0
  78. package/dist/storage/s3/index.d.ts +14 -0
  79. package/dist/storage/s3/index.js +27 -0
  80. package/dist/storage/s3/index.js.map +1 -0
  81. package/dist/storage/s3/server.cjs +61 -0
  82. package/dist/storage/s3/server.cjs.map +1 -0
  83. package/dist/storage/s3/server.d.cts +19 -0
  84. package/dist/storage/s3/server.d.ts +19 -0
  85. package/dist/storage/s3/server.js +36 -0
  86. package/dist/storage/s3/server.js.map +1 -0
  87. package/package.json +165 -0
@@ -0,0 +1,16 @@
1
+ import { ServerStorageAdapter } from '../../index.js';
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 };
@@ -0,0 +1,26 @@
1
+ // src/storage/local/server.ts
2
+ import { mkdir, writeFile } from "fs/promises";
3
+ import path from "path";
4
+ function localSign(config = {}) {
5
+ var _a, _b;
6
+ const uploadDir = (_a = config.uploadDir) != null ? _a : "public/uploads";
7
+ const publicPath = ((_b = config.publicPath) != null ? _b : "/uploads").replace(/\/$/, "");
8
+ return {
9
+ async sign(req) {
10
+ const form = await req.formData();
11
+ const file = form.get("file");
12
+ if (!(file instanceof File)) throw new Error("No file provided");
13
+ const safeName = file.name.replace(/[^a-zA-Z0-9._-]/g, "_");
14
+ const fileName = `${Date.now()}-${safeName}`;
15
+ const absDir = path.resolve(process.cwd(), uploadDir);
16
+ await mkdir(absDir, { recursive: true });
17
+ const buffer = Buffer.from(await file.arrayBuffer());
18
+ await writeFile(path.join(absDir, fileName), buffer);
19
+ return { url: `${publicPath}/${fileName}` };
20
+ }
21
+ };
22
+ }
23
+ export {
24
+ localSign
25
+ };
26
+ //# sourceMappingURL=server.js.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,SAAS,OAAO,iBAAiB;AACjC,OAAO,UAAU;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,KAAK,QAAQ,QAAQ,IAAI,GAAG,SAAS;AACpD,YAAM,MAAM,QAAQ,EAAE,WAAW,KAAK,CAAC;AAEvC,YAAM,SAAS,OAAO,KAAK,MAAM,KAAK,YAAY,CAAC;AACnD,YAAM,UAAU,KAAK,KAAK,QAAQ,QAAQ,GAAG,MAAM;AAEnD,aAAO,EAAE,KAAK,GAAG,UAAU,IAAI,QAAQ,GAAG;AAAA,IAC5C;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,52 @@
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/s3/index.ts
21
+ var s3_exports = {};
22
+ __export(s3_exports, {
23
+ s3Storage: () => s3Storage
24
+ });
25
+ module.exports = __toCommonJS(s3_exports);
26
+ function s3Storage(config = {}) {
27
+ var _a;
28
+ const signEndpoint = (_a = config.signEndpoint) != null ? _a : "/api/admin/sign";
29
+ return {
30
+ async upload(file) {
31
+ const signRes = await fetch(signEndpoint, {
32
+ method: "POST",
33
+ headers: { "Content-Type": "application/json" },
34
+ body: JSON.stringify({ filename: file.name, contentType: file.type })
35
+ });
36
+ if (!signRes.ok) throw new Error("Failed to get presigned URL");
37
+ const { uploadUrl, publicUrl } = await signRes.json();
38
+ const putRes = await fetch(uploadUrl, {
39
+ method: "PUT",
40
+ headers: { "Content-Type": file.type },
41
+ body: file
42
+ });
43
+ if (!putRes.ok) throw new Error("S3 upload failed");
44
+ return { url: publicUrl };
45
+ }
46
+ };
47
+ }
48
+ // Annotate the CommonJS export names for ESM import in node:
49
+ 0 && (module.exports = {
50
+ s3Storage
51
+ });
52
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/storage/s3/index.ts"],"sourcesContent":["import type { ClientStorageAdapter } from \"../../types\";\n\nexport interface S3ClientConfig {\n /** Endpoint that returns a presigned PUT URL. Default `/api/admin/sign`. */\n signEndpoint?: string;\n}\n\n/**\n * S3 client storage: requests a presigned PUT URL from the server, then PUTs the\n * file directly to S3. Pure `fetch` — safe in client components. The matching\n * server signer lives at `@dalgoridim/headless-cms/storage/s3/server`.\n */\nexport function s3Storage(config: S3ClientConfig = {}): ClientStorageAdapter {\n const signEndpoint = config.signEndpoint ?? \"/api/admin/sign\";\n\n return {\n async upload(file: File) {\n const signRes = await fetch(signEndpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ filename: file.name, contentType: file.type }),\n });\n if (!signRes.ok) throw new Error(\"Failed to get presigned URL\");\n const { uploadUrl, publicUrl } = await signRes.json();\n\n const putRes = await fetch(uploadUrl, {\n method: \"PUT\",\n headers: { \"Content-Type\": file.type },\n body: file,\n });\n if (!putRes.ok) throw new Error(\"S3 upload failed\");\n\n return { url: publicUrl as string };\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAYO,SAAS,UAAU,SAAyB,CAAC,GAAyB;AAZ7E;AAaE,QAAM,gBAAe,YAAO,iBAAP,YAAuB;AAE5C,SAAO;AAAA,IACL,MAAM,OAAO,MAAY;AACvB,YAAM,UAAU,MAAM,MAAM,cAAc;AAAA,QACxC,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,EAAE,UAAU,KAAK,MAAM,aAAa,KAAK,KAAK,CAAC;AAAA,MACtE,CAAC;AACD,UAAI,CAAC,QAAQ,GAAI,OAAM,IAAI,MAAM,6BAA6B;AAC9D,YAAM,EAAE,WAAW,UAAU,IAAI,MAAM,QAAQ,KAAK;AAEpD,YAAM,SAAS,MAAM,MAAM,WAAW;AAAA,QACpC,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,KAAK,KAAK;AAAA,QACrC,MAAM;AAAA,MACR,CAAC;AACD,UAAI,CAAC,OAAO,GAAI,OAAM,IAAI,MAAM,kBAAkB;AAElD,aAAO,EAAE,KAAK,UAAoB;AAAA,IACpC;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,14 @@
1
+ import { ClientStorageAdapter } from '../../index.cjs';
2
+
3
+ interface S3ClientConfig {
4
+ /** Endpoint that returns a presigned PUT URL. Default `/api/admin/sign`. */
5
+ signEndpoint?: string;
6
+ }
7
+ /**
8
+ * S3 client storage: requests a presigned PUT URL from the server, then PUTs the
9
+ * file directly to S3. Pure `fetch` — safe in client components. The matching
10
+ * server signer lives at `@dalgoridim/headless-cms/storage/s3/server`.
11
+ */
12
+ declare function s3Storage(config?: S3ClientConfig): ClientStorageAdapter;
13
+
14
+ export { type S3ClientConfig, s3Storage };
@@ -0,0 +1,14 @@
1
+ import { ClientStorageAdapter } from '../../index.js';
2
+
3
+ interface S3ClientConfig {
4
+ /** Endpoint that returns a presigned PUT URL. Default `/api/admin/sign`. */
5
+ signEndpoint?: string;
6
+ }
7
+ /**
8
+ * S3 client storage: requests a presigned PUT URL from the server, then PUTs the
9
+ * file directly to S3. Pure `fetch` — safe in client components. The matching
10
+ * server signer lives at `@dalgoridim/headless-cms/storage/s3/server`.
11
+ */
12
+ declare function s3Storage(config?: S3ClientConfig): ClientStorageAdapter;
13
+
14
+ export { type S3ClientConfig, s3Storage };
@@ -0,0 +1,27 @@
1
+ // src/storage/s3/index.ts
2
+ function s3Storage(config = {}) {
3
+ var _a;
4
+ const signEndpoint = (_a = config.signEndpoint) != null ? _a : "/api/admin/sign";
5
+ return {
6
+ async upload(file) {
7
+ const signRes = await fetch(signEndpoint, {
8
+ method: "POST",
9
+ headers: { "Content-Type": "application/json" },
10
+ body: JSON.stringify({ filename: file.name, contentType: file.type })
11
+ });
12
+ if (!signRes.ok) throw new Error("Failed to get presigned URL");
13
+ const { uploadUrl, publicUrl } = await signRes.json();
14
+ const putRes = await fetch(uploadUrl, {
15
+ method: "PUT",
16
+ headers: { "Content-Type": file.type },
17
+ body: file
18
+ });
19
+ if (!putRes.ok) throw new Error("S3 upload failed");
20
+ return { url: publicUrl };
21
+ }
22
+ };
23
+ }
24
+ export {
25
+ s3Storage
26
+ };
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/storage/s3/index.ts"],"sourcesContent":["import type { ClientStorageAdapter } from \"../../types\";\n\nexport interface S3ClientConfig {\n /** Endpoint that returns a presigned PUT URL. Default `/api/admin/sign`. */\n signEndpoint?: string;\n}\n\n/**\n * S3 client storage: requests a presigned PUT URL from the server, then PUTs the\n * file directly to S3. Pure `fetch` — safe in client components. The matching\n * server signer lives at `@dalgoridim/headless-cms/storage/s3/server`.\n */\nexport function s3Storage(config: S3ClientConfig = {}): ClientStorageAdapter {\n const signEndpoint = config.signEndpoint ?? \"/api/admin/sign\";\n\n return {\n async upload(file: File) {\n const signRes = await fetch(signEndpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ filename: file.name, contentType: file.type }),\n });\n if (!signRes.ok) throw new Error(\"Failed to get presigned URL\");\n const { uploadUrl, publicUrl } = await signRes.json();\n\n const putRes = await fetch(uploadUrl, {\n method: \"PUT\",\n headers: { \"Content-Type\": file.type },\n body: file,\n });\n if (!putRes.ok) throw new Error(\"S3 upload failed\");\n\n return { url: publicUrl as string };\n },\n };\n}\n"],"mappings":";AAYO,SAAS,UAAU,SAAyB,CAAC,GAAyB;AAZ7E;AAaE,QAAM,gBAAe,YAAO,iBAAP,YAAuB;AAE5C,SAAO;AAAA,IACL,MAAM,OAAO,MAAY;AACvB,YAAM,UAAU,MAAM,MAAM,cAAc;AAAA,QACxC,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,QAC9C,MAAM,KAAK,UAAU,EAAE,UAAU,KAAK,MAAM,aAAa,KAAK,KAAK,CAAC;AAAA,MACtE,CAAC;AACD,UAAI,CAAC,QAAQ,GAAI,OAAM,IAAI,MAAM,6BAA6B;AAC9D,YAAM,EAAE,WAAW,UAAU,IAAI,MAAM,QAAQ,KAAK;AAEpD,YAAM,SAAS,MAAM,MAAM,WAAW;AAAA,QACpC,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,KAAK,KAAK;AAAA,QACrC,MAAM;AAAA,MACR,CAAC;AACD,UAAI,CAAC,OAAO,GAAI,OAAM,IAAI,MAAM,kBAAkB;AAElD,aAAO,EAAE,KAAK,UAAoB;AAAA,IACpC;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,61 @@
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/s3/server.ts
21
+ var server_exports = {};
22
+ __export(server_exports, {
23
+ s3Sign: () => s3Sign
24
+ });
25
+ module.exports = __toCommonJS(server_exports);
26
+ var import_client_s3 = require("@aws-sdk/client-s3");
27
+ var import_s3_request_presigner = require("@aws-sdk/s3-request-presigner");
28
+ function s3Sign(config = {}) {
29
+ var _a;
30
+ const keyPrefix = ((_a = config.keyPrefix) != null ? _a : "uploads").replace(/\/$/, "");
31
+ const publicUrlFor = (key) => config.publicBaseUrl ? `${config.publicBaseUrl.replace(/\/$/, "")}/${key}` : `https://${config.bucket}.s3.${config.region}.amazonaws.com/${key}`;
32
+ const client = new import_client_s3.S3Client({
33
+ region: config.region,
34
+ credentials: config.accessKeyId && config.secretAccessKey ? {
35
+ accessKeyId: config.accessKeyId,
36
+ secretAccessKey: config.secretAccessKey
37
+ } : void 0
38
+ });
39
+ return {
40
+ async sign(req) {
41
+ const { filename, contentType } = await req.json();
42
+ const safeName = (filename != null ? filename : "file").replace(/[^a-zA-Z0-9._-]/g, "_");
43
+ const key = `${keyPrefix}/${Date.now()}-${safeName}`;
44
+ const uploadUrl = await (0, import_s3_request_presigner.getSignedUrl)(
45
+ client,
46
+ new import_client_s3.PutObjectCommand({
47
+ Bucket: config.bucket,
48
+ Key: key,
49
+ ContentType: contentType
50
+ }),
51
+ { expiresIn: 60 }
52
+ );
53
+ return { uploadUrl, publicUrl: publicUrlFor(key) };
54
+ }
55
+ };
56
+ }
57
+ // Annotate the CommonJS export names for ESM import in node:
58
+ 0 && (module.exports = {
59
+ s3Sign
60
+ });
61
+ //# sourceMappingURL=server.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/storage/s3/server.ts"],"sourcesContent":["import { S3Client, PutObjectCommand } from \"@aws-sdk/client-s3\";\nimport { getSignedUrl } from \"@aws-sdk/s3-request-presigner\";\nimport type { ServerStorageAdapter } from \"../../types\";\n\nexport interface S3ServerConfig {\n bucket?: string;\n region?: string;\n accessKeyId?: string;\n secretAccessKey?: string;\n /** Public base URL for stored objects (e.g. a CDN). Defaults to the S3 URL. */\n publicBaseUrl?: string;\n /** Key prefix (folder) for uploads. Default `uploads`. */\n keyPrefix?: string;\n}\n\n/**\n * S3 server signer: issues a presigned PUT URL for `{ filename, contentType }`.\n * Mount its `sign` via `createCmsHandlers`. Server-only (imports the AWS SDK).\n */\nexport function s3Sign(config: S3ServerConfig = {}): ServerStorageAdapter {\n const keyPrefix = (config.keyPrefix ?? \"uploads\").replace(/\\/$/, \"\");\n const publicUrlFor = (key: string) =>\n config.publicBaseUrl\n ? `${config.publicBaseUrl.replace(/\\/$/, \"\")}/${key}`\n : `https://${config.bucket}.s3.${config.region}.amazonaws.com/${key}`;\n\n const client = new S3Client({\n region: config.region,\n credentials:\n config.accessKeyId && config.secretAccessKey\n ? {\n accessKeyId: config.accessKeyId,\n secretAccessKey: config.secretAccessKey,\n }\n : undefined,\n });\n\n return {\n async sign(req: Request) {\n const { filename, contentType } = (await req.json()) as {\n filename?: string;\n contentType?: string;\n };\n const safeName = (filename ?? \"file\").replace(/[^a-zA-Z0-9._-]/g, \"_\");\n const key = `${keyPrefix}/${Date.now()}-${safeName}`;\n\n const uploadUrl = await getSignedUrl(\n client,\n new PutObjectCommand({\n Bucket: config.bucket,\n Key: key,\n ContentType: contentType,\n }),\n { expiresIn: 60 },\n );\n\n return { uploadUrl, publicUrl: publicUrlFor(key) };\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAA2C;AAC3C,kCAA6B;AAkBtB,SAAS,OAAO,SAAyB,CAAC,GAAyB;AAnB1E;AAoBE,QAAM,cAAa,YAAO,cAAP,YAAoB,WAAW,QAAQ,OAAO,EAAE;AACnE,QAAM,eAAe,CAAC,QACpB,OAAO,gBACH,GAAG,OAAO,cAAc,QAAQ,OAAO,EAAE,CAAC,IAAI,GAAG,KACjD,WAAW,OAAO,MAAM,OAAO,OAAO,MAAM,kBAAkB,GAAG;AAEvE,QAAM,SAAS,IAAI,0BAAS;AAAA,IAC1B,QAAQ,OAAO;AAAA,IACf,aACE,OAAO,eAAe,OAAO,kBACzB;AAAA,MACE,aAAa,OAAO;AAAA,MACpB,iBAAiB,OAAO;AAAA,IAC1B,IACA;AAAA,EACR,CAAC;AAED,SAAO;AAAA,IACL,MAAM,KAAK,KAAc;AACvB,YAAM,EAAE,UAAU,YAAY,IAAK,MAAM,IAAI,KAAK;AAIlD,YAAM,YAAY,8BAAY,QAAQ,QAAQ,oBAAoB,GAAG;AACrE,YAAM,MAAM,GAAG,SAAS,IAAI,KAAK,IAAI,CAAC,IAAI,QAAQ;AAElD,YAAM,YAAY,UAAM;AAAA,QACtB;AAAA,QACA,IAAI,kCAAiB;AAAA,UACnB,QAAQ,OAAO;AAAA,UACf,KAAK;AAAA,UACL,aAAa;AAAA,QACf,CAAC;AAAA,QACD,EAAE,WAAW,GAAG;AAAA,MAClB;AAEA,aAAO,EAAE,WAAW,WAAW,aAAa,GAAG,EAAE;AAAA,IACnD;AAAA,EACF;AACF;","names":[]}
@@ -0,0 +1,19 @@
1
+ import { ServerStorageAdapter } from '../../index.cjs';
2
+
3
+ interface S3ServerConfig {
4
+ bucket?: string;
5
+ region?: string;
6
+ accessKeyId?: string;
7
+ secretAccessKey?: string;
8
+ /** Public base URL for stored objects (e.g. a CDN). Defaults to the S3 URL. */
9
+ publicBaseUrl?: string;
10
+ /** Key prefix (folder) for uploads. Default `uploads`. */
11
+ keyPrefix?: string;
12
+ }
13
+ /**
14
+ * S3 server signer: issues a presigned PUT URL for `{ filename, contentType }`.
15
+ * Mount its `sign` via `createCmsHandlers`. Server-only (imports the AWS SDK).
16
+ */
17
+ declare function s3Sign(config?: S3ServerConfig): ServerStorageAdapter;
18
+
19
+ export { type S3ServerConfig, s3Sign };
@@ -0,0 +1,19 @@
1
+ import { ServerStorageAdapter } from '../../index.js';
2
+
3
+ interface S3ServerConfig {
4
+ bucket?: string;
5
+ region?: string;
6
+ accessKeyId?: string;
7
+ secretAccessKey?: string;
8
+ /** Public base URL for stored objects (e.g. a CDN). Defaults to the S3 URL. */
9
+ publicBaseUrl?: string;
10
+ /** Key prefix (folder) for uploads. Default `uploads`. */
11
+ keyPrefix?: string;
12
+ }
13
+ /**
14
+ * S3 server signer: issues a presigned PUT URL for `{ filename, contentType }`.
15
+ * Mount its `sign` via `createCmsHandlers`. Server-only (imports the AWS SDK).
16
+ */
17
+ declare function s3Sign(config?: S3ServerConfig): ServerStorageAdapter;
18
+
19
+ export { type S3ServerConfig, s3Sign };
@@ -0,0 +1,36 @@
1
+ // src/storage/s3/server.ts
2
+ import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
3
+ import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
4
+ function s3Sign(config = {}) {
5
+ var _a;
6
+ const keyPrefix = ((_a = config.keyPrefix) != null ? _a : "uploads").replace(/\/$/, "");
7
+ const publicUrlFor = (key) => config.publicBaseUrl ? `${config.publicBaseUrl.replace(/\/$/, "")}/${key}` : `https://${config.bucket}.s3.${config.region}.amazonaws.com/${key}`;
8
+ const client = new S3Client({
9
+ region: config.region,
10
+ credentials: config.accessKeyId && config.secretAccessKey ? {
11
+ accessKeyId: config.accessKeyId,
12
+ secretAccessKey: config.secretAccessKey
13
+ } : void 0
14
+ });
15
+ return {
16
+ async sign(req) {
17
+ const { filename, contentType } = await req.json();
18
+ const safeName = (filename != null ? filename : "file").replace(/[^a-zA-Z0-9._-]/g, "_");
19
+ const key = `${keyPrefix}/${Date.now()}-${safeName}`;
20
+ const uploadUrl = await getSignedUrl(
21
+ client,
22
+ new PutObjectCommand({
23
+ Bucket: config.bucket,
24
+ Key: key,
25
+ ContentType: contentType
26
+ }),
27
+ { expiresIn: 60 }
28
+ );
29
+ return { uploadUrl, publicUrl: publicUrlFor(key) };
30
+ }
31
+ };
32
+ }
33
+ export {
34
+ s3Sign
35
+ };
36
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/storage/s3/server.ts"],"sourcesContent":["import { S3Client, PutObjectCommand } from \"@aws-sdk/client-s3\";\nimport { getSignedUrl } from \"@aws-sdk/s3-request-presigner\";\nimport type { ServerStorageAdapter } from \"../../types\";\n\nexport interface S3ServerConfig {\n bucket?: string;\n region?: string;\n accessKeyId?: string;\n secretAccessKey?: string;\n /** Public base URL for stored objects (e.g. a CDN). Defaults to the S3 URL. */\n publicBaseUrl?: string;\n /** Key prefix (folder) for uploads. Default `uploads`. */\n keyPrefix?: string;\n}\n\n/**\n * S3 server signer: issues a presigned PUT URL for `{ filename, contentType }`.\n * Mount its `sign` via `createCmsHandlers`. Server-only (imports the AWS SDK).\n */\nexport function s3Sign(config: S3ServerConfig = {}): ServerStorageAdapter {\n const keyPrefix = (config.keyPrefix ?? \"uploads\").replace(/\\/$/, \"\");\n const publicUrlFor = (key: string) =>\n config.publicBaseUrl\n ? `${config.publicBaseUrl.replace(/\\/$/, \"\")}/${key}`\n : `https://${config.bucket}.s3.${config.region}.amazonaws.com/${key}`;\n\n const client = new S3Client({\n region: config.region,\n credentials:\n config.accessKeyId && config.secretAccessKey\n ? {\n accessKeyId: config.accessKeyId,\n secretAccessKey: config.secretAccessKey,\n }\n : undefined,\n });\n\n return {\n async sign(req: Request) {\n const { filename, contentType } = (await req.json()) as {\n filename?: string;\n contentType?: string;\n };\n const safeName = (filename ?? \"file\").replace(/[^a-zA-Z0-9._-]/g, \"_\");\n const key = `${keyPrefix}/${Date.now()}-${safeName}`;\n\n const uploadUrl = await getSignedUrl(\n client,\n new PutObjectCommand({\n Bucket: config.bucket,\n Key: key,\n ContentType: contentType,\n }),\n { expiresIn: 60 },\n );\n\n return { uploadUrl, publicUrl: publicUrlFor(key) };\n },\n };\n}\n"],"mappings":";AAAA,SAAS,UAAU,wBAAwB;AAC3C,SAAS,oBAAoB;AAkBtB,SAAS,OAAO,SAAyB,CAAC,GAAyB;AAnB1E;AAoBE,QAAM,cAAa,YAAO,cAAP,YAAoB,WAAW,QAAQ,OAAO,EAAE;AACnE,QAAM,eAAe,CAAC,QACpB,OAAO,gBACH,GAAG,OAAO,cAAc,QAAQ,OAAO,EAAE,CAAC,IAAI,GAAG,KACjD,WAAW,OAAO,MAAM,OAAO,OAAO,MAAM,kBAAkB,GAAG;AAEvE,QAAM,SAAS,IAAI,SAAS;AAAA,IAC1B,QAAQ,OAAO;AAAA,IACf,aACE,OAAO,eAAe,OAAO,kBACzB;AAAA,MACE,aAAa,OAAO;AAAA,MACpB,iBAAiB,OAAO;AAAA,IAC1B,IACA;AAAA,EACR,CAAC;AAED,SAAO;AAAA,IACL,MAAM,KAAK,KAAc;AACvB,YAAM,EAAE,UAAU,YAAY,IAAK,MAAM,IAAI,KAAK;AAIlD,YAAM,YAAY,8BAAY,QAAQ,QAAQ,oBAAoB,GAAG;AACrE,YAAM,MAAM,GAAG,SAAS,IAAI,KAAK,IAAI,CAAC,IAAI,QAAQ;AAElD,YAAM,YAAY,MAAM;AAAA,QACtB;AAAA,QACA,IAAI,iBAAiB;AAAA,UACnB,QAAQ,OAAO;AAAA,UACf,KAAK;AAAA,UACL,aAAa;AAAA,QACf,CAAC;AAAA,QACD,EAAE,WAAW,GAAG;AAAA,MAClB;AAEA,aAAO,EAAE,WAAW,WAAW,aAAa,GAAG,EAAE;AAAA,IACnD;AAAA,EACF;AACF;","names":[]}
package/package.json ADDED
@@ -0,0 +1,165 @@
1
+ {
2
+ "name": "@dalgoridim/headless-cms",
3
+ "version": "0.1.0",
4
+ "description": "Database-agnostic, inline-edit headless CMS engine for React / Next.js apps",
5
+ "license": "UNLICENSED",
6
+ "author": "dalgoridim",
7
+ "keywords": [
8
+ "cms",
9
+ "headless-cms",
10
+ "inline-edit",
11
+ "react",
12
+ "nextjs",
13
+ "firestore",
14
+ "postgres",
15
+ "cloudinary"
16
+ ],
17
+ "engines": {
18
+ "node": ">=18"
19
+ },
20
+ "type": "module",
21
+ "sideEffects": false,
22
+ "main": "./dist/index.cjs",
23
+ "module": "./dist/index.js",
24
+ "types": "./dist/index.d.ts",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.ts",
28
+ "import": "./dist/index.js",
29
+ "require": "./dist/index.cjs"
30
+ },
31
+ "./client": {
32
+ "types": "./dist/client/index.d.ts",
33
+ "import": "./dist/client/index.js",
34
+ "require": "./dist/client/index.cjs"
35
+ },
36
+ "./server": {
37
+ "types": "./dist/server/index.d.ts",
38
+ "import": "./dist/server/index.js",
39
+ "require": "./dist/server/index.cjs"
40
+ },
41
+ "./adapters/firestore": {
42
+ "types": "./dist/adapters/firestore/index.d.ts",
43
+ "import": "./dist/adapters/firestore/index.js",
44
+ "require": "./dist/adapters/firestore/index.cjs"
45
+ },
46
+ "./adapters/postgres": {
47
+ "types": "./dist/adapters/postgres/index.d.ts",
48
+ "import": "./dist/adapters/postgres/index.js",
49
+ "require": "./dist/adapters/postgres/index.cjs"
50
+ },
51
+ "./storage/cloudinary": {
52
+ "types": "./dist/storage/cloudinary/index.d.ts",
53
+ "import": "./dist/storage/cloudinary/index.js",
54
+ "require": "./dist/storage/cloudinary/index.cjs"
55
+ },
56
+ "./storage/cloudinary/server": {
57
+ "types": "./dist/storage/cloudinary/server.d.ts",
58
+ "import": "./dist/storage/cloudinary/server.js",
59
+ "require": "./dist/storage/cloudinary/server.cjs"
60
+ },
61
+ "./storage/s3": {
62
+ "types": "./dist/storage/s3/index.d.ts",
63
+ "import": "./dist/storage/s3/index.js",
64
+ "require": "./dist/storage/s3/index.cjs"
65
+ },
66
+ "./storage/s3/server": {
67
+ "types": "./dist/storage/s3/server.d.ts",
68
+ "import": "./dist/storage/s3/server.js",
69
+ "require": "./dist/storage/s3/server.cjs"
70
+ },
71
+ "./storage/local": {
72
+ "types": "./dist/storage/local/index.d.ts",
73
+ "import": "./dist/storage/local/index.js",
74
+ "require": "./dist/storage/local/index.cjs"
75
+ },
76
+ "./storage/local/server": {
77
+ "types": "./dist/storage/local/server.d.ts",
78
+ "import": "./dist/storage/local/server.js",
79
+ "require": "./dist/storage/local/server.cjs"
80
+ },
81
+ "./auth/firebase": {
82
+ "types": "./dist/auth/firebase/index.d.ts",
83
+ "import": "./dist/auth/firebase/index.js",
84
+ "require": "./dist/auth/firebase/index.cjs"
85
+ },
86
+ "./auth/firebase/client": {
87
+ "types": "./dist/auth/firebase/client/index.d.ts",
88
+ "import": "./dist/auth/firebase/client/index.js",
89
+ "require": "./dist/auth/firebase/client/index.cjs"
90
+ },
91
+ "./auth/nextauth": {
92
+ "types": "./dist/auth/nextauth/index.d.ts",
93
+ "import": "./dist/auth/nextauth/index.js",
94
+ "require": "./dist/auth/nextauth/index.cjs"
95
+ }
96
+ },
97
+ "files": [
98
+ "dist"
99
+ ],
100
+ "scripts": {
101
+ "build": "tsup",
102
+ "dev": "tsup --watch",
103
+ "typecheck": "tsc --noEmit",
104
+ "prepare": "tsup"
105
+ },
106
+ "peerDependencies": {
107
+ "@aws-sdk/client-s3": ">=3",
108
+ "@aws-sdk/s3-request-presigner": ">=3",
109
+ "cloudinary": ">=2",
110
+ "firebase": ">=10",
111
+ "firebase-admin": ">=12",
112
+ "next": ">=14",
113
+ "pg": ">=8",
114
+ "react": ">=18",
115
+ "react-dom": ">=18"
116
+ },
117
+ "peerDependenciesMeta": {
118
+ "@aws-sdk/client-s3": {
119
+ "optional": true
120
+ },
121
+ "@aws-sdk/s3-request-presigner": {
122
+ "optional": true
123
+ },
124
+ "cloudinary": {
125
+ "optional": true
126
+ },
127
+ "firebase": {
128
+ "optional": true
129
+ },
130
+ "firebase-admin": {
131
+ "optional": true
132
+ },
133
+ "next": {
134
+ "optional": true
135
+ },
136
+ "pg": {
137
+ "optional": true
138
+ }
139
+ },
140
+ "dependencies": {
141
+ "clsx": "^2.1.1",
142
+ "lucide-react": "^0.556.0",
143
+ "react-markdown": "^10.1.0",
144
+ "remark-gfm": "^4.0.1",
145
+ "sonner": "^2.0.7",
146
+ "tailwind-merge": "^3.4.0"
147
+ },
148
+ "devDependencies": {
149
+ "@aws-sdk/client-s3": "^3.700.0",
150
+ "@aws-sdk/s3-request-presigner": "^3.700.0",
151
+ "@types/node": "^20.0.0",
152
+ "@types/pg": "^8.11.10",
153
+ "@types/react": "^19.0.0",
154
+ "@types/react-dom": "^19.0.0",
155
+ "cloudinary": "^2.9.0",
156
+ "firebase": "^12.6.0",
157
+ "firebase-admin": "^13.6.0",
158
+ "next": "^16.0.10",
159
+ "pg": "^8.13.1",
160
+ "react": "^19.0.0",
161
+ "react-dom": "^19.0.0",
162
+ "tsup": "^8.5.1",
163
+ "typescript": "^5.7.0"
164
+ }
165
+ }