@contember/bindx 0.1.4 → 0.1.8

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.
Files changed (76) hide show
  1. package/dist/adapter/ContemberAdapter.d.ts +11 -14
  2. package/dist/adapter/ContemberAdapter.d.ts.map +1 -1
  3. package/dist/brand/ComponentBrand.d.ts +1 -24
  4. package/dist/brand/ComponentBrand.d.ts.map +1 -1
  5. package/dist/contember/index.d.ts +1 -2
  6. package/dist/contember/index.d.ts.map +1 -1
  7. package/dist/handles/EntityHandle.d.ts +18 -29
  8. package/dist/handles/EntityHandle.d.ts.map +1 -1
  9. package/dist/handles/FieldHandle.d.ts +5 -3
  10. package/dist/handles/FieldHandle.d.ts.map +1 -1
  11. package/dist/handles/HasManyListHandle.d.ts +4 -3
  12. package/dist/handles/HasManyListHandle.d.ts.map +1 -1
  13. package/dist/handles/HasOneHandle.d.ts +33 -36
  14. package/dist/handles/HasOneHandle.d.ts.map +1 -1
  15. package/dist/handles/PlaceholderHandle.d.ts +9 -19
  16. package/dist/handles/PlaceholderHandle.d.ts.map +1 -1
  17. package/dist/handles/proxyFactory.d.ts +9 -37
  18. package/dist/handles/proxyFactory.d.ts.map +1 -1
  19. package/dist/handles/types.d.ts +4 -0
  20. package/dist/handles/types.d.ts.map +1 -1
  21. package/dist/index.d.ts +3 -2
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/persistence/ContemberSchemaMutationAdapter.d.ts +24 -1
  24. package/dist/persistence/ContemberSchemaMutationAdapter.d.ts.map +1 -1
  25. package/dist/schema/ContemberSchema.d.ts +1 -97
  26. package/dist/schema/ContemberSchema.d.ts.map +1 -1
  27. package/dist/schema/SchemaLoader.d.ts +1 -27
  28. package/dist/schema/SchemaLoader.d.ts.map +1 -1
  29. package/dist/schema/SchemaRegistry.d.ts +1 -94
  30. package/dist/schema/SchemaRegistry.d.ts.map +1 -1
  31. package/dist/schema/roles.d.ts +1 -61
  32. package/dist/schema/roles.d.ts.map +1 -1
  33. package/dist/schema/types.d.ts +1 -178
  34. package/dist/schema/types.d.ts.map +1 -1
  35. package/dist/selection/SelectionMetaCollector.d.ts +1 -31
  36. package/dist/selection/SelectionMetaCollector.d.ts.map +1 -1
  37. package/dist/selection/SelectionScope.d.ts +1 -76
  38. package/dist/selection/SelectionScope.d.ts.map +1 -1
  39. package/dist/selection/buildQuery.d.ts +1 -44
  40. package/dist/selection/buildQuery.d.ts.map +1 -1
  41. package/dist/selection/createFragment.d.ts +1 -28
  42. package/dist/selection/createFragment.d.ts.map +1 -1
  43. package/dist/selection/createSelectionBuilder.d.ts +1 -17
  44. package/dist/selection/createSelectionBuilder.d.ts.map +1 -1
  45. package/dist/selection/queryTypes.d.ts +1 -83
  46. package/dist/selection/queryTypes.d.ts.map +1 -1
  47. package/dist/selection/types.d.ts +1 -237
  48. package/dist/selection/types.d.ts.map +1 -1
  49. package/dist/utils/aliasGenerator.d.ts +1 -24
  50. package/dist/utils/aliasGenerator.d.ts.map +1 -1
  51. package/package.json +4 -4
  52. package/src/adapter/ContemberAdapter.ts +193 -123
  53. package/src/brand/ComponentBrand.ts +1 -28
  54. package/src/contember/index.ts +1 -8
  55. package/src/handles/EntityHandle.ts +131 -61
  56. package/src/handles/FieldHandle.ts +19 -3
  57. package/src/handles/HasManyListHandle.ts +15 -12
  58. package/src/handles/HasOneHandle.ts +98 -66
  59. package/src/handles/PlaceholderHandle.ts +26 -24
  60. package/src/handles/proxyFactory.ts +29 -128
  61. package/src/handles/types.ts +6 -0
  62. package/src/index.ts +22 -3
  63. package/src/persistence/ContemberSchemaMutationAdapter.ts +19 -1
  64. package/src/schema/ContemberSchema.ts +14 -132
  65. package/src/schema/SchemaLoader.ts +1 -93
  66. package/src/schema/SchemaRegistry.ts +1 -286
  67. package/src/schema/roles.ts +10 -83
  68. package/src/schema/types.ts +21 -238
  69. package/src/selection/SelectionMetaCollector.ts +1 -122
  70. package/src/selection/SelectionScope.ts +1 -208
  71. package/src/selection/buildQuery.ts +1 -134
  72. package/src/selection/createFragment.ts +1 -50
  73. package/src/selection/createSelectionBuilder.ts +1 -283
  74. package/src/selection/queryTypes.ts +8 -135
  75. package/src/selection/types.ts +13 -320
  76. package/src/utils/aliasGenerator.ts +1 -56
