@collective-intelligence/external-apps-client-sdk 0.1.8 → 0.1.9

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.
package/README.md CHANGED
@@ -31,14 +31,66 @@ plus slack) before throwing `Run did not finish`; pass `deadlineMs` to change
31
31
  it and `signal` to cancel. Polling starts every `idleMs` (50 ms) and backs off
32
32
  to at most one second while no new events arrive.
33
33
 
34
+ ## Workflow results and read recovery
35
+
36
+ A successful Workflow with a declared output contract exposes its persisted
37
+ result in the run returned by `runs.get`:
38
+
39
+ ```json
40
+ {
41
+ "status": "succeeded",
42
+ "result": {
43
+ "nativeStatus": "completed",
44
+ "output": {
45
+ "activeSearch": {
46
+ "notionPageId": "notion-search-123",
47
+ "url": "https://notion.so/notion-search-123",
48
+ "name": "Senior engineer",
49
+ "status": "created"
50
+ },
51
+ "customer": { "created": false, "id": "customer-42", "name": "Acme" },
52
+ "requirements": { "role": "engineer", "seniority": "senior" }
53
+ }
54
+ }
55
+ }
56
+ ```
57
+
58
+ This is an excerpt of the run JSON in the successful SDK response's `value`.
59
+ The Workflow selects and validates `output`; it is portable JSON, not a
60
+ search-specific SDK type. Unmapped intermediate node fields are not public
61
+ output. `runs.stream` returns an event page; its `completed` event's `data`
62
+ equals the run's `result`. `runs.follow` also returns an event page and drains
63
+ remaining pages after a terminal snapshot, so read the completion event's
64
+ `data.output` there. It does not return a run snapshot.
65
+
66
+ `runs.get` and `runs.stream` return a failed `CiResult` for an HTTP read failure;
67
+ `runs.follow` propagates that failure as an error. Following has no automatic
68
+ read retry, even for a retryable error. Retain the original `runId` and explicitly
69
+ call `get`, `stream`, or `follow` again when retrying observation. Do not invoke
70
+ the Workflow again to recover its result. A new `follow` starts reading the
71
+ same run's events from the beginning; use `stream({ runId, afterCursor })` when
72
+ the application owns a saved cursor.
73
+
74
+ Native execution and result persistence continue after the browser disconnects.
75
+ The first authorized `get` or `stream` after completion publishes the external
76
+ terminal receipt; `follow` uses those same reads. Access remains scoped to the
77
+ original owner, Organization, Application and audit subject. Historical terminal
78
+ runs are not backfilled or adapted. A missing promised output is a technical
79
+ invariant defect, not a successful empty or partial result.
80
+
81
+ Analysis history and candidate results remain Knowledge reads. A matching
82
+ completion notification must wait until those results are actually available in
83
+ Knowledge; a completed command alone does not establish that readiness. See the
84
+ [Workflow output contract and recovery guide](../../../docs/architecture/external-app-gateway.md#workflow-results-and-observation).
85
+
86
+ ## Common entity CRUD
87
+
34
88
  The `@collective-intelligence/external-apps-client-sdk/resources` entrypoint
35
89
  provides the portable resource contracts and `createResourceClient`. A resource
36
90
  client supports filtering, sorting, text search, page or cursor pagination,
37
91
  opaque IDs and revisions, optimistic concurrency, idempotency, soft deletion,
38
92
  restore, and hard deletion according to the resource's declared capabilities.
39
93
 
40
- ## Common entity CRUD
41
-
42
94
  Use the explicit `protocol: "entity"` option for the common page-based CRUD API.
43
95
  Both the root and `/resources` entrypoints export these builders:
44
96
 
@@ -82,7 +134,8 @@ authorizes access. They are configuration, never mutation-body authority.
82
134
  including identity, login, logout, and `runs_follow`. `createFixedWorkflowClient`
83
135
  posts a Fixed workflow BFF route and returns `{ runId }`.
84
136
 
85
- The common client exposes `list`, `get`, `create`, `update`, and `delete`.
137
+ The common client exposes `list`, `get`, `create`, `update`, `delete`, and
138
+ `upload` (see [File uploads](#file-uploads)).
86
139
  `delete` calls the explicit soft-delete route. Every mutation requires an operation
87
140
  key; update/delete also require the revision originally edited. Reads accept an
88
141
  optional `{ signal }`. Mutations are independent of view unmount cancellation.
@@ -100,6 +153,61 @@ During migration, omitting `protocol` retains the distinct legacy resource facad
100
153
  including its optional update keys, cursor pagination and explicit lifecycle
101
154
  methods. Existing hard-delete behavior is never relabeled as common `delete`.
102
155
 
156
+ ## File uploads
157
+
158
+ A File field holds files of a CI entity. The browser sends the file bytes
159
+ straight to storage; they never pass through CI or a BFF:
160
+
161
+ 1. `upload({ field, filename, mimeType })` requests a File upload for one
162
+ File field. The definition must declare `capabilities.upload: true`;
163
+ otherwise the call fails with `capability_not_supported` and sends nothing.
164
+ 2. PUT the bytes to the returned `url` with the returned `headers`.
165
+ 3. Write the entity with `{ upload: uploadId }` for that File field key.
166
+
167
+ ```ts
168
+ const slot = await leads.upload(
169
+ { field: "resume", filename: file.name, mimeType: file.type },
170
+ { signal }
171
+ )
172
+ if (slot.ok) {
173
+ await fetch(slot.value.url, {
174
+ body: file,
175
+ headers: slot.value.headers,
176
+ method: slot.value.method
177
+ })
178
+ await leads.update({
179
+ expectedRevision: record.revision,
180
+ id: record.id,
181
+ idempotencyKey: crypto.randomUUID(),
182
+ value: { resume: { upload: slot.value.uploadId } }
183
+ })
184
+ }
185
+ ```
186
+
187
+ `EntityFileFieldWrite` types the write form of a File field key:
188
+
189
+ - `{ upload: uploadId }` adds a File upload.
190
+ - `{ id }` keeps a file. A File value read before also keeps it; its other keys
191
+ are ignored.
192
+ - `null` removes every file of the field.
193
+ - An ordered array sets the exact list of a multiple File field.
194
+ - An absent key keeps the files unchanged.
195
+
196
+ The definition's create and update schemas must accept this form for each
197
+ File field key. Reads return `EntityFileValue` objects:
198
+ `{ id, url, filename, mimeType, size, source }`, where `source` is `managed` or
199
+ `external_url`. A single File field reads as one File value or `null`; a
200
+ multiple one as an array.
201
+
202
+ A File upload is single use: the first successful write consumes it, and CI
203
+ deletes an unused one after a retention window. Request a new one to retry.
204
+ `upload` fails with `upload_not_supported` when the Organization storage can
205
+ not presign, with `invalid_request` (`details.reason` `not_a_file_field` or
206
+ `type_not_accepted`) for a field or MIME type the schema refuses, and with
207
+ `not_found` for an unknown schema. A write that refuses its write form answers
208
+ `invalid_request` with `details.field` and `details.reason`; a File field of a
209
+ connector-owned entity answers `conflict`.
210
+
103
211
  ## Workspace development
104
212
 
105
213
  The repository's [Effect demo](../../../demo/external-app-effect/README.md)
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as CiErrorCode, A as ResourceIdentityField, B as ResourceRecord, C as ResourceCursor, Ct as FederatedAuthError, D as ResourceFilter, Dt as FederatedSessionIdentity, E as ResourceErrorCode, Et as FederatedAuthState, F as ResourceListRequest, G as ResourceSort, H as ResourceRequestOptions, I as ResourceListResult, J as ResourceUpdateRequest, K as ResourceTransport, L as ResourceMutationInput, M as ResourceLifecycleInput, N as ResourceLifecycleRequest, O as ResourceGetRequest, Ot as createFederatedAuth, P as ResourceListQuery, Q as CiError, R as ResourcePagination, S as ResourceCreateRequest, St as FederatedAuth, T as ResourceError, Tt as FederatedAuthOptions, U as ResourceResult, V as ResourceRecordId, W as ResourceRevision, X as ProxyTransportOptions, Y as ProxyAuthentication, Z as createProxyTransport, _ as IdempotencyKey, _t as KnowledgeQuery, a as createResourceClient, at as ClientOperationId, b as ResourceClient, bt as WorkflowInvokeTarget, c as EntityDeleteInput, ct as ClientOperationOutput, d as EntityOperationResult, dt as clientOperationIds, et as CiResult, f as EntityPage, ft as isClientOperationId, g as EntityUpdateInput, gt as JsonObject, h as EntityTransport, ht as ConversationHistory, i as createEntityProtocol, it as ClientOperationDefinition, j as ResourceJsonValue, k as ResourceId, l as EntityListQuery, lt as OperationExecutionOptions, m as EntityRequest, mt as ConversationContinueTarget, n as EntityHttpTransportOptions, nt as OperationRequest, o as EntityClient, ot as ClientOperationInput, p as EntityProtocol, pt as AgentInvokeTarget, q as ResourceTransportRequest, r as createEntityHttpTransport, rt as OperationSuccess, s as EntityCreateInput, st as ClientOperationMap, t as EntityHttpDestination, tt as JsonValue, u as EntityOperation, ut as TypedOperationExecutor, v as PortableResourceSchema, vt as QueryFilter, w as ResourceDefinition, wt as FederatedAuthErrorCode, x as ResourceCreateInput, xt as ClientFetch, y as ResourceCapabilities, yt as SearchQuery, z as ResourcePaginationMode } from "./resources-D95LlDMa.js";
1
+ import { $ as ResourceUpdateRequest, A as ResourceError, At as FederatedAuthOptions, B as ResourceListRequest, C as PortableResourceSchema, Ct as QueryFilter, D as ResourceCreateRequest, Dt as FederatedAuth, E as ResourceCreateInput, Et as ClientFetch, F as ResourceIdentityField, G as ResourceRecord, H as ResourceMutationInput, I as ResourceJsonValue, J as ResourceResult, K as ResourceRecordId, L as ResourceLifecycleInput, M as ResourceFilter, Mt as FederatedSessionIdentity, N as ResourceGetRequest, Nt as createFederatedAuth, O as ResourceCursor, Ot as FederatedAuthError, P as ResourceId, Q as ResourceTransportRequest, R as ResourceLifecycleRequest, S as IdempotencyKey, St as KnowledgeQuery, T as ResourceClient, Tt as WorkflowInvokeTarget, U as ResourcePagination, V as ResourceListResult, W as ResourcePaginationMode, X as ResourceSort, Y as ResourceRevision, Z as ResourceTransport, _ as EntityRequest, _t as isClientOperationId, a as createResourceClient, at as CiResult, b as EntityUploadInput, bt as ConversationHistory, c as EntityDeleteInput, ct as OperationSuccess, d as EntityFileWrite, dt as ClientOperationInput, et as ProxyAuthentication, f as EntityListQuery, ft as ClientOperationMap, g as EntityProtocol, gt as clientOperationIds, h as EntityPage, ht as TypedOperationExecutor, i as createEntityProtocol, it as CiErrorCode, j as ResourceErrorCode, jt as FederatedAuthState, k as ResourceDefinition, kt as FederatedAuthErrorCode, l as EntityFileFieldWrite, lt as ClientOperationDefinition, m as EntityOperationResult, mt as OperationExecutionOptions, n as EntityHttpTransportOptions, nt as createProxyTransport, o as EntityClient, ot as JsonValue, p as EntityOperation, pt as ClientOperationOutput, q as ResourceRequestOptions, r as createEntityHttpTransport, rt as CiError, s as EntityCreateInput, st as OperationRequest, t as EntityHttpDestination, tt as ProxyTransportOptions, u as EntityFileValue, ut as ClientOperationId, v as EntityTransport, vt as AgentInvokeTarget, w as ResourceCapabilities, wt as SearchQuery, x as EntityUploadSlot, xt as JsonObject, y as EntityUpdateInput, yt as ConversationContinueTarget, z as ResourceListQuery } from "./resources-DxMBAy-Z.js";
2
2
  type ServerSessionAuthOptions = Readonly<{
3
3
  basePath: string;
4
4
  fetch?: ClientFetch;
@@ -889,4 +889,4 @@ type DirectTransportOptions = Readonly<{
889
889
  tenantUrl: string;
890
890
  }>;
891
891
  declare const createDirectTransport: <Operations extends ClientOperationMap>(options: DirectTransportOptions) => TypedOperationExecutor<Operations>;
892
- export { type CiError, type CiErrorCode, type CiResult, type CiRunCancellation, type CiStreamEvent, type CiStreamPage, type ClientDomains, type ClientFetch, type ClientOperationDefinition, type ClientOperationId, type ClientOperationInput, type ClientOperationMap, type ClientOperationOutput, type ClientSdkClient, type ClientSdkEntrypoint, DEFAULT_FOLLOW_RUN_DEADLINE_MS, type DelegatedApplicationRuntime, type DelegatedApplicationRuntimeOptions, type DelegatedRuntimeState, type DirectTransportOptions, type EntityClient, type EntityCreateInput, type EntityDeleteInput, type EntityHttpDestination, type EntityHttpTransportOptions, type EntityListQuery, type EntityOperation, type EntityOperationResult, type EntityPage, type EntityProtocol, type EntityRequest, type EntityTransport, type EntityUpdateInput, type FederatedAuth, FederatedAuthError, type FederatedAuthErrorCode, type FederatedAuthOptions, type FederatedAuthState, type FederatedSessionIdentity, type FixedWorkflowClient, type FixedWorkflowClientOptions, type FollowRunOptions, type FollowRunSource, type IdempotencyKey, type JsonObject, type JsonValue, type KnowledgeQuery, type OperationExecutionOptions, type OperationRequest, type OperationSuccess, type OrganizationClient, type PortableResourceSchema, type ProxyAuthentication, type ProxyTransportOptions, type QueryFilter, type ResourceCapabilities, type ResourceClient, type ResourceCreateInput, type ResourceCreateRequest, type ResourceCursor, type ResourceDefinition, type ResourceError, type ResourceErrorCode, type ResourceFilter, type ResourceGetRequest, type ResourceId, type ResourceIdentityField, type ResourceJsonValue, type ResourceLifecycleInput, type ResourceLifecycleRequest, type ResourceListQuery, type ResourceListRequest, type ResourceListResult, type ResourceMutationInput, type ResourcePagination, type ResourcePaginationMode, type ResourceRecord, type ResourceRecordId, type ResourceRequestOptions, type ResourceResult, type ResourceRevision, type ResourceSort, type ResourceTransport, type ResourceTransportRequest, type ResourceUpdateRequest, type SearchQuery, type ServerSessionAuthOptions, type TypedOperationExecutor, type WorkflowInvokeTarget, clientOperationIds, clientSdkProtocolVersion, createClient, createDelegatedApplicationRuntime, createDirectTransport, createEntityHttpTransport, createEntityProtocol, createFederatedAuth, createFixedWorkflowClient, createProxyTransport, createResourceClient, createServerSessionAuth, followRun, isClientOperationId, nextStreamCursor };
892
+ export { type CiError, type CiErrorCode, type CiResult, type CiRunCancellation, type CiStreamEvent, type CiStreamPage, type ClientDomains, type ClientFetch, type ClientOperationDefinition, type ClientOperationId, type ClientOperationInput, type ClientOperationMap, type ClientOperationOutput, type ClientSdkClient, type ClientSdkEntrypoint, DEFAULT_FOLLOW_RUN_DEADLINE_MS, type DelegatedApplicationRuntime, type DelegatedApplicationRuntimeOptions, type DelegatedRuntimeState, type DirectTransportOptions, type EntityClient, type EntityCreateInput, type EntityDeleteInput, type EntityFileFieldWrite, type EntityFileValue, type EntityFileWrite, type EntityHttpDestination, type EntityHttpTransportOptions, type EntityListQuery, type EntityOperation, type EntityOperationResult, type EntityPage, type EntityProtocol, type EntityRequest, type EntityTransport, type EntityUpdateInput, type EntityUploadInput, type EntityUploadSlot, type FederatedAuth, FederatedAuthError, type FederatedAuthErrorCode, type FederatedAuthOptions, type FederatedAuthState, type FederatedSessionIdentity, type FixedWorkflowClient, type FixedWorkflowClientOptions, type FollowRunOptions, type FollowRunSource, type IdempotencyKey, type JsonObject, type JsonValue, type KnowledgeQuery, type OperationExecutionOptions, type OperationRequest, type OperationSuccess, type OrganizationClient, type PortableResourceSchema, type ProxyAuthentication, type ProxyTransportOptions, type QueryFilter, type ResourceCapabilities, type ResourceClient, type ResourceCreateInput, type ResourceCreateRequest, type ResourceCursor, type ResourceDefinition, type ResourceError, type ResourceErrorCode, type ResourceFilter, type ResourceGetRequest, type ResourceId, type ResourceIdentityField, type ResourceJsonValue, type ResourceLifecycleInput, type ResourceLifecycleRequest, type ResourceListQuery, type ResourceListRequest, type ResourceListResult, type ResourceMutationInput, type ResourcePagination, type ResourcePaginationMode, type ResourceRecord, type ResourceRecordId, type ResourceRequestOptions, type ResourceResult, type ResourceRevision, type ResourceSort, type ResourceTransport, type ResourceTransportRequest, type ResourceUpdateRequest, type SearchQuery, type ServerSessionAuthOptions, type TypedOperationExecutor, type WorkflowInvokeTarget, clientOperationIds, clientSdkProtocolVersion, createClient, createDelegatedApplicationRuntime, createDirectTransport, createEntityHttpTransport, createEntityProtocol, createFederatedAuth, createFixedWorkflowClient, createProxyTransport, createResourceClient, createServerSessionAuth, followRun, isClientOperationId, nextStreamCursor };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as parseMountPath, c as isClientOperationId, i as createHttpOperationTransport, n as createResourceClient, o as parseOriginUrl, r as createEntityProtocol, s as clientOperationIds, t as createEntityHttpTransport } from "./resources-BYm1KWAZ.js";
1
+ import { a as parseMountPath, c as isClientOperationId, i as createHttpOperationTransport, n as createResourceClient, o as parseOriginUrl, r as createEntityProtocol, s as clientOperationIds, t as createEntityHttpTransport } from "./resources-BP_TaCP6.js";
2
2
  const base64Url = (bytes) => {
3
3
  let binary = "";
4
4
  for (const byte of bytes) binary += String.fromCodePoint(byte);
@@ -7734,6 +7734,11 @@ const operationKey = {
7734
7734
  pattern: "^[\\w.-]{1,256}$",
7735
7735
  type: "string"
7736
7736
  };
7737
+ const uploadText = {
7738
+ maxLength: 255,
7739
+ minLength: 1,
7740
+ type: "string"
7741
+ };
7737
7742
  const requestSchema = (definition, operation, properties) => ({
7738
7743
  additionalProperties: false,
7739
7744
  properties: {
@@ -7792,6 +7797,11 @@ const createEntityProtocol = (definition) => {
7792
7797
  expectedRevision: identifier,
7793
7798
  id: identifier,
7794
7799
  idempotencyKey: operationKey
7800
+ }),
7801
+ requestSchema(definition, "upload", {
7802
+ field: uploadText,
7803
+ filename: uploadText,
7804
+ mimeType: uploadText
7795
7805
  })
7796
7806
  ]
7797
7807
  });
@@ -7819,7 +7829,8 @@ const createEntityProtocol = (definition) => {
7819
7829
  "rate_limited",
7820
7830
  "transport_error",
7821
7831
  "unauthenticated",
7822
- "unavailable"
7832
+ "unavailable",
7833
+ "upload_not_supported"
7823
7834
  ] },
7824
7835
  details: { type: "object" },
7825
7836
  message: { type: "string" },
@@ -7883,6 +7894,15 @@ const createEntityProtocol = (definition) => {
7883
7894
  required: [...record.required, "deletedAt"]
7884
7895
  }));
