@nsp-labs/agnostic-sdk 1.0.4 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +67 -0
- package/README.md +100 -6
- package/package.json +1 -1
- package/src/generated/openapi.d.ts +829 -0
- package/src/index.d.ts +3 -2
- package/src/index.js +6 -1
- package/src/lib/manifest.d.ts +41 -0
- package/src/lib/manifest.js +117 -0
- package/src/lib/runtime-client.d.ts +27 -1
- package/src/lib/runtime-client.js +124 -6
- package/src/lib/types.d.ts +93 -0
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,73 @@ and pass the runtime OpenAPI schema check.
|
|
|
9
9
|
|
|
10
10
|
## Unreleased
|
|
11
11
|
|
|
12
|
+
## 1.4.0 - 2026-09-02
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- Added `data.table(name).records.aggregate(...)` for bounded server-side
|
|
17
|
+
`count`, `sum`, `avg`, `min`, and `max` queries with filters, search, up to
|
|
18
|
+
two grouping dimensions, ordering, and a capped result size.
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- Regenerated the Runtime OpenAPI client with the backwards-compatible Data
|
|
23
|
+
aggregate endpoint. The runtime identity remains the only source of project
|
|
24
|
+
and environment scope.
|
|
25
|
+
|
|
26
|
+
## 1.3.0 - 2026-08-12
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- Added `storage.bucket(name).createUpload`, `completeUpload`, `get`,
|
|
31
|
+
`createDownloadUrl`, and `delete` with project/environment/runtime-owner
|
|
32
|
+
binding and stable Files errors.
|
|
33
|
+
- Added the canonical `files.read`, `files.write`, `files.delete`, and
|
|
34
|
+
`files.links.create` Runtime API capability mapping.
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
- Regenerated the Runtime OpenAPI client for the complete Files facade while
|
|
39
|
+
keeping provider bucket names, object keys, and credentials outside public
|
|
40
|
+
types.
|
|
41
|
+
- Bumped the compatible server-only SDK contract to `1.3.0`; existing runtime
|
|
42
|
+
paths remain backwards compatible.
|
|
43
|
+
|
|
44
|
+
## 1.2.0 - 2026-08-10
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
|
|
48
|
+
- Added the server-only
|
|
49
|
+
`storage.bucket(name).anonymousUploads.claim(...)` helper and its Runtime API
|
|
50
|
+
schema for idempotent anonymous session claim with ready/processing handles.
|
|
51
|
+
|
|
52
|
+
### Changed
|
|
53
|
+
|
|
54
|
+
- Clarified in the exported Runtime SDK manifest that App Auth self-service
|
|
55
|
+
profile mutations use the public App Auth API through the project backend/BFF;
|
|
56
|
+
they are not runtime-token mutations and do not expand the callable SDK
|
|
57
|
+
surface.
|
|
58
|
+
- Generated the runtime OpenAPI layer with the backwards-compatible Files claim
|
|
59
|
+
endpoint; existing Runtime API paths are unchanged.
|
|
60
|
+
|
|
61
|
+
## 1.1.0 - 2026-07-26
|
|
62
|
+
|
|
63
|
+
### Added
|
|
64
|
+
|
|
65
|
+
- Added an exact public-surface drift guard and a deterministic manifest
|
|
66
|
+
fingerprint so Agent codegen can re-read the installed SDK contract on every
|
|
67
|
+
generation step instead of relying on a copied namespace list.
|
|
68
|
+
- Added `auth.getSession()` for optional App Auth sessions and
|
|
69
|
+
`auth.requireScopes()` for application-level scope guardrails after session
|
|
70
|
+
verification.
|
|
71
|
+
|
|
72
|
+
### Changed
|
|
73
|
+
|
|
74
|
+
- Runtime SDK manifest consumers can now derive scaffold versions, Agent review
|
|
75
|
+
allowlists, and source-write deny rules from the exported package contract.
|
|
76
|
+
The runtime OpenAPI schema is unchanged; the callable SDK surface adds only
|
|
77
|
+
the backwards-compatible App Auth helpers listed above.
|
|
78
|
+
|
|
12
79
|
## 1.0.4 - 2026-06-18
|
|
13
80
|
|
|
14
81
|
### Changed
|
package/README.md
CHANGED
|
@@ -36,7 +36,8 @@ Runtime tokens are server-side credentials. Do not put
|
|
|
36
36
|
`AGNOSTIC_RUNTIME_TOKEN` in browser, mobile, Vite, or static frontend bundles.
|
|
37
37
|
|
|
38
38
|
The current public runtime surface includes `auth`, `context`, `data`,
|
|
39
|
-
`workflows`, and `workflowRuns`.
|
|
39
|
+
`storage`, `workflows`, and `workflowRuns`. `storage.bucket(name)` supports the
|
|
40
|
+
server-side Files lifecycle and anonymous upload claim.
|
|
40
41
|
|
|
41
42
|
## App Auth
|
|
42
43
|
|
|
@@ -46,13 +47,33 @@ the incoming App Auth session through the runtime helper:
|
|
|
46
47
|
```ts
|
|
47
48
|
const session = await agnostic.auth.requireSession(request);
|
|
48
49
|
|
|
49
|
-
await agnostic.data
|
|
50
|
-
'
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
await agnostic.data
|
|
51
|
+
.table('orders')
|
|
52
|
+
.records.update(
|
|
53
|
+
'order_123',
|
|
54
|
+
{ values: { status: 'fulfilled' } },
|
|
55
|
+
{ actor: session.actor },
|
|
56
|
+
);
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Use `getSession(request)` for routes that support both guests and signed-in
|
|
60
|
+
users. It returns `null` when the request has no App Auth session:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
const session = await agnostic.auth.getSession(request);
|
|
54
64
|
```
|
|
55
65
|
|
|
66
|
+
Use `requireScopes(request, scopes)` for application-level scope guardrails.
|
|
67
|
+
This verifies the session first and throws `app_auth_scope_missing` when one of
|
|
68
|
+
the required app-user scopes is absent:
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
const session = await agnostic.auth.requireScopes(request, ['orders:write']);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Scope checks do not replace ownership or other business rules in the
|
|
75
|
+
application backend.
|
|
76
|
+
|
|
56
77
|
The helper extracts `Authorization: Bearer <app-session>` or an
|
|
57
78
|
`agnostic_app_session_*` cookie, then calls
|
|
58
79
|
`/api/v1/runtime/app-auth/session/verify` with the server-side runtime token.
|
|
@@ -60,6 +81,15 @@ It returns sanitized user/session claims and an `app_user` actor for audit
|
|
|
60
81
|
metadata. `agnostic.auth.getUser(userId)` reads sanitized App Auth user claims
|
|
61
82
|
for the same runtime project.
|
|
62
83
|
|
|
84
|
+
For a browser frontend and backend deployed on different hosts, login must use
|
|
85
|
+
the application backend/BFF. The BFF requests bearer mode from App Auth and
|
|
86
|
+
places the tokens in host-only HttpOnly cookies on its own host before calling
|
|
87
|
+
`requireSession(request)`. A host-only cookie set by `api.agn0.ru` is not sent
|
|
88
|
+
to an application backend host. Do not solve this with `Domain=.agn0.ru` or
|
|
89
|
+
browser token storage. For cross-origin frontend/backend pairs, return a
|
|
90
|
+
separate non-secret CSRF token from the BFF and validate it on state-changing
|
|
91
|
+
cookie-authenticated requests.
|
|
92
|
+
|
|
63
93
|
## Data
|
|
64
94
|
|
|
65
95
|
```ts
|
|
@@ -68,6 +98,17 @@ const orders = await agnostic.data.table('orders').records.list({
|
|
|
68
98
|
limit: 50,
|
|
69
99
|
});
|
|
70
100
|
|
|
101
|
+
const revenueByStatus = await agnostic.data.table('orders').records.aggregate({
|
|
102
|
+
filter: { currency: 'RUB' },
|
|
103
|
+
groupBy: ['status'],
|
|
104
|
+
metrics: [
|
|
105
|
+
{ operation: 'count', as: 'orders' },
|
|
106
|
+
{ operation: 'sum', field: 'amount', as: 'revenue' },
|
|
107
|
+
],
|
|
108
|
+
orderBy: [{ by: 'revenue', direction: 'desc' }],
|
|
109
|
+
limit: 20,
|
|
110
|
+
});
|
|
111
|
+
|
|
71
112
|
const created = await agnostic.data.table('orders').records.create({
|
|
72
113
|
values: {
|
|
73
114
|
customerId: 'cust_123',
|
|
@@ -82,6 +123,10 @@ await agnostic.data.table('orders').records.update(created.id, {
|
|
|
82
123
|
await agnostic.data.table('orders').records.delete(created.id);
|
|
83
124
|
```
|
|
84
125
|
|
|
126
|
+
Aggregate queries support `count`, `sum`, `avg`, `min`, and `max`. They are
|
|
127
|
+
executed by the data provider, allow at most two grouping fields, return at
|
|
128
|
+
most 100 groups, and require the existing `data.read` capability.
|
|
129
|
+
|
|
85
130
|
## Workflows
|
|
86
131
|
|
|
87
132
|
```ts
|
|
@@ -94,6 +139,55 @@ const finished = await agnostic.workflowRuns.wait(run.id, {
|
|
|
94
139
|
});
|
|
95
140
|
```
|
|
96
141
|
|
|
142
|
+
## Anonymous File Claim
|
|
143
|
+
|
|
144
|
+
After creating the business object, claim the anonymous upload session from the
|
|
145
|
+
application backend. Reuse the same `externalRef` and `idempotencyKey` for saga
|
|
146
|
+
retries:
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
const attachments = await agnostic.storage
|
|
150
|
+
.bucket('order-files')
|
|
151
|
+
.anonymousUploads.claim({
|
|
152
|
+
token: attachmentSessionToken,
|
|
153
|
+
externalRef: `order:${order.id}`,
|
|
154
|
+
idempotencyKey: `order:${order.id}`,
|
|
155
|
+
});
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
The runtime token and anonymous claim token must remain server-side. The result
|
|
159
|
+
contains server-selected `ready` or `processing` file handles; callers do not
|
|
160
|
+
submit file IDs.
|
|
161
|
+
|
|
162
|
+
## Files
|
|
163
|
+
|
|
164
|
+
```ts
|
|
165
|
+
const bucket = agnostic.storage.bucket('uploads');
|
|
166
|
+
const upload = await bucket.createUpload({
|
|
167
|
+
fileName: 'invoice.pdf',
|
|
168
|
+
contentType: 'application/pdf',
|
|
169
|
+
size: contents.byteLength,
|
|
170
|
+
checksumSha256,
|
|
171
|
+
access: 'private',
|
|
172
|
+
idempotencyKey: `invoice:${invoice.id}:v1`,
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
await fetch(upload.uploadUrl, {
|
|
176
|
+
method: 'PUT',
|
|
177
|
+
headers: upload.requiredHeaders,
|
|
178
|
+
body: contents,
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
const completed = await bucket.completeUpload(upload.id);
|
|
182
|
+
const file = await bucket.get(completed.file.id);
|
|
183
|
+
const download = await bucket.createDownloadUrl(file.id);
|
|
184
|
+
await bucket.delete(file.id);
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Reuse the same idempotency key and IDs when retrying. Keep the SDK and runtime
|
|
188
|
+
token server-side; only a short scoped upload/download URL may cross into a
|
|
189
|
+
browser after the application has authorized the request.
|
|
190
|
+
|
|
97
191
|
## Actor Metadata
|
|
98
192
|
|
|
99
193
|
After an application backend has verified its App Auth session and business
|
package/package.json
CHANGED