@peers-app/peers-sdk 0.25.16 → 0.25.18

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 (33) hide show
  1. package/dist/contracts/__tests__/contract-proxy.test.js +24 -1
  2. package/dist/contracts/__tests__/contract-resolvers.test.js +3 -0
  3. package/dist/contracts/contract-provider-router.d.ts +16 -2
  4. package/dist/contracts/contract-provider-router.js +4 -0
  5. package/dist/contracts/contract-providers.table.d.ts +2 -2
  6. package/dist/contracts/contract-proxy.d.ts +11 -0
  7. package/dist/contracts/contract-proxy.js +11 -3
  8. package/dist/contracts/contract-resolvers.js +12 -1
  9. package/dist/contracts/index.d.ts +3 -0
  10. package/dist/contracts/index.js +18 -2
  11. package/dist/contracts/system/contract-catalog-contract.d.ts +38 -0
  12. package/dist/contracts/system/contract-catalog-contract.js +51 -0
  13. package/dist/contracts/system/http-contract.d.ts +80 -0
  14. package/dist/contracts/system/http-contract.js +93 -0
  15. package/dist/contracts/system/index.d.ts +3 -0
  16. package/dist/contracts/system/index.js +3 -0
  17. package/dist/contracts/system/scheduler-contract.d.ts +54 -0
  18. package/dist/contracts/system/scheduler-contract.js +70 -0
  19. package/dist/data/tool-access-approvals.d.ts +3 -3
  20. package/dist/package-loader/index.d.ts +1 -0
  21. package/dist/package-loader/index.js +1 -0
  22. package/dist/package-loader/isolated-artifact.d.ts +37 -0
  23. package/dist/package-loader/isolated-artifact.js +79 -2
  24. package/dist/package-loader/isolated-artifact.test.js +25 -0
  25. package/dist/package-loader/isolated-persistent-var-gateway.js +19 -0
  26. package/dist/package-loader/isolated-runtime.d.ts +28 -1
  27. package/dist/package-loader/package-loader.js +4 -0
  28. package/dist/package-loader/package-loader.test.js +50 -2
  29. package/dist/package-loader/package-network-policy.d.ts +52 -0
  30. package/dist/package-loader/package-network-policy.js +62 -0
  31. package/dist/system-ids.d.ts +31 -0
  32. package/dist/system-ids.js +32 -1
  33. package/package.json +1 -1
