@peers-app/peers-sdk 0.27.3 → 0.27.5

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 (272) hide show
  1. package/dist/contracts/contract-proxy.d.ts +7 -0
  2. package/dist/contracts/contract-proxy.js +19 -2
  3. package/dist/contracts/contract-transport.d.ts +2 -1
  4. package/dist/contracts/contract-transport.js +24 -2
  5. package/dist/contracts/create-local-consumer.js +16 -1
  6. package/dist/contracts/index.d.ts +2 -0
  7. package/dist/contracts/index.js +2 -0
  8. package/dist/contracts/system/index.d.ts +2 -0
  9. package/dist/contracts/system/index.js +2 -0
  10. package/dist/contracts/system/invites-contract.js +2 -1
  11. package/dist/contracts/system/sync-check-contract.d.ts +97 -0
  12. package/dist/contracts/system/sync-check-contract.js +115 -0
  13. package/dist/contracts/tool-arguments.d.ts +15 -0
  14. package/dist/contracts/tool-arguments.js +41 -0
  15. package/dist/contracts/tool-catalog-service.js +2 -12
  16. package/dist/contracts/tool-catalog.js +6 -2
  17. package/dist/data/change-tracking.d.ts +40 -0
  18. package/dist/data/change-tracking.js +89 -0
  19. package/dist/data/orm/types.d.ts +24 -7
  20. package/dist/data/orm/types.js +97 -24
  21. package/dist/define/manifest.js +6 -34
  22. package/dist/device/binary-peer-connection-v2.d.ts +7 -15
  23. package/dist/device/binary-peer-connection-v2.js +14 -30
  24. package/dist/device/connection.d.ts +34 -43
  25. package/dist/device/connection.js +188 -186
  26. package/dist/device/device.d.ts +1 -8
  27. package/dist/device/device.js +1 -30
  28. package/dist/device/socket.type.d.ts +6 -12
  29. package/dist/package-loader/package-loader.js +27 -22
  30. package/dist/system-ids.d.ts +5 -0
  31. package/dist/system-ids.js +6 -1
  32. package/package.json +4 -2
  33. package/dist/context/user-context-identity.test.d.ts +0 -1
  34. package/dist/context/user-context-identity.test.js +0 -220
  35. package/dist/contracts/__tests__/action-dispatch.test.d.ts +0 -1
  36. package/dist/contracts/__tests__/action-dispatch.test.js +0 -319
  37. package/dist/contracts/__tests__/also-implements.test.d.ts +0 -1
  38. package/dist/contracts/__tests__/also-implements.test.js +0 -110
  39. package/dist/contracts/__tests__/builder.test.d.ts +0 -1
  40. package/dist/contracts/__tests__/builder.test.js +0 -669
  41. package/dist/contracts/__tests__/contract-events.test.d.ts +0 -1
  42. package/dist/contracts/__tests__/contract-events.test.js +0 -199
  43. package/dist/contracts/__tests__/contract-observables.test.d.ts +0 -1
  44. package/dist/contracts/__tests__/contract-observables.test.js +0 -290
  45. package/dist/contracts/__tests__/contract-provider-router.test.d.ts +0 -1
  46. package/dist/contracts/__tests__/contract-provider-router.test.js +0 -315
  47. package/dist/contracts/__tests__/contract-proxy.test.d.ts +0 -1
  48. package/dist/contracts/__tests__/contract-proxy.test.js +0 -657
  49. package/dist/contracts/__tests__/contract-resolvers.test.d.ts +0 -1
  50. package/dist/contracts/__tests__/contract-resolvers.test.js +0 -758
  51. package/dist/contracts/__tests__/contract-subscription-lifecycle.test.d.ts +0 -1
  52. package/dist/contracts/__tests__/contract-subscription-lifecycle.test.js +0 -353
  53. package/dist/contracts/__tests__/contract-table-events.test.d.ts +0 -1
  54. package/dist/contracts/__tests__/contract-table-events.test.js +0 -209
  55. package/dist/contracts/__tests__/contract-transport.test.d.ts +0 -1
  56. package/dist/contracts/__tests__/contract-transport.test.js +0 -163
  57. package/dist/contracts/__tests__/extract.test.d.ts +0 -1
  58. package/dist/contracts/__tests__/extract.test.js +0 -145
  59. package/dist/contracts/__tests__/frozen-contracts.test.d.ts +0 -1
  60. package/dist/contracts/__tests__/frozen-contracts.test.js +0 -191
  61. package/dist/contracts/__tests__/generic-tool-dispatch.test.d.ts +0 -1
  62. package/dist/contracts/__tests__/generic-tool-dispatch.test.js +0 -130
  63. package/dist/contracts/__tests__/host-contract-client.test.d.ts +0 -1
  64. package/dist/contracts/__tests__/host-contract-client.test.js +0 -793
  65. package/dist/contracts/__tests__/host-contract-consumer.test.d.ts +0 -1
  66. package/dist/contracts/__tests__/host-contract-consumer.test.js +0 -163
  67. package/dist/contracts/__tests__/host-contract-transport.test.d.ts +0 -1
  68. package/dist/contracts/__tests__/host-contract-transport.test.js +0 -66
  69. package/dist/contracts/__tests__/integration.test.d.ts +0 -1
  70. package/dist/contracts/__tests__/integration.test.js +0 -348
  71. package/dist/contracts/__tests__/legacy-removal.test.d.ts +0 -1
  72. package/dist/contracts/__tests__/legacy-removal.test.js +0 -128
  73. package/dist/contracts/__tests__/persistent-registry.test.d.ts +0 -1
  74. package/dist/contracts/__tests__/persistent-registry.test.js +0 -109
  75. package/dist/contracts/__tests__/playground.test.d.ts +0 -1
  76. package/dist/contracts/__tests__/playground.test.js +0 -216
  77. package/dist/contracts/__tests__/registry.test.d.ts +0 -1
  78. package/dist/contracts/__tests__/registry.test.js +0 -238
  79. package/dist/contracts/__tests__/remote-contract-transport.test.d.ts +0 -1
  80. package/dist/contracts/__tests__/remote-contract-transport.test.js +0 -119
  81. package/dist/contracts/__tests__/system-contracts.test.d.ts +0 -1
  82. package/dist/contracts/__tests__/system-contracts.test.js +0 -247
  83. package/dist/contracts/__tests__/target-dispatch.d.ts +0 -11
  84. package/dist/contracts/__tests__/target-dispatch.js +0 -24
  85. package/dist/contracts/__tests__/tool-catalog-inventory.test.d.ts +0 -1
  86. package/dist/contracts/__tests__/tool-catalog-inventory.test.js +0 -44
  87. package/dist/contracts/__tests__/tool-catalog-service.test.d.ts +0 -1
  88. package/dist/contracts/__tests__/tool-catalog-service.test.js +0 -482
  89. package/dist/contracts/__tests__/tool-catalog.test.d.ts +0 -1
  90. package/dist/contracts/__tests__/tool-catalog.test.js +0 -1199
  91. package/dist/contracts/__tests__/validate.test.d.ts +0 -1
  92. package/dist/contracts/__tests__/validate.test.js +0 -991
  93. package/dist/contracts/__tests__/workflow-context.test.d.ts +0 -1
  94. package/dist/contracts/__tests__/workflow-context.test.js +0 -50
  95. package/dist/data/access-level.test.d.ts +0 -1
  96. package/dist/data/access-level.test.js +0 -53
  97. package/dist/data/change-tracking.test.d.ts +0 -1
  98. package/dist/data/change-tracking.test.js +0 -62
  99. package/dist/data/files/files.test.d.ts +0 -1
  100. package/dist/data/files/files.test.js +0 -770
  101. package/dist/data/group-members.test.d.ts +0 -1
  102. package/dist/data/group-members.test.js +0 -336
  103. package/dist/data/group-share.test.d.ts +0 -1
  104. package/dist/data/group-share.test.js +0 -110
  105. package/dist/data/groups.test.d.ts +0 -1
  106. package/dist/data/groups.test.js +0 -153
  107. package/dist/data/orm/cursor.test.d.ts +0 -1
  108. package/dist/data/orm/cursor.test.js +0 -314
  109. package/dist/data/orm/data-query.mongo.test.d.ts +0 -1
  110. package/dist/data/orm/data-query.mongo.test.js +0 -367
  111. package/dist/data/orm/data-query.sqlite.test.d.ts +0 -1
  112. package/dist/data/orm/data-query.sqlite.test.js +0 -365
  113. package/dist/data/orm/data-query.test.d.ts +0 -1
  114. package/dist/data/orm/data-query.test.js +0 -545
  115. package/dist/data/orm/dependency-injection.test.d.ts +0 -1
  116. package/dist/data/orm/dependency-injection.test.js +0 -171
  117. package/dist/data/orm/event-registry.test.d.ts +0 -1
  118. package/dist/data/orm/event-registry.test.js +0 -44
  119. package/dist/data/orm/multi-cursors.test.d.ts +0 -1
  120. package/dist/data/orm/multi-cursors.test.js +0 -463
  121. package/dist/data/orm/sql.data-source.test.d.ts +0 -1
  122. package/dist/data/orm/sql.data-source.test.js +0 -731
  123. package/dist/data/orm/table-container-events.test.d.ts +0 -1
  124. package/dist/data/orm/table-container-events.test.js +0 -101
  125. package/dist/data/orm/table-container.test.d.ts +0 -1
  126. package/dist/data/orm/table-container.test.js +0 -273
  127. package/dist/data/orm/table.event-source.test.d.ts +0 -1
  128. package/dist/data/orm/table.event-source.test.js +0 -331
  129. package/dist/data/orm/types.test.d.ts +0 -1
  130. package/dist/data/orm/types.test.js +0 -409
  131. package/dist/data/package-table-identity.test.d.ts +0 -1
  132. package/dist/data/package-table-identity.test.js +0 -46
  133. package/dist/data/package-version-permissions.test.d.ts +0 -1
  134. package/dist/data/package-version-permissions.test.js +0 -107
  135. package/dist/data/package-version-resolver.test.d.ts +0 -4
  136. package/dist/data/package-version-resolver.test.js +0 -543
  137. package/dist/data/package-versions.test.d.ts +0 -1
  138. package/dist/data/package-versions.test.js +0 -227
  139. package/dist/data/persistent-vars.conflict.test.d.ts +0 -1
  140. package/dist/data/persistent-vars.conflict.test.js +0 -126
  141. package/dist/data/persistent-vars.migration.test.d.ts +0 -1
  142. package/dist/data/persistent-vars.migration.test.js +0 -133
  143. package/dist/data/persistent-vars.package-scope.test.d.ts +0 -1
  144. package/dist/data/persistent-vars.package-scope.test.js +0 -27
  145. package/dist/data/sync-recovery-queue.test.d.ts +0 -1
  146. package/dist/data/sync-recovery-queue.test.js +0 -215
  147. package/dist/data/table-signing.test.d.ts +0 -1
  148. package/dist/data/table-signing.test.js +0 -118
  149. package/dist/data/tool-access.test.d.ts +0 -1
  150. package/dist/data/tool-access.test.js +0 -166
  151. package/dist/data/user-permissions.test.d.ts +0 -1
  152. package/dist/data/user-permissions.test.js +0 -305
  153. package/dist/data/user-trust-levels.test.d.ts +0 -1
  154. package/dist/data/user-trust-levels.test.js +0 -37
  155. package/dist/define/also-implements.test.d.ts +0 -1
  156. package/dist/define/also-implements.test.js +0 -123
  157. package/dist/define/declare-contract.test.d.ts +0 -1
  158. package/dist/define/declare-contract.test.js +0 -573
  159. package/dist/define/define.test.d.ts +0 -1
  160. package/dist/define/define.test.js +0 -1010
  161. package/dist/define/empty-fields.test.d.ts +0 -1
  162. package/dist/define/empty-fields.test.js +0 -55
  163. package/dist/define/events-observables.test.d.ts +0 -1
  164. package/dist/define/events-observables.test.js +0 -1013
  165. package/dist/define/serve-members.test.d.ts +0 -1
  166. package/dist/define/serve-members.test.js +0 -630
  167. package/dist/define/vars.test.d.ts +0 -1
  168. package/dist/define/vars.test.js +0 -39
  169. package/dist/device/binary-peer-connection-v2.test.d.ts +0 -1
  170. package/dist/device/binary-peer-connection-v2.test.js +0 -730
  171. package/dist/device/binary-peer-connection.d.ts +0 -58
  172. package/dist/device/binary-peer-connection.js +0 -516
  173. package/dist/device/binary-peer-connection.test.d.ts +0 -1
  174. package/dist/device/binary-peer-connection.test.js +0 -184
  175. package/dist/device/connection.test.d.ts +0 -1
  176. package/dist/device/connection.test.js +0 -613
  177. package/dist/device/device-election.test.d.ts +0 -1
  178. package/dist/device/device-election.test.js +0 -516
  179. package/dist/device/device.test.d.ts +0 -1
  180. package/dist/device/device.test.js +0 -243
  181. package/dist/device/frame-cipher.test.d.ts +0 -1
  182. package/dist/device/frame-cipher.test.js +0 -219
  183. package/dist/device/get-trust-level-fn.test.d.ts +0 -1
  184. package/dist/device/get-trust-level-fn.test.js +0 -685
  185. package/dist/device/streamed-socket.d.ts +0 -23
  186. package/dist/device/streamed-socket.js +0 -255
  187. package/dist/device/streamed-socket.test.d.ts +0 -1
  188. package/dist/device/streamed-socket.test.js +0 -216
  189. package/dist/device/tx-encoding.test.d.ts +0 -1
  190. package/dist/device/tx-encoding.test.js +0 -295
  191. package/dist/device-pairing/cpace.test.d.ts +0 -1
  192. package/dist/device-pairing/cpace.test.js +0 -116
  193. package/dist/device-pairing/device-pairing.test.d.ts +0 -1
  194. package/dist/device-pairing/device-pairing.test.js +0 -211
  195. package/dist/hlc.test.d.ts +0 -1
  196. package/dist/hlc.test.js +0 -45
  197. package/dist/host-credentials.test.d.ts +0 -1
  198. package/dist/host-credentials.test.js +0 -88
  199. package/dist/identity/account-email.test.d.ts +0 -1
  200. package/dist/identity/account-email.test.js +0 -59
  201. package/dist/identity/anchor-document.test.d.ts +0 -1
  202. package/dist/identity/anchor-document.test.js +0 -16
  203. package/dist/identity/anchor-resolution.test.d.ts +0 -1
  204. package/dist/identity/anchor-resolution.test.js +0 -130
  205. package/dist/identity/key-change.test.d.ts +0 -1
  206. package/dist/identity/key-change.test.js +0 -811
  207. package/dist/invites/group-approval.test.d.ts +0 -1
  208. package/dist/invites/group-approval.test.js +0 -223
  209. package/dist/invites/invite-token.test.d.ts +0 -1
  210. package/dist/invites/invite-token.test.js +0 -123
  211. package/dist/keys.test.d.ts +0 -1
  212. package/dist/keys.test.js +0 -336
  213. package/dist/logging/console-logger.test.d.ts +0 -1
  214. package/dist/logging/console-logger.test.js +0 -300
  215. package/dist/logging/console-logs.table.test.d.ts +0 -1
  216. package/dist/logging/console-logs.table.test.js +0 -156
  217. package/dist/observable.test.d.ts +0 -1
  218. package/dist/observable.test.js +0 -309
  219. package/dist/package-build/build-package.test.d.ts +0 -1
  220. package/dist/package-build/build-package.test.js +0 -204
  221. package/dist/package-build/contract-add.test.d.ts +0 -1
  222. package/dist/package-build/contract-add.test.js +0 -467
  223. package/dist/package-build/freeze-contracts.test.d.ts +0 -1
  224. package/dist/package-build/freeze-contracts.test.js +0 -355
  225. package/dist/package-installer/package-author-signing.test.d.ts +0 -1
  226. package/dist/package-installer/package-author-signing.test.js +0 -200
  227. package/dist/package-installer/package-cloner.test.d.ts +0 -1
  228. package/dist/package-installer/package-cloner.test.js +0 -278
  229. package/dist/package-installer/package-creator.test.d.ts +0 -1
  230. package/dist/package-installer/package-creator.test.js +0 -908
  231. package/dist/package-installer/package-dev-tools.test.d.ts +0 -1
  232. package/dist/package-installer/package-dev-tools.test.js +0 -64
  233. package/dist/package-installer/package-installer.test.d.ts +0 -1
  234. package/dist/package-installer/package-installer.test.js +0 -882
  235. package/dist/package-installer/package-propagation.test.d.ts +0 -1
  236. package/dist/package-installer/package-propagation.test.js +0 -1269
  237. package/dist/package-installer/package-publisher.test.d.ts +0 -1
  238. package/dist/package-installer/package-publisher.test.js +0 -153
  239. package/dist/package-installer/package-remote-checker.test.d.ts +0 -1
  240. package/dist/package-installer/package-remote-checker.test.js +0 -334
  241. package/dist/package-installer/package-seed-installer.test.d.ts +0 -1
  242. package/dist/package-installer/package-seed-installer.test.js +0 -123
  243. package/dist/package-installer/package-tarball.test.d.ts +0 -1
  244. package/dist/package-installer/package-tarball.test.js +0 -75
  245. package/dist/package-installer/peers-core-installer.test.d.ts +0 -1
  246. package/dist/package-installer/peers-core-installer.test.js +0 -49
  247. package/dist/package-installer/peers-core-trust-anchor.test.d.ts +0 -1
  248. package/dist/package-installer/peers-core-trust-anchor.test.js +0 -155
  249. package/dist/package-loader/contract-package-loader.test.d.ts +0 -1
  250. package/dist/package-loader/contract-package-loader.test.js +0 -274
  251. package/dist/package-loader/host-authority-loading.test.d.ts +0 -1
  252. package/dist/package-loader/host-authority-loading.test.js +0 -104
  253. package/dist/package-loader/host-dispatch-policy.test.d.ts +0 -1
  254. package/dist/package-loader/host-dispatch-policy.test.js +0 -56
  255. package/dist/package-loader/isolated-artifact.test.d.ts +0 -1
  256. package/dist/package-loader/isolated-artifact.test.js +0 -688
  257. package/dist/package-loader/isolated-persistent-var-gateway.test.d.ts +0 -1
  258. package/dist/package-loader/isolated-persistent-var-gateway.test.js +0 -56
  259. package/dist/package-loader/isolated-table-gateway.test.d.ts +0 -1
  260. package/dist/package-loader/isolated-table-gateway.test.js +0 -633
  261. package/dist/package-loader/package-loader.test.d.ts +0 -1
  262. package/dist/package-loader/package-loader.test.js +0 -1764
  263. package/dist/package-loader/resolve-consumed-contracts.test.d.ts +0 -1
  264. package/dist/package-loader/resolve-consumed-contracts.test.js +0 -166
  265. package/dist/serial-json.compat.test.d.ts +0 -1
  266. package/dist/serial-json.compat.test.js +0 -369
  267. package/dist/serial-json.test.d.ts +0 -1
  268. package/dist/serial-json.test.js +0 -401
  269. package/dist/testing/mock-host-contract.test.d.ts +0 -1
  270. package/dist/testing/mock-host-contract.test.js +0 -782
  271. package/dist/utils.test.d.ts +0 -1
  272. package/dist/utils.test.js +0 -232
