@saltcorn/admin-models 1.6.3-beta.1 → 1.7.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/cjs/index.cjs +18 -0
  2. package/cjs/models/backup-retention.cjs +18 -0
  3. package/cjs/models/backup.cjs +18 -0
  4. package/cjs/models/config-check.cjs +18 -0
  5. package/cjs/models/file-globs.cjs +18 -0
  6. package/cjs/models/pack.cjs +18 -0
  7. package/cjs/models/snapshot.cjs +18 -0
  8. package/cjs/models/tenant.cjs +18 -0
  9. package/cjs/models/zip-extract.cjs +18 -0
  10. package/cjs/models/zip-format.cjs +18 -0
  11. package/cjs/models/zip-worker.cjs +18 -0
  12. package/cjs/models/zip-writer.cjs +18 -0
  13. package/cjs/models/zip.cjs +18 -0
  14. package/dist/index.d.ts +6 -5
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +12 -18
  17. package/dist/index.js.map +1 -1
  18. package/dist/models/backup-retention.d.ts +57 -0
  19. package/dist/models/backup-retention.d.ts.map +1 -0
  20. package/dist/models/backup-retention.js +108 -0
  21. package/dist/models/backup-retention.js.map +1 -0
  22. package/dist/models/backup.d.ts +7 -3
  23. package/dist/models/backup.d.ts.map +1 -1
  24. package/dist/models/backup.js +479 -409
  25. package/dist/models/backup.js.map +1 -1
  26. package/dist/models/config-check.d.ts +2 -1
  27. package/dist/models/config-check.d.ts.map +1 -1
  28. package/dist/models/config-check.js +16 -23
  29. package/dist/models/config-check.js.map +1 -1
  30. package/dist/models/file-globs.d.ts +34 -0
  31. package/dist/models/file-globs.d.ts.map +1 -0
  32. package/dist/models/file-globs.js +47 -0
  33. package/dist/models/file-globs.js.map +1 -0
  34. package/dist/models/pack.d.ts +3 -2
  35. package/dist/models/pack.d.ts.map +1 -1
  36. package/dist/models/pack.js +147 -151
  37. package/dist/models/pack.js.map +1 -1
  38. package/dist/models/snapshot.d.ts +1 -1
  39. package/dist/models/snapshot.d.ts.map +1 -1
  40. package/dist/models/snapshot.js +26 -29
  41. package/dist/models/snapshot.js.map +1 -1
  42. package/dist/models/tenant.d.ts +1 -1
  43. package/dist/models/tenant.d.ts.map +1 -1
  44. package/dist/models/tenant.js +45 -48
  45. package/dist/models/tenant.js.map +1 -1
  46. package/dist/models/zip-extract.d.ts +14 -0
  47. package/dist/models/zip-extract.d.ts.map +1 -0
  48. package/dist/models/zip-extract.js +110 -0
  49. package/dist/models/zip-extract.js.map +1 -0
  50. package/dist/models/zip-format.d.ts +57 -0
  51. package/dist/models/zip-format.d.ts.map +1 -0
  52. package/dist/models/zip-format.js +106 -0
  53. package/dist/models/zip-format.js.map +1 -0
  54. package/dist/models/zip-worker.d.ts +2 -0
  55. package/dist/models/zip-worker.d.ts.map +1 -0
  56. package/dist/models/zip-worker.js +177 -0
  57. package/dist/models/zip-worker.js.map +1 -0
  58. package/dist/models/zip-writer.d.ts +75 -0
  59. package/dist/models/zip-writer.d.ts.map +1 -0
  60. package/dist/models/zip-writer.js +321 -0
  61. package/dist/models/zip-writer.js.map +1 -0
  62. package/dist/models/zip.d.ts +101 -0
  63. package/dist/models/zip.d.ts.map +1 -0
  64. package/dist/models/zip.js +211 -0
  65. package/dist/models/zip.js.map +1 -0
  66. package/dist/tests/backup-retention.test.d.ts +2 -0
  67. package/dist/tests/backup-retention.test.d.ts.map +1 -0
  68. package/dist/tests/backup-retention.test.js +134 -0
  69. package/dist/tests/backup-retention.test.js.map +1 -0
  70. package/dist/tests/backup.test.d.ts +2 -0
  71. package/dist/tests/backup.test.d.ts.map +1 -0
  72. package/dist/tests/backup.test.js +385 -0
  73. package/dist/tests/backup.test.js.map +1 -0
  74. package/dist/tests/cfgcheck.test.d.ts +2 -0
  75. package/dist/tests/cfgcheck.test.d.ts.map +1 -0
  76. package/dist/tests/cfgcheck.test.js +32 -0
  77. package/dist/tests/cfgcheck.test.js.map +1 -0
  78. package/dist/tests/file-globs.test.d.ts +2 -0
  79. package/dist/tests/file-globs.test.d.ts.map +1 -0
  80. package/dist/tests/file-globs.test.js +66 -0
  81. package/dist/tests/file-globs.test.js.map +1 -0
  82. package/dist/tests/pack.test.d.ts +2 -0
  83. package/dist/tests/pack.test.d.ts.map +1 -0
  84. package/dist/tests/pack.test.js +780 -0
  85. package/dist/tests/pack.test.js.map +1 -0
  86. package/dist/tests/random.test.d.ts +2 -0
  87. package/dist/tests/random.test.d.ts.map +1 -0
  88. package/dist/tests/random.test.js +150 -0
  89. package/dist/tests/random.test.js.map +1 -0
  90. package/dist/tests/tenant.test.d.ts +2 -0
  91. package/dist/tests/tenant.test.d.ts.map +1 -0
  92. package/dist/tests/tenant.test.js +106 -0
  93. package/dist/tests/tenant.test.js.map +1 -0
  94. package/dist/tests/zip.test.d.ts +2 -0
  95. package/dist/tests/zip.test.d.ts.map +1 -0
  96. package/dist/tests/zip.test.js +319 -0
  97. package/dist/tests/zip.test.js.map +1 -0
  98. package/gen-cjs-shims.cjs +71 -0
  99. package/package.json +39 -29
