jsonbadger 0.5.0 → 0.6.1

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 (123) hide show
  1. package/README.md +36 -18
  2. package/docs/api/connection.md +144 -0
  3. package/docs/api/delta-tracker.md +106 -0
  4. package/docs/api/document.md +77 -0
  5. package/docs/api/field-types.md +329 -0
  6. package/docs/api/index.md +35 -0
  7. package/docs/api/model.md +392 -0
  8. package/docs/api/query-builder.md +81 -0
  9. package/docs/api/schema.md +204 -0
  10. package/docs/architecture-flow.md +397 -0
  11. package/docs/examples.md +495 -218
  12. package/docs/jsonb-ops.md +171 -0
  13. package/docs/lifecycle/model-compilation.md +111 -0
  14. package/docs/lifecycle.md +146 -0
  15. package/docs/query-translation.md +11 -10
  16. package/package.json +10 -3
  17. package/src/connection/connect.js +12 -17
  18. package/src/connection/connection.js +128 -0
  19. package/src/connection/server-capabilities.js +60 -59
  20. package/src/constants/defaults.js +32 -19
  21. package/src/constants/{id-strategies.js → id-strategy.js} +28 -29
  22. package/src/constants/intake-mode.js +8 -0
  23. package/src/debug/debug-logger.js +17 -15
  24. package/src/errors/model-overwrite-error.js +25 -0
  25. package/src/errors/query-error.js +25 -23
  26. package/src/errors/validation-error.js +25 -23
  27. package/src/field-types/base-field-type.js +137 -140
  28. package/src/field-types/builtins/advanced.js +365 -365
  29. package/src/field-types/builtins/index.js +579 -585
  30. package/src/field-types/field-type-namespace.js +9 -0
  31. package/src/field-types/registry.js +149 -122
  32. package/src/index.js +26 -36
  33. package/src/migration/ensure-index.js +157 -154
  34. package/src/migration/ensure-schema.js +27 -15
  35. package/src/migration/ensure-table.js +44 -31
  36. package/src/migration/schema-indexes-resolver.js +8 -6
  37. package/src/model/document-instance.js +29 -540
  38. package/src/model/document.js +60 -0
  39. package/src/model/factory/constants.js +36 -0
  40. package/src/model/factory/index.js +58 -0
  41. package/src/model/model.js +875 -0
  42. package/src/model/operations/delete-one.js +39 -0
  43. package/src/model/operations/insert-one.js +35 -0
  44. package/src/model/operations/query-builder.js +132 -0
  45. package/src/model/operations/update-one.js +333 -0
  46. package/src/model/state.js +34 -0
  47. package/src/schema/field-definition-parser.js +213 -218
  48. package/src/schema/path-introspection.js +87 -82
  49. package/src/schema/schema-compiler.js +126 -212
  50. package/src/schema/schema.js +621 -138
  51. package/src/sql/index.js +17 -0
  52. package/src/sql/jsonb/ops.js +153 -0
  53. package/src/{query → sql/jsonb}/path-parser.js +54 -43
  54. package/src/sql/jsonb/read/elem-match.js +133 -0
  55. package/src/{query → sql/jsonb/read}/operators/contains.js +13 -7
  56. package/src/sql/jsonb/read/operators/elem-match.js +9 -0
  57. package/src/{query → sql/jsonb/read}/operators/has-all-keys.js +17 -11
  58. package/src/{query → sql/jsonb/read}/operators/has-any-keys.js +18 -11
  59. package/src/sql/jsonb/read/operators/has-key.js +12 -0
  60. package/src/{query → sql/jsonb/read}/operators/jsonpath-exists.js +22 -15
  61. package/src/{query → sql/jsonb/read}/operators/jsonpath-match.js +22 -15
  62. package/src/{query → sql/jsonb/read}/operators/size.js +23 -16
  63. package/src/sql/parameter-binder.js +18 -13
  64. package/src/sql/read/build-count-query.js +12 -0
  65. package/src/sql/read/build-find-query.js +25 -0
  66. package/src/sql/read/limit-skip.js +21 -0
  67. package/src/sql/read/sort.js +85 -0
  68. package/src/sql/read/where/base-fields.js +310 -0
  69. package/src/sql/read/where/casting.js +90 -0
  70. package/src/sql/read/where/context.js +79 -0
  71. package/src/sql/read/where/field-clause.js +58 -0
  72. package/src/sql/read/where/index.js +38 -0
  73. package/src/sql/read/where/operator-entries.js +29 -0
  74. package/src/{query → sql/read/where}/operators/all.js +16 -10
  75. package/src/sql/read/where/operators/eq.js +12 -0
  76. package/src/{query → sql/read/where}/operators/gt.js +23 -16
  77. package/src/{query → sql/read/where}/operators/gte.js +23 -16
  78. package/src/{query → sql/read/where}/operators/in.js +18 -12
  79. package/src/sql/read/where/operators/index.js +40 -0
  80. package/src/{query → sql/read/where}/operators/lt.js +23 -16
  81. package/src/{query → sql/read/where}/operators/lte.js +23 -16
  82. package/src/sql/read/where/operators/ne.js +12 -0
  83. package/src/{query → sql/read/where}/operators/nin.js +18 -12
  84. package/src/{query → sql/read/where}/operators/regex.js +14 -8
  85. package/src/sql/read/where/operators.js +126 -0
  86. package/src/sql/read/where/text-operators.js +83 -0
  87. package/src/sql/run.js +46 -0
  88. package/src/sql/write/build-delete-query.js +33 -0
  89. package/src/sql/write/build-insert-query.js +42 -0
  90. package/src/sql/write/build-update-query.js +65 -0
  91. package/src/utils/assert.js +34 -27
  92. package/src/utils/delta-tracker/.archive/1 tracker-redesign-codex-v2.md +250 -0
  93. package/src/utils/delta-tracker/.archive/1 tracker-redesign-gemini.md +101 -0
  94. package/src/utils/delta-tracker/.archive/2 evaluation by gemini.txt +65 -0
  95. package/src/utils/delta-tracker/.archive/2 evaluation by grok.txt +39 -0
  96. package/src/utils/delta-tracker/.archive/3 gemini evaluate grok.txt +37 -0
  97. package/src/utils/delta-tracker/.archive/3 grok evaluate gemini.txt +63 -0
  98. package/src/utils/delta-tracker/.archive/4 gemini veredict.txt +16 -0
  99. package/src/utils/delta-tracker/.archive/index.1.js +587 -0
  100. package/src/utils/delta-tracker/.archive/index.2.js +612 -0
  101. package/src/utils/delta-tracker/index.js +592 -0
  102. package/src/utils/dirty-tracker/inline.js +335 -0
  103. package/src/utils/dirty-tracker/instance.js +414 -0
  104. package/src/utils/dirty-tracker/static.js +343 -0
  105. package/src/utils/json-safe.js +13 -9
  106. package/src/utils/object-path.js +227 -33
  107. package/src/utils/object.js +408 -168
  108. package/src/utils/string.js +55 -0
  109. package/src/utils/value.js +169 -30
  110. package/docs/api.md +0 -152
  111. package/src/connection/disconnect.js +0 -16
  112. package/src/connection/pool-store.js +0 -46
  113. package/src/model/model-factory.js +0 -555
  114. package/src/query/limit-skip-compiler.js +0 -31
  115. package/src/query/operators/elem-match.js +0 -3
  116. package/src/query/operators/eq.js +0 -6
  117. package/src/query/operators/has-key.js +0 -6
  118. package/src/query/operators/index.js +0 -60
  119. package/src/query/operators/ne.js +0 -6
  120. package/src/query/query-builder.js +0 -93
  121. package/src/query/sort-compiler.js +0 -30
  122. package/src/query/where-compiler.js +0 -477
  123. package/src/sql/sql-runner.js +0 -31
