@saltcorn/admin-models 1.7.0-alpha.0 → 1.7.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/cjs/models/backup-retention.cjs +18 -0
  2. package/cjs/models/file-globs.cjs +18 -0
  3. package/cjs/models/zip-extract.cjs +18 -0
  4. package/cjs/models/zip-format.cjs +18 -0
  5. package/cjs/models/zip-worker.cjs +18 -0
  6. package/cjs/models/zip-writer.cjs +18 -0
  7. package/cjs/models/zip.cjs +18 -0
  8. package/dist/index.d.ts +2 -2
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/models/backup-retention.d.ts +57 -0
  11. package/dist/models/backup-retention.d.ts.map +1 -0
  12. package/dist/models/backup-retention.js +108 -0
  13. package/dist/models/backup-retention.js.map +1 -0
  14. package/dist/models/backup.d.ts +4 -1
  15. package/dist/models/backup.d.ts.map +1 -1
  16. package/dist/models/backup.js +364 -302
  17. package/dist/models/backup.js.map +1 -1
  18. package/dist/models/file-globs.d.ts +34 -0
  19. package/dist/models/file-globs.d.ts.map +1 -0
  20. package/dist/models/file-globs.js +47 -0
  21. package/dist/models/file-globs.js.map +1 -0
  22. package/dist/models/pack.d.ts +1 -1
  23. package/dist/models/pack.d.ts.map +1 -1
  24. package/dist/models/pack.js +26 -1
  25. package/dist/models/pack.js.map +1 -1
  26. package/dist/models/tenant.d.ts.map +1 -1
  27. package/dist/models/tenant.js +2 -0
  28. package/dist/models/tenant.js.map +1 -1
  29. package/dist/models/zip-extract.d.ts +14 -0
  30. package/dist/models/zip-extract.d.ts.map +1 -0
  31. package/dist/models/zip-extract.js +110 -0
  32. package/dist/models/zip-extract.js.map +1 -0
  33. package/dist/models/zip-format.d.ts +57 -0
  34. package/dist/models/zip-format.d.ts.map +1 -0
  35. package/dist/models/zip-format.js +106 -0
  36. package/dist/models/zip-format.js.map +1 -0
  37. package/dist/models/zip-worker.d.ts +2 -0
  38. package/dist/models/zip-worker.d.ts.map +1 -0
  39. package/dist/models/zip-worker.js +177 -0
  40. package/dist/models/zip-worker.js.map +1 -0
  41. package/dist/models/zip-writer.d.ts +75 -0
  42. package/dist/models/zip-writer.d.ts.map +1 -0
  43. package/dist/models/zip-writer.js +321 -0
  44. package/dist/models/zip-writer.js.map +1 -0
  45. package/dist/models/zip.d.ts +101 -0
  46. package/dist/models/zip.d.ts.map +1 -0
  47. package/dist/models/zip.js +211 -0
  48. package/dist/models/zip.js.map +1 -0
  49. package/dist/tests/backup-retention.test.d.ts +2 -0
  50. package/dist/tests/backup-retention.test.d.ts.map +1 -0
  51. package/dist/tests/backup-retention.test.js +134 -0
  52. package/dist/tests/backup-retention.test.js.map +1 -0
  53. package/dist/tests/backup.test.js +186 -2
  54. package/dist/tests/backup.test.js.map +1 -1
  55. package/dist/tests/file-globs.test.d.ts +2 -0
  56. package/dist/tests/file-globs.test.d.ts.map +1 -0
  57. package/dist/tests/file-globs.test.js +66 -0
  58. package/dist/tests/file-globs.test.js.map +1 -0
  59. package/dist/tests/pack.test.js +14 -3
  60. package/dist/tests/pack.test.js.map +1 -1
  61. package/dist/tests/random.test.js +3 -3
  62. package/dist/tests/random.test.js.map +1 -1
  63. package/dist/tests/tenant.test.js +7 -7
  64. package/dist/tests/tenant.test.js.map +1 -1
  65. package/dist/tests/zip.test.d.ts +2 -0
  66. package/dist/tests/zip.test.d.ts.map +1 -0
  67. package/dist/tests/zip.test.js +319 -0
  68. package/dist/tests/zip.test.js.map +1 -0
  69. package/package.json +15 -9
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=backup-retention.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup-retention.test.d.ts","sourceRoot":"","sources":["../../tests/backup-retention.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,134 @@
1
+ import { selectBackupsToDelete, selectBackupsToDeleteGrouped, } from "../models/backup-retention.js";
2
+ import { describe, it, expect } from "@saltcorn/db-common/test_expect";
3
+ const mkEntry = (iso, key) => ({
4
+ key: key || `sc-backup-Site-${iso}.zip`,
5
+ date: new Date(`${iso}T03:00:00Z`),
6
+ });
7
+ /** N consecutive daily backups ending at `end` (inclusive), newest last */
8
+ const dailySeries = (end, n, prefix = "Site") => {
9
+ const endDate = new Date(`${end}T03:00:00Z`);
10
+ const out = [];
11
+ for (let i = n - 1; i >= 0; i--) {
12
+ const d = new Date(endDate.getTime() - i * 86400000);
13
+ const iso = d.toISOString().slice(0, 10);
14
+ out.push({ key: `sc-backup-${prefix}-${iso}.zip`, date: d });
15
+ }
16
+ return out;
17
+ };
18
+ const policy = (p) => ({
19
+ keep_daily: 0,
20
+ keep_weekly: 0,
21
+ keep_monthly: 0,
22
+ keep_yearly: 0,
23
+ keep_min: 0,
24
+ ...p,
25
+ });
26
+ describe("selectBackupsToDelete", () => {
27
+ it("returns nothing for an empty list", () => {
28
+ expect(selectBackupsToDelete([], policy({ keep_daily: 7 }))).toEqual([]);
29
+ });
30
+ it("keeps the last N daily backups", () => {
31
+ const entries = dailySeries("2026-07-26", 30);
32
+ const del = selectBackupsToDelete(entries, policy({ keep_daily: 7 }));
33
+ expect(del).toHaveLength(23);
34
+ const deletedKeys = new Set(del.map((e) => e.key));
35
+ // the 7 newest must survive
36
+ for (const e of entries.slice(-7))
37
+ expect(deletedKeys.has(e.key)).toBe(false);
38
+ });
39
+ it("keeps one backup per ISO week for keep_weekly", () => {
40
+ const entries = dailySeries("2026-07-26", 28); // 4+ ISO weeks
41
+ const del = selectBackupsToDelete(entries, policy({ keep_weekly: 4 }));
42
+ const kept = entries.filter((e) => !del.includes(e));
43
+ expect(kept).toHaveLength(4);
44
+ // one kept backup per week, all on distinct days
45
+ const days = new Set(kept.map((e) => e.date.toISOString().slice(0, 10)));
46
+ expect(days.size).toBe(4);
47
+ });
48
+ it("a single backup can satisfy multiple tiers", () => {
49
+ const entries = [mkEntry("2026-07-26")];
50
+ const del = selectBackupsToDelete(entries, policy({
51
+ keep_daily: 7,
52
+ keep_weekly: 4,
53
+ keep_monthly: 12,
54
+ keep_yearly: 3,
55
+ }));
56
+ expect(del).toEqual([]);
57
+ });
58
+ it("combined GFS policy over a year of daily backups", () => {
59
+ const entries = dailySeries("2026-07-26", 365);
60
+ const del = selectBackupsToDelete(entries, policy({
61
+ keep_daily: 7,
62
+ keep_weekly: 4,
63
+ keep_monthly: 12,
64
+ keep_yearly: 3,
65
+ }));
66
+ const kept = entries.length - del.length;
67
+ // 7 daily + 4 weekly + 12 monthly + yearly, minus overlaps
68
+ expect(kept).toBeGreaterThanOrEqual(12);
69
+ expect(kept).toBeLessThanOrEqual(26);
70
+ });
71
+ it("keep_min prevents deleting the last backups even when all are old", () => {
72
+ // 5 backups, all several years old, policy window long passed
73
+ const entries = dailySeries("2020-01-05", 5);
74
+ const del = selectBackupsToDelete(entries, policy({ keep_daily: 7, keep_min: 3 }));
75
+ // keep_daily keeps 5 (each its own day-bucket within capacity 7)
76
+ expect(del).toEqual([]);
77
+ // stricter: only 1 daily slot, keep_min=3 → exactly 2 deleted
78
+ const del2 = selectBackupsToDelete(entries, policy({ keep_daily: 1, keep_min: 3 }));
79
+ expect(del2).toHaveLength(2);
80
+ });
81
+ it("never deletes everything when keep_min > 0", () => {
82
+ const entries = dailySeries("2019-06-01", 10);
83
+ const del = selectBackupsToDelete(entries, policy({ keep_min: 1 }));
84
+ expect(del).toHaveLength(9);
85
+ // the newest is the one retained
86
+ expect(del.map((e) => e.key)).not.toContain(entries[9].key);
87
+ });
88
+ it("keeps the newest backup of each of the last N months", () => {
89
+ // one backup every 5 days for a year
90
+ const entries = [];
91
+ const end = new Date("2026-07-26T03:00:00Z").getTime();
92
+ for (let i = 72; i >= 0; i--) {
93
+ const d = new Date(end - i * 5 * 86400000);
94
+ entries.push({
95
+ key: `sc-backup-Site-${d.toISOString().slice(0, 10)}.zip`,
96
+ date: d,
97
+ });
98
+ }
99
+ const del = selectBackupsToDelete(entries, policy({ keep_monthly: 3 }));
100
+ const kept = entries.filter((e) => !del.includes(e));
101
+ expect(kept).toHaveLength(3);
102
+ const months = new Set(kept.map((e) => e.date.toISOString().slice(0, 7)));
103
+ expect(months.size).toBe(3);
104
+ });
105
+ });
106
+ describe("selectBackupsToDeleteGrouped", () => {
107
+ it("applies the policy per tenant", () => {
108
+ const root = dailySeries("2026-07-26", 10, "Root");
109
+ const t1 = dailySeries("2026-07-26", 10, "tenant1");
110
+ const del = selectBackupsToDeleteGrouped([...root, ...t1], policy({ keep_daily: 7 }));
111
+ // 3 deleted per tenant — tenants do not steal each other's slots
112
+ expect(del).toHaveLength(6);
113
+ expect(del.filter((e) => e.key.includes("Root"))).toHaveLength(3);
114
+ expect(del.filter((e) => e.key.includes("tenant1"))).toHaveLength(3);
115
+ });
116
+ it("groups by basename, ignoring the key path prefix", () => {
117
+ const withPrefix = dailySeries("2026-07-26", 10).map((e) => ({
118
+ ...e,
119
+ key: `backups/prod/${e.key}`,
120
+ }));
121
+ const del = selectBackupsToDeleteGrouped(withPrefix, policy({ keep_daily: 7 }));
122
+ expect(del).toHaveLength(3);
123
+ });
124
+ it("groups non-matching filenames by their own basename", () => {
125
+ const odd = {
126
+ key: "manual-export.zip",
127
+ date: new Date("2020-01-01T00:00:00Z"),
128
+ };
129
+ const del = selectBackupsToDeleteGrouped([odd, ...dailySeries("2026-07-26", 3)], policy({ keep_daily: 1, keep_min: 1 }));
130
+ // the odd file forms its own group and is kept by its own keep_min
131
+ expect(del.map((e) => e.key)).not.toContain("manual-export.zip");
132
+ });
133
+ });
134
+ //# sourceMappingURL=backup-retention.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backup-retention.test.js","sourceRoot":"","sources":["../../tests/backup-retention.test.ts"],"names":[],"mappings":"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"}
@@ -3,10 +3,12 @@ import { getState } from "@saltcorn/data/db/state";
3
3
  import basePlugin from "@saltcorn/data/base-plugin";
