@homer0/jimple 2.0.1 → 2.0.2

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.
package/dist/esm/index.js CHANGED
@@ -16,6 +16,10 @@ var __copyProps = (to, from, except, desc) => {
16
16
  return to;
17
17
  };
18
18
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
19
+ // If the importer is in node compatibility mode or this is not an ESM
20
+ // file that has been converted to a CommonJS file using a Babel-
21
+ // compatible transform (i.e. "__esModule" has not been set), then set
22
+ // "default" to the CommonJS "module.exports" for node compatibility.
19
23
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
20
24
  mod
21
25
  ));
@@ -51,6 +55,10 @@ var require_Jimple = __commonJS({
51
55
  static provider(register) {
52
56
  return { register };
53
57
  }
58
+ /**
59
+ * Create a Jimple Container.
60
+ * @param {Object?} [values] - An optional object whose keys and values will be associated in the container at initialization
61
+ */
54
62
  constructor(values) {
55
63
  this._items = {};
56
64
  this._instances = /* @__PURE__ */ new Map();
@@ -61,6 +69,13 @@ var require_Jimple = __commonJS({
61
69
  this.set(key, values[key]);
62
70
  }, this);
63
71
  }
72
+ /**
73
+ * Return the specified parameter or service. If the service is not built yet, this function will construct the service
74
+ * injecting all the dependencies needed in it's definition so the returned object is totally usable on the fly.
75
+ * @param {string} key - The key of the parameter or service to return
76
+ * @return {*} The object related to the service or the value of the parameter associated with the key informed
77
+ * @throws If the key does not exist
78
+ */
64
79
  get(key) {
65
80
  checkDefined(this, key);
66
81
  let item = this._items[key];
@@ -81,21 +96,53 @@ var require_Jimple = __commonJS({
81
96
  }
82
97
  return obj;
83
98
  }
99
+ /**
100
+ * Defines a new parameter or service.
101
+ * @param {string} key - The key of the parameter or service to be defined
102
+ * @param {*} value - The value of the parameter or a function that receives the container as parameter and constructs the service
103
+ */
84
104
  set(key, value) {
85
105
  this._items[key] = value;
86
106
  }
107
+ /**
108
+ * Returns if a service or parameter with the informed key is already defined in the container.
109
+ * @param {string} key - The key of the parameter or service to be checked.
110
+ * @return {boolean} If the key exists in the container or not
111
+ */
87
112
  has(key) {
88
113
  return this._items.hasOwnProperty(key);
89
114
  }
115
+ /**
116
+ * Defines a service as a factory, so the instances are not cached in the service and that function is always called
117
+ * @param {function(Jimple):*} fn - The function that constructs the service that is a factory
118
+ * @return {function(Jimple):*} The same function passed as parameter
119
+ */
90
120
  factory(fn) {
91
121
  return addFunctionTo(this._factories, fn);
92
122
  }
123
+ /**
124
+ * Defines a function as a parameter, so that function is not considered a service
125
+ * @param {*} fn - The function to not be considered a service
126
+ * @return {*} The same function passed as parameter
127
+ */
93
128
  protect(fn) {
94
129
  return addFunctionTo(this._protected, fn);
95
130
  }
131
+ /**
132
+ * Return all the keys registered in the container
133
+ * @returns {Array<string>}
134
+ */
96
135
  keys() {
97
136
  return Object.keys(this._items);
98
137
  }
138
+ /**
139
+ * Extends a service already registered in the container
140
+ * @param {string} key - The key of the service to be extended
141
+ * @param {function(*, Jimple):*} fn - The function that will be used to extend the service
142
+ * @throws If the key is not already defined
143
+ * @throws If the key saved in the container does not correspond to a service
144
+ * @throws If the function passed it not...well, a function
145
+ */
99
146
  extend(key, fn) {
100
147
  checkDefined(this, key);
101
148
  let originalItem = this._items[key];
@@ -109,9 +156,20 @@ var require_Jimple = __commonJS({
109
156
  this._factories.add(this._items[key]);
110
157
  }
111
158
  }
159
+ /**
160
+ * Uses an provider to extend the service, so it's easy to split the service and parameter definitions across the system
161
+ * @param {{register: function(Jimple)}} provider - The provider to be used to register services and parameters in this container
162
+ */
112
163
  register(provider2) {
113
164
  provider2.register(this);
114
165
  }
166
+ /**
167
+ * Returns the raw value of a service or parameter. So, in the case of a service, for example, the value returned is the
168
+ * function used to construct the service.
169
+ * @param {string} key - The key of the service or parameter to return.
170
+ * @throws If the key does not exist in the container
171
+ * @return {*} The raw value of the service or parameter
172
+ */
115
173
  raw(key) {
116
174
  checkDefined(this, key);
117
175
  return this._items[key];
@@ -127,6 +185,15 @@ var Jimple = import_jimple.default;
127
185
 
128
186
  // src/jimple/index.ts
129
187
  var Jimple2 = class extends Jimple {
188
+ /**
189
+ * This is a version of the `get` method that doesn't throw if the key doesn't exist. It
190
+ * will return `undefined` instead.
191
+ *
192
+ * @param key The key of the parameter or service to return.
193
+ * @returns The object related to the service or the value of the parameter
194
+ * associated with the given key.
195
+ * @template T The type of the returned object.
196
+ */
130
197
  try(key) {
131
198
  if (!this.has(key)) {
132
199
  return void 0;
@@ -137,87 +204,183 @@ var Jimple2 = class extends Jimple {
137
204
  var jimple = (...args) => new Jimple2(...args);
138
205
 
139
206
  // src/factories/resourceFactory.ts
140
- var resourceFactory = () => (name, key, fn) => ({
141
- [name]: true,
142
- [key]: fn
143
- });
207
+ var resourceFactory = () => (
208
+ /**
209
+ * Generates a new resource using the contraint defined in the factory.
210
+ *
211
+ * @param name The name of the resource.
212
+ * @param key The property key for the function.
213
+ * @param fn The resource function.
214
+ * @returns An object with the `name` set to `true`, and the `fn` as the `key`.
215
+ * @template Name The literal type of `name`, to be used in the return object.
216
+ * @template Key The literal type of `key`, to be used in the return object.
217
+ * @template Fn The type of `fn`, restricted by the factory constraint.
218
+ * @example
219
+ *
220
+ * const myAction = factory('action', 'fn', (c) => {
221
+ * c.set('foo', 'bar');
222
+ * });
223
+ *
224
+ */
225
+ (name, key, fn) => ({
226
+ [name]: true,
227
+ [key]: fn
228
+ })
229
+ );
144
230
 
145
231
  // src/factories/resourceCreatorFactory.ts
146
- var resourceCreatorFactory = () => (name, key, creatorFn) => {
147
- const fnToProxy = (...args) => {
148
- const actualResource = creatorFn(...args);
149
- return resourceFactory()(name, key, actualResource);
150
- };
151
- const handler = {
152
- name,
153
- resource: null,
154
- get(target, property) {
155
- let result;
156
- if (property === this.name) {
157
- result = true;
158
- } else if (property === key) {
159
- if (this.resource === null) {
160
- const newResource = creatorFn();
161
- this.resource = newResource;
232
+ var resourceCreatorFactory = () => (
233
+ /**
234
+ * Generates a new resource creator using the contraint defined in the factory.
235
+ *
236
+ * @param name The name of the resource.
237
+ * @param key The property key for the function.
238
+ * @param creatorFn The curried function that returns the actual resource function.
239
+ * @returns A resource creator: an object that can be used as a resource, and as a
240
+ * function that returns a resource.
241
+ * @template Name The literal type of `name`, to be used in the return object.
242
+ * @template Key The literal type of `key`, to be used in the return object.
243
+ * @template ResFn The type of the resource function, the creator function needs
244
+ * to return. This is restricted by the factory constraint.
245
+ * @template CreatorFn The literal type of `creatorFn`, to be used in the return
246
+ * object.
247
+ * @example
248
+ *
249
+ * const myAction = factory('action', 'fn', (name = 'foo') => (c) => {
250
+ * c.set(name, 'bar');
251
+ * });
252
+ *
253
+ */
254
+ (name, key, creatorFn) => {
255
+ const fnToProxy = (...args) => {
256
+ const actualResource = creatorFn(...args);
257
+ return resourceFactory()(name, key, actualResource);
258
+ };
259
+ const handler = {
260
+ name,
261
+ resource: null,
262
+ get(target, property) {
263
+ let result;
264
+ if (property === this.name) {
265
+ result = true;
266
+ } else if (property === key) {
267
+ if (this.resource === null) {
268
+ const newResource = creatorFn();
269
+ this.resource = newResource;
270
+ }
271
+ result = this.resource;
272
+ } else {
273
+ const targetKey = property;
274
+ result = target[targetKey];
275
+ }
276
+ return result;
277
+ },
278
+ has(target, property) {
279
+ if (property === this.name || property === key) {
280
+ return true;
162
281
  }
163
- result = this.resource;
164
- } else {
165
282
  const targetKey = property;
166
- result = target[targetKey];
283
+ return targetKey in target;
167
284
  }
168
- return result;
169
- },
170
- has(target, property) {
171
- if (property === this.name || property === key) {
172
- return true;
173
- }
174
- const targetKey = property;
175
- return targetKey in target;
176
- }
177
- };
178
- return new Proxy(fnToProxy, handler);
179
- };
285
+ };
286
+ return new Proxy(fnToProxy, handler);
287
+ }
288
+ );
180
289
 
181
290
  // src/factories/resourcesCollectionFactory.ts
182
- var resourcesCollectionFactory = () => (name, key, fn) => {
183
- const collectionResourceFactory = resourceFactory();
184
- return (items) => {
185
- const invalidKeys = [name, key];
186
- const itemsKeys = Object.keys(items);
187
- const invalidKey = itemsKeys.some(
188
- (itemKey) => invalidKeys.includes(String(itemKey))
189
- );
190
- if (invalidKey) {
191
- throw new Error(
192
- `No item on the collection can have the keys \`${name}\` nor \`${key}\``
291
+ var resourcesCollectionFactory = () => (
292
+ /**
293
+ * Generates a function to create a collection of resources of an specified type. A
294
+ * collection is a dictionary of resources, and a resource itself, and when its
295
+ * "resource function" gets called, it calls the function of every resource (with the
296
+ * same args it recevied).
297
+ *
298
+ * @param name The resource name the items in the collection must have.
299
+ * @param key The key property the items in the collection must have.
300
+ * @param fn A custom function to process the items in the collection, when the
301
+ * collection function gets called.
302
+ * @returns A function that can be used to create a resources collection.
303
+ * @template Name The literal type of `name`, to be used in the return object.
304
+ * @template Key The literal type of `key`, to be used in the return object.
305
+ * @template ItemKey To capture the name of the resources in the collection.
306
+ * @template Items The kind of dictionary of resources the return function will
307
+ * expect.
308
+ * @template CustomFn The type of `fn`, restricted by the factory constraint.
309
+ * @example
310
+ *
311
+ * const myActions = factory('action', 'fn')({ myActionA, myActionB });
312
+ *
313
+ */
314
+ (name, key, fn) => {
315
+ const collectionResourceFactory = resourceFactory();
316
+ return (items) => {
317
+ const invalidKeys = [name, key];
318
+ const itemsKeys = Object.keys(items);
319
+ const invalidKey = itemsKeys.some(
320
+ (itemKey) => invalidKeys.includes(String(itemKey))
193
321
  );
194
- }
195
- const invalidItem = itemsKeys.find(
196
- (itemKey) => typeof items[itemKey]?.[key] !== "function"
197
- );
198
- if (invalidItem) {
199
- throw new Error(
200
- `The item \`${String(
201
- invalidItem
202
- )}\` is invalid: it doesn't have a \`${key}\` function`
322
+ if (invalidKey) {
323
+ throw new Error(
324
+ `No item on the collection can have the keys \`${name}\` nor \`${key}\``
325
+ );
326
+ }
327
+ const invalidItem = itemsKeys.find(
328
+ (itemKey) => typeof items[itemKey]?.[key] !== "function"
203
329
  );
204
- }
205
- const useFn = fn ? (...args) => fn(items, ...args) : (...args) => {
206
- itemsKeys.forEach((itemK) => {
207
- const item = items[itemK];
208
- const itemFn = item[key];
209
- itemFn(...args);
210
- });
211
- };
212
- return {
213
- ...collectionResourceFactory(name, key, useFn),
214
- ...items
330
+ if (invalidItem) {
331
+ throw new Error(
332
+ `The item \`${String(
333
+ invalidItem
334
+ )}\` is invalid: it doesn't have a \`${key}\` function`
335
+ );
336
+ }
337
+ const useFn = fn ? (...args) => fn(items, ...args) : (...args) => {
338
+ itemsKeys.forEach((itemK) => {
339
+ const item = items[itemK];
340
+ const itemFn = item[key];
341
+ itemFn(...args);
342
+ });
343
+ };
344
+ return {
345
+ ...collectionResourceFactory(name, key, useFn),
346
+ ...items
347
+ };
215
348
  };
216
- };
217
- };
349
+ }
350
+ );
218
351
 
219
352
  // src/helpers/injectHelper.ts
220
353
  var InjectHelper = class {
354
+ /**
355
+ * This method is meant to be used to validate the dependencies a service receives, and
356
+ * needs.
357
+ * It will check on the received dependencies, if a specific dependency exists, it will
358
+ * return it, otherwise, it will create a new instance.
359
+ *
360
+ * @param dependencies The dependencies received by the implementation.
361
+ * @param key The key of the dependency to validate.
362
+ * @param init A function to create a dependency in case it doesn't exist in
363
+ * the dictionary.
364
+ * @returns An instance of the dependency.
365
+ * @template DepKey The literal key of the dependency to validate.
366
+ * @template DepType The type of the dependency, obtained from the dictionary sent
367
+ * to the constructor.
368
+ * @example
369
+ *
370
+ * type Dependencies = {
371
+ * dep: string;
372
+ * };
373
+ * const helper = new InjectHelper<Dependencies>();
374
+ *
375
+ * type MyServiceOptions = {
376
+ * inject?: Partial<Dependencies>;
377
+ * };
378
+ * const myService = ({ inject = {} }: MyServiceOptions) => {
379
+ * const dep = helper.get(inject, 'dep', () => 'default');
380
+ * console.log('dep:', dep);
381
+ * };
382
+ *
383
+ */
221
384
  get(dependencies, key, init) {
222
385
  const existing = dependencies[key];
223
386
  if (typeof existing !== "undefined") {
@@ -225,6 +388,43 @@ var InjectHelper = class {
225
388
  }
226
389
  return init();
227
390
  }
391
+ /**
392
+ * This is meant to be used in a provider creator to resolve dependencies' names sent as
393
+ * options. For each dependency, the method will first check if a new name was
394
+ * specified, and try to get it with that name, otherwise, it will try to get it with
395
+ * the default name, and if it doesn't exist, it will just keep it as `undefined` and
396
+ * expect the service implements {@link InjectHelper.get} to ensure the dependency.
397
+ *
398
+ * @param dependencies The dependencies needed by the service.
399
+ * @param container A reference to the Jimple container.
400
+ * @param inject A dictionary of dependencies names.
401
+ * @returns A dictionary of dependencies to send to the service.
402
+ * @template DepKey The literal key of the dependencies to validate.
403
+ * @template Container The type of the Jimple container.
404
+ * @example
405
+ *
406
+ * type Dependencies = {
407
+ * dep: string;
408
+ * };
409
+ * const helper = new InjectHelper<Dependencies>();
410
+ *
411
+ * type MyProviderOptions = {
412
+ * services?: {
413
+ * [key in keyof Dependencies]?: string;
414
+ * };
415
+ * };
416
+ *
417
+ * const myProvider = providerCreator(
418
+ * ({ services = {} }: MyProviderOptions) =>
419
+ * (container) => {
420
+ * container.set('myService', () => {
421
+ * const inject = helper.resolve(['dep'], container, services);
422
+ * return myService({ inject });
423
+ * });
424
+ * },
425
+ * );
426
+ *
427
+ */
228
428
  resolve(dependencies, container, inject) {
229
429
  const result = dependencies.reduce((acc, key) => {
230
430
  if (inject[key]) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../node_modules/jimple/src/Jimple.js","../../src/jimplemod/index.ts","../../src/jimple/index.ts","../../src/factories/resourceFactory.ts","../../src/factories/resourceCreatorFactory.ts","../../src/factories/resourcesCollectionFactory.ts","../../src/helpers/injectHelper.ts","../../src/helpers/provider.ts","../../src/helpers/providerCreator.ts","../../src/helpers/providers.ts"],"sourcesContent":["\"use strict\";\n\nfunction assert(ok, message) {\n if (!ok) {\n throw new Error(message)\n }\n}\n\nfunction isFunction(fn) {\n return Object.prototype.toString.call(fn) === \"[object Function]\" && fn.constructor.name === \"Function\";\n}\n\nfunction isPlainObject(value) {\n if (Object.prototype.toString.call(value) !== '[object Object]') {\n return false;\n }\n let prototype = Object.getPrototypeOf(value);\n return prototype === null || prototype === Object.prototype;\n}\n\nfunction checkDefined(container, key) {\n assert(container.has(key), `Identifier \"${key}\" is not defined.`);\n}\n\nfunction addFunctionTo(set, fn) {\n assert(isFunction(fn), \"Service definition is not a Closure or invokable object\");\n set.add(fn);\n return fn;\n}\n\n/**\n * The Jimple Container class\n *\n * @public\n */\nclass Jimple {\n static provider(register) {\n return ({ register });\n }\n /**\n * Create a Jimple Container.\n * @param {Object?} [values] - An optional object whose keys and values will be associated in the container at initialization\n */\n constructor(values) {\n this._items = {};\n this._instances = new Map();\n this._factories = new Set();\n this._protected = new Set();\n values = isPlainObject(values) ? values : {};\n Object.keys(values).forEach(function(key) {\n this.set(key, values[key]);\n }, this);\n }\n /**\n * Return the specified parameter or service. If the service is not built yet, this function will construct the service\n * injecting all the dependencies needed in it's definition so the returned object is totally usable on the fly.\n * @param {string} key - The key of the parameter or service to return\n * @return {*} The object related to the service or the value of the parameter associated with the key informed\n * @throws If the key does not exist\n */\n get(key) {\n checkDefined(this, key);\n let item = this._items[key];\n let obj;\n if (isFunction(item)) {\n if (this._protected.has(item)) {\n obj = item;\n } else if (this._instances.has(item)) {\n obj = this._instances.get(item);\n } else {\n obj = item(this);\n if (!this._factories.has(item)) {\n this._instances.set(item, obj);\n }\n }\n } else {\n obj = item;\n }\n return obj;\n }\n /**\n * Defines a new parameter or service.\n * @param {string} key - The key of the parameter or service to be defined\n * @param {*} value - The value of the parameter or a function that receives the container as parameter and constructs the service\n */\n set(key, value) {\n this._items[key] = value;\n }\n\n /**\n * Returns if a service or parameter with the informed key is already defined in the container.\n * @param {string} key - The key of the parameter or service to be checked.\n * @return {boolean} If the key exists in the container or not\n */\n has(key) {\n return this._items.hasOwnProperty(key);\n }\n\n /**\n * Defines a service as a factory, so the instances are not cached in the service and that function is always called\n * @param {function(Jimple):*} fn - The function that constructs the service that is a factory\n * @return {function(Jimple):*} The same function passed as parameter\n */\n factory(fn) {\n return addFunctionTo(this._factories, fn);\n }\n\n /**\n * Defines a function as a parameter, so that function is not considered a service\n * @param {*} fn - The function to not be considered a service\n * @return {*} The same function passed as parameter\n */\n protect(fn) {\n return addFunctionTo(this._protected, fn);\n }\n\n /**\n * Return all the keys registered in the container\n * @returns {Array<string>}\n */\n keys() {\n return Object.keys(this._items);\n }\n\n /**\n * Extends a service already registered in the container\n * @param {string} key - The key of the service to be extended\n * @param {function(*, Jimple):*} fn - The function that will be used to extend the service\n * @throws If the key is not already defined\n * @throws If the key saved in the container does not correspond to a service\n * @throws If the function passed it not...well, a function\n */\n extend(key, fn) {\n checkDefined(this, key);\n let originalItem = this._items[key];\n assert(isFunction(originalItem) && this._protected.has(originalItem) === false, `Identifier '${key}' does not contain a service definition`);\n assert(isFunction(fn), `The 'new' service definition for '${key}' is not a invokable object.`);\n this._items[key] = function(app) {\n return fn(originalItem(app), app);\n }\n if (this._factories.has(originalItem)) {\n this._factories.delete(originalItem);\n this._factories.add(this._items[key]);\n }\n }\n\n /**\n * Uses an provider to extend the service, so it's easy to split the service and parameter definitions across the system\n * @param {{register: function(Jimple)}} provider - The provider to be used to register services and parameters in this container\n */\n register(provider) {\n provider.register(this);\n }\n\n /**\n * Returns the raw value of a service or parameter. So, in the case of a service, for example, the value returned is the\n * function used to construct the service.\n * @param {string} key - The key of the service or parameter to return.\n * @throws If the key does not exist in the container\n * @return {*} The raw value of the service or parameter\n */\n raw(key) {\n checkDefined(this, key);\n return this._items[key];\n }\n}\n\nmodule.exports = Jimple;\n","// @ts-expect-error - the idea is to have `any` and assert on export.\nimport JimpleOriginal from 'jimple';\nimport { Container as JimpleContainer } from './jimple.type';\n\nconst Jimple = JimpleOriginal as typeof JimpleContainer;\n\nexport { Jimple };\nexport type { JimpleContainer };\n","import { Jimple as JimpleMod } from '../jimplemod';\n\nexport class Jimple extends JimpleMod {\n /**\n * This is a version of the `get` method that doesn't throw if the key doesn't exist. It\n * will return `undefined` instead.\n *\n * @param key The key of the parameter or service to return.\n * @returns The object related to the service or the value of the parameter\n * associated with the given key.\n * @template T The type of the returned object.\n */\n try<T = unknown>(key: string): T | undefined {\n if (!this.has(key)) {\n return undefined;\n }\n\n return this.get<T>(key);\n }\n}\n/**\n * Shorthand for `new Jimple()`.\n *\n * @param args The same parameters as the {@link Jimple} constructor.\n * @returns A new instance of {@link Jimple}.\n */\nexport const jimple = (...args: ConstructorParameters<typeof Jimple>): Jimple =>\n new Jimple(...args);\n","import type { GenericFn, Resource } from './factories.types';\n/**\n * Generates a function to create resources of an specified type. This function itself\n * doesn't have logic, but it's just in charge of creating the constraint for the resource\n * function.\n *\n * As all the other _\"factory functions\"_, this is meant to be used as a building block\n * when extending the container.\n *\n * @returns A function that can be used to create a resource with a specified type of\n * function.\n * @template ResourceFn The type of function the resource needs to have.\n * @example\n *\n * type ActionFn = (c: Jimple) => void;\n * const factory = resourceFactory<ActionFn>();\n * const myAction = factory('action', 'fn', (c) => {\n * c.set('foo', 'bar');\n * });\n *\n */\nexport const resourceFactory =\n <ResourceFn extends GenericFn>() =>\n /**\n * Generates a new resource using the contraint defined in the factory.\n *\n * @param name The name of the resource.\n * @param key The property key for the function.\n * @param fn The resource function.\n * @returns An object with the `name` set to `true`, and the `fn` as the `key`.\n * @template Name The literal type of `name`, to be used in the return object.\n * @template Key The literal type of `key`, to be used in the return object.\n * @template Fn The type of `fn`, restricted by the factory constraint.\n * @example\n *\n * const myAction = factory('action', 'fn', (c) => {\n * c.set('foo', 'bar');\n * });\n *\n */\n <Name extends string, Key extends string, Fn extends ResourceFn>(\n name: Name,\n key: Key,\n fn: Fn,\n ): Resource<Name, Key, Fn> =>\n ({\n [name]: true,\n [key]: fn,\n } as Resource<Name, Key, Fn>);\n","import { resourceFactory } from './resourceFactory';\nimport type {\n GenericFn,\n GenericCurriedFn,\n ResourceCreator,\n ResourceCreatorCurriedFn,\n ResourceCreatorHandler,\n} from './factories.types';\n/**\n * Generates a function to create resource creators of an specified type. This function\n * itself doesn't have logic, but it's just in charge of creating the constraint for the\n * resource creator function.\n *\n * As all the other _\"factory functions\"_, this is meant to be used as a building block\n * when extending the container.\n *\n * @returns A function that can be used to create \"resource creators\".\n * @template ResourceFn The type of function the resource creator needs to have.\n * @example\n *\n * type ActionFn = (c: Jimple) => void;\n * const factory = resourceCreatorFactory<ActionFn>();\n * const myAction = factory('action', 'fn', (name = 'foo') => (c) => {\n * c.set(name, 'bar');\n * });\n *\n */\nexport const resourceCreatorFactory =\n <ResourceFn extends GenericFn>() =>\n /**\n * Generates a new resource creator using the contraint defined in the factory.\n *\n * @param name The name of the resource.\n * @param key The property key for the function.\n * @param creatorFn The curried function that returns the actual resource function.\n * @returns A resource creator: an object that can be used as a resource, and as a\n * function that returns a resource.\n * @template Name The literal type of `name`, to be used in the return object.\n * @template Key The literal type of `key`, to be used in the return object.\n * @template ResFn The type of the resource function, the creator function needs\n * to return. This is restricted by the factory constraint.\n * @template CreatorFn The literal type of `creatorFn`, to be used in the return\n * object.\n * @example\n *\n * const myAction = factory('action', 'fn', (name = 'foo') => (c) => {\n * c.set(name, 'bar');\n * });\n *\n */\n <\n Name extends string,\n Key extends string,\n ResFn extends ResourceFn,\n CreatorFn extends GenericCurriedFn<ResFn>,\n >(\n name: Name,\n key: Key,\n creatorFn: CreatorFn,\n ): ResourceCreator<Name, Key, CreatorFn, ResourceFn> => {\n const fnToProxy: ResourceCreatorCurriedFn<Name, Key, CreatorFn> = (...args) => {\n const actualResource = creatorFn(...args) as ReturnType<CreatorFn>;\n return resourceFactory<ResFn>()(name, key, actualResource);\n };\n\n const handler: ResourceCreatorHandler<Name, Key, CreatorFn> = {\n name,\n resource: null,\n get(target, property) {\n let result;\n if (property === this.name) {\n result = true;\n } else if (property === key) {\n if (this.resource === null) {\n const newResource = creatorFn() as ReturnType<CreatorFn>;\n this.resource = newResource;\n }\n result = this.resource;\n } else {\n const targetKey = property as keyof typeof target;\n result = target[targetKey];\n }\n\n return result;\n },\n has(target, property) {\n if (property === this.name || property === key) {\n return true;\n }\n\n const targetKey = property as keyof typeof target;\n return targetKey in target;\n },\n };\n\n return new Proxy(fnToProxy, handler) as unknown as ResourceCreator<\n Name,\n Key,\n CreatorFn,\n ResourceFn\n >;\n };\n","import { resourceFactory } from './resourceFactory';\nimport type { GenericFn, Resource } from './factories.types';\n/**\n * Generates a function to configure a collection of resources of an specified type. This\n * function itself doesn't have logic, but it's just in charge of creating the constraint\n * for the resource name and function.\n *\n * As all the other _\"factory functions\"_, this is meant to be used as a building block\n * when extending the container.\n *\n * @returns A function that can be used to configure a collection of resources.\n * @template ResourceName The literal type of the name the resources needs to have.\n * @template ResourceFn The type of function the resources needs to have.\n * @example\n *\n * type ActionFn = (c: Jimple) => void;\n * const factory = resourcesCollectionFactory<'action', ActionFn>();\n * const myActions = factory('action', 'fn')({ myActionA, myActionB });\n *\n */\nexport const resourcesCollectionFactory =\n <ResourceName extends string, ResourceFn extends GenericFn>() =>\n /**\n * Generates a function to create a collection of resources of an specified type. A\n * collection is a dictionary of resources, and a resource itself, and when its\n * \"resource function\" gets called, it calls the function of every resource (with the\n * same args it recevied).\n *\n * @param name The resource name the items in the collection must have.\n * @param key The key property the items in the collection must have.\n * @param fn A custom function to process the items in the collection, when the\n * collection function gets called.\n * @returns A function that can be used to create a resources collection.\n * @template Name The literal type of `name`, to be used in the return object.\n * @template Key The literal type of `key`, to be used in the return object.\n * @template ItemKey To capture the name of the resources in the collection.\n * @template Items The kind of dictionary of resources the return function will\n * expect.\n * @template CustomFn The type of `fn`, restricted by the factory constraint.\n * @example\n *\n * const myActions = factory('action', 'fn')({ myActionA, myActionB });\n *\n */\n <\n Name extends string,\n Key extends string,\n ItemKey extends string,\n Items extends Record<ItemKey, Resource<ResourceName, Key, ResourceFn>>,\n CustomFn extends (items: Items, ...rest: Parameters<ResourceFn>) => void,\n >(\n name: Name,\n key: Key,\n fn?: CustomFn,\n ) => {\n const collectionResourceFactory = resourceFactory<ResourceFn>();\n /**\n * The actual function that recevies the items and creates the collection.\n *\n * @param items A dictionary of resources for the collection.\n * @returns A dictionary of the resources, that it's also a resource.\n * @template ItemsParam The literal type of `items`, to be used in the return\n * object.\n * @throws If the dictionary contains the resource name or function key as keys.\n * @throws If one of the items doesn't have the resource function.\n */\n return <ItemsParam>(\n items: ItemsParam & Items,\n ): typeof items & Resource<Name, Key, ResourceFn> => {\n const invalidKeys: string[] = [name, key];\n const itemsKeys = Object.keys(items) as Array<keyof Items>;\n\n const invalidKey = itemsKeys.some((itemKey) =>\n invalidKeys.includes(String(itemKey)),\n );\n if (invalidKey) {\n throw new Error(\n `No item on the collection can have the keys \\`${name}\\` nor \\`${key}\\``,\n );\n }\n\n const invalidItem = itemsKeys.find(\n (itemKey) => typeof items[itemKey]?.[key] !== 'function',\n );\n if (invalidItem) {\n throw new Error(\n `The item \\`${String(\n invalidItem,\n )}\\` is invalid: it doesn't have a \\`${key}\\` function`,\n );\n }\n\n const useFn = fn\n ? (...args: Parameters<ResourceFn>) => fn(items, ...args)\n : (...args: Parameters<ResourceFn>) => {\n itemsKeys.forEach((itemK) => {\n const item = items[itemK]!;\n const itemFn = item[key];\n itemFn(...args);\n });\n };\n\n return {\n ...collectionResourceFactory(name, key, useFn as ResourceFn),\n ...items,\n };\n };\n };\n","import type { Jimple } from '../jimple';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- They are dynamically extended.\ntype GenericDict = Record<any, any>;\n/**\n * A helper that reusable services can use to resolve dependencies in constructors and/or\n * providers.\n *\n * @template InjectDictionary A dictionary of the dependencies and their types.\n * @template InjectKey The literal type of the dictionary types.\n */\nexport class InjectHelper<\n InjectDictionary extends GenericDict,\n InjectKey = keyof InjectDictionary,\n> {\n /**\n * This method is meant to be used to validate the dependencies a service receives, and\n * needs.\n * It will check on the received dependencies, if a specific dependency exists, it will\n * return it, otherwise, it will create a new instance.\n *\n * @param dependencies The dependencies received by the implementation.\n * @param key The key of the dependency to validate.\n * @param init A function to create a dependency in case it doesn't exist in\n * the dictionary.\n * @returns An instance of the dependency.\n * @template DepKey The literal key of the dependency to validate.\n * @template DepType The type of the dependency, obtained from the dictionary sent\n * to the constructor.\n * @example\n *\n * type Dependencies = {\n * dep: string;\n * };\n * const helper = new InjectHelper<Dependencies>();\n *\n * type MyServiceOptions = {\n * inject?: Partial<Dependencies>;\n * };\n * const myService = ({ inject = {} }: MyServiceOptions) => {\n * const dep = helper.get(inject, 'dep', () => 'default');\n * console.log('dep:', dep);\n * };\n *\n */\n get<DepKey extends InjectKey, DepType = InjectDictionary[DepKey]>(\n dependencies: Partial<InjectDictionary>,\n key: InjectKey,\n init: () => DepType,\n ): DepType {\n const existing = dependencies[key];\n if (typeof existing !== 'undefined') {\n return existing!;\n }\n\n return init();\n }\n /**\n * This is meant to be used in a provider creator to resolve dependencies' names sent as\n * options. For each dependency, the method will first check if a new name was\n * specified, and try to get it with that name, otherwise, it will try to get it with\n * the default name, and if it doesn't exist, it will just keep it as `undefined` and\n * expect the service implements {@link InjectHelper.get} to ensure the dependency.\n *\n * @param dependencies The dependencies needed by the service.\n * @param container A reference to the Jimple container.\n * @param inject A dictionary of dependencies names.\n * @returns A dictionary of dependencies to send to the service.\n * @template DepKey The literal key of the dependencies to validate.\n * @template Container The type of the Jimple container.\n * @example\n *\n * type Dependencies = {\n * dep: string;\n * };\n * const helper = new InjectHelper<Dependencies>();\n *\n * type MyProviderOptions = {\n * services?: {\n * [key in keyof Dependencies]?: string;\n * };\n * };\n *\n * const myProvider = providerCreator(\n * ({ services = {} }: MyProviderOptions) =>\n * (container) => {\n * container.set('myService', () => {\n * const inject = helper.resolve(['dep'], container, services);\n * return myService({ inject });\n * });\n * },\n * );\n *\n */\n resolve<DepKey extends InjectKey, Container extends Jimple>(\n dependencies: DepKey[],\n container: Container,\n inject: Partial<Record<keyof InjectDictionary, string>>,\n ): Partial<InjectDictionary> {\n const result = dependencies.reduce<Partial<InjectDictionary>>((acc, key) => {\n if (inject[key]) {\n acc[key] = container.get<InjectDictionary[typeof key]>(inject[key]!);\n return acc;\n }\n\n const keyStr = key as unknown as string;\n if (container.has(keyStr)) {\n acc[key] = container.get<InjectDictionary[typeof key]>(keyStr);\n return acc;\n }\n\n return acc;\n }, {});\n\n return result;\n }\n}\n/**\n * Shorthand for `new InjectHelper()`.\n *\n * @returns A new instance of {@link InjectHelper}.\n */\nexport const injectHelper = <InjectDictionary extends GenericDict>() =>\n new InjectHelper<InjectDictionary>();\n","import type { Jimple } from '../jimple';\nimport { resourceFactory } from '../factories';\n\nexport type ProviderName = 'provider';\nexport type ProviderKey = 'register';\n/**\n * The function the container will call when the provider is registered.\n *\n * @param container A reference for container where the provider is being registered.\n * @template ContainerType The type of the Jimple container (in case it gets\n * subclassed).\n */\nexport type ProviderRegisterFn<ContainerType extends Jimple = Jimple> = (\n container: ContainerType,\n) => void;\n/**\n * Generates a function to create providers for a specific type of container.\n *\n * @returns A function to create providers.\n * @template ContainerType The type of the Jimple container (in case it gets\n * subclassed).\n */\nexport const createProvider = <ContainerType extends Jimple = Jimple>() => {\n type RegisterFn = ProviderRegisterFn<ContainerType>;\n const factory = resourceFactory<RegisterFn>();\n return (register: RegisterFn) => factory('provider', 'register', register);\n};\n/**\n * Creates a resource to be registered in a Jimple container.\n *\n * @example\n *\n * export const myService = provider((c) => {\n * c.set('myService', () => new MyService());\n * });\n *\n */\nexport const provider = createProvider();\n/**\n * A resource that can be registered in a Jimple container.\n */\nexport type Provider = ReturnType<typeof provider>;\n","import type { Jimple } from '../jimple';\nimport { resourceCreatorFactory, type GenericCurriedFn } from '../factories';\nimport type { ProviderRegisterFn } from './provider';\n/**\n * Generates a function to create \"provider creators\" for a specific type of container.\n *\n * @returns A function to generate provider creators.\n * @template ContainerType The type of the Jimple container (in case it gets\n * subclassed).\n */\nexport const createProviderCreator = <ContainerType extends Jimple = Jimple>() => {\n type RegisterFn = ProviderRegisterFn<ContainerType>;\n type ProviderCreatorFn = GenericCurriedFn<RegisterFn>;\n const factory = resourceCreatorFactory<RegisterFn>();\n return <CreatorFn extends ProviderCreatorFn>(creator: CreatorFn) =>\n factory('provider', 'register', creator);\n};\n/**\n * Generates a \"provider creator\": a provider that can also be called as a function in\n * order to create a configured provider.\n *\n * @example\n *\n * export const myService = providerCreator((options: Opts = {}) => (c) => {\n * c.set('myService', () => new MyService(options));\n * });\n *\n */\nexport const providerCreator = createProviderCreator();\n/**\n * A function that returns a provider registration function.\n */\nexport type ProviderCreatorFn = Parameters<typeof providerCreator>[0];\n","import type { Jimple } from '../jimple';\nimport { resourcesCollectionFactory } from '../factories';\nimport type { ProviderRegisterFn, ProviderName } from './provider';\n/**\n * Generates a function to create a providers collection for a specific type of container.\n *\n * @returns A function to create providers collections.\n * @template ContainerType The type of the Jimple container (in case it gets\n * subclassed).\n */\nexport const createProviders = <ContainerType extends Jimple = Jimple>() => {\n type RegisterFn = ProviderRegisterFn<ContainerType>;\n const factory = resourcesCollectionFactory<ProviderName, RegisterFn>();\n return factory('provider', 'register');\n};\n/**\n * Generates a collection of providers. A collection is a dictionary of providers that can\n * also be used as a provider, and when it gets registered, it will register all of the\n * providers in the collection.\n *\n * @param items A dictionary of providers.\n * @example\n *\n * <caption>Assuming we already have two service providers...</caption>\n *\n * export const services = providers({\n * myServiceProvider,\n * myOtherServiceProvider,\n * });\n *\n */\nexport const providers = createProviders();\n"],"mappings":"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","names":["Jimple","provider","JimpleOriginal","Jimple"]}
1
+ {"version":3,"sources":["../../../../../node_modules/jimple/src/Jimple.js","../../src/jimplemod/index.ts","../../src/jimple/index.ts","../../src/factories/resourceFactory.ts","../../src/factories/resourceCreatorFactory.ts","../../src/factories/resourcesCollectionFactory.ts","../../src/helpers/injectHelper.ts","../../src/helpers/provider.ts","../../src/helpers/providerCreator.ts","../../src/helpers/providers.ts"],"sourcesContent":["\"use strict\";\n\nfunction assert(ok, message) {\n if (!ok) {\n throw new Error(message)\n }\n}\n\nfunction isFunction(fn) {\n return Object.prototype.toString.call(fn) === \"[object Function]\" && fn.constructor.name === \"Function\";\n}\n\nfunction isPlainObject(value) {\n if (Object.prototype.toString.call(value) !== '[object Object]') {\n return false;\n }\n let prototype = Object.getPrototypeOf(value);\n return prototype === null || prototype === Object.prototype;\n}\n\nfunction checkDefined(container, key) {\n assert(container.has(key), `Identifier \"${key}\" is not defined.`);\n}\n\nfunction addFunctionTo(set, fn) {\n assert(isFunction(fn), \"Service definition is not a Closure or invokable object\");\n set.add(fn);\n return fn;\n}\n\n/**\n * The Jimple Container class\n *\n * @public\n */\nclass Jimple {\n static provider(register) {\n return ({ register });\n }\n /**\n * Create a Jimple Container.\n * @param {Object?} [values] - An optional object whose keys and values will be associated in the container at initialization\n */\n constructor(values) {\n this._items = {};\n this._instances = new Map();\n this._factories = new Set();\n this._protected = new Set();\n values = isPlainObject(values) ? values : {};\n Object.keys(values).forEach(function(key) {\n this.set(key, values[key]);\n }, this);\n }\n /**\n * Return the specified parameter or service. If the service is not built yet, this function will construct the service\n * injecting all the dependencies needed in it's definition so the returned object is totally usable on the fly.\n * @param {string} key - The key of the parameter or service to return\n * @return {*} The object related to the service or the value of the parameter associated with the key informed\n * @throws If the key does not exist\n */\n get(key) {\n checkDefined(this, key);\n let item = this._items[key];\n let obj;\n if (isFunction(item)) {\n if (this._protected.has(item)) {\n obj = item;\n } else if (this._instances.has(item)) {\n obj = this._instances.get(item);\n } else {\n obj = item(this);\n if (!this._factories.has(item)) {\n this._instances.set(item, obj);\n }\n }\n } else {\n obj = item;\n }\n return obj;\n }\n /**\n * Defines a new parameter or service.\n * @param {string} key - The key of the parameter or service to be defined\n * @param {*} value - The value of the parameter or a function that receives the container as parameter and constructs the service\n */\n set(key, value) {\n this._items[key] = value;\n }\n\n /**\n * Returns if a service or parameter with the informed key is already defined in the container.\n * @param {string} key - The key of the parameter or service to be checked.\n * @return {boolean} If the key exists in the container or not\n */\n has(key) {\n return this._items.hasOwnProperty(key);\n }\n\n /**\n * Defines a service as a factory, so the instances are not cached in the service and that function is always called\n * @param {function(Jimple):*} fn - The function that constructs the service that is a factory\n * @return {function(Jimple):*} The same function passed as parameter\n */\n factory(fn) {\n return addFunctionTo(this._factories, fn);\n }\n\n /**\n * Defines a function as a parameter, so that function is not considered a service\n * @param {*} fn - The function to not be considered a service\n * @return {*} The same function passed as parameter\n */\n protect(fn) {\n return addFunctionTo(this._protected, fn);\n }\n\n /**\n * Return all the keys registered in the container\n * @returns {Array<string>}\n */\n keys() {\n return Object.keys(this._items);\n }\n\n /**\n * Extends a service already registered in the container\n * @param {string} key - The key of the service to be extended\n * @param {function(*, Jimple):*} fn - The function that will be used to extend the service\n * @throws If the key is not already defined\n * @throws If the key saved in the container does not correspond to a service\n * @throws If the function passed it not...well, a function\n */\n extend(key, fn) {\n checkDefined(this, key);\n let originalItem = this._items[key];\n assert(isFunction(originalItem) && this._protected.has(originalItem) === false, `Identifier '${key}' does not contain a service definition`);\n assert(isFunction(fn), `The 'new' service definition for '${key}' is not a invokable object.`);\n this._items[key] = function(app) {\n return fn(originalItem(app), app);\n }\n if (this._factories.has(originalItem)) {\n this._factories.delete(originalItem);\n this._factories.add(this._items[key]);\n }\n }\n\n /**\n * Uses an provider to extend the service, so it's easy to split the service and parameter definitions across the system\n * @param {{register: function(Jimple)}} provider - The provider to be used to register services and parameters in this container\n */\n register(provider) {\n provider.register(this);\n }\n\n /**\n * Returns the raw value of a service or parameter. So, in the case of a service, for example, the value returned is the\n * function used to construct the service.\n * @param {string} key - The key of the service or parameter to return.\n * @throws If the key does not exist in the container\n * @return {*} The raw value of the service or parameter\n */\n raw(key) {\n checkDefined(this, key);\n return this._items[key];\n }\n}\n\nmodule.exports = Jimple;\n","// @ts-expect-error - the idea is to have `any` and assert on export.\nimport JimpleOriginal from 'jimple';\nimport { Container as JimpleContainer } from './jimple.type';\n\nconst Jimple = JimpleOriginal as typeof JimpleContainer;\n\nexport { Jimple };\nexport type { JimpleContainer };\n","import { Jimple as JimpleMod } from '../jimplemod';\n\nexport class Jimple extends JimpleMod {\n /**\n * This is a version of the `get` method that doesn't throw if the key doesn't exist. It\n * will return `undefined` instead.\n *\n * @param key The key of the parameter or service to return.\n * @returns The object related to the service or the value of the parameter\n * associated with the given key.\n * @template T The type of the returned object.\n */\n try<T = unknown>(key: string): T | undefined {\n if (!this.has(key)) {\n return undefined;\n }\n\n return this.get<T>(key);\n }\n}\n/**\n * Shorthand for `new Jimple()`.\n *\n * @param args The same parameters as the {@link Jimple} constructor.\n * @returns A new instance of {@link Jimple}.\n */\nexport const jimple = (...args: ConstructorParameters<typeof Jimple>): Jimple =>\n new Jimple(...args);\n","import type { GenericFn, Resource } from './factories.types';\n/**\n * Generates a function to create resources of an specified type. This function itself\n * doesn't have logic, but it's just in charge of creating the constraint for the resource\n * function.\n *\n * As all the other _\"factory functions\"_, this is meant to be used as a building block\n * when extending the container.\n *\n * @returns A function that can be used to create a resource with a specified type of\n * function.\n * @template ResourceFn The type of function the resource needs to have.\n * @example\n *\n * type ActionFn = (c: Jimple) => void;\n * const factory = resourceFactory<ActionFn>();\n * const myAction = factory('action', 'fn', (c) => {\n * c.set('foo', 'bar');\n * });\n *\n */\nexport const resourceFactory =\n <ResourceFn extends GenericFn>() =>\n /**\n * Generates a new resource using the contraint defined in the factory.\n *\n * @param name The name of the resource.\n * @param key The property key for the function.\n * @param fn The resource function.\n * @returns An object with the `name` set to `true`, and the `fn` as the `key`.\n * @template Name The literal type of `name`, to be used in the return object.\n * @template Key The literal type of `key`, to be used in the return object.\n * @template Fn The type of `fn`, restricted by the factory constraint.\n * @example\n *\n * const myAction = factory('action', 'fn', (c) => {\n * c.set('foo', 'bar');\n * });\n *\n */\n <Name extends string, Key extends string, Fn extends ResourceFn>(\n name: Name,\n key: Key,\n fn: Fn,\n ): Resource<Name, Key, Fn> =>\n ({\n [name]: true,\n [key]: fn,\n } as Resource<Name, Key, Fn>);\n","import { resourceFactory } from './resourceFactory';\nimport type {\n GenericFn,\n GenericCurriedFn,\n ResourceCreator,\n ResourceCreatorCurriedFn,\n ResourceCreatorHandler,\n} from './factories.types';\n/**\n * Generates a function to create resource creators of an specified type. This function\n * itself doesn't have logic, but it's just in charge of creating the constraint for the\n * resource creator function.\n *\n * As all the other _\"factory functions\"_, this is meant to be used as a building block\n * when extending the container.\n *\n * @returns A function that can be used to create \"resource creators\".\n * @template ResourceFn The type of function the resource creator needs to have.\n * @example\n *\n * type ActionFn = (c: Jimple) => void;\n * const factory = resourceCreatorFactory<ActionFn>();\n * const myAction = factory('action', 'fn', (name = 'foo') => (c) => {\n * c.set(name, 'bar');\n * });\n *\n */\nexport const resourceCreatorFactory =\n <ResourceFn extends GenericFn>() =>\n /**\n * Generates a new resource creator using the contraint defined in the factory.\n *\n * @param name The name of the resource.\n * @param key The property key for the function.\n * @param creatorFn The curried function that returns the actual resource function.\n * @returns A resource creator: an object that can be used as a resource, and as a\n * function that returns a resource.\n * @template Name The literal type of `name`, to be used in the return object.\n * @template Key The literal type of `key`, to be used in the return object.\n * @template ResFn The type of the resource function, the creator function needs\n * to return. This is restricted by the factory constraint.\n * @template CreatorFn The literal type of `creatorFn`, to be used in the return\n * object.\n * @example\n *\n * const myAction = factory('action', 'fn', (name = 'foo') => (c) => {\n * c.set(name, 'bar');\n * });\n *\n */\n <\n Name extends string,\n Key extends string,\n ResFn extends ResourceFn,\n CreatorFn extends GenericCurriedFn<ResFn>,\n >(\n name: Name,\n key: Key,\n creatorFn: CreatorFn,\n ): ResourceCreator<Name, Key, CreatorFn, ResourceFn> => {\n const fnToProxy: ResourceCreatorCurriedFn<Name, Key, CreatorFn> = (...args) => {\n const actualResource = creatorFn(...args) as ReturnType<CreatorFn>;\n return resourceFactory<ResFn>()(name, key, actualResource);\n };\n\n const handler: ResourceCreatorHandler<Name, Key, CreatorFn> = {\n name,\n resource: null,\n get(target, property) {\n let result;\n if (property === this.name) {\n result = true;\n } else if (property === key) {\n if (this.resource === null) {\n const newResource = creatorFn() as ReturnType<CreatorFn>;\n this.resource = newResource;\n }\n result = this.resource;\n } else {\n const targetKey = property as keyof typeof target;\n result = target[targetKey];\n }\n\n return result;\n },\n has(target, property) {\n if (property === this.name || property === key) {\n return true;\n }\n\n const targetKey = property as keyof typeof target;\n return targetKey in target;\n },\n };\n\n return new Proxy(fnToProxy, handler) as unknown as ResourceCreator<\n Name,\n Key,\n CreatorFn,\n ResourceFn\n >;\n };\n","import { resourceFactory } from './resourceFactory';\nimport type { GenericFn, Resource } from './factories.types';\n/**\n * Generates a function to configure a collection of resources of an specified type. This\n * function itself doesn't have logic, but it's just in charge of creating the constraint\n * for the resource name and function.\n *\n * As all the other _\"factory functions\"_, this is meant to be used as a building block\n * when extending the container.\n *\n * @returns A function that can be used to configure a collection of resources.\n * @template ResourceName The literal type of the name the resources needs to have.\n * @template ResourceFn The type of function the resources needs to have.\n * @example\n *\n * type ActionFn = (c: Jimple) => void;\n * const factory = resourcesCollectionFactory<'action', ActionFn>();\n * const myActions = factory('action', 'fn')({ myActionA, myActionB });\n *\n */\nexport const resourcesCollectionFactory =\n <ResourceName extends string, ResourceFn extends GenericFn>() =>\n /**\n * Generates a function to create a collection of resources of an specified type. A\n * collection is a dictionary of resources, and a resource itself, and when its\n * \"resource function\" gets called, it calls the function of every resource (with the\n * same args it recevied).\n *\n * @param name The resource name the items in the collection must have.\n * @param key The key property the items in the collection must have.\n * @param fn A custom function to process the items in the collection, when the\n * collection function gets called.\n * @returns A function that can be used to create a resources collection.\n * @template Name The literal type of `name`, to be used in the return object.\n * @template Key The literal type of `key`, to be used in the return object.\n * @template ItemKey To capture the name of the resources in the collection.\n * @template Items The kind of dictionary of resources the return function will\n * expect.\n * @template CustomFn The type of `fn`, restricted by the factory constraint.\n * @example\n *\n * const myActions = factory('action', 'fn')({ myActionA, myActionB });\n *\n */\n <\n Name extends string,\n Key extends string,\n ItemKey extends string,\n Items extends Record<ItemKey, Resource<ResourceName, Key, ResourceFn>>,\n CustomFn extends (items: Items, ...rest: Parameters<ResourceFn>) => void,\n >(\n name: Name,\n key: Key,\n fn?: CustomFn,\n ) => {\n const collectionResourceFactory = resourceFactory<ResourceFn>();\n /**\n * The actual function that recevies the items and creates the collection.\n *\n * @param items A dictionary of resources for the collection.\n * @returns A dictionary of the resources, that it's also a resource.\n * @template ItemsParam The literal type of `items`, to be used in the return\n * object.\n * @throws If the dictionary contains the resource name or function key as keys.\n * @throws If one of the items doesn't have the resource function.\n */\n return <ItemsParam>(\n items: ItemsParam & Items,\n ): typeof items & Resource<Name, Key, ResourceFn> => {\n const invalidKeys: string[] = [name, key];\n const itemsKeys = Object.keys(items) as Array<keyof Items>;\n\n const invalidKey = itemsKeys.some((itemKey) =>\n invalidKeys.includes(String(itemKey)),\n );\n if (invalidKey) {\n throw new Error(\n `No item on the collection can have the keys \\`${name}\\` nor \\`${key}\\``,\n );\n }\n\n const invalidItem = itemsKeys.find(\n (itemKey) => typeof items[itemKey]?.[key] !== 'function',\n );\n if (invalidItem) {\n throw new Error(\n `The item \\`${String(\n invalidItem,\n )}\\` is invalid: it doesn't have a \\`${key}\\` function`,\n );\n }\n\n const useFn = fn\n ? (...args: Parameters<ResourceFn>) => fn(items, ...args)\n : (...args: Parameters<ResourceFn>) => {\n itemsKeys.forEach((itemK) => {\n const item = items[itemK]!;\n const itemFn = item[key];\n itemFn(...args);\n });\n };\n\n return {\n ...collectionResourceFactory(name, key, useFn as ResourceFn),\n ...items,\n };\n };\n };\n","import type { Jimple } from '../jimple';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- They are dynamically extended.\ntype GenericDict = Record<any, any>;\n/**\n * A helper that reusable services can use to resolve dependencies in constructors and/or\n * providers.\n *\n * @template InjectDictionary A dictionary of the dependencies and their types.\n * @template InjectKey The literal type of the dictionary types.\n */\nexport class InjectHelper<\n InjectDictionary extends GenericDict,\n InjectKey = keyof InjectDictionary,\n> {\n /**\n * This method is meant to be used to validate the dependencies a service receives, and\n * needs.\n * It will check on the received dependencies, if a specific dependency exists, it will\n * return it, otherwise, it will create a new instance.\n *\n * @param dependencies The dependencies received by the implementation.\n * @param key The key of the dependency to validate.\n * @param init A function to create a dependency in case it doesn't exist in\n * the dictionary.\n * @returns An instance of the dependency.\n * @template DepKey The literal key of the dependency to validate.\n * @template DepType The type of the dependency, obtained from the dictionary sent\n * to the constructor.\n * @example\n *\n * type Dependencies = {\n * dep: string;\n * };\n * const helper = new InjectHelper<Dependencies>();\n *\n * type MyServiceOptions = {\n * inject?: Partial<Dependencies>;\n * };\n * const myService = ({ inject = {} }: MyServiceOptions) => {\n * const dep = helper.get(inject, 'dep', () => 'default');\n * console.log('dep:', dep);\n * };\n *\n */\n get<DepKey extends InjectKey, DepType = InjectDictionary[DepKey]>(\n dependencies: Partial<InjectDictionary>,\n key: InjectKey,\n init: () => DepType,\n ): DepType {\n const existing = dependencies[key];\n if (typeof existing !== 'undefined') {\n return existing!;\n }\n\n return init();\n }\n /**\n * This is meant to be used in a provider creator to resolve dependencies' names sent as\n * options. For each dependency, the method will first check if a new name was\n * specified, and try to get it with that name, otherwise, it will try to get it with\n * the default name, and if it doesn't exist, it will just keep it as `undefined` and\n * expect the service implements {@link InjectHelper.get} to ensure the dependency.\n *\n * @param dependencies The dependencies needed by the service.\n * @param container A reference to the Jimple container.\n * @param inject A dictionary of dependencies names.\n * @returns A dictionary of dependencies to send to the service.\n * @template DepKey The literal key of the dependencies to validate.\n * @template Container The type of the Jimple container.\n * @example\n *\n * type Dependencies = {\n * dep: string;\n * };\n * const helper = new InjectHelper<Dependencies>();\n *\n * type MyProviderOptions = {\n * services?: {\n * [key in keyof Dependencies]?: string;\n * };\n * };\n *\n * const myProvider = providerCreator(\n * ({ services = {} }: MyProviderOptions) =>\n * (container) => {\n * container.set('myService', () => {\n * const inject = helper.resolve(['dep'], container, services);\n * return myService({ inject });\n * });\n * },\n * );\n *\n */\n resolve<DepKey extends InjectKey, Container extends Jimple>(\n dependencies: DepKey[],\n container: Container,\n inject: Partial<Record<keyof InjectDictionary, string>>,\n ): Partial<InjectDictionary> {\n const result = dependencies.reduce<Partial<InjectDictionary>>((acc, key) => {\n if (inject[key]) {\n acc[key] = container.get<InjectDictionary[typeof key]>(inject[key]!);\n return acc;\n }\n\n const keyStr = key as unknown as string;\n if (container.has(keyStr)) {\n acc[key] = container.get<InjectDictionary[typeof key]>(keyStr);\n return acc;\n }\n\n return acc;\n }, {});\n\n return result;\n }\n}\n/**\n * Shorthand for `new InjectHelper()`.\n *\n * @returns A new instance of {@link InjectHelper}.\n */\nexport const injectHelper = <InjectDictionary extends GenericDict>() =>\n new InjectHelper<InjectDictionary>();\n","import type { Jimple } from '../jimple';\nimport { resourceFactory } from '../factories';\n\nexport type ProviderName = 'provider';\nexport type ProviderKey = 'register';\n/**\n * The function the container will call when the provider is registered.\n *\n * @param container A reference for container where the provider is being registered.\n * @template ContainerType The type of the Jimple container (in case it gets\n * subclassed).\n */\nexport type ProviderRegisterFn<ContainerType extends Jimple = Jimple> = (\n container: ContainerType,\n) => void;\n/**\n * Generates a function to create providers for a specific type of container.\n *\n * @returns A function to create providers.\n * @template ContainerType The type of the Jimple container (in case it gets\n * subclassed).\n */\nexport const createProvider = <ContainerType extends Jimple = Jimple>() => {\n type RegisterFn = ProviderRegisterFn<ContainerType>;\n const factory = resourceFactory<RegisterFn>();\n return (register: RegisterFn) => factory('provider', 'register', register);\n};\n/**\n * Creates a resource to be registered in a Jimple container.\n *\n * @example\n *\n * export const myService = provider((c) => {\n * c.set('myService', () => new MyService());\n * });\n *\n */\nexport const provider = createProvider();\n/**\n * A resource that can be registered in a Jimple container.\n */\nexport type Provider = ReturnType<typeof provider>;\n","import type { Jimple } from '../jimple';\nimport { resourceCreatorFactory, type GenericCurriedFn } from '../factories';\nimport type { ProviderRegisterFn } from './provider';\n/**\n * Generates a function to create \"provider creators\" for a specific type of container.\n *\n * @returns A function to generate provider creators.\n * @template ContainerType The type of the Jimple container (in case it gets\n * subclassed).\n */\nexport const createProviderCreator = <ContainerType extends Jimple = Jimple>() => {\n type RegisterFn = ProviderRegisterFn<ContainerType>;\n type ProviderCreatorFn = GenericCurriedFn<RegisterFn>;\n const factory = resourceCreatorFactory<RegisterFn>();\n return <CreatorFn extends ProviderCreatorFn>(creator: CreatorFn) =>\n factory('provider', 'register', creator);\n};\n/**\n * Generates a \"provider creator\": a provider that can also be called as a function in\n * order to create a configured provider.\n *\n * @example\n *\n * export const myService = providerCreator((options: Opts = {}) => (c) => {\n * c.set('myService', () => new MyService(options));\n * });\n *\n */\nexport const providerCreator = createProviderCreator();\n/**\n * A function that returns a provider registration function.\n */\nexport type ProviderCreatorFn = Parameters<typeof providerCreator>[0];\n","import type { Jimple } from '../jimple';\nimport { resourcesCollectionFactory } from '../factories';\nimport type { ProviderRegisterFn, ProviderName } from './provider';\n/**\n * Generates a function to create a providers collection for a specific type of container.\n *\n * @returns A function to create providers collections.\n * @template ContainerType The type of the Jimple container (in case it gets\n * subclassed).\n */\nexport const createProviders = <ContainerType extends Jimple = Jimple>() => {\n type RegisterFn = ProviderRegisterFn<ContainerType>;\n const factory = resourcesCollectionFactory<ProviderName, RegisterFn>();\n return factory('provider', 'register');\n};\n/**\n * Generates a collection of providers. A collection is a dictionary of providers that can\n * also be used as a provider, and when it gets registered, it will register all of the\n * providers in the collection.\n *\n * @param items A dictionary of providers.\n * @example\n *\n * <caption>Assuming we already have two service providers...</caption>\n *\n * export const services = providers({\n * myServiceProvider,\n * myOtherServiceProvider,\n * });\n *\n */\nexport const providers = createProviders();\n"],"mappings":"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","names":["Jimple","provider","JimpleOriginal","Jimple"]}
package/dist/index.js CHANGED
@@ -21,6 +21,10 @@ var __copyProps = (to, from, except, desc) => {
21
21
  return to;
22
22
  };
23
23
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
+ // If the importer is in node compatibility mode or this is not an ESM
25
+ // file that has been converted to a CommonJS file using a Babel-
26
+ // compatible transform (i.e. "__esModule" has not been set), then set
27
+ // "default" to the CommonJS "module.exports" for node compatibility.
24
28
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
29
  mod
26
30
  ));
@@ -57,6 +61,10 @@ var require_Jimple = __commonJS({
57
61
  static provider(register) {
58
62
  return { register };
59
63
  }
64
+ /**
65
+ * Create a Jimple Container.
66
+ * @param {Object?} [values] - An optional object whose keys and values will be associated in the container at initialization
67
+ */
60
68
  constructor(values) {
61
69
  this._items = {};
62
70
  this._instances = /* @__PURE__ */ new Map();
@@ -67,6 +75,13 @@ var require_Jimple = __commonJS({
67
75
  this.set(key, values[key]);
68
76
  }, this);
69
77
  }
78
+ /**
79
+ * Return the specified parameter or service. If the service is not built yet, this function will construct the service
80
+ * injecting all the dependencies needed in it's definition so the returned object is totally usable on the fly.
81
+ * @param {string} key - The key of the parameter or service to return
82
+ * @return {*} The object related to the service or the value of the parameter associated with the key informed
83
+ * @throws If the key does not exist
84
+ */
70
85
  get(key) {
71
86
  checkDefined(this, key);
72
87
  let item = this._items[key];
@@ -87,21 +102,53 @@ var require_Jimple = __commonJS({
87
102
  }
88
103
  return obj;
89
104
  }
105
+ /**
106
+ * Defines a new parameter or service.
107
+ * @param {string} key - The key of the parameter or service to be defined
108
+ * @param {*} value - The value of the parameter or a function that receives the container as parameter and constructs the service
109
+ */
90
110
  set(key, value) {
91
111
  this._items[key] = value;
92
112
  }
113
+ /**
114
+ * Returns if a service or parameter with the informed key is already defined in the container.
115
+ * @param {string} key - The key of the parameter or service to be checked.
116
+ * @return {boolean} If the key exists in the container or not
117
+ */
93
118
  has(key) {
94
119
  return this._items.hasOwnProperty(key);
95
120
  }
121
+ /**
122
+ * Defines a service as a factory, so the instances are not cached in the service and that function is always called
123
+ * @param {function(Jimple):*} fn - The function that constructs the service that is a factory
124
+ * @return {function(Jimple):*} The same function passed as parameter
125
+ */
96
126
  factory(fn) {
97
127
  return addFunctionTo(this._factories, fn);
98
128
  }
129
+ /**
130
+ * Defines a function as a parameter, so that function is not considered a service
131
+ * @param {*} fn - The function to not be considered a service
132
+ * @return {*} The same function passed as parameter
133
+ */
99
134
  protect(fn) {
100
135
  return addFunctionTo(this._protected, fn);
101
136
  }
137
+ /**
138
+ * Return all the keys registered in the container
139
+ * @returns {Array<string>}
140
+ */
102
141
  keys() {
103
142
  return Object.keys(this._items);
104
143
  }
144
+ /**
145
+ * Extends a service already registered in the container
146
+ * @param {string} key - The key of the service to be extended
147
+ * @param {function(*, Jimple):*} fn - The function that will be used to extend the service
148
+ * @throws If the key is not already defined
149
+ * @throws If the key saved in the container does not correspond to a service
150
+ * @throws If the function passed it not...well, a function
151
+ */
105
152
  extend(key, fn) {
106
153
  checkDefined(this, key);
107
154
  let originalItem = this._items[key];
@@ -115,9 +162,20 @@ var require_Jimple = __commonJS({
115
162
  this._factories.add(this._items[key]);
116
163
  }
117
164
  }
165
+ /**
166
+ * Uses an provider to extend the service, so it's easy to split the service and parameter definitions across the system
167
+ * @param {{register: function(Jimple)}} provider - The provider to be used to register services and parameters in this container
168
+ */
118
169
  register(provider2) {
119
170
  provider2.register(this);
120
171
  }
172
+ /**
173
+ * Returns the raw value of a service or parameter. So, in the case of a service, for example, the value returned is the
174
+ * function used to construct the service.
175
+ * @param {string} key - The key of the service or parameter to return.
176
+ * @throws If the key does not exist in the container
177
+ * @return {*} The raw value of the service or parameter
178
+ */
121
179
  raw(key) {
122
180
  checkDefined(this, key);
123
181
  return this._items[key];
@@ -152,6 +210,15 @@ var Jimple = import_jimple.default;
152
210
 
153
211
  // src/jimple/index.ts
154
212
  var Jimple2 = class extends Jimple {
213
+ /**
214
+ * This is a version of the `get` method that doesn't throw if the key doesn't exist. It
215
+ * will return `undefined` instead.
216
+ *
217
+ * @param key The key of the parameter or service to return.
218
+ * @returns The object related to the service or the value of the parameter
219
+ * associated with the given key.
220
+ * @template T The type of the returned object.
221
+ */
155
222
  try(key) {
156
223
  if (!this.has(key)) {
157
224
  return void 0;
@@ -162,87 +229,183 @@ var Jimple2 = class extends Jimple {
162
229
  var jimple = (...args) => new Jimple2(...args);
163
230
 
164
231
  // src/factories/resourceFactory.ts
165
- var resourceFactory = () => (name, key, fn) => ({
166
- [name]: true,
167
- [key]: fn
168
- });
232
+ var resourceFactory = () => (
233
+ /**
234
+ * Generates a new resource using the contraint defined in the factory.
235
+ *
236
+ * @param name The name of the resource.
237
+ * @param key The property key for the function.
238
+ * @param fn The resource function.
239
+ * @returns An object with the `name` set to `true`, and the `fn` as the `key`.
240
+ * @template Name The literal type of `name`, to be used in the return object.
241
+ * @template Key The literal type of `key`, to be used in the return object.
242
+ * @template Fn The type of `fn`, restricted by the factory constraint.
243
+ * @example
244
+ *
245
+ * const myAction = factory('action', 'fn', (c) => {
246
+ * c.set('foo', 'bar');
247
+ * });
248
+ *
249
+ */
250
+ (name, key, fn) => ({
251
+ [name]: true,
252
+ [key]: fn
253
+ })
254
+ );
169
255
 
170
256
  // src/factories/resourceCreatorFactory.ts
171
- var resourceCreatorFactory = () => (name, key, creatorFn) => {
172
- const fnToProxy = (...args) => {
173
- const actualResource = creatorFn(...args);
174
- return resourceFactory()(name, key, actualResource);
175
- };
176
- const handler = {
177
- name,
178
- resource: null,
179
- get(target, property) {
180
- let result;
181
- if (property === this.name) {
182
- result = true;
183
- } else if (property === key) {
184
- if (this.resource === null) {
185
- const newResource = creatorFn();
186
- this.resource = newResource;
257
+ var resourceCreatorFactory = () => (
258
+ /**
259
+ * Generates a new resource creator using the contraint defined in the factory.
260
+ *
261
+ * @param name The name of the resource.
262
+ * @param key The property key for the function.
263
+ * @param creatorFn The curried function that returns the actual resource function.
264
+ * @returns A resource creator: an object that can be used as a resource, and as a
265
+ * function that returns a resource.
266
+ * @template Name The literal type of `name`, to be used in the return object.
267
+ * @template Key The literal type of `key`, to be used in the return object.
268
+ * @template ResFn The type of the resource function, the creator function needs
269
+ * to return. This is restricted by the factory constraint.
270
+ * @template CreatorFn The literal type of `creatorFn`, to be used in the return
271
+ * object.
272
+ * @example
273
+ *
274
+ * const myAction = factory('action', 'fn', (name = 'foo') => (c) => {
275
+ * c.set(name, 'bar');
276
+ * });
277
+ *
278
+ */
279
+ (name, key, creatorFn) => {
280
+ const fnToProxy = (...args) => {
281
+ const actualResource = creatorFn(...args);
282
+ return resourceFactory()(name, key, actualResource);
283
+ };
284
+ const handler = {
285
+ name,
286
+ resource: null,
287
+ get(target, property) {
288
+ let result;
289
+ if (property === this.name) {
290
+ result = true;
291
+ } else if (property === key) {
292
+ if (this.resource === null) {
293
+ const newResource = creatorFn();
294
+ this.resource = newResource;
295
+ }
296
+ result = this.resource;
297
+ } else {
298
+ const targetKey = property;
299
+ result = target[targetKey];
300
+ }
301
+ return result;
302
+ },
303
+ has(target, property) {
304
+ if (property === this.name || property === key) {
305
+ return true;
187
306
  }
188
- result = this.resource;
189
- } else {
190
307
  const targetKey = property;
191
- result = target[targetKey];
308
+ return targetKey in target;
192
309
  }
193
- return result;
194
- },
195
- has(target, property) {
196
- if (property === this.name || property === key) {
197
- return true;
198
- }
199
- const targetKey = property;
200
- return targetKey in target;
201
- }
202
- };
203
- return new Proxy(fnToProxy, handler);
204
- };
310
+ };
311
+ return new Proxy(fnToProxy, handler);
312
+ }
313
+ );
205
314
 
206
315
  // src/factories/resourcesCollectionFactory.ts
207
- var resourcesCollectionFactory = () => (name, key, fn) => {
208
- const collectionResourceFactory = resourceFactory();
209
- return (items) => {
210
- const invalidKeys = [name, key];
211
- const itemsKeys = Object.keys(items);
212
- const invalidKey = itemsKeys.some(
213
- (itemKey) => invalidKeys.includes(String(itemKey))
214
- );
215
- if (invalidKey) {
216
- throw new Error(
217
- `No item on the collection can have the keys \`${name}\` nor \`${key}\``
316
+ var resourcesCollectionFactory = () => (
317
+ /**
318
+ * Generates a function to create a collection of resources of an specified type. A
319
+ * collection is a dictionary of resources, and a resource itself, and when its
320
+ * "resource function" gets called, it calls the function of every resource (with the
321
+ * same args it recevied).
322
+ *
323
+ * @param name The resource name the items in the collection must have.
324
+ * @param key The key property the items in the collection must have.
325
+ * @param fn A custom function to process the items in the collection, when the
326
+ * collection function gets called.
327
+ * @returns A function that can be used to create a resources collection.
328
+ * @template Name The literal type of `name`, to be used in the return object.
329
+ * @template Key The literal type of `key`, to be used in the return object.
330
+ * @template ItemKey To capture the name of the resources in the collection.
331
+ * @template Items The kind of dictionary of resources the return function will
332
+ * expect.
333
+ * @template CustomFn The type of `fn`, restricted by the factory constraint.
334
+ * @example
335
+ *
336
+ * const myActions = factory('action', 'fn')({ myActionA, myActionB });
337
+ *
338
+ */
339
+ (name, key, fn) => {
340
+ const collectionResourceFactory = resourceFactory();
341
+ return (items) => {
342
+ const invalidKeys = [name, key];
343
+ const itemsKeys = Object.keys(items);
344
+ const invalidKey = itemsKeys.some(
345
+ (itemKey) => invalidKeys.includes(String(itemKey))
218
346
  );
219
- }
220
- const invalidItem = itemsKeys.find(
221
- (itemKey) => typeof items[itemKey]?.[key] !== "function"
222
- );
223
- if (invalidItem) {
224
- throw new Error(
225
- `The item \`${String(
226
- invalidItem
227
- )}\` is invalid: it doesn't have a \`${key}\` function`
347
+ if (invalidKey) {
348
+ throw new Error(
349
+ `No item on the collection can have the keys \`${name}\` nor \`${key}\``
350
+ );
351
+ }
352
+ const invalidItem = itemsKeys.find(
353
+ (itemKey) => typeof items[itemKey]?.[key] !== "function"
228
354
  );
229
- }
230
- const useFn = fn ? (...args) => fn(items, ...args) : (...args) => {
231
- itemsKeys.forEach((itemK) => {
232
- const item = items[itemK];
233
- const itemFn = item[key];
234
- itemFn(...args);
235
- });
236
- };
237
- return {
238
- ...collectionResourceFactory(name, key, useFn),
239
- ...items
355
+ if (invalidItem) {
356
+ throw new Error(
357
+ `The item \`${String(
358
+ invalidItem
359
+ )}\` is invalid: it doesn't have a \`${key}\` function`
360
+ );
361
+ }
362
+ const useFn = fn ? (...args) => fn(items, ...args) : (...args) => {
363
+ itemsKeys.forEach((itemK) => {
364
+ const item = items[itemK];
365
+ const itemFn = item[key];
366
+ itemFn(...args);
367
+ });
368
+ };
369
+ return {
370
+ ...collectionResourceFactory(name, key, useFn),
371
+ ...items
372
+ };
240
373
  };
241
- };
242
- };
374
+ }
375
+ );
243
376
 
244
377
  // src/helpers/injectHelper.ts
245
378
  var InjectHelper = class {
379
+ /**
380
+ * This method is meant to be used to validate the dependencies a service receives, and
381
+ * needs.
382
+ * It will check on the received dependencies, if a specific dependency exists, it will
383
+ * return it, otherwise, it will create a new instance.
384
+ *
385
+ * @param dependencies The dependencies received by the implementation.
386
+ * @param key The key of the dependency to validate.
387
+ * @param init A function to create a dependency in case it doesn't exist in
388
+ * the dictionary.
389
+ * @returns An instance of the dependency.
390
+ * @template DepKey The literal key of the dependency to validate.
391
+ * @template DepType The type of the dependency, obtained from the dictionary sent
392
+ * to the constructor.
393
+ * @example
394
+ *
395
+ * type Dependencies = {
396
+ * dep: string;
397
+ * };
398
+ * const helper = new InjectHelper<Dependencies>();
399
+ *
400
+ * type MyServiceOptions = {
401
+ * inject?: Partial<Dependencies>;
402
+ * };
403
+ * const myService = ({ inject = {} }: MyServiceOptions) => {
404
+ * const dep = helper.get(inject, 'dep', () => 'default');
405
+ * console.log('dep:', dep);
406
+ * };
407
+ *
408
+ */
246
409
  get(dependencies, key, init) {
247
410
  const existing = dependencies[key];
248
411
  if (typeof existing !== "undefined") {
@@ -250,6 +413,43 @@ var InjectHelper = class {
250
413
  }
251
414
  return init();
252
415
  }
416
+ /**
417
+ * This is meant to be used in a provider creator to resolve dependencies' names sent as
418
+ * options. For each dependency, the method will first check if a new name was
419
+ * specified, and try to get it with that name, otherwise, it will try to get it with
420
+ * the default name, and if it doesn't exist, it will just keep it as `undefined` and
421
+ * expect the service implements {@link InjectHelper.get} to ensure the dependency.
422
+ *
423
+ * @param dependencies The dependencies needed by the service.
424
+ * @param container A reference to the Jimple container.
425
+ * @param inject A dictionary of dependencies names.
426
+ * @returns A dictionary of dependencies to send to the service.
427
+ * @template DepKey The literal key of the dependencies to validate.
428
+ * @template Container The type of the Jimple container.
429
+ * @example
430
+ *
431
+ * type Dependencies = {
432
+ * dep: string;
433
+ * };
434
+ * const helper = new InjectHelper<Dependencies>();
435
+ *
436
+ * type MyProviderOptions = {
437
+ * services?: {
438
+ * [key in keyof Dependencies]?: string;
439
+ * };
440
+ * };
441
+ *
442
+ * const myProvider = providerCreator(
443
+ * ({ services = {} }: MyProviderOptions) =>
444
+ * (container) => {
445
+ * container.set('myService', () => {
446
+ * const inject = helper.resolve(['dep'], container, services);
447
+ * return myService({ inject });
448
+ * });
449
+ * },
450
+ * );
451
+ *
452
+ */
253
453
  resolve(dependencies, container, inject) {
254
454
  const result = dependencies.reduce((acc, key) => {
255
455
  if (inject[key]) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../node_modules/jimple/src/Jimple.js","../src/index.ts","../src/jimplemod/index.ts","../src/jimple/index.ts","../src/factories/resourceFactory.ts","../src/factories/resourceCreatorFactory.ts","../src/factories/resourcesCollectionFactory.ts","../src/helpers/injectHelper.ts","../src/helpers/provider.ts","../src/helpers/providerCreator.ts","../src/helpers/providers.ts"],"sourcesContent":["\"use strict\";\n\nfunction assert(ok, message) {\n if (!ok) {\n throw new Error(message)\n }\n}\n\nfunction isFunction(fn) {\n return Object.prototype.toString.call(fn) === \"[object Function]\" && fn.constructor.name === \"Function\";\n}\n\nfunction isPlainObject(value) {\n if (Object.prototype.toString.call(value) !== '[object Object]') {\n return false;\n }\n let prototype = Object.getPrototypeOf(value);\n return prototype === null || prototype === Object.prototype;\n}\n\nfunction checkDefined(container, key) {\n assert(container.has(key), `Identifier \"${key}\" is not defined.`);\n}\n\nfunction addFunctionTo(set, fn) {\n assert(isFunction(fn), \"Service definition is not a Closure or invokable object\");\n set.add(fn);\n return fn;\n}\n\n/**\n * The Jimple Container class\n *\n * @public\n */\nclass Jimple {\n static provider(register) {\n return ({ register });\n }\n /**\n * Create a Jimple Container.\n * @param {Object?} [values] - An optional object whose keys and values will be associated in the container at initialization\n */\n constructor(values) {\n this._items = {};\n this._instances = new Map();\n this._factories = new Set();\n this._protected = new Set();\n values = isPlainObject(values) ? values : {};\n Object.keys(values).forEach(function(key) {\n this.set(key, values[key]);\n }, this);\n }\n /**\n * Return the specified parameter or service. If the service is not built yet, this function will construct the service\n * injecting all the dependencies needed in it's definition so the returned object is totally usable on the fly.\n * @param {string} key - The key of the parameter or service to return\n * @return {*} The object related to the service or the value of the parameter associated with the key informed\n * @throws If the key does not exist\n */\n get(key) {\n checkDefined(this, key);\n let item = this._items[key];\n let obj;\n if (isFunction(item)) {\n if (this._protected.has(item)) {\n obj = item;\n } else if (this._instances.has(item)) {\n obj = this._instances.get(item);\n } else {\n obj = item(this);\n if (!this._factories.has(item)) {\n this._instances.set(item, obj);\n }\n }\n } else {\n obj = item;\n }\n return obj;\n }\n /**\n * Defines a new parameter or service.\n * @param {string} key - The key of the parameter or service to be defined\n * @param {*} value - The value of the parameter or a function that receives the container as parameter and constructs the service\n */\n set(key, value) {\n this._items[key] = value;\n }\n\n /**\n * Returns if a service or parameter with the informed key is already defined in the container.\n * @param {string} key - The key of the parameter or service to be checked.\n * @return {boolean} If the key exists in the container or not\n */\n has(key) {\n return this._items.hasOwnProperty(key);\n }\n\n /**\n * Defines a service as a factory, so the instances are not cached in the service and that function is always called\n * @param {function(Jimple):*} fn - The function that constructs the service that is a factory\n * @return {function(Jimple):*} The same function passed as parameter\n */\n factory(fn) {\n return addFunctionTo(this._factories, fn);\n }\n\n /**\n * Defines a function as a parameter, so that function is not considered a service\n * @param {*} fn - The function to not be considered a service\n * @return {*} The same function passed as parameter\n */\n protect(fn) {\n return addFunctionTo(this._protected, fn);\n }\n\n /**\n * Return all the keys registered in the container\n * @returns {Array<string>}\n */\n keys() {\n return Object.keys(this._items);\n }\n\n /**\n * Extends a service already registered in the container\n * @param {string} key - The key of the service to be extended\n * @param {function(*, Jimple):*} fn - The function that will be used to extend the service\n * @throws If the key is not already defined\n * @throws If the key saved in the container does not correspond to a service\n * @throws If the function passed it not...well, a function\n */\n extend(key, fn) {\n checkDefined(this, key);\n let originalItem = this._items[key];\n assert(isFunction(originalItem) && this._protected.has(originalItem) === false, `Identifier '${key}' does not contain a service definition`);\n assert(isFunction(fn), `The 'new' service definition for '${key}' is not a invokable object.`);\n this._items[key] = function(app) {\n return fn(originalItem(app), app);\n }\n if (this._factories.has(originalItem)) {\n this._factories.delete(originalItem);\n this._factories.add(this._items[key]);\n }\n }\n\n /**\n * Uses an provider to extend the service, so it's easy to split the service and parameter definitions across the system\n * @param {{register: function(Jimple)}} provider - The provider to be used to register services and parameters in this container\n */\n register(provider) {\n provider.register(this);\n }\n\n /**\n * Returns the raw value of a service or parameter. So, in the case of a service, for example, the value returned is the\n * function used to construct the service.\n * @param {string} key - The key of the service or parameter to return.\n * @throws If the key does not exist in the container\n * @return {*} The raw value of the service or parameter\n */\n raw(key) {\n checkDefined(this, key);\n return this._items[key];\n }\n}\n\nmodule.exports = Jimple;\n","export * from './jimple';\nexport * from './factories';\nexport * from './helpers';\n","// @ts-expect-error - the idea is to have `any` and assert on export.\nimport JimpleOriginal from 'jimple';\nimport { Container as JimpleContainer } from './jimple.type';\n\nconst Jimple = JimpleOriginal as typeof JimpleContainer;\n\nexport { Jimple };\nexport type { JimpleContainer };\n","import { Jimple as JimpleMod } from '../jimplemod';\n\nexport class Jimple extends JimpleMod {\n /**\n * This is a version of the `get` method that doesn't throw if the key doesn't exist. It\n * will return `undefined` instead.\n *\n * @param key The key of the parameter or service to return.\n * @returns The object related to the service or the value of the parameter\n * associated with the given key.\n * @template T The type of the returned object.\n */\n try<T = unknown>(key: string): T | undefined {\n if (!this.has(key)) {\n return undefined;\n }\n\n return this.get<T>(key);\n }\n}\n/**\n * Shorthand for `new Jimple()`.\n *\n * @param args The same parameters as the {@link Jimple} constructor.\n * @returns A new instance of {@link Jimple}.\n */\nexport const jimple = (...args: ConstructorParameters<typeof Jimple>): Jimple =>\n new Jimple(...args);\n","import type { GenericFn, Resource } from './factories.types';\n/**\n * Generates a function to create resources of an specified type. This function itself\n * doesn't have logic, but it's just in charge of creating the constraint for the resource\n * function.\n *\n * As all the other _\"factory functions\"_, this is meant to be used as a building block\n * when extending the container.\n *\n * @returns A function that can be used to create a resource with a specified type of\n * function.\n * @template ResourceFn The type of function the resource needs to have.\n * @example\n *\n * type ActionFn = (c: Jimple) => void;\n * const factory = resourceFactory<ActionFn>();\n * const myAction = factory('action', 'fn', (c) => {\n * c.set('foo', 'bar');\n * });\n *\n */\nexport const resourceFactory =\n <ResourceFn extends GenericFn>() =>\n /**\n * Generates a new resource using the contraint defined in the factory.\n *\n * @param name The name of the resource.\n * @param key The property key for the function.\n * @param fn The resource function.\n * @returns An object with the `name` set to `true`, and the `fn` as the `key`.\n * @template Name The literal type of `name`, to be used in the return object.\n * @template Key The literal type of `key`, to be used in the return object.\n * @template Fn The type of `fn`, restricted by the factory constraint.\n * @example\n *\n * const myAction = factory('action', 'fn', (c) => {\n * c.set('foo', 'bar');\n * });\n *\n */\n <Name extends string, Key extends string, Fn extends ResourceFn>(\n name: Name,\n key: Key,\n fn: Fn,\n ): Resource<Name, Key, Fn> =>\n ({\n [name]: true,\n [key]: fn,\n } as Resource<Name, Key, Fn>);\n","import { resourceFactory } from './resourceFactory';\nimport type {\n GenericFn,\n GenericCurriedFn,\n ResourceCreator,\n ResourceCreatorCurriedFn,\n ResourceCreatorHandler,\n} from './factories.types';\n/**\n * Generates a function to create resource creators of an specified type. This function\n * itself doesn't have logic, but it's just in charge of creating the constraint for the\n * resource creator function.\n *\n * As all the other _\"factory functions\"_, this is meant to be used as a building block\n * when extending the container.\n *\n * @returns A function that can be used to create \"resource creators\".\n * @template ResourceFn The type of function the resource creator needs to have.\n * @example\n *\n * type ActionFn = (c: Jimple) => void;\n * const factory = resourceCreatorFactory<ActionFn>();\n * const myAction = factory('action', 'fn', (name = 'foo') => (c) => {\n * c.set(name, 'bar');\n * });\n *\n */\nexport const resourceCreatorFactory =\n <ResourceFn extends GenericFn>() =>\n /**\n * Generates a new resource creator using the contraint defined in the factory.\n *\n * @param name The name of the resource.\n * @param key The property key for the function.\n * @param creatorFn The curried function that returns the actual resource function.\n * @returns A resource creator: an object that can be used as a resource, and as a\n * function that returns a resource.\n * @template Name The literal type of `name`, to be used in the return object.\n * @template Key The literal type of `key`, to be used in the return object.\n * @template ResFn The type of the resource function, the creator function needs\n * to return. This is restricted by the factory constraint.\n * @template CreatorFn The literal type of `creatorFn`, to be used in the return\n * object.\n * @example\n *\n * const myAction = factory('action', 'fn', (name = 'foo') => (c) => {\n * c.set(name, 'bar');\n * });\n *\n */\n <\n Name extends string,\n Key extends string,\n ResFn extends ResourceFn,\n CreatorFn extends GenericCurriedFn<ResFn>,\n >(\n name: Name,\n key: Key,\n creatorFn: CreatorFn,\n ): ResourceCreator<Name, Key, CreatorFn, ResourceFn> => {\n const fnToProxy: ResourceCreatorCurriedFn<Name, Key, CreatorFn> = (...args) => {\n const actualResource = creatorFn(...args) as ReturnType<CreatorFn>;\n return resourceFactory<ResFn>()(name, key, actualResource);\n };\n\n const handler: ResourceCreatorHandler<Name, Key, CreatorFn> = {\n name,\n resource: null,\n get(target, property) {\n let result;\n if (property === this.name) {\n result = true;\n } else if (property === key) {\n if (this.resource === null) {\n const newResource = creatorFn() as ReturnType<CreatorFn>;\n this.resource = newResource;\n }\n result = this.resource;\n } else {\n const targetKey = property as keyof typeof target;\n result = target[targetKey];\n }\n\n return result;\n },\n has(target, property) {\n if (property === this.name || property === key) {\n return true;\n }\n\n const targetKey = property as keyof typeof target;\n return targetKey in target;\n },\n };\n\n return new Proxy(fnToProxy, handler) as unknown as ResourceCreator<\n Name,\n Key,\n CreatorFn,\n ResourceFn\n >;\n };\n","import { resourceFactory } from './resourceFactory';\nimport type { GenericFn, Resource } from './factories.types';\n/**\n * Generates a function to configure a collection of resources of an specified type. This\n * function itself doesn't have logic, but it's just in charge of creating the constraint\n * for the resource name and function.\n *\n * As all the other _\"factory functions\"_, this is meant to be used as a building block\n * when extending the container.\n *\n * @returns A function that can be used to configure a collection of resources.\n * @template ResourceName The literal type of the name the resources needs to have.\n * @template ResourceFn The type of function the resources needs to have.\n * @example\n *\n * type ActionFn = (c: Jimple) => void;\n * const factory = resourcesCollectionFactory<'action', ActionFn>();\n * const myActions = factory('action', 'fn')({ myActionA, myActionB });\n *\n */\nexport const resourcesCollectionFactory =\n <ResourceName extends string, ResourceFn extends GenericFn>() =>\n /**\n * Generates a function to create a collection of resources of an specified type. A\n * collection is a dictionary of resources, and a resource itself, and when its\n * \"resource function\" gets called, it calls the function of every resource (with the\n * same args it recevied).\n *\n * @param name The resource name the items in the collection must have.\n * @param key The key property the items in the collection must have.\n * @param fn A custom function to process the items in the collection, when the\n * collection function gets called.\n * @returns A function that can be used to create a resources collection.\n * @template Name The literal type of `name`, to be used in the return object.\n * @template Key The literal type of `key`, to be used in the return object.\n * @template ItemKey To capture the name of the resources in the collection.\n * @template Items The kind of dictionary of resources the return function will\n * expect.\n * @template CustomFn The type of `fn`, restricted by the factory constraint.\n * @example\n *\n * const myActions = factory('action', 'fn')({ myActionA, myActionB });\n *\n */\n <\n Name extends string,\n Key extends string,\n ItemKey extends string,\n Items extends Record<ItemKey, Resource<ResourceName, Key, ResourceFn>>,\n CustomFn extends (items: Items, ...rest: Parameters<ResourceFn>) => void,\n >(\n name: Name,\n key: Key,\n fn?: CustomFn,\n ) => {\n const collectionResourceFactory = resourceFactory<ResourceFn>();\n /**\n * The actual function that recevies the items and creates the collection.\n *\n * @param items A dictionary of resources for the collection.\n * @returns A dictionary of the resources, that it's also a resource.\n * @template ItemsParam The literal type of `items`, to be used in the return\n * object.\n * @throws If the dictionary contains the resource name or function key as keys.\n * @throws If one of the items doesn't have the resource function.\n */\n return <ItemsParam>(\n items: ItemsParam & Items,\n ): typeof items & Resource<Name, Key, ResourceFn> => {\n const invalidKeys: string[] = [name, key];\n const itemsKeys = Object.keys(items) as Array<keyof Items>;\n\n const invalidKey = itemsKeys.some((itemKey) =>\n invalidKeys.includes(String(itemKey)),\n );\n if (invalidKey) {\n throw new Error(\n `No item on the collection can have the keys \\`${name}\\` nor \\`${key}\\``,\n );\n }\n\n const invalidItem = itemsKeys.find(\n (itemKey) => typeof items[itemKey]?.[key] !== 'function',\n );\n if (invalidItem) {\n throw new Error(\n `The item \\`${String(\n invalidItem,\n )}\\` is invalid: it doesn't have a \\`${key}\\` function`,\n );\n }\n\n const useFn = fn\n ? (...args: Parameters<ResourceFn>) => fn(items, ...args)\n : (...args: Parameters<ResourceFn>) => {\n itemsKeys.forEach((itemK) => {\n const item = items[itemK]!;\n const itemFn = item[key];\n itemFn(...args);\n });\n };\n\n return {\n ...collectionResourceFactory(name, key, useFn as ResourceFn),\n ...items,\n };\n };\n };\n","import type { Jimple } from '../jimple';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- They are dynamically extended.\ntype GenericDict = Record<any, any>;\n/**\n * A helper that reusable services can use to resolve dependencies in constructors and/or\n * providers.\n *\n * @template InjectDictionary A dictionary of the dependencies and their types.\n * @template InjectKey The literal type of the dictionary types.\n */\nexport class InjectHelper<\n InjectDictionary extends GenericDict,\n InjectKey = keyof InjectDictionary,\n> {\n /**\n * This method is meant to be used to validate the dependencies a service receives, and\n * needs.\n * It will check on the received dependencies, if a specific dependency exists, it will\n * return it, otherwise, it will create a new instance.\n *\n * @param dependencies The dependencies received by the implementation.\n * @param key The key of the dependency to validate.\n * @param init A function to create a dependency in case it doesn't exist in\n * the dictionary.\n * @returns An instance of the dependency.\n * @template DepKey The literal key of the dependency to validate.\n * @template DepType The type of the dependency, obtained from the dictionary sent\n * to the constructor.\n * @example\n *\n * type Dependencies = {\n * dep: string;\n * };\n * const helper = new InjectHelper<Dependencies>();\n *\n * type MyServiceOptions = {\n * inject?: Partial<Dependencies>;\n * };\n * const myService = ({ inject = {} }: MyServiceOptions) => {\n * const dep = helper.get(inject, 'dep', () => 'default');\n * console.log('dep:', dep);\n * };\n *\n */\n get<DepKey extends InjectKey, DepType = InjectDictionary[DepKey]>(\n dependencies: Partial<InjectDictionary>,\n key: InjectKey,\n init: () => DepType,\n ): DepType {\n const existing = dependencies[key];\n if (typeof existing !== 'undefined') {\n return existing!;\n }\n\n return init();\n }\n /**\n * This is meant to be used in a provider creator to resolve dependencies' names sent as\n * options. For each dependency, the method will first check if a new name was\n * specified, and try to get it with that name, otherwise, it will try to get it with\n * the default name, and if it doesn't exist, it will just keep it as `undefined` and\n * expect the service implements {@link InjectHelper.get} to ensure the dependency.\n *\n * @param dependencies The dependencies needed by the service.\n * @param container A reference to the Jimple container.\n * @param inject A dictionary of dependencies names.\n * @returns A dictionary of dependencies to send to the service.\n * @template DepKey The literal key of the dependencies to validate.\n * @template Container The type of the Jimple container.\n * @example\n *\n * type Dependencies = {\n * dep: string;\n * };\n * const helper = new InjectHelper<Dependencies>();\n *\n * type MyProviderOptions = {\n * services?: {\n * [key in keyof Dependencies]?: string;\n * };\n * };\n *\n * const myProvider = providerCreator(\n * ({ services = {} }: MyProviderOptions) =>\n * (container) => {\n * container.set('myService', () => {\n * const inject = helper.resolve(['dep'], container, services);\n * return myService({ inject });\n * });\n * },\n * );\n *\n */\n resolve<DepKey extends InjectKey, Container extends Jimple>(\n dependencies: DepKey[],\n container: Container,\n inject: Partial<Record<keyof InjectDictionary, string>>,\n ): Partial<InjectDictionary> {\n const result = dependencies.reduce<Partial<InjectDictionary>>((acc, key) => {\n if (inject[key]) {\n acc[key] = container.get<InjectDictionary[typeof key]>(inject[key]!);\n return acc;\n }\n\n const keyStr = key as unknown as string;\n if (container.has(keyStr)) {\n acc[key] = container.get<InjectDictionary[typeof key]>(keyStr);\n return acc;\n }\n\n return acc;\n }, {});\n\n return result;\n }\n}\n/**\n * Shorthand for `new InjectHelper()`.\n *\n * @returns A new instance of {@link InjectHelper}.\n */\nexport const injectHelper = <InjectDictionary extends GenericDict>() =>\n new InjectHelper<InjectDictionary>();\n","import type { Jimple } from '../jimple';\nimport { resourceFactory } from '../factories';\n\nexport type ProviderName = 'provider';\nexport type ProviderKey = 'register';\n/**\n * The function the container will call when the provider is registered.\n *\n * @param container A reference for container where the provider is being registered.\n * @template ContainerType The type of the Jimple container (in case it gets\n * subclassed).\n */\nexport type ProviderRegisterFn<ContainerType extends Jimple = Jimple> = (\n container: ContainerType,\n) => void;\n/**\n * Generates a function to create providers for a specific type of container.\n *\n * @returns A function to create providers.\n * @template ContainerType The type of the Jimple container (in case it gets\n * subclassed).\n */\nexport const createProvider = <ContainerType extends Jimple = Jimple>() => {\n type RegisterFn = ProviderRegisterFn<ContainerType>;\n const factory = resourceFactory<RegisterFn>();\n return (register: RegisterFn) => factory('provider', 'register', register);\n};\n/**\n * Creates a resource to be registered in a Jimple container.\n *\n * @example\n *\n * export const myService = provider((c) => {\n * c.set('myService', () => new MyService());\n * });\n *\n */\nexport const provider = createProvider();\n/**\n * A resource that can be registered in a Jimple container.\n */\nexport type Provider = ReturnType<typeof provider>;\n","import type { Jimple } from '../jimple';\nimport { resourceCreatorFactory, type GenericCurriedFn } from '../factories';\nimport type { ProviderRegisterFn } from './provider';\n/**\n * Generates a function to create \"provider creators\" for a specific type of container.\n *\n * @returns A function to generate provider creators.\n * @template ContainerType The type of the Jimple container (in case it gets\n * subclassed).\n */\nexport const createProviderCreator = <ContainerType extends Jimple = Jimple>() => {\n type RegisterFn = ProviderRegisterFn<ContainerType>;\n type ProviderCreatorFn = GenericCurriedFn<RegisterFn>;\n const factory = resourceCreatorFactory<RegisterFn>();\n return <CreatorFn extends ProviderCreatorFn>(creator: CreatorFn) =>\n factory('provider', 'register', creator);\n};\n/**\n * Generates a \"provider creator\": a provider that can also be called as a function in\n * order to create a configured provider.\n *\n * @example\n *\n * export const myService = providerCreator((options: Opts = {}) => (c) => {\n * c.set('myService', () => new MyService(options));\n * });\n *\n */\nexport const providerCreator = createProviderCreator();\n/**\n * A function that returns a provider registration function.\n */\nexport type ProviderCreatorFn = Parameters<typeof providerCreator>[0];\n","import type { Jimple } from '../jimple';\nimport { resourcesCollectionFactory } from '../factories';\nimport type { ProviderRegisterFn, ProviderName } from './provider';\n/**\n * Generates a function to create a providers collection for a specific type of container.\n *\n * @returns A function to create providers collections.\n * @template ContainerType The type of the Jimple container (in case it gets\n * subclassed).\n */\nexport const createProviders = <ContainerType extends Jimple = Jimple>() => {\n type RegisterFn = ProviderRegisterFn<ContainerType>;\n const factory = resourcesCollectionFactory<ProviderName, RegisterFn>();\n return factory('provider', 'register');\n};\n/**\n * Generates a collection of providers. A collection is a dictionary of providers that can\n * also be used as a provider, and when it gets registered, it will register all of the\n * providers in the collection.\n *\n * @param items A dictionary of providers.\n * @example\n *\n * <caption>Assuming we already have two service providers...</caption>\n *\n * export const services = providers({\n * myServiceProvider,\n * myOtherServiceProvider,\n * });\n *\n */\nexport const providers = createProviders();\n"],"mappings":"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","names":["module","Jimple","provider","Jimple","JimpleOriginal","Jimple"]}
1
+ {"version":3,"sources":["../../../../node_modules/jimple/src/Jimple.js","../src/index.ts","../src/jimplemod/index.ts","../src/jimple/index.ts","../src/factories/resourceFactory.ts","../src/factories/resourceCreatorFactory.ts","../src/factories/resourcesCollectionFactory.ts","../src/helpers/injectHelper.ts","../src/helpers/provider.ts","../src/helpers/providerCreator.ts","../src/helpers/providers.ts"],"sourcesContent":["\"use strict\";\n\nfunction assert(ok, message) {\n if (!ok) {\n throw new Error(message)\n }\n}\n\nfunction isFunction(fn) {\n return Object.prototype.toString.call(fn) === \"[object Function]\" && fn.constructor.name === \"Function\";\n}\n\nfunction isPlainObject(value) {\n if (Object.prototype.toString.call(value) !== '[object Object]') {\n return false;\n }\n let prototype = Object.getPrototypeOf(value);\n return prototype === null || prototype === Object.prototype;\n}\n\nfunction checkDefined(container, key) {\n assert(container.has(key), `Identifier \"${key}\" is not defined.`);\n}\n\nfunction addFunctionTo(set, fn) {\n assert(isFunction(fn), \"Service definition is not a Closure or invokable object\");\n set.add(fn);\n return fn;\n}\n\n/**\n * The Jimple Container class\n *\n * @public\n */\nclass Jimple {\n static provider(register) {\n return ({ register });\n }\n /**\n * Create a Jimple Container.\n * @param {Object?} [values] - An optional object whose keys and values will be associated in the container at initialization\n */\n constructor(values) {\n this._items = {};\n this._instances = new Map();\n this._factories = new Set();\n this._protected = new Set();\n values = isPlainObject(values) ? values : {};\n Object.keys(values).forEach(function(key) {\n this.set(key, values[key]);\n }, this);\n }\n /**\n * Return the specified parameter or service. If the service is not built yet, this function will construct the service\n * injecting all the dependencies needed in it's definition so the returned object is totally usable on the fly.\n * @param {string} key - The key of the parameter or service to return\n * @return {*} The object related to the service or the value of the parameter associated with the key informed\n * @throws If the key does not exist\n */\n get(key) {\n checkDefined(this, key);\n let item = this._items[key];\n let obj;\n if (isFunction(item)) {\n if (this._protected.has(item)) {\n obj = item;\n } else if (this._instances.has(item)) {\n obj = this._instances.get(item);\n } else {\n obj = item(this);\n if (!this._factories.has(item)) {\n this._instances.set(item, obj);\n }\n }\n } else {\n obj = item;\n }\n return obj;\n }\n /**\n * Defines a new parameter or service.\n * @param {string} key - The key of the parameter or service to be defined\n * @param {*} value - The value of the parameter or a function that receives the container as parameter and constructs the service\n */\n set(key, value) {\n this._items[key] = value;\n }\n\n /**\n * Returns if a service or parameter with the informed key is already defined in the container.\n * @param {string} key - The key of the parameter or service to be checked.\n * @return {boolean} If the key exists in the container or not\n */\n has(key) {\n return this._items.hasOwnProperty(key);\n }\n\n /**\n * Defines a service as a factory, so the instances are not cached in the service and that function is always called\n * @param {function(Jimple):*} fn - The function that constructs the service that is a factory\n * @return {function(Jimple):*} The same function passed as parameter\n */\n factory(fn) {\n return addFunctionTo(this._factories, fn);\n }\n\n /**\n * Defines a function as a parameter, so that function is not considered a service\n * @param {*} fn - The function to not be considered a service\n * @return {*} The same function passed as parameter\n */\n protect(fn) {\n return addFunctionTo(this._protected, fn);\n }\n\n /**\n * Return all the keys registered in the container\n * @returns {Array<string>}\n */\n keys() {\n return Object.keys(this._items);\n }\n\n /**\n * Extends a service already registered in the container\n * @param {string} key - The key of the service to be extended\n * @param {function(*, Jimple):*} fn - The function that will be used to extend the service\n * @throws If the key is not already defined\n * @throws If the key saved in the container does not correspond to a service\n * @throws If the function passed it not...well, a function\n */\n extend(key, fn) {\n checkDefined(this, key);\n let originalItem = this._items[key];\n assert(isFunction(originalItem) && this._protected.has(originalItem) === false, `Identifier '${key}' does not contain a service definition`);\n assert(isFunction(fn), `The 'new' service definition for '${key}' is not a invokable object.`);\n this._items[key] = function(app) {\n return fn(originalItem(app), app);\n }\n if (this._factories.has(originalItem)) {\n this._factories.delete(originalItem);\n this._factories.add(this._items[key]);\n }\n }\n\n /**\n * Uses an provider to extend the service, so it's easy to split the service and parameter definitions across the system\n * @param {{register: function(Jimple)}} provider - The provider to be used to register services and parameters in this container\n */\n register(provider) {\n provider.register(this);\n }\n\n /**\n * Returns the raw value of a service or parameter. So, in the case of a service, for example, the value returned is the\n * function used to construct the service.\n * @param {string} key - The key of the service or parameter to return.\n * @throws If the key does not exist in the container\n * @return {*} The raw value of the service or parameter\n */\n raw(key) {\n checkDefined(this, key);\n return this._items[key];\n }\n}\n\nmodule.exports = Jimple;\n","export * from './jimple';\nexport * from './factories';\nexport * from './helpers';\n","// @ts-expect-error - the idea is to have `any` and assert on export.\nimport JimpleOriginal from 'jimple';\nimport { Container as JimpleContainer } from './jimple.type';\n\nconst Jimple = JimpleOriginal as typeof JimpleContainer;\n\nexport { Jimple };\nexport type { JimpleContainer };\n","import { Jimple as JimpleMod } from '../jimplemod';\n\nexport class Jimple extends JimpleMod {\n /**\n * This is a version of the `get` method that doesn't throw if the key doesn't exist. It\n * will return `undefined` instead.\n *\n * @param key The key of the parameter or service to return.\n * @returns The object related to the service or the value of the parameter\n * associated with the given key.\n * @template T The type of the returned object.\n */\n try<T = unknown>(key: string): T | undefined {\n if (!this.has(key)) {\n return undefined;\n }\n\n return this.get<T>(key);\n }\n}\n/**\n * Shorthand for `new Jimple()`.\n *\n * @param args The same parameters as the {@link Jimple} constructor.\n * @returns A new instance of {@link Jimple}.\n */\nexport const jimple = (...args: ConstructorParameters<typeof Jimple>): Jimple =>\n new Jimple(...args);\n","import type { GenericFn, Resource } from './factories.types';\n/**\n * Generates a function to create resources of an specified type. This function itself\n * doesn't have logic, but it's just in charge of creating the constraint for the resource\n * function.\n *\n * As all the other _\"factory functions\"_, this is meant to be used as a building block\n * when extending the container.\n *\n * @returns A function that can be used to create a resource with a specified type of\n * function.\n * @template ResourceFn The type of function the resource needs to have.\n * @example\n *\n * type ActionFn = (c: Jimple) => void;\n * const factory = resourceFactory<ActionFn>();\n * const myAction = factory('action', 'fn', (c) => {\n * c.set('foo', 'bar');\n * });\n *\n */\nexport const resourceFactory =\n <ResourceFn extends GenericFn>() =>\n /**\n * Generates a new resource using the contraint defined in the factory.\n *\n * @param name The name of the resource.\n * @param key The property key for the function.\n * @param fn The resource function.\n * @returns An object with the `name` set to `true`, and the `fn` as the `key`.\n * @template Name The literal type of `name`, to be used in the return object.\n * @template Key The literal type of `key`, to be used in the return object.\n * @template Fn The type of `fn`, restricted by the factory constraint.\n * @example\n *\n * const myAction = factory('action', 'fn', (c) => {\n * c.set('foo', 'bar');\n * });\n *\n */\n <Name extends string, Key extends string, Fn extends ResourceFn>(\n name: Name,\n key: Key,\n fn: Fn,\n ): Resource<Name, Key, Fn> =>\n ({\n [name]: true,\n [key]: fn,\n } as Resource<Name, Key, Fn>);\n","import { resourceFactory } from './resourceFactory';\nimport type {\n GenericFn,\n GenericCurriedFn,\n ResourceCreator,\n ResourceCreatorCurriedFn,\n ResourceCreatorHandler,\n} from './factories.types';\n/**\n * Generates a function to create resource creators of an specified type. This function\n * itself doesn't have logic, but it's just in charge of creating the constraint for the\n * resource creator function.\n *\n * As all the other _\"factory functions\"_, this is meant to be used as a building block\n * when extending the container.\n *\n * @returns A function that can be used to create \"resource creators\".\n * @template ResourceFn The type of function the resource creator needs to have.\n * @example\n *\n * type ActionFn = (c: Jimple) => void;\n * const factory = resourceCreatorFactory<ActionFn>();\n * const myAction = factory('action', 'fn', (name = 'foo') => (c) => {\n * c.set(name, 'bar');\n * });\n *\n */\nexport const resourceCreatorFactory =\n <ResourceFn extends GenericFn>() =>\n /**\n * Generates a new resource creator using the contraint defined in the factory.\n *\n * @param name The name of the resource.\n * @param key The property key for the function.\n * @param creatorFn The curried function that returns the actual resource function.\n * @returns A resource creator: an object that can be used as a resource, and as a\n * function that returns a resource.\n * @template Name The literal type of `name`, to be used in the return object.\n * @template Key The literal type of `key`, to be used in the return object.\n * @template ResFn The type of the resource function, the creator function needs\n * to return. This is restricted by the factory constraint.\n * @template CreatorFn The literal type of `creatorFn`, to be used in the return\n * object.\n * @example\n *\n * const myAction = factory('action', 'fn', (name = 'foo') => (c) => {\n * c.set(name, 'bar');\n * });\n *\n */\n <\n Name extends string,\n Key extends string,\n ResFn extends ResourceFn,\n CreatorFn extends GenericCurriedFn<ResFn>,\n >(\n name: Name,\n key: Key,\n creatorFn: CreatorFn,\n ): ResourceCreator<Name, Key, CreatorFn, ResourceFn> => {\n const fnToProxy: ResourceCreatorCurriedFn<Name, Key, CreatorFn> = (...args) => {\n const actualResource = creatorFn(...args) as ReturnType<CreatorFn>;\n return resourceFactory<ResFn>()(name, key, actualResource);\n };\n\n const handler: ResourceCreatorHandler<Name, Key, CreatorFn> = {\n name,\n resource: null,\n get(target, property) {\n let result;\n if (property === this.name) {\n result = true;\n } else if (property === key) {\n if (this.resource === null) {\n const newResource = creatorFn() as ReturnType<CreatorFn>;\n this.resource = newResource;\n }\n result = this.resource;\n } else {\n const targetKey = property as keyof typeof target;\n result = target[targetKey];\n }\n\n return result;\n },\n has(target, property) {\n if (property === this.name || property === key) {\n return true;\n }\n\n const targetKey = property as keyof typeof target;\n return targetKey in target;\n },\n };\n\n return new Proxy(fnToProxy, handler) as unknown as ResourceCreator<\n Name,\n Key,\n CreatorFn,\n ResourceFn\n >;\n };\n","import { resourceFactory } from './resourceFactory';\nimport type { GenericFn, Resource } from './factories.types';\n/**\n * Generates a function to configure a collection of resources of an specified type. This\n * function itself doesn't have logic, but it's just in charge of creating the constraint\n * for the resource name and function.\n *\n * As all the other _\"factory functions\"_, this is meant to be used as a building block\n * when extending the container.\n *\n * @returns A function that can be used to configure a collection of resources.\n * @template ResourceName The literal type of the name the resources needs to have.\n * @template ResourceFn The type of function the resources needs to have.\n * @example\n *\n * type ActionFn = (c: Jimple) => void;\n * const factory = resourcesCollectionFactory<'action', ActionFn>();\n * const myActions = factory('action', 'fn')({ myActionA, myActionB });\n *\n */\nexport const resourcesCollectionFactory =\n <ResourceName extends string, ResourceFn extends GenericFn>() =>\n /**\n * Generates a function to create a collection of resources of an specified type. A\n * collection is a dictionary of resources, and a resource itself, and when its\n * \"resource function\" gets called, it calls the function of every resource (with the\n * same args it recevied).\n *\n * @param name The resource name the items in the collection must have.\n * @param key The key property the items in the collection must have.\n * @param fn A custom function to process the items in the collection, when the\n * collection function gets called.\n * @returns A function that can be used to create a resources collection.\n * @template Name The literal type of `name`, to be used in the return object.\n * @template Key The literal type of `key`, to be used in the return object.\n * @template ItemKey To capture the name of the resources in the collection.\n * @template Items The kind of dictionary of resources the return function will\n * expect.\n * @template CustomFn The type of `fn`, restricted by the factory constraint.\n * @example\n *\n * const myActions = factory('action', 'fn')({ myActionA, myActionB });\n *\n */\n <\n Name extends string,\n Key extends string,\n ItemKey extends string,\n Items extends Record<ItemKey, Resource<ResourceName, Key, ResourceFn>>,\n CustomFn extends (items: Items, ...rest: Parameters<ResourceFn>) => void,\n >(\n name: Name,\n key: Key,\n fn?: CustomFn,\n ) => {\n const collectionResourceFactory = resourceFactory<ResourceFn>();\n /**\n * The actual function that recevies the items and creates the collection.\n *\n * @param items A dictionary of resources for the collection.\n * @returns A dictionary of the resources, that it's also a resource.\n * @template ItemsParam The literal type of `items`, to be used in the return\n * object.\n * @throws If the dictionary contains the resource name or function key as keys.\n * @throws If one of the items doesn't have the resource function.\n */\n return <ItemsParam>(\n items: ItemsParam & Items,\n ): typeof items & Resource<Name, Key, ResourceFn> => {\n const invalidKeys: string[] = [name, key];\n const itemsKeys = Object.keys(items) as Array<keyof Items>;\n\n const invalidKey = itemsKeys.some((itemKey) =>\n invalidKeys.includes(String(itemKey)),\n );\n if (invalidKey) {\n throw new Error(\n `No item on the collection can have the keys \\`${name}\\` nor \\`${key}\\``,\n );\n }\n\n const invalidItem = itemsKeys.find(\n (itemKey) => typeof items[itemKey]?.[key] !== 'function',\n );\n if (invalidItem) {\n throw new Error(\n `The item \\`${String(\n invalidItem,\n )}\\` is invalid: it doesn't have a \\`${key}\\` function`,\n );\n }\n\n const useFn = fn\n ? (...args: Parameters<ResourceFn>) => fn(items, ...args)\n : (...args: Parameters<ResourceFn>) => {\n itemsKeys.forEach((itemK) => {\n const item = items[itemK]!;\n const itemFn = item[key];\n itemFn(...args);\n });\n };\n\n return {\n ...collectionResourceFactory(name, key, useFn as ResourceFn),\n ...items,\n };\n };\n };\n","import type { Jimple } from '../jimple';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- They are dynamically extended.\ntype GenericDict = Record<any, any>;\n/**\n * A helper that reusable services can use to resolve dependencies in constructors and/or\n * providers.\n *\n * @template InjectDictionary A dictionary of the dependencies and their types.\n * @template InjectKey The literal type of the dictionary types.\n */\nexport class InjectHelper<\n InjectDictionary extends GenericDict,\n InjectKey = keyof InjectDictionary,\n> {\n /**\n * This method is meant to be used to validate the dependencies a service receives, and\n * needs.\n * It will check on the received dependencies, if a specific dependency exists, it will\n * return it, otherwise, it will create a new instance.\n *\n * @param dependencies The dependencies received by the implementation.\n * @param key The key of the dependency to validate.\n * @param init A function to create a dependency in case it doesn't exist in\n * the dictionary.\n * @returns An instance of the dependency.\n * @template DepKey The literal key of the dependency to validate.\n * @template DepType The type of the dependency, obtained from the dictionary sent\n * to the constructor.\n * @example\n *\n * type Dependencies = {\n * dep: string;\n * };\n * const helper = new InjectHelper<Dependencies>();\n *\n * type MyServiceOptions = {\n * inject?: Partial<Dependencies>;\n * };\n * const myService = ({ inject = {} }: MyServiceOptions) => {\n * const dep = helper.get(inject, 'dep', () => 'default');\n * console.log('dep:', dep);\n * };\n *\n */\n get<DepKey extends InjectKey, DepType = InjectDictionary[DepKey]>(\n dependencies: Partial<InjectDictionary>,\n key: InjectKey,\n init: () => DepType,\n ): DepType {\n const existing = dependencies[key];\n if (typeof existing !== 'undefined') {\n return existing!;\n }\n\n return init();\n }\n /**\n * This is meant to be used in a provider creator to resolve dependencies' names sent as\n * options. For each dependency, the method will first check if a new name was\n * specified, and try to get it with that name, otherwise, it will try to get it with\n * the default name, and if it doesn't exist, it will just keep it as `undefined` and\n * expect the service implements {@link InjectHelper.get} to ensure the dependency.\n *\n * @param dependencies The dependencies needed by the service.\n * @param container A reference to the Jimple container.\n * @param inject A dictionary of dependencies names.\n * @returns A dictionary of dependencies to send to the service.\n * @template DepKey The literal key of the dependencies to validate.\n * @template Container The type of the Jimple container.\n * @example\n *\n * type Dependencies = {\n * dep: string;\n * };\n * const helper = new InjectHelper<Dependencies>();\n *\n * type MyProviderOptions = {\n * services?: {\n * [key in keyof Dependencies]?: string;\n * };\n * };\n *\n * const myProvider = providerCreator(\n * ({ services = {} }: MyProviderOptions) =>\n * (container) => {\n * container.set('myService', () => {\n * const inject = helper.resolve(['dep'], container, services);\n * return myService({ inject });\n * });\n * },\n * );\n *\n */\n resolve<DepKey extends InjectKey, Container extends Jimple>(\n dependencies: DepKey[],\n container: Container,\n inject: Partial<Record<keyof InjectDictionary, string>>,\n ): Partial<InjectDictionary> {\n const result = dependencies.reduce<Partial<InjectDictionary>>((acc, key) => {\n if (inject[key]) {\n acc[key] = container.get<InjectDictionary[typeof key]>(inject[key]!);\n return acc;\n }\n\n const keyStr = key as unknown as string;\n if (container.has(keyStr)) {\n acc[key] = container.get<InjectDictionary[typeof key]>(keyStr);\n return acc;\n }\n\n return acc;\n }, {});\n\n return result;\n }\n}\n/**\n * Shorthand for `new InjectHelper()`.\n *\n * @returns A new instance of {@link InjectHelper}.\n */\nexport const injectHelper = <InjectDictionary extends GenericDict>() =>\n new InjectHelper<InjectDictionary>();\n","import type { Jimple } from '../jimple';\nimport { resourceFactory } from '../factories';\n\nexport type ProviderName = 'provider';\nexport type ProviderKey = 'register';\n/**\n * The function the container will call when the provider is registered.\n *\n * @param container A reference for container where the provider is being registered.\n * @template ContainerType The type of the Jimple container (in case it gets\n * subclassed).\n */\nexport type ProviderRegisterFn<ContainerType extends Jimple = Jimple> = (\n container: ContainerType,\n) => void;\n/**\n * Generates a function to create providers for a specific type of container.\n *\n * @returns A function to create providers.\n * @template ContainerType The type of the Jimple container (in case it gets\n * subclassed).\n */\nexport const createProvider = <ContainerType extends Jimple = Jimple>() => {\n type RegisterFn = ProviderRegisterFn<ContainerType>;\n const factory = resourceFactory<RegisterFn>();\n return (register: RegisterFn) => factory('provider', 'register', register);\n};\n/**\n * Creates a resource to be registered in a Jimple container.\n *\n * @example\n *\n * export const myService = provider((c) => {\n * c.set('myService', () => new MyService());\n * });\n *\n */\nexport const provider = createProvider();\n/**\n * A resource that can be registered in a Jimple container.\n */\nexport type Provider = ReturnType<typeof provider>;\n","import type { Jimple } from '../jimple';\nimport { resourceCreatorFactory, type GenericCurriedFn } from '../factories';\nimport type { ProviderRegisterFn } from './provider';\n/**\n * Generates a function to create \"provider creators\" for a specific type of container.\n *\n * @returns A function to generate provider creators.\n * @template ContainerType The type of the Jimple container (in case it gets\n * subclassed).\n */\nexport const createProviderCreator = <ContainerType extends Jimple = Jimple>() => {\n type RegisterFn = ProviderRegisterFn<ContainerType>;\n type ProviderCreatorFn = GenericCurriedFn<RegisterFn>;\n const factory = resourceCreatorFactory<RegisterFn>();\n return <CreatorFn extends ProviderCreatorFn>(creator: CreatorFn) =>\n factory('provider', 'register', creator);\n};\n/**\n * Generates a \"provider creator\": a provider that can also be called as a function in\n * order to create a configured provider.\n *\n * @example\n *\n * export const myService = providerCreator((options: Opts = {}) => (c) => {\n * c.set('myService', () => new MyService(options));\n * });\n *\n */\nexport const providerCreator = createProviderCreator();\n/**\n * A function that returns a provider registration function.\n */\nexport type ProviderCreatorFn = Parameters<typeof providerCreator>[0];\n","import type { Jimple } from '../jimple';\nimport { resourcesCollectionFactory } from '../factories';\nimport type { ProviderRegisterFn, ProviderName } from './provider';\n/**\n * Generates a function to create a providers collection for a specific type of container.\n *\n * @returns A function to create providers collections.\n * @template ContainerType The type of the Jimple container (in case it gets\n * subclassed).\n */\nexport const createProviders = <ContainerType extends Jimple = Jimple>() => {\n type RegisterFn = ProviderRegisterFn<ContainerType>;\n const factory = resourcesCollectionFactory<ProviderName, RegisterFn>();\n return factory('provider', 'register');\n};\n/**\n * Generates a collection of providers. A collection is a dictionary of providers that can\n * also be used as a provider, and when it gets registered, it will register all of the\n * providers in the collection.\n *\n * @param items A dictionary of providers.\n * @example\n *\n * <caption>Assuming we already have two service providers...</caption>\n *\n * export const services = providers({\n * myServiceProvider,\n * myOtherServiceProvider,\n * });\n *\n */\nexport const providers = createProviders();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,wDAAAA,SAAA;AAAA;AAEA,aAAS,OAAO,IAAI,SAAS;AACzB,UAAI,CAAC,IAAI;AACL,cAAM,IAAI,MAAM,OAAO;AAAA,MAC3B;AAAA,IACJ;AAEA,aAAS,WAAW,IAAI;AACpB,aAAO,OAAO,UAAU,SAAS,KAAK,EAAE,MAAM,uBAAuB,GAAG,YAAY,SAAS;AAAA,IACjG;AAEA,aAAS,cAAc,OAAO;AAC1B,UAAI,OAAO,UAAU,SAAS,KAAK,KAAK,MAAM,mBAAmB;AAC7D,eAAO;AAAA,MACX;AACA,UAAI,YAAY,OAAO,eAAe,KAAK;AAC3C,aAAO,cAAc,QAAQ,cAAc,OAAO;AAAA,IACtD;AAEA,aAAS,aAAa,WAAW,KAAK;AAClC,aAAO,UAAU,IAAI,GAAG,GAAG,eAAe,sBAAsB;AAAA,IACpE;AAEA,aAAS,cAAc,KAAK,IAAI;AAC5B,aAAO,WAAW,EAAE,GAAG,yDAAyD;AAChF,UAAI,IAAI,EAAE;AACV,aAAO;AAAA,IACX;AAOA,QAAMC,UAAN,MAAa;AAAA,MACT,OAAO,SAAS,UAAU;AACxB,eAAQ,EAAE,SAAS;AAAA,MACrB;AAAA;AAAA;AAAA;AAAA;AAAA,MAKA,YAAY,QAAQ;AAChB,aAAK,SAAS,CAAC;AACf,aAAK,aAAa,oBAAI,IAAI;AAC1B,aAAK,aAAa,oBAAI,IAAI;AAC1B,aAAK,aAAa,oBAAI,IAAI;AAC1B,iBAAS,cAAc,MAAM,IAAI,SAAS,CAAC;AAC3C,eAAO,KAAK,MAAM,EAAE,QAAQ,SAAS,KAAK;AACtC,eAAK,IAAI,KAAK,OAAO,GAAG,CAAC;AAAA,QAC7B,GAAG,IAAI;AAAA,MACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQA,IAAI,KAAK;AACL,qBAAa,MAAM,GAAG;AACtB,YAAI,OAAO,KAAK,OAAO,GAAG;AAC1B,YAAI;AACJ,YAAI,WAAW,IAAI,GAAG;AAClB,cAAI,KAAK,WAAW,IAAI,IAAI,GAAG;AAC3B,kBAAM;AAAA,UACV,WAAW,KAAK,WAAW,IAAI,IAAI,GAAG;AAClC,kBAAM,KAAK,WAAW,IAAI,IAAI;AAAA,UAClC,OAAO;AACH,kBAAM,KAAK,IAAI;AACf,gBAAI,CAAC,KAAK,WAAW,IAAI,IAAI,GAAG;AAC5B,mBAAK,WAAW,IAAI,MAAM,GAAG;AAAA,YACjC;AAAA,UACJ;AAAA,QACJ,OAAO;AACH,gBAAM;AAAA,QACV;AACA,eAAO;AAAA,MACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,IAAI,KAAK,OAAO;AACZ,aAAK,OAAO,GAAG,IAAI;AAAA,MACvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,IAAI,KAAK;AACL,eAAO,KAAK,OAAO,eAAe,GAAG;AAAA,MACzC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,QAAQ,IAAI;AACR,eAAO,cAAc,KAAK,YAAY,EAAE;AAAA,MAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,QAAQ,IAAI;AACR,eAAO,cAAc,KAAK,YAAY,EAAE;AAAA,MAC5C;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,OAAO;AACH,eAAO,OAAO,KAAK,KAAK,MAAM;AAAA,MAClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUA,OAAO,KAAK,IAAI;AACZ,qBAAa,MAAM,GAAG;AACtB,YAAI,eAAe,KAAK,OAAO,GAAG;AAClC,eAAO,WAAW,YAAY,KAAK,KAAK,WAAW,IAAI,YAAY,MAAM,OAAO,eAAe,4CAA4C;AAC3I,eAAO,WAAW,EAAE,GAAG,qCAAqC,iCAAiC;AAC7F,aAAK,OAAO,GAAG,IAAI,SAAS,KAAK;AAC7B,iBAAO,GAAG,aAAa,GAAG,GAAG,GAAG;AAAA,QACpC;AACA,YAAI,KAAK,WAAW,IAAI,YAAY,GAAG;AACnC,eAAK,WAAW,OAAO,YAAY;AACnC,eAAK,WAAW,IAAI,KAAK,OAAO,GAAG,CAAC;AAAA,QACxC;AAAA,MACJ;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,SAASC,WAAU;AACf,QAAAA,UAAS,SAAS,IAAI;AAAA,MAC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MASA,IAAI,KAAK;AACL,qBAAa,MAAM,GAAG;AACtB,eAAO,KAAK,OAAO,GAAG;AAAA,MAC1B;AAAA,IACJ;AAEA,IAAAF,QAAO,UAAUC;AAAA;AAAA;;;ACvKjB;AAAA;AAAA;AAAA,gBAAAE;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,oBAA2B;AAG3B,IAAM,SAAS,cAAAC;;;ACFR,IAAMC,UAAN,cAAqB,OAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUpC,IAAiB,KAA4B;AAC3C,QAAI,CAAC,KAAK,IAAI,GAAG,GAAG;AAClB,aAAO;AAAA,IACT;AAEA,WAAO,KAAK,IAAO,GAAG;AAAA,EACxB;AACF;AAOO,IAAM,SAAS,IAAI,SACxB,IAAIA,QAAO,GAAG,IAAI;;;ACNb,IAAM,kBACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,CACE,MACA,KACA,QAEC;AAAA,IACC,CAAC,IAAI,GAAG;AAAA,IACR,CAAC,GAAG,GAAG;AAAA,EACT;AAAA;;;ACrBG,IAAM,yBACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,CAME,MACA,KACA,cACsD;AACtD,UAAM,YAA4D,IAAI,SAAS;AAC7E,YAAM,iBAAiB,UAAU,GAAG,IAAI;AACxC,aAAO,gBAAuB,EAAE,MAAM,KAAK,cAAc;AAAA,IAC3D;AAEA,UAAM,UAAwD;AAAA,MAC5D;AAAA,MACA,UAAU;AAAA,MACV,IAAI,QAAQ,UAAU;AACpB,YAAI;AACJ,YAAI,aAAa,KAAK,MAAM;AAC1B,mBAAS;AAAA,QACX,WAAW,aAAa,KAAK;AAC3B,cAAI,KAAK,aAAa,MAAM;AAC1B,kBAAM,cAAc,UAAU;AAC9B,iBAAK,WAAW;AAAA,UAClB;AACA,mBAAS,KAAK;AAAA,QAChB,OAAO;AACL,gBAAM,YAAY;AAClB,mBAAS,OAAO,SAAS;AAAA,QAC3B;AAEA,eAAO;AAAA,MACT;AAAA,MACA,IAAI,QAAQ,UAAU;AACpB,YAAI,aAAa,KAAK,QAAQ,aAAa,KAAK;AAC9C,iBAAO;AAAA,QACT;AAEA,cAAM,YAAY;AAClB,eAAO,aAAa;AAAA,MACtB;AAAA,IACF;AAEA,WAAO,IAAI,MAAM,WAAW,OAAO;AAAA,EAMrC;AAAA;;;ACjFK,IAAM,6BACX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBA,CAOE,MACA,KACA,OACG;AACH,UAAM,4BAA4B,gBAA4B;AAW9D,WAAO,CACL,UACmD;AACnD,YAAM,cAAwB,CAAC,MAAM,GAAG;AACxC,YAAM,YAAY,OAAO,KAAK,KAAK;AAEnC,YAAM,aAAa,UAAU;AAAA,QAAK,CAAC,YACjC,YAAY,SAAS,OAAO,OAAO,CAAC;AAAA,MACtC;AACA,UAAI,YAAY;AACd,cAAM,IAAI;AAAA,UACR,iDAAiD,gBAAgB;AAAA,QACnE;AAAA,MACF;AAEA,YAAM,cAAc,UAAU;AAAA,QAC5B,CAAC,YAAY,OAAO,MAAM,OAAO,IAAI,GAAG,MAAM;AAAA,MAChD;AACA,UAAI,aAAa;AACf,cAAM,IAAI;AAAA,UACR,cAAc;AAAA,YACZ;AAAA,UACF,uCAAuC;AAAA,QACzC;AAAA,MACF;AAEA,YAAM,QAAQ,KACV,IAAI,SAAiC,GAAG,OAAO,GAAG,IAAI,IACtD,IAAI,SAAiC;AACnC,kBAAU,QAAQ,CAAC,UAAU;AAC3B,gBAAM,OAAO,MAAM,KAAK;AACxB,gBAAM,SAAS,KAAK,GAAG;AACvB,iBAAO,GAAG,IAAI;AAAA,QAChB,CAAC;AAAA,MACH;AAEJ,aAAO;AAAA,QACL,GAAG,0BAA0B,MAAM,KAAK,KAAmB;AAAA,QAC3D,GAAG;AAAA,MACL;AAAA,IACF;AAAA,EACF;AAAA;;;AChGK,IAAM,eAAN,MAGL;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA+BA,IACE,cACA,KACA,MACS;AACT,UAAM,WAAW,aAAa,GAAG;AACjC,QAAI,OAAO,aAAa,aAAa;AACnC,aAAO;AAAA,IACT;AAEA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsCA,QACE,cACA,WACA,QAC2B;AAC3B,UAAM,SAAS,aAAa,OAAkC,CAAC,KAAK,QAAQ;AAC1E,UAAI,OAAO,GAAG,GAAG;AACf,YAAI,GAAG,IAAI,UAAU,IAAkC,OAAO,GAAG,CAAE;AACnE,eAAO;AAAA,MACT;AAEA,YAAM,SAAS;AACf,UAAI,UAAU,IAAI,MAAM,GAAG;AACzB,YAAI,GAAG,IAAI,UAAU,IAAkC,MAAM;AAC7D,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,IACT,GAAG,CAAC,CAAC;AAEL,WAAO;AAAA,EACT;AACF;AAMO,IAAM,eAAe,MAC1B,IAAI,aAA+B;;;ACrG9B,IAAM,iBAAiB,MAA6C;AAEzE,QAAM,UAAU,gBAA4B;AAC5C,SAAO,CAAC,aAAyB,QAAQ,YAAY,YAAY,QAAQ;AAC3E;AAWO,IAAM,WAAW,eAAe;;;AC3BhC,IAAM,wBAAwB,MAA6C;AAGhF,QAAM,UAAU,uBAAmC;AACnD,SAAO,CAAsC,YAC3C,QAAQ,YAAY,YAAY,OAAO;AAC3C;AAYO,IAAM,kBAAkB,sBAAsB;;;AClB9C,IAAM,kBAAkB,MAA6C;AAE1E,QAAM,UAAU,2BAAqD;AACrE,SAAO,QAAQ,YAAY,UAAU;AACvC;AAiBO,IAAM,YAAY,gBAAgB;","names":["module","Jimple","provider","Jimple","JimpleOriginal","Jimple"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@homer0/jimple",
3
3
  "description": "An extended version of the Jimple lib, with extra features",
4
- "version": "2.0.1",
4
+ "version": "2.0.2",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/homer0/packages.git",
@@ -23,11 +23,11 @@
23
23
  "dist/"
24
24
  ],
25
25
  "devDependencies": {
26
- "jest": "^29.4.1",
26
+ "jest": "^29.4.3",
27
27
  "jimple": "^1.5.0",
28
28
  "ts-jest": "^29.0.5",
29
- "tsup": "^6.5.0",
30
- "typescript": "^4.9.4"
29
+ "tsup": "^6.6.3",
30
+ "typescript": "^4.9.5"
31
31
  },
32
32
  "engine-strict": true,
33
33
  "engines": {
@@ -43,5 +43,5 @@
43
43
  "build": "tsup src/index.ts",
44
44
  "prepublishOnly": "npm run build"
45
45
  },
46
- "gitHead": "59c0f6af6901b9f4edb8d2ec36abaf11f6b0780d"
46
+ "gitHead": "1ed6ea29e2035f10f0dff60203b6b1d54c601dc8"
47
47
  }