This commit is contained in:
Tutur33
2023-11-24 22:35:41 +01:00
parent 3c0b507a93
commit 7644b2a0f7
45165 changed files with 4803356 additions and 3 deletions
+9
View File
@@ -0,0 +1,9 @@
# The MIT License
Copyright 2022 Harminder Virk, contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+53
View File
@@ -0,0 +1,53 @@
<div align="center">
<img src="https://res.cloudinary.com/adonisjs/image/upload/q_100/v1558612869/adonis-readme_zscycu.jpg" width="600px">
</div>
<br />
<div align="center">
<h3> IoC Container of AdonisJS </h3>
<p> Fold is the IoC container used the AdonisJS framework to <strong>register and resolve</strong> the framework wide dependencies </p>
</div>
<br />
<div align="center">
[![gh-workflow-image]][gh-workflow-url] [![npm-image]][npm-url] ![][typescript-image] [![license-image]][license-url] [![synk-image]][synk-url]
</div>
<div align="center">
<h3>
<a href="https://preview.adonisjs.com">
Website
</a>
<span> | </span>
<a href="https://preview.adonisjs.com/packages/ioc-container">
Guides
</a>
<span> | </span>
<a href="CONTRIBUTING.md">
Contributing
</a>
</h3>
</div>
<div align="center">
<sub>Built with ❤︎ by <a href="https://twitter.com/AmanVirk1">Harminder Virk</a>
</div>
[gh-workflow-image]: https://img.shields.io/github/workflow/status/adonisjs/fold/test?style=for-the-badge
[gh-workflow-url]: https://github.com/adonisjs/fold/actions/workflows/test.yml "Github action"
[typescript-image]: https://img.shields.io/badge/Typescript-294E80.svg?style=for-the-badge&logo=typescript
[typescript-url]: "typescript"
[npm-image]: https://img.shields.io/npm/v/@adonisjs/fold/alpha.svg?style=for-the-badge&logo=npm
[npm-url]: https://npmjs.org/package/@adonisjs/fold/v/alpha "npm"
[license-image]: https://img.shields.io/npm/l/@adonisjs/fold?color=blueviolet&style=for-the-badge
[license-url]: LICENSE.md "license"
[synk-image]: https://img.shields.io/snyk/vulnerabilities/github/adonisjs/fold?label=Synk%20Vulnerabilities&style=for-the-badge
[synk-url]: https://snyk.io/test/github/adonisjs/fold?targetFile=package.json "synk"
+4
View File
@@ -0,0 +1,4 @@
export * from './src/Contracts';
export { Ioc } from './src/Ioc';
export { inject } from './src/decorators';
export { Registrar } from './src/Registrar';
+32
View File
@@ -0,0 +1,32 @@
"use strict";
/*
* @adonisjs/fold
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Registrar = exports.inject = exports.Ioc = void 0;
__exportStar(require("./src/Contracts"), exports);
var Ioc_1 = require("./src/Ioc");
Object.defineProperty(exports, "Ioc", { enumerable: true, get: function () { return Ioc_1.Ioc; } });
var decorators_1 = require("./src/decorators");
Object.defineProperty(exports, "inject", { enumerable: true, get: function () { return decorators_1.inject; } });
var Registrar_1 = require("./src/Registrar");
Object.defineProperty(exports, "Registrar", { enumerable: true, get: function () { return Registrar_1.Registrar; } });
+252
View File
@@ -0,0 +1,252 @@
declare type Function = (...args: any[]) => any;
export declare type ExtractFunctions<T> = {
[P in keyof T]: T[P] extends Function ? P : never;
}[keyof T];
/**
* Unwraps the promise
*/
declare type UnWrapPromise<T> = T extends Promise<infer U> ? U : T;
/**
* Shape of the bind callback method
*/
export declare type BindCallback<ReturnValue extends any, Container extends IocContract> = (container: Container) => ReturnValue;
/**
* Shape of the fake callback method
*/
export declare type FakeCallback<ReturnValue extends any, Container extends IocContract> = (container: Container, originalValue: ReturnValue) => ReturnValue;
/**
* Shape of resolved lookup node, resolved using `getResolver().resolve()`
* method.
*/
export declare type IocResolverLookupNode<Namespace extends string> = {
namespace: Namespace;
type: 'binding' | 'alias';
method: string;
};
/**
* Shape of class constructor
*/
export declare type Constructor<T> = new (...args: any[]) => T;
/**
* Shape of class constructor with `makePlain` property
*/
export declare type PlainConstructor = {
makePlain: true;
};
/**
* Type of the "withBindings" method
*/
export interface WithBindings<ContainerBindings extends any> {
<Bindings extends (keyof ContainerBindings)[]>(namespaces: [...Bindings], cb: (...args: {
[M in keyof Bindings]: Bindings[M] extends keyof ContainerBindings ? ContainerBindings[Bindings[M]] : any;
}) => void): void;
<Namespace extends (keyof ContainerBindings | string)[]>(namespaces: readonly [...Namespace], cb: (...args: {
[M in keyof Namespace]: Namespace[M] extends keyof ContainerBindings ? ContainerBindings[Namespace[M]] : any;
}) => void): void;
}
/**
* Finding return type of the `ioc.make` method based upon the
* input argument.
*
* - String and LookupNode = Returns any
* - Class constructor with "makePlain" are returned as it is
* - Otherwise an instance of the class constructor is returned
* - All other values are returned as it is
*/
export declare type InferMakeType<T> = T extends string | LookupNode<string> ? any : T extends PlainConstructor ? T : T extends Constructor<infer A> ? A : T;
/**
* Shape of lookup node pulled using `ioc.lookup` method. This node
* can be passed to `ioc.use`, or `ioc.make` to skip many checks
* and resolve the binding right away.
*/
export declare type LookupNode<Namespace extends string> = {
namespace: Namespace;
type: 'binding' | 'alias';
};
/**
* Ioc container interface
*/
export interface IocContract<ContainerBindings extends any = any> {
/**
* Registered aliases. The key is the alias and value is the
* absolute directory path
*/
importAliases: {
[alias: string]: string;
};
/**
* Enable/disable proxies. Proxies are mainly required for fakes to
* work
*/
useProxies(enable?: boolean): this;
/**
* Define the module type for resolving auto import aliases. Defaults
* to `cjs`
*/
module: 'cjs' | 'esm';
/**
* Register a binding with a callback. The callback return value will be
* used when binding is resolved
*/
bind<Binding extends keyof ContainerBindings>(binding: Binding, callback: BindCallback<ContainerBindings[Binding], this>): this;
bind<Binding extends string>(binding: Binding, callback: BindCallback<Binding extends keyof ContainerBindings ? ContainerBindings[Binding] : any, this>): this;
/**
* Same as the [[bind]] method, but registers a singleton only. Singleton's callback
* is invoked only for the first time and then the cached value is used
*/
singleton<Binding extends keyof ContainerBindings>(binding: Binding, callback: BindCallback<ContainerBindings[Binding], this>): this;
singleton<Binding extends string>(binding: Binding, callback: BindCallback<Binding extends keyof ContainerBindings ? ContainerBindings[Binding] : any, this>): this;
/**
* Define an import alias
*/
alias(absolutePath: string, alias: string): this;
/**
* Register a fake for a namespace. Fakes works both for "bindings" and "import aliases".
* Fakes only work when proxies are enabled using "useProxies".
*/
fake<Namespace extends keyof ContainerBindings>(namespace: Namespace, callback: FakeCallback<ContainerBindings[Namespace], this>): this;
fake<Namespace extends string>(namespace: Namespace, callback: FakeCallback<Namespace extends keyof ContainerBindings ? ContainerBindings[Namespace] : any, this>): this;
/**
* Clear selected or all the fakes. Calling the method with no arguments
* will clear all the fakes
*/
restore<Namespace extends keyof ContainerBindings>(namespace?: Namespace): this;
restore(namespace?: string): this;
/**
* Find if a fake has been registered for a given namespace
*/
hasFake<Namespace extends keyof ContainerBindings>(namespace: Namespace): boolean;
hasFake(namespace: string): boolean;
/**
* Find if a binding exists for a given namespace
*/
hasBinding<Binding extends keyof ContainerBindings>(namespace: Binding): boolean;
hasBinding(namespace: string): boolean;
/**
* Find if a namespace is part of the auto import aliases. Returns false, when namespace
* is an alias path but has an explicit binding too
*/
isAliasPath(namespace: string): boolean;
/**
* Lookup a namespace. The output contains the complete namespace,
* along with its type. The type is an "alias" or a "binding".
*
* Null is returned when unable to lookup the namespace inside the container
*
* Note: This method just checks if a namespace is registered or binding
* or can be it resolved from auto import aliases or not. However,
* it doesn't check for the module existence on the disk.
*
* Optionally you can define a prefix namespace
* to be used to build the complete namespace. For example:
*
* - namespace: UsersController
* - prefixNamespace: App/Controllers/Http
* - Output: App/Controllers/Http/UsersController
*
* Prefix namespace is ignored for absolute namespaces. For example:
*
* - namespace: /App/UsersController
* - prefixNamespace: App/Controllers/Http
* - Output: App/UsersController
*/
lookup<Namespace extends Extract<keyof ContainerBindings, string>>(namespace: Namespace | LookupNode<Namespace>, prefixNamespace?: string): LookupNode<Namespace>;
lookup<Namespace extends string>(namespace: Namespace | LookupNode<Namespace>, prefixNamespace?: string): Namespace extends keyof ContainerBindings ? LookupNode<Namespace> : LookupNode<string> | null;
/**
* Same as [[lookup]]. But raises exception instead of returning null
*/
lookupOrFail<Namespace extends Extract<keyof ContainerBindings, string>>(namespace: Namespace | LookupNode<Namespace>, prefixNamespace?: string): LookupNode<Namespace>;
lookupOrFail<Namespace extends string>(namespace: Namespace | LookupNode<Namespace>, prefixNamespace?: string): Namespace extends keyof ContainerBindings ? LookupNode<Namespace> : LookupNode<string>;
/**
* Resolve a binding by invoking the binding factory function. An exception
* is raised, if the binding namespace is unregistered.
*/
resolveBinding<Binding extends Extract<keyof ContainerBindings, string>>(binding: Binding): ContainerBindings[Binding];
resolveBinding<Binding extends string>(namespace: Binding): Binding extends keyof ContainerBindings ? ContainerBindings[Binding] : any;
/**
* Import namespace from the auto import aliases. This method assumes you are
* using native ES modules
*/
import(namespace: string): Promise<any>;
/**
* Same as the "import" method, but uses CJS for requiring the module from its
* path
*/
require(namespace: string): any;
/**
* The use method looks up a namespace inside both the bindings and the
* auto import aliases
*/
use<Binding extends Extract<keyof ContainerBindings, string>>(lookupNode: Binding | LookupNode<Binding>): ContainerBindings[Binding];
use<Binding extends string>(lookupNode: Binding | LookupNode<Binding>): Binding extends keyof ContainerBindings ? ContainerBindings[Binding] : any;
/**
* Same as the [[use]] method, but instead uses ES modules for resolving
* the auto import aliases
*/
useAsync<Binding extends Extract<keyof ContainerBindings, string>>(lookupNode: Binding | LookupNode<Binding>): Promise<ContainerBindings[Binding]>;
useAsync<Binding extends string>(lookupNode: Binding | LookupNode<Binding>): Promise<Binding extends keyof ContainerBindings ? ContainerBindings[Binding] : any>;
/**
* Makes an instance of the class by first resolving it.
*/
make<Binding extends Extract<keyof ContainerBindings, string>>(lookupNode: Binding | LookupNode<Binding>, args?: any[]): ContainerBindings[Binding];
make<T extends any>(value: T | LookupNode<string>, args?: any[]): T extends keyof ContainerBindings ? ContainerBindings[T] : InferMakeType<T>;
/**
* Same as the [[make]] method, but instead uses ES modules for resolving
* the auto import aliases
*/
makeAsync<Binding extends Extract<keyof ContainerBindings, string>>(lookupNode: Binding | LookupNode<Binding>, args?: any[]): Promise<ContainerBindings[Binding]>;
makeAsync<T extends any>(value: T | LookupNode<string>, args?: any[]): Promise<T extends keyof ContainerBindings ? ContainerBindings[T] : InferMakeType<T>>;
/**
* The "withBindings" method invokes the defined callback when it is
* able to resolve all the mentioned bindings.
*/
withBindings: WithBindings<ContainerBindings>;
/**
* @deprecated: Use "withBindings" instead
*/
with: WithBindings<ContainerBindings>;
/**
* Call a method on an object and automatically inject its depdencies
*/
call<T extends any, Method extends ExtractFunctions<T>>(target: T, method: Method, args?: any[]): T[Method] extends Function ? ReturnType<T[Method]> : any;
/**
* Call a method on an object and automatically inject its depdencies
*/
callAsync<T extends any, Method extends ExtractFunctions<T>>(target: T, method: Method, args?: any[]): T[Method] extends Function ? Promise<UnWrapPromise<ReturnType<T[Method]>>> : Promise<any>;
/**
* Trap container lookup calls. It includes
*
* - Ioc.use
* - Ioc.useAsync
* - Ioc.make
* - Ioc.makeAsync
* - Ioc.require
* - Ioc.import
* - Ioc.resolveBinding
*/
trap(callback: (namespace: string) => any): this;
/**
* Returns the resolver instance to resolve Ioc container bindings with
* little ease. Since, the IocResolver uses an in-memory cache to
* improve the lookup speed, we suggest keeping a reference to
* the output of this method to leverage caching
*/
getResolver(fallbackMethod?: string, rcNamespaceKey?: string, fallbackNamespace?: string): IocResolverContract<ContainerBindings>;
}
/**
* IoC resolver allows resolving IoC container bindings by defining
* prefix namespaces
*/
export interface IocResolverContract<ContainerBindings extends any> {
/**
* Resolve IoC container binding
*/
resolve<Namespace extends Extract<keyof ContainerBindings, string>>(namespace: Namespace, prefixNamespace?: string): IocResolverLookupNode<Namespace>;
resolve<Namespace extends string>(namespace: Namespace, prefixNamespace?: string): Namespace extends keyof ContainerBindings ? IocResolverLookupNode<Namespace> : IocResolverLookupNode<string>;
/**
* Call method on an IoC container binding
*/
call<Namespace extends Extract<keyof ContainerBindings, string>>(namespace: Namespace | string, prefixNamespace?: string, args?: any[] | ((instance: any) => any[])): Promise<any>;
call<Namespace extends Extract<keyof ContainerBindings, string>>(namespace: IocResolverLookupNode<Namespace | string>, prefixNamespace: undefined, args?: any[] | ((instance: any) => any[])): Promise<any>;
}
export {};
+10
View File
@@ -0,0 +1,10 @@
"use strict";
/*
* @adonisjs/fold
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,8 @@
import { Exception } from '@poppinss/utils';
/**
* Raised when trying to inject a primitive value like "StringConstructor"
* to a class constructor or method
*/
export declare class InvalidInjectionException extends Exception {
static invoke(value: any, parentName: string, index: number): InvalidInjectionException;
}
@@ -0,0 +1,23 @@
"use strict";
/*
* @adonisjs/fold
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.InvalidInjectionException = void 0;
const utils_1 = require("@poppinss/utils");
/**
* Raised when trying to inject a primitive value like "StringConstructor"
* to a class constructor or method
*/
class InvalidInjectionException extends utils_1.Exception {
static invoke(value, parentName, index) {
const primitiveName = `{${value.name} Constructor}`;
return new this(`Cannot inject "${primitiveName}" to "${parentName}" at position "${index + 1}"`);
}
}
exports.InvalidInjectionException = InvalidInjectionException;
@@ -0,0 +1,15 @@
import { Exception } from '@poppinss/utils';
/**
* Raised when unable to lookup a namespace
*/
export declare class IocLookupException extends Exception {
static lookupFailed(namespace: string): IocLookupException;
/**
* Invalid namespace type
*/
static invalidNamespace(): IocLookupException;
/**
* Fake is missing and yet resolved
*/
static missingFake(namespace: string): IocLookupException;
}
+33
View File
@@ -0,0 +1,33 @@
"use strict";
/*
* @adonisjs/fold
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.IocLookupException = void 0;
const utils_1 = require("@poppinss/utils");
/**
* Raised when unable to lookup a namespace
*/
class IocLookupException extends utils_1.Exception {
static lookupFailed(namespace) {
return new this(`Cannot resolve "${namespace}" namespace from the IoC Container`, 500, 'E_IOC_LOOKUP_FAILED');
}
/**
* Invalid namespace type
*/
static invalidNamespace() {
return new this('"Ioc.lookup" accepts a namespace string or a lookup node', 500, 'E_INVALID_IOC_NAMESPACE');
}
/**
* Fake is missing and yet resolved
*/
static missingFake(namespace) {
return new this(`Cannot resolve fake for "${namespace}" namespace`, 500, 'E_MISSING_IOC_FAKE');
}
}
exports.IocLookupException = IocLookupException;
+24
View File
@@ -0,0 +1,24 @@
import { IocContract, BindCallback } from '../Contracts';
/**
* Manages the IoC container bindings
*/
export declare class Bindings {
private container;
/**
* Registered bindings
*/
private list;
constructor(container: IocContract);
/**
* Find if namespace is a binding
*/
has(namespace: string): boolean;
/**
* Define a binding
*/
register(binding: string, callback: BindCallback<any, IocContract>, singleton: boolean): this;
/**
* Resolve a binding. An exception is raised, if the binding is missing
*/
resolve(binding: string): any;
}
+56
View File
@@ -0,0 +1,56 @@
"use strict";
/*
* @adonisjs/fold
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Bindings = void 0;
const IocLookupException_1 = require("../Exceptions/IocLookupException");
/**
* Manages the IoC container bindings
*/
class Bindings {
constructor(container) {
this.container = container;
/**
* Registered bindings
*/
this.list = new Map();
}
/**
* Find if namespace is a binding
*/
has(namespace) {
return this.list.has(namespace);
}
/**
* Define a binding
*/
register(binding, callback, singleton) {
this.list.set(binding, { callback, singleton });
return this;
}
/**
* Resolve a binding. An exception is raised, if the binding is missing
*/
resolve(binding) {
const bindingNode = this.list.get(binding);
if (!bindingNode) {
throw IocLookupException_1.IocLookupException.lookupFailed(binding);
}
let resolvedValue;
if (bindingNode.singleton) {
bindingNode.cachedValue = bindingNode.cachedValue ?? bindingNode.callback(this.container);
resolvedValue = bindingNode.cachedValue;
}
else {
resolvedValue = bindingNode.callback(this.container);
}
return resolvedValue;
}
}
exports.Bindings = Bindings;
+33
View File
@@ -0,0 +1,33 @@
import { FakeCallback, IocContract } from '../Contracts';
/**
* Manages the container fakes
*/
export declare class Fakes {
private container;
/**
* Registered fakes
*/
private list;
constructor(container: IocContract);
/**
* Register a fake for a given namespace
*/
register(namespace: string, callback: FakeCallback<any, IocContract>): this;
/**
* Find if namespace has a fake registered
*/
has(namespace: string): boolean;
/**
* Clear all fakes
*/
clear(): void;
/**
* Delete fake for a given namespace
*/
delete(namespace: string): boolean;
/**
* Resolve the fake for a given namespace. An exception is raised if
* not fake is defined
*/
resolve(namespace: string, originalValue: any): boolean;
}
+62
View File
@@ -0,0 +1,62 @@
"use strict";
/*
* @adonisjs/fold
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Fakes = void 0;
const IocLookupException_1 = require("../Exceptions/IocLookupException");
/**
* Manages the container fakes
*/
class Fakes {
constructor(container) {
this.container = container;
/**
* Registered fakes
*/
this.list = new Map();
}
/**
* Register a fake for a given namespace
*/
register(namespace, callback) {
this.list.set(namespace, { callback });
return this;
}
/**
* Find if namespace has a fake registered
*/
has(namespace) {
return this.list.has(namespace);
}
/**
* Clear all fakes
*/
clear() {
return this.list.clear();
}
/**
* Delete fake for a given namespace
*/
delete(namespace) {
return this.list.delete(namespace);
}
/**
* Resolve the fake for a given namespace. An exception is raised if
* not fake is defined
*/
resolve(namespace, originalValue) {
const fake = this.list.get(namespace);
if (!fake) {
throw IocLookupException_1.IocLookupException.missingFake(namespace);
}
fake.cachedValue = fake.cachedValue ?? fake.callback(this.container, originalValue);
return fake.cachedValue;
}
}
exports.Fakes = Fakes;
+43
View File
@@ -0,0 +1,43 @@
import { IocContract } from '../Contracts';
/**
* Manages the import aliases
*/
export declare class ImportAliases {
private container;
/**
* Registered aliases
*/
list: {
[alias: string]: string;
};
/**
* In-memory require cache to speed up lookup calls. Yes, "require"
* is slow. Check "perf/require.js"
*/
private requireCache;
constructor(container: IocContract);
/**
* Returns the matching alias for the given namespace
*/
private getPathAlias;
/**
* Returns path for a given alias
*/
private makeAliasPath;
/**
* Register an import alias
*/
register(absolutePath: string, alias: string): this;
/**
* Find if a namespace is part of the import aliases
*/
has(namespace: string): boolean;
/**
* Import the namespace from the registered import aliases.
*/
resolve(namespace: string): any;
/**
* Same as [[resolve]] but uses ES modules
*/
resolveAsync(namespace: string): Promise<any>;
}
+130
View File
@@ -0,0 +1,130 @@
"use strict";
/*
* @adonisjs/fold
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ImportAliases = void 0;
const path_1 = require("path");
const IocLookupException_1 = require("../Exceptions/IocLookupException");
/**
* Manages the import aliases
*/
class ImportAliases {
constructor(container) {
this.container = container;
/**
* Registered aliases
*/
this.list = {};
/**
* In-memory require cache to speed up lookup calls. Yes, "require"
* is slow. Check "perf/require.js"
*/
this.requireCache = new Map();
}
/**
* Returns the matching alias for the given namespace
*/
getPathAlias(namespace) {
return Object.keys(this.list).find((alias) => {
return namespace.startsWith(`${alias}/`);
});
}
/**
* Returns path for a given alias
*/
makeAliasPath(namespace, alias) {
return (0, path_1.normalize)(namespace.replace(alias, this.list[alias]));
}
/**
* Register an import alias
*/
register(absolutePath, alias) {
this.list[alias] = absolutePath;
return this;
}
/**
* Find if a namespace is part of the import aliases
*/
has(namespace) {
return !!this.getPathAlias(namespace);
}
/**
* Import the namespace from the registered import aliases.
*/
resolve(namespace) {
const alias = this.getPathAlias(namespace);
if (!alias) {
throw IocLookupException_1.IocLookupException.lookupFailed(namespace);
}
const cacheItem = this.requireCache.get(namespace);
if (cacheItem) {
return cacheItem.value;
}
/**
* Absolute path to the module
*/
const diskPath = this.makeAliasPath(namespace, alias);
/**
* Require the module
*/
const value = require(diskPath);
/**
* Cache the output
*/
this.requireCache.set(namespace, { diskPath, value });
/**
* Return the value
*/
return value;
}
/**
* Same as [[resolve]] but uses ES modules
*/
async resolveAsync(namespace) {
/**
* Piggy back on resolve when using cjs module system
*/
if (this.container.module === 'cjs') {
return this.resolve(namespace);
}
const alias = this.getPathAlias(namespace);
if (!alias) {
throw IocLookupException_1.IocLookupException.lookupFailed(namespace);
}
/**
* Import the module. The following code will only compile to esm
* when the output of this build is esm
*/
return Promise.resolve().then(() => __importStar(require(this.makeAliasPath(namespace, alias))));
}
}
exports.ImportAliases = ImportAliases;
+42
View File
@@ -0,0 +1,42 @@
import { IocContract } from '../Contracts';
/**
* Exposes the API to injecting dependencies to a class or a method
*/
export declare class Injector {
private container;
constructor(container: IocContract);
/**
* Resolves the injections to be injected to a method or the
* class constructor
*/
private resolve;
/**
* Resolves the injections to be injected to a method or the
* class constructor
*/
private resolveAsync;
/**
* Find if the value can be instantiated
*/
private isNewable;
/**
* Get injections for a given property from the target
*/
private getInjections;
/**
* Inject dependencies to the constructor of the class
*/
make(target: any, runtimeValues: any[]): any;
/**
* Inject dependencies asynchronously to the constructor of the class
*/
makeAsync(target: any, runtimeValues: any[]): Promise<any>;
/**
* Injects dependencies to the class method
*/
call(target: any, method: string, runtimeValues: any[]): any;
/**
* Injects dependencies asynchronously to the class method
*/
callAsync(target: any, method: string, runtimeValues: any[]): Promise<any>;
}
+127
View File
@@ -0,0 +1,127 @@
"use strict";
/*
* @adonisjs/fold
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Injector = void 0;
const helpers_1 = require("../helpers");
const helpers_2 = require("@poppinss/utils/build/helpers");
const InvalidInjectionException_1 = require("../Exceptions/InvalidInjectionException");
/**
* Exposes the API to injecting dependencies to a class or a method
*/
class Injector {
constructor(container) {
this.container = container;
}
/**
* Resolves the injections to be injected to a method or the
* class constructor
*/
resolve(targetName, injections, runtimeValues) {
/**
* If the runtime values length is greater or same as the length
* of injections, then we treat them as the source of truth
* and inject them as it is
*/
if (runtimeValues.length >= injections.length) {
return runtimeValues;
}
/**
* Loop over all the injections and give preference to runtime value
* for a given index, otherwise fallback to `container.make`.
*/
return injections.map((injection, index) => {
if (runtimeValues[index] !== undefined) {
return runtimeValues[index];
}
/**
* Disallow object and primitive constructors
*/
if ((0, helpers_1.isPrimtiveConstructor)(injection)) {
throw InvalidInjectionException_1.InvalidInjectionException.invoke(injections[index], targetName, index);
}
return this.container.make(injection);
});
}
/**
* Resolves the injections to be injected to a method or the
* class constructor
*/
async resolveAsync(targetName, injections, runtimeValues) {
/**
* If the runtime values length is greater or same as the length
* of injections, then we treat them as the source of truth
* and inject them as it is
*/
if (runtimeValues.length >= injections.length) {
return runtimeValues;
}
/**
* Loop over all the injections and give preference to runtime value
* for a given index, otherwise fallback to `container.makeAsync`.
*/
return Promise.all(injections.map((injection, index) => {
if (runtimeValues[index] !== undefined) {
return runtimeValues[index];
}
/**
* Disallow object and primitive constructors
*/
if ((0, helpers_1.isPrimtiveConstructor)(injection)) {
throw InvalidInjectionException_1.InvalidInjectionException.invoke(injections[index], targetName, index);
}
return this.container.makeAsync(injection);
}));
}
/**
* Find if the value can be instantiated
*/
isNewable(target) {
return (helpers_2.types.isFunction(target) || helpers_2.types.isClass(target)) && target.makePlain !== true;
}
/**
* Get injections for a given property from the target
*/
getInjections(target, prop) {
return target.hasOwnProperty('inject') ? target.inject[prop] || [] : [];
}
/**
* Inject dependencies to the constructor of the class
*/
make(target, runtimeValues) {
if (!this.isNewable(target)) {
return target;
}
return new target(...this.resolve(target.name, this.getInjections(target, 'instance'), runtimeValues));
}
/**
* Inject dependencies asynchronously to the constructor of the class
*/
async makeAsync(target, runtimeValues) {
if (!this.isNewable(target)) {
return target;
}
return new target(...(await this.resolveAsync(target.name, this.getInjections(target, 'instance'), runtimeValues)));
}
/**
* Injects dependencies to the class method
*/
call(target, method, runtimeValues) {
const constructor = target.constructor;
return target[method](...this.resolve(`${constructor.name}.${method}`, this.getInjections(constructor, method), runtimeValues));
}
/**
* Injects dependencies asynchronously to the class method
*/
async callAsync(target, method, runtimeValues) {
const constructor = target.constructor;
return target[method](...(await this.resolveAsync(`${constructor.name}.${method}`, this.getInjections(constructor, method), runtimeValues)));
}
}
exports.Injector = Injector;
+14
View File
@@ -0,0 +1,14 @@
import type { Fakes } from './Fakes';
/**
* Proxies the objects to fallback to fake, when it exists.
*/
export declare class IocProxyObject {
namespace: string;
value: any;
options: Fakes;
constructor(namespace: string, value: any, options: Fakes);
}
/**
* Proxies the class constructor to fallback to fake, when it exists.
*/
export declare function IocProxyClass(namespace: string, value: any, options: Fakes): any;
+105
View File
@@ -0,0 +1,105 @@
"use strict";
/*
* @adonisjs/fold
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.IocProxyClass = exports.IocProxyObject = void 0;
function getBindingValue(handler) {
return handler.options.has(handler.namespace)
? handler.options.resolve(handler.namespace, handler.value)
: handler.value;
}
/**
* Proxy handler to handle objects
*/
const objectHandler = (options) => {
return {
get(_, key, receiver) {
const descriptor = Object.getOwnPropertyDescriptor(options.value, key);
/**
* Handling the proxy invariants use case. Learn more
*
* https://262.ecma-international.org/8.0/#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver
*
* Check the following "get" trap
* https://github.com/kpruden/on-change/blob/5b80da1f5f7ac80c37d7bd19122188acb7ad0b19/index.js#L44-L66
*/
if (descriptor && !descriptor.configurable) {
if (descriptor.set && !descriptor.get) {
return undefined;
}
if (descriptor.writable === false) {
return Reflect.get(options.value, key, receiver);
}
}
return Reflect.get(getBindingValue(options), key, receiver);
},
apply(_, thisArgument, args) {
return Reflect.apply(getBindingValue(options), thisArgument, args);
},
defineProperty(_, propertyKey, attributes) {
return Reflect.defineProperty(getBindingValue(options), propertyKey, attributes);
},
deleteProperty(_, propertyKey) {
return Reflect.deleteProperty(getBindingValue(options), propertyKey);
},
getOwnPropertyDescriptor(_, propertyKey) {
return Reflect.getOwnPropertyDescriptor(getBindingValue(options), propertyKey);
},
getPrototypeOf(_) {
return Reflect.getPrototypeOf(getBindingValue(options));
},
has(_, propertyKey) {
return Reflect.has(getBindingValue(options), propertyKey);
},
isExtensible(_) {
return Reflect.isExtensible(getBindingValue(options));
},
ownKeys(_) {
return Reflect.ownKeys(getBindingValue(options));
},
preventExtensions() {
throw new Error('Cannot prevent extensions during a fake');
},
set(_, propertyKey, value, receiver) {
return Reflect.set(getBindingValue(options), propertyKey, value, receiver);
},
setPrototypeOf(_, proto) {
return Reflect.setPrototypeOf(getBindingValue(options), proto);
},
};
};
/**
* Proxy handler to handle classes and functions
*/
const classHandler = (options) => {
return Object.assign({}, objectHandler(options), {
construct(_, args, newTarget) {
return Reflect.construct(getBindingValue(options), args, newTarget);
},
});
};
/**
* Proxies the objects to fallback to fake, when it exists.
*/
class IocProxyObject {
constructor(namespace, value, options) {
this.namespace = namespace;
this.value = value;
this.options = options;
return new Proxy(value, objectHandler({ namespace, value, options }));
}
}
exports.IocProxyObject = IocProxyObject;
/**
* Proxies the class constructor to fallback to fake, when it exists.
*/
function IocProxyClass(namespace, value, options) {
return new Proxy(value, classHandler({ namespace, value, options }));
}
exports.IocProxyClass = IocProxyClass;
+192
View File
@@ -0,0 +1,192 @@
import { IocContract, BindCallback, FakeCallback, LookupNode } from '../Contracts';
import { IocResolver } from '../Resolver';
export declare class Ioc implements IocContract {
private fakes;
private bindings;
private injector;
private aliases;
/**
* The current state of using proxies
*/
private usingProxies;
/**
* A custom method to trap `ioc.use` and `ioc.make` statements
*/
private trapCallback;
/**
* Define the module type for resolving auto import aliases. Defaults
* to `cjs`
*/
module: 'cjs' | 'esm';
/**
* Registered aliases. The key is the alias and value is the
* absolute directory path
*/
get importAliases(): IocContract['importAliases'];
/**
* Detect if the module export value is an esm module
*/
private isEsm;
/**
* Wraps object and class to a proxy to enable the fakes
* API
*/
private wrapAsProxy;
/**
* Wrap value inside proxy by also inspecting for esm
* default exports
*/
private wrapEsmModuleAsProxy;
/**
* Makes an instance of a class by injecting dependencies
*/
private makeRaw;
/**
* Makes an instance of a class asynchronously by injecting dependencies
*/
private makeRawAsync;
/**
* Enable/disable proxies. Proxies are mainly required for fakes to
* work
*/
useProxies(enable?: boolean): this;
/**
* Register a binding with a callback. The callback return value will be
* used when binding is resolved
*/
bind(binding: string, callback: BindCallback<any, this>): this;
/**
* Same as the [[bind]] method, but registers a singleton only. Singleton's callback
* is invoked only for the first time and then the cached value is used
*/
singleton(binding: string, callback: BindCallback<any, this>): this;
/**
* Define an import alias
*/
alias(absolutePath: string, alias: string): this;
/**
* Register a fake for a namespace. Fakes works both for "bindings" and "import aliases".
* Fakes only work when proxies are enabled using "useProxies".
*/
fake(namespace: string, callback: FakeCallback<any, this>): this;
/**
* Clear selected or all the fakes. Calling the method with no arguments
* will clear all the fakes
*/
restore(namespace?: string): this;
/**
* Find if a fake has been registered for a given namespace
*/
hasFake(namespace: string): boolean;
/**
* Find if a binding exists for a given namespace
*/
hasBinding(namespace: string): boolean;
/**
* Find if a namespace is part of the auto import aliases. Returns false, when namespace
* is an alias path but has an explicit binding too
*/
isAliasPath(namespace: string): boolean;
/**
* Lookup a namespace. The output contains the complete namespace,
* along with its type. The type is an "alias" or a "binding".
*
* Null is returned when unable to lookup the namespace inside the container
*
* Note: This method just checks if a namespace is registered or binding
* or can be it resolved from auto import aliases or not. However,
* it doesn't check for the module existence on the disk.
*
* Optionally you can define a prefix namespace
* to be used to build the complete namespace. For example:
*
* - namespace: UsersController
* - prefixNamespace: App/Controllers/Http
* - Output: App/Controllers/Http/UsersController
*
* Prefix namespace is ignored for absolute namespaces. For example:
*
* - namespace: /App/UsersController
* - prefixNamespace: App/Controllers/Http
* - Output: App/UsersController
*/
lookup(namespace: string | LookupNode<string>, prefixNamespace?: string): null | any;
/**
* Same as [[lookup]]. But raises exception instead of returning null
*/
lookupOrFail(namespace: string | LookupNode<string>, prefixNamespace?: string): LookupNode<string>;
/**
* Resolve a binding by invoking the binding factory function. An exception
* is raised, if the binding namespace is unregistered.
*/
resolveBinding(binding: string): any;
/**
* Import namespace from the auto import aliases. This method assumes you are
* using native ES modules
*/
import(namespace: string): Promise<any>;
/**
* Same as the "import" method, but uses CJS for requiring the module from its
* path
*/
require(namespace: string): any;
/**
* The use method looks up a namespace inside both the bindings and the
* auto import aliases
*/
use(namespace: string | LookupNode<string>): any;
/**
* Same as the [[use]] method, but instead uses ES modules for resolving
* the auto import aliases
*/
useAsync(namespace: string | LookupNode<string>): Promise<any>;
/**
* Makes an instance of the class by first resolving it.
*/
make(namespace: LookupNode<string> | any, args?: any[]): any;
/**
* Same as the [[make]] method, but instead uses ES modules for resolving
* the auto import aliases
*/
makeAsync(namespace: LookupNode<string> | any, args?: any[]): Promise<any>;
/**
* Define a callback to be called when all of the container
* bindings are available.
*
* Note: This method is exclusive for bindings and doesn't resolve
* auto import aliases
*/
withBindings(namespaces: readonly any[], cb: (...args: any) => void): void;
/**
* @deprecated: Use "withBindings" instead
*/
with(namespaces: readonly any[], cb: (...args: any) => void): void;
/**
* Call method on an object and automatically resolve its depdencies
*/
call(target: any, method: any, args?: any[]): any;
/**
* Same as [[call]], but uses ES modules for resolving the auto
* import aliases
*/
callAsync(target: any, method: any, args?: any[]): Promise<any>;
/**
* Trap container lookup calls. It includes
*
* - Ioc.use
* - Ioc.useAsync
* - Ioc.make
* - Ioc.makeAsync
* - Ioc.require
* - Ioc.import
* - Ioc.resolveBinding
*/
trap(callback: (namespace: string) => any): this;
/**
* Returns the resolver instance to resolve Ioc container bindings with
* little ease. Since, the IocResolver uses an in-memory cache to
* improve the lookup speed, we suggest keeping a reference to
* the output of this method to leverage caching
*/
getResolver(fallbackMethod?: string, rcNamespaceKey?: string, fallbackNamespace?: string): IocResolver;
}
+468
View File
@@ -0,0 +1,468 @@
"use strict";
/*
* @adonisjs/fold
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Ioc = void 0;
const utils_1 = require("@poppinss/utils");
const helpers_1 = require("@poppinss/utils/build/helpers");
const Fakes_1 = require("./Fakes");
const Bindings_1 = require("./Bindings");
const Injector_1 = require("./Injector");
const Resolver_1 = require("../Resolver");
const ImportAliases_1 = require("./ImportAliases");
const helpers_2 = require("../helpers");
const IocProxy_1 = require("./IocProxy");
const IocLookupException_1 = require("../Exceptions/IocLookupException");
class Ioc {
constructor() {
this.fakes = new Fakes_1.Fakes(this);
this.bindings = new Bindings_1.Bindings(this);
this.injector = new Injector_1.Injector(this);
this.aliases = new ImportAliases_1.ImportAliases(this);
/**
* The current state of using proxies
*/
this.usingProxies = false;
/**
* Define the module type for resolving auto import aliases. Defaults
* to `cjs`
*/
this.module = 'cjs';
}
/**
* Registered aliases. The key is the alias and value is the
* absolute directory path
*/
get importAliases() {
return this.aliases.list;
}
/**
* Detect if the module export value is an esm module
*/
isEsm(value) {
return this.module === 'esm' ? true : (0, helpers_2.isEsm)(value);
}
/**
* Wraps object and class to a proxy to enable the fakes
* API
*/
wrapAsProxy(namespace, value) {
/**
* Wrap objects inside proxy
*/
if (helpers_1.types.isObject(value)) {
return new IocProxy_1.IocProxyObject(namespace, value, this.fakes);
}
/**
* Wrap class inside proxy
*/
if (helpers_1.types.isClass(value)) {
return (0, IocProxy_1.IocProxyClass)(namespace, value, this.fakes);
}
return value;
}
/**
* Wrap value inside proxy by also inspecting for esm
* default exports
*/
wrapEsmModuleAsProxy(namespace, value) {
/**
* Wrap the default export of esm modules inside in a proxy and
* not the entire module
*/
if (this.isEsm(value)) {
if (value.default) {
/**
* We should never mutate the actual ESM module object and always clone it first
* for abvious reasons that objects are shared by reference
*/
const clonedModule = Object.getOwnPropertyNames(value).reduce((result, key) => {
result[key] = value[key];
return result;
}, {});
clonedModule.default = this.wrapAsProxy(namespace, clonedModule.default);
return clonedModule;
}
/**
* We don't proxy named exports as we don't have a good story on what to proxy
*
* - Should we proxy the whole module?
* - Or should be expose api to allow proxying a selected set of modules
*/
return value;
}
return this.wrapAsProxy(namespace, value);
}
/**
* Makes an instance of a class by injecting dependencies
*/
makeRaw(value, args) {
return this.injector.make(value, args || []);
}
/**
* Makes an instance of a class asynchronously by injecting dependencies
*/
async makeRawAsync(value, args) {
return this.injector.makeAsync(value, args || []);
}
/**
* Enable/disable proxies. Proxies are mainly required for fakes to
* work
*/
useProxies(enable = true) {
this.usingProxies = !!enable;
return this;
}
/**
* Register a binding with a callback. The callback return value will be
* used when binding is resolved
*/
bind(binding, callback) {
(0, helpers_2.ensureIsFunction)(callback, '"ioc.bind" expect 2nd argument to be a function');
this.bindings.register(binding, callback, false);
return this;
}
/**
* Same as the [[bind]] method, but registers a singleton only. Singleton's callback
* is invoked only for the first time and then the cached value is used
*/
singleton(binding, callback) {
(0, helpers_2.ensureIsFunction)(callback, '"ioc.singleton" expect 2nd argument to be a function');
this.bindings.register(binding, callback, true);
return this;
}
/**
* Define an import alias
*/
alias(absolutePath, alias) {
this.aliases.register(absolutePath, alias);
return this;
}
/**
* Register a fake for a namespace. Fakes works both for "bindings" and "import aliases".
* Fakes only work when proxies are enabled using "useProxies".
*/
fake(namespace, callback) {
(0, helpers_2.ensureIsFunction)(callback, '"ioc.fake" expect 2nd argument to be a function');
this.fakes.register(namespace, callback);
return this;
}
/**
* Clear selected or all the fakes. Calling the method with no arguments
* will clear all the fakes
*/
restore(namespace) {
namespace ? this.fakes.delete(namespace) : this.fakes.clear();
return this;
}
/**
* Find if a fake has been registered for a given namespace
*/
hasFake(namespace) {
return this.fakes.has(namespace);
}
/**
* Find if a binding exists for a given namespace
*/
hasBinding(namespace) {
return this.bindings.has(namespace);
}
/**
* Find if a namespace is part of the auto import aliases. Returns false, when namespace
* is an alias path but has an explicit binding too
*/
isAliasPath(namespace) {
if (this.bindings.has(namespace)) {
return false;
}
return this.aliases.has(namespace);
}
/**
* Lookup a namespace. The output contains the complete namespace,
* along with its type. The type is an "alias" or a "binding".
*
* Null is returned when unable to lookup the namespace inside the container
*
* Note: This method just checks if a namespace is registered or binding
* or can be it resolved from auto import aliases or not. However,
* it doesn't check for the module existence on the disk.
*
* Optionally you can define a prefix namespace
* to be used to build the complete namespace. For example:
*
* - namespace: UsersController
* - prefixNamespace: App/Controllers/Http
* - Output: App/Controllers/Http/UsersController
*
* Prefix namespace is ignored for absolute namespaces. For example:
*
* - namespace: /App/UsersController
* - prefixNamespace: App/Controllers/Http
* - Output: App/UsersController
*/
lookup(namespace, prefixNamespace) {
if (typeof namespace !== 'string' && namespace['namespace'] && namespace['type']) {
return namespace;
}
/**
* Ensure namespace is defined as a string only
*/
if (typeof namespace !== 'string') {
throw IocLookupException_1.IocLookupException.invalidNamespace();
}
/**
* Build complete namespace
*/
if (namespace.startsWith('/')) {
namespace = namespace.substr(1);
}
else if (prefixNamespace) {
namespace = `${prefixNamespace.replace(/\/$/, '')}/${namespace}`;
}
/**
* Namespace is a binding
*/
if (this.hasBinding(namespace)) {
return {
type: 'binding',
namespace: namespace,
};
}
/**
* Namespace is an alias
*/
if (this.isAliasPath(namespace)) {
return {
type: 'alias',
namespace: namespace,
};
}
return null;
}
/**
* Same as [[lookup]]. But raises exception instead of returning null
*/
lookupOrFail(namespace, prefixNamespace) {
const lookupNode = this.lookup(namespace, prefixNamespace);
if (!lookupNode) {
throw IocLookupException_1.IocLookupException.lookupFailed(namespace);
}
return lookupNode;
}
/**
* Resolve a binding by invoking the binding factory function. An exception
* is raised, if the binding namespace is unregistered.
*/
resolveBinding(binding) {
if (this.trapCallback) {
return this.trapCallback(binding);
}
const value = this.bindings.resolve(binding);
if (this.usingProxies) {
return this.wrapAsProxy(binding, value);
}
return value;
}
/**
* Import namespace from the auto import aliases. This method assumes you are
* using native ES modules
*/
async import(namespace) {
if (this.trapCallback) {
return this.trapCallback(namespace);
}
const value = await this.aliases.resolveAsync(namespace);
if (this.usingProxies) {
return this.wrapEsmModuleAsProxy(namespace, value);
}
return value;
}
/**
* Same as the "import" method, but uses CJS for requiring the module from its
* path
*/
require(namespace) {
if (this.trapCallback) {
return this.trapCallback(namespace);
}
const value = this.aliases.resolve(namespace);
if (this.usingProxies) {
return this.wrapEsmModuleAsProxy(namespace, value);
}
return value;
}
/**
* The use method looks up a namespace inside both the bindings and the
* auto import aliases
*/
use(namespace) {
if (this.trapCallback) {
return this.trapCallback(typeof namespace === 'string' ? namespace : namespace['namespace']);
}
const lookupNode = this.lookupOrFail(namespace);
if (lookupNode.type === 'alias') {
return this.require(lookupNode.namespace);
}
return this.resolveBinding(lookupNode.namespace);
}
/**
* Same as the [[use]] method, but instead uses ES modules for resolving
* the auto import aliases
*/
async useAsync(namespace) {
if (this.trapCallback) {
return this.trapCallback(typeof namespace === 'string' ? namespace : namespace['namespace']);
}
const lookupNode = this.lookupOrFail(namespace);
if (lookupNode.type === 'alias') {
return this.import(lookupNode.namespace);
}
return this.resolveBinding(lookupNode.namespace);
}
/**
* Makes an instance of the class by first resolving it.
*/
make(namespace, args) {
const isContainerNamespace = typeof namespace === 'string' || (namespace['namespace'] && namespace['type']);
/**
* Value is not a container namespace or a lookup
* node
*/
if (!isContainerNamespace) {
return this.makeRaw(namespace, args);
}
/**
* Invoke trap callback (if registered)
*/
if (this.trapCallback) {
return this.trapCallback(typeof namespace === 'string' ? namespace : namespace['namespace']);
}
const lookupNode = this.lookupOrFail(namespace);
/**
* We do not touch bindings at all. The factory function
* return value is used as it is
*/
if (lookupNode.type === 'binding') {
return this.resolveBinding(lookupNode.namespace);
}
const value = this.require(lookupNode.namespace);
/**
* We attempt to make an instance of only the export
* default of a ES module
*/
if (this.isEsm(value) && value.default) {
return this.makeRaw(value.default, args || []);
}
return this.makeRaw(value, args);
}
/**
* Same as the [[make]] method, but instead uses ES modules for resolving
* the auto import aliases
*/
async makeAsync(namespace, args) {
const isContainerNamespace = typeof namespace === 'string' || (namespace['namespace'] && namespace['type']);
/**
* Value is not a container namespace or a lookup
* node
*/
if (!isContainerNamespace) {
return this.makeRawAsync(namespace, args);
}
/**
* Invoke trap callback (if registered)
*/
if (this.trapCallback) {
return this.trapCallback(typeof namespace === 'string' ? namespace : namespace['namespace']);
}
const lookupNode = this.lookupOrFail(namespace);
/**
* We do not touch bindings at all. The factory function
* return value is used as it is
*/
if (lookupNode.type === 'binding') {
return this.resolveBinding(lookupNode.namespace);
}
const value = await this.import(lookupNode.namespace);
/**
* We attempt to make an instance of only the export
* default of a ES module
*/
if (this.isEsm(value) && value.default) {
return this.makeRawAsync(value.default, args || []);
}
return this.makeRawAsync(value, args);
}
/**
* Define a callback to be called when all of the container
* bindings are available.
*
* Note: This method is exclusive for bindings and doesn't resolve
* auto import aliases
*/
withBindings(namespaces, cb) {
if (namespaces.every((namespace) => this.hasBinding(namespace))) {
/**
* The callback accepts a tuple, whereas map returns an array. So we
* need to cast the value to any by hand
*/
cb(...namespaces.map((namespace) => this.resolveBinding(namespace)));
}
}
/**
* @deprecated: Use "withBindings" instead
*/
with(namespaces, cb) {
process.emitWarning('DeprecationWarning', 'container.with() is deprecated. Use container.withBindings() instead');
return this.withBindings(namespaces, cb);
}
/**
* Call method on an object and automatically resolve its depdencies
*/
call(target, method, args) {
if (typeof target[method] !== 'function') {
throw new utils_1.Exception(`Missing method "${method}" on "${target.constructor.name}"`);
}
return this.injector.call(target, method, args || []);
}
/**
* Same as [[call]], but uses ES modules for resolving the auto
* import aliases
*/
async callAsync(target, method, args) {
if (typeof target[method] !== 'function') {
throw new utils_1.Exception(`Missing method "${method}" on "${target.constructor.name}"`);
}
return this.injector.callAsync(target, method, args || []);
}
/**
* Trap container lookup calls. It includes
*
* - Ioc.use
* - Ioc.useAsync
* - Ioc.make
* - Ioc.makeAsync
* - Ioc.require
* - Ioc.import
* - Ioc.resolveBinding
*/
trap(callback) {
this.trapCallback = callback;
return this;
}
/**
* Returns the resolver instance to resolve Ioc container bindings with
* little ease. Since, the IocResolver uses an in-memory cache to
* improve the lookup speed, we suggest keeping a reference to
* the output of this method to leverage caching
*/
getResolver(fallbackMethod, rcNamespaceKey, fallbackNamespace) {
return new Resolver_1.IocResolver(this, fallbackMethod, rcNamespaceKey, fallbackNamespace);
}
}
exports.Ioc = Ioc;
+62
View File
@@ -0,0 +1,62 @@
import { Constructor } from '../Contracts';
/**
* Registrar is used to register and boot the providers
*/
export declare class Registrar {
private providerConstructorParams;
private basePath?;
/**
* The first level of provider paths provided to the registrar
*/
private providersPaths;
/**
* An array of loaded providers. Their can be more providers than the
* `_providersPaths` array, since each provider can provide it's
* own sub providers
*/
private providers;
/**
* Method to instantiate provider instances. One can also defined
* a custom instantiater function
*/
private providersInstantiater;
/**
* Whether or not the providers can be collected
*/
private collected;
constructor(providerConstructorParams: any[], basePath?: string | undefined);
/**
* Load the provider by requiring the file from the disk
* and instantiate it. If ioc container is using ES6
* imports, then default exports are handled
* automatically.
*/
private loadProvider;
/**
* Loop's over an array of provider paths and pushes them to the
* `providers` collection. This collection is later used to
* register and boot providers
*/
private collect;
/**
* Register an array of provider paths
*/
useProviders(providersPaths: string[], callback?: <T extends Constructor<any>>(provider: T) => InstanceType<T>): this;
/**
* Register all the providers by instantiating them and
* calling the `register` method.
*
* The provider instance will be returned, which can be used
* to boot them as well.
*/
register(): Promise<any[]>;
/**
* Boot all the providers by calling the `boot` method.
* Boot methods are called in series.
*/
boot(): Promise<void>;
/**
* Register an boot providers together.
*/
registerAndBoot(): Promise<any[]>;
}
+129
View File
@@ -0,0 +1,129 @@
"use strict";
/*
* @adonisjs/fold
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Registrar = void 0;
const path_1 = require("path");
const utils_1 = require("@poppinss/utils");
const helpers_1 = require("@poppinss/utils/build/helpers");
/**
* Registrar is used to register and boot the providers
*/
class Registrar {
constructor(providerConstructorParams, basePath) {
this.providerConstructorParams = providerConstructorParams;
this.basePath = basePath;
/**
* The first level of provider paths provided to the registrar
*/
this.providersPaths = [];
/**
* An array of loaded providers. Their can be more providers than the
* `_providersPaths` array, since each provider can provide it's
* own sub providers
*/
this.providers = [];
/**
* Method to instantiate provider instances. One can also defined
* a custom instantiater function
*/
this.providersInstantiater = (provider) => new provider(...this.providerConstructorParams);
/**
* Whether or not the providers can be collected
*/
this.collected = false;
}
/**
* Load the provider by requiring the file from the disk
* and instantiate it. If ioc container is using ES6
* imports, then default exports are handled
* automatically.
*/
async loadProvider(providerPath, basePath) {
providerPath = this.basePath
? (0, helpers_1.resolveFrom)(basePath || this.basePath, providerPath)
: providerPath;
const provider = (0, utils_1.esmRequire)(providerPath);
if (typeof provider !== 'function') {
throw new utils_1.Exception(`"${providerPath}" provider must use export default statement`);
}
return {
provider: this.providersInstantiater(provider),
resolvedPath: (0, path_1.dirname)(providerPath),
};
}
/**
* Loop's over an array of provider paths and pushes them to the
* `providers` collection. This collection is later used to
* register and boot providers
*/
async collect(providerPaths, basePath) {
for (let providerPath of providerPaths) {
const { provider, resolvedPath } = await this.loadProvider(providerPath, basePath);
this.providers.push(provider);
if (provider.provides) {
await this.collect(provider.provides, resolvedPath);
}
}
}
/**
* Register an array of provider paths
*/
useProviders(providersPaths, callback) {
this.providersPaths = providersPaths;
if (typeof callback === 'function') {
this.providersInstantiater = callback;
}
return this;
}
/**
* Register all the providers by instantiating them and
* calling the `register` method.
*
* The provider instance will be returned, which can be used
* to boot them as well.
*/
async register() {
if (this.collected) {
return this.providers;
}
this.collected = true;
await this.collect(this.providersPaths);
/**
* Register collected providers
*/
this.providers.forEach((provider) => {
if (typeof provider.register === 'function') {
provider.register();
}
});
return this.providers;
}
/**
* Boot all the providers by calling the `boot` method.
* Boot methods are called in series.
*/
async boot() {
const providers = await this.register();
for (let provider of providers) {
if (typeof provider.boot === 'function') {
await provider.boot();
}
}
}
/**
* Register an boot providers together.
*/
async registerAndBoot() {
const providers = await this.register();
await this.boot();
return providers;
}
}
exports.Registrar = Registrar;
+32
View File
@@ -0,0 +1,32 @@
import { IocContract, IocResolverLookupNode, IocResolverContract } from '../Contracts';
/**
* Exposes the API to resolve and call bindings from the IoC container. The resolver
* internally caches the IoC container lookup nodes to boost performance.
*/
export declare class IocResolver implements IocResolverContract<any> {
private container;
private fallbackMethod?;
private rcNamespaceKey?;
private fallbackNamespace?;
private lookupCache;
/**
* The namespace that will be used as a prefix when resolving
* bindings
*/
private prefixNamespace;
constructor(container: IocContract, fallbackMethod?: string | undefined, rcNamespaceKey?: string | undefined, fallbackNamespace?: string | undefined);
/**
* Returns the prefix namespace by giving preference to the
* `.adonisrc.json` file
*/
private getPrefixNamespace;
/**
* Resolves the namespace and returns it's lookup node
*/
resolve(namespace: string, prefixNamespace?: string | undefined): IocResolverLookupNode<string>;
/**
* Calls the namespace.method expression with any arguments that needs to
* be passed. Also supports type-hinting dependencies.
*/
call(namespace: string | IocResolverLookupNode<string>, prefixNamespace?: string, args?: any[] | ((instance: any) => any[])): Promise<any>;
}
+95
View File
@@ -0,0 +1,95 @@
"use strict";
/*
* @adonisjs/fold
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.IocResolver = void 0;
/**
* Exposes the API to resolve and call bindings from the IoC container. The resolver
* internally caches the IoC container lookup nodes to boost performance.
*/
class IocResolver {
constructor(container, fallbackMethod, rcNamespaceKey, fallbackNamespace) {
this.container = container;
this.fallbackMethod = fallbackMethod;
this.rcNamespaceKey = rcNamespaceKey;
this.fallbackNamespace = fallbackNamespace;
this.lookupCache = {};
/**
* The namespace that will be used as a prefix when resolving
* bindings
*/
this.prefixNamespace = this.getPrefixNamespace();
}
/**
* Returns the prefix namespace by giving preference to the
* `.adonisrc.json` file
*/
getPrefixNamespace() {
/**
* Use fallback namespace, when lookup inside rcFile is not required
*/
if (!this.rcNamespaceKey) {
return this.fallbackNamespace;
}
/**
* If container doesn't have `Application` binding, then there is no
* way for us to read rcFile namespaces and hence we use the fallback
* namespace
*/
if (!this.container.hasBinding('Adonis/Core/Application')) {
return this.fallbackNamespace;
}
/**
* Attempt to resolve the rcNamespace key from the rcFile
* For example: The rc file has following namespaces
* {
* "controllers": "App/Controllers/Http"
* }
* We will use the value next to the `controllers` key
*/
const application = this.container.use('Adonis/Core/Application');
return application.namespacesMap.get(this.rcNamespaceKey) || this.fallbackNamespace;
}
/**
* Resolves the namespace and returns it's lookup node
*/
resolve(namespace, prefixNamespace = this.prefixNamespace) {
const cacheKey = prefixNamespace ? `${prefixNamespace}/${namespace}` : namespace;
/**
* Return from cache, when the node exists
*/
const cacheNode = this.lookupCache[cacheKey];
if (cacheNode) {
return cacheNode;
}
let method = this.fallbackMethod || 'handle';
/**
* Split the namespace to lookup the method on it. If method isn't
* defined, we will use the conventional `handle` method.
*/
const tokens = namespace.split('.');
if (tokens.length > 1) {
method = tokens.pop();
}
const lookupNode = this.container.lookupOrFail(tokens.join('.'), prefixNamespace);
this.lookupCache[cacheKey] = { ...lookupNode, method };
return this.lookupCache[cacheKey];
}
/**
* Calls the namespace.method expression with any arguments that needs to
* be passed. Also supports type-hinting dependencies.
*/
async call(namespace, prefixNamespace, args) {
const lookupNode = typeof namespace === 'string' ? this.resolve(namespace, prefixNamespace) : namespace;
const instance = await this.container.makeAsync(lookupNode.namespace);
args = typeof args === 'function' ? args(instance) : args;
return this.container.callAsync(instance, lookupNode.method, args);
}
}
exports.IocResolver = IocResolver;
+7
View File
@@ -0,0 +1,7 @@
/**
* Injects bindings to the class constructor
*/
export declare function inject(value?: any): {
(target: any, propertyKey: string): void;
(target: any): void;
};
+64
View File
@@ -0,0 +1,64 @@
"use strict";
/*
* @adonisjs/fold
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.inject = void 0;
/**
* Injects bindings to the class constructor
*/
function inject(value) {
// eslint-disable-next-line no-redeclare
function decorator(target, propertyKey) {
/**
* Consturctor injections
*/
if (!propertyKey) {
if (!target.hasOwnProperty('inject')) {
Object.defineProperty(target, 'inject', {
value: {},
});
}
target.inject.instance = target.inject.instance || [];
const constructorParams = Reflect.getMetadata('design:paramtypes', target);
if (constructorParams) {
constructorParams.forEach((param, index) => {
if (value && value[index]) {
target.inject.instance.push(value[index]);
}
else {
target.inject.instance.push(param);
}
});
}
return;
}
/**
* Parameter injections
*/
if (!target.constructor.hasOwnProperty('inject')) {
Object.defineProperty(target.constructor, 'inject', {
value: {},
});
}
target.constructor.inject[propertyKey] = target.constructor.inject[propertyKey] || [];
const methodParams = Reflect.getMetadata('design:paramtypes', target, propertyKey);
if (methodParams) {
methodParams.forEach((param, index) => {
if (value && value[index]) {
target.constructor.inject[propertyKey].push(value[index]);
}
else {
target.constructor.inject[propertyKey].push(param);
}
});
}
}
return decorator;
}
exports.inject = inject;
+14
View File
@@ -0,0 +1,14 @@
/**
* Returns a boolean telling if value is an esm module
* with `export default`.
*/
export declare function isEsm(value: any): boolean;
/**
* Returns a boolean telling if value is a primitive or object constructor.
*/
export declare function isPrimtiveConstructor(value: any): boolean;
/**
* Raises error with a message when callback is not
* a function.
*/
export declare function ensureIsFunction(callback: Function, message: string): void;
+37
View File
@@ -0,0 +1,37 @@
"use strict";
/*
* @adonisjs/fold
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ensureIsFunction = exports.isPrimtiveConstructor = exports.isEsm = void 0;
const utils_1 = require("@poppinss/utils");
/**
* Returns a boolean telling if value is an esm module
* with `export default`.
*/
function isEsm(value) {
return value && value.__esModule;
}
exports.isEsm = isEsm;
/**
* Returns a boolean telling if value is a primitive or object constructor.
*/
function isPrimtiveConstructor(value) {
return [String, Function, Object, Date, Number, Boolean].indexOf(value) > -1;
}
exports.isPrimtiveConstructor = isPrimtiveConstructor;
/**
* Raises error with a message when callback is not
* a function.
*/
function ensureIsFunction(callback, message) {
if (typeof callback !== 'function') {
throw new utils_1.Exception(message, 500, 'E_RUNTIME_EXCEPTION');
}
}
exports.ensureIsFunction = ensureIsFunction;
+9
View File
@@ -0,0 +1,9 @@
# The MIT License
Copyright 2021 Harminder Virk, contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1 @@
export * from './src/Helpers';
@@ -0,0 +1,25 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./src/Helpers"), exports);
@@ -0,0 +1,10 @@
export * as lodash from './src/lodash';
export { slash } from './src/slash';
export { flatten } from './src/flatten';
export { Exception } from './src/Exception';
export { safeParse } from './src/safeParse';
export { esmRequire } from './src/esmRequire';
export { esmResolver } from './src/esmResolver';
export { safeStringify } from './src/safeStringify';
export { defineStaticProperty } from './src/defineStaticProperty';
export { ManagerConfigValidator } from './src/ManagerConfigValidator';
@@ -0,0 +1,53 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ManagerConfigValidator = exports.defineStaticProperty = exports.safeStringify = exports.esmResolver = exports.esmRequire = exports.safeParse = exports.Exception = exports.flatten = exports.slash = exports.lodash = void 0;
exports.lodash = __importStar(require("./src/lodash"));
var slash_1 = require("./src/slash");
Object.defineProperty(exports, "slash", { enumerable: true, get: function () { return slash_1.slash; } });
var flatten_1 = require("./src/flatten");
Object.defineProperty(exports, "flatten", { enumerable: true, get: function () { return flatten_1.flatten; } });
var Exception_1 = require("./src/Exception");
Object.defineProperty(exports, "Exception", { enumerable: true, get: function () { return Exception_1.Exception; } });
var safeParse_1 = require("./src/safeParse");
Object.defineProperty(exports, "safeParse", { enumerable: true, get: function () { return safeParse_1.safeParse; } });
var esmRequire_1 = require("./src/esmRequire");
Object.defineProperty(exports, "esmRequire", { enumerable: true, get: function () { return esmRequire_1.esmRequire; } });
var esmResolver_1 = require("./src/esmResolver");
Object.defineProperty(exports, "esmResolver", { enumerable: true, get: function () { return esmResolver_1.esmResolver; } });
var safeStringify_1 = require("./src/safeStringify");
Object.defineProperty(exports, "safeStringify", { enumerable: true, get: function () { return safeStringify_1.safeStringify; } });
var defineStaticProperty_1 = require("./src/defineStaticProperty");
Object.defineProperty(exports, "defineStaticProperty", { enumerable: true, get: function () { return defineStaticProperty_1.defineStaticProperty; } });
var ManagerConfigValidator_1 = require("./src/ManagerConfigValidator");
Object.defineProperty(exports, "ManagerConfigValidator", { enumerable: true, get: function () { return ManagerConfigValidator_1.ManagerConfigValidator; } });
@@ -0,0 +1,17 @@
/**
* Extended Error object with the option to set error `status` and `code`.
* At AdonisJs, we prefer exceptions with proper error codes to handle
* them without relying on message pattern matching.
*
* ```js
* new Exception('message', 500, 'E_RUNTIME_EXCEPTION')
* ```
*/
export declare class Exception extends Error {
name: string;
message: string;
help?: string;
code?: string;
status: number;
constructor(message: string, status?: number, code?: string);
}
@@ -0,0 +1,68 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Exception = void 0;
/**
* Extended Error object with the option to set error `status` and `code`.
* At AdonisJs, we prefer exceptions with proper error codes to handle
* them without relying on message pattern matching.
*
* ```js
* new Exception('message', 500, 'E_RUNTIME_EXCEPTION')
* ```
*/
class Exception extends Error {
constructor(message, status = 500, code) {
super(message);
/**
* Set error message
*/
Object.defineProperty(this, 'message', {
configurable: true,
enumerable: false,
value: code ? `${code}: ${message}` : message,
writable: true,
});
/**
* Set error name as a public property
*/
Object.defineProperty(this, 'name', {
configurable: true,
enumerable: false,
value: this.constructor.name,
writable: true,
});
/**
* Set status as a public property
*/
Object.defineProperty(this, 'status', {
configurable: true,
enumerable: false,
value: status,
writable: true,
});
/**
* Set error code as a public property (only when defined)
*/
if (code) {
Object.defineProperty(this, 'code', {
configurable: true,
enumerable: false,
value: code,
writable: true,
});
}
/**
* Update the stack trace
*/
Error.captureStackTrace(this, this.constructor);
}
}
exports.Exception = Exception;
@@ -0,0 +1,28 @@
/**
* Message builder exposes an API to JSON.stringify values by encoding purpose
* and expiryDate inside them. It returns a readable string, which is the
* output of `JSON.stringify`.
*
* Why use this over `JSON.stringify`?
*
* - It protects you from JSON poisioning
* - Allows encoding expiry dates to the message. It means, the message builer is
* helpful, when you want to encode a message and pass it around, but also control
* the TTL of the message
* - Allows encoding purpose. Again, useful for distribution.
*/
export declare class MessageBuilder {
private getExpiryDate;
/**
* Returns a boolean telling, if message has been expired or not
*/
private isExpired;
/**
* Builds a message by encoding expiry and purpose inside it
*/
build(message: any, expiresIn?: string | number, purpose?: string): string;
/**
* Verifies the message for expiry and purpose
*/
verify<T extends any>(message: any, purpose?: string): null | T;
}
@@ -0,0 +1,97 @@
"use strict";
/*
* @adonisjs/encryption
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MessageBuilder = void 0;
const ms_1 = __importDefault(require("ms"));
const safeParse_1 = require("../safeParse");
const safeStringify_1 = require("../safeStringify");
/**
* Message builder exposes an API to JSON.stringify values by encoding purpose
* and expiryDate inside them. It returns a readable string, which is the
* output of `JSON.stringify`.
*
* Why use this over `JSON.stringify`?
*
* - It protects you from JSON poisioning
* - Allows encoding expiry dates to the message. It means, the message builer is
* helpful, when you want to encode a message and pass it around, but also control
* the TTL of the message
* - Allows encoding purpose. Again, useful for distribution.
*/
class MessageBuilder {
getExpiryDate(expiresIn) {
if (!expiresIn) {
return undefined;
}
const expiryMs = typeof expiresIn === 'string' ? (0, ms_1.default)(expiresIn) : expiresIn;
if (expiryMs === undefined || expiryMs === null) {
throw new Error(`Invalid value for expiresIn "${expiresIn}"`);
}
return new Date(Date.now() + expiryMs);
}
/**
* Returns a boolean telling, if message has been expired or not
*/
isExpired(message) {
if (!message.expiryDate) {
return false;
}
try {
const expiryDate = new Date(message.expiryDate);
return isNaN(expiryDate.getTime()) || expiryDate < new Date();
}
catch (error) {
return true;
}
}
/**
* Builds a message by encoding expiry and purpose inside it
*/
build(message, expiresIn, purpose) {
const expiryDate = this.getExpiryDate(expiresIn);
return (0, safeStringify_1.safeStringify)({ message, purpose, expiryDate });
}
/**
* Verifies the message for expiry and purpose
*/
verify(message, purpose) {
const parsed = (0, safeParse_1.safeParse)(message);
/**
* Safe parse returns the value as it is when unable to JSON.parse it. However, in
* our case if value was correctly parsed, it should never match the input
*/
if (parsed === message) {
return null;
}
/**
* Missing ".message" property
*/
if (!parsed.message) {
return null;
}
/**
* Ensure purposes are same.
*/
if (parsed.purpose !== purpose) {
return null;
}
/**
* Ensure isn't expired
*/
if (this.isExpired(parsed)) {
return null;
}
return parsed.message;
}
}
exports.MessageBuilder = MessageBuilder;
@@ -0,0 +1,46 @@
/**
* A simple class to build an object incrementally. It is helpful when you
* want to add properties to the object conditionally.
*
* Instead of writing
* ```
* const obj = {
* ...(user.id ? { id: user.id } : {}),
* ...(user.firstName && user.lastName ? { name: `${user.firstName} ${user.lastName}` } : {}),
* }
* ```
*
* You can write
*
* const obj = new ObjectBuilder()
* .add('id', user.id)
* .add(
* 'fullName',
* user.firstName && user.lastName ? `${user.firstName} ${user.lastName}` : undefined
* )
* .value
*/
export declare class ObjectBuilder {
private ignoreNull?;
value: any;
constructor(ignoreNull?: boolean | undefined);
/**
* Add value to the property.
*
* - Undefined values are ignored
* - Null values are ignored, when `ignoreNull` is set to true
*/
add(key: string, value: any): this;
/**
* Remove value from the object
*/
remove(key: string): this;
/**
* Find if a value exists
*/
has(key: string): boolean;
/**
* Get the existing value
*/
get<T extends any>(key: string): T;
}
@@ -0,0 +1,75 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ObjectBuilder = void 0;
/**
* A simple class to build an object incrementally. It is helpful when you
* want to add properties to the object conditionally.
*
* Instead of writing
* ```
* const obj = {
* ...(user.id ? { id: user.id } : {}),
* ...(user.firstName && user.lastName ? { name: `${user.firstName} ${user.lastName}` } : {}),
* }
* ```
*
* You can write
*
* const obj = new ObjectBuilder()
* .add('id', user.id)
* .add(
* 'fullName',
* user.firstName && user.lastName ? `${user.firstName} ${user.lastName}` : undefined
* )
* .value
*/
class ObjectBuilder {
constructor(ignoreNull) {
this.ignoreNull = ignoreNull;
this.value = {};
}
/**
* Add value to the property.
*
* - Undefined values are ignored
* - Null values are ignored, when `ignoreNull` is set to true
*/
add(key, value) {
if (value === undefined) {
return this;
}
if (this.ignoreNull === true && value === null) {
return this;
}
this.value[key] = value;
return this;
}
/**
* Remove value from the object
*/
remove(key) {
delete this.value[key];
return this;
}
/**
* Find if a value exists
*/
has(key) {
return this.get(key) !== undefined;
}
/**
* Get the existing value
*/
get(key) {
return this.value[key];
}
}
exports.ObjectBuilder = ObjectBuilder;
@@ -0,0 +1,33 @@
/// <reference types="node" />
/**
* Helper class to base64 encode/decode values with option
* for url encoding and decoding
*/
declare class Base64 {
/**
* Base64 encode Buffer or string
*/
encode(arrayBuffer: ArrayBuffer | SharedArrayBuffer): string;
encode(data: string, encoding?: BufferEncoding): string;
/**
* Base64 decode a previously encoded string or Buffer.
*/
decode(encode: string, encoding: BufferEncoding, strict: true): string | null;
decode(encode: string, encoding: undefined, strict: true): string | null;
decode(encode: string, encoding?: BufferEncoding, strict?: false): string;
decode(encode: Buffer, encoding?: BufferEncoding): string;
/**
* Base64 encode Buffer or string to be URL safe. (RFC 4648)
*/
urlEncode(arrayBuffer: ArrayBuffer | SharedArrayBuffer): string;
urlEncode(data: string, encoding?: BufferEncoding): string;
/**
* Base64 URL decode a previously encoded string or Buffer. (RFC 4648)
*/
urlDecode(encode: string, encoding: BufferEncoding, strict: true): string | null;
urlDecode(encode: string, encoding: undefined, strict: true): string | null;
urlDecode(encode: string, encoding?: BufferEncoding, strict?: false): string;
urlDecode(encode: Buffer, encoding?: BufferEncoding): string;
}
export declare const base64: Base64;
export {};
@@ -0,0 +1,48 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.base64 = void 0;
/**
* Helper class to base64 encode/decode values with option
* for url encoding and decoding
*/
class Base64 {
encode(data, encoding) {
if (typeof data === 'string') {
return Buffer.from(data, encoding).toString('base64');
}
return Buffer.from(data).toString('base64');
}
decode(encoded, encoding = 'utf-8', strict = false) {
if (Buffer.isBuffer(encoded)) {
return encoded.toString(encoding);
}
const decoded = Buffer.from(encoded, 'base64').toString(encoding);
if (strict && this.encode(decoded, encoding) !== encoded) {
return null;
}
return decoded;
}
urlEncode(data, encoding) {
const encoded = typeof data === 'string' ? this.encode(data, encoding) : this.encode(data);
return encoded.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');
}
urlDecode(encoded, encoding = 'utf-8', strict = false) {
if (Buffer.isBuffer(encoded)) {
return encoded.toString(encoding);
}
const decoded = Buffer.from(encoded, 'base64').toString(encoding);
if (strict && this.urlEncode(decoded, encoding) !== encoded) {
return null;
}
return decoded;
}
}
exports.base64 = new Base64();
@@ -0,0 +1,21 @@
declare type Constructor = new (...args: any[]) => any;
/**
* Converting unions to intersection
*/
declare type UnionToIntersection<T> = (T extends any ? (x: T) => any : never) extends (x: infer R) => any ? R : never;
/**
* Normalizes constructor to work with mixins. There is an open bug for mixins
* to allow constructors other than `...args: any[]`
*
* https://github.com/microsoft/TypeScript/issues/37142
*/
export declare type NormalizeConstructor<T extends Constructor> = {
new (...args: any[]): InstanceType<T>;
} & Omit<T, 'constructor'>;
/**
* Compose a class by applying mixins to it.
* The code is inspired by https://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/, its
* just that I have added the support for static types too.
*/
export declare const compose: <SuperClass extends Constructor, M extends ((superclass: SuperClass) => Constructor)[]>(superclass: SuperClass, ...mixins: M) => SuperClass & UnionToIntersection<ReturnType<M[number]>>;
export {};
@@ -0,0 +1,20 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.compose = void 0;
/**
* Compose a class by applying mixins to it.
* The code is inspired by https://justinfagnani.com/2015/12/21/real-mixins-with-javascript-classes/, its
* just that I have added the support for static types too.
*/
const compose = (superclass, ...mixins) => {
return mixins.reduce((c, mixin) => mixin(c), superclass);
};
exports.compose = compose;
@@ -0,0 +1,4 @@
/**
* Returns an array of file paths from the given location.
*/
export declare function fsReadAll(location: string, callback?: (file: string) => boolean): string[];
@@ -0,0 +1,23 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.fsReadAll = void 0;
const fs_readdir_recursive_1 = __importDefault(require("fs-readdir-recursive"));
const isScriptFile_1 = require("../isScriptFile");
/**
* Returns an array of file paths from the given location.
*/
function fsReadAll(location, callback) {
return (0, fs_readdir_recursive_1.default)(location).filter(typeof callback === 'function' ? callback : isScriptFile_1.isScriptFile);
}
exports.fsReadAll = fsReadAll;
@@ -0,0 +1,14 @@
export { default as cuid } from 'cuid';
export * as file from '@poppinss/file-generator';
export { base64 } from './base64';
export { compose, NormalizeConstructor } from './compose';
export { fsReadAll } from './fsReadAll';
export { interpolate } from './interpolate';
export { MessageBuilder } from './MessageBuilder';
export { ObjectBuilder } from './ObjectBuilder';
export { requireAll } from './requireAll';
export { resolveDir } from './resolveDir';
export { resolveFrom } from './resolveFrom';
export { safeEqual } from './safeEqual';
export * as string from './string';
export * as types from './types';
@@ -0,0 +1,62 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.types = exports.string = exports.safeEqual = exports.resolveFrom = exports.resolveDir = exports.requireAll = exports.ObjectBuilder = exports.MessageBuilder = exports.interpolate = exports.fsReadAll = exports.compose = exports.base64 = exports.file = exports.cuid = void 0;
var cuid_1 = require("cuid");
Object.defineProperty(exports, "cuid", { enumerable: true, get: function () { return __importDefault(cuid_1).default; } });
exports.file = __importStar(require("@poppinss/file-generator"));
var base64_1 = require("./base64");
Object.defineProperty(exports, "base64", { enumerable: true, get: function () { return base64_1.base64; } });
var compose_1 = require("./compose");
Object.defineProperty(exports, "compose", { enumerable: true, get: function () { return compose_1.compose; } });
var fsReadAll_1 = require("./fsReadAll");
Object.defineProperty(exports, "fsReadAll", { enumerable: true, get: function () { return fsReadAll_1.fsReadAll; } });
var interpolate_1 = require("./interpolate");
Object.defineProperty(exports, "interpolate", { enumerable: true, get: function () { return interpolate_1.interpolate; } });
var MessageBuilder_1 = require("./MessageBuilder");
Object.defineProperty(exports, "MessageBuilder", { enumerable: true, get: function () { return MessageBuilder_1.MessageBuilder; } });
var ObjectBuilder_1 = require("./ObjectBuilder");
Object.defineProperty(exports, "ObjectBuilder", { enumerable: true, get: function () { return ObjectBuilder_1.ObjectBuilder; } });
var requireAll_1 = require("./requireAll");
Object.defineProperty(exports, "requireAll", { enumerable: true, get: function () { return requireAll_1.requireAll; } });
var resolveDir_1 = require("./resolveDir");
Object.defineProperty(exports, "resolveDir", { enumerable: true, get: function () { return resolveDir_1.resolveDir; } });
var resolveFrom_1 = require("./resolveFrom");
Object.defineProperty(exports, "resolveFrom", { enumerable: true, get: function () { return resolveFrom_1.resolveFrom; } });
var safeEqual_1 = require("./safeEqual");
Object.defineProperty(exports, "safeEqual", { enumerable: true, get: function () { return safeEqual_1.safeEqual; } });
exports.string = __importStar(require("./string"));
exports.types = __importStar(require("./types"));
@@ -0,0 +1,7 @@
/**
* A simple function interpolate values inside curly braces.
*
* @example
* `interpolate('hello {{ username }}', { username: 'virk' })`
*/
export declare function interpolate(input: string, data: any): string;
@@ -0,0 +1,46 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.interpolate = void 0;
function uncurryThis(fn) {
return function (...args) {
return Function.call.apply(fn, args);
};
}
const hasOwnProperty = uncurryThis(Object.prototype.hasOwnProperty);
/**
* Parses prop
*/
function parseProp(data, key) {
const tokens = key.split('.');
while (tokens.length) {
if (data === null || typeof data !== 'object') {
return;
}
const token = tokens.shift();
data = hasOwnProperty(data, token) ? data[token] : undefined;
}
return data;
}
/**
* A simple function interpolate values inside curly braces.
*
* @example
* `interpolate('hello {{ username }}', { username: 'virk' })`
*/
function interpolate(input, data) {
return input.replace(/(\\)?{{(.*?)}}/g, (_, escapeChar, key) => {
if (escapeChar) {
return `{{${key}}}`;
}
return parseProp(data, key.trim());
});
}
exports.interpolate = interpolate;
@@ -0,0 +1,8 @@
/**
* Require all files from a given directory. The method automatically looks
* for files ending with `.ts`, `.js` and `.json`. Also files ending with
* `.d.ts` are ignored.
*/
export declare function requireAll(location: string, recursive?: boolean, optional?: boolean, filter?: (file: string) => boolean | string): {
[key: string]: any;
} | undefined;
@@ -0,0 +1,65 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.requireAll = void 0;
const path_1 = require("path");
const require_all_1 = __importDefault(require("require-all"));
const esmResolver_1 = require("../esmResolver");
const isScriptFile_1 = require("../isScriptFile");
/**
* Function to filter and keep script files only
*/
function fileFilter(file) {
return (0, isScriptFile_1.isScriptFile)(file);
}
/**
* Require all files from a given directory. The method automatically looks
* for files ending with `.ts`, `.js` and `.json`. Also files ending with
* `.d.ts` are ignored.
*/
function requireAll(location, recursive = true, optional = false, filter = fileFilter) {
try {
return (0, require_all_1.default)({
dirname: location,
recursive,
filter: (file) => {
let result = true;
/**
* Invoke user defined function
*/
if (typeof filter === 'function') {
result = filter(file);
}
/**
* Use the default file name when file is meant to
* be kept
*/
if (result === true) {
const ext = (0, path_1.extname)(file);
return file.replace(new RegExp(`${ext}$`), '');
}
return result;
},
resolve: esmResolver_1.esmResolver,
});
}
catch (error) {
if (error.code === 'ENOENT' && optional) {
return;
}
else {
throw error;
}
}
}
exports.requireAll = requireAll;
@@ -0,0 +1,5 @@
/**
* Resolves path to a given directory. The method is similar to `require.resolve`,
* but also works for directories with no `index.js` file.
*/
export declare function resolveDir(fromLocation: string, dirPath: string): string;
@@ -0,0 +1,46 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveDir = void 0;
const resolve_from_1 = __importDefault(require("resolve-from"));
const path_1 = require("path");
/**
* Resolves path to a given directory. The method is similar to `require.resolve`,
* but also works for directories with no `index.js` file.
*/
function resolveDir(fromLocation, dirPath) {
if ((0, path_1.isAbsolute)(dirPath)) {
return dirPath;
}
/**
* Relative paths are made by joining the baseDir
*/
if (dirPath.startsWith('./') || dirPath.startsWith(`.${path_1.sep}`)) {
return (0, path_1.join)(fromLocation, dirPath);
}
/**
* From here on, we are dealing with a package inside node module.
*/
let packageName = '';
const tokens = dirPath.replace(/\\/g, '/').split('/');
if (tokens.length && tokens[0].startsWith('@')) {
packageName = `${tokens.shift()}/`;
}
packageName += tokens.shift();
const resolved = resolve_from_1.default.silent(fromLocation, (0, path_1.join)(packageName, 'package.json'));
if (!resolved) {
throw new Error(`Cannot locate directory "${dirPath}"`);
}
return (0, path_1.join)((0, path_1.dirname)(resolved), tokens.join('/'));
}
exports.resolveDir = resolveDir;
@@ -0,0 +1,5 @@
/**
* Resolves module from a given directory. It is similar to `require.resolve`
* but carefull handles the absolute paths.
*/
export declare function resolveFrom(fromLocation: string, modulePath: string): string;
@@ -0,0 +1,27 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveFrom = void 0;
const path_1 = require("path");
const resolve_from_1 = __importDefault(require("resolve-from"));
/**
* Resolves module from a given directory. It is similar to `require.resolve`
* but carefull handles the absolute paths.
*/
function resolveFrom(fromLocation, modulePath) {
if ((0, path_1.isAbsolute)(modulePath)) {
return modulePath;
}
return (0, resolve_from_1.default)(fromLocation, modulePath);
}
exports.resolveFrom = resolveFrom;
@@ -0,0 +1,10 @@
declare type BufferSafeValue = ArrayBuffer | SharedArrayBuffer | number[] | string | {
valueOf(): string | object;
} | {
[Symbol.toPrimitive](hint: 'string'): string;
};
/**
* Generates a random string for a given size
*/
export declare function safeEqual<T extends BufferSafeValue>(value: T, comparisonValue: T): boolean;
export {};
@@ -0,0 +1,42 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.safeEqual = void 0;
const buffer_1 = require("buffer");
const crypto_1 = require("crypto");
/**
* Generates a random string for a given size
*/
function safeEqual(value, comparisonValue) {
if (typeof value === 'string' && typeof comparisonValue === 'string') {
/**
* The length of the main value to ensure that we compare equal strings
* against each other to get a constant time.
*/
const expectedLength = buffer_1.Buffer.byteLength(value);
/**
* Value A
*/
const valueBuffer = buffer_1.Buffer.alloc(expectedLength, 0, 'utf-8');
valueBuffer.write(value);
/**
* Value B
*/
const comparisonValueBuffer = buffer_1.Buffer.alloc(expectedLength, 0, 'utf-8');
comparisonValueBuffer.write(comparisonValue);
/**
* Ensure values are same and also have same length
*/
return ((0, crypto_1.timingSafeEqual)(valueBuffer, comparisonValueBuffer) &&
expectedLength === buffer_1.Buffer.byteLength(comparisonValue));
}
return (0, crypto_1.timingSafeEqual)(buffer_1.Buffer.from(value), buffer_1.Buffer.from(comparisonValue));
}
exports.safeEqual = safeEqual;
@@ -0,0 +1,124 @@
import { EncodeOptions } from 'he';
import { BytesOptions } from 'bytes';
export { default as toSlug } from 'slugify';
/**
* The method is a copy/paste from the "title-case" package. They have
* a dependency on "tslib", which I don't want.
*/
export declare function titleCase(input: string): string;
/**
* Define an irregular rule
*/
export declare function defineIrregularRule(singleValue: string, pluralValue: string): void;
/**
* Define uncountable rule
*/
export declare function defineUncountableRule(word: string): void;
/**
* Convert string to camelcase
*/
export declare function camelCase(value: string): string;
/**
* Convert string to snakecase
*/
export declare function snakeCase(value: string): string;
/**
* Convert string to dashcase
*/
export declare function dashCase(value: string, options?: {
capitalize?: boolean;
}): string;
/**
* Convert string to pascal case
*/
export declare function pascalCase(value: string): string;
/**
* Convert string to capital case
*/
export declare function capitalCase(value: string): string;
/**
* Convert string to sentence case
*/
export declare function sentenceCase(value: string): string;
/**
* Convert string to dot case
*/
export declare function dotCase(value: string): string;
/**
* Remove all sort of casing from the string
*/
export declare function noCase(value: string): string;
/**
* Pluralize a word
*/
export declare function pluralize(word: string): string;
/**
* Singularize a word
*/
export declare function singularize(word: string): string;
/**
* Truncate a sentence till a give limit of characters
*/
export declare function truncate(sentence: string, charactersLimit: number, options?: {
completeWords?: boolean;
suffix?: string;
}): string;
/**
* Same as truncate, but strips out the HTML
*/
export declare function excerpt(sentence: string, charactersLimit: number, options?: {
completeWords?: boolean;
suffix?: string;
}): string;
/**
* Condenses multiple whitespaces from a string
*/
export declare function condenseWhitespace(value: string): string;
/**
* Escape HTML entities
*/
export declare function escapeHTML(value: string, options?: {
encodeSymbols?: boolean;
}): string;
/**
* Encode symbols that arent printable ASCII symbols
*/
export declare function encodeSymbols(value: string, options?: EncodeOptions): string;
/**
* Convert array of values to a sentence
*/
export declare function toSentence(values: any[], options?: {
separator?: string;
pairSeparator?: string;
lastSeparator?: string;
}): string;
/**
* Convert a number to a human readable string
*/
export declare function prettyBytes(value: number, options?: BytesOptions): string;
/**
* Convert milliseconds to a human readable string
*/
export declare function prettyMs(value: number, options?: {
long: boolean;
}): string;
/**
* Find if a string is empty. Including any number of whitespaces
*/
export declare function isEmpty(value: string): boolean;
/**
* Ordinalize a give number or string
*/
export declare function ordinalize(value: string | number): string;
/**
* Converts unit expression to bytes
*/
export declare function toBytes(value: string | number): number;
/**
* Converts time expression to milliseconds
*/
export declare function toMs(value: string | number): number;
/**
* Generates a random string for a given size
*/
export declare function generateRandom(size: number): string;
@@ -0,0 +1,328 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateRandom = exports.toMs = exports.toBytes = exports.ordinalize = exports.isEmpty = exports.prettyMs = exports.prettyBytes = exports.toSentence = exports.encodeSymbols = exports.escapeHTML = exports.condenseWhitespace = exports.excerpt = exports.truncate = exports.singularize = exports.pluralize = exports.noCase = exports.dotCase = exports.sentenceCase = exports.capitalCase = exports.pascalCase = exports.dashCase = exports.snakeCase = exports.camelCase = exports.defineUncountableRule = exports.defineIrregularRule = exports.titleCase = exports.toSlug = void 0;
const ms_1 = __importDefault(require("ms"));
const truncatise_1 = __importDefault(require("truncatise"));
const crypto_1 = require("crypto");
const he_1 = __importDefault(require("he"));
const changeCase = __importStar(require("change-case"));
const bytes_1 = __importDefault(require("bytes"));
const pluralize_1 = require("pluralize");
var slugify_1 = require("slugify");
Object.defineProperty(exports, "toSlug", { enumerable: true, get: function () { return __importDefault(slugify_1).default; } });
const SMALL_WORDS = /\b(?:an?d?|a[st]|because|but|by|en|for|i[fn]|neither|nor|o[fnr]|only|over|per|so|some|tha[tn]|the|to|up|upon|vs?\.?|versus|via|when|with|without|yet)\b/i;
const TOKENS = /[^\s:–—-]+|./g;
const WHITESPACE = /\s/;
const IS_MANUAL_CASE = /.(?=[A-Z]|\..)/;
const ALPHANUMERIC_PATTERN = /[A-Za-z0-9\u00C0-\u00FF]/;
/**
* The method is a copy/paste from the "title-case" package. They have
* a dependency on "tslib", which I don't want.
*/
function titleCase(input) {
let output = '';
let result;
while ((result = TOKENS.exec(input)) !== null) {
const { 0: token, index } = result;
if (!IS_MANUAL_CASE.test(token) &&
(!SMALL_WORDS.test(token) || index === 0 || index + token.length === input.length) &&
(input.charAt(index + token.length) !== ':' ||
WHITESPACE.test(input.charAt(index + token.length + 1)))) {
output += token.replace(ALPHANUMERIC_PATTERN, (char) => char.toUpperCase());
continue;
}
output += token;
}
return output;
}
exports.titleCase = titleCase;
/**
* Normalizes base64 string by removing special chars and padding
*/
function normalizeBase64(value) {
return value.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');
}
/**
* Define an irregular rule
*/
function defineIrregularRule(singleValue, pluralValue) {
(0, pluralize_1.addIrregularRule)(singleValue, pluralValue);
}
exports.defineIrregularRule = defineIrregularRule;
/**
* Define uncountable rule
*/
function defineUncountableRule(word) {
(0, pluralize_1.addUncountableRule)(word);
}
exports.defineUncountableRule = defineUncountableRule;
/**
* Convert string to camelcase
*/
function camelCase(value) {
return changeCase.camelCase(value);
}
exports.camelCase = camelCase;
/**
* Convert string to snakecase
*/
function snakeCase(value) {
return changeCase.snakeCase(value);
}
exports.snakeCase = snakeCase;
/**
* Convert string to dashcase
*/
function dashCase(value, options) {
if (options && options.capitalize) {
return changeCase.headerCase(value);
}
return changeCase.paramCase(value);
}
exports.dashCase = dashCase;
/**
* Convert string to pascal case
*/
function pascalCase(value) {
return changeCase.pascalCase(value);
}
exports.pascalCase = pascalCase;
/**
* Convert string to capital case
*/
function capitalCase(value) {
return changeCase.capitalCase(value);
}
exports.capitalCase = capitalCase;
/**
* Convert string to sentence case
*/
function sentenceCase(value) {
return changeCase.sentenceCase(value);
}
exports.sentenceCase = sentenceCase;
/**
* Convert string to dot case
*/
function dotCase(value) {
return changeCase.dotCase(value);
}
exports.dotCase = dotCase;
/**
* Remove all sort of casing from the string
*/
function noCase(value) {
return changeCase.noCase(value);
}
exports.noCase = noCase;
/**
* Pluralize a word
*/
function pluralize(word) {
return (0, pluralize_1.plural)(word);
}
exports.pluralize = pluralize;
/**
* Singularize a word
*/
function singularize(word) {
return (0, pluralize_1.singular)(word);
}
exports.singularize = singularize;
/**
* Truncate a sentence till a give limit of characters
*/
function truncate(sentence, charactersLimit, options) {
return (0, truncatise_1.default)(sentence, {
TruncateLength: charactersLimit,
/**
* Do not complete words when "completeWords" is not explicitly set
* to true
*/
Strict: options && options.completeWords === true ? false : true,
StripHTML: false,
TruncateBy: 'characters',
Suffix: options && options.suffix,
});
}
exports.truncate = truncate;
/**
* Same as truncate, but strips out the HTML
*/
function excerpt(sentence, charactersLimit, options) {
return (0, truncatise_1.default)(sentence, {
TruncateLength: charactersLimit,
/**
* Do not complete words when "completeWords" is not explicitly set
* to true
*/
Strict: options && options.completeWords === true ? false : true,
StripHTML: true,
TruncateBy: 'characters',
Suffix: options && options.suffix,
});
}
exports.excerpt = excerpt;
/**
* Condenses multiple whitespaces from a string
*/
function condenseWhitespace(value) {
return value.trim().replace(/\s{2,}/g, ' ');
}
exports.condenseWhitespace = condenseWhitespace;
/**
* Escape HTML entities
*/
function escapeHTML(value, options) {
value = he_1.default.escape(value);
if (options && options.encodeSymbols) {
value = encodeSymbols(value, { allowUnsafeSymbols: true });
}
return value;
}
exports.escapeHTML = escapeHTML;
/**
* Encode symbols that arent printable ASCII symbols
*/
function encodeSymbols(value, options) {
return he_1.default.encode(value, options);
}
exports.encodeSymbols = encodeSymbols;
/**
* Convert array of values to a sentence
*/
function toSentence(values, options) {
/**
* Empty array
*/
if (values.length === 0) {
return '';
}
/**
* Just one item
*/
if (values.length === 1) {
return values[0];
}
/**
* Giving some love to two items, so that one can use oxford comma's
*/
if (values.length === 2) {
return `${values[0]}${options?.pairSeparator || ' and '}${values[1]}`;
}
const normalized = Object.assign({ separator: ', ', lastSeparator: ', and ' }, options);
/**
* Make sentence
*/
return `${values.slice(0, -1).join(normalized.separator)}${normalized.lastSeparator}${values[values.length - 1]}`;
}
exports.toSentence = toSentence;
/**
* Convert a number to a human readable string
*/
function prettyBytes(value, options) {
return bytes_1.default.format(value, options);
}
exports.prettyBytes = prettyBytes;
/**
* Convert milliseconds to a human readable string
*/
function prettyMs(value, options) {
return (0, ms_1.default)(value, options);
}
exports.prettyMs = prettyMs;
/**
* Find if a string is empty. Including any number of whitespaces
*/
function isEmpty(value) {
return value.trim().length === 0;
}
exports.isEmpty = isEmpty;
/**
* Ordinalize a give number or string
*/
function ordinalize(value) {
const transformedValue = Math.abs(typeof value === 'string' ? parseInt(value) : value);
if (!Number.isFinite(transformedValue) || Number.isNaN(transformedValue)) {
throw new Error('Cannot ordinalize NAN or infinite numbers');
}
const percent = transformedValue % 100;
if (percent >= 10 && percent <= 20) {
return `${value}th`;
}
const decimal = transformedValue % 10;
switch (decimal) {
case 1:
return `${value}st`;
case 2:
return `${value}nd`;
case 3:
return `${value}rd`;
default:
return `${value}th`;
}
}
exports.ordinalize = ordinalize;
/**
* Converts unit expression to bytes
*/
function toBytes(value) {
if (typeof value === 'number') {
return value;
}
return bytes_1.default.parse(value);
}
exports.toBytes = toBytes;
/**
* Converts time expression to milliseconds
*/
function toMs(value) {
if (typeof value === 'number') {
return value;
}
return (0, ms_1.default)(value);
}
exports.toMs = toMs;
/**
* Generates a random string for a given size
*/
function generateRandom(size) {
const bits = (size + 1) * 6;
const buffer = (0, crypto_1.randomBytes)(Math.ceil(bits / 8));
return normalizeBase64(buffer.toString('base64')).slice(0, size);
}
exports.generateRandom = generateRandom;
@@ -0,0 +1,86 @@
/// <reference types="node" />
/**
* Lookup the type for a given value
*/
export declare function lookup(value: any): 'undefined' | 'null' | 'boolean' | 'buffer' | 'number' | 'string' | 'arguments' | 'object' | 'date' | 'array' | 'regexp' | 'error' | 'function' | 'class' | 'generatorfunction' | 'symbol' | 'map' | 'weakmap' | 'set' | 'weakset' | 'int8array' | 'uint8array' | 'uint8clampedarray' | 'int16array' | 'uint16array' | 'int32array' | 'uint32array' | 'float32array' | 'float64array';
/**
* Find if a given value is undefined
*/
export declare function isUndefined(value: any): value is undefined;
/**
* Find if a given value is null
*/
export declare function isNull(value: any): value is null;
/**
* Find if a given value is a boolean
*/
export declare function isBoolean(value: any): value is boolean;
/**
* Find if a given value is a buffer
*/
export declare function isBuffer(value: any): value is Buffer;
/**
* Find if a given value is a number
*/
export declare function isNumber(value: any): value is number;
/**
* Find if a given value is a string
*/
export declare function isString(value: any): value is string;
/**
* Find if a given value is function arguments
*/
export declare function isArguments(value: any): boolean;
/**
* Find if a given value is a plain object
*/
export declare function isObject(value: any): boolean;
/**
* Find if a given value is a date instance
*/
export declare function isDate(value: any): value is Date;
/**
* Find if a given value is an array
*/
export declare function isArray(value: any): value is any[];
/**
* Find if a given value is an regularExpression
*/
export declare function isRegexp(value: any): value is RegExp;
/**
* Find if a given value is an instance of Error class
*/
export declare function isError(value: any): boolean;
/**
* Find if a given value is a Function
*/
export declare function isFunction(value: any): value is Function;
/**
* Find if a given value is a class. Uses regular expression, since there
* is no way to natively distinguish a class and a function in Javascript
*/
export declare function isClass(value: any): boolean;
/**
* Find if a value is an integer or not
*/
export declare function isInteger(value: number): value is number;
/**
* Find if a value is float value or not. The values with more than
* zero remainder returns true
*/
export declare function isFloat(value: number): value is number;
/**
* Find if the value has given decimal place or not.
*
* Since there is no direct way in Javascript to check for decimal place. We make
* use of regex to find it out.
*
* Numeric values are converted to string by calling `value.toString()` before
* testing it against the regex.
*
* If this method returns `true`, then you can safely parse the string with `parseFloat`
* method.
*/
export declare function isDecimal(value: string | number, options?: {
decimalPlaces?: string;
}): boolean;
@@ -0,0 +1,161 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.isDecimal = exports.isFloat = exports.isInteger = exports.isClass = exports.isFunction = exports.isError = exports.isRegexp = exports.isArray = exports.isDate = exports.isObject = exports.isArguments = exports.isString = exports.isNumber = exports.isBuffer = exports.isBoolean = exports.isNull = exports.isUndefined = exports.lookup = void 0;
const kind_of_1 = __importDefault(require("kind-of"));
const toString = Function.prototype.toString;
/**
* Lookup the type for a given value
*/
function lookup(value) {
const kind = (0, kind_of_1.default)(value);
if (kind === 'function' && /^class\s/.test(toString.call(value))) {
return 'class';
}
return kind;
}
exports.lookup = lookup;
/**
* Find if a given value is undefined
*/
function isUndefined(value) {
return lookup(value) === 'undefined';
}
exports.isUndefined = isUndefined;
/**
* Find if a given value is null
*/
function isNull(value) {
return lookup(value) === 'null';
}
exports.isNull = isNull;
/**
* Find if a given value is a boolean
*/
function isBoolean(value) {
return lookup(value) === 'boolean';
}
exports.isBoolean = isBoolean;
/**
* Find if a given value is a buffer
*/
function isBuffer(value) {
return lookup(value) === 'buffer';
}
exports.isBuffer = isBuffer;
/**
* Find if a given value is a number
*/
function isNumber(value) {
return lookup(value) === 'number';
}
exports.isNumber = isNumber;
/**
* Find if a given value is a string
*/
function isString(value) {
return lookup(value) === 'string';
}
exports.isString = isString;
/**
* Find if a given value is function arguments
*/
function isArguments(value) {
return lookup(value) === 'arguments';
}
exports.isArguments = isArguments;
/**
* Find if a given value is a plain object
*/
function isObject(value) {
return lookup(value) === 'object';
}
exports.isObject = isObject;
/**
* Find if a given value is a date instance
*/
function isDate(value) {
return lookup(value) === 'date';
}
exports.isDate = isDate;
/**
* Find if a given value is an array
*/
function isArray(value) {
return lookup(value) === 'array';
}
exports.isArray = isArray;
/**
* Find if a given value is an regularExpression
*/
function isRegexp(value) {
return lookup(value) === 'regexp';
}
exports.isRegexp = isRegexp;
/**
* Find if a given value is an instance of Error class
*/
function isError(value) {
return lookup(value) === 'error';
}
exports.isError = isError;
/**
* Find if a given value is a Function
*/
function isFunction(value) {
return lookup(value) === 'function';
}
exports.isFunction = isFunction;
/**
* Find if a given value is a class. Uses regular expression, since there
* is no way to natively distinguish a class and a function in Javascript
*/
function isClass(value) {
return lookup(value) === 'class';
}
exports.isClass = isClass;
/**
* Find if a value is an integer or not
*/
function isInteger(value) {
return Number.isInteger(value);
}
exports.isInteger = isInteger;
/**
* Find if a value is float value or not. The values with more than
* zero remainder returns true
*/
function isFloat(value) {
return value !== (value | 0);
}
exports.isFloat = isFloat;
/**
* Find if the value has given decimal place or not.
*
* Since there is no direct way in Javascript to check for decimal place. We make
* use of regex to find it out.
*
* Numeric values are converted to string by calling `value.toString()` before
* testing it against the regex.
*
* If this method returns `true`, then you can safely parse the string with `parseFloat`
* method.
*/
function isDecimal(value, options) {
if (typeof value === 'number') {
value = value.toString();
}
const decimalPlaces = (options && options.decimalPlaces) || '1,';
return new RegExp(`^[-+]?([0-9]+)?(\\.[0-9]{${decimalPlaces}})$`).test(value);
}
exports.isDecimal = isDecimal;
@@ -0,0 +1,20 @@
/**
* A simple class to raise consistent exceptions for invalid config
* for driver based implementations.
*/
export declare class ManagerConfigValidator {
private config;
private serviceName;
private configLocation;
constructor(config: any, serviceName: string, configLocation: string);
/**
* Validates that the default key name is defined inside the config
* for a given module/service
*/
validateDefault(keyName: string): void;
/**
* Validates that the list to ensure that is is defined and the default
* key name is also part of the list.
*/
validateList(listName: string, keyName: string): void;
}
@@ -0,0 +1,55 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ManagerConfigValidator = void 0;
const Exception_1 = require("./Exception");
/**
* A simple class to raise consistent exceptions for invalid config
* for driver based implementations.
*/
class ManagerConfigValidator {
constructor(config, serviceName, configLocation) {
this.config = config;
this.serviceName = serviceName;
this.configLocation = configLocation;
}
/**
* Validates that the default key name is defined inside the config
* for a given module/service
*/
validateDefault(keyName) {
if (!this.config[keyName]) {
throw new Exception_1.Exception([
`Invalid "${this.serviceName}" config. Missing value for "${keyName}".`,
`Make sure to set it inside the "${this.configLocation}" file`,
].join(' '));
}
}
/**
* Validates that the list to ensure that is is defined and the default
* key name is also part of the list.
*/
validateList(listName, keyName) {
if (!this.config[listName]) {
throw new Exception_1.Exception([
`Invalid "${this.serviceName}" config. Missing value for "${listName}".`,
`Make sure to set it inside the "${this.configLocation}" file`,
].join(' '));
}
const defaultValue = this.config[keyName];
if (!this.config[listName][defaultValue]) {
throw new Exception_1.Exception([
`Invalid "${this.serviceName}" config. "${defaultValue}" is not defined inside "${listName}".`,
`Make sure to set it inside the "${this.configLocation}" file`,
].join(' '));
}
}
}
exports.ManagerConfigValidator = ManagerConfigValidator;
@@ -0,0 +1,11 @@
declare type Constructor = new (...args: any[]) => any;
declare type AbstractConstructor = abstract new (...args: any[]) => any;
/**
* Define static properties on a class with inheritance in play.
*/
export declare function defineStaticProperty<T extends Constructor | AbstractConstructor, Prop extends keyof T>(self: T, BaseClass: Constructor | AbstractConstructor, { propertyName, defaultValue, strategy, }: {
propertyName: Prop;
defaultValue: T[Prop];
strategy: 'inherit' | 'define' | ((value: T[Prop]) => T[Prop]);
}): void;
export {};
@@ -0,0 +1,57 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.defineStaticProperty = void 0;
const cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
/**
* Define static properties on a class with inheritance in play.
*/
function defineStaticProperty(self, BaseClass, { propertyName, defaultValue, strategy, }) {
if (!self.hasOwnProperty(propertyName)) {
/**
* Class is inhering the base class directly and hence we don't have to
* copy any properties
*/
if (Object.getPrototypeOf(self.prototype) === BaseClass.prototype || strategy === 'define') {
Object.defineProperty(self, propertyName, {
value: defaultValue,
configurable: true,
enumerable: true,
writable: true,
});
return;
}
/**
* Class is inherting another sub class. We must copy the values to the self
* class, otherwise mutating them inside the self class will be reflected
* on the base class.
*/
const value = self[propertyName];
if (value === undefined) {
Object.defineProperty(self, propertyName, {
value: defaultValue,
configurable: true,
enumerable: true,
writable: true,
});
return;
}
Object.defineProperty(self, propertyName, {
value: typeof strategy === 'function' ? strategy(value) : (0, cloneDeep_1.default)(value),
configurable: true,
enumerable: true,
writable: true,
});
}
}
exports.defineStaticProperty = defineStaticProperty;
@@ -0,0 +1,5 @@
/**
* Handles ESM `default` exports and common js vanilla exports. The `default`
* exports are only entertained, when `esmEnabled` is set to true.
*/
export declare function esmRequire(filePath: string): any;
@@ -0,0 +1,20 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.esmRequire = void 0;
const esmResolver_1 = require("./esmResolver");
/**
* Handles ESM `default` exports and common js vanilla exports. The `default`
* exports are only entertained, when `esmEnabled` is set to true.
*/
function esmRequire(filePath) {
return (0, esmResolver_1.esmResolver)(require(filePath));
}
exports.esmRequire = esmRequire;
@@ -0,0 +1 @@
export declare function esmResolver(output: any): any;
@@ -0,0 +1,15 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.esmResolver = void 0;
function esmResolver(output) {
return output && output.__esModule && output.default ? output.default : output;
}
exports.esmResolver = esmResolver;
@@ -0,0 +1,2 @@
export declare type ReplacerFn = (this: any, key: string, value: any) => any;
export declare function stringify(obj: any, replacer?: ReplacerFn, spacer?: string | number): any;
@@ -0,0 +1,101 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.stringify = void 0;
/**
* Exact copy of https://github.com/davidmarkclements/fast-safe-stringify/blob/master/index.js
* with a few changes that were introduced in https://github.com/davidmarkclements/fast-safe-stringify/pull/52 PR.
*/
const arr = [];
const replacerStack = [];
// Regular stringify
function stringify(obj, replacer, spacer) {
decirc(obj, '', [], undefined);
let res;
if (replacerStack.length === 0) {
res = JSON.stringify(obj, replacer, spacer);
}
else {
res = JSON.stringify(obj, replaceGetterValues(replacer), spacer);
}
while (arr.length !== 0) {
var part = arr.pop();
if (part.length === 4) {
Object.defineProperty(part[0], part[1], part[3]);
}
else {
part[0][part[1]] = part[2];
}
}
return res;
}
exports.stringify = stringify;
function decirc(val, k, stack, parent) {
let i;
if (typeof val === 'object' && val !== null) {
for (i = 0; i < stack.length; i++) {
if (stack[i] === val) {
let propertyDescriptor = Object.getOwnPropertyDescriptor(parent, k);
if (propertyDescriptor.get !== undefined) {
if (propertyDescriptor.configurable) {
Object.defineProperty(parent, k, { value: '[Circular]' });
arr.push([parent, k, val, propertyDescriptor]);
}
else {
replacerStack.push([val, k]);
}
}
else {
parent[k] = '[Circular]';
arr.push([parent, k, val]);
}
return;
}
}
stack.push(val);
// Optimize for Arrays. Big arrays could kill the performance otherwise!
if (Array.isArray(val)) {
for (i = 0; i < val.length; i++) {
decirc(val[i], i, stack, val);
}
}
else {
var keys = Object.keys(val);
for (i = 0; i < keys.length; i++) {
var key = keys[i];
decirc(val[key], key, stack, val);
}
}
stack.pop();
}
}
// wraps replacer function to handle values we couldn't replace
// and mark them as [Circular]
function replaceGetterValues(replacer) {
replacer =
replacer !== undefined
? replacer
: function (_, v) {
return v;
};
return function (key, val) {
if (replacerStack.length > 0) {
for (var i = 0; i < replacerStack.length; i++) {
var part = replacerStack[i];
if (part[1] === key && part[0] === val) {
val = '[Circular]';
replacerStack.splice(i, 1);
break;
}
}
}
return replacer.call(this, key, val);
};
}
@@ -0,0 +1 @@
export { flattie as flatten } from 'flattie';
@@ -0,0 +1,13 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.flatten = void 0;
var flattie_1 = require("flattie");
Object.defineProperty(exports, "flatten", { enumerable: true, get: function () { return flattie_1.flattie; } });
@@ -0,0 +1,5 @@
/**
* Returns `true` when file ends with `.js`, `.json` or
* `.ts` but not `.d.ts`.
*/
export declare function isScriptFile(file: string): boolean;
@@ -0,0 +1,28 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.isScriptFile = void 0;
const path_1 = require("path");
const JS_MODULES = ['.js', '.json'];
/**
* Returns `true` when file ends with `.js`, `.json` or
* `.ts` but not `.d.ts`.
*/
function isScriptFile(file) {
const ext = (0, path_1.extname)(file);
if (JS_MODULES.includes(ext)) {
return true;
}
if (ext === '.ts' && !file.endsWith('.d.ts')) {
return true;
}
return false;
}
exports.isScriptFile = isScriptFile;
@@ -0,0 +1,13 @@
/// <reference path="../../types/lodash.types.d.ts" />
export { default as pick } from 'lodash/pick';
export { default as omit } from 'lodash/omit';
export { default as has } from 'lodash/has';
export { default as get } from 'lodash/get';
export { default as set } from 'lodash/set';
export { default as unset } from 'lodash/unset';
export { default as mergeWith } from 'lodash/mergeWith';
export { default as merge } from 'lodash/merge';
export { default as size } from 'lodash/size';
export { default as clone } from 'lodash/clone';
export { default as cloneDeep } from 'lodash/cloneDeep';
export { default as toPath } from 'lodash/toPath';
@@ -0,0 +1,39 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.toPath = exports.cloneDeep = exports.clone = exports.size = exports.merge = exports.mergeWith = exports.unset = exports.set = exports.get = exports.has = exports.omit = exports.pick = void 0;
/// <reference path="../types/lodash.types.d.ts" />
var pick_1 = require("lodash/pick");
Object.defineProperty(exports, "pick", { enumerable: true, get: function () { return __importDefault(pick_1).default; } });
var omit_1 = require("lodash/omit");
Object.defineProperty(exports, "omit", { enumerable: true, get: function () { return __importDefault(omit_1).default; } });
var has_1 = require("lodash/has");
Object.defineProperty(exports, "has", { enumerable: true, get: function () { return __importDefault(has_1).default; } });
var get_1 = require("lodash/get");
Object.defineProperty(exports, "get", { enumerable: true, get: function () { return __importDefault(get_1).default; } });
var set_1 = require("lodash/set");
Object.defineProperty(exports, "set", { enumerable: true, get: function () { return __importDefault(set_1).default; } });
var unset_1 = require("lodash/unset");
Object.defineProperty(exports, "unset", { enumerable: true, get: function () { return __importDefault(unset_1).default; } });
var mergeWith_1 = require("lodash/mergeWith");
Object.defineProperty(exports, "mergeWith", { enumerable: true, get: function () { return __importDefault(mergeWith_1).default; } });
var merge_1 = require("lodash/merge");
Object.defineProperty(exports, "merge", { enumerable: true, get: function () { return __importDefault(merge_1).default; } });
var size_1 = require("lodash/size");
Object.defineProperty(exports, "size", { enumerable: true, get: function () { return __importDefault(size_1).default; } });
var clone_1 = require("lodash/clone");
Object.defineProperty(exports, "clone", { enumerable: true, get: function () { return __importDefault(clone_1).default; } });
var cloneDeep_1 = require("lodash/cloneDeep");
Object.defineProperty(exports, "cloneDeep", { enumerable: true, get: function () { return __importDefault(cloneDeep_1).default; } });
var toPath_1 = require("lodash/toPath");
Object.defineProperty(exports, "toPath", { enumerable: true, get: function () { return __importDefault(toPath_1).default; } });
@@ -0,0 +1,5 @@
/**
* Copied directly from https://github.com/nuxt-contrib/destr/blob/master/src/index.ts but
* instead raises the malformed JSON exceptions vs swallowing them
*/
export declare function safeParse(val: string, reviver?: (this: any, jsonKey: string, jsonValue: any) => any): any;
@@ -0,0 +1,42 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.safeParse = void 0;
// https://github.com/fastify/secure-json-parse
// https://github.com/hapijs/bourne
const suspectProtoRx = /"(?:_|\\u005[Ff])(?:_|\\u005[Ff])(?:p|\\u0070)(?:r|\\u0072)(?:o|\\u006[Ff])(?:t|\\u0074)(?:o|\\u006[Ff])(?:_|\\u005[Ff])(?:_|\\u005[Ff])"\s*:/;
const suspectConstructorRx = /"(?:c|\\u0063)(?:o|\\u006[Ff])(?:n|\\u006[Ee])(?:s|\\u0073)(?:t|\\u0074)(?:r|\\u0072)(?:u|\\u0075)(?:c|\\u0063)(?:t|\\u0074)(?:o|\\u006[Ff])(?:r|\\u0072)"\s*:/;
const JsonSigRx = /^["{[]|^-?[0-9][0-9.]*$/;
function jsonParseTransform(key, value, reviver) {
if (key === '__proto__' || key === 'constructor') {
return;
}
return reviver ? reviver(key, value) : value;
}
/**
* Copied directly from https://github.com/nuxt-contrib/destr/blob/master/src/index.ts but
* instead raises the malformed JSON exceptions vs swallowing them
*/
function safeParse(val, reviver) {
if (typeof val !== 'string') {
return val;
}
if (val === 'null') {
return null;
}
if (!JsonSigRx.test(val)) {
return val;
}
if (suspectProtoRx.test(val) || suspectConstructorRx.test(val)) {
return JSON.parse(val, (key, value) => jsonParseTransform(key, value, reviver));
}
return JSON.parse(val, reviver);
}
exports.safeParse = safeParse;
@@ -0,0 +1,5 @@
import { ReplacerFn } from './fast-safe-stringify';
/**
* Safely stringifies a Javascript native value
*/
export declare function safeStringify(value: any, replacer?: ReplacerFn, space?: string | number): string;
@@ -0,0 +1,39 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.safeStringify = void 0;
const fast_safe_stringify_1 = require("./fast-safe-stringify");
/**
* Replacer to handle bigints and remove Circular values all together
*/
function jsonStringifyReplacer(replacer, removeCircular) {
return function (key, value) {
if (removeCircular && value === '[Circular]') {
return;
}
const val = replacer ? replacer.call(this, key, value) : value;
if (typeof val === 'bigint') {
return val.toString();
}
return val;
};
}
/**
* Safely stringifies a Javascript native value
*/
function safeStringify(value, replacer, space) {
try {
return JSON.stringify(value, jsonStringifyReplacer(replacer, false), space);
}
catch {
return (0, fast_safe_stringify_1.stringify)(value, jsonStringifyReplacer(replacer, true), space);
}
}
exports.safeStringify = safeStringify;
@@ -0,0 +1,5 @@
/**
* Convert windows path to unix.
* Copied from https://github.com/sindresorhus/slash as the package is ESM only
*/
export declare function slash(filePath: string): string;
@@ -0,0 +1,24 @@
"use strict";
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.slash = void 0;
/**
* Convert windows path to unix.
* Copied from https://github.com/sindresorhus/slash as the package is ESM only
*/
function slash(filePath) {
const isExtendedLengthPath = /^\\\\\?\\/.test(filePath);
const hasNonAscii = /[^\u0000-\u0080]+/.test(filePath); // eslint-disable-line no-control-regex
if (isExtendedLengthPath || hasNonAscii) {
return filePath;
}
return filePath.replace(/\\/g, '/');
}
exports.slash = slash;
+151
View File
@@ -0,0 +1,151 @@
{
"name": "@poppinss/utils",
"version": "4.0.4",
"description": "Handy utilities for repetitive work",
"main": "build/index.js",
"files": [
"build/src",
"build/index.d.ts",
"build/index.js",
"types",
"build/helpers.d.ts",
"build/helpers.js"
],
"scripts": {
"mrm": "mrm --preset=@adonisjs/mrm-preset",
"pretest": "npm run lint",
"test": "node .bin/test.js",
"clean": "del build",
"compile": "npm run lint && npm run clean && tsc",
"build": "npm run compile",
"commit": "git-cz",
"release": "np --message=\"chore(release): %s\"",
"version": "npm run build",
"format": "prettier --write .",
"prepublishOnly": "npm run build",
"lint": "eslint . --ext=.ts",
"sync-labels": "github-label-sync --labels ./node_modules/@adonisjs/mrm-preset/gh-labels.json poppinss/utils"
},
"keywords": [
"utils"
],
"author": "virk,poppinss",
"license": "MIT",
"devDependencies": {
"@adonisjs/mrm-preset": "^5.0.3",
"@adonisjs/require-ts": "^2.0.11",
"@poppinss/dev-utils": "^2.0.3",
"@types/fs-readdir-recursive": "^1.0.0",
"@types/lodash": "^4.14.181",
"@types/ms": "^0.7.31",
"@types/node": "^17.0.23",
"@types/pluralize": "0.0.29",
"@types/require-all": "^3.0.3",
"del-cli": "^4.0.1",
"doctoc": "^2.1.0",
"eslint": "^8.13.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-adonis": "^2.1.0",
"eslint-plugin-prettier": "^4.0.0",
"github-label-sync": "^2.2.0",
"husky": "^7.0.4",
"japa": "^4.0.0",
"mrm": "^4.0.0",
"np": "^7.6.1",
"prettier": "^2.6.2",
"typescript": "^4.6.3"
},
"nyc": {
"exclude": [
"test"
],
"extension": [
".ts"
]
},
"config": {
"commitizen": {
"path": "cz-conventional-changelog"
}
},
"np": {
"contents": ".",
"anyBranch": false
},
"dependencies": {
"@poppinss/file-generator": "^1.0.2",
"@types/bytes": "^3.1.1",
"@types/he": "^1.1.2",
"bytes": "^3.1.2",
"change-case": "^4.1.2",
"cuid": "^2.1.8",
"flattie": "^1.1.0",
"fs-readdir-recursive": "^1.1.0",
"he": "^1.2.0",
"kind-of": "^6.0.3",
"lodash": "^4.17.21",
"ms": "^2.1.3",
"pluralize": "^8.0.0",
"require-all": "^3.0.0",
"resolve-from": "^5.0.0",
"slugify": "^1.6.5",
"truncatise": "0.0.8"
},
"directories": {
"doc": "docs",
"test": "test"
},
"repository": {
"type": "git",
"url": "git+https://github.com/poppinss/utils.git"
},
"bugs": {
"url": "https://github.com/poppinss/utils/issues"
},
"homepage": "https://github.com/poppinss/utils#readme",
"eslintConfig": {
"extends": [
"plugin:adonis/typescriptPackage",
"prettier",
"prettier"
],
"plugins": [
"prettier",
"prettier"
],
"rules": {
"prettier/prettier": [
"error",
{
"endOfLine": "auto"
}
]
}
},
"eslintIgnore": [
"build"
],
"prettier": {
"trailingComma": "es5",
"semi": false,
"singleQuote": true,
"useTabs": false,
"quoteProps": "consistent",
"bracketSpacing": true,
"arrowParens": "always",
"printWidth": 100
},
"mrmConfig": {
"core": false,
"license": "MIT",
"services": [
"github-actions"
],
"minNodeVersion": "16.13.1",
"probotApps": [
"stale",
"lock"
],
"runGhActionsOnWindows": true
}
}
@@ -0,0 +1,65 @@
/*
* @poppinss/utils
*
* (c) Harminder Virk <virk@adonisjs.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
type PropertyName = string | number | symbol
type PropertyNames = PropertyName | ReadonlyArray<PropertyName>
declare module 'lodash/pick' {
export default function pick<T>(
object: T | null | undefined,
...props: Array<PropertyNames>
): Partial<T>
}
declare module 'lodash/omit' {
export default function omit<T extends object>(
object: T | null | undefined,
...paths: Array<PropertyNames>
): Partial<T>
}
declare module 'lodash/has' {
export default function has<T>(object: T, path: PropertyNames): boolean
}
declare module 'lodash/get' {
export default function get(object: any, path: PropertyNames, defaultValue?: any): any
}
declare module 'lodash/set' {
export default function set(object: any, path: PropertyNames, value: any): any
}
declare module 'lodash/unset' {
export default function unset(object: any, path: PropertyNames): boolean
}
declare module 'lodash/mergeWith' {
export default function mergeWith(object: any, ...otherArgs: any[]): any
}
declare module 'lodash/merge' {
export default function merge(object: any, ...otherArgs: any[]): any
}
declare module 'lodash/size' {
export default function size(collection: object | string | null | undefined): number
}
declare module 'lodash/clone' {
export default function clone<T>(value: T): T
}
declare module 'lodash/cloneDeep' {
export default function cloneDeep<T>(value: T): T
}
declare module 'lodash/toPath' {
export default function toPath(value: any): string[]
}
+141
View File
@@ -0,0 +1,141 @@
{
"name": "@adonisjs/fold",
"version": "8.2.0",
"description": "Dependency manager and IoC container for your next NodeJs application",
"main": "build/index.js",
"files": [
"build/src",
"build/index.d.ts",
"build/index.js"
],
"scripts": {
"mrm": "mrm --preset=@adonisjs/mrm-preset",
"pretest": "npm run lint",
"test": "node -r @adonisjs/require-ts/build/register bin/test.ts",
"lint": "eslint . --ext=.ts",
"clean": "del-cli build",
"compile": "npm run lint && npm run clean && tsc",
"build": "npm run compile",
"commit": "git-cz",
"release": "np --message=\"chore(release): %s\"",
"version": "npm run build",
"sync-labels": "github-label-sync --labels ./node_modules/@adonisjs/mrm-preset/gh-labels.json adonisjs/fold",
"format": "prettier --write .",
"prepublishOnly": "npm run build"
},
"author": "adonisjs,virk",
"license": "MIT",
"repository": {
"type": "git",
"url": "git+https://github.com/poppinss/adonis-fold.git"
},
"keywords": [
"ioc",
"dependency",
"injection",
"service",
"provider",
"autoloading"
],
"bugs": {
"url": "https://github.com/poppinss/adonis-fold/issues"
},
"homepage": "https://github.com/poppinss/adonis-fold#readme",
"devDependencies": {
"@adonisjs/mrm-preset": "^5.0.3",
"@adonisjs/require-ts": "^2.0.11",
"@japa/assert": "^1.3.4",
"@japa/run-failed-tests": "^1.0.3",
"@japa/runner": "^2.0.7",
"@japa/spec-reporter": "^1.1.7",
"@poppinss/dev-utils": "^2.0.3",
"@types/node": "^17.0.25",
"benchmark": "^2.1.4",
"commitizen": "^4.2.4",
"cz-conventional-changelog": "^3.3.0",
"del-cli": "^4.0.1",
"eslint": "^8.13.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-adonis": "^2.1.0",
"eslint-plugin-prettier": "^4.0.0",
"github-label-sync": "^2.2.0",
"husky": "^7.0.4",
"mrm": "^4.0.0",
"np": "^7.6.1",
"prettier": "^2.6.2",
"reflect-metadata": "^0.1.13",
"typescript": "^4.6.3"
},
"nyc": {
"exclude": [
"test"
],
"extension": [
".ts"
]
},
"husky": {
"hooks": {
"commit-msg": "node ./node_modules/@adonisjs/mrm-preset/validateCommit/conventional/validate.js"
}
},
"config": {
"commitizen": {
"path": "cz-conventional-changelog"
}
},
"np": {
"contents": ".",
"anyBranch": false
},
"dependencies": {
"@poppinss/utils": "^4.0.4"
},
"publishConfig": {
"access": "public",
"tag": "latest"
},
"mrmConfig": {
"core": true,
"license": "MIT",
"services": [
"github-actions"
],
"minNodeVersion": "14.15.4",
"probotApps": [
"stale",
"lock"
],
"runGhActionsOnWindows": false
},
"eslintConfig": {
"extends": [
"plugin:adonis/typescriptPackage",
"prettier"
],
"plugins": [
"prettier"
],
"rules": {
"prettier/prettier": [
"error",
{
"endOfLine": "auto"
}
]
}
},
"eslintIgnore": [
"build"
],
"prettier": {
"trailingComma": "es5",
"semi": false,
"singleQuote": true,
"useTabs": false,
"quoteProps": "consistent",
"bracketSpacing": true,
"arrowParens": "always",
"printWidth": 100
}
}