@byline/core 0.9.3
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 +373 -0
- package/README.md +17 -0
- package/dist/@types/admin-types.d.ts +275 -0
- package/dist/@types/admin-types.d.ts.map +1 -0
- package/dist/@types/admin-types.js +18 -0
- package/dist/@types/admin-types.js.map +1 -0
- package/dist/@types/collection-types.d.ts +816 -0
- package/dist/@types/collection-types.d.ts.map +1 -0
- package/dist/@types/collection-types.js +217 -0
- package/dist/@types/collection-types.js.map +1 -0
- package/dist/@types/db-types.d.ts +463 -0
- package/dist/@types/db-types.d.ts.map +1 -0
- package/dist/@types/db-types.js +2 -0
- package/dist/@types/db-types.js.map +1 -0
- package/dist/@types/field-data-types.d.ts +147 -0
- package/dist/@types/field-data-types.d.ts.map +1 -0
- package/dist/@types/field-data-types.js +38 -0
- package/dist/@types/field-data-types.js.map +1 -0
- package/dist/@types/field-types.d.ts +579 -0
- package/dist/@types/field-types.d.ts.map +1 -0
- package/dist/@types/field-types.js +32 -0
- package/dist/@types/field-types.js.map +1 -0
- package/dist/@types/index.d.ts +18 -0
- package/dist/@types/index.d.ts.map +1 -0
- package/dist/@types/index.js +18 -0
- package/dist/@types/index.js.map +1 -0
- package/dist/@types/populate-types.d.ts +54 -0
- package/dist/@types/populate-types.d.ts.map +1 -0
- package/dist/@types/populate-types.js +9 -0
- package/dist/@types/populate-types.js.map +1 -0
- package/dist/@types/query-predicate.d.ts +74 -0
- package/dist/@types/query-predicate.d.ts.map +1 -0
- package/dist/@types/query-predicate.js +9 -0
- package/dist/@types/query-predicate.js.map +1 -0
- package/dist/@types/site-config.d.ts +212 -0
- package/dist/@types/site-config.d.ts.map +1 -0
- package/dist/@types/site-config.js +9 -0
- package/dist/@types/site-config.js.map +1 -0
- package/dist/@types/storage-types.d.ts +86 -0
- package/dist/@types/storage-types.d.ts.map +1 -0
- package/dist/@types/storage-types.js +9 -0
- package/dist/@types/storage-types.js.map +1 -0
- package/dist/@types/store-types.d.ts +134 -0
- package/dist/@types/store-types.d.ts.map +1 -0
- package/dist/@types/store-types.js +24 -0
- package/dist/@types/store-types.js.map +1 -0
- package/dist/@types/type-utils.d.ts +17 -0
- package/dist/@types/type-utils.d.ts.map +1 -0
- package/dist/@types/type-utils.js +9 -0
- package/dist/@types/type-utils.js.map +1 -0
- package/dist/auth/apply-before-read.d.ts +36 -0
- package/dist/auth/apply-before-read.d.ts.map +1 -0
- package/dist/auth/apply-before-read.js +68 -0
- package/dist/auth/apply-before-read.js.map +1 -0
- package/dist/auth/apply-before-read.test.node.d.ts +9 -0
- package/dist/auth/apply-before-read.test.node.d.ts.map +1 -0
- package/dist/auth/apply-before-read.test.node.js +144 -0
- package/dist/auth/apply-before-read.test.node.js.map +1 -0
- package/dist/auth/assert-actor-can-perform.d.ts +39 -0
- package/dist/auth/assert-actor-can-perform.d.ts.map +1 -0
- package/dist/auth/assert-actor-can-perform.js +64 -0
- package/dist/auth/assert-actor-can-perform.js.map +1 -0
- package/dist/auth/assert-actor-can-perform.test.node.d.ts +9 -0
- package/dist/auth/assert-actor-can-perform.test.node.d.ts.map +1 -0
- package/dist/auth/assert-actor-can-perform.test.node.js +119 -0
- package/dist/auth/assert-actor-can-perform.test.node.js.map +1 -0
- package/dist/auth/index.d.ts +11 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +11 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/register-collection-abilities.d.ts +40 -0
- package/dist/auth/register-collection-abilities.d.ts.map +1 -0
- package/dist/auth/register-collection-abilities.js +87 -0
- package/dist/auth/register-collection-abilities.js.map +1 -0
- package/dist/auth/register-collection-abilities.test.node.d.ts +9 -0
- package/dist/auth/register-collection-abilities.test.node.d.ts.map +1 -0
- package/dist/auth/register-collection-abilities.test.node.js +124 -0
- package/dist/auth/register-collection-abilities.test.node.js.map +1 -0
- package/dist/config/config.d.ts +10 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +108 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/routes.d.ts +16 -0
- package/dist/config/routes.d.ts.map +1 -0
- package/dist/config/routes.js +26 -0
- package/dist/config/routes.js.map +1 -0
- package/dist/config/validate-admin-configs.d.ts +33 -0
- package/dist/config/validate-admin-configs.d.ts.map +1 -0
- package/dist/config/validate-admin-configs.js +250 -0
- package/dist/config/validate-admin-configs.js.map +1 -0
- package/dist/config/validate-admin-configs.test.node.d.ts +9 -0
- package/dist/config/validate-admin-configs.test.node.d.ts.map +1 -0
- package/dist/config/validate-admin-configs.test.node.js +224 -0
- package/dist/config/validate-admin-configs.test.node.js.map +1 -0
- package/dist/config/validate-collections.d.ts +33 -0
- package/dist/config/validate-collections.d.ts.map +1 -0
- package/dist/config/validate-collections.js +70 -0
- package/dist/config/validate-collections.js.map +1 -0
- package/dist/config/validate-collections.test.node.d.ts +9 -0
- package/dist/config/validate-collections.test.node.d.ts.map +1 -0
- package/dist/config/validate-collections.test.node.js +149 -0
- package/dist/config/validate-collections.test.node.js.map +1 -0
- package/dist/core.d.ts +89 -0
- package/dist/core.d.ts.map +1 -0
- package/dist/core.js +99 -0
- package/dist/core.js.map +1 -0
- package/dist/defaults/default-values.d.ts +13 -0
- package/dist/defaults/default-values.d.ts.map +1 -0
- package/dist/defaults/default-values.js +60 -0
- package/dist/defaults/default-values.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/errors.d.ts +98 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +134 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/logger.d.ts +62 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +120 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/registry.d.ts +65 -0
- package/dist/lib/registry.d.ts.map +1 -0
- package/dist/lib/registry.js +133 -0
- package/dist/lib/registry.js.map +1 -0
- package/dist/logger/index.d.ts +3 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js +3 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/patches/apply-patches.d.ts +21 -0
- package/dist/patches/apply-patches.d.ts.map +1 -0
- package/dist/patches/apply-patches.js +357 -0
- package/dist/patches/apply-patches.js.map +1 -0
- package/dist/patches/index.d.ts +3 -0
- package/dist/patches/index.d.ts.map +1 -0
- package/dist/patches/index.js +4 -0
- package/dist/patches/index.js.map +1 -0
- package/dist/patches/patch-types.d.ts +82 -0
- package/dist/patches/patch-types.d.ts.map +1 -0
- package/dist/patches/patch-types.js +3 -0
- package/dist/patches/patch-types.js.map +1 -0
- package/dist/patches/patch.test.node.d.ts +2 -0
- package/dist/patches/patch.test.node.d.ts.map +1 -0
- package/dist/patches/patch.test.node.js +193 -0
- package/dist/patches/patch.test.node.js.map +1 -0
- package/dist/query/parse-where.d.ts +100 -0
- package/dist/query/parse-where.d.ts.map +1 -0
- package/dist/query/parse-where.js +352 -0
- package/dist/query/parse-where.js.map +1 -0
- package/dist/query/parse-where.test.node.d.ts +9 -0
- package/dist/query/parse-where.test.node.d.ts.map +1 -0
- package/dist/query/parse-where.test.node.js +581 -0
- package/dist/query/parse-where.test.node.js.map +1 -0
- package/dist/schemas/zod/builder.d.ts +466 -0
- package/dist/schemas/zod/builder.d.ts.map +1 -0
- package/dist/schemas/zod/builder.js +276 -0
- package/dist/schemas/zod/builder.js.map +1 -0
- package/dist/schemas/zod/cache.d.ts +14 -0
- package/dist/schemas/zod/cache.d.ts.map +1 -0
- package/dist/schemas/zod/cache.js +40 -0
- package/dist/schemas/zod/cache.js.map +1 -0
- package/dist/schemas/zod/index.d.ts +4 -0
- package/dist/schemas/zod/index.d.ts.map +1 -0
- package/dist/schemas/zod/index.js +4 -0
- package/dist/schemas/zod/index.js.map +1 -0
- package/dist/schemas/zod/types.d.ts +13 -0
- package/dist/schemas/zod/types.d.ts.map +1 -0
- package/dist/schemas/zod/types.js +2 -0
- package/dist/schemas/zod/types.js.map +1 -0
- package/dist/services/collection-bootstrap.d.ts +46 -0
- package/dist/services/collection-bootstrap.d.ts.map +1 -0
- package/dist/services/collection-bootstrap.js +108 -0
- package/dist/services/collection-bootstrap.js.map +1 -0
- package/dist/services/collection-bootstrap.test.node.d.ts +9 -0
- package/dist/services/collection-bootstrap.test.node.d.ts.map +1 -0
- package/dist/services/collection-bootstrap.test.node.js +208 -0
- package/dist/services/collection-bootstrap.test.node.js.map +1 -0
- package/dist/services/document-lifecycle.d.ts +245 -0
- package/dist/services/document-lifecycle.d.ts.map +1 -0
- package/dist/services/document-lifecycle.js +481 -0
- package/dist/services/document-lifecycle.js.map +1 -0
- package/dist/services/document-lifecycle.test.node.d.ts +9 -0
- package/dist/services/document-lifecycle.test.node.d.ts.map +1 -0
- package/dist/services/document-lifecycle.test.node.js +781 -0
- package/dist/services/document-lifecycle.test.node.js.map +1 -0
- package/dist/services/document-read.d.ts +26 -0
- package/dist/services/document-read.d.ts.map +1 -0
- package/dist/services/document-read.js +60 -0
- package/dist/services/document-read.js.map +1 -0
- package/dist/services/field-upload.d.ts +100 -0
- package/dist/services/field-upload.d.ts.map +1 -0
- package/dist/services/field-upload.js +328 -0
- package/dist/services/field-upload.js.map +1 -0
- package/dist/services/field-upload.test.node.d.ts +9 -0
- package/dist/services/field-upload.test.node.d.ts.map +1 -0
- package/dist/services/field-upload.test.node.js +337 -0
- package/dist/services/field-upload.test.node.js.map +1 -0
- package/dist/services/index.d.ts +10 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +11 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/populate.d.ts +299 -0
- package/dist/services/populate.d.ts.map +1 -0
- package/dist/services/populate.js +484 -0
- package/dist/services/populate.js.map +1 -0
- package/dist/services/populate.test.node.d.ts +9 -0
- package/dist/services/populate.test.node.d.ts.map +1 -0
- package/dist/services/populate.test.node.js +910 -0
- package/dist/services/populate.test.node.js.map +1 -0
- package/dist/services/relation-projection.d.ts +52 -0
- package/dist/services/relation-projection.d.ts.map +1 -0
- package/dist/services/relation-projection.js +81 -0
- package/dist/services/relation-projection.js.map +1 -0
- package/dist/services/richtext-populate.d.ts +87 -0
- package/dist/services/richtext-populate.d.ts.map +1 -0
- package/dist/services/richtext-populate.js +189 -0
- package/dist/services/richtext-populate.js.map +1 -0
- package/dist/services/richtext-populate.test.node.d.ts +9 -0
- package/dist/services/richtext-populate.test.node.d.ts.map +1 -0
- package/dist/services/richtext-populate.test.node.js +197 -0
- package/dist/services/richtext-populate.test.node.js.map +1 -0
- package/dist/storage/collection-fingerprint.d.ts +21 -0
- package/dist/storage/collection-fingerprint.d.ts.map +1 -0
- package/dist/storage/collection-fingerprint.js +172 -0
- package/dist/storage/collection-fingerprint.js.map +1 -0
- package/dist/storage/collection-fingerprint.test.node.d.ts +9 -0
- package/dist/storage/collection-fingerprint.test.node.d.ts.map +1 -0
- package/dist/storage/collection-fingerprint.test.node.js +256 -0
- package/dist/storage/collection-fingerprint.test.node.js.map +1 -0
- package/dist/storage/field-store-map.d.ts +59 -0
- package/dist/storage/field-store-map.d.ts.map +1 -0
- package/dist/storage/field-store-map.js +75 -0
- package/dist/storage/field-store-map.js.map +1 -0
- package/dist/storage/field-store-map.test.node.d.ts +9 -0
- package/dist/storage/field-store-map.test.node.d.ts.map +1 -0
- package/dist/storage/field-store-map.test.node.js +117 -0
- package/dist/storage/field-store-map.test.node.js.map +1 -0
- package/dist/storage/index.d.ts +10 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +10 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/utils/normalise-dates.d.ts +15 -0
- package/dist/utils/normalise-dates.d.ts.map +1 -0
- package/dist/utils/normalise-dates.js +22 -0
- package/dist/utils/normalise-dates.js.map +1 -0
- package/dist/utils/slugify.d.ts +56 -0
- package/dist/utils/slugify.d.ts.map +1 -0
- package/dist/utils/slugify.js +91 -0
- package/dist/utils/slugify.js.map +1 -0
- package/dist/utils/slugify.test.node.d.ts +9 -0
- package/dist/utils/slugify.test.node.d.ts.map +1 -0
- package/dist/utils/slugify.test.node.js +86 -0
- package/dist/utils/slugify.test.node.js.map +1 -0
- package/dist/utils/storage-utils.d.ts +36 -0
- package/dist/utils/storage-utils.d.ts.map +1 -0
- package/dist/utils/storage-utils.js +38 -0
- package/dist/utils/storage-utils.js.map +1 -0
- package/dist/utils/utils.general.d.ts +64 -0
- package/dist/utils/utils.general.d.ts.map +1 -0
- package/dist/utils/utils.general.js +219 -0
- package/dist/utils/utils.general.js.map +1 -0
- package/dist/validation/index.d.ts +9 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +9 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/shared.d.ts +36 -0
- package/dist/validation/shared.d.ts.map +1 -0
- package/dist/validation/shared.js +42 -0
- package/dist/validation/shared.js.map +1 -0
- package/dist/workflow/index.d.ts +2 -0
- package/dist/workflow/index.d.ts.map +1 -0
- package/dist/workflow/index.js +3 -0
- package/dist/workflow/index.js.map +1 -0
- package/dist/workflow/workflow.d.ts +40 -0
- package/dist/workflow/workflow.d.ts.map +1 -0
- package/dist/workflow/workflow.js +96 -0
- package/dist/workflow/workflow.js.map +1 -0
- package/dist/workflow/workflow.test.node.d.ts +2 -0
- package/dist/workflow/workflow.test.node.d.ts.map +1 -0
- package/dist/workflow/workflow.test.node.js +198 -0
- package/dist/workflow/workflow.test.node.js.map +1 -0
- package/package.json +88 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This Source Code is subject to the terms of the Mozilla Public
|
|
3
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
4
|
+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
5
|
+
*
|
|
6
|
+
* Copyright (c) Infonomic Company Limited
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Relationship population service.
|
|
10
|
+
*
|
|
11
|
+
* `populateDocuments` walks a set of reconstructed documents, finds every
|
|
12
|
+
* relation leaf that matches a caller-supplied populate spec, batches
|
|
13
|
+
* fetches against each target collection (one DB round-trip per depth
|
|
14
|
+
* level per target collection), and replaces each leaf in place with the
|
|
15
|
+
* populated document. Missing targets become a `{ _resolved: false }`
|
|
16
|
+
* stub; already-visited targets become a `{ _cycle: true }` stub.
|
|
17
|
+
*
|
|
18
|
+
* Consumed by both `@byline/client` (external read API with `populate`
|
|
19
|
+
* and `depth` options) and the admin webapp's API-preview server fn.
|
|
20
|
+
*
|
|
21
|
+
* A request-scoped `ReadContext` is threaded through the walk. Its
|
|
22
|
+
* `visited` set and `readCount` budget guard against recursive reads —
|
|
23
|
+
* particularly the A→B→A failure mode that appears when future
|
|
24
|
+
* `afterRead` hooks invoke their own reads from within populated
|
|
25
|
+
* documents. The guard is in place from day one so that the hook work
|
|
26
|
+
* in Phase 4+ cannot reintroduce the problem.
|
|
27
|
+
*
|
|
28
|
+
* See docs/analysis/RELATIONSHIPS-ANALYSIS.md for the full design rationale.
|
|
29
|
+
*
|
|
30
|
+
* ---------------------------------------------------------------------
|
|
31
|
+
* DSL summary
|
|
32
|
+
* ---------------------------------------------------------------------
|
|
33
|
+
*
|
|
34
|
+
* The populate DSL has two independent axes:
|
|
35
|
+
*
|
|
36
|
+
* 1. **Scope** — which relations in the *source* document to walk.
|
|
37
|
+
* 2. **Projection** — which fields of each *target* document to load.
|
|
38
|
+
*
|
|
39
|
+
* The top-level `populate` value selects scope + (optionally) a uniform
|
|
40
|
+
* projection across the whole tree:
|
|
41
|
+
*
|
|
42
|
+
* - `populate: true` → walk every relation leaf,
|
|
43
|
+
* default projection at every
|
|
44
|
+
* depth. See below for exactly
|
|
45
|
+
* what the default projection
|
|
46
|
+
* returns.
|
|
47
|
+
* - `populate: '*'` → walk every relation leaf, full
|
|
48
|
+
* document projection at every
|
|
49
|
+
* depth. Symmetric with the
|
|
50
|
+
* sub-spec shorthand and intended
|
|
51
|
+
* for tools like the admin API
|
|
52
|
+
* preview where the whole tree
|
|
53
|
+
* should be visible.
|
|
54
|
+
* - `populate: { name: … }` → walk only the named relations.
|
|
55
|
+
* - `populate: undefined` → skip populate entirely (no-op).
|
|
56
|
+
*
|
|
57
|
+
* Default projection — exactly what comes back for `true` (and for any
|
|
58
|
+
* sub-spec whose `select` is omitted):
|
|
59
|
+
*
|
|
60
|
+
* - **Document row metadata, always present** (lives on the
|
|
61
|
+
* `document_versions` row, not in the `store_*` tables, so it is
|
|
62
|
+
* returned regardless of the `fields` projection):
|
|
63
|
+
* `document_version_id`, `document_id`, `collection_id`, `path`,
|
|
64
|
+
* `status`, `created_at`, `updated_at`.
|
|
65
|
+
* - **The `useAsTitle` field** (schema-declared identity field;
|
|
66
|
+
* falls back to the first declared text field when `useAsTitle`
|
|
67
|
+
* is not set on the `CollectionDefinition`). This is the one
|
|
68
|
+
* entry added to the `fields` object.
|
|
69
|
+
*
|
|
70
|
+
* In effect "default projection" is "enough to identify and label the
|
|
71
|
+
* target" — document metadata for wiring, plus one user-defined field
|
|
72
|
+
* (typically `title`) for a human-readable label. Callers wanting more
|
|
73
|
+
* use `'*'` (full doc) or `{ select: [...] }` (explicit fields).
|
|
74
|
+
*
|
|
75
|
+
* Each matched leaf carries a `PopulateFieldSpec` that selects projection:
|
|
76
|
+
*
|
|
77
|
+
* - `true` → default projection: the target's
|
|
78
|
+
* identity field (`useAsTitle`,
|
|
79
|
+
* falling back to the first text
|
|
80
|
+
* field). Document metadata
|
|
81
|
+
* (`document_id`, `collection_id`,
|
|
82
|
+
* `path`, `status`, timestamps) is
|
|
83
|
+
* always included for free — it
|
|
84
|
+
* lives on the row, not in the
|
|
85
|
+
* store_* tables.
|
|
86
|
+
* - `'*'` → full document: every field of
|
|
87
|
+
* the target is loaded.
|
|
88
|
+
* - `{ select: [...] }` → explicit field list, merged with
|
|
89
|
+
* the identity field so downstream
|
|
90
|
+
* UI always has a label to render.
|
|
91
|
+
* - `{ populate: {...} }` → nested populate for the next
|
|
92
|
+
* depth level. Combinable with
|
|
93
|
+
* `select`.
|
|
94
|
+
*
|
|
95
|
+
* Examples:
|
|
96
|
+
*
|
|
97
|
+
* populate: true
|
|
98
|
+
* → every relation, default projection at every depth level.
|
|
99
|
+
*
|
|
100
|
+
* populate: '*'
|
|
101
|
+
* → every relation, full projection at every depth level
|
|
102
|
+
* (use for API previews / debug views that want the whole tree).
|
|
103
|
+
*
|
|
104
|
+
* populate: { heroImage: true }
|
|
105
|
+
* → only heroImage, default projection. If heroImage's own
|
|
106
|
+
* relations exist, they populate at the next depth with `true`.
|
|
107
|
+
*
|
|
108
|
+
* populate: { heroImage: '*' }
|
|
109
|
+
* → only heroImage, full document. If heroImage's own relations
|
|
110
|
+
* exist, they populate at the next depth with `'*'` (consistent
|
|
111
|
+
* with how `true` propagates).
|
|
112
|
+
*
|
|
113
|
+
* populate: { author: { select: ['name'] } }
|
|
114
|
+
* → only author; fetch `name` + identity field.
|
|
115
|
+
*
|
|
116
|
+
* populate: { author: { select: ['name'], populate: { employer: '*' } } }
|
|
117
|
+
* → author with `name` at depth 1; employer fully populated at depth 2.
|
|
118
|
+
*
|
|
119
|
+
* Notes:
|
|
120
|
+
*
|
|
121
|
+
* - `'*'` belongs on the sub-spec (or as the whole top-level spec),
|
|
122
|
+
* not inside `select`. `select` is always an explicit field list.
|
|
123
|
+
* - Projection defaults are transitive at every depth: `true` propagates
|
|
124
|
+
* `true` into nested levels; `'*'` propagates `'*'`. Explicit
|
|
125
|
+
* `{ populate: {...} }` maps take precedence when declared.
|
|
126
|
+
* - Multiple leaves pointing at the same target document are batched
|
|
127
|
+
* into a single fetch; their projection specs are merged (any `'*'`
|
|
128
|
+
* wins; otherwise selects union together, identity field is always
|
|
129
|
+
* added).
|
|
130
|
+
*/
|
|
131
|
+
import type { RequestContext } from '@byline/auth';
|
|
132
|
+
import type { CollectionDefinition, FieldSet, IDbAdapter, PopulateFieldSpec, PopulateSpec, ReadContext, ReadMode, RelatedDocumentValue, RelationField } from '../@types/index.js';
|
|
133
|
+
export type { ReadContext } from '../@types/index.js';
|
|
134
|
+
/** Build a fresh ReadContext. */
|
|
135
|
+
export declare function createReadContext(overrides?: Partial<ReadContext>): ReadContext;
|
|
136
|
+
export type { PopulateFieldOptions, PopulateFieldSpec, PopulateMap, PopulateSpec, } from '../@types/populate-types.js';
|
|
137
|
+
export interface PopulateOptions {
|
|
138
|
+
db: IDbAdapter;
|
|
139
|
+
/** Every collection definition in the app — needed to resolve target fields. */
|
|
140
|
+
collections: CollectionDefinition[];
|
|
141
|
+
/** The source collection id for `documents`. */
|
|
142
|
+
collectionId: string;
|
|
143
|
+
/**
|
|
144
|
+
* Documents to populate, as returned from a read operation. Must carry
|
|
145
|
+
* `document_id` and `fields`. Mutated in place — every relation leaf
|
|
146
|
+
* in `fields` that is walked becomes an envelope: the original
|
|
147
|
+
* `{ targetDocumentId, targetCollectionId, relationshipType?,
|
|
148
|
+
* cascadeDelete? }` refs are preserved, and discriminator fields
|
|
149
|
+
* (`_resolved`, `_cycle`) plus an optional `document` property are
|
|
150
|
+
* layered on top. See the `PopulatedRelationValue` /
|
|
151
|
+
* `UnresolvedRelationValue` / `CycleRelationValue` interfaces below.
|
|
152
|
+
*/
|
|
153
|
+
documents: Array<Record<string, any>>;
|
|
154
|
+
/** What to populate. Omit to no-op. */
|
|
155
|
+
populate?: PopulateSpec;
|
|
156
|
+
/**
|
|
157
|
+
* Max walk depth. Defaults to 1 when `populate` is present, 0 otherwise.
|
|
158
|
+
* Clamped to `readContext.maxDepth`.
|
|
159
|
+
*/
|
|
160
|
+
depth?: number;
|
|
161
|
+
/** Locale forwarded to the batch fetch. */
|
|
162
|
+
locale?: string;
|
|
163
|
+
/**
|
|
164
|
+
* Read mode forwarded to `getDocumentsByDocumentIds`. Selects whether
|
|
165
|
+
* populated targets are resolved from `current_documents` (default,
|
|
166
|
+
* `'any'`) or `current_published_documents` (`'published'`). Public
|
|
167
|
+
* consumers of `@byline/client` typically want `'published'` so a
|
|
168
|
+
* populated target that currently has a newer draft still resolves to
|
|
169
|
+
* its last published version rather than leaking a draft.
|
|
170
|
+
*/
|
|
171
|
+
readMode?: ReadMode;
|
|
172
|
+
/**
|
|
173
|
+
* Request-scoped recursion guard. Omit to create a fresh context for
|
|
174
|
+
* this top-level call. Threaded through by future read-side hooks to
|
|
175
|
+
* prevent A→B→A infinite loops.
|
|
176
|
+
*/
|
|
177
|
+
readContext?: ReadContext;
|
|
178
|
+
/**
|
|
179
|
+
* Request-scoped auth context. Required when any target collection in the
|
|
180
|
+
* walk has a `beforeRead` hook configured. Each target's hook is invoked
|
|
181
|
+
* (and cached on `readContext.beforeReadCache`) before its batch fetch,
|
|
182
|
+
* and the resulting predicate is ANDed onto the fetch's WHERE. When
|
|
183
|
+
* omitted — most synthetic / test call paths — `beforeRead` hooks are
|
|
184
|
+
* skipped entirely; the production read paths all forward this through
|
|
185
|
+
* from `CollectionHandle`.
|
|
186
|
+
*/
|
|
187
|
+
requestContext?: RequestContext;
|
|
188
|
+
/**
|
|
189
|
+
* Skip `beforeRead` hook resolution on every target collection. The
|
|
190
|
+
* top-level read's `_bypassBeforeRead` flag rides through to populate
|
|
191
|
+
* here so admin tooling sees the same unscoped tree on populated
|
|
192
|
+
* relations as it does on the source document.
|
|
193
|
+
*/
|
|
194
|
+
bypassBeforeRead?: true;
|
|
195
|
+
/**
|
|
196
|
+
* Registered richtext server-side populate function (typically resolved
|
|
197
|
+
* once at the top level from `ServerConfig.fields.richText.populate`).
|
|
198
|
+
* Threaded through populate so each materialised target also gets its
|
|
199
|
+
* rich-text leaves populated before its `afterRead` hook fires —
|
|
200
|
+
* ensuring user-land hooks observe fully populated content regardless
|
|
201
|
+
* of whether the target arrived via a relation field on the source or
|
|
202
|
+
* via a richtext document link / inline image. Omit when no richtext
|
|
203
|
+
* adapter is registered.
|
|
204
|
+
*/
|
|
205
|
+
richTextPopulate?: import('../@types/index.js').RichTextPopulateFn;
|
|
206
|
+
}
|
|
207
|
+
/** Marker placed in a relation leaf when the target was already materialised earlier in this request. */
|
|
208
|
+
export interface CycleRelationValue extends RelatedDocumentValue {
|
|
209
|
+
_resolved: true;
|
|
210
|
+
_cycle: true;
|
|
211
|
+
}
|
|
212
|
+
/** Marker placed in a relation leaf when the target was not found (deleted). */
|
|
213
|
+
export interface UnresolvedRelationValue extends RelatedDocumentValue {
|
|
214
|
+
_resolved: false;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Envelope placed in a relation leaf when populate successfully fetched
|
|
218
|
+
* the target document. The `document` field carries the raw storage-shape
|
|
219
|
+
* doc (`@byline/client` then reshapes it to `ClientDocument` during
|
|
220
|
+
* response shaping).
|
|
221
|
+
*/
|
|
222
|
+
export interface PopulatedRelationValue extends RelatedDocumentValue {
|
|
223
|
+
_resolved: true;
|
|
224
|
+
document: Record<string, any>;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Populate relation leaves in `opts.documents` in place, one DB
|
|
228
|
+
* round-trip per depth level per target collection.
|
|
229
|
+
*/
|
|
230
|
+
export declare function populateDocuments(opts: PopulateOptions): Promise<void>;
|
|
231
|
+
declare function visitedKey(collectionId: string, documentId: string): string;
|
|
232
|
+
/**
|
|
233
|
+
* A single relation leaf pending populate. `parent[key]` currently holds a
|
|
234
|
+
* `RelatedDocumentValue`; after processing it holds either a populated
|
|
235
|
+
* document or a stub (cycle / unresolved).
|
|
236
|
+
*/
|
|
237
|
+
interface RelationLeafRef {
|
|
238
|
+
parent: Record<string, any>;
|
|
239
|
+
key: string;
|
|
240
|
+
field: RelationField;
|
|
241
|
+
value: RelatedDocumentValue;
|
|
242
|
+
/**
|
|
243
|
+
* Per-leaf populate sub-spec resolved from the PopulateMap.
|
|
244
|
+
*
|
|
245
|
+
* - `true` → default projection (identity field only).
|
|
246
|
+
* - `'*'` → full document (all fields).
|
|
247
|
+
* - object → explicit `select` and/or nested `populate`.
|
|
248
|
+
*/
|
|
249
|
+
sub: PopulateFieldSpec;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Walk `fields` against `fieldDefs` and collect every relation leaf whose
|
|
253
|
+
* name matches `populate`. Recurses through `group` / `array` / `blocks`
|
|
254
|
+
* using the same populate spec (structure field names do not scope the
|
|
255
|
+
* match — if `populate: { author: true }` is given, every `author`
|
|
256
|
+
* relation found in the tree matches).
|
|
257
|
+
*/
|
|
258
|
+
declare function collectRelationLeaves(fields: Record<string, any>, fieldDefs: FieldSet, populate: PopulateSpec, acc: RelationLeafRef[]): void;
|
|
259
|
+
declare function matchesPopulate(fieldName: string, populate: PopulateSpec): PopulateFieldSpec | undefined;
|
|
260
|
+
/**
|
|
261
|
+
* Build the `fields` array for a batch fetch against a single target
|
|
262
|
+
* collection.
|
|
263
|
+
*
|
|
264
|
+
* - Any leaf with `sub === '*'` → `undefined` (fetch all fields).
|
|
265
|
+
* - Otherwise → union of explicit `select` lists from each leaf,
|
|
266
|
+
* merged with the target's identity field (`useAsTitle`, falling
|
|
267
|
+
* back to the first text field). `sub === true` contributes no
|
|
268
|
+
* selects, so a batch of only-`true` leaves collapses to the
|
|
269
|
+
* identity field alone — the default projection.
|
|
270
|
+
*
|
|
271
|
+
* Document metadata (`document_id`, `collection_id`, `path`, `status`,
|
|
272
|
+
* timestamps) lives on the row itself and is always returned — it does
|
|
273
|
+
* not need to appear in the `fields` list.
|
|
274
|
+
*/
|
|
275
|
+
declare function buildBatchSelect(leaves: RelationLeafRef[], targetDef: CollectionDefinition | undefined): string[] | undefined;
|
|
276
|
+
/**
|
|
277
|
+
* Merge the per-leaf sub-populate specs for all leaves pointing at a
|
|
278
|
+
* single (now-populated) target document into a single PopulateSpec for
|
|
279
|
+
* the next level's walk of that document. Returns `undefined` if the
|
|
280
|
+
* leaves don't request any nested population (in which case the populated
|
|
281
|
+
* document's own relations stay as raw refs).
|
|
282
|
+
*
|
|
283
|
+
* Sub-spec semantics at the next level:
|
|
284
|
+
* - `'*'` → propagate `'*'` (scope=all, full projection, recursive).
|
|
285
|
+
* `'*'` wins over `true` when both appear in the same batch
|
|
286
|
+
* so the caller's "full document" intent is preserved.
|
|
287
|
+
* - `true` → recurse into every relation of the target (scope=all,
|
|
288
|
+
* default projection).
|
|
289
|
+
* - object → forward any nested `populate` map; ignore `select`.
|
|
290
|
+
*/
|
|
291
|
+
declare function reduceChildPopulate(leaves: RelationLeafRef[], targetDocumentId: string): PopulateSpec | undefined;
|
|
292
|
+
export declare const __internal: {
|
|
293
|
+
collectRelationLeaves: typeof collectRelationLeaves;
|
|
294
|
+
matchesPopulate: typeof matchesPopulate;
|
|
295
|
+
buildBatchSelect: typeof buildBatchSelect;
|
|
296
|
+
reduceChildPopulate: typeof reduceChildPopulate;
|
|
297
|
+
visitedKey: typeof visitedKey;
|
|
298
|
+
};
|
|
299
|
+
//# sourceMappingURL=populate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"populate.d.ts","sourceRoot":"","sources":["../../src/services/populate.ts"],"names":[],"mappings":"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"}
|