Fix and consolidate linting across the monorepo (#35012)

This commit is contained in:
Sam Seay 2022-10-12 15:05:01 +13:00 committed by GitHub
parent 7aca607899
commit 55b49cb50a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
113 changed files with 3637 additions and 1936 deletions

View File

@ -7,7 +7,7 @@ concurrency:
jobs: jobs:
lint-test-js: lint-test-js:
name: Test JS name: Lint and Test JS
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@ -15,5 +15,8 @@ jobs:
- name: Setup WooCommerce Monorepo - name: Setup WooCommerce Monorepo
uses: ./.github/actions/setup-woocommerce-monorepo uses: ./.github/actions/setup-woocommerce-monorepo
- name: Lint
run: pnpm run -r --filter='woocommerce/client/admin...' --filter='!@woocommerce/e2e*' --filter='!@woocommerce/api' --color lint
- name: Test - name: Test
run: pnpm run test --filter='woocommerce/client/admin...' --filter='!@woocommerce/e2e*' --filter='!@woocommerce/api' --color run: pnpm run test --filter='woocommerce/client/admin...' --filter='!@woocommerce/e2e*' --filter='!@woocommerce/api' --color

View File

@ -9,6 +9,15 @@
"semverRange": "^", "semverRange": "^",
"workspace": true, "workspace": true,
"versionGroups": [ "versionGroups": [
{
"dependencies": [
"@typescript-eslint/**"
],
"pinVersion": "latest",
"packages": [
"**"
]
},
{ {
"dependencies": [ "dependencies": [
"react", "react",

View File

@ -29,7 +29,7 @@
"@types/node": "14.14.33", "@types/node": "14.14.33",
"@woocommerce/eslint-plugin": "workspace:*", "@woocommerce/eslint-plugin": "workspace:*",
"@wordpress/data": "^6.15.0", "@wordpress/data": "^6.15.0",
"@wordpress/eslint-plugin": "^11.0.0", "@wordpress/eslint-plugin": "^11.1.0",
"@wordpress/prettier-config": "^1.1.1", "@wordpress/prettier-config": "^1.1.1",
"babel-loader": "^8.2.3", "babel-loader": "^8.2.3",
"chalk": "^4.1.2", "chalk": "^4.1.2",

View File

@ -435,7 +435,7 @@ export const testSubscriptionsInclusion = () => {
} ); } );
describe( 'A US store will see the Subscriptions inclusion', () => { describe( 'A US store will see the Subscriptions inclusion', () => {
const profileWizard = new OnboardingWizard( page ); const profileWizard = new OnboardingWizard( page );
const login = new Login( page ); new Login( page );
beforeAll( async () => { beforeAll( async () => {
await resetWooCommerceState(); await resetWooCommerceState();

View File

@ -2,6 +2,8 @@
* External dependencies * External dependencies
*/ */
import { afterAll, beforeAll, describe, it } from '@jest/globals'; import { afterAll, beforeAll, describe, it } from '@jest/globals';
// TODO fix the type for this module.
// eslint-disable-next-line
import { createSimpleProduct, withRestApi } from '@woocommerce/e2e-utils'; import { createSimpleProduct, withRestApi } from '@woocommerce/e2e-utils';
/** /**

View File

@ -52,7 +52,9 @@ const verifyPublishAndTrash = async (
if ( button === '.order_actions li .save_order' ) { if ( button === '.order_actions li .save_order' ) {
await expect( page ).toMatchElement( await expect( page ).toMatchElement(
'#select2-order_status-container', '#select2-order_status-container',
{ text: 'Processing' } {
text: 'Processing',
}
); );
await expect( page ).toMatchElement( await expect( page ).toMatchElement(
'#woocommerce-order-notes .note_content', '#woocommerce-order-notes .note_content',

View File

@ -3,4 +3,5 @@ module.exports = {
rules: { rules: {
'jsdoc/check-tag-names': 'off', 'jsdoc/check-tag-names': 'off',
}, },
root: true,
}; };

View File

@ -195,6 +195,7 @@ const createSampleData = async () => {
} ); } );
// Create an order with all possible numerical fields (taxes, fees, refunds, etc). // Create an order with all possible numerical fields (taxes, fees, refunds, etc).
// eslint-disable-next-line
const { body: taxSetting } = await getRequest( const { body: taxSetting } = await getRequest(
'settings/general/woocommerce_calc_taxes' 'settings/general/woocommerce_calc_taxes'
); );
@ -202,6 +203,7 @@ const createSampleData = async () => {
value: 'yes', value: 'yes',
} ); } );
// eslint-disable-next-line
const { body: taxRate } = await postRequest( 'taxes', { const { body: taxRate } = await postRequest( 'taxes', {
country: '*', country: '*',
state: '*', state: '*',
@ -209,15 +211,18 @@ const createSampleData = async () => {
city: '*', city: '*',
rate: '5.5000', rate: '5.5000',
name: 'Tax', name: 'Tax',
// eslint-disable-next-line
rate: '5.5', rate: '5.5',
shipping: true, shipping: true,
} ); } );
// eslint-disable-next-line
const { body: coupon } = await postRequest( 'coupons', { const { body: coupon } = await postRequest( 'coupons', {
code: 'save5', code: 'save5',
amount: '5', amount: '5',
} ); } );
// eslint-disable-next-line
const { body: order4 } = await ordersApi.create.order( { const { body: order4 } = await ordersApi.create.order( {
...orderBaseData, ...orderBaseData,
line_items: [ line_items: [

View File

@ -273,8 +273,7 @@ const createSampleSimpleProducts = async ( categories, attributes, tags ) => {
{ {
id: '2579cf07-8b08-4c25-888a-b6258dd1f035', id: '2579cf07-8b08-4c25-888a-b6258dd1f035',
name: 'Single', name: 'Single',
file: file: 'https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg',
'https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg',
}, },
], ],
download_limit: 1, download_limit: 1,
@ -336,14 +335,12 @@ const createSampleSimpleProducts = async ( categories, attributes, tags ) => {
{ {
id: 'cc10249f-1de2-44d4-93d3-9f88ae629f76', id: 'cc10249f-1de2-44d4-93d3-9f88ae629f76',
name: 'Single 1', name: 'Single 1',
file: file: 'https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg',
'https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/single.jpg',
}, },
{ {
id: 'aea8ef69-ccdc-4d83-8e21-3c395ebb9411', id: 'aea8ef69-ccdc-4d83-8e21-3c395ebb9411',
name: 'Single 2', name: 'Single 2',
file: file: 'https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/album.jpg',
'https://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2017/08/album.jpg',
}, },
], ],
download_limit: 1, download_limit: 1,

View File

@ -6,9 +6,9 @@
* - `flat_rate` * - `flat_rate`
* - `local_pickup` * - `local_pickup`
* *
* @param methodId * @param {string} methodId
* @param cost * @param {string} cost
* @return shipping method object that can serve as a request payload for adding a shipping method to a shipping zone. * @return {Object} shipping method object that can serve as a request payload for adding a shipping method to a shipping zone.
*/ */
const getShippingMethodExample = ( methodId, cost ) => { const getShippingMethodExample = ( methodId, cost ) => {
const shippingMethodExample = { const shippingMethodExample = {

View File

@ -13,7 +13,7 @@ const shippingZone = {
/** /**
* Constructs a default shipping zone object. * Constructs a default shipping zone object.
* *
* @return default shipping zone * @return {Object} default shipping zone
*/ */
const getShippingZoneExample = () => { const getShippingZoneExample = () => {
return shippingZone; return shippingZone;

View File

@ -29,6 +29,7 @@ const taxRatesApi = {
method: 'GET', method: 'GET',
path: 'taxes/<id>', path: 'taxes/<id>',
responseCode: 200, responseCode: 200,
// eslint-disable-next-line no-undef
taxRate: async ( taxRateId ) => taxes( `coupons/${ taxRateId }` ), taxRate: async ( taxRateId ) => taxes( `coupons/${ taxRateId }` ),
}, },
listAll: { listAll: {

View File

@ -47,9 +47,11 @@ const variationsApi = {
path: 'products/<product_id>/variations/<id>', path: 'products/<product_id>/variations/<id>',
responseCode: 200, responseCode: 200,
payload: getVariationExample(), payload: getVariationExample(),
// eslint-disable-next-line
variation: async ( productId, variationId, variationDetails ) => variation: async ( productId, variationId, variationDetails ) =>
putRequest( putRequest(
`products/${ productId }/variations/${ variationId }`, `products/${ productId }/variations/${ variationId }`,
// eslint-disable-next-line
taxRateDetails taxRateDetails
), ),
}, },
@ -75,6 +77,7 @@ const variationsApi = {
payload: shared.getBatchPayloadExample( getVariationExample() ), payload: shared.getBatchPayloadExample( getVariationExample() ),
variations: async ( batchUpdatePayload ) => variations: async ( batchUpdatePayload ) =>
postRequest( postRequest(
// eslint-disable-next-line
`products/${ productId }/variations/${ variationId }`, `products/${ productId }/variations/${ variationId }`,
batchUpdatePayload batchUpdatePayload
), ),

View File

@ -167,6 +167,7 @@ describe( 'Coupons API tests', () => {
expect( deletedCouponIds ).toEqual( couponIdsToDelete ); expect( deletedCouponIds ).toEqual( couponIdsToDelete );
// Verify that the 2 deleted coupons cannot be retrieved. // Verify that the 2 deleted coupons cannot be retrieved.
// eslint-disable-next-line
for ( const couponId of couponIdsToDelete ) { for ( const couponId of couponIdsToDelete ) {
const { status } = await couponsApi.retrieve.coupon( couponId ); const { status } = await couponsApi.retrieve.coupon( couponId );
@ -202,6 +203,7 @@ describe( 'Coupons API tests', () => {
const actualCreatedCoupons = response.body.create; const actualCreatedCoupons = response.body.create;
// Save their coupon ID's // Save their coupon ID's
// eslint-disable-next-line
for ( const coupon of allCoupons ) { for ( const coupon of allCoupons ) {
const { id } = actualCreatedCoupons.find( const { id } = actualCreatedCoupons.find(
( { code } ) => coupon.code === code ( { code } ) => coupon.code === code

View File

@ -199,6 +199,7 @@ describe( 'Orders API test', () => {
expectedLineTaxTotal, expectedLineTaxTotal,
] of expectedTaxTotalsPerLineItem ) { ] of expectedTaxTotalsPerLineItem ) {
const { total_tax: actualLineTaxTotal } = body.line_items.find( const { total_tax: actualLineTaxTotal } = body.line_items.find(
// eslint-disable-next-line
( { product_id } ) => product_id === product.id ( { product_id } ) => product_id === product.id
); );

View File

@ -162,6 +162,7 @@ describe( 'Orders API tests', () => {
per_page: 10, per_page: 10,
} ); } );
expect( allOrders.statusCode ).toEqual( 200 ); expect( allOrders.statusCode ).toEqual( 200 );
// eslint-disable-next-line
const allOrdersIds = allOrders.body.map( ( order ) => order.id ); const allOrdersIds = allOrders.body.map( ( order ) => order.id );
expect( allOrdersIds ).toHaveLength( ORDERS_COUNT ); expect( allOrdersIds ).toHaveLength( ORDERS_COUNT );
@ -286,6 +287,7 @@ describe( 'Orders API tests', () => {
} ); } );
expect( result1.statusCode ).toEqual( 200 ); expect( result1.statusCode ).toEqual( 200 );
expect( result1.body ).toHaveLength( 5 ); expect( result1.body ).toHaveLength( 5 );
// eslint-disable-next-line
result1.body.forEach( ( order ) => result1.body.forEach( ( order ) =>
expect( order ).toEqual( expect( order ).toEqual(
expect.objectContaining( { expect.objectContaining( {
@ -299,6 +301,7 @@ describe( 'Orders API tests', () => {
} ); } );
expect( result2.statusCode ).toEqual( 200 ); expect( result2.statusCode ).toEqual( 200 );
expect( result2.body ).toHaveLength( 3 ); expect( result2.body ).toHaveLength( 3 );
// eslint-disable-next-line
result2.body.forEach( ( order ) => result2.body.forEach( ( order ) =>
expect( order ).toEqual( expect( order ).toEqual(
expect.objectContaining( { expect.objectContaining( {
@ -317,6 +320,7 @@ describe( 'Orders API tests', () => {
} ); } );
expect( result1.statusCode ).toEqual( 200 ); expect( result1.statusCode ).toEqual( 200 );
expect( result1.body ).toHaveLength( 2 ); expect( result1.body ).toHaveLength( 2 );
// eslint-disable-next-line
result1.body.forEach( ( order ) => result1.body.forEach( ( order ) =>
expect( order ).toEqual( expect( order ).toEqual(
expect.objectContaining( { expect.objectContaining( {
@ -340,6 +344,7 @@ describe( 'Orders API tests', () => {
); );
}; };
// eslint-disable-next-line
const verifyOrderPrecision = ( order, dp ) => { const verifyOrderPrecision = ( order, dp ) => {
expectPrecisionToMatch( order.discount_total, dp ); expectPrecisionToMatch( order.discount_total, dp );
expectPrecisionToMatch( order.discount_tax, dp ); expectPrecisionToMatch( order.discount_tax, dp );
@ -413,6 +418,7 @@ describe( 'Orders API tests', () => {
} ); } );
expect( result1.statusCode ).toEqual( 200 ); expect( result1.statusCode ).toEqual( 200 );
expect( result1.body ).toHaveLength( 7 ); expect( result1.body ).toHaveLength( 7 );
// eslint-disable-next-line
result1.body.forEach( ( order ) => result1.body.forEach( ( order ) =>
expect( order.billing.email ).toContain( 'example.com' ) expect( order.billing.email ).toContain( 'example.com' )
); );
@ -439,6 +445,7 @@ describe( 'Orders API tests', () => {
} ); } );
expect( result4.statusCode ).toEqual( 200 ); expect( result4.statusCode ).toEqual( 200 );
expect( result4.body ).toHaveLength( 5 ); expect( result4.body ).toHaveLength( 5 );
// eslint-disable-next-line
result4.body.forEach( ( order ) => result4.body.forEach( ( order ) =>
expect( order.billing.last_name ).toEqual( 'Doe' ) expect( order.billing.last_name ).toEqual( 'Doe' )
); );
@ -449,6 +456,7 @@ describe( 'Orders API tests', () => {
} ); } );
expect( result5.statusCode ).toEqual( 200 ); expect( result5.statusCode ).toEqual( 200 );
expect( result5.body ).toHaveLength( 2 ); expect( result5.body ).toHaveLength( 2 );
// eslint-disable-next-line
result5.body.forEach( ( order ) => result5.body.forEach( ( order ) =>
expect( order ).toEqual( expect( order ).toEqual(
expect.objectContaining( { expect.objectContaining( {
@ -472,7 +480,9 @@ describe( 'Orders API tests', () => {
// Verify all dates are in descending order. // Verify all dates are in descending order.
let lastDate = Date.now(); let lastDate = Date.now();
// eslint-disable-next-line
result.body.forEach( ( { date_created } ) => { result.body.forEach( ( { date_created } ) => {
// eslint-disable-next-line
const created = Date.parse( date_created + '.000Z' ); const created = Date.parse( date_created + '.000Z' );
expect( lastDate ).toBeGreaterThanOrEqual( created ); expect( lastDate ).toBeGreaterThanOrEqual( created );
lastDate = created; lastDate = created;
@ -488,7 +498,9 @@ describe( 'Orders API tests', () => {
// Verify all dates are in ascending order. // Verify all dates are in ascending order.
let lastDate = 0; let lastDate = 0;
// eslint-disable-next-line
result.body.forEach( ( { date_created } ) => { result.body.forEach( ( { date_created } ) => {
// eslint-disable-next-line
const created = Date.parse( date_created + '.000Z' ); const created = Date.parse( date_created + '.000Z' );
expect( created ).toBeGreaterThanOrEqual( lastDate ); expect( created ).toBeGreaterThanOrEqual( lastDate );
lastDate = created; lastDate = created;

View File

@ -101,9 +101,8 @@ describe( 'Products API tests: CRUD', () => {
expect( body.id ).toEqual( productId ); expect( body.id ).toEqual( productId );
// Verify that the product can no longer be retrieved. // Verify that the product can no longer be retrieved.
const { const { status: retrieveDeletedProductStatus } =
status: retrieveDeletedProductStatus, await productsApi.retrieve.product( productId );
} = await productsApi.retrieve.product( productId );
expect( retrieveDeletedProductStatus ).toEqual( 404 ); expect( retrieveDeletedProductStatus ).toEqual( 404 );
} ); } );
@ -156,6 +155,7 @@ describe( 'Products API tests: CRUD', () => {
// Verify that the regular price of each product was updated // Verify that the regular price of each product was updated
for ( let i = 0; i < actualUpdatedProducts.length; i++ ) { for ( let i = 0; i < actualUpdatedProducts.length; i++ ) {
// eslint-disable-next-line
const { id, regular_price } = actualUpdatedProducts[ i ]; const { id, regular_price } = actualUpdatedProducts[ i ];
expect( id ).toEqual( expectedProducts[ i ].id ); expect( id ).toEqual( expectedProducts[ i ].id );
@ -186,6 +186,7 @@ describe( 'Products API tests: CRUD', () => {
// Verify that the deleted product ID's can no longer be retrieved // Verify that the deleted product ID's can no longer be retrieved
for ( const id of idsToDelete ) { for ( const id of idsToDelete ) {
// eslint-disable-next-line
const { status } = await productsApi.retrieve.product( id ); const { status } = await productsApi.retrieve.product( id );
expect( status ).toEqual( 404 ); expect( status ).toEqual( 404 );

View File

@ -28,10 +28,8 @@ describe( 'Shipping methods API tests', () => {
async ( methodTitle, methodId, cost ) => { async ( methodTitle, methodId, cost ) => {
const shippingMethod = getShippingMethodExample( methodId, cost ); const shippingMethod = getShippingMethodExample( methodId, cost );
const { const { status, body } =
status, await shippingMethodsApi.create.shippingMethod(
body,
} = await shippingMethodsApi.create.shippingMethod(
shippingZoneId, shippingZoneId,
shippingMethod shippingMethod
); );

View File

@ -12,9 +12,11 @@ const { BASE_URL, USER_KEY, USER_SECRET, USE_INDEX_PERMALINKS } = process.env;
// Set up our empty collection // Set up our empty collection
if ( typeof USER_KEY === 'undefined' ) { if ( typeof USER_KEY === 'undefined' ) {
// eslint-disable-next-line
console.log( 'No USER_KEY was defined.' ); console.log( 'No USER_KEY was defined.' );
} }
if ( typeof USER_SECRET === 'undefined' ) { if ( typeof USER_SECRET === 'undefined' ) {
// eslint-disable-next-line
console.log( 'No USER_SECRET was defined.' ); console.log( 'No USER_SECRET was defined.' );
} }
@ -41,6 +43,7 @@ const postmanCollection = new Collection( {
// Get the API url // Get the API url
if ( typeof BASE_URL === 'undefined' ) { if ( typeof BASE_URL === 'undefined' ) {
// eslint-disable-next-line
console.log( 'No BASE_URL was defined.' ); console.log( 'No BASE_URL was defined.' );
} }
@ -62,6 +65,7 @@ postmanCollection.variables.add( {
// Get the API request data // Get the API request data
const resources = require( '../../endpoints' ); const resources = require( '../../endpoints' );
// eslint-disable-next-line
resourceKeys = Object.keys( resources ); resourceKeys = Object.keys( resources );
// Add the requests to folders in the collection // Add the requests to folders in the collection
@ -108,8 +112,10 @@ fs.writeFile(
JSON.stringify( collectionJSON ), JSON.stringify( collectionJSON ),
( err ) => { ( err ) => {
if ( err ) { if ( err ) {
// eslint-disable-next-line
console.log( err ); console.log( err );
} }
// eslint-disable-next-line
console.log( 'File saved!' ); console.log( 'File saved!' );
} }
); );

View File

@ -1,5 +1,6 @@
require( 'dotenv' ).config(); require( 'dotenv' ).config();
const { USER_KEY, USER_SECRET } = process.env; const { USER_KEY, USER_SECRET } = process.env;
// eslint-disable-next-line
const request = require( 'supertest' )( API_PATH ); const request = require( 'supertest' )( API_PATH );
/** /**
@ -7,7 +8,7 @@ const request = require( 'supertest' )( API_PATH );
* *
* @param {string} requestPath The path of the request. * @param {string} requestPath The path of the request.
* @param {Object} queryString Optional. An object of one or more `key: value` query string parameters. * @param {Object} queryString Optional. An object of one or more `key: value` query string parameters.
* @return {Response} * @return {Response} The response object.
*/ */
const getRequest = async ( requestPath, queryString = {} ) => { const getRequest = async ( requestPath, queryString = {} ) => {
const response = await request const response = await request
@ -23,7 +24,7 @@ const getRequest = async ( requestPath, queryString = {} ) => {
* *
* @param {string} requestPath The path of the request. * @param {string} requestPath The path of the request.
* @param {Object} requestBody The body of the request to submit. * @param {Object} requestBody The body of the request to submit.
* @return {Response} * @return {Response} The response object.
*/ */
const postRequest = async ( requestPath, requestBody ) => { const postRequest = async ( requestPath, requestBody ) => {
const response = await request const response = await request
@ -39,7 +40,7 @@ const postRequest = async ( requestPath, requestBody ) => {
* *
* @param {string} requestPath The path of the request. * @param {string} requestPath The path of the request.
* @param {Object} requestBody The body of the request to submit. * @param {Object} requestBody The body of the request to submit.
* @return {Request} * @return {Request} The request object.
*/ */
const putRequest = async ( requestPath, requestBody ) => { const putRequest = async ( requestPath, requestBody ) => {
const response = await request const response = await request
@ -55,7 +56,7 @@ const putRequest = async ( requestPath, requestBody ) => {
* *
* @param {string} requestPath The path of the request. * @param {string} requestPath The path of the request.
* @param {boolean} deletePermanently Flag to permanently delete the resource. * @param {boolean} deletePermanently Flag to permanently delete the resource.
* @return {Response} * @return {Response} The response object.
*/ */
const deleteRequest = async ( requestPath, deletePermanently = false ) => { const deleteRequest = async ( requestPath, deletePermanently = false ) => {
const requestBody = deletePermanently ? { force: true } : {}; const requestBody = deletePermanently ? { force: true } : {};

View File

@ -6,3 +6,4 @@ jest.config.js
package.json package.json
package-lock.json package-lock.json
tsconfig.json tsconfig.json
__tests__

View File

@ -1,32 +1,12 @@
module.exports = { module.exports = {
parser: '@typescript-eslint/parser', extends: [ 'plugin:@woocommerce/eslint-plugin/recommended' ],
env: { plugins: [ 'jest' ],
'jest/globals': true, root: true,
},
ignorePatterns: [ 'dist/', 'node_modules/' ],
rules: { rules: {
'no-unused-vars': 'off', // These warning rules are stop gaps for eslint issues that need to be fixed later.
'no-dupe-class-members': 'off', '@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-use-before-define': 'off',
'no-useless-constructor': 'off', '@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/no-useless-constructor': 2, '@typescript-eslint/no-unused-vars': 'off',
}, },
plugins: [ '@typescript-eslint/eslint-plugin' ],
extends: [ 'plugin:@wordpress/eslint-plugin/recommended-with-formatting' ],
overrides: [
{
files: [ '**/*.js', '**/*.ts' ],
settings: {
jsdoc: {
mode: 'typescript',
},
},
},
{
files: [ '**/*.spec.ts', '**/*.test.ts' ],
rules: {
'no-console': 'off',
},
},
],
}; };

View File

@ -53,6 +53,7 @@
"@types/node": "13.13.5", "@types/node": "13.13.5",
"@typescript-eslint/eslint-plugin": "^5.3.1", "@typescript-eslint/eslint-plugin": "^5.3.1",
"@typescript-eslint/parser": "^5.3.1", "@typescript-eslint/parser": "^5.3.1",
"@woocommerce/eslint-plugin": "workspace:*",
"axios-mock-adapter": "^1.20.0", "axios-mock-adapter": "^1.20.0",
"eslint": "^8.2.0", "eslint": "^8.2.0",
"jest": "^27", "jest": "^27",

View File

@ -1,10 +1,13 @@
/**
* Internal dependencies
*/
import { Model } from '../models'; import { Model } from '../models';
/** /**
* A dummy model that can be used in test files. * A dummy model that can be used in test files.
*/ */
export class DummyModel extends Model { export class DummyModel extends Model {
public name: string = ''; public name = '';
public constructor( partial?: Partial< DummyModel > ) { public constructor( partial?: Partial< DummyModel > ) {
super(); super();

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { Model, ModelID } from '../models'; import { Model, ModelID } from '../models';
/** /**
@ -352,7 +355,8 @@ implements
UpdatesModels< T >, UpdatesModels< T >,
UpdatesChildModels< T >, UpdatesChildModels< T >,
DeletesModels< T >, DeletesModels< T >,
DeletesChildModels< T > { DeletesChildModels< T >
{
/** /**
* The hook used to list models. * The hook used to list models.
* *
@ -460,7 +464,7 @@ implements
} }
return ( this.listHook as ListChildFn< T > )( return ( this.listHook as ListChildFn< T > )(
( paramsOrParent as unknown ) as ParentID< T >, paramsOrParent as unknown as ParentID< T >,
params params
); );
} }
@ -493,7 +497,7 @@ implements
} }
return ( this.createHook as CreateChildFn< T > )( return ( this.createHook as CreateChildFn< T > )(
( propertiesOrParent as unknown ) as ParentID< T >, propertiesOrParent as unknown as ParentID< T >,
properties as Partial< ModelClass< T > > properties as Partial< ModelClass< T > >
); );
} }
@ -520,7 +524,7 @@ implements
} }
return ( this.readHook as ReadChildFn< T > )( return ( this.readHook as ReadChildFn< T > )(
( idOrParent as unknown ) as ParentID< T >, idOrParent as unknown as ParentID< T >,
childID childID
); );
} }
@ -547,14 +551,14 @@ implements
if ( properties === undefined ) { if ( properties === undefined ) {
return ( this.updateHook as UpdateFn< T > )( return ( this.updateHook as UpdateFn< T > )(
idOrParent as ModelID, idOrParent as ModelID,
( propertiesOrChildID as unknown ) as UpdateParams< T > propertiesOrChildID as unknown as UpdateParams< T >
); );
} }
return ( this.updateHook as UpdateChildFn< T > )( return ( this.updateHook as UpdateChildFn< T > )(
( idOrParent as unknown ) as ParentID< T >, idOrParent as unknown as ParentID< T >,
propertiesOrChildID as ModelID, propertiesOrChildID as ModelID,
( properties as unknown ) as UpdateParams< T > properties as unknown as UpdateParams< T >
); );
} }
@ -580,7 +584,7 @@ implements
} }
return ( this.deleteHook as DeleteChildFn< T > )( return ( this.deleteHook as DeleteChildFn< T > )(
( idOrParent as unknown ) as ParentID< T >, idOrParent as unknown as ParentID< T >,
childID childID
); );
} }

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { Model, ModelConstructor } from '../models'; import { Model, ModelConstructor } from '../models';
/** /**

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { ModelTransformation, TransformationOrder } from '../model-transformer'; import { ModelTransformation, TransformationOrder } from '../model-transformer';
/** /**

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { ModelTransformation } from '../model-transformer'; import { ModelTransformation } from '../model-transformer';
/** /**

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { ModelTransformation, TransformationOrder } from '../model-transformer'; import { ModelTransformation, TransformationOrder } from '../model-transformer';
export class IgnorePropertyTransformation implements ModelTransformation { export class IgnorePropertyTransformation implements ModelTransformation {

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { ModelTransformation, TransformationOrder } from '../model-transformer'; import { ModelTransformation, TransformationOrder } from '../model-transformer';
import { Model } from '../../models'; import { Model } from '../../models';
@ -15,7 +18,8 @@ type KeyChanges< T extends Model > = {
* other transformations to prevent the changed key from causing problems. * other transformations to prevent the changed key from causing problems.
*/ */
export class KeyChangeTransformation< T extends Model > export class KeyChangeTransformation< T extends Model >
implements ModelTransformation { implements ModelTransformation
{
/** /**
* Ensure that this transformation always happens at the very end since it changes the keys * Ensure that this transformation always happens at the very end since it changes the keys
* in the transformed object. * in the transformed object.

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { import {
ModelTransformation, ModelTransformation,
ModelTransformer, ModelTransformer,
@ -11,7 +14,8 @@ import { Model, ModelConstructor } from '../../models';
* @template T * @template T
*/ */
export class ModelTransformerTransformation< T extends Model > export class ModelTransformerTransformation< T extends Model >
implements ModelTransformation { implements ModelTransformation
{
public readonly fromModelOrder = TransformationOrder.Normal; public readonly fromModelOrder = TransformationOrder.Normal;
/** /**

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { ModelTransformation, TransformationOrder } from '../model-transformer'; import { ModelTransformation, TransformationOrder } from '../model-transformer';
/** /**
@ -134,6 +137,7 @@ export class PropertyTypeTransformation implements ModelTransformation {
case PropertyType.String: case PropertyType.String:
return String( value ); return String( value );
case PropertyType.Integer: case PropertyType.Integer:
// eslint-disable-next-line
return parseInt( value ); return parseInt( value );
case PropertyType.Float: case PropertyType.Float:
return parseFloat( value ); return parseFloat( value );

View File

@ -1,5 +1,12 @@
import { HTTPClient, HTTPResponse } from '../http-client'; /**
* External dependencies
*/
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios'; import axios, { AxiosInstance, AxiosRequestConfig } from 'axios';
/**
* Internal dependencies
*/
import { HTTPClient, HTTPResponse } from '../http-client';
import { AxiosInterceptor } from './axios-interceptor'; import { AxiosInterceptor } from './axios-interceptor';
import { AxiosResponseInterceptor } from './axios-response-interceptor'; import { AxiosResponseInterceptor } from './axios-response-interceptor';

View File

@ -1,3 +1,6 @@
/**
* External dependencies
*/
import { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'; import { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
/** /**

View File

@ -1,6 +1,13 @@
/**
* External dependencies
*/
import type { AxiosRequestConfig } from 'axios'; import type { AxiosRequestConfig } from 'axios';
import * as createHmac from 'create-hmac'; import * as createHmac from 'create-hmac';
import * as OAuth from 'oauth-1.0a'; import * as OAuth from 'oauth-1.0a';
/**
* Internal dependencies
*/
import { AxiosInterceptor } from './axios-interceptor'; import { AxiosInterceptor } from './axios-interceptor';
import { buildURLWithParams } from './utils'; import { buildURLWithParams } from './utils';
@ -56,6 +63,7 @@ export class AxiosOAuthInterceptor extends AxiosInterceptor {
request.headers.Authorization = this.oauth.toHeader( request.headers.Authorization = this.oauth.toHeader(
this.oauth.authorize( { this.oauth.authorize( {
url, url,
// eslint-disable-next-line
method: request.method!, method: request.method!,
} ) } )
).Authorization; ).Authorization;

View File

@ -1,4 +1,11 @@
/**
* External dependencies
*/
import { AxiosResponse } from 'axios'; import { AxiosResponse } from 'axios';
/**
* Internal dependencies
*/
import { AxiosInterceptor } from './axios-interceptor'; import { AxiosInterceptor } from './axios-interceptor';
import { HTTPResponse } from '../http-client'; import { HTTPResponse } from '../http-client';

View File

@ -1,5 +1,12 @@
import { AxiosInterceptor } from './axios-interceptor'; /**
* External dependencies
*/
import { AxiosRequestConfig } from 'axios'; import { AxiosRequestConfig } from 'axios';
/**
* Internal dependencies
*/
import { AxiosInterceptor } from './axios-interceptor';
import { buildURL } from './utils'; import { buildURL } from './utils';
/** /**

View File

@ -1,3 +1,6 @@
/**
* External dependencies
*/
import { AxiosRequestConfig } from 'axios'; import { AxiosRequestConfig } from 'axios';
// @ts-ignore // @ts-ignore

View File

@ -1,6 +1,13 @@
/**
* External dependencies
*/
import { AxiosRequestConfig } from 'axios';
/**
* Internal dependencies
*/
import { HTTPClient } from './http-client'; import { HTTPClient } from './http-client';
import { AxiosClient, AxiosOAuthInterceptor } from './axios'; import { AxiosClient, AxiosOAuthInterceptor } from './axios';
import { AxiosRequestConfig } from 'axios';
import { AxiosInterceptor } from './axios/axios-interceptor'; import { AxiosInterceptor } from './axios/axios-interceptor';
import { AxiosURLToQueryInterceptor } from './axios/axios-url-to-query-interceptor'; import { AxiosURLToQueryInterceptor } from './axios/axios-url-to-query-interceptor';

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { Model } from '../model'; import { Model } from '../model';
import { HTTPClient } from '../../http'; import { HTTPClient } from '../../http';
import { couponRESTRepository } from '../../repositories'; import { couponRESTRepository } from '../../repositories';
@ -126,7 +129,7 @@ export class Coupon extends Model {
* *
* @type {number} * @type {number}
*/ */
public readonly usageCount: Number = 0; public readonly usageCount: number = 0;
/** /**
* Flags if the coupon can only be used on its own and not combined with other coupons. * Flags if the coupon can only be used on its own and not combined with other coupons.
@ -154,21 +157,21 @@ export class Coupon extends Model {
* *
* @type {number} * @type {number}
*/ */
public readonly usageLimit: Number = -1; public readonly usageLimit: number = -1;
/** /**
* How many times the coupon can be used per customer. * How many times the coupon can be used per customer.
* *
* @type {number} * @type {number}
*/ */
public readonly usageLimitPerUser: Number = -1; public readonly usageLimitPerUser: number = -1;
/** /**
* Max number of items in the cart the coupon can be applied to. * Max number of items in the cart the coupon can be applied to.
* *
* @type {number} * @type {number}
*/ */
public readonly limitUsageToXItems: Number = -1; public readonly limitUsageToXItems: number = -1;
/** /**
* Flags if the free shipping option requires a coupon. This coupon will enable free shipping. * Flags if the free shipping option requires a coupon. This coupon will enable free shipping.

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { HTTPClient } from '../../http'; import { HTTPClient } from '../../http';
import { orderRESTRepository } from '../../repositories'; import { orderRESTRepository } from '../../repositories';
import { import {

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { MetaData } from '../../shared-types'; import { MetaData } from '../../shared-types';
import { Model, ModelID } from '../../model'; import { Model, ModelID } from '../../model';
import { TaxStatus } from './types'; import { TaxStatus } from './types';

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { AbstractProductData } from './data'; import { AbstractProductData } from './data';
import { ModelID } from '../../model'; import { ModelID } from '../../model';
import { CatalogVisibility, ProductTerm, ProductAttribute } from '../shared'; import { CatalogVisibility, ProductTerm, ProductAttribute } from '../shared';
@ -153,4 +156,4 @@ export abstract class AbstractProduct extends AbstractProductData {
}; };
} }
export interface IProductCommon extends AbstractProduct {} export type IProductCommon = AbstractProduct;

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { Model } from '../../model'; import { Model } from '../../model';
/** /**
@ -12,4 +15,4 @@ abstract class AbstractProductCrossSells extends Model {
public readonly crossSellIds: Array< number > = []; public readonly crossSellIds: Array< number > = [];
} }
export interface IProductCrossSells extends AbstractProductCrossSells {} export type IProductCrossSells = AbstractProductCrossSells;

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { Model } from '../../model'; import { Model } from '../../model';
import { MetaData, PostStatus, ObjectLinks } from '../../shared-types'; import { MetaData, PostStatus, ObjectLinks } from '../../shared-types';
import { ProductImage } from '../shared'; import { ProductImage } from '../shared';

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { Model } from '../../model'; import { Model } from '../../model';
import { ProductDownload } from '../shared'; import { ProductDownload } from '../shared';
@ -48,4 +51,4 @@ abstract class AbstractProductDelivery extends Model {
public readonly purchaseNote: string = ''; public readonly purchaseNote: string = '';
} }
export interface IProductDelivery extends AbstractProductDelivery {} export type IProductDelivery = AbstractProductDelivery;

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { Model } from '../../model'; import { Model } from '../../model';
/** /**
@ -19,4 +22,4 @@ abstract class AbstractProductExternal extends Model {
public readonly externalUrl: string = ''; public readonly externalUrl: string = '';
} }
export interface IProductExternal extends AbstractProductExternal {} export type IProductExternal = AbstractProductExternal;

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { Model } from '../../model'; import { Model } from '../../model';
/** /**
@ -12,4 +15,4 @@ abstract class AbstractProductGrouped extends Model {
public readonly groupedProducts: Array< number > = []; public readonly groupedProducts: Array< number > = [];
} }
export interface IProductGrouped extends AbstractProductGrouped {} export type IProductGrouped = AbstractProductGrouped;

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { Model } from '../../model'; import { Model } from '../../model';
import { BackorderStatus, StockStatus } from '../shared'; import { BackorderStatus, StockStatus } from '../shared';
@ -62,4 +65,4 @@ abstract class AbstractProductInventory extends Model {
public readonly lowStockThreshold: number = -1; public readonly lowStockThreshold: number = -1;
} }
export interface IProductInventory extends AbstractProductInventory {} export type IProductInventory = AbstractProductInventory;

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { Model } from '../../model'; import { Model } from '../../model';
/** /**
@ -54,4 +57,4 @@ abstract class AbstractProductPrice extends Model {
public readonly saleEnd: Date | null = null; public readonly saleEnd: Date | null = null;
} }
export interface IProductPrice extends AbstractProductPrice {} export type IProductPrice = AbstractProductPrice;

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { Model } from '../../model'; import { Model } from '../../model';
import { Taxability } from '../shared'; import { Taxability } from '../shared';
@ -20,4 +23,4 @@ abstract class AbstractProductSalesTax extends Model {
public readonly taxClass: string = ''; public readonly taxClass: string = '';
} }
export interface IProductSalesTax extends AbstractProductSalesTax {} export type IProductSalesTax = AbstractProductSalesTax;

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { Model } from '../../model'; import { Model } from '../../model';
/** /**
@ -61,4 +64,4 @@ abstract class AbstractProductShipping extends Model {
public readonly shippingClassId: number = 0; public readonly shippingClassId: number = 0;
} }
export interface IProductShipping extends AbstractProductShipping {} export type IProductShipping = AbstractProductShipping;

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { Model } from '../../model'; import { Model } from '../../model';
/** /**
@ -12,4 +15,4 @@ abstract class AbstractProductUpSells extends Model {
public readonly upSellIds: Array< number > = []; public readonly upSellIds: Array< number > = [];
} }
export interface IProductUpSells extends AbstractProductUpSells {} export type IProductUpSells = AbstractProductUpSells;

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { import {
AbstractProduct, AbstractProduct,
IProductCommon, IProductCommon,
@ -51,7 +54,8 @@ export type ExternalProductRepositoryParams = ModelRepositoryParams<
* @typedef ListsExternalProducts * @typedef ListsExternalProducts
* @alias ListsModels.<ExternalProduct> * @alias ListsModels.<ExternalProduct>
*/ */
export type ListsExternalProducts = ListsModels< ExternalProductRepositoryParams >; export type ListsExternalProducts =
ListsModels< ExternalProductRepositoryParams >;
/** /**
* An interface for external simple products using the repository. * An interface for external simple products using the repository.
@ -59,7 +63,8 @@ export type ListsExternalProducts = ListsModels< ExternalProductRepositoryParams
* @typedef CreatesExternalProducts * @typedef CreatesExternalProducts
* @alias CreatesModels.<ExternalProduct> * @alias CreatesModels.<ExternalProduct>
*/ */
export type CreatesExternalProducts = CreatesModels< ExternalProductRepositoryParams >; export type CreatesExternalProducts =
CreatesModels< ExternalProductRepositoryParams >;
/** /**
* An interface for reading external products using the repository. * An interface for reading external products using the repository.
@ -67,7 +72,8 @@ export type CreatesExternalProducts = CreatesModels< ExternalProductRepositoryPa
* @typedef ReadsExternalProducts * @typedef ReadsExternalProducts
* @alias ReadsModels.<ExternalProduct> * @alias ReadsModels.<ExternalProduct>
*/ */
export type ReadsExternalProducts = ReadsModels< ExternalProductRepositoryParams >; export type ReadsExternalProducts =
ReadsModels< ExternalProductRepositoryParams >;
/** /**
* An interface for updating external products using the repository. * An interface for updating external products using the repository.
@ -75,7 +81,8 @@ export type ReadsExternalProducts = ReadsModels< ExternalProductRepositoryParams
* @typedef UpdatesExternalProducts * @typedef UpdatesExternalProducts
* @alias UpdatesModels.<ExternalProduct> * @alias UpdatesModels.<ExternalProduct>
*/ */
export type UpdatesExternalProducts = UpdatesModels< ExternalProductRepositoryParams >; export type UpdatesExternalProducts =
UpdatesModels< ExternalProductRepositoryParams >;
/** /**
* An interface for deleting external products using the repository. * An interface for deleting external products using the repository.
@ -83,7 +90,8 @@ export type UpdatesExternalProducts = UpdatesModels< ExternalProductRepositoryPa
* @typedef DeletesExternalProducts * @typedef DeletesExternalProducts
* @alias DeletesModels.<ExternalProduct> * @alias DeletesModels.<ExternalProduct>
*/ */
export type DeletesExternalProducts = DeletesModels< ExternalProductRepositoryParams >; export type DeletesExternalProducts =
DeletesModels< ExternalProductRepositoryParams >;
/** /**
* The base for the external product object. * The base for the external product object.
@ -95,7 +103,8 @@ export class ExternalProduct
IProductExternal, IProductExternal,
IProductPrice, IProductPrice,
IProductSalesTax, IProductSalesTax,
IProductUpSells { IProductUpSells
{
/** /**
* @see ./abstracts/external.ts * @see ./abstracts/external.ts
*/ */

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { import {
AbstractProduct, AbstractProduct,
IProductCommon, IProductCommon,
@ -44,7 +47,8 @@ export type GroupedProductRepositoryParams = ModelRepositoryParams<
* @typedef ListsGroupedProducts * @typedef ListsGroupedProducts
* @alias ListsModels.<GroupedProduct> * @alias ListsModels.<GroupedProduct>
*/ */
export type ListsGroupedProducts = ListsModels< GroupedProductRepositoryParams >; export type ListsGroupedProducts =
ListsModels< GroupedProductRepositoryParams >;
/** /**
* An interface for creating Grouped products using the repository. * An interface for creating Grouped products using the repository.
@ -52,7 +56,8 @@ export type ListsGroupedProducts = ListsModels< GroupedProductRepositoryParams >
* @typedef CreatesGroupedProducts * @typedef CreatesGroupedProducts
* @alias CreatesModels.<GroupedProduct> * @alias CreatesModels.<GroupedProduct>
*/ */
export type CreatesGroupedProducts = CreatesModels< GroupedProductRepositoryParams >; export type CreatesGroupedProducts =
CreatesModels< GroupedProductRepositoryParams >;
/** /**
* An interface for reading Grouped products using the repository. * An interface for reading Grouped products using the repository.
@ -60,7 +65,8 @@ export type CreatesGroupedProducts = CreatesModels< GroupedProductRepositoryPara
* @typedef ReadsGroupedProducts * @typedef ReadsGroupedProducts
* @alias ReadsModels.<GroupedProduct> * @alias ReadsModels.<GroupedProduct>
*/ */
export type ReadsGroupedProducts = ReadsModels< GroupedProductRepositoryParams >; export type ReadsGroupedProducts =
ReadsModels< GroupedProductRepositoryParams >;
/** /**
* An interface for updating Grouped products using the repository. * An interface for updating Grouped products using the repository.
@ -68,7 +74,8 @@ export type ReadsGroupedProducts = ReadsModels< GroupedProductRepositoryParams >
* @typedef UpdatesGroupedProducts * @typedef UpdatesGroupedProducts
* @alias UpdatesModels.<GroupedProduct> * @alias UpdatesModels.<GroupedProduct>
*/ */
export type UpdatesGroupedProducts = UpdatesModels< GroupedProductRepositoryParams >; export type UpdatesGroupedProducts =
UpdatesModels< GroupedProductRepositoryParams >;
/** /**
* An interface for deleting Grouped products using the repository. * An interface for deleting Grouped products using the repository.
@ -76,14 +83,16 @@ export type UpdatesGroupedProducts = UpdatesModels< GroupedProductRepositoryPara
* @typedef DeletesGroupedProducts * @typedef DeletesGroupedProducts
* @alias DeletesModels.<GroupedProduct> * @alias DeletesModels.<GroupedProduct>
*/ */
export type DeletesGroupedProducts = DeletesModels< GroupedProductRepositoryParams >; export type DeletesGroupedProducts =
DeletesModels< GroupedProductRepositoryParams >;
/** /**
* The base for the Grouped product object. * The base for the Grouped product object.
*/ */
export class GroupedProduct export class GroupedProduct
extends AbstractProduct extends AbstractProduct
implements IProductCommon, IProductGrouped, IProductUpSells { implements IProductCommon, IProductGrouped, IProductUpSells
{
/** /**
* @see ./abstracts/grouped.ts * @see ./abstracts/grouped.ts
*/ */

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { import {
AbstractProduct, AbstractProduct,
IProductCommon, IProductCommon,
@ -71,7 +74,8 @@ export type ListsSimpleProducts = ListsModels< SimpleProductRepositoryParams >;
* @typedef CreatesSimpleProducts * @typedef CreatesSimpleProducts
* @alias CreatesModels.<SimpleProduct> * @alias CreatesModels.<SimpleProduct>
*/ */
export type CreatesSimpleProducts = CreatesModels< SimpleProductRepositoryParams >; export type CreatesSimpleProducts =
CreatesModels< SimpleProductRepositoryParams >;
/** /**
* An interface for reading simple products using the repository. * An interface for reading simple products using the repository.
@ -87,7 +91,8 @@ export type ReadsSimpleProducts = ReadsModels< SimpleProductRepositoryParams >;
* @typedef UpdatesSimpleProducts * @typedef UpdatesSimpleProducts
* @alias UpdatesModels.<SimpleProduct> * @alias UpdatesModels.<SimpleProduct>
*/ */
export type UpdatesSimpleProducts = UpdatesModels< SimpleProductRepositoryParams >; export type UpdatesSimpleProducts =
UpdatesModels< SimpleProductRepositoryParams >;
/** /**
* An interface for deleting simple products using the repository. * An interface for deleting simple products using the repository.
@ -95,7 +100,8 @@ export type UpdatesSimpleProducts = UpdatesModels< SimpleProductRepositoryParams
* @typedef DeletesSimpleProducts * @typedef DeletesSimpleProducts
* @alias DeletesModels.<SimpleProduct> * @alias DeletesModels.<SimpleProduct>
*/ */
export type DeletesSimpleProducts = DeletesModels< SimpleProductRepositoryParams >; export type DeletesSimpleProducts =
DeletesModels< SimpleProductRepositoryParams >;
/** /**
* The base for the simple product object. * The base for the simple product object.
@ -110,7 +116,8 @@ export class SimpleProduct
IProductPrice, IProductPrice,
IProductSalesTax, IProductSalesTax,
IProductShipping, IProductShipping,
IProductUpSells { IProductUpSells
{
/** /**
* @see ./abstracts/cross-sells.ts * @see ./abstracts/cross-sells.ts
*/ */

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { import {
AbstractProduct, AbstractProduct,
IProductCommon, IProductCommon,
@ -59,7 +62,8 @@ export type VariableProductRepositoryParams = ModelRepositoryParams<
* @typedef ListsVariableProducts * @typedef ListsVariableProducts
* @alias ListsModels.<VariableProduct> * @alias ListsModels.<VariableProduct>
*/ */
export type ListsVariableProducts = ListsModels< VariableProductRepositoryParams >; export type ListsVariableProducts =
ListsModels< VariableProductRepositoryParams >;
/** /**
* An interface for creating variable products using the repository. * An interface for creating variable products using the repository.
@ -67,7 +71,8 @@ export type ListsVariableProducts = ListsModels< VariableProductRepositoryParams
* @typedef CreatesVariableProducts * @typedef CreatesVariableProducts
* @alias CreatesModels.<VariableProduct> * @alias CreatesModels.<VariableProduct>
*/ */
export type CreatesVariableProducts = CreatesModels< VariableProductRepositoryParams >; export type CreatesVariableProducts =
CreatesModels< VariableProductRepositoryParams >;
/** /**
* An interface for reading variable products using the repository. * An interface for reading variable products using the repository.
@ -75,7 +80,8 @@ export type CreatesVariableProducts = CreatesModels< VariableProductRepositoryPa
* @typedef ReadsVariableProducts * @typedef ReadsVariableProducts
* @alias ReadsModels.<VariableProduct> * @alias ReadsModels.<VariableProduct>
*/ */
export type ReadsVariableProducts = ReadsModels< VariableProductRepositoryParams >; export type ReadsVariableProducts =
ReadsModels< VariableProductRepositoryParams >;
/** /**
* An interface for updating variable products using the repository. * An interface for updating variable products using the repository.
@ -83,7 +89,8 @@ export type ReadsVariableProducts = ReadsModels< VariableProductRepositoryParams
* @typedef UpdatesVariableProducts * @typedef UpdatesVariableProducts
* @alias UpdatesModels.<VariableProduct> * @alias UpdatesModels.<VariableProduct>
*/ */
export type UpdatesVariableProducts = UpdatesModels< VariableProductRepositoryParams >; export type UpdatesVariableProducts =
UpdatesModels< VariableProductRepositoryParams >;
/** /**
* An interface for deleting variable products using the repository. * An interface for deleting variable products using the repository.
@ -91,7 +98,8 @@ export type UpdatesVariableProducts = UpdatesModels< VariableProductRepositoryPa
* @typedef DeletesVariableProducts * @typedef DeletesVariableProducts
* @alias DeletesModels.<VariableProduct> * @alias DeletesModels.<VariableProduct>
*/ */
export type DeletesVariableProducts = DeletesModels< VariableProductRepositoryParams >; export type DeletesVariableProducts =
DeletesModels< VariableProductRepositoryParams >;
/** /**
* The base for the Variable product object. * The base for the Variable product object.
@ -104,7 +112,8 @@ export class VariableProduct
IProductInventory, IProductInventory,
IProductSalesTax, IProductSalesTax,
IProductShipping, IProductShipping,
IProductUpSells { IProductUpSells
{
/** /**
* @see ./abstracts/cross-sells.ts * @see ./abstracts/cross-sells.ts
*/ */

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { ModelID } from '../model'; import { ModelID } from '../model';
import { import {
AbstractProductData, AbstractProductData,
@ -59,7 +62,8 @@ export type ProductVariationRepositoryParams = ModelRepositoryParams<
* @typedef ListsProductVariations * @typedef ListsProductVariations
* @alias ListsModels.<ProductVariation> * @alias ListsModels.<ProductVariation>
*/ */
export type ListsProductVariations = ListsChildModels< ProductVariationRepositoryParams >; export type ListsProductVariations =
ListsChildModels< ProductVariationRepositoryParams >;
/** /**
* An interface for creating variable products using the repository. * An interface for creating variable products using the repository.
@ -67,7 +71,8 @@ export type ListsProductVariations = ListsChildModels< ProductVariationRepositor
* @typedef CreatesProductVariations * @typedef CreatesProductVariations
* @alias CreatesModels.<ProductVariation> * @alias CreatesModels.<ProductVariation>
*/ */
export type CreatesProductVariations = CreatesChildModels< ProductVariationRepositoryParams >; export type CreatesProductVariations =
CreatesChildModels< ProductVariationRepositoryParams >;
/** /**
* An interface for reading variable products using the repository. * An interface for reading variable products using the repository.
@ -75,7 +80,8 @@ export type CreatesProductVariations = CreatesChildModels< ProductVariationRepos
* @typedef ReadsProductVariations * @typedef ReadsProductVariations
* @alias ReadsModels.<ProductVariation> * @alias ReadsModels.<ProductVariation>
*/ */
export type ReadsProductVariations = ReadsChildModels< ProductVariationRepositoryParams >; export type ReadsProductVariations =
ReadsChildModels< ProductVariationRepositoryParams >;
/** /**
* An interface for updating variable products using the repository. * An interface for updating variable products using the repository.
@ -83,7 +89,8 @@ export type ReadsProductVariations = ReadsChildModels< ProductVariationRepositor
* @typedef UpdatesProductVariations * @typedef UpdatesProductVariations
* @alias UpdatesModels.<ProductVariation> * @alias UpdatesModels.<ProductVariation>
*/ */
export type UpdatesProductVariations = UpdatesChildModels< ProductVariationRepositoryParams >; export type UpdatesProductVariations =
UpdatesChildModels< ProductVariationRepositoryParams >;
/** /**
* An interface for deleting variable products using the repository. * An interface for deleting variable products using the repository.
@ -91,7 +98,8 @@ export type UpdatesProductVariations = UpdatesChildModels< ProductVariationRepos
* @typedef DeletesProductVariations * @typedef DeletesProductVariations
* @alias DeletesModels.<ProductVariation> * @alias DeletesModels.<ProductVariation>
*/ */
export type DeletesProductVariations = DeletesChildModels< ProductVariationRepositoryParams >; export type DeletesProductVariations =
DeletesChildModels< ProductVariationRepositoryParams >;
/** /**
* The base for the product variation object. * The base for the product variation object.
@ -103,7 +111,8 @@ export class ProductVariation
IProductInventory, IProductInventory,
IProductPrice, IProductPrice,
IProductSalesTax, IProductSalesTax,
IProductShipping { IProductShipping
{
/** /**
* @see ./abstracts/delivery.ts * @see ./abstracts/delivery.ts
*/ */

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { Model, ModelID } from '../model'; import { Model, ModelID } from '../model';
import { HTTPClient } from '../../http'; import { HTTPClient } from '../../http';
import { settingGroupRESTRepository } from '../../repositories'; import { settingGroupRESTRepository } from '../../repositories';
@ -7,7 +10,8 @@ import { ListsModels, ModelRepositoryParams } from '../../framework';
* The parameters embedded in this generic can be used in the ModelRepository in order to give * The parameters embedded in this generic can be used in the ModelRepository in order to give
* type-safety in an incredibly granular way. * type-safety in an incredibly granular way.
*/ */
export type SettingGroupRepositoryParams = ModelRepositoryParams< SettingGroup >; export type SettingGroupRepositoryParams =
ModelRepositoryParams< SettingGroup >;
/** /**
* An interface for listing setting groups using the repository. * An interface for listing setting groups using the repository.

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { Model, ModelID } from '../model'; import { Model, ModelID } from '../model';
import { HTTPClient } from '../../http'; import { HTTPClient } from '../../http';
import { settingRESTRepository } from '../../repositories'; import { settingRESTRepository } from '../../repositories';

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { Model } from './model'; import { Model } from './model';
/** /**

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { HTTPClient } from '../../../http'; import { HTTPClient } from '../../../http';
import { ModelRepository } from '../../../framework'; import { ModelRepository } from '../../../framework';
import { import {

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import couponRESTRepository from './coupon'; import couponRESTRepository from './coupon';
export { couponRESTRepository }; export { couponRESTRepository };

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { import {
IgnorePropertyTransformation, IgnorePropertyTransformation,
KeyChangeTransformation, KeyChangeTransformation,
@ -5,7 +8,6 @@ import {
PropertyType, PropertyType,
PropertyTypeTransformation, PropertyTypeTransformation,
} from '../../../framework'; } from '../../../framework';
import { Coupon } from '../../../models'; import { Coupon } from '../../../models';
/** /**

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import orderRESTRepository from './order'; import orderRESTRepository from './order';
export { orderRESTRepository }; export { orderRESTRepository };

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { HTTPClient } from '../../../http'; import { HTTPClient } from '../../../http';
import { ModelRepository } from '../../../framework'; import { ModelRepository } from '../../../framework';
import { import {

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { import {
IgnorePropertyTransformation, IgnorePropertyTransformation,
KeyChangeTransformation, KeyChangeTransformation,

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { HTTPClient } from '../../../http'; import { HTTPClient } from '../../../http';
import { ModelRepository } from '../../../framework'; import { ModelRepository } from '../../../framework';
import { import {

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { HTTPClient } from '../../../http'; import { HTTPClient } from '../../../http';
import { ModelRepository } from '../../../framework'; import { ModelRepository } from '../../../framework';
import { import {

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { createProductTransformer } from './shared'; import { createProductTransformer } from './shared';
import { groupedProductRESTRepository } from './grouped-product'; import { groupedProductRESTRepository } from './grouped-product';
import { simpleProductRESTRepository } from './simple-product'; import { simpleProductRESTRepository } from './simple-product';

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { import {
AddPropertyTransformation, AddPropertyTransformation,
CustomTransformation, CustomTransformation,

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { HTTPClient } from '../../../http'; import { HTTPClient } from '../../../http';
import { ModelRepository } from '../../../framework'; import { ModelRepository } from '../../../framework';
import { import {

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { HTTPClient } from '../../../http'; import { HTTPClient } from '../../../http';
import { ModelRepository } from '../../../framework'; import { ModelRepository } from '../../../framework';
import { import {

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { HTTPClient } from '../../../http'; import { HTTPClient } from '../../../http';
import { ModelRepository } from '../../../framework'; import { ModelRepository } from '../../../framework';
import { import {
@ -66,9 +69,8 @@ export function productVariationRESTRepository(
...shipping, ...shipping,
]; ];
const transformer = createProductDataTransformer< ProductVariation >( const transformer =
transformations createProductDataTransformer< ProductVariation >( transformations );
);
return new ModelRepository( return new ModelRepository(
restListChild< ProductVariationRepositoryParams >( restListChild< ProductVariationRepositoryParams >(

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import settingRESTRepository from './setting'; import settingRESTRepository from './setting';
import settingGroupRESTRepository from './setting-group'; import settingGroupRESTRepository from './setting-group';

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { HTTPClient } from '../../../http'; import { HTTPClient } from '../../../http';
import { import {
ModelRepository, ModelRepository,

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { HTTPClient } from '../../../http'; import { HTTPClient } from '../../../http';
import { import {
ModelRepository, ModelRepository,

View File

@ -1,4 +1,8 @@
/**
* Internal dependencies
*/
import { HTTPClient } from '../../http'; import { HTTPClient } from '../../http';
import { ModelID, MetaData, ModelConstructor } from '../../models';
import { import {
ListFn, ListFn,
ModelRepositoryParams, ModelRepositoryParams,
@ -20,7 +24,6 @@ import {
// @ts-ignore // @ts-ignore
ModelParentID, ModelParentID,
} from '../../framework'; } from '../../framework';
import { ModelID, MetaData, ModelConstructor } from '../../models';
/** /**
* Creates a new transformer for metadata models. * Creates a new transformer for metadata models.

View File

@ -1,3 +1,6 @@
/**
* Internal dependencies
*/
import { Setting, UpdatesSettings } from '../models'; import { Setting, UpdatesSettings } from '../models';
/** /**

View File

@ -0,0 +1,3 @@
// Import the default config file and expose it in the project root.
// Useful for editor integrations.
module.exports = require( '@wordpress/prettier-config' );

View File

@ -1,3 +1,11 @@
module.exports = { module.exports = {
extends: ['plugin:@woocommerce/eslint-plugin/recommended'], extends: ['plugin:@woocommerce/eslint-plugin/recommended'],
plugins: ['jest'],
root: true,
env: {
'jest/globals': true,
},
globals: {
page: true,
},
}; };

View File

@ -41,7 +41,8 @@
"@wordpress/babel-plugin-import-jsx-pragma": "1.1.3", "@wordpress/babel-plugin-import-jsx-pragma": "1.1.3",
"@wordpress/babel-preset-default": "3.0.2", "@wordpress/babel-preset-default": "3.0.2",
"@wordpress/browserslist-config": "^4.1.0", "@wordpress/browserslist-config": "^4.1.0",
"eslint": "^8.12.0" "eslint": "^8.12.0",
"eslint-plugin-jest": "23.20.0"
}, },
"peerDependencies": { "peerDependencies": {
"@woocommerce/api": "^0.2.0", "@woocommerce/api": "^0.2.0",

View File

@ -12,7 +12,7 @@ module.exports = {
'no-useless-constructor': 'off', 'no-useless-constructor': 'off',
'@typescript-eslint/no-useless-constructor': 2, '@typescript-eslint/no-useless-constructor': 2,
}, },
plugins: [ '@typescript-eslint/eslint-plugin' ], plugins: [ '@typescript-eslint/eslint-plugin', 'jest' ],
extends: [ 'plugin:@wordpress/eslint-plugin/recommended-with-formatting' ], extends: [ 'plugin:@wordpress/eslint-plugin/recommended-with-formatting' ],
overrides: [ overrides: [
{ {
@ -30,4 +30,8 @@ module.exports = {
}, },
}, },
], ],
globals: {
page: true,
browser: true,
},
}; };

View File

@ -31,13 +31,14 @@
"@babel/polyfill": "7.12.1", "@babel/polyfill": "7.12.1",
"@babel/preset-env": "7.12.7", "@babel/preset-env": "7.12.7",
"@typescript-eslint/eslint-plugin": "^5.3.0", "@typescript-eslint/eslint-plugin": "^5.3.0",
"@woocommerce/eslint-plugin": "workspace:*",
"@typescript-eslint/parser": "^5.3.0", "@typescript-eslint/parser": "^5.3.0",
"@woocommerce/eslint-plugin": "workspace:*",
"@woocommerce/internal-e2e-builds": "workspace:*", "@woocommerce/internal-e2e-builds": "workspace:*",
"@wordpress/babel-plugin-import-jsx-pragma": "1.1.3", "@wordpress/babel-plugin-import-jsx-pragma": "1.1.3",
"@wordpress/babel-preset-default": "3.0.2", "@wordpress/babel-preset-default": "3.0.2",
"@wordpress/browserslist-config": "^4.1.0", "@wordpress/browserslist-config": "^4.1.0",
"eslint": "^8.1.0" "eslint": "^8.1.0",
"eslint-plugin-jest": "23.20.0"
}, },
"peerDependencies": { "peerDependencies": {
"@woocommerce/api": "^0.2.0" "@woocommerce/api": "^0.2.0"

View File

@ -1,7 +1,3 @@
/**
* @format
*/
/** /**
* Internal dependencies * Internal dependencies
*/ */
@ -34,7 +30,7 @@ const uuid = require( 'uuid' );
/** /**
* Verify and publish * Verify and publish
* *
* @param noticeText The text that appears in the notice after publishing. * @param {string} noticeText The text that appears in the notice after publishing.
*/ */
const verifyAndPublish = async ( noticeText ) => { const verifyAndPublish = async ( noticeText ) => {
// Wait for auto save // Wait for auto save
@ -53,7 +49,7 @@ const verifyAndPublish = async ( noticeText ) => {
/** /**
* Wait for primary button to be enabled and click. * Wait for primary button to be enabled and click.
* *
* @param waitForNetworkIdle - Wait for network idle after click * @param {boolean} waitForNetworkIdle - Wait for network idle after click
* @return {Promise<void>} * @return {Promise<void>}
*/ */
const waitAndClickPrimary = async ( waitForNetworkIdle = true ) => { const waitAndClickPrimary = async ( waitForNetworkIdle = true ) => {
@ -258,9 +254,9 @@ const createSimpleProduct = async (
/** /**
* Create simple product with categories * Create simple product with categories
* *
* @param productName Product's name which can be changed when writing a test * @param {string} productName Product's name which can be changed when writing a test
* @param productPrice Product's price which can be changed when writing a test * @param {string} productPrice Product's price which can be changed when writing a test
* @param categoryName Product's category which can be changed when writing a test * @param {string} categoryName Product's category which can be changed when writing a test
*/ */
const createSimpleProductWithCategory = async ( const createSimpleProductWithCategory = async (
productName, productName,
@ -287,10 +283,10 @@ const createSimpleProductWithCategory = async (
/** /**
* Create simple downloadable product * Create simple downloadable product
* *
* @param name Product's name. Defaults to 'Simple Product' (see createSimpleProduct definition). * @param {string} name Product's name. Defaults to 'Simple Product' (see createSimpleProduct definition).
* @param downloadLimit Product's download limit. Defaults to '-1' (unlimited). * @param {number} downloadLimit Product's download limit. Defaults to '-1' (unlimited).
* @param downloadName Product's download name. Defaults to 'Single'. * @param {string} downloadName Product's download name. Defaults to 'Single'.
* @param price Product's price. Defaults to '$9.99' (see createSimpleProduct definition). * @param {string} price Product's price. Defaults to '$9.99' (see createSimpleProduct definition).
*/ */
const createSimpleDownloadableProduct = async ( const createSimpleDownloadableProduct = async (
name, name,
@ -318,8 +314,8 @@ const createSimpleDownloadableProduct = async (
* Create variable product. * Create variable product.
* Also, create variations for all attributes. * Also, create variations for all attributes.
* *
* @param varProduct Defaults to the variable product object in `default.json` * @param {Object} varProduct Defaults to the variable product object in `default.json`
* @return the ID of the created variable product * @return {number} the ID of the created variable product
*/ */
const createVariableProduct = async ( varProduct = defaultVariableProduct ) => { const createVariableProduct = async ( varProduct = defaultVariableProduct ) => {
const { attributes } = varProduct; const { attributes } = varProduct;
@ -329,6 +325,7 @@ const createVariableProduct = async ( varProduct = defaultVariableProduct ) => {
const aIdx = 0; // attributes[] index const aIdx = 0; // attributes[] index
// Create variation for all attributes // Create variation for all attributes
// eslint-disable-next-line no-shadow
const createVariation = ( aIdx ) => { const createVariation = ( aIdx ) => {
const { name, options } = attributes[ aIdx ]; const { name, options } = attributes[ aIdx ];
const isLastAttribute = aIdx === attributes.length - 1; const isLastAttribute = aIdx === attributes.length - 1;
@ -389,8 +386,8 @@ const createVariableProduct = async ( varProduct = defaultVariableProduct ) => {
/** /**
* Create grouped product. * Create grouped product.
* *
* @param groupedProduct Defaults to the grouped product object in `default.json` * @param {Object} groupedProduct Defaults to the grouped product object in `default.json`
* @return ID of the grouped product * @return {number} ID of the grouped product
*/ */
const createGroupedProduct = async ( const createGroupedProduct = async (
groupedProduct = defaultGroupedProduct groupedProduct = defaultGroupedProduct
@ -406,6 +403,7 @@ const createGroupedProduct = async (
} }
// Using the api, create the grouped product // Using the api, create the grouped product
// eslint-disable-next-line prefer-const
groupedProductRequest = { groupedProductRequest = {
name, name,
groupedProducts: simpleProductIds, groupedProducts: simpleProductIds,
@ -452,7 +450,7 @@ const createOrder = async ( orderOptions = {} ) => {
/** /**
* Create a basic order with the provided order status. * Create a basic order with the provided order status.
* *
* @param orderStatus Status of the new order. Defaults to `Pending payment`. * @param {string} orderStatus Status of the new order. Defaults to `Pending payment`.
*/ */
const createSimpleOrder = async ( orderStatus = 'Pending payment' ) => { const createSimpleOrder = async ( orderStatus = 'Pending payment' ) => {
// Go to 'Add new order' page // Go to 'Add new order' page
@ -487,7 +485,7 @@ const createSimpleOrder = async ( orderStatus = 'Pending payment' ) => {
* Creates a batch of orders from the given `statuses` * Creates a batch of orders from the given `statuses`
* using the "Batch Create Order" API. * using the "Batch Create Order" API.
* *
* @param statuses Array of order statuses * @param {Array} statuses Array of order statuses
*/ */
const batchCreateOrders = async ( statuses ) => { const batchCreateOrders = async ( statuses ) => {
const defaultOrder = config.get( 'orders.basicPaidOrder' ); const defaultOrder = config.get( 'orders.basicPaidOrder' );
@ -511,8 +509,8 @@ const batchCreateOrders = async ( statuses ) => {
/** /**
* Adds a product to an order in the merchant. * Adds a product to an order in the merchant.
* *
* @param orderId ID of the order to add the product to. * @param {number} orderId ID of the order to add the product to.
* @param productName Name of the product being added to the order. * @param {string} productName Name of the product being added to the order.
*/ */
const addProductToOrder = async ( orderId, productName ) => { const addProductToOrder = async ( orderId, productName ) => {
await merchant.goToOrder( orderId ); await merchant.goToOrder( orderId );
@ -545,8 +543,8 @@ const addProductToOrder = async ( orderId, productName ) => {
/** /**
* Creates a basic coupon with the provided coupon amount. Returns the coupon code. * Creates a basic coupon with the provided coupon amount. Returns the coupon code.
* *
* @param couponAmount Amount to be applied. Defaults to 5. * @param {string} couponAmount Amount to be applied. Defaults to 5.
* @param discountType Type of a coupon. Defaults to Fixed cart discount. * @param {string} discountType Type of a coupon. Defaults to Fixed cart discount.
*/ */
const createCoupon = async ( const createCoupon = async (
couponAmount = '5', couponAmount = '5',
@ -582,10 +580,10 @@ const createCoupon = async (
/** /**
* Adds a shipping zone along with a shipping method. * Adds a shipping zone along with a shipping method.
* *
* @param zoneName Shipping zone name. * @param {string} zoneName Shipping zone name.
* @param zoneLocation Shiping zone location. Defaults to country:US. For states use: state:US:CA * @param {string} zoneLocation Shiping zone location. Defaults to country:US. For states use: state:US:CA
* @param zipCode Shipping zone zip code. Defaults to empty one space. * @param {string} zipCode Shipping zone zip code. Defaults to empty one space.
* @param zoneMethod Shipping method type. Defaults to flat_rate (use also: free_shipping or local_pickup) * @param {string} zoneMethod Shipping method type. Defaults to flat_rate (use also: free_shipping or local_pickup)
*/ */
const addShippingZoneAndMethod = async ( const addShippingZoneAndMethod = async (
zoneName, zoneName,
@ -632,8 +630,8 @@ const addShippingZoneAndMethod = async (
/** /**
* Click the Update button on the order details page. * Click the Update button on the order details page.
* *
* @param noticeText The text that appears in the notice after updating the order. * @param {string} noticeText The text that appears in the notice after updating the order.
* @param waitForSave Optionally wait for auto save. * @param {boolean} waitForSave Optionally wait for auto save.
*/ */
const clickUpdateOrder = async ( noticeText, waitForSave = false ) => { const clickUpdateOrder = async ( noticeText, waitForSave = false ) => {
if ( waitForSave ) { if ( waitForSave ) {

View File

@ -4,8 +4,8 @@ import { Factory } from 'fishery';
/** /**
* Creates a new factory for creating grouped products. * Creates a new factory for creating grouped products.
* *
* @param {HTTPClient} httpClient The HTTP client we will give the repository. * @param {Object} httpClient The HTTP client we will give the repository.
* @return {AsyncFactory} The factory for creating models. * @return {Object} The factory for creating models.
*/ */
export function groupedProductFactory( httpClient ) { export function groupedProductFactory( httpClient ) {
const repository = GroupedProduct.restRepository( httpClient ); const repository = GroupedProduct.restRepository( httpClient );

View File

@ -5,8 +5,8 @@ import crypto from 'crypto';
/** /**
* Creates a new factory for creating models. * Creates a new factory for creating models.
* *
* @param {HTTPClient} httpClient The HTTP client we will give the repository. * @param {Object} httpClient The HTTP client we will give the repository.
* @return {AsyncFactory} The factory for creating models. * @return {Object} The factory for creating models.
*/ */
export function simpleProductFactory( httpClient ) { export function simpleProductFactory( httpClient ) {
const repository = SimpleProduct.restRepository( httpClient ); const repository = SimpleProduct.restRepository( httpClient );

View File

@ -6,8 +6,8 @@ import { Factory } from 'fishery';
* This does not include creating product variations. * This does not include creating product variations.
* Instead, use `variationFactory()` for that. * Instead, use `variationFactory()` for that.
* *
* @param {HTTPClient} httpClient The HTTP client we will give the repository. * @param {Object} httpClient The HTTP client we will give the repository.
* @return {AsyncFactory} The factory for creating models. * @return {Object} The factory for creating models.
*/ */
export function variableProductFactory( httpClient ) { export function variableProductFactory( httpClient ) {
const repository = VariableProduct.restRepository( httpClient ); const repository = VariableProduct.restRepository( httpClient );

View File

@ -4,8 +4,8 @@ import { Factory } from 'fishery';
/** /**
* Creates a new factory for creating a product variation. * Creates a new factory for creating a product variation.
* *
* @param {HTTPClient} httpClient The HTTP client we will give the repository. * @param {Object} httpClient The HTTP client we will give the repository.
* @return {AsyncFactory} The factory for creating models. * @return {Object} The factory for creating models.
*/ */
export function variationFactory( httpClient ) { export function variationFactory( httpClient ) {
const repository = ProductVariation.restRepository( httpClient ); const repository = ProductVariation.restRepository( httpClient );

View File

@ -79,4 +79,4 @@ export const MY_ACCOUNT_ACCOUNT_DETAILS = SHOP_MY_ACCOUNT_PAGE + 'edit-account';
* *
* @type {boolean} * @type {boolean}
*/ */
export const IS_RETEST_MODE = process.env.E2E_RETEST == '1'; export const IS_RETEST_MODE = process.env.E2E_RETEST === '1';

View File

@ -267,10 +267,10 @@ const shopper = {
// Single search results may go directly to product page // Single search results may go directly to product page
if ( await page.waitForSelector( 'h2.entry-title' ) ) { if ( await page.waitForSelector( 'h2.entry-title' ) ) {
await expect( page ).toMatchElement( 'h2.entry-title', { await expect( page ).toMatchElement( 'h2.entry-title', {
text: prouductName text: prouductName,
} ); } );
await expect( page ).toClick( 'h2.entry-title > a', { await expect( page ).toClick( 'h2.entry-title > a', {
text: prouductName text: prouductName,
} ); } );
} }
await page.waitForSelector( 'h1.entry-title' ); await page.waitForSelector( 'h1.entry-title' );

View File

@ -1,10 +1,10 @@
/** /**
* Take a string name and generate the slug for it. * Take a string name and generate the slug for it.
* Example: 'My plugin' => 'my-plugin' * Example: 'My plugin' => 'my-plugin'
*
* @param text string to convert to a slug
*
* Sourced from: https://gist.github.com/spyesx/561b1d65d4afb595f295 * Sourced from: https://gist.github.com/spyesx/561b1d65d4afb595f295
*
* @param {string} text string to convert to a slug.
* @return {string} slug.
*/ */
export const getSlug = ( text ) => { export const getSlug = ( text ) => {
text = text.trim().toLowerCase(); text = text.trim().toLowerCase();
@ -39,7 +39,7 @@ export const itIf = ( condition ) => ( condition ? it : it.skip );
/** /**
* Wait for a timeout in milliseconds * Wait for a timeout in milliseconds
* *
* @param timeout delay time in milliseconds * @param {number} timeout delay time in milliseconds
* @return {Promise<void>} * @return {Promise<void>}
*/ */
export const waitForTimeout = async ( timeout ) => { export const waitForTimeout = async ( timeout ) => {

View File

@ -16,9 +16,9 @@ const userEndpoint = '/wp/v2/users';
/** /**
* Utility function to delete all merchant created data store objects. * Utility function to delete all merchant created data store objects.
* *
* @param repository * @param {unknown} repository
* @param defaultObjectId * @param {number | null} defaultObjectId
* @param statuses Status of the object to check * @param {Array<string>} statuses Status of the object to check
* @return {Promise<void>} * @return {Promise<void>}
*/ */
const deleteAllRepositoryObjects = async ( const deleteAllRepositoryObjects = async (
@ -27,7 +27,7 @@ const deleteAllRepositoryObjects = async (
statuses = [ 'draft', 'publish', 'trash' ] statuses = [ 'draft', 'publish', 'trash' ]
) => { ) => {
let objects; let objects;
const minimum = defaultObjectId == null ? 0 : 1; const minimum = defaultObjectId === null ? 0 : 1;
for ( let s = 0; s < statuses.length; s++ ) { for ( let s = 0; s < statuses.length; s++ ) {
const status = statuses[ s ]; const status = statuses[ s ];
@ -35,7 +35,7 @@ const deleteAllRepositoryObjects = async (
while ( objects.length > minimum ) { while ( objects.length > minimum ) {
for ( let o = 0; o < objects.length; o++ ) { for ( let o = 0; o < objects.length; o++ ) {
// Skip default data store object // Skip default data store object
if ( objects[ o ].id == defaultObjectId ) { if ( objects[ o ].id === defaultObjectId ) {
continue; continue;
} }
// We may be getting a cached copy of the dataset and the object has already been deleted. // We may be getting a cached copy of the dataset and the object has already been deleted.
@ -52,7 +52,7 @@ const deleteAllRepositoryObjects = async (
* Utility to flatten a tax rate. * Utility to flatten a tax rate.
* *
* @param {Object} taxRate Tax rate to be flattened. * @param {Object} taxRate Tax rate to be flattened.
* @return {string} * @return {string} The flattened tax rate.
*/ */
const flattenTaxRate = ( taxRate ) => { const flattenTaxRate = ( taxRate ) => {
return taxRate.rate + '/' + taxRate.class + '/' + taxRate.name; return taxRate.rate + '/' + taxRate.class + '/' + taxRate.name;
@ -159,7 +159,7 @@ export const withRestApi = {
if ( productCategories.data && productCategories.data.length ) { if ( productCategories.data && productCategories.data.length ) {
for ( let c = 0; c < productCategories.data.length; c++ ) { for ( let c = 0; c < productCategories.data.length; c++ ) {
// The default `uncategorized` category can't be deleted // The default `uncategorized` category can't be deleted
if ( productCategories.data[ c ].slug == 'uncategorized' ) { if ( productCategories.data[ c ].slug === 'uncategorized' ) {
continue; continue;
} }
const response = await client.delete( const response = await client.delete(
@ -226,12 +226,12 @@ export const withRestApi = {
/** /**
* Adds a shipping zone along with a shipping method using the API. * Adds a shipping zone along with a shipping method using the API.
* *
* @param zoneName Shipping zone name. * @param {string} zoneName Shipping zone name.
* @param zoneLocation Shiping zone location. Defaults to country:US. For states use: state:US:CA. * @param {string} zoneLocation Shiping zone location. Defaults to country:US. For states use: state:US:CA.
* @param zipCode Shipping zone zip code. Default is no zip code. * @param {string} zipCode Shipping zone zip code. Default is no zip code.
* @param zoneMethod Shipping method type. Defaults to flat_rate (use also: free_shipping or local_pickup). * @param {string} zoneMethod Shipping method type. Defaults to flat_rate (use also: free_shipping or local_pickup).
* @param cost Shipping method cost. Default is no cost. * @param {string} cost Shipping method cost. Default is no cost.
* @param additionalZoneMethods Array of additional zone methods to add to the shipping zone. * @param {Array} additionalZoneMethods Array of additional zone methods to add to the shipping zone.
* @param {boolean} testResponse Test the response status code. * @param {boolean} testResponse Test the response status code.
*/ */
addShippingZoneAndMethod: async ( addShippingZoneAndMethod: async (
@ -310,6 +310,7 @@ export const withRestApi = {
// Add any additional zones, if provided // Add any additional zones, if provided
if ( additionalZoneMethods.length > 0 ) { if ( additionalZoneMethods.length > 0 ) {
for ( let z = 0; z < additionalZoneMethods.length; z++ ) { for ( let z = 0; z < additionalZoneMethods.length; z++ ) {
// eslint-disable-next-line no-shadow
const response = await client.post( const response = await client.post(
path + `/${ zoneId }/methods`, path + `/${ zoneId }/methods`,
{ method_id: additionalZoneMethods[ z ] } { method_id: additionalZoneMethods[ z ] }
@ -331,7 +332,7 @@ export const withRestApi = {
if ( shippingZones.data && shippingZones.data.length ) { if ( shippingZones.data && shippingZones.data.length ) {
for ( let z = 0; z < shippingZones.data.length; z++ ) { for ( let z = 0; z < shippingZones.data.length; z++ ) {
// The data store doesn't support deleting the default zone. // The data store doesn't support deleting the default zone.
if ( shippingZones.data[ z ].id == 0 ) { if ( shippingZones.data[ z ].id === 0 ) {
continue; continue;
} }
const response = await client.delete( const response = await client.delete(
@ -367,7 +368,7 @@ export const withRestApi = {
/** /**
* Delete a customer account by their email address if the user exists. * Delete a customer account by their email address if the user exists.
* *
* @param emailAddress Customer user account email address. * @param {string} emailAddress Customer user account email address.
* @return {Promise<void>} * @return {Promise<void>}
*/ */
deleteCustomerByEmail: async ( emailAddress ) => { deleteCustomerByEmail: async ( emailAddress ) => {
@ -394,7 +395,7 @@ export const withRestApi = {
/** /**
* Reset a settings group to default values except selects. * Reset a settings group to default values except selects.
* *
* @param settingsGroup * @param {unknown} settingsGroup
* @param {boolean} testResponse Test the response status code. * @param {boolean} testResponse Test the response status code.
* @return {Promise<void>} * @return {Promise<void>}
*/ */
@ -411,8 +412,8 @@ export const withRestApi = {
for ( let s = 0; s < settings.length; s++ ) { for ( let s = 0; s < settings.length; s++ ) {
// The rest api doesn't allow selects to be set to ''. // The rest api doesn't allow selects to be set to ''.
if ( if (
settings[ s ].type == 'select' && settings[ s ].type === 'select' &&
settings[ s ].default == '' settings[ s ].default === ''
) { ) {
continue; continue;
} }
@ -428,7 +429,7 @@ export const withRestApi = {
defaultSetting defaultSetting
); );
// Multi-selects have a default '' but return an empty []. // Multi-selects have a default '' but return an empty [].
if ( testResponse && settings[ s ].type != 'multiselect' ) { if ( testResponse && settings[ s ].type !== 'multiselect' ) {
expect( response.value ).toBe( defaultSetting.value ); expect( response.value ).toBe( defaultSetting.value );
} }
} }
@ -467,7 +468,7 @@ export const withRestApi = {
/** /**
* Create a batch of orders using the "Batch Create Order" API endpoint. * Create a batch of orders using the "Batch Create Order" API endpoint.
* *
* @param orders Array of orders to be created * @param {Array} orders Array of orders to be created
* @param {boolean} testResponse Test the response status code. * @param {boolean} testResponse Test the response status code.
*/ */
batchCreateOrders: async ( orders, testResponse = true ) => { batchCreateOrders: async ( orders, testResponse = true ) => {
@ -482,8 +483,8 @@ export const withRestApi = {
/** /**
* Add tax classes. * Add tax classes.
* *
* @param {<Array<Object>>} taxClasses Array of tax class objects. * @param {Array<Object>} taxClasses Array of tax class objects.
* @return {Promise<void>} * @return {Promise<void>} Promise resolving once tax classes have been added.
*/ */
addTaxClasses: async ( taxClasses ) => { addTaxClasses: async ( taxClasses ) => {
// Only add tax classes which don't already exist. // Only add tax classes which don't already exist.
@ -502,7 +503,7 @@ export const withRestApi = {
/** /**
* Add tax rates. * Add tax rates.
* *
* @param {<Array<Object>>} taxRates Array of tax rate objects. * @param {Array<Object>} taxRates Array of tax rate objects.
* @return {Promise<void>} * @return {Promise<void>}
*/ */
addTaxRates: async ( taxRates ) => { addTaxRates: async ( taxRates ) => {

View File

@ -122,9 +122,9 @@ export const backboneUnblocked = async () => {
/** /**
* Conditionally wait for a selector without throwing an error. * Conditionally wait for a selector without throwing an error.
* *
* @param selector * @param {string} selector
* @param timeoutInSeconds * @param {number} timeoutInSeconds
* @return {Promise<boolean>} * @return {Promise<boolean>} True if selector is found, false otherwise.
*/ */
export const waitForSelectorWithoutThrow = async ( export const waitForSelectorWithoutThrow = async (
selector, selector,
@ -292,7 +292,7 @@ export const searchForOrder = async ( value, orderId, customerName ) => {
* Apply a coupon code within cart or checkout. * Apply a coupon code within cart or checkout.
* Method will try to apply a coupon in the checkout, otherwise will try to apply in the cart. * Method will try to apply a coupon in the checkout, otherwise will try to apply in the cart.
* *
* @param couponCode string * @param {string} couponCode string
* @return {Promise<void>} * @return {Promise<void>}
*/ */
export const applyCoupon = async ( couponCode ) => { export const applyCoupon = async ( couponCode ) => {
@ -318,7 +318,7 @@ export const applyCoupon = async ( couponCode ) => {
/** /**
* Remove one coupon within cart or checkout. * Remove one coupon within cart or checkout.
* *
* @param couponCode Coupon name. * @param {string} couponCode Coupon name.
* @return {Promise<void>} * @return {Promise<void>}
*/ */
export const removeCoupon = async ( couponCode ) => { export const removeCoupon = async ( couponCode ) => {
@ -375,7 +375,7 @@ export const clickAndWaitForSelector = async (
* Behavior can be modified with @param options. Possible keys: `visible`, `hidden`, `timeout`. * Behavior can be modified with @param options. Possible keys: `visible`, `hidden`, `timeout`.
* More details at: https://pptr.dev/#?product=Puppeteer&show=api-pagewaitforselectorselector-options * More details at: https://pptr.dev/#?product=Puppeteer&show=api-pagewaitforselectorselector-options
* *
* @param {Puppeteer.Page} page Puppeteer representation of the page. * @param {Object} page Puppeteer representation of the page.
* @param {string} selector CSS selector of the element * @param {string} selector CSS selector of the element
* @param {Object} options Custom options to modify function behavior. * @param {Object} options Custom options to modify function behavior.
*/ */
@ -394,11 +394,12 @@ export async function waitForSelector( page, selector, options = {} ) {
* *
* @param {string} selector Selector of the element you want to get the attribute from. * @param {string} selector Selector of the element you want to get the attribute from.
* @param {string} attribute The desired HTML attribute. * @param {string} attribute The desired HTML attribute.
* @return {Promise<string>} * @return {Promise<string>} Promise resolving to the attribute value.
*/ */
export async function getSelectorAttribute( selector, attribute ) { export async function getSelectorAttribute( selector, attribute ) {
return await page.$eval( return await page.$eval(
selector, selector,
// eslint-disable-next-line no-shadow
( element, attribute ) => element.getAttribute( attribute ), ( element, attribute ) => element.getAttribute( attribute ),
attribute attribute
); );

View File

@ -4,10 +4,10 @@ export class AdminEdit {
/** /**
* Publish the object being edited and verify published status * Publish the object being edited and verify published status
* *
* @param button Publish button selector * @param {string} button Publish button selector
* @param publishNotice Publish notice selector * @param {string} publishNotice Publish notice selector
* @param publishVerification Expected notice on successful publish * @param {string} publishVerification Expected notice on successful publish
* @return {Promise<void>} * @return {Promise<void>} Promise resolving when the object is published
*/ */
async verifyPublish( button, publishNotice, publishVerification ) { async verifyPublish( button, publishNotice, publishVerification ) {
// Wait for auto save // Wait for auto save
@ -24,7 +24,7 @@ export class AdminEdit {
/** /**
* Get the ID of the object being edited * Get the ID of the object being edited
* *
* @return {Promise<*>} * @return {Promise<*>} Promise resolving to the ID of the object being edited.
*/ */
async getId() { async getId() {
const postId = await page.$( '#post_ID' ); const postId = await page.$( '#post_ID' );

View File

@ -31,7 +31,7 @@
"main": "index.js", "main": "index.js",
"dependencies": { "dependencies": {
"@typescript-eslint/parser": "^5.14.0", "@typescript-eslint/parser": "^5.14.0",
"@wordpress/eslint-plugin": "^11.0.0", "@wordpress/eslint-plugin": "^13.3.0",
"eslint-plugin-react-hooks": "^4.3.0", "eslint-plugin-react-hooks": "^4.3.0",
"eslint-plugin-testing-library": "^5.1.0", "eslint-plugin-testing-library": "^5.1.0",
"requireindex": "^1.2.0" "requireindex": "^1.2.0"
@ -47,7 +47,7 @@
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.17.5", "@babel/core": "^7.17.5",
"eslint": "^8.11.0", "eslint": "^8.25.0",
"jest": "^27.5.1", "jest": "^27.5.1",
"jest-cli": "^27.5.1", "jest-cli": "^27.5.1",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",

View File

@ -45,7 +45,7 @@
"devDependencies": { "devDependencies": {
"@babel/core": "^7.17.5", "@babel/core": "^7.17.5",
"@types/debug": "^4.1.7", "@types/debug": "^4.1.7",
"@wordpress/eslint-plugin": "^11.0.0", "@woocommerce/eslint-plugin": "workspace:*",
"eslint": "^8.12.0", "eslint": "^8.12.0",
"jest": "^27.5.1", "jest": "^27.5.1",
"jest-cli": "^27.5.1", "jest-cli": "^27.5.1",

View File

@ -1,5 +1,3 @@
/** @format */
module.exports = { module.exports = {
root: true, root: true,
env: { env: {

View File

@ -237,7 +237,6 @@ module.exports = function ( grunt ) {
grunt.loadNpmTasks( 'grunt-rtlcss' ); grunt.loadNpmTasks( 'grunt-rtlcss' );
grunt.loadNpmTasks( 'grunt-postcss' ); grunt.loadNpmTasks( 'grunt-postcss' );
grunt.loadNpmTasks( 'grunt-stylelint' ); grunt.loadNpmTasks( 'grunt-stylelint' );
grunt.loadNpmTasks( 'gruntify-eslint' );
grunt.loadNpmTasks( 'grunt-contrib-uglify' ); grunt.loadNpmTasks( 'grunt-contrib-uglify' );
grunt.loadNpmTasks( 'grunt-contrib-cssmin' ); grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
grunt.loadNpmTasks( 'grunt-contrib-concat' ); grunt.loadNpmTasks( 'grunt-contrib-concat' );
@ -250,7 +249,7 @@ module.exports = function ( grunt ) {
// Register tasks. // Register tasks.
grunt.registerTask( 'default', [ 'js', 'css' ] ); grunt.registerTask( 'default', [ 'js', 'css' ] );
grunt.registerTask( 'js', [ 'eslint', 'copy:js', 'uglify:js_assets' ] ); grunt.registerTask( 'js', [ 'copy:js', 'uglify:js_assets' ] );
grunt.registerTask( 'css', [ grunt.registerTask( 'css', [
'sass', 'sass',

View File

@ -7,8 +7,7 @@
"main": "Gruntfile.js", "main": "Gruntfile.js",
"scripts": { "scripts": {
"turbo:build": "grunt assets", "turbo:build": "grunt assets",
"build": "pnpm -w exec turbo run turbo:build --filter=$npm_package_name", "build": "pnpm -w exec turbo run turbo:build --filter=$npm_package_name"
"lint": "grunt eslint stylelint --force"
}, },
"devDependencies": { "devDependencies": {
"@wordpress/stylelint-config": "19.1.0", "@wordpress/stylelint-config": "19.1.0",

Some files were not shown because too many files have changed in this diff Show More