Compare commits

..

No commits in common. "c4483f073e8357106c43f481c3f1aefb82c637a4" and "b164c7d97f8c91181c4577f5e7e0a5a0b52c9667" have entirely different histories.

27 changed files with 40 additions and 62 deletions

View File

@ -1,12 +0,0 @@
import { describe, expectTypeOf, test } from "vitest";
describe("ArrayElement utils", () => {
test("Given an array, it should return the element type of the array", () => {
type ArrayElement<T extends readonly unknown[]> =
T extends readonly (infer U)[] ? U : never;
type result = ArrayElement<["a", "b", "c"]>;
expectTypeOf<result>().toEqualTypeOf<"a" | "b" | "c">();
});
});

View File

@ -1,17 +0,0 @@
/**
* Get the element type of an array.
*/
export type ArrayElement<T extends readonly unknown[]> =
T extends readonly (infer U)[] ? U : never;
/**
* Get the first element type of a tuple.
*/
export type TupleFirstElement<T extends readonly unknown[]> =
T extends readonly [infer U, ...unknown[]] ? U : never;
/**
* Get the LAST element type of a tuple.
*/
export type TupleLastElement<T extends readonly unknown[]> =
T extends readonly [...unknown[], infer U] ? U : never;

View File

@ -1 +0,0 @@
export * from "./array-element.js";

View File

@ -1,5 +1,5 @@
import { BaseFile } from "../../../files/base-file.js";
import { Entity } from "../entity.js"; import { Entity } from "../entity.js";
import { BaseFile } from "./base-file.js";
/** /**
* Represents a file as managed by the domain. * Represents a file as managed by the domain.

View File

@ -1,5 +1,5 @@
import { ImageMimeType } from "../../../files/mime-type.js";
import { DomainFile } from "./domain-file.js"; import { DomainFile } from "./domain-file.js";
import { ImageMimeType } from "./mime-type.js";
/** /**
* Represents an image file. * Represents an image file.

View File

@ -1,2 +1,10 @@
export * from "./base-file.js";
export * from "./bytes.js";
export * from "./domain-file.js"; export * from "./domain-file.js";
export * from "./image-file.js"; export * from "./image-file.js";
export * from "./invalid-file-type-error.js";
export * from "./is-mime-type.js";
export * from "./is-uploaded-file.js";
export * from "./media-file.js";
export * from "./mime-type.js";
export * from "./uploaded-file.js";

View File

@ -1,4 +1,4 @@
import { TaggedError } from "../error/tagged-error.js"; import { TaggedError } from "../../../error/tagged-error.js";
export class InvalidFileTypeError extends TaggedError<"InvalidFileTypeError"> { export class InvalidFileTypeError extends TaggedError<"InvalidFileTypeError"> {
constructor() { constructor() {

View File

@ -5,7 +5,7 @@ import { MimeType } from "./mime-type.js";
*/ */
export function isMimeType<T extends MimeType>( export function isMimeType<T extends MimeType>(
expectedMimeType: T, expectedMimeType: T,
actualMimeType: string, actualFileType: string,
): actualMimeType is T { ): actualFileType is T {
return actualMimeType.match("^" + expectedMimeType + "$") !== null; return actualFileType.match("^" + expectedMimeType + "$") !== null;
} }

View File

@ -1,5 +1,5 @@
import validator from "validator"; import validator from "validator";
import { isRecord } from "../record/is-record.js"; import { isRecord } from "../../../record/is-record.js";
import { InMemoryFile } from "./uploaded-file.js"; import { InMemoryFile } from "./uploaded-file.js";
const { isBase64, isMimeType } = validator; const { isBase64, isMimeType } = validator;

View File