4
4
  getState().registerPlugin("base", basePlugin);
5
5
  import backup from "../models/backup.js";
6
- const { create_backup, restore } = backup;
6
+ const { create_backup, restore, auto_backup_now } = backup;
7
7
  import reset from "@saltcorn/data/db/reset_schema";
8
8
  import fixtures from "@saltcorn/data/db/fixtures";
9
- import { unlink } from "fs/promises";
9
+ import { unlink, mkdtemp, writeFile, readdir, rm, stat } from "fs/promises";
10
+ import { join } from "path";
11
+ import { tmpdir } from "os";
10
12
  import Table from "@saltcorn/data/models/table";
11
13
  import View from "@saltcorn/data/models/view";
12
14
  import User from "@saltcorn/data/models/user";
@@ -20,6 +22,8 @@ import WorkflowStep from "@saltcorn/data/models/workflow_step";
20
22
  import { assertIsSet, assertsObjectIsUser, } from "@saltcorn/data/tests/assertions";
21
23
  import { afterAll, describe, it, expect, beforeAll, jest, } from "@saltcorn/db-common/test_expect";
22
24
  import Field from "@saltcorn/data/models/field";
25
+ import File from "@saltcorn/data/models/file";
26
+ import Zip from "adm-zip";
23
27
  import * as mocks from "@saltcorn/data/tests/mocks";