@@ -0,0 +1,319 @@
1
+ import { mkdtemp, mkdir, rm, readFile, writeFile, stat } from "fs/promises";
2
+ import { createWriteStream } from "fs";
3
+ import { randomFillSync } from "crypto";
4
+ import { Readable } from "stream";
5
+ import { join } from "path";
6
+ import { tmpdir } from "os";
7
+ import Zip from "adm-zip";
8
+ import { Open } from "unzipper";
9
+ import { ZipBuilder } from "../models/zip.js";
10
+ import { extractZip } from "../models/zip-extract.js";
11
+ import { ZipStreamWriter } from "../models/zip-writer.js";
12
+ import { afterAll, beforeAll, describe, it, expect, jest, } from "@saltcorn/db-common/test_expect";
13
+ jest.setTimeout(60000);
14
+ let dir;
15
+ let sourceDir;
16
+ /**
17
+ * Big enough to pass through the writer, the worker and the reader in
18
+ * several chunks, so the streaming paths are actually exercised, and random
19
+ * so that it does not compress away to nothing on the way.
20
+ */
21
+ const bigContent = Buffer.alloc(6 * 1024 * 1024);
22
+ /**
23
+ * An archive made by `zip -X -r -P 'hunter2!'` of a "hello world" small.txt
24
+ * and a files/big.txt of 100,000 x's - the shape of a backup from before the
25
+ * zip writer was brought in-process.
26
+ */
27
+ const LEGACY_ZIP_BASE64 = "UEsDBAoACQAAAARJD12FEUoNFwAAAAsAAAAJAAAAc21hbGwudHh0EMEQLQZe6Qx3/ZjBiV" +
28
+ "K8M4BlVk1MBIRQSwcIhRFKDRcAAAALAAAAUEsDBAoAAAAAAARJD10AAAAAAAAAAAAAAAAG" +
29
+ "AAAAZmlsZXMvUEsDBBQACQAIAARJD11xEQf+fgAAAKCGAQANAAAAZmlsZXMvYmlnLnR4dD" +
30
+ "tuR/AdZQjw43ZCt1y8UL6+ryS38VIMZ4RU0tjnf0dWfV4lZ0f5FjWnuw+OoGJL0TXGIK/a" +
31
+ "qDql9X9/n2GffctLzTmZJJouu5IyCPV2AharTlHVwtPTvYCwF/w1x+FT14MtEQWbCLioU4" +
32
+ "WeHDO32GpxHsMFX6MP0o8wYGDpnVBLBwhxEQf+fgAAAKCGAQBQSwECHgMKAAkAAAAESQ9d" +
33
+ "hRFKDRcAAAALAAAACQAAAAAAAAABAAAAtIEAAAAAc21hbGwudHh0UEsBAh4DCgAAAAAABE" +
34
+ "kPXQAAAAAAAAAAAAAAAAYAAAAAAAAAAAAQAP1BTgAAAGZpbGVzL1BLAQIeAxQACQAIAARJ" +
35
+ "D11xEQf+fgAAAKCGAQANAAAAAAAAAAEAAAC0gXIAAABmaWxlcy9iaWcudHh0UEsFBgAAAA" +
36
+ "ADAAMApgAAACsBAAAAAA==";
37
+ beforeAll(async () => {
38
+ dir = await mkdtemp(join(tmpdir(), "sc-zip-test-"));
39
+ sourceDir = join(dir, "source");
40
+ await mkdir(sourceDir, { recursive: true });
41
+ randomFillSync(bigContent);
42
+ await writeFile(join(sourceDir, "big.bin"), bigContent);
43
+ await writeFile(join(sourceDir, "small.txt"), "hello world");
44
+ await writeFile(join(sourceDir, "empty.txt"), "");
45
+ });
46
+ afterAll(async () => {
47
+ await rm(dir, { recursive: true, force: true });
48
+ });
49
+ /** an archive with one of everything: buffer, file, empty file, directory */
50
+ const buildArchive = async (path, password) => {
51
+ const zip = await ZipBuilder.toFile(path, password);
52
+ await zip.addBuffer("pack.json", Buffer.from(JSON.stringify({ a: 1 })));
53
+ await zip.addDirectory("files");
54
+ await zip.addLocalFile("files/big.bin", join(sourceDir, "big.bin"));
55
+ await zip.addLocalFile("files/small.txt", join(sourceDir, "small.txt"));
56
+ await zip.addLocalFile("files/empty.txt", join(sourceDir, "empty.txt"));
57
+ await zip.finish();
58
+ };
59
+ describe("zip round trip", () => {
60
+ it("writes and reads back every kind of entry", async () => {
61
+ const zipPath = join(dir, "roundtrip.zip");
62
+ await buildArchive(zipPath);
63
+ const out = join(dir, "roundtrip-out");
64
+ await extractZip(zipPath, out);
65
+ expect((await readFile(join(out, "pack.json"))).toString()).toBe('{"a":1}');
66
+ expect((await readFile(join(out, "files/small.txt"))).toString()).toBe("hello world");
67
+ expect((await stat(join(out, "files/empty.txt"))).size).toBe(0);
68
+ expect((await stat(join(out, "files"))).isDirectory()).toBe(true);
69
+ const big = await readFile(join(out, "files/big.bin"));
70
+ expect(Buffer.compare(big, bigContent)).toBe(0);
71
+ });
72
+ it("produces an archive other zip readers understand", async () => {
73
+ // adm-zip is an independent implementation: if it agrees, the archive is
74
+ // a real zip file and not just something our own reader happens to read
75
+ const zipPath = join(dir, "compat.zip");
76
+ await buildArchive(zipPath);
77
+ const zip = new Zip(zipPath);
78
+ expect(zip.getEntries().map((e) => e.entryName)).toEqual([
79
+ "pack.json",
80
+ "files/",
81
+ "files/big.bin",
82
+ "files/small.txt",
83
+ "files/empty.txt",
84
+ ]);
85
+ expect(zip.readAsText("files/small.txt")).toBe("hello world");
86
+ expect(Buffer.compare(zip.readFile("files/big.bin"), bigContent)).toBe(0);
87
+ });
88
+ it("reads an archive written by another zip writer", async () => {
89
+ const zipPath = join(dir, "foreign.zip");
90
+ const zip = new Zip();
91
+ zip.addFile("a/b.txt", Buffer.from("written by adm-zip"));
92
+ zip.addFile("big.bin", bigContent);
93
+ zip.writeZip(zipPath);
94
+ const out = join(dir, "foreign-out");
95
+ await extractZip(zipPath, out);
96
+ expect((await readFile(join(out, "a/b.txt"))).toString()).toBe("written by adm-zip");
97
+ expect(Buffer.compare(await readFile(join(out, "big.bin")), bigContent)).toBe(0);
98
+ });
99
+ it("rejects a corrupted archive rather than writing out bad data", async () => {
100
+ const zipPath = join(dir, "corrupt.zip");
101
+ await buildArchive(zipPath);
102
+ // flip a byte in the middle of the compressed data
103
+ const bytes = await readFile(zipPath);
104
+ bytes[Math.floor(bytes.length / 2)] ^= 0xff;
105
+ await writeFile(zipPath, bytes);
106
+ let error;
107
+ await extractZip(zipPath, join(dir, "corrupt-out")).catch((e) => {
108
+ error = e;
109
+ });
110
+ expect(!!error).toBe(true);
111
+ });
112
+ it("refuses to extract outside the target directory", async () => {
113
+ const zipPath = join(dir, "slip.zip");
114
+ const out = createWriteStream(zipPath);
115
+ const closed = new Promise((resolve, reject) => {
116
+ out.on("finish", () => resolve());
117
+ out.on("error", reject);
118
+ });
119
+ const writer = new ZipStreamWriter(out);
120
+ // ZipStreamWriter strips leading slashes, so climb out with ..
121
+ await writer.addBuffer("../escaped.txt", Buffer.from("nope"));
122
+ await writer.finalize();
123
+ out.end();
124
+ await closed;
125
+ let error;
126
+ await extractZip(zipPath, join(dir, "slip-out")).catch((e) => {
127
+ error = e;
128
+ });
129
+ expect(error?.message).toContain("outside the target");
130
+ });
131
+ });
132
+ describe("zip streaming", () => {
133
+ it("emits the archive while it is still being built", async () => {
134
+ // the point of the streaming writer: bytes come out as entries go in,
135
+ // so an archive larger than memory can be produced
136
+ const zip = await ZipBuilder.toStream();
137
+ const chunks = [];
138
+ let bytesBeforeFinish = 0;
139
+ const consumed = (async () => {
140
+ for await (const chunk of zip.stream)
141
+ chunks.push(chunk);
142
+ })();
143
+ await zip.addLocalFile("big.bin", join(sourceDir, "big.bin"));
144
+ await zip.addLocalFile("big2.bin", join(sourceDir, "big.bin"));
145
+ bytesBeforeFinish = chunks.reduce((n, c) => n + c.length, 0);
146
+ await zip.finish();
147
+ await consumed;
148
+ expect(bytesBeforeFinish).toBeGreaterThan(0);
149
+ expect(chunks.length).toBeGreaterThan(1);
150
+ // and what came out is a complete archive
151
+ const zipPath = join(dir, "streamed.zip");
152
+ await writeFile(zipPath, Buffer.concat(chunks));
153
+ const out = join(dir, "streamed-out");
154
+ await extractZip(zipPath, out);
155
+ expect(Buffer.compare(await readFile(join(out, "big.bin")), bigContent)).toBe(0);
156
+ expect(Buffer.compare(await readFile(join(out, "big2.bin")), bigContent)).toBe(0);
157
+ });
158
+ it("adds an entry from a stream of unknown length", async () => {
159
+ // content produced in the main thread - a table dump - goes in chunk by
160
+ // chunk, so it is never assembled into one buffer anywhere
161
+ const zipPath = join(dir, "fromstream.zip");
162
+ const zip = await ZipBuilder.toFile(zipPath);
163
+ const parts = [
164
+ Buffer.from("["),
165
+ ...Array.from({ length: 200 }, (_, i) => Buffer.from(JSON.stringify({ id: i, pad: "x".repeat(1000) }) + ",")),
166
+ Buffer.from("]"),
167
+ ];
168
+ await zip.addStream("tables/rows.json", Readable.from(parts));
169
+ await zip.addBuffer("pack.json", Buffer.from("{}"));
170
+ await zip.finish();
171
+ const out = join(dir, "fromstream-out");
172
+ await extractZip(zipPath, out);
173
+ expect(Buffer.compare(await readFile(join(out, "tables/rows.json")), Buffer.concat(parts))).toBe(0);
174
+ // it fit within the probe, so it is a plain entry any reader can read
175
+ expect(new Zip(zipPath).readFile("tables/rows.json").length).toBe(Buffer.concat(parts).length);
176
+ });
177
+ it("takes every chunk from a source that reuses its buffer", async () => {
178
+ // a Readable is free to fill and push one buffer over and over. Handing
179
+ // that buffer to the worker thread must not leave the producer holding a
180
+ // detached one, which would silently drop every chunk after the first
181
+ const zipPath = join(dir, "reused-buffer.zip");
182
+ const chunk = Buffer.alloc(64 * 1024, 65);
183
+ let pushed = 0;
184
+ const source = new Readable({
185
+ read() {
186
+ this.push(pushed++ < 8 ? chunk : null);
187
+ },
188
+ });
189
+ const zip = await ZipBuilder.toFile(zipPath);
190
+ await zip.addStream("reused.bin", source);
191
+ await zip.finish();
192
+ const out = join(dir, "reused-buffer-out");
193
+ await extractZip(zipPath, out);
194
+ const written = await readFile(join(out, "reused.bin"));
195
+ expect(written.length).toBe(chunk.length * 8);
196
+ expect(Buffer.compare(written, Buffer.concat(Array(8).fill(chunk)))).toBe(0);
197
+ });
198
+ it("stops building when the consumer gives up", async () => {
199
+ const zip = await ZipBuilder.toStream();
200
+ zip.stream.destroy(new Error("consumer went away"));
201
+ let error;
202
+ try {
203
+ // eventually the worker is torn down and adding entries fails, rather
204
+ // than blocking forever on a reader that is never coming back
205
+ for (let i = 0; i < 200; i++)
206
+ await zip.addLocalFile(`big${i}.bin`, join(sourceDir, "big.bin"));
207
+ await zip.finish();
208
+ }
209
+ catch (e) {
210
+ error = e;
211
+ }
212
+ await zip.discard();
213
+ expect(!!error).toBe(true);
214
+ });
215
+ });
216
+ describe("zip encryption", () => {
217
+ const password = "hunter2!";
218
+ it("encrypts entries with the password", async () => {
219
+ const zipPath = join(dir, "encrypted.zip");
220
+ await buildArchive(zipPath, password);
221
+ // entry names stay readable, contents do not
222
+ const zip = new Zip(zipPath);
223
+ expect(zip.getEntries().map((e) => e.entryName)).toContain("files/small.txt");
224
+ expect(() => zip.readFile("files/small.txt")).toThrow();
225
+ expect(zip.readFile("files/small.txt", password).toString()).toBe("hello world");
226
+ const out = join(dir, "encrypted-out");
227
+ await extractZip(zipPath, out, password);
228
+ expect(Buffer.compare(await readFile(join(out, "files/big.bin")), bigContent)).toBe(0);
229
+ });
230
+ it("reports that a password is needed when it is missing or wrong", async () => {
231
+ const zipPath = join(dir, "encrypted2.zip");
232
+ await buildArchive(zipPath, password);
233
+ let missing;
234
+ await extractZip(zipPath, join(dir, "enc-missing")).catch((e) => {
235
+ missing = e;
236
+ });
237
+ expect(missing?.requiresPassword).toBe(true);
238
+ let wrong;
239
+ await extractZip(zipPath, join(dir, "enc-wrong"), "not it").catch((e) => {
240
+ wrong = e;
241
+ });
242
+ expect(wrong?.requiresPassword).toBe(true);
243
+ });
244
+ it("restores a backup encrypted by an older Saltcorn", async () => {
245
+ // Backups used to be made by the system `zip -P`, which puts the sizes in
246
+ // the local header and takes the password check byte from the CRC, where
247
+ // the writer here uses a data descriptor and the modification time. Those
248
+ // archives are still out there and still have to restore.
249
+ const zipPath = join(dir, "legacy.zip");
250
+ await writeFile(zipPath, Buffer.from(LEGACY_ZIP_BASE64, "base64"));
251
+ const out = join(dir, "legacy-out");
252
+ await extractZip(zipPath, out, password);
253
+ expect((await readFile(join(out, "small.txt"))).toString()).toBe("hello world");
254
+ const big = await readFile(join(out, "files/big.txt"));
255
+ expect(big.length).toBe(100000);
256
+ expect(big.toString()).toBe("x".repeat(100000));
257
+ let missing;
258
+ await extractZip(zipPath, join(dir, "legacy-missing")).catch((e) => {
259
+ missing = e;
260
+ });
261
+ expect(missing?.requiresPassword).toBe(true);
262
+ });
263
+ });
264
+ describe("zip64", () => {
265
+ /** write an archive with the writer directly, so options can be set */
266
+ const writeWith = async (path, options, add) => {
267
+ const out = createWriteStream(path);
268
+ const closed = new Promise((resolve, reject) => {
269
+ out.on("finish", () => resolve());
270
+ out.on("error", reject);
271
+ });
272
+ const writer = new ZipStreamWriter(out, options);
273
+ await add(writer);
274
+ await writer.finalize();
275
+ out.end();
276
+ await closed;
277
+ };
278
+ it("writes entries over the size limit in zip64 format", async () => {
279
+ // the real threshold is 3.75GB; lower it so the format can be tested
280
+ // without writing four gigabytes
281
+ const zipPath = join(dir, "zip64entry.zip");
282
+ await writeWith(zipPath, { zip64Threshold: 1024 }, async (w) => {
283
+ await w.addBuffer("big.bin", bigContent);
284
+ await w.addBuffer("tiny.txt", Buffer.from("small enough"));
285
+ });
286
+ const out = join(dir, "zip64entry-out");
287
+ await extractZip(zipPath, out);
288
+ expect(Buffer.compare(await readFile(join(out, "big.bin")), bigContent)).toBe(0);
289
+ expect((await readFile(join(out, "tiny.txt"))).toString()).toBe("small enough");
290
+ // an independent reader agrees it is a valid zip64 archive
291
+ expect(new Zip(zipPath).readAsText("tiny.txt")).toBe("small enough");
292
+ });
293
+ it("falls back to zip64 for a stream that outgrows the probe", async () => {
294
+ // an entry of unknown length that does not end within probeLimit has to
295
+ // be written in zip64 format: there is no way back once the local header
296
+ // has gone out
297
+ const zipPath = join(dir, "zip64stream.zip");
298
+ await writeWith(zipPath, { probeLimit: 1024 }, async (w) => {
299
+ await w.addStream("long.bin", Readable.from([bigContent]));
300
+ await w.addStream("short.bin", Readable.from([Buffer.from("brief")]));
301
+ });
302
+ const out = join(dir, "zip64stream-out");
303
+ await extractZip(zipPath, out);
304
+ expect(Buffer.compare(await readFile(join(out, "long.bin")), bigContent)).toBe(0);
305
+ expect((await readFile(join(out, "short.bin"))).toString()).toBe("brief");
306
+ });
307
+ it("writes a zip64 end of central directory past 65535 entries", async () => {
308
+ const count = 70000;
309
+ const zipPath = join(dir, "manyentries.zip");
310
+ await writeWith(zipPath, { level: 1 }, async (w) => {
311
+ for (let i = 0; i < count; i++)
312
+ await w.addBuffer(`e/${i}.txt`, Buffer.from(`entry ${i}`));
313
+ });
314
+ const entries = (await Open.file(zipPath)).files;
315
+ expect(entries.length).toBe(count);
316
+ expect(entries[count - 1].path).toBe(`e/${count - 1}.txt`);
317
+ });
318
+ });
319
+ //# sourceMappingURL=zip.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zip.test.js","sourceRoot":"","sources":["../../tests/zip.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Generates CommonJS interop shims under ./cjs for every importable module.
3
+ *
4
+ * This package is ESM ("type": "module"). When an out-of-tree CommonJS package
5
+ * does `require("@saltcorn/data/models/table")`, Node's require(ESM) returns the
6
+ * module *namespace* ({ __esModule: true, default: Table }) rather than the
7
+ * class itself, which breaks `const Table = require(...)`. The package "exports"
8
+ * map routes the "require" condition to these shims, which unwrap the default
9
+ * export so CommonJS consumers keep getting the value they got before the ESM
10
+ * conversion. ESM consumers (the "import" condition) get ./dist directly.
11
+ *
12
+ * Run automatically before tsc (see package.json "pretsc"). The shims only
13
+ * mirror the source module tree, so they can be generated without a build.
14
+ */
15
+ const fs = require("fs");
16
+ const path = require("path");
17
+
18
+ const ROOT = __dirname;
19
+ const SRC_SKIP = new Set(["node_modules", "dist", "cjs", "mobile-mocks"]);
20
+
21
+ function walk(dir, acc = []) {
22
+ for (const ent of fs.readdirSync(dir, { withFileTypes: true })) {
23
+ if (ent.isDirectory()) {
24
+ if (SRC_SKIP.has(ent.name)) continue;
25
+ walk(path.join(dir, ent.name), acc);
26
+ } else if (
27
+ ent.isFile() &&
28
+ ent.name.endsWith(".ts") &&
29
+ !ent.name.endsWith(".d.ts") &&
30
+ !ent.name.endsWith(".test.ts")
31
+ ) {
32
+ acc.push(path.join(dir, ent.name));
33
+ }
34
+ }
35
+ return acc;
36
+ }
37
+
38
+ const SHIM = (
39
+ distRel
40
+ ) => `// CommonJS interop shim — AUTO-GENERATED, DO NOT EDIT.
41
+ // See gen-cjs-shims.cjs.
42
+ "use strict";
43
+ const m = require(${JSON.stringify(distRel)});
44
+ const e = m && m.__esModule && "default" in m ? m.default : m;
45
+ module.exports = e;
46
+ if (e !== m && e && (typeof e === "object" || typeof e === "function")) {
47
+ for (const k in m) {
48
+ if (k === "default" || k === "__esModule" || k in e) continue;
49
+ try {
50
+ Object.defineProperty(e, k, {
51
+ get: () => m[k],
52
+ enumerable: true,
53
+ configurable: true,
54
+ });
55
+ } catch {}
56
+ }
57
+ }
58
+ `;
59
+
60
+ let count = 0;
61
+ for (const file of walk(ROOT)) {
62
+ const rel = path.relative(ROOT, file).replace(/\.ts$/, "");
63
+ const cjsPath = path.join(ROOT, "cjs", rel + ".cjs");
64
+ const distRel =
65
+ path.relative(path.dirname(cjsPath), path.join(ROOT, "dist", rel)) + ".js";
66
+ const normalized = distRel.startsWith(".") ? distRel : "./" + distRel;
67
+ fs.mkdirSync(path.dirname(cjsPath), { recursive: true });
68
+ fs.writeFileSync(cjsPath, SHIM(normalized));
69
+ count++;
70
+ }
71
+ console.log(`gen-cjs-shims: wrote ${count} shims under cjs/`);
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "@saltcorn/admin-models",
3
- "version": "1.6.3-beta.1",
3
+ "version": "1.7.0-alpha.1",
4
4
  "description": "models only required by the admin interface for Saltcorn, open-source no-code platform",
