@bsb/base 9.0.4 → 9.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.
Files changed (218) hide show
  1. package/lib/base/BSBConfig.d.ts +3 -3
  2. package/lib/base/BSBConfig.js +9 -14
  3. package/lib/base/BSBConfig.js.map +1 -1
  4. package/lib/base/BSBEvents.d.ts +3 -3
  5. package/lib/base/BSBEvents.js +12 -17
  6. package/lib/base/BSBEvents.js.map +1 -1
  7. package/lib/base/BSBObservable.d.ts +4 -4
  8. package/lib/base/BSBObservable.js +17 -22
  9. package/lib/base/BSBObservable.js.map +1 -1
  10. package/lib/base/BSBService.d.ts +7 -8
  11. package/lib/base/BSBService.js +17 -22
  12. package/lib/base/BSBService.js.map +1 -1
  13. package/lib/base/BSBServiceClient.d.ts +4 -4
  14. package/lib/base/BSBServiceClient.js +12 -18
  15. package/lib/base/BSBServiceClient.js.map +1 -1
  16. package/lib/base/EventValidator.d.ts +16 -17
  17. package/lib/base/EventValidator.js +13 -34
  18. package/lib/base/EventValidator.js.map +1 -1
  19. package/lib/base/ObservableBackend.d.ts +2 -2
  20. package/lib/base/ObservableBackend.js +21 -26
  21. package/lib/base/ObservableBackend.js.map +1 -1
  22. package/lib/base/PluginConfig.d.ts +9 -7
  23. package/lib/base/PluginConfig.js +4 -11
  24. package/lib/base/PluginConfig.js.map +1 -1
  25. package/lib/base/PluginEvents.d.ts +4 -4
  26. package/lib/base/PluginEvents.js +4 -9
  27. package/lib/base/PluginEvents.js.map +1 -1
  28. package/lib/base/PluginObservable.d.ts +13 -14
  29. package/lib/base/PluginObservable.js +4 -8
  30. package/lib/base/PluginObservable.js.map +1 -1
  31. package/lib/base/ResourceContext.d.ts +1 -1
  32. package/lib/base/ResourceContext.js +1 -5
  33. package/lib/base/ResourceContext.js.map +1 -1
  34. package/lib/base/base.d.ts +3 -3
  35. package/lib/base/base.js +10 -18
  36. package/lib/base/base.js.map +1 -1
  37. package/lib/base/errorMessages.d.ts +1 -1
  38. package/lib/base/errorMessages.js +6 -11
  39. package/lib/base/errorMessages.js.map +1 -1
  40. package/lib/base/factory.d.ts +1 -1
  41. package/lib/base/factory.js +19 -22
  42. package/lib/base/factory.js.map +1 -1
  43. package/lib/base/functions.d.ts +19 -14
  44. package/lib/base/functions.js +19 -26
  45. package/lib/base/functions.js.map +1 -1
  46. package/lib/base/index.d.ts +18 -18
  47. package/lib/base/index.js +18 -37
  48. package/lib/base/index.js.map +1 -1
  49. package/lib/base/logFormatter.d.ts +1 -1
  50. package/lib/base/logFormatter.js +10 -14
  51. package/lib/base/logFormatter.js.map +1 -1
  52. package/lib/base/module-runtime.d.ts +3 -0
  53. package/lib/base/module-runtime.js +15 -0
  54. package/lib/base/module-runtime.js.map +1 -0
  55. package/lib/base/tools.d.ts +1 -1
  56. package/lib/base/tools.js +9 -13
  57. package/lib/base/tools.js.map +1 -1
  58. package/lib/cli.js +13 -12
  59. package/lib/cli.js.map +1 -1
  60. package/lib/dev.js +22 -11
  61. package/lib/dev.js.map +1 -1
  62. package/lib/index.d.ts +3 -3
  63. package/lib/index.js +3 -19
  64. package/lib/index.js.map +1 -1
  65. package/lib/interfaces/events.d.ts +2 -2
  66. package/lib/interfaces/events.js +1 -4
  67. package/lib/interfaces/events.js.map +1 -1
  68. package/lib/interfaces/index.d.ts +13 -12
  69. package/lib/interfaces/index.js +12 -32
  70. package/lib/interfaces/index.js.map +1 -1
  71. package/lib/interfaces/logging.d.ts +3 -3
  72. package/lib/interfaces/logging.js +1 -4
  73. package/lib/interfaces/logging.js.map +1 -1
  74. package/lib/interfaces/metrics.d.ts +2 -2
  75. package/lib/interfaces/metrics.js +1 -5
  76. package/lib/interfaces/metrics.js.map +1 -1
  77. package/lib/interfaces/observable-types.d.ts +1 -1
  78. package/lib/interfaces/observable-types.js +1 -4
  79. package/lib/interfaces/observable-types.js.map +1 -1
  80. package/lib/interfaces/observable.d.ts +8 -9
  81. package/lib/interfaces/observable.js +1 -2
  82. package/lib/interfaces/observable.js.map +1 -1
  83. package/lib/interfaces/options.d.ts +15 -6
  84. package/lib/interfaces/options.js +2 -5
  85. package/lib/interfaces/options.js.map +1 -1
  86. package/lib/interfaces/plugins.d.ts +2 -2
  87. package/lib/interfaces/plugins.js +1 -4
  88. package/lib/interfaces/plugins.js.map +1 -1
  89. package/lib/interfaces/result.js +8 -18
  90. package/lib/interfaces/result.js.map +1 -1
  91. package/lib/interfaces/schema-events.d.ts +5 -20
  92. package/lib/interfaces/schema-events.js +7 -14
  93. package/lib/interfaces/schema-events.js.map +1 -1
  94. package/lib/interfaces/schema-types.d.ts +32 -352
  95. package/lib/interfaces/schema-types.js +77 -512
  96. package/lib/interfaces/schema-types.js.map +1 -1
  97. package/lib/interfaces/service.d.ts +1 -1
  98. package/lib/interfaces/service.js +1 -2
  99. package/lib/interfaces/service.js.map +1 -1
  100. package/lib/interfaces/tools.js +8 -13
  101. package/lib/interfaces/tools.js.map +1 -1
  102. package/lib/plugins/config-default/index.d.ts +16 -14
  103. package/lib/plugins/config-default/index.js +66 -50
  104. package/lib/plugins/config-default/index.js.map +1 -1
  105. package/lib/plugins/config-default/interfaces.d.ts +1 -1
  106. package/lib/plugins/config-default/interfaces.js +1 -2
  107. package/lib/plugins/config-default/interfaces.js.map +1 -1
  108. package/lib/plugins/events-default/events/broadcast.d.ts +1 -1
  109. package/lib/plugins/events-default/events/broadcast.js +2 -6
  110. package/lib/plugins/events-default/events/broadcast.js.map +1 -1
  111. package/lib/plugins/events-default/events/emit.d.ts +1 -1
  112. package/lib/plugins/events-default/events/emit.js +4 -8
  113. package/lib/plugins/events-default/events/emit.js.map +1 -1
  114. package/lib/plugins/events-default/events/emitAndReturn.d.ts +1 -1
  115. package/lib/plugins/events-default/events/emitAndReturn.js +4 -8
  116. package/lib/plugins/events-default/events/emitAndReturn.js.map +1 -1
  117. package/lib/plugins/events-default/events/emitStreamAndReceiveStream.d.ts +1 -1
  118. package/lib/plugins/events-default/events/emitStreamAndReceiveStream.js +8 -12
  119. package/lib/plugins/events-default/events/emitStreamAndReceiveStream.js.map +1 -1
  120. package/lib/plugins/events-default/events/index.d.ts +4 -4
  121. package/lib/plugins/events-default/events/index.js +4 -11
  122. package/lib/plugins/events-default/events/index.js.map +1 -1
  123. package/lib/plugins/events-default/index.d.ts +5 -5
  124. package/lib/plugins/events-default/index.js +10 -15
  125. package/lib/plugins/events-default/index.js.map +1 -1
  126. package/lib/plugins/observable-default/index.d.ts +5 -5
  127. package/lib/plugins/observable-default/index.js +8 -13
  128. package/lib/plugins/observable-default/index.js.map +1 -1
  129. package/lib/plugins/service-benchmarkify/index.d.ts +196 -0
  130. package/lib/plugins/service-benchmarkify/index.js +133 -0
  131. package/lib/plugins/service-benchmarkify/index.js.map +1 -0
  132. package/lib/plugins/service-default0/index.d.ts +189 -0
  133. package/lib/plugins/service-default0/index.js +113 -0
  134. package/lib/plugins/service-default0/index.js.map +1 -0
  135. package/lib/{tests/sb/plugins/events/emitStreamAndReceiveStream.d.ts → plugins/service-default1/client.d.ts} +16 -4
  136. package/lib/plugins/service-default1/client.js +66 -0
  137. package/lib/plugins/service-default1/client.js.map +1 -0
  138. package/lib/plugins/service-default1/index.d.ts +202 -0
  139. package/lib/plugins/service-default1/index.js +174 -0
  140. package/lib/plugins/service-default1/index.js.map +1 -0
  141. package/lib/plugins/service-default2/index.d.ts +217 -0
  142. package/lib/plugins/service-default2/index.js +132 -0
  143. package/lib/plugins/service-default2/index.js.map +1 -0
  144. package/lib/plugins/service-default3/index.d.ts +91 -0
  145. package/lib/plugins/service-default3/index.js +83 -0
  146. package/lib/plugins/service-default3/index.js.map +1 -0
  147. package/lib/plugins/service-default4/index.d.ts +67 -0
  148. package/lib/{tests.js → plugins/service-default4/index.js} +31 -17
  149. package/lib/plugins/service-default4/index.js.map +1 -0
  150. package/lib/schemas/config-default.json +24 -16
  151. package/lib/schemas/config-default.plugin.json +24 -16
  152. package/lib/schemas/events-default.json +1 -1
  153. package/lib/schemas/events-default.plugin.json +1 -1
  154. package/lib/schemas/observable-default.json +15 -5
  155. package/lib/schemas/observable-default.plugin.json +15 -5
  156. package/lib/schemas/service-benchmarkify.json +314 -0
  157. package/lib/schemas/service-default0.json +279 -0
  158. package/lib/schemas/service-default1.json +327 -0
  159. package/lib/schemas/service-default2.json +355 -0
  160. package/lib/schemas/service-default3.json +107 -0
  161. package/lib/schemas/service-default4.json +63 -0
  162. package/lib/scripts/bsb-client-cli.js +9 -9
  163. package/lib/scripts/bsb-client-cli.js.map +1 -1
  164. package/lib/scripts/bsb-plugin-cli.js +93 -64
  165. package/lib/scripts/bsb-plugin-cli.js.map +1 -1
  166. package/lib/scripts/export-schemas.js +15 -12
  167. package/lib/scripts/export-schemas.js.map +1 -1
  168. package/lib/scripts/extract-schemas-from-source.js +73 -56
  169. package/lib/scripts/extract-schemas-from-source.js.map +1 -1
  170. package/lib/scripts/generate-client-types.d.ts +1 -16
  171. package/lib/scripts/generate-client-types.js +120 -313
  172. package/lib/scripts/generate-client-types.js.map +1 -1
  173. package/lib/scripts/generate-plugin-json.js +9 -10
  174. package/lib/scripts/generate-plugin-json.js.map +1 -1
  175. package/lib/serviceBase/config.d.ts +4 -4
  176. package/lib/serviceBase/config.js +33 -35
  177. package/lib/serviceBase/config.js.map +1 -1
  178. package/lib/serviceBase/events.d.ts +6 -6
  179. package/lib/serviceBase/events.js +42 -44
  180. package/lib/serviceBase/events.js.map +1 -1
  181. package/lib/serviceBase/index.d.ts +7 -7
  182. package/lib/serviceBase/index.js +7 -23
  183. package/lib/serviceBase/index.js.map +1 -1
  184. package/lib/serviceBase/observable.d.ts +5 -5
  185. package/lib/serviceBase/observable.js +21 -25
  186. package/lib/serviceBase/observable.js.map +1 -1
  187. package/lib/serviceBase/plugins.d.ts +3 -3
  188. package/lib/serviceBase/plugins.js +48 -54
  189. package/lib/serviceBase/plugins.js.map +1 -1
  190. package/lib/serviceBase/serviceBase.d.ts +3 -3
  191. package/lib/serviceBase/serviceBase.js +40 -44
  192. package/lib/serviceBase/serviceBase.js.map +1 -1
  193. package/lib/serviceBase/services.d.ts +6 -6
  194. package/lib/serviceBase/services.js +21 -22
  195. package/lib/serviceBase/services.js.map +1 -1
  196. package/package.json +18 -11
  197. package/lib/tests/mocks.d.ts +0 -37
  198. package/lib/tests/mocks.js +0 -164
  199. package/lib/tests/mocks.js.map +0 -1
  200. package/lib/tests/sb/plugins/events/broadcast.d.ts +0 -30
  201. package/lib/tests/sb/plugins/events/broadcast.js +0 -357
  202. package/lib/tests/sb/plugins/events/broadcast.js.map +0 -1
  203. package/lib/tests/sb/plugins/events/emit.d.ts +0 -30
  204. package/lib/tests/sb/plugins/events/emit.js +0 -353
  205. package/lib/tests/sb/plugins/events/emit.js.map +0 -1
  206. package/lib/tests/sb/plugins/events/emitAndReturn.d.ts +0 -30
  207. package/lib/tests/sb/plugins/events/emitAndReturn.js +0 -382
  208. package/lib/tests/sb/plugins/events/emitAndReturn.js.map +0 -1
  209. package/lib/tests/sb/plugins/events/emitStreamAndReceiveStream.js +0 -298
  210. package/lib/tests/sb/plugins/events/emitStreamAndReceiveStream.js.map +0 -1
  211. package/lib/tests/sb/plugins/events/index.d.ts +0 -28
  212. package/lib/tests/sb/plugins/events/index.js +0 -69
  213. package/lib/tests/sb/plugins/events/index.js.map +0 -1
  214. package/lib/tests/trace.d.ts +0 -41
  215. package/lib/tests/trace.js +0 -85
  216. package/lib/tests/trace.js.map +0 -1
  217. package/lib/tests.d.ts +0 -27
  218. package/lib/tests.js.map +0 -1
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  /**
3
2
  * BSB (Better-Service-Base) is an event-bus based microservice framework.
4
3
  * Copyright (C) 2016 - 2025 BetterCorp (PTY) Ltd
@@ -25,557 +24,123 @@
25
24
  * You should have received a copy of the GNU Affero General Public License
26
25
  * along with this program. If not, see <https://www.gnu.org/licenses/>.
27
26
  */