24
28
  const { mockReqRes, plugin_with_routes } = mocks;
25
29
  afterAll(db.close);
@@ -198,4 +202,184 @@ describe("Backup and restore", () => {
198
202
  expect(User.table.description).toBe("Users are the best");
199
203
  });
200
204
  });
205
+ describe("auto backup retention to local directory", () => {
206
+ it("deletes backups not retained by the tiered policy", async () => {
207
+ const dir = await mkdtemp(join(tmpdir(), "sc-backup-retention-"));
208
+ const prefix = getState().getConfig("backup_file_prefix");
209
+ await getState().setConfig("site_name", "RetTest");
210
+ await getState().setConfig("auto_backup_destination", "Local directory");
211
+ await getState().setConfig("auto_backup_directory", dir);
212
+ await getState().setConfig("auto_backup_retention_mode", "Tiered (GFS)");
213
+ await getState().setConfig("auto_backup_keep_daily", 1);
214
+ await getState().setConfig("auto_backup_keep_weekly", 0);
215
+ await getState().setConfig("auto_backup_keep_monthly", 0);
216
+ await getState().setConfig("auto_backup_keep_yearly", 0);
217
+ await getState().setConfig("auto_backup_keep_min", 1);
218
+ // older backups of the same site, plus files the policy must not touch
219
+ for (const day of ["2020-01-01-00-00", "2020-01-02-00-00"])
220
+ await writeFile(join(dir, `${prefix}RetTest-${day}.zip`), "old");
221
+ await writeFile(join(dir, "not-a-backup.zip"), "keep me");
222
+ await writeFile(join(dir, `${prefix}RetTest-2020-01-03.txt`), "keep me");
223
+ await auto_backup_now();
224
+ const remaining = await readdir(dir);
225
+ // one backup of this site is retained (keep_daily=1, all in one day bucket)
226
+ expect(remaining.filter((f) => f.startsWith(`${prefix}RetTest`) && f.endsWith(".zip"))).toHaveLength(1);
227
+ // files outside the backup prefix or not zips are never deleted
228
+ expect(remaining).toContain("not-a-backup.zip");
229
+ expect(remaining).toContain(`${prefix}RetTest-2020-01-03.txt`);
230
+ await rm(dir, { recursive: true, force: true });
231
+ });
232
+ it("does not delete anything when retention is not configured", async () => {
233
+ const dir = await mkdtemp(join(tmpdir(), "sc-backup-retention-"));
234
+ const prefix = getState().getConfig("backup_file_prefix");
235
+ await getState().setConfig("auto_backup_directory", dir);
236
+ await getState().setConfig("auto_backup_retention_mode", "Expiration");
237
+ await getState().setConfig("auto_backup_expire_days", null);
238
+ for (const day of ["2020-01-01-00-00", "2020-01-02-00-00"])
239
+ await writeFile(join(dir, `${prefix}RetTest-${day}.zip`), "old");
240
+ await auto_backup_now();
241
+ const remaining = await readdir(dir);
242
+ expect(remaining).toContain(`${prefix}RetTest-2020-01-01-00-00.zip`);
243
+ expect(remaining).toContain(`${prefix}RetTest-2020-01-02-00-00.zip`);
244
+ await rm(dir, { recursive: true, force: true });
245
+ });
246
+ });
247
+ describe("backup file exclusion", () => {
248
+ it("excludes files matching the configured globs", async () => {
249
+ await File.ensure_file_store();
250
+ const mv = async (fnm) => {
251
+ await writeFile(fnm, "cecinestpasunpng");
252
+ };
253
+ await File.from_req_files({ mimetype: "video/mp4", name: "bigvideo.mp4", mv, size: 16 }, 1, 100);
254
+ await File.from_req_files({ mimetype: "image/png", name: "keepme.png", mv, size: 16 }, 1, 100);
255
+ await File.new_folder("cache");
256
+ await File.from_req_files({ mimetype: "image/png", name: "thumb.png", mv, size: 16 }, 1, 100, "cache");
257
+ await getState().setConfig("backup_exclude_file_globs", "*.mp4, cache/**");
258
+ const fnm = await create_backup();
259
+ const zip = new Zip(fnm);
260
+ const entries = zip.getEntries().map((e) => e.entryName);
261
+ const filesCsv = zip.readAsText("files.csv");
262
+ await unlink(fnm);
263
+ await getState().setConfig("backup_exclude_file_globs", "");
264
+ expect(entries).toContain("files/keepme.png");
265
+ expect(entries.filter((e) => e.includes("bigvideo"))).toHaveLength(0);
266
+ expect(entries.filter((e) => e.includes("thumb.png"))).toHaveLength(0);
267
+ // excluded files are also left out of the file metadata
268
+ expect(filesCsv.includes("keepme.png")).toBe(true);
269
+ expect(filesCsv.includes("bigvideo.mp4")).toBe(false);
270
+ expect(filesCsv.includes("thumb.png")).toBe(false);
271
+ });
272
+ it("includes all files when no globs are configured", async () => {
273
+ const fnm = await create_backup();
274
+ const entries = new Zip(fnm)
275
+ .getEntries()
276
+ .map((e) => e.entryName)
277
+ .join("\n");
278
+ await unlink(fnm);
279
+ expect(entries.includes("bigvideo.mp4")).toBe(true);
280
+ expect(entries.includes("keepme.png")).toBe(true);
281
+ expect(entries.includes("thumb.png")).toBe(true);
282
+ });
283
+ });
284
+ describe("backup destinations", () => {
285
+ // backup file names are built from the site name, and the other test files
286
+ // run in parallel in this same working directory - so give this file's
287
+ // backups a name only it produces
288
+ const siteName = "DestTest";
289
+ /** zips of this site left lying around in the working directory */
290
+ const strayBackups = async () => {
291
+ const prefix = getState().getConfig("backup_file_prefix");
292
+ return (await readdir(process.cwd())).filter((f) => f.startsWith(`${prefix}${siteName}-`) && f.endsWith(".zip"));
293
+ };
294
+ it("writes a local directory backup into the directory itself", async () => {
295
+ // the OS temporary directory is usually a different filesystem (tmpfs on
296
+ // most Linux distributions), like the Docker volumes and external drives
297
+ // of issue #4332: the backup must be written where it belongs rather than
298
+ // written elsewhere and renamed, because renaming across filesystems
299
+ // fails with EXDEV
300
+ const dir = await mkdtemp(join(tmpdir(), "sc-backup-dest-"));
301
+ await getState().setConfig("site_name", siteName);
302
+ await getState().setConfig("auto_backup_destination", "Local directory");
303
+ await getState().setConfig("auto_backup_directory", dir);
304
+ await getState().setConfig("auto_backup_retention_mode", "Expiration");
305
+ await getState().setConfig("auto_backup_expire_days", null);
306
+ await auto_backup_now();
307
+ const written = (await readdir(dir)).filter((f) => f.endsWith(".zip"));
308
+ expect(written).toHaveLength(1);
309
+ // and it is a readable backup, not a truncated or empty file
310
+ const zip = new Zip(join(dir, written[0]));
311
+ expect(zip.getEntries().map((e) => e.entryName)).toContain("pack.json");
312
+ // nothing was staged in the working directory on the way there
313
+ expect(await strayBackups()).toHaveLength(0);
314
+ await rm(dir, { recursive: true, force: true });
315
+ });
316
+ it("creates no local file when backing up to Saltcorn files", async () => {
317
+ await File.ensure_file_store();
318
+ await getState().setConfig("site_name", siteName);
319
+ await getState().setConfig("auto_backup_destination", "Saltcorn files");
320
+ // in a folder of its own: on SQLite every test file shares one file
321
+ // store, and a file appearing and disappearing in its root upsets the
322
+ // test files listing it in parallel
323
+ await getState().setConfig("auto_backup_directory", "desttest-backups");
324
+ await auto_backup_now();
325
+ const backupFile = (await File.find({ folder: "desttest-backups", mime_sub: "zip" })).find((f) => f.filename.startsWith(getState().getConfig("backup_file_prefix")));
326
+ assertIsSet(backupFile);
327
+ // the size recorded in the file listing is the size on disk
328
+ const stats = await stat(backupFile.location);
329
+ expect(backupFile.size_kb).toBe(Math.round(stats.size / 1024));
330
+ expect(await strayBackups()).toHaveLength(0);
331
+ await backupFile.delete();
332
+ });
333
+ });
334
+ describe("encrypted backups", () => {
335
+ const password = "hunter2!";
336
+ afterAll(async () => {
337
+ await getState().setConfig("backup_password", "");
338
+ });
339
+ it("encrypts the backup with the configured password", async () => {
340
+ await getState().setConfig("backup_password", password);
341
+ const fnm = await create_backup();
342
+ try {
343
+ const zip = new Zip(fnm);
344
+ // the entry names are readable, the contents are not
345
+ expect(zip.getEntries().map((e) => e.entryName)).toContain("pack.json");
346
+ expect(() => zip.readFile("pack.json")).toThrow();
347
+ const pack = JSON.parse(zip.readFile("pack.json", password).toString());
348
+ expect(Array.isArray(pack.tables)).toBe(true);
349
+ }
350
+ finally {
351
+ await unlink(fnm);
352
+ }
353
+ });
354
+ it("restores an encrypted backup", async () => {
355
+ await getState().setConfig("backup_password", password);
356
+ const fnm = await create_backup();
357
+ try {
358
+ await reset();
359
+ expect(Table.findOne({ name: "books" })).toBe(null);
360
+ const err = await restore(fnm, (p) => { }, true, password);
361
+ expect(err).toBe(undefined);
362
+ const books = Table.findOne({ name: "books" });
363
+ assertIsSet(books);
364
+ }
365
+ finally {
366
+ await unlink(fnm);
367
+ }
368
+ });
369
+ it("reports that a password is required when it is missing", async () => {
370
+ await getState().setConfig("backup_password", password);
371
+ const fnm = await create_backup();
372
+ try {
373
+ let error;
374
+ await restore(fnm, (p) => { }, true).catch((e) => {
375
+ error = e;
376
+ });
377
+ expect(error).toBeTruthy();
378
+ expect(error.requiresPassword).toBe(true);
379
+ }
380
+ finally {
381
+ await unlink(fnm);
382
+ }
383
+ });
384
+ });
201
385
  //# sourceMappingURL=backup.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"backup.test.js","sourceRoot":"","sources":["../../tests/backup.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"backup.test.js","sourceRoot":"","sources":["../../tests/backup.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=file-globs.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-globs.test.d.ts","sourceRoot":"","sources":["../../tests/file-globs.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,66 @@