@ -1,4 +1,4 @@
import { DomainFile } from "../domain/entity/files/domain-file.js"; import { DomainFile } from "./domain-file.js";
/** /**
* Represents a media file, either an image, a video or an audio file. * Represents a media file, either an image, a video or an audio file.

View File

@ -1,4 +1,4 @@
import { Base64String } from "../domain/types/base-64.js"; import { Base64String } from "../../types/base-64.js";
import { BaseFile } from "./base-file.js"; import { BaseFile } from "./base-file.js";
/** /**

View File

@ -1 +1,2 @@
export * from "./entity.js"; export * from "./entity.js";
export * from "./files/index.js";

View File

@ -1,8 +1,5 @@
import { TaggedVariant } from "../../variant/variant.js"; import { TaggedVariant } from "../../variant/variant.js";
/**
* An event is a tagged variant with a payload and a timestamp.
*/
export interface Event<TTag extends string, TPayload> export interface Event<TTag extends string, TPayload>
extends TaggedVariant<TTag> { extends TaggedVariant<TTag> {
payload: TPayload; payload: TPayload;

View File

@ -1,6 +1,3 @@
/**
* A PolicyMap maps user types to their security policies.
*/
export type PolicyMap< export type PolicyMap<
UserType extends string, UserType extends string,
PolicyType extends string, PolicyType extends string,

View File

@ -1,3 +1,3 @@
export * from "./email.js"; export * from "./email.js";
export * from "./semver.js"; export * from "./sem-ver.js";
export * from "./uuid.js"; export * from "./uuid.js";

View File

@ -3,6 +3,11 @@ import { AsyncResult } from "../../result/async-result.js";
/** /**
* A use case is a piece of domain logic that can be executed. * A use case is a piece of domain logic that can be executed.
*
* It can be one of two types:
*
* - `Query`: A use case that only reads data.
* - `Command`: A use case that modifies data.
*/ */
export type UseCase< export type UseCase<
TDependencies, TDependencies,

View File

@ -1,8 +1,15 @@
import { VariantTag } from "../variant/variant.js";
import { TaggedError } from "./tagged-error.js"; import { TaggedError } from "./tagged-error.js";
/** /**
* Indicates if a value is an error. * Indicates if a value is an error.
*
* In case it is an error, the type of the error is able to be inferred.
*/ */
export function isError(err: unknown): err is TaggedError<string> { export function isError(err: unknown): err is TaggedError<string> {
return err instanceof TaggedError; return (
err instanceof Error &&
VariantTag in err &&
typeof err[VariantTag] === "string"
);
} }

View File

@ -1,7 +1,9 @@
import { TaggedVariant, VariantTag } from "../variant/index.js"; import { TaggedVariant, VariantTag } from "../variant/index.js";
/** /**
* A TaggedError is a tagged variant with an error message. * Un TaggedError es un error que tiene un tag que lo identifica, lo cual
* permite a los consumidores de la instancia de error identificar el tipo de
* error que ocurrió.
*/ */
export class TaggedError<Tag extends string> export class TaggedError<Tag extends string>
extends Error extends Error

View File

@ -1,11 +1,11 @@
import { TaggedError } from "./tagged-error.js"; import { TaggedError } from "./tagged-error.js";
/** /**
* `UnexpectedError` represents any type of unexpected error. * `UnexpectedError` representa cualquier tipo de error inesperado.
* *
* This error is used to represent errors that should not occur in * Este error se utiliza para representar errores que no deberían ocurrir en
* the application logic, but that could always happen and * la lógica de la aplicación, pero que siempre podrían suceder y
* we must be prepared to handle. * debemos estar preparados para manejarlos.
*/ */
export class UnexpectedError extends TaggedError<"UnexpectedError"> { export class UnexpectedError extends TaggedError<"UnexpectedError"> {
constructor() { constructor() {

View File

@ -1,8 +0,0 @@
export * from "./base-file.js";
export * from "./bytes.js";
export * from "./invalid-file-type-error.js";
export * from "./is-mime-type.js";
export * from "./is-uploaded-file.js";
export * from "./media-file.js";
export * from "./mime-type.js";
export * from "./uploaded-file.js";

View File

@ -1,4 +1,3 @@
export * from "./array/index.js";
export * from "./domain/index.js"; export * from "./domain/index.js";
export * from "./error/index.js"; export * from "./error/index.js";
export * from "./record/index.js"; export * from "./record/index.js";

View File

@ -32,7 +32,7 @@ describe("timeout", () => {
}, },
); );
test("using timeout we can define a timeout in milliseconds", async () => { test("using ms we can define a timeout in milliseconds", async () => {
const start = Date.now(); const start = Date.now();
await timeout(100); await timeout(100);
const end = Date.now(); const end = Date.now();