7885
7896
  const validatePage = ajv.compile(resultSchema(page));
7897
+ const validateUploadSlot = ajv.compile(resultSchema(objectSchema({
7898
+ headers: {
7899
+ additionalProperties: { type: "string" },
7900
+ type: "object"
7901
+ },
7902
+ method: { const: "PUT" },
7903
+ uploadId: identifier,
7904
+ url: identifier
7905
+ })));
7886
7906
  const coherentPage = (input) => {
7887
7907
  if (!validatePage(input)) return false;
7888
7908
  if (!input.ok) return true;
@@ -7894,7 +7914,8 @@ const createEntityProtocol = (definition) => {
7894
7914
  delete: validateDeleted,
7895
7915
  get: validateRecord,
7896
7916
  list: coherentPage,
7897
- update: validateRecord
7917
+ update: validateRecord,
7918
+ upload: validateUploadSlot
7898
7919
  };
7899
7920
  return {
7900
7921
  decodeRequest: (input) => {
@@ -7967,7 +7988,8 @@ const createCommonEntityClient = (options) => {
7967
7988
  delete: "delete",
7968
7989
  get: "get",
7969
7990
  list: "search",
7970
- update: "update"
7991
+ update: "update",
7992
+ upload: "upload"
7971
7993
  }[input.operation]] !== true) return {
7972
7994
  correlationId,
7973
7995
  error: {
@@ -8022,7 +8044,11 @@ const createCommonEntityClient = (options) => {
8022
8044
  update: (input) => execute({
8023
8045
  ...input,
8024
8046
  operation: "update"
8025
- })
8047
+ }),
8048
+ upload: (input, requestOptions) => execute({
8049
+ ...input,
8050
+ operation: "upload"
8051
+ }, requestOptions)
8026
8052
  };
8027
8053
  };