@@ -435,7 +435,7 @@ describe("contract proxy — error handling", () => {
435
435
  tools: {
436
436
  listGrants: {
437
437
  tool: { toolId: (0, utils_1.newid)(), name: "listGrants", accessLevel: 0 },
438
- toolFn: async (host) => {
438
+ toolFn: async (_input, host) => {
439
439
  seen.push(host.callerPackageId ?? null);
440
440
  return "ok";
441
441
  },
@@ -452,6 +452,29 @@ describe("contract proxy — error handling", () => {
452
452
  }, { callerPackageId: "00pkg00000000000000000001" });
453
453
  expect(seen).toEqual(["00pkg00000000000000000001"]);
454
454
  });
455
+ it("rejects extra arguments that could shadow forwarded call context", async () => {
456
+ const toolFn = jest.fn(async (_input, host) => host.callerPackageId ?? null);
457
+ const provider = (0, contract_proxy_1.createContractProvider)({
458
+ contractId: CONTRACT_ID,
459
+ version: 1,
460
+ forwardCallContext: true,
461
+ tools: {
462
+ request: {
463
+ tool: { toolId: (0, utils_1.newid)(), name: "request", accessLevel: 0 },
464
+ toolFn,
465
+ },
466
+ },
467
+ });
468
+ await expect(provider({
469
+ contractId: CONTRACT_ID,
470
+ version: 1,
471
+ member: "tool",
472
+ name: "request",
473
+ operation: "run",
474
+ args: [{ url: "https://example.com" }, { callerPackageId: (0, utils_1.newid)() }],
475
+ }, { callerPackageId: (0, utils_1.newid)() })).rejects.toThrow(/single argument when host context is forwarded/);
476
+ expect(toolFn).not.toHaveBeenCalled();
477
+ });
455
478
  it.each([
456
479
  ["tool", "missingTool"],
457
480
  ["observable", "missingObservable"],
@@ -168,6 +168,9 @@ describe("Self-trusted contract caller authorization", () => {
168
168
  ["Tool Access Control", system_ids_1.toolAccessControlContractId],
169
169
  ["Identity", system_ids_1.identityContractId],
170
170
  ["Invites", system_ids_1.invitesContractId],
171
+ ["HTTP", system_ids_1.httpContractId],
172
+ ["Scheduler", system_ids_1.schedulerContractId],
173
+ ["Contract Catalog", system_ids_1.contractCatalogContractId],
171
174
  ])("rejects remote %s as local-only", async (_name, contractId) => {
172
175
  const { remoteIdentity, user } = makeIdentity();
173
176
  const records = new Map();
@@ -27,10 +27,17 @@ export interface IContractProviderEndpointRequest {
27
27
  /** Target contract version. */
28
28
  version: number;
29
29
  /**
30
- * Provider selected by trusted host state. This value is never copied from
31
- * an {@link IContractCall} or other guest payload.
30
+ * Provider selected by trusted host state after any requested provider has
31
+ * been checked against the registry.
32
32
  */
33
33
  providerPackageId?: string;
34
+ /**
35
+ * Provider named on the call by a local UI consumer.
36
+ *
37
+ * Set only when the router was created with `allowRequestedProvider`. Remote
38
+ * routers leave this unset.
39
+ */
40
+ requestedProviderPackageId?: string;
34
41
  /** Canonical data context returned by the authorization hook. */
35
42
  dataContextId?: string;
36
43
  /**
@@ -65,6 +72,13 @@ export interface IContractProviderRouterOptions {
65
72
  * provider-aware and automatically selects a new endpoint after a provider switch.
66
73
  */
67
74
  resolveProviderPackageId?: ContractProviderPackageResolver;
75
+ /**
76
+ * When true, a local caller may name `providerPackageId` on the call.
77
+ *
78
+ * The resolver must still reject ids that are not registered. Remote routers
79
+ * leave this false.
80
+ */
81
+ allowRequestedProvider?: boolean;
68
82
  /** Resolves an endpoint after authorization succeeds. */
69
83
  resolveEndpoint: ContractProviderEndpointResolver;
70
84
  /** Caller identity derived from the trusted underlying connection/session. */
@@ -121,11 +121,15 @@ function createContractProviderRouter(transport, opts) {
121
121
  ...call,
122
122
  dataContextId: authorization.dataContextId,
123
123
  };
124
+ const requestedProviderPackageId = opts.allowRequestedProvider && !targetDeviceId && typeof call.providerPackageId === "string"
125
+ ? call.providerPackageId
126
+ : undefined;
124
127
  const endpointRequest = {
125
128
  contractId: call.contractId,
126
129
  version: call.version,
127
130
  dataContextId: authorization.dataContextId,
128
131
  targetDeviceId,
132
+ requestedProviderPackageId,
129
133
  context,
130
134
  notify,
131
135
  };
@@ -17,15 +17,15 @@ declare const schema: z.ZodObject<{
17
17
  }, "strip", z.ZodTypeAny, {
18
18
  version: number;
19
19
  contractId: string;
20
- contractProviderId: string;
21
20
  providerPackageId: string;
21
+ contractProviderId: string;
22
22
  isActive: boolean;
23
23
  registeredAt: string;
24
24
  }, {
25
25
  version: number;
26
26
  contractId: string;
27
- contractProviderId: string;
28
27
  providerPackageId: string;
28
+ contractProviderId: string;
29
29
  isActive: boolean;
30
30
  registeredAt: string;
31
31
  }>;
@@ -62,6 +62,14 @@ export interface IContractCall {
62
62
  * under its own identity.
63
63
  */
64
64
  targetDeviceId?: string;
65
+ /**
66
+ * Provider to address when a contract has more than one.
67
+ *
68
+ * Honored by the local UI router after it checks the id is registered, and by
69
+ * the isolated runtime when the caller declared a consume of this contract.
70
+ * Remote device routers ignore it and keep the active provider.
71
+ */
72
+ providerPackageId?: string;
65
73
  /**
66
74
  * For any subscription call (a generic `event`, a table `dataChanged`, or an observable
67
75
  * value stream): the consumer-chosen id that ties a `"subscribe"` (and its later
@@ -256,9 +264,12 @@ export interface IContractToolContext {
256
264
  * @param transport Bidirectional channel to the provider; requests go out on
257
265
  * {@link CONTRACT_REQUEST_CHANNEL}, notifications arrive on {@link CONTRACT_NOTIFY_CHANNEL}.
258
266
  * @param opts.dataContextId Optional data context to scope every call to.
267
+ * @param opts.providerPackageId Optional provider to address. The local host
268
+ * accepts it only when that package is registered for this contract version.
259
269
  */
260
270
  export declare function createContractConsumer(contract: IContractDefinition, transport: IContractTransport, opts?: {
261
271
  dataContextId?: string;
272
+ providerPackageId?: string;
262
273
  }): IContractConsumer;
263
274
  /**
264
275
  * Build the **remote** consumer side of a contract: a factory of tools-only consumers whose
@@ -73,12 +73,17 @@ exports.CONTRACT_CALL_RPC = contract_transport_1.CONTRACT_REQUEST_CHANNEL;
73
73
  * @param transport Bidirectional channel to the provider; requests go out on
74
74
  * {@link CONTRACT_REQUEST_CHANNEL}, notifications arrive on {@link CONTRACT_NOTIFY_CHANNEL}.
75
75
  * @param opts.dataContextId Optional data context to scope every call to.
76
+ * @param opts.providerPackageId Optional provider to address. The local host
77
+ * accepts it only when that package is registered for this contract version.
76
78
  */
77
79
  function createContractConsumer(contract, transport, opts = {}) {
78
80
  const { contractId, version } = contract;
79
- const { dataContextId } = opts;
81
+ const { dataContextId, providerPackageId } = opts;
80
82
  let disposed = false;
81
- const emitRequest = (call) => transport.emit(contract_transport_1.CONTRACT_REQUEST_CHANNEL, call);
83
+ const emitRequest = (call) => transport.emit(contract_transport_1.CONTRACT_REQUEST_CHANNEL, {
84
+ ...call,
85
+ ...(providerPackageId ? { providerPackageId } : {}),
86
+ });
82
87
  const request = (call) => disposed
83
88
  ? Promise.reject(new Error(`Contract consumer ${contractId} v${version} is disposed`))
84
89
  : emitRequest(call);
@@ -535,13 +540,16 @@ function createContractProvider(resolution, opts = {}) {
535
540
  }
536
541
  await assertContractToolAccess(tool, call, context);
537
542
  if (resolution.toolContext || resolution.forwardCallContext) {
543
+ if (call.args.length > 1) {
544
+ throw new Error("Permission denied: tool runs accept a single argument when host context is forwarded");
545
+ }
538
546
  const base = resolution.toolContext ?? {
539
547
  dataContextId: context.dataContext?.dataContextId ?? "",
540
548
  getVariable: async () => {
541
549
  throw new Error("Persistent variables are not available to this contract tool");
542
550
  },
543
551
  };
544
- return tool.toolFn(...call.args, {
552
+ return tool.toolFn(call.args[0], {
545
553
  ...base,
546
554
  callerPackageId: context.callerPackageId,
547
555
  });
@@ -147,9 +147,12 @@ async function isSelfTrustedContractCaller(userContext, remoteIdentity) {
147
147
  }
148
148
  const permissionDenied = (call, reason) => new Error(`Permission denied: ${call.member} '${call.name}'.${call.operation} on contract ${call.contractId}${reason ? ` (${reason})` : ""}`);
149
149
  const localOnlyContractIds = new Set([
150
+ system_ids_1.contractCatalogContractId,
151
+ system_ids_1.httpContractId,
150
152
  system_ids_1.identityContractId,
151
153
  system_ids_1.invitesContractId,
152
154
  system_ids_1.localFoldersContractId,
155
+ system_ids_1.schedulerContractId,
153
156
  system_ids_1.toolAccessControlContractId,
154
157
  ]);
155
158
  /**
@@ -322,6 +325,7 @@ function resolvesWithoutUser(contractId, version, peekUserContext) {
322
325
  function createLocalUserContextContractProviderRouter(transport, opts) {
323
326
  const { getUserContext, peekUserContext, allowedContractIds, resolveVariable } = opts;
324
327
  return (0, contract_provider_router_1.createContractProviderRouter)(transport, {
328
+ allowRequestedProvider: true,
325
329
  authorizeCall: async (call) => {
326
330
  if (allowedContractIds && !allowedContractIds.has(call.contractId)) {
327
331
  throw new Error(`Permission denied: contract ${call.contractId} is not available locally`);
@@ -341,12 +345,19 @@ function createLocalUserContextContractProviderRouter(transport, opts) {
341
345
  context,
342
346
  };
343
347
  },
344
- resolveProviderPackageId: async ({ contractId, version, dataContextId }) => {
348
+ resolveProviderPackageId: async ({ contractId, version, dataContextId, requestedProviderPackageId, }) => {
345
349
  if (resolvesWithoutUser(contractId, version, peekUserContext)) {
346
350
  return undefined;
347
351
  }
348
352
  const userContext = await getUserContext();
349
353
  const dataContext = getAuthorizedLocalDataContext(userContext, dataContextId);
354
+ if (requestedProviderPackageId) {
355
+ const registered = dataContext.packageLoader?.contractRegistry.getRegisteredProviderIds(contractId, version) ?? [];
356
+ if (!registered.includes(requestedProviderPackageId)) {
357
+ throw new Error(`Package ${requestedProviderPackageId} is not a registered provider for ${contractId} v${version}`);
358
+ }
359
+ return requestedProviderPackageId;
360
+ }
350
361
  return getActiveProviderPackageId(dataContext, contractId, version);
351
362
  },
352
363
  resolveEndpoint: async (request) => {
@@ -12,12 +12,15 @@ export { getHostContractTransport, type HostContractTransportListener, registerH
12
12
  export { PersistentContractRegistry } from "./persistent-registry";
13
13
  export { ContractRegistry, type IContractProviderRegistration } from "./registry";
14
14
  export { createRemoteContractEndpoint, getRemoteContractTransportFactory, type IRemoteContractHost, type IRemoteContractTarget, type RemoteContractTransportFactory, resolveRemoteTargetEndpoint, setRemoteContractTransportFactory, } from "./remote-contract-transport";
15
+ export { CONTRACT_CATALOG_VERSION, contractCatalogProviderPackageId, getContractCatalogDefinition, type IContractCatalogConsumer, type IContractProviderInfo, type IListContractProvidersInput, } from "./system/contract-catalog-contract";
15
16
  export { DEVICE_OPERATIONS_CONTRACT_VERSION, DEVICE_OPERATIONS_MAX_QUERY_LENGTH, DEVICE_OPERATIONS_MAX_RESULT_BYTES, DEVICE_OPERATIONS_MAX_ROWS, DEVICE_OPERATIONS_MAX_TOOLS, type DeviceOperationCapability, deviceOperationsProviderPackageId, deviceOperationsToolIds, getDeviceOperationsContractDefinition, type IDeviceDatabaseQueryInput, type IDeviceDatabaseQueryResult, type IDeviceOperationStatus, type IDeviceToolListInput, type IDeviceToolLookupInput, type IDeviceToolLookupResult, type IDeviceToolRunInput, } from "./system/device-operations-contract";
17
+ export { getHttpContractDefinition, HTTP_CONTRACT_VERSION, HTTP_DEFAULT_TIMEOUT_MS, HTTP_MAX_BODY_BYTES, HTTP_MAX_TIMEOUT_MS, httpProviderPackageId, type IHttpCancelInput, type IHttpConsumer, type IHttpCredentialInfo, type IHttpMultipartPart, type IHttpPolicyInfo, type IHttpRequestInput, type IHttpRequestResult, } from "./system/http-contract";
16
18
  export { getIdentityContractDefinition, IDENTITY_CONTRACT_VERSION, type IIdentityConsumer, type IIdentityKeyInfo, type IIdentityRegistryKey, type IIdentityRotateKeyInput, type IIdentityRotateKeyResult, type IIdentitySessionInfo, } from "./system/identity-contract";
17
19
  export { getInvitesContractDefinition, type IAcceptInviteResult, type ICreatedInvite, type IInvitePreview, type IInvitesConsumer, INVITES_CONTRACT_VERSION, } from "./system/invites-contract";
18
20
  export { getLocalFoldersContractDefinition, type ILocalFolderAssembleInput, type ILocalFolderAssembleResult, type ILocalFolderChange, type ILocalFolderChangedEvent, type ILocalFolderEntry, type ILocalFolderFileBlocks, type ILocalFolderFileBlocksInput, type ILocalFolderGrantInfo, type ILocalFolderIndexInput, type ILocalFolderIndexResult, type ILocalFolderJobFinishedEvent, type ILocalFolderJobHandle, type ILocalFolderJobInfo, type ILocalFolderJobProgressEvent, type ILocalFolderListInput, type ILocalFolderManifestBlock, type ILocalFolderMoveInput, type ILocalFolderPathInput, type ILocalFolderPurgeTrashInput, type ILocalFolderReadRangeInput, type ILocalFolderReadRangeResult, type ILocalFolderRequestGrantInput, type ILocalFolderStatInput, LOCAL_FOLDERS_ASSEMBLE_STALL_MS, LOCAL_FOLDERS_CHUNK_AVG, LOCAL_FOLDERS_CHUNK_MAX, LOCAL_FOLDERS_CHUNK_MIN, LOCAL_FOLDERS_CONTRACT_VERSION, LOCAL_FOLDERS_GETBLOCKS_MAX_BLOCKS, LOCAL_FOLDERS_GETBLOCKS_MAX_BYTES, LOCAL_FOLDERS_HAVE_BATCH, LOCAL_FOLDERS_JOB_TTL_MS, LOCAL_FOLDERS_READ_RANGE_MAX, LOCAL_FOLDERS_RESERVED_DIR, type LocalFolderChangeKind, type LocalFolderEntryKind, type LocalFolderJobKind, type LocalFolderMode, localFoldersProviderPackageId, } from "./system/local-folders-contract";
19
21
  export { getLogsContractDefinition, type ILogsConsumer, LOGS_CONTRACT_VERSION, resolveLogsContract, } from "./system/logs-contract";
20
22
  export * from "./system/network-contracts";
23
+ export { getSchedulerContractDefinition, type IScheduleInfo, type IScheduleInput, type ISchedulerConsumer, SCHEDULER_CONTRACT_VERSION, SCHEDULER_MAX_DELAY_MS, schedulerProviderPackageId, } from "./system/scheduler-contract";
21
24
  export { getToolAccessControlContractDefinition, type IToolAccessControlConsumer, TOOL_ACCESS_CONTROL_CONTRACT_VERSION, } from "./system/tool-access-control-contract";
22
25
  export { type ISystemContractRegistration, installSystemContracts, listSystemContracts, registerSystemContract, } from "./system-contracts";
23
26
  export type { IAlsoImplementsDeclaration, IConsumedContract, IConsumedContractHandle, IConsumedContractOptions, IContractDefinition, IContractEvent, IContractObservable, IContractTable, IContractTool, IPackageDefinitionResult, IRemoteContract, IRemoteContractConsumer, IRemoteContractHandle, IResolvedContract, IValidationError, IValidationResult, } from "./types";
@@ -14,8 +14,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.DEVICE_OPERATIONS_MAX_ROWS = exports.DEVICE_OPERATIONS_MAX_RESULT_BYTES = exports.DEVICE_OPERATIONS_MAX_QUERY_LENGTH = exports.DEVICE_OPERATIONS_CONTRACT_VERSION = exports.setRemoteContractTransportFactory = exports.resolveRemoteTargetEndpoint = exports.getRemoteContractTransportFactory = exports.createRemoteContractEndpoint = exports.ContractRegistry = exports.PersistentContractRegistry = exports.waitForHostContractTransport = exports.subscribeHostContractTransport = exports.registerHostContractTransport = exports.getHostContractTransport = exports.hostContractConsumer = exports.setSchemaToFieldsFn = exports.extractToolShape = exports.extractTableShape = exports.createLocalContractConsumer = exports.contractsSchema = exports.contractsMetaData = exports.ContractsTable = exports.Contracts = exports.inProcessTransportPair = exports.connectionContractTransport = exports.CONTRACT_REQUEST_CHANNEL = exports.CONTRACT_NOTIFY_CHANNEL = exports.verifyRemoteContractIdentity = exports.registerContractResolver = exports.isSelfTrustedContractCaller = exports.handleContractCall = exports.getContractResolver = exports.createUserContextContractProviderRouter = exports.createLocalUserContextContractProviderRouter = exports.authorizeRemoteContractCall = exports.sameUserContractPermissionCheck = exports.createRemoteContractConsumer = exports.createContractProviderSession = exports.createContractProviderEndpoint = exports.createContractProvider = exports.createContractConsumer = exports.CONTRACT_CALL_RPC = exports.contractProvidersSchema = exports.contractProvidersMetaData = exports.ContractProvidersTable = exports.ContractProviders = exports.createContractProviderRouter = exports.PackageBuilder = exports.definePackage = exports.ContractBuilder = void 0;
18
- exports.validateProviderSatisfiesContract = exports.validateImmutability = exports.validateAlsoImplements = exports.contractKey = exports.registerSystemContract = exports.listSystemContracts = exports.installSystemContracts = exports.TOOL_ACCESS_CONTROL_CONTRACT_VERSION = exports.getToolAccessControlContractDefinition = exports.resolveLogsContract = exports.LOGS_CONTRACT_VERSION = exports.getLogsContractDefinition = exports.localFoldersProviderPackageId = exports.LOCAL_FOLDERS_RESERVED_DIR = exports.LOCAL_FOLDERS_READ_RANGE_MAX = exports.LOCAL_FOLDERS_JOB_TTL_MS = exports.LOCAL_FOLDERS_HAVE_BATCH = exports.LOCAL_FOLDERS_GETBLOCKS_MAX_BYTES = exports.LOCAL_FOLDERS_GETBLOCKS_MAX_BLOCKS = exports.LOCAL_FOLDERS_CONTRACT_VERSION = exports.LOCAL_FOLDERS_CHUNK_MIN = exports.LOCAL_FOLDERS_CHUNK_MAX = exports.LOCAL_FOLDERS_CHUNK_AVG = exports.LOCAL_FOLDERS_ASSEMBLE_STALL_MS = exports.getLocalFoldersContractDefinition = exports.INVITES_CONTRACT_VERSION = exports.getInvitesContractDefinition = exports.IDENTITY_CONTRACT_VERSION = exports.getIdentityContractDefinition = exports.getDeviceOperationsContractDefinition = exports.deviceOperationsToolIds = exports.deviceOperationsProviderPackageId = exports.DEVICE_OPERATIONS_MAX_TOOLS = void 0;
17
+ exports.DEVICE_OPERATIONS_CONTRACT_VERSION = exports.getContractCatalogDefinition = exports.contractCatalogProviderPackageId = exports.CONTRACT_CATALOG_VERSION = exports.setRemoteContractTransportFactory = exports.resolveRemoteTargetEndpoint = exports.getRemoteContractTransportFactory = exports.createRemoteContractEndpoint = exports.ContractRegistry = exports.PersistentContractRegistry = exports.waitForHostContractTransport = exports.subscribeHostContractTransport = exports.registerHostContractTransport = exports.getHostContractTransport = exports.hostContractConsumer = exports.setSchemaToFieldsFn = exports.extractToolShape = exports.extractTableShape = exports.createLocalContractConsumer = exports.contractsSchema = exports.contractsMetaData = exports.ContractsTable = exports.Contracts = exports.inProcessTransportPair = exports.connectionContractTransport = exports.CONTRACT_REQUEST_CHANNEL = exports.CONTRACT_NOTIFY_CHANNEL = exports.verifyRemoteContractIdentity = exports.registerContractResolver = exports.isSelfTrustedContractCaller = exports.handleContractCall = exports.getContractResolver = exports.createUserContextContractProviderRouter = exports.createLocalUserContextContractProviderRouter = exports.authorizeRemoteContractCall = exports.sameUserContractPermissionCheck = exports.createRemoteContractConsumer = exports.createContractProviderSession = exports.createContractProviderEndpoint = exports.createContractProvider = exports.createContractConsumer = exports.CONTRACT_CALL_RPC = exports.contractProvidersSchema = exports.contractProvidersMetaData = exports.ContractProvidersTable = exports.ContractProviders = exports.createContractProviderRouter = exports.PackageBuilder = exports.definePackage = exports.ContractBuilder = void 0;
18
+ exports.validateProviderSatisfiesContract = exports.validateImmutability = exports.validateAlsoImplements = exports.contractKey = exports.registerSystemContract = exports.listSystemContracts = exports.installSystemContracts = exports.TOOL_ACCESS_CONTROL_CONTRACT_VERSION = exports.getToolAccessControlContractDefinition = exports.schedulerProviderPackageId = exports.SCHEDULER_MAX_DELAY_MS = exports.SCHEDULER_CONTRACT_VERSION = exports.getSchedulerContractDefinition = exports.resolveLogsContract = exports.LOGS_CONTRACT_VERSION = exports.getLogsContractDefinition = exports.localFoldersProviderPackageId = exports.LOCAL_FOLDERS_RESERVED_DIR = exports.LOCAL_FOLDERS_READ_RANGE_MAX = exports.LOCAL_FOLDERS_JOB_TTL_MS = exports.LOCAL_FOLDERS_HAVE_BATCH = exports.LOCAL_FOLDERS_GETBLOCKS_MAX_BYTES = exports.LOCAL_FOLDERS_GETBLOCKS_MAX_BLOCKS = exports.LOCAL_FOLDERS_CONTRACT_VERSION = exports.LOCAL_FOLDERS_CHUNK_MIN = exports.LOCAL_FOLDERS_CHUNK_MAX = exports.LOCAL_FOLDERS_CHUNK_AVG = exports.LOCAL_FOLDERS_ASSEMBLE_STALL_MS = exports.getLocalFoldersContractDefinition = exports.INVITES_CONTRACT_VERSION = exports.getInvitesContractDefinition = exports.IDENTITY_CONTRACT_VERSION = exports.getIdentityContractDefinition = exports.httpProviderPackageId = exports.HTTP_MAX_TIMEOUT_MS = exports.HTTP_MAX_BODY_BYTES = exports.HTTP_DEFAULT_TIMEOUT_MS = exports.HTTP_CONTRACT_VERSION = exports.getHttpContractDefinition = exports.getDeviceOperationsContractDefinition = exports.deviceOperationsToolIds = exports.deviceOperationsProviderPackageId = exports.DEVICE_OPERATIONS_MAX_TOOLS = exports.DEVICE_OPERATIONS_MAX_ROWS = exports.DEVICE_OPERATIONS_MAX_RESULT_BYTES = exports.DEVICE_OPERATIONS_MAX_QUERY_LENGTH = void 0;
19
19
  var builder_1 = require("./builder");
20
20
  Object.defineProperty(exports, "ContractBuilder", { enumerable: true, get: function () { return builder_1.ContractBuilder; } });
21
21
  Object.defineProperty(exports, "definePackage", { enumerable: true, get: function () { return builder_1.definePackage; } });
@@ -76,6 +76,10 @@ Object.defineProperty(exports, "createRemoteContractEndpoint", { enumerable: tru
76
76
  Object.defineProperty(exports, "getRemoteContractTransportFactory", { enumerable: true, get: function () { return remote_contract_transport_1.getRemoteContractTransportFactory; } });
77
77
  Object.defineProperty(exports, "resolveRemoteTargetEndpoint", { enumerable: true, get: function () { return remote_contract_transport_1.resolveRemoteTargetEndpoint; } });
78
78
  Object.defineProperty(exports, "setRemoteContractTransportFactory", { enumerable: true, get: function () { return remote_contract_transport_1.setRemoteContractTransportFactory; } });
79
+ var contract_catalog_contract_1 = require("./system/contract-catalog-contract");
80
+ Object.defineProperty(exports, "CONTRACT_CATALOG_VERSION", { enumerable: true, get: function () { return contract_catalog_contract_1.CONTRACT_CATALOG_VERSION; } });
81
+ Object.defineProperty(exports, "contractCatalogProviderPackageId", { enumerable: true, get: function () { return contract_catalog_contract_1.contractCatalogProviderPackageId; } });
82
+ Object.defineProperty(exports, "getContractCatalogDefinition", { enumerable: true, get: function () { return contract_catalog_contract_1.getContractCatalogDefinition; } });
79
83
  var device_operations_contract_1 = require("./system/device-operations-contract");
80
84
  Object.defineProperty(exports, "DEVICE_OPERATIONS_CONTRACT_VERSION", { enumerable: true, get: function () { return device_operations_contract_1.DEVICE_OPERATIONS_CONTRACT_VERSION; } });
81
85
  Object.defineProperty(exports, "DEVICE_OPERATIONS_MAX_QUERY_LENGTH", { enumerable: true, get: function () { return device_operations_contract_1.DEVICE_OPERATIONS_MAX_QUERY_LENGTH; } });
@@ -85,6 +89,13 @@ Object.defineProperty(exports, "DEVICE_OPERATIONS_MAX_TOOLS", { enumerable: true
85
89
  Object.defineProperty(exports, "deviceOperationsProviderPackageId", { enumerable: true, get: function () { return device_operations_contract_1.deviceOperationsProviderPackageId; } });
86
90
  Object.defineProperty(exports, "deviceOperationsToolIds", { enumerable: true, get: function () { return device_operations_contract_1.deviceOperationsToolIds; } });
87
91
  Object.defineProperty(exports, "getDeviceOperationsContractDefinition", { enumerable: true, get: function () { return device_operations_contract_1.getDeviceOperationsContractDefinition; } });
92
+ var http_contract_1 = require("./system/http-contract");
93
+ Object.defineProperty(exports, "getHttpContractDefinition", { enumerable: true, get: function () { return http_contract_1.getHttpContractDefinition; } });
94
+ Object.defineProperty(exports, "HTTP_CONTRACT_VERSION", { enumerable: true, get: function () { return http_contract_1.HTTP_CONTRACT_VERSION; } });
95
+ Object.defineProperty(exports, "HTTP_DEFAULT_TIMEOUT_MS", { enumerable: true, get: function () { return http_contract_1.HTTP_DEFAULT_TIMEOUT_MS; } });
96
+ Object.defineProperty(exports, "HTTP_MAX_BODY_BYTES", { enumerable: true, get: function () { return http_contract_1.HTTP_MAX_BODY_BYTES; } });
97
+ Object.defineProperty(exports, "HTTP_MAX_TIMEOUT_MS", { enumerable: true, get: function () { return http_contract_1.HTTP_MAX_TIMEOUT_MS; } });
98
+ Object.defineProperty(exports, "httpProviderPackageId", { enumerable: true, get: function () { return http_contract_1.httpProviderPackageId; } });
88
99
  var identity_contract_1 = require("./system/identity-contract");
89
100
  Object.defineProperty(exports, "getIdentityContractDefinition", { enumerable: true, get: function () { return identity_contract_1.getIdentityContractDefinition; } });
90
101
  Object.defineProperty(exports, "IDENTITY_CONTRACT_VERSION", { enumerable: true, get: function () { return identity_contract_1.IDENTITY_CONTRACT_VERSION; } });
@@ -110,6 +121,11 @@ Object.defineProperty(exports, "getLogsContractDefinition", { enumerable: true,
110
121
  Object.defineProperty(exports, "LOGS_CONTRACT_VERSION", { enumerable: true, get: function () { return logs_contract_1.LOGS_CONTRACT_VERSION; } });
111
122
  Object.defineProperty(exports, "resolveLogsContract", { enumerable: true, get: function () { return logs_contract_1.resolveLogsContract; } });
112
123
  __exportStar(require("./system/network-contracts"), exports);
124
+ var scheduler_contract_1 = require("./system/scheduler-contract");
125
+ Object.defineProperty(exports, "getSchedulerContractDefinition", { enumerable: true, get: function () { return scheduler_contract_1.getSchedulerContractDefinition; } });
126
+ Object.defineProperty(exports, "SCHEDULER_CONTRACT_VERSION", { enumerable: true, get: function () { return scheduler_contract_1.SCHEDULER_CONTRACT_VERSION; } });
127
+ Object.defineProperty(exports, "SCHEDULER_MAX_DELAY_MS", { enumerable: true, get: function () { return scheduler_contract_1.SCHEDULER_MAX_DELAY_MS; } });
128
+ Object.defineProperty(exports, "schedulerProviderPackageId", { enumerable: true, get: function () { return scheduler_contract_1.schedulerProviderPackageId; } });
113
129
  var tool_access_control_contract_1 = require("./system/tool-access-control-contract");
114
130
  Object.defineProperty(exports, "getToolAccessControlContractDefinition", { enumerable: true, get: function () { return tool_access_control_contract_1.getToolAccessControlContractDefinition; } });
115
131
  Object.defineProperty(exports, "TOOL_ACCESS_CONTROL_CONTRACT_VERSION", { enumerable: true, get: function () { return tool_access_control_contract_1.TOOL_ACCESS_CONTROL_CONTRACT_VERSION; } });
@@ -0,0 +1,38 @@
1
+ import type { IContractConsumerBase } from "../contract-proxy";
2
+ import type { IContractDefinition } from "../types";
3
+ /** Version of the built-in System Contract Catalog. */
4
+ export declare const CONTRACT_CATALOG_VERSION = 1;
5
+ /** Package id of the System Contract Catalog provider. */
6
+ export declare const contractCatalogProviderPackageId = "000peers0system0000000001";
7
+ /** One registered provider of a contract version. */
8
+ export interface IContractProviderInfo {
9
+ packageId: string;
10
+ /** Display name from the Packages row, or the package id for the system provider. */
11
+ name: string;
12
+ /** True when this package is the active provider for the contract version. */
13
+ active: boolean;
14
+ }
15
+ /** Input for listing providers of one contract version. */
16
+ export interface IListContractProvidersInput {
17
+ contractId: string;
18
+ version: number;
19
+ }
20
+ /**
21
+ * Consumer shape for the System Contract Catalog.
22
+ *
23
+ * Hub packages use this to discover every provider of a shared contract.
24
+ */
25
+ export interface IContractCatalogConsumer extends IContractConsumerBase {
26
+ tools: {
27
+ listContractProviders(input: IListContractProvidersInput): Promise<{
28
+ providers: IContractProviderInfo[];
29
+ }>;
30
+ };
31
+ }
32
+ /**
33
+ * Return the local-only catalog contract that lists providers of another contract.
34
+ *
35
+ * The active provider remains the default for ordinary calls. This tool exists so a
36
+ * consumer can address every registered provider, not only the active one.
37
+ */
38
+ export declare function getContractCatalogDefinition(): IContractDefinition;
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.contractCatalogProviderPackageId = exports.CONTRACT_CATALOG_VERSION = void 0;
4
+ exports.getContractCatalogDefinition = getContractCatalogDefinition;
5
+ const system_ids_1 = require("../../system-ids");
6
+ const field_type_1 = require("../../types/field-type");
7
+ const system_contracts_1 = require("../system-contracts");
8
+ /** Version of the built-in System Contract Catalog. */
9
+ exports.CONTRACT_CATALOG_VERSION = 1;
10
+ /** Package id of the System Contract Catalog provider. */
11
+ exports.contractCatalogProviderPackageId = system_ids_1.peersSystemPackageId;
12
+ const field = (name, type, description, opts = {}) => ({ name, type, description, ...opts });
13
+ let definition;
14
+ /**
15
+ * Return the local-only catalog contract that lists providers of another contract.
16
+ *
17
+ * The active provider remains the default for ordinary calls. This tool exists so a
18
+ * consumer can address every registered provider, not only the active one.
19
+ */
20
+ function getContractCatalogDefinition() {
21
+ definition ??= {
22
+ contractId: system_ids_1.contractCatalogContractId,
23
+ version: exports.CONTRACT_CATALOG_VERSION,
24
+ devTag: "dev",
25
+ name: "System Contract Catalog",
26
+ description: "Lists the packages registered as providers of a contract version.",
27
+ tables: [],
28
+ tools: [
29
+ {
30
+ name: "listContractProviders",
31
+ usageDescription: "List every package registered for a contract version, including inactive ones.",
32
+ inputFields: [
33
+ field("contractId", field_type_1.FieldType.id, "Contract to look up."),
34
+ field("version", field_type_1.FieldType.number, "Contract version."),
35
+ ],
36
+ outputFields: [
37
+ field("providers", field_type_1.FieldType.object, "Registered providers in registration order, with packageId, name, and active.", { isArray: true }),
38
+ ],
39
+ },
40
+ ],
41
+ observables: [],
42
+ events: [],
43
+ };
44
+ return definition;
45
+ }
46
+ (0, system_contracts_1.registerSystemContract)({
47
+ providerPackageId: exports.contractCatalogProviderPackageId,
48
+ contractId: system_ids_1.contractCatalogContractId,
49
+ version: exports.CONTRACT_CATALOG_VERSION,
50
+ getDefinition: getContractCatalogDefinition,
51
+ });
@@ -0,0 +1,80 @@
1
+ import type { IContractConsumerBase } from "../contract-proxy";
2
+ import type { IContractDefinition } from "../types";
3
+ /** Version of the built-in System HTTP contract. */
4
+ export declare const HTTP_CONTRACT_VERSION = 1;
5
+ /** Default request deadline when the caller omits `timeoutMs`. */
6
+ export declare const HTTP_DEFAULT_TIMEOUT_MS = 30000;
7
+ /** Longest request deadline System HTTP will honor. */
8
+ export declare const HTTP_MAX_TIMEOUT_MS = 120000;
9
+ /** Largest request or response body, in decoded bytes. */
10
+ export declare const HTTP_MAX_BODY_BYTES: number;
11
+ /** Package id of the System HTTP provider. */
12
+ export declare const httpProviderPackageId = "000peers0system0000000001";
13
+ /** One multipart part. Use `text` for a form field or `bodyBase64` for bytes. */
14
+ export interface IHttpMultipartPart {
15
+ name: string;
16
+ filename?: string;
17
+ contentType?: string;
18
+ /** UTF-8 form field. Used instead of `bodyBase64` when set. */
19
+ text?: string;
20
+ bodyBase64?: string;
21
+ }
22
+ /** Input for {@link IHttpConsumer tools.request}. */
23
+ export interface IHttpRequestInput {
24
+ requestId: string;
25
+ method: string;
26
+ url: string;
27
+ headers?: Record<string, string>;
28
+ body?: string;
29
+ bodyBase64?: string;
30
+ multipart?: IHttpMultipartPart[];
31
+ credentialRef?: string;
32
+ responseType?: "json" | "text" | "base64";
33
+ timeoutMs?: number;
34
+ }
35
+ /** Result of one System HTTP request. Non-2xx responses are returned, not thrown. */
36
+ export interface IHttpRequestResult {
37
+ status: number;
38
+ ok: boolean;
39
+ contentType: string;
40
+ body: unknown;
41
+ }
42
+ /** Input for cancelling an in-flight request owned by the calling package. */
43
+ export interface IHttpCancelInput {
44
+ requestId: string;
45
+ }
46
+ /** One credential declaration safe to show in the admin UI. The secret value is omitted. */
47
+ export interface IHttpCredentialInfo {
48
+ ref: string;
49
+ header: string;
50
+ secretVar: string;
51
+ scope: "user" | "device";
52
+ }
53
+ /** Network declaration for one package, as shown to the operator. */
54
+ export interface IHttpPolicyInfo {
55
+ allowedHosts: string[];
56
+ credentials: IHttpCredentialInfo[];
57
+ }
58
+ /**
59
+ * Consumer shape for System HTTP.
60
+ *
61
+ * Isolated packages call `request` and `cancel`. The Packages screen calls `describePolicy`.
62
+ */
63
+ export interface IHttpConsumer extends IContractConsumerBase {
64
+ tools: {
65
+ request(input: IHttpRequestInput): Promise<IHttpRequestResult>;
66
+ cancel(input: IHttpCancelInput): Promise<{
67
+ cancelled: boolean;
68
+ }>;
69
+ describePolicy(input: {
70
+ packageId: string;
71
+ }): Promise<IHttpPolicyInfo>;
72
+ };
73
+ }
74
+ /**
75
+ * Return the local-only System HTTP contract shape.
76
+ *
77
+ * The host performs `fetch`. Guests name an allowlisted URL and an optional
78
+ * credential ref; they never receive the secret or an open network.
79
+ */
80
+ export declare function getHttpContractDefinition(): IContractDefinition;
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.httpProviderPackageId = exports.HTTP_MAX_BODY_BYTES = exports.HTTP_MAX_TIMEOUT_MS = exports.HTTP_DEFAULT_TIMEOUT_MS = exports.HTTP_CONTRACT_VERSION = void 0;
4
+ exports.getHttpContractDefinition = getHttpContractDefinition;
5
+ const system_ids_1 = require("../../system-ids");
6
+ const field_type_1 = require("../../types/field-type");
7
+ const system_contracts_1 = require("../system-contracts");
8
+ /** Version of the built-in System HTTP contract. */
9
+ exports.HTTP_CONTRACT_VERSION = 1;
10
+ /** Default request deadline when the caller omits `timeoutMs`. */
11
+ exports.HTTP_DEFAULT_TIMEOUT_MS = 30_000;
12
+ /** Longest request deadline System HTTP will honor. */
13
+ exports.HTTP_MAX_TIMEOUT_MS = 120_000;
14
+ /** Largest request or response body, in decoded bytes. */
15
+ exports.HTTP_MAX_BODY_BYTES = 8 * 1024 * 1024;
16
+ /** Package id of the System HTTP provider. */
17
+ exports.httpProviderPackageId = system_ids_1.peersSystemPackageId;
18
+ const field = (name, type, description, opts = {}) => ({ name, type, description, ...opts });
19
+ let definition;
20
+ /**
21
+ * Return the local-only System HTTP contract shape.
22
+ *
23
+ * The host performs `fetch`. Guests name an allowlisted URL and an optional
24
+ * credential ref; they never receive the secret or an open network.
25
+ */
26
+ function getHttpContractDefinition() {
27
+ definition ??= {
28
+ contractId: system_ids_1.httpContractId,
29
+ version: exports.HTTP_CONTRACT_VERSION,
30
+ devTag: "dev",
31
+ name: "System HTTP",
32
+ description: "Host-mediated HTTPS for isolated packages. Hosts must be declared on the package, and credentials are injected by reference.",
33
+ tables: [],
34
+ tools: [
35
+ {
36
+ name: "request",
37
+ usageDescription: "Perform one HTTPS request to a host this package declared. Non-2xx responses are returned.",
38
+ inputFields: [
39
+ field("requestId", field_type_1.FieldType.string, "Caller-chosen id used to cancel this request."),
40
+ field("method", field_type_1.FieldType.string, "HTTP method: GET, POST, PUT, PATCH, DELETE, or HEAD."),
41
+ field("url", field_type_1.FieldType.string, "Absolute https URL whose host is on this package's allowlist."),
42
+ field("headers", field_type_1.FieldType.object, "Optional request headers. Credential headers are overwritten.", {
43
+ optional: true,
44
+ }),
45
+ field("body", field_type_1.FieldType.string, "UTF-8 request body.", { optional: true }),
46
+ field("bodyBase64", field_type_1.FieldType.string, "Base64 request body. Used instead of body when set.", {
47
+ optional: true,
48
+ }),
49
+ field("multipart", field_type_1.FieldType.object, "Multipart parts with name and bodyBase64. Used instead of body when set.", { optional: true, isArray: true }),
50
+ field("credentialRef", field_type_1.FieldType.string, "Credential ref from this package's network declaration.", { optional: true }),
51
+ field("responseType", field_type_1.FieldType.string, 'How to decode the response: "json", "text", or "base64". Defaults to json.', { optional: true }),
52
+ field("timeoutMs", field_type_1.FieldType.number, `Deadline in milliseconds. Defaults to ${exports.HTTP_DEFAULT_TIMEOUT_MS} and is capped at ${exports.HTTP_MAX_TIMEOUT_MS}.`, { optional: true }),
53
+ ],
54
+ outputFields: [
55
+ field("status", field_type_1.FieldType.number, "HTTP status code."),
56
+ field("ok", field_type_1.FieldType.boolean, "True when the status is 2xx."),
57
+ field("contentType", field_type_1.FieldType.string, "Response Content-Type, or empty."),
58
+ field("body", field_type_1.FieldType.any, "Decoded response body."),
59
+ ],
60
+ },
61
+ {
62
+ name: "cancel",
63
+ usageDescription: "Abort one in-flight request started by this package.",
64
+ inputFields: [field("requestId", field_type_1.FieldType.string, "Id passed to request.")],
65
+ outputFields: [
66
+ field("cancelled", field_type_1.FieldType.boolean, "True when a matching request was aborted."),
67
+ ],
68
+ },
69
+ {
70
+ name: "describePolicy",
71
+ usageDescription: "Return the host allowlist and credential refs declared by a package. Secret values are omitted.",
72
+ inputFields: [
73
+ field("packageId", field_type_1.FieldType.id, "Package whose network declaration to read."),
74
+ ],
75
+ outputFields: [
76
+ field("allowedHosts", field_type_1.FieldType.string, "Hostnames the package may request.", {
77
+ isArray: true,
78
+ }),
79
+ field("credentials", field_type_1.FieldType.object, "Credential refs, headers, and logical secret names. Values are not included.", { isArray: true }),
80
+ ],
81
+ },
82
+ ],
83
+ observables: [],
84
+ events: [],
85
+ };
86
+ return definition;
87
+ }
88
+ (0, system_contracts_1.registerSystemContract)({
89
+ providerPackageId: exports.httpProviderPackageId,
90
+ contractId: system_ids_1.httpContractId,
91
+ version: exports.HTTP_CONTRACT_VERSION,
92
+ getDefinition: getHttpContractDefinition,
93
+ });
@@ -2,11 +2,14 @@
2
2
  * Built-in system contracts. Importing this barrel runs each module's
3
3
  * {@link registerSystemContract} side effect so the catalog is populated.
4
4
  */
5
+ import "./contract-catalog-contract";
5
6
  import "./device-operations-contract";
7
+ import "./http-contract";
6
8
  import "./identity-contract";
7
9
  import "./invites-contract";
8
10
  import "./logs-contract";
9
11
  import "./network-contracts";
12
+ import "./scheduler-contract";
10
13
  import "./tool-access-control-contract";
11
14
  export { DEVICE_OPERATIONS_CONTRACT_VERSION, DEVICE_OPERATIONS_MAX_QUERY_LENGTH, DEVICE_OPERATIONS_MAX_RESULT_BYTES, DEVICE_OPERATIONS_MAX_ROWS, DEVICE_OPERATIONS_MAX_TOOLS, type DeviceOperationCapability, deviceOperationsProviderPackageId, deviceOperationsToolIds, getDeviceOperationsContractDefinition, type IDeviceDatabaseQueryInput, type IDeviceDatabaseQueryResult, type IDeviceOperationStatus, type IDeviceToolListInput, type IDeviceToolLookupInput, type IDeviceToolLookupResult, type IDeviceToolRunInput, } from "./device-operations-contract";
12
15
  export { getIdentityContractDefinition, IDENTITY_CONTRACT_VERSION, type IIdentityConsumer, type IIdentityKeyInfo, type IIdentityRegistryKey, type IIdentityRotateKeyInput, type IIdentityRotateKeyResult, type IIdentitySessionInfo, } from "./identity-contract";
@@ -19,11 +19,14 @@ exports.TOOL_ACCESS_CONTROL_CONTRACT_VERSION = exports.getToolAccessControlContr
19
19
  * Built-in system contracts. Importing this barrel runs each module's
20
20
  * {@link registerSystemContract} side effect so the catalog is populated.
21
21
  */
22
+ require("./contract-catalog-contract");
22
23
  require("./device-operations-contract");
24
+ require("./http-contract");
23
25
  require("./identity-contract");
24
26
  require("./invites-contract");
25
27
  require("./logs-contract");
26
28
  require("./network-contracts");
29
+ require("./scheduler-contract");
27
30
  require("./tool-access-control-contract");
28
31
  var device_operations_contract_1 = require("./device-operations-contract");
29
32
  Object.defineProperty(exports, "DEVICE_OPERATIONS_CONTRACT_VERSION", { enumerable: true, get: function () { return device_operations_contract_1.DEVICE_OPERATIONS_CONTRACT_VERSION; } });