@argentic/chest-sdk 0.1.1 → 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 (57) hide show
  1. package/README.md +573 -37
  2. package/client/index.ts +12 -5
  3. package/client/src/ai.ts +374 -0
  4. package/client/src/api.ts +85 -0
  5. package/client/src/chest.ts +80 -0
  6. package/client/src/errors.ts +58 -3
  7. package/client/src/events.ts +228 -0
  8. package/client/src/files.ts +93 -88
  9. package/client/src/member.ts +61 -17
  10. package/client/src/members.ts +167 -0
  11. package/client/src/notifications.ts +148 -0
  12. package/client/src/testing.ts +564 -0
  13. package/dist/index.d.ts +5 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +12 -5
  16. package/dist/index.js.map +1 -1
  17. package/dist/src/ai.d.ts +131 -0
  18. package/dist/src/ai.d.ts.map +1 -0
  19. package/dist/src/ai.js +290 -0
  20. package/dist/src/ai.js.map +1 -0
  21. package/dist/src/api.d.ts +11 -0
  22. package/dist/src/api.d.ts.map +1 -0
  23. package/dist/src/api.js +93 -0
  24. package/dist/src/api.js.map +1 -0
  25. package/dist/src/chest.d.ts +10 -0
  26. package/dist/src/chest.d.ts.map +1 -0
  27. package/dist/src/chest.js +49 -0
  28. package/dist/src/chest.js.map +1 -0
  29. package/dist/src/errors.d.ts +19 -0
  30. package/dist/src/errors.d.ts.map +1 -1
  31. package/dist/src/errors.js +49 -3
  32. package/dist/src/errors.js.map +1 -1
  33. package/dist/src/events.d.ts +56 -0
  34. package/dist/src/events.d.ts.map +1 -0
  35. package/dist/src/events.js +193 -0
  36. package/dist/src/events.js.map +1 -0
  37. package/dist/src/files.d.ts +17 -1
  38. package/dist/src/files.d.ts.map +1 -1
  39. package/dist/src/files.js +95 -92
  40. package/dist/src/files.js.map +1 -1
  41. package/dist/src/member.d.ts +10 -3
  42. package/dist/src/member.d.ts.map +1 -1
  43. package/dist/src/member.js +34 -11
  44. package/dist/src/member.js.map +1 -1
  45. package/dist/src/members.d.ts +34 -0
  46. package/dist/src/members.d.ts.map +1 -0
  47. package/dist/src/members.js +146 -0
  48. package/dist/src/members.js.map +1 -0
  49. package/dist/src/notifications.d.ts +25 -0
  50. package/dist/src/notifications.d.ts.map +1 -0
  51. package/dist/src/notifications.js +121 -0
  52. package/dist/src/notifications.js.map +1 -0
  53. package/dist/src/testing.d.ts +101 -0
  54. package/dist/src/testing.d.ts.map +1 -0
  55. package/dist/src/testing.js +552 -0
  56. package/dist/src/testing.js.map +1 -0
  57. package/package.json +40 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chest.js","sourceRoot":"","sources":["../../client/src/chest.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAgC/D,sEAAsE;AACtE,gEAAgE;AAChE,+DAA+D;AAC/D,MAAM,mBAAmB,GAAG,wCAAwC,CAAC;AAErE,SAAS,IAAI,CAAC,IAAY,EAAE,KAAiC;IAC3D,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,cAAc,EAAE,GAAG,EAAE,2BAA2B,IAAI,wBAAwB,CAAC,CAAC;IACnJ,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IAC9C,IAAI,CAAC;QACH,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,IAAI,GAAG,GAAW,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAC;AAE9D,+DAA+D;AAC/D,SAAS,MAAM,CAAC,EAAQ,EAAE,IAAY;IACpC,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACxL,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED,2EAA2E;AAC3E,sBAAsB;AACtB,MAAM,CAAC,MAAM,KAAK,GAAU;IAC1B,IAAI,YAAY;QACd,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;IACxF,CAAC;IACD,IAAI,QAAQ;QACV,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC;IACD,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACtE,CAAC;IACD,KAAK,CAAC,EAAE,GAAkB,IAAI,CAAC,GAAG,EAAE;QAClC,MAAM,OAAO,GAAG,OAAO,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAAE,MAAM,IAAI,UAAU,CAAC,4BAA4B,CAAC,CAAC;QACxF,OAAO,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IACjC,CAAC;CACF,CAAC"}
