From c794c899e5edba2337ed94e2166f75b025f0523b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Fri, 29 Dec 2023 01:07:06 +0100 Subject: [PATCH] First version: 20231229.0.0 (#2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Julien Valverdé Reviewed-on: https://git.jvalver.de/Thilawyn/thilatrait/pulls/2 --- .drone.jsonnet | 90 +++++++++++--------- bun.lockb | Bin 20853 -> 152097 bytes package.json | 10 ++- rollup.config.js | 12 ++- src/class.ts | 68 --------------- src/index.ts | 173 ++++++++++++++++++++++++++++++++++++++- src/legacy/tests.ts | 74 +++++++++++++++++ src/legacy/trait.ts | 126 ++++++++++++++++++++++++++++ src/legacy/util/class.ts | 109 ++++++++++++++++++++++++ src/tests.ts | 79 ++++++++++++------ src/trait.ts | 87 -------------------- src/utils.ts | 1 - 12 files changed, 602 insertions(+), 227 deletions(-) delete mode 100644 src/class.ts create mode 100644 src/legacy/tests.ts create mode 100644 src/legacy/trait.ts create mode 100644 src/legacy/util/class.ts delete mode 100644 src/trait.ts delete mode 100644 src/utils.ts diff --git a/.drone.jsonnet b/.drone.jsonnet index 8b33506..2a13019 100644 --- a/.drone.jsonnet +++ b/.drone.jsonnet @@ -19,9 +19,20 @@ local lint_step = { commands: ["bun lint:tsc"], }; -local generate_docker_tags_step = { - name: "generate-docker-tags", - image: "git.jvalver.de/thilawyn/drone-better-docker-autotag", +local build_step = { + name: "build", + image: bun_image, + commands: ["bun run build"], +}; + +local publish_step = { + name: "publish", + image: "plugins/npm", + + settings: { + registry: "https://git.jvalver.de/api/packages/jvalverde/npm", + token: { from_secret: "npm_token" }, + }, }; @@ -48,46 +59,45 @@ local generate_docker_tags_step = { ], }, - // Build the server and legacy API docker images without publishing them for pull requests - // { - // kind: "pipeline", - // type: "docker", - // name: "build-docker", + // Build the package without publishing for pull requests + { + kind: "pipeline", + type: "docker", + name: "build", - // trigger: { - // ref: { - // include: ["refs/pull/**"] - // } - // }, + trigger: { + ref: { + include: ["refs/pull/**"] + } + }, - // steps: [ - // fetch_step, - // generate_docker_tags_step, - // build_website_docker_step(false), - // build_legacy_api_docker_step(false), - // ], - // }, + steps: [ + install_step, + lint_step, + build_step, + ], + }, - // Build the server and legacy API docker images and publish them for master and tags - // { - // kind: "pipeline", - // type: "docker", - // name: "build-publish-docker", + // Build and publish the package for master and tags + { + kind: "pipeline", + type: "docker", + name: "build-publish", - // trigger: { - // ref: { - // include: [ - // "refs/heads/master", - // "refs/tags/**", - // ] - // } - // }, + trigger: { + ref: { + include: [ + "refs/heads/master", + "refs/tags/**", + ] + } + }, - // steps: [ - // fetch_step, - // generate_docker_tags_step, - // build_website_docker_step(true), - // build_legacy_api_docker_step(true), - // ], - // }, + steps: [ + install_step, + lint_step, + build_step, + publish_step, + ], + }, ] diff --git a/bun.lockb b/bun.lockb index ada479ec1da18794383ac5e5eddefbc73b9585e2..6908c42eda6b88f7986caaa7d40c5bde6ba3a027 100755 GIT binary patch literal 152097 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%0D-{aP(G*!R=|NI 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, - to: AbstractClass, -) { - Object.getOwnPropertyNames(from).forEach(name => { - if (name === "length" - || name === "prototype" - ) - return - - Object.defineProperty( - to, - name, - Object.getOwnPropertyDescriptor(from, name) || Object.create(null), - ) - }) - - Object.getOwnPropertyNames(from.prototype).forEach(name => { - Object.defineProperty( - to.prototype, - name, - Object.getOwnPropertyDescriptor(from.prototype, name) || Object.create(null), - ) - }) -} - -export const flattenClass = < - C extends AbstractClass ->(class_: C) => - getInheritanceHierarchy(class_) - .reduce((flattened, current) => { - copyClassProperties(current, flattened) - return flattened - }, class {}) as C - -/** - * Returns an array of classes representing the inheritance hierarchy of a given class constructor. The array includes the given class constructor itself and all its parent classes in the order of inheritance. - * - * @param class_ The class constructor for which to generate the inheritance hierarchy. - * @returns An array of class constructors representing the inheritance hierarchy of `Class`. - */ -export function getInheritanceHierarchy( - class_: AbstractClass -): AbstractClass[] { - const parent = Object.getPrototypeOf(class_) - - return isClass(parent) - ? [...getInheritanceHierarchy(parent), class_] - : [class_] -} - -/** - * Determines whether a given value is a class constructor or not by checking if its `toString` method returns a string matching the pattern of a class definition. - * - * @param el The value to check for class constructor status. - * @returns A boolean indicating whether `el` is a class constructor or not. - */ -export const isClass = (el: { toString: () => string }) => - Boolean(el.toString().match(/^class(?: [.\S]+)?(?: extends [.\S]+)? {[\s\S]*}$/)) diff --git a/src/index.ts b/src/index.ts index 46c8360..fc70958 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,170 @@ -export * from "./class" -export * from "./trait" -export * from "./utils" +import { AbstractClass, AbstractConstructor, Opaque, UnionToIntersection } from "type-fest" + + +/** + * Represents the static members of a class. + * @template C - The class type. + */ +export type StaticMembers = Pick + + +/** + * Represents a trait that can be applied to a class. + * @template C - The abstract class type. + */ +export type Trait< + C extends AbstractClass +> = Opaque< + TraitApplier, + "thilatrait/Trait" +> + +/** + * Represents the function signature for applying a trait to a parent class. + * @template C - The abstract class type. + */ +export type TraitApplier< + C extends AbstractClass +> = + (Parent: AbstractConstructor) => C + +/** + * Unwraps the type of the class from a given trait. + * @template T - The trait type. + */ +export type UnwrapTraitC = + T extends Trait + ? C + : never + + +/** + * Creates a trait using the provided trait applier function. + * @template C - The abstract class type. + * @param applier - The trait applier function. + * @returns A trait. + * @example + * Creates a trait: + * ```ts + * const Permissible = trait(Parent => { + * abstract class Permissible extends Parent { + * static readonly defaultPermissions: string[] = [] + * permissions: string[] = [] + * + * constructor(...args: any[]) { + * super(...args) + * } + * } + * + * return Permissible + * }) + * ``` + * Creates a generic trait: + * ```ts + * const Identifiable = () => + * trait(Parent => { + * abstract class Identifiable extends Parent { + * abstract readonly id: ID + * + * equals(el: Identifiable) { + * return this.id === el.id + * } + * + * constructor(...args: any[]) { + * super(...args) + * } + * } + * + * return Identifiable + * }) + * ``` + */ +export function trait< + C extends AbstractClass +>( + applier: TraitApplier +) { + return applier as Trait +} + + +/** + * Extends a class with the given traits and expresses their combined functionality. + * @template C - The abstract class type. + * @template Traits - An array of traits. + * @param extend - The class to extend. + * @param traits - An array of traits to apply. + * @returns A new class type expressing the combined functionality of the base class and traits. + * @example + * Extends a superclass and applies traits: + * ```ts + * class User extends extendsAndExpresses(Entity, [Identifiable(), Permissible]) { + * readonly id: bigint + * + * constructor(id: bigint) { + * super() + * this.id = id + * } + * } + * ``` + */ +export function extendsAndExpresses< + C extends AbstractClass, + Traits extends readonly Trait[], +>( + extend: C, + traits: Traits, +) { + return traits.reduce( + (previous, trait) => trait(previous), + extend, + ) as ( + AbstractClass< + InstanceType & + UnionToIntersection< + InstanceType< + UnwrapTraitC< + Traits[number] + > + > + >, + + ConstructorParameters + > & + + StaticMembers & + StaticMembers< + UnionToIntersection< + UnwrapTraitC< + Traits[number] + > + > + > + ) +} + +/** + * Expresses the combined functionality of multiple traits. + * @template Traits - An array of trait. + * @param traits - An array of trait to apply. + * @returns A new class type expressing the combined functionality of the traits. + * @example + * Applies traits to a class: + * ```ts + * class User extends expresses(Identifiable(), Permissible) { + * readonly id: bigint + * + * constructor(id: bigint) { + * super() + * this.id = id + * } + * } + * ``` + */ +export function expresses< + Traits extends readonly Trait[], +>( + ...traits: Traits +) { + return extendsAndExpresses(Object, traits) +} diff --git a/src/legacy/tests.ts b/src/legacy/tests.ts new file mode 100644 index 0000000..e86528d --- /dev/null +++ b/src/legacy/tests.ts @@ -0,0 +1,74 @@ +import { AbstractClass } from "type-fest" +import { expresses } from "./trait" + + +function inspectClass(class_: AbstractClass) { + Object.getOwnPropertyNames(class_).forEach(name => { + console.log( + "[static]", + name, + Object.getOwnPropertyDescriptor(class_, name) + ) + }) + + Object.getOwnPropertyNames(class_.prototype).forEach(name => { + console.log( + "[prototype]", + name, + Object.getOwnPropertyDescriptor(class_.prototype, name) + ) + }) +} + + +abstract class Identified { + abstract id: ID + + equals(el: Identified) { + return this.id === el.id + } + + // initializer() { + // console.log("Identified initializer") + // } +} + +class ImplementsIdentifiable extends Identified { + id!: ID +} + + +abstract class Permissible { + static readonly defaultPermissions: string[] = [] + permissions: string[] = [] + // permissions!: string[] + + constructor() { + console.log("Permissible constructor") + } + + initializer() { + console.log("Permissible initializer") + this.permissions = [] + } +} + + +class User extends expresses( + Identified as typeof Identified, + // Identified, + Permissible, +) { + readonly id: bigint + + constructor(id: bigint) { + super() + this.id = id + } +} + +const user1 = new User(BigInt(1)) +const user2 = new User(BigInt(2)) + +console.log(user1) +console.log(user1.equals(user2)) diff --git a/src/legacy/trait.ts b/src/legacy/trait.ts new file mode 100644 index 0000000..10cc87b --- /dev/null +++ b/src/legacy/trait.ts @@ -0,0 +1,126 @@ +import { AbstractClass, Class, UnionToIntersection } from "type-fest" +import { StaticMembers, copyProperties, getInheritanceHierarchy } from "./util/class" + + +/** + * Represents a trait that can be used to define common behavior + * for classes and abstract classes. + * @typeParam T - The type of the trait. + */ +export type Trait = + AbstractClass + + +/** + * Creates a link class that expresses the given traits. + * @param traits - An array of traits to be expressed by the link class. + * @returns A dynamically created class that expresses the given traits. + * @typeParam Traits - An array of traits that the link class expresses. + */ +export function expresses< + Traits extends readonly Trait[] +>( + ...traits: Traits +) { + return makeLinkClass(traits) +} + + +/** + * Creates a link class that extends a base class and expresses the given traits. + * @param extend - The base class or abstract class to extend. + * @param traits - An array of traits to be expressed by the link class. + * @returns A dynamically created class that extends the given base class and expresses the given traits. + * @typeParam C - The type of the base class to extend. + * @typeParam Traits - An array of traits that the link class expresses. + */ +export function extendsAndExpresses< + C extends Class + | AbstractClass, + Traits extends readonly Trait[], +>( + extend: C, + ...traits: Traits +) { + return makeLinkClass(traits, extend) +} + + +/** + * Creates a link class that expresses the given traits and optionally extends a base class. + * @param traits - An array of traits to be expressed by the link class. + * @param extend - The base class or abstract class to extend (optional). + * @returns A dynamically created class that expresses the given traits and extends the base class. + * @typeParam Traits - An array of traits that the link class expresses. + * @typeParam C - The type of the base class to extend (optional). + */ +export function makeLinkClass< + Traits extends readonly Trait[], + C extends Class + | AbstractClass + | undefined = undefined, +>( + traits: Traits, + extend?: C, +) { + const class_ = extend + ? class extends extend { + constructor(...args: any[]) { + super(...args) + + traits.forEach(trait => { + trait.prototype.initializer?.call(this) + }) + } + } + : class { + constructor() { + traits.forEach(trait => { + trait.prototype.initializer?.call(this) + }) + } + } + + traits.forEach(trait => { + getInheritanceHierarchy(trait).forEach(current => { + copyProperties( + current, + class_, + ["name", "length"], + ["constructor"], + ) + }) + }) + + return class_ as unknown as ( + (C extends Class | AbstractClass + ? ( + AbstractClass< + InstanceType & + UnionToIntersection< + InstanceType< + Traits[number] + > + >, + + ConstructorParameters + > & + + StaticMembers + ) + : Trait< + UnionToIntersection< + InstanceType< + Traits[number] + > + > + > + ) & + + StaticMembers< + UnionToIntersection< + Traits[number] + > + > + ) +} diff --git a/src/legacy/util/class.ts b/src/legacy/util/class.ts new file mode 100644 index 0000000..518c960 --- /dev/null +++ b/src/legacy/util/class.ts @@ -0,0 +1,109 @@ +import { AbstractClass } from "type-fest" + + +/** + * Represents the static members of a class. + * + * @template C - The type of the class for which static members are extracted. + * @typeparam The static members of the class. + */ +export type StaticMembers = Pick + + +/** + * Flattens the inheritance hierarchy of a given class by copying all properties + * from its superclass chain into a single object. + * + * @template C - The type of the class to be flattened, extending AbstractClass. + * @param C - The class to be flattened. + * @returns A new class with properties flattened from the entire inheritance hierarchy. + */ +export function flattenClass< + C extends AbstractClass +>(class_: C) { + const flattenedClass = class {} as unknown as C + + getInheritanceHierarchy(class_).forEach(current => { + copyProperties(current, flattenedClass) + }) + + copyProperty(class_, flattenedClass, "name") + copyProperty(class_.prototype, flattenedClass.prototype, "constructor") + + return flattenedClass +} + + +/** + * Retrieves the inheritance hierarchy of a given class, including itself. + * + * @param class_ - The class for which the inheritance hierarchy is retrieved. + * @returns An array representing the inheritance hierarchy, ordered from the furthest in the hierarchy to `class_` itself. + */ +export function getInheritanceHierarchy( + class_: AbstractClass +): AbstractClass[] { + const parent = Object.getPrototypeOf(class_) + + return isClass(parent) + ? [...getInheritanceHierarchy(parent), class_] + : [class_] +} + + +/** + * Checks if a given element appears to be a class based on its string representation. + * + * @param el - The element to check for being a class. + * @returns `true` if the element is likely a class; otherwise, `false`. + */ +export function isClass(el: { toString: () => string }) { + return Boolean(el.toString().match(/^class(?: [.\S]+)?(?: extends [.\S]+)? {[\s\S]*}$/)) +} + + +/** + * Copies properties from one class to another, including static and prototype properties. + * + * @param from - The source class to copy properties from. + * @param to - The destination class to copy properties to. + */ +export function copyProperties( + from: AbstractClass, + to: AbstractClass, + ignoreKeys: string[] = [], + ignorePrototypeKeys: string[] = [], +) { + Object.getOwnPropertyNames(from).forEach(name => { + if (name === "prototype" + || ignoreKeys.find(v => v === name) + ) + return + + // console.log(from, to, name, Object.getOwnPropertyDescriptor(from, name)) + + copyProperty(from, to, name) + }) + + Object.getOwnPropertyNames(from.prototype).forEach(name => { + if (ignorePrototypeKeys.find(v => v === name)) + return + + // console.log(from, to, name, Object.getOwnPropertyDescriptor(from, name)) + + copyProperty(from.prototype, to.prototype, name) + }) +} + + +export function copyProperty( + from: unknown, + to: unknown, + name: string, +) { + Object.defineProperty( + to, + name, + Object.getOwnPropertyDescriptor(from, name) || Object.create(null), + ) +} diff --git a/src/tests.ts b/src/tests.ts index 4520fd6..37e9412 100644 --- a/src/tests.ts +++ b/src/tests.ts @@ -1,29 +1,62 @@ -import { mixTraits } from "./trait" +import { expresses, trait } from "." -abstract class Identified { - abstract id: ID +const Identifiable = () => + trait(Parent => { + abstract class Identifiable extends Parent { + abstract readonly id: ID - equals(el: Identified) { - return this.id === el.id + equals(el: Identifiable) { + return this.id === el.id + } + + constructor(...args: any[]) { + super(...args) + console.log("Identified constructor") + } + } + + return Identifiable + }) + +const ImplementsIdentifiable = (defaultID: ID) => + trait(Parent => { + abstract class ImplementsIdentifiable extends Identifiable()(Parent) { + id: ID = defaultID + } + + return ImplementsIdentifiable + }) + + +const Permissible = trait(Parent => { + abstract class Permissible extends Parent { + static readonly defaultPermissions: string[] = [] + permissions: string[] = [] + + constructor(...args: any[]) { + super(...args) + console.log("Permissible constructor") + } + } + + return Permissible +}) + + +const UserProto = expresses( + // Identifiable(), + ImplementsIdentifiable(0n), + Permissible, +) + +class User extends UserProto { + constructor(id: bigint) { + super() + this.id = id } } -abstract class ProvideIdentified extends Identified { - id!: ID -} - -abstract class Permissible { - protected permissions: string[] = [] -} - - -class User extends mixTraits( - Identified, - // Identified, - Permissible, -) { - id: bigint = BigInt(-1) -} - -const user = new User() +const user1 = new User(1n) +console.log(user1) +console.log(user1.equals(user1)) diff --git a/src/trait.ts b/src/trait.ts deleted file mode 100644 index 021d69a..0000000 --- a/src/trait.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { AbstractClass, Class, UnionToIntersection } from "type-fest" -import { copyClassProperties, flattenClass } from "./class" -import { StaticMembers } from "./utils" - - -export type Trait = - AbstractClass - - -// export function applyTrait< -// C extends Class | AbstractClass, -// TraitC extends Trait, -// >( -// class_: C, -// trait: TraitC, -// ) { -// copyClassProperties(trait, class_) - -// return class_ as ( -// (C extends Class -// ? Class< -// InstanceType & InstanceType, -// ConstructorParameters -// > -// : AbstractClass< -// InstanceType & InstanceType, -// ConstructorParameters -// > -// ) & -// StaticMembers & -// StaticMembers -// ) -// } - - -export const extendAndApplyTraits = < - C extends Class | AbstractClass, - Traits extends readonly Trait[], ->( - classToExtend: C, - traits: Traits, -) => - traits.reduce((class_, trait) => { - copyClassProperties(flattenClass(trait), class_) - return class_ - }, class extends classToExtend {}) as ( - AbstractClass< - InstanceType & - UnionToIntersection< - InstanceType - >, - - ConstructorParameters - > & - - StaticMembers< - C & - UnionToIntersection< - Traits[number] - > - > - ) - - -export const mixTraits = < - Traits extends readonly Trait[] ->( - ...traits: Traits -) => - traits.reduce((class_, trait) => { - copyClassProperties(flattenClass(trait), class_) - return class_ - }, class {}) as ( - Trait< - UnionToIntersection< - InstanceType< - Traits[number] - > - > - > & - - StaticMembers< - UnionToIntersection< - Traits[number] - > - > - ) diff --git a/src/utils.ts b/src/utils.ts deleted file mode 100644 index 87f5f52..0000000 --- a/src/utils.ts +++ /dev/null @@ -1 +0,0 @@ -export type StaticMembers = Pick