@tier0/sdk-v2 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/NOTICE.md +7 -0
- package/README.md +201 -2
- package/dist/cjs/app-identity-contract.generated.d.ts +22 -0
- package/dist/cjs/app-identity-contract.generated.js +51 -0
- package/dist/cjs/app-identity-contract.generated.js.map +1 -0
- package/dist/cjs/capabilities.d.ts +54 -0
- package/dist/cjs/capabilities.js +134 -0
- package/dist/cjs/capabilities.js.map +1 -0
- package/dist/cjs/client.d.ts +604 -0
- package/dist/cjs/client.js +35 -0
- package/dist/cjs/client.js.map +1 -0
- package/dist/cjs/cloud-server.d.ts +31 -0
- package/dist/cjs/cloud-server.js +114 -0
- package/dist/cjs/cloud-server.js.map +1 -0
- package/dist/cjs/cloud-transport.d.ts +46 -0
- package/dist/cjs/cloud-transport.js +192 -0
- package/dist/cjs/cloud-transport.js.map +1 -0
- package/dist/cjs/controls.d.ts +93 -0
- package/dist/cjs/controls.js +169 -0
- package/dist/cjs/controls.js.map +1 -0
- package/dist/cjs/data/bootstrap.d.ts +66 -0
- package/dist/cjs/data/bootstrap.js +282 -0
- package/dist/cjs/data/bootstrap.js.map +1 -0
- package/dist/cjs/data/call.d.ts +16 -0
- package/dist/cjs/data/call.js +51 -0
- package/dist/cjs/data/call.js.map +1 -0
- package/dist/cjs/data/client.d.ts +92 -0
- package/dist/cjs/data/client.js +102 -0
- package/dist/cjs/data/client.js.map +1 -0
- package/dist/cjs/data/collection.d.ts +238 -0
- package/dist/cjs/data/collection.js +441 -0
- package/dist/cjs/data/collection.js.map +1 -0
- package/dist/cjs/data/context.d.ts +10 -0
- package/dist/cjs/data/context.js +39 -0
- package/dist/cjs/data/context.js.map +1 -0
- package/dist/cjs/data/declarations.d.ts +11 -0
- package/dist/cjs/data/declarations.js +18 -0
- package/dist/cjs/data/declarations.js.map +1 -0
- package/dist/cjs/data/define.d.ts +69 -0
- package/dist/cjs/data/define.js +31 -0
- package/dist/cjs/data/define.js.map +1 -0
- package/dist/cjs/data/error.d.ts +60 -0
- package/dist/cjs/data/error.js +184 -0
- package/dist/cjs/data/error.js.map +1 -0
- package/dist/cjs/data/index.d.ts +21 -0
- package/dist/cjs/data/index.js +43 -0
- package/dist/cjs/data/index.js.map +1 -0
- package/dist/cjs/data/schema.d.ts +82 -0
- package/dist/cjs/data/schema.js +607 -0
- package/dist/cjs/data/schema.js.map +1 -0
- package/dist/cjs/data/sort.d.ts +8 -0
- package/dist/cjs/data/sort.js +21 -0
- package/dist/cjs/data/sort.js.map +1 -0
- package/dist/cjs/files.d.ts +67 -0
- package/dist/cjs/files.js +119 -0
- package/dist/cjs/files.js.map +1 -0
- package/dist/cjs/framework-scope.d.ts +1 -0
- package/dist/cjs/framework-scope.js +14 -0
- package/dist/cjs/framework-scope.js.map +1 -0
- package/dist/cjs/index.d.ts +14 -0
- package/dist/cjs/index.js +33 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/mq/broker.d.ts +65 -0
- package/dist/cjs/mq/broker.js +115 -0
- package/dist/cjs/mq/broker.js.map +1 -0
- package/dist/cjs/mq/client.d.ts +37 -0
- package/dist/cjs/mq/client.js +321 -0
- package/dist/cjs/mq/client.js.map +1 -0
- package/dist/cjs/mq/index.d.ts +5 -0
- package/dist/cjs/mq/index.js +11 -0
- package/dist/cjs/mq/index.js.map +1 -0
- package/dist/cjs/mq/types.d.ts +48 -0
- package/dist/cjs/mq/types.js +3 -0
- package/dist/cjs/mq/types.js.map +1 -0
- package/dist/cjs/openapi/api.generated.d.ts +820 -0
- package/dist/cjs/openapi/api.generated.js +607 -0
- package/dist/cjs/openapi/api.generated.js.map +1 -0
- package/dist/cjs/openapi/client.d.ts +56 -0
- package/dist/cjs/openapi/client.js +219 -0
- package/dist/cjs/openapi/client.js.map +1 -0
- package/dist/cjs/openapi/codecs.generated.d.ts +2234 -0
- package/dist/cjs/openapi/codecs.generated.js +6 -0
- package/dist/cjs/openapi/codecs.generated.js.map +1 -0
- package/dist/cjs/openapi/index.d.ts +5 -0
- package/dist/cjs/openapi/index.js +12 -0
- package/dist/cjs/openapi/index.js.map +1 -0
- package/dist/cjs/openapi/types.generated.d.ts +3227 -0
- package/dist/cjs/openapi/types.generated.js +3 -0
- package/dist/cjs/openapi/types.generated.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/react.d.ts +9 -0
- package/dist/cjs/react.js +16 -0
- package/dist/cjs/react.js.map +1 -0
- package/dist/cjs/runtime-context.d.ts +9 -0
- package/dist/cjs/runtime-context.js +25 -0
- package/dist/cjs/runtime-context.js.map +1 -0
- package/dist/cjs/runtime-env.d.ts +1 -0
- package/dist/cjs/runtime-env.js +18 -0
- package/dist/cjs/runtime-env.js.map +1 -0
- package/dist/cjs/source.d.ts +39 -0
- package/dist/cjs/source.js +29 -0
- package/dist/cjs/source.js.map +1 -0
- package/dist/cjs/stream.d.ts +40 -0
- package/dist/cjs/stream.js +33 -0
- package/dist/cjs/stream.js.map +1 -0
- package/dist/cjs/uns-v2/client.d.ts +54 -0
- package/dist/cjs/uns-v2/client.js +177 -0
- package/dist/cjs/uns-v2/client.js.map +1 -0
- package/dist/cjs/uns-v2/codec.d.ts +11 -0
- package/dist/cjs/uns-v2/codec.js +290 -0
- package/dist/cjs/uns-v2/codec.js.map +1 -0
- package/dist/cjs/uns-v2/data-client.d.ts +10 -0
- package/dist/cjs/uns-v2/data-client.js +18 -0
- package/dist/cjs/uns-v2/data-client.js.map +1 -0
- package/dist/cjs/uns-v2/generated.d.ts +15551 -0
- package/dist/cjs/uns-v2/generated.js +139 -0
- package/dist/cjs/uns-v2/generated.js.map +1 -0
- package/dist/cjs/uns-v2/index.d.ts +5 -0
- package/dist/cjs/uns-v2/index.js +24 -0
- package/dist/cjs/uns-v2/index.js.map +1 -0
- package/dist/cjs/vue.d.ts +9 -0
- package/dist/cjs/vue.js +39 -0
- package/dist/cjs/vue.js.map +1 -0
- package/dist/esm/app-identity-contract.generated.d.ts +22 -0
- package/dist/esm/app-identity-contract.generated.js +48 -0
- package/dist/esm/app-identity-contract.generated.js.map +1 -0
- package/dist/esm/capabilities.d.ts +54 -0
- package/dist/esm/capabilities.js +129 -0
- package/dist/esm/capabilities.js.map +1 -0
- package/dist/esm/client.d.ts +604 -0
- package/dist/esm/client.js +32 -0
- package/dist/esm/client.js.map +1 -0
- package/dist/esm/cloud-server.d.ts +31 -0
- package/dist/esm/cloud-server.js +109 -0
- package/dist/esm/cloud-server.js.map +1 -0
- package/dist/esm/cloud-transport.d.ts +46 -0
- package/dist/esm/cloud-transport.js +187 -0
- package/dist/esm/cloud-transport.js.map +1 -0
- package/dist/esm/controls.d.ts +93 -0
- package/dist/esm/controls.js +163 -0
- package/dist/esm/controls.js.map +1 -0
- package/dist/esm/data/bootstrap.d.ts +66 -0
- package/dist/esm/data/bootstrap.js +277 -0
- package/dist/esm/data/bootstrap.js.map +1 -0
- package/dist/esm/data/call.d.ts +16 -0
- package/dist/esm/data/call.js +47 -0
- package/dist/esm/data/call.js.map +1 -0
- package/dist/esm/data/client.d.ts +92 -0
- package/dist/esm/data/client.js +99 -0
- package/dist/esm/data/client.js.map +1 -0
- package/dist/esm/data/collection.d.ts +238 -0
- package/dist/esm/data/collection.js +434 -0
- package/dist/esm/data/collection.js.map +1 -0
- package/dist/esm/data/context.d.ts +10 -0
- package/dist/esm/data/context.js +34 -0
- package/dist/esm/data/context.js.map +1 -0
- package/dist/esm/data/declarations.d.ts +11 -0
- package/dist/esm/data/declarations.js +10 -0
- package/dist/esm/data/declarations.js.map +1 -0
- package/dist/esm/data/define.d.ts +69 -0
- package/dist/esm/data/define.js +27 -0
- package/dist/esm/data/define.js.map +1 -0
- package/dist/esm/data/error.d.ts +60 -0
- package/dist/esm/data/error.js +178 -0
- package/dist/esm/data/error.js.map +1 -0
- package/dist/esm/data/index.d.ts +21 -0
- package/dist/esm/data/index.js +18 -0
- package/dist/esm/data/index.js.map +1 -0
- package/dist/esm/data/schema.d.ts +82 -0
- package/dist/esm/data/schema.js +596 -0
- package/dist/esm/data/schema.js.map +1 -0
- package/dist/esm/data/sort.d.ts +8 -0
- package/dist/esm/data/sort.js +18 -0
- package/dist/esm/data/sort.js.map +1 -0
- package/dist/esm/files.d.ts +67 -0
- package/dist/esm/files.js +113 -0
- package/dist/esm/files.js.map +1 -0
- package/dist/esm/framework-scope.d.ts +1 -0
- package/dist/esm/framework-scope.js +11 -0
- package/dist/esm/framework-scope.js.map +1 -0
- package/dist/esm/index.d.ts +14 -0
- package/dist/esm/index.js +10 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/mq/broker.d.ts +65 -0
- package/dist/esm/mq/broker.js +109 -0
- package/dist/esm/mq/broker.js.map +1 -0
- package/dist/esm/mq/client.d.ts +37 -0
- package/dist/esm/mq/client.js +314 -0
- package/dist/esm/mq/client.js.map +1 -0
- package/dist/esm/mq/index.d.ts +5 -0
- package/dist/esm/mq/index.js +3 -0
- package/dist/esm/mq/index.js.map +1 -0
- package/dist/esm/mq/types.d.ts +48 -0
- package/dist/esm/mq/types.js +2 -0
- package/dist/esm/mq/types.js.map +1 -0
- package/dist/esm/openapi/api.generated.d.ts +820 -0
- package/dist/esm/openapi/api.generated.js +603 -0
- package/dist/esm/openapi/api.generated.js.map +1 -0
- package/dist/esm/openapi/client.d.ts +56 -0
- package/dist/esm/openapi/client.js +210 -0
- package/dist/esm/openapi/client.js.map +1 -0
- package/dist/esm/openapi/codecs.generated.d.ts +2234 -0
- package/dist/esm/openapi/codecs.generated.js +3 -0
- package/dist/esm/openapi/codecs.generated.js.map +1 -0
- package/dist/esm/openapi/index.d.ts +5 -0
- package/dist/esm/openapi/index.js +3 -0
- package/dist/esm/openapi/index.js.map +1 -0
- package/dist/esm/openapi/types.generated.d.ts +3227 -0
- package/dist/esm/openapi/types.generated.js +2 -0
- package/dist/esm/openapi/types.generated.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/react.d.ts +9 -0
- package/dist/esm/react.js +12 -0
- package/dist/esm/react.js.map +1 -0
- package/dist/esm/runtime-context.d.ts +9 -0
- package/dist/esm/runtime-context.js +22 -0
- package/dist/esm/runtime-context.js.map +1 -0
- package/dist/esm/runtime-env.d.ts +1 -0
- package/dist/esm/runtime-env.js +15 -0
- package/dist/esm/runtime-env.js.map +1 -0
- package/dist/esm/source.d.ts +39 -0
- package/dist/esm/source.js +25 -0
- package/dist/esm/source.js.map +1 -0
- package/dist/esm/stream.d.ts +40 -0
- package/dist/esm/stream.js +29 -0
- package/dist/esm/stream.js.map +1 -0
- package/dist/esm/uns-v2/client.d.ts +54 -0
- package/dist/esm/uns-v2/client.js +170 -0
- package/dist/esm/uns-v2/client.js.map +1 -0
- package/dist/esm/uns-v2/codec.d.ts +11 -0
- package/dist/esm/uns-v2/codec.js +284 -0
- package/dist/esm/uns-v2/codec.js.map +1 -0
- package/dist/esm/uns-v2/data-client.d.ts +10 -0
- package/dist/esm/uns-v2/data-client.js +14 -0
- package/dist/esm/uns-v2/data-client.js.map +1 -0
- package/dist/esm/uns-v2/generated.d.ts +15551 -0
- package/dist/esm/uns-v2/generated.js +136 -0
- package/dist/esm/uns-v2/generated.js.map +1 -0
- package/dist/esm/uns-v2/index.d.ts +5 -0
- package/dist/esm/uns-v2/index.js +5 -0
- package/dist/esm/uns-v2/index.js.map +1 -0
- package/dist/esm/vue.d.ts +9 -0
- package/dist/esm/vue.js +36 -0
- package/dist/esm/vue.js.map +1 -0
- package/docs/acceptance-2026-10-22.md +88 -0
- package/package.json +242 -4
- package/skills/tier0-sdk-v2/SKILL.md +66 -0
- package/skills/tier0-sdk-v2/references/integration.md +72 -0
- package/skills/tier0-sdk-v2-agent/SKILL.md +73 -0
- package/skills/tier0-sdk-v2-agent/references/results.md +45 -0
- package/skills/tier0-sdk-v2-controls/SKILL.md +63 -0
- package/skills/tier0-sdk-v2-data/SKILL.md +57 -0
- package/skills/tier0-sdk-v2-data/references/consistency.md +70 -0
- package/skills/tier0-sdk-v2-data/references/errors.md +69 -0
- package/skills/tier0-sdk-v2-data/references/modeling.md +77 -0
- package/skills/tier0-sdk-v2-data/references/read-write.md +72 -0
- package/skills/tier0-sdk-v2-data/references/schema-evolution.md +36 -0
- package/skills/tier0-sdk-v2-files/SKILL.md +85 -0
- package/skills/tier0-sdk-v2-files/references/delete.md +22 -0
- package/skills/tier0-sdk-v2-files/references/download.md +49 -0
- package/skills/tier0-sdk-v2-files/references/multipart.md +42 -0
- package/skills/tier0-sdk-v2-files/references/upload.md +27 -0
- package/skills/tier0-sdk-v2-files/references/url.md +22 -0
- package/skills/tier0-sdk-v2-members/SKILL.md +56 -0
- package/skills/tier0-sdk-v2-members/references/app-members.md +41 -0
- package/skills/tier0-sdk-v2-members/references/platform-members.md +56 -0
- package/skills/tier0-sdk-v2-mq/SKILL.md +78 -0
- package/skills/tier0-sdk-v2-mq/references/quickstart.md +69 -0
- package/skills/tier0-sdk-v2-notifications/SKILL.md +42 -0
- package/skills/tier0-sdk-v2-notifications/references/get.md +34 -0
- package/skills/tier0-sdk-v2-notifications/references/send.md +72 -0
- package/skills/tier0-sdk-v2-source/SKILL.md +38 -0
- package/skills/tier0-sdk-v2-source/references/changes.md +40 -0
- package/skills/tier0-sdk-v2-source/references/create.md +63 -0
- package/skills/tier0-sdk-v2-source/references/delete.md +47 -0
- package/skills/tier0-sdk-v2-source/references/protocols.md +36 -0
- package/skills/tier0-sdk-v2-source/references/read.md +34 -0
- package/skills/tier0-sdk-v2-source/references/state.md +37 -0
- package/skills/tier0-sdk-v2-source/references/update.md +61 -0
- package/skills/tier0-sdk-v2-stream/SKILL.md +43 -0
- package/skills/tier0-sdk-v2-stream/references/create.md +55 -0
- package/skills/tier0-sdk-v2-stream/references/delete.md +35 -0
- package/skills/tier0-sdk-v2-stream/references/deploy.md +63 -0
- package/skills/tier0-sdk-v2-stream/references/lifecycle.md +25 -0
- package/skills/tier0-sdk-v2-stream/references/read.md +35 -0
- package/skills/tier0-sdk-v2-stream/references/update.md +35 -0
- package/skills/tier0-sdk-v2-system/SKILL.md +64 -0
- package/skills/tier0-sdk-v2-system/references/info.md +23 -0
- package/skills/tier0-sdk-v2-system/references/whoami.md +21 -0
- package/skills/tier0-sdk-v2-uns/SKILL.md +53 -0
- package/skills/tier0-sdk-v2-uns/references/create.md +85 -0
- package/skills/tier0-sdk-v2-uns/references/data-workflows.md +73 -0
- package/skills/tier0-sdk-v2-uns/references/delete.md +69 -0
- package/skills/tier0-sdk-v2-uns/references/namespace.md +75 -0
- package/skills/tier0-sdk-v2-uns/references/read.md +32 -0
- package/skills/tier0-sdk-v2-uns/references/restore.md +41 -0
- package/skills/tier0-sdk-v2-uns/references/update.md +86 -0
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Collection = exports.Cursor = exports.MAX_ATOMIC_ITEMS = exports.MAX_PAGE_SIZE = void 0;
|
|
4
|
+
exports.assertAtomicBatch = assertAtomicBatch;
|
|
5
|
+
exports.toDoc = toDoc;
|
|
6
|
+
const error_js_1 = require("./error.js");
|
|
7
|
+
const schema_js_1 = require("./schema.js");
|
|
8
|
+
const sort_js_1 = require("./sort.js");
|
|
9
|
+
/** UNS page limit for find / aggregate / distinct. */
|
|
10
|
+
exports.MAX_PAGE_SIZE = 200;
|
|
11
|
+
/**
|
|
12
|
+
* UNS commits at most 200 items in one synchronous atomic batch
|
|
13
|
+
* (insertMany, bulkWrite, data.transact).
|
|
14
|
+
*/
|
|
15
|
+
exports.MAX_ATOMIC_ITEMS = 200;
|
|
16
|
+
/** Rejects batches UNS would refuse, before anything is sent. */
|
|
17
|
+
function assertAtomicBatch(operation, count) {
|
|
18
|
+
if (count > exports.MAX_ATOMIC_ITEMS) {
|
|
19
|
+
throw new error_js_1.DataError({
|
|
20
|
+
message: `${operation} commits at most ${exports.MAX_ATOMIC_ITEMS} items atomically; got ${count}. ` +
|
|
21
|
+
`Split the input into chunks of ${exports.MAX_ATOMIC_ITEMS} (each chunk commits on its own; give each chunk a stable ` +
|
|
22
|
+
'idempotencyKey or fixed _ids so a retry is safe), or keep all-or-nothing work within one batch.',
|
|
23
|
+
status: 400,
|
|
24
|
+
code: 'BATCH_LIMIT_EXCEEDED',
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function toDoc(record) {
|
|
29
|
+
return {
|
|
30
|
+
...record.data,
|
|
31
|
+
_id: record.id,
|
|
32
|
+
_meta: { revision: record.revision, createdAt: record.createdAt, updatedAt: record.updatedAt },
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Async-iterable result set. Pages hold at most 200 items; the page source
|
|
37
|
+
* decides whether the next page is reached by cursor or by offset page number.
|
|
38
|
+
*/
|
|
39
|
+
class Cursor {
|
|
40
|
+
fetchPage;
|
|
41
|
+
sortSpec;
|
|
42
|
+
limitCount;
|
|
43
|
+
projection;
|
|
44
|
+
started = false;
|
|
45
|
+
constructor(fetchPage, options = {}) {
|
|
46
|
+
this.fetchPage = fetchPage;
|
|
47
|
+
this.sortSpec = options.sort;
|
|
48
|
+
this.limitCount = options.limit;
|
|
49
|
+
this.projection = options.projection;
|
|
50
|
+
}
|
|
51
|
+
assertNotStarted() {
|
|
52
|
+
if (this.started)
|
|
53
|
+
throw new Error('Cursor options must be set before iteration starts.');
|
|
54
|
+
}
|
|
55
|
+
sort(sort) {
|
|
56
|
+
this.assertNotStarted();
|
|
57
|
+
this.sortSpec = sort;
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
/** Total number of documents to return (pages are fetched ≤200 at a time). */
|
|
61
|
+
limit(count) {
|
|
62
|
+
this.assertNotStarted();
|
|
63
|
+
this.limitCount = count;
|
|
64
|
+
return this;
|
|
65
|
+
}
|
|
66
|
+
project(projection) {
|
|
67
|
+
this.assertNotStarted();
|
|
68
|
+
this.projection = projection;
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
async *[Symbol.asyncIterator]() {
|
|
72
|
+
this.started = true;
|
|
73
|
+
const sort = (0, sort_js_1.toSortPairs)(this.sortSpec);
|
|
74
|
+
let remaining = this.limitCount ?? Number.POSITIVE_INFINITY;
|
|
75
|
+
// One page size for the whole iteration: offset pages are only stable when it never changes.
|
|
76
|
+
const size = Math.min(exports.MAX_PAGE_SIZE, remaining);
|
|
77
|
+
let token = null;
|
|
78
|
+
while (remaining > 0) {
|
|
79
|
+
const page = await this.fetchPage({ token, size, sort, projection: this.projection });
|
|
80
|
+
for (const item of page.items.slice(0, remaining))
|
|
81
|
+
yield item;
|
|
82
|
+
remaining -= page.items.length;
|
|
83
|
+
if (page.next === null || page.items.length === 0)
|
|
84
|
+
return;
|
|
85
|
+
token = page.next;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async toArray() {
|
|
89
|
+
const out = [];
|
|
90
|
+
for await (const item of this)
|
|
91
|
+
out.push(item);
|
|
92
|
+
return out;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.Cursor = Cursor;
|
|
96
|
+
/** Pipelines made only of `$match` / `$sort` page by cursor; UNS requires offset paging for any other stage. */
|
|
97
|
+
function isDirectPipeline(stages) {
|
|
98
|
+
return stages.every((stage) => Object.keys(stage).every((key) => key === '$match' || key === '$sort'));
|
|
99
|
+
}
|
|
100
|
+
function compact(value) {
|
|
101
|
+
return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined));
|
|
102
|
+
}
|
|
103
|
+
function idsInOrder(ids) {
|
|
104
|
+
return Object.entries(ids ?? {})
|
|
105
|
+
.sort(([a], [b]) => Number(a) - Number(b))
|
|
106
|
+
.map(([, id]) => id);
|
|
107
|
+
}
|
|
108
|
+
function assertNoWriteErrors(result, operation, committed = {}) {
|
|
109
|
+
if (result.writeErrors && result.writeErrors.length > 0) {
|
|
110
|
+
const counts = Object.entries(committed).map(([name, value]) => `${name}=${value}`).join(', ');
|
|
111
|
+
throw new error_js_1.DataError({
|
|
112
|
+
message: `${operation} stopped on ${result.writeErrors.length} write error(s)${counts ? `; already committed: ${counts}` : ''}.`,
|
|
113
|
+
status: 409,
|
|
114
|
+
code: 'WRITE_ERRORS',
|
|
115
|
+
details: { writeErrors: result.writeErrors, committed },
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
class Collection {
|
|
120
|
+
definition;
|
|
121
|
+
runtime;
|
|
122
|
+
constructor(definition, runtime) {
|
|
123
|
+
this.definition = definition;
|
|
124
|
+
this.runtime = runtime;
|
|
125
|
+
}
|
|
126
|
+
get alias() {
|
|
127
|
+
return this.definition.alias;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* One call with stale-ID recovery. A call continuing a cursor or
|
|
131
|
+
* resumeAfter token of the old collection is not retried: the token means
|
|
132
|
+
* nothing to a recreated collection.
|
|
133
|
+
*/
|
|
134
|
+
post(operation, body, options = {}) {
|
|
135
|
+
const page = body.page;
|
|
136
|
+
const continues = typeof body.cursor === 'string' || typeof body.resumeAfter === 'string' || typeof page?.cursor === 'string';
|
|
137
|
+
return this.runtime.recover(() => this.send(operation, body, options), { retry: !continues });
|
|
138
|
+
}
|
|
139
|
+
async send(operation, body, options = {}) {
|
|
140
|
+
const collectionId = await this.runtime.resolve(this.definition);
|
|
141
|
+
return this.runtime.call(operation, { collectionId, ...compact(body) }, { dataSubject: this.runtime.subject(), ...options });
|
|
142
|
+
}
|
|
143
|
+
/* ---------------------------------- reads --------------------------------- */
|
|
144
|
+
find(filter = {}, options = {}) {
|
|
145
|
+
return new Cursor(async ({ token, size, sort, projection }) => {
|
|
146
|
+
const result = await this.post('recordFind', {
|
|
147
|
+
filter: Object.keys(filter).length > 0 ? filter : undefined,
|
|
148
|
+
sort,
|
|
149
|
+
projection,
|
|
150
|
+
limit: size,
|
|
151
|
+
cursor: typeof token === 'string' ? token : undefined,
|
|
152
|
+
});
|
|
153
|
+
return {
|
|
154
|
+
items: result.items.map((record) => toDoc(record)),
|
|
155
|
+
next: result.pageInfo.hasMore && result.pageInfo.nextCursor ? result.pageInfo.nextCursor : null,
|
|
156
|
+
};
|
|
157
|
+
}, options);
|
|
158
|
+
}
|
|
159
|
+
async findOne(filter = {}, options = {}) {
|
|
160
|
+
const [first] = await this.find(filter, { ...options, limit: 1 }).toArray();
|
|
161
|
+
return first ?? null;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* One numbered page plus the total match count, for paged list screens.
|
|
165
|
+
* Uses `recordAggregatePipeline` offset paging.
|
|
166
|
+
*/
|
|
167
|
+
async findPage(filter = {}, options = {}) {
|
|
168
|
+
const page = Math.max(1, Math.trunc(options.page ?? 1));
|
|
169
|
+
const pageSize = Math.min(exports.MAX_PAGE_SIZE, Math.max(1, Math.trunc(options.pageSize ?? 20)));
|
|
170
|
+
const pipeline = [];
|
|
171
|
+
if (Object.keys(filter).length > 0)
|
|
172
|
+
pipeline.push({ $match: filter });
|
|
173
|
+
const sort = (0, sort_js_1.toSortPairs)(options.sort);
|
|
174
|
+
if (sort)
|
|
175
|
+
pipeline.push({ $sort: sort });
|
|
176
|
+
if (options.projection)
|
|
177
|
+
pipeline.push({ $project: options.projection });
|
|
178
|
+
const [rows, total] = await Promise.all([
|
|
179
|
+
this.post('recordAggregatePipeline', { pipeline, page: { mode: 'offset', page, size: pageSize } }),
|
|
180
|
+
this.countDocuments(filter),
|
|
181
|
+
]);
|
|
182
|
+
return { items: rows.items, total, page, pageSize };
|
|
183
|
+
}
|
|
184
|
+
async countDocuments(filter = {}) {
|
|
185
|
+
const result = await this.post('recordCount', {
|
|
186
|
+
filter: Object.keys(filter).length > 0 ? filter : undefined,
|
|
187
|
+
});
|
|
188
|
+
return result.count;
|
|
189
|
+
}
|
|
190
|
+
/** Distinct values of a field (every page). */
|
|
191
|
+
async distinct(field, filter = {}) {
|
|
192
|
+
const values = [];
|
|
193
|
+
for (let page = 1;; page += 1) {
|
|
194
|
+
const result = await this.post('recordDistinct', {
|
|
195
|
+
field,
|
|
196
|
+
filter: Object.keys(filter).length > 0 ? filter : undefined,
|
|
197
|
+
page: { mode: 'offset', page, size: exports.MAX_PAGE_SIZE },
|
|
198
|
+
});
|
|
199
|
+
values.push(...result.values);
|
|
200
|
+
if (!result.pageInfo.hasMore)
|
|
201
|
+
return values;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Runs a pipeline (`$match`, `$sort`, `$group`, `$project`, `$set`,
|
|
206
|
+
* `$lookup`, `$unwind`, `$skip`, `$limit`, `$count`). `$sort` accepts
|
|
207
|
+
* `{ field: 1 | -1 }`; `$lookup` takes `from` (a declared collection or
|
|
208
|
+
* alias of this App) instead of a collection ID. Rows are whatever the
|
|
209
|
+
* pipeline outputs, not wrapped records.
|
|
210
|
+
*
|
|
211
|
+
* Pipelines of only `$match` / `$sort` page by cursor; any other stage pages
|
|
212
|
+
* by offset (UNS rejects cursors for transformed results). The `$exists`,
|
|
213
|
+
* `$distinct` and `$frequencies` stages are listed in the UNS schema but not
|
|
214
|
+
* executed by the record pipeline; use `countDocuments`, `distinct` or `$group`.
|
|
215
|
+
*/
|
|
216
|
+
aggregate(pipeline) {
|
|
217
|
+
// Recovery wraps stage preparation too, so a retry re-resolves `$lookup` IDs.
|
|
218
|
+
return new Cursor(({ token, size }) => this.runtime.recover(() => this.aggregatePage(pipeline, token, size), { retry: typeof token !== 'string' }));
|
|
219
|
+
}
|
|
220
|
+
async aggregatePage(pipeline, token, size) {
|
|
221
|
+
const stages = await this.prepareStages(pipeline);
|
|
222
|
+
const last = stages[stages.length - 1];
|
|
223
|
+
if (last !== undefined && '$count' in last) {
|
|
224
|
+
// A final $count returns one row and forbids an explicit page.
|
|
225
|
+
const result = await this.send('recordAggregatePipeline', { pipeline: stages });
|
|
226
|
+
return { items: result.items, next: null };
|
|
227
|
+
}
|
|
228
|
+
if (isDirectPipeline(stages)) {
|
|
229
|
+
const result = await this.send('recordAggregatePipeline', {
|
|
230
|
+
pipeline: stages,
|
|
231
|
+
page: { mode: 'cursor', size, ...(typeof token === 'string' ? { cursor: token } : {}) },
|
|
232
|
+
});
|
|
233
|
+
return { items: result.items, next: result.pageInfo.hasMore && result.pageInfo.nextCursor ? result.pageInfo.nextCursor : null };
|
|
234
|
+
}
|
|
235
|
+
const page = typeof token === 'number' ? token : 1;
|
|
236
|
+
const result = await this.send('recordAggregatePipeline', {
|
|
237
|
+
pipeline: stages,
|
|
238
|
+
page: { mode: 'offset', page, size },
|
|
239
|
+
});
|
|
240
|
+
return {
|
|
241
|
+
items: result.items,
|
|
242
|
+
next: result.pageInfo.hasMore ? (result.pageInfo.nextPage ?? page + 1) : null,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
/** Converts Mongo-style `$sort` objects and resolves `$lookup.from`, recursively. */
|
|
246
|
+
async prepareStages(pipeline) {
|
|
247
|
+
return Promise.all(pipeline.map(async (stage) => {
|
|
248
|
+
if ('$sort' in stage && !Array.isArray(stage.$sort)) {
|
|
249
|
+
return { ...stage, $sort: (0, sort_js_1.toSortPairs)(stage.$sort) };
|
|
250
|
+
}
|
|
251
|
+
if ('$lookup' in stage && stage.$lookup && typeof stage.$lookup === 'object') {
|
|
252
|
+
const { from, pipeline: inner, ...lookup } = stage.$lookup;
|
|
253
|
+
const resolved = { ...lookup };
|
|
254
|
+
if (from !== undefined)
|
|
255
|
+
resolved.collectionId = await this.runtime.resolve(from);
|
|
256
|
+
if (Array.isArray(inner))
|
|
257
|
+
resolved.pipeline = await this.prepareStages(inner);
|
|
258
|
+
return { ...stage, $lookup: resolved };
|
|
259
|
+
}
|
|
260
|
+
return stage;
|
|
261
|
+
}));
|
|
262
|
+
}
|
|
263
|
+
/* --------------------------------- writes --------------------------------- */
|
|
264
|
+
async insertOne(document, options = {}) {
|
|
265
|
+
const { id, data } = (0, schema_js_1.validateDocument)(this.definition, document);
|
|
266
|
+
const result = await this.post('recordInsertOne', { id, data, idempotencyKey: options.idempotencyKey });
|
|
267
|
+
return { insertedId: result.insertedId };
|
|
268
|
+
}
|
|
269
|
+
/** Inserts up to 200 documents atomically (all or none). */
|
|
270
|
+
async insertMany(documents, options = {}) {
|
|
271
|
+
if (documents.length === 0)
|
|
272
|
+
return { insertedCount: 0, insertedIds: [] };
|
|
273
|
+
assertAtomicBatch('insertMany', documents.length);
|
|
274
|
+
const prepared = documents.map((document) => (0, schema_js_1.validateDocument)(this.definition, document));
|
|
275
|
+
const result = await this.post('recordInsertMany', {
|
|
276
|
+
documents: prepared.map(({ id, data }) => compact({ id, data })),
|
|
277
|
+
ordered: true,
|
|
278
|
+
atomic: true,
|
|
279
|
+
idempotencyKey: options.idempotencyKey,
|
|
280
|
+
});
|
|
281
|
+
assertNoWriteErrors(result, 'insertMany');
|
|
282
|
+
return { insertedCount: result.insertedCount ?? 0, insertedIds: idsInOrder(result.insertedIds) };
|
|
283
|
+
}
|
|
284
|
+
async updateOne(filter, update, options = {}) {
|
|
285
|
+
const result = await this.post('recordUpdateOne', {
|
|
286
|
+
filter,
|
|
287
|
+
update: (0, schema_js_1.validateUpdate)(this.definition, update),
|
|
288
|
+
upsert: options.upsert,
|
|
289
|
+
expectedRevision: options.expectedRevision,
|
|
290
|
+
sort: (0, sort_js_1.toSortPairs)(options.sort),
|
|
291
|
+
arrayFilters: options.arrayFilters,
|
|
292
|
+
idempotencyKey: options.idempotencyKey,
|
|
293
|
+
});
|
|
294
|
+
return { matchedCount: result.matchedCount ?? 0, modifiedCount: result.modifiedCount ?? 0, upsertedId: result.upsertedId ?? null };
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Updates every match like Mongo's updateMany: documents commit one by one
|
|
298
|
+
* (not atomically), following `resumeAfter` until every match is processed.
|
|
299
|
+
* A failure stops the run and reports the counts already committed. For
|
|
300
|
+
* all-or-nothing multi-document changes use `data.transact` (≤200 items).
|
|
301
|
+
*/
|
|
302
|
+
async updateMany(filter, update, options = {}) {
|
|
303
|
+
const validated = (0, schema_js_1.validateUpdate)(this.definition, update);
|
|
304
|
+
let matchedCount = 0;
|
|
305
|
+
let modifiedCount = 0;
|
|
306
|
+
let resumeAfter;
|
|
307
|
+
do {
|
|
308
|
+
const result = await this.post('recordUpdateMany', {
|
|
309
|
+
filter,
|
|
310
|
+
update: validated,
|
|
311
|
+
arrayFilters: options.arrayFilters,
|
|
312
|
+
atomic: false,
|
|
313
|
+
resumeAfter,
|
|
314
|
+
});
|
|
315
|
+
matchedCount += result.matchedCount ?? 0;
|
|
316
|
+
modifiedCount += result.modifiedCount ?? 0;
|
|
317
|
+
assertNoWriteErrors(result, 'updateMany', { matchedCount, modifiedCount });
|
|
318
|
+
resumeAfter = result.hasMore && result.resumeAfter ? result.resumeAfter : undefined;
|
|
319
|
+
} while (resumeAfter);
|
|
320
|
+
return { matchedCount, modifiedCount };
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Replaces the whole body. Fields written by another App version and not in
|
|
324
|
+
* this declaration are lost — prefer `updateOne` with `$set`.
|
|
325
|
+
*/
|
|
326
|
+
async replaceOne(filter, replacement, options = {}) {
|
|
327
|
+
const { data } = (0, schema_js_1.validateDocument)(this.definition, replacement);
|
|
328
|
+
const result = await this.post('recordReplaceOne', {
|
|
329
|
+
filter,
|
|
330
|
+
replacement: data,
|
|
331
|
+
upsert: options.upsert,
|
|
332
|
+
expectedRevision: options.expectedRevision,
|
|
333
|
+
sort: (0, sort_js_1.toSortPairs)(options.sort),
|
|
334
|
+
idempotencyKey: options.idempotencyKey,
|
|
335
|
+
});
|
|
336
|
+
return { matchedCount: result.matchedCount ?? 0, modifiedCount: result.modifiedCount ?? 0, upsertedId: result.upsertedId ?? null };
|
|
337
|
+
}
|
|
338
|
+
/** Soft-deletes one record; requires `uns.delete` on the App key. */
|
|
339
|
+
async deleteOne(filter, options = {}) {
|
|
340
|
+
const result = await this.post('recordDeleteOne', { filter, expectedRevision: options.expectedRevision, sort: (0, sort_js_1.toSortPairs)(options.sort), idempotencyKey: options.idempotencyKey });
|
|
341
|
+
return { deletedCount: result.deletedCount ?? 0 };
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Soft-deletes every match, one document at a time like Mongo's deleteMany
|
|
345
|
+
* (not atomic), following `resumeAfter`; requires `uns.delete` on the App key.
|
|
346
|
+
*/
|
|
347
|
+
async deleteMany(filter) {
|
|
348
|
+
let deletedCount = 0;
|
|
349
|
+
let resumeAfter;
|
|
350
|
+
do {
|
|
351
|
+
const result = await this.post('recordDeleteMany', { filter, atomic: false, resumeAfter });
|
|
352
|
+
deletedCount += result.deletedCount ?? 0;
|
|
353
|
+
assertNoWriteErrors(result, 'deleteMany', { deletedCount });
|
|
354
|
+
resumeAfter = result.hasMore && result.resumeAfter ? result.resumeAfter : undefined;
|
|
355
|
+
} while (resumeAfter);
|
|
356
|
+
return { deletedCount };
|
|
357
|
+
}
|
|
358
|
+
/**
|
|
359
|
+
* Atomic read-modify-write. A state transition puts the expected state in
|
|
360
|
+
* the filter: `findOneAndUpdate({ _id, status: "DRAFT" }, { $set: { status: "SUBMITTED" } })`
|
|
361
|
+
* returns null when another request moved the record first.
|
|
362
|
+
*/
|
|
363
|
+
async findOneAndUpdate(filter, update, options = {}) {
|
|
364
|
+
const result = await this.post('recordFindOneAndUpdate', {
|
|
365
|
+
filter,
|
|
366
|
+
update: (0, schema_js_1.validateUpdate)(this.definition, update),
|
|
367
|
+
upsert: options.upsert,
|
|
368
|
+
expectedRevision: options.expectedRevision,
|
|
369
|
+
sort: (0, sort_js_1.toSortPairs)(options.sort),
|
|
370
|
+
arrayFilters: options.arrayFilters,
|
|
371
|
+
returnDocument: options.returnDocument ?? 'after',
|
|
372
|
+
projection: options.projection,
|
|
373
|
+
idempotencyKey: options.idempotencyKey,
|
|
374
|
+
});
|
|
375
|
+
return result.value ? toDoc(result.value) : null;
|
|
376
|
+
}
|
|
377
|
+
async findOneAndReplace(filter, replacement, options = {}) {
|
|
378
|
+
const { data } = (0, schema_js_1.validateDocument)(this.definition, replacement);
|
|
379
|
+
const result = await this.post('recordFindOneAndReplace', {
|
|
380
|
+
filter,
|
|
381
|
+
replacement: data,
|
|
382
|
+
upsert: options.upsert,
|
|
383
|
+
expectedRevision: options.expectedRevision,
|
|
384
|
+
sort: (0, sort_js_1.toSortPairs)(options.sort),
|
|
385
|
+
returnDocument: options.returnDocument ?? 'after',
|
|
386
|
+
projection: options.projection,
|
|
387
|
+
idempotencyKey: options.idempotencyKey,
|
|
388
|
+
});
|
|
389
|
+
return result.value ? toDoc(result.value) : null;
|
|
390
|
+
}
|
|
391
|
+
async findOneAndDelete(filter, options = {}) {
|
|
392
|
+
const result = await this.post('recordFindOneAndDelete', {
|
|
393
|
+
filter,
|
|
394
|
+
expectedRevision: options.expectedRevision,
|
|
395
|
+
sort: (0, sort_js_1.toSortPairs)(options.sort),
|
|
396
|
+
projection: options.projection,
|
|
397
|
+
idempotencyKey: options.idempotencyKey,
|
|
398
|
+
});
|
|
399
|
+
return result.value ? toDoc(result.value) : null;
|
|
400
|
+
}
|
|
401
|
+
/** Up to 200 mixed single-record writes in one atomic call (insertOne / updateOne / replaceOne / deleteOne). */
|
|
402
|
+
async bulkWrite(operations, options = {}) {
|
|
403
|
+
assertAtomicBatch('bulkWrite', operations.length);
|
|
404
|
+
const mapped = operations.map((operation) => {
|
|
405
|
+
if ('insertOne' in operation) {
|
|
406
|
+
const { id, data } = (0, schema_js_1.validateDocument)(this.definition, operation.insertOne.document);
|
|
407
|
+
return { insertOne: compact({ id, data }) };
|
|
408
|
+
}
|
|
409
|
+
if ('updateOne' in operation) {
|
|
410
|
+
const { filter, update, upsert, sort } = operation.updateOne;
|
|
411
|
+
return { updateOne: compact({ filter, update: (0, schema_js_1.validateUpdate)(this.definition, update), upsert, sort: (0, sort_js_1.toSortPairs)(sort) }) };
|
|
412
|
+
}
|
|
413
|
+
if ('replaceOne' in operation) {
|
|
414
|
+
const { filter, replacement, upsert, sort } = operation.replaceOne;
|
|
415
|
+
const { data } = (0, schema_js_1.validateDocument)(this.definition, replacement);
|
|
416
|
+
return { replaceOne: compact({ filter, replacement: data, upsert, sort: (0, sort_js_1.toSortPairs)(sort) }) };
|
|
417
|
+
}
|
|
418
|
+
if ('deleteOne' in operation) {
|
|
419
|
+
return { deleteOne: compact({ filter: operation.deleteOne.filter, sort: (0, sort_js_1.toSortPairs)(operation.deleteOne.sort) }) };
|
|
420
|
+
}
|
|
421
|
+
throw new Error(`Unsupported bulkWrite operation ${Object.keys(operation).join(', ')}; use updateMany() / deleteMany() or data.transact().`);
|
|
422
|
+
});
|
|
423
|
+
if (mapped.length === 0) {
|
|
424
|
+
return { insertedCount: 0, matchedCount: 0, modifiedCount: 0, deletedCount: 0, upsertedCount: 0, insertedIds: {}, upsertedIds: {} };
|
|
425
|
+
}
|
|
426
|
+
const result = await this.post('recordBulkWrite', { operations: mapped, ordered: true, atomic: true, idempotencyKey: options.idempotencyKey });
|
|
427
|
+
assertNoWriteErrors(result, 'bulkWrite');
|
|
428
|
+
const numericKeys = (ids) => Object.fromEntries(Object.entries(ids ?? {}).map(([index, id]) => [Number(index), id]));
|
|
429
|
+
return {
|
|
430
|
+
insertedCount: result.insertedCount ?? 0,
|
|
431
|
+
matchedCount: result.matchedCount ?? 0,
|
|
432
|
+
modifiedCount: result.modifiedCount ?? 0,
|
|
433
|
+
deletedCount: result.deletedCount ?? 0,
|
|
434
|
+
upsertedCount: result.upsertedCount ?? 0,
|
|
435
|
+
insertedIds: numericKeys(result.insertedIds),
|
|
436
|
+
upsertedIds: numericKeys(result.upsertedIds),
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
exports.Collection = Collection;
|
|
441
|
+
//# sourceMappingURL=collection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collection.js","sourceRoot":"","sources":["../../../src/data/collection.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Mongo-driver-style collection handle over the UNS record operations\n * (`recordFind`, `recordInsertMany`, ...).\n *\n * Stored records `{ id, data, revision, createdAt, updatedAt }` are exposed as\n * flat documents `{ _id, ...data, _meta: { revision, createdAt, updatedAt } }`;\n * filters, sorts and projections use the same paths (`status`,\n * `customer.id`, `_id`, `_meta.updatedAt`).\n */\nimport type { UnsV2OperationName } from '../uns-v2/generated.js';\nimport type { CallOptions, DataCall } from './call.js';\nimport type { CollectionDefinition, RecordMeta } from './define.js';\nimport { DataError } from './error.js';\nimport { validateDocument, validateUpdate } from './schema.js';\nimport { toSortPairs, type Filter, type Sort, type SortPairs } from './sort.js';\n\n/** UNS page limit for find / aggregate / distinct. */\nexport const MAX_PAGE_SIZE = 200;\n\n/**\n * UNS commits at most 200 items in one synchronous atomic batch\n * (insertMany, bulkWrite, data.transact).\n */\nexport const MAX_ATOMIC_ITEMS = 200;\n\nexport type WithMeta<T> = T & { _id: string; _meta: RecordMeta };\nexport type Projection = Record<string, 0 | 1 | boolean>;\nexport type Update = Record<string, unknown>;\n\nexport interface UnsRecord {\n id: string;\n data: Record<string, unknown>;\n revision: number;\n createdAt: number;\n updatedAt: number;\n}\n\ninterface PageInfo {\n hasMore: boolean;\n nextCursor?: string | null;\n nextPage?: number | null;\n}\n\n/** Position of the next page: an opaque cursor or a 1-based offset page number. */\ntype PageToken = string | number;\n\ninterface Page<T> {\n items: T[];\n /** Token of the following page; null when this was the last one. */\n next: PageToken | null;\n}\n\ninterface WriteResult {\n matchedCount?: number;\n modifiedCount?: number;\n deletedCount?: number;\n insertedCount?: number;\n upsertedId?: string | null;\n insertedIds?: Record<string, string>;\n upsertedIds?: Record<string, string>;\n upsertedCount?: number;\n writeErrors?: unknown[];\n hasMore?: boolean;\n resumeAfter?: string | null;\n}\n\n/** Runtime services a collection handle needs from its client. */\nexport interface CollectionRuntime {\n call: DataCall;\n /** Collection ID of a declaration or declared alias, ensuring all declarations first. */\n resolve(target: CollectionDefinition | string): Promise<string>;\n /** Runs a call, re-ensuring and retrying once when its collection ID went stale (see bootstrap). */\n recover<R>(fn: () => Promise<R>, options?: { retry?: boolean }): Promise<R>;\n /** Data subject of the request being served. */\n subject(): string | undefined;\n}\n\n/** Rejects batches UNS would refuse, before anything is sent. */\nexport function assertAtomicBatch(operation: string, count: number) {\n if (count > MAX_ATOMIC_ITEMS) {\n throw new DataError({\n message:\n `${operation} commits at most ${MAX_ATOMIC_ITEMS} items atomically; got ${count}. ` +\n `Split the input into chunks of ${MAX_ATOMIC_ITEMS} (each chunk commits on its own; give each chunk a stable ` +\n 'idempotencyKey or fixed _ids so a retry is safe), or keep all-or-nothing work within one batch.',\n status: 400,\n code: 'BATCH_LIMIT_EXCEEDED',\n });\n }\n}\n\nexport function toDoc<T>(record: UnsRecord): WithMeta<T> {\n return {\n ...(record.data as T),\n _id: record.id,\n _meta: { revision: record.revision, createdAt: record.createdAt, updatedAt: record.updatedAt },\n };\n}\n\n/**\n * Async-iterable result set. Pages hold at most 200 items; the page source\n * decides whether the next page is reached by cursor or by offset page number.\n */\nexport class Cursor<T> implements AsyncIterable<T> {\n private sortSpec?: Sort;\n private limitCount?: number;\n private projection?: Projection;\n private started = false;\n\n constructor(\n private readonly fetchPage: (state: {\n token: PageToken | null;\n size: number;\n sort?: SortPairs;\n projection?: Projection;\n }) => Promise<Page<T>>,\n options: { sort?: Sort; limit?: number; projection?: Projection } = {},\n ) {\n this.sortSpec = options.sort;\n this.limitCount = options.limit;\n this.projection = options.projection;\n }\n\n private assertNotStarted() {\n if (this.started) throw new Error('Cursor options must be set before iteration starts.');\n }\n\n sort(sort: Sort): this {\n this.assertNotStarted();\n this.sortSpec = sort;\n return this;\n }\n\n /** Total number of documents to return (pages are fetched ≤200 at a time). */\n limit(count: number): this {\n this.assertNotStarted();\n this.limitCount = count;\n return this;\n }\n\n project(projection: Projection): this {\n this.assertNotStarted();\n this.projection = projection;\n return this;\n }\n\n async *[Symbol.asyncIterator](): AsyncIterator<T> {\n this.started = true;\n const sort = toSortPairs(this.sortSpec);\n let remaining = this.limitCount ?? Number.POSITIVE_INFINITY;\n // One page size for the whole iteration: offset pages are only stable when it never changes.\n const size = Math.min(MAX_PAGE_SIZE, remaining);\n let token: PageToken | null = null;\n while (remaining > 0) {\n const page = await this.fetchPage({ token, size, sort, projection: this.projection });\n for (const item of page.items.slice(0, remaining)) yield item;\n remaining -= page.items.length;\n if (page.next === null || page.items.length === 0) return;\n token = page.next;\n }\n }\n\n async toArray(): Promise<T[]> {\n const out: T[] = [];\n for await (const item of this) out.push(item);\n return out;\n }\n}\n\n/** Pipelines made only of `$match` / `$sort` page by cursor; UNS requires offset paging for any other stage. */\nfunction isDirectPipeline(stages: readonly Record<string, unknown>[]): boolean {\n return stages.every((stage) => Object.keys(stage).every((key) => key === '$match' || key === '$sort'));\n}\n\nexport interface FindOptions {\n sort?: Sort;\n limit?: number;\n projection?: Projection;\n}\n\nexport interface FindPageOptions {\n sort?: Sort;\n /** 1-based page number. */\n page?: number;\n /** At most 200. */\n pageSize?: number;\n projection?: Projection;\n}\n\nexport interface UpdateOptions {\n upsert?: boolean;\n /** Reject the write with VERSION_CONFLICT unless the record is at this revision. */\n expectedRevision?: number;\n sort?: Sort;\n arrayFilters?: Record<string, unknown>[];\n idempotencyKey?: string;\n}\n\nexport interface FindOneAndOptions extends UpdateOptions {\n returnDocument?: 'before' | 'after';\n projection?: Projection;\n}\n\nexport type BulkOperation =\n | { insertOne: { document: Record<string, unknown> } }\n | { updateOne: { filter: Filter; update: Update; upsert?: boolean; sort?: Sort } }\n | { replaceOne: { filter: Filter; replacement: Record<string, unknown>; upsert?: boolean; sort?: Sort } }\n | { deleteOne: { filter: Filter; sort?: Sort } };\n\nfunction compact<T extends Record<string, unknown>>(value: T): T {\n return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined)) as T;\n}\n\nfunction idsInOrder(ids: Record<string, string> | undefined): string[] {\n return Object.entries(ids ?? {})\n .sort(([a], [b]) => Number(a) - Number(b))\n .map(([, id]) => id);\n}\n\nfunction assertNoWriteErrors(result: WriteResult, operation: string, committed: Record<string, number> = {}) {\n if (result.writeErrors && result.writeErrors.length > 0) {\n const counts = Object.entries(committed).map(([name, value]) => `${name}=${value}`).join(', ');\n throw new DataError({\n message: `${operation} stopped on ${result.writeErrors.length} write error(s)${counts ? `; already committed: ${counts}` : ''}.`,\n status: 409,\n code: 'WRITE_ERRORS',\n details: { writeErrors: result.writeErrors, committed },\n });\n }\n}\n\nexport class Collection<T extends object = Record<string, unknown>, TInput extends object = T> {\n constructor(\n readonly definition: CollectionDefinition,\n private readonly runtime: CollectionRuntime,\n ) {}\n\n get alias(): string {\n return this.definition.alias;\n }\n\n /**\n * One call with stale-ID recovery. A call continuing a cursor or\n * resumeAfter token of the old collection is not retried: the token means\n * nothing to a recreated collection.\n */\n private post<R>(operation: UnsV2OperationName, body: Record<string, unknown>, options: CallOptions = {}): Promise<R> {\n const page = body.page as { cursor?: unknown } | undefined;\n const continues = typeof body.cursor === 'string' || typeof body.resumeAfter === 'string' || typeof page?.cursor === 'string';\n return this.runtime.recover(() => this.send<R>(operation, body, options), { retry: !continues });\n }\n\n private async send<R>(operation: UnsV2OperationName, body: Record<string, unknown>, options: CallOptions = {}): Promise<R> {\n const collectionId = await this.runtime.resolve(this.definition);\n return this.runtime.call<R>(operation, { collectionId, ...compact(body) }, { dataSubject: this.runtime.subject(), ...options });\n }\n\n /* ---------------------------------- reads --------------------------------- */\n\n find(filter: Filter = {}, options: FindOptions = {}): Cursor<WithMeta<T>> {\n return new Cursor<WithMeta<T>>(async ({ token, size, sort, projection }) => {\n const result = await this.post<{ items: UnsRecord[]; pageInfo: PageInfo }>('recordFind', {\n filter: Object.keys(filter).length > 0 ? filter : undefined,\n sort,\n projection,\n limit: size,\n cursor: typeof token === 'string' ? token : undefined,\n });\n return {\n items: result.items.map((record) => toDoc<T>(record)),\n next: result.pageInfo.hasMore && result.pageInfo.nextCursor ? result.pageInfo.nextCursor : null,\n };\n }, options);\n }\n\n async findOne(filter: Filter = {}, options: Omit<FindOptions, 'limit'> = {}): Promise<WithMeta<T> | null> {\n const [first] = await this.find(filter, { ...options, limit: 1 }).toArray();\n return first ?? null;\n }\n\n /**\n * One numbered page plus the total match count, for paged list screens.\n * Uses `recordAggregatePipeline` offset paging.\n */\n async findPage(\n filter: Filter = {},\n options: FindPageOptions = {},\n ): Promise<{ items: WithMeta<T>[]; total: number; page: number; pageSize: number }> {\n const page = Math.max(1, Math.trunc(options.page ?? 1));\n const pageSize = Math.min(MAX_PAGE_SIZE, Math.max(1, Math.trunc(options.pageSize ?? 20)));\n const pipeline: Record<string, unknown>[] = [];\n if (Object.keys(filter).length > 0) pipeline.push({ $match: filter });\n const sort = toSortPairs(options.sort);\n if (sort) pipeline.push({ $sort: sort });\n if (options.projection) pipeline.push({ $project: options.projection });\n const [rows, total] = await Promise.all([\n this.post<{ items: WithMeta<T>[] }>('recordAggregatePipeline', { pipeline, page: { mode: 'offset', page, size: pageSize } }),\n this.countDocuments(filter),\n ]);\n return { items: rows.items, total, page, pageSize };\n }\n\n async countDocuments(filter: Filter = {}): Promise<number> {\n const result = await this.post<{ count: number }>('recordCount', {\n filter: Object.keys(filter).length > 0 ? filter : undefined,\n });\n return result.count;\n }\n\n /** Distinct values of a field (every page). */\n async distinct(field: string, filter: Filter = {}): Promise<unknown[]> {\n const values: unknown[] = [];\n for (let page = 1; ; page += 1) {\n const result = await this.post<{ values: unknown[]; pageInfo: PageInfo }>('recordDistinct', {\n field,\n filter: Object.keys(filter).length > 0 ? filter : undefined,\n page: { mode: 'offset', page, size: MAX_PAGE_SIZE },\n });\n values.push(...result.values);\n if (!result.pageInfo.hasMore) return values;\n }\n }\n\n /**\n * Runs a pipeline (`$match`, `$sort`, `$group`, `$project`, `$set`,\n * `$lookup`, `$unwind`, `$skip`, `$limit`, `$count`). `$sort` accepts\n * `{ field: 1 | -1 }`; `$lookup` takes `from` (a declared collection or\n * alias of this App) instead of a collection ID. Rows are whatever the\n * pipeline outputs, not wrapped records.\n *\n * Pipelines of only `$match` / `$sort` page by cursor; any other stage pages\n * by offset (UNS rejects cursors for transformed results). The `$exists`,\n * `$distinct` and `$frequencies` stages are listed in the UNS schema but not\n * executed by the record pipeline; use `countDocuments`, `distinct` or `$group`.\n */\n aggregate<R = Record<string, unknown>>(pipeline: Record<string, unknown>[]): Cursor<R> {\n // Recovery wraps stage preparation too, so a retry re-resolves `$lookup` IDs.\n return new Cursor<R>(({ token, size }) => this.runtime.recover(() => this.aggregatePage<R>(pipeline, token, size), { retry: typeof token !== 'string' }));\n }\n\n private async aggregatePage<R>(\n pipeline: Record<string, unknown>[],\n token: PageToken | null,\n size: number,\n ): Promise<Page<R>> {\n const stages = await this.prepareStages(pipeline);\n const last = stages[stages.length - 1];\n if (last !== undefined && '$count' in last) {\n // A final $count returns one row and forbids an explicit page.\n const result = await this.send<{ items: R[] }>('recordAggregatePipeline', { pipeline: stages });\n return { items: result.items, next: null };\n }\n if (isDirectPipeline(stages)) {\n const result = await this.send<{ items: R[]; pageInfo: PageInfo }>('recordAggregatePipeline', {\n pipeline: stages,\n page: { mode: 'cursor', size, ...(typeof token === 'string' ? { cursor: token } : {}) },\n });\n return { items: result.items, next: result.pageInfo.hasMore && result.pageInfo.nextCursor ? result.pageInfo.nextCursor : null };\n }\n const page = typeof token === 'number' ? token : 1;\n const result = await this.send<{ items: R[]; pageInfo: PageInfo }>('recordAggregatePipeline', {\n pipeline: stages,\n page: { mode: 'offset', page, size },\n });\n return {\n items: result.items,\n next: result.pageInfo.hasMore ? (result.pageInfo.nextPage ?? page + 1) : null,\n };\n }\n\n /** Converts Mongo-style `$sort` objects and resolves `$lookup.from`, recursively. */\n private async prepareStages(pipeline: readonly Record<string, unknown>[]): Promise<Record<string, unknown>[]> {\n return Promise.all(\n pipeline.map(async (stage) => {\n if ('$sort' in stage && !Array.isArray(stage.$sort)) {\n return { ...stage, $sort: toSortPairs(stage.$sort as Sort) };\n }\n if ('$lookup' in stage && stage.$lookup && typeof stage.$lookup === 'object') {\n const { from, pipeline: inner, ...lookup } = stage.$lookup as Record<string, unknown>;\n const resolved: Record<string, unknown> = { ...lookup };\n if (from !== undefined) resolved.collectionId = await this.runtime.resolve(from as CollectionDefinition | string);\n if (Array.isArray(inner)) resolved.pipeline = await this.prepareStages(inner as Record<string, unknown>[]);\n return { ...stage, $lookup: resolved };\n }\n return stage;\n }),\n );\n }\n\n /* --------------------------------- writes --------------------------------- */\n\n async insertOne(document: TInput & { _id?: string }, options: { idempotencyKey?: string } = {}): Promise<{ insertedId: string }> {\n const { id, data } = validateDocument(this.definition, document as Record<string, unknown>);\n const result = await this.post<{ insertedId: string }>('recordInsertOne', { id, data, idempotencyKey: options.idempotencyKey });\n return { insertedId: result.insertedId };\n }\n\n /** Inserts up to 200 documents atomically (all or none). */\n async insertMany(\n documents: readonly (TInput & { _id?: string })[],\n options: { idempotencyKey?: string } = {},\n ): Promise<{ insertedCount: number; insertedIds: string[] }> {\n if (documents.length === 0) return { insertedCount: 0, insertedIds: [] };\n assertAtomicBatch('insertMany', documents.length);\n const prepared = documents.map((document) => validateDocument(this.definition, document as Record<string, unknown>));\n const result = await this.post<WriteResult>('recordInsertMany', {\n documents: prepared.map(({ id, data }) => compact({ id, data })),\n ordered: true,\n atomic: true,\n idempotencyKey: options.idempotencyKey,\n });\n assertNoWriteErrors(result, 'insertMany');\n return { insertedCount: result.insertedCount ?? 0, insertedIds: idsInOrder(result.insertedIds) };\n }\n\n async updateOne(\n filter: Filter,\n update: Update,\n options: UpdateOptions = {},\n ): Promise<{ matchedCount: number; modifiedCount: number; upsertedId: string | null }> {\n const result = await this.post<WriteResult>('recordUpdateOne', {\n filter,\n update: validateUpdate(this.definition, update),\n upsert: options.upsert,\n expectedRevision: options.expectedRevision,\n sort: toSortPairs(options.sort),\n arrayFilters: options.arrayFilters,\n idempotencyKey: options.idempotencyKey,\n });\n return { matchedCount: result.matchedCount ?? 0, modifiedCount: result.modifiedCount ?? 0, upsertedId: result.upsertedId ?? null };\n }\n\n /**\n * Updates every match like Mongo's updateMany: documents commit one by one\n * (not atomically), following `resumeAfter` until every match is processed.\n * A failure stops the run and reports the counts already committed. For\n * all-or-nothing multi-document changes use `data.transact` (≤200 items).\n */\n async updateMany(\n filter: Filter,\n update: Update,\n options: Pick<UpdateOptions, 'arrayFilters'> = {},\n ): Promise<{ matchedCount: number; modifiedCount: number }> {\n const validated = validateUpdate(this.definition, update);\n let matchedCount = 0;\n let modifiedCount = 0;\n let resumeAfter: string | undefined;\n do {\n const result: WriteResult = await this.post<WriteResult>('recordUpdateMany', {\n filter,\n update: validated,\n arrayFilters: options.arrayFilters,\n atomic: false,\n resumeAfter,\n });\n matchedCount += result.matchedCount ?? 0;\n modifiedCount += result.modifiedCount ?? 0;\n assertNoWriteErrors(result, 'updateMany', { matchedCount, modifiedCount });\n resumeAfter = result.hasMore && result.resumeAfter ? result.resumeAfter : undefined;\n } while (resumeAfter);\n return { matchedCount, modifiedCount };\n }\n\n /**\n * Replaces the whole body. Fields written by another App version and not in\n * this declaration are lost — prefer `updateOne` with `$set`.\n */\n async replaceOne(\n filter: Filter,\n replacement: TInput,\n options: Omit<UpdateOptions, 'arrayFilters'> = {},\n ): Promise<{ matchedCount: number; modifiedCount: number; upsertedId: string | null }> {\n const { data } = validateDocument(this.definition, replacement as Record<string, unknown>);\n const result = await this.post<WriteResult>('recordReplaceOne', {\n filter,\n replacement: data,\n upsert: options.upsert,\n expectedRevision: options.expectedRevision,\n sort: toSortPairs(options.sort),\n idempotencyKey: options.idempotencyKey,\n });\n return { matchedCount: result.matchedCount ?? 0, modifiedCount: result.modifiedCount ?? 0, upsertedId: result.upsertedId ?? null };\n }\n\n /** Soft-deletes one record; requires `uns.delete` on the App key. */\n async deleteOne(filter: Filter, options: Pick<UpdateOptions, 'expectedRevision' | 'sort' | 'idempotencyKey'> = {}): Promise<{ deletedCount: number }> {\n const result = await this.post<WriteResult>(\n 'recordDeleteOne',\n { filter, expectedRevision: options.expectedRevision, sort: toSortPairs(options.sort), idempotencyKey: options.idempotencyKey },\n );\n return { deletedCount: result.deletedCount ?? 0 };\n }\n\n /**\n * Soft-deletes every match, one document at a time like Mongo's deleteMany\n * (not atomic), following `resumeAfter`; requires `uns.delete` on the App key.\n */\n async deleteMany(filter: Filter): Promise<{ deletedCount: number }> {\n let deletedCount = 0;\n let resumeAfter: string | undefined;\n do {\n const result: WriteResult = await this.post<WriteResult>('recordDeleteMany', { filter, atomic: false, resumeAfter });\n deletedCount += result.deletedCount ?? 0;\n assertNoWriteErrors(result, 'deleteMany', { deletedCount });\n resumeAfter = result.hasMore && result.resumeAfter ? result.resumeAfter : undefined;\n } while (resumeAfter);\n return { deletedCount };\n }\n\n /**\n * Atomic read-modify-write. A state transition puts the expected state in\n * the filter: `findOneAndUpdate({ _id, status: \"DRAFT\" }, { $set: { status: \"SUBMITTED\" } })`\n * returns null when another request moved the record first.\n */\n async findOneAndUpdate(filter: Filter, update: Update, options: FindOneAndOptions = {}): Promise<WithMeta<T> | null> {\n const result = await this.post<{ value: UnsRecord | null }>('recordFindOneAndUpdate', {\n filter,\n update: validateUpdate(this.definition, update),\n upsert: options.upsert,\n expectedRevision: options.expectedRevision,\n sort: toSortPairs(options.sort),\n arrayFilters: options.arrayFilters,\n returnDocument: options.returnDocument ?? 'after',\n projection: options.projection,\n idempotencyKey: options.idempotencyKey,\n });\n return result.value ? toDoc<T>(result.value) : null;\n }\n\n async findOneAndReplace(\n filter: Filter,\n replacement: TInput,\n options: Omit<FindOneAndOptions, 'arrayFilters'> = {},\n ): Promise<WithMeta<T> | null> {\n const { data } = validateDocument(this.definition, replacement as Record<string, unknown>);\n const result = await this.post<{ value: UnsRecord | null }>('recordFindOneAndReplace', {\n filter,\n replacement: data,\n upsert: options.upsert,\n expectedRevision: options.expectedRevision,\n sort: toSortPairs(options.sort),\n returnDocument: options.returnDocument ?? 'after',\n projection: options.projection,\n idempotencyKey: options.idempotencyKey,\n });\n return result.value ? toDoc<T>(result.value) : null;\n }\n\n async findOneAndDelete(\n filter: Filter,\n options: Pick<FindOneAndOptions, 'expectedRevision' | 'sort' | 'projection' | 'idempotencyKey'> = {},\n ): Promise<WithMeta<T> | null> {\n const result = await this.post<{ value: UnsRecord | null }>(\n 'recordFindOneAndDelete',\n {\n filter,\n expectedRevision: options.expectedRevision,\n sort: toSortPairs(options.sort),\n projection: options.projection,\n idempotencyKey: options.idempotencyKey,\n },\n );\n return result.value ? toDoc<T>(result.value) : null;\n }\n\n /** Up to 200 mixed single-record writes in one atomic call (insertOne / updateOne / replaceOne / deleteOne). */\n async bulkWrite(\n operations: readonly BulkOperation[],\n options: { idempotencyKey?: string } = {},\n ): Promise<{\n insertedCount: number;\n matchedCount: number;\n modifiedCount: number;\n deletedCount: number;\n upsertedCount: number;\n insertedIds: Record<number, string>;\n upsertedIds: Record<number, string>;\n }> {\n assertAtomicBatch('bulkWrite', operations.length);\n const mapped = operations.map((operation) => {\n if ('insertOne' in operation) {\n const { id, data } = validateDocument(this.definition, operation.insertOne.document);\n return { insertOne: compact({ id, data }) };\n }\n if ('updateOne' in operation) {\n const { filter, update, upsert, sort } = operation.updateOne;\n return { updateOne: compact({ filter, update: validateUpdate(this.definition, update), upsert, sort: toSortPairs(sort) }) };\n }\n if ('replaceOne' in operation) {\n const { filter, replacement, upsert, sort } = operation.replaceOne;\n const { data } = validateDocument(this.definition, replacement);\n return { replaceOne: compact({ filter, replacement: data, upsert, sort: toSortPairs(sort) }) };\n }\n if ('deleteOne' in operation) {\n return { deleteOne: compact({ filter: operation.deleteOne.filter, sort: toSortPairs(operation.deleteOne.sort) }) };\n }\n throw new Error(\n `Unsupported bulkWrite operation ${Object.keys(operation).join(', ')}; use updateMany() / deleteMany() or data.transact().`,\n );\n });\n if (mapped.length === 0) {\n return { insertedCount: 0, matchedCount: 0, modifiedCount: 0, deletedCount: 0, upsertedCount: 0, insertedIds: {}, upsertedIds: {} };\n }\n const result = await this.post<WriteResult>(\n 'recordBulkWrite',\n { operations: mapped, ordered: true, atomic: true, idempotencyKey: options.idempotencyKey },\n );\n assertNoWriteErrors(result, 'bulkWrite');\n const numericKeys = (ids: Record<string, string> | undefined) =>\n Object.fromEntries(Object.entries(ids ?? {}).map(([index, id]) => [Number(index), id]));\n return {\n insertedCount: result.insertedCount ?? 0,\n matchedCount: result.matchedCount ?? 0,\n modifiedCount: result.modifiedCount ?? 0,\n deletedCount: result.deletedCount ?? 0,\n upsertedCount: result.upsertedCount ?? 0,\n insertedIds: numericKeys(result.insertedIds),\n upsertedIds: numericKeys(result.upsertedIds),\n };\n }\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** Runs `fn` as part of the business request whose headers are given. */
|
|
2
|
+
export declare function runWithRequestContext<T>(headers: Headers, fn: () => T): T;
|
|
3
|
+
/**
|
|
4
|
+
* Runs `fn` as the App itself, outside any employee's request: use it for
|
|
5
|
+
* work that outlives or is detached from the request (timers, queues, fire-
|
|
6
|
+
* and-forget follow-ups). Its data calls carry no data subject.
|
|
7
|
+
*/
|
|
8
|
+
export declare function runAsApp<T>(fn: () => T): T;
|
|
9
|
+
/** The data subject of the request being served, if any. */
|
|
10
|
+
export declare function currentDataSubject(): string | undefined;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runWithRequestContext = runWithRequestContext;
|
|
4
|
+
exports.runAsApp = runAsApp;
|
|
5
|
+
exports.currentDataSubject = currentDataSubject;
|
|
6
|
+
/**
|
|
7
|
+
* Request context for the data layer.
|
|
8
|
+
*
|
|
9
|
+
* The Tier0 App Gateway signs the current employee into
|
|
10
|
+
* `X-Tier0-App-Data-Subject` on each business request. UNS uses it to narrow
|
|
11
|
+
* App-key access to that employee (data rules, record leases). The data layer
|
|
12
|
+
* forwards it only while serving that request: the App's request entry point
|
|
13
|
+
* opens the context with `runWithRequestContext`, and ensure, seed writes and
|
|
14
|
+
* `runAsApp(...)` background work never carry it.
|
|
15
|
+
*/
|
|
16
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
17
|
+
const cloud_transport_js_1 = require("../cloud-transport.js");
|
|
18
|
+
// One store per process, shared across dev-server module reloads.
|
|
19
|
+
const STORAGE_KEY = Symbol.for('tier0.sdk-v2.data.request-context');
|
|
20
|
+
const globalStore = globalThis;
|
|
21
|
+
const storage = (globalStore[STORAGE_KEY] ??= new node_async_hooks_1.AsyncLocalStorage());
|
|
22
|
+
/** Runs `fn` as part of the business request whose headers are given. */
|
|
23
|
+
function runWithRequestContext(headers, fn) {
|
|
24
|
+
const dataSubject = headers.get(cloud_transport_js_1.UNS_V2_APP_DATA_SUBJECT_HEADER)?.trim() || undefined;
|
|
25
|
+
return storage.run(dataSubject ? { dataSubject } : {}, fn);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Runs `fn` as the App itself, outside any employee's request: use it for
|
|
29
|
+
* work that outlives or is detached from the request (timers, queues, fire-
|
|
30
|
+
* and-forget follow-ups). Its data calls carry no data subject.
|
|
31
|
+
*/
|
|
32
|
+
function runAsApp(fn) {
|
|
33
|
+
return storage.run(null, fn);
|
|
34
|
+
}
|
|
35
|
+
/** The data subject of the request being served, if any. */
|
|
36
|
+
function currentDataSubject() {
|
|
37
|
+
return storage.getStore()?.dataSubject;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/data/context.ts"],"names":[],"mappings":";;AAyBA,sDAGC;AAOD,4BAEC;AAGD,gDAEC;AA1CD;;;;;;;;;GASG;AACH,uDAAqD;AACrD,8DAAuE;AAMvE,kEAAkE;AAClE,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;AACpE,MAAM,WAAW,GAAG,UAEnB,CAAC;AACF,MAAM,OAAO,GAAG,CAAC,WAAW,CAAC,WAAW,CAAC,KAAK,IAAI,oCAAiB,EAAyB,CAAC,CAAC;AAE9F,yEAAyE;AACzE,SAAgB,qBAAqB,CAAI,OAAgB,EAAE,EAAW;IACpE,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,mDAA8B,CAAC,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IACrF,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;AAC7D,CAAC;AAED;;;;GAIG;AACH,SAAgB,QAAQ,CAAI,EAAW;IACrC,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAC/B,CAAC;AAED,4DAA4D;AAC5D,SAAgB,kBAAkB;IAChC,OAAO,OAAO,CAAC,QAAQ,EAAE,EAAE,WAAW,CAAC;AACzC,CAAC","sourcesContent":["/**\n * Request context for the data layer.\n *\n * The Tier0 App Gateway signs the current employee into\n * `X-Tier0-App-Data-Subject` on each business request. UNS uses it to narrow\n * App-key access to that employee (data rules, record leases). The data layer\n * forwards it only while serving that request: the App's request entry point\n * opens the context with `runWithRequestContext`, and ensure, seed writes and\n * `runAsApp(...)` background work never carry it.\n */\nimport { AsyncLocalStorage } from 'node:async_hooks';\nimport { UNS_V2_APP_DATA_SUBJECT_HEADER } from '../cloud-transport.js';\n\ninterface RequestContext {\n dataSubject?: string;\n}\n\n// One store per process, shared across dev-server module reloads.\nconst STORAGE_KEY = Symbol.for('tier0.sdk-v2.data.request-context');\nconst globalStore = globalThis as typeof globalThis & {\n [STORAGE_KEY]?: AsyncLocalStorage<RequestContext | null>;\n};\nconst storage = (globalStore[STORAGE_KEY] ??= new AsyncLocalStorage<RequestContext | null>());\n\n/** Runs `fn` as part of the business request whose headers are given. */\nexport function runWithRequestContext<T>(headers: Headers, fn: () => T): T {\n const dataSubject = headers.get(UNS_V2_APP_DATA_SUBJECT_HEADER)?.trim() || undefined;\n return storage.run(dataSubject ? { dataSubject } : {}, fn);\n}\n\n/**\n * Runs `fn` as the App itself, outside any employee's request: use it for\n * work that outlives or is detached from the request (timers, queues, fire-\n * and-forget follow-ups). Its data calls carry no data subject.\n */\nexport function runAsApp<T>(fn: () => T): T {\n return storage.run(null, fn);\n}\n\n/** The data subject of the request being served, if any. */\nexport function currentDataSubject(): string | undefined {\n return storage.getStore()?.dataSubject;\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@tier0/sdk-v2/data/define` — collection declarations, their types and the
|
|
3
|
+
* schema compiler, without the runtime client. Safe for browser bundles: it
|
|
4
|
+
* loads no Node built-ins, transport, request context or bootstrap, so
|
|
5
|
+
* components and routes can import declarations and `Doc` types from here
|
|
6
|
+
* while data reads and writes stay on the server (`@tier0/sdk-v2/data`).
|
|
7
|
+
*/
|
|
8
|
+
export { defineCollection, MAX_COLLECTIONS } from './define.js';
|
|
9
|
+
export type { CollectionDefinition, CollectionSchema, Doc, IndexSpec, NewDoc, RecordMeta, SeedDoc } from './define.js';
|
|
10
|
+
export { CollectionSchemaError, compileCollection, validateDocument } from './schema.js';
|
|
11
|
+
export type { CompiledCollection, NormalizedIndex, RecordSchema, SchemaIssue } from './schema.js';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateDocument = exports.compileCollection = exports.CollectionSchemaError = exports.MAX_COLLECTIONS = exports.defineCollection = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* `@tier0/sdk-v2/data/define` — collection declarations, their types and the
|
|
6
|
+
* schema compiler, without the runtime client. Safe for browser bundles: it
|
|
7
|
+
* loads no Node built-ins, transport, request context or bootstrap, so
|
|
8
|
+
* components and routes can import declarations and `Doc` types from here
|
|
9
|
+
* while data reads and writes stay on the server (`@tier0/sdk-v2/data`).
|
|
10
|
+
*/
|
|
11
|
+
var define_js_1 = require("./define.js");
|
|
12
|
+
Object.defineProperty(exports, "defineCollection", { enumerable: true, get: function () { return define_js_1.defineCollection; } });
|
|
13
|
+
Object.defineProperty(exports, "MAX_COLLECTIONS", { enumerable: true, get: function () { return define_js_1.MAX_COLLECTIONS; } });
|
|
14
|
+
var schema_js_1 = require("./schema.js");
|
|
15
|
+
Object.defineProperty(exports, "CollectionSchemaError", { enumerable: true, get: function () { return schema_js_1.CollectionSchemaError; } });
|
|
16
|
+
Object.defineProperty(exports, "compileCollection", { enumerable: true, get: function () { return schema_js_1.compileCollection; } });
|
|
17
|
+
Object.defineProperty(exports, "validateDocument", { enumerable: true, get: function () { return schema_js_1.validateDocument; } });
|
|
18
|
+
//# sourceMappingURL=declarations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"declarations.js","sourceRoot":"","sources":["../../../src/data/declarations.ts"],"names":[],"mappings":";;;AAAA;;;;;;GAMG;AACH,yCAAgE;AAAvD,6GAAA,gBAAgB,OAAA;AAAE,4GAAA,eAAe,OAAA;AAE1C,yCAAyF;AAAhF,kHAAA,qBAAqB,OAAA;AAAE,8GAAA,iBAAiB,OAAA;AAAE,6GAAA,gBAAgB,OAAA","sourcesContent":["/**\n * `@tier0/sdk-v2/data/define` — collection declarations, their types and the\n * schema compiler, without the runtime client. Safe for browser bundles: it\n * loads no Node built-ins, transport, request context or bootstrap, so\n * components and routes can import declarations and `Doc` types from here\n * while data reads and writes stay on the server (`@tier0/sdk-v2/data`).\n */\nexport { defineCollection, MAX_COLLECTIONS } from './define.js';\nexport type { CollectionDefinition, CollectionSchema, Doc, IndexSpec, NewDoc, RecordMeta, SeedDoc } from './define.js';\nexport { CollectionSchemaError, compileCollection, validateDocument } from './schema.js';\nexport type { CompiledCollection, NormalizedIndex, RecordSchema, SchemaIssue } from './schema.js';\n"]}
|