diff --git a/README.md b/README.md index 1015336..40547d7 100644 --- a/README.md +++ b/README.md @@ -6,33 +6,35 @@ The following modules are considered public API ready for consumption: -- [`@enzastdlib/async`](./async) — Utilities for working with asynchronous and `Promise`-based code. -- [`@enzastdlib/collections`](./collections) — Utilities for working with collections like arrays and records. -- [`@enzastdlib/commands`](./commands) — Create command line tools with validation powered by [JSON Schema 2019-09](https://json-schema.org/specification-links.html#draft-2019-09-formerly-known-as-draft-8). -- [`@enzastdlib/decorators`](./decorators) — Create function decorators that access metadata with a streamlined API. -- [`@enzastdlib/environment`](./environment) — Parse and validate both environment variables and dotenv files powered by [JSON Schema 2019-09](https://json-schema.org/specification-links.html#draft-2019-09-formerly-known-as-draft-8). -- [`@enzastdlib/errors`](./errors) — General error objects that are used across `enzastdlib`. -- [`@enzastdlib/path`](./events) — Create typed events with a typed version of `EventTarget`. -- [`@enzastdlib/json5`](./json5) — Parse JSON5 documents and expressions. -- [`@enzastdlib/os`](./os) — Utilities for abstracting away operating system specifics. -- [`@enzastdlib/path`](./path) — Utilities for working with file system paths and URLs. -- [`@enzastdlib/realm`](./realm) — Create custom JavaScript and TypeScript execution environments. -- [`@enzastdlib/rpc`](./rpc) — Contains supplemental typing for creating fully typed and validated RPC clients and servers. -- [`@enzastdlib/rpc-http`](./rpc-http) — Create fully typed and validated RPC clients and servers using HTTP as the transport. -- [`@enzastdlib/rpc-messageport`](./rpc-messageport) — Create fully typed and validated RPC clients and servers using [`MessagePort`](https://developer.mozilla.org/en-US/docs/Web/API/MessagePort)-like API instances as the transport. -- [`@enzastdlib/rpc-protocol`](./rpc-protocol) — Create fully typed and validated RPC clients and servers powered by [JSON Schema 2019-09](https://json-schema.org/specification-links.html#draft-2019-09-formerly-known-as-draft-8). -- [`@enzastdlib/rpc-streams`](./rpc-streams) — Create fully typed and validated RPC clients and servers using a pair of [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) / [`WritableStream`](https://developer.mozilla.org/en-US/docs/Web/API/WritableStream) instances as the transport. -- [`@enzastdlib/schema`](./schema) — Create easy to use validators powered by [JSON Schema 2019-09](https://json-schema.org/specification-links.html#draft-2019-09-formerly-known-as-draft-8). -- [`@enzastdlib/strings`](./strings) — Utilities for working with strings. -- [`@enzastdlib/testing`](./testing) — Utilities for working with Deno's testing API. +- [`@enzastdlib/async`](https://deno.land/x/enzastdlib/async/mod.ts?doc) — Utilities for working with asynchronous and `Promise`-based code. +- [`@enzastdlib/collections`](https://deno.land/x/enzastdlib/collections/mod.ts?doc) — Utilities for working with collections like arrays and records. +- [`@enzastdlib/commands`](https://deno.land/x/enzastdlib/commands/mod.ts?doc) — Create command line tools with validation powered by [JSON Schema 2019-09](https://json-schema.org/specification-links.html#draft-2019-09-formerly-known-as-draft-8). +- [`@enzastdlib/decorators`](https://deno.land/x/enzastdlib/decorators/mod.ts?doc) — Create function decorators that access metadata with a streamlined API. +- [`@enzastdlib/environment`](https://deno.land/x/enzastdlib/environment/mod.ts?doc) — Parse and validate both environment variables and dotenv files powered by [JSON Schema 2019-09](https://json-schema.org/specification-links.html#draft-2019-09-formerly-known-as-draft-8). +- [`@enzastdlib/errors`](https://deno.land/x/enzastdlib/errors/mod.ts?doc) — General error objects that are used across `enzastdlib`. +- [`@enzastdlib/path`](https://deno.land/x/enzastdlib/events/mod.ts?doc) — Create typed events with a typed version of `EventTarget`. +- [`@enzastdlib/json5`](https://deno.land/x/enzastdlib/json5/mod.ts?doc) — Parse JSON5 documents and expressions. +- [`@enzastdlib/os`](https://deno.land/x/enzastdlib/os/mod.ts?doc) — Utilities for abstracting away operating system specifics. +- [`@enzastdlib/path`](https://deno.land/x/enzastdlib/path/mod.ts?doc) — Utilities for working with file system paths and URLs. +- [`@enzastdlib/realm`](https://deno.land/x/enzastdlib/realm/mod.ts?doc) — Create custom JavaScript and TypeScript execution environments. +- [`@enzastdlib/rpc`](https://deno.land/x/enzastdlib/rpc/mod.ts?doc) — Contains supplemental typing for creating fully typed and validated RPC clients and servers. +- [`@enzastdlib/rpc-http`](https://deno.land/x/enzastdlib/rpc-http/mod.ts?doc) — Create fully typed and validated RPC clients and servers using HTTP as the transport. +- [`@enzastdlib/rpc-messageport`](https://deno.land/x/enzastdlib/rpc-messageport/mod.ts?doc) — Create fully typed and validated RPC clients and servers using [`MessagePort`](https://developer.mozilla.org/en-US/docs/Web/API/MessagePort)-like API instances as the transport. +- [`@enzastdlib/rpc-protocol`](https://deno.land/x/enzastdlib/rpc-protocol/mod.ts?doc) — Create fully typed and validated RPC clients and servers powered by [JSON Schema 2019-09](https://json-schema.org/specification-links.html#draft-2019-09-formerly-known-as-draft-8). +- [`@enzastdlib/rpc-streams`](https://deno.land/x/enzastdlib/rpc-streams/mod.ts?doc) — Create fully typed and validated RPC clients and servers using a pair of [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) / [`WritableStream`](https://developer.mozilla.org/en-US/docs/Web/API/WritableStream) instances as the transport. +- [`@enzastdlib/schema`](https://deno.land/x/enzastdlib/schema/mod.ts?doc) — Create easy to use validators powered by [JSON Schema 2019-09](https://json-schema.org/specification-links.html#draft-2019-09-formerly-known-as-draft-8). +- [`@enzastdlib/strings`](https://deno.land/x/enzastdlib/strings/mod.ts?doc) — Utilities for working with strings. +- [`@enzastdlib/testing`](https://deno.land/x/enzastdlib/testing/mod.ts?doc) — Utilities for working with Deno's testing API. ## Importing -... +```typescript +import * as mod from 'https://deno.land/x/enzastdlib/.../mod.ts'; +``` ## Documentation -... +Visit the documentation at [Deno's module registry](https://deno.land/x/enzastdlib?doc). ## Need Help? diff --git a/TODO.md b/TODO.md index 2e69ec0..d5d3ec2 100644 --- a/TODO.md +++ b/TODO.md @@ -2,4 +2,8 @@ - Create API examples via the `@example` JSDoc annotation for all public API. +- Add possible thrown exceptions to all public API docs. + +- Add Deno flags used to all public API docs. + - Vendor external requirements. diff --git a/async/README.md b/async/README.md index 1c2ee80..4dfbcae 100644 --- a/async/README.md +++ b/async/README.md @@ -4,8 +4,10 @@ Utilities for working with asynchronous and `Promise`-based code. ## Importing -... +```typescript +import * as mod from 'https://deno.land/x/enzastdlib/async/mod.ts'; +``` ## Documentation -... +Visit the documentation at [Deno's module registry](https://deno.land/x/enzastdlib/async/mod.ts?doc). diff --git a/async/iterable.ts b/async/iterable.ts index e448310..30d04e4 100644 --- a/async/iterable.ts +++ b/async/iterable.ts @@ -1,3 +1,30 @@ +/** + * Returns all values collected from the `iterable` in an array. + * + * > **NOTE**: This function is the equivilent of [`Array.fromAsync`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fromAsync) + * > if it available in your runtime use that instead. + * + * @param iterable + * @returns + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { arrayFromIterable } from 'https://deno.land/x/enzastdlib/async/mod.ts'; + * + * async function* myGenerator(): AsyncGenerator { + * yield Promise.resolve(1); + * yield Promise.resolve(2); + * yield Promise.resolve(3); + * } + * + * const generator = myGenerator(); + * + * const numbers = await arrayFromIterable(generator); + * + * assertEquals(numbers, [1, 2, 3]); + * ``` + */ export async function arrayFromIterable( iterable: AsyncIterable, ): Promise { diff --git a/async/promise.ts b/async/promise.ts index 2e12ef9..fc28654 100644 --- a/async/promise.ts +++ b/async/promise.ts @@ -1,5 +1,18 @@ /** * Returns type wrapped in a `Promise` if not already a `Promise`-wrapped value. + * + * @example + * ```typescript + * import type { Promisify } from 'https://deno.land/x/enzastdlib/async/mod.ts'; + * + * function plainFunction(): number { + * return 1; + * } + * + * type plainFunctionReturn = ReturnType; // `number` + * + * type plainFunctionReturnPromisified = Promisify; // `Promise` + * ``` */ export type Promisify = Value extends Promise ? Value : Promise; @@ -8,6 +21,27 @@ export type Promisify = Value extends Promise ? Value * Returns a `Promise` instance along with its resolve and reject functions. * * @returns + * + * @example + * ```typescript + * import { + * assertEquals, + * assertInstanceOf, + * } from 'https://deno.land/std/testing/asserts.ts'; + * import { makePromise } from 'https://deno.land/x/enzastdlib/async/mod.ts'; + * import { assertTypeOf } from 'https://deno.land/x/enzastdlib/testing/mod.ts'; + * + * const { promise, resolve, reject } = makePromise(); + * + * assertInstanceOf(promise, Promise); + * + * assertTypeOf(resolve, 'function'); + * assertTypeOf(reject, 'function'); + * + * resolve(42); + * + * assertEquals(await promise, 42); + * ``` */ export function makePromise(): { promise: Promise; diff --git a/collections/README.md b/collections/README.md index 01afe14..ee42626 100644 --- a/collections/README.md +++ b/collections/README.md @@ -4,8 +4,10 @@ Utilities for working with collections like arrays and records. ## Importing -... +```typescript +import * as mod from 'https://deno.land/x/enzastdlib/collections/mod.ts'; +``` ## Documentation -... +Visit the documentation at [Deno's module registry](https://deno.land/x/enzastdlib/collections/mod.ts?doc). diff --git a/collections/class.ts b/collections/class.ts index 08c824a..f35eaba 100644 --- a/collections/class.ts +++ b/collections/class.ts @@ -2,6 +2,25 @@ import { OmitValues, PickValues } from './object.ts'; /** * Returns an `Object` containing all the methods of a `Class`. + * + * @example + * ```typescript + * import type { MethodsOf } from 'https://deno.land/x/enzastdlib/collections/mod.ts'; + * + * class MyClass { + * myProperty = false; + * + * methodOne(): number { + * return 42; + * } + * + * methodTwo(): string { + * return "Hello World"; + * } + * } + * + * type MyMethods = MethodsOf; // `{ methodOne: () => number; methodTwo: () => string; }` + * ``` */ export type MethodsOf = PickValues< Cls, @@ -12,6 +31,25 @@ export type MethodsOf = PickValues< /** * Returns an `Object` containing all the properties of a `Class`. + * + * @example + * ```typescript + * import type { PropertiesOf } from 'https://deno.land/x/enzastdlib/collections/mod.ts'; + * + * class MyClass { + * myProperty = false; + * + * methodOne(): number { + * return 42; + * } + * + * methodTwo(): string { + * return "Hello World"; + * } + * } + * + * type MyProperties = PropertiesOf; // `{ myProperty: boolean; }` + * ``` */ export type PropertiesOf = OmitValues< Cls, diff --git a/collections/object.ts b/collections/object.ts index 073d585..521313f 100644 --- a/collections/object.ts +++ b/collections/object.ts @@ -1,28 +1,87 @@ /** - * Represents an `Object` that has no properties. + * Represents an `Object` type that has no properties. + * + * @example + * ```typescript + * import type { EmptyObject } from 'https://deno.land/x/enzastdlib/collections/mod.ts'; + * + * type X = EmptyObject; // `{ [x: string]: never; [x: number]: never; [x: symbol]: never }` + * ``` */ export type EmptyObject = Record; /** - * Returns an `Object` where properties with `Type` as the their typing are omitted. + * Returns an `Object` where members with the given type are picked into a new `Object` type. + * + * @example + * ```typescript + * import type { PickValues } from 'https://deno.land/x/enzastdlib/collections/mod.ts'; + * + * const MY_CONSTANT_OBJECT = { + * myBoolean: false, + * + * myNumber: 42, + * + * myString: 'Hello World', + * + * otherNumber: 84, + * } as const; + * + * type FilteredValues = PickValues; // `{ readonly myNumber: 42; readonly otherNumber: 84; }` */ export type PickValues = { [Key in keyof Obj as Obj[Key] extends Value ? Key : never]: Obj[Key]; }; /** - * Returns an `Object` where properties with `Type` as the their typing are omitted. + * Returns an `Object` where members with the given type are omitted from a new `Object` type. + * + * @example + * ```typescript + * import type { OmitValues } from 'https://deno.land/x/enzastdlib/collections/mod.ts'; + * + * const MY_CONSTANT_OBJECT = { + * myBoolean: false, + * + * myNumber: 42, + * + * myString: 'Hello World', + * + * otherNumber: 84, + * } as const; + * + * type FilteredValues = OmitValues; // `{ readonly myBoolean: false; readonly myString: "Hello World"; }` */ export type OmitValues = { [Key in keyof Obj as Obj[Key] extends Value ? never : Key]: Obj[Key]; }; /** - * Returns all the values of an `Object` as a type union. + * Returns all the values of an `Object` as a type union of its values. + * + * @example + * ```typescript + * import type { ValueOf } from 'https://deno.land/x/enzastdlib/collections/mod.ts'; + * + * const MY_CONSTANT_OBJECT = { + * x: 1, + * y: 2, + * z: 3 + * } as const; + * + * type MyValues = ValueOf; // `1 | 2 | 3` + * ``` */ export type ValueOf = Obj[keyof Obj]; /** - * Represents an `Object` that has unknown properties. + * Represents an `Object` type that has unknown properties. + * + * @example + * ```typescript + * import type { UnknownObject } from 'https://deno.land/x/enzastdlib/collections/mod.ts'; + * + * type X = UnknownObject; // `{ [x: string]: unknown; [x: number]: unknown; [x: symbol]: unknown }` + * ``` */ export type UnknownObject = Record; diff --git a/commands/README.md b/commands/README.md index b6cb940..b90907e 100644 --- a/commands/README.md +++ b/commands/README.md @@ -4,11 +4,13 @@ Create command line tools with validation powered by [JSON Schema 2019-09](https ## Importing -... +```typescript +import * as mod from 'https://deno.land/x/enzastdlib/commands/mod.ts'; +``` ## Documentation -... +Visit the documentation at [Deno's module registry](https://deno.land/x/enzastdlib/commands/mod.ts?doc). ## Dependencies diff --git a/commands/exit_codes.ts b/commands/exit_codes.ts index 21f33cc..ae31918 100644 --- a/commands/exit_codes.ts +++ b/commands/exit_codes.ts @@ -10,8 +10,8 @@ export const EXIT_CODES = { /** * Represents when the command was called successfully. * - * **NOTE**: By default this value is used if no number - * is returned by the commands callback. + * > **NOTE**: By default this value is used if no number + * > is returned by the commands callback. */ resolved: 0, diff --git a/decorators/README.md b/decorators/README.md index a064bb4..2cd1a08 100644 --- a/decorators/README.md +++ b/decorators/README.md @@ -4,8 +4,10 @@ Create function decorators that access metadata with a streamlined API. ## Importing -... +```typescript +import * as mod from 'https://deno.land/x/enzastdlib/decorators/mod.ts'; +``` ## Documentation -... +Visit the documentation at [Deno's module registry](https://deno.land/x/enzastdlib/decorators/mod.ts?doc). diff --git a/environment/README.md b/environment/README.md index 7ef1cfb..2dae729 100644 --- a/environment/README.md +++ b/environment/README.md @@ -4,11 +4,13 @@ Parse and validate both environment variables and dotenv files powered by [JSON ## Importing -... +```typescript +import * as mod from 'https://deno.land/x/enzastdlib/environment/mod.ts'; +``` ## Documentation -... +Visit the documentation at [Deno's module registry](https://deno.land/x/enzastdlib/environment/mod.ts?doc). ## Compatibility diff --git a/errors/README.md b/errors/README.md index 3536a9e..316e341 100644 --- a/errors/README.md +++ b/errors/README.md @@ -4,8 +4,10 @@ General error objects that are used across `enzastdlib`. ## Importing -... +```typescript +import * as mod from 'https://deno.land/x/enzastdlib/errors/mod.ts'; +``` ## Documentation -... +Visit the documentation at [Deno's module registry](https://deno.land/x/enzastdlib/errors/mod.ts?doc). diff --git a/errors/internalerror.ts b/errors/internalerror.ts index 142c2ed..6123acb 100644 --- a/errors/internalerror.ts +++ b/errors/internalerror.ts @@ -1,6 +1,15 @@ /** - * Represents an exception regarding an error that occured within - * the internals of a system. + * Represents an exception regarding an error that occured within the internals + * of a system. + * + * @example + * ```typescript + * import { InternalError } from 'https://deno.land/x/enzastdlib/errors/mod.ts'; + * + * throw new InternalError( + * 'an exception occured while processing the http request', + * ); + * ``` */ export class InternalError extends Error { readonly name = InternalError.name; diff --git a/errors/validationerror.ts b/errors/validationerror.ts index 3afb966..919703d 100644 --- a/errors/validationerror.ts +++ b/errors/validationerror.ts @@ -1,5 +1,14 @@ /** - * Represents an exception regarding validation of data or input. + * Represents an exception regarding user-facing validation of data or input. + * + * @example + * ```typescript + * import { ValidationError } from 'https://deno.land/x/enzastdlib/errors/mod.ts'; + * + * throw new ValidationError( + * 'property \'MyInterface.myProperty\' was a \'string\', expected \'number\'', + * ); + * ``` */ export class ValidationError extends Error { readonly name = ValidationError.name; diff --git a/events/README.md b/events/README.md index 64c58a5..93ddb40 100644 --- a/events/README.md +++ b/events/README.md @@ -4,8 +4,10 @@ Create typed events with a typed version of `EventTarget`. ## Importing -... +```typescript +import * as mod from 'https://deno.land/x/enzastdlib/events/mod.ts'; +``` ## Documentation -... +Visit the documentation at [Deno's module registry](https://deno.land/x/enzastdlib/events/mod.ts?doc). diff --git a/events/eventtarget.ts b/events/eventtarget.ts index ad0cc8d..9e99ae9 100644 --- a/events/eventtarget.ts +++ b/events/eventtarget.ts @@ -1,6 +1,13 @@ -export type TypedEventMap = Record; +// **NOTE**: The method descriptions of `TypedEventTarget` was taken from +// TypeScript's built-in descriptions of `EventTarget`. -export type TypedEventListener = +/** + * Represents the expected listener typing passed to `TypedEventTarget.addEventListener` + * and `TypedEventTarget.removeEventListener`. + * + * @private + */ +type TypedEventListener = | (( evt: Event, ) => void | Promise) @@ -8,11 +15,133 @@ export type TypedEventListener = handleEvent(evt: Event): void | Promise; }; -export class TypedEventTarget +/** + * Represents a record of event names associated with their `CustomEvent`-derived + * classes. + * + * @example + * ```typescript + * class UpdateEvent extends CustomEvent<{ original: unknown, replacement: unknown }> {} + * + * // **NOTE**: While you can import this type and use `interface MyEvents extends TypedEventRecord` + * // you will lose autocomplete in IDEs. + * // + * // So this example is just showcasing the expected interface of `Record`. + * type MyEvents = { + * update: UpdateEvent; + * }; + * ``` + */ +export type TypedEventRecord = Record; + +/** + * Represents a strongly-typed inheritable verison of the standard Web API `EventTarget`. + * + * @example + * ```typescript + * import { + * assertEquals, + * assertInstanceOf, + * } from 'https://deno.land/std/testing/asserts.ts'; + * import { TypedEventTarget } from 'https://deno.land/x/enzastdlib/events/mod.ts'; + * + * interface UpdateEventDetail { + * original: unknown; + * + * replacement: unknown; + * } + * + * class UpdateEvent extends CustomEvent { + * constructor(detail: UpdateEventDetail) { + * // **IMPORTANT**: Make sure to set the name of your event in the + * // constructor to match the one located in your event record. + * // + * // Which in this case is `update`. + * super('update', { detail }); + * } + * } + * + * type MyEvents = { + * update: UpdateEvent; + * }; + * + * class MyEventTarget extends TypedEventTarget {} + * + * // **NOTE**: Alternatively you can just construct the `TypedEventTarget` without + * // using inheritence: + * // + * // const event_target = new TypedEventTarget(); + * const event_target = new MyEventTarget(); + * + * assertInstanceOf(event_target, EventTarget); + * + * event_target.addEventListener('update', (event: UpdateEvent): void => { + * assertInstanceOf(event, CustomEvent); + * + * assertEquals(event.detail, { + * original: 42, + * replacement: 82, + * }); + * }); + * + * const event = new UpdateEvent({ + * original: 42, + * replacement: 84, + * }); + * + * event_target.dispatchEvent(event); + * ``` + */ +export class TypedEventTarget extends EventTarget { - addEventListener( + /** + * Appends an event listener for events whose type attribute value is type. The + * callback argument sets the callback that will be invoked when the event is + * dispatched. + * + * The options argument sets listener-specific options. For compatibility this + * can be a boolean, in which case the method behaves exactly as if the value was + * specified as options's capture. + * + * When set to true, options's capture prevents callback from being invoked when + * the event's eventPhase attribute value is BUBBLING_PHASE. When false (or not present), + * callback will not be invoked when event's eventPhase attribute value is + * CAPTURING_PHASE. Either way, callback will be invoked if event's eventPhase + * attribute value is AT_TARGET. + * + * When set to true, options's passive indicates that the callback will not + * cancel the event by invoking preventDefault(). This is used to enable performance + * optimizations described in § 2.8 Observing event listeners. + * + * When set to true, options's once indicates that the callback will only be + * invoked once after which the event listener will be removed. + * + * The event listener is appended to target's event listener list and is not + * appended if it has the same type, callback, and capture. + * + * @param type + * @param listener + * @param options + * + * @example + * ```typescript + * import { TypedEventTarget } from 'https://deno.land/x/enzastdlib/events/mod.ts'; + * + * type MyEvents = { + * myEvent: CustomEvent<{ myValue: number }>; + * }; + * + * const event_target = new TypedEventTarget(); + * + * event_target.addEventListener( + * 'myEvent', + * (event) => console.log(event.detail.myValue), + * ); + * ``` + */ + addEventListener( type: Type, - listener: TypedEventListener | null, + listener: TypedEventListener | null, options?: boolean | AddEventListenerOptions | undefined, ): void { super.addEventListener( @@ -25,15 +154,64 @@ export class TypedEventTarget ); } - dispatchEvent( + /** + * Dispatches a synthetic event event to target and returns true if either event's + * cancelable attribute value is false or its preventDefault() method was not + * invoked, and false otherwise. + * + * @param event + * @returns + * + * @example + * ```typescript + * import { TypedEventTarget } from 'https://deno.land/x/enzastdlib/events/mod.ts'; + * + * const event_target = new TypedEventTarget< + * { myEvent: CustomEvent<{ myValue: number }> } + * >(); + * + * const event = new CustomEvent('myEvent', { detail: { myValue: 1 } }); + * + * event_target.addEventListener('myEvent', console.log); + * + * event_target.dispatchEvent(event); // `{ myValue: 1 }` + * ``` + */ + dispatchEvent( event: Event, ): boolean { return super.dispatchEvent(event); } - removeEventListener( + /** + * Removes the event listener in target's event listener list with the same type, + * callback, and options. + * + * @param type + * @param listener + * @param options + * + * @example + * ```typescript + * import { TypedEventTarget } from 'https://deno.land/x/enzastdlib/events/mod.ts'; + * + * type MyEvents = { + * myEvent: CustomEvent<{ myValue: number }>; + * }; + * + * function onMyEvent(event: MyEvents['myEvent']): void { + * console.log(event.detail.myValue); + * } + * + * const event_target = new TypedEventTarget(); + * + * event_target.addEventListener('myEvent', onMyEvent); + * event_target.removeEventListener('myEvent', onMyEvent); + * ``` + */ + removeEventListener( type: Type, - listener: TypedEventListener | null, + listener: TypedEventListener | null, options?: boolean | EventListenerOptions | undefined, ): void { super.removeEventListener( diff --git a/json5/README.md b/json5/README.md index 93a4f43..5c5262c 100644 --- a/json5/README.md +++ b/json5/README.md @@ -4,11 +4,13 @@ Parse JSON5 documents and expressions. ## Importing -... +```typescript +import * as mod from 'https://deno.land/x/enzastdlib/json5/mod.ts'; +``` ## Documentation -... +Visit the documentation at [Deno's module registry](https://deno.land/x/enzastdlib/json5/mod.ts?doc). ## Dependencies diff --git a/json5/TODO.md b/json5/TODO.md index ed974ea..9ef6f44 100644 --- a/json5/TODO.md +++ b/json5/TODO.md @@ -1,5 +1,4 @@ # TODO -- Add docstrings. - +- Add tests for `parseJSON5ExpressionRecord`. - Vendor dependencies into single file importable scripts. diff --git a/json5/document.ts b/json5/document.ts index 6dc9662..a133ded 100644 --- a/json5/document.ts +++ b/json5/document.ts @@ -1,5 +1,42 @@ import { parse, stringify } from '../vendor/@CesiumLabs-json5.ts'; +/** + * Parses a JSON5 document into a JavaScript value. + * + * @param text + * @param reviver + * @returns + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { parseJSON5 } from 'https://deno.land/x/enzastdlib/json5/mod.ts'; + * + * assertEquals( + * parseJSON5(`{propA:'Hello',propB:'World!'}`), + * { propA: 'Hello', propB: 'World!' } + * ); + * ``` + */ export const parseJSON5 = parse; +/** + * Returns a JavaScript value stringified into a JSON5 document. + * + * @param value + * @param replacer + * @param space + * @returns + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { stringifyJSON5 } from 'https://deno.land/x/enzastdlib/json5/mod.ts'; + * + * assertEquals( + * stringifyJSON5({ propA: 'Hello', propB: 'World!' }), + * `{propA:'Hello',propB:'World!'}` + * ); + * ``` + */ export const stringifyJSON5 = stringify; diff --git a/json5/expression.ts b/json5/expression.ts index c219ebe..fd1f900 100644 --- a/json5/expression.ts +++ b/json5/expression.ts @@ -8,6 +8,56 @@ import type { } from './types.ts'; import { JSON5_TYPE_NAMES } from './types.ts'; +/** + * Returns an expression parsed following a simplified JSON5 syntax. + * + * > **NOTE**: If your specified type has start / end delimiters those are not required. + * > + * > ex. For objects use `propA: 'Hello', propB: 'World!'` instead of `{ propA: 'Hello', propB: 'World!' }` + * + * @param type + * @param expression + * @returns + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { + * JSON5_TYPE_NAMES, + * parseJSON5Expression, + * } from 'https://deno.land/x/enzastdlib/json5/mod.ts'; + * + * assertEquals( + * parseJSON5Expression(JSON5_TYPE_NAMES.array, `'Hello', 'World!'`), + * ['Hello', 'World!'] + * ); + * + * assertEquals( + * parseJSON5Expression(JSON5_TYPE_NAMES.boolean, 'true'), + * true + * ); + * + * assertEquals( + * parseJSON5Expression(JSON5_TYPE_NAMES.null, 'null'), + * null + * ); + * + * assertEquals( + * parseJSON5Expression(JSON5_TYPE_NAMES.number, '42'), + * 42 + * ); + * + * assertEquals( + * parseJSON5Expression(JSON5_TYPE_NAMES.object, `propA: 'Hello', propB: 'World!'`), + * { propA: 'Hello', propB: 'World!' } + * ); + * + * assertEquals( + * parseJSON5Expression(JSON5_TYPE_NAMES.string, 'Hello World!'), + * 'Hello World!' + * ); + * ``` + */ export function parseJSON5Expression( type: (typeof JSON5_TYPE_NAMES)['array'], expression: string, diff --git a/json5/record.ts b/json5/record.ts index f09baf5..e8af6f7 100644 --- a/json5/record.ts +++ b/json5/record.ts @@ -2,8 +2,72 @@ import { parseJSON5Expression } from './expression.ts'; import type { JSONSchema, JSONSchemaObject } from '../schema/mod.ts'; +/** + * Represents a record of JSON5 expressions. + * + * @example + * ```typescript + * import type { JSON5ExpressionRecord } from 'https://deno.land/x/enzastdlib/json5/mod.ts'; + * + * const record = { + * myArray: `'Hello', 'World!'`, + * } satisfies JSON5ExpressionRecord; + * ``` + */ export type JSON5ExpressionRecord = Record; +/** + * Returns an expression parsed following a simplified JSON5 syntax using a + * a JSON Schema for type hinting. + * + * > **WARNING**: Only top-level keys are used for type hinting during parsing. + * + * @param schema + * @param record + * @returns + * + * @example + * **schema.ts** + * ```typescript + * import type { JSONSchema, typeofschema } from 'https://deno.land/x/enzastdlib/schema/mod.ts'; + * + * export const MY_SCHEMA = { + * type: 'object', + * + * required: ['_'], + * additionalProperties: false, + * + * properties: { + * myArray: { + * type: 'array', + * + * items: { + * type: 'string', + * }, + * }, + * }, + * } as const satisfies JSONSchema; + * + * export type MySchemaType = typeofschema; + * ``` + * + * **mod.ts** + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { parseJSON5ExpressionRecord } from 'https://deno.land/x/enzastdlib/json5/mod.ts'; + * + * import type { MySchemaType } from "./schema.ts"; + * import { MY_SCHEMA } from "./schema.ts"; + * + * const parsed = parseJSON5ExpressionRecord(MY_SCHEMA, { + * myArray: `'Hello', 'World!'`, + * }); + * + * assertEquals(parsed, { + * myArray: ['Hello', 'World!'], + * }); + * ``` + */ export function parseJSON5ExpressionRecord( schema: JSONSchemaObject, record: JSON5ExpressionRecord, diff --git a/os/README.md b/os/README.md index d8e448e..ea43570 100644 --- a/os/README.md +++ b/os/README.md @@ -4,11 +4,13 @@ Utilities for abstracting away operating system specifics. ## Importing -... +```typescript +import * as mod from 'https://deno.land/x/enzastdlib/os/mod.ts'; +``` ## Documentation -... +Visit the documentation at [Deno's module registry](https://deno.land/x/enzastdlib/os/mod.ts?doc). ## Compatibility @@ -25,3 +27,7 @@ The following functions are compatible with Deno only: This module imports the following external libraries: - https://github.com/denoland/deno_std/tree/main/path + +## Credits + +- https://github.com/adrg/xdg — Had concise documentation for polyfilling the XDG Base Directory spec on non-XDG platforms. diff --git a/os/darwin.ts b/os/darwin.ts index e00bcdd..b0d1dd3 100644 --- a/os/darwin.ts +++ b/os/darwin.ts @@ -2,28 +2,93 @@ import { join } from '../vendor/@deno-std-path.ts'; /** * Returns the home directory of the current user. + * + * > **NOTE**: Returns the value of the environment variable `$HOME`. + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { getUserHome } from 'https://deno.land/x/enzastdlib/os/darwin.ts'; + * + * assertEquals( + * getUserHome(), + * '/Users/novacbn' + * ); + * ``` */ export const getUserHome = () => Deno.env.get('HOME')!; /** * Returns the cached data directory of the current user. + * + * > **NOTE**: Returns the value of the environment variable `$HOME` joined with `Library/Caches`. + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { getUserCache } from 'https://deno.land/x/enzastdlib/os/darwin.ts'; + * + * assertEquals( + * getUserCache(), + * '/Users/novacbn/Library/Caches' + * ); + * ``` */ export const getUserCache = () => join(getUserHome(), 'Library', 'Caches'); /** * Returns the config directory of the current user. + * + * > **NOTE**: Returns the value of the environment variable `$HOME` joined with `Library/Application Support`. + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { getUserConfig } from 'https://deno.land/x/enzastdlib/os/darwin.ts'; + * + * assertEquals( + * getUserConfig(), + * '/Users/novacbn/Library/Application Support' + * ); + * ``` */ export const getUserConfig = () => join(getUserHome(), 'Library', 'Application Support'); /** * Returns the data directory of the current user. + * + * > **NOTE**: Returns the value of the environment variable `$HOME` joined with `Library/Application Support`. + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { getUserData } from 'https://deno.land/x/enzastdlib/os/darwin.ts'; + * + * assertEquals( + * getUserData(), + * '/Users/novacbn/Library/Application Support' + * ); + * ``` */ export const getUserData = () => join(getUserHome(), 'Library', 'Application Support'); /** * Returns the state directory of the current user. + * + * > **NOTE**: Returns the value of the environment variable `$HOME` joined with `Library/Application Support`. + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { getUserState } from 'https://deno.land/x/enzastdlib/os/darwin.ts'; + * + * assertEquals( + * getUserState(), + * '/Users/novacbn/Library/Application Support' + * ); + * ``` */ export const getUserState = () => join(getUserHome(), 'Library', 'Application Support'); diff --git a/os/linux.ts b/os/linux.ts index cb03157..d2319b4 100644 --- a/os/linux.ts +++ b/os/linux.ts @@ -2,11 +2,38 @@ import { join } from '../vendor/@deno-std-path.ts'; /** * Returns the home directory of the current user. + * + * > **NOTE**: Returns the value of the environment variable `$HOME`. + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { getUserHome } from 'https://deno.land/x/enzastdlib/os/linux.ts'; + * + * assertEquals( + * getUserHome(), + * '/home/novacbn' + * ); + * ``` */ export const getUserHome = () => Deno.env.get('HOME')!; /** * Returns the cached data directory of the current user. + * + * > **NOTE**: Returns the value of the environment variable `XDG_CACHE_HOME` or `$HOME` + * > joined with `.cache` as a fallback. + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { getUserCache } from 'https://deno.land/x/enzastdlib/os/linux.ts'; + * + * assertEquals( + * getUserCache(), + * '/home/novacbn/.cache' + * ); + * ``` */ export const getUserCache = () => Deno.env.get('XDG_CACHE_HOME') ?? @@ -14,6 +41,20 @@ export const getUserCache = () => /** * Returns the config directory of the current user. + * + * > **NOTE**: Returns the value of the environment variable `XDG_CONFIG_HOME` or `$HOME` + * > joined with `.config` as a fallback. + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { getUserConfig } from 'https://deno.land/x/enzastdlib/os/linux.ts'; + * + * assertEquals( + * getUserConfig(), + * '/home/novacbn/.config' + * ); + * ``` */ export const getUserConfig = () => Deno.env.get('XDG_CONFIG_HOME') ?? @@ -21,6 +62,20 @@ export const getUserConfig = () => /** * Returns the data directory of the current user. + * + * > **NOTE**: Returns the value of the environment variable `XDG_DATA_HOME` or `$HOME` + * > joined with `.local/share` as a fallback. + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { getUserData } from 'https://deno.land/x/enzastdlib/os/linux.ts'; + * + * assertEquals( + * getUserData(), + * '/home/novacbn/.local/share' + * ); + * ``` */ export const getUserData = () => Deno.env.get('XDG_DATA_HOME') ?? @@ -28,6 +83,20 @@ export const getUserData = () => /** * Returns the state directory of the current user. + * + * > **NOTE**: Returns the value of the environment variable `XDG_STATE_HOME` or `$HOME` + * > joined with `.local/state` as a fallback. + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { getUserState } from 'https://deno.land/x/enzastdlib/os/linux.ts'; + * + * assertEquals( + * getUserState(), + * '/home/novacbn/.local/state' + * ); + * ``` */ export const getUserState = () => Deno.env.get('XDG_STATE_HOME') ?? diff --git a/os/mod.ts b/os/mod.ts index 04e18e5..02dcce8 100644 --- a/os/mod.ts +++ b/os/mod.ts @@ -1,6 +1,9 @@ /** * Utilities for abstracting away operating system specifics. * + * > **NOTE**: You can import individual platforms via `import { ... } from 'https://deno.land/x/enzastdlib/os/${PLATFORM}.ts';` + * > or have the platform be auto-detected via `import { ... } from 'https://deno.land/x/enzastdlib/os/mod.ts';`. + * * @module */ diff --git a/os/windows.ts b/os/windows.ts index 81007bf..155b392 100644 --- a/os/windows.ts +++ b/os/windows.ts @@ -1,24 +1,89 @@ /** * Returns the cached data directory of the current user. + * + * > **NOTE**: Returns the value of the environment variable `%LocalAppData%`. + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { getUserCache } from 'https://deno.land/x/enzastdlib/os/windows.ts'; + * + * assertEquals( + * getUserCache(), + * 'C:\\Users\\novacbn\\AppData\\Local' + * ); + * ``` */ export const getUserCache = () => Deno.env.get('LocalAppData')!; /** * Returns the config directory of the current user. + * + * > **NOTE**: Returns the value of the environment variable `%AppData%`. + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { getUserConfig } from 'https://deno.land/x/enzastdlib/os/windows.ts'; + * + * assertEquals( + * getUserConfig(), + * 'C:\\Users\\novacbn\\AppData\\Roaming' + * ); + * ``` */ export const getUserConfig = () => Deno.env.get('AppData')!; /** * Returns the data directory of the current user. + * + * > **NOTE**: Returns the value of the environment variable `%LocalAppData%`. + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { getUserData } from 'https://deno.land/x/enzastdlib/os/windows.ts'; + * + * assertEquals( + * getUserData(), + * 'C:\\Users\\novacbn\\AppData\\Local' + * ); + * ``` */ export const getUserData = () => Deno.env.get('LocalAppData')!; /** * Returns the home directory of the current user. + * + * > **NOTE**: Returns the value of the environment variable `%USERPROFILE%`. + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { getUserHome } from 'https://deno.land/x/enzastdlib/os/windows.ts'; + * + * assertEquals( + * getUserHome(), + * 'C:\\Users\\novacbn' + * ); + * ``` */ export const getUserHome = () => Deno.env.get('USERPROFILE')!; /** * Returns the state directory of the current user. + * + * > **NOTE**: Returns the value of the environment variable `%LocalAppData%`. + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { getUserState } from 'https://deno.land/x/enzastdlib/os/windows.ts'; + * + * assertEquals( + * getUserState(), + * 'C:\\Users\\novacbn\\AppData\\Local' + * ); + * ``` */ export const getUserState = () => Deno.env.get('LocalAppData')!; diff --git a/path/README.md b/path/README.md index 0ab9c11..258ec08 100644 --- a/path/README.md +++ b/path/README.md @@ -4,8 +4,10 @@ Utilities for working with file system paths and URLs. ## Importing -... +```typescript +import * as mod from 'https://deno.land/x/enzastdlib/path/mod.ts'; +``` ## Documentation -... +Visit the documentation at [Deno's module registry](https://deno.land/x/enzastdlib/path/mod.ts?doc). diff --git a/path/issubpath.ts b/path/issubpath.ts index d0e92fd..ee6ffaf 100644 --- a/path/issubpath.ts +++ b/path/issubpath.ts @@ -6,6 +6,17 @@ import { relative } from '../vendor/@deno-std-path.ts'; * @param parent * @param child * @returns + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { isSubPath } from 'https://deno.land/x/enzastdlib/path/mod.ts'; + * + * assertEquals( + * isSubPath('/home/novacbn', '/home/novacbn/Pictures'), + * true + * ); + * ``` */ export function isSubPath(parent: string, child: string): boolean { const relative_path = relative(parent, child); diff --git a/path/issuburl.ts b/path/issuburl.ts index 951214a..9ebb496 100644 --- a/path/issuburl.ts +++ b/path/issuburl.ts @@ -6,6 +6,20 @@ import { relativePathname } from './relativepathname.ts'; * @param parent * @param child * @returns + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { isSubURL } from 'https://deno.land/x/enzastdlib/path/mod.ts'; + * + * const URL_A = new URL("https://example.domain/assets"); + * const URL_B = new URL("https://example.domain/assets/scripts/main.js"); + * + * assertEquals( + * isSubURL(URL_A, URL_B), + * true + * ); + * ``` */ export function isSubURL(parent: URL, child: URL): boolean { if (parent.origin !== child.origin) return false; diff --git a/path/relativepathname.ts b/path/relativepathname.ts index 6ec06cc..9a83171 100644 --- a/path/relativepathname.ts +++ b/path/relativepathname.ts @@ -8,6 +8,20 @@ const { relative } = posix; * @param from * @param to * @returns + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { relativePathname } from 'https://deno.land/x/enzastdlib/path/mod.ts'; + * + * const URL_A = new URL("https://example.domain/assets"); + * const URL_B = new URL("https://example.domain/assets/scripts/main.js"); + * + * assertEquals( + * relativePathname(URL_A, URL_B), + * 'scripts/main.js' + * ); + * ``` */ export function relativePathname(from: URL, to: URL): string { return relative(from.pathname, to.pathname); diff --git a/realm/README.md b/realm/README.md index 59416c6..475d187 100644 --- a/realm/README.md +++ b/realm/README.md @@ -11,11 +11,13 @@ Create custom JavaScript and TypeScript execution environments. ## Importing -... +```typescript +import * as mod from 'https://deno.land/x/enzastdlib/realm/mod.ts'; +``` ## Documentation -... +Visit the documentation at [Deno's module registry](https://deno.land/x/enzastdlib/realm/mod.ts?doc). ## Compatibility diff --git a/realm/evaluate.ts b/realm/evaluate.ts index 03adea4..e50399e 100644 --- a/realm/evaluate.ts +++ b/realm/evaluate.ts @@ -9,7 +9,7 @@ export interface EvaluateModuleOptions { /** * Represents the `globalThis` global object exposed to the execution environment. * - * **NOTE**: All members of this object will be exposed as globals to the evaluated + * > **NOTE**: All members of this object will be exposed as globals to the evaluated * code. */ readonly globalThis?: GlobalThisType; diff --git a/realm/mod.ts b/realm/mod.ts index d44dd76..c2f6552 100644 --- a/realm/mod.ts +++ b/realm/mod.ts @@ -10,9 +10,9 @@ * * This module imports the following external libraries: * + * - https://github.com/denoland/deno_emit * - https://github.com/denoland/deno_std/tree/main/fs * - https://github.com/denoland/deno_std/tree/main/path - * - https://github.com/esbuild/deno-esbuild * * @module */ diff --git a/rpc-http/README.md b/rpc-http/README.md index 718a6be..c5dd1a8 100644 --- a/rpc-http/README.md +++ b/rpc-http/README.md @@ -8,11 +8,13 @@ Create fully typed and validated RPC clients and servers using HTTP as the trans ## Importing -... +```typescript +import * as mod from 'https://deno.land/x/enzastdlib/rpc-http/mod.ts'; +``` -## Description +## Documentation -... +Visit the documentation at [Deno's module registry](https://deno.land/x/enzastdlib/rpc-http/mod.ts?doc). ## Compatibility diff --git a/rpc-messageport/README.md b/rpc-messageport/README.md index b0a9633..b2bc85c 100644 --- a/rpc-messageport/README.md +++ b/rpc-messageport/README.md @@ -4,8 +4,10 @@ Create fully typed and validated RPC clients and servers using [`MessagePort`](h ## Importing -... +```typescript +import * as mod from 'https://deno.land/x/enzastdlib/rpc-messageport/mod.ts'; +``` ## Documentation -... +Visit the documentation at [Deno's module registry](https://deno.land/x/enzastdlib/rpc-messageport/mod.ts?doc). diff --git a/rpc-protocol/README.md b/rpc-protocol/README.md index 9b972d8..8f606dc 100644 --- a/rpc-protocol/README.md +++ b/rpc-protocol/README.md @@ -10,11 +10,13 @@ Create fully typed and validated RPC clients and servers powered by [JSON Schema ## Importing -... +```typescript +import * as mod from 'https://deno.land/x/enzastdlib/rpc-protocol/mod.ts'; +``` ## Documentation -... +Visit the documentation at [Deno's module registry](https://deno.land/x/enzastdlib/rpc-protocol/mod.ts?doc). ## Dependencies diff --git a/rpc-protocol/payload.ts b/rpc-protocol/payload.ts index 9f02b82..142645c 100644 --- a/rpc-protocol/payload.ts +++ b/rpc-protocol/payload.ts @@ -42,8 +42,8 @@ export interface CallOptions { * Represents a signal that allows you to abort an ongoing call to the * server. * - * **NOTE**: The client transport layer has to implement support for - * this feature. ex. whatever implements `ClientOptions.processProcedure`. + * > **NOTE**: The client transport layer has to implement support for + * > this feature. ex. whatever implements `ClientOptions.processProcedure`. */ readonly signal?: AbortSignal; } diff --git a/rpc-streams/README.md b/rpc-streams/README.md index ac94e7a..6f9bf21 100644 --- a/rpc-streams/README.md +++ b/rpc-streams/README.md @@ -4,11 +4,13 @@ Create fully typed and validated RPC clients and servers using a pair of [`Reada ## Importing -... +```typescript +import * as mod from 'https://deno.land/x/enzastdlib/rpc-streams/mod.ts'; +``` ## Documentation -... +Visit the documentation at [Deno's module registry](https://deno.land/x/enzastdlib/rpc-streams/mod.ts?doc). ## Dependencies diff --git a/rpc/README.md b/rpc/README.md index 315f4aa..e85b3a1 100644 --- a/rpc/README.md +++ b/rpc/README.md @@ -4,8 +4,10 @@ Contains supplemental typing for creating fully typed and validated RPC clients ## Importing -... +```typescript +import * as mod from 'https://deno.land/x/enzastdlib/rpc/mod.ts'; +``` ## Documentation -... +Visit the documentation at [Deno's module registry](https://deno.land/x/enzastdlib/rpc/mod.ts?doc). diff --git a/schema/README.md b/schema/README.md index 702e84b..1493f3a 100644 --- a/schema/README.md +++ b/schema/README.md @@ -4,11 +4,13 @@ Create easy to use validators powered by [JSON Schema 2019-09](https://json-sche ## Importing -... +```typescript +import * as mod from 'https://deno.land/x/enzastdlib/schema/mod.ts'; +``` ## Documentation -... +Visit the documentation at [Deno's module registry](https://deno.land/x/enzastdlib/schema/mod.ts?doc). ## Dependencies diff --git a/schema/errors.ts b/schema/errors.ts index 9b1bfc7..2753fa4 100644 --- a/schema/errors.ts +++ b/schema/errors.ts @@ -1,5 +1,14 @@ +/** + * Represents details about a validation error that occured. + */ export interface Error { + /** + * Represents the details about what validation error occured. + */ message: string; + /** + * Represents the name of the property where the validation error occured. + */ property: string; } diff --git a/schema/schema.ts b/schema/schema.ts index 6a2f9f9..d79384c 100644 --- a/schema/schema.ts +++ b/schema/schema.ts @@ -5,18 +5,116 @@ import type { TypeName, } from '../vendor/@jrylan-json-schema-typed.ts'; +/** + * Represents the JSON Schema structure typing for arrays. + * + * @example + * ```typescript + * import type { JSONSchemaArray } from 'https://deno.land/x/enzastdlib/schema/mod.ts'; + * + * const MY_ARRAY_SCHEMA = { + * type: 'array', + * + * items: { + * type: 'string', + * }, + * } as const satisfies JSONSchemaArray; + * ``` + */ export type JSONSchemaArray = JSONSchema201909.Array; +/** + * Represents the JSON Schema structure typing for booleans. + * + * @example + * ```typescript + * import type { JSONSchemaBoolean } from 'https://deno.land/x/enzastdlib/schema/mod.ts'; + * + * const MY_BOOLEAN_SCHEMA = { + * type: 'boolean', + * } as const satisfies JSONSchemaBoolean; + * ``` + */ export type JSONSchemaBoolean = JSONSchema201909.Boolean; +/** + * Represents the JSON Schema structure typing for nulls. + * + * @example + * ```typescript + * import type { JSONSchemaNull } from 'https://deno.land/x/enzastdlib/schema/mod.ts'; + * + * const MY_NULL_SCHEMA = { + * type: 'null', + * } as const satisfies JSONSchemaNull; + * ``` + */ export type JSONSchemaNull = JSONSchema201909.Null; +/** + * Represents the JSON Schema structure typing for numbers. + * + * @example + * ```typescript + * import type { JSONSchemaNumber } from 'https://deno.land/x/enzastdlib/schema/mod.ts'; + * + * const MY_NUMBER_SCHEMA = { + * type: 'number', + * + * minimum: 0, + * maximum: 42, + * } as const satisfies JSONSchemaNumber; + * ``` + */ export type JSONSchemaNumber = JSONSchema201909.Number; +/** + * Represents the JSON Schema structure typing for objects. + * + * @example + * ```typescript + * import type { JSONSchemaObject } from 'https://deno.land/x/enzastdlib/schema/mod.ts'; + * + * const MY_OBJECT_SCHEMA = { + * type: 'object', + * + * additionalProperties: { + * type: 'string', + * }, + * } as const satisfies JSONSchemaObject; + * ``` + */ export type JSONSchemaObject = JSONSchema201909.Object; +/** + * Represents the JSON Schema structure typing for strings. + * + * @example + * ```typescript + * import type { JSONSchemaString } from 'https://deno.land/x/enzastdlib/schema/mod.ts'; + * + * const MY_STRING_SCHEMA = { + * type: 'string', + * + * minLength: 1, + * maxLength: 64, + * } as const satisfies JSONSchemaString; + * ``` + */ export type JSONSchemaString = JSONSchema201909.String; +/** + * Represents a union of all supported JSON Schema structure typings. + * + * @example + * ```typescript + * import type { JSONSchema } from 'https://deno.land/x/enzastdlib/schema/mod.ts'; + * + * const MY_STRING_SCHEMA = { + * type: 'string', + * } as const satisfies JSONSchema; + * ``` + */ export type JSONSchema = | JSONSchemaArray | JSONSchemaBoolean @@ -25,8 +123,45 @@ export type JSONSchema = | JSONSchemaObject | JSONSchemaString; +/** + * Represents a union of all possible type names supported by JSON Schema. + * + * @example + * ```typescript + * import type { JSONSchemaTypes } from 'https://deno.land/x/enzastdlib/schema/mod.ts'; + * + * const my_schema_type = 'integer' satisfies JSONSchemaTypes; + * ``` + */ export type JSONSchemaTypes = `${TypeName}`; +/** + * Converts a constant JSON Schema object into TypeScript typing at compile-time. + * + * > **WARNING**: Depending on the complexity of your JSON Schemas, your type checking + * > and continous integration suites might experience slowdowns. + * + * > **WARNING**: It is recommended to put schema-related code into a seperate + * > TypeScript file (ex. `*.schema.ts`) to allow your IDE to cache the resulting + * > typings. + * > + * > Otherwise you might experience slowdowns with your IDE. + * + * @example + * ```typescript + * import type { JSONSchema, typeofschema } from 'https://deno.land/x/enzastdlib/schema/mod.ts'; + * + * const MY_OBJECT_SCHEMA = { + * type: 'object', + * + * additionalProperties: { + * type: 'string', + * }, + * } as const satisfies JSONSchema; + * + * type MyObjectType = typeofschema; // `{ [x: string]: string; }` + * ``` + */ export type typeofschema = FromSchema< // @ts-ignore - HACK: They're both draft 2019-09 based, they just have mismatched types. Schema diff --git a/schema/types.ts b/schema/types.ts index 73ddf4a..81d27aa 100644 --- a/schema/types.ts +++ b/schema/types.ts @@ -2,6 +2,18 @@ import type { JsonValue } from '../vendor/@deno-std-json.ts'; import type { JSONSchemaTypes } from './schema.ts'; +/** + * Returns the JSON Schema type of a specified JavaScript type. + * + * @example + * ```typescript + * import type { SchemaTypeOf } from 'https://deno.land/x/enzastdlib/schema/mod.ts'; + * + * const my_string = 'Hello World!'; + * + * type MyStringSchemaType = SchemaTypeOf; // "string" + * ``` + */ export type SchemaTypeOf = Type extends boolean ? 'boolean' : (Type extends null ? 'null' : ( @@ -15,6 +27,18 @@ export type SchemaTypeOf = Type extends boolean ) )); +/** + * Returns the JavaScript type of the specified JSON Schema type. + * + * @example + * ```typescript + * import type { TypeOfSchemaType } from 'https://deno.land/x/enzastdlib/schema/mod.ts'; + * + * type MySchemaType = 'integer'; + * + * type MyType = TypeOfSchemaType; // `number` + * ``` + */ export type TypeOfSchemaType = SchemaType extends 'boolean' ? boolean : (SchemaType extends 'null' ? null : ( diff --git a/schema/util.ts b/schema/util.ts index 1cbbb36..fc96870 100644 --- a/schema/util.ts +++ b/schema/util.ts @@ -1 +1,4 @@ +/** + * Represents the JSON Schema version supported by this module. + */ export const VERSION_SCHEMA = '2019-09'; diff --git a/schema/validator.ts b/schema/validator.ts index 272003a..efe5cdc 100644 --- a/schema/validator.ts +++ b/schema/validator.ts @@ -6,14 +6,190 @@ import type { Error } from './errors.ts'; import type { JSONSchema } from './schema.ts'; import { VERSION_SCHEMA } from './util.ts'; +/** + * Represents a JSON Schema validator made by `makeValidator`. + */ export interface Validator { + /** + * Returns `true` if the specified `value` has no validation errors, otherwise + * `false`. + * + * @param value + * @returns + * + * @example + * **schema.ts** + * ```typescript + * import type { JSONSchema, typeofschema } from 'https://deno.land/x/enzastdlib/schema/mod.ts'; + * + * const MY_STRING_SCHEMA = { + * type: 'string', + * + * minLength: 1, + * } as const satisfies JSONSchema; + * + * type MyStringType = typeofschema; + * ``` + * + * **mod.ts** + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { makeValidator } from 'https://deno.land/x/enzastdlib/schema/mod.ts'; + * + * import type { MyStringType } from './schema.ts'; + * import { MY_STRING_SCHEMA } from './schema.ts'; + * + * const validator = makeValidator(MY_STRING_SCHEMA); + * + * assertEquals( + * validator.instanceOf('Hello World!'), + * true, + * ); + * + * assertEquals( + * validator.instanceOf(''), + * false, + * ); + * + * assertEquals( + * validator.instanceOf(42), + * false, + * ); + * ``` + */ instanceOf(value: Type | unknown): value is Type; + /** + * Returns `Error` objects of any validation errors that have occured regarding + * the specified `value`, if any. + * + * @param value + * @returns + * + * @example + * **schema.ts** + * ```typescript + * import type { JSONSchema, typeofschema } from 'https://deno.land/x/enzastdlib/schema/mod.ts'; + * + * const MY_STRING_SCHEMA = { + * type: 'string', + * + * minLength: 1, + * } as const satisfies JSONSchema; + * + * type MyStringType = typeofschema; + * ``` + * + * **mod.ts** + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { makeValidator } from 'https://deno.land/x/enzastdlib/schema/mod.ts'; + * + * import type { MyStringType } from './schema.ts'; + * import { MY_STRING_SCHEMA } from './schema.ts'; + * + * const validator = makeValidator(MY_STRING_SCHEMA); + * + * assertEquals( + * validator.instanceOf('Hello World!'), + * undefined, + * ); + * + * assertEquals( + * validator.instanceOf(''), + * [{ message: "String is too short (0 < 1).", property: "#" }], + * ); + * + * assertEquals( + * validator.instanceOf(42), + * [{ message: 'Instance type "number" is invalid. Expected "string".', property: "#" }], + * ); + * ``` + */ test(value: Type | unknown): Error[] | undefined; + /** + * Throws an exception if any validation errors occured regarding the specified `value`, + * otherwise returns `true`. + * + * @param value + * @returns + * + * @example + * **schema.ts** + * ```typescript + * import type { JSONSchema, typeofschema } from 'https://deno.land/x/enzastdlib/schema/mod.ts'; + * + * const MY_STRING_SCHEMA = { + * type: 'string', + * + * minLength: 1, + * } as const satisfies JSONSchema; + * + * type MyStringType = typeofschema; + * ``` + * + * **mod.ts** + * ```typescript + * import { assertEquals, assertThrows } from 'https://deno.land/std/testing/asserts.ts'; + * import { ValidationError } from 'https://deno.land/x/enzastdlib/errors/mod.ts'; + * import { makeValidator } from 'https://deno.land/x/enzastdlib/schema/mod.ts'; + * + * import type { MyStringType } from './schema.ts'; + * import { MY_STRING_SCHEMA } from './schema.ts'; + * + * const validator = makeValidator(MY_STRING_SCHEMA); + * + * assertEquals( + * validator.instanceOf('Hello World!'), + * true, + * ) + * + * assertThrows( + * () => validator.instanceOf(''), + * ValidationError, + * ); + * + * assertThrows( + * () => validator.instanceOf(42), + * ValidationError, + * ); + * ``` + */ validate(value: Type | unknown): value is Type; } +/** + * Makes a new `Validator` for validating input values are of the specified `schema` + * JSON Schema definition. + * + * @param schema + * @returns + * + * @example + * **schema.ts** + * ```typescript + * import type { JSONSchema, typeofschema } from 'https://deno.land/x/enzastdlib/schema/mod.ts'; + * + * const MY_STRING_SCHEMA = { + * type: 'string', + * + * minLength: 1, + * } as const satisfies JSONSchema; + * + * type MyStringType = typeofschema; + * ``` + * + * **mod.ts** + * ```typescript + * import { makeValidator } from 'https://deno.land/x/enzastdlib/schema/mod.ts'; + * + * import type { MyStringType } from './schema.ts'; + * import { MY_STRING_SCHEMA } from './schema.ts'; + * + * const validator = makeValidator(MY_STRING_SCHEMA); + * ``` + */ export function makeValidator( schema: JSONSchema, ): Validator { diff --git a/strings/README.md b/strings/README.md index 1eb6a3c..01ecf48 100644 --- a/strings/README.md +++ b/strings/README.md @@ -4,8 +4,10 @@ Utilities for working with strings. ## Importing -... +```typescript +import * as mod from 'https://deno.land/x/enzastdlib/strings/mod.ts'; +``` ## Documentation -... +Visit the documentation at [Deno's module registry](https://deno.land/x/enzastdlib/strings/mod.ts?doc). diff --git a/strings/splitlength.ts b/strings/splitlength.ts index f3f1269..f52f76c 100644 --- a/strings/splitlength.ts +++ b/strings/splitlength.ts @@ -11,6 +11,27 @@ const EXPRESSION_WORDS = /\s*[^\s]+/g; * @param text * @param max_length * @returns + * + * @example + * ```typescript + * import { assertEquals } from 'https://deno.land/std/testing/asserts.ts'; + * import { splitLength } from 'https://deno.land/x/enzastdlib/strings/mod.ts'; + * + * // **NOTE**: Taken from `deno lint --help`. + * const text = + * 'The configuration file can be used to configure different aspects of deno including TypeScript, linting, and code formatting. Typically the configuration file will be called `deno.json` or `deno.jsonc` and automatically detected; in that case this flag is not necessary.\nSee https://deno.land/manual@v1.33.0/getting_started/configuration_file'; + * + * assertEquals( + * splitLength(text, 66), + * [ + * 'The configuration file can be used to configure different aspects of', + * 'deno including TypeScript, linting, and code formatting. Typically', + * 'the configuration file will be called `deno.json` or `deno.jsonc` and', + * 'automatically detected; in that case this flag is not necessary.', + * 'See https://deno.land/manual@v1.33.0/getting_started/configuration_file', + * ]; + * ); + * ``` */ export function splitLength(text: string, max_length: number): string[] { const lines = text.split(EXPRESSION_NEWLINE); diff --git a/testing/README.md b/testing/README.md index 2fb9a27..d8e5e11 100644 --- a/testing/README.md +++ b/testing/README.md @@ -4,8 +4,10 @@ Utilities for working with Deno's testing API. ## Importing -... +```typescript +import * as mod from 'https://deno.land/x/enzastdlib/testing/mod.ts'; +``` ## Documentation -... +Visit the documentation at [Deno's module registry](https://deno.land/x/enzastdlib/testing/mod.ts?doc). diff --git a/testing/asserts.ts b/testing/asserts.ts index 9319cdf..4c6940a 100644 --- a/testing/asserts.ts +++ b/testing/asserts.ts @@ -19,6 +19,18 @@ type BuiltinTypes = /** * Make an assertion that `actual` has the type of `expected_type`. * If not then throw. + * + * @param actual + * @param expected_type + * @param message + * @returns + * + * @example + * ```typescript + * import { assertTypeOf } from 'https://deno.land/x/enzastdlib/testing/mod.ts'; + * + * assertTypeOf('Hello World!', 'string'); + * ``` */ export function assertTypeOf( actual: unknown,