@@ -0,0 +1,329 @@
1
+ # Field Types API
2
+
3
+ Use field types inside `Schema` definitions to describe how each path is interpreted, cast, and validated.
4
+
5
+ ## Quick Start
6
+
7
+ ```js
8
+ import JsonBadger, {Schema} from 'jsonbadger';
9
+
10
+ const user_schema = new Schema({
11
+ name: {type: String, trim: true, minLength: 2},
12
+ age: {type: Number, min: 18},
13
+ active: Boolean,
14
+ tags: [String],
15
+ preferences: {type: Map, of: String},
16
+ payload: {},
17
+ idempotency_key: JsonBadger.field_types.UUIDv7,
18
+ score: {type: 'Double'},
19
+ value: {type: 'Union', of: [String, Number]}
20
+ });
21
+ ```
22
+
23
+ > **Note:** A field type is the per-path type definition. `JsonBadger.field_types.UUIDv7` is the type reference; `{type: JsonBadger.field_types.UUIDv7, required: true}` is the field definition.
24
+
25
+ ## Declaration Forms
26
+
27
+ ### Implicit form
28
+
29
+ ```js
30
+ const schema = new Schema({
31
+ name: String,
32
+ age: Number,
33
+ active: Boolean,
34
+ tags: [String]
35
+ });
36
+ ```
37
+
38
+ ### Explicit form
39
+
40
+ ```js
41
+ const schema = new Schema({
42
+ name: {type: String, trim: true},
43
+ age: {type: Number, min: 18},
44
+ preferences: {type: Map, of: String},
45
+ score: {type: 'Double'}
46
+ });
47
+ ```
48
+
49
+ ### Nested object form
50
+
51
+ ```js
52
+ const schema = new Schema({
53
+ profile: {
54
+ name: String,
55
+ city: String
56
+ }
57
+ });
58
+ ```
59
+
60
+ > **Note:** The key `type` is reserved inside schema definitions. If a nested object really needs a property named `type`, define that property explicitly:
61
+ >
62
+ > ```js
63
+ > const schema = new Schema({
64
+ > asset: {
65
+ > type: {type: String},
66
+ > ticker: String
67
+ > }
68
+ > });
69
+ > ```
70
+
71
+ ## Built-in Field Types
72
+
73
+ The default registry includes these canonical field types:
74
+
75
+ 1. `String`
76
+ 2. `Number`
77
+ 3. `Date`
78
+ 4. `Boolean`
79
+ 5. `UUIDv7`
80
+ 6. `Buffer`
81
+ 7. `Mixed`
82
+ 8. `Array`
83
+ 9. `Map`
84
+ 10. `Decimal128`
85
+ 11. `BigInt`
86
+ 12. `Double`
87
+ 13. `Int32`
88
+ 14. `Union`
89
+
90
+ Use constructor references where they exist:
91
+
92
+ ```js
93
+ const schema = new Schema({
94
+ name: String,
95
+ active: Boolean,
96
+ payload: {},
97
+ tags: [String],
98
+ preferences: {type: Map, of: String}
99
+ });
100
+ ```
101
+
102
+ Use string aliases for advanced built-ins:
103
+
104
+ ```js
105
+ const schema = new Schema({
106
+ score: {type: 'Double'},
107
+ count: {type: 'Int32'},
108
+ value: {type: 'Union', of: [String, Number]}
109
+ });
110
+ ```
111
+
112
+ Use the public namespace for the built-in UUIDv7 reference and boolean casting sets:
113
+
114
+ ```js
115
+ JsonBadger.field_types.UUIDv7;
116
+ JsonBadger.field_types.boolean_convert_to_true;
117
+ JsonBadger.field_types.boolean_convert_to_false;
118
+ ```
119
+
120
+ ## Common Options
121
+
122
+ These options are implemented by the base field-type layer and work across field types:
123
+
124
+ 1. `required`
125
+ 2. `default`
126
+ 3. `validate`
127
+ 4. `get`
128
+ 5. `set`
129
+ 6. `alias`
130
+
131
+ ```js
132
+ const schema = new Schema({
133
+ name: {
134
+ type: String,
135
+ required: true,
136
+ default: 'Anonymous',
137
+ set(value) {
138
+ return value.trim();
139
+ },
140
+ get(value) {
141
+ return value;
142
+ },
143
+ validate(value) {
144
+ return value.length >= 2;
145
+ },
146
+ alias: 'display_name'
147
+ }
148
+ });
149
+ ```
150
+
151
+ ## Type-Specific Options
152
+
153
+ ### String
154
+
155
+ ```js
156
+ const schema = new Schema({
157
+ name: {
158
+ type: String,
159
+ trim: true,
160
+ lowercase: true,
161
+ match: /^[a-z ]+$/,
162
+ minLength: 2,
163
+ maxLength: 40
164
+ }
165
+ });
166
+ ```
167
+
168
+ Supported options:
169
+
170
+ 1. `trim`
171
+ 2. `lowercase`
172
+ 3. `uppercase`
173
+ 4. `match`
174
+ 5. `enum`
175
+ 6. `minLength`
176
+ 7. `maxLength`
177
+
178
+ ### Number
179
+
180
+ ```js
181
+ const schema = new Schema({
182
+ age: {
183
+ type: Number,
184
+ min: 18,
185
+ max: 99
186
+ }
187
+ });
188
+ ```
189
+
190
+ Supported options:
191
+
192
+ 1. `min`
193
+ 2. `max`
194
+ 3. `enum`
195
+
196
+ ### Date
197
+
198
+ ```js
199
+ const schema = new Schema({
200
+ published_at: {
201
+ type: Date,
202
+ min: new Date('2020-01-01')
203
+ }
204
+ });
205
+ ```
206
+
207
+ Supported options:
208
+
209
+ 1. `min`
210
+ 2. `max`
211
+
212
+ ### Array
213
+
214
+ ```js
215
+ const schema = new Schema({
216
+ tags: [String],
217
+ scores: {type: Array, of: Number}
218
+ });
219
+ ```
220
+
221
+ > **Note:** Arrays default to `[]`. Set `default: undefined` when you want to disable the implicit empty-array default.
222
+
223
+ ### Map
224
+
225
+ ```js
226
+ const schema = new Schema({
227
+ preferences: {type: Map, of: String}
228
+ });
229
+ ```
230
+
231
+ ### Union
232
+
233
+ ```js
234
+ const schema = new Schema({
235
+ value: {
236
+ type: 'Union',
237
+ of: [String, Number]
238
+ }
239
+ });
240
+ ```
241
+
242
+ ## Runtime Notes
243
+
244
+ 1. `Mixed` accepts any value and skips type-specific casting.
245
+ 2. `Boolean` casting uses the public sets `JsonBadger.field_types.boolean_convert_to_true` and `JsonBadger.field_types.boolean_convert_to_false`.
246
+ 3. `UUIDv7` normalizes to lowercase and rejects non-v7 UUID strings.
247
+ 4. `Map` casts input into a plain object with string keys.
248
+ 5. `Union` keeps exact matches first, then tries casts in declared order.
249
+
250
+ ## Introspection
251
+
252
+ Use `schema.get_path(path_name)` to inspect one compiled field type:
253
+
254
+ ```js
255
+ const schema = new Schema({
256
+ name: {type: String, minLength: 2}
257
+ });
258
+
259
+ const field_type = schema.get_path('name');
260
+ const type_name = schema.get_path_type('name');
261
+ ```
262
+
263
+ The field-type instance exposes these introspection fields:
264
+
265
+ 1. `path`
266
+ 2. `instance`
267
+ 3. `validators`
268
+ 4. `regExp`
269
+ 5. `enum_values`
270
+
271
+ ## Registry Namespace
272
+
273
+ Use the public registry namespace to register or resolve field types.
274
+
275
+ ### `JsonBadger.field_type.register(name, type_constructor, aliases?)`
276
+
277
+ ```js
278
+ JsonBadger.field_type.register('Money', money_field_type, ['money']);
279
+ ```
280
+
281
+ Registers a canonical name and optional aliases.
282
+
283
+ ### `JsonBadger.field_type.resolve(type)`
284
+
285
+ ```js
286
+ const type_name = JsonBadger.field_type.resolve('money');
287
+ ```
288
+
289
+ Returns the canonical registered name, or `null` when the alias is unknown.
290
+
291
+ ## Custom Field Types
292
+
293
+ Custom field types are registry-based.
294
+
295
+ Register the type first, then use the registered name or alias in schema definitions.
296
+
297
+ ```js
298
+ class money_field_type {
299
+ constructor(path, options) {
300
+ this.path = path;
301
+ this.options = options || {};
302
+ this.instance = 'Money';
303
+ }
304
+
305
+ validate(value, context) {
306
+ return;
307
+ }
308
+ }
309
+
310
+ JsonBadger.field_type.register('Money', money_field_type, ['money']);
311
+ ```
312
+
313
+ ```js
314
+ const schema = new Schema({
315
+ price: {type: 'Money'},
316
+ discount_price: {type: 'money'}
317
+ });
318
+ ```
319
+
320
+ Custom field types should follow the same runtime shape as built-in field types. At minimum, the constructed instance should expose:
321
+
322
+ 1. `path`
323
+ 2. `options`
324
+ 3. `instance`
325
+ 4. `validate(value, context)` when custom validation is needed
326
+
327
+ Use registration names or aliases in schema definitions. Raw constructor references are not the documented custom-type entry path.
328
+
329
+ > **Note:** There is no separate required base class for custom types. The important part is matching the field-type instance contract the schema/runtime expects.
@@ -0,0 +1,35 @@
1
+ # API Index
2
+
3
+ Use this directory for module-scoped API reference pages.
4
+
5
+ ## TOC
6
+
7
+ - [API Index](#api-index)
8
+ - [Top-level Exports](#top-level-exports)
9
+ - [Module Docs](#module-docs)
10
+
11
+ ## Top-level Exports
12
+
13
+ Named exports:
14
+ - `connect(uri, options)`
15
+ - `Schema`
16
+ - `ID_STRATEGY`
17
+ - `field_type`
18
+
19
+ Default export (`JsonBadger`) includes the same plus:
20
+ - `field_type.register(name, type_constructor, aliases?)`
21
+ - `field_type.resolve(type)`
22
+ - `field_types.UUIDv7`
23
+ - `field_types.boolean_convert_to_true`
24
+ - `field_types.boolean_convert_to_false`
25
+
26
+ ## Module Docs
27
+
28
+ - [`connection.md`](connection.md)
29
+ - [`delta-tracker.md`](delta-tracker.md)
30
+ - [`document.md`](document.md)
31
+ - [`schema.md`](schema.md)
32
+ - [`model.md`](model.md)
33
+ - [`query-builder.md`](query-builder.md)
34
+ - [`field-types.md`](field-types.md)
35
+ - [`../query-translation.md`](../query-translation.md)