yamlite 0.38.0 → 0.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -3
- package/dist/browser/chokidar.mjs +1 -1
- package/dist/browser/expose.mjs +10 -17
- package/dist/browser/fs.d.mts +5 -0
- package/dist/browser/fs.mjs +1 -1
- package/dist/cli.mjs +3 -2
- package/dist/core.d.mts +22 -13
- package/dist/core.mjs +3 -3
- package/dist/{fs-DZ4QHM93.mjs → fs-BM30qNPb.mjs} +8 -1
- package/dist/{index-OSyELQEX.d.mts → index-CDLxve55.d.mts} +2 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{src-DdRmp-vT.mjs → src-NOJw_gTE.mjs} +185 -12
- package/dist/ui/assets/{ErdView-Cv4lBB9J.js → ErdView-Dqs3Ly-E.js} +1 -1
- package/dist/ui/assets/{MarkdownField-UKgTcG0X.js → MarkdownField-Bg4zDZM_.js} +1 -1
- package/dist/ui/assets/PageView-D0hs43d8.js +1 -0
- package/dist/ui/assets/access-DSnHSuXB.js +1 -0
- package/dist/ui/assets/{index-BnlDexUD.js → index-LbUt_Zkt.js} +58 -57
- package/dist/ui/assets/load-ylhnQAWa.js +2 -0
- package/dist/ui/index.html +1 -1
- package/dist/ui-embed/{ErdView-Dk-iexgy.js → ErdView-CgNnAf5I.js} +2 -2
- package/dist/ui-embed/{HintPopover-D5P2UuTa.js → HintPopover-8CeJLQO5.js} +1611 -1605
- package/dist/ui-embed/{PageView-BzCYlXPg.js → PageView-B29tXeqW.js} +158 -141
- package/dist/ui-embed/{activity-letLdXN4.js → activity-DecWPHxS.js} +1 -1
- package/dist/ui-embed/embed.js +875 -852
- package/dist/ui-embed/{pageFrame-CFoU6UjD.js → pageFrame-ClOBfTt9.js} +1 -1
- package/dist/{workspace-B4WnIeHR.mjs → workspace-Cp5-yHYp.mjs} +7 -3
- package/package.json +1 -1
- package/dist/ui/assets/PageView-SFpedZG6.js +0 -1
- package/dist/ui/assets/load-S46Mj3YT.js +0 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { basename, delimiter, dirname, extname, isAbsolute, join, matchesGlob, normalize, posix, relative, resolve, sep } from "node:path";
|
|
2
|
-
import { accessSync, chmodSync, constants, cpSync, createReadStream, existsSync, linkSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, rmdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { accessSync, chmodSync, constants, copyFileSync, cpSync, createReadStream, existsSync, linkSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, rmdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { homedir, tmpdir } from "node:os";
|
|
4
4
|
import { Document, Scalar, isMap, isNode, isScalar, isSeq, parse, parseDocument, stringify } from "yaml";
|
|
5
5
|
import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
|
|
@@ -1105,6 +1105,12 @@ function reconcileViews(store, spec, apply) {
|
|
|
1105
1105
|
}
|
|
1106
1106
|
//#endregion
|
|
1107
1107
|
//#region src/pages/access.ts
|
|
1108
|
+
const DENIED_FILES = [
|
|
1109
|
+
".yamlite/",
|
|
1110
|
+
"yamlite.yaml",
|
|
1111
|
+
"yamlite.yml"
|
|
1112
|
+
];
|
|
1113
|
+
const MAX_PAGE_FILE_BYTES = 10485760;
|
|
1108
1114
|
const PAGE_AI_DEFAULT_TOKENS = 1024;
|
|
1109
1115
|
const PAGE_AI_MAX_TOKENS = 8192;
|
|
1110
1116
|
const canRead = (page, name) => Object.hasOwn(page.access, name);
|
|
@@ -1115,6 +1121,30 @@ function trustedViews(page, views) {
|
|
|
1115
1121
|
for (const name of Object.keys(page.access)) for (let v = name; v !== void 0 && parentOf.has(v) && !trusted.has(v); v = parentOf.get(v)) trusted.add(v);
|
|
1116
1122
|
return trusted;
|
|
1117
1123
|
}
|
|
1124
|
+
function normalizeFilePath(path) {
|
|
1125
|
+
if (path.startsWith("/") || path.startsWith("\\") || /^[a-z]:/i.test(path)) return null;
|
|
1126
|
+
const parts = path.split(/[\\/]/);
|
|
1127
|
+
if (parts.includes("..")) return null;
|
|
1128
|
+
const kept = parts.filter((p) => p !== "" && p !== ".");
|
|
1129
|
+
if (kept.length === 0) return null;
|
|
1130
|
+
return kept.join("/") + (path.endsWith("/") ? "/" : "");
|
|
1131
|
+
}
|
|
1132
|
+
const fileGranted = (files, path) => files.some((entry) => entry.endsWith("/") ? path.startsWith(entry) : path === entry);
|
|
1133
|
+
const deniedFile = (path, denied) => fileGranted(denied.map((d) => d.toLowerCase()), path.toLowerCase());
|
|
1134
|
+
const CONTENT_TYPES = {
|
|
1135
|
+
png: "image/png",
|
|
1136
|
+
jpg: "image/jpeg",
|
|
1137
|
+
jpeg: "image/jpeg",
|
|
1138
|
+
webp: "image/webp",
|
|
1139
|
+
gif: "image/gif",
|
|
1140
|
+
svg: "image/svg+xml",
|
|
1141
|
+
pdf: "application/pdf",
|
|
1142
|
+
txt: "text/plain"
|
|
1143
|
+
};
|
|
1144
|
+
function contentTypeOf(path) {
|
|
1145
|
+
const ext = path.slice(path.lastIndexOf(".") + 1).toLowerCase();
|
|
1146
|
+
return path.includes(".") && Object.hasOwn(CONTENT_TYPES, ext) ? CONTENT_TYPES[ext] : "application/octet-stream";
|
|
1147
|
+
}
|
|
1118
1148
|
//#endregion
|
|
1119
1149
|
//#region src/config.ts
|
|
1120
1150
|
const CONFIG_NAMES = ["yamlite.yaml", "yamlite.yml"];
|
|
@@ -1639,6 +1669,7 @@ const PAGE_KEYS = [
|
|
|
1639
1669
|
"access",
|
|
1640
1670
|
"sql",
|
|
1641
1671
|
"network",
|
|
1672
|
+
"files",
|
|
1642
1673
|
"ai"
|
|
1643
1674
|
];
|
|
1644
1675
|
const PAGE_NAME = /^[a-z0-9][a-z0-9_-]*$/;
|
|
@@ -1654,6 +1685,16 @@ function toOrigin(where, raw) {
|
|
|
1654
1685
|
if (url.protocol !== "https:" && url.protocol !== "http:" || raw.replace(/\/$/, "") !== url.origin) throw invalid();
|
|
1655
1686
|
return url.origin;
|
|
1656
1687
|
}
|
|
1688
|
+
function toFiles(where, raw) {
|
|
1689
|
+
if (raw === void 0 || raw === null) return [];
|
|
1690
|
+
if (!Array.isArray(raw)) throw new Error(`${where}files must be a list of root-relative files and folders`);
|
|
1691
|
+
return raw.map((entry) => {
|
|
1692
|
+
const invalid = (why) => /* @__PURE__ */ new Error(`${where}files entry ${JSON.stringify(entry)} ${why}`);
|
|
1693
|
+
if (typeof entry !== "string" || normalizeFilePath(entry) !== entry) throw invalid("must be a root-relative path without .., . or empty segments");
|
|
1694
|
+
if (deniedFile(entry, DENIED_FILES)) throw invalid("is YAMLite's own and cannot be granted");
|
|
1695
|
+
return entry;
|
|
1696
|
+
});
|
|
1697
|
+
}
|
|
1657
1698
|
function toPageAi(where, raw) {
|
|
1658
1699
|
if (raw === void 0 || raw === null || raw === false) return null;
|
|
1659
1700
|
if (raw === true) return { maxOutputTokens: PAGE_AI_DEFAULT_TOKENS };
|
|
@@ -1694,6 +1735,7 @@ function toPages(raw, place) {
|
|
|
1694
1735
|
access,
|
|
1695
1736
|
sql: v.sql === true,
|
|
1696
1737
|
network: (v.network ?? []).map((o) => toOrigin(where, o)),
|
|
1738
|
+
files: toFiles(where, v.files),
|
|
1697
1739
|
ai: toPageAi(where, v.ai)
|
|
1698
1740
|
};
|
|
1699
1741
|
});
|
|
@@ -4238,6 +4280,37 @@ var ProposalStore = class {
|
|
|
4238
4280
|
};
|
|
4239
4281
|
//#endregion
|
|
4240
4282
|
//#region src/serve/context.ts
|
|
4283
|
+
function onDisk(path) {
|
|
4284
|
+
try {
|
|
4285
|
+
return realpathSync.native(path);
|
|
4286
|
+
} catch {
|
|
4287
|
+
try {
|
|
4288
|
+
return join(realpathSync.native(dirname(path)), basename(path));
|
|
4289
|
+
} catch {
|
|
4290
|
+
return path;
|
|
4291
|
+
}
|
|
4292
|
+
}
|
|
4293
|
+
}
|
|
4294
|
+
function deniedFiles(root, stateDir, dbPath) {
|
|
4295
|
+
const base = onDisk(root);
|
|
4296
|
+
const inside = (path) => {
|
|
4297
|
+
const rel = relative(base, path);
|
|
4298
|
+
return rel === "" || rel.startsWith("..") || isAbsolute(rel) ? null : rel.split(sep).join("/");
|
|
4299
|
+
};
|
|
4300
|
+
const state = inside(onDisk(stateDir));
|
|
4301
|
+
const given = inside(join(onDisk(dirname(dbPath)), basename(dbPath)));
|
|
4302
|
+
const dbs = [.../* @__PURE__ */ new Set([given, inside(onDisk(dbPath))])].filter((db) => db !== null);
|
|
4303
|
+
return [
|
|
4304
|
+
...DENIED_FILES,
|
|
4305
|
+
...state === null ? [] : [`${state}/`],
|
|
4306
|
+
...dbs.flatMap((db) => [
|
|
4307
|
+
db,
|
|
4308
|
+
`${db}-wal`,
|
|
4309
|
+
`${db}-shm`,
|
|
4310
|
+
`${db}-journal`
|
|
4311
|
+
])
|
|
4312
|
+
];
|
|
4313
|
+
}
|
|
4241
4314
|
function displayPath$1(root, path) {
|
|
4242
4315
|
const rel = relative(root, path);
|
|
4243
4316
|
return rel === "" || rel.startsWith("..") ? path : rel;
|
|
@@ -6520,11 +6593,56 @@ function pageSpec(ctx, name) {
|
|
|
6520
6593
|
if (!page) throw new HttpError(404, `unknown page: ${name}`);
|
|
6521
6594
|
return page;
|
|
6522
6595
|
}
|
|
6596
|
+
const FILE_HEADERS = {
|
|
6597
|
+
"cache-control": "no-store",
|
|
6598
|
+
"x-content-type-options": "nosniff",
|
|
6599
|
+
"content-security-policy": "default-src 'none'; style-src 'unsafe-inline'; sandbox"
|
|
6600
|
+
};
|
|
6601
|
+
const tooLarge = (path) => new HttpError(413, `${path} is larger than 10 MB`);
|
|
6602
|
+
const missing = (path) => new HttpError(404, `file not found: ${path}`);
|
|
6603
|
+
function grantedFile(root, files, denied, path) {
|
|
6604
|
+
let real;
|
|
6605
|
+
let size;
|
|
6606
|
+
try {
|
|
6607
|
+
real = realpathSync.native(join(root, path));
|
|
6608
|
+
const st = statSync(real);
|
|
6609
|
+
if (!st.isFile()) throw missing(path);
|
|
6610
|
+
size = st.size;
|
|
6611
|
+
} catch (e) {
|
|
6612
|
+
if (e instanceof HttpError) throw e;
|
|
6613
|
+
throw missing(path);
|
|
6614
|
+
}
|
|
6615
|
+
const rel = relative(realpathSync.native(root), real);
|
|
6616
|
+
const shown = rel.split(sep).join("/");
|
|
6617
|
+
if (rel.startsWith("..") || isAbsolute(rel) || !fileGranted(files, shown) || deniedFile(shown, denied)) throw new HttpError(403, `${path} leads outside this page's files`);
|
|
6618
|
+
if (size > 10485760) throw tooLarge(path);
|
|
6619
|
+
return {
|
|
6620
|
+
real,
|
|
6621
|
+
size
|
|
6622
|
+
};
|
|
6623
|
+
}
|
|
6624
|
+
const readGranted = (ctx, page, path) => readFileSync(grantedFile(ctx.root, page.files, ctx.deniedFiles, path).real);
|
|
6523
6625
|
const pageRoutes = (router, ctx) => {
|
|
6524
6626
|
router.add("GET", "/api/pages/:page/html", ({ params }) => {
|
|
6525
6627
|
const page = pageSpec(ctx, params.page);
|
|
6526
6628
|
return { html: readPageHtml(page.path, displayPath$1(ctx.root, page.path)) };
|
|
6527
6629
|
});
|
|
6630
|
+
router.add("GET", "/api/pages/:page/file", async ({ params, query, signal }) => {
|
|
6631
|
+
const page = pageSpec(ctx, params.page);
|
|
6632
|
+
const asked = query.get("path");
|
|
6633
|
+
if (!asked) throw new HttpError(400, "path is required");
|
|
6634
|
+
const path = normalizeFilePath(asked);
|
|
6635
|
+
if (path === null || !fileGranted(page.files, path)) throw new HttpError(403, `${asked} is not in this page's files`);
|
|
6636
|
+
if (deniedFile(path, ctx.deniedFiles)) throw new HttpError(403, `${asked} is YAMLite's own and no page may read it`);
|
|
6637
|
+
let bytes = await ctx.pageFiles?.(path, signal);
|
|
6638
|
+
if (bytes === "missing") throw missing(path);
|
|
6639
|
+
if (bytes === "too-large" || bytes !== void 0 && bytes.length > 10485760) throw tooLarge(path);
|
|
6640
|
+
bytes ??= readGranted(ctx, page, path);
|
|
6641
|
+
return new Response(bytes, { headers: {
|
|
6642
|
+
...FILE_HEADERS,
|
|
6643
|
+
"content-type": contentTypeOf(path)
|
|
6644
|
+
} });
|
|
6645
|
+
});
|
|
6528
6646
|
};
|
|
6529
6647
|
//#endregion
|
|
6530
6648
|
//#region src/serve/routes/pageai.ts
|
|
@@ -7077,6 +7195,7 @@ const metaRoutes = (router, ctx) => {
|
|
|
7077
7195
|
access: p.access,
|
|
7078
7196
|
sql: p.sql,
|
|
7079
7197
|
network: p.network,
|
|
7198
|
+
files: p.files,
|
|
7080
7199
|
ai: p.ai
|
|
7081
7200
|
})),
|
|
7082
7201
|
views: ctx.y.tables.flatMap((t) => declaredViews(t).map(({ spec, parent, depth, path }) => {
|
|
@@ -7299,11 +7418,23 @@ const schemaRoutes = (router, ctx) => {
|
|
|
7299
7418
|
};
|
|
7300
7419
|
});
|
|
7301
7420
|
};
|
|
7421
|
+
const SEPARATORS = [
|
|
7422
|
+
" ",
|
|
7423
|
+
" ",
|
|
7424
|
+
"\n",
|
|
7425
|
+
"\r",
|
|
7426
|
+
"-",
|
|
7427
|
+
"_",
|
|
7428
|
+
".",
|
|
7429
|
+
"/"
|
|
7430
|
+
];
|
|
7431
|
+
const isSeparator = (c) => SEPARATORS.includes(c);
|
|
7432
|
+
const squash = (s) => [...s].filter((c) => !isSeparator(c)).join("");
|
|
7302
7433
|
const DEFAULT_PER = 20;
|
|
7303
7434
|
const MAX_PER = 200;
|
|
7304
7435
|
function parseSearchQuery(params) {
|
|
7305
7436
|
const needle = params.get("q")?.trim() ?? "";
|
|
7306
|
-
if ([...needle].length < 2) throw new HttpError(400, `q needs at least 2 characters`);
|
|
7437
|
+
if ([...squash(needle)].length < 2) throw new HttpError(400, `q needs at least 2 characters`);
|
|
7307
7438
|
const raw = params.get("per");
|
|
7308
7439
|
if (raw === null) return {
|
|
7309
7440
|
needle,
|
|
@@ -7331,25 +7462,27 @@ function labelColumn(t) {
|
|
|
7331
7462
|
}
|
|
7332
7463
|
const literal = (s) => `'${s.replaceAll("'", "''")}'`;
|
|
7333
7464
|
const text = (column) => `CAST(${q(column)} AS TEXT)`;
|
|
7334
|
-
const
|
|
7465
|
+
const char = (c) => c < " " ? `char(${c.charCodeAt(0)})` : literal(c);
|
|
7466
|
+
const squashed = (expr) => SEPARATORS.reduce((e, c) => `replace(${e}, ${char(c)}, '')`, `lower(${expr})`);
|
|
7467
|
+
const contains = (column) => `instr(${squashed(text(column))}, needle.v) > 0`;
|
|
7335
7468
|
function tableHits(t) {
|
|
7336
7469
|
const columns = [t.key, ...[...t.columns.keys()].filter((c) => c !== t.key)].filter((c) => t.columns.get(c) !== "BOOLEAN");
|
|
7337
7470
|
if (columns.length === 0) return null;
|
|
7338
7471
|
const pick = (then) => `CASE ${columns.map((c) => `WHEN ${contains(c)} THEN ${then(c)}`).join(" ")} END`;
|
|
7339
7472
|
const label = labelColumn(t);
|
|
7340
|
-
return `SELECT ${literal(t.name)} AS tbl, ${text(t.key)} AS k, ${label ? text(label) : "NULL"} AS lbl, ${pick(literal)} AS col, ${pick(text)} AS val FROM main.${q(t.name)}, needle WHERE ${columns.map(contains).join(" OR ")}`;
|
|
7473
|
+
return `SELECT ${literal(t.name)} AS tbl, ${text(t.key)} AS k, ${squashed(text(t.key))} AS sk, ${label ? text(label) : "NULL"} AS lbl, ${pick(literal)} AS col, ${pick(text)} AS val FROM main.${q(t.name)}, needle WHERE ${columns.map(contains).join(" OR ")}`;
|
|
7341
7474
|
}
|
|
7342
7475
|
function buildSearchSql(tables, needle, per) {
|
|
7343
7476
|
const selects = tables.map(tableHits).filter((s) => s !== null);
|
|
7344
7477
|
if (selects.length === 0) return null;
|
|
7345
7478
|
return {
|
|
7346
|
-
sql: `WITH needle(v) AS (SELECT
|
|
7479
|
+
sql: `WITH needle(v) AS (SELECT ${squashed("?")}),
|
|
7347
7480
|
hits AS (${selects.join(" UNION ALL ")}),
|
|
7348
7481
|
ranked AS (
|
|
7349
7482
|
SELECT hits.*,
|
|
7350
|
-
CASE WHEN
|
|
7351
|
-
WHEN substr(
|
|
7352
|
-
WHEN instr(
|
|
7483
|
+
CASE WHEN sk = needle.v THEN 0
|
|
7484
|
+
WHEN substr(sk, 1, length(needle.v)) = needle.v THEN 1
|
|
7485
|
+
WHEN instr(sk, needle.v) > 0 THEN 2
|
|
7353
7486
|
ELSE 3 END AS grade,
|
|
7354
7487
|
count(*) OVER (PARTITION BY tbl) AS total
|
|
7355
7488
|
FROM hits, needle
|
|
@@ -7572,6 +7705,40 @@ function warningScrubber(root, specPaths) {
|
|
|
7572
7705
|
return name === "" ? out : out.split(root).join(name);
|
|
7573
7706
|
};
|
|
7574
7707
|
}
|
|
7708
|
+
function grantedCandidates(root, entries) {
|
|
7709
|
+
const found = [];
|
|
7710
|
+
const walk = (rel) => {
|
|
7711
|
+
let items;
|
|
7712
|
+
try {
|
|
7713
|
+
items = readdirSync(join(root, rel), { withFileTypes: true });
|
|
7714
|
+
} catch {
|
|
7715
|
+
return;
|
|
7716
|
+
}
|
|
7717
|
+
for (const item of items) {
|
|
7718
|
+
const path = `${rel}${item.name}`;
|
|
7719
|
+
if (item.isDirectory()) walk(`${path}/`);
|
|
7720
|
+
else found.push(path);
|
|
7721
|
+
}
|
|
7722
|
+
};
|
|
7723
|
+
for (const entry of entries) if (entry.endsWith("/")) walk(entry);
|
|
7724
|
+
else found.push(entry);
|
|
7725
|
+
return found;
|
|
7726
|
+
}
|
|
7727
|
+
function copyPageFiles(root, dir, grants, denied, skipped) {
|
|
7728
|
+
for (const path of new Set(grantedCandidates(root, grants))) {
|
|
7729
|
+
if (deniedFile(path, denied)) continue;
|
|
7730
|
+
let real;
|
|
7731
|
+
try {
|
|
7732
|
+
real = grantedFile(root, grants, denied, path).real;
|
|
7733
|
+
} catch (e) {
|
|
7734
|
+
if (e instanceof HttpError && e.status === 413) skipped[path] = "is larger than 10 MB";
|
|
7735
|
+
continue;
|
|
7736
|
+
}
|
|
7737
|
+
const dest = join(dir, "data", "files", `${path}.bin`);
|
|
7738
|
+
mkdirSync(dirname(dest), { recursive: true });
|
|
7739
|
+
copyFileSync(real, dest);
|
|
7740
|
+
}
|
|
7741
|
+
}
|
|
7575
7742
|
const writeJson = (path, value) => writeFileSync(path, JSON.stringify(value));
|
|
7576
7743
|
async function writeSnapshotData(opts) {
|
|
7577
7744
|
const root = resolve(opts.root);
|
|
@@ -7583,6 +7750,7 @@ async function writeSnapshotData(opts) {
|
|
|
7583
7750
|
const yaml = [];
|
|
7584
7751
|
const pages = [];
|
|
7585
7752
|
const skippedPages = {};
|
|
7753
|
+
const skippedFiles = {};
|
|
7586
7754
|
const all = y.tables.map((t) => t.name);
|
|
7587
7755
|
const unknown = (opts.tables ?? []).filter((n) => !all.includes(n));
|
|
7588
7756
|
if (unknown.length > 0) throw new Error(`unknown table: ${unknown.join(", ")}`);
|
|
@@ -7607,6 +7775,8 @@ async function writeSnapshotData(opts) {
|
|
|
7607
7775
|
agent: null,
|
|
7608
7776
|
git: null,
|
|
7609
7777
|
reloadConfig: () => {},
|
|
7778
|
+
pageFiles: null,
|
|
7779
|
+
deniedFiles: deniedFiles(root, stateDir, dbPath),
|
|
7610
7780
|
proposals: new ProposalStore({
|
|
7611
7781
|
store,
|
|
7612
7782
|
dry: store,
|
|
@@ -7638,6 +7808,7 @@ async function writeSnapshotData(opts) {
|
|
|
7638
7808
|
}
|
|
7639
7809
|
}
|
|
7640
7810
|
const kept = new Set(pages.map(([name]) => name));
|
|
7811
|
+
copyPageFiles(root, opts.dir, y.pages.filter((p) => kept.has(p.name)).flatMap((p) => p.files), ctx.deniedFiles, skippedFiles);
|
|
7641
7812
|
meta = {
|
|
7642
7813
|
...served,
|
|
7643
7814
|
root: basename(root),
|
|
@@ -7708,7 +7879,8 @@ async function writeSnapshotData(opts) {
|
|
|
7708
7879
|
tables: selected,
|
|
7709
7880
|
warnings,
|
|
7710
7881
|
pages: pages.map(([name]) => name),
|
|
7711
|
-
skippedPages
|
|
7882
|
+
skippedPages,
|
|
7883
|
+
skippedFiles
|
|
7712
7884
|
};
|
|
7713
7885
|
});
|
|
7714
7886
|
}
|
|
@@ -7796,7 +7968,7 @@ async function exportSite(opts) {
|
|
|
7796
7968
|
if (!html.includes("<head>")) throw new Error(`${indexPath} has no <head>`);
|
|
7797
7969
|
const index = html.replace("<head>", `<head>\n ${STATIC_META}\n ${FILE_GUARD}`);
|
|
7798
7970
|
writeFileSync(join(staging, "index.html"), index);
|
|
7799
|
-
const { tables, warnings, pages, skippedPages } = await writeSnapshotData({
|
|
7971
|
+
const { tables, warnings, pages, skippedPages, skippedFiles } = await writeSnapshotData({
|
|
7800
7972
|
root: opts.root,
|
|
7801
7973
|
tables: opts.tables,
|
|
7802
7974
|
dir: staging,
|
|
@@ -7825,7 +7997,8 @@ async function exportSite(opts) {
|
|
|
7825
7997
|
tables,
|
|
7826
7998
|
warnings,
|
|
7827
7999
|
pages,
|
|
7828
|
-
skippedPages
|
|
8000
|
+
skippedPages,
|
|
8001
|
+
skippedFiles
|
|
7829
8002
|
};
|
|
7830
8003
|
} catch (e) {
|
|
7831
8004
|
rmSync(staging, {
|
|
@@ -8401,4 +8574,4 @@ async function open(options) {
|
|
|
8401
8574
|
};
|
|
8402
8575
|
}
|
|
8403
8576
|
//#endregion
|
|
8404
|
-
export {
|
|
8577
|
+
export { deniedFiles as A, check as B, describeChange as C, isRead as D, PageSql as E, Router as F, resolveConfig as G, configPath as H, createHandler as I, fileGranted as J, DENIED_FILES as K, HttpError as L, readRecord as M, assertSynced as N, statementCount as O, toWire as P, COLUMN_TYPES as Q, isLoopback as R, which as S, worthShowing as T, parseConfig as U, CONFIG_NAMES as V, readsFile as W, declaredViews as X, normalizeFilePath as Y, Store as Z, ghReady as _, query as a, gitLog as b, exportSite as c, validateNewTable as d, ReviewRefused as f, DIFF_LIMIT as g, templatePath as h, formatTable as i, ProposalStore as j, EventHub as k, ROUTES as l, STEP_KINDS as m, formatCsv as n, generateConfig as o, localDriver as p, MAX_PAGE_FILE_BYTES as q, formatJson as r, init as s, open as t, createTable as u, gitBranches as v, fieldChanges as w, gitStatus as x, gitDiff as y, loopbackHosts as z };
|