5
5
  "homepage": "https://saltcorn.com",
6
+ "type": "module",
6
7
  "scripts": {
7
- "test": "node --experimental-vm-modules ../../node_modules/jest/bin/jest.js ./tests --runInBand",
8
+ "test": "cd dist && NODE_ENV=test node --require ../setup-test-schema.cjs --test --test-concurrency=4 --test-force-exit",
9
+ "gen:cjs-shims": "node gen-cjs-shims.cjs",
10
+ "pretsc": "node gen-cjs-shims.cjs",
8
11
  "tsc": "tsc -p tsconfig.json",
9
12
  "clean": "rm -rf ./dist/*"
10
13
  },
@@ -12,8 +15,24 @@
12
15
  "license": "MIT",
13
16
  "main": "dist/index.js",
14
17
  "exports": {
15
- ".": "./dist/index.js",
16
- "./*": "./dist/*.js"
18
+ ".": {
19
+ "types": "./dist/index.d.ts",
20
+ "require": "./cjs/index.cjs",
21
+ "import": "./dist/index.js",
22
+ "default": "./dist/index.js"
23
+ },
24
+ "./*.js": {
25
+ "types": "./dist/*.d.ts",
26
+ "require": "./cjs/*.cjs",
27
+ "import": "./dist/*.js",
28
+ "default": "./dist/*.js"
29
+ },
30
+ "./*": {
31
+ "types": "./dist/*.d.ts",
32
+ "require": "./cjs/*.cjs",
33
+ "import": "./dist/*.js",
34
+ "default": "./dist/*.js"
35
+ }
17
36
  },
