@vsaas/loopback 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 (69) hide show
  1. package/LICENSE +25 -0
  2. package/README.md +91 -0
  3. package/common/models/README.md +109 -0
  4. package/common/models/access-token.json +37 -0
  5. package/common/models/acl.json +17 -0
  6. package/common/models/application.json +130 -0
  7. package/common/models/change.json +25 -0
  8. package/common/models/checkpoint.json +14 -0
  9. package/common/models/email.json +11 -0
  10. package/common/models/key-value-model.json +4 -0
  11. package/common/models/role-mapping.json +26 -0
  12. package/common/models/role.json +30 -0
  13. package/common/models/scope.json +14 -0
  14. package/common/models/user.json +118 -0
  15. package/dist/_virtual/_rolldown/runtime.cjs +32 -0
  16. package/dist/common/models/access-token.cjs +144 -0
  17. package/dist/common/models/access-token2.cjs +43 -0
  18. package/dist/common/models/acl.cjs +428 -0
  19. package/dist/common/models/acl2.cjs +27 -0
  20. package/dist/common/models/application.cjs +100 -0
  21. package/dist/common/models/application2.cjs +118 -0
  22. package/dist/common/models/change.cjs +404 -0
  23. package/dist/common/models/change2.cjs +25 -0
  24. package/dist/common/models/checkpoint.cjs +43 -0
  25. package/dist/common/models/checkpoint2.cjs +18 -0
  26. package/dist/common/models/email.cjs +18 -0
  27. package/dist/common/models/email2.cjs +30 -0
  28. package/dist/common/models/key-value-model.cjs +140 -0
  29. package/dist/common/models/key-value-model2.cjs +14 -0
  30. package/dist/common/models/role-mapping.cjs +57 -0
  31. package/dist/common/models/role-mapping2.cjs +34 -0
  32. package/dist/common/models/role.cjs +396 -0
  33. package/dist/common/models/role2.cjs +38 -0
  34. package/dist/common/models/scope.cjs +30 -0
  35. package/dist/common/models/scope2.cjs +21 -0
  36. package/dist/common/models/user.cjs +810 -0
  37. package/dist/common/models/user2.cjs +118 -0
  38. package/dist/index.cjs +16 -0
  39. package/dist/lib/access-context.cjs +228 -0
  40. package/dist/lib/application.cjs +450 -0
  41. package/dist/lib/builtin-models.cjs +60 -0
  42. package/dist/lib/configure-shared-methods.cjs +41 -0
  43. package/dist/lib/connectors/base-connector.cjs +23 -0
  44. package/dist/lib/connectors/mail-direct-transport.cjs +375 -0
  45. package/dist/lib/connectors/mail-stub-transport.cjs +86 -0
  46. package/dist/lib/connectors/mail.cjs +128 -0
  47. package/dist/lib/connectors/memory.cjs +19 -0
  48. package/dist/lib/current-context.cjs +22 -0
  49. package/dist/lib/globalize.cjs +29 -0
  50. package/dist/lib/loopback.cjs +313 -0
  51. package/dist/lib/model.cjs +1009 -0
  52. package/dist/lib/persisted-model.cjs +1835 -0
  53. package/dist/lib/registry.cjs +291 -0
  54. package/dist/lib/runtime.cjs +25 -0
  55. package/dist/lib/server-app.cjs +231 -0
  56. package/dist/lib/utils.cjs +154 -0
  57. package/dist/package.cjs +124 -0
  58. package/dist/server/middleware/context.cjs +7 -0
  59. package/dist/server/middleware/error-handler.cjs +6 -0
  60. package/dist/server/middleware/favicon.cjs +13 -0
  61. package/dist/server/middleware/rest.cjs +44 -0
  62. package/dist/server/middleware/static.cjs +14 -0
  63. package/dist/server/middleware/status.cjs +28 -0
  64. package/dist/server/middleware/token.cjs +66 -0
  65. package/dist/server/middleware/url-not-found.cjs +20 -0
  66. package/favicon.ico +0 -0
  67. package/package.json +121 -0
  68. package/templates/reset-form.ejs +3 -0
  69. package/templates/verify.ejs +9 -0
