Added settings and group repositories with some basic functionality
This commit is contained in:
parent
4c2637c479
commit
fccf1fb66e
|
@ -1,5 +1,6 @@
|
|||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
verbose: true,
|
||||
rootDir: 'src',
|
||||
testEnvironment: 'node',
|
||||
testPathIgnorePatterns: [ '/node_modules/', '/dist/' ],
|
||||
|
|
|
@ -14,7 +14,7 @@ describe( 'ModelRepository', () => {
|
|||
it( 'should list', async () => {
|
||||
const model = new DummyModel();
|
||||
const callback = jest.fn().mockResolvedValue( [ model ] );
|
||||
const repository = new ModelRepository< DummyModel >( callback, null, null, null, null );
|
||||
const repository = new ModelRepository< DummyModel, { search: string } >( callback, null, null, null, null );
|
||||
|
||||
const listed = await repository.list( { search: 'test' } );
|
||||
expect( listed ).toContain( model );
|
||||
|
@ -62,7 +62,7 @@ describe( 'ModelRepository', () => {
|
|||
it( 'should update', async () => {
|
||||
const model = new DummyModel();
|
||||
const callback = jest.fn().mockResolvedValue( model );
|
||||
const repository = new ModelRepository< DummyModel >( null, null, null, callback, null );
|
||||
const repository = new ModelRepository< DummyModel, void, 'name' >( null, null, null, callback, null );
|
||||
|
||||
const updated = await repository.update( 1, { name: 'new-name' } );
|
||||
expect( updated ).toBe( model );
|
||||
|
@ -70,7 +70,7 @@ describe( 'ModelRepository', () => {
|
|||
} );
|
||||
|
||||
it( 'should throw error on update without callback', () => {
|
||||
const repository = new ModelRepository< DummyModel >( null, null, null, null, null );
|
||||
const repository = new ModelRepository< DummyModel, void, 'name' >( null, null, null, null, null );
|
||||
|
||||
expect( () => repository.update( 1, { name: 'new-name' } ) ).toThrowError( /not supported/i );
|
||||
} );
|
||||
|
|
|
@ -1,22 +1,8 @@
|
|||
import { Model, ModelID, ModelParentID } from '../models/model';
|
||||
|
||||
/**
|
||||
* The parameters for filtering.
|
||||
*
|
||||
* @typedef ListParams
|
||||
* @property {string} [search] The string we want to search for.
|
||||
* @property {number} [perPage] The number of models we should have on each page.
|
||||
* @property {number} [page] The offset for the page we're requesting.
|
||||
* @property {('asc'|'desc')} [order] The ordering direction.
|
||||
* @property {string} [orderBy] The field we want to order using.
|
||||
*/
|
||||
export interface ListParams {
|
||||
search?: string;
|
||||
perPage?: number;
|
||||
page?: number,
|
||||
order?: 'asc' | 'desc';
|
||||
orderBy?: string;
|
||||
}
|
||||
// Helpers for making types easier to work with.
|
||||
type UpdateParams< T extends Model, U > = [ U ] extends [ keyof T ] ? Pick< T, U > : undefined;
|
||||
type HasParent< P, T, F > = [ P ] extends [ ModelParentID ] ? T : F;
|
||||
|
||||
/**
|
||||
* A callback for listing models using a data source.
|
||||
|
@ -25,9 +11,9 @@ export interface ListParams {
|
|||
* @param {L} [params] The list parameters for the query.
|
||||
* @return {Promise.<Array.<T>>} Resolves to an array of created models.
|
||||
* @template {Model} T
|
||||
* @template {ListParams} L
|
||||
* @template L
|
||||
*/
|
||||
export type ListFn< T extends Model, L extends ListParams > = ( params?: L ) => Promise< T[] >;
|
||||
export type ListFn< T extends Model, L > = ( params?: L ) => Promise< T[] >;
|
||||
|
||||
/**
|
||||
* A callback for listing child models using a data source.
|
||||
|
@ -37,10 +23,10 @@ export type ListFn< T extends Model, L extends ListParams > = ( params?: L ) =>
|
|||
* @param {L} [params] The list parameters for the query.
|
||||
* @return {Promise.<Array.<T>>} Resolves to an array of created models.
|
||||
* @template {Model} T
|
||||
* @template {ListParams} L
|
||||
* @template {ModelParentID} P
|
||||
* @template L
|
||||
*/
|
||||
export type ListChildFn< T extends Model, L extends ListParams, P extends ModelParentID > = ( parent: P, params?: L ) => Promise< T[] >;
|
||||
export type ListChildFn< T extends Model, P extends ModelParentID | undefined, L > = ( parent: P, params?: L ) => Promise< T[] >;
|
||||
|
||||
/**
|
||||
* A callback for creating a model using a data source.
|
||||
|
@ -72,18 +58,22 @@ export type ReadFn< T extends Model > = ( id: ModelID ) => Promise< T >;
|
|||
* @template {Model} T
|
||||
* @template {ModelParentID} P
|
||||
*/
|
||||
export type ReadChildFn< T extends Model, P extends ModelParentID > = ( parent: P, childID: ModelID ) => Promise< T >;
|
||||
export type ReadChildFn< T extends Model, P extends ModelParentID | undefined > = ( parent: P, childID: ModelID ) => Promise< T >;
|
||||
|
||||
/**
|
||||
* A callback for updating a model using a data source.
|
||||
*
|
||||
* @callback UpdateFn
|
||||
* @param {ModelID} id The ID of the model.
|
||||
* @param {Partial.<T>} properties The properties to update.
|
||||
* @param {Pick.<T,U>} properties The properties to update.
|
||||
* @return {Promise.<T>} Resolves to the updated model.
|
||||
* @template {Model} T
|
||||
* @template {string} U
|
||||
*/
|
||||
export type UpdateFn< T extends Model > = ( id: ModelID, properties: Partial< T > ) => Promise< T >;
|
||||
export type UpdateFn< T extends Model, U extends keyof T | undefined > = (
|
||||
id: ModelID,
|
||||
properties: UpdateParams< T, U >,
|
||||
) => Promise< T >;
|
||||
|
||||
/**
|
||||
* A callback for updating a child model using a data source.
|
||||
|
@ -91,15 +81,16 @@ export type UpdateFn< T extends Model > = ( id: ModelID, properties: Partial< T
|
|||
* @callback UpdateChildFn
|
||||
* @param {P} parent The parent identifier for the model.
|
||||
* @param {ModelID} childID The ID of the model.
|
||||
* @param {Partial.<T>} properties The properties to update.
|
||||
* @param {Pick.<T,U>} properties The properties to update.
|
||||
* @return {Promise.<T>} Resolves to the updated model.
|
||||
* @template {Model} T
|
||||
* @template {ModelParentID} P
|
||||
* @template {string} U
|
||||
*/
|
||||
export type UpdateChildFn< T extends Model, P extends ModelParentID > = (
|
||||
export type UpdateChildFn< T extends Model, P extends ModelParentID | undefined, U extends keyof T | undefined > = (
|
||||
parent: P,
|
||||
childID: ModelID,
|
||||
properties: Partial< T >,
|
||||
properties: UpdateParams< T, U >,
|
||||
) => Promise< T >;
|
||||
|
||||
/**
|
||||
|
@ -120,7 +111,7 @@ export type DeleteFn = ( id: ModelID ) => Promise< boolean >;
|
|||
* @return {Promise.<boolean>} Resolves to true once the model has been deleted.
|
||||
* @template {ModelParentID} P
|
||||
*/
|
||||
export type DeleteChildFn< P extends ModelParentID > = ( parent: P, childID: ModelID ) => Promise< boolean >;
|
||||
export type DeleteChildFn< P extends ModelParentID | undefined > = ( parent: P, childID: ModelID ) => Promise< boolean >;
|
||||
|
||||
/**
|
||||
* An interface for repositories that can list models.
|
||||
|
@ -128,23 +119,23 @@ export type DeleteChildFn< P extends ModelParentID > = ( parent: P, childID: Mod
|
|||
* @typedef ListsModels
|
||||
* @property {ListFn.<T,L>} list Lists models using the repository.
|
||||
* @template {Model} T
|
||||
* @template {ListParams} L
|
||||
* @template L
|
||||
*/
|
||||
export interface ListsModels< T extends Model, L extends ListParams > {
|
||||
list( params: L ): Promise< T[] >;
|
||||
export interface ListsModels< T extends Model, L = undefined > {
|
||||
list( params?: L ): Promise< T[] >;
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface for repositories that can list child models.
|
||||
*
|
||||
* @typedef ListsChildModels
|
||||
* @property {ListChildFn.<T,L,P>} list Lists models using the repository.
|
||||
* @property {ListChildFn.<T,P,L>} list Lists models using the repository.
|
||||
* @template {Model} T
|
||||
* @template {ListParams} L
|
||||
* @template {ModelParentID} P
|
||||
* @template L
|
||||
*/
|
||||
export interface ListsChildModels< T extends Model, L extends ListParams, P extends ModelParentID > {
|
||||
list( parent: P, params: L ): Promise< T[] >;
|
||||
export interface ListsChildModels< T extends Model, P extends ModelParentID | undefined, L = undefined > {
|
||||
list( parent: P, params?: L ): Promise< T[] >;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -177,7 +168,7 @@ export interface ReadsModels< T extends Model > {
|
|||
* @template {Model} T
|
||||
* @template {ModelParentID} P
|
||||
*/
|
||||
export interface ReadsChildModels< T extends Model, P extends ModelParentID > {
|
||||
export interface ReadsChildModels< T extends Model, P extends ModelParentID | undefined > {
|
||||
read( parent: P, childID: ModelID ): Promise< T >;
|
||||
}
|
||||
|
||||
|
@ -185,23 +176,25 @@ export interface ReadsChildModels< T extends Model, P extends ModelParentID > {
|
|||
* An interface for repositories that can update models.
|
||||
*
|
||||
* @typedef UpdatesModels
|
||||
* @property {UpdateFn.<T>} update Updates a model using the repository.
|
||||
* @property {UpdateFn.<T,U>} update Updates a model using the repository.
|
||||
* @template {Model} T
|
||||
* @template {string} U
|
||||
*/
|
||||
export interface UpdatesModels< T extends Model > {
|
||||
update( id: ModelID, properties: Partial< T > ): Promise< T >;
|
||||
export interface UpdatesModels< T extends Model, U extends keyof T | undefined > {
|
||||
update( id: ModelID, properties: UpdateParams< T, U > ): Promise< T >;
|
||||
}
|
||||
|
||||
/**
|
||||
* An interface for repositories that can update models.
|
||||
*
|
||||
* @typedef UpdatesChildModels
|
||||
* @property {UpdateChildFn.<T,P>} update Updates a model using the repository.
|
||||
* @property {UpdateChildFn.<T,P,U>} update Updates a model using the repository.
|
||||
* @template {Model} T
|
||||
* @template {ModelParentID} P
|
||||
* @template {string} U
|
||||
*/
|
||||
export interface UpdatesChildModels< T extends Model, P extends ModelParentID > {
|
||||
update( parent: P, childID: ModelID, properties: Partial< T > ): Promise< T >;
|
||||
export interface UpdatesChildModels< T extends Model, P extends ModelParentID | undefined, U extends keyof T | undefined > {
|
||||
update( parent: P, childID: ModelID, properties: UpdateParams< T, U > ): Promise< T >;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -221,7 +214,7 @@ export interface DeletesModels {
|
|||
* @property {DeleteChildFn.<P>} delete Deletes a model using the repository.
|
||||
* @template {ModelParentID} P
|
||||
*/
|
||||
export interface DeletesChildModels< P extends ModelParentID > {
|
||||
export interface DeletesChildModels< P extends ModelParentID | undefined > {
|
||||
delete( parent: P, childID: ModelID ): Promise< boolean >;
|
||||
}
|
||||
|
||||
|
@ -231,25 +224,31 @@ export interface DeletesChildModels< P extends ModelParentID > {
|
|||
* error when attempting to perform that action.
|
||||
*
|
||||
* @template {Model} T
|
||||
* @template {ListParams} L
|
||||
* @template {ModelParentID|void} P
|
||||
* @template {Object|undefined} L
|
||||
* @template {string|undefined} U
|
||||
* @template {ModelParentID|undefined} P
|
||||
*/
|
||||
export class ModelRepository< T extends Model, L extends ListParams = ListParams, P extends ModelParentID = never > implements
|
||||
export class ModelRepository<
|
||||
T extends Model,
|
||||
L = undefined,
|
||||
U extends keyof T | undefined = undefined,
|
||||
P extends ModelParentID | undefined = undefined
|
||||
> implements
|
||||
ListsModels< T, L >,
|
||||
ListsChildModels< T, L, P >,
|
||||
ListsChildModels< T, P, L >,
|
||||
ReadsModels< T >,
|
||||
ReadsChildModels< T, [ P ] extends [ ModelParentID ] ? P : never >,
|
||||
UpdatesModels< T >,
|
||||
UpdatesChildModels< T, [ P ] extends [ ModelParentID ] ? P : never >,
|
||||
ReadsChildModels< T, HasParent< P, P, undefined > >,
|
||||
UpdatesModels< T, U >,
|
||||
UpdatesChildModels< T, HasParent< P, P, undefined >, U >,
|
||||
DeletesModels,
|
||||
DeletesChildModels< [ P ] extends [ ModelParentID ] ? P : never > {
|
||||
DeletesChildModels< HasParent< P, P, undefined > > {
|
||||
/**
|
||||
* The hook used to list models.
|
||||
*
|
||||
* @type {ListFn.<T>|ListChildFn<T>}
|
||||
* @type {ListFn.<T,P,L>|ListChildFn<T,P,L>}
|
||||
* @private
|
||||
*/
|
||||
private readonly listHook: ( [ P ] extends [ ModelParentID ] ? ListChildFn< T, L, P > : ListFn< T, L > ) | null;
|
||||
private readonly listHook: HasParent< P, ListChildFn< T, P, L >, ListFn< T, L > > | null;
|
||||
|
||||
/**
|
||||
* The hook used to create models
|
||||
|
@ -262,42 +261,42 @@ export class ModelRepository< T extends Model, L extends ListParams = ListParams
|
|||
/**
|
||||
* The hook used to read models.
|
||||
*
|
||||
* @type {ReadFn.<T>|ReadChildFn.<T>}
|
||||
* @type {ReadFn.<T>|ReadChildFn.<T,P>}
|
||||
* @private
|
||||
*/
|
||||
private readonly readHook: ( [ P ] extends [ ModelParentID ] ? ReadChildFn< T, P > : ReadFn< T > ) | null;
|
||||
private readonly readHook: HasParent< P, ReadChildFn< T, P >, ReadFn< T > > | null;
|
||||
|
||||
/**
|
||||
* The hook used to update models.
|
||||
*
|
||||
* @type {UpdateFn.<T>|UpdateChildFn.<T>}
|
||||
* @type {UpdateFn.<T,U>|UpdateChildFn.<T,P,U>}
|
||||
* @private
|
||||
*/
|
||||
private readonly updateHook: ( [ P ] extends [ ModelParentID ] ? UpdateChildFn< T, P > : UpdateFn< T > ) | null;
|
||||
private readonly updateHook: HasParent< P, UpdateChildFn< T, P, U >, UpdateFn< T, U > > | null;
|
||||
|
||||
/**
|
||||
* The hook used to delete models.
|
||||
*
|
||||
* @type {DeleteFn|DeleteChildFn.<T>}
|
||||
* @type {DeleteFn|DeleteChildFn.<P>}
|
||||
* @private
|
||||
*/
|
||||
private readonly deleteHook: ( [ P ] extends [ ModelParentID ] ? DeleteChildFn< P > : DeleteFn ) | null;
|
||||
private readonly deleteHook: HasParent< P, DeleteChildFn< P >, DeleteFn > | null;
|
||||
|
||||
/**
|
||||
* Creates a new repository instance.
|
||||
*
|
||||
* @param {ListFn.<T>|ListChildFn<T>} listHook The hook for model listing.
|
||||
* @param {ListFn.<T,L>|ListChildFn<T,P,L>} listHook The hook for model listing.
|
||||
* @param {CreateFn.<T>|null} createHook The hook for model creation.
|
||||
* @param {ReadFn.<T>|ReadChildFn.<T,P>|null} readHook The hook for model reading.
|
||||
* @param {UpdateFn.<T>|UpdateChildFn.<T,P>|null} updateHook The hook for model updating.
|
||||
* @param {UpdateFn.<T,U>|UpdateChildFn.<T,P,U>|null} updateHook The hook for model updating.
|
||||
* @param {DeleteFn|DeleteChildFn.<P>|null} deleteHook The hook for model deletion.
|
||||
*/
|
||||
public constructor(
|
||||
listHook: ( [ P ] extends [ ModelParentID ] ? ListChildFn< T, L, P > : ListFn< T, L > ) | null,
|
||||
listHook: HasParent< P, ListChildFn< T, P, L >, ListFn< T, L > > | null,
|
||||
createHook: CreateFn< T > | null,
|
||||
readHook: ( [ P ] extends [ ModelParentID ] ? ReadChildFn< T, P > : ReadFn< T > ) | null,
|
||||
updateHook: ( [ P ] extends [ ModelParentID ] ? UpdateChildFn< T, P > : UpdateFn< T > ) | null,
|
||||
deleteHook: ( [ P ] extends [ ModelParentID ] ? DeleteChildFn< P > : DeleteFn ) | null,
|
||||
readHook: HasParent< P, ReadChildFn< T, P >, ReadFn< T > > | null,
|
||||
updateHook: HasParent< P, UpdateChildFn< T, P, U >, UpdateFn< T, U > > | null,
|
||||
deleteHook: HasParent< P, DeleteChildFn< P >, DeleteFn > | null,
|
||||
) {
|
||||
this.listHook = listHook;
|
||||
this.createHook = createHook;
|
||||
|
@ -309,11 +308,11 @@ export class ModelRepository< T extends Model, L extends ListParams = ListParams
|
|||
/**
|
||||
* Lists models using the repository.
|
||||
*
|
||||
* @param {P|L} [paramsOrParent] The params for the lookup or the parent to list if the model is a child.
|
||||
* @param {L|P} [paramsOrParent] The params for the lookup or the parent to list if the model is a child.
|
||||
* @param {L} [params] The params when using the parent.
|
||||
* @return {Promise.<Array.<T>>} Resolves to the listed models.
|
||||
*/
|
||||
public list( paramsOrParent?: P | L, params?: L ): Promise< T[] > {
|
||||
public list( paramsOrParent?: L | P, params?: L ): Promise< T[] > {
|
||||
if ( ! this.listHook ) {
|
||||
throw new Error( 'The \'create\' operation is not supported on this model.' );
|
||||
}
|
||||
|
@ -324,7 +323,7 @@ export class ModelRepository< T extends Model, L extends ListParams = ListParams
|
|||
);
|
||||
}
|
||||
|
||||
return ( this.listHook as ListChildFn< T, L, P > )(
|
||||
return ( this.listHook as ListChildFn< T, P, L > )(
|
||||
paramsOrParent as P,
|
||||
params,
|
||||
);
|
||||
|
@ -352,7 +351,7 @@ export class ModelRepository< T extends Model, L extends ListParams = ListParams
|
|||
* @return {Promise.<T>} Resolves to the loaded model.
|
||||
*/
|
||||
public read(
|
||||
idOrParent: ModelID | P,
|
||||
idOrParent: ModelID | P | undefined,
|
||||
childID?: ModelID,
|
||||
): Promise< T > {
|
||||
if ( ! this.readHook ) {
|
||||
|
@ -380,22 +379,22 @@ export class ModelRepository< T extends Model, L extends ListParams = ListParams
|
|||
* @return {Promise.<T>} Resolves to the updated model.
|
||||
*/
|
||||
public update(
|
||||
idOrParent: ModelID | P,
|
||||
propertiesOrChildID: Partial< T > | ModelID,
|
||||
properties?: Partial< T >,
|
||||
idOrParent: ModelID | P | undefined,
|
||||
propertiesOrChildID: UpdateParams< T, U > | ModelID,
|
||||
properties?: UpdateParams< T, U >,
|
||||
): Promise< T > {
|
||||
if ( ! this.updateHook ) {
|
||||
throw new Error( 'The \'update\' operation is not supported on this model.' );
|
||||
}
|
||||
|
||||
if ( properties === undefined ) {
|
||||
return ( this.updateHook as UpdateFn< T > )(
|
||||
return ( this.updateHook as UpdateFn< T, U > )(
|
||||
idOrParent as ModelID,
|
||||
propertiesOrChildID as Partial< T >,
|
||||
propertiesOrChildID as UpdateParams< T, U >,
|
||||
);
|
||||
}
|
||||
|
||||
return ( this.updateHook as UpdateChildFn< T, P > )(
|
||||
return ( this.updateHook as UpdateChildFn< T, P, U > )(
|
||||
idOrParent as P,
|
||||
propertiesOrChildID as ModelID,
|
||||
properties,
|
||||
|
@ -409,7 +408,7 @@ export class ModelRepository< T extends Model, L extends ListParams = ListParams
|
|||
* @param {ModelID} [childID] The ID of the model when using the parent.
|
||||
* @return {Promise.<T>} Resolves to the loaded model.
|
||||
*/
|
||||
public delete( idOrParent: ModelID | P, childID?: ModelID ): Promise< boolean > {
|
||||
public delete( idOrParent: ModelID | P | undefined, childID?: ModelID ): Promise< boolean > {
|
||||
if ( ! this.deleteHook ) {
|
||||
throw new Error( 'The \'delete\' operation is not supported on this model.' );
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
import { Model, ModelID } from '../model';
|
||||
|
||||
/**
|
||||
* A settings group object.
|
||||
*/
|
||||
export class SettingGroup extends Model {
|
||||
/**
|
||||
* The label of the setting group.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
public readonly label: string = '';
|
||||
|
||||
/**
|
||||
* The description of the setting group.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
public readonly description: string = '';
|
||||
|
||||
/**
|
||||
* The ID of the group this is a child of.
|
||||
*
|
||||
* @type {ModelID|null}
|
||||
*/
|
||||
public readonly parentID: ModelID | null = null;
|
||||
|
||||
/**
|
||||
* Creates a new setting group instance with the given properties
|
||||
*
|
||||
* @param {Object} properties The properties to set in the object.
|
||||
*/
|
||||
public constructor( properties: Partial< SettingGroup > = {} ) {
|
||||
super();
|
||||
Object.assign( this, properties );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
import { Model, ModelID, ModelParentID } from '../model';
|
||||
|
||||
/**
|
||||
* The default types of settings that are available.
|
||||
*/
|
||||
type SettingType = 'text' | 'select' | 'multiselect' | 'checkbox' | 'number';
|
||||
|
||||
/**
|
||||
* An interface describing the shape of setting parent data.
|
||||
*
|
||||
* @typedef SettingParentID
|
||||
* @property {ModelID} settingGroupID The ID of the setting group for the setting.
|
||||
*/
|
||||
export interface SettingParentID extends ModelParentID {
|
||||
settingGroupID: ModelID;
|
||||
}
|
||||
|
||||
/**
|
||||
* A setting object.
|
||||
*/
|
||||
export class Setting extends Model {
|
||||
/**
|
||||
* The label of the setting.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
public readonly label: string = '';
|
||||
|
||||
/**
|
||||
* The description of the setting.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
public readonly description: string = '';
|
||||
|
||||
/**
|
||||
* The type of the setting.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
public readonly type: string | SettingType = '';
|
||||
|
||||
/**
|
||||
* The options of the setting, if it has any.
|
||||
*
|
||||
* @type {Object.<string, string>|null}
|
||||
*/
|
||||
public readonly options: { [key: string]: string } | null = null;
|
||||
|
||||
/**
|
||||
* The default value for the setting.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
public readonly default: string = '';
|
||||
|
||||
/**
|
||||
* The current value of the setting.
|
||||
*
|
||||
* @type {string}
|
||||
*/
|
||||
public readonly value: string = '';
|
||||
|
||||
/**
|
||||
* Creates a new setting instance with the given properties
|
||||
*
|
||||
* @param {Object} properties The properties to set in the object.
|
||||
*/
|
||||
public constructor( properties: Partial< Setting > = {} ) {
|
||||
super();
|
||||
Object.assign( this, properties );
|
||||
}
|
||||
}
|
|
@ -2,11 +2,10 @@ import { simpleProductRESTRepository } from '../simple-product';
|
|||
import { mock, MockProxy } from 'jest-mock-extended';
|
||||
import { HTTPClient, HTTPResponse } from '../../../../http';
|
||||
import { SimpleProduct } from '../../../../models';
|
||||
import { CreatesModels } from '../../../../framework/model-repository';
|
||||
|
||||
describe( 'simpleProductRESTRepository', () => {
|
||||
let httpClient: MockProxy< HTTPClient >;
|
||||
let repository: CreatesModels< SimpleProduct >;
|
||||
let repository: ReturnType< typeof simpleProductRESTRepository >;
|
||||
|
||||
beforeEach( () => {
|
||||
httpClient = mock< HTTPClient >();
|
||||
|
|
|
@ -2,12 +2,6 @@ import { HTTPClient } from '../../../http';
|
|||
import { CreateFn, CreatesModels, ModelRepository } from '../../../framework/model-repository';
|
||||
import { SimpleProduct } from '../../../models';
|
||||
|
||||
/**
|
||||
* Creates a callback for REST model creation.
|
||||
*
|
||||
* @param {HTTPClient} httpClient The HTTP client for requests.
|
||||
* @return {CreateFn<SimpleProduct>} The callback for creating models via the REST API.
|
||||
*/
|
||||
function restCreate( httpClient: HTTPClient ): CreateFn< SimpleProduct > {
|
||||
return async ( properties ) => {
|
||||
const response = await httpClient.post(
|
||||
|
@ -31,7 +25,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<SimpleProduct>} 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(
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
import { mock, MockProxy } from 'jest-mock-extended';
|
||||
import { HTTPClient, HTTPResponse } from '../../../../http';
|
||||
import { settingGroupRESTRepository } from '../setting-group';
|
||||
|
||||
describe( 'settingGroupRESTRepository', () => {
|
||||
let httpClient: MockProxy< HTTPClient >;
|
||||
let repository: ReturnType< typeof settingGroupRESTRepository >;
|
||||
|
||||
beforeEach( () => {
|
||||
httpClient = mock< HTTPClient >();
|
||||
repository = settingGroupRESTRepository( httpClient );
|
||||
} );
|
||||
|
||||
it( 'should list', async () => {
|
||||
httpClient.get.mockResolvedValue( new HTTPResponse(
|
||||
200,
|
||||
{},
|
||||
[
|
||||
{
|
||||
id: 'group_1',
|
||||
label: 'Test Group 1',
|
||||
},
|
||||
{
|
||||
id: 'group_2',
|
||||
label: 'Test Group 2',
|
||||
},
|
||||
],
|
||||
) );
|
||||
|
||||
const list = await repository.list();
|
||||
|
||||
expect( list ).toHaveLength( 2 );
|
||||
expect( list[ 0 ] ).toMatchObject( { id: 'group_1', label: 'Test Group 1' } );
|
||||
expect( list[ 1 ] ).toMatchObject( { id: 'group_2', label: 'Test Group 2' } );
|
||||
expect( httpClient.get ).toHaveBeenCalledWith( '/wc/v3/settings' );
|
||||
} );
|
||||
} );
|
|
@ -0,0 +1,77 @@
|
|||
import { mock, MockProxy } from 'jest-mock-extended';
|
||||
import { HTTPClient, HTTPResponse } from '../../../../http';
|
||||
import { settingRESTRepository } from '../setting';
|
||||
|
||||
describe( 'settingGroupRESTRepository', () => {
|
||||
let httpClient: MockProxy< HTTPClient >;
|
||||
let repository: ReturnType< typeof settingRESTRepository >;
|
||||
|
||||
beforeEach( () => {
|
||||
httpClient = mock< HTTPClient >();
|
||||
repository = settingRESTRepository( httpClient );
|
||||
} );
|
||||
|
||||
it( 'should list', async () => {
|
||||
httpClient.get.mockResolvedValue( new HTTPResponse(
|
||||
200,
|
||||
{},
|
||||
[
|
||||
{
|
||||
id: 'setting_1',
|
||||
label: 'Test Setting 1',
|
||||
},
|
||||
{
|
||||
id: 'setting_2',
|
||||
label: 'Test Setting 2',
|
||||
},
|
||||
],
|
||||
) );
|
||||
|
||||
const list = await repository.list( { settingGroupID: 'general' } );
|
||||
|
||||
expect( list ).toHaveLength( 2 );
|
||||
expect( list[ 0 ] ).toMatchObject( { id: 'setting_1', label: 'Test Setting 1' } );
|
||||
expect( list[ 1 ] ).toMatchObject( { id: 'setting_2', label: 'Test Setting 2' } );
|
||||
expect( httpClient.get ).toHaveBeenCalledWith( '/wc/v3/settings/general' );
|
||||
} );
|
||||
|
||||
it( 'should read', async () => {
|
||||
httpClient.get.mockResolvedValue( new HTTPResponse(
|
||||
200,
|
||||
{},
|
||||
{
|
||||
id: 'setting_1',
|
||||
label: 'Test Setting',
|
||||
},
|
||||
) );
|
||||
|
||||
const read = await repository.read( { settingGroupID: 'general' }, 'setting_1' );
|
||||
|
||||
expect( read ).toMatchObject( { id: 'setting_1', label: 'Test Setting' } );
|
||||
expect( httpClient.get ).toHaveBeenCalledWith( '/wc/v3/settings/general/setting_1' );
|
||||
} );
|
||||
|
||||
it( 'should update', async () => {
|
||||
httpClient.patch.mockResolvedValue( new HTTPResponse(
|
||||
200,
|
||||
{},
|
||||
{
|
||||
id: 'setting_1',
|
||||
label: 'Test Setting',
|
||||
value: 'updated-value',
|
||||
},
|
||||
) );
|
||||
|
||||
const updated = await repository.update(
|
||||
{ settingGroupID: 'general' },
|
||||
'setting_1',
|
||||
{ value: 'test-value' },
|
||||
);
|
||||
|
||||
expect( updated ).toMatchObject( { id: 'setting_1', value: 'updated-value' } );
|
||||
expect( httpClient.patch ).toHaveBeenCalledWith(
|
||||
'/wc/v3/settings/general/setting_1',
|
||||
{ value: 'test-value' },
|
||||
);
|
||||
} );
|
||||
} );
|
|
@ -0,0 +1,37 @@
|
|||
import { HTTPClient } from '../../../http';
|
||||
import { ListFn, ListsModels, ModelRepository } from '../../../framework/model-repository';
|
||||
import { SettingGroup } from '../../../models/settings/setting-group';
|
||||
|
||||
function restList( httpClient: HTTPClient ): ListFn< SettingGroup, void > {
|
||||
return async () => {
|
||||
const response = await httpClient.get( '/wc/v3/settings' );
|
||||
|
||||
const list: SettingGroup[] = [];
|
||||
for ( const raw of response.data ) {
|
||||
list.push( new SettingGroup( {
|
||||
id: raw.id,
|
||||
label: raw.label,
|
||||
description: raw.description,
|
||||
parentID: raw.parent_id,
|
||||
} ) );
|
||||
}
|
||||
|
||||
return Promise.resolve( list );
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {ListsModels.<SettingGroup>} A repository for interacting with models via the REST API.
|
||||
*/
|
||||
export function settingGroupRESTRepository( httpClient: HTTPClient ): ListsModels< SettingGroup > {
|
||||
return new ModelRepository(
|
||||
restList( httpClient ),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
import { HTTPClient } from '../../../http';
|
||||
import {
|
||||
ListChildFn,
|
||||
ListsChildModels,
|
||||
ModelRepository,
|
||||
ReadChildFn,
|
||||
ReadsChildModels,
|
||||
UpdateChildFn, UpdatesChildModels,
|
||||
} from '../../../framework/model-repository';
|
||||
import { Setting, SettingParentID } from '../../../models/settings/setting';
|
||||
|
||||
function restList( httpClient: HTTPClient ): ListChildFn< Setting, SettingParentID, undefined > {
|
||||
return async ( parent ) => {
|
||||
const response = await httpClient.get( '/wc/v3/settings/' + parent.settingGroupID );
|
||||
|
||||
const list: Setting[] = [];
|
||||
for ( const raw of response.data ) {
|
||||
list.push( new Setting( {
|
||||
id: raw.id,
|
||||
label: raw.label,
|
||||
description: raw.description,
|
||||
type: raw.type,
|
||||
options: raw.options,
|
||||
default: raw.default,
|
||||
value: raw.value,
|
||||
} ) );
|
||||
}
|
||||
|
||||
return Promise.resolve( list );
|
||||
};
|
||||
}
|
||||
|
||||
function restRead( httpClient: HTTPClient ): ReadChildFn< Setting, SettingParentID > {
|
||||
return async ( parent, id ) => {
|
||||
const response = await httpClient.get( '/wc/v3/settings/' + parent.settingGroupID + '/' + id );
|
||||
|
||||
return Promise.resolve( new Setting( {
|
||||
id: response.data.id,
|
||||
label: response.data.label,
|
||||
description: response.data.description,
|
||||
type: response.data.type,
|
||||
options: response.data.options,
|
||||
default: response.data.default,
|
||||
value: response.data.value,
|
||||
} ) );
|
||||
};
|
||||
}
|
||||
|
||||
function restUpdate( httpClient: HTTPClient ): UpdateChildFn< Setting, SettingParentID, 'value' > {
|
||||
return async ( parent, id, params ) => {
|
||||
const response = await httpClient.patch(
|
||||
'/wc/v3/settings/' + parent.settingGroupID + '/' + id,
|
||||
params,
|
||||
);
|
||||
|
||||
return Promise.resolve( new Setting( {
|
||||
id: response.data.id,
|
||||
label: response.data.label,
|
||||
description: response.data.description,
|
||||
type: response.data.type,
|
||||
options: response.data.options,
|
||||
default: response.data.default,
|
||||
value: response.data.value,
|
||||
} ) );
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
* ListsChildModels.<Setting,SettingParentID>|
|
||||
* ReadsChildModels.<Setting,SettingParentID>|
|
||||
* UpdatesChildModels.<Setting,SettingParentID>
|
||||
* } A repository for interacting with models via the REST API.
|
||||
*/
|
||||
export function settingRESTRepository( httpClient: HTTPClient ):
|
||||
ListsChildModels< Setting, SettingParentID > &
|
||||
ReadsChildModels< Setting, SettingParentID > &
|
||||
UpdatesChildModels< Setting, SettingParentID, 'value' > {
|
||||
return new ModelRepository< Setting, undefined, 'value', SettingParentID >(
|
||||
restList( httpClient ),
|
||||
null,
|
||||
restRead( httpClient ),
|
||||
restUpdate( httpClient ),
|
||||
null,
|
||||
);
|
||||
}
|
Loading…
Reference in New Issue