@vsaas/loopback-datasource-juggler 10.0.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 (63) hide show
  1. package/LICENSE +25 -0
  2. package/NOTICE +23 -0
  3. package/README.md +74 -0
  4. package/dist/_virtual/_rolldown/runtime.js +4 -0
  5. package/dist/index.js +26 -0
  6. package/dist/lib/browser.depd.js +13 -0
  7. package/dist/lib/case-utils.js +21 -0
  8. package/dist/lib/connectors/kv-memory.js +158 -0
  9. package/dist/lib/connectors/memory.js +810 -0
  10. package/dist/lib/connectors/transient.js +126 -0
  11. package/dist/lib/dao.js +2445 -0
  12. package/dist/lib/datasource.js +2215 -0
  13. package/dist/lib/date-string.js +87 -0
  14. package/dist/lib/geo.js +244 -0
  15. package/dist/lib/globalize.js +33 -0
  16. package/dist/lib/hooks.js +79 -0
  17. package/dist/lib/id-utils.js +66 -0
  18. package/dist/lib/include.js +795 -0
  19. package/dist/lib/include_utils.js +104 -0
  20. package/dist/lib/introspection.js +37 -0
  21. package/dist/lib/jutil.js +65 -0
  22. package/dist/lib/kvao/delete-all.js +57 -0
  23. package/dist/lib/kvao/delete.js +43 -0
  24. package/dist/lib/kvao/expire.js +35 -0
  25. package/dist/lib/kvao/get.js +34 -0
  26. package/dist/lib/kvao/index.js +28 -0
  27. package/dist/lib/kvao/iterate-keys.js +38 -0
  28. package/dist/lib/kvao/keys.js +55 -0
  29. package/dist/lib/kvao/set.js +39 -0
  30. package/dist/lib/kvao/ttl.js +35 -0
  31. package/dist/lib/list.js +101 -0
  32. package/dist/lib/mixins.js +58 -0
  33. package/dist/lib/model-builder.js +608 -0
  34. package/dist/lib/model-definition.js +231 -0
  35. package/dist/lib/model-utils.js +368 -0
  36. package/dist/lib/model.js +586 -0
  37. package/dist/lib/observer.js +235 -0
  38. package/dist/lib/relation-definition.js +2604 -0
  39. package/dist/lib/relations.js +587 -0
  40. package/dist/lib/scope.js +392 -0
  41. package/dist/lib/transaction.js +183 -0
  42. package/dist/lib/types.js +58 -0
  43. package/dist/lib/utils.js +625 -0
  44. package/dist/lib/validations.js +742 -0
  45. package/dist/package.js +93 -0
  46. package/package.json +85 -0
  47. package/types/common.d.ts +28 -0
  48. package/types/connector.d.ts +52 -0
  49. package/types/datasource.d.ts +324 -0
  50. package/types/date-string.d.ts +21 -0
  51. package/types/inclusion-mixin.d.ts +44 -0
  52. package/types/index.d.ts +36 -0
  53. package/types/kv-model.d.ts +201 -0
  54. package/types/model.d.ts +368 -0
  55. package/types/observer-mixin.d.ts +174 -0
  56. package/types/persisted-model.d.ts +505 -0
  57. package/types/query.d.ts +108 -0
  58. package/types/relation-mixin.d.ts +577 -0
  59. package/types/relation.d.ts +301 -0
  60. package/types/scope.d.ts +92 -0
  61. package/types/transaction-mixin.d.ts +47 -0
  62. package/types/types.d.ts +65 -0
  63. package/types/validation-mixin.d.ts +287 -0