@@ -9,10 +9,29 @@ export declare class CapabilityNotGranted extends ChestError {
9
9
  export declare class QuotaExceeded extends ChestError {
10
10
  constructor();
11
11
  }
12
+ export declare class RateLimited extends ChestError {
13
+ constructor();
14
+ }
12
15
  export declare class TooLarge extends ChestError {
13
16
  constructor();
14
17
  }
15
18
  export declare class Unavailable extends ChestError {
16
19
  constructor();
17
20
  }
21
+ export declare class AiCapReached extends ChestError {
22
+ readonly scope: "tool" | "chest";
23
+ readonly resetsAt: Date;
24
+ constructor(scope: "tool" | "chest", resetsAt: Date);
25
+ }
26
+ export type AiUnavailableReason = "no_connector" | "provider_key_invalid" | "provider_unavailable";
27
+ export declare class AiUnavailable extends ChestError {
28
+ readonly reason: AiUnavailableReason;
29
+ constructor(reason: AiUnavailableReason);
30
+ }
31
+ export declare class AiModelNotAllowed extends ChestError {
32
+ constructor();
33
+ }
34
+ export declare class AiRefused extends ChestError {
35
+ constructor();
36
+ }
18
37
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../client/src/errors.ts"],"names":[],"mappings":"AAEA,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,YAAY,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAKxD;CACF;AAKD,qBAAa,oBAAqB,SAAQ,UAAU;IAClD,YAAY,UAAU,EAAE,MAAM,EAE7B;CACF;AAID,qBAAa,aAAc,SAAQ,UAAU;IAC3C,cAEC;CACF;AAGD,qBAAa,QAAS,SAAQ,UAAU;IACtC,cAEC;CACF;AAID,qBAAa,WAAY,SAAQ,UAAU;IACzC,cAEC;CACF"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../client/src/errors.ts"],"names":[],"mappings":"AAEA,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,YAAY,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAKxD;CACF;AAKD,qBAAa,oBAAqB,SAAQ,UAAU;IAClD,YAAY,UAAU,EAAE,MAAM,EAE7B;CACF;AAMD,qBAAa,aAAc,SAAQ,UAAU;IAC3C,cAEC;CACF;AAID,qBAAa,WAAY,SAAQ,UAAU;IACzC,cAEC;CACF;AAID,qBAAa,QAAS,SAAQ,UAAU;IACtC,cAEC;CACF;AAID,qBAAa,WAAY,SAAQ,UAAU;IACzC,cAEC;CACF;AAMD,qBAAa,YAAa,SAAQ,UAAU;IAC1C,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IACxB,YAAY,KAAK,EAAE,MAAM,GAAG,OAAO,EAAE,QAAQ,EAAE,IAAI,EAIlD;CACF;AAID,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,sBAAsB,GAAG,sBAAsB,CAAC;AAKnG,qBAAa,aAAc,SAAQ,UAAU;IAC3C,QAAQ,CAAC,MAAM,EAAE,mBAAmB,CAAC;IACrC,YAAY,MAAM,EAAE,mBAAmB,EAGtC;CACF;AAID,qBAAa,iBAAkB,SAAQ,UAAU;IAC/C,cAEC;CACF;AAGD,qBAAa,SAAU,SAAQ,UAAU;IACvC,cAEC;CACF"}
@@ -18,14 +18,24 @@ export class CapabilityNotGranted extends ChestError {
18
18
  super("capability_not_granted", 403, `the Chest did not grant the capability "${capability}" to this version of the tool`);
19
19
  }
20
20
  }