@@ -1,355 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const promises_1 = require("node:fs/promises");
4
- const node_os_1 = require("node:os");
5
- const path = require("node:path");
6
- const peer_id_1 = require("../peer-id");
7
- const build_package_1 = require("./build-package");
8
- const cli_1 = require("./cli");
9
- const freeze_contracts_1 = require("./freeze-contracts");
10
- const sdkRoot = path.resolve(__dirname, "../..");
11
- const packageId = (0, peer_id_1.newid)();
12
- const contractId = (0, peer_id_1.newid)();
13
- let root;
14
- /** A `/define` package providing Probe v1 (and v2 when asked), its tool shaped by `input`. */
15
- function declaration(version, input, description = "Probe.", withV2 = false) {
16
- const contract = (contractVersion) => `defineContract({
17
- contractId: ${JSON.stringify(contractId)}, version: ${contractVersion}, name: "Probe",
18
- tools: [defineTool({
19
- name: "probe", usageDescription: ${JSON.stringify(description)}, accessLevel: 0,
20
- inputSchema: z.object(${input}), outputSchema: z.object({}),
21
- handler: () => ({}),
22
- })],
23
- })`;
24
- return `
25
- import { defineContract, definePackage, defineTool, z } from "@peers-app/peers-sdk/define";
26
- export default definePackage((pkg) => {
27
- pkg.packageId = ${JSON.stringify(packageId)};
28
- pkg.version = ${JSON.stringify(version)};
29
- pkg.provides(${contract(1)});
30
- ${withV2 ? `pkg.provides(${contract(2)});` : ""}
31
- });
32
- `;
33
- }
34
- const frozen = async () => JSON.parse(await (0, promises_1.readFile)(path.join(root, "frozen-contracts.json"), "utf8"));
35
- beforeEach(async () => {
36
- root = await (0, promises_1.mkdtemp)(path.join((0, node_os_1.tmpdir)(), "peers-package-freeze-"));
37
- await (0, promises_1.mkdir)(path.join(root, "src"));
38
- await (0, promises_1.mkdir)(path.join(root, "node_modules/@peers-app"), { recursive: true });
39
- await (0, promises_1.symlink)(sdkRoot, path.join(root, "node_modules/@peers-app/peers-sdk"), "dir");
40
- await (0, promises_1.symlink)(path.dirname(require.resolve("esbuild/package.json")), path.join(root, "node_modules/esbuild"), "dir");
41
- await (0, promises_1.writeFile)(path.join(root, "package.json"), '{"name":"freeze-probe","version":"1.0.0"}');
42
- await (0, promises_1.writeFile)(path.join(root, "src/package.ts"), declaration("1.0.0", "{ name: z.string() }"));
43
- });
44
- afterEach(async () => {
45
- await (0, promises_1.rm)(root, { recursive: true, force: true });
46
- });
47
- test("freezes a release's contracts, then the build refuses a shape change but not a new description", async () => {
48
- const log = jest.spyOn(console, "log").mockImplementation(() => undefined);
49
- const error = jest.spyOn(console, "error").mockImplementation(() => undefined);
50
- try {
51
- // Nothing frozen yet: the check passes, saying so, and the build runs.
52
- await expect((0, cli_1.main)(["contract", "freeze", "--check", "--root", root])).resolves.toBe(0);
53
- expect(log).toHaveBeenCalledWith(expect.stringContaining("nothing is frozen yet"));
54
- await expect((0, freeze_contracts_1.freezePackageContracts)({ root })).resolves.toMatchObject({
55
- packageVersion: "1.0.0",
56
- added: [expect.objectContaining({ contractId, version: 1, frozenBy: "1.0.0" })],
57
- written: true,
58
- });
59
- expect((await frozen()).contracts.map(({ version, frozenBy }) => [version, frozenBy])).toEqual([
60
- [1, "1.0.0"],
61
- ]);
62
- await expect((0, freeze_contracts_1.freezePackageContracts)({ root })).resolves.toMatchObject({
63
- added: [],
64
- written: false,
65
- });
66
- // A new description is allowed; a changed input isn't, in the build or the check.
67
- await (0, promises_1.writeFile)(path.join(root, "src/package.ts"), declaration("1.1.0", "{ name: z.string() }", "Probe, described again."));
68
- await expect((0, build_package_1.buildPackage)({ root })).resolves.toMatchObject({});
69
- await (0, promises_1.writeFile)(path.join(root, "src/package.ts"), declaration("1.1.0", "{ name: z.string(), count: z.number() }"));
70
- await expect((0, build_package_1.buildPackage)({ root })).rejects.toThrow(`This build changes a frozen contract:\nProbe (${contractId}@1), frozen by 1.0.0: tool probe changed.`);
71
- await expect((0, build_package_1.generatePackageManifest)({ root })).rejects.toThrow("tool probe changed");
72
- const beforeFailure = await (0, promises_1.readFile)(path.join(root, "frozen-contracts.json"), "utf8");
73
- await expect((0, cli_1.main)(["contract", "freeze", "--check", "--root", root])).resolves.toBe(1);
74
- await expect((0, cli_1.main)(["contract", "freeze", "--root", root])).resolves.toBe(1);
75
- expect(error).toHaveBeenCalledWith(expect.stringContaining("tool probe changed"));
76
- expect((await frozen()).contracts).toHaveLength(1);
77
- expect(await (0, promises_1.readFile)(path.join(root, "frozen-contracts.json"), "utf8")).toBe(beforeFailure);
78
- // The change goes in a new version, which the next stable release freezes.
79
- await (0, promises_1.writeFile)(path.join(root, "src/package.ts"), declaration("2.0.0", "{ name: z.string() }", "Probe.", true));
80
- await expect((0, cli_1.main)(["contract", "freeze", "--root", root])).resolves.toBe(0);
81
- expect((await frozen()).contracts.map(({ version, frozenBy }) => [version, frozenBy])).toEqual([
82
- [1, "1.0.0"],
83
- [2, "2.0.0"],
84
- ]);
85
- }
86
- finally {
87
- log.mockRestore();
88
- error.mockRestore();
89
- }
90
- });
91
- test("doesn't note a frozen version the package still serves through alsoImplements", async () => {
92
- const log = jest.spyOn(console, "log").mockImplementation(() => undefined);
93
- const v2 = (alsoImplements) => `
94
- import { defineContract, definePackage, defineTool, z } from "@peers-app/peers-sdk/define";
95
- export default definePackage((pkg) => {
96
- pkg.packageId = ${JSON.stringify(packageId)};
97
- pkg.version = "2.0.0";
98
- pkg.provides(defineContract({
99
- contractId: ${JSON.stringify(contractId)}, version: 2, name: "Probe",
100
- tools: [defineTool({
101
- name: "probe", usageDescription: "Probe.", accessLevel: 0,
102
- inputSchema: z.object({ name: z.string(), tag: z.string().optional() }),
103
- outputSchema: z.object({}), handler: () => ({}),
104
- })],
105
- ${alsoImplements}
106
- }));
107
- });
108
- `;
109
- try {
110
- await (0, freeze_contracts_1.freezePackageContracts)({ root });
111
- await (0, promises_1.writeFile)(path.join(root, "src/package.ts"), v2("alsoImplements: [1],"));
112
- await expect((0, freeze_contracts_1.freezePackageContracts)({ root, check: true })).resolves.toMatchObject({
113
- check: { changed: [], notProvided: [] },
114
- });
115
- await expect((0, cli_1.main)(["contract", "freeze", "--root", root])).resolves.toBe(0);
116
- expect(log).not.toHaveBeenCalledWith(expect.stringContaining("is no longer provided"));
117
- expect((await frozen()).contracts.map(({ version, frozenBy }) => [version, frozenBy])).toEqual([
118
- [1, "1.0.0"],
119
- [2, "2.0.0"],
120
- ]);
121
- // Without the alias, v1's consumers lose this provider, and the check says so.
122
- await (0, promises_1.writeFile)(path.join(root, "src/package.ts"), v2(""));
123
- const checked = await (0, freeze_contracts_1.freezePackageContracts)({ root, check: true });
124
- expect(checked.check.notProvided.map(({ version }) => version)).toEqual([1]);
125
- }
126
- finally {
127
- log.mockRestore();
128
- }
129
- });
130
- test("reads an isolated artifact with a cwd-relative bundle and a separate root", async () => {
131
- const built = await (0, build_package_1.buildPackage)({ root });
132
- await expect((0, freeze_contracts_1.freezePackageContracts)({
133
- root,
134
- bundle: path.relative(process.cwd(), built.artifactPath),
135
- })).resolves.toMatchObject({ written: true, packageVersion: "1.0.0" });
136
- await expect((0, freeze_contracts_1.freezePackageContracts)({ root, bundle: built.artifactPath, check: true })).resolves.toMatchObject({ written: false, check: { changed: [] } });
137
- });
138
- test("checks a bundle's carried shapes against frozen versions before writing", async () => {
139
- await (0, freeze_contracts_1.freezePackageContracts)({ root });
140
- const file = path.join(root, "frozen-contracts.json");
141
- const before = await (0, promises_1.readFile)(file, "utf8");
142
- const built = await (0, build_package_1.buildPackage)({ root });
143
- const { frozenBy: _frozenBy, ...original } = (await frozen()).contracts[0];
144
- const carried = {
145
- ...original,
146
- tools: [{ ...original.tools[0], inputFields: [] }],
147
- };
148
- const manifest = structuredClone(built.manifest);
149
- manifest.provides[0].version = 2;
150
- manifest.provides[0].tools[0].inputFields = [];
151
- manifest.provides[0].alsoImplements = [{ contractId, version: 1, definition: carried }];
152
- await (0, promises_1.writeFile)(built.artifactPath, `PEERS_ISOLATED_PACKAGE_V1\n${JSON.stringify({ manifest, providerSource: "void 0;" })}\n`);
153
- for (const check of [true, false]) {
154
- await expect((0, freeze_contracts_1.freezePackageContracts)({ root, bundle: built.artifactPath, check })).resolves.toMatchObject({
155
- added: [],
156
- written: false,
157
- check: {
158
- changed: [{ contract: { contractId, version: 1 }, changes: ["tool probe changed"] }],
159
- },
160
- });
161
- expect(await (0, promises_1.readFile)(file, "utf8")).toBe(before);
162
- }
163
- await expect((0, freeze_contracts_1.assertFrozenContracts)(root, manifest)).rejects.toThrow("tool probe changed");
164
- });
165
- test("only a provided host contract's aliases quiet retirement notes, with inclusive ranges", async () => {
166
- await (0, freeze_contracts_1.freezePackageContracts)({ root });
167
- const { frozenBy: _frozenBy, ...original } = (await frozen()).contracts[0];
168
- const otherId = (0, peer_id_1.newid)();
169
- const provided = { ...original, contractId: otherId, version: 3 };
170
- const bundle = path.join(root, "aliases.bundle.js");
171
- const target = { contractId, version: { from: 1, to: 2 } };
172
- const cases = [
173
- { key: `${otherId}@3`, target, notProvided: [] },
174
- { key: `${otherId}@2`, target, notProvided: [expect.objectContaining({ contractId })] },
175
- {
176
- key: `${otherId}@3`,
177
- target: { contractId: otherId, version: { from: 1, to: 2 } },
178
- notProvided: [expect.objectContaining({ contractId })],
179
- },
180
- ];
181
- for (const { key, target, notProvided } of cases) {
182
- await (0, promises_1.writeFile)(bundle, `exports.packageDefinition = {
183
- version: "2.0.0", contracts: [${JSON.stringify(provided)}],
184
- alsoImplements: new Map([[${JSON.stringify(key)}, [${JSON.stringify(target)}]]]),
185
- };`);
186
- for (const check of [true, false]) {
187
- await expect((0, freeze_contracts_1.freezePackageContracts)({ root, bundle, check })).resolves.toMatchObject({
188
- check: { changed: [], notProvided },
189
- });
190
- }
191
- }
192
- });
193
- test.each([
194
- "{}",
195
- `new Map([[${JSON.stringify(`${contractId}@2`)}, {}]])`,
196
- `new Map([[${JSON.stringify(`${contractId}@2`)}, [null]]])`,
197
- `new Map([[${JSON.stringify(`${contractId}@2`)}, [{ contractId: ${JSON.stringify(contractId)}, version: 1.5 }]]])`,
198
- `new Map([[${JSON.stringify(`${contractId}@2`)}, [{ contractId: ${JSON.stringify(contractId)}, version: { from: 2, to: 1 } }]]])`,
199
- ])("rejects malformed host alsoImplements without changing the snapshot: %s", async (aliases) => {
200
- await (0, freeze_contracts_1.freezePackageContracts)({ root });
201
- const file = path.join(root, "frozen-contracts.json");
202
- const before = await (0, promises_1.readFile)(file, "utf8");
203
- const { frozenBy: _frozenBy, ...original } = (await frozen()).contracts[0];
204
- const bundle = path.join(root, "invalid-alias.bundle.js");
205
- await (0, promises_1.writeFile)(bundle, `exports.packageDefinition = {
206
- version: "2.0.0", contracts: [${JSON.stringify({ ...original, version: 2 })}],
207
- alsoImplements: ${aliases},
208
- };`);
209
- for (const check of [true, false]) {
210
- await expect((0, freeze_contracts_1.freezePackageContracts)({ root, bundle, check })).rejects.toThrow("Invalid alsoImplements");
211
- expect(await (0, promises_1.readFile)(file, "utf8")).toBe(before);
212
- }
213
- });
214
- test.each([
215
- "",
216
- "{",
217
- "null",
218
- "{}",
219
- '{"contracts":[{}]}',
220
- '{"contracts":null}',
221
- ])("rejects a malformed snapshot without overwriting it: %s", async (content) => {
222
- const file = path.join(root, "frozen-contracts.json");
223
- await (0, promises_1.writeFile)(file, content);
224
- await expect((0, freeze_contracts_1.freezePackageContracts)({ root })).rejects.toThrow();
225
- await expect((0, freeze_contracts_1.freezePackageContracts)({ root, check: true })).rejects.toThrow();
226
- await expect((0, build_package_1.buildPackage)({ root })).rejects.toThrow();
227
- expect(await (0, promises_1.readFile)(file, "utf8")).toBe(content);
228
- });
229
- test("rejects incomplete shapes and duplicate frozen identities", async () => {
230
- await (0, freeze_contracts_1.freezePackageContracts)({ root });
231
- const snapshot = await frozen();
232
- const invalid = [
233
- { contracts: snapshot.contracts.map(({ version: _version, ...entry }) => entry) },
234
- { contracts: snapshot.contracts.map(({ tools: _tools, ...entry }) => entry) },
235
- { contracts: snapshot.contracts.map((entry) => ({ ...entry, tools: [{ name: "broken" }] })) },
236
- { contracts: [...snapshot.contracts, ...snapshot.contracts] },
237
- ];
238
- for (const content of invalid) {
239
- await (0, promises_1.writeFile)(path.join(root, "frozen-contracts.json"), JSON.stringify(content));
240
- await expect((0, freeze_contracts_1.freezePackageContracts)({ root, check: true })).rejects.toThrow("Invalid");
241
- }
242
- });
243
- test("accepts an empty contracts list and refuses to freeze a missing package version", async () => {
244
- await (0, promises_1.writeFile)(path.join(root, "frozen-contracts.json"), '{"contracts":[]}');
245
- await expect((0, freeze_contracts_1.freezePackageContracts)({ root })).resolves.toMatchObject({ written: true });
246
- const snapshot = await (0, promises_1.readFile)(path.join(root, "frozen-contracts.json"), "utf8");
247
- const bundle = path.join(root, "missing-version.js");
248
- await (0, promises_1.writeFile)(bundle, "exports.packageDefinition = { contracts: [] };");
249
- await expect((0, freeze_contracts_1.freezePackageContracts)({ root, bundle })).rejects.toThrow("no version");
250
- expect(await (0, promises_1.readFile)(path.join(root, "frozen-contracts.json"), "utf8")).toBe(snapshot);
251
- });
252
- test("reports a newly written empty snapshot", async () => {
253
- const bundle = path.join(root, "empty.js");
254
- await (0, promises_1.writeFile)(bundle, 'exports.packageDefinition = { version: "1.0.0", contracts: [] };');
255
- const log = jest.spyOn(console, "log").mockImplementation(() => undefined);
256
- try {
257
- await expect((0, cli_1.main)(["contract", "freeze", "--root", root, "--bundle", bundle])).resolves.toBe(0);
258
- expect(log).toHaveBeenCalledWith(expect.stringContaining("Wrote "));
259
- expect((await frozen()).contracts).toEqual([]);
260
- }
261
- finally {
262
- log.mockRestore();
263
- }
264
- });
265
- test("rejects malformed host definitions without creating or replacing a snapshot", async () => {
266
- const bundle = path.join(root, "malformed.bundle.js");
267
- await (0, promises_1.writeFile)(bundle, 'exports.packageDefinition = { version: "1.0.0", contracts: [{}] };');
268
- for (const check of [true, false]) {
269
- await expect((0, freeze_contracts_1.freezePackageContracts)({ root, bundle, check })).rejects.toThrow("Invalid contracts");
270
- }
271
- await expect((0, promises_1.readFile)(path.join(root, "frozen-contracts.json"))).rejects.toMatchObject({
272
- code: "ENOENT",
273
- });
274
- await (0, freeze_contracts_1.freezePackageContracts)({ root });
275
- const before = await (0, promises_1.readFile)(path.join(root, "frozen-contracts.json"), "utf8");
276
- for (const check of [true, false]) {
277
- await expect((0, freeze_contracts_1.freezePackageContracts)({ root, bundle, check })).rejects.toThrow("Invalid contracts");
278
- }
279
- expect(await (0, promises_1.readFile)(path.join(root, "frozen-contracts.json"), "utf8")).toBe(before);
280
- });
281
- test("rejects duplicate host contracts without writing and preserves unknown shape keys", async () => {
282
- await (0, freeze_contracts_1.freezePackageContracts)({ root });
283
- const file = path.join(root, "frozen-contracts.json");
284
- const before = await (0, promises_1.readFile)(file, "utf8");
285
- const { frozenBy: _frozenBy, ...original } = (await frozen()).contracts[0];
286
- const changed = { ...original, tools: [] };
287
- const bundle = path.join(root, "duplicate.bundle.js");
288
- const writeBundle = (contracts) => (0, promises_1.writeFile)(bundle, `exports.packageDefinition = ${JSON.stringify({ version: "1.1.0", contracts })};`);
289
- await writeBundle([changed, original]);
290
- for (const check of [true, false]) {
291
- await expect((0, freeze_contracts_1.freezePackageContracts)({ root, bundle, check })).rejects.toThrow("Duplicate provided contract");
292
- }
293
- expect(await (0, promises_1.readFile)(file, "utf8")).toBe(before);
294
- await (0, promises_1.rm)(file);
295
- await expect((0, freeze_contracts_1.freezePackageContracts)({ root, bundle })).rejects.toThrow("Duplicate provided contract");
296
- await expect((0, promises_1.readFile)(file)).rejects.toMatchObject({ code: "ENOENT" });
297
- const extended = {
298
- ...original,
299
- tools: [{ ...original.tools[0], futureShape: { enabled: true } }],
300
- };
301
- await writeBundle([extended]);
302
- await (0, freeze_contracts_1.freezePackageContracts)({ root, bundle });
303
- expect((await frozen()).contracts[0].tools[0]).toMatchObject({ futureShape: { enabled: true } });
304
- await writeBundle([
305
- { ...extended, tools: [{ ...extended.tools[0], futureShape: { enabled: false } }] },
306
- ]);
307
- expect((await (0, freeze_contracts_1.freezePackageContracts)({ root, bundle, check: true })).check.changed).toHaveLength(1);
308
- });
309
- test("reads a host-backed package's CommonJS bundle, with the SDK and zod as externals", async () => {
310
- const bundle = path.join(root, "legacy.bundle.js");
311
- const tool = (fields) => `{
312
- tool: {
313
- toolId: ${JSON.stringify((0, peer_id_1.newid)())}, name: "act", code: "", usageDescription: "Act.",
314
- inputSchema: { type: "complex", fields: ${fields} },
315
- outputSchema: { type: "complex", fields: [] },
316
- },
317
- }`;
318
- const legacy = (version, fields) => `
319
- const { definePackage } = require("PeersSDK");
320
- require("zod");
321
- exports.packageDefinition = definePackage((pkg) => {
322
- pkg.packageId = ${JSON.stringify(packageId)};
323
- pkg.version = ${JSON.stringify(version)};
324
- const contract = pkg.contract(${JSON.stringify(contractId)}, 1, "Legacy", "A legacy contract.");
325
- contract.tools = [${tool(fields)}];
326
- });
327
- `;
328
- await (0, promises_1.writeFile)(bundle, legacy("0.5.0", '[{ name: "value", type: "string" }]'));
329
- await expect((0, freeze_contracts_1.freezePackageContracts)({ root, bundle })).resolves.toMatchObject({
330
- packageVersion: "0.5.0",
331
- added: [expect.objectContaining({ name: "Legacy", version: 1, frozenBy: "0.5.0" })],
332
- });
333
- expect((await frozen()).contracts[0]).not.toHaveProperty("devTag");
334
- await (0, promises_1.writeFile)(bundle, legacy("0.6.0", '[{ name: "value", type: "number" }]'));
335
- const checked = await (0, freeze_contracts_1.freezePackageContracts)({ root, bundle, check: true });
336
- expect(checked.check.changed.map(({ changes }) => changes)).toEqual([["tool act changed"]]);
337
- // v2 also implementing v1 still serves it; without that, v1 is no longer provided.
338
- const upgraded = (alsoImplements) => `
339
- const { definePackage } = require("PeersSDK");
340
- exports.packageDefinition = definePackage((pkg) => {
341
- pkg.packageId = ${JSON.stringify(packageId)};
342
- pkg.version = "1.0.0";
343
- const contract = pkg.contract(${JSON.stringify(contractId)}, 2, "Legacy", "A legacy contract.");
344
- contract.tools = [${tool('[{ name: "value", type: "string" }]')}];
345
- ${alsoImplements}
346
- });
347
- `;
348
- await (0, promises_1.writeFile)(bundle, upgraded(`contract.alsoImplements(${JSON.stringify(contractId)}, 1);`));
349
- await expect((0, freeze_contracts_1.freezePackageContracts)({ root, bundle, check: true })).resolves.toMatchObject({
350
- check: { changed: [], notProvided: [] },
351
- });
352
- await (0, promises_1.writeFile)(bundle, upgraded(""));
353
- const dropped = await (0, freeze_contracts_1.freezePackageContracts)({ root, bundle, check: true });
354
- expect(dropped.check.notProvided.map(({ version }) => version)).toEqual([1]);
355
- });
@@ -1,200 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const keys_1 = require("../keys");
4
- const utils_1 = require("../utils");
5
- const package_author_signing_1 = require("./package-author-signing");
6
- function makePV(overrides) {
7
- return {
8
- packageId: (0, utils_1.newid)(),
9
- packageVersionId: (0, utils_1.newid)(),
10
- version: "1.2.3",
11
- versionTag: "stable",
12
- packageBundleFileHash: "abc123hash",
13
- routesBundleFileHash: "routes456hash",
14
- uiBundleFileHash: "ui789hash",
15
- ...overrides,
16
- };
17
- }
18
- describe("package-author-signing", () => {
19
- const keys = (0, keys_1.newKeys)();
20
- describe("PACKAGE_SIGNING_KEY_PREFIX", () => {
21
- it("has the expected value", () => {
22
- expect(package_author_signing_1.PACKAGE_SIGNING_KEY_PREFIX).toBe("packageSigningKey_");
23
- });
24
- });
25
- describe("buildAuthorSignedPayload", () => {
26
- it("extracts the correct fields from a PV", () => {
27
- const pv = makePV();
28
- const payload = (0, package_author_signing_1.buildAuthorSignedPayload)(pv, keys.publicKey);
29
- expect(payload).toEqual({
30
- packageId: pv.packageId,
31
- packageVersionId: pv.packageVersionId,
32
- version: "1.2.3",
33
- versionTag: "stable",
34
- packageBundleFileHash: "abc123hash",
35
- routesBundleFileHash: "routes456hash",
36
- uiBundleFileHash: "ui789hash",
37
- publicKey: keys.publicKey,
38
- });
39
- });
40
- it("omits optional hash fields when undefined", () => {
41
- const pv = makePV({ routesBundleFileHash: undefined, uiBundleFileHash: undefined });
42
- const payload = (0, package_author_signing_1.buildAuthorSignedPayload)(pv, keys.publicKey);
43
- expect(payload).not.toHaveProperty("routesBundleFileHash");
44
- expect(payload).not.toHaveProperty("uiBundleFileHash");
45
- expect(payload.packageBundleFileHash).toBe("abc123hash");
46
- });
47
- it("omits uiBundleFileHash but includes routesBundleFileHash when only ui is undefined", () => {
48
- const pv = makePV({ uiBundleFileHash: undefined });
49
- const payload = (0, package_author_signing_1.buildAuthorSignedPayload)(pv, keys.publicKey);
50
- expect(payload.routesBundleFileHash).toBe("routes456hash");
51
- expect(payload).not.toHaveProperty("uiBundleFileHash");
52
- });
53
- it("treats empty string versionTag the same as undefined", () => {
54
- const pv = makePV({ versionTag: undefined });
55
- const payload = (0, package_author_signing_1.buildAuthorSignedPayload)(pv, keys.publicKey);
56
- expect(payload.versionTag).toBe("");
57
- });
58
- });
59
- describe("signPackageAuthor + verifyPackageAuthorSignature round-trip", () => {
60
- it("produces a valid signature that verifies", () => {
61
- const pv = makePV();
62
- const signature = (0, package_author_signing_1.signPackageAuthor)(pv, keys.secretKey);
63
- expect(typeof signature).toBe("string");
64
- expect(signature.length).toBeGreaterThan(0);
65
- const result = (0, package_author_signing_1.verifyPackageAuthorSignature)({ ...pv, packageAuthorSignature: signature }, keys.publicKey);
66
- expect(result.valid).toBe(true);
67
- expect(result.publicKey).toBe(keys.publicKey);
68
- });
69
- it("works with only the required bundle hash (no routes or ui)", () => {
70
- const pv = makePV({ routesBundleFileHash: undefined, uiBundleFileHash: undefined });
71
- const signature = (0, package_author_signing_1.signPackageAuthor)(pv, keys.secretKey);
72
- const result = (0, package_author_signing_1.verifyPackageAuthorSignature)({ ...pv, packageAuthorSignature: signature }, keys.publicKey);
73
- expect(result.valid).toBe(true);
74
- });
75
- it("works with undefined versionTag", () => {
76
- const pv = makePV({ versionTag: undefined });
77
- const signature = (0, package_author_signing_1.signPackageAuthor)(pv, keys.secretKey);
78
- const result = (0, package_author_signing_1.verifyPackageAuthorSignature)({ ...pv, packageAuthorSignature: signature }, keys.publicKey);
79
- expect(result.valid).toBe(true);
80
- });
81
- });
82
- describe("verification fails on tampered fields", () => {
83
- const pv = makePV();
84
- let signature;
85
- beforeAll(() => {
86
- signature = (0, package_author_signing_1.signPackageAuthor)(pv, keys.secretKey);
87
- });
88
- it("fails when packageBundleFileHash is changed", () => {
89
- const tampered = {
90
- ...pv,
91
- packageBundleFileHash: "tampered",
92
- packageAuthorSignature: signature,
93
- };
94
- const result = (0, package_author_signing_1.verifyPackageAuthorSignature)(tampered, keys.publicKey);
95
- expect(result.valid).toBe(false);
96
- });
97
- it("fails when version is changed", () => {
98
- const tampered = { ...pv, version: "9.9.9", packageAuthorSignature: signature };
99
- const result = (0, package_author_signing_1.verifyPackageAuthorSignature)(tampered, keys.publicKey);
100
- expect(result.valid).toBe(false);
101
- });
102
- it("fails when versionTag is changed", () => {
103
- const tampered = { ...pv, versionTag: "beta", packageAuthorSignature: signature };
104
- const result = (0, package_author_signing_1.verifyPackageAuthorSignature)(tampered, keys.publicKey);
105
- expect(result.valid).toBe(false);
106
- });
107
- it("fails when packageId is changed", () => {
108
- const tampered = { ...pv, packageId: (0, utils_1.newid)(), packageAuthorSignature: signature };
109
- const result = (0, package_author_signing_1.verifyPackageAuthorSignature)(tampered, keys.publicKey);
110
- expect(result.valid).toBe(false);
111
- });
112
- it("fails when packageVersionId is changed", () => {
113
- const tampered = { ...pv, packageVersionId: (0, utils_1.newid)(), packageAuthorSignature: signature };
114
- const result = (0, package_author_signing_1.verifyPackageAuthorSignature)(tampered, keys.publicKey);
115
- expect(result.valid).toBe(false);
116
- });
117
- it("fails when routesBundleFileHash is changed", () => {
118
- const tampered = {
119
- ...pv,
120
- routesBundleFileHash: "tampered",
121
- packageAuthorSignature: signature,
122
- };
123
- const result = (0, package_author_signing_1.verifyPackageAuthorSignature)(tampered, keys.publicKey);
124
- expect(result.valid).toBe(false);
125
- });
126
- it("fails when uiBundleFileHash is changed", () => {
127
- const tampered = { ...pv, uiBundleFileHash: "tampered", packageAuthorSignature: signature };
128
- const result = (0, package_author_signing_1.verifyPackageAuthorSignature)(tampered, keys.publicKey);
129
- expect(result.valid).toBe(false);
130
- });
131
- it("fails when a signed createdBy is changed", () => {
132
- const signed = makePV({ createdBy: "00author0000000000000000a" });
133
- const signedSignature = (0, package_author_signing_1.signPackageAuthor)(signed, keys.secretKey);
134
- const tampered = {
135
- ...signed,
136
- createdBy: "00attacker000000000000000a",
137
- packageAuthorSignature: signedSignature,
138
- };
139
- const result = (0, package_author_signing_1.verifyPackageAuthorSignature)(tampered, keys.publicKey);
140
- expect(result.valid).toBe(false);
141
- });
142
- });
143
- describe("verification fails with wrong key", () => {
144
- it("rejects when verified against a different key", () => {
145
- const pv = makePV();
146
- const signature = (0, package_author_signing_1.signPackageAuthor)(pv, keys.secretKey);
147
- const otherKeys = (0, keys_1.newKeys)();
148
- const result = (0, package_author_signing_1.verifyPackageAuthorSignature)({ ...pv, packageAuthorSignature: signature }, otherKeys.publicKey);
149
- expect(result.valid).toBe(false);
150
- });
151
- });
152
- describe("TOFU enforcement via expectedPublicKey", () => {
153
- it("succeeds when expectedPublicKey matches the signer", () => {
154
- const pv = makePV();
155
- const signature = (0, package_author_signing_1.signPackageAuthor)(pv, keys.secretKey);
156
- const result = (0, package_author_signing_1.verifyPackageAuthorSignature)({ ...pv, packageAuthorSignature: signature }, keys.publicKey);
157
- expect(result.valid).toBe(true);
158
- expect(result.publicKey).toBe(keys.publicKey);
159
- });
160
- it("fails when expectedPublicKey does not match the signer", () => {
161
- const pv = makePV();
162
- const signature = (0, package_author_signing_1.signPackageAuthor)(pv, keys.secretKey);
163
- const differentKey = (0, keys_1.newKeys)().publicKey;
164
- const result = (0, package_author_signing_1.verifyPackageAuthorSignature)({ ...pv, packageAuthorSignature: signature }, differentKey);
165
- expect(result.valid).toBe(false);
166
- });
167
- });
168
- describe("edge cases", () => {
169
- it("returns invalid when packageAuthorSignature is undefined", () => {
170
- const pv = makePV();
171
- const result = (0, package_author_signing_1.verifyPackageAuthorSignature)({ ...pv, packageAuthorSignature: undefined }, keys.publicKey);
172
- expect(result.valid).toBe(false);
173
- });
174
- it("returns invalid when packageAuthorSignature is malformed", () => {
175
- const pv = makePV();
176
- const result = (0, package_author_signing_1.verifyPackageAuthorSignature)({ ...pv, packageAuthorSignature: "not-a-valid-signature!!!" }, keys.publicKey);
177
- expect(result.valid).toBe(false);
178
- });
179
- it("returns invalid when expectedPublicKey is malformed", () => {
180
- const pv = makePV();
181
- const signature = (0, package_author_signing_1.signPackageAuthor)(pv, keys.secretKey);
182
- const result = (0, package_author_signing_1.verifyPackageAuthorSignature)({ ...pv, packageAuthorSignature: signature }, "not-a-valid-key");
183
- expect(result.valid).toBe(false);
184
- });
185
- it("signature is deterministic for same inputs", () => {
186
- const pv = makePV();
187
- const sig1 = (0, package_author_signing_1.signPackageAuthor)(pv, keys.secretKey);
188
- const sig2 = (0, package_author_signing_1.signPackageAuthor)(pv, keys.secretKey);
189
- expect(sig1).toBe(sig2);
190
- });
191
- it("derives the correct public key from the secret key", () => {
192
- const pv = makePV();
193
- const signature = (0, package_author_signing_1.signPackageAuthor)(pv, keys.secretKey);
194
- const derived = (0, keys_1.hydrateKeys)(keys.secretKey);
195
- expect(derived.publicKey).toBe(keys.publicKey);
196
- const result = (0, package_author_signing_1.verifyPackageAuthorSignature)({ ...pv, packageAuthorSignature: signature }, derived.publicKey);
197
- expect(result.valid).toBe(true);
198
- });
199
- });
200
- });
@@ -1 +0,0 @@
1
- export {};