okno 1.0.0-beta.19 → 1.0.0-beta.21
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/bake.d.ts +19 -0
- package/dist/bake.d.ts.map +1 -0
- package/dist/dispatch-CmTJLIKc.js +930 -0
- package/dist/editor/index.js +2884 -2767
- package/dist/engine/index.js +183 -0
- package/dist/index.js +1 -1
- package/dist/next/config.d.ts.map +1 -1
- package/dist/next/index.js +37 -39
- package/dist/{plugin-jvqdZWC0.js → plugin-DcdYJY8n.js} +143 -176
- package/dist/vite/index.js +1 -1
- package/dist/vite/plugin.d.ts.map +1 -1
- package/package.json +5 -1
- package/dist/dispatch-DKZB5I61.js +0 -1054
|
@@ -0,0 +1,930 @@
|
|
|
1
|
+
import { join as g, relative as U, sep as I, dirname as P, resolve as ie } from "node:path";
|
|
2
|
+
import { readdir as x, readFile as _e, writeFile as $e } from "node:fs/promises";
|
|
3
|
+
import { existsSync as _, readFileSync as b, readdirSync as D, statSync as ke, realpathSync as we, writeFileSync as T, mkdirSync as M, unlinkSync as L, renameSync as Se } from "node:fs";
|
|
4
|
+
import { execSync as ee } from "node:child_process";
|
|
5
|
+
import { fileURLToPath as be } from "node:url";
|
|
6
|
+
import { p as J, b as q, a as ve, e as Oe } from "./encode-DoojdsVU.js";
|
|
7
|
+
import { o as je } from "./order-bAkdncZC.js";
|
|
8
|
+
import { simpleGit as le } from "simple-git";
|
|
9
|
+
import "./acorn-CZBJD705.js";
|
|
10
|
+
import { applyKeyChanges as ce, setStringsSchema as Te, saveFields as Ae, setLocales as xe, setName as Pe, setUrl as Re, renameSlug as Me, reorderKind as Ee, setLayout as Ne, setCollectionOrder as Ie, setDrafts as We, deleteSchemaEntry as Fe, scaffoldEntry as Le, fieldsToContent as ze, EngineError as Ce } from "./engine/index.js";
|
|
11
|
+
const Ue = /* @__PURE__ */ new Set([".astro", ".svelte", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".vue"]), Je = /* @__PURE__ */ new Set([
|
|
12
|
+
"node_modules",
|
|
13
|
+
".astro",
|
|
14
|
+
".svelte-kit",
|
|
15
|
+
".next",
|
|
16
|
+
".nuxt",
|
|
17
|
+
".vite",
|
|
18
|
+
"dist",
|
|
19
|
+
"build",
|
|
20
|
+
".git",
|
|
21
|
+
".turbo"
|
|
22
|
+
]);
|
|
23
|
+
async function Z(e, n) {
|
|
24
|
+
const s = new RegExp(`import\\s*\\{([^}]+)\\}\\s*from\\s*["']okno[:/]${n}["']`, "g"), a = /* @__PURE__ */ new Set();
|
|
25
|
+
async function f(l) {
|
|
26
|
+
let m;
|
|
27
|
+
try {
|
|
28
|
+
m = await x(l, { withFileTypes: !0 });
|
|
29
|
+
} catch {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
for (const u of m) {
|
|
33
|
+
if (u.name.startsWith(".") && u.name !== "." || Je.has(u.name)) continue;
|
|
34
|
+
const i = g(l, u.name);
|
|
35
|
+
if (u.isDirectory()) {
|
|
36
|
+
await f(i);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const t = u.name.lastIndexOf(".");
|
|
40
|
+
if (t === -1) continue;
|
|
41
|
+
const o = u.name.slice(t);
|
|
42
|
+
if (!Ue.has(o)) continue;
|
|
43
|
+
let r;
|
|
44
|
+
try {
|
|
45
|
+
r = await _e(i, "utf-8");
|
|
46
|
+
} catch {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (!(!r.includes(`okno:${n}`) && !r.includes(`okno/${n}`)))
|
|
50
|
+
for (const p of r.matchAll(s)) {
|
|
51
|
+
const c = p[1] ?? "";
|
|
52
|
+
for (const h of c.split(",")) {
|
|
53
|
+
const d = h.trim().split(/\s+as\s+/)[0]?.trim();
|
|
54
|
+
d && /^[A-Za-z_$][\w$]*$/.test(d) && a.add(d);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return await f(e), a;
|
|
60
|
+
}
|
|
61
|
+
async function $t(e, n) {
|
|
62
|
+
const s = await Qe(e), a = new Map(s.map((o) => [o.name, o.first])), f = Xe(e), l = [
|
|
63
|
+
"// Auto-generated by okno. Do not edit.",
|
|
64
|
+
"",
|
|
65
|
+
"/** A wrapped content value that can be spread onto elements and rendered as text. */",
|
|
66
|
+
"type OknoValue<T = unknown> = {",
|
|
67
|
+
' readonly "data-okno": string',
|
|
68
|
+
" toString(): string",
|
|
69
|
+
// NB: NO `[Symbol.toPrimitive]` in the TYPE. Svelte 5's element-attribute type
|
|
70
|
+
// carries a symbol index signature for attachments (`[key: symbol]: Attachment`),
|
|
71
|
+
// and a `(hint: string) => string` toPrimitive isn't assignable to it — so a
|
|
72
|
+
// `{...field}` spread would fail type-check on every element. The runtime keeps
|
|
73
|
+
// Symbol.toPrimitive (see runtime/wrap.ts) so `{field}` / String(field) still
|
|
74
|
+
// coerce; `toString()` covers the static string-coercion the type needs.
|
|
75
|
+
" onedit(callback: (value: T) => void): () => void",
|
|
76
|
+
" /** Re-root reads at a locale; no-op when unset or on the default locale. Returns the SAME wrapped shape (not `this`, which would drop array element types). */",
|
|
77
|
+
" locale(code?: string | null): OknoWrapped<T>",
|
|
78
|
+
" /** `true` when this field/reference actually holds a value — every read is a truthy wrapper, so `entry.ref ? …` can't tell set from unset. */",
|
|
79
|
+
" readonly exists: boolean",
|
|
80
|
+
"}",
|
|
81
|
+
"",
|
|
82
|
+
"/** Array-membership boundary — only on array items (never on a scalar `{...field}` spread, so it can't collide with HTML attributes). Spread onto the item wrapper: `<article {...item.slot}>` → data-okno-item=\"<list>.<i>\". `slot` is a reserved field key so content can't shadow it. */",
|
|
83
|
+
'type OknoSlot = { readonly slot: { readonly "data-okno-item": string } }',
|
|
84
|
+
"",
|
|
85
|
+
"/** A media value's `.image` handle — a spreadable bundle for a framework image component (Astro `<Image {...cover.image}>`): build-optimized `src` (from `okno/files`), plus alt/dimensions and the edit hook. Use `<img {...cover}>` for the raw/universal path. `src` is loose (framework's shape, e.g. Astro `ImageMetadata`) so okno stays framework-agnostic. */",
|
|
86
|
+
'type OknoImage = { src: any; alt: string; width?: number; height?: number; readonly "data-okno": string }',
|
|
87
|
+
"",
|
|
88
|
+
"/** Recursively wraps content types so values are spreadable/renderable. Media (`{src}`) and link (`{url,text}`) objects keep RAW attribute values so `<img {...media}>` / `<a {...link}>` type-check; media also exposes `.image`; other objects expose wrapped fields + the data-okno hook. Array items also carry `.slot`. */",
|
|
89
|
+
"type OknoWrapped<T> =",
|
|
90
|
+
" T extends string | number | boolean",
|
|
91
|
+
" ? OknoValue<T>",
|
|
92
|
+
" : T extends ReadonlyArray<infer U>",
|
|
93
|
+
" ? (OknoWrapped<U> & OknoSlot)[]",
|
|
94
|
+
" : T extends { src: string }",
|
|
95
|
+
' ? Omit<T, "focal"> & OknoValue<T> & { readonly image: OknoImage } & (T extends { focal: infer F } ? { readonly focal: OknoWrapped<F> } : {})',
|
|
96
|
+
" : T extends { url: string; text: string }",
|
|
97
|
+
" ? { href: string; target?: string; rel?: string } & OknoValue<T>",
|
|
98
|
+
" : T extends Record<string, unknown>",
|
|
99
|
+
" ? { [K in keyof T]: OknoWrapped<T[K]> } & OknoValue<T>",
|
|
100
|
+
" : OknoValue<T>",
|
|
101
|
+
"",
|
|
102
|
+
"/** Content referenced in code but not yet scaffolded — shape unknown, so every field is a flat leaf. Nested access (`home.hero.title`) is a type error on purpose: okno fields are flat (dividers organize the editor, they don't nest data). Use a Block for nested shapes. */",
|
|
103
|
+
"type OknoUnscaffolded = OknoWrapped<Record<string, unknown>>",
|
|
104
|
+
"",
|
|
105
|
+
"/** Authorship + timestamp metadata Okno writes on every entry (page, collection item, global). Read-only — never edit or spread; it's the data your own `.sort()` uses. Each is wrapped, so render `{a.updated.date}` and compare `String(a.updated.date)`. */",
|
|
106
|
+
"type OknoStamp = { readonly date: string; readonly author: string }",
|
|
107
|
+
"type OknoMeta = {",
|
|
108
|
+
" readonly created: OknoWrapped<OknoStamp>",
|
|
109
|
+
" readonly updated: OknoWrapped<OknoStamp>",
|
|
110
|
+
"}",
|
|
111
|
+
""
|
|
112
|
+
], m = (o, r, p) => {
|
|
113
|
+
const c = `typeof import("${p}").default`, h = f?.[o]?.[r]?.fields, d = h ? Object.entries(h) : [], y = d.filter(
|
|
114
|
+
([, w]) => w?.type === "reference" && typeof w.collection == "string" && a.has(w.collection)
|
|
115
|
+
), $ = d.filter(([, w]) => w?.type === "enum"), k = '"created" | "updated"';
|
|
116
|
+
if (y.length === 0 && $.length === 0) return `OknoWrapped<Omit<${c}, ${k}>> & OknoMeta`;
|
|
117
|
+
const v = `${[...y, ...$].map(([w]) => `"${w}"`).join(" | ")} | ${k}`, O = [
|
|
118
|
+
...y.map(([w, S]) => {
|
|
119
|
+
const R = `typeof import("./collections/${S.collection}/${a.get(S.collection)}").default`;
|
|
120
|
+
return `${w}: ${S.multiple ? `${R}[]` : R}`;
|
|
121
|
+
}),
|
|
122
|
+
...$.map(([w, S]) => {
|
|
123
|
+
const R = (Array.isArray(S.options) ? S.options : []).map((A) => typeof A == "string" ? A : A?.value).filter((A) => typeof A == "string"), F = `{ name: string; value: ${R.length ? R.map((A) => JSON.stringify(A)).join(" | ") : "string"} }`;
|
|
124
|
+
return `${w}: ${S.multiple ? `${F}[]` : F}`;
|
|
125
|
+
})
|
|
126
|
+
].join("; ");
|
|
127
|
+
return `OknoWrapped<Omit<${c}, ${v}> & { ${O} }> & OknoMeta`;
|
|
128
|
+
}, [u, i, t] = await Promise.all([
|
|
129
|
+
Z(n, "pages"),
|
|
130
|
+
Z(n, "globals"),
|
|
131
|
+
Z(n, "collections")
|
|
132
|
+
]);
|
|
133
|
+
l.push(
|
|
134
|
+
...ue("okno:pages", "pages", await Q(g(e, "pages")), u, m)
|
|
135
|
+
), l.push(...Ze(s, t, m)), l.push(
|
|
136
|
+
...ue("okno:globals", "globals", await Q(g(e, "globals")), i, m)
|
|
137
|
+
), l.push(...Ge(qe(e), He(f))), l.push(...Ve()), l.push(...Be());
|
|
138
|
+
for (const o of ["pages", "collections", "globals", "locales", "strings", "content"])
|
|
139
|
+
l.push(`declare module "okno/${o}" {`, ` export * from "okno:${o}";`, "}", "");
|
|
140
|
+
await $e(g(e, "modules.d.ts"), l.join(`
|
|
141
|
+
`));
|
|
142
|
+
}
|
|
143
|
+
function ue(e, n, s, a, f) {
|
|
144
|
+
const l = /* @__PURE__ */ new Set(), m = [];
|
|
145
|
+
for (const u of s)
|
|
146
|
+
m.push(` export const ${u}: ${f(n, u, `./${n}/${u}`)}`), l.add(u);
|
|
147
|
+
for (const u of a)
|
|
148
|
+
l.has(u) || m.push(` export const ${u}: OknoUnscaffolded`);
|
|
149
|
+
return [`declare module "${e}" {`, ...m, "}", ""];
|
|
150
|
+
}
|
|
151
|
+
function Ve() {
|
|
152
|
+
return [
|
|
153
|
+
'declare module "okno:locales" {',
|
|
154
|
+
' /** A configured language. `id` is the BCP-47 tag (e.g. "zh-Hant"), `name` the display label, `slug` the URL segment you map into routing. `link(url)` returns this page\'s hreflang <link> descriptor — spread onto a <link> (pass Astro.url for an absolute href). Okno owns no routing; you map these. */',
|
|
155
|
+
" export interface OknoLocale {",
|
|
156
|
+
" id: string",
|
|
157
|
+
" name: string",
|
|
158
|
+
" slug: string",
|
|
159
|
+
' link(url: URL | string): { rel: "alternate"; hreflang: string; href: string }',
|
|
160
|
+
" }",
|
|
161
|
+
" /** The configured languages; `locales.default` is the base-locale entry. Empty (`.default` undefined) when no languages are configured. */",
|
|
162
|
+
" export const locales: OknoLocale[] & { default: OknoLocale }",
|
|
163
|
+
"}",
|
|
164
|
+
""
|
|
165
|
+
];
|
|
166
|
+
}
|
|
167
|
+
function Be() {
|
|
168
|
+
return [
|
|
169
|
+
'declare module "okno:content" {',
|
|
170
|
+
' /** Unified content namespace — `import * as okno from "okno:content"` then `okno.pages.home`, `okno.globals.nav`, `okno.collections.articles`, `okno.strings.nav.home`. */',
|
|
171
|
+
' export * as pages from "okno:pages"',
|
|
172
|
+
' export * as globals from "okno:globals"',
|
|
173
|
+
' export * as collections from "okno:collections"',
|
|
174
|
+
' export { strings } from "okno:strings"',
|
|
175
|
+
"}",
|
|
176
|
+
""
|
|
177
|
+
];
|
|
178
|
+
}
|
|
179
|
+
function Ge(e, n) {
|
|
180
|
+
const s = e.length ? `${Ke(e, n)}` : "any", a = e.length ? `
|
|
181
|
+
locale(code?: string | null): ${s}` : "";
|
|
182
|
+
return [
|
|
183
|
+
'declare module "okno:strings" {',
|
|
184
|
+
" /** The UI-strings store. A plain leaf is string-like (spread `{...s.nav.home}` for the edit hook, render `{s.nav.home}` for the text); a SLOTTED leaf is a `(params) => …` function — call it, then spread/render the result (`{...s.cart.items({count})}`). `.locale(code)` re-roots the whole tree at a language. */",
|
|
185
|
+
` export const strings: ${e.length ? `${s} & {${a}
|
|
186
|
+
}` : "any"}`,
|
|
187
|
+
"}",
|
|
188
|
+
""
|
|
189
|
+
];
|
|
190
|
+
}
|
|
191
|
+
function Ke(e, n) {
|
|
192
|
+
const s = { children: /* @__PURE__ */ new Map() };
|
|
193
|
+
for (const m of e) {
|
|
194
|
+
let u = s;
|
|
195
|
+
for (const i of m.split(".")) {
|
|
196
|
+
let t = u.children.get(i);
|
|
197
|
+
t || (t = { children: /* @__PURE__ */ new Map() }, u.children.set(i, t)), u = t;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
const a = (m) => m === "text" ? "string" : "number", f = (m) => {
|
|
201
|
+
const u = n[m];
|
|
202
|
+
return !u || Object.keys(u).length === 0 ? "OknoValue<string>" : `(p: { ${Object.entries(u).map(([t, o]) => `${JSON.stringify(t)}: ${a(o)}`).join("; ")} }) => OknoValue<string>`;
|
|
203
|
+
}, l = (m, u) => m.children.size === 0 ? f(u) : `{ ${[...m.children.entries()].map(
|
|
204
|
+
([t, o]) => `${JSON.stringify(t)}: ${l(o, u ? `${u}.${t}` : t)}`
|
|
205
|
+
).join("; ")} }`;
|
|
206
|
+
return l(s, "");
|
|
207
|
+
}
|
|
208
|
+
function He(e) {
|
|
209
|
+
const n = {}, s = e?.strings;
|
|
210
|
+
if (!s || typeof s != "object" || Array.isArray(s)) return n;
|
|
211
|
+
for (const [a, f] of Object.entries(s)) {
|
|
212
|
+
const l = f?.slots;
|
|
213
|
+
if (!l || typeof l != "object" || Array.isArray(l)) continue;
|
|
214
|
+
const m = {};
|
|
215
|
+
for (const [u, i] of Object.entries(l))
|
|
216
|
+
(i === "text" || i === "number" || i === "count") && (m[u] = i);
|
|
217
|
+
Object.keys(m).length && (n[a] = m);
|
|
218
|
+
}
|
|
219
|
+
return n;
|
|
220
|
+
}
|
|
221
|
+
function Ze(e, n, s) {
|
|
222
|
+
const a = /* @__PURE__ */ new Set(), f = [];
|
|
223
|
+
for (const l of e) {
|
|
224
|
+
const m = s("collections", l.name, `./collections/${l.name}/${l.first}`);
|
|
225
|
+
f.push(` export const ${l.name}: (${m})[]`), a.add(l.name);
|
|
226
|
+
}
|
|
227
|
+
for (const l of n)
|
|
228
|
+
a.has(l) || f.push(` export const ${l}: OknoUnscaffolded[]`);
|
|
229
|
+
return ['declare module "okno:collections" {', ...f, "}", ""];
|
|
230
|
+
}
|
|
231
|
+
function Xe(e) {
|
|
232
|
+
const n = g(e, "schema.ts");
|
|
233
|
+
if (!_(n)) return null;
|
|
234
|
+
try {
|
|
235
|
+
let s = b(n, "utf8");
|
|
236
|
+
const a = s.indexOf("export default");
|
|
237
|
+
return a === -1 ? null : (s = s.slice(a + 14).replace(/\bas const\b/g, "").replace(/\bsatisfies\s+[A-Za-z0-9_.]+/g, "").trim(), s.endsWith(";") && (s = s.slice(0, -1).trim()), JSON.parse(s));
|
|
238
|
+
} catch {
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
function qe(e) {
|
|
243
|
+
const n = g(e, "strings.ts");
|
|
244
|
+
if (!_(n)) return [];
|
|
245
|
+
try {
|
|
246
|
+
let s = b(n, "utf8");
|
|
247
|
+
const a = s.indexOf("export default");
|
|
248
|
+
if (a === -1) return [];
|
|
249
|
+
s = s.slice(a + 14).replace(/\bas const\b/g, "").replace(/\bsatisfies\s+[A-Za-z0-9_.]+/g, "").trim(), s.endsWith(";") && (s = s.slice(0, -1).trim());
|
|
250
|
+
const f = JSON.parse(s);
|
|
251
|
+
return f && typeof f == "object" && !Array.isArray(f) ? Object.keys(f) : [];
|
|
252
|
+
} catch {
|
|
253
|
+
return [];
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
async function Qe(e) {
|
|
257
|
+
const n = g(e, "collections");
|
|
258
|
+
if (!_(n)) return [];
|
|
259
|
+
const s = (await x(n, { withFileTypes: !0 })).filter((f) => f.isDirectory()), a = [];
|
|
260
|
+
for (const f of s) {
|
|
261
|
+
const l = await Q(g(n, f.name));
|
|
262
|
+
l.length > 0 && a.push({ name: f.name, first: l[0] });
|
|
263
|
+
}
|
|
264
|
+
return a;
|
|
265
|
+
}
|
|
266
|
+
async function Q(e) {
|
|
267
|
+
return _(e) ? (await x(e)).filter((s) => s.endsWith(".ts") && s !== "index.ts" && s !== "modules.d.ts").map((s) => s.replace(".ts", "")) : [];
|
|
268
|
+
}
|
|
269
|
+
function te(e) {
|
|
270
|
+
try {
|
|
271
|
+
return ee(e, { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
272
|
+
} catch {
|
|
273
|
+
return null;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
function Ye() {
|
|
277
|
+
const e = te("git rev-parse --abbrev-ref HEAD");
|
|
278
|
+
if (e && e !== "HEAD") return e;
|
|
279
|
+
const n = process.env;
|
|
280
|
+
return n.CF_PAGES_BRANCH || // Cloudflare Pages
|
|
281
|
+
n.VERCEL_GIT_COMMIT_REF || // Vercel
|
|
282
|
+
n.BRANCH || // Netlify
|
|
283
|
+
n.GITHUB_REF_NAME || // GitHub Actions
|
|
284
|
+
"main";
|
|
285
|
+
}
|
|
286
|
+
function kt() {
|
|
287
|
+
const e = te("git remote get-url origin");
|
|
288
|
+
if (!e) return null;
|
|
289
|
+
const n = e.match(/github\.com[:/]([^/]+)\/([^/]+?)(?:\.git)?\/?$/);
|
|
290
|
+
return n ? `${n[1]}/${n[2]}@${Ye()}` : null;
|
|
291
|
+
}
|
|
292
|
+
function wt() {
|
|
293
|
+
const e = te("git rev-parse --show-toplevel");
|
|
294
|
+
return e ? U(e, process.cwd()).split(I).join("/") : "";
|
|
295
|
+
}
|
|
296
|
+
const ne = '__oknoSetImages(import.meta.glob("/okno/files/**/*.{png,jpg,jpeg,webp,avif,gif,svg,tiff}", { eager: false }))', fe = P(be(import.meta.url)), De = [
|
|
297
|
+
ie(fe, "./runtime/wrap.js"),
|
|
298
|
+
// bundled at dist/ (Vite plugin chunk)
|
|
299
|
+
ie(fe, "../runtime/wrap.js")
|
|
300
|
+
// bundled at dist/next/ (Next entry)
|
|
301
|
+
];
|
|
302
|
+
function St() {
|
|
303
|
+
for (const e of De)
|
|
304
|
+
if (_(e)) return b(e, "utf-8");
|
|
305
|
+
return null;
|
|
306
|
+
}
|
|
307
|
+
function bt() {
|
|
308
|
+
return [
|
|
309
|
+
'export * as pages from "okno:pages"',
|
|
310
|
+
'export * as globals from "okno:globals"',
|
|
311
|
+
'export * as collections from "okno:collections"',
|
|
312
|
+
'export { strings } from "okno:strings"'
|
|
313
|
+
].join(`
|
|
314
|
+
`);
|
|
315
|
+
}
|
|
316
|
+
function B(e) {
|
|
317
|
+
const n = g(e, "schema.ts");
|
|
318
|
+
if (!_(n)) return null;
|
|
319
|
+
try {
|
|
320
|
+
const a = J(b(n, "utf-8"))?.locales?.supported;
|
|
321
|
+
if (!Array.isArray(a) || a.length === 0) return null;
|
|
322
|
+
const f = a.map((l) => typeof l == "string" ? l : l?.id).filter((l) => typeof l == "string");
|
|
323
|
+
return f.length ? new Set(f) : null;
|
|
324
|
+
} catch {
|
|
325
|
+
return null;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
function C(e, n) {
|
|
329
|
+
return n ? n.has(e) : nt.test(e);
|
|
330
|
+
}
|
|
331
|
+
function et(e) {
|
|
332
|
+
for (const n of [e, "en"])
|
|
333
|
+
try {
|
|
334
|
+
const s = new Intl.DisplayNames([n], { type: "language" }).of(e);
|
|
335
|
+
if (s && s !== e) return s;
|
|
336
|
+
} catch {
|
|
337
|
+
}
|
|
338
|
+
return e;
|
|
339
|
+
}
|
|
340
|
+
async function se(e) {
|
|
341
|
+
return _(e) ? (await x(e)).filter((s) => s.endsWith(".ts") && s !== "index.ts") : [];
|
|
342
|
+
}
|
|
343
|
+
function tt(e) {
|
|
344
|
+
const n = g(e, "schema.ts"), s = {}, a = /* @__PURE__ */ new Set();
|
|
345
|
+
if (!_(n)) return { orders: s, drafts: a };
|
|
346
|
+
try {
|
|
347
|
+
const l = J(b(n, "utf-8"))?.collections ?? {};
|
|
348
|
+
for (const [m, u] of Object.entries(l))
|
|
349
|
+
Array.isArray(u?.order) && (s[m] = u.order.filter((i) => typeof i == "string")), u?.drafts === !0 && a.add(m);
|
|
350
|
+
} catch {
|
|
351
|
+
}
|
|
352
|
+
return { orders: s, drafts: a };
|
|
353
|
+
}
|
|
354
|
+
const nt = /^[a-z]{2,3}(-[a-z]{4})?(-([a-z]{2}|[0-9]{3}))?$/i, G = (e) => e.replace(/[^a-zA-Z0-9]/g, "_");
|
|
355
|
+
function oe(e) {
|
|
356
|
+
return e.replace(".ts", "").replace(/-/g, "_");
|
|
357
|
+
}
|
|
358
|
+
function he(e) {
|
|
359
|
+
return e.replace(".ts", "").replace(/-/g, "_");
|
|
360
|
+
}
|
|
361
|
+
function V(e) {
|
|
362
|
+
return e.replace(".ts", "");
|
|
363
|
+
}
|
|
364
|
+
function vt(e) {
|
|
365
|
+
const n = g(e, "schema.ts");
|
|
366
|
+
let s = [], a = "";
|
|
367
|
+
if (_(n))
|
|
368
|
+
try {
|
|
369
|
+
const f = J(b(n, "utf-8")), l = f?.locales?.supported;
|
|
370
|
+
Array.isArray(l) && (s = l.map((m) => typeof m == "string" ? { id: m } : m).filter((m) => !!m && typeof m.id == "string").map((m) => ({
|
|
371
|
+
id: m.id,
|
|
372
|
+
name: m.name || et(m.id),
|
|
373
|
+
// Preserve an intentionally empty slug (= no URL prefix for the default).
|
|
374
|
+
slug: typeof m.slug == "string" ? m.slug : m.id.toLowerCase()
|
|
375
|
+
})), a = typeof f.locales.default == "string" ? f.locales.default : s[0]?.id ?? "");
|
|
376
|
+
} catch {
|
|
377
|
+
}
|
|
378
|
+
return [
|
|
379
|
+
`const __raw = ${JSON.stringify(s)}`,
|
|
380
|
+
`const __def = ${JSON.stringify(a)}`,
|
|
381
|
+
// Swap the locale prefix on a path (empty slug = no prefix). Best-effort,
|
|
382
|
+
// matches the editor's own resolver; fully translated paths = dev's own tags.
|
|
383
|
+
"function __swap(pathname, slug) {",
|
|
384
|
+
' const norm = (pathname || "/").replace(/\\/+$/, "") || "/"',
|
|
385
|
+
' const segs = norm.split("/").filter(Boolean)',
|
|
386
|
+
" const known = __raw.find((l) => l.slug && l.slug === segs[0])",
|
|
387
|
+
' const rest = known ? "/" + segs.slice(1).join("/") : norm',
|
|
388
|
+
' const r = rest === "" ? "/" : rest',
|
|
389
|
+
" if (!slug) return r",
|
|
390
|
+
' return r === "/" ? "/" + slug : "/" + slug + r',
|
|
391
|
+
"}",
|
|
392
|
+
'const __origin = (url) => (typeof url === "object" && url !== null ? url.origin : "")',
|
|
393
|
+
'const __path = (url) => (typeof url === "object" && url !== null ? url.pathname : String(url || "/"))',
|
|
394
|
+
"/** The configured languages — an array of { id, name, slug, link(url) }.",
|
|
395
|
+
" * link(url) → this entry's hreflang <link> descriptor (spread onto a <link>;",
|
|
396
|
+
" * pass Astro.url for an absolute href). `locales.default` is the base entry. */",
|
|
397
|
+
"export const locales = __raw.map((l) => ({",
|
|
398
|
+
" ...l,",
|
|
399
|
+
' link: (url) => ({ rel: "alternate", hreflang: l.id, href: __origin(url) + __swap(__path(url), l.slug) }),',
|
|
400
|
+
"}))",
|
|
401
|
+
// `.default` = the base-locale entry (same object reference as in the array).
|
|
402
|
+
"locales.default = locales.find((l) => l.id === __def) || locales[0]"
|
|
403
|
+
].join(`
|
|
404
|
+
`);
|
|
405
|
+
}
|
|
406
|
+
async function Ot(e) {
|
|
407
|
+
const n = g(e, "strings.ts");
|
|
408
|
+
if (!_(n))
|
|
409
|
+
return [
|
|
410
|
+
'import { __oknoMakeStrings } from "okno:runtime"',
|
|
411
|
+
'export const strings = __oknoMakeStrings({}, {}, "")'
|
|
412
|
+
].join(`
|
|
413
|
+
`);
|
|
414
|
+
const s = g(e, "schema.ts"), a = _(s), f = B(e), l = g(e, "strings"), m = [];
|
|
415
|
+
if (_(l)) {
|
|
416
|
+
const r = await x(l, { withFileTypes: !0 });
|
|
417
|
+
for (const p of r) {
|
|
418
|
+
if (!p.isFile() || !p.name.endsWith(".ts") || p.name === "index.ts") continue;
|
|
419
|
+
const c = p.name.replace(/\.ts$/, "");
|
|
420
|
+
C(c, f) && m.push(c);
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
const u = [
|
|
424
|
+
'import { __oknoMakeStrings, __oknoLocalize, __oknoExpandStrings } from "okno:runtime"',
|
|
425
|
+
`import _strings_default from "${n}"`
|
|
426
|
+
];
|
|
427
|
+
a && u.push(`import __schema from "${s}"`);
|
|
428
|
+
const i = a ? "__schema?.strings" : "{}", t = a ? "__schema?.locales?.default" : '""';
|
|
429
|
+
if (m.length === 0)
|
|
430
|
+
return u.push(`export const strings = __oknoMakeStrings(__oknoExpandStrings(_strings_default), ${i}, ${t})`), u.join(`
|
|
431
|
+
`);
|
|
432
|
+
const o = [];
|
|
433
|
+
for (const r of m) {
|
|
434
|
+
const p = G(r);
|
|
435
|
+
u.push(`import _strings_${p} from "${g(l, r + ".ts")}"`), o.push(`"${r}": __oknoExpandStrings(_strings_${p})`);
|
|
436
|
+
}
|
|
437
|
+
return u.push("const _strings_base = __oknoExpandStrings(_strings_default)"), u.push(`const _strings_localized = __oknoLocalize(_strings_base, { ${o.join(", ")} })`), u.push(`export const strings = __oknoMakeStrings(_strings_localized, ${i}, ${t})`), u.join(`
|
|
438
|
+
`);
|
|
439
|
+
}
|
|
440
|
+
async function jt(e, n = /* @__PURE__ */ new Set()) {
|
|
441
|
+
const s = g(e, "pages"), a = g(e, "schema.ts"), f = _(a), l = [
|
|
442
|
+
'import { __oknoWrap, __oknoLocalize, __oknoResolveRefs, __oknoResolveEnums, __oknoSetImages } from "okno:runtime"',
|
|
443
|
+
ne
|
|
444
|
+
];
|
|
445
|
+
f && (l.push('import * as __collections from "okno:collections"'), l.push(`import __schema from "${a}"`));
|
|
446
|
+
let m = "[]";
|
|
447
|
+
const u = (t, o) => {
|
|
448
|
+
if (!f) return `_${t}`;
|
|
449
|
+
const r = `__schema?.pages?.["${o}"]?.fields`;
|
|
450
|
+
return `__oknoResolveEnums(__oknoResolveRefs(_${t}, ${r}, __collections, ${m}), ${r}, ${m})`;
|
|
451
|
+
}, i = /* @__PURE__ */ new Set();
|
|
452
|
+
if (_(s)) {
|
|
453
|
+
const t = B(e), r = (await x(s, { withFileTypes: !0 })).filter((c) => c.isDirectory() && C(c.name, t)).map((c) => c.name);
|
|
454
|
+
m = JSON.stringify(r);
|
|
455
|
+
const p = await se(s);
|
|
456
|
+
for (const c of p) {
|
|
457
|
+
const h = oe(c), d = he(c), y = V(c), $ = g(s, c);
|
|
458
|
+
if (r.length === 0) {
|
|
459
|
+
l.push(`import _${h} from "${$}"`), l.push(`export const ${d} = __oknoWrap(${u(h, y)}, "${y}")`), i.add(d);
|
|
460
|
+
continue;
|
|
461
|
+
}
|
|
462
|
+
const k = [`import _${h}_default from "${$}"`], v = [];
|
|
463
|
+
for (const O of r) {
|
|
464
|
+
const w = g(s, O, c);
|
|
465
|
+
if (_(w)) {
|
|
466
|
+
const S = G(O);
|
|
467
|
+
k.push(`import _${h}_${S} from "${w}"`), v.push(`"${O}": _${h}_${S}`);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
l.push(...k), l.push(`const _${h} = __oknoLocalize(_${h}_default, { ${v.join(", ")} })`), l.push(`export const ${d} = __oknoWrap(${u(h, y)}, "${y}")`), i.add(d);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
for (const t of n)
|
|
474
|
+
i.has(t) || l.push(`export const ${t} = __oknoWrap(null, "${t}")`);
|
|
475
|
+
return l.join(`
|
|
476
|
+
`);
|
|
477
|
+
}
|
|
478
|
+
async function Tt(e, n = /* @__PURE__ */ new Set(), s = !1) {
|
|
479
|
+
const a = g(e, "collections");
|
|
480
|
+
if (!_(a)) {
|
|
481
|
+
const d = [];
|
|
482
|
+
for (const y of n) {
|
|
483
|
+
const $ = y.replace(/-/g, "_");
|
|
484
|
+
d.push(`export const ${$} = []`);
|
|
485
|
+
}
|
|
486
|
+
return d.join(`
|
|
487
|
+
`) || "export {}";
|
|
488
|
+
}
|
|
489
|
+
const f = B(e), l = await x(a, { withFileTypes: !0 }), m = l.filter((d) => d.isDirectory() && C(d.name, f)).map((d) => d.name), u = l.filter((d) => d.isDirectory() && !m.includes(d.name)).map((d) => d.name), i = JSON.stringify(m);
|
|
490
|
+
for (const d of u) {
|
|
491
|
+
const y = await x(g(a, d), { withFileTypes: !0 }).catch(() => []);
|
|
492
|
+
for (const $ of y)
|
|
493
|
+
$.isDirectory() && C($.name, f) && console.warn(
|
|
494
|
+
`[okno] "collections/${d}/${$.name}/" looks like a misplaced locale folder. Collection locale overrides go at "collections/${$.name}/${d}/<slug>.ts" (locale right after "collections/"). This folder will NOT be localized.`
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
const { orders: t, drafts: o } = tt(e), r = g(e, "schema.ts"), p = _(r), c = [
|
|
498
|
+
'import { __oknoWrap, __oknoLocalize, __oknoResolveRefs, __oknoResolveEnums, __oknoSetImages } from "okno:runtime"',
|
|
499
|
+
ne
|
|
500
|
+
];
|
|
501
|
+
p && c.push(`import __schema from "${r}"`);
|
|
502
|
+
const h = [];
|
|
503
|
+
for (const d of u) {
|
|
504
|
+
const y = g(a, d), $ = je(await se(y), V, t[d]), k = d.replace(/-/g, "_"), v = s && o.has(d), O = [];
|
|
505
|
+
for (const w of $) {
|
|
506
|
+
const S = `_${k}_${oe(w)}`, R = V(w), K = g(y, w);
|
|
507
|
+
if (m.length === 0)
|
|
508
|
+
c.push(`import ${S} from "${K}"`);
|
|
509
|
+
else {
|
|
510
|
+
const F = [`import ${S}_default from "${K}"`], A = [];
|
|
511
|
+
for (const H of m) {
|
|
512
|
+
const re = g(a, H, d, w);
|
|
513
|
+
if (_(re)) {
|
|
514
|
+
const ae = G(H);
|
|
515
|
+
F.push(`import ${S}_${ae} from "${re}"`), A.push(`"${H}": ${S}_${ae}`);
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
c.push(...F), c.push(`const ${S} = __oknoLocalize(${S}_default, { ${A.join(", ")} })`);
|
|
519
|
+
}
|
|
520
|
+
O.push({ varName: S, itemName: R });
|
|
521
|
+
}
|
|
522
|
+
c.push(`const __oknoRaw_${k} = [${O.map((w) => w.varName).join(", ")}]`), h.push({ name: d, safe: k, draftsOn: v, items: O });
|
|
523
|
+
}
|
|
524
|
+
p && c.push(`const __oknoNs = { ${h.map((d) => `${d.safe}: __oknoRaw_${d.safe}`).join(", ")} }`);
|
|
525
|
+
for (const d of h) {
|
|
526
|
+
const y = (k) => {
|
|
527
|
+
const v = `__schema?.collections?.["${d.name}"]?.fields`;
|
|
528
|
+
return `__oknoWrap(${p ? `__oknoResolveEnums(__oknoResolveRefs(${k.varName}, ${v}, __oknoNs, ${i}), ${v}, ${i})` : k.varName}, "${d.name}.${k.itemName}")`;
|
|
529
|
+
}, $ = d.draftsOn ? `[${d.items.map((k) => `[${k.varName}, ${y(k)}]`).join(", ")}].filter((e) => e[0]?.status !== "draft").map((e) => e[1])` : `[${d.items.map(y).join(", ")}]`;
|
|
530
|
+
c.push(`export const ${d.safe} = ${$}`);
|
|
531
|
+
}
|
|
532
|
+
return c.join(`
|
|
533
|
+
`);
|
|
534
|
+
}
|
|
535
|
+
async function At(e, n = /* @__PURE__ */ new Set()) {
|
|
536
|
+
const s = g(e, "globals"), a = g(e, "schema.ts"), f = _(a), l = [
|
|
537
|
+
'import { __oknoWrap, __oknoLocalize, __oknoResolveRefs, __oknoResolveEnums, __oknoSetImages } from "okno:runtime"',
|
|
538
|
+
ne
|
|
539
|
+
];
|
|
540
|
+
f && (l.push('import * as __collections from "okno:collections"'), l.push(`import __schema from "${a}"`));
|
|
541
|
+
let m = "[]";
|
|
542
|
+
const u = (t, o) => {
|
|
543
|
+
if (!f) return `_${t}`;
|
|
544
|
+
const r = `__schema?.globals?.["${o}"]?.fields`;
|
|
545
|
+
return `__oknoResolveEnums(__oknoResolveRefs(_${t}, ${r}, __collections, ${m}), ${r}, ${m})`;
|
|
546
|
+
}, i = /* @__PURE__ */ new Set();
|
|
547
|
+
if (_(s)) {
|
|
548
|
+
const t = B(e), r = (await x(s, { withFileTypes: !0 })).filter((c) => c.isDirectory() && C(c.name, t)).map((c) => c.name);
|
|
549
|
+
m = JSON.stringify(r);
|
|
550
|
+
const p = await se(s);
|
|
551
|
+
for (const c of p) {
|
|
552
|
+
const h = oe(c), d = he(c), y = V(c), $ = g(s, c);
|
|
553
|
+
if (r.length === 0) {
|
|
554
|
+
l.push(`import _${h} from "${$}"`), l.push(`export const ${d} = __oknoWrap(${u(h, y)}, "${y}")`), i.add(d);
|
|
555
|
+
continue;
|
|
556
|
+
}
|
|
557
|
+
const k = [`import _${h}_default from "${$}"`], v = [];
|
|
558
|
+
for (const O of r) {
|
|
559
|
+
const w = g(s, O, c);
|
|
560
|
+
if (_(w)) {
|
|
561
|
+
const S = G(O);
|
|
562
|
+
k.push(`import _${h}_${S} from "${w}"`), v.push(`"${O}": _${h}_${S}`);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
l.push(...k), l.push(`const _${h} = __oknoLocalize(_${h}_default, { ${v.join(", ")} })`), l.push(`export const ${d} = __oknoWrap(${u(h, y)}, "${y}")`), i.add(d);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
for (const t of n)
|
|
569
|
+
i.has(t) || l.push(`export const ${t} = __oknoWrap(null, "${t}")`);
|
|
570
|
+
return l.join(`
|
|
571
|
+
`);
|
|
572
|
+
}
|
|
573
|
+
const ge = /* @__PURE__ */ new Map();
|
|
574
|
+
function N(e) {
|
|
575
|
+
ge.set(e, Date.now());
|
|
576
|
+
}
|
|
577
|
+
function xt(e) {
|
|
578
|
+
const n = ge.get(e);
|
|
579
|
+
return n !== void 0 && Date.now() - n < 3e3;
|
|
580
|
+
}
|
|
581
|
+
const st = ["pages", "collections", "globals"];
|
|
582
|
+
function E(e, n) {
|
|
583
|
+
if (!n || n.includes("..") || n.includes("\0") || n.startsWith("/") || !n.endsWith(".ts")) return null;
|
|
584
|
+
const s = g(e, n);
|
|
585
|
+
return s !== e && !s.startsWith(e + I) ? null : s;
|
|
586
|
+
}
|
|
587
|
+
function W(e, n) {
|
|
588
|
+
if (!n || n.includes("..") || n.includes("\0") || n.startsWith("/")) return null;
|
|
589
|
+
const s = g(e, n);
|
|
590
|
+
return s !== e && !s.startsWith(e + I) ? null : s;
|
|
591
|
+
}
|
|
592
|
+
function ot(e) {
|
|
593
|
+
const n = {}, s = (f) => {
|
|
594
|
+
if (_(f))
|
|
595
|
+
for (const l of D(f, { withFileTypes: !0 })) {
|
|
596
|
+
const m = g(f, l.name);
|
|
597
|
+
if (l.isDirectory()) s(m);
|
|
598
|
+
else if (l.name.endsWith(".ts") && l.name !== "index.ts") {
|
|
599
|
+
const u = U(e, m).split(I).join("/");
|
|
600
|
+
n[u] = b(m, "utf-8");
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
};
|
|
604
|
+
for (const f of st) s(g(e, f));
|
|
605
|
+
const a = g(e, "strings.ts");
|
|
606
|
+
return _(a) && (n["strings.ts"] = b(a, "utf-8")), s(g(e, "strings")), n;
|
|
607
|
+
}
|
|
608
|
+
function ye(e) {
|
|
609
|
+
const n = g(e, "files"), s = [], a = (f) => {
|
|
610
|
+
if (_(f))
|
|
611
|
+
for (const l of D(f, { withFileTypes: !0 })) {
|
|
612
|
+
const m = g(f, l.name);
|
|
613
|
+
if (l.isDirectory()) a(m);
|
|
614
|
+
else if (l.name !== ".okno-tree.json") {
|
|
615
|
+
const u = U(n, m).split(I).join("/");
|
|
616
|
+
s.push({ path: `files/${u}`, filename: l.name, size: ke(m).size });
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
};
|
|
620
|
+
return a(n), s;
|
|
621
|
+
}
|
|
622
|
+
function rt(e) {
|
|
623
|
+
const n = g(e, "schema.ts"), s = g(e, "users.json"), a = g(e, "settings.json"), f = g(e, "origins.json");
|
|
624
|
+
return {
|
|
625
|
+
schema: _(n) ? b(n, "utf-8") : null,
|
|
626
|
+
users: _(s) ? b(s, "utf-8") : null,
|
|
627
|
+
settings: _(a) ? b(a, "utf-8") : null,
|
|
628
|
+
origins: _(f) ? b(f, "utf-8") : null,
|
|
629
|
+
content: ot(e),
|
|
630
|
+
files: ye(e)
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
const me = (e) => e.replace(/[^a-zA-Z0-9._-]/g, "-"), de = (e) => e.split("/").map((n) => n.replace(/[^a-zA-Z0-9._-]/g, "-")).filter((n) => n && n !== "-" && n !== "..").join("/");
|
|
634
|
+
function j(e) {
|
|
635
|
+
const n = g(e, "schema.ts");
|
|
636
|
+
let s = `import type { Schema } from "okno"
|
|
637
|
+
|
|
638
|
+
`, a = {};
|
|
639
|
+
if (_(n)) {
|
|
640
|
+
const f = b(n, "utf-8"), l = f.indexOf("export default");
|
|
641
|
+
l > 0 && (s = f.slice(0, l));
|
|
642
|
+
try {
|
|
643
|
+
a = J(f) ?? {};
|
|
644
|
+
} catch {
|
|
645
|
+
a = {};
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
return { schema: a, header: s };
|
|
649
|
+
}
|
|
650
|
+
function at(e, n, s) {
|
|
651
|
+
T(g(e, "schema.ts"), ve(n, s));
|
|
652
|
+
}
|
|
653
|
+
function it(e, n, s, a, f) {
|
|
654
|
+
const l = g(e, n), m = new Set(f), u = [];
|
|
655
|
+
if (!_(l) || Object.keys(a).length === 0 && m.size === 0) return u;
|
|
656
|
+
const i = [], t = (o) => {
|
|
657
|
+
for (const r of D(o, { withFileTypes: !0 })) {
|
|
658
|
+
const p = g(o, r.name);
|
|
659
|
+
r.isDirectory() ? t(p) : r.name === `${s}.ts` && i.push(p);
|
|
660
|
+
}
|
|
661
|
+
};
|
|
662
|
+
t(l);
|
|
663
|
+
for (const o of i) {
|
|
664
|
+
let r;
|
|
665
|
+
try {
|
|
666
|
+
r = J(b(o, "utf-8"));
|
|
667
|
+
} catch {
|
|
668
|
+
continue;
|
|
669
|
+
}
|
|
670
|
+
let p, c = !1;
|
|
671
|
+
if (Array.isArray(r))
|
|
672
|
+
p = r.map((d) => {
|
|
673
|
+
if (d && typeof d == "object" && !Array.isArray(d)) {
|
|
674
|
+
const y = ce(d, a, m);
|
|
675
|
+
return y.changed && (c = !0), y.out;
|
|
676
|
+
}
|
|
677
|
+
return d;
|
|
678
|
+
});
|
|
679
|
+
else if (r && typeof r == "object") {
|
|
680
|
+
const d = ce(r, a, m);
|
|
681
|
+
p = d.out, c = d.changed;
|
|
682
|
+
} else
|
|
683
|
+
continue;
|
|
684
|
+
if (!c) continue;
|
|
685
|
+
N(o), T(o, q(p));
|
|
686
|
+
const h = U(e, o).split(I).join("/");
|
|
687
|
+
u.push({ rel: h, abs: o }), console.log(`[okno] field-change migrated content: ${h}`, { renames: a, deletes: f });
|
|
688
|
+
}
|
|
689
|
+
return u;
|
|
690
|
+
}
|
|
691
|
+
let X;
|
|
692
|
+
function Y(e) {
|
|
693
|
+
return X || (X = ee("git rev-parse --show-toplevel", { cwd: e, encoding: "utf-8" }).trim()), X;
|
|
694
|
+
}
|
|
695
|
+
function pe(e) {
|
|
696
|
+
return U(Y(e), we(e)).split(I).join("/");
|
|
697
|
+
}
|
|
698
|
+
let z;
|
|
699
|
+
function lt(e) {
|
|
700
|
+
if (z !== void 0) return z;
|
|
701
|
+
try {
|
|
702
|
+
z = ee("git config user.name", { cwd: e, encoding: "utf-8" }).trim() || "local";
|
|
703
|
+
} catch {
|
|
704
|
+
z = "local";
|
|
705
|
+
}
|
|
706
|
+
return z;
|
|
707
|
+
}
|
|
708
|
+
async function Pt(e, n) {
|
|
709
|
+
const { method: s, route: a } = n, f = { files: [], modules: [] }, l = (t, o) => {
|
|
710
|
+
const r = t.split("/")[0];
|
|
711
|
+
r !== "pages" && r !== "collections" && r !== "globals" || (f.modules.push(r), f.files.push(o));
|
|
712
|
+
}, m = () => f.modules.push("pages", "collections", "globals"), u = (t, o) => {
|
|
713
|
+
at(e, t, o), m();
|
|
714
|
+
}, i = (t, o) => ({ status: t, body: o, invalidation: f });
|
|
715
|
+
try {
|
|
716
|
+
if (s === "GET" && a === "content") return i(200, rt(e));
|
|
717
|
+
if (s === "POST" && a === "content/save") {
|
|
718
|
+
const { path: t, content: o, created: r, author: p } = await n.json();
|
|
719
|
+
if (!t || !o) return i(400, { error: "Missing path or content" });
|
|
720
|
+
const c = E(e, t);
|
|
721
|
+
if (!c) return i(400, { error: "Invalid path" });
|
|
722
|
+
const h = Oe(o, { now: (/* @__PURE__ */ new Date()).toISOString(), author: p || lt(e), created: r });
|
|
723
|
+
return M(P(c), { recursive: !0 }), N(c), T(c, h), l(t, c), i(200, { ok: !0, commit: { fileSha: "" } });
|
|
724
|
+
}
|
|
725
|
+
if (s === "POST" && a === "content/delete") {
|
|
726
|
+
const t = (await n.json())?.path;
|
|
727
|
+
if (!t) return i(400, { error: "Missing path" });
|
|
728
|
+
const o = E(e, t);
|
|
729
|
+
return o ? (_(o) && (L(o), l(t, o)), i(200, { ok: !0 })) : i(400, { error: "Invalid path" });
|
|
730
|
+
}
|
|
731
|
+
if (s === "POST" && a === "strings/save") {
|
|
732
|
+
const { path: t, content: o } = await n.json();
|
|
733
|
+
if (!t || !o || typeof o != "object") return i(400, { error: "Missing path or content" });
|
|
734
|
+
if (t !== "strings.ts" && !/^strings\/[^/]+\.ts$/.test(t)) return i(400, { error: "Invalid strings path" });
|
|
735
|
+
const r = E(e, t);
|
|
736
|
+
return r ? (M(P(r), { recursive: !0 }), N(r), T(r, q(o)), f.modules.push("strings", "content"), f.files.push(r), i(200, { ok: !0, commit: { fileSha: "" } })) : i(400, { error: "Invalid path" });
|
|
737
|
+
}
|
|
738
|
+
if (s === "POST" && a === "strings/set-schema") {
|
|
739
|
+
const { strings: t } = await n.json();
|
|
740
|
+
if (t != null && (typeof t != "object" || Array.isArray(t))) return i(400, { error: "Invalid strings" });
|
|
741
|
+
const { schema: o, header: r } = j(e);
|
|
742
|
+
return Te(o, t), u(o, r), f.modules.push("strings", "content"), i(200, { ok: !0, commit: { fileSha: "" }, schema: o });
|
|
743
|
+
}
|
|
744
|
+
if (s === "GET" && a === "publish-state")
|
|
745
|
+
try {
|
|
746
|
+
const o = await le(Y(e)).status(), r = pe(e), p = o.files.some((c) => c.path.startsWith(r + "/"));
|
|
747
|
+
return i(200, { pendingPublish: p || o.ahead > 0 });
|
|
748
|
+
} catch {
|
|
749
|
+
return i(200, { pendingPublish: !1 });
|
|
750
|
+
}
|
|
751
|
+
if (s === "POST" && a === "publish") {
|
|
752
|
+
const t = le(Y(e)), o = pe(e);
|
|
753
|
+
await t.raw(["add", "-A", "--", o]);
|
|
754
|
+
const r = await t.status(), p = r.staged.length > 0;
|
|
755
|
+
let c = !1;
|
|
756
|
+
p && (await t.commit("okno: publish content"), c = !0);
|
|
757
|
+
let h = !1, d = null;
|
|
758
|
+
try {
|
|
759
|
+
(c || r.ahead > 0) && (await t.push(), h = !0);
|
|
760
|
+
} catch (y) {
|
|
761
|
+
d = y instanceof Error ? y.message.split(`
|
|
762
|
+
`)[0] : String(y);
|
|
763
|
+
}
|
|
764
|
+
return i(200, { ok: !0, alreadyUpToDate: !c && r.ahead === 0, committed: c, pushed: h, pushError: d });
|
|
765
|
+
}
|
|
766
|
+
if (s === "POST" && a === "schema/save-fields") {
|
|
767
|
+
const { kind: t, name: o, fields: r, renames: p, deletes: c } = await n.json();
|
|
768
|
+
if (!t || !o || !r) return i(400, { error: "Missing kind, name or fields" });
|
|
769
|
+
const { schema: h, header: d } = j(e);
|
|
770
|
+
Ae(h, t, o, r), u(h, d);
|
|
771
|
+
const y = p && typeof p == "object" ? p : {}, $ = Array.isArray(c) ? c : [];
|
|
772
|
+
if (Object.keys(y).length > 0 || $.length > 0)
|
|
773
|
+
for (const { rel: k, abs: v } of it(e, t, o, y, $)) l(k, v);
|
|
774
|
+
return i(200, { ok: !0, commit: { fileSha: "" }, schema: h });
|
|
775
|
+
}
|
|
776
|
+
if (s === "POST" && a === "schema/set-locales") {
|
|
777
|
+
const t = (await n.json())?.locales, { schema: o, header: r } = j(e);
|
|
778
|
+
return xe(o, t), u(o, r), i(200, { ok: !0, commit: { fileSha: "" } });
|
|
779
|
+
}
|
|
780
|
+
if (s === "POST" && a === "schema/set-name") {
|
|
781
|
+
const { kind: t, slug: o, name: r } = await n.json();
|
|
782
|
+
if (!t || !o || !r) return i(400, { error: "Missing kind, slug or name" });
|
|
783
|
+
const { schema: p, header: c } = j(e);
|
|
784
|
+
return Pe(p, t, o, r), u(p, c), i(200, { ok: !0, commit: { fileSha: "" } });
|
|
785
|
+
}
|
|
786
|
+
if (s === "POST" && a === "schema/set-url") {
|
|
787
|
+
const { kind: t, slug: o, url: r } = await n.json();
|
|
788
|
+
if (!t || !o) return i(400, { error: "Missing kind or slug" });
|
|
789
|
+
const { schema: p, header: c } = j(e);
|
|
790
|
+
return Re(p, t, o, r), u(p, c), i(200, { ok: !0, commit: { fileSha: "" } });
|
|
791
|
+
}
|
|
792
|
+
if (s === "POST" && a === "schema/rename-slug") {
|
|
793
|
+
const { kind: t, from: o, to: r } = await n.json();
|
|
794
|
+
if (!t || !o || !r) return i(400, { error: "Missing kind, from or to" });
|
|
795
|
+
const { schema: p, header: c } = j(e), { unchanged: h } = Me(p, t, o, r);
|
|
796
|
+
if (h) return i(200, { ok: !0, unchanged: !0 });
|
|
797
|
+
u(p, c);
|
|
798
|
+
const d = `${t}/${o}.ts`, y = `${t}/${r}.ts`, $ = E(e, d), k = E(e, y);
|
|
799
|
+
return $ && k && _($) && (M(P(k), { recursive: !0 }), N($), N(k), T(k, b($)), L($), l(d, $), l(y, k)), i(200, { ok: !0, commit: { fileSha: "" }, schema: p, from: o, to: r, kind: t });
|
|
800
|
+
}
|
|
801
|
+
if (s === "POST" && a === "schema/reorder") {
|
|
802
|
+
const { kind: t, order: o } = await n.json();
|
|
803
|
+
if (!t || !Array.isArray(o)) return i(400, { error: "Missing kind or order" });
|
|
804
|
+
const { schema: r, header: p } = j(e);
|
|
805
|
+
return Ee(r, t, o), u(r, p), i(200, { ok: !0, commit: { fileSha: "" }, schema: r });
|
|
806
|
+
}
|
|
807
|
+
if (s === "POST" && a === "schema/set-layout") {
|
|
808
|
+
const { kind: t, layout: o } = await n.json();
|
|
809
|
+
if (!t || !Array.isArray(o)) return i(400, { error: "Missing kind or layout" });
|
|
810
|
+
const { schema: r, header: p } = j(e);
|
|
811
|
+
return Ne(r, t, o), u(r, p), i(200, { ok: !0, commit: { fileSha: "" }, schema: r });
|
|
812
|
+
}
|
|
813
|
+
if (s === "POST" && a === "collections/set-order") {
|
|
814
|
+
const { name: t, order: o } = await n.json();
|
|
815
|
+
if (!t || !Array.isArray(o)) return i(400, { error: "Missing name or order" });
|
|
816
|
+
const { schema: r, header: p } = j(e);
|
|
817
|
+
return Ie(r, t, o), u(r, p), i(200, { ok: !0, commit: { fileSha: "" }, schema: r });
|
|
818
|
+
}
|
|
819
|
+
if (s === "POST" && a === "collections/set-drafts") {
|
|
820
|
+
const { name: t, drafts: o } = await n.json();
|
|
821
|
+
if (!t || typeof o != "boolean") return i(400, { error: "Missing name or drafts" });
|
|
822
|
+
const { schema: r, header: p } = j(e);
|
|
823
|
+
return We(r, t, o), u(r, p), i(200, { ok: !0, commit: { fileSha: "" }, schema: r });
|
|
824
|
+
}
|
|
825
|
+
if (s === "POST" && a === "schema/delete-entry") {
|
|
826
|
+
const { kind: t, name: o } = await n.json();
|
|
827
|
+
if (!t || !o) return i(400, { error: "Missing kind or name" });
|
|
828
|
+
const { schema: r, header: p } = j(e);
|
|
829
|
+
Fe(r, t, o), u(r, p);
|
|
830
|
+
const c = `${t}/${o}.ts`, h = E(e, c);
|
|
831
|
+
return h && _(h) && (N(h), L(h), l(c, h)), i(200, { ok: !0, commit: { fileSha: "" }, schema: r });
|
|
832
|
+
}
|
|
833
|
+
if (s === "POST" && a === "setup/scaffold-page") {
|
|
834
|
+
const { name: t, kind: o, fields: r, label: p } = await n.json();
|
|
835
|
+
if (!t || !o) return i(400, { error: "Missing name or kind" });
|
|
836
|
+
const c = r ?? [], { schema: h, header: d } = j(e);
|
|
837
|
+
if (Le(h, t, o, c, p), u(h, d), o !== "blocks") {
|
|
838
|
+
const y = `${o}/${t}.ts`, $ = E(e, y);
|
|
839
|
+
if ($) {
|
|
840
|
+
const k = o === "collections" ? `export default []
|
|
841
|
+
` : q(ze(c));
|
|
842
|
+
M(P($), { recursive: !0 }), N($), T($, k), l(y, $);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
return i(200, { ok: !0 });
|
|
846
|
+
}
|
|
847
|
+
if (s === "GET" && a === "files") {
|
|
848
|
+
const t = g(e, "files", ".okno-tree.json");
|
|
849
|
+
return i(200, {
|
|
850
|
+
files: ye(e),
|
|
851
|
+
manifest: _(t) ? b(t, "utf-8") : null
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
if (s === "POST" && a === "files/blob") {
|
|
855
|
+
const t = me(decodeURIComponent(n.header("x-okno-filename") || "")), o = n.header("x-okno-dir") ? decodeURIComponent(n.header("x-okno-dir")) : "";
|
|
856
|
+
if (!t || t === "-") return i(400, { error: "Invalid filename" });
|
|
857
|
+
const r = de(o), p = r ? `${r}/${t}` : t, c = W(e, `files/${p}`);
|
|
858
|
+
if (!c) return i(400, { error: "Invalid path" });
|
|
859
|
+
const h = await n.binary();
|
|
860
|
+
return h.length === 0 ? i(400, { error: "Empty body" }) : (M(P(c), { recursive: !0 }), T(c, h), i(200, { ok: !0, blobSha: "", path: `files/${p}`, filename: t }));
|
|
861
|
+
}
|
|
862
|
+
if (s === "POST" && a === "files/commit") return i(200, { ok: !0 });
|
|
863
|
+
if (s === "POST" && a === "files/upload") {
|
|
864
|
+
const { filename: t, content: o, dir: r } = await n.json();
|
|
865
|
+
if (!t || o == null) return i(400, { error: "Missing filename or content" });
|
|
866
|
+
const p = me(t);
|
|
867
|
+
if (!p || p === "-") return i(400, { error: "Invalid filename" });
|
|
868
|
+
const c = de(r ?? ""), h = c ? `${c}/${p}` : p, d = W(e, `files/${h}`);
|
|
869
|
+
return d ? (M(P(d), { recursive: !0 }), T(d, Buffer.from(o, "base64")), i(200, { ok: !0, path: `files/${h}`, filename: p, commit: { fileSha: "" } })) : i(400, { error: "Invalid path" });
|
|
870
|
+
}
|
|
871
|
+
if (s === "POST" && a === "files/delete") {
|
|
872
|
+
const t = (await n.json())?.path;
|
|
873
|
+
if (!t) return i(400, { error: "Missing path" });
|
|
874
|
+
const o = W(e, t);
|
|
875
|
+
return o ? (_(o) && L(o), i(200, { ok: !0 })) : i(400, { error: "Invalid path" });
|
|
876
|
+
}
|
|
877
|
+
if (s === "POST" && a === "files/delete-many") {
|
|
878
|
+
const t = (await n.json())?.paths;
|
|
879
|
+
if (!Array.isArray(t)) return i(400, { error: "Missing paths" });
|
|
880
|
+
for (const o of t) {
|
|
881
|
+
const r = W(e, String(o));
|
|
882
|
+
r && _(r) && L(r);
|
|
883
|
+
}
|
|
884
|
+
return i(200, { ok: !0 });
|
|
885
|
+
}
|
|
886
|
+
if (s === "POST" && a === "files/rename") {
|
|
887
|
+
const { from: t, to: o } = await n.json();
|
|
888
|
+
if (!t || !o) return i(400, { error: "Missing from or to" });
|
|
889
|
+
const r = W(e, t), p = W(e, o);
|
|
890
|
+
return !r || !p ? i(400, { error: "Invalid path" }) : _(r) ? (M(P(p), { recursive: !0 }), Se(r, p), i(200, { ok: !0, commit: { fileSha: "" } })) : i(404, { error: "Source not found" });
|
|
891
|
+
}
|
|
892
|
+
if (s === "POST" && a === "users/save") {
|
|
893
|
+
const t = (await n.json())?.users;
|
|
894
|
+
return Array.isArray(t) ? (T(g(e, "users.json"), JSON.stringify(t, null, " ") + `
|
|
895
|
+
`), i(200, { ok: !0, commit: { fileSha: "" } })) : i(400, { error: "Missing users" });
|
|
896
|
+
}
|
|
897
|
+
if (s === "POST" && a === "settings/save") {
|
|
898
|
+
const t = (await n.json())?.settings;
|
|
899
|
+
return !t || typeof t != "object" ? i(400, { error: "Missing settings" }) : (T(g(e, "settings.json"), JSON.stringify(t, null, " ") + `
|
|
900
|
+
`), i(200, { ok: !0, commit: { fileSha: "" } }));
|
|
901
|
+
}
|
|
902
|
+
if (s === "POST" && a === "origins/save") {
|
|
903
|
+
const t = (await n.json())?.origins;
|
|
904
|
+
if (!Array.isArray(t) || t.some((r) => typeof r != "string")) return i(400, { error: "Missing origins" });
|
|
905
|
+
const o = [...new Set(t.map((r) => r.trim()).filter(Boolean))];
|
|
906
|
+
return T(g(e, "origins.json"), JSON.stringify(o, null, " ") + `
|
|
907
|
+
`), i(200, { ok: !0, origins: o, commit: { fileSha: "" } });
|
|
908
|
+
}
|
|
909
|
+
return null;
|
|
910
|
+
} catch (t) {
|
|
911
|
+
return t instanceof Ce ? { status: t.status, body: { error: t.message } } : { status: 500, body: { error: t instanceof Error ? t.message : String(t) } };
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
export {
|
|
915
|
+
ne as I,
|
|
916
|
+
Tt as a,
|
|
917
|
+
jt as b,
|
|
918
|
+
At as c,
|
|
919
|
+
Ot as d,
|
|
920
|
+
vt as e,
|
|
921
|
+
bt as f,
|
|
922
|
+
St as g,
|
|
923
|
+
wt as h,
|
|
924
|
+
kt as i,
|
|
925
|
+
$t as j,
|
|
926
|
+
Pt as k,
|
|
927
|
+
xt as l,
|
|
928
|
+
rt as m,
|
|
929
|
+
Z as s
|
|
930
|
+
};
|