8028
8054
  const capabilityByOperation = {
@@ -8147,6 +8173,15 @@ const encode = (request) => {
8147
8173
  method: "POST",
8148
8174
  path: `/records/${encodeURIComponent(request.id)}/soft-delete`
8149
8175
  };
8176
+ case "upload": return {
8177
+ body: JSON.stringify({
8178
+ field: request.field,
8179
+ filename: request.filename,
8180
+ mimeType: request.mimeType
8181
+ }),
8182
+ method: "POST",
8183
+ path: "/uploads"
8184
+ };
8150
8185
  }
8151
8186
  };
8152
8187
  const createEntityHttpTransport = (options) => {
@@ -376,7 +376,25 @@ interface MemberUserPage {
376
376
  pageSize: number;
377
377
  totalItems: number;
378
378
  }
379
+ declare const storageFileIdBrand: unique symbol;
380
+ /** A durable private file of the application's Organization. */
381
+ type StorageFileId = string & Readonly<{
382
+ [storageFileIdBrand]: "StorageFileId";
383
+ }>;
384
+ /**
385
+ * One file of up to 10 MiB, base64-encoded. CI accepts the content types
386
+ * `application/pdf`, `image/jpeg` and `image/png`.
387
+ */
388
+ interface DurableFileUpload {
389
+ contentBase64: string;
390
+ contentType: string;
391
+ fileName: string;
392
+ sizeBytes: number;
393
+ }
379
394
  type ExternalApplicationServiceOperationRequest = {
395
+ input: DurableFileUpload;
396
+ operationId: "files_upload";
397
+ } | {
380
398
  input: {
381
399
  email: string;
382
400
  name: string;
@@ -420,7 +438,9 @@ type ExternalApplicationServiceOperationRequest = {
420
438
  interface UserCompanyLinks {
421
439
  entityIds: string[];
422
440
  }
423
- type ExternalApplicationServiceOperationSuccess = EnvelopeSuccess<"members_create_or_get", MemberUser & {
441
+ type ExternalApplicationServiceOperationSuccess = EnvelopeSuccess<"files_upload", {
442
+ storageFileId: StorageFileId;
443
+ }> | EnvelopeSuccess<"members_create_or_get", MemberUser & {
424
444
  outcome: MemberUserResolution;
425
445
  }> | EnvelopeSuccess<"members_get", MemberUser> | EnvelopeSuccess<"members_list", MemberUserPage> | EnvelopeSuccess<"members_update", MemberUser> | EnvelopeSuccess<"members_remove", {
426
446
  userId: string;
@@ -516,6 +536,8 @@ type ResourceCapabilities = Readonly<{
516
536
  search: true;
517
537
  softDelete?: boolean;
518
538
  update?: boolean;
539
+ /** File uploads for the File fields of a common entity resource. */
540
+ upload?: boolean;
519
541
  }>;
520
542
  type ResourcePaginationMode = "cursor" | "page";
521
543
  type PortableResourceSchema = Readonly<Record<string, ResourceJsonValue>>;
@@ -602,7 +624,9 @@ type ResourceListResult<Entity> = Readonly<{
602
624
  totalItems: number;
603
625
  totalPages: number;
604
626
  }>;
605
- type ResourceErrorCode = "capability_not_supported" | "conflict" | "forbidden" | "internal" | "invalid_request" | "not_found" | "rate_limited" | "transport_error" | "unauthenticated" | "unavailable";
627
+ type ResourceErrorCode = "capability_not_supported" | "conflict" | "forbidden" | "internal" | "invalid_request" | "not_found" | "rate_limited" | "transport_error" | "unauthenticated" | "unavailable" |
628
+ /** The CI Organization storage can not take a presigned File upload. */
629
+ "upload_not_supported";
606
630
  type ResourceError = Readonly<{
607
631
  code: ResourceErrorCode;
608
632
  /** Client-observed dispatch outcome; uncertainty never proves rollback. */
@@ -694,7 +718,7 @@ interface ResourceClient<Entity, Create = Entity, Update = Partial<Entity>> {
694
718
  readonly update: (input: ResourceMutationInput<Update>, options?: ResourceRequestOptions) => Promise<ResourceResult<ResourceRecord<Entity>>>;
695
719
  }
696
720
  /** Common entity operations. Generic resource lifecycle/cursor APIs remain separate. */
697
- type EntityOperation = "list" | "get" | "create" | "update" | "delete";
721
+ type EntityOperation = "list" | "get" | "create" | "update" | "delete" | "upload";
698
722
  type EntityListQuery = Omit<ResourceListQuery, "pagination" | "includeDeleted"> & Readonly<{
699
723
  pagination: Extract<ResourcePagination, {
700
724
  mode: "page";
@@ -710,6 +734,42 @@ type EntityUpdateInput<Patch> = ResourceMutationInput<Patch> & Readonly<{
710
734
  type EntityDeleteInput = ResourceLifecycleInput & Readonly<{
711
735
  idempotencyKey: IdempotencyKey;
712
736
  }>;
737
+ /** A File upload request for one File field of the entity schema. */
738
+ type EntityUploadInput = Readonly<{
739
+ field: string;
740
+ filename: string;
741
+ mimeType: string;
742
+ }>;
743
+ /** PUT the file bytes to `url` with `headers`; then write `{ upload: uploadId }`. */
744
+ type EntityUploadSlot = Readonly<{
745
+ headers: Readonly<Record<string, string>>;
746
+ method: "PUT";
747
+ uploadId: string;
748
+ url: string;
749
+ }>;
750
+ /** The read-time value of one file of a File field. */
751
+ type EntityFileValue = Readonly<{
752
+ id: string;
753
+ url: string;
754
+ filename: string;
755
+ mimeType: string | null;
756
+ size: number | null;
757
+ source: "managed" | "external_url";
758
+ }>;
759
+ /** `{ upload }` adds a File upload; `{ id }`, or a File value read before, keeps that file. */
760
+ type EntityFileWrite = Readonly<{
761
+ upload: string;
762
+ id?: never;
763
+ }> | Readonly<{
764
+ id: string;
765
+ upload?: never;
766
+ }>;
767
+ /**
768
+ * The write form of a File field key: one file or `null` for a single field,
769
+ * an ordered array for a multiple field, `null` removes every file. Omit the
770
+ * key to keep its files unchanged.
771
+ */
772
+ type EntityFileFieldWrite = EntityFileWrite | readonly EntityFileWrite[] | null;
713
773
  type EntityRequestIdentity = Readonly<{
714
774
  requestId: string;
715
775
  resourceId: string;
@@ -726,8 +786,10 @@ type EntityRequest<Create = unknown, Patch = unknown> = EntityRequestIdentity &
726
786
  operation: "update";
727
787
  }> & EntityUpdateInput<Patch>) | (Readonly<{
728
788
  operation: "delete";
729
- }> & EntityDeleteInput));
730
- type EntityOperationResult<Value, Operation extends EntityOperation> = Operation extends "list" ? EntityPage<Value> : ResourceRecord<Value>;
789
+ }> & EntityDeleteInput) | (Readonly<{
790
+ operation: "upload";
791
+ }> & EntityUploadInput));
792
+ type EntityOperationResult<Value, Operation extends EntityOperation> = Operation extends "list" ? EntityPage<Value> : Operation extends "upload" ? EntityUploadSlot : ResourceRecord<Value>;
731
793
  /** Codecs return safe typed failures without coercing values or performing I/O. */
732
794
  type EntityProtocol<Value, Create = Value, Patch = Partial<Value>> = Readonly<{
733
795
  decodeRequest: (input: unknown) => ResourceResult<EntityRequest<Create, Patch>>;
@@ -746,6 +808,8 @@ interface EntityClient<Value, Create = Value, Patch = Partial<Value>> {
746
808
  readonly create: (input: EntityCreateInput<Create>) => Promise<ResourceResult<ResourceRecord<Value>>>;
747
809
  readonly update: (input: EntityUpdateInput<Patch>) => Promise<ResourceResult<ResourceRecord<Value>>>;
748
810
  readonly delete: (input: EntityDeleteInput) => Promise<ResourceResult<ResourceRecord<Value>>>;
811
+ /** A single-use File upload slot; requires the `upload` capability. */
812
+ readonly upload: (input: EntityUploadInput, options?: ResourceRequestOptions) => Promise<ResourceResult<EntityUploadSlot>>;
749
813
  }
750
814
  type ClientOptions<Value, Create, Patch> = Readonly<{
751
815
  definition: ResourceDefinition<Value, Create, Patch>;
@@ -775,4 +839,4 @@ type EntityHttpTransportOptions = Readonly<{
775
839
  fetch?: ClientFetch;
776
840
  }>;
777
841
  declare const createEntityHttpTransport: (options: EntityHttpTransportOptions) => EntityTransport;
778
- export { CiErrorCode as $, ResourceIdentityField as A, ResourceRecord as B, ResourceCursor as C, FederatedAuthError as Ct, ResourceFilter as D, FederatedSessionIdentity as Dt, ResourceErrorCode as E, FederatedAuthState as Et, ResourceListRequest as F, ResourceSort as G, ResourceRequestOptions as H, ResourceListResult as I, ResourceUpdateRequest as J, ResourceTransport as K, ResourceMutationInput as L, ResourceLifecycleInput as M, ResourceLifecycleRequest as N, ResourceGetRequest as O, createFederatedAuth as Ot, ResourceListQuery as P, CiError as Q, ResourcePagination as R, ResourceCreateRequest as S, FederatedAuth as St, ResourceError as T, FederatedAuthOptions as Tt, ResourceResult as U, ResourceRecordId as V, ResourceRevision as W, ProxyTransportOptions as X, ProxyAuthentication as Y, createProxyTransport as Z, IdempotencyKey as _, KnowledgeQuery as _t, createResourceClient as a, ClientOperationId as at, ResourceClient as b, WorkflowInvokeTarget as bt, EntityDeleteInput as c, ClientOperationOutput as ct, EntityOperationResult as d, clientOperationIds as dt, CiResult as et, EntityPage as f, isClientOperationId as ft, EntityUpdateInput as g, JsonObject as gt, EntityTransport as h, ConversationHistory as ht, createEntityProtocol as i, ClientOperationDefinition as it, ResourceJsonValue as j, ResourceId as k, EntityListQuery as l, OperationExecutionOptions as lt, EntityRequest as m, ConversationContinueTarget as mt, EntityHttpTransportOptions as n, OperationRequest as nt, EntityClient as o, ClientOperationInput as ot, EntityProtocol as p, AgentInvokeTarget as pt, ResourceTransportRequest as q, createEntityHttpTransport as r, OperationSuccess as rt, EntityCreateInput as s, ClientOperationMap as st, EntityHttpDestination as t, JsonValue as tt, EntityOperation as u, TypedOperationExecutor as ut, PortableResourceSchema as v, QueryFilter as vt, ResourceDefinition as w, FederatedAuthErrorCode as wt, ResourceCreateInput as x, ClientFetch as xt, ResourceCapabilities as y, SearchQuery as yt, ResourcePaginationMode as z };
842
+ export { ResourceUpdateRequest as $, ResourceError as A, FederatedAuthOptions as At, ResourceListRequest as B, PortableResourceSchema as C, QueryFilter as Ct, ResourceCreateRequest as D, FederatedAuth as Dt, ResourceCreateInput as E, ClientFetch as Et, ResourceIdentityField as F, ResourceRecord as G, ResourceMutationInput as H, ResourceJsonValue as I, ResourceResult as J, ResourceRecordId as K, ResourceLifecycleInput as L, ResourceFilter as M, FederatedSessionIdentity as Mt, ResourceGetRequest as N, createFederatedAuth as Nt, ResourceCursor as O, FederatedAuthError as Ot, ResourceId as P, ResourceTransportRequest as Q, ResourceLifecycleRequest as R, IdempotencyKey as S, KnowledgeQuery as St, ResourceClient as T, WorkflowInvokeTarget as Tt, ResourcePagination as U, ResourceListResult as V, ResourcePaginationMode as W, ResourceSort as X, ResourceRevision as Y, ResourceTransport as Z, EntityRequest as _, isClientOperationId as _t, createResourceClient as a, CiResult as at, EntityUploadInput as b, ConversationHistory as bt, EntityDeleteInput as c, OperationSuccess as ct, EntityFileWrite as d, ClientOperationInput as dt, ProxyAuthentication as et, EntityListQuery as f, ClientOperationMap as ft, EntityProtocol as g, clientOperationIds as gt, EntityPage as h, TypedOperationExecutor as ht, createEntityProtocol as i, CiErrorCode as it, ResourceErrorCode as j, FederatedAuthState as jt, ResourceDefinition as k, FederatedAuthErrorCode as kt, EntityFileFieldWrite as l, ClientOperationDefinition as lt, EntityOperationResult as m, OperationExecutionOptions as mt, EntityHttpTransportOptions as n, createProxyTransport as nt, EntityClient as o, JsonValue as ot, EntityOperation as p, ClientOperationOutput as pt, ResourceRequestOptions as q, createEntityHttpTransport as r, CiError as rt, EntityCreateInput as s, OperationRequest as st, EntityHttpDestination as t, ProxyTransportOptions as tt, EntityFileValue as u, ClientOperationId as ut, EntityTransport as v, AgentInvokeTarget as vt, ResourceCapabilities as w, SearchQuery as wt, EntityUploadSlot as x, JsonObject as xt, EntityUpdateInput as y, ConversationContinueTarget as yt, ResourceListQuery as z };
@@ -1,2 +1,2 @@
1
- import { A as ResourceIdentityField, B as ResourceRecord, C as ResourceCursor, D as ResourceFilter, E as ResourceErrorCode, F as ResourceListRequest, G as ResourceSort, H as ResourceRequestOptions, I as ResourceListResult, J as ResourceUpdateRequest, K as ResourceTransport, L as ResourceMutationInput, M as ResourceLifecycleInput, N as ResourceLifecycleRequest, O as ResourceGetRequest, P as ResourceListQuery, R as ResourcePagination, S as ResourceCreateRequest, T as ResourceError, U as ResourceResult, V as ResourceRecordId, W as ResourceRevision, _ as IdempotencyKey, a as createResourceClient, b as ResourceClient, c as EntityDeleteInput, d as EntityOperationResult, f as EntityPage, g as EntityUpdateInput, h as EntityTransport, i as createEntityProtocol, j as ResourceJsonValue, k as ResourceId, l as EntityListQuery, m as EntityRequest, n as EntityHttpTransportOptions, o as EntityClient, p as EntityProtocol, q as ResourceTransportRequest, r as createEntityHttpTransport, s as EntityCreateInput, t as EntityHttpDestination, u as EntityOperation, v as PortableResourceSchema, w as ResourceDefinition, x as ResourceCreateInput, y as ResourceCapabilities, z as ResourcePaginationMode } from "./resources-D95LlDMa.js";
2
- export { type EntityClient, type EntityCreateInput, type EntityDeleteInput, type EntityHttpDestination, type EntityHttpTransportOptions, type EntityListQuery, type EntityOperation, type EntityOperationResult, type EntityPage, type EntityProtocol, type EntityRequest, type EntityTransport, type EntityUpdateInput, type IdempotencyKey, type PortableResourceSchema, type ResourceCapabilities, type ResourceClient, type ResourceCreateInput, type ResourceCreateRequest, type ResourceCursor, type ResourceDefinition, type ResourceError, type ResourceErrorCode, type ResourceFilter, type ResourceGetRequest, type ResourceId, type ResourceIdentityField, type ResourceJsonValue, type ResourceLifecycleInput, type ResourceLifecycleRequest, type ResourceListQuery, type ResourceListRequest, type ResourceListResult, type ResourceMutationInput, type ResourcePagination, type ResourcePaginationMode, type ResourceRecord, type ResourceRecordId, type ResourceRequestOptions, type ResourceResult, type ResourceRevision, type ResourceSort, type ResourceTransport, type ResourceTransportRequest, type ResourceUpdateRequest, createEntityHttpTransport, createEntityProtocol, createResourceClient };
1
+ import { $ as ResourceUpdateRequest, A as ResourceError, B as ResourceListRequest, C as PortableResourceSchema, D as ResourceCreateRequest, E as ResourceCreateInput, F as ResourceIdentityField, G as ResourceRecord, H as ResourceMutationInput, I as ResourceJsonValue, J as ResourceResult, K as ResourceRecordId, L as ResourceLifecycleInput, M as ResourceFilter, N as ResourceGetRequest, O as ResourceCursor, P as ResourceId, Q as ResourceTransportRequest, R as ResourceLifecycleRequest, S as IdempotencyKey, T as ResourceClient, U as ResourcePagination, V as ResourceListResult, W as ResourcePaginationMode, X as ResourceSort, Y as ResourceRevision, Z as ResourceTransport, _ as EntityRequest, a as createResourceClient, b as EntityUploadInput, c as EntityDeleteInput, d as EntityFileWrite, f as EntityListQuery, g as EntityProtocol, h as EntityPage, i as createEntityProtocol, j as ResourceErrorCode, k as ResourceDefinition, l as EntityFileFieldWrite, m as EntityOperationResult, n as EntityHttpTransportOptions, o as EntityClient, p as EntityOperation, q as ResourceRequestOptions, r as createEntityHttpTransport, s as EntityCreateInput, t as EntityHttpDestination, u as EntityFileValue, v as EntityTransport, w as ResourceCapabilities, x as EntityUploadSlot, y as EntityUpdateInput, z as ResourceListQuery } from "./resources-DxMBAy-Z.js";
2
+ export { type EntityClient, type EntityCreateInput, type EntityDeleteInput, type EntityFileFieldWrite, type EntityFileValue, type EntityFileWrite, type EntityHttpDestination, type EntityHttpTransportOptions, type EntityListQuery, type EntityOperation, type EntityOperationResult, type EntityPage, type EntityProtocol, type EntityRequest, type EntityTransport, type EntityUpdateInput, type EntityUploadInput, type EntityUploadSlot, type IdempotencyKey, type PortableResourceSchema, type ResourceCapabilities, type ResourceClient, type ResourceCreateInput, type ResourceCreateRequest, type ResourceCursor, type ResourceDefinition, type ResourceError, type ResourceErrorCode, type ResourceFilter, type ResourceGetRequest, type ResourceId, type ResourceIdentityField, type ResourceJsonValue, type ResourceLifecycleInput, type ResourceLifecycleRequest, type ResourceListQuery, type ResourceListRequest, type ResourceListResult, type ResourceMutationInput, type ResourcePagination, type ResourcePaginationMode, type ResourceRecord, type ResourceRecordId, type ResourceRequestOptions, type ResourceResult, type ResourceRevision, type ResourceSort, type ResourceTransport, type ResourceTransportRequest, type ResourceUpdateRequest, createEntityHttpTransport, createEntityProtocol, createResourceClient };
package/dist/resources.js CHANGED
@@ -1,2 +1,2 @@
1
- import { n as createResourceClient, r as createEntityProtocol, t as createEntityHttpTransport } from "./resources-BYm1KWAZ.js";
1
+ import { n as createResourceClient, r as createEntityProtocol, t as createEntityHttpTransport } from "./resources-BP_TaCP6.js";
2
2
  export { createEntityHttpTransport, createEntityProtocol, createResourceClient };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@collective-intelligence/external-apps-client-sdk",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Framework-neutral client for Collective Intelligence external applications.",
5
5
  "type": "module",
6
6
  "sideEffects": false,