okno 1.0.0-alpha.1
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/codegen/generate.d.ts +6 -0
- package/dist/codegen/generate.d.ts.map +1 -0
- package/dist/editor/index.js +19339 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/plugin-C4ZJr14i.js +440 -0
- package/dist/runtime/wrap.d.ts +11 -0
- package/dist/runtime/wrap.d.ts.map +1 -0
- package/dist/types/fields.d.ts +73 -0
- package/dist/types/fields.d.ts.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/schema.d.ts +47 -0
- package/dist/types/schema.d.ts.map +1 -0
- package/dist/vite/dev-server.d.ts +8 -0
- package/dist/vite/dev-server.d.ts.map +1 -0
- package/dist/vite/index.d.ts +2 -0
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +4 -0
- package/dist/vite/plugin.d.ts +4 -0
- package/dist/vite/plugin.d.ts.map +1 -0
- package/package.json +62 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export type { OknoSchema, OknoConfig, PageDef, CollectionDef, GlobalDef, Fields, AnyField, StringField, NumberField, BooleanField, DateField, EnumField, RichtextField, FileField, SlugField, ReferenceField, GroupField, } from "./types/index.ts";
|
|
2
|
+
export { okno } from "./vite/index.ts";
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,UAAU,EACV,UAAU,EACV,OAAO,EACP,aAAa,EACb,SAAS,EACT,MAAM,EACN,QAAQ,EACR,WAAW,EACX,WAAW,EACX,YAAY,EACZ,SAAS,EACT,SAAS,EACT,aAAa,EACb,SAAS,EACT,SAAS,EACT,cAAc,EACd,UAAU,GACV,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
import { join as u, extname as M, dirname as R, relative as D, resolve as y } from "node:path";
|
|
2
|
+
import { existsSync as $, readFileSync as V, mkdirSync as H, writeFileSync as J } from "node:fs";
|
|
3
|
+
import { readdir as v, writeFile as G, readFile as A } from "node:fs/promises";
|
|
4
|
+
import { fileURLToPath as U } from "node:url";
|
|
5
|
+
import { simpleGit as B } from "simple-git";
|
|
6
|
+
async function E(a) {
|
|
7
|
+
const n = [
|
|
8
|
+
"// Auto-generated by okno. Do not edit.",
|
|
9
|
+
"",
|
|
10
|
+
"/** A wrapped content value that can be spread onto elements and rendered as text. */",
|
|
11
|
+
"type OknoValue<T = unknown> = {",
|
|
12
|
+
' readonly "data-okno": string',
|
|
13
|
+
" toString(): string",
|
|
14
|
+
" [Symbol.toPrimitive](hint: string): string",
|
|
15
|
+
" on(callback: (value: T) => void): () => void",
|
|
16
|
+
"}",
|
|
17
|
+
"",
|
|
18
|
+
"/** Recursively wraps content types so all leaf values are spreadable OknoValues. */",
|
|
19
|
+
"type OknoWrapped<T> =",
|
|
20
|
+
" T extends string | number | boolean",
|
|
21
|
+
" ? OknoValue<T>",
|
|
22
|
+
" : T extends Array<infer U>",
|
|
23
|
+
" ? OknoWrapped<U>[]",
|
|
24
|
+
" : T extends Record<string, unknown>",
|
|
25
|
+
" ? { [K in keyof T]: OknoWrapped<T[K]> } & OknoValue<T>",
|
|
26
|
+
" : OknoValue<T>",
|
|
27
|
+
""
|
|
28
|
+
], o = u(a, "pages"), e = await W(o);
|
|
29
|
+
if (e.length > 0) {
|
|
30
|
+
n.push('declare module "okno:pages" {');
|
|
31
|
+
for (const r of e) {
|
|
32
|
+
const t = `./pages/${r}`;
|
|
33
|
+
n.push(` import _${N(r)} from "${t}"`), n.push(` export const ${r}: OknoWrapped<typeof _${N(r)}>`);
|
|
34
|
+
}
|
|
35
|
+
n.push("}"), n.push("");
|
|
36
|
+
}
|
|
37
|
+
const s = u(a, "collections");
|
|
38
|
+
if ($(s)) {
|
|
39
|
+
const r = (await v(s, { withFileTypes: !0 })).filter((t) => t.isDirectory());
|
|
40
|
+
if (r.length > 0) {
|
|
41
|
+
n.push('declare module "okno:collections" {');
|
|
42
|
+
for (const t of r) {
|
|
43
|
+
const i = await W(u(s, t.name));
|
|
44
|
+
if (i.length === 0) continue;
|
|
45
|
+
const p = i[0];
|
|
46
|
+
n.push(
|
|
47
|
+
` import _${N(t.name)}_item from "./collections/${t.name}/${p}"`
|
|
48
|
+
), n.push(` export const ${t.name}: OknoWrapped<typeof _${N(t.name)}_item>[]`);
|
|
49
|
+
}
|
|
50
|
+
n.push("}"), n.push("");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
const l = u(a, "globals"), c = await W(l);
|
|
54
|
+
if (c.length > 0) {
|
|
55
|
+
n.push('declare module "okno:globals" {');
|
|
56
|
+
for (const r of c) {
|
|
57
|
+
const t = `./globals/${r}`;
|
|
58
|
+
n.push(` import _${N(r)} from "${t}"`), n.push(` export const ${r}: OknoWrapped<typeof _${N(r)}>`);
|
|
59
|
+
}
|
|
60
|
+
n.push("}"), n.push("");
|
|
61
|
+
}
|
|
62
|
+
await G(u(a, "modules.d.ts"), n.join(`
|
|
63
|
+
`));
|
|
64
|
+
}
|
|
65
|
+
async function W(a) {
|
|
66
|
+
return $(a) ? (await v(a)).filter((o) => o.endsWith(".ts") && o !== "index.ts" && o !== "modules.d.ts").map((o) => o.replace(".ts", "")) : [];
|
|
67
|
+
}
|
|
68
|
+
function N(a) {
|
|
69
|
+
return a.replace(/-/g, "_");
|
|
70
|
+
}
|
|
71
|
+
const K = {
|
|
72
|
+
".webp": "image/webp",
|
|
73
|
+
".png": "image/png",
|
|
74
|
+
".jpg": "image/jpeg",
|
|
75
|
+
".jpeg": "image/jpeg",
|
|
76
|
+
".gif": "image/gif",
|
|
77
|
+
".svg": "image/svg+xml",
|
|
78
|
+
".avif": "image/avif",
|
|
79
|
+
".ico": "image/x-icon",
|
|
80
|
+
".mp4": "video/mp4",
|
|
81
|
+
".webm": "video/webm",
|
|
82
|
+
".ogg": "video/ogg",
|
|
83
|
+
".mp3": "audio/mpeg",
|
|
84
|
+
".wav": "audio/wav",
|
|
85
|
+
".flac": "audio/flac",
|
|
86
|
+
".pdf": "application/pdf",
|
|
87
|
+
".woff2": "font/woff2",
|
|
88
|
+
".woff": "font/woff",
|
|
89
|
+
".ttf": "font/ttf",
|
|
90
|
+
".otf": "font/otf"
|
|
91
|
+
};
|
|
92
|
+
function z(a, n) {
|
|
93
|
+
a.middlewares.use((o, e, s) => {
|
|
94
|
+
var t;
|
|
95
|
+
if (o.method !== "GET" || !((t = o.url) != null && t.startsWith("/okno/files/"))) return s();
|
|
96
|
+
const l = o.url.slice(12).split("?")[0];
|
|
97
|
+
if (!l) return s();
|
|
98
|
+
const c = u(n, "files", l);
|
|
99
|
+
if (!$(c))
|
|
100
|
+
return e.statusCode = 404, e.end("Not found");
|
|
101
|
+
const r = M(l).toLowerCase();
|
|
102
|
+
e.setHeader("Content-Type", K[r] || "application/octet-stream"), e.setHeader("Cache-Control", "public, max-age=3600"), e.end(V(c));
|
|
103
|
+
}), a.middlewares.use(async (o, e, s) => {
|
|
104
|
+
var c;
|
|
105
|
+
if (!((c = o.url) != null && c.startsWith("/__okno/"))) return s();
|
|
106
|
+
const l = o.url.slice(8);
|
|
107
|
+
e.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate"), e.setHeader("Pragma", "no-cache"), e.setHeader("Expires", "0");
|
|
108
|
+
try {
|
|
109
|
+
if (o.method === "POST" && l.startsWith("mirror")) {
|
|
110
|
+
const t = new URL(o.url, "http://localhost").searchParams.get("path");
|
|
111
|
+
if (!t || t.includes("..") || !t.startsWith("files/"))
|
|
112
|
+
return e.statusCode = 400, e.setHeader("Content-Type", "application/json"), e.end(JSON.stringify({ error: "Invalid path" }));
|
|
113
|
+
const i = u(n, t);
|
|
114
|
+
if ($(i))
|
|
115
|
+
return e.setHeader("Content-Type", "application/json"), e.end(JSON.stringify({ ok: !0, skipped: !0 }));
|
|
116
|
+
const p = await X(o);
|
|
117
|
+
return H(R(i), { recursive: !0 }), J(i, p), e.setHeader("Content-Type", "application/json"), e.end(JSON.stringify({ ok: !0, written: t, bytes: p.length }));
|
|
118
|
+
}
|
|
119
|
+
if (o.method === "POST" && l === "sync") {
|
|
120
|
+
const r = await Y(o), t = r == null ? void 0 : r.path;
|
|
121
|
+
if (t) {
|
|
122
|
+
const f = u(n, t);
|
|
123
|
+
return I(a, t, f), e.setHeader("Content-Type", "application/json"), e.end(JSON.stringify({ ok: !0, invalidated: t }));
|
|
124
|
+
}
|
|
125
|
+
const i = B(n), p = await i.revparse(["--show-toplevel"]), m = D(p.trim(), n);
|
|
126
|
+
try {
|
|
127
|
+
const f = await i.pull();
|
|
128
|
+
for (const d of f.files)
|
|
129
|
+
if (d.startsWith(`${m}/`)) {
|
|
130
|
+
const h = d.slice(`${m}/`.length), g = u(n, h);
|
|
131
|
+
I(a, h, g);
|
|
132
|
+
}
|
|
133
|
+
return e.setHeader("Content-Type", "application/json"), e.end(JSON.stringify({ ok: !0, files: f.files }));
|
|
134
|
+
} catch (f) {
|
|
135
|
+
const d = f instanceof Error ? f.message : String(f);
|
|
136
|
+
return console.warn(`[okno] sync: git pull skipped — ${d.split(`
|
|
137
|
+
`)[0]}`), e.setHeader("Content-Type", "application/json"), e.end(JSON.stringify({ ok: !0, pullSkipped: !0, reason: d }));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
e.statusCode = 404, e.end(JSON.stringify({ error: "Not found" }));
|
|
141
|
+
} catch (r) {
|
|
142
|
+
e.statusCode = 500, e.end(JSON.stringify({ error: String(r) }));
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
function X(a) {
|
|
147
|
+
return new Promise((n, o) => {
|
|
148
|
+
const e = [];
|
|
149
|
+
a.on("data", (s) => e.push(s)), a.on("end", () => n(Buffer.concat(e))), a.on("error", o);
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
function Y(a) {
|
|
153
|
+
return new Promise((n) => {
|
|
154
|
+
let o = "";
|
|
155
|
+
a.on("data", (e) => {
|
|
156
|
+
o += e;
|
|
157
|
+
}), a.on("end", () => {
|
|
158
|
+
try {
|
|
159
|
+
n(o ? JSON.parse(o) : null);
|
|
160
|
+
} catch {
|
|
161
|
+
n(null);
|
|
162
|
+
}
|
|
163
|
+
}), a.on("error", () => n(null));
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
function I(a, n, o) {
|
|
167
|
+
const e = "\0okno:";
|
|
168
|
+
let s;
|
|
169
|
+
if (n.startsWith("pages/") ? s = e + "pages" : n.startsWith("collections/") ? s = e + "collections" : n.startsWith("globals/") && (s = e + "globals"), s) {
|
|
170
|
+
const l = a.moduleGraph.getModuleById(s);
|
|
171
|
+
l && a.moduleGraph.invalidateModule(l);
|
|
172
|
+
const c = a.moduleGraph.getModulesByFile(o);
|
|
173
|
+
c && c.forEach((r) => {
|
|
174
|
+
a.moduleGraph.invalidateModule(r);
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const Z = "okno:", O = "\0okno:", L = R(U(import.meta.url)), k = y(L, "../../editor"), Q = y(L, "../runtime");
|
|
179
|
+
function ct(a = {}) {
|
|
180
|
+
const n = a.dir ?? "okno";
|
|
181
|
+
let o, e;
|
|
182
|
+
return a.isEditor, {
|
|
183
|
+
name: "okno",
|
|
184
|
+
enforce: "pre",
|
|
185
|
+
config() {
|
|
186
|
+
return {
|
|
187
|
+
define: {
|
|
188
|
+
__OKNO_API_URL__: JSON.stringify(a.apiUrl ?? "")
|
|
189
|
+
},
|
|
190
|
+
server: {
|
|
191
|
+
watch: {
|
|
192
|
+
// Ignore content + media files to prevent auto-refresh on save.
|
|
193
|
+
// Pages/collections/globals are managed via the editor's own
|
|
194
|
+
// invalidation flow; files are static assets served by URL
|
|
195
|
+
// (the browser refetches if a path changes) and the manifest
|
|
196
|
+
// (.okno-tree.json) is editor-only metadata that Vite doesn't
|
|
197
|
+
// need to know about.
|
|
198
|
+
ignored: [
|
|
199
|
+
`**/${n}/pages/**`,
|
|
200
|
+
`**/${n}/collections/**`,
|
|
201
|
+
`**/${n}/globals/**`,
|
|
202
|
+
`**/${n}/files/**`
|
|
203
|
+
]
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
resolve: {
|
|
207
|
+
alias: {
|
|
208
|
+
"@modules": y(k, "modules"),
|
|
209
|
+
"@lib": y(k, "lib"),
|
|
210
|
+
"@controllers": y(k, "controllers"),
|
|
211
|
+
"@components": y(k, "components"),
|
|
212
|
+
"@pages": y(k, "pages"),
|
|
213
|
+
"@assets": y(k, "assets"),
|
|
214
|
+
"@/types": y(k, "lib/types"),
|
|
215
|
+
"@logger": y(k, "lib/logger.svelte")
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
},
|
|
220
|
+
configResolved(s) {
|
|
221
|
+
o = s.root, e = y(o, n);
|
|
222
|
+
},
|
|
223
|
+
async buildStart() {
|
|
224
|
+
$(e) && await E(e);
|
|
225
|
+
},
|
|
226
|
+
configureServer(s) {
|
|
227
|
+
z(s, e);
|
|
228
|
+
},
|
|
229
|
+
async handleHotUpdate(s) {
|
|
230
|
+
const l = u(e, "schema.ts"), c = u(e, "users.json"), r = u(e, "permissions.ts"), t = u(e, "modules.d.ts");
|
|
231
|
+
if (s.file === l) {
|
|
232
|
+
await E(e);
|
|
233
|
+
for (const i of ["pages", "collections", "globals"]) {
|
|
234
|
+
const p = s.server.moduleGraph.getModuleById(O + i);
|
|
235
|
+
p && s.server.moduleGraph.invalidateModule(p);
|
|
236
|
+
}
|
|
237
|
+
return [];
|
|
238
|
+
}
|
|
239
|
+
if (s.file === c || s.file === r || s.file === t)
|
|
240
|
+
return [];
|
|
241
|
+
},
|
|
242
|
+
resolveId(s) {
|
|
243
|
+
if (s.startsWith(Z))
|
|
244
|
+
return "\0" + s;
|
|
245
|
+
},
|
|
246
|
+
async load(s) {
|
|
247
|
+
if (!s.startsWith(O)) return;
|
|
248
|
+
const l = s.slice(O.length);
|
|
249
|
+
if (l === "runtime")
|
|
250
|
+
return `export { __oknoWrap } from "${u(Q, "wrap.ts")}"`;
|
|
251
|
+
if (l === "pages") {
|
|
252
|
+
const c = await j(o, "pages");
|
|
253
|
+
return await et(e, c);
|
|
254
|
+
}
|
|
255
|
+
if (l === "collections") {
|
|
256
|
+
const c = await j(o, "collections");
|
|
257
|
+
return await ot(e, c);
|
|
258
|
+
}
|
|
259
|
+
if (l === "globals") {
|
|
260
|
+
const c = await j(o, "globals");
|
|
261
|
+
return await nt(e, c);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
async function b(a) {
|
|
267
|
+
return $(a) ? (await v(a)).filter((o) => o.endsWith(".ts") && o !== "index.ts") : [];
|
|
268
|
+
}
|
|
269
|
+
const q = /* @__PURE__ */ new Set([".astro", ".svelte", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".vue"]), tt = /* @__PURE__ */ new Set([
|
|
270
|
+
"node_modules",
|
|
271
|
+
".astro",
|
|
272
|
+
".svelte-kit",
|
|
273
|
+
".next",
|
|
274
|
+
".nuxt",
|
|
275
|
+
".vite",
|
|
276
|
+
"dist",
|
|
277
|
+
"build",
|
|
278
|
+
".git",
|
|
279
|
+
".turbo"
|
|
280
|
+
]);
|
|
281
|
+
async function j(a, n) {
|
|
282
|
+
const o = new RegExp(`import\\s*\\{([^}]+)\\}\\s*from\\s*["']okno:${n}["']`, "g"), e = /* @__PURE__ */ new Set();
|
|
283
|
+
async function s(l) {
|
|
284
|
+
var r;
|
|
285
|
+
let c;
|
|
286
|
+
try {
|
|
287
|
+
c = await v(l, { withFileTypes: !0 });
|
|
288
|
+
} catch {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
for (const t of c) {
|
|
292
|
+
if (t.name.startsWith(".") && t.name !== "." || tt.has(t.name)) continue;
|
|
293
|
+
const i = u(l, t.name);
|
|
294
|
+
if (t.isDirectory()) {
|
|
295
|
+
await s(i);
|
|
296
|
+
continue;
|
|
297
|
+
}
|
|
298
|
+
const p = t.name.lastIndexOf(".");
|
|
299
|
+
if (p === -1) continue;
|
|
300
|
+
const m = t.name.slice(p);
|
|
301
|
+
if (!q.has(m)) continue;
|
|
302
|
+
let f;
|
|
303
|
+
try {
|
|
304
|
+
f = await A(i, "utf-8");
|
|
305
|
+
} catch {
|
|
306
|
+
continue;
|
|
307
|
+
}
|
|
308
|
+
if (f.includes(`okno:${n}`))
|
|
309
|
+
for (const d of f.matchAll(o)) {
|
|
310
|
+
const h = d[1] ?? "";
|
|
311
|
+
for (const g of h.split(",")) {
|
|
312
|
+
const w = (r = g.trim().split(/\s+as\s+/)[0]) == null ? void 0 : r.trim();
|
|
313
|
+
w && /^[A-Za-z_$][\w$]*$/.test(w) && e.add(w);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return await s(a), e;
|
|
319
|
+
}
|
|
320
|
+
function S(a) {
|
|
321
|
+
return a.replace(".ts", "").replace(/-/g, "_");
|
|
322
|
+
}
|
|
323
|
+
function x(a) {
|
|
324
|
+
return a.replace(".ts", "").replace(/-/g, "_");
|
|
325
|
+
}
|
|
326
|
+
function C(a) {
|
|
327
|
+
return a.replace(".ts", "");
|
|
328
|
+
}
|
|
329
|
+
async function et(a, n = /* @__PURE__ */ new Set()) {
|
|
330
|
+
const o = u(a, "pages"), e = [
|
|
331
|
+
'import { __oknoWrap } from "okno:runtime"'
|
|
332
|
+
], s = /* @__PURE__ */ new Set();
|
|
333
|
+
if ($(o)) {
|
|
334
|
+
const c = (await v(o, { withFileTypes: !0 })).filter((t) => t.isDirectory()).map((t) => t.name);
|
|
335
|
+
if (c.length > 0) {
|
|
336
|
+
const t = c[0], i = await b(u(o, t));
|
|
337
|
+
for (const p of i) {
|
|
338
|
+
const m = S(p), f = x(p), d = [], h = [];
|
|
339
|
+
for (const g of c) {
|
|
340
|
+
const w = u(o, g, p);
|
|
341
|
+
if ($(w)) {
|
|
342
|
+
const _ = `_${m}_${g}`;
|
|
343
|
+
d.push(`import ${_} from "${w}"`), g === t ? h.push(`...${_}`) : h.push(`${g}: { ..._${m}_${t}, ...${_} }`);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
e.push(...d), e.push(`const _${m} = { ${h.join(", ")} }`), e.push(`export const ${f} = __oknoWrap(_${m}, "${f}")`), s.add(f);
|
|
347
|
+
}
|
|
348
|
+
} else {
|
|
349
|
+
const t = await b(o);
|
|
350
|
+
for (const i of t) {
|
|
351
|
+
const p = S(i), m = x(i), f = C(i), d = u(o, i);
|
|
352
|
+
e.push(`import _${p} from "${d}"`), e.push(`export const ${m} = __oknoWrap(_${p}, "${f}")`), s.add(m);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
for (const l of n)
|
|
357
|
+
s.has(l) || e.push(`export const ${l} = __oknoWrap(null, "${l}")`);
|
|
358
|
+
return e.join(`
|
|
359
|
+
`);
|
|
360
|
+
}
|
|
361
|
+
async function ot(a, n = /* @__PURE__ */ new Set()) {
|
|
362
|
+
const o = u(a, "collections");
|
|
363
|
+
if (!$(o)) {
|
|
364
|
+
const t = [];
|
|
365
|
+
for (const i of n) {
|
|
366
|
+
const p = i.replace(/-/g, "_");
|
|
367
|
+
t.push(`export const ${p} = []`);
|
|
368
|
+
}
|
|
369
|
+
return t.join(`
|
|
370
|
+
`) || "export {}";
|
|
371
|
+
}
|
|
372
|
+
const e = await v(o, { withFileTypes: !0 }), s = e.filter((t) => t.isDirectory() && /^[a-z]{2}(-[a-z]{2})?$/.test(t.name)).map((t) => t.name), l = e.filter((t) => t.isDirectory() && !s.includes(t.name)).map((t) => t.name), c = s.length > 0, r = [
|
|
373
|
+
'import { __oknoWrap } from "okno:runtime"'
|
|
374
|
+
];
|
|
375
|
+
if (c) {
|
|
376
|
+
const t = s[0];
|
|
377
|
+
for (const i of l) {
|
|
378
|
+
const p = u(o, t, i);
|
|
379
|
+
if (!$(p)) continue;
|
|
380
|
+
const m = await b(p), f = [];
|
|
381
|
+
for (const d of m) {
|
|
382
|
+
const h = `_${i}_${S(d)}`, g = x(d), w = [], _ = [];
|
|
383
|
+
for (const P of s) {
|
|
384
|
+
const F = u(o, P, i, d);
|
|
385
|
+
if ($(F)) {
|
|
386
|
+
const T = `${h}_${P}`;
|
|
387
|
+
w.push(`import ${T} from "${F}"`), P === t ? _.push(`...${T}`) : _.push(`${P}: { ...${h}_${t}, ...${T} }`);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
r.push(...w), r.push(`const ${h} = { ${_.join(", ")} }`), f.push(`__oknoWrap(${h}, "${i}.${g}")`);
|
|
391
|
+
}
|
|
392
|
+
r.push(`export const ${i} = [${f.join(", ")}]`);
|
|
393
|
+
}
|
|
394
|
+
} else
|
|
395
|
+
for (const t of l) {
|
|
396
|
+
const i = u(o, t), p = await b(i), m = [], f = t.replace(/-/g, "_");
|
|
397
|
+
for (const d of p) {
|
|
398
|
+
const h = `_${f}_${S(d)}`, g = C(d);
|
|
399
|
+
r.push(`import ${h} from "${u(i, d)}"`), m.push(`__oknoWrap(${h}, "${t}.${g}")`);
|
|
400
|
+
}
|
|
401
|
+
r.push(`export const ${f} = [${m.join(", ")}]`);
|
|
402
|
+
}
|
|
403
|
+
return r.join(`
|
|
404
|
+
`);
|
|
405
|
+
}
|
|
406
|
+
async function nt(a, n = /* @__PURE__ */ new Set()) {
|
|
407
|
+
const o = u(a, "globals"), e = [
|
|
408
|
+
'import { __oknoWrap } from "okno:runtime"'
|
|
409
|
+
], s = /* @__PURE__ */ new Set();
|
|
410
|
+
if ($(o)) {
|
|
411
|
+
const c = (await v(o, { withFileTypes: !0 })).filter((t) => t.isDirectory()).map((t) => t.name);
|
|
412
|
+
if (c.length > 0) {
|
|
413
|
+
const t = c[0], i = await b(u(o, t));
|
|
414
|
+
for (const p of i) {
|
|
415
|
+
const m = S(p), f = x(p), d = [], h = [];
|
|
416
|
+
for (const g of c) {
|
|
417
|
+
const w = u(o, g, p);
|
|
418
|
+
if ($(w)) {
|
|
419
|
+
const _ = `_${m}_${g}`;
|
|
420
|
+
d.push(`import ${_} from "${w}"`), g === t ? h.push(`...${_}`) : h.push(`${g}: { ..._${m}_${t}, ...${_} }`);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
e.push(...d), e.push(`const _${m} = { ${h.join(", ")} }`), e.push(`export const ${f} = __oknoWrap(_${m}, "${f}")`), s.add(f);
|
|
424
|
+
}
|
|
425
|
+
} else {
|
|
426
|
+
const t = await b(o);
|
|
427
|
+
for (const i of t) {
|
|
428
|
+
const p = S(i), m = x(i), f = C(i), d = u(o, i);
|
|
429
|
+
e.push(`import _${p} from "${d}"`), e.push(`export const ${m} = __oknoWrap(_${p}, "${f}")`), s.add(m);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
for (const l of n)
|
|
434
|
+
s.has(l) || e.push(`export const ${l} = __oknoWrap(null, "${l}")`);
|
|
435
|
+
return e.join(`
|
|
436
|
+
`);
|
|
437
|
+
}
|
|
438
|
+
export {
|
|
439
|
+
ct as o
|
|
440
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wraps content data in a Proxy that:
|
|
3
|
+
* - Returns `data-okno` attribute when spread ({...value})
|
|
4
|
+
* - Returns string value when used in templates ({value})
|
|
5
|
+
* - Forwards native string/number methods (value.length, value.includes(), etc.)
|
|
6
|
+
* - Returns nested proxies for group access (value.child)
|
|
7
|
+
* - Returns empty proxies for non-existing fields
|
|
8
|
+
* - Supports .on(callback) for reactive change subscriptions
|
|
9
|
+
*/
|
|
10
|
+
export declare function __oknoWrap(data: unknown, prefix: string): any;
|
|
11
|
+
//# sourceMappingURL=wrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrap.d.ts","sourceRoot":"","sources":["../../src/runtime/wrap.ts"],"names":[],"mappings":"AAmEA;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,CA0I7D"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/** Base properties shared by all field types */
|
|
2
|
+
interface FieldBase {
|
|
3
|
+
required?: boolean;
|
|
4
|
+
localized?: boolean;
|
|
5
|
+
hidden?: boolean;
|
|
6
|
+
help?: string;
|
|
7
|
+
}
|
|
8
|
+
/** Plain text field */
|
|
9
|
+
export interface StringField extends FieldBase {
|
|
10
|
+
type: "string";
|
|
11
|
+
default?: string;
|
|
12
|
+
min?: number;
|
|
13
|
+
max?: number;
|
|
14
|
+
pattern?: string;
|
|
15
|
+
email?: boolean;
|
|
16
|
+
url?: boolean;
|
|
17
|
+
phone?: boolean;
|
|
18
|
+
multiline?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/** Numeric field */
|
|
21
|
+
export interface NumberField extends FieldBase {
|
|
22
|
+
type: "number";
|
|
23
|
+
default?: number;
|
|
24
|
+
min?: number;
|
|
25
|
+
max?: number;
|
|
26
|
+
integer?: boolean;
|
|
27
|
+
}
|
|
28
|
+
/** Boolean toggle */
|
|
29
|
+
export interface BooleanField extends FieldBase {
|
|
30
|
+
type: "boolean";
|
|
31
|
+
default?: boolean;
|
|
32
|
+
}
|
|
33
|
+
/** Date/datetime field */
|
|
34
|
+
export interface DateField extends FieldBase {
|
|
35
|
+
type: "date";
|
|
36
|
+
default?: string | "now";
|
|
37
|
+
}
|
|
38
|
+
/** Dropdown / multi-select */
|
|
39
|
+
export interface EnumField extends FieldBase {
|
|
40
|
+
type: "enum";
|
|
41
|
+
options: string[];
|
|
42
|
+
multiple?: boolean;
|
|
43
|
+
default?: string | string[];
|
|
44
|
+
}
|
|
45
|
+
/** Rich text / HTML content */
|
|
46
|
+
export interface RichtextField extends FieldBase {
|
|
47
|
+
type: "richtext";
|
|
48
|
+
}
|
|
49
|
+
/** Files file (image, video, audio, document) */
|
|
50
|
+
export interface FileField extends FieldBase {
|
|
51
|
+
type: "file";
|
|
52
|
+
accept?: "image" | "video" | "audio" | "document" | "*";
|
|
53
|
+
}
|
|
54
|
+
/** Auto-generated URL slug from another field */
|
|
55
|
+
export interface SlugField extends FieldBase {
|
|
56
|
+
type: "slug";
|
|
57
|
+
from: string;
|
|
58
|
+
}
|
|
59
|
+
/** Reference to another collection */
|
|
60
|
+
export interface ReferenceField extends FieldBase {
|
|
61
|
+
type: "reference";
|
|
62
|
+
collection: string;
|
|
63
|
+
multiple?: boolean;
|
|
64
|
+
}
|
|
65
|
+
/** Nested field group */
|
|
66
|
+
export interface GroupField {
|
|
67
|
+
type: "group";
|
|
68
|
+
fields: Record<string, AnyField>;
|
|
69
|
+
}
|
|
70
|
+
/** Union of all field types */
|
|
71
|
+
export type AnyField = StringField | NumberField | BooleanField | DateField | EnumField | RichtextField | FileField | SlugField | ReferenceField | GroupField;
|
|
72
|
+
export {};
|
|
73
|
+
//# sourceMappingURL=fields.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../../src/types/fields.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,UAAU,SAAS;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;CACb;AAED,uBAAuB;AACvB,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC7C,IAAI,EAAE,QAAQ,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,SAAS,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,oBAAoB;AACpB,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC7C,IAAI,EAAE,QAAQ,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,qBAAqB;AACrB,MAAM,WAAW,YAAa,SAAQ,SAAS;IAC9C,IAAI,EAAE,SAAS,CAAA;IACf,OAAO,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,0BAA0B;AAC1B,MAAM,WAAW,SAAU,SAAQ,SAAS;IAC3C,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;CACxB;AAED,8BAA8B;AAC9B,MAAM,WAAW,SAAU,SAAQ,SAAS;IAC3C,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAC3B;AAED,+BAA+B;AAC/B,MAAM,WAAW,aAAc,SAAQ,SAAS;IAC/C,IAAI,EAAE,UAAU,CAAA;CAChB;AAED,iDAAiD;AACjD,MAAM,WAAW,SAAU,SAAQ,SAAS;IAC3C,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,GAAG,CAAA;CACvD;AAED,iDAAiD;AACjD,MAAM,WAAW,SAAU,SAAQ,SAAS;IAC3C,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACZ;AAED,sCAAsC;AACtC,MAAM,WAAW,cAAe,SAAQ,SAAS;IAChD,IAAI,EAAE,WAAW,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,yBAAyB;AACzB,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,OAAO,CAAA;IACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;CAChC;AAED,+BAA+B;AAC/B,MAAM,MAAM,QAAQ,GACjB,WAAW,GACX,WAAW,GACX,YAAY,GACZ,SAAS,GACT,SAAS,GACT,aAAa,GACb,SAAS,GACT,SAAS,GACT,cAAc,GACd,UAAU,CAAA"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export type { StringField, NumberField, BooleanField, DateField, EnumField, RichtextField, FileField, SlugField, ReferenceField, GroupField, AnyField, } from "./fields.ts";
|
|
2
|
+
export type { Fields, PageDef, CollectionDef, GlobalDef, OknoSchema, OknoConfig, } from "./schema.ts";
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,WAAW,EACX,WAAW,EACX,YAAY,EACZ,SAAS,EACT,SAAS,EACT,aAAa,EACb,SAAS,EACT,SAAS,EACT,cAAc,EACd,UAAU,EACV,QAAQ,GACR,MAAM,aAAa,CAAA;AAEpB,YAAY,EACX,MAAM,EACN,OAAO,EACP,aAAa,EACb,SAAS,EACT,UAAU,EACV,UAAU,GACV,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { AnyField } from "./fields.ts";
|
|
2
|
+
/** Fields definition - a record of field name to field config */
|
|
3
|
+
export type Fields = Record<string, AnyField>;
|
|
4
|
+
/** Page definition - a singleton content type */
|
|
5
|
+
export interface PageDef {
|
|
6
|
+
/** Display name shown in editor (sidebar, page title). Falls back to slug. */
|
|
7
|
+
name?: string;
|
|
8
|
+
fields: Fields;
|
|
9
|
+
}
|
|
10
|
+
/** Collection definition - multiple items with required slug */
|
|
11
|
+
export interface CollectionDef {
|
|
12
|
+
name?: string;
|
|
13
|
+
fields: Fields & {
|
|
14
|
+
slug: {
|
|
15
|
+
type: "slug";
|
|
16
|
+
from: string;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/** Global definition - site-wide singleton */
|
|
21
|
+
export interface GlobalDef {
|
|
22
|
+
name?: string;
|
|
23
|
+
fields: Fields;
|
|
24
|
+
}
|
|
25
|
+
/** The full schema that users define in okno/schema.ts */
|
|
26
|
+
export interface OknoSchema {
|
|
27
|
+
pages?: Record<string, PageDef>;
|
|
28
|
+
collections?: Record<string, CollectionDef>;
|
|
29
|
+
globals?: Record<string, GlobalDef>;
|
|
30
|
+
}
|
|
31
|
+
/** Plugin configuration */
|
|
32
|
+
export interface OknoConfig {
|
|
33
|
+
/** Path to the okno content directory (default: "okno") */
|
|
34
|
+
dir?: string;
|
|
35
|
+
/** URL of the okno backend API (for GitHub OAuth and production content) */
|
|
36
|
+
apiUrl?: string;
|
|
37
|
+
/** Whether this is the editor build (disables HMR on content changes) */
|
|
38
|
+
isEditor?: boolean;
|
|
39
|
+
/** Localization configuration */
|
|
40
|
+
locales?: {
|
|
41
|
+
/** Default/base locale code (e.g. "en") */
|
|
42
|
+
default: string;
|
|
43
|
+
/** Supported locale codes (e.g. ["en", "cs", "de"]) */
|
|
44
|
+
supported: string[];
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/types/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE3C,iEAAiE;AACjE,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;AAE7C,iDAAiD;AACjD,MAAM,WAAW,OAAO;IACvB,8EAA8E;IAC9E,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACd;AAED,gEAAgE;AAChE,MAAM,WAAW,aAAa;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,GAAG;QAChB,IAAI,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAA;KACpC,CAAA;CACD;AAED,8CAA8C;AAC9C,MAAM,WAAW,SAAS;IACzB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACd;AAED,0DAA0D;AAC1D,MAAM,WAAW,UAAU;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;CACnC;AAED,2BAA2B;AAC3B,MAAM,WAAW,UAAU;IAC1B,2DAA2D;IAC3D,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,yEAAyE;IACzE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,iCAAiC;IACjC,OAAO,CAAC,EAAE;QACT,2CAA2C;QAC3C,OAAO,EAAE,MAAM,CAAA;QACf,uDAAuD;QACvD,SAAS,EAAE,MAAM,EAAE,CAAA;KACnB,CAAA;CACD"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ViteDevServer } from "vite";
|
|
2
|
+
/**
|
|
3
|
+
* Dev server middleware: single endpoint for syncing local files with remote.
|
|
4
|
+
* All content CRUD goes through the backend. This just pulls changes
|
|
5
|
+
* and invalidates Vite's module cache so pages serve fresh content.
|
|
6
|
+
*/
|
|
7
|
+
export declare function createDevServer(server: ViteDevServer, oknoDir: string): void;
|
|
8
|
+
//# sourceMappingURL=dev-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../../src/vite/dev-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAA;AAczC;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,QA+FrE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vite/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/vite/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAClC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAepD,wBAAgB,IAAI,CAAC,MAAM,GAAE,UAAe,GAAG,MAAM,CAqHpD"}
|