@@ -0,0 +1,291 @@
1
+ "use strict";
2
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
3
+ const require_lib_globalize = require("./globalize.cjs");
4
+ const require_lib_model = require("./model.cjs");
5
+ const require_lib_persisted_model = require("./persisted-model.cjs");
6
+ //#region src/lib/registry.ts
7
+ var require_registry = /* @__PURE__ */ require_runtime.__commonJSMin(((exports, module) => {
8
+ const g = require_lib_globalize;
9
+ const assert = require("assert");
10
+ const juggler = require("@vsaas/loopback-datasource-juggler");
11
+ const debug = require("debug")("loopback:registry");
12
+ const DataSource = juggler.DataSource;
13
+ const ModelBuilder = juggler.ModelBuilder;
14
+ const deprecated = require("depd")("strong-remoting");
15
+ module.exports = Registry;
16
+ /**
17
+ * Define and reference `Models` and `DataSources`.
18
+ *
19
+ * @class
20
+ */
21
+ function Registry() {
22
+ this.defaultDataSources = {};
23
+ this.modelBuilder = new ModelBuilder();
24
+ require_lib_model(this);
25
+ require_lib_persisted_model(this);
26
+ this.modelBuilder.defaultModelBaseClass = this.getModel("Model");
27
+ }
28
+ /**
29
+ * Create a named vanilla JavaScript class constructor with an attached
30
+ * set of properties and options.
31
+ *
32
+ * This function comes with two variants:
33
+ * * `loopback.createModel(name, properties, options)`
34
+ * * `loopback.createModel(config)`
35
+ *
36
+ * In the second variant, the parameters `name`, `properties` and `options`
37
+ * are provided in the config object. Any additional config entries are
38
+ * interpreted as `options`, i.e. the following two configs are identical:
39
+ *
40
+ * ```js
41
+ * { name: 'Customer', base: 'User' }
42
+ * { name: 'Customer', options: { base: 'User' } }
43
+ * ```
44
+ *
45
+ * **Example**
46
+ *
47
+ * Create an `Author` model using the three-parameter variant:
48
+ *
49
+ * ```js
50
+ * loopback.createModel(
51
+ * 'Author',
52
+ * {
53
+ * firstName: 'string',
54
+ * lastName: 'string'
55
+ * },
56
+ * {
57
+ * relations: {
58
+ * books: {
59
+ * model: 'Book',
60
+ * type: 'hasAndBelongsToMany'
61
+ * }
62
+ * }
63
+ * }
64
+ * );
65
+ * ```
66
+ *
67
+ * Create the same model using a config object:
68
+ *
69
+ * ```js
70
+ * loopback.createModel({
71
+ * name: 'Author',
72
+ * properties: {
73
+ * firstName: 'string',
74
+ * lastName: 'string'
75
+ * },
76
+ * relations: {
77
+ * books: {
78
+ * model: 'Book',
79
+ * type: 'hasAndBelongsToMany'
80
+ * }
81
+ * }
82
+ * });
83
+ * ```
84
+ *
85
+ * @param {String} name Unique name.
86
+ * @param {Object} properties
87
+ * @param {Object} options (optional)
88
+ *
89
+ * @header loopback.createModel
90
+ */
91
+ Registry.prototype.createModel = function(name, properties, options) {
92
+ if (arguments.length === 1 && typeof name === "object") {
93
+ const config = name;
94
+ name = config.name;
95
+ properties = config.properties;
96
+ options = buildModelOptionsFromConfig(config);
97
+ assert(typeof name === "string", "The model-config property `name` must be a string");
98
+ }
99
+ options = options || {};
100
+ let BaseModel = options.base || options.super;
101
+ if (typeof BaseModel === "string") {
102
+ const baseName = BaseModel;
103
+ BaseModel = this.findModel(BaseModel);
104
+ if (!BaseModel) throw new Error(g.f("Model not found: model `%s` is extending an unknown model `%s`.", name, baseName));
105
+ }
106
+ BaseModel = BaseModel || this.getModel("PersistedModel");
107
+ const model = BaseModel.extend(name, properties, options);
108
+ model.registry = this;
109
+ this._defineRemoteMethods(model, model.settings.methods);
110
+ return model;
111
+ };
112
+ function buildModelOptionsFromConfig(config) {
113
+ const options = Object.assign({}, config.options);
114
+ for (const key in config) {
115
+ if ([
116
+ "name",
117
+ "properties",
118
+ "options"
119
+ ].indexOf(key) !== -1) continue;
120
+ if (options[key] !== void 0) continue;
121
+ options[key] = config[key];
122
+ }
123
+ return options;
124
+ }
125
+ function addACL(acls, acl) {
126
+ for (let i = 0, n = acls.length; i < n; i++) if (acls[i].property === acl.property && acls[i].accessType === acl.accessType && acls[i].principalType === acl.principalType && acls[i].principalId === acl.principalId) {
127
+ acls[i] = acl;
128
+ return;
129
+ }
130
+ acls.push(acl);
131
+ }
132
+ /**
133
+ * Alter an existing Model class.
134
+ * @param {Model} ModelCtor The model constructor to alter.
135
+ * @options {Object} config Additional configuration to apply
136
+ * @property {DataSource} dataSource Attach the model to a dataSource.
137
+ * @property {Object} [relations] Model relations to add/update.
138
+ *
139
+ * @header loopback.configureModel(ModelCtor, config)
140
+ */
141
+ Registry.prototype.configureModel = function(ModelCtor, config) {
142
+ const settings = ModelCtor.settings;
143
+ const modelName = ModelCtor.modelName;
144
+ ModelCtor.config = config;
145
+ if (typeof config.relations === "object" && config.relations !== null) {
146
+ const relations = settings.relations = settings.relations || {};
147
+ Object.keys(config.relations).forEach(function(key) {
148
+ relations[key] = Object.assign(relations[key] || {}, config.relations[key]);
149
+ });
150
+ } else if (config.relations != null) g.warn("The relations property of `%s` configuration must be an object", modelName);
151
+ if (Array.isArray(config.acls)) {
152
+ const acls = settings.acls = settings.acls || [];
153
+ config.acls.forEach(function(acl) {
154
+ addACL(acls, acl);
155
+ });
156
+ } else if (config.acls != null) g.warn("The acls property of `%s` configuration must be an array of objects", modelName);
157
+ const excludedProperties = {
158
+ base: true,
159
+ super: true,
160
+ relations: true,
161
+ acls: true,
162
+ dataSource: true
163
+ };
164
+ if (typeof config.options === "object" && config.options !== null) for (const p in config.options) if (!(p in excludedProperties)) settings[p] = config.options[p];
165
+ else g.warn("Property `%s` cannot be reconfigured for `%s`", p, modelName);
166
+ else if (config.options != null) g.warn("The options property of `%s` configuration must be an object", modelName);
167
+ if (config.dataSource) {
168
+ assert(config.dataSource instanceof DataSource, "Cannot configure " + ModelCtor.modelName + ": config.dataSource must be an instance of DataSource");
169
+ ModelCtor.attachTo(config.dataSource);
170
+ debug("Attached model `%s` to dataSource `%s`", modelName, config.dataSource.name);
171
+ } else if (config.dataSource === null || config.dataSource === false) debug("Model `%s` is not attached to any DataSource by configuration.", modelName);
172
+ else {
173
+ debug("Model `%s` is not attached to any DataSource, possibly by a mistake.", modelName);
174
+ g.warn("The configuration of `%s` is missing {{`dataSource`}} property.\nUse `null` or `false` to mark models not attached to any data source.", modelName);
175
+ }
176
+ const newMethodNames = config.methods && Object.keys(config.methods);
177
+ const hasNewMethods = newMethodNames && newMethodNames.length;
178
+ const hasDescendants = this.getModelByType(ModelCtor) !== ModelCtor;
179
+ if (hasNewMethods && hasDescendants) g.warn("Child models of `%s` will not inherit newly defined remote methods %s.", modelName, newMethodNames);
180
+ this._defineRemoteMethods(ModelCtor, config.methods);
181
+ };
182
+ Registry.prototype._defineRemoteMethods = function(ModelCtor, methods) {
183
+ if (!methods) return;
184
+ if (typeof methods !== "object") {
185
+ g.warn("Ignoring non-object \"methods\" setting of \"%s\".", ModelCtor.modelName);
186
+ return;
187
+ }
188
+ Object.keys(methods).forEach(function(key) {
189
+ let meta = methods[key];
190
+ const m = key.match(/^prototype\.(.*)$/);
191
+ const isStatic = !m;
192
+ if (typeof meta.isStatic !== "boolean") {
193
+ key = isStatic ? key : m[1];
194
+ meta = Object.assign({}, meta, { isStatic });
195
+ } else if (meta.isStatic && m) throw new Error(g.f("Remoting metadata for %s.%s {{\"isStatic\"}} does not match new method name-based style.", ModelCtor.modelName, key));
196
+ else {
197
+ key = isStatic ? key : m[1];
198
+ if (!meta.isStatic && isStatic) deprecated(g.f("Remoting metadata {{\"isStatic\"}} is deprecated. Please specify {{\"prototype.name\"}} in method name instead for {{isStatic=false}}."));
199
+ }
200
+ ModelCtor.remoteMethod(key, meta);
201
+ });
202
+ };
203
+ /**
204
+ * Look up a model class by name from all models created by
205
+ * `loopback.createModel()`
206
+ * @param {String|Function} modelOrName The model name or a `Model` constructor.
207
+ * @returns {Model} The model class
208
+ *
209
+ * @header loopback.findModel(modelName)
210
+ */
211
+ Registry.prototype.findModel = function(modelName) {
212
+ if (typeof modelName === "function") return modelName;
213
+ return this.modelBuilder.models[modelName];
214
+ };
215
+ /**
216
+ * Look up a model class by name from all models created by
217
+ * `loopback.createModel()`. **Throw an error when no such model exists.**
218
+ *
219
+ * @param {String} modelOrName The model name or a `Model` constructor.
220
+ * @returns {Model} The model class
221
+ *
222
+ * @header loopback.getModel(modelName)
223
+ */
224
+ Registry.prototype.getModel = function(modelName) {
225
+ const model = this.findModel(modelName);
226
+ if (model) return model;
227
+ throw new Error(g.f("Model not found: %s", modelName));
228
+ };
229
+ /**
230
+ * Look up a model class by the base model class.
231
+ * The method can be used by LoopBack
232
+ * to find configured models in models.json over the base model.
233
+ * @param {Model} modelType The base model class
234
+ * @returns {Model} The subclass if found or the base class
235
+ *
236
+ * @header loopback.getModelByType(modelType)
237
+ */
238
+ Registry.prototype.getModelByType = function(modelType) {
239
+ const type = typeof modelType;
240
+ assert(["function", "string"].indexOf(type) > -1, "The model type must be a constructor or model name");
241
+ if (type === "string") modelType = this.getModel(modelType);
242
+ const models = this.modelBuilder.models;
243
+ for (const m in models) if (models[m].prototype instanceof modelType) return models[m];
244
+ return modelType;
245
+ };
246
+ /**
247
+ * Create a data source with passing the provided options to the connector.
248
+ *
249
+ * @param {String} name Optional name.
250
+ * @options {Object} options Data Source options
251
+ * @property {Object} connector LoopBack connector.
252
+ * @property {*} [*] Other&nbsp;connector properties.
253
+ * See the relevant connector documentation.
254
+ */
255
+ Registry.prototype.createDataSource = function(name, options) {
256
+ const self = this;
257
+ const ds = new DataSource(name, options, self.modelBuilder);
258
+ ds.createModel = function(name, properties, settings) {
259
+ settings = settings || {};
260
+ let BaseModel = settings.base || settings.super;
261
+ if (!BaseModel) {
262
+ const connectorTypes = ds.getTypes();
263
+ if (Array.isArray(connectorTypes) && connectorTypes.indexOf("db") !== -1) BaseModel = self.PersistedModel;
264
+ else BaseModel = self.Model;
265
+ settings.base = BaseModel;
266
+ }
267
+ const ModelCtor = self.createModel(name, properties, settings);
268
+ ModelCtor.attachTo(ds);
269
+ return ModelCtor;
270
+ };
271
+ if (ds.settings && ds.settings.defaultForType) {
272
+ const msg = g.f("{{DataSource}} option {{\"defaultForType\"}} is no longer supported");
273
+ throw new Error(msg);
274
+ }
275
+ return ds;
276
+ };
277
+ /**
278
+ * Get an in-memory data source. Use one if it already exists.
279
+ *
280
+ * @param {String} [name] The name of the data source.
281
+ * If not provided, the `'default'` is used.
282
+ */
283
+ Registry.prototype.memory = function(name) {
284
+ name = name || "default";
285
+ let memory = (this._memoryDataSources || (this._memoryDataSources = {}))[name];
286
+ if (!memory) memory = this._memoryDataSources[name] = this.createDataSource({ connector: "memory" });
287
+ return memory;
288
+ };
289
+ }));
290
+ //#endregion
291
+ module.exports = require_registry();
@@ -0,0 +1,25 @@
1
+ //#region src/lib/runtime.ts
2
+ var require_runtime = /* @__PURE__ */ require("../_virtual/_rolldown/runtime.cjs").__commonJSMin(((exports, module) => {
3
+ /**
4
+ * True if running in a browser environment; false otherwise.
5
+ * @header loopback.isBrowser
6
+ */
7
+ const isBrowser = typeof window !== "undefined";
8
+ /**
9
+ * True if running in a server environment; false otherwise.
10
+ * @header loopback.isServer
11
+ */
12
+ const runtime = {
13
+ isBrowser,
14
+ isServer: !isBrowser
15
+ };
16
+ Object.defineProperty(runtime, "loopback", {
17
+ value: null,
18
+ writable: true,
19
+ configurable: true,
20
+ enumerable: false
21
+ });
22
+ module.exports = runtime;
23
+ }));
24
+ //#endregion
25
+ module.exports = require_runtime();
@@ -0,0 +1,231 @@
1
+ const require_runtime = require("../_virtual/_rolldown/runtime.cjs");
2
+ const require_lib_globalize = require("./globalize.cjs");
3
+ //#region src/lib/server-app.ts
4
+ var require_server_app = /* @__PURE__ */ require_runtime.__commonJSMin(((exports, module) => {
5
+ const g = require_lib_globalize;
6
+ const assert = require("assert");
7
+ const express = require("express");
8
+ const mergePhaseNameLists = require("@vsaas/remoting/phases").mergePhaseNameLists;
9
+ const debug = require("debug")("loopback:app");
10
+ const BUILTIN_MIDDLEWARE = { builtin: true };
11
+ const proto = {};
12
+ function loopbackExpress() {
13
+ const app = express();
14
+ app.__expressLazyRouter = app.lazyrouter;
15
+ Object.assign(app, proto);
16
+ return app;
17
+ }
18
+ /**
19
+ * Register a middleware using a factory function and a JSON config.
20
+ *
21
+ * **Example**
22
+ *
23
+ * ```js
24
+ * app.middlewareFromConfig(compression, {
25
+ * enabled: true,
26
+ * phase: 'initial',
27
+ * params: {
28
+ * threshold: 128
29
+ * }
30
+ * });
31
+ * ```
32
+ *
33
+ * @param {function} factory The factory function creating a middleware handler.
34
+ * Typically a result of `require()` call, e.g. `require('compression')`.
35
+ * @options {Object} config The configuration.
36
+ * @property {String} phase The phase to register the middleware in.
37
+ * @property {Boolean} [enabled] Whether the middleware is enabled.
38
+ * Default: `true`.
39
+ * @property {Array|*} [params] The arguments to pass to the factory
40
+ * function. Either an array of arguments,
41
+ * or the value of the first argument when the factory expects
42
+ * a single argument only.
43
+ * @property {Array|string|RegExp} [paths] Optional list of paths limiting
44
+ * the scope of the middleware.
45
+ *
46
+ * @returns {object} this (fluent API)
47
+ *
48
+ * @header app.middlewareFromConfig(factory, config)
49
+ */
50
+ proto.middlewareFromConfig = function(factory, config) {
51
+ assert(typeof factory === "function", "\"factory\" must be a function");
52
+ assert(typeof config === "object", "\"config\" must be an object");
53
+ assert(typeof config.phase === "string" && config.phase, "\"config.phase\" must be a non-empty string");
54
+ if (config.enabled === false) return;
55
+ let params = config.params;
56
+ if (params === void 0) params = [];
57
+ else if (!Array.isArray(params)) params = [params];
58
+ let handler = factory.apply(null, params);
59
+ let verbs = config.methods || config.verbs;
60
+ if (Array.isArray(verbs)) {
61
+ verbs = verbs.map(function(verb) {
62
+ return verb && verb.toUpperCase();
63
+ });
64
+ if (verbs.indexOf("ALL") === -1) {
65
+ const originalHandler = handler;
66
+ if (handler.length <= 3) handler = function(req, res, next) {
67
+ if (verbs.indexOf(req.method.toUpperCase()) === -1) return next();
68
+ originalHandler(req, res, next);
69
+ };
70
+ else handler = function(err, req, res, next) {
71
+ if (verbs.indexOf(req.method.toUpperCase()) === -1) return next(err);
72
+ originalHandler(err, req, res, next);
73
+ };
74
+ }
75
+ }
76
+ this.middleware(config.phase, config.paths || [], handler);
77
+ return this;
78
+ };
79
+ /**
80
+ * Register (new) middleware phases.
81
+ *
82
+ * If all names are new, then the phases are added just before "routes" phase.
83
+ * Otherwise the provided list of names is merged with the existing phases
84
+ * in such way that the order of phases is preserved.
85
+ *
86
+ * **Examples**
87
+ *
88
+ * ```js
89
+ * // built-in phases:
90
+ * // initial, session, auth, parse, routes, files, final
91
+ *
92
+ * app.defineMiddlewarePhases('custom');
93
+ * // new list of phases
94
+ * // initial, session, auth, parse, custom, routes, files, final
95
+ *
96
+ * app.defineMiddlewarePhases([
97
+ * 'initial', 'postinit', 'preauth', 'routes', 'subapps'
98
+ * ]);
99
+ * // new list of phases
100
+ * // initial, postinit, preauth, session, auth, parse, custom,
101
+ * // routes, subapps, files, final
102
+ * ```
103
+ *
104
+ * @param {string|Array.<string>} nameOrArray A phase name or a list of phase
105
+ * names to add.
106
+ *
107
+ * @returns {object} this (fluent API)
108
+ *
109
+ * @header app.defineMiddlewarePhases(nameOrArray)
110
+ */
111
+ proto.defineMiddlewarePhases = function(nameOrArray) {
112
+ this.lazyrouter();
113
+ if (Array.isArray(nameOrArray)) this._requestHandlingPhases = mergePhaseNameLists(this._requestHandlingPhases, nameOrArray);
114
+ else {
115
+ const routesIx = this._requestHandlingPhases.indexOf("routes");
116
+ this._requestHandlingPhases.splice(routesIx - 1, 0, nameOrArray);
117
+ }
118
+ return this;
119
+ };
120
+ /**
121
+ * Register a middleware handler to be executed in a given phase.
122
+ * @param {string} name The phase name, e.g. "init" or "routes".
123
+ * @param {Array|string|RegExp} [paths] Optional list of paths limiting
124
+ * the scope of the middleware.
125
+ * String paths are interpreted as expressjs path patterns,
126
+ * regular expressions are used as-is.
127
+ * @param {function} handler The middleware handler, one of
128
+ * `function(req, res, next)` or
129
+ * `function(err, req, res, next)`
130
+ * @returns {object} this (fluent API)
131
+ *
132
+ * @header app.middleware(name, handler)
133
+ */
134
+ proto.middleware = function(name, paths, handler) {
135
+ this.lazyrouter();
136
+ if (handler === void 0 && typeof paths === "function") {
137
+ handler = paths;
138
+ paths = void 0;
139
+ }
140
+ assert(typeof name === "string" && name, "\"name\" must be a non-empty string");
141
+ assert(typeof handler === "function", "\"handler\" must be a function");
142
+ if (paths === void 0) paths = "/";
143
+ const fullPhaseName = name;
144
+ const handlerName = handler.name || "<anonymous>";
145
+ const m = name.match(/^(.+):(before|after)$/);
146
+ if (m) name = m[1];
147
+ if (this._requestHandlingPhases.indexOf(name) === -1) throw new Error(g.f("Unknown {{middleware}} phase %s", name));
148
+ debug("use %s %s %s", fullPhaseName, paths, handlerName);
149
+ this._skipLayerSorting = true;
150
+ this.use(paths, handler);
151
+ const layer = this._findLayerByHandler(handler);
152
+ if (layer) layer.phase = fullPhaseName;
153
+ else debug("No matching layer is found for %s %s", fullPhaseName, handlerName);
154
+ this._skipLayerSorting = false;
155
+ this._sortLayersByPhase();
156
+ return this;
157
+ };
158
+ /*!
159
+ * Find the corresponding express layer by handler
160
+ *
161
+ * This is needed because monitoring agents such as NewRelic can add handlers
162
+ * to the stack. For example, NewRelic adds sentinel handler. We need to search
163
+ * the stackto find the correct layer.
164
+ */
165
+ proto._findLayerByHandler = function(handler) {
166
+ for (let k = this._router.stack.length - 1; k >= 0; k--) {
167
+ const isOriginal = this._router.stack[k].handle === handler;
168
+ const isNewRelic = this._router.stack[k].handle["__NR_original"] === handler;
169
+ const isAppDynamics = this._router.stack[k].handle["__appdynamicsProxyInfo__"] && this._router.stack[k].handle["__appdynamicsProxyInfo__"]["orig"] === handler;
170
+ if (isOriginal || isNewRelic || isAppDynamics) return this._router.stack[k];
171
+ else for (const p in this._router.stack[k].handle) if (this._router.stack[k].handle[p] === handler) return this._router.stack[k];
172
+ }
173
+ return null;
174
+ };
175
+ proto.lazyrouter = function() {
176
+ const self = this;
177
+ if (self._router) return;
178
+ self.__expressLazyRouter();
179
+ const router = self._router;
180
+ router.stack.forEach(function(layer) {
181
+ layer.phase = BUILTIN_MIDDLEWARE;
182
+ });
183
+ router.__expressUse = router.use;
184
+ router.use = function useAndSort() {
185
+ const retval = this.__expressUse.apply(this, arguments);
186
+ self._sortLayersByPhase();
187
+ return retval;
188
+ };
189
+ router.__expressRoute = router.route;
190
+ router.route = function routeAndSort() {
191
+ const retval = this.__expressRoute.apply(this, arguments);
192
+ self._sortLayersByPhase();
193
+ return retval;
194
+ };
195
+ self._requestHandlingPhases = [
196
+ "initial",
197
+ "session",
198
+ "auth",
199
+ "parse",
200
+ "routes",
201
+ "files",
202
+ "final"
203
+ ];
204
+ };
205
+ proto._sortLayersByPhase = function() {
206
+ if (this._skipLayerSorting) return;
207
+ const phaseOrder = {};
208
+ this._requestHandlingPhases.forEach(function(name, ix) {
209
+ phaseOrder[name + ":before"] = ix * 3;
210
+ phaseOrder[name] = ix * 3 + 1;
211
+ phaseOrder[name + ":after"] = ix * 3 + 2;
212
+ });
213
+ this._router.stack.sort(compareLayers);
214
+ function compareLayers(left, right) {
215
+ const leftPhase = left.phase;
216
+ const rightPhase = right.phase;
217
+ if (leftPhase === rightPhase) return 0;
218
+ if (leftPhase === BUILTIN_MIDDLEWARE) return -1;
219
+ if (rightPhase === BUILTIN_MIDDLEWARE) return 1;
220
+ if (leftPhase === void 0) {
221
+ if (rightPhase === "routes") return -1;
222
+ return phaseOrder.routes - phaseOrder[rightPhase];
223
+ }
224
+ if (rightPhase === void 0) return -compareLayers(right, left);
225
+ return phaseOrder[leftPhase] - phaseOrder[rightPhase];
226
+ }
227
+ };
228
+ module.exports = loopbackExpress;
229
+ }));
230
+ //#endregion
231
+ module.exports = require_server_app();
@@ -0,0 +1,154 @@
1
+ //#region src/lib/utils.ts
2
+ var require_utils = /* @__PURE__ */ require("../_virtual/_rolldown/runtime.cjs").__commonJSMin(((exports, module) => {
3
+ const hasOwnProperty = Object.prototype.hasOwnProperty;
4
+ function createPromiseCallback() {
5
+ let cb;
6
+ const promise = new Promise(function(resolve, reject) {
7
+ cb = function(err, data) {
8
+ if (err) return reject(err);
9
+ return resolve(data);
10
+ };
11
+ });
12
+ cb.promise = promise;
13
+ return cb;
14
+ }
15
+ function asCallback(promise, cb) {
16
+ if (typeof cb !== "function") return promise;
17
+ promise.then(function(result) {
18
+ cb(null, result);
19
+ }, function(err) {
20
+ cb(err);
21
+ });
22
+ return cb;
23
+ }
24
+ function invokeWithCallback(fn, receiver, args) {
25
+ return new Promise(function(resolve, reject) {
26
+ const argCount = args ? args.length : 0;
27
+ const invokeArgs = new Array(argCount + 1);
28
+ for (let i = 0; i < argCount; i++) invokeArgs[i] = args[i];
29
+ invokeArgs[argCount] = function(err, value) {
30
+ if (err) return reject(err);
31
+ resolve(value);
32
+ };
33
+ fn.apply(receiver, invokeArgs);
34
+ });
35
+ }
36
+ /**
37
+ * Divide an async call with large array into multiple calls using smaller chunks
38
+ * @param {Array} largeArray - the large array to be chunked
39
+ * @param {Number} chunkSize - size of each chunks
40
+ * @param {Function} processFunction - the function to be called multiple times
41
+ * @param {Function} cb - the callback
42
+ */
43
+ function uploadInChunks(largeArray, chunkSize, processFunction, cb) {
44
+ cb = cb || createPromiseCallback();
45
+ (async function() {
46
+ if (!chunkSize || chunkSize < 1 || largeArray.length <= chunkSize) return invokeWithCallback(processFunction, null, [largeArray]);
47
+ let previousResults;
48
+ for (let start = 0; start < largeArray.length; start += chunkSize) {
49
+ const results = await invokeWithCallback(processFunction, null, [largeArray.slice(start, start + chunkSize)]);
50
+ previousResults = mergeChunkResults(previousResults, results);
51
+ }
52
+ return previousResults;
53
+ })().then(function(results) {
54
+ cb(null, results);
55
+ }, function(err) {
56
+ cb(err);
57
+ });
58
+ return cb.promise;
59
+ }
60
+ /**
61
+ * Page async download calls
62
+ * @param {Object} filter - filter object used for the async call
63
+ * @param {Number} chunkSize - size of each chunks
64
+ * @param {Function} processFunction - the function to be called multiple times
65
+ * @param {Function} cb - the callback
66
+ */
67
+ function downloadInChunks(filter, chunkSize, processFunction, cb) {
68
+ cb = cb || createPromiseCallback();
69
+ const baseFilter = filter ? cloneFilter(filter) : {};
70
+ (async function() {
71
+ if (!chunkSize || chunkSize < 1) return invokeWithCallback(processFunction, null, [baseFilter]);
72
+ let results;
73
+ let skip = 0;
74
+ while (true) {
75
+ const currentFilter = cloneFilter(baseFilter);
76
+ currentFilter.skip = skip;
77
+ currentFilter.limit = chunkSize;
78
+ const pagedResults = await invokeWithCallback(processFunction, null, [currentFilter]);
79
+ results = mergeChunkResults(results, pagedResults);
80
+ const pagedResultCount = pagedResults && typeof pagedResults.length === "number" ? pagedResults.length : 0;
81
+ if (pagedResultCount < chunkSize) return results;
82
+ skip += pagedResultCount;
83
+ }
84
+ })().then(function(results) {
85
+ cb(null, results);
86
+ }, function(err) {
87
+ cb(err);
88
+ });
89
+ return cb.promise;
90
+ }
91
+ /**
92
+ * Concat current results into previous results
93
+ * Assumption made here that the previous results and current results are homogeneous
94
+ * @param {Object|Array} previousResults
95
+ * @param {Object|Array} currentResults
96
+ */
97
+ function concatResults(previousResults, currentResults) {
98
+ if (Array.isArray(currentResults)) previousResults = concatArrays(previousResults, currentResults);
99
+ else if (typeof currentResults === "object") {
100
+ for (const key in currentResults) if (hasOwnProperty.call(currentResults, key)) previousResults[key] = concatResults(previousResults[key], currentResults[key]);
101
+ } else previousResults = currentResults;
102
+ return previousResults;
103
+ }
104
+ function mergeChunkResults(previousResults, currentResults) {
105
+ if (typeof previousResults === "undefined" || previousResults === null) return cloneChunkResult(currentResults);
106
+ if (typeof currentResults === "undefined" || currentResults === null) return previousResults;
107
+ if (Array.isArray(previousResults) && Array.isArray(currentResults)) {
108
+ appendArrayItems(previousResults, currentResults);
109
+ return previousResults;
110
+ }
111
+ if (isPlainObject(previousResults) && isPlainObject(currentResults)) {
112
+ for (const key in currentResults) if (hasOwnProperty.call(currentResults, key)) previousResults[key] = mergeChunkResults(previousResults[key], currentResults[key]);
113
+ return previousResults;
114
+ }
115
+ return currentResults;
116
+ }
117
+ function cloneChunkResult(value) {
118
+ if (Array.isArray(value)) return value.slice();
119
+ if (isPlainObject(value)) {
120
+ const clone = {};
121
+ for (const key in value) if (hasOwnProperty.call(value, key)) clone[key] = cloneChunkResult(value[key]);
122
+ return clone;
123
+ }
124
+ return value;
125
+ }
126
+ function appendArrayItems(target, items) {
127
+ for (let i = 0; i < items.length; i++) target.push(items[i]);
128
+ }
129
+ function concatArrays(left, right) {
130
+ const result = new Array(left.length + right.length);
131
+ let index = 0;
132
+ for (let i = 0; i < left.length; i++) result[index++] = left[i];
133
+ for (let i = 0; i < right.length; i++) result[index++] = right[i];
134
+ return result;
135
+ }
136
+ function isPlainObject(value) {
137
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
138
+ const prototype = Object.getPrototypeOf(value);
139
+ return prototype === Object.prototype || prototype === null;
140
+ }
141
+ function cloneFilter(filter) {
142
+ return JSON.parse(JSON.stringify(filter));
143
+ }
144
+ module.exports = {
145
+ asCallback,
146
+ concatResults,
147
+ createPromiseCallback,
148
+ downloadInChunks,
149
+ invokeWithCallback,
150
+ uploadInChunks
151
+ };
152
+ }));
153
+ //#endregion
154
+ module.exports = require_utils();