@filelayer/core 0.3.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/CHANGELOG.md +338 -0
  2. package/LICENSE +202 -0
  3. package/MIGRATIONS.md +328 -0
  4. package/NOTICE +37 -0
  5. package/README.md +343 -0
  6. package/SEMANTICS.md +729 -0
  7. package/dist/authz.d.ts +524 -0
  8. package/dist/authz.d.ts.map +1 -0
  9. package/dist/authz.js +889 -0
  10. package/dist/authz.js.map +1 -0
  11. package/dist/db.d.ts +145 -0
  12. package/dist/db.d.ts.map +1 -0
  13. package/dist/db.js +217 -0
  14. package/dist/db.js.map +1 -0
  15. package/dist/delivery.d.ts +293 -0
  16. package/dist/delivery.d.ts.map +1 -0
  17. package/dist/delivery.js +519 -0
  18. package/dist/delivery.js.map +1 -0
  19. package/dist/errors.d.ts +16 -0
  20. package/dist/errors.d.ts.map +1 -0
  21. package/dist/errors.js +21 -0
  22. package/dist/errors.js.map +1 -0
  23. package/dist/filelayer.d.ts +542 -0
  24. package/dist/filelayer.d.ts.map +1 -0
  25. package/dist/filelayer.js +1360 -0
  26. package/dist/filelayer.js.map +1 -0
  27. package/dist/index.d.ts +8 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +8 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/simple.d.ts +297 -0
  32. package/dist/simple.d.ts.map +1 -0
  33. package/dist/simple.js +492 -0
  34. package/dist/simple.js.map +1 -0
  35. package/dist/storage.d.ts +269 -0
  36. package/dist/storage.d.ts.map +1 -0
  37. package/dist/storage.js +700 -0
  38. package/dist/storage.js.map +1 -0
  39. package/dist/store.d.ts +432 -0
  40. package/dist/store.d.ts.map +1 -0
  41. package/dist/store.js +862 -0
  42. package/dist/store.js.map +1 -0
  43. package/package.json +77 -0
  44. package/schema.sql +1190 -0
  45. package/src/authz.ts +1398 -0
  46. package/src/db.ts +271 -0
  47. package/src/delivery.ts +737 -0
  48. package/src/errors.ts +24 -0
  49. package/src/filelayer.ts +1836 -0
  50. package/src/index.ts +7 -0
  51. package/src/simple.ts +666 -0
  52. package/src/storage.ts +917 -0
  53. package/src/store.ts +1072 -0
  54. package/test/delivery.test.ts +0 -0
  55. package/test/group-subjects.test.ts +1072 -0
  56. package/test/helpers.ts +65 -0
  57. package/test/listing.test.ts +689 -0
  58. package/test/local-s3.d.mts +33 -0
  59. package/test/local-s3.mjs +400 -0
  60. package/test/persistence.test.ts +953 -0
  61. package/test/regression.test.ts +619 -0
  62. package/test/s3-live.test.ts +322 -0
  63. package/test/security.test.ts +1652 -0
  64. package/test/semantics.test.ts +888 -0
  65. package/test/storage.test.ts +437 -0
  66. package/test/tiers.test.ts +432 -0
  67. package/test/vault-example.test.ts +302 -0
  68. package/tsconfig.build.json +29 -0
  69. package/tsconfig.json +19 -0
@@ -0,0 +1,65 @@
1
+ import assert from 'node:assert/strict';
2
+ import { createTestDb, type Queryable } from '../src/db.ts';
3
+ import { Filelayer, FilelayerError } from '../src/filelayer.ts';
4
+ import { MemoryStorage } from '../src/storage.ts';
5
+
6
+ export interface World {
7
+ db: Queryable;
8
+ storage: MemoryStorage;
9
+ fl: Filelayer;
10
+ }
11
+
12
+ export async function newWorld(): Promise<World> {
13
+ const { db } = await createTestDb();
14
+ const storage = new MemoryStorage();
15
+ const fl = new Filelayer(db, storage, { baseUrl: 'https://files.example.test' });
16
+ return { db, storage, fl };
17
+ }
18
+
19
+ export const bytes = (s: string): Uint8Array => new TextEncoder().encode(s);
20
+ export const text = (u: Uint8Array): string => new TextDecoder().decode(u);
21
+
22
+ /** Assert a call rejects with a FilelayerError of the given HTTP-ish status. */
23
+ export async function rejects(
24
+ fn: () => Promise<unknown>,
25
+ status: number,
26
+ code?: string,
27
+ ): Promise<FilelayerError> {
28
+ let err: unknown;
29
+ try {
30
+ await fn();
31
+ } catch (e) {
32
+ err = e;
33
+ }
34
+ assert.ok(err instanceof FilelayerError, `expected FilelayerError, got ${String(err)}`);
35
+ assert.equal(err.status, status, `expected status ${status}, got ${err.status} (${err.reason})`);
36
+ if (code) assert.equal(err.code, code);
37
+ return err;
38
+ }
39
+
40
+ /** Assert a raw SQL statement is rejected by the database itself. */
41
+ export async function dbRejects(
42
+ db: Queryable,
43
+ sql: string,
44
+ params: unknown[],
45
+ match: RegExp,
46
+ ): Promise<string> {
47
+ let msg: string | null = null;
48
+ try {
49
+ await db.query(sql, params);
50
+ } catch (e) {
51
+ msg = (e as Error).message;
52
+ }
53
+ assert.ok(msg !== null, 'expected the database to reject this statement, but it succeeded');
54
+ assert.match(msg, match);
55
+ return msg;
56
+ }
57
+
58
+ /** Pass null to count the system chain (decisions with no tenant). */
59
+ export async function countAudit(db: Queryable, orgId: string | null): Promise<number> {
60
+ const { rows } = await db.query<{ c: number }>(
61
+ `SELECT count(*)::int AS c FROM audit_event WHERE org_id IS NOT DISTINCT FROM $1`,
62
+ [orgId],
63
+ );
64
+ return Number(rows[0]!.c);
65
+ }