Added @template JSDoc tag to API package for better IDE support

This commit is contained in:
Christopher Allford 2020-09-29 12:00:09 -07:00
parent ef93f22321
commit 8c5548d06e
6 changed files with 89 additions and 67 deletions

View File

@ -14,7 +14,7 @@ module.exports = {
'no-useless-constructor': 'off',
'@typescript-eslint/no-useless-constructor': 2,
},
'plugins': [
plugins: [
'@typescript-eslint'
],
extends: [
@ -22,17 +22,22 @@ module.exports = {
],
overrides: [
{
'files': [
files: [
'**/*.js',
'**/*.ts'
]
],
settings: {
jsdoc: {
mode: 'typescript',
},
},
},
{
'files': [
files: [
'**/*.spec.ts',
'**/*.test.ts'
],
'rules': {
rules: {
'no-console': 'off',
}
}

View File

@ -1,46 +1,51 @@
import { Model } from '../models/model';
import { Model, ModelID } from '../models/model';
/**
* A callback for creating a model using a data source.
*
* @callback CreateFn
* @param {Object} properties The properties of the model to create.
* @return {Promise.<Model>} Resolves to the created model.
* @template {Model} T
* @param {Partial.<T>} properties The properties of the model to create.
* @return {Promise.<T>} Resolves to the created model.
*/
export type CreateFn< T > = ( properties: Partial< T > ) => Promise< T >;
export type CreateFn< T extends Model > = ( properties: Partial< T > ) => Promise< T >;
/**
* A callback for reading a model using a data source.
*
* @callback ReadFn
* @param {number|Object} id The ID or object used to find the model.
* @return {Promise.<Model>} Resolves to the read model.
* @template {Model} T
* @param {ModelID} id The ID of the model.
* @return {Promise.<T>} Resolves to the read model.
*/
export type ReadFn< IDParam, T > = ( id: IDParam ) => Promise< T >;
export type ReadFn< T extends Model > = ( id: ModelID ) => Promise< T >;
/**
* A callback for updating a model using a data source.
*
* @callback UpdateFn
* @param {number|Object} id The ID or object used to find the model.
* @return {Promise.<Model>} Resolves to the updated model.
* @template {Model} T
* @param {ModelID} id The ID of the model.
* @param {Partial.<T>} properties The properties of the model.
* @return {Promise.<T>} Resolves to the updated model.
*/
export type UpdateFn< IDParam, T > = ( id: IDParam, properties: Partial< T > ) => Promise< T >;
export type UpdateFn< T > = ( id: ModelID, properties: Partial< T > ) => Promise< T >;
/**
* A callback for deleting a model from a data source.
*
* @callback DeleteFn
* @param {number|Object} id The ID or object used to find the model.
* @param {ModelID} id The ID of the model.
* @return {Promise.<boolean>} Resolves to true once the model has been deleted.
*/
export type DeleteFn< IDParam > = ( id: IDParam ) => Promise< boolean >;
export type DeleteFn = ( id: ModelID ) => Promise< boolean >;
/**
* An interface for repositories that can create models.
*
* @typedef CreatesModels
* @property {CreateFn} create Creates a model using the repository.
* @property {CreateFn.<T>} create Creates a model using the repository.
* @template {Model} T
*/
export interface CreatesModels< T extends Model > {
create( properties: Partial< T > ): Promise< T >;
@ -50,20 +55,22 @@ export interface CreatesModels< T extends Model > {
* An interface for repositories that can read models.
*
* @typedef ReadsModels
* @property {ReadFn} read Reads a model using the repository.
* @property {ReadFn.<T>} read Reads a model using the repository.
* @template {Model} T
*/
export interface ReadsModels< T extends Model, IDParam = number > {
read( id: IDParam ): Promise< T >;
export interface ReadsModels< T extends Model > {
read( id: ModelID ): Promise< T >;
}
/**
* An interface for repositories that can update models.
*
* @typedef UpdatesModels
* @property {UpdateFn} update Updates a model using the repository.
* @property {UpdateFn.<T>} update Updates a model using the repository.
* @template {Model} T
*/
export interface UpdatesModels< T extends Model, IDParam = number > {
update( id: IDParam, properties: Partial< T > ): Promise< T >;
export interface UpdatesModels< T extends Model > {
update( id: ModelID, properties: Partial< T > ): Promise< T >;
}
/**
@ -72,24 +79,26 @@ export interface UpdatesModels< T extends Model, IDParam = number > {
* @typedef DeletesModels
* @property {DeleteFn} delete Deletes a model using the repository.
*/
export interface DeletesModels< IDParam = number > {
delete( id: IDParam ): Promise< boolean >;
export interface DeletesModels {
delete( id: ModelID ): Promise< boolean >;
}
/**
* A class for performing CRUD operations on models using a number of internal hooks.
* Note that if a model does not support a given operation then it will throw an
* error when attempting to perform that action.
*
* @template {Model} T
*/
export class ModelRepository< T extends Model, IDParam = number > implements
export class ModelRepository< T extends Model > implements
CreatesModels< T >,
ReadsModels< T, IDParam >,
UpdatesModels< T, IDParam >,
DeletesModels< IDParam > {
ReadsModels< T >,
UpdatesModels< T >,
DeletesModels {
/**
* The hook used to create models
*
* @type {CreateFn}
* @type {CreateFn.<T>}
* @private
*/
private readonly createHook: CreateFn< T > | null;
@ -97,18 +106,18 @@ export class ModelRepository< T extends Model, IDParam = number > implements
/**
* The hook used to read models.
*
* @type {ReadFn}
* @type {ReadFn.<T>}
* @private
*/
private readonly readHook: ReadFn< IDParam, T > | null;
private readonly readHook: ReadFn< T > | null;
/**
* The hook used to update models.
*
* @type {UpdateFn}
* @type {UpdateFn.<T>}
* @private
*/
private readonly updateHook: UpdateFn< IDParam, T > | null;
private readonly updateHook: UpdateFn< T > | null;
/**
* The hook used to delete models.
@ -116,21 +125,21 @@ export class ModelRepository< T extends Model, IDParam = number > implements
* @type {DeleteFn}
* @private
*/
private readonly deleteHook: DeleteFn< IDParam > | null;
private readonly deleteHook: DeleteFn | null;
/**
* Creates a new repository instance.
*
* @param {CreateFn|null} createHook The hook for model creation.
* @param {ReadFn|null} readHook The hook for model reading.
* @param {UpdateFn|null} updateHook The hook for model updating.
* @param {DeleteFn|null} deleteHook The hook for model deletion.
* @param {CreateFn.<T>|null} createHook The hook for model creation.
* @param {ReadFn.<T>|null} readHook The hook for model reading.
* @param {UpdateFn.<T>|null} updateHook The hook for model updating.
* @param {DeleteFn.<T>|null} deleteHook The hook for model deletion.
*/
public constructor(
createHook: CreateFn< T > | null,
readHook: ReadFn< IDParam, T > | null,
updateHook: UpdateFn< IDParam, T > | null,
deleteHook: DeleteFn< IDParam > | null,
readHook: ReadFn< T > | null,
updateHook: UpdateFn< T > | null,
deleteHook: DeleteFn | null,
) {
this.createHook = createHook;
this.readHook = readHook;
@ -141,8 +150,8 @@ export class ModelRepository< T extends Model, IDParam = number > implements
/**
* Creates the given model.
*
* @param {Object} properties The properties for the model we'd like to create.
* @return {Promise.<Model>} A promise that resolves to the model after creation.
* @param {Partial.<T>} properties The properties for the model we'd like to create.
* @return {Promise.<T>} A promise that resolves to the model after creation.
*/
public create( properties: Partial< T > ): Promise< T > {
if ( ! this.createHook ) {
@ -155,10 +164,10 @@ export class ModelRepository< T extends Model, IDParam = number > implements
/**
* Reads the given model.
*
* @param {number|Object} id The identifier for the model to read.
* @return {Promise.<Model>} A promise that resolves to the model.
* @param {string|number} id The identifier for the model to read.
* @return {Promise.<T>} A promise that resolves to the model.
*/
public read( id: IDParam ): Promise< T > {
public read( id: ModelID ): Promise< T > {
if ( ! this.readHook ) {
throw new Error( 'The \'read\' operation is not supported on this model.' );
}
@ -169,11 +178,11 @@ export class ModelRepository< T extends Model, IDParam = number > implements
/**
* Updates the given model.
*
* @param {number|Object} id The identifier for the model to create.
* @param {Object} properties The model properties that we'd like to update.
* @return {Promise.<Model>} A promise that resolves to the model after updating.
* @param {string|number} id The identifier for the model to create.
* @param {Partial.<T>} properties The model properties that we'd like to update.
* @return {Promise.<T>} A promise that resolves to the model after updating.
*/
public update( id: IDParam, properties: Partial< T > ): Promise< T > {
public update( id: ModelID, properties: Partial< T > ): Promise< T > {
if ( ! this.updateHook ) {
throw new Error( 'The \'update\' operation is not supported on this model.' );
}
@ -184,10 +193,10 @@ export class ModelRepository< T extends Model, IDParam = number > implements
/**
* Deletes the given model.
*
* @param {number|Object} id The identifier for the model to delete.
* @param {string|number} id The identifier for the model to delete.
* @return {Promise.<boolean>} A promise that resolves to "true" on success.
*/
public delete( id: IDParam ): Promise< boolean > {
public delete( id: ModelID ): Promise< boolean > {
if ( ! this.deleteHook ) {
throw new Error( 'The \'delete\' operation is not supported on this model.' );
}

View File

@ -75,7 +75,7 @@ export class AxiosClient implements HTTPClient {
* Performs a PUT request.
*
* @param {string} path The path we should send the request to.
* @param {Object} data Any parameters that should be passed in the request.
* @param {Object} data Any parameters that should be passed in the request.
* @return {Promise.<HTTPResponse>} The response from the API.
*/
public put< T = any >(
@ -89,7 +89,7 @@ export class AxiosClient implements HTTPClient {
* Performs a PATCH request.
*
* @param {string} path The path we should query.
* @param {*} data Any parameters that should be passed in the request.
* @param {*} data Any parameters that should be passed in the request.
* @return {Promise.<HTTPResponse>} The response from the API.
*/
public patch< T = any >(
@ -103,7 +103,7 @@ export class AxiosClient implements HTTPClient {
* Performs a DELETE request.
*
* @param {string} path The path we should send the request to.
* @param {*} data Any parameters that should be passed in the request.
* @param {*} data Any parameters that should be passed in the request.
* @return {Promise.<HTTPResponse>} The response from the API.
*/
public delete< T = any >(

View File

@ -45,7 +45,7 @@ export interface HTTPClient {
* Performs a GET request.
*
* @param {string} path The path we should send the request to.
* @param {*} params Any parameters that should be passed in the request.
* @param {*} params Any parameters that should be passed in the request.
* @return {Promise.<HTTPResponse>} The response from the API.
*/
get< T = any >( path: string, params?: any ): Promise< HTTPResponse< T > >;
@ -54,7 +54,7 @@ export interface HTTPClient {
* Performs a POST request.
*
* @param {string} path The path we should send the request to.
* @param {*} data Any parameters that should be passed in the request.
* @param {*} data Any parameters that should be passed in the request.
* @return {Promise.<HTTPResponse>} The response from the API.
*/
post< T = any >( path: string, data?: any ): Promise< HTTPResponse< T > >;
@ -63,7 +63,7 @@ export interface HTTPClient {
* Performs a PUT request.
*
* @param {string} path The path we should send the request to.
* @param {*} data Any parameters that should be passed in the request.
* @param {*} data Any parameters that should be passed in the request.
* @return {Promise.<HTTPResponse>} The response from the API.
*/
put< T = any >( path: string, data?: any ): Promise< HTTPResponse< T > >;
@ -72,7 +72,7 @@ export interface HTTPClient {
* Performs a PATCH request.
*
* @param {string} path The path we should send the request to.
* @param {*} data Any parameters that should be passed in the request.
* @param {*} data Any parameters that should be passed in the request.
* @return {Promise.<HTTPResponse>} The response from the API.
*/
patch< T = any >( path: string, data?: any ): Promise< HTTPResponse< T > >;
@ -81,7 +81,7 @@ export interface HTTPClient {
* Performs a DELETE request.
*
* @param {string} path The path we should send the request to.
* @param {*} data Any parameters that should be passed in the request.
* @param {*} data Any parameters that should be passed in the request.
* @return {Promise.<HTTPResponse>} The response from the API.
*/
delete< T = any >( path: string, data?: any ): Promise< HTTPResponse< T > >;

View File

@ -1,11 +1,19 @@
/**
* A base class for all models.
* The ID of a model.
*
* @typedef ModelID
* @alias string|number
*/
export type ModelID = string | number;
/**
* The base class for all models.
*/
export abstract class Model {
/**
* The ID of the model if it exists.
*
* @type {number|null}
* @type {string|number|null}
*/
public readonly id: number | null = null;
public readonly id: ModelID | undefined;
}

View File

@ -6,7 +6,7 @@ import { SimpleProduct } from '../../../models';
* Creates a callback for REST model creation.
*
* @param {HTTPClient} httpClient The HTTP client for requests.
* @return {CreateFn} The callback for creating models via the REST API.
* @return {CreateFn<SimpleProduct>} The callback for creating models via the REST API.
*/
function restCreate( httpClient: HTTPClient ): CreateFn< SimpleProduct > {
return async ( properties ) => {
@ -31,7 +31,7 @@ function restCreate( httpClient: HTTPClient ): CreateFn< SimpleProduct > {
* Creates a new ModelRepository instance for interacting with models via the REST API.
*
* @param {HTTPClient} httpClient The HTTP client for the REST requests to be made using.
* @return {CreatesModels} A repository for interacting with models via the REST API.
* @return {CreatesModels<SimpleProduct>} A repository for interacting with models via the REST API.
*/
export function simpleProductRESTRepository( httpClient: HTTPClient ): CreatesModels< SimpleProduct > {
return new ModelRepository(