18
37
  "typesVersions": {
19
38
  "*": {
@@ -24,57 +43,48 @@
24
43
  },
25
44
  "files": [
26
45
  "dist/**/*",
27
- "!dist/tsconfig.ref.tsbuildinfo"
46
+ "!dist/tsconfig.ref.tsbuildinfo",
47
+ "cjs/**/*.cjs",
48
+ "gen-cjs-shims.cjs"
28
49
  ],
29
50
  "dependencies": {
30
51
  "@aws-sdk/client-s3": "3.1057.0",
31
52
  "@aws-sdk/lib-storage": "3.1057.0",
32
- "@saltcorn/types": "1.6.3-beta.1",
33
- "@saltcorn/markup": "1.6.3-beta.1",
34
- "@saltcorn/db-common": "1.6.3-beta.1",
35
- "@saltcorn/data": "1.6.3-beta.1",
36
- "adm-zip": "0.5.16",
53
+ "@saltcorn/types": "1.7.0-alpha.1",
54
+ "@saltcorn/markup": "1.7.0-alpha.1",
55
+ "@saltcorn/db-common": "1.7.0-alpha.1",
56
+ "@saltcorn/data": "1.7.0-alpha.1",
37
57
  "chaos-guinea-pig": "0.2.1",
38
58
  "csv-stringify": "^6.5.2",
39
59
  "csvtojson": "^2.0.10",
40
60
  "dateformat": "^4.6.3",
61
+ "glob-to-regexp": "^0.4.1",
41
62
  "lodash": "^4.17.23",
42
63
  "node-fetch": "2.6.9",
64
+ "semver": "^7.6.3",
43
65
  "ssh2-sftp-client": "11.0.0",
44
- "tmp-promise": "^3.0.3"
66
+ "tmp-promise": "^3.0.3",
67
+ "unzipper": "^0.12.5"
45
68
  },
46
69
  "repository": "github:saltcorn/saltcorn",
47
70
  "publishConfig": {
48
71
  "access": "public"
49
72
  },
50
73
  "devDependencies": {
51
- "@saltcorn/sbadmin2": "1.6.3-beta.1",
74
+ "@saltcorn/sbadmin2": "1.7.0-alpha.1",
52
75
  "@types/adm-zip": "0.5.7",
53
76
  "@types/dateformat": "5.0.0",
54
- "@types/jest": "29.5.14",
77
+ "@types/glob-to-regexp": "^0.4.4",
55
78
  "@types/lodash": "4.14.182",
56
79
  "@types/node": "^20.14.7",
57
80
  "@types/node-fetch": "2.5.12",
81
+ "@types/semver": "^7.7.1",
58
82
  "@types/ssh2-sftp-client": "9.0.3",
59
83
  "@types/tmp": "^0.2.3",
60
- "jest": "29.7.0",
61
- "ts-jest": "29.2.5",
84
+ "@types/unzipper": "0.10.11",
85
+ "adm-zip": "0.5.16",
62
86
  "typescript": "5.9.2"
63
87
  },
64
- "jest": {
65
- "transform": {},
66
- "preset": "ts-jest",
67
- "testEnvironment": "node",
68
- "modulePathIgnorePatterns": [
69
- ".*\\.js$"
70
- ],
71
- "moduleNameMapper": {
72
- "@saltcorn/sqlite/(.*)": "<rootDir>/../sqlite/dist/$1",
73
- "@saltcorn/db-common/(.*)": "<rootDir>/../db-common/dist/$1",
74
- "@saltcorn/data/(.*)": "<rootDir>/../saltcorn-data/dist/$1",
75
- "@saltcorn/types/(.*)": "<rootDir>/../saltcorn-types/dist/$1"
76
- }
77
- },
78
88
  "overrides": {
79
89
  "parse5": "7.2.1",
80
90
  "undici": "7.12.0",