28
- Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.bsb = void 0;
30
- exports.optional = optional;
31
- exports.nullable = nullable;
32
- exports.bsbToJsonSchema = bsbToJsonSchema;
33
- exports.bsbToZod = bsbToZod;
34
- const zod_1 = require("zod");
35
- // ============================================================================
36
- // Builder API - Fluent Interface for Creating BSB Types
37
- // ============================================================================
38
- /**
39
- * BSB type builder providing a fluent API for creating cross-language type definitions.
40
- *
41
- * @example
42
- * ```typescript
43
- * import { bsb, optional } from '@bsb/base';
44
- *
45
- * const UserSchema = bsb.object({
46
- * id: bsb.uuid('User unique identifier'),
47
- * name: bsb.string({ min: 1, max: 100, description: 'User full name' }),
48
- * email: bsb.string({ description: 'User email address' }),
49
- * age: optional(bsb.int32({ min: 0, max: 150, description: 'User age' })),
50
- * });
51
- * ```
52
- */
53
- exports.bsb = {
54
- /**
55
- * Create a string type with optional constraints.
56
- */
27
+ import * as av from '@anyvali/js';
28
+ export function withDescription(schema, description) {
29
+ if (!description) {
30
+ return schema;
31
+ }
32
+ const originalExport = schema.export.bind(schema);
33
+ schema.export = ((mode) => {
34
+ const doc = originalExport(mode);
35
+ doc.extensions = {
36
+ ...doc.extensions,
37
+ bsb: {
38
+ ...(doc.extensions?.bsb ?? {}),
39
+ description,
40
+ },
41
+ };
42
+ return doc;
43
+ });
44
+ return schema;
45
+ }
46
+ function withNumericOptions(schema, options) {
47
+ let next = schema;
48
+ if (options?.min !== undefined)
49
+ next = next.min(options.min);
50
+ if (options?.max !== undefined)
51
+ next = next.max(options.max);
52
+ return withDescription(next, options?.description);
53
+ }
54
+ export const bsb = {
57
55
  string(options) {
58
- return {
59
- _bsb: 'string',
60
- minLength: options?.min,
61
- maxLength: options?.max,
62
- pattern: options?.pattern,
63
- description: options?.description,
64
- };
56
+ let schema = av.string();
57
+ if (options?.min !== undefined)
58
+ schema = schema.minLength(options.min);
59
+ if (options?.max !== undefined)
60
+ schema = schema.maxLength(options.max);
61
+ if (options?.pattern)
62
+ schema = schema.pattern(options.pattern);
63
+ return withDescription(schema, options?.description);
65
64
  },
66
- /**
67
- * Create a UUID string type (RFC 4122).
68
- *
69
- * Format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
70
- *
71
- * Language mappings:
72
- * - JavaScript/TypeScript: string
73
- * - C#: Guid
74
- * - Go: uuid.UUID
75
- * - Java: UUID
76
- */
77
65
  uuid(description) {
78
- return {
79
- _bsb: 'string',
80
- format: 'uuid',
81
- description,
82
- };
66
+ return withDescription(av.string().format('uuid'), description);
83
67
  },
84
- /**
85
- * Create an ISO 8601 datetime string type.
86
- *
87
- * Format: 2024-01-01T12:00:00Z
88
- *
89
- * Language mappings:
90
- * - JavaScript/TypeScript: Date | string
91
- * - C#: DateTime
92
- * - Go: time.Time
93
- * - Java: Instant
94
- */
95
68
  datetime(description) {
96
- return {
97
- _bsb: 'string',
98
- format: 'datetime',
99
- description,
100
- };
69
+ return withDescription(av.string().format('date-time'), description);
101
70
  },
102
- /**
103
- * Create an email address string type.
104
- */
105
71
  email(description) {
106
- return {
107
- _bsb: 'string',
108
- format: 'email',
109
- description,
110
- };
72
+ return withDescription(av.string().format('email'), description);
111
73
  },
112
- /**
113
- * Create a URI string type.
114
- */
115
74
  uri(description) {
116
- return {
117
- _bsb: 'string',
118
- format: 'uri',
119
- description,
120
- };
75
+ return withDescription(av.string().format('url'), description);
121
76
  },
122
- /**
123
- * Create a URL string type.
124
- */
125
77
  url(description) {
126
- return {
127
- _bsb: 'string',
128
- format: 'url',
129
- description,
130
- };
78
+ return withDescription(av.string().format('url'), description);
131
79
  },
132
- /**
133
- * Create a 32-bit signed integer type.
134
- *
135
- * Range: -2,147,483,648 to 2,147,483,647
136
- *
137
- * Language mappings:
138
- * - JavaScript/TypeScript: number
139
- * - C#: int
140
- * - Go: int32
141
- * - Java: int
142
- */
143
80
  int32(options) {
144
- return {
145
- _bsb: 'number',
146
- numberType: 'int32',
147
- min: options?.min ?? -2147483648,
148
- max: options?.max ?? 2147483647,
149
- description: options?.description,
150
- };
81
+ return withNumericOptions(av.int32(), options);
151
82
  },
152
- /**
153
- * Create a 64-bit signed integer type.
154
- *
155
- * Range: -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
156
- *
157
- * Note: JavaScript can only safely represent integers up to 2^53.
158
- *
159
- * Language mappings:
160
- * - JavaScript/TypeScript: number
161
- * - C#: long
162
- * - Go: int64
163
- * - Java: long
164
- */
165
83
  int64(options) {
166
- return {
167
- _bsb: 'number',
168
- numberType: 'int64',
169
- min: options?.min,
170
- max: options?.max,
171
- description: options?.description,
172
- };
84
+ return withNumericOptions(av.int64(), options);
173
85
  },
174
- /**
175
- * Create a 32-bit floating point number type.
176
- *
177
- * Language mappings:
178
- * - JavaScript/TypeScript: number
179
- * - C#: float
180
- * - Go: float32
181
- * - Java: float
182
- */
183
86
  float(options) {
184
- return {
185
- _bsb: 'number',
186
- numberType: 'float',
187
- min: options?.min,
188
- max: options?.max,
189
- description: options?.description,
190
- };
87
+ return withNumericOptions(av.float32(), options);
191
88
  },
192
- /**
193
- * Create a 64-bit floating point number type.
194
- *
195
- * Language mappings:
196
- * - JavaScript/TypeScript: number
197
- * - C#: double
198
- * - Go: float64
199
- * - Java: double
200
- */
201
89
  double(options) {
202
- return {
203
- _bsb: 'number',
204
- numberType: 'double',
205
- min: options?.min,
206
- max: options?.max,
207
- description: options?.description,
208
- };
90
+ return withNumericOptions(av.float64(), options);
91
+ },
92
+ number(options) {
93
+ return withNumericOptions(av.number(), options);
209
94
  },
210
- /**
211
- * Create a boolean type.
212
- *
213
- * Language mappings:
214
- * - JavaScript/TypeScript: boolean
215
- * - C#: bool
216
- * - Go: bool
217
- * - Java: boolean
218
- */
219
95
  boolean(description) {
220
- return {
221
- _bsb: 'boolean',
222
- description,
223
- };
96
+ return withDescription(av.bool(), description);
224
97
  },
225
- /**
226
- * Create a bytes type for binary data.
227
- * Maps to:
228
- * - JavaScript/TypeScript: Uint8Array or Buffer
229
- * - C#: byte[]
230
- * - Go: []byte
231
- * - Java: byte[]
232
- * - Python: bytes
233
- */
234
98
  bytes(description) {
235
- return {
236
- _bsb: 'bytes',
237
- description,
238
- };
99
+ return withDescription(av.unknown(), description);
239
100
  },
240
- /**
241
- * Create an array type with element type and optional size constraints.
242
- *
243
- * @example
244
- * ```typescript
245
- * const TagsSchema = bsb.array(
246
- * bsb.string({ max: 50 }),
247
- * { min: 1, max: 10, description: 'List of tags' }
248
- * );
249
- * ```
250
- */
251
101
  array(items, options) {
252
- return {
253
- _bsb: 'array',
254
- items,
255
- minItems: options?.min,
256
- maxItems: options?.max,
257
- description: options?.description,
258
- };
102
+ let schema = av.array(items);
103
+ if (options?.min !== undefined)
104
+ schema = schema.minItems(options.min);
105
+ if (options?.max !== undefined)
106
+ schema = schema.maxItems(options.max);
107
+ return withDescription(schema, options?.description);
259
108
  },
260
- /**
261
- * Create an object type with named properties.
262
- *
263
- * Required fields are automatically determined based on the optional flag.
264
- *
265
- * @example
266
- * ```typescript
267
- * const UserSchema = bsb.object({
268
- * id: bsb.uuid('User ID'),
269
- * name: bsb.string({ min: 1, max: 100, description: 'Full name' }),
270
- * email: optional(bsb.email('Email address')),
271
- * }, 'User object');
272
- * ```
273
- */
274
109
  object(properties, description) {
275
- // Compute required fields (non-optional)
276
- const required = Object.keys(properties).filter((key) => properties[key].optional !== true);
277
- return {
278
- _bsb: 'object',
279
- properties,
280
- required,
281
- description,
282
- };
110
+ return withDescription(av.object(properties, { unknownKeys: 'strip' }), description);
283
111
  },
284
- /**
285
- * Create an enum type with fixed string values.
286
- *
287
- * @example
288
- * ```typescript
289
- * const StatusSchema = bsb.enum(
290
- * ['pending', 'in-progress', 'completed', 'failed'],
291
- * 'Task status'
292
- * );
293
- * ```
294
- */
295
112
  enum(values, description) {
296
- return {
297
- _bsb: 'enum',
298
- values: [...values],
299
- description,
300
- };
113
+ return withDescription(av.enum_(values), description);
301
114
  },
302
- /**
303
- * Create a union type representing one of multiple possible types.
304
- *
305
- * @example
306
- * ```typescript
307
- * const IdSchema = bsb.union([
308
- * bsb.uuid('UUID identifier'),
309
- * bsb.int32({ description: 'Numeric identifier' }),
310
- * ], 'Flexible identifier');
311
- * ```
312
- */
313
115
  union(types, description) {
314
- return {
315
- _bsb: 'union',
316
- types,
317
- description,
318
- };
319
- },
320
- /**
321
- * Create a generic number type (defaults to double for floating point).
322
- * This is a convenience wrapper for double().
323
- */
324
- number(options) {
325
- return this.double(options);
116
+ if (types.length === 0) {
117
+ return withDescription(av.unknown(), description ?? 'unknown');
118
+ }
119
+ return withDescription(av.union(types), description);
326
120
  },
327
- /**
328
- * Create a void type for functions that don't return a value.
329
- */
330
121
  void() {
331
- return this.union([], 'void');
122
+ return withDescription(av.unknown(), 'void');
332
123
  },
333
- /**
334
- * Create an unknown type for dynamic/any data.
335
- */
336
124
  unknown(description) {
337
- return this.union([], description || 'unknown');
125
+ return withDescription(av.unknown(), description);
338
126
  },
339
- /**
340
- * Create a record/map type with string keys and a value type.
341
- */
342
- record(keyType, valueType, description) {
343
- // Records are represented as objects with dynamic properties
344
- // For now, we'll use a union as a placeholder
345
- return this.union([valueType], description || 'record');
127
+ record(_keyType, valueType, description) {
128
+ return withDescription(av.record(valueType), description);
346
129
  },
347
130
  };
348
- // ============================================================================
349
- // Type Modifiers
350
- // ============================================================================
351
- /**
352
- * Mark a type as optional.
353
- * Optional fields are not required in object schemas.
354
- *
355
- * @example
356
- * ```typescript
357
- * const UserSchema = bsb.object({
358
- * name: bsb.string(), // Required
359
- * bio: optional(bsb.string()), // Optional
360
- * });
361
- * ```
362
- */
363
- function optional(type) {
364
- return { ...type, optional: true };
131
+ export function optional(type) {
132
+ return av.optional(type);
365
133
  }
366
- /**
367
- * Mark a type as nullable.
368
- * Nullable fields can have null values in addition to their defined type.
369
- *
370
- * @example
371
- * ```typescript
372
- * const UserSchema = bsb.object({
373
- * lastLogin: nullable(bsb.datetime('Last login time')),
374
- * });
375
- * ```
376
- */
377
- function nullable(type) {
378
- return { ...type, nullable: true };
134
+ export function nullable(type) {
135
+ return av.nullable(type);
379
136
  }
380
- // ============================================================================
381
- // JSON Schema Conversion
382
- // ============================================================================
383
- /**
384
- * Convert BSB type to JSON Schema format.
385
- * Used for schema export and client code generation.
386
- */
387
- function bsbToJsonSchema(type) {
388
- const base = {};
389
- if (type.description)
390
- base.description = type.description;
391
- switch (type._bsb) {
392
- case 'string': {
393
- const schema = { ...base, type: 'string' };
394
- if (type.format)
395
- schema.format = type.format;
396
- if (type.minLength !== undefined)
397
- schema.minLength = type.minLength;
398
- if (type.maxLength !== undefined)
399
- schema.maxLength = type.maxLength;
400
- if (type.pattern)
401
- schema.pattern = type.pattern;
402
- return schema;
403
- }
404
- case 'number': {
405
- const isInteger = type.numberType === 'int32' || type.numberType === 'int64';
406
- const schema = {
407
- ...base,
408
- type: isInteger ? 'integer' : 'number',
409
- format: type.numberType,
410
- };
411
- if (type.min !== undefined)
412
- schema.minimum = type.min;
413
- if (type.max !== undefined)
414
- schema.maximum = type.max;
415
- return schema;
416
- }
417
- case 'boolean':
418
- return { ...base, type: 'boolean' };
419
- case 'bytes':
420
- return {
421
- ...base,
422
- type: 'string',
423
- contentEncoding: 'base64',
424
- };
425
- case 'array': {
426
- const schema = {
427
- ...base,
428
- type: 'array',
429
- items: bsbToJsonSchema(type.items),
430
- };
431
- if (type.minItems !== undefined)
432
- schema.minItems = type.minItems;
433
- if (type.maxItems !== undefined)
434
- schema.maxItems = type.maxItems;
435
- return schema;
436
- }
437
- case 'object': {
438
- const properties = {};
439
- for (const [key, value] of Object.entries(type.properties)) {
440
- properties[key] = bsbToJsonSchema(value);
441
- }
442
- return {
443
- ...base,
444
- type: 'object',
445
- properties,
446
- required: type.required,
447
- };
448
- }
449
- case 'enum':
450
- return {
451
- ...base,
452
- type: 'string',
453
- enum: type.values,
454
- };
455
- case 'union':
456
- return {
457
- ...base,
458
- oneOf: type.types.map(bsbToJsonSchema),
459
- };
460
- default:
461
- throw new Error(`Unknown BSB type: ${type._bsb}`);
462
- }
137
+ export function bsbToJsonSchema(type) {
138
+ return type.export('extended');
463
139
  }
464
- // ============================================================================
465
- // Runtime Validation (Zod Conversion)
466
- // ============================================================================
467
- /**
468
- * Convert BSB type to Zod schema for runtime validation.
469
- * This is only used in Node.js plugins for runtime validation.
470
- * Other languages will have their own validation implementations.
471
- */
472
- function bsbToZod(type) {
473
- switch (type._bsb) {
474
- case 'string': {
475
- let schema = zod_1.z.string();
476
- if (type.format === 'uuid')
477
- schema = schema.uuid();
478
- if (type.format === 'datetime')
479
- schema = schema.datetime();
480
- if (type.format === 'email')
481
- schema = schema.email();
482
- if (type.format === 'uri' || type.format === 'url')
483
- schema = schema.url();
484
- if (type.minLength !== undefined)
485
- schema = schema.min(type.minLength);
486
- if (type.maxLength !== undefined)
487
- schema = schema.max(type.maxLength);
488
- if (type.pattern)
489
- schema = schema.regex(new RegExp(type.pattern));
490
- if (type.optional)
491
- return schema.optional();
492
- if (type.nullable)
493
- return schema.nullable();
494
- return schema;
495
- }
496
- case 'number': {
497
- let schema = zod_1.z.number();
498
- if (type.numberType === 'int32' || type.numberType === 'int64') {
499
- schema = schema.int();
500
- }
501
- if (type.min !== undefined)
502
- schema = schema.min(type.min);
503
- if (type.max !== undefined)
504
- schema = schema.max(type.max);
505
- if (type.optional)
506
- return schema.optional();
507
- if (type.nullable)
508
- return schema.nullable();
509
- return schema;
510
- }
511
- case 'boolean': {
512
- let schema = zod_1.z.boolean();
513
- if (type.optional)
514
- return schema.optional();
515
- if (type.nullable)
516
- return schema.nullable();
517
- return schema;
518
- }
519
- case 'bytes': {
520
- let schema = zod_1.z.instanceof(Uint8Array);
521
- if (type.optional)
522
- return schema.optional();
523
- if (type.nullable)
524
- return schema.nullable();
525
- return schema;
526
- }
527
- case 'array': {
528
- let schema = zod_1.z.array(bsbToZod(type.items));
529
- if (type.minItems !== undefined)
530
- schema = schema.min(type.minItems);
531
- if (type.maxItems !== undefined)
532
- schema = schema.max(type.maxItems);
533
- if (type.optional)
534
- return schema.optional();
535
- if (type.nullable)
536
- return schema.nullable();
537
- return schema;
538
- }
539
- case 'object': {
540
- const shape = {};
541
- for (const [key, value] of Object.entries(type.properties)) {
542
- shape[key] = bsbToZod(value);
543
- }
544
- let schema = zod_1.z.object(shape);
545
- if (type.optional)
546
- return schema.optional();
547
- if (type.nullable)
548
- return schema.nullable();
549
- return schema;
550
- }
551
- case 'enum': {
552
- let schema = zod_1.z.enum(type.values);
553
- if (type.optional)
554
- return schema.optional();
555
- if (type.nullable)
556
- return schema.nullable();
557
- return schema;
558
- }
559
- case 'union': {
560
- // Empty union = unknown/any type (used by bsb.unknown() and bsb.void())
561
- if (type.types.length === 0) {
562
- let schema = zod_1.z.unknown();
563
- if (type.optional)
564
- return schema.optional();
565
- if (type.nullable)
566
- return schema.nullable();
567
- return schema;
568
- }
569
- const schemas = type.types.map(bsbToZod);
570
- let schema = zod_1.z.union(schemas);
571
- if (type.optional)
572
- return schema.optional();
573
- if (type.nullable)
574
- return schema.nullable();
575
- return schema;
576
- }
577
- default:
578
- throw new Error(`Unknown BSB type: ${type._bsb}`);
579
- }
140
+ export function exportPortableSchema(type) {
141
+ return type.export('extended');
142
+ }
143
+ export function importPortableSchema(document) {
144
+ return av.importSchema(document);
580
145
  }
581
146
  //# sourceMappingURL=schema-types.js.map