@@ -1,320 +1,13 @@
1
- import type { ComponentBrand, AnyBrand } from '../brand/ComponentBrand.js'
2
- import type { EntityWhere, EntityOrderBy } from './queryTypes.js'
3
-
4
- /**
5
- * Symbol used to store selection metadata on builder objects
6
- */
7
- export const SELECTION_META = Symbol('SELECTION_META')
8
-
9
- /**
10
- * Options for has-many relation selection with typed filter/orderBy
11
- *
12
- * @typeParam TItem - The related entity type (array item type)
13
- * @typeParam TAlias - Optional alias for the field
14
- */
15
- export interface HasManyOptions<
16
- TItem = unknown,
17
- TAlias extends string = string,
18
- > {
19
- as?: TAlias
20
- filter?: EntityWhere<TItem>
21
- orderBy?: readonly EntityOrderBy<TItem>[]
22
- limit?: number
23
- offset?: number
24
- totalCount?: boolean
25
- }
26
-
27
- /**
28
- * Metadata for a selected field (runtime)
29
- */
30
- export interface SelectionFieldMeta {
31
- /** Original field name in the entity */
32
- fieldName: string
33
- /** Alias (output key) - defaults to fieldName */
34
- alias: string
35
- /** Full path to this field (for JSX components) */
36
- path: string[]
37
- /** Whether this is a relation (has nested fields) */
38
- isRelation: boolean
39
- /** Whether this is an array/has-many relation */
40
- isArray: boolean
41
- /** For relations: nested selection metadata */
42
- nested?: SelectionMeta
43
- /** For has-many: additional parameters */
44
- hasManyParams?: {
45
- filter?: unknown
46
- orderBy?: unknown
47
- limit?: number
48
- offset?: number
49
- totalCount?: boolean
50
- }
51
- }
52
-
53
- /**
54
- * Runtime metadata for a complete selection
55
- */
56
- export interface SelectionMeta {
57
- fields: Map<string, SelectionFieldMeta>
58
- }
59
-
60
- /**
61
- * Extract item type from array
62
- */
63
- type ArrayItemType<T> = T extends Array<infer U> ? U : never
64
-
65
- /**
66
- * A fragment defined with the fluent builder
67
- *
68
- * @typeParam TModel - The entity model type
69
- * @typeParam TResult - The selected fields result type
70
- * @typeParam TBrand - Component brand type for validation (defaults to AnyBrand)
71
- */
72
- export interface FluentFragment<
73
- TModel,
74
- TResult,
75
- TBrand extends AnyBrand = AnyBrand,
76
- > {
77
- /** Runtime metadata */
78
- readonly __meta: SelectionMeta
79
- /** Type brand for result type */
80
- readonly __resultType: TResult
81
- /** Type brand for model type */
82
- readonly __modelType: TModel
83
- /** Marker for type checking */
84
- readonly __isFragment: true
85
- /** Component brand for type-level tracking */
86
- readonly __brand?: TBrand
87
- /** Runtime brand symbols for validation */
88
- readonly __brands?: Set<symbol>
89
- /** Runtime roles for validation */
90
- readonly __roles?: readonly string[]
91
- }
92
-
93
- /**
94
- * Scalar method on selection builder - selects a scalar field
95
- */
96
- export interface ScalarMethod<TEntity, K extends keyof TEntity, TSelected extends object, THasManyParams extends object> {
97
- /** Select field with original name */
98
- (): SelectionBuilder<TEntity, TSelected & Pick<TEntity, K>, THasManyParams>
99
- /** Select field with alias */
100
- <TAlias extends string>(options: { as: TAlias }): SelectionBuilder<
101
- TEntity,
102
- TSelected & { [P in TAlias]: TEntity[K] },
103
- THasManyParams
104
- >
105
- }
106
-
107
- /**
108
- * Has-one method on selection builder - selects a relation to single entity
109
- */
110
- export interface HasOneMethod<
111
- TEntity,
112
- K extends keyof TEntity,
113
- TRelated,
114
- TSelected extends object,
115
- THasManyParams extends object,
116
- > {
117
- /** Select with inline callback */
118
- <TNestedSelected extends object>(
119
- selector: (builder: SelectionBuilder<TRelated>) => SelectionBuilder<TRelated, TNestedSelected, object>,
120
- ): SelectionBuilder<TEntity, TSelected & { [P in K & string]: TNestedSelected }, THasManyParams>
121
-
122
- /** Select with fragment */
123
- <TFragmentResult extends object>(
124
- fragment: FluentFragment<TRelated, TFragmentResult>,
125
- ): SelectionBuilder<TEntity, TSelected & { [P in K & string]: TFragmentResult }, THasManyParams>
126
-
127
- /** Select with multiple fragments (merged) - result type is intersection of all fragment result types */
128
- <T1 extends object, T2 extends object>(
129
- fragment1: FluentFragment<TRelated, T1>,
130
- fragment2: FluentFragment<TRelated, T2>,
131
- ): SelectionBuilder<TEntity, TSelected & { [P in K & string]: T1 & T2 }, THasManyParams>
132
-
133
- /** Select with three fragments (merged) */
134
- <T1 extends object, T2 extends object, T3 extends object>(
135
- fragment1: FluentFragment<TRelated, T1>,
136
- fragment2: FluentFragment<TRelated, T2>,
137
- fragment3: FluentFragment<TRelated, T3>,
138
- ): SelectionBuilder<TEntity, TSelected & { [P in K & string]: T1 & T2 & T3 }, THasManyParams>
139
-
140
- /** Select with alias and callback */
141
- <TAlias extends string, TNestedSelected extends object>(
142
- options: { as: TAlias },
143
- selector: (builder: SelectionBuilder<TRelated>) => SelectionBuilder<TRelated, TNestedSelected, object>,
144
- ): SelectionBuilder<TEntity, TSelected & { [P in TAlias]: TNestedSelected }, THasManyParams>
145
-
146
- /** Select with alias and fragment */
147
- <TAlias extends string, TFragmentResult extends object>(
148
- options: { as: TAlias },
149
- fragment: FluentFragment<TRelated, TFragmentResult>,
150
- ): SelectionBuilder<TEntity, TSelected & { [P in TAlias]: TFragmentResult }, THasManyParams>
151
-
152
- /** Select with alias and two fragments (merged) */
153
- <TAlias extends string, T1 extends object, T2 extends object>(
154
- options: { as: TAlias },
155
- fragment1: FluentFragment<TRelated, T1>,
156
- fragment2: FluentFragment<TRelated, T2>,
157
- ): SelectionBuilder<TEntity, TSelected & { [P in TAlias]: T1 & T2 }, THasManyParams>
158
-
159
- /** Select with alias and three fragments (merged) */
160
- <TAlias extends string, T1 extends object, T2 extends object, T3 extends object>(
161
- options: { as: TAlias },
162
- fragment1: FluentFragment<TRelated, T1>,
163
- fragment2: FluentFragment<TRelated, T2>,
164
- fragment3: FluentFragment<TRelated, T3>,
165
- ): SelectionBuilder<TEntity, TSelected & { [P in TAlias]: T1 & T2 & T3 }, THasManyParams>
166
- }
167
-
168
- /**
169
- * Resolve alias from options or fall back to field name
170
- */
171
- type ResolveAlias<K, TOptions> = TOptions extends { as: infer A extends string } ? A : K & string
172
-
173
- /**
174
- * Has-many method on selection builder - selects a relation to multiple entities
175
- */
176
- export interface HasManyMethod<
177
- TEntity,
178
- K extends keyof TEntity,
179
- TItem,
180
- TSelected extends object,
181
- THasManyParams extends object,
182
- > {
183
- /** Select with inline callback (no options) */
184
- <TNestedSelected extends object>(
185
- selector: (builder: SelectionBuilder<TItem>) => SelectionBuilder<TItem, TNestedSelected, object>,
186
- ): SelectionBuilder<
187
- TEntity,
188
- TSelected & { [P in K & string]: TNestedSelected[] },
189
- THasManyParams & { [P in K & string]: object }
190
- >
191
-
192
- /** Select with fragment (no options) */
193
- <TFragmentResult extends object>(
194
- fragment: FluentFragment<TItem, TFragmentResult>,
195
- ): SelectionBuilder<
196
- TEntity,
197
- TSelected & { [P in K & string]: TFragmentResult[] },
198
- THasManyParams & { [P in K & string]: object }
199
- >
200
-
201
- /** Select with two fragments (merged, no options) */
202
- <T1 extends object, T2 extends object>(
203
- fragment1: FluentFragment<TItem, T1>,
204
- fragment2: FluentFragment<TItem, T2>,
205
- ): SelectionBuilder<
206
- TEntity,
207
- TSelected & { [P in K & string]: (T1 & T2)[] },
208
- THasManyParams & { [P in K & string]: object }
209
- >
210
-
211
- /** Select with three fragments (merged, no options) */
212
- <T1 extends object, T2 extends object, T3 extends object>(
213
- fragment1: FluentFragment<TItem, T1>,
214
- fragment2: FluentFragment<TItem, T2>,
215
- fragment3: FluentFragment<TItem, T3>,
216
- ): SelectionBuilder<
217
- TEntity,
218
- TSelected & { [P in K & string]: (T1 & T2 & T3)[] },
219
- THasManyParams & { [P in K & string]: object }
220
- >
221
-
222
- /** Select with options and callback */
223
- <TOptions extends HasManyOptions<TItem>, TNestedSelected extends object>(
224
- options: TOptions,
225
- selector: (builder: SelectionBuilder<TItem>) => SelectionBuilder<TItem, TNestedSelected, object>,
226
- ): SelectionBuilder<
227
- TEntity,
228
- TSelected & { [P in ResolveAlias<K, TOptions>]: TNestedSelected[] },
229
- THasManyParams & { [P in ResolveAlias<K, TOptions>]: TOptions }
230
- >
231
-
232
- /** Select with options and fragment */
233
- <TOptions extends HasManyOptions<TItem>, TFragmentResult extends object>(
234
- options: TOptions,
235
- fragment: FluentFragment<TItem, TFragmentResult>,
236
- ): SelectionBuilder<
237
- TEntity,
238
- TSelected & { [P in ResolveAlias<K, TOptions>]: TFragmentResult[] },
239
- THasManyParams & { [P in ResolveAlias<K, TOptions>]: TOptions }
240
- >
241
-
242
- /** Select with options and two fragments (merged) */
243
- <TOptions extends HasManyOptions<TItem>, T1 extends object, T2 extends object>(
244
- options: TOptions,
245
- fragment1: FluentFragment<TItem, T1>,
246
- fragment2: FluentFragment<TItem, T2>,
247
- ): SelectionBuilder<
248
- TEntity,
249
- TSelected & { [P in ResolveAlias<K, TOptions>]: (T1 & T2)[] },
250
- THasManyParams & { [P in ResolveAlias<K, TOptions>]: TOptions }
251
- >
252
-
253
- /** Select with options and three fragments (merged) */
254
- <TOptions extends HasManyOptions<TItem>, T1 extends object, T2 extends object, T3 extends object>(
255
- options: TOptions,
256
- fragment1: FluentFragment<TItem, T1>,
257
- fragment2: FluentFragment<TItem, T2>,
258
- fragment3: FluentFragment<TItem, T3>,
259
- ): SelectionBuilder<
260
- TEntity,
261
- TSelected & { [P in ResolveAlias<K, TOptions>]: (T1 & T2 & T3)[] },
262
- THasManyParams & { [P in ResolveAlias<K, TOptions>]: TOptions }
263
- >
264
- }
265
-
266
- /**
267
- * Maps entity fields to their corresponding builder methods
268
- */
269
- type SelectionBuilderMethods<TEntity, TSelected extends object, THasManyParams extends object> = {
270
- [K in keyof TEntity]-?: TEntity[K] extends Array<infer U>
271
- ? HasManyMethod<TEntity, K, U, TSelected, THasManyParams>
272
- : NonNullable<TEntity[K]> extends object
273
- ? HasOneMethod<TEntity, K, NonNullable<TEntity[K]>, TSelected, THasManyParams>
274
- : ScalarMethod<TEntity, K, TSelected, THasManyParams>
275
- }
276
-
277
- /**
278
- * The main fluent selection builder interface.
279
- *
280
- * @typeParam TEntity - The entity type being selected from
281
- * @typeParam TSelected - Accumulated type of selected fields (grows with each selection)
282
- * @typeParam THasManyParams - Record tracking has-many parameters for alias consistency
283
- *
284
- * @example
285
- * ```ts
286
- * // Select scalar fields
287
- * e.id().title().content()
288
- * // Type: { id: string, title: string, content: string }
289
- *
290
- * // Select with alias
291
- * e.title({ as: 'headline' })
292
- * // Type: { headline: string }
293
- *
294
- * // Select has-one relation
295
- * e.author(a => a.name().email())
296
- * // Type: { author: { name: string, email: string } }
297
- *
298
- * // Select has-many with options
299
- * e.tags({ filter: { active: true } }, t => t.name())
300
- * // Type: { tags: { name: string }[] }
301
- * ```
302
- */
303
- export type SelectionBuilder<TEntity, TSelected extends object = object, THasManyParams extends object = object> =
304
- SelectionBuilderMethods<TEntity, TSelected, THasManyParams> & {
305
- [SELECTION_META]: SelectionMeta
306
- /** Type brand for the selected result */
307
- readonly __selected: TSelected
308
- }
309
-
310
- /**
311
- * Extracts the selected type from a SelectionBuilder
312
- */
313
- export type InferSelection<T> = T extends SelectionBuilder<infer _E, infer S, infer _P> ? S : never
314
-
315
- /**
316
- * Type for the fluent definer function used in useEntity/useEntityList
317
- */
318
- export type FluentDefiner<TModel, TResult extends object> = (
319
- builder: SelectionBuilder<TModel>,
320
- ) => SelectionBuilder<TModel, TResult, object>
1
+ export {
2
+ SELECTION_META,
3
+ type SelectionBuilder,
4
+ type SelectionMeta,
5
+ type SelectionFieldMeta,
6
+ type FluentFragment,
7
+ type FluentDefiner,
8
+ type HasManyOptions,
9
+ type InferSelection,
10
+ type ScalarMethod,
11
+ type HasOneMethod,
12
+ type HasManyMethod,
13
+ } from '@contember/bindx-client'
@@ -1,56 +1 @@
1
- import type { HasManyParams } from '../selection/SelectionScope.js'
2
-
3
- /**
4
- * Generates an alias for a has-many relation based on field name and parameters.
5
- *
6
- * If no parameters are provided or all are undefined, returns the fieldName as-is.
7
- * Otherwise, generates a deterministic alias by hashing the parameters.
8
- *
9
- * @param fieldName - The original field name
10
- * @param params - Optional has-many parameters (filter, orderBy, limit, offset)
11
- * @returns The alias to use for this has-many relation
12
- *
13
- * @example
14
- * ```ts
15
- * // No params - returns fieldName
16
- * generateHasManyAlias('tags') // => 'tags'
17
- *
18
- * // With filter - generates unique alias
19
- * generateHasManyAlias('tags', { filter: { active: true } }) // => 'tags_a7x9k2'
20
- *
21
- * // Different params - different aliases
22
- * generateHasManyAlias('tags', { filter: { active: false } }) // => 'tags_b3m1p8'
23
- * ```
24
- */
25
- export function generateHasManyAlias(fieldName: string, params?: HasManyParams): string {
26
- if (!params) {
27
- return fieldName
28
- }
29
-
30
- const { filter, orderBy, limit, offset } = params
31
-
32
- // If all params are undefined, return fieldName
33
- if (filter === undefined && orderBy === undefined && limit === undefined && offset === undefined) {
34
- return fieldName
35
- }
36
-
37
- // Serialize parameters deterministically
38
- const serialized = JSON.stringify({
39
- f: filter,
40
- o: orderBy,
41
- l: limit,
42
- s: offset,
43
- })
44
-
45
- // Simple djb2 hash algorithm
46
- let hash = 5381
47
- for (let i = 0; i < serialized.length; i++) {
48
- hash = ((hash << 5) + hash) + serialized.charCodeAt(i)
49
- hash = hash & hash // Convert to 32-bit integer
50
- }
51
-
52
- // Convert to base36 and take first 6 characters for compact representation
53
- const hashStr = Math.abs(hash).toString(36).slice(0, 6)
54
-
55
- return `${fieldName}_${hashStr}`
56
- }
1
+ export { generateHasManyAlias } from '@contember/bindx-client'