21
- // What the tool keeps would go beyond what its Chest gives it: its total
22
- // (1 GiB of files) or its count (10,000 objects).
21
+ // The call would take the tool beyond what its Chest gives it: for files,
22
+ // their total (1 GiB unless its manifest asks more) or their count (10,000
23
+ // objects); for notifications, 1,000 recipients an hour, 100 items per member
24
+ // a day or 600 badge writes a minute. A refused call changes nothing.
23
25
  export class QuotaExceeded extends ChestError {
24
26
  constructor() {
25
27
  super("quota_exceeded", 429, "the Chest refused: the tool's quota would be exceeded");
26
28
  }
27
29
  }
28
- // One object is beyond the bound of one (32 MiB for a file).
30
+ // The tool called the Chest's API more often than its bound (600 calls a
31
+ // minute for its members): it waits before calling again.
32
+ export class RateLimited extends ChestError {
33
+ constructor() {
34
+ super("rate_limited", 429, "the Chest refused: too many calls, wait a minute");
35
+ }
36
+ }
37
+ // One object is beyond the bound of one (for a file, the tool's largest
38
+ // object: 32 MiB unless its manifest asks more, 512 MiB at most).
29
39
  export class TooLarge extends ChestError {
30
40
  constructor() {
31
41
  super("too_large", 413, "the Chest refused: the object is too large");
@@ -38,4 +48,40 @@ export class Unavailable extends ChestError {
38
48
  super("unavailable", 503, "the Chest is unavailable");
39
49
  }
40
50
  }
51
+ // The month's AI budget is spent: the tool's cap (scope "tool") or the
52
+ // Chest's (scope "chest"), until resetsAt. Nothing was spent on the refused
53
+ // call. Keep the tool usable without AI and tell the member AI features are
54
+ // paused.
55
+ export class AiCapReached extends ChestError {
56
+ scope;
57
+ resetsAt;
58
+ constructor(scope, resetsAt) {
59
+ super("cap_reached", 402, `the Chest refused: the ${scope === "tool" ? "tool's" : "Chest's"} AI budget for the month is spent until ${resetsAt.toISOString()}`);
60
+ this.scope = scope;
61
+ this.resetsAt = resetsAt;
62
+ }
63
+ }
64
+ // AI cannot answer now, for a reason the Chest's owner or the provider must
65
+ // fix (the code is the reason). Keep the tool usable without AI and tell the
66
+ // member AI features are paused.
67
+ export class AiUnavailable extends ChestError {
68
+ reason;
69
+ constructor(reason) {
70
+ super(reason, reason === "provider_key_invalid" ? 502 : 503, reason === "no_connector" ? "AI is not set up in this Chest: no connector behind the model" : reason === "provider_key_invalid" ? "the AI provider refused the Chest's key" : "the AI provider failed or did not answer");
71
+ this.reason = reason;
72
+ }
73
+ }
74
+ // The model is not one of the aliases the tool declared in its chest.json
75
+ // ("ai": {"models"}): default, fast, smart, embedding.
76
+ export class AiModelNotAllowed extends ChestError {
77
+ constructor() {
78
+ super("model_not_allowed", 403, "the Chest refused: the model is not one the tool declared (default, fast, smart or embedding in chest.json)");
79
+ }
80
+ }
81
+ // The provider's moderation refused the content of the request.
82
+ export class AiRefused extends ChestError {
83
+ constructor() {
84
+ super("content_refused", 422, "the AI provider refused the content of the request");
85
+ }
86
+ }
41
87
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../client/src/errors.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,mEAAmE;AACnE,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC1B,IAAI,CAAS;IACb,MAAM,CAAS;IACxB,YAAY,IAAY,EAAE,MAAc,EAAE,OAAe;QACvD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED,4EAA4E;AAC5E,0EAA0E;AAC1E,WAAW;AACX,MAAM,OAAO,oBAAqB,SAAQ,UAAU;IAClD,YAAY,UAAkB;QAC5B,KAAK,CAAC,wBAAwB,EAAE,GAAG,EAAE,2CAA2C,UAAU,+BAA+B,CAAC,CAAC;IAC7H,CAAC;CACF;AAED,yEAAyE;AACzE,kDAAkD;AAClD,MAAM,OAAO,aAAc,SAAQ,UAAU;IAC3C;QACE,KAAK,CAAC,gBAAgB,EAAE,GAAG,EAAE,uDAAuD,CAAC,CAAC;IACxF,CAAC;CACF;AAED,6DAA6D;AAC7D,MAAM,OAAO,QAAS,SAAQ,UAAU;IACtC;QACE,KAAK,CAAC,WAAW,EAAE,GAAG,EAAE,4CAA4C,CAAC,CAAC;IACxE,CAAC;CACF;AAED,4EAA4E;AAC5E,gDAAgD;AAChD,MAAM,OAAO,WAAY,SAAQ,UAAU;IACzC;QACE,KAAK,CAAC,aAAa,EAAE,GAAG,EAAE,0BAA0B,CAAC,CAAC;IACxD,CAAC;CACF"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../client/src/errors.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,mEAAmE;AACnE,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC1B,IAAI,CAAS;IACb,MAAM,CAAS;IACxB,YAAY,IAAY,EAAE,MAAc,EAAE,OAAe;QACvD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED,4EAA4E;AAC5E,0EAA0E;AAC1E,WAAW;AACX,MAAM,OAAO,oBAAqB,SAAQ,UAAU;IAClD,YAAY,UAAkB;QAC5B,KAAK,CAAC,wBAAwB,EAAE,GAAG,EAAE,2CAA2C,UAAU,+BAA+B,CAAC,CAAC;IAC7H,CAAC;CACF;AAED,0EAA0E;AAC1E,2EAA2E;AAC3E,8EAA8E;AAC9E,sEAAsE;AACtE,MAAM,OAAO,aAAc,SAAQ,UAAU;IAC3C;QACE,KAAK,CAAC,gBAAgB,EAAE,GAAG,EAAE,uDAAuD,CAAC,CAAC;IACxF,CAAC;CACF;AAED,yEAAyE;AACzE,0DAA0D;AAC1D,MAAM,OAAO,WAAY,SAAQ,UAAU;IACzC;QACE,KAAK,CAAC,cAAc,EAAE,GAAG,EAAE,kDAAkD,CAAC,CAAC;IACjF,CAAC;CACF;AAED,wEAAwE;AACxE,kEAAkE;AAClE,MAAM,OAAO,QAAS,SAAQ,UAAU;IACtC;QACE,KAAK,CAAC,WAAW,EAAE,GAAG,EAAE,4CAA4C,CAAC,CAAC;IACxE,CAAC;CACF;AAED,4EAA4E;AAC5E,gDAAgD;AAChD,MAAM,OAAO,WAAY,SAAQ,UAAU;IACzC;QACE,KAAK,CAAC,aAAa,EAAE,GAAG,EAAE,0BAA0B,CAAC,CAAC;IACxD,CAAC;CACF;AAED,uEAAuE;AACvE,4EAA4E;AAC5E,4EAA4E;AAC5E,UAAU;AACV,MAAM,OAAO,YAAa,SAAQ,UAAU;IACjC,KAAK,CAAmB;IACxB,QAAQ,CAAO;IACxB,YAAY,KAAuB,EAAE,QAAc;QACjD,KAAK,CAAC,aAAa,EAAE,GAAG,EAAE,0BAA0B,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,2CAA2C,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;QAChK,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF;AAMD,4EAA4E;AAC5E,6EAA6E;AAC7E,iCAAiC;AACjC,MAAM,OAAO,aAAc,SAAQ,UAAU;IAClC,MAAM,CAAsB;IACrC,YAAY,MAA2B;QACrC,KAAK,CAAC,MAAM,EAAE,MAAM,KAAK,sBAAsB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,cAAc,CAAC,CAAC,CAAC,+DAA+D,CAAC,CAAC,CAAC,MAAM,KAAK,sBAAsB,CAAC,CAAC,CAAC,yCAAyC,CAAC,CAAC,CAAC,0CAA0C,CAAC,CAAC;QACvR,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED,0EAA0E;AAC1E,uDAAuD;AACvD,MAAM,OAAO,iBAAkB,SAAQ,UAAU;IAC/C;QACE,KAAK,CAAC,mBAAmB,EAAE,GAAG,EAAE,6GAA6G,CAAC,CAAC;IACjJ,CAAC;CACF;AAED,gEAAgE;AAChE,MAAM,OAAO,SAAU,SAAQ,UAAU;IACvC;QACE,KAAK,CAAC,iBAAiB,EAAE,GAAG,EAAE,oDAAoD,CAAC,CAAC;IACtF,CAAC;CACF"}
@@ -0,0 +1,56 @@
1
+ import type { IncomingMessage } from "node:http";
2
+ export type MemberChange = "name" | "photo" | "role" | "groups" | "email";
3
+ export type MemberUpdated = {
4
+ id: string;
5
+ type: "member.updated";
6
+ occurredAt: string;
7
+ data: {
8
+ id: string;
9
+ changed: MemberChange[];
10
+ };
11
+ };
12
+ export type AccessRevoked = {
13
+ id: string;
14
+ type: "access.revoked";
15
+ occurredAt: string;
16
+ data: {
17
+ id: string;
18
+ };
19
+ };
20
+ export type MemberRemoved = {
21
+ id: string;
22
+ type: "member.removed";
23
+ occurredAt: string;
24
+ data: {
25
+ id: string;
26
+ };
27
+ };
28
+ export type MemberErased = {
29
+ id: string;
30
+ type: "member.erased";
31
+ occurredAt: string;
32
+ data: {
33
+ id: string;
34
+ erasure: string;
35
+ deadline: string;
36
+ };
37
+ };
38
+ export type ChestEvent = MemberUpdated | AccessRevoked | MemberRemoved | MemberErased;
39
+ export type ChestEventType = ChestEvent["type"];
40
+ export type Handlers = {
41
+ [K in ChestEventType]?: (event: Extract<ChestEvent, {
42
+ type: K;
43
+ }>) => void | Promise<void>;
44
+ };
45
+ export type Seen = {
46
+ has(id: string): boolean | Promise<boolean>;
47
+ add(id: string): void | Promise<void>;
48
+ };
49
+ export declare function memorySeen(limit?: number): Seen;
50
+ export declare const erasureIdPattern: RegExp;
51
+ export declare function verify(request: IncomingMessage | Request): Promise<ChestEvent | null>;
52
+ export declare function handle(request: IncomingMessage | Request, handlers: Handlers, options?: {
53
+ seen?: Seen;
54
+ }): Promise<number>;
55
+ export declare function acknowledgeErasure(erasure: string): Promise<void>;
56
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../client/src/events.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AA4BjD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE1E,MAAM,MAAM,aAAa,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,YAAY,EAAE,CAAA;KAAE,CAAA;CAAE,CAAC;AAEtI,MAAM,MAAM,aAAa,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC;AAE7G,MAAM,MAAM,aAAa,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC;AAG7G,MAAM,MAAM,YAAY,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,eAAe,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAC;AAE9I,MAAM,MAAM,UAAU,GAAG,aAAa,GAAG,aAAa,GAAG,aAAa,GAAG,YAAY,CAAC;AACtF,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;AAGhD,MAAM,MAAM,QAAQ,GAAG;KAAG,CAAC,IAAI,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,EAAE;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;CAAE,CAAC;AAWrH,MAAM,MAAM,IAAI,GAAG;IAAE,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAAC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC;AAI1G,wBAAgB,UAAU,CAAC,KAAK,SAAQ,GAAG,IAAI,CAU9C;AAcD,eAAO,MAAM,gBAAgB,QAAwB,CAAC;AAoGtD,wBAAsB,MAAM,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAG3F;AAWD,wBAAsB,MAAM,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,IAAI,CAAA;CAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAanI;AAQD,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASvE"}
@@ -0,0 +1,193 @@
1
+ import { createHash, createHmac, timingSafeEqual } from "node:crypto";
2
+ import { ask, refusal } from "./api.js";
3
+ import { ChestError, Unavailable } from "./errors.js";
4
+ import { memberIdPattern } from "./member.js";
5
+ import { forget } from "./members.js";
6
+ // memorySeen keeps the last limit ids in this process: lost at a restart,
7
+ // enough for a tool whose handlers are idempotent anyway.
8
+ export function memorySeen(limit = 10000) {
9
+ const ids = new Set();
10
+ return {
11
+ has: id => ids.has(id),
12
+ add: id => {
13
+ ids.delete(id);
14
+ ids.add(id);
15
+ while (ids.size > limit)
16
+ ids.delete(ids.values().next().value);
17
+ },
18
+ };
19
+ }
20
+ // The key of the events is HMAC-SHA256 of this label under the text of
21
+ // CHEST_TOKEN, exactly as the Chest derives it (chest/toolfront): neither the
22
+ // token itself nor the key of the Chest-Member assertion.
23
+ const label = "Chest-Event v1";
24
+ const claims = ["aud", "iat", "exp", "jti", "digest"];
25
+ // Clocks of the Chest and of the container may differ by this much, in seconds.
26
+ const skew = 5;
27
+ const maxSignature = 2048;
28
+ const maxBody = 64 << 10;
29
+ const compact = /^([A-Za-z0-9_-]+)\.([A-Za-z0-9_-]+)\.([A-Za-z0-9_-]+)$/u;
30
+ const eventIdPattern = /^evt_[a-z2-7]{26}$/u;
31
+ // The grammar of an erasure's identifier, as the Chest mints it.
32
+ export const erasureIdPattern = /^era_[a-z2-7]{26}$/u;
33
+ const changes = ["name", "photo", "role", "groups", "email"];
34
+ function object(value) {
35
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
36
+ }
37
+ function json(raw) {
38
+ try {
39
+ return JSON.parse(raw);
40
+ }
41
+ catch {
42
+ return null;
43
+ }
44
+ }
45
+ const instant = (v) => typeof v === "string" && v.length <= 40 && !Number.isNaN(Date.parse(v));
46
+ function headerOf(request) {
47
+ const headers = request.headers;
48
+ const value = typeof headers.get === "function" ? headers.get("chest-event") : headers["chest-event"];
49
+ return typeof value === "string" && value.length <= maxSignature ? value : null;
50
+ }
51
+ // bodyOf reads the body, 64 KiB at most; null beyond, or when it was read
52
+ // already.
53
+ async function bodyOf(request) {
54
+ try {
55
+ if (request instanceof Request) {
56
+ if (request.bodyUsed || Number(request.headers.get("content-length") ?? "0") > maxBody)
57
+ return null;
58
+ const raw = Buffer.from(await request.arrayBuffer());
59
+ return raw.length <= maxBody ? raw : null;
60
+ }
61
+ const chunks = [];
62
+ let size = 0;
63
+ for await (const chunk of request) {
64
+ size += chunk.length;
65
+ if (size > maxBody)
66
+ return null;
67
+ chunks.push(chunk);
68
+ }
69
+ return Buffer.concat(chunks);
70
+ }
71
+ catch {
72
+ return null;
73
+ }
74
+ }
75
+ // envelope reads a signed delivery: the envelope when the signature, the tool,
76
+ // the time and the digest of the body hold; known says its type is one this
77
+ // SDK reads.
78
+ async function envelope(request) {
79
+ const token = process.env["CHEST_TOKEN"];
80
+ const tool = process.env["CHEST_TOOL"];
81
+ if (!token || !/^[A-Za-z0-9_-]{43,512}$/u.test(token) || !tool || request.method !== "POST")
82
+ return null;
83
+ const signature = headerOf(request);
84
+ const parts = signature === null ? null : compact.exec(signature);
85
+ if (!parts)
86
+ return null;
87
+ const [, encodedHeader = "", encodedPayload = "", encodedSignature = ""] = parts;
88
+ const header = object(json(Buffer.from(encodedHeader, "base64url").toString("utf8")));
89
+ if (!header || Object.keys(header).length !== 2 || header["alg"] !== "HS256" || header["typ"] !== "JWT")
90
+ return null;
91
+ const key = createHmac("sha256", Buffer.from(token, "utf8")).update(label).digest();
92
+ const expected = createHmac("sha256", key).update(encodedHeader + "." + encodedPayload).digest();
93
+ const given = Buffer.from(encodedSignature, "base64url");
94
+ if (given.length !== expected.length || !timingSafeEqual(given, expected))
95
+ return null;
96
+ const payload = object(json(Buffer.from(encodedPayload, "base64url").toString("utf8")));
97
+ if (!payload || Object.keys(payload).length !== claims.length || !claims.every(name => Object.hasOwn(payload, name)))
98
+ return null;
99
+ const { aud, iat, exp, jti, digest } = payload;
100
+ if (aud !== tool || typeof jti !== "string" || !eventIdPattern.test(jti) || typeof digest !== "string")
101
+ return null;
102
+ if (typeof iat !== "number" || !Number.isSafeInteger(iat) || typeof exp !== "number" || !Number.isSafeInteger(exp) || exp <= iat)
103
+ return null;
104
+ const now = Math.floor(Date.now() / 1000);
105
+ if (iat > now + skew || exp <= now - skew)
106
+ return null;
107
+ const body = await bodyOf(request);
108
+ if (body === null)
109
+ return null;
110
+ const sum = createHash("sha256").update(body).digest();
111
+ const told = Buffer.from(digest, "base64url");
112
+ if (told.length !== sum.length || !timingSafeEqual(told, sum))
113
+ return null;
114
+ const e = object(json(body.toString("utf8")));
115
+ if (!e || Object.keys(e).length !== 4 || e["id"] !== jti || typeof e["type"] !== "string" || !instant(e["occurredAt"]))
116
+ return null;
117
+ const data = object(e["data"]);
118
+ if (!data || typeof data["id"] !== "string" || !memberIdPattern.test(data["id"]))
119
+ return null;
120
+ const keys = Object.keys(data).sort().join(",");
121
+ const base = { id: jti, occurredAt: e["occurredAt"] };
122
+ switch (e["type"]) {
123
+ case "member.updated": {
124
+ const changed = data["changed"];
125
+ if (keys !== "changed,id" || !Array.isArray(changed) || changed.length < 1 || changed.length > changes.length || !changed.every(c => typeof c === "string" && changes.includes(c)) || new Set(changed).size !== changed.length)
126
+ return null;
127
+ return { known: true, event: { ...base, type: "member.updated", data: { id: data["id"], changed: [...changed] } } };
128
+ }
129
+ case "access.revoked":
130
+ case "member.removed":
131
+ return keys === "id" ? { known: true, event: { ...base, type: e["type"], data: { id: data["id"] } } } : null;
132
+ case "member.erased":
133
+ if (keys !== "deadline,erasure,id" || typeof data["erasure"] !== "string" || !erasureIdPattern.test(data["erasure"]) || !instant(data["deadline"]))
134
+ return null;
135
+ return { known: true, event: { ...base, type: "member.erased", data: { id: data["id"], erasure: data["erasure"], deadline: data["deadline"] } } };
136
+ }
137
+ // A type of a later Chest: signed, so the tool accepts it, and ignores it.
138
+ return { known: false, event: { id: jti } };
139
+ }
140
+ // verify returns the event a delivery carries, or null when it is not one
141
+ // the Chest made for this tool — no or another signature, for another tool,
142
+ // expired, a body that is not the one signed, not a POST — or when it is of a
143
+ // type this SDK does not know. It reads the body (64 KiB at most): call it
144
+ // before anything else reads it. It never throws for what a request carries.
145
+ export async function verify(request) {
146
+ const read = await envelope(request);
147
+ return read?.known ? read.event : null;
148
+ }
149
+ const remembered = memorySeen();
150
+ // handle verifies one delivery and hands the event to its handler, once:
151
+ // the status to answer the Chest. 401 for a delivery that is not the
152
+ // Chest's; 204 for an event handled, one already seen (seen.has), a type
153
+ // without a handler or one this SDK does not know. A handler that throws
154
+ // leaves the event unseen and handle throws: answer 500, the Chest delivers
155
+ // it again. seen is the store of the ids handled (memorySeen by default,
156
+ // lost at a restart: give a durable one).
157
+ export async function handle(request, handlers, options = {}) {
158
+ const read = await envelope(request);
159
+ if (!read)
160
+ return 401;
161
+ if (!read.known)
162
+ return 204;
163
+ const seen = options.seen ?? remembered;
164
+ const event = read.event;
165
+ if (await seen.has(event.id))
166
+ return 204;
167
+ // A member changed or left: what lookup kept of them is stale.
168
+ forget();
169
+ const handler = handlers[event.type];
170
+ if (handler)
171
+ await handler(event);
172
+ await seen.add(event.id);
173
+ return 204;
174
+ }
175
+ // acknowledgeErasure tells the Chest the tool deleted or anonymised what it
176
+ // kept of the person of that erasure (member.erased): the owner sees it done.
177
+ // Acknowledging again is harmless. Errors: ChestError erasure_not_found
178
+ // (404, an erasure this tool was not told of), invalid_id (400),
179
+ // CapabilityNotGranted (403: the version does not receive member events),
180
+ // Unavailable.
181
+ export async function acknowledgeErasure(erasure) {
182
+ if (typeof erasure !== "string" || !erasureIdPattern.test(erasure))
183
+ throw new ChestError("invalid_id", 400, "invalid erasure identifier");
184
+ const response = await ask("events", "POST", `/erasures/${erasure}/done`);
185
+ if (response.status === 204)
186
+ return;
187
+ if (response.status < 400) {
188
+ await response.body?.cancel();
189
+ throw new Unavailable();
190
+ }
191
+ throw await refusal(response, "events");
192
+ }
193
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../client/src/events.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,8 @@ export type FileObject = {
3
3
  type: string;
4
4
  size: number;
5
5
  updated: string;
6
+ width?: number;
7
+ height?: number;
6
8
  };