@@ -0,0 +1,201 @@
1
+ // Copyright IBM Corp. 2018. All Rights Reserved.
2
+ // Node module: loopback-datasource-juggler
3
+ // This file is licensed under the MIT License.
4
+ // License text available at https://opensource.org/licenses/MIT
5
+
6
+ import { Callback, Options, PromiseOrVoid } from './common';
7
+ import { ModelBase, ModelData } from './model';
8
+
9
+ /**
10
+ * Data object for KV models
11
+ */
12
+ export type KVData<T extends ModelBase = ModelBase> = ModelData<T>;
13
+
14
+ /**
15
+ * Key/Value model. Strictly speaking, KeyValueModel is not a class
16
+ * but a mixin into existing model classes
17
+ */
18
+ export declare class KeyValueModel extends ModelBase {
19
+ /**
20
+ * Return the value associated with a given key.
21
+ *
22
+ * @param {string} key Key to use when searching the database.
23
+ * @options {Object} options
24
+ * @callback {Function} callback
25
+ * @param {Error} err Error object.
26
+ * @param {any} result Value associated with the given key.
27
+ * @promise
28
+ *
29
+ * @header KeyValueModel.get(key, cb)
30
+ */
31
+ static get(key: string, options?: Options, callback?: Callback<KVData>): PromiseOrVoid<KVData>;
32
+
33
+ /**
34
+ * Persist a value and associate it with the given key.
35
+ *
36
+ * @param {string} key Key to associate with the given value.
37
+ * @param {any} value Value to persist.
38
+ * @options {Number|Object} options Optional settings for the key-value
39
+ * pair. If a Number is provided, it is set as the TTL (time to live) in ms
40
+ * (milliseconds) for the key-value pair.
41
+ * @property {Number} ttl TTL for the key-value pair in ms.
42
+ * @callback {Function} callback
43
+ * @param {Error} err Error object.
44
+ * @promise
45
+ *
46
+ * @header KeyValueModel.set(key, value, cb)
47
+ */
48
+ static set(
49
+ key: string,
50
+ value: KVData,
51
+ options?: Options,
52
+ callback?: Callback<void>,
53
+ ): PromiseOrVoid<void>;
54
+
55
+ /**
56
+ * Delete the key-value pair associated to the given key.
57
+ *
58
+ * @param {string} key Key to use when searching the database.
59
+ * @options {Object} options
60
+ * @callback {Function} callback
61
+ * @param {Error} err Error object.
62
+ * @param {*} result Value associated with the given key.
63
+ * @promise
64
+ */
65
+ static delete(key: string, options?: Options, callback?: Callback<void>): PromiseOrVoid<void>;
66
+
67
+ /**
68
+ * Delete all keys (and values) associated to the current model.
69
+ *
70
+ * @options {Object} options Unused ATM, placeholder for future options.
71
+ * @callback {Function} callback
72
+ * @param {Error} err Error object.
73
+ * @promise
74
+ */
75
+ static deleteAll(options?: Options, callback?: Callback<void>): PromiseOrVoid<void>;
76
+
77
+ /**
78
+ * Set the TTL (time to live) in ms (milliseconds) for a given key. TTL is the
79
+ * remaining time before a key-value pair is discarded from the database.
80
+ *
81
+ * @param {string} key Key to use when searching the database.
82
+ * @param {Number} ttl TTL in ms to set for the key.
83
+ * @options {Object} options
84
+ * @callback {Function} callback
85
+ * @param {Error} err Error object.
86
+ * @promise
87
+ *
88
+ * @header KeyValueModel.expire(key, ttl, cb)
89
+ */
90
+ static expire(
91
+ key: string,
92
+ ttl: number,
93
+ options?: Options,
94
+ callback?: Callback<void>,
95
+ ): PromiseOrVoid<void>;
96
+
97
+ /**
98
+ * Return the TTL (time to live) for a given key. TTL is the remaining time
99
+ * before a key-value pair is discarded from the database.
100
+ *
101
+ * @param {string} key Key to use when searching the database.
102
+ * @options {Object} options
103
+ * @callback {Function} callback
104
+ * @param {Error} error
105
+ * @param {Number} ttl Expiration time for the key-value pair. `undefined` if
106
+ * TTL was not initially set.
107
+ * @promise
108
+ *
109
+ * @header KeyValueModel.ttl(key, cb)
110
+ */
111
+ static ttl(key: string, options?: Options, callback?: Callback<number>): PromiseOrVoid<number>;
112
+
113
+ /**
114
+ * Return all keys in the database.
115
+ *
116
+ * **WARNING**: This method is not suitable for large data sets as all
117
+ * key-values pairs are loaded into memory at once. For large data sets,
118
+ * use `iterateKeys()` instead.
119
+ *
120
+ * @param {Object} filter An optional filter object with the following
121
+ * @param {string} filter.match Glob string used to filter returned
122
+ * keys (i.e. `userid.*`). All connectors are required to support `*` and
123
+ * `?`, but may also support additional special characters specific to the
124
+ * database.
125
+ * @param {Object} options
126
+ * @callback {Function} callback
127
+ * @promise
128
+ *
129
+ * @header KeyValueModel.keys(filter, cb)
130
+ */
131
+ static keys(
132
+ filter?: KVFilter,
133
+ options?: Options,
134
+ callback?: Callback<string[]>,
135
+ ): PromiseOrVoid<string[]>;
136
+
137
+ /**
138
+ * Asynchronously iterate all keys in the database. Similar to `.keys()` but
139
+ * instead allows for iteration over large data sets without having to load
140
+ * everything into memory at once.
141
+ *
142
+ * Callback example:
143
+ * ```js
144
+ * // Given a model named `Color` with two keys `red` and `blue`
145
+ * var iterator = Color.iterateKeys();
146
+ * it.next(function(err, key) {
147
+ * // key contains `red`
148
+ * it.next(function(err, key) {
149
+ * // key contains `blue`
150
+ * });
151
+ * });
152
+ * ```
153
+ *
154
+ * Promise example:
155
+ * ```js
156
+ * // Given a model named `Color` with two keys `red` and `blue`
157
+ * var iterator = Color.iterateKeys();
158
+ * Promise.resolve().then(function() {
159
+ * return it.next();
160
+ * })
161
+ * .then(function(key) {
162
+ * // key contains `red`
163
+ * return it.next();
164
+ * });
165
+ * .then(function(key) {
166
+ * // key contains `blue`
167
+ * });
168
+ * ```
169
+ *
170
+ * @param {Object} filter An optional filter object with the following
171
+ * @param {string} filter.match
172
+ * @param {Object} options
173
+ * @returns {AsyncKeyIterator} An Object implementing `next(cb) -> Promise`
174
+ * function that can be used to iterate all keys.
175
+ *
176
+ * @header KeyValueModel.iterateKeys(filter)
177
+ */
178
+ static iterateKeys(filter?: KVFilter, options?: Options): AsyncKeyIterator;
179
+ }
180
+
181
+ export type KVFilter = {
182
+ /**
183
+ * Glob string to use to filter returned keys (i.e. `userid.*`). All connectors
184
+ * are required to support `*` and `?`. They may also support additional special
185
+ * characters that are specific to the backing database.
186
+ */
187
+ match: string;
188
+ };
189
+
190
+ /**
191
+ * Async iterator to return keys one by one. The value will be undefined if there is
192
+ * no more keys
193
+ */
194
+ export interface AsyncKeyIterator {
195
+ /**
196
+ * Try to fetch the next key
197
+ * @param callback Callback function. If not provided, the return value will be
198
+ * a promise
199
+ */
200
+ next(callback?: Callback<string | undefined>): PromiseOrVoid<string | undefined>;
201
+ }
@@ -0,0 +1,368 @@
1
+ // Copyright IBM Corp. 2018,2019. All Rights Reserved.
2
+ // Node module: loopback-datasource-juggler
3
+ // This file is licensed under the MIT License.
4
+ // License text available at https://opensource.org/licenses/MIT
5
+
6
+ import { EventEmitter } from 'events';
7
+ import { AnyObject, Options } from './common';
8
+ import { DataSource } from './datasource';
9
+ import { Listener, OperationHookContext } from './observer-mixin';
10
+
11
+ /**
12
+ * Property types
13
+ */
14
+ export type PropertyType = string | Function | { [property: string]: PropertyType };
15
+
16
+ /**
17
+ * Property definition
18
+ */
19
+ export interface PropertyDefinition extends AnyObject {
20
+ type?: PropertyType;
21
+ id?: boolean | number;
22
+ }
23
+
24
+ /**
25
+ * Schema definition
26
+ */
27
+ export interface Schema {
28
+ name: string;
29
+ properties: ModelProperties;
30
+ settings?: ModelSettings;
31
+ }
32
+
33
+ /**
34
+ * ID definition
35
+ */
36
+ export interface IdDefinition {
37
+ name: string;
38
+ id: number;
39
+ property: AnyObject;
40
+ }
41
+
42
+ /**
43
+ * Index definition
44
+ */
45
+ export interface IndexDefinition extends AnyObject {}
46
+
47
+ /**
48
+ * Column metadata
49
+ */
50
+ export interface ColumnMetadata extends AnyObject {
51
+ name: string;
52
+ }
53
+
54
+ /**
55
+ * Definition of model properties, for example
56
+ * ```ts
57
+ * {
58
+ * name: {type: String, required: true},
59
+ * }
60
+ * ```
61
+ */
62
+ export interface ModelProperties {
63
+ [name: string]: PropertyDefinition;
64
+ }
65
+
66
+ /**
67
+ * Model settings, for example
68
+ * ```ts
69
+ * {
70
+ * strict: true,
71
+ * }
72
+ * ```
73
+ */
74
+ export interface ModelSettings extends AnyObject {
75
+ strict?: boolean;
76
+ forceId?: boolean;
77
+ }
78
+
79
+ /**
80
+ * Model definition
81
+ */
82
+ export declare class ModelDefinition extends EventEmitter implements Schema {
83
+ name: string;
84
+ properties: ModelProperties;
85
+ rawProperties: AnyObject;
86
+ settings?: ModelSettings;
87
+ relations?: AnyObject[];
88
+
89
+ constructor(
90
+ modelBuilder: ModelBuilder | null | undefined,
91
+ name: string,
92
+ properties?: ModelProperties,
93
+ settings?: ModelSettings,
94
+ );
95
+ constructor(modelBuilder: ModelBuilder | null | undefined, schema: Schema);
96
+
97
+ tableName(connectorType: string): string;
98
+ columnName(connectorType: string, propertyName: string): string;
99
+ columnNames(connectorType: string): string[];
100
+ columnMetadata(connectorType: string, propertyName: string): ColumnMetadata;
101
+
102
+ ids(): IdDefinition[];
103
+ idName(): string;
104
+ idNames(): string[];
105
+
106
+ defineProperty(propertyName: string, propertyDefinition: PropertyDefinition): void;
107
+ indexes(): { [name: string]: IndexDefinition };
108
+ build(forceRebuild?: boolean): AnyObject;
109
+ toJSON(forceRebuild?: boolean): AnyObject;
110
+ }
111
+
112
+ /**
113
+ * Base class for LoopBack 3.x models
114
+ */
115
+ export declare class ModelBase {
116
+ static dataSource?: DataSource;
117
+ static modelName: string;
118
+ static definition: ModelDefinition;
119
+ static readonly base: typeof ModelBase;
120
+
121
+ /**
122
+ * Extend the model with the specified model, properties, and other settings.
123
+ * For example, to extend an existing model:
124
+ *
125
+ * ```js
126
+ * const Customer = User.extend('Customer', {
127
+ * accountId: String,
128
+ * vip: Boolean
129
+ * });
130
+ * ```
131
+ *
132
+ * @param className Name of the new model being defined.
133
+ * @param subClassProperties child model properties, added to base model
134
+ * properties.
135
+ * @param subClassSettings child model settings such as relations and acls,
136
+ * merged with base model settings.
137
+ */
138
+ static extend<ChildModel extends typeof ModelBase = typeof ModelBase>(
139
+ modelName: string,
140
+ properties?: ModelProperties,
141
+ settings?: ModelSettings,
142
+ ): ChildModel;
143
+
144
+ /**
145
+ * Attach the model class to a data source
146
+ * @param ds The data source
147
+ */
148
+ static attachTo(ds: DataSource): void;
149
+
150
+ /**
151
+ * Get model property type.
152
+ * @param {string} propName Property name
153
+ * @returns {string} Name of property type
154
+ */
155
+ static getPropertyType(propName: string): string | null;
156
+
157
+ /**
158
+ * Checks if property is hidden.
159
+ * @param {string} propertyName Property name
160
+ * @returns {Boolean} true or false if hidden or not.
161
+ */
162
+ static isHiddenProperty(propertyName: string): boolean;
163
+
164
+ /**
165
+ * Checks if property is protected.
166
+ * @param {string} propertyName Property name
167
+ * @returns {Boolean} true or false if protected or not.
168
+ */
169
+ static isProtectedProperty(propertyName: string): boolean;
170
+
171
+ /**
172
+ * Gets properties defined with 'updateOnly' flag set to true from the model.
173
+ * This flag is also set to true internally for the id property, if this
174
+ * property is generated and IdInjection is true.
175
+ * @returns {updateOnlyProps} List of properties with updateOnly set to true.
176
+ */
177
+ static getUpdateOnlyProperties(): string[];
178
+
179
+ /**
180
+ * Constructor for ModelBase
181
+ *
182
+ * NOTE: We have to use `constructor(...args: any[]);` so that it can be used
183
+ * for `return class extends superClass`.
184
+ *
185
+ * @param {AnyObject} data Initial object data
186
+ * @param {Options} options An object to control the instantiation
187
+ */
188
+ constructor(...args: any[]);
189
+ // constructor(data: AnyObject, options?: Options);
190
+
191
+ /**
192
+ * Convert the model instance to a plain json object
193
+ */
194
+ toJSON(): AnyObject;
195
+
196
+ /**
197
+ * Populate properties from a JSON object
198
+ * @param obj The source object
199
+ */
200
+ fromObject(obj: AnyObject): void;
201
+
202
+ /**
203
+ * Convert model instance to a plain JSON object.
204
+ * Returns a canonical object representation (no getters and setters).
205
+ *
206
+ * @param options Options for the conversion
207
+ * @property {boolean} onlySchema Restrict properties to dataSource only.
208
+ * Default is false. If true, the function returns only properties defined
209
+ * in the schema; Otherwise it returns all enumerable properties.
210
+ * @property {boolean} removeHidden Boolean flag as part of the transformation.
211
+ * If true, then hidden properties should not be brought out.
212
+ * @property {boolean} removeProtected Boolean flag as part of the transformation.
213
+ * If true, then protected properties should not be brought out.
214
+ * @returns {object} returns Plain JSON object
215
+ */
216
+ toObject(options?: Options): AnyObject;
217
+
218
+ /**
219
+ * Define a property on the model.
220
+ * @param {string} prop Property name
221
+ * @param definition Various property configuration
222
+ */
223
+ defineProperty(propertyName: string, definition: Partial<PropertyDefinition>): void;
224
+
225
+ getDataSource(): DataSource;
226
+
227
+ /**
228
+ *
229
+ * @param {string} anotherClass could be string or class. Name of the class
230
+ * or the class itself
231
+ * @param {Object} options An object to control the instantiation
232
+ * @returns {ModelClass}
233
+ */
234
+ static mixin(anotherClass: string | ModelBaseClass | object, options?: Options): ModelBaseClass;
235
+
236
+ // ObserverMixin members are added as static methods, this is difficult to
237
+ // describe in TypeScript in a way that's easy to use by consumers.
238
+ // As a workaround, we include a copy of ObserverMixin members here.
239
+ //
240
+ // Ideally, we want to describe the context argument as
241
+ // `OperationHookContext<this>`. Unfortunately, that's not supported by
242
+ // TypeScript for static members. A nice workaround is described in
243
+ // https://github.com/microsoft/TypeScript/issues/5863#issuecomment-410887254
244
+ // - Describe the context using a generic argument `T`.
245
+ // - Use `this: T` argument to let the compiler infer what's the target
246
+ // model class we are going to observe.
247
+
248
+ /**
249
+ * Register an asynchronous observer for the given operation (event).
250
+ *
251
+ * Example:
252
+ *
253
+ * Registers a `before save` observer for a given model.
254
+ *
255
+ * ```javascript
256
+ * MyModel.observe('before save', function filterProperties(ctx, next) {
257
+ * if (ctx.options && ctx.options.skipPropertyFilter) return next();
258
+ * if (ctx.instance) {
259
+ * FILTERED_PROPERTIES.forEach(function(p) {
260
+ * ctx.instance.unsetAttribute(p);
261
+ * });
262
+ * } else {
263
+ * FILTERED_PROPERTIES.forEach(function(p) {
264
+ * delete ctx.data[p];
265
+ * });
266
+ * }
267
+ * next();
268
+ * });
269
+ * ```
270
+ *
271
+ * @param {String} operation The operation name.
272
+ * @callback {function} listener The listener function. It will be invoked with
273
+ * `this` set to the model constructor, e.g. `User`.
274
+ * @end
275
+ */
276
+ static observe<T extends typeof ModelBase>(
277
+ this: T,
278
+ operation: string,
279
+ listener: Listener<OperationHookContext<T>>,
280
+ ): void;
281
+
282
+ /**
283
+ * Unregister an asynchronous observer for the given operation (event).
284
+ *
285
+ * Example:
286
+ *
287
+ * ```javascript
288
+ * MyModel.removeObserver('before save', function removedObserver(ctx, next) {
289
+ * // some logic user want to apply to the removed observer...
290
+ * next();
291
+ * });
292
+ * ```
293
+ *
294
+ * @param {String} operation The operation name.
295
+ * @callback {function} listener The listener function.
296
+ * @end
297
+ */
298
+ static removeObserver<T extends typeof ModelBase>(
299
+ this: T,
300
+ operation: string,
301
+ listener: Listener<OperationHookContext<T>>,
302
+ ): Listener<OperationHookContext<T>> | undefined;
303
+
304
+ /**
305
+ * Unregister all asynchronous observers for the given operation (event).
306
+ *
307
+ * Example:
308
+ *
309
+ * Remove all observers connected to the `before save` operation.
310
+ *
311
+ * ```javascript
312
+ * MyModel.clearObservers('before save');
313
+ * ```
314
+ *
315
+ * @param {String} operation The operation name.
316
+ * @end
317
+ */
318
+ static clearObservers(operation: string): void;
319
+ }
320
+
321
+ export type ModelBaseClass = typeof ModelBase;
322
+
323
+ export declare class ModelBuilder extends EventEmitter {
324
+ static defaultInstance: ModelBuilder;
325
+
326
+ models: { [name: string]: ModelBaseClass };
327
+ definitions: { [name: string]: ModelDefinition };
328
+ settings: ModelSettings;
329
+
330
+ defaultModelBaseClass: typeof ModelBase;
331
+
332
+ getModel(name: string, forceCreate?: boolean): ModelBaseClass;
333
+
334
+ getModelDefinition(name: string): ModelDefinition | undefined;
335
+
336
+ define(
337
+ className: string,
338
+ properties?: ModelProperties,
339
+ settings?: ModelSettings,
340
+ parent?: ModelBaseClass,
341
+ ): ModelBaseClass;
342
+
343
+ defineProperty(modelName: string, propertyName: string, propertyDefinition: AnyObject): void;
344
+
345
+ defineValueType(type: string, aliases?: string[]): void;
346
+
347
+ extendModel(modelName: string, properties: AnyObject): void;
348
+
349
+ getSchemaName(name?: string): string;
350
+
351
+ resolveType(type: any): any;
352
+
353
+ buildModels(schemas: AnyObject, createModel?: Function): { [name: string]: ModelBaseClass };
354
+
355
+ buildModelFromInstance(name: string, json: AnyObject, options: Options): ModelBaseClass;
356
+ }
357
+
358
+ /**
359
+ * An extension of the built-in Partial<T> type which allows partial values
360
+ * in deeply nested properties too.
361
+ */
362
+ export type DeepPartial<T> = { [P in keyof T]?: DeepPartial<T[P]> };
363
+
364
+ /**
365
+ * Union export type for model instance or plain object representing the model
366
+ * instance
367
+ */
368
+ export type ModelData<T extends ModelBase = ModelBase> = T | DeepPartial<T>;