@collective-intelligence/external-apps-server-sdk 0.1.9 → 0.1.11
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 +131 -39
- package/dist/admin.d.ts +537 -319
- package/dist/admin.js +1 -1
- package/dist/auth/better-auth.d.ts +4 -2
- package/dist/auth/federated.d.ts +17 -7
- package/dist/auth/federated.js +1 -1
- package/dist/auth.d.ts +3 -1
- package/dist/express.d.ts +15 -2
- package/dist/gateway/contracts.d.ts +15 -2
- package/dist/gateway.d.ts +15 -2
- package/dist/gateway.js +2 -2
- package/dist/index.d.ts +232 -73
- package/dist/index.js +3 -3
- package/dist/knowledge-sources/payload.d.ts +23 -2
- package/dist/knowledge-sources/strapi.d.ts +23 -2
- package/dist/persistence/drizzle.d.ts +43 -4
- package/dist/persistence/drizzle.js +4 -4
- package/dist/resources.d.ts +39 -5
- package/dist/resources.js +3 -3
- package/dist/runtime/effect.d.ts +93 -5
- package/dist/runtime/effect.js +4 -4
- package/dist/runtime/express.d.ts +15 -2
- package/dist/runtime/nestjs.d.ts +36 -5
- package/dist/runtime/nestjs.js +2 -2
- package/dist/runtime/next.d.ts +37 -6
- package/dist/runtime/next.js +2 -2
- package/dist/runtime/web.d.ts +19 -4
- package/dist/runtime/web.js +2 -2
- package/dist/tools/ai-sdk.js +2 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -503,47 +503,41 @@ const sent = await ci.messages.send({
|
|
|
503
503
|
reached its rate limit; it is retryable, and the client repeats it with the
|
|
504
504
|
same key.
|
|
505
505
|
|
|
506
|
-
##
|
|
506
|
+
## Application users and roles
|
|
507
507
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
one the credentials were authorized for through `organizationId`; a request
|
|
512
|
-
cannot reach another Organization.
|
|
508
|
+
Use `ci.users` and `ci.roles` with a delegated user token or service
|
|
509
|
+
credentials. CI checks the caller's current `users.create` and `assignRoles`
|
|
510
|
+
permissions. These methods replace the former `ci.members` API.
|
|
513
511
|
|
|
514
512
|
```ts
|
|
515
|
-
const
|
|
516
|
-
authentication: { credentials, mode: "service" },
|
|
517
|
-
tenantUrl
|
|
518
|
-
})
|
|
519
|
-
|
|
520
|
-
const created = await ci.members.createOrGet({
|
|
513
|
+
const created = await ci.users.createOrGet({
|
|
521
514
|
email: "info@rossi.example",
|
|
522
515
|
name: "Rossi Srl",
|
|
523
|
-
organizationId
|
|
516
|
+
organizationId,
|
|
517
|
+
roles: ["patient"],
|
|
518
|
+
serverRole: "onboarding" // Optional for service calls; omission uses the credential default.
|
|
524
519
|
})
|
|
525
|
-
// created.value.result
|
|
520
|
+
// On success: created.value.result = { userId, email, name, created, kind }
|
|
521
|
+
// kind is "member" or "external_app_user".
|
|
526
522
|
```
|
|
527
523
|
|
|
528
|
-
- `createOrGet`
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
- `
|
|
536
|
-
`
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
- Only `temporarily_unavailable` is retryable (the client retries it); a
|
|
546
|
-
creation CI refuses is a non-retryable `internal_error`.
|
|
524
|
+
- `createOrGet` reuses the person's auth identity. A new app user has no
|
|
525
|
+
Organization membership. An existing member remains a member.
|
|
526
|
+
- `get({ organizationId, userId })` and
|
|
527
|
+
`list({ organizationId, page?, pageSize? })` read users accessible to this
|
|
528
|
+
app. A list result contains `items`.
|
|
529
|
+
- `deactivate({ organizationId, userId })` ends access to the calling app for
|
|
530
|
+
an app user it may deactivate; it does not remove Organization membership.
|
|
531
|
+
- `roles.list({ organizationId })` returns `items` with role `id` and `key`.
|
|
532
|
+
`roles.assign({ organizationId, userId, roles })` and `roles.revoke(...)`
|
|
533
|
+
change this app's assignments within the caller's `assignRoles` permission.
|
|
534
|
+
They cannot write Organization Roles, Groups, or another app's roles.
|
|
535
|
+
- Pass `serverRole` on a service request to select an allowed Server Role via
|
|
536
|
+
`x-external-server-role`. It applies only to that request; credentials and
|
|
537
|
+
subsequent calls retain their default. It does not impersonate a user.
|
|
538
|
+
- Refusals preserve the structured error, including a reason such as
|
|
539
|
+
`role_not_assignable`. Non-retryable refusals are returned without retrying.
|
|
540
|
+
CI records the actual user, or application and Server Role, as the actor.
|
|
547
541
|
|
|
548
542
|
## Durable files
|
|
549
543
|
|
|
@@ -579,6 +573,79 @@ await ci.workflows.invoke({
|
|
|
579
573
|
- It needs the `ai:attachments` scope. Only service credentials may call it: a
|
|
580
574
|
delegated user token or an anonymous visitor gets `operation_not_allowed`.
|
|
581
575
|
|
|
576
|
+
### Entity File fields
|
|
577
|
+
|
|
578
|
+
A File field of an entity schema takes a different flow: the file becomes a
|
|
579
|
+
File value of the entity, not a stored file a workflow reads.
|
|
580
|
+
`resources.createUpload` asks CI for a single-use upload slot, the server PUTs
|
|
581
|
+
the bytes straight to storage, and the entity write through CI's resources API
|
|
582
|
+
names the slot's `uploadId` as `{ upload }` for that File field key:
|
|
583
|
+
|
|
584
|
+
```ts
|
|
585
|
+
const slot = await ci.resources.createUpload({
|
|
586
|
+
field: "memberLogo",
|
|
587
|
+
filename: "logo.png",
|
|
588
|
+
mimeType: "image/png",
|
|
589
|
+
organizationId,
|
|
590
|
+
schemaId: "apito.vetrina.schemas.member-company"
|
|
591
|
+
})
|
|
592
|
+
if (slot.ok) {
|
|
593
|
+
const { headers, method, uploadId, url } = slot.value.result
|
|
594
|
+
await fetch(url, { body: logo, headers, method })
|
|
595
|
+
// The entity write then sends { memberLogo: { upload: uploadId } }.
|
|
596
|
+
}
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
- Two credentials can ask for a slot, as for entity writes: the member's
|
|
600
|
+
delegated token (`exchangeMemberSession`), writing as that member; or the
|
|
601
|
+
application's service credential, for schemas declared by the application's
|
|
602
|
+
own package only, writing as the Organization default service principal.
|
|
603
|
+
`schemaId` is the schema id or FQN.
|
|
604
|
+
- A refusal resolves `{ ok: false, error }` with CI's `correlationId` and a
|
|
605
|
+
`code`; `upload_not_supported` means the Organization storage cannot presign
|
|
606
|
+
uploads. Only `retryable` failures are retried.
|
|
607
|
+
- Each attempt, request and response body, is bounded by `timeoutMs`
|
|
608
|
+
(10 seconds by default); a CI that stops answering ends in a retryable
|
|
609
|
+
`unavailable`. `signal` cancels: a cancelled request rejects with the
|
|
610
|
+
signal's reason.
|
|
611
|
+
- The PUT is the caller's: send exactly `headers` to `url` with `method`. No
|
|
612
|
+
file bytes pass through CI's API. A slot is single use: the first successful
|
|
613
|
+
write consumes it; request a new one to retry.
|
|
614
|
+
- The write form of a File field key is `{ upload }` to add the uploaded file,
|
|
615
|
+
`{ id }` (or a File value read before) to keep a file, an ordered array for a
|
|
616
|
+
multiple field, or `null` to remove every file. Omit the key to keep its
|
|
617
|
+
files.
|
|
618
|
+
- `/runtime/effect` exports the Effect schemas `EntityFileValue` (a File value
|
|
619
|
+
as CI reads return it), `EntityFileWrite` (one file of a write) and
|
|
620
|
+
`EntityFileFieldWrite` (the write form of a File field key). Their types
|
|
621
|
+
equal the client SDK types of the same name. They validate CI entity
|
|
622
|
+
values; a portable resource form has no File field, so
|
|
623
|
+
`projectResourceSchema` refuses them.
|
|
624
|
+
|
|
625
|
+
## Runtime origin
|
|
626
|
+
|
|
627
|
+
The browser origins of an Organization are the `allowedOrigins` that its
|
|
628
|
+
installed applications declare, plus one runtime origin per application. A
|
|
629
|
+
confidential application sets its runtime origin, for example the URL of each
|
|
630
|
+
new deployment; CI keeps storage CORS in line with the Organization origins, so
|
|
631
|
+
a browser on that origin can upload to a presigned storage URL.
|
|
632
|
+
|
|
633
|
+
```ts
|
|
634
|
+
await ci.origins.setRuntime({
|
|
635
|
+
organizationId,
|
|
636
|
+
origin: `https://${process.env.VERCEL_URL}`
|
|
637
|
+
})
|
|
638
|
+
// value.result: { origin }
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
- Each call replaces the application's previous runtime origin, so the list
|
|
642
|
+
does not grow; declare stable origins, such as the production site, in
|
|
643
|
+
`allowedOrigins`.
|
|
644
|
+
- `origin` is an exact HTTPS origin (`https://host[:port]`, no path), or a
|
|
645
|
+
loopback HTTP origin with a port; other values get `invalid_request`.
|
|
646
|
+
- It needs the `origins:write` scope. Only service credentials may call it: a
|
|
647
|
+
delegated user token or an anonymous visitor gets `operation_not_allowed`.
|
|
648
|
+
|
|
582
649
|
## Member company links
|
|
583
650
|
|
|
584
651
|
An application links a member of its Organization to the Knowledge company
|
|
@@ -1146,8 +1213,12 @@ const handle = createResourceHttpHandler({
|
|
|
1146
1213
|
|
|
1147
1214
|
`auth` is the existing `createFederatedAuth(...)` instance. Its server-only
|
|
1148
1215
|
`getEntityContext` resolves current CI application, user, organization, scopes,
|
|
1149
|
-
roles and
|
|
1150
|
-
|
|
1216
|
+
the user's effective app roles and App Permissions. CI never sends Group IDs or
|
|
1217
|
+
Platform Permissions. The browser session JSON at `<basePath>/session` carries
|
|
1218
|
+
`expiresAt` and an `identity` with `userId`, `organizationId`, `appId`, `kind`
|
|
1219
|
+
(`member` or `external_app_user`), `roles`, `appPermissions`, `email` and
|
|
1220
|
+
`name`; it never carries the Access token. A user without a role on the app has
|
|
1221
|
+
no session and no entity access. Local Better Auth sessions do
|
|
1151
1222
|
not establish CI entity authority. Browser framework adapters require this
|
|
1152
1223
|
verified context instead of boolean authorization. Machine gateway calls retain
|
|
1153
1224
|
their separate caller policy.
|
|
@@ -1343,8 +1414,9 @@ A renewal applies the same admission rule as `/oauth/identity`:
|
|
|
1343
1414
|
|
|
1344
1415
|
- the external Application is enabled;
|
|
1345
1416
|
- the CI session is live;
|
|
1346
|
-
- the user is not banned
|
|
1347
|
-
|
|
1417
|
+
- the user is not banned, is a member or an active External App User of the
|
|
1418
|
+
Organization, and holds at least one role on the app other than
|
|
1419
|
+
`anonymous` (Direct Role Assignments replace the roles that Groups give);
|
|
1348
1420
|
- the scopes of the sign-in are still allowed.
|
|
1349
1421
|
|
|
1350
1422
|
A refusal ends nothing. When the condition is corrected, the same Renewal
|
|
@@ -1426,7 +1498,7 @@ const caller = await tokens.verify(bearerToken)
|
|
|
1426
1498
|
// userId, organizationId, applicationId, clientId, scopes, sessionId, expiresAt
|
|
1427
1499
|
|
|
1428
1500
|
const identity = await tokens.identity(bearerToken, { signal: request.signal })
|
|
1429
|
-
// the same fields, and user { id, email, name }, roles,
|
|
1501
|
+
// the same fields, and user { id, email, name }, kind, roles, appPermissions
|
|
1430
1502
|
```
|
|
1431
1503
|
|
|
1432
1504
|
- `verify` is offline against the issuer key set: ES256 signature, issuer,
|
|
@@ -1434,7 +1506,8 @@ const identity = await tokens.identity(bearerToken, { signal: request.signal })
|
|
|
1434
1506
|
It does not see a revocation before the token expires.
|
|
1435
1507
|
- `identity` runs `verify`, then reads CI's current identity for the token and
|
|
1436
1508
|
checks that it describes the same grant. Use it when the API needs the
|
|
1437
|
-
user's roles or
|
|
1509
|
+
user's app roles or App Permissions, or must stop at once when CI revokes
|
|
1510
|
+
the token or a role. It
|
|
1438
1511
|
is one CI request for each call, with a 10-second limit; cache the result
|
|
1439
1512
|
for as long as a role change may take to reach your API. Pass the `signal`
|
|
1440
1513
|
of the request you serve: when it aborts, the CI request ends and the call
|
|
@@ -1562,3 +1635,22 @@ values use `soft_delete` and `hard_delete`, and gateway principal kinds use
|
|
|
1562
1635
|
`detached_user` and `service_principal`. Public method and capability property
|
|
1563
1636
|
names such as `softDelete` remain unchanged. External HTTP, OAuth, JSON Schema
|
|
1564
1637
|
and provider values retain their required spelling at their adapter boundaries.
|
|
1638
|
+
|
|
1639
|
+
### CI relation-member reads
|
|
1640
|
+
|
|
1641
|
+
CI-backed resources created by `defineCiEntityResource` accept the common client
|
|
1642
|
+
`listMembers(parentId, field, query, { signal })` operation. The shared Fetch handler
|
|
1643
|
+
mounts `POST /records/:parentId/relation-members/search` below the resource base
|
|
1644
|
+
path and forwards `{ field, ...query }` to the bound CI schema route. Existing
|
|
1645
|
+
verified tenant, organization, resource and user-grant checks still apply;
|
|
1646
|
+
`authorizeWithUserAuth` classifies this operation under `readScope`.
|
|
1647
|
+
|
|
1648
|
+
The page envelope and exact totals remain unchanged. Member records are JSON
|
|
1649
|
+
objects validated independently of the parent schema, as are member query field
|
|
1650
|
+
names; CI resolves and authorizes the actual member schema. Abort signals and
|
|
1651
|
+
correlation IDs pass through the proxy. All four typed read-limit metrics
|
|
1652
|
+
(`work`, `nodes`, `relation_ids`, `bytes`) retain `invalid_request` details
|
|
1653
|
+
`{ reason: "read_limit_exceeded", budget }` and rejected read outcomes. Local
|
|
1654
|
+
`defineEntityResource` repositories have no CI relation resolver and return
|
|
1655
|
+
`capability_not_supported`; the legacy CRUD facade does not expose this route.
|
|
1656
|
+
See the client SDK README for complete IDs, bounded includes and narrowing guidance.
|