Added settings and group repositories with some basic functionality

This commit is contained in:
Christopher Allford 2020-09-30 13:11:31 -07:00
parent 4c2637c479
commit fccf1fb66e
11 changed files with 431 additions and 88 deletions

View File

@ -1,5 +1,6 @@
module.exports = {
preset: 'ts-jest',
verbose: true,
rootDir: 'src',
testEnvironment: 'node',
testPathIgnorePatterns: [ '/node_modules/', '/dist/' ],

View File

@ -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 );
} );

View File

@ -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.' );
}

View File

@ -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 );
}
}

View File

@ -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 );
}
}

View File

@ -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 >();

View File

@ -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(

View File

@ -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' );
} );
} );

View File

@ -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' },
);
} );
} );

View File

@ -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,
);
}

View File

@ -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,
);
}