7
9
  export type FileData = {
8
10
  data: Uint8Array;
@@ -21,8 +23,22 @@ export declare function list(options?: {
21
23
  }): Promise<FilePage>;
22
24
  declare function remove(name: string): Promise<boolean>;
23
25
  export { remove as delete };
24
- export declare function url(name: string): Promise<{
26
+ export declare function stat(name: string): Promise<FileObject | null>;
27
+ export declare function move(from: string, to: string): Promise<FileObject>;
28
+ export declare function url(name: string, options?: {
29
+ thumbnail?: 256 | 1024;
30
+ download?: boolean;
31
+ }): Promise<{
25
32
  url: string;
26
33
  expiresIn: number;
27
34
  }>;
35
+ export declare function uploadUrl(name: string, options?: {
36
+ maxSize?: number;
37
+ types?: string[];
38
+ expiresIn?: number;
39
+ }): Promise<{
40
+ url: string;
41
+ method: "PUT";
42
+ expiresIn: number;
43
+ }>;
28
44
  //# sourceMappingURL=files.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../client/src/files.ts"],"names":[],"mappings":"AAkBA,MAAM,MAAM,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AACvF,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AACxE,MAAM,MAAM,QAAQ,GAAG;IAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAgGpE,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAQrG;AAGD,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAUhE;AAKD,wBAAsB,IAAI,CAAC,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAa/F;AAGD,iBAAe,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CASpD;AACD,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,CAAC;AAM5B,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAOnF"}
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../client/src/files.ts"],"names":[],"mappings":"AAqBA,MAAM,MAAM,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AACxH,MAAM,MAAM,QAAQ,GAAG;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AACxE,MAAM,MAAM,QAAQ,GAAG;IAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAuCpE,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CASrG;AAGD,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAUhE;AAKD,wBAAsB,IAAI,CAAC,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAa/F;AAGD,iBAAe,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CASpD;AACD,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,CAAC;AAI5B,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAWnE;AAID,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAQxE;AAQD,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAYjJ;AAUD,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAclL"}