diff --git a/CHANGELOG.md b/CHANGELOG.md index 101fe74..6511081 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Change Log (@egomobile/documentation) +## 0.4.0 + +- add tools to add function dependencies +- reorganize code, especially types + ## 0.3.0 - implement serializable types and `serializeDependencies()` utility function diff --git a/README.md b/README.md index d841a65..e5286fe 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ npm install --save @egomobile/documentation ```typescript import { defaultDependencies, - DependsOn + DependsOn, + functionDependsOn } from "@egomobile/documentation"; @DependsOn({ @@ -76,6 +77,12 @@ class MyDocumentedClass { } } +function myFunction() { + // ... +} +// do this for functions as well +functionDependsOn(myFunction); + console.log( // by default all information are // stored in this module-wide array diff --git a/package-lock.json b/package-lock.json index 0b7b750..dbba902 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@egomobile/documentation", - "version": "0.3.0", + "version": "0.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@egomobile/documentation", - "version": "0.3.0", + "version": "0.4.0", "license": "LGPL-3.0", "devDependencies": { "@egomobile/tsconfig": "^5.0.0", diff --git a/package.json b/package.json index 4ddcfb4..537e2dc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@egomobile/documentation", - "version": "0.3.0", + "version": "0.4.0", "description": "Tools for documenting (TypeScript) code.", "main": "lib/index.js", "engines": { diff --git a/src/decorators/DependsOn.ts b/src/decorators/DependsOn.ts index 7a6304f..a9219ed 100644 --- a/src/decorators/DependsOn.ts +++ b/src/decorators/DependsOn.ts @@ -15,341 +15,8 @@ // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . -import type { ClassOrInstance, ClassPropKey, Collection, Constructor, IArrayLike, Nilable, Optional, ReferenceValue } from "../types/internal"; -import { isCollection } from "../utils/internal"; - -/** - * Repository of `IDependencyInformationEntity` grouped by their name. - */ -export type DependencyInformationEntities = IDependencyInformationEntity[]; - -/** - * Repository of `IDependencyInformationEntityAttribute` grouped by their name. - */ -export type DependencyInformationEntityAttributes = IDependencyInformationEntityAttribute[]; - -/** - * A function that returns an `IDependencyInformation` based on a `DependencyItem`. - */ -export type DependencyInfoResolver = (item: DependencyItem) => IDependencyInformation; - -/** - * An item for `dependencies`. - */ -export type DependencyItem = - IClassDependencyItem | - IMethodDependencyItem | - IParameterDependencyItem | - IPropertyDependencyItem; - -/** - * A function that resolves collection of `DependencyItemWithInfo`s. - */ -export type DependencyItemCollectionResolver = () => Collection; - -/** - * An extension of `DependencyItem`. - */ -export type DependencyItemWithInfo = DependencyItem & { - /** - * The underlying information. - */ - info: IDependencyInformation; -}; - -/** - * A `IDependencyItem` with information about a class and its dependencies. - */ -export interface IClassDependencyItem extends IDependencyItem { - /** - * The underlying constructor. - */ - constructor: Constructor; - /** - * The type - */ - type: "class"; -} - -/** - * Information about a dependency. - */ -export interface IDependencyInformation { - /** - * A reference value. Value should be handled as slug value, case-insensitive. - */ - app: ReferenceValue; - /** - * An optional value that categories this app. Value should be handled as slug value, case-insensitive. - */ - category?: Nilable; - /** - * If there is an action on `app`'s side, it will - * have effects in this application in general. - * - * @default `false` - */ - hasLocalEffects?: Nilable; - /** - * If there is an action in this application, - * it will have effects on `app`'s side in general. - * - * @default `true` - */ - hasRemoteEffects?: Nilable; - /** - * Optional entities for this app. - */ - entities?: Nilable; - /** - * Optional unique key. Value should be handled case-insensitive. - */ - key?: Nilable; - /** - * An optional list of references. Should be handled as URIs. - */ - references?: Nilable; - /** - * Optional notes/remarks for this app. Should be handled as Markdown, if possible. - */ - remarks?: Nilable; - /** - * An optional value that classifies the application. Value should be handled as slug value, case-insensitive. - */ - type?: Nilable; -} - -/** - * An entity inside a `IDependencyInformation` object. - */ -export interface IDependencyInformationEntity { - /** - * Optional list of attributes. - */ - attributes?: Nilable; - /** - * An optional value that categories this entity. Value should be handled as slug value, case-insensitive. - */ - category?: Nilable; - /** - * If there is an action on this entity side, it will - * have effects in this application in general. - * - * @default `false` - */ - hasLocalEffects?: Nilable; - /** - * If there is an action in this application, - * it will have effects only on entity's side in general. - * - * @default `true` - */ - hasRemoteEffects?: Nilable; - /** - * The unique key. Value should be handled case-insensitive. - */ - key: ReferenceValue; - /** - * An optional list of references. Should be handled as URIs. - */ - references?: Nilable; - /** - * Optional notes/remarks for this entity. Should be handled as Markdown, if possible. - */ - remarks?: Nilable; - /** - * An optional value that classifies the entity. Value should be handled as slug value, case-insensitive. - */ - type?: Nilable; -} - -/** - * An attribute inside a `IDependencyInformationEntity` object. - */ -export interface IDependencyInformationEntityAttribute { - /** - * An optional value that categories this attribute. Value should be handled as slug value, case-insensitive. - */ - category?: Nilable; - /** - * If there is an action on this attribute side, it will - * have effects in this application in general. - * - * @default `false` - */ - hasLocalEffects?: Nilable; - /** - * If there is an action in this application, - * it will have effects only on attribute's side in general. - * - * @default `true` - */ - hasRemoteEffects?: Nilable; - /** - * The unique key. Value should be handled as slug value, case-insensitive. - */ - key: ReferenceValue; - /** - * An optional list of references. Should be handled as URIs. - */ - references?: Nilable; - /** - * Optional notes/remarks for this attribute. Should be handled as Markdown, if possible. - */ - remarks?: Nilable; - /** - * An optional value that classifies the attribute. Value should be handled as slug value, case-insensitive. - */ - type?: Nilable; -} - -/** - * A basic dependency item. - */ -export interface IDependencyItem { -} - -/** - * A `IDependencyItem` with information about a class method and its dependencies. - */ -export interface IMethodDependencyItem extends IDependencyItem { - /** - * The underlying class or constructor. - */ - classOrInstance: ClassOrInstance; - /** - * The key / name. - */ - key: ClassPropKey; - /** - * The type. - */ - type: "method"; -} - -/** - * A `IDependencyItem` with information about a paremeter of a class method and its dependencies. - */ -export interface IParameterDependencyItem extends IDependencyItem { - /** - * The underlying class or constructor. - */ - classOrInstance: ClassOrInstance; - /** - * The zero-based index inside the method. - */ - index: number; - /** - * The key / name, if available. - */ - key?: Optional; - /** - * The type. - */ - type: "parameter"; -} - -/** - * A `IDependencyItem` with information about a class property and its dependencies. - */ -export interface IPropertyDependencyItem extends IDependencyItem { - /** - * The underlying class or constructor. - */ - classOrInstance: ClassOrInstance; - /** - * The key / name. - */ - key: ClassPropKey; - /** - * The type. - */ - type: "property"; -} - -/** - * Default collection of of `DependencyItemWithInfo`s. - */ -export const defaultDependencies: IArrayLike = []; - -let dependenciesResolver: DependencyItemCollectionResolver = () => { - return defaultDependencies; -}; - -/** - * Returns the collection of `DependencyItemWithInfo` items. - * - * @example - * ``` - * import { - * getDependencies, - * setDependencies - * } from "@egomobile/documentation" - * - * // initially this is an array - * console.log( - * getDependencies() - * ) - * - * // you can also define a function that returns the collection - * const newDependencyCollection = new Set() - * - * setDependencies(newDependencyCollection) - * - * // should be the set from `newDependencyCollection` now - * console.log( - * getDependencies() - * ) - * ``` - * - * @returns {Collection} The current, global collection of `DependencyItemWithInfo`s. - */ -export function getDependencies(): Collection { - return dependenciesResolver(); -} - -/** - * Sets up the global collection of `DependencyItemWithInfo`s. - * - * @example - * ``` - * import { - * getDependencies, - * setDependencies - * } from "@egomobile/documentation" - * - * // initially this is an array - * console.log( - * getDependencies() - * ) - * - * // you can also define a function that returns the collection - * const newDependencyCollection = new Set() - * - * setDependencies(newDependencyCollection) - * - * // should be the set from `newDependencyCollection` now - * console.log( - * getDependencies() - * ) - * ``` - * - * @param {Collection|DependencyItemCollectionResolver} collectionOrResolver The collection or a function that resolves it. - */ -export function setDependencies(collectionOrResolver: Collection | DependencyItemCollectionResolver): void { - if (typeof collectionOrResolver === "function") { - dependenciesResolver = collectionOrResolver; - } - else { - if (!isCollection(collectionOrResolver)) { - throw new TypeError("collection is not valid"); - } - - dependenciesResolver = () => { - return collectionOrResolver as Collection; - }; - } -} +import type { IDependencyInformation, IParameterDependencyItem, IPropertyDependencyItem, IMethodDependencyItem, IClassDependencyItem, DependencyInfoResolver, DependencyInfoCollectionArg } from "../types"; +import type { ClassPropKey, CreateDependsOnHelpersFunc, Nilable, Optional } from "../types/internal"; /** * Adds meta for a class, property, method or parameter @@ -423,48 +90,20 @@ export function setDependencies(collectionOrResolver: Collection>} [dependencies] The custom collection for the items. + * @param {IDependencyInformation|DependencyInfoResolver} infoOrResolver The dependency information or the function that resolves it. + * @param {Nilable} [dependenciesOrResolver] The custom collection for the dependency info items or the function that resolves it. * * @returns {ClassDecorator|MethodDecorator|ParameterDecorator|PropertyDecorator} The new decorator function. */ export function DependsOn( infoOrResolver: IDependencyInformation | DependencyInfoResolver, - dependencies?: Nilable> + dependenciesOrResolver?: Nilable ): any { - const getInfo = (item: DependencyItem) => { - if (typeof infoOrResolver === "function") { - return infoOrResolver(item); - } - - return infoOrResolver; - }; + const createDependsOnHelpers: CreateDependsOnHelpersFunc = require("../utils/internal").createDependsOnHelpers; - const getDepsCollection: (() => Collection) = - dependencies ? - () => { - return dependencies!; - } : - getDependencies; - const addItem = (item: DependencyItem) => { - const deps = getDepsCollection(); - - const itemToAdd: DependencyItemWithInfo = { - ...item, - - "info": getInfo(item) - }; - - if ("push" in deps) { - deps.push(itemToAdd); // array-like - } - else if ("add" in deps) { - deps.add(itemToAdd); // set-like - } - else { - throw new TypeError("unsupported collection type"); - } - }; + const { + addItem + } = createDependsOnHelpers(infoOrResolver, dependenciesOrResolver); return (...args: any[]) => { const target: any = args[0]; diff --git a/src/functions/dependsOn.ts b/src/functions/dependsOn.ts new file mode 100644 index 0000000..b4dadb4 --- /dev/null +++ b/src/functions/dependsOn.ts @@ -0,0 +1,44 @@ +// This file is part of the @egomobile/documentation distribution. +// Copyright (c) Next.e.GO Mobile SE, Aachen, Germany (https://e-go-mobile.com/) +// +// @egomobile/documentation is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, version 3. +// +// @egomobile/documentation is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +import type { DependencyInfoCollectionArg, DependencyInfoResolver, IDependencyInformation, IFunctionDependencyItem } from "../types"; +import type { CreateDependsOnHelpersFunc, Func, Nilable } from "../types/internal"; + +/** + * Adds dependency information for a function. + * + * @param {Func} func The function. + * @param {IDependencyInformation|DependencyInfoResolver} infoOrResolver The dependency information or the function that resolves it. + * @param {Nilable} [dependenciesOrResolver] The custom collection for the dependency info items or the function that resolves it. + */ +export function functionDependsOn( + func: Func, + infoOrResolver: IDependencyInformation | DependencyInfoResolver, + dependenciesOrResolver?: Nilable +) { + const createDependsOnHelpers: CreateDependsOnHelpersFunc = + require("../utils/internal").createDependsOnHelpers; + + const { + addItem + } = createDependsOnHelpers(infoOrResolver, dependenciesOrResolver); + + const newFunctionItem: IFunctionDependencyItem = { + "key": func.name, + "type": "function" + }; + + addItem(newFunctionItem); +} diff --git a/src/functions/index.ts b/src/functions/index.ts new file mode 100644 index 0000000..a94684e --- /dev/null +++ b/src/functions/index.ts @@ -0,0 +1,105 @@ +// This file is part of the @egomobile/documentation distribution. +// Copyright (c) Next.e.GO Mobile SE, Aachen, Germany (https://e-go-mobile.com/) +// +// @egomobile/documentation is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, version 3. +// +// @egomobile/documentation is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +import type { DependencyItemCollectionResolver, DependencyItemWithInfo } from "../types"; +import type { Collection, IsCollectionFunc } from "../types/internal"; + +/** + * Default collection of of `DependencyItemWithInfo`s. + */ +export const defaultDependencies: DependencyItemWithInfo[] = []; + +let dependenciesResolver: DependencyItemCollectionResolver = () => { + return defaultDependencies; +}; + +/** + * Returns the collection of `DependencyItemWithInfo` items. + * + * @example + * ``` + * import { + * getDependencies, + * setDependencies + * } from "@egomobile/documentation" + * + * // initially this is an array + * console.log( + * getDependencies() + * ) + * + * // you can also define a function that returns the collection + * const newDependencyCollection = new Set() + * + * setDependencies(newDependencyCollection) + * + * // should be the set from `newDependencyCollection` now + * console.log( + * getDependencies() + * ) + * ``` + * + * @returns {Collection} The current, global collection of `DependencyItemWithInfo`s. + */ +export function getDependencies(): Collection { + return dependenciesResolver(); +} + +/** + * Sets up the global collection of `DependencyItemWithInfo`s. + * + * @example + * ``` + * import { + * getDependencies, + * setDependencies + * } from "@egomobile/documentation" + * + * // initially this is an array + * console.log( + * getDependencies() + * ) + * + * // you can also define a function that returns the collection + * const newDependencyCollection = new Set() + * + * setDependencies(newDependencyCollection) + * + * // should be the set from `newDependencyCollection` now + * console.log( + * getDependencies() + * ) + * ``` + * + * @param {Collection|DependencyItemCollectionResolver} collectionOrResolver The collection or a function that resolves it. + */ +export function setDependencies(collectionOrResolver: Collection | DependencyItemCollectionResolver): void { + const isCollection: IsCollectionFunc = require("../utils/internal"); + + if (typeof collectionOrResolver === "function") { + dependenciesResolver = collectionOrResolver; + } + else { + if (!isCollection(collectionOrResolver)) { + throw new TypeError("collection is not valid"); + } + + dependenciesResolver = () => { + return collectionOrResolver as Collection; + }; + } +} + +export * from "./dependsOn"; diff --git a/src/index.ts b/src/index.ts index b693259..d7d4a43 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,6 +13,8 @@ // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . -export * from "./decorators"; +// !!!KEEP THIS IN THAT ORDER!!! export * from "./types"; export * from "./utils"; +export * from "./functions"; +export * from "./decorators"; diff --git a/src/types/dependencies.ts b/src/types/dependencies.ts new file mode 100644 index 0000000..f8faeaf --- /dev/null +++ b/src/types/dependencies.ts @@ -0,0 +1,295 @@ +// This file is part of the @egomobile/documentation distribution. +// Copyright (c) Next.e.GO Mobile SE, Aachen, Germany (https://e-go-mobile.com/) +// +// @egomobile/documentation is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, version 3. +// +// @egomobile/documentation is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +import type { IWithClassNameProp, IWithClassOrInstanceProp, IWithEffectsProps, IWithIsStaticProp, IWithReferencesProp, IWithRemarksProp, IWithTypeProp } from "."; +import type { ClassPropKey, Collection, Constructor, Nilable, Nullable, Optional, ReferenceValue } from "./internal"; + +/** + * Type of an `dependenciesOrResolver` argument. + */ +export type DependencyInfoCollectionArg = Collection | (() => Collection); + +/** + * Type of an `infoOrResolver` argument. + */ +export type DependencyInfoArg = IDependencyInformation | DependencyInfoResolver; + +/** + * A function that returns an `IDependencyInformation` based on a `DependencyItem`. + */ +export type DependencyInfoResolver = (item: DependencyItem) => IDependencyInformation; + +/** + * Repository of `IDependencyInformationEntity` grouped by their name. + */ +export type DependencyInformationEntities = IDependencyInformationEntity[]; + +/** + * Repository of `IDependencyInformationEntityAttribute` grouped by their name. + */ +export type DependencyInformationEntityAttributes = IDependencyInformationEntityAttribute[]; + +/** + * An item for `dependencies`. + */ +export type DependencyItem = + IClassDependencyItem | + IFunctionDependencyItem | + IMethodDependencyItem | + IParameterDependencyItem | + IPropertyDependencyItem; + +/** + * A function that resolves collection of `DependencyItemWithInfo`s. + */ +export type DependencyItemCollectionResolver = () => Collection; + +/** + * An extension of `DependencyItem`. + */ +export type DependencyItemWithInfo = DependencyItem & { + /** + * The underlying information. + */ + info: IDependencyInformation; +}; + +/** + * A `IDependencyItem` with information about a class and its dependencies. + */ +export interface IClassDependencyItem extends IDependencyItem { + /** + * The underlying constructor. + */ + constructor: Constructor; + /** + * The type + */ + type: "class"; +} + +/** + * Information about a dependency. + */ +export interface IDependencyInformation extends Partial, Partial, Partial, Partial { + /** + * A reference value. Value should be handled as slug value, case-insensitive. + */ + app: ReferenceValue; + /** + * An optional value that categories this app. Value should be handled as slug value, case-insensitive. + */ + category?: Nilable; + /** + * Optional entities for this app. + */ + entities?: Nilable; + /** + * Optional unique key. Value should be handled case-insensitive. + */ + key?: Nilable; +} + +/** + * An entity inside a `IDependencyInformation` object. + */ +export interface IDependencyInformationEntity extends Partial, Partial, Partial, Partial { + /** + * Optional list of attributes. + */ + attributes?: Nilable; + /** + * An optional value that categories this entity. Value should be handled as slug value, case-insensitive. + */ + category?: Nilable; + /** + * The unique key. Value should be handled case-insensitive. + */ + key: ReferenceValue; +} + +/** + * An attribute inside a `IDependencyInformationEntity` object. + */ +export interface IDependencyInformationEntityAttribute extends Partial, Partial, Partial, Partial { + /** + * An optional value that categories this attribute. Value should be handled as slug value, case-insensitive. + */ + category?: Nilable; + /** + * The unique key. Value should be handled as slug value, case-insensitive. + */ + key: ReferenceValue; +} + +/** + * A basic dependency item. + */ +export interface IDependencyItem { +} + +/** + * A `IDependencyItem` with information about a function and its dependencies. + */ +export interface IFunctionDependencyItem extends IDependencyItem { + /** + * The key / name. + */ + key: string; + /** + * The type. + */ + type: "function"; +} + +/** + * A `IDependencyItem` with information about a class method and its dependencies. + */ +export interface IMethodDependencyItem extends IDependencyItem, Partial { + /** + * The key / name. + */ + key: ClassPropKey; + /** + * The type. + */ + type: "method"; +} + +/** + * A `IDependencyItem` with information about a paremeter of a class method and its dependencies. + */ +export interface IParameterDependencyItem extends IDependencyItem, Partial { + /** + * The zero-based index inside the method. + */ + index: number; + /** + * The key / name, if available. + */ + key?: Optional; + /** + * The type. + */ + type: "parameter"; +} + +/** + * A `IDependencyItem` with information about a class property and its dependencies. + */ +export interface IPropertyDependencyItem extends IDependencyItem, Partial { + /** + * The key / name. + */ + key: ClassPropKey; + /** + * The type. + */ + type: "property"; +} + +/** + * A serizable version of an `IClassDependencyItem`. + */ +export interface ISerializableClassDependencyItemWithInfo extends ISerializableDependencyItemWithInfo { + /** + * The name of the class. + */ + name: string; + /** + * The type + */ + type: "class"; +} + +/** + * A serizable version of an `IDependencyItem`. + */ +export interface ISerializableDependencyItemWithInfo { + /** + * The underlying information. + */ + info: IDependencyInformation; +} + +/** + * A serizable version of an `IFunctionDependencyItem`. + */ +export interface ISerializableFunctionDependencyItemWithInfo extends ISerializableDependencyItemWithInfo { + /** + * The name of the function. + */ + name: string; + /** + * The type. + */ + type: "function"; +} + +/** + * A serizable version of an `IMethodDependencyItem`. + */ +export interface ISerializableMethodDependencyItemWithInfo extends ISerializableDependencyItemWithInfo, IWithClassNameProp, IWithIsStaticProp { + /** + * The name of the method. + */ + name: string; + /** + * The type. + */ + type: "method"; +} + +/** + * A serizable version of an `IParameterDependencyItem`. + */ +export interface ISerializableParameterDependencyItemWithInfo extends ISerializableDependencyItemWithInfo, IWithClassNameProp, IWithIsStaticProp { + /** + * The zero-based index inside the method. + */ + index: number; + /** + * The name, if available. + */ + name: Nullable; + /** + * The type. + */ + type: "parameter"; +} + +/** + * A serizable version of an `IPropertyDependencyItem`. + */ +export interface ISerializablePropertyDependencyItemWithInfo extends ISerializableDependencyItemWithInfo, IWithClassNameProp, IWithIsStaticProp { + /** + * The name of the property. + */ + name: string; + /** + * The type. + */ + type: "property"; +} + +/** + * An serializable dependency info item. + */ +export type SerializableDependencyItem = + ISerializableClassDependencyItemWithInfo | + ISerializableFunctionDependencyItemWithInfo | + ISerializableMethodDependencyItemWithInfo | + ISerializableParameterDependencyItemWithInfo | + ISerializablePropertyDependencyItemWithInfo; diff --git a/src/types/index.ts b/src/types/index.ts index f6c0151..4405907 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -13,104 +13,86 @@ // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . -import type { IDependencyInformation } from "../decorators"; -import type { Nullable } from "./internal"; +import type { ClassOrInstance, Nilable, Nullable } from "./internal"; /** - * A serizable version of an `IClassDependencyItem`. + * An object with a `className` property. */ -export interface ISerializableClassDependencyItemWithInfo extends ISerializableDependencyItemWithInfo { - /** - * The name of the class. - */ - name: string; +export interface IWithClassNameProp { /** - * The type + * The name of the underlying class, if available. */ - type: "class"; + className: Nullable; } /** - * A serizable version of an `IDependencyItem`. + * An object with a `classOrInstance` property. */ -export interface ISerializableDependencyItemWithInfo { +export interface IWithClassOrInstanceProp { /** - * The underlying information. + * The underlying class or constructor. */ - info: IDependencyInformation; + classOrInstance: ClassOrInstance; } /** - * A serizable version of an `IMethodDependencyItem`. + * An object with effects properties. */ -export interface ISerializableMethodDependencyItemWithInfo extends ISerializableDependencyItemWithInfo, IWithClassNameProp, IWithIsStaticProp { +export interface IWithEffectsProps { /** - * The name of the method. + * If there is an action on `app`'s side, it will + * have effects in this application in general. + * + * @default `false` */ - name: string; + hasLocalEffects: Nilable; /** - * The type. + * If there is an action in this application, + * it will have effects on `app`'s side in general. + * + * @default `true` */ - type: "method"; + hasRemoteEffects: Nilable; } /** - * A serizable version of an `IParameterDependencyItem`. + * An object with an `isStatic` property. */ -export interface ISerializableParameterDependencyItemWithInfo extends ISerializableDependencyItemWithInfo, IWithClassNameProp, IWithIsStaticProp { - /** - * The zero-based index inside the method. - */ - index: number; - /** - * The name, if available. - */ - name: Nullable; +export interface IWithIsStaticProp { /** - * The type. + * Is underlying type static or not. */ - type: "parameter"; + isStatic: boolean; } /** - * A serizable version of an `IPropertyDependencyItem`. + * An object with a `references` property. */ -export interface ISerializablePropertyDependencyItemWithInfo extends ISerializableDependencyItemWithInfo, IWithClassNameProp, IWithIsStaticProp { - /** - * The name of the property. - */ - name: string; +export interface IWithReferencesProp { /** - * The type. + * An optional list of references. Should be handled as URIs. */ - type: "property"; + references: Nilable; } /** - * An object with an `className` property. + * An object with a `remarks` property. */ -export interface IWithClassNameProp { +export interface IWithRemarksProp { /** - * The name of the underlying class, if available. + * Optional notes/remarks. Should be handled as Markdown, if possible. */ - className: Nullable; + references: Nilable; } /** - * An object with an `isStatic` property. + * An object with a `type` property. */ -export interface IWithIsStaticProp { +export interface IWithTypeProp { /** - * Is underlying type static or not. + * An optional value for classification. Value should be handled as slug value, case-insensitive. */ - isStatic: boolean; + type: Nilable; } -/** - * An serializable dependency info item. - */ -export type SerializableDependencyItem = - ISerializableClassDependencyItemWithInfo | - ISerializableMethodDependencyItemWithInfo | - ISerializableParameterDependencyItemWithInfo | - ISerializablePropertyDependencyItemWithInfo; +export * from "./dependencies"; diff --git a/src/types/internal.ts b/src/types/internal.ts index 0666078..6ea6cf6 100644 --- a/src/types/internal.ts +++ b/src/types/internal.ts @@ -13,6 +13,8 @@ // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . +import type { DependencyInfoArg, DependencyInfoCollectionArg, DependencyItem, DependencyItemWithInfo, IDependencyInformation } from "./dependencies"; + export type ClassOrInstance = T | Constructor; export type ClassPropKey = string | symbol; @@ -21,12 +23,34 @@ export type Collection = IArrayLike | ISetLike; -export type Constructor = (new (...args: any[]) => T); +export type Constructor = + (new (...args: any[]) => T); + +export type CreateDependsOnHelpersFunc = + ( + infoOrResolver: DependencyInfoArg, + dependenciesOrResolver: Nilable + ) => { + addItem: (item: DependencyItem) => void; + getDepsCollection: () => Collection; + getInfo: () => IDependencyInformation; + }; + +export type Func = (...args: any[]) => any; + +export type GetClassNameFunc = + (classOrInstance: ClassOrInstance) => Nullable; export interface IArrayLike { push(item: T): any; } +export type IsCollectionFunc = + (val: any) => val is Collection; + +export type IsConstructorFunc = + (classOrInstance: ClassOrInstance) => classOrInstance is Constructor; + export interface ISetLike { add(item: T): any; } diff --git a/src/utils/index.ts b/src/utils/index.ts index d82a114..356a257 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -13,10 +13,8 @@ // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . -import type { DependencyItemWithInfo } from "../decorators"; -import type { ISerializableClassDependencyItemWithInfo, ISerializableMethodDependencyItemWithInfo, ISerializableParameterDependencyItemWithInfo, ISerializablePropertyDependencyItemWithInfo, SerializableDependencyItem } from "../types"; -import type { List } from "../types/internal"; -import { getClassName, isConstructor } from "./internal"; +import type { DependencyItemWithInfo, ISerializableClassDependencyItemWithInfo, ISerializableFunctionDependencyItemWithInfo, ISerializableMethodDependencyItemWithInfo, ISerializableParameterDependencyItemWithInfo, ISerializablePropertyDependencyItemWithInfo, SerializableDependencyItem } from "../types"; +import type { GetClassNameFunc, IsConstructorFunc, List } from "../types/internal"; /** * Serialized a list of dependency items. @@ -26,6 +24,9 @@ import { getClassName, isConstructor } from "./internal"; * @returns {SerializableDependencyItem[]} The serialized list. */ export function serializeDependencies(list: List): SerializableDependencyItem[] { + const getClassName: GetClassNameFunc = require("./internal").getClassName; + const isConstructor: IsConstructorFunc = require("./internal").isConstructor; + const serializedItems: SerializableDependencyItem[] = []; for (const item of list) { @@ -62,7 +63,7 @@ export function serializeDependencies(list: List): Seria newSerializedItem = newClassItem; } - else { + else if (item.type === "property") { const newClassItem: ISerializablePropertyDependencyItemWithInfo = { "className": getClassName(item.classOrInstance), "info": item.info, @@ -73,6 +74,15 @@ export function serializeDependencies(list: List): Seria newSerializedItem = newClassItem; } + else { + const newClassItem: ISerializableFunctionDependencyItemWithInfo = { + "info": item.info, + "name": item.key, + "type": item.type + }; + + newSerializedItem = newClassItem; + } serializedItems.push( newSerializedItem diff --git a/src/utils/internal.ts b/src/utils/internal.ts index f78e21e..16f04a4 100644 --- a/src/utils/internal.ts +++ b/src/utils/internal.ts @@ -13,7 +13,59 @@ // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . -import type { ClassOrInstance, Collection, Constructor, Nullable } from "../types/internal"; +import type { DependencyInfoArg, DependencyInfoCollectionArg, DependencyItem, DependencyItemWithInfo } from "../types"; +import type { ClassOrInstance, Collection, Constructor, Nilable, Nullable } from "../types/internal"; + +export function createDependsOnHelpers( + infoOrResolver: DependencyInfoArg, + dependenciesOrResolver: Nilable +) { + const { getDependencies } = require("../functions"); + + const getInfo = (item: DependencyItem) => { + if (typeof infoOrResolver === "function") { + return infoOrResolver(item); + } + + return infoOrResolver; + }; + + const getDepsCollection: (() => Collection) = + dependenciesOrResolver ? + () => { + return typeof dependenciesOrResolver === "function" ? + dependenciesOrResolver() : + dependenciesOrResolver!; + } : + getDependencies; + + const addItem = (item: DependencyItem) => { + const deps = getDepsCollection(); + + const itemToAdd: DependencyItemWithInfo = { + ...item, + + "info": getInfo(item) + }; + + if ("push" in deps) { + deps.push(itemToAdd); // array-like + } + else if ("add" in deps) { + deps.add(itemToAdd); // set-like + } + else { + throw new TypeError("unsupported collection type"); + } + }; + + return { + addItem, + getDepsCollection, + getInfo + }; +} + export function getClassName(classOrInstance: ClassOrInstance): Nullable { if (isConstructor(classOrInstance)) {