1
+ import { parseGlobList, matchesAnyGlob } from "../models/file-globs.js";
2
+ import { describe, it, expect } from "@saltcorn/db-common/test_expect";
3
+ const matches = (globs, path) => matchesAnyGlob(parseGlobList(globs), path);
4
+ describe("parseGlobList", () => {
5
+ it("ignores empty and blank entries", () => {
6
+ expect(parseGlobList("")).toHaveLength(0);
7
+ expect(parseGlobList(null)).toHaveLength(0);
8
+ expect(parseGlobList(undefined)).toHaveLength(0);
9
+ expect(parseGlobList(" , ,")).toHaveLength(0);
10
+ expect(parseGlobList("*.mp4, *.mov")).toHaveLength(2);
11
+ });
12
+ });
13
+ describe("matchesAnyGlob", () => {
14
+ it("matches nothing when there are no globs", () => {
15
+ expect(matches("", "foo.png")).toBe(false);
16
+ });
17
+ it("matches by extension in any folder", () => {
18
+ expect(matches("*.mp4", "movie.mp4")).toBe(true);
19
+ expect(matches("*.mp4", "uploads/holiday/movie.mp4")).toBe(true);
20
+ expect(matches("*.mp4", "movie.mp4.txt")).toBe(false);
21
+ expect(matches("*.mp4", "movie.png")).toBe(false);
22
+ });
23
+ it("is case insensitive", () => {
24
+ expect(matches("*.jpg", "IMG_0001.JPG")).toBe(true);
25
+ expect(matches("Cache/**", "cache/thumb.png")).toBe(true);
26
+ });
27
+ it("matches any glob in the list", () => {
28
+ expect(matches("*.mp4, *.mov", "clip.mov")).toBe(true);
29
+ expect(matches(" *.mp4 , *.mov ", "clip.mp4")).toBe(true);
30
+ expect(matches("*.mp4, *.mov", "clip.avi")).toBe(false);
31
+ });
32
+ it("anchors the match", () => {
33
+ expect(matches("report.pdf", "report.pdf")).toBe(true);
34
+ expect(matches("report.pdf", "old_report.pdf")).toBe(false);
35
+ expect(matches("report", "report.pdf")).toBe(false);
36
+ });
37
+ it("does not let * cross directory separators", () => {
38
+ expect(matches("uploads/*.png", "uploads/logo.png")).toBe(true);
39
+ expect(matches("uploads/*.png", "uploads/icons/logo.png")).toBe(false);
40
+ expect(matches("uploads/**/*.png", "uploads/icons/logo.png")).toBe(true);
41
+ });
42
+ it("matches a whole subtree with **", () => {
43
+ expect(matches("cache/**", "cache/a.png")).toBe(true);
44
+ expect(matches("cache/**", "cache/deep/nested/a.png")).toBe(true);
45
+ expect(matches("cache/**", "notcache/a.png")).toBe(false);
46
+ });
47
+ it("matches the directory itself for a subtree glob", () => {
48
+ expect(matchesAnyGlob(parseGlobList("cache/**"), "cache", true)).toBe(true);
49
+ expect(matchesAnyGlob(parseGlobList("cache/**"), "cache", false)).toBe(false);
50
+ expect(matchesAnyGlob(parseGlobList("cache/**"), "other", true)).toBe(false);
51
+ });
52
+ it("supports ? and character classes", () => {
53
+ expect(matches("photo?.png", "photo1.png")).toBe(true);
54
+ expect(matches("photo?.png", "photo12.png")).toBe(false);
55
+ expect(matches("photo[0-9].png", "photo7.png")).toBe(true);
56
+ expect(matches("photo[0-9].png", "photox.png")).toBe(false);
57
+ });
58
+ it("treats dots in globs literally", () => {
59
+ expect(matches("a.b", "axb")).toBe(false);
60
+ });
61
+ it("normalises leading slashes and backslashes", () => {
62
+ expect(matches("cache/**", "/cache/a.png")).toBe(true);
63
+ expect(matches("cache/*.png", "cache\\a.png")).toBe(true);
64
+ });
65
+ });
66
+ //# sourceMappingURL=file-globs.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-globs.test.js","sourceRoot":"","sources":["../../tests/file-globs.test.ts"],"names":[],"mappings":"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"}
@@ -538,7 +538,18 @@ describe("pack install", () => {
538
538
  it("installs pack", async () => {
539
539
  const can = await can_install_pack(todoPack);
540
540
  expect(can).toBe(true);
541
- await install_pack(todoPack, "Todo list", () => { });
541
+ const logMsgs = [];
542
+ await install_pack(todoPack, "Todo list", () => { }, undefined, (msg) => logMsgs.push(msg));
543
+ // one line per entity type that's actually in the pack...
544
+ expect(logMsgs).toContain("Restoring table definitions");
545
+ expect(logMsgs).toContain("Restoring views");
546
+ expect(logMsgs).toContain("Restoring pages");
547
+ expect(logMsgs).toContain("Restoring page groups");
548
+ // ...and nothing for the empty sections
549
+ expect(logMsgs).not.toContain("Restoring triggers");
550
+ expect(logMsgs).not.toContain("Restoring tags");
551
+ expect(logMsgs).not.toContain("Restoring models");
552
+ expect(logMsgs).not.toContain("Restoring roles");
542
553
  const tbl = Table.findOne({ name: "TodoItems" });
543
554
  expect(!!tbl).toBe(true);
544
555
  const menu = getState().getConfig("menu_items", []);
@@ -726,7 +737,7 @@ describe("rls_enabled in packs", () => {
726
737
  expect(tpack.ownership_field_name).toBe("owner_id");
727
738
  });
728
739
  it("field-based RLS pack install enables RLS in PostgreSQL", async () => {
729
- if (db.isSQLite)
740
+ if (!db.supports_row_level_security)
730
741
  return;
731
742
  const schema = db.getTenantSchema();
732
743
  const cls = await db.query(`SELECT relrowsecurity, relforcerowsecurity
@@ -753,7 +764,7 @@ describe("rls_enabled in packs", () => {
753
764
  expect(tpack.ownership_field_name).toBeFalsy();
754
765
  });
755
766
  it("formula-only RLS pack install enables RLS in PostgreSQL", async () => {
756
- if (db.isSQLite)
767
+ if (!db.supports_row_level_security)
757
768
  return;
758
769
  const schema = db.getTenantSchema();
759
770
  const cls = await db.query(`SELECT relrowsecurity, relforcerowsecurity