@kidecms/core 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/generator.js +1 -1
- package/dist/integration.js +43 -25
- package/dist/runtime.js +1 -1
- package/dist/schema.js +1 -1
- package/package.json +1 -1
- package/dist/blocks.js +0 -110
package/dist/generator.js
CHANGED
|
@@ -357,7 +357,7 @@ ${apiTypes}
|
|
|
357
357
|
};
|
|
358
358
|
export const generate = async (config, options) => {
|
|
359
359
|
const outputDir = options.outputDir;
|
|
360
|
-
const coreImportPath = options.coreImportPath ?? "
|
|
360
|
+
const coreImportPath = options.coreImportPath ?? "@kidecms/core";
|
|
361
361
|
const runtimeImportPath = options.runtimeImportPath ?? "../runtime";
|
|
362
362
|
const configImportPath = options.configImportPath ?? "../cms.config";
|
|
363
363
|
await mkdir(outputDir, { recursive: true });
|
package/dist/integration.js
CHANGED
|
@@ -70,7 +70,25 @@ export default function cmsIntegration(options) {
|
|
|
70
70
|
const corePkgDir = path.dirname(path.dirname(fileURLToPath(import.meta.url)));
|
|
71
71
|
const adminDir = path.join(corePkgDir, "admin");
|
|
72
72
|
const routesDir = path.join(corePkgDir, "routes");
|
|
73
|
-
|
|
73
|
+
// Find tw-animate-css — pnpm may hoist it anywhere in the dep tree
|
|
74
|
+
const findTwAnimate = () => {
|
|
75
|
+
const candidates = [
|
|
76
|
+
path.join(corePkgDir, "node_modules", "tw-animate-css", "dist", "tw-animate.css"),
|
|
77
|
+
path.join(root, "node_modules", "tw-animate-css", "dist", "tw-animate.css"),
|
|
78
|
+
];
|
|
79
|
+
// Walk up from corePkgDir
|
|
80
|
+
let dir = corePkgDir;
|
|
81
|
+
while (dir !== path.dirname(dir)) {
|
|
82
|
+
candidates.push(path.join(dir, "node_modules", "tw-animate-css", "dist", "tw-animate.css"));
|
|
83
|
+
dir = path.dirname(dir);
|
|
84
|
+
}
|
|
85
|
+
for (const candidate of candidates) {
|
|
86
|
+
if (existsSync(candidate))
|
|
87
|
+
return candidate;
|
|
88
|
+
}
|
|
89
|
+
return candidates[0];
|
|
90
|
+
};
|
|
91
|
+
const twAnimateCssPath = findTwAnimate();
|
|
74
92
|
const userAdminCss = path.resolve(root, "src/styles/admin.css");
|
|
75
93
|
const generatedDir = path.join(root, "node_modules", ".kide");
|
|
76
94
|
mkdirSync(generatedDir, { recursive: true });
|
|
@@ -134,41 +152,41 @@ export default function cmsIntegration(options) {
|
|
|
134
152
|
},
|
|
135
153
|
});
|
|
136
154
|
// Inject admin pages
|
|
137
|
-
injectRoute({ pattern: "/admin/login", entrypoint: "
|
|
138
|
-
injectRoute({ pattern: "/admin/setup", entrypoint: "
|
|
139
|
-
injectRoute({ pattern: "/admin/invite", entrypoint: "
|
|
140
|
-
injectRoute({ pattern: "/admin/assets", entrypoint: "
|
|
141
|
-
injectRoute({ pattern: "/admin/assets/[id]", entrypoint: "
|
|
142
|
-
injectRoute({ pattern: "/admin/[...path]", entrypoint: "
|
|
155
|
+
injectRoute({ pattern: "/admin/login", entrypoint: "@kidecms/core/routes/pages/admin/login.astro" });
|
|
156
|
+
injectRoute({ pattern: "/admin/setup", entrypoint: "@kidecms/core/routes/pages/admin/setup.astro" });
|
|
157
|
+
injectRoute({ pattern: "/admin/invite", entrypoint: "@kidecms/core/routes/pages/admin/invite.astro" });
|
|
158
|
+
injectRoute({ pattern: "/admin/assets", entrypoint: "@kidecms/core/routes/pages/admin/assets/index.astro" });
|
|
159
|
+
injectRoute({ pattern: "/admin/assets/[id]", entrypoint: "@kidecms/core/routes/pages/admin/assets/[id].astro" });
|
|
160
|
+
injectRoute({ pattern: "/admin/[...path]", entrypoint: "@kidecms/core/routes/pages/admin/[...path].astro" });
|
|
143
161
|
// Inject API routes
|
|
144
|
-
injectRoute({ pattern: "/api/cms/auth/login", entrypoint: "
|
|
145
|
-
injectRoute({ pattern: "/api/cms/auth/logout", entrypoint: "
|
|
146
|
-
injectRoute({ pattern: "/api/cms/auth/setup", entrypoint: "
|
|
147
|
-
injectRoute({ pattern: "/api/cms/auth/invite", entrypoint: "
|
|
148
|
-
injectRoute({ pattern: "/api/cms/assets/upload", entrypoint: "
|
|
149
|
-
injectRoute({ pattern: "/api/cms/assets/folders", entrypoint: "
|
|
150
|
-
injectRoute({ pattern: "/api/cms/assets/[id]", entrypoint: "
|
|
151
|
-
injectRoute({ pattern: "/api/cms/assets", entrypoint: "
|
|
152
|
-
injectRoute({ pattern: "/api/cms/ai/alt-text", entrypoint: "
|
|
153
|
-
injectRoute({ pattern: "/api/cms/ai/seo", entrypoint: "
|
|
154
|
-
injectRoute({ pattern: "/api/cms/ai/translate", entrypoint: "
|
|
155
|
-
injectRoute({ pattern: "/api/cms/cron/publish", entrypoint: "
|
|
162
|
+
injectRoute({ pattern: "/api/cms/auth/login", entrypoint: "@kidecms/core/routes/api/cms/auth/login.ts" });
|
|
163
|
+
injectRoute({ pattern: "/api/cms/auth/logout", entrypoint: "@kidecms/core/routes/api/cms/auth/logout.ts" });
|
|
164
|
+
injectRoute({ pattern: "/api/cms/auth/setup", entrypoint: "@kidecms/core/routes/api/cms/auth/setup.ts" });
|
|
165
|
+
injectRoute({ pattern: "/api/cms/auth/invite", entrypoint: "@kidecms/core/routes/api/cms/auth/invite.ts" });
|
|
166
|
+
injectRoute({ pattern: "/api/cms/assets/upload", entrypoint: "@kidecms/core/routes/api/cms/assets/upload.ts" });
|
|
167
|
+
injectRoute({ pattern: "/api/cms/assets/folders", entrypoint: "@kidecms/core/routes/api/cms/assets/folders.ts" });
|
|
168
|
+
injectRoute({ pattern: "/api/cms/assets/[id]", entrypoint: "@kidecms/core/routes/api/cms/assets/[id].ts" });
|
|
169
|
+
injectRoute({ pattern: "/api/cms/assets", entrypoint: "@kidecms/core/routes/api/cms/assets/index.ts" });
|
|
170
|
+
injectRoute({ pattern: "/api/cms/ai/alt-text", entrypoint: "@kidecms/core/routes/api/cms/ai/alt-text.ts" });
|
|
171
|
+
injectRoute({ pattern: "/api/cms/ai/seo", entrypoint: "@kidecms/core/routes/api/cms/ai/seo.ts" });
|
|
172
|
+
injectRoute({ pattern: "/api/cms/ai/translate", entrypoint: "@kidecms/core/routes/api/cms/ai/translate.ts" });
|
|
173
|
+
injectRoute({ pattern: "/api/cms/cron/publish", entrypoint: "@kidecms/core/routes/api/cms/cron/publish.ts" });
|
|
156
174
|
injectRoute({
|
|
157
175
|
pattern: "/api/cms/locks/[...path]",
|
|
158
|
-
entrypoint: "
|
|
176
|
+
entrypoint: "@kidecms/core/routes/api/cms/locks/[...path].ts",
|
|
159
177
|
});
|
|
160
|
-
injectRoute({ pattern: "/api/cms/preview/render", entrypoint: "
|
|
178
|
+
injectRoute({ pattern: "/api/cms/preview/render", entrypoint: "@kidecms/core/routes/api/cms/preview/render.ts" });
|
|
161
179
|
injectRoute({
|
|
162
180
|
pattern: "/api/cms/references/[collection]/[id]",
|
|
163
|
-
entrypoint: "
|
|
181
|
+
entrypoint: "@kidecms/core/routes/api/cms/references/[collection]/[id].ts",
|
|
164
182
|
});
|
|
165
|
-
injectRoute({ pattern: "/api/cms/img/[...path]", entrypoint: "
|
|
183
|
+
injectRoute({ pattern: "/api/cms/img/[...path]", entrypoint: "@kidecms/core/routes/api/cms/img/[...path].ts" });
|
|
166
184
|
injectRoute({
|
|
167
185
|
pattern: "/api/cms/[collection]/[...path]",
|
|
168
|
-
entrypoint: "
|
|
186
|
+
entrypoint: "@kidecms/core/routes/api/cms/[collection]/[...path].ts",
|
|
169
187
|
});
|
|
170
188
|
// Inject auth middleware
|
|
171
|
-
addMiddleware({ entrypoint: "
|
|
189
|
+
addMiddleware({ entrypoint: "@kidecms/core/middleware/auth.ts", order: "pre" });
|
|
172
190
|
// Generate schema, types, validators, and API
|
|
173
191
|
console.log(" [cms] Generating schema, types, validators, and API...");
|
|
174
192
|
try {
|
package/dist/runtime.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
let runtime = null;
|
|
2
|
-
const runtimeError = () => new Error("
|
|
2
|
+
const runtimeError = () => new Error("@kidecms/core runtime not initialized. Call configureCmsRuntime(...) and initSchema(...) from your app before using runtime APIs.");
|
|
3
3
|
export const configureCmsRuntime = (config) => {
|
|
4
4
|
runtime = config;
|
|
5
5
|
};
|
package/dist/schema.js
CHANGED
|
@@ -7,7 +7,7 @@ export const resetSchema = () => {
|
|
|
7
7
|
};
|
|
8
8
|
export const getSchema = () => {
|
|
9
9
|
if (!schema) {
|
|
10
|
-
throw new Error("
|
|
10
|
+
throw new Error("@kidecms/core schema not initialized. Call initSchema(...) from your app before using runtime APIs.");
|
|
11
11
|
}
|
|
12
12
|
return schema;
|
|
13
13
|
};
|
package/package.json
CHANGED
package/dist/blocks.js
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { cmsImage, cmsSrcset } from "./image";
|
|
2
|
-
import { renderRichText } from "./richtext";
|
|
3
|
-
function esc(value) {
|
|
4
|
-
return String(value ?? "")
|
|
5
|
-
.replace(/&/g, "&")
|
|
6
|
-
.replace(/</g, "<")
|
|
7
|
-
.replace(/>/g, ">")
|
|
8
|
-
.replace(/"/g, """);
|
|
9
|
-
}
|
|
10
|
-
function parseJson(value) {
|
|
11
|
-
if (typeof value === "string") {
|
|
12
|
-
try {
|
|
13
|
-
return JSON.parse(value);
|
|
14
|
-
}
|
|
15
|
-
catch {
|
|
16
|
-
return value;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
return value;
|
|
20
|
-
}
|
|
21
|
-
function isRichText(value) {
|
|
22
|
-
const parsed = parseJson(value);
|
|
23
|
-
return parsed && typeof parsed === "object" && parsed.type === "root";
|
|
24
|
-
}
|
|
25
|
-
function isImageUrl(value) {
|
|
26
|
-
const stringValue = String(value ?? "");
|
|
27
|
-
return stringValue.startsWith("/uploads/") || stringValue.startsWith("http://") || stringValue.startsWith("https://");
|
|
28
|
-
}
|
|
29
|
-
function isImageArray(value) {
|
|
30
|
-
const parsed = parseJson(value);
|
|
31
|
-
return Array.isArray(parsed) && parsed.length > 0 && parsed.every((entry) => isImageUrl(entry));
|
|
32
|
-
}
|
|
33
|
-
function isRepeaterArray(value) {
|
|
34
|
-
const parsed = parseJson(value);
|
|
35
|
-
return Array.isArray(parsed) && parsed.length > 0 && typeof parsed[0] === "object" && parsed[0] !== null;
|
|
36
|
-
}
|
|
37
|
-
function renderImage(src) {
|
|
38
|
-
if (src.startsWith("/uploads/")) {
|
|
39
|
-
return `<img src="${esc(cmsImage(src, 1024))}" srcset="${esc(cmsSrcset(src))}" sizes="(max-width: 768px) 100vw, 768px" alt="" loading="lazy" class="h-auto w-full rounded-lg object-cover" />`;
|
|
40
|
-
}
|
|
41
|
-
return `<img src="${esc(src)}" alt="" loading="lazy" class="w-full rounded-lg object-cover" />`;
|
|
42
|
-
}
|
|
43
|
-
function renderFieldValue(key, value) {
|
|
44
|
-
if (value === null || value === undefined || value === "")
|
|
45
|
-
return "";
|
|
46
|
-
const parsed = parseJson(value);
|
|
47
|
-
if (isRichText(value)) {
|
|
48
|
-
return `<div class="prose">${renderRichText(parsed)}</div>`;
|
|
49
|
-
}
|
|
50
|
-
if (isImageArray(value)) {
|
|
51
|
-
const images = Array.isArray(parsed) ? parsed : [];
|
|
52
|
-
return `<div class="grid gap-4">${images.map((src) => renderImage(String(src))).join("")}</div>`;
|
|
53
|
-
}
|
|
54
|
-
if (isImageUrl(value)) {
|
|
55
|
-
return renderImage(String(value));
|
|
56
|
-
}
|
|
57
|
-
if (isRepeaterArray(value)) {
|
|
58
|
-
const items = Array.isArray(parsed) ? parsed : [];
|
|
59
|
-
let html = `<div class="grid gap-3">`;
|
|
60
|
-
for (const item of items) {
|
|
61
|
-
html += `<div class="rounded-lg border border-gray-200 bg-gray-50 px-5 py-4">`;
|
|
62
|
-
for (const [itemKey, itemValue] of Object.entries(item)) {
|
|
63
|
-
if (itemKey === "_key" || itemKey === "id" || !itemValue)
|
|
64
|
-
continue;
|
|
65
|
-
const className = itemKey.includes("description") || itemKey.includes("answer") || itemKey.includes("body")
|
|
66
|
-
? "m-0 text-gray-500"
|
|
67
|
-
: "mb-1 font-semibold";
|
|
68
|
-
html += `<p class="${className}">${esc(itemValue)}</p>`;
|
|
69
|
-
}
|
|
70
|
-
html += `</div>`;
|
|
71
|
-
}
|
|
72
|
-
html += `</div>`;
|
|
73
|
-
return html;
|
|
74
|
-
}
|
|
75
|
-
if (key === "heading" || key === "title") {
|
|
76
|
-
return `<h2 class="mb-3 text-xl font-semibold">${esc(value)}</h2>`;
|
|
77
|
-
}
|
|
78
|
-
if (key === "eyebrow" || key === "label") {
|
|
79
|
-
return `<p class="mb-1 text-xs font-semibold uppercase tracking-wide text-teal-700">${esc(value)}</p>`;
|
|
80
|
-
}
|
|
81
|
-
if (key === "ctaLabel" || key === "ctaHref") {
|
|
82
|
-
return "";
|
|
83
|
-
}
|
|
84
|
-
return `<p class="text-gray-500">${esc(value)}</p>`;
|
|
85
|
-
}
|
|
86
|
-
export function renderBlock(block) {
|
|
87
|
-
const { type: _type, _key, ...fields } = block;
|
|
88
|
-
let html = `<section>`;
|
|
89
|
-
if (fields.eyebrow) {
|
|
90
|
-
html += renderFieldValue("eyebrow", fields.eyebrow);
|
|
91
|
-
}
|
|
92
|
-
for (const key of ["heading", "title"]) {
|
|
93
|
-
if (fields[key]) {
|
|
94
|
-
html += renderFieldValue(key, fields[key]);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
for (const [key, value] of Object.entries(fields)) {
|
|
98
|
-
if (["eyebrow", "heading", "title", "ctaLabel", "ctaHref"].includes(key))
|
|
99
|
-
continue;
|
|
100
|
-
html += renderFieldValue(key, value);
|
|
101
|
-
}
|
|
102
|
-
if (fields.ctaLabel && fields.ctaHref) {
|
|
103
|
-
html += `<a href="${esc(fields.ctaHref)}" class="mt-4 inline-block rounded-md bg-teal-700 px-4 py-2 text-sm text-white no-underline">${esc(fields.ctaLabel)}</a>`;
|
|
104
|
-
}
|
|
105
|
-
html += `</section>`;
|
|
106
|
-
return html;
|
|
107
|
-
}
|
|
108
|
-
export function renderBlocks(blocks) {
|
|
109
|
-
return blocks.map(renderBlock).join("");
|
|
110
|
-
}
|