diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 545d6fa..13b6208 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -3,7 +3,7 @@ name: "CodeQL" on: push: - branches: [ main ] + branches: [ main, beta ] pull_request: branches: [ main ] schedule: @@ -21,7 +21,7 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'javascript' ] + language: [ 'javascript-typescript' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] # Learn more: # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed diff --git a/.github/workflows/semantic-release.yml b/.github/workflows/semantic-release.yml index 220ffec..0d25a51 100644 --- a/.github/workflows/semantic-release.yml +++ b/.github/workflows/semantic-release.yml @@ -10,16 +10,16 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 persist-credentials: false - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v3 with: version: latest - name: Setup Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: 'lts/*' cache: 'pnpm' diff --git a/.releaserc b/.releaserc index 16bfd7c..0555499 100644 --- a/.releaserc +++ b/.releaserc @@ -9,8 +9,8 @@ "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", - "@semantic-release/github", "@semantic-release/npm", + "@semantic-release/github", ["@semantic-release/changelog", { "changelogFile": "CHANGELOG.md" }], diff --git a/gen/fixer.ts b/gen/fixer.ts index ba4fd43..abaad40 100644 --- a/gen/fixer.ts +++ b/gen/fixer.ts @@ -1,7 +1,9 @@ /* eslint-disable no-console */ import { ApiSchema } from './schema' +import resSchema from './resources.js' import { sortObjectFields } from '../src/util' -import { inspect } from 'util' +import Inflector from './inflector.js' +import { CONFIG } from './generator.js' @@ -30,7 +32,7 @@ const fixRedundantComponents = (schema: ApiSchema): ApiSchema => { res.components = sortObjectFields(res.components) }) - + console.log('Redundant components have been replaced') return schema @@ -38,16 +40,61 @@ const fixRedundantComponents = (schema: ApiSchema): ApiSchema => { } -const fixSchema = (schema: ApiSchema): ApiSchema => { +const fixSchema = async (schema: ApiSchema): Promise => { + console.log('Fixing parsed schema...') - const fixedSchema = fixRedundantComponents(schema) + + let fixedSchema = schema + fixedSchema = fixRedundantComponents(fixedSchema) + fixedSchema = await enrichSchema(fixedSchema) + console.log('Schema fixed.') + return fixedSchema + } -export default fixSchema +const enrichSchema = async (schema: ApiSchema): Promise => { + + const resourcesInfo = CONFIG.LOCAL? resSchema.load() : await resSchema.download() + + if (!resourcesInfo) { + console.log('Error reading reasources data') + process.exit() + } + + Object.entries(schema.components).forEach(([key, val]) => { + const resId = Inflector.snakeCase(key) + const resFields = resSchema.getResourceFields(resourcesInfo, resId) + if (resFields) Object.entries(val.attributes).forEach(([name, info]) => { + const field = resFields[name] + if (!field) console.log(`Warning, field not found in resources data: ${resId}.${name}`) + info.sortable = field?.sortable || false + info.filterable = field?.filterable || false + }) + }) + + + Object.values(schema.resources).forEach(r => { + Object.entries(r.components).forEach(([key, val]) => { + const resId = Inflector.snakeCase(key) + const resFields = resSchema.getResourceFields(resourcesInfo, resId) + if (resFields) Object.entries(val.attributes).forEach(([name, info]) => { + const field = resFields[name] + if (!field) console.log(`Warning, field not found in resources data: ${resId}.${name}`) + info.sortable = field?.sortable || false + info.filterable = field?.filterable || false + }) + }) + }) + + console.log('Api schema has been enriched with resources data') + + return schema + +} const fixHeadingEmptyLines = (lines: string[]): string[] => { @@ -62,4 +109,8 @@ const fixHeadingEmptyLines = (lines: string[]): string[] => { } -export { fixHeadingEmptyLines } + +export default { + fixSchema, + fixHeadingEmptyLines +} diff --git a/gen/generator.ts b/gen/generator.ts index bf2042a..072da49 100644 --- a/gen/generator.ts +++ b/gen/generator.ts @@ -1,21 +1,24 @@ import apiSchema, { Resource, Operation, Component, Cardinality, Attribute, isObjectType } from './schema' import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, rmSync } from 'fs' -import { basename } from 'path' -import { snakeCase } from 'lodash' -import fixSchema, { fixHeadingEmptyLines } from './fixer' +import { basename } from 'node:path' +import Fixer from './fixer' +import Inflector from './inflector' /**** SDK source code generator settings ****/ -const CONFIG = { +export const CONFIG = { RELATIONSHIP_FUNCTIONS: true, TRIGGER_FUNCTIONS: true, - ACTION_FUNCTIONS: true + ACTION_FUNCTIONS: true, + LEAZY_LOADING: true, + LOCAL: false, + MICRO_CLIENTS: true } /**** **** **** **** **** **** **** **** ****/ -const Inflector = require('inflector-js') +const RESOURCE_COMMON_FIELDS = ['type', 'id', 'reference', 'reference_origin', 'metadata', 'created_at', 'updated_at'] type OperationType = 'retrieve' | 'list' | 'create' | 'update' | 'delete' @@ -54,6 +57,7 @@ const loadTemplates = (): void => { const generate = async (localSchema?: boolean) => { console.log('>> Local schema: ' + (localSchema || false) + '\n') + CONFIG.LOCAL = localSchema || false if (!localSchema) { @@ -68,11 +72,16 @@ const generate = async (localSchema?: boolean) => { const schemaInfo = await apiSchema.download() - if (schemaInfo.version === currentVersion) { - console.log('No new OpenAPI schema version: ' + currentVersion) + if (!schemaInfo) { + console.log('Unable to download OpenAPI schema') return } - else console.log(`New OpenAPI schema version: ${currentVersion} --> ${schemaInfo.version}`) + else + if (schemaInfo.version === currentVersion) { + console.log('No new OpenAPI schema version: ' + currentVersion) + return + } + else console.log(`New OpenAPI schema version: ${currentVersion} --> ${schemaInfo.version}`) } @@ -82,6 +91,7 @@ const generate = async (localSchema?: boolean) => { return } + console.log('Generating SDK resources from schema ' + schemaPath) const schema = apiSchema.parse(schemaPath) @@ -89,8 +99,7 @@ const generate = async (localSchema?: boolean) => { // Remove redundant components and force usage of global resource component - fixSchema(schema) - // console.log(inspect(schema, false, null, true)) + const fixedSchema = await Fixer.fixSchema(schema) loadTemplates() @@ -107,7 +116,7 @@ const generate = async (localSchema?: boolean) => { // Check singletons - Object.entries(schema.resources).forEach(([type, res]) => { + Object.entries(fixedSchema.resources).forEach(([type, res]) => { if (Object.values(res.operations).some(op => op.singleton)) { global.singletons[type] = Object.keys(res.components)[0] } @@ -115,7 +124,7 @@ const generate = async (localSchema?: boolean) => { const resources: { [key: string]: ApiRes } = {} - Object.entries(schema.resources).forEach(([type, res]) => { + Object.entries(fixedSchema.resources).forEach(([type, res]) => { const name = Inflector.pluralize(Inflector.camelize(type)) as string @@ -139,7 +148,7 @@ const generate = async (localSchema?: boolean) => { apiClass: name, models, singleton, - operations: singleton? [] : operations, + operations: singleton ? [] : operations, taggable, versionable } @@ -150,6 +159,7 @@ const generate = async (localSchema?: boolean) => { updateApiResources(resources) updateSdkInterfaces(resources) updateModelTypes(resources) + // updateApiMicroClients(resources) console.log(`SDK generation completed [${global.version}].\n`) @@ -182,7 +192,9 @@ const tabsString = (num: number): string => { const updateSdkInterfaces = (resources: { [key: string]: ApiRes }): void => { - const cl = readFileSync('src/commercelayer.ts', { encoding: 'utf-8' }) + const filePath = 'src/commercelayer.ts' + + const cl = readFileSync(filePath, { encoding: 'utf-8' }) const lines = cl.split('\n') @@ -201,8 +213,8 @@ const updateSdkInterfaces = (resources: { [key: string]: ApiRes }): void => { Object.entries(resources).forEach(([type, res]) => { let def = defTpl def = def.replace(/##__TAB__##/g, '\t') - def = def.replace('##__RESOURCE_TYPE__##', type) - def = def.replace('##__RESOURCE_CLASS__##', res.apiClass) + def = def.replace(/##__RESOURCE_TYPE__##/, type) + def = def.replace(/##__RESOURCE_CLASS__##/, res.apiClass) definitions.push(def) }) @@ -217,11 +229,11 @@ const updateSdkInterfaces = (resources: { [key: string]: ApiRes }): void => { const iniTpl = iniTplLine.text.substring(iniTplIdx) const initializations: string[] = [] - Object.entries(resources).forEach(([type, res]) => { + if (!CONFIG.LEAZY_LOADING) Object.entries(resources).forEach(([type, res]) => { let ini = iniTpl ini = ini.replace(/##__TAB__##/g, '\t') - ini = ini.replace('##__RESOURCE_TYPE__##', type) - ini = ini.replace('##__RESOURCE_CLASS__##', res.apiClass) + ini = ini.replace(/##__RESOURCE_TYPE__##/, type) + ini = ini.replace(/##__RESOURCE_CLASS__##/, res.apiClass) initializations.push(ini) }) @@ -230,7 +242,26 @@ const updateSdkInterfaces = (resources: { [key: string]: ApiRes }): void => { lines.splice(iniStartIdx, iniStopIdx - iniStartIdx, ...initializations) - writeFileSync('src/commercelayer.ts', lines.join('\n'), { encoding: 'utf-8' }) + // Leazy Loading + const llTplLine = findLine('##__CL_RESOURCES_LEAZY_LOADING_TEMPLATE::', lines) + const llTplIdx = llTplLine.offset + '##__CL_RESOURCES_LEAZY_LOADING_TEMPLATE::'.length + 1 + const llTpl = llTplLine.text.substring(llTplIdx) + + const leazyLoaders: string[] = [] + if (CONFIG.LEAZY_LOADING) Object.entries(resources).forEach(([type, res]) => { + let ll = llTpl + ll = ll.replace(/##__TAB__##/g, '\t') + ll = ll.replace(/##__RESOURCE_TYPE__##/g, type) + ll = ll.replace(/##__RESOURCE_CLASS__##/g, res.apiClass) + leazyLoaders.push(ll) + }) + + const llStartIdx = findLine('##__CL_RESOURCES_LEAZY_LOADING_START__##', lines).index + 2 + const llStopIdx = findLine('##__CL_RESOURCES_LEAZY_LOADING_STOP__##', lines).index + lines.splice(llStartIdx, llStopIdx - llStartIdx, ...leazyLoaders) + + + writeFileSync(filePath, lines.join('\n'), { encoding: 'utf-8' }) console.log('API interfaces generated.') @@ -239,7 +270,9 @@ const updateSdkInterfaces = (resources: { [key: string]: ApiRes }): void => { const updateModelTypes = (resources: { [key: string]: ApiRes }): void => { - const cl = readFileSync('src/model.ts', { encoding: 'utf-8' }) + const filePath = 'src/model.ts' + + const cl = readFileSync(filePath, { encoding: 'utf-8' }) const lines = cl.split('\n') @@ -250,11 +283,13 @@ const updateModelTypes = (resources: { [key: string]: ApiRes }): void => { const exports: string[] = [copyrightHeader(templates.header)] const types: string[] = [] + Object.entries(resources).forEach(([type, res]) => { let exp = expTpl exp = exp.replace(/##__TAB__##/g, '\t') - exp = exp.replace('##__RESOURCE_TYPE__##', type) - exp = exp.replace('##__RESOURCE_MODELS__##', res.models.join(', ')) + exp = exp.replace(/##__RESOURCE_TYPE__##/, type) + exp = exp.replace(/##__RESOURCE_MODELS__##/, res.models.join(', ')) + exp = exp.replace(/##__RESOURCE_BASE_MODEL__##/g, String(res.models[0])) exports.push(exp) types.push(`\t'${type}'`) }) @@ -264,7 +299,7 @@ const updateModelTypes = (resources: { [key: string]: ApiRes }): void => { lines.splice(expStartIdx, expStopIdx - expStartIdx, ...exports) - writeFileSync('src/model.ts', lines.join('\n'), { encoding: 'utf-8' }) + writeFileSync(filePath, lines.join('\n'), { encoding: 'utf-8' }) console.log('Model types generated.') @@ -273,7 +308,9 @@ const updateModelTypes = (resources: { [key: string]: ApiRes }): void => { const updateApiResources = (resources: { [key: string]: ApiRes }): void => { - const cl = readFileSync('src/api.ts', { encoding: 'utf-8' }) + const filePath = 'src/api.ts' + + const cl = readFileSync(filePath, { encoding: 'utf-8' }) const lines = cl.split('\n') @@ -294,13 +331,18 @@ const updateApiResources = (resources: { [key: string]: ApiRes }): void => { const taggables: string[] = [] const versionables: string[] = [] + const fieldsets: string[] = [] + const sortables: string[] = [] + Object.entries(resources).forEach(([type, res]) => { let exp = expTpl exp = exp.replace(/##__TAB__##/g, '\t') - exp = exp.replace('##__RESOURCE_TYPE__##', type) - exp = exp.replace('##__RESOURCE_CLASS__##', res.apiClass) + exp = exp.replace(/##__RESOURCE_TYPE__##/, type) + exp = exp.replace(/##__RESOURCE_CLASS__##/, res.apiClass) + exp = exp.replace(/##__RESOURCE_MODEL__##/, Inflector.singularize(res.apiClass)) exports.push(exp) + const tabType = `\t'${type}'` types.push(tabType) @@ -312,6 +354,9 @@ const updateApiResources = (resources: { [key: string]: ApiRes }): void => { if (res.taggable) taggables.push(tabType) if (res.versionable) versionables.push(tabType) + fieldsets.push(`\t${res.type}: models.${Inflector.singularize(res.apiClass)}`) + sortables.push(`\t${res.type}: models.${Inflector.singularize(res.apiClass)}Sort`) + }) const expStartIdx = findLine('##__API_RESOURCES_START__##', lines).index + 2 @@ -362,7 +407,15 @@ const updateApiResources = (resources: { [key: string]: ApiRes }): void => { const rvStopIdx = findLine('##__API_RESOURCE_VERSIONABLE_STOP__##', lines).index lines.splice(rvStartIdx, rvStopIdx - rvStartIdx, versionables.join('\n|')) - fixHeadingEmptyLines(lines) + const rfStartIdx = findLine('##__API_RESOURCE_FIELDS_START__##', lines).index + 1 + const rfStopIdx = findLine('##__API_RESOURCE_FIELDS_STOP__##', lines).index + lines.splice(rfStartIdx, rfStopIdx - rfStartIdx, fieldsets.join(',\n')) + + const sfStartIdx = findLine('##__API_RESOURCE_SORTABLE_FIELDS_START__##', lines).index + 1 + const sfStopIdx = findLine('##__API_RESOURCE_SORTABLE_FIELDS_STOP__##', lines).index + lines.splice(sfStartIdx, sfStopIdx - sfStartIdx, sortables.join(',\n')) + + Fixer.fixHeadingEmptyLines(lines) writeFileSync('src/api.ts', lines.join('\n'), { encoding: 'utf-8' }) @@ -371,6 +424,41 @@ const updateApiResources = (resources: { [key: string]: ApiRes }): void => { } + +const updateApiMicroClients = (resources: { [key: string]: ApiRes }): void => { + + const filePath = 'src/micro.ts' + + const cl = readFileSync(filePath, { encoding: 'utf-8' }) + + const lines = cl.split('\n') + + const cltTpl = templates.client + + const clients: string[] = [copyrightHeader(templates.header)] + + if (CONFIG.MICRO_CLIENTS) { + Object.entries(resources).forEach(([type, res]) => { + let clt = cltTpl + clt = clt.replace(/##__RESOURCE_CLASS__##/g, res.apiClass) + clt = clt.replace(/##__RESOURCE_CLASS_INIT__##/g, Inflector.camelize(res.apiClass, true)) + clients.push(`${clt}\n`) + }) + } + + const cltStartIdx = findLine('##__API_RESOURCES_MICRO_CLIENTS_START__##', lines).index + 1 + const cltStopIdx = findLine('##__API_RESOURCES_MICRO_CLIENTS_STOP__##', lines).index + lines.splice(cltStartIdx, cltStopIdx - cltStartIdx, ...clients) + + writeFileSync(filePath, lines.join('\n'), { encoding: 'utf-8' }) + + if (CONFIG.MICRO_CLIENTS) console.log('API micro clients generated.') + else console.log('API micro clients generation skipped.') + +} + + + const generateSpec = (type: string, name: string, resource: Resource): string => { let spec = templates.spec @@ -417,12 +505,12 @@ const generateSpec = (type: string, name: string, resource: Resource): string => const compUpdKey = Object.keys(resource.components).find(c => c.endsWith('Update')) if (compUpdKey) { const compUpd = resource.components[compUpdKey] - const triggers = Object.values(compUpd.attributes).filter(a => a.name.startsWith('_') ) + const triggers = Object.values(compUpd.attributes).filter(a => a.name.startsWith('_')) if (triggers.length > 0) { const tplt = templates.spec_trigger.split('\n').join('\n\t') for (const trigger of triggers) { - const triggerValue = (trigger.type === 'boolean')? 'true' : `randomValue('${trigger.type}')` - const triggerParams = (trigger.type === 'boolean')? 'id' : 'id, triggerValue' + const triggerValue = (trigger.type === 'boolean') ? 'true' : `randomValue('${trigger.type}')` + const triggerParams = (trigger.type === 'boolean') ? 'id' : 'id, triggerValue' let specTrg = tplt specTrg = specTrg.replace(/##__OPERATION_NAME__##/g, trigger.name) specTrg = specTrg.replace(/##__TRIGGER_VALUE__##/g, triggerValue) @@ -506,7 +594,7 @@ const triggerFunctions = (type: string, name: string, resource: Resource, operat const tplt = templates.trigger for (const trigger of triggers) { - const resId = `${snakeCase(type)}Id` + const resId = `${Inflector.underscore(type)}Id` const op: Operation = { type, path: `/${type}/{${resId}}`, @@ -562,8 +650,8 @@ const generateResource = (type: string, name: string, resource: Resource): strin if (['create', 'update'].includes(opName)) qryMod.add('QueryParamsRetrieve') if (['retrieve', 'list'].includes(opName)) { /* do nothing: - retrieve operation is common to all resoucres - list operation is common to all non singleton resoucres + retrieve operation is common to all resoucres + list operation is common to all non singleton resoucres */ } else { @@ -578,10 +666,10 @@ const generateResource = (type: string, name: string, resource: Resource): strin const tplrOp = templatedOperation(resName, opName, op, tplr) if (op.relationship.cardinality === Cardinality.to_one) qryMod.add('QueryParamsRetrieve') else - if (op.relationship.cardinality === Cardinality.to_many) { - qryMod.add('QueryParamsList') - resMod.add('ListResponse') - } + if (op.relationship.cardinality === Cardinality.to_many) { + qryMod.add('QueryParamsList') + resMod.add('ListResponse') + } operations.push(tplrOp.operation) } else @@ -599,23 +687,24 @@ const generateResource = (type: string, name: string, resource: Resource): strin // Trigger functions (only boolean) if (CONFIG.TRIGGER_FUNCTIONS) triggerFunctions(type, resName, resource, operations) - + if (operations && (operations.length > 0)) declaredImportsCommon.add('ResourcesConfig') res = res.replace(/##__RESOURCE_MODEL_TYPE__##/g, resModelType) - res = res.replace(/##__RESPONSE_MODELS__##/g, (resMod.size > 0) ? `, ${Array.from(resMod).join(', ')}`: '') + res = res.replace(/##__RESPONSE_MODELS__##/g, (resMod.size > 0) ? `, ${Array.from(resMod).join(', ')}` : '') res = res.replace(/##__MODEL_RESOURCE_INTERFACE__##/g, resModelInterface) res = res.replace(/##__IMPORT_RESOURCE_COMMON__##/, Array.from(declaredImportsCommon).join(', ')) + res = res.replace(/##__MODEL_SORTABLE_INTERFACE__##/, (resModelType === 'ApiSingleton') ? '' : `, ${resModelInterface}Sort`) const importQueryModels = (qryMod.size > 0)? `import type { ${Array.from(qryMod).sort().reverse().join(', ')} } from '../query'` : '' res = res.replace(/##__IMPORT_QUERY_MODELS__##/, importQueryModels) - + // Resource definition res = res.replace(/##__RESOURCE_TYPE__##/g, type) res = res.replace(/##__RESOURCE_CLASS__##/g, resName) - const resourceOperations = (operations && (operations.length > 0))? operations.join('\n\n\t') : '' + const resourceOperations = (operations && (operations.length > 0)) ? operations.join('\n\n\t') : '' res = res.replace(/##__RESOURCE_OPERATIONS__##/, resourceOperations) @@ -629,18 +718,28 @@ const generateResource = (type: string, name: string, resource: Resource): strin const modelInterfaces: string[] = [] const resourceInterfaces: string[] = [] const relationshipTypes: Set = new Set() + const sortableFields: string[] = [] + const filterableFields: string[] = [] typesArray.forEach(t => { const cudSuffix = getCUDSuffix(t) resourceInterfaces.push(`Resource${cudSuffix}`) - const tplCmp = templatedComponent(resName, t, resource.components[t]) + const component: Component = resource.components[t] + const tplCmp = templatedComponent(resName, t, component) tplCmp.models.forEach(m => declaredImportsModels.add(m)) modelInterfaces.push(tplCmp.component) if (cudSuffix) tplCmp.models.forEach(t => relationshipTypes.add(t)) + else { + sortableFields.push('id', ...Object.values(component.attributes).filter(f => (f.sortable && !RESOURCE_COMMON_FIELDS.includes(f.name))).map(f => f.name)) + filterableFields.push('id', ...Object.values(component.attributes).filter(f => (f.filterable && !RESOURCE_COMMON_FIELDS.includes(f.name))).map(f => f.name)) + } }) res = res.replace(/##__MODEL_INTERFACES__##/g, modelInterfaces.join('\n\n\n')) res = res.replace(/##__IMPORT_RESOURCE_INTERFACES__##/g, resourceInterfaces.join(', ')) + res = res.replace(/##__MODEL_SORTABLE_FIELDS__##/g, sortableFields.map(f => { return `'${f}'` }).join(' | ')) + res = res.replace(/##__MODEL_FILTERABLE_FIELDS__##/g, filterableFields.map(f => { return `'${f}'` }).join(' | ')) + // Relationships definition const relTypesArray = Array.from(relationshipTypes).map(i => `type ${i}Rel = ResourceRel & { type: ${i}Type }`) @@ -650,7 +749,7 @@ const generateResource = (type: string, name: string, resource: Resource): strin const impResMod: string[] = Array.from(declaredImportsModels) .filter(i => !typesArray.includes(i)) // exludes resource self reference .map(i => { - const resFileName = snakeCase(Object.values(global.singletons).includes(i)? i : Inflector.pluralize(i)) + const resFileName = Inflector.underscore(Object.values(global.singletons).includes(i)? i : Inflector.pluralize(i)) return `import type { ${i}${relationshipTypes.has(i)? `, ${i}Type` : ''} } from './${resFileName}'` }) const importStr = impResMod.join('\n') + (impResMod.length ? '\n' : '') @@ -701,7 +800,7 @@ const templatedOperation = (res: string, name: string, op: Operation, tpl: strin if (!types.includes(responseType)) types.push(responseType) } - const opIdVar = op.id? Inflector.camelize(op.id, true) : '' + const opIdVar = op.id ? Inflector.camelize(op.id, true) : '' if (op.relationship) { // Relationship operation = operation.replace(/##__RELATIONSHIP_TYPE__##/g, op.relationship.type) operation = operation.replace(/##__RELATIONSHIP_PATH__##/g, op.path.substring(1).replace('{' + op.id, '${_' + opIdVar)) @@ -722,11 +821,11 @@ const templatedOperation = (res: string, name: string, op: Operation, tpl: strin operation = operation.replace(/##__MODEL_RESOURCE_INTERFACE__##/g, Inflector.singularize(res)) operation = operation.replace(/##__ACTION_PAYLOAD_PARAM__##/g, isObjectType(op.requestType)? ` payload: ${Inflector.camelize(op.name)}DataType,` : '') operation = operation.replace(/##__ACTION_PAYLOAD__##/g, isObjectType(op.requestType)? ' ...payload ' : '') - operation = operation.replace(/##__ACTION_COMMAND__##/g, op.type) + operation = operation.replace(/##__ACTION_COMMAND__##/g, op.type.toUpperCase()) } if (placeholders) Object.entries(placeholders).forEach(([key, val]) => { - const plh = (key.startsWith('##__') && key.endsWith('__##'))? key : `##__${key.toUpperCase()}__##` + const plh = (key.startsWith('##__') && key.endsWith('__##')) ? key : `##__${key.toUpperCase()}__##` operation = operation.replace(key, val) }) @@ -741,12 +840,12 @@ const templatedOperation = (res: string, name: string, op: Operation, tpl: strin const fixAttributeType = (attr: Attribute): string => { if (attr.enum?.length > 0) return `${attr.enum.map(a => `'${a}'`).join(' | ')}` else - switch (attr.type) { - case 'integer': return 'number' - case 'object': return 'Record' - case 'object[]': return 'Array>' - default: return attr.type - } + switch (attr.type) { + case 'integer': return 'number' + case 'object': return 'Record' + case 'object[]': return 'Array>' + default: return attr.type + } } @@ -770,6 +869,11 @@ const isCUDModel = (name: string): boolean => { } +const nullable = (type: string): string => { + return `Nullable<${type}>` +} + + type ComponentEnums = { [key: string]: string } const templatedComponent = (res: string, name: string, cmp: Component): { component: string, models: string[], enums: ComponentEnums } => { @@ -783,11 +887,12 @@ const templatedComponent = (res: string, name: string, cmp: Component): { compon const attributes = Object.values(cmp.attributes) const fields: string[] = [] attributes.forEach(a => { - if (!['type', 'id', 'reference', 'reference_origin', 'metadata', 'created_at', 'updated_at'].includes(a.name)) { + if (!RESOURCE_COMMON_FIELDS.includes(a.name)) { if (cudModel || a.fetchable) { let attrType = fixAttributeType(a) if (a.enum) enums[a.name] = attrType - fields.push(`${a.name}${a.required ? '' : '?'}: ${attrType}${a.required ? '' : ' | null'}`) + // fields.push('/**\n* Unique identifier for the resource (hash).\n* @example ```"XAyRWNUzyN"```\n*/') + fields.push(`${a.name}${a.required ? '' : '?'}: ${a.required ? attrType : nullable(attrType)}`) } } }) @@ -808,7 +913,6 @@ const templatedComponent = (res: string, name: string, cmp: Component): { compon let resName = r.type if (resName !== 'object') { - const relStr = cudModel ? 'Rel' : '' if (r.polymorphic && r.oneOf) { resName = r.oneOf.map(o => `${o}${relStr}`).join(' | ') @@ -826,7 +930,7 @@ const templatedComponent = (res: string, name: string, cmp: Component): { compon else resName += '[]' } - rels.push(`${r.name}${r.required ? '' : '?'}: ${resName}${r.required ? '' : ' | null'}`) + rels.push(`${r.name}${r.required ? '' : '?'}: ${r.required ? resName : nullable(resName)}`) } }) diff --git a/gen/inflector.ts b/gen/inflector.ts new file mode 100644 index 0000000..fe73b46 --- /dev/null +++ b/gen/inflector.ts @@ -0,0 +1,295 @@ +/** + * Inspired by inflector-js --> https://github.com/didanurwanda/inflector-js + */ + + +const _Inflector = { + + uncountableWords: [ + 'equipment', 'information', 'rice', 'money', 'species', 'series', + 'fish', 'sheep', 'moose', 'deer', 'news' + ], + + pluralRules: [ + [/(m)an$/gi, '$1en'], + [/(pe)rson$/gi, '$1ople'], + [/(child)$/gi, '$1ren'], + [/^(ox)$/gi, '$1en'], + [/(ax|test)is$/gi, '$1es'], + [/(octop|vir)us$/gi, '$1i'], + [/(alias|status)$/gi, '$1es'], + [/(bu)s$/gi, '$1ses'], + [/(buffal|tomat|potat)o$/gi, '$1oes'], + [/([ti])um$/gi, '$1a'], + [/sis$/gi, 'ses'], + [/(?:([^f])fe|([lr])f)$/gi, '$1$2ves'], + [/(hive)$/gi, '$1s'], + [/([^aeiouy]|qu)y$/gi, '$1ies'], + [/(x|ch|ss|sh)$/gi, '$1es'], + [/(matr|vert|ind)ix|ex$/gi, '$1ices'], + [/([m|l])ouse$/gi, '$1ice'], + [/(quiz)$/gi, '$1zes'], + [/s$/gi, 's'], + [/$/gi, 's'] + ], + + singularRules: [ + [/(m)en$/gi, '$1an'], + [/(pe)ople$/gi, '$1rson'], + [/(child)ren$/gi, '$1'], + [/([ti])a$/gi, '$1um'], + [/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/gi, '$1$2sis'], + [/(hive)s$/gi, '$1'], + [/(tive)s$/gi, '$1'], + [/(curve)s$/gi, '$1'], + [/([lr])ves$/gi, '$1f'], + [/([^fo])ves$/gi, '$1fe'], + [/([^aeiouy]|qu)ies$/gi, '$1y'], + [/(s)eries$/gi, '$1eries'], + [/(m)ovies$/gi, '$1ovie'], + [/(x|ch|ss|sh)es$/gi, '$1'], + [/([m|l])ice$/gi, '$1ouse'], + [/(bus)es$/gi, '$1'], + [/(o)es$/gi, '$1'], + [/(shoe)s$/gi, '$1'], + [/(cris|ax|test)es$/gi, '$1is'], + [/(octop|vir)i$/gi, '$1us'], + [/(alias|status)es$/gi, '$1'], + [/^(ox)en/gi, '$1'], + [/(vert|ind)ices$/gi, '$1ex'], + [/(matr)ices$/gi, '$1ix'], + [/(quiz)zes$/gi, '$1'], + [/s$/gi, ''] + ], + + nonTitlecasedWords: [ + 'and', 'or', 'nor', 'a', 'an', 'the', 'so', 'but', 'to', 'of', 'at', + 'by', 'from', 'into', 'on', 'onto', 'off', 'out', 'in', 'over', + 'with', 'for' + ], + + idSuffix: /(_ids|_id)$/g, + underbar: /_/g, + spaceOrUnderbar: /[ _]/g, + uppercase: /([A-Z])/g, + underbarPrefix: /^_/, + + applyRules: (str: string, rules: Array>, skip: string[], override?: string): string => { + if (override) { + str = override + } else { + const ignore = (skip.includes(str.toLowerCase())) + if (!ignore) { + for (let x = 0; x < rules.length; x++) { + if (str.match(rules[x][0])) { + str = str.replace(rules[x][0], rules[x][1] as string) + break; + } + } + } + } + return str + }, + + + /* + Inflector.pluralize('person') -> 'people' + Inflector.pluralize('octopus') -> 'octopi' + Inflector.pluralize('Hat') -> 'Hats' + Inflector.pluralize('person', 'guys') -> 'guys' + */ + pluralize: (str: string, plural?: string): string => { + return _Inflector.applyRules( + str, + _Inflector.pluralRules, + _Inflector.uncountableWords, + plural + ) + }, + + /* + Inflector.singularize('person') -> 'person' + Inflector.singularize('octopi') -> 'octopus' + Inflector.singularize('hats') -> 'hat' + Inflector.singularize('guys', 'person') -> 'person' + */ + singularize: (str: string, singular?: string): string => { + return _Inflector.applyRules( + str, + _Inflector.singularRules, + _Inflector.uncountableWords, + singular + ) + }, + + /* + Inflector.camelize('message_properties') -> 'MessageProperties' + Inflector.camelize('message_properties', true) -> 'messageProperties' + */ + camelize: (str: string, lowFirstLetter?: boolean): string => { + // str = str.toLowerCase() + const strPath = str.split('/') + for (let i = 0; i < strPath.length; i++) { + const strArr = strPath[i].split('_') + const initX = ((lowFirstLetter && i + 1 === strPath.length) ? (1) : (0)) + for (let x = initX; x < strArr.length; x++) { + strArr[x] = strArr[x].charAt(0).toUpperCase() + strArr[x].substring(1) + } + strPath[i] = strArr.join('') + } + str = strPath.join('::') + + // fix + if (lowFirstLetter) { + const first = str.charAt(0).toLowerCase() + const last = str.slice(1) + str = first + last + } + return str + }, + + /* + Inflector.underscore('MessageProperties') -> 'message_properties' + Inflector.underscore('messageProperties') -> 'message_properties' + */ + underscore: (str: string): string => { + const strPath = str.split('::') + for (let i = 0; i < strPath.length; i++) { + strPath[i] = strPath[i].replace(_Inflector.uppercase, '_$1') + strPath[i] = strPath[i].replace(_Inflector.underbarPrefix, '') + } + str = strPath.join('/').toLowerCase() + return str + }, + snakeCase: (str: string): string => { + return _Inflector.underscore(str) + }, + + /* + Inflector.humanize('message_properties') -> 'Message properties' + Inflector.humanize('message_properties') -> 'message properties' + */ + humanize: (str: string, lowFirstLetter: boolean): string => { + str = str.toLowerCase() + str = str.replace(_Inflector.idSuffix, '') + str = str.replace(_Inflector.underbar, ' ') + if (!lowFirstLetter) { + str = _Inflector.capitalize(str) + } + return str + }, + + /* + Inflector.capitalize('message_properties') -> 'Message_properties' + Inflector.capitalize('message properties') -> 'Message properties' + */ + capitalize: (str: string): string => { + str = str.toLowerCase() + str = str.substring(0, 1).toUpperCase() + str.substring(1) + return str + }, + + /* + Inflector.dasherize('message_properties') -> 'message-properties' + Inflector.dasherize('message properties') -> 'message-properties' + */ + dasherize: (str: string): string => { + str = str.toLocaleLowerCase() + str = str.replace(_Inflector.spaceOrUnderbar, '-') + return str + }, + kebabCase: (str: string): string => { + return _Inflector.dasherize(str) + }, + + /* + Inflector.camel2words('message_properties') -> 'Message Properties' + Inflector.camel2words('message properties') -> 'Message Properties' + Inflactor.camel2words('Message_propertyId', true) -> 'Message Properties Id' + */ + camel2words: (str: string, allFirstUpper: boolean): string => { + // str = str.toLowerCase() + if (allFirstUpper) { + str = _Inflector.camelize(str) + str = _Inflector.underscore(str) + } else { + str = str.toLowerCase() + } + + str = str.replace(_Inflector.underbar, ' ') + const strArr = str.split(' ') + for (let x = 0; x < strArr.length; x++) { + const d = strArr[x].split('-') + for (let i = 0; i < d.length; i++) { + if (!_Inflector.nonTitlecasedWords.includes(d[i].toLowerCase())) { + d[i] = _Inflector.capitalize(d[i]) + } + } + strArr[x] = d.join('-') + } + str = strArr.join(' ') + str = str.substring(0, 1).toUpperCase() + str.substring(1) + return str + }, + + /* + Inflector.demodulize('Message::Bus::Properties') -> 'Properties' + */ + demodulize: (str: string): string => { + const strArr = str.split('::') + str = strArr[strArr.length - 1] + return str + }, + + /* + Inflector.tableize('MessageBusProperty') -> 'message_bus_properties' + */ + tableize: (str: string): string => { + str = _Inflector.pluralize(_Inflector.underscore(str)) + return str + }, + + /* + Inflector.classify('message_bus_properties') -> 'MessageBusProperty' + */ + classify: (str: string): string => { + str = _Inflector.singularize(_Inflector.camelize(str)) + return str + }, + + /* + Inflector.foreignKey('MessageBusProperty') -> 'message_bus_property_id' + Inflector.foreignKey('MessageBusProperty', true) -> 'message_bus_propertyid' + */ + foreignKey: (str: string, dropIdUbar: boolean) => { + str = _Inflector.underscore(_Inflector.demodulize(str)) + (dropIdUbar ? ('') : ('_')) + 'id' + return str + }, + + /* + Inflector.ordinalize('the 1 pitch') -> 'the 1st pitch' + */ + ordinalize: (str: string): string => { + const strArr = str.split(' ') + for (let x = 0; x < strArr.length; x++) { + const i = parseInt(strArr[x]) + if (Number.isNaN(i)) { + const ltd = strArr[x].substring(strArr[x].length - 2) + const ld = strArr[x].substring(strArr[x].length - 1) + let suf = "th"; + if ((ltd !== "11") && (ltd !== "12") && (ltd !== "13")) { + if (ld === "1") suf = "st" + else if (ld === "2") suf = "nd" + else if (ld === "3") suf = "rd" + } + strArr[x] += suf + } + } + str = strArr.join(' ') + return str + } +} + + + +export default _Inflector diff --git a/gen/resources copy.json b/gen/resources copy.json new file mode 100644 index 0000000..d6694bb --- /dev/null +++ b/gen/resources copy.json @@ -0,0 +1,130 @@ +[ + { + "id": "api_credential", + "attributes": { + "fields": { + "mode": { + "sortable": true, + "filterable": true + } + }, + "relationships": { + "organization": { + "filterable": true + }, + "role": { + "filterable": true + } + } + } + }, + { + "id": "application_membership", + "attributes": { + "fields": {}, + "relationships": { + "api_credential": { + "filterable": true + }, + "membership": { + "filterable": true + }, + "organization": { + "filterable": true + }, + "role": { + "filterable": true + } + } + } + }, + { + "id": "membership", + "attributes": { + "fields": { + "status": { + "filterable": true + } + }, + "relationships": { + "organization": { + "filterable": true + }, + "role": { + "filterable": true + }, + "application_memberships": { + "filterable": true + } + } + } + }, + { + "id": "organization", + "attributes": { + "fields": {}, + "relationships": { + "memberships": { + "filterable": true + }, + "roles": { + "filterable": true + }, + "permissions": { + "filterable": true + }, + "api_credentials": { + "filterable": true + } + } + } + }, + { + "id": "permission", + "attributes": { + "fields": {}, + "relationships": { + "organization": { + "filterable": true + }, + "role": { + "filterable": true + } + } + } + }, + { + "id": "role", + "attributes": { + "fields": {}, + "relationships": { + "organization": { + "filterable": true + }, + "permissions": { + "filterable": true + }, + "memberships": { + "filterable": true + }, + "api_credentials": { + "filterable": true + } + } + } + }, + { + "id": "user", + "attributes": { + "fields": {}, + "relationships": {} + } + }, + { + "id": "version", + "attributes": { + "fields": {}, + "relationships": {} + } + } +] \ No newline at end of file diff --git a/gen/resources.json b/gen/resources.json new file mode 100644 index 0000000..d6694bb --- /dev/null +++ b/gen/resources.json @@ -0,0 +1,130 @@ +[ + { + "id": "api_credential", + "attributes": { + "fields": { + "mode": { + "sortable": true, + "filterable": true + } + }, + "relationships": { + "organization": { + "filterable": true + }, + "role": { + "filterable": true + } + } + } + }, + { + "id": "application_membership", + "attributes": { + "fields": {}, + "relationships": { + "api_credential": { + "filterable": true + }, + "membership": { + "filterable": true + }, + "organization": { + "filterable": true + }, + "role": { + "filterable": true + } + } + } + }, + { + "id": "membership", + "attributes": { + "fields": { + "status": { + "filterable": true + } + }, + "relationships": { + "organization": { + "filterable": true + }, + "role": { + "filterable": true + }, + "application_memberships": { + "filterable": true + } + } + } + }, + { + "id": "organization", + "attributes": { + "fields": {}, + "relationships": { + "memberships": { + "filterable": true + }, + "roles": { + "filterable": true + }, + "permissions": { + "filterable": true + }, + "api_credentials": { + "filterable": true + } + } + } + }, + { + "id": "permission", + "attributes": { + "fields": {}, + "relationships": { + "organization": { + "filterable": true + }, + "role": { + "filterable": true + } + } + } + }, + { + "id": "role", + "attributes": { + "fields": {}, + "relationships": { + "organization": { + "filterable": true + }, + "permissions": { + "filterable": true + }, + "memberships": { + "filterable": true + }, + "api_credentials": { + "filterable": true + } + } + } + }, + { + "id": "user", + "attributes": { + "fields": {}, + "relationships": {} + } + }, + { + "id": "version", + "attributes": { + "fields": {}, + "relationships": {} + } + } +] \ No newline at end of file diff --git a/gen/resources.ts b/gen/resources.ts new file mode 100644 index 0000000..7669bfe --- /dev/null +++ b/gen/resources.ts @@ -0,0 +1,65 @@ +import { readFileSync, writeFileSync } from "node:fs" +import { resolve } from "node:path" + + +const RESOURCES_LOCAL_PATH = resolve('./gen/resources.json') +const RESOURCES_REMOTE_URL = 'https://core.commercelayer.io/api/public/resources' + + +const downloadResources = async (url?: string): Promise => { + + const resourcesUrl = url || RESOURCES_REMOTE_URL + const resourcesOutPath = RESOURCES_LOCAL_PATH + + console.log(`Downloading resources ... [${resourcesUrl}]`) + + const response = await fetch(resourcesUrl) + const resources = (await response.json()).data + + if (resources) writeFileSync(resourcesOutPath, JSON.stringify(resources, null, 4)) + else console.log('Resources file is empty!') + + return resources + +} + + +const loadResources = (): any => { + + const schemaPath = RESOURCES_LOCAL_PATH + + console.log(`Loading resources ... [${schemaPath}]`) + + try { + const schema = readFileSync(schemaPath, { encoding: 'utf-8'}) + return JSON.parse(schema) + } catch (error) { + console.log('Error loading local resources schema: ' + schemaPath) + return undefined + } + +} + + +const getResource = (resources: any[], resId: string): { fields: any, relationships: any } => { + return resources.find(r => r.id === resId) +} + +const getResourceFields = (resources: any[] | any, resId: string): any => { + return (Array.isArray(resources)? getResource(resources, resId) : resources)?.attributes.fields +} + +const getResourceRelationships = (resources: any[] | any, resId: string): any => { + return (Array.isArray(resources)? getResource(resources, resId) : resources)?.attributes.relationships +} + + +export default { + download: downloadResources, + load: loadResources, + getResource, + getResourceFields, + getResourceRelationships, + localPath: RESOURCES_LOCAL_PATH, + remoteUrl: RESOURCES_REMOTE_URL +} diff --git a/gen/schema.ts b/gen/schema.ts index dae25cb..b3908c7 100644 --- a/gen/schema.ts +++ b/gen/schema.ts @@ -1,11 +1,7 @@ import { readFileSync, writeFileSync } from 'fs' -import { snakeCase } from 'lodash' -import axios from 'axios' import { resolve } from 'path' import { sortObjectFields } from '../src/util' - - -const Inflector = require('inflector-js') +import Inflector from './inflector' const SCHEMA_LOCAL_PATH = resolve('./gen/openapi.json') @@ -27,8 +23,8 @@ const downloadSchema = async (url?: string): Promise => { console.log(`Downloading OpenAPI schema ... [${schemaUrl}]`) - const response = await axios.get(schemaUrl) - const schema = await response.data + const response = await fetch(schemaUrl) + const schema = await response.json() if (schema) writeFileSync(schemaOutPath, JSON.stringify(schema, null, 4)) else console.log('OpenAPI schema is empty!') @@ -87,7 +83,7 @@ const parseSchema = (path: string): ApiSchema => { Object.keys(apiSchema.components).forEach(c => { if (!specialComponentMatcher.test(c)) components[c] = apiSchema.components[c] else - if (snakeCase(c.replace(specialComponentMatcher, '')) === singRes) resources[p].components[c] = apiSchema.components[c] + if (Inflector.snakeCase(c.replace(specialComponentMatcher, '')) === singRes) resources[p].components[c] = apiSchema.components[c] }) // Sort components resources[p].components = sortObjectFields(resources[p].components) @@ -165,11 +161,13 @@ const parsePaths = (schemaPaths: any[]): PathMap => { const [oKey, oValue] = o + const singleton = oValue.tags.includes('singleton') + const op: Operation = { path: pKey, type: oKey, name: operationName(oKey, id, relOrCmd), - singleton: oValue.tags.includes('singleton'), + singleton, } if (id) op.id = id @@ -210,6 +208,7 @@ const parsePaths = (schemaPaths: any[]): PathMap => { } + if (skip) console.log(`Operation skipped: ${op.name} [${op.path}]`) else operations[op.name] = op @@ -284,7 +283,9 @@ const parseComponents = (schemaComponents: any[]): ComponentMap => { type: (aValue.type === 'array') ? `${aValue.items.type}[]` : aValue.type, required: requiredAttributes.includes(aKey) || (fetchable && !aValue.nullable && !cKey.match(/(Create|Update)$/)), fetchable, - enum: aValue.enum + enum: aValue.enum, + description: aValue.description, + example: aValue.example } }) @@ -354,7 +355,11 @@ type Attribute = { name: string required: boolean fetchable: boolean + sortable?: boolean + filterable?: boolean enum: string[] + description?: string + example?: string } enum Cardinality { diff --git a/gen/templates/client.tpl b/gen/templates/client.tpl new file mode 100644 index 0000000..77c06ee --- /dev/null +++ b/gen/templates/client.tpl @@ -0,0 +1,3 @@ +export const ##__RESOURCE_CLASS_INIT__##Client = (init: InitParamType): api.##__RESOURCE_CLASS__## => { + return new api.##__RESOURCE_CLASS__##(initParam(init)) +} \ No newline at end of file diff --git a/gen/templates/relationship_many.tpl b/gen/templates/relationship_many.tpl index 7423a92..eaad9fc 100644 --- a/gen/templates/relationship_many.tpl +++ b/gen/templates/relationship_many.tpl @@ -1,4 +1,4 @@ -async ##__OPERATION_NAME__##(##__RESOURCE_ID__##: string | ##__MODEL_RESOURCE_INTERFACE__##, params?: QueryParamsList, options?: ResourcesConfig): Promise> { +async ##__OPERATION_NAME__##(##__RESOURCE_ID__##: string | ##__MODEL_RESOURCE_INTERFACE__##, params?: QueryParamsList<##__RESOURCE_RESPONSE_CLASS__##>, options?: ResourcesConfig): Promise> { const _##__RESOURCE_ID__## = (##__RESOURCE_ID__## as ##__MODEL_RESOURCE_INTERFACE__##).id || ##__RESOURCE_ID__## as string return this.resources.fetch<##__RESOURCE_RESPONSE_CLASS__##>({ type: '##__RELATIONSHIP_TYPE__##' }, `##__RELATIONSHIP_PATH__##`, params, options) as unknown as ListResponse<##__RESOURCE_RESPONSE_CLASS__##> } \ No newline at end of file diff --git a/gen/templates/relationship_one.tpl b/gen/templates/relationship_one.tpl index a486290..2341a75 100644 --- a/gen/templates/relationship_one.tpl +++ b/gen/templates/relationship_one.tpl @@ -1,4 +1,4 @@ -async ##__OPERATION_NAME__##(##__RESOURCE_ID__##: string | ##__MODEL_RESOURCE_INTERFACE__##, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise<##__RESOURCE_RESPONSE_CLASS__##> { +async ##__OPERATION_NAME__##(##__RESOURCE_ID__##: string | ##__MODEL_RESOURCE_INTERFACE__##, params?: QueryParamsRetrieve<##__RESOURCE_RESPONSE_CLASS__##>, options?: ResourcesConfig): Promise<##__RESOURCE_RESPONSE_CLASS__##> { const _##__RESOURCE_ID__## = (##__RESOURCE_ID__## as ##__MODEL_RESOURCE_INTERFACE__##).id || ##__RESOURCE_ID__## as string return this.resources.fetch<##__RESOURCE_RESPONSE_CLASS__##>({ type: '##__RELATIONSHIP_TYPE__##' }, `##__RELATIONSHIP_PATH__##`, params, options) as unknown as ##__RESOURCE_RESPONSE_CLASS__## } \ No newline at end of file diff --git a/gen/templates/resource.tpl b/gen/templates/resource.tpl index b5731a7..158587f 100644 --- a/gen/templates/resource.tpl +++ b/gen/templates/resource.tpl @@ -1,5 +1,6 @@ +import type { Nullable } from '../types' import { ##__RESOURCE_MODEL_TYPE__## } from '../resource' -import type { ##__IMPORT_RESOURCE_INTERFACES__##, ##__IMPORT_RESOURCE_COMMON__##, ResourceRel##__RESPONSE_MODELS__## } from '../resource' +import type { ##__IMPORT_RESOURCE_INTERFACES__##, ##__IMPORT_RESOURCE_COMMON__##, ResourceRel##__RESPONSE_MODELS__##, ResourceSort, /* ResourceFilter */ } from '../resource' ##__IMPORT_QUERY_MODELS__## ##__IMPORT_RESOURCE_MODELS__## @@ -8,6 +9,10 @@ type ##__MODEL_RESOURCE_INTERFACE__##Type = '##__RESOURCE_TYPE__##' type ##__MODEL_RESOURCE_INTERFACE__##Rel = ResourceRel & { type: ##__MODEL_RESOURCE_INTERFACE__##Type } ##__RELATIONSHIP_TYPES__## +export type ##__MODEL_RESOURCE_INTERFACE__##Sort = Pick<##__MODEL_RESOURCE_INTERFACE__##, ##__MODEL_SORTABLE_FIELDS__##> & ResourceSort +// export type ##__MODEL_RESOURCE_INTERFACE__##Filter = Pick<##__MODEL_RESOURCE_INTERFACE__##, ##__MODEL_FILTERABLE_FIELDS__##> & ResourceFilter + + ##__MODEL_INTERFACES__## @@ -24,7 +29,11 @@ class ##__RESOURCE_CLASS__## extends ##__RESOURCE_MODEL_TYPE__##<##__MODEL_RESOU relationship(id: string | ResourceId | null): ##__MODEL_RESOURCE_INTERFACE__##Rel { - return ((id === null) || (typeof id === 'string')) ? { id, type: ##__RESOURCE_CLASS__##.TYPE } : { id: id.id, type: ##__RESOURCE_CLASS__##.TYPE } + return super.relationshipOneToOne<##__MODEL_RESOURCE_INTERFACE__##Rel>(id) + } + + relationshipToMany(...ids: string[]): ##__MODEL_RESOURCE_INTERFACE__##Rel[] { + return super.relationshipOneToMany<##__MODEL_RESOURCE_INTERFACE__##Rel>(...ids) } diff --git a/gen/templates/spec.tpl b/gen/templates/spec.tpl index d58cd63..848dd8d 100644 --- a/gen/templates/spec.tpl +++ b/gen/templates/spec.tpl @@ -4,7 +4,7 @@ **/ import { CommerceLayerProvisioningClient, ##__RESOURCE_MODEL__## } from '../../src' -import { isEqual } from 'lodash' +import isEqual from 'lodash.isequal' // eslint-disable-next-line @typescript-eslint/no-unused-vars import { getClient, TestData, CommonData, handleError, interceptRequest, checkCommon, checkCommonData, checkCommonParamsList, checkCommonParams, currentAccessToken, randomValue } from '../../test/common' @@ -29,15 +29,17 @@ describe('##__RESOURCE_CLASS__## resource', () => { const params = { fields: { [resourceType]: CommonData.paramsFields } } const resData = attributes - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('post') - checkCommon(config, resourceType) - checkCommonData(config, resourceType, attributes) - expect(clp[resourceType].is##__RESOURCE_MODEL__##(config.data.data)).toBeTruthy() + const intId = clp.addRequestInterceptor((request) => { + const data = JSON.parse(String(request.options.body)) + expect(request.options.method).toBe('POST') + checkCommon(request, resourceType) + checkCommonData(data, resourceType, attributes) + expect(clp[resourceType].is##__RESOURCE_MODEL__##(data.data)).toBeTruthy() return interceptRequest() }) await clp[resourceType].create(resData, params, CommonData.options) + .then((res: ##__RESOURCE_MODEL__##) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -51,14 +53,15 @@ describe('##__RESOURCE_CLASS__## resource', () => { const id = TestData.id const params = { fields: {[resourceType]: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken) - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken) + checkCommonParams(request, params) return interceptRequest() }) await clp[resourceType].retrieve(id, params, CommonData.options) + .then((res: ##__RESOURCE_MODEL__##) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -73,16 +76,18 @@ describe('##__RESOURCE_CLASS__## resource', () => { const params = { fields: { [resourceType]: CommonData.paramsFields } } const resData = { id: TestData.id, ...attributes} - const intId = clp.addRequestInterceptor((config) => { - if (config.method !== 'get') { - expect(config.method).toBe('patch') - checkCommon(config, resourceType, resData.id, currentAccessToken) - checkCommonData(config, resourceType, attributes, resData.id) + const intId = clp.addRequestInterceptor((request) => { + if (request.options.method !== 'GET') { + const data = JSON.parse(String(request.options.body)) + expect(request.options.method).toBe('PATCH') + checkCommon(request, resourceType, resData.id, currentAccessToken) + checkCommonData(data, resourceType, attributes, resData.id) } return interceptRequest() }) await clp[resourceType].update(resData, params, CommonData.options) + .then((res: ##__RESOURCE_MODEL__##) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -95,9 +100,9 @@ describe('##__RESOURCE_CLASS__## resource', () => { const id = TestData.id - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('delete') - checkCommon(config, resourceType, id, currentAccessToken) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('DELETE') + checkCommon(request, resourceType, id, currentAccessToken) return interceptRequest() }) @@ -114,10 +119,10 @@ describe('##__RESOURCE_CLASS__## resource', () => { const params = CommonData.paramsList - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType) - checkCommonParamsList(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType) + checkCommonParamsList(request, params) return interceptRequest() }) @@ -134,10 +139,10 @@ describe('##__RESOURCE_CLASS__## resource', () => { const params = { fields: { [resourceType]: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType) - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType) + checkCommonParams(request, params) return interceptRequest() }) diff --git a/gen/templates/spec_relationship.tpl b/gen/templates/spec_relationship.tpl index 37be486..6d2a955 100644 --- a/gen/templates/spec_relationship.tpl +++ b/gen/templates/spec_relationship.tpl @@ -4,10 +4,10 @@ it(resourceType + '.##__OPERATION_NAME__##', async () => { const id = TestData.id const params = { fields: { ##__RELATIONSHIP_TYPE__##: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, '##__OPERATION_NAME__##') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, '##__OPERATION_NAME__##') + checkCommonParams(request, params) return interceptRequest() }) diff --git a/gen/templates/spec_trigger.tpl b/gen/templates/spec_trigger.tpl index b06ad85..f3614fe 100644 --- a/gen/templates/spec_trigger.tpl +++ b/gen/templates/spec_trigger.tpl @@ -8,10 +8,10 @@ it(resourceType + '.##__OPERATION_NAME__##', async () => { const attributes = { [triggerAttr]: triggerValue } const id = TestData.id - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('patch') - checkCommon(config, resourceType, id, currentAccessToken) - checkCommonData(config, resourceType, attributes, id) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('PATCH') + checkCommon(request, resourceType, id, currentAccessToken) + checkCommonData(request, resourceType, attributes, id) return interceptRequest() }) diff --git a/package.json b/package.json index dde37d9..3476324 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,9 @@ "javascript", "ecommerce", "jamstack", - "commercelayer" + "commercelayer", + "sdk", + "provisioning" ], "author": "Pierluigi Viti ", "license": "MIT", @@ -29,32 +31,27 @@ "lib/**/*" ], "engines": { - "node": ">=16 || ^14.17" - }, - "dependencies": { - "axios": "1.6.8" + "node": ">=20" }, "devDependencies": { - "@babel/preset-env": "^7.24.3", + "@babel/preset-env": "^7.24.4", "@babel/preset-typescript": "^7.24.1", "@commercelayer/eslint-config-ts": "1.4.5", - "@commercelayer/js-auth": "^5.2.1", + "@commercelayer/js-auth": "^6.0.0", "@semantic-release/changelog": "^6.0.3", "@semantic-release/git": "^10.0.1", "@types/debug": "^4.1.12", "@types/jest": "^29.5.12", - "@types/lodash": "^4.17.0", - "@types/node": "^20.11.30", + "@types/node": "^20.12.4", "dotenv": "^16.4.5", "eslint": "^8.57.0", - "inflector-js": "^1.0.1", "jest": "^29.7.0", "json-typescript": "^1.1.2", "jsonapi-typescript": "^0.1.3", - "lodash": "^4.17.21", - "semantic-release": "^23.0.6", + "lodash.isequal": "^4.5.0", + "semantic-release": "^23.0.7", "tsup": "^8.0.2", - "tsx": "^4.7.1", + "tsx": "^4.7.2", "typescript": "^5.4.3" }, "repository": "github:commercelayer/provisioning-sdk", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 112b8b5..445fb20 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,72 +7,61 @@ settings: overrides: ansi-regex: 5.0.1 -dependencies: - axios: - specifier: 1.6.8 - version: 1.6.8 - devDependencies: '@babel/preset-env': - specifier: ^7.24.3 - version: 7.24.3(@babel/core@7.24.3) + specifier: ^7.24.4 + version: 7.24.4(@babel/core@7.24.4) '@babel/preset-typescript': specifier: ^7.24.1 - version: 7.24.1(@babel/core@7.24.3) + version: 7.24.1(@babel/core@7.24.4) '@commercelayer/eslint-config-ts': specifier: 1.4.5 version: 1.4.5(eslint@8.57.0)(typescript@5.4.3) '@commercelayer/js-auth': - specifier: ^5.2.1 - version: 5.2.1 + specifier: ^6.0.0 + version: 6.0.0 '@semantic-release/changelog': specifier: ^6.0.3 - version: 6.0.3(semantic-release@23.0.6) + version: 6.0.3(semantic-release@23.0.7) '@semantic-release/git': specifier: ^10.0.1 - version: 10.0.1(semantic-release@23.0.6) + version: 10.0.1(semantic-release@23.0.7) '@types/debug': specifier: ^4.1.12 version: 4.1.12 '@types/jest': specifier: ^29.5.12 version: 29.5.12 - '@types/lodash': - specifier: ^4.17.0 - version: 4.17.0 '@types/node': - specifier: ^20.11.30 - version: 20.11.30 + specifier: ^20.12.4 + version: 20.12.4 dotenv: specifier: ^16.4.5 version: 16.4.5 eslint: specifier: ^8.57.0 version: 8.57.0 - inflector-js: - specifier: ^1.0.1 - version: 1.0.1 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@20.11.30) + version: 29.7.0(@types/node@20.12.4) json-typescript: specifier: ^1.1.2 version: 1.1.2 jsonapi-typescript: specifier: ^0.1.3 version: 0.1.3 - lodash: - specifier: ^4.17.21 - version: 4.17.21 + lodash.isequal: + specifier: ^4.5.0 + version: 4.5.0 semantic-release: - specifier: ^23.0.6 - version: 23.0.6(typescript@5.4.3) + specifier: ^23.0.7 + version: 23.0.7(typescript@5.4.3) tsup: specifier: ^8.0.2 version: 8.0.2(typescript@5.4.3) tsx: - specifier: ^4.7.1 - version: 4.7.1 + specifier: ^4.7.2 + version: 4.7.2 typescript: specifier: ^5.4.3 version: 5.4.3 @@ -100,22 +89,22 @@ packages: picocolors: 1.0.0 dev: true - /@babel/compat-data@7.24.1: - resolution: {integrity: sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA==} + /@babel/compat-data@7.24.4: + resolution: {integrity: sha512-vg8Gih2MLK+kOkHJp4gBEIkyaIi00jgWot2D9QOmmfLC8jINSOzmCLta6Bvz/JSBCqnegV0L80jhxkol5GWNfQ==} engines: {node: '>=6.9.0'} dev: true - /@babel/core@7.24.3: - resolution: {integrity: sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==} + /@babel/core@7.24.4: + resolution: {integrity: sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.24.2 - '@babel/generator': 7.24.1 + '@babel/generator': 7.24.4 '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3) - '@babel/helpers': 7.24.1 - '@babel/parser': 7.24.1 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.4) + '@babel/helpers': 7.24.4 + '@babel/parser': 7.24.4 '@babel/template': 7.24.0 '@babel/traverse': 7.24.1 '@babel/types': 7.24.0 @@ -128,8 +117,8 @@ packages: - supports-color dev: true - /@babel/generator@7.24.1: - resolution: {integrity: sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==} + /@babel/generator@7.24.4: + resolution: {integrity: sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.24.0 @@ -156,49 +145,49 @@ packages: resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/compat-data': 7.24.1 + '@babel/compat-data': 7.24.4 '@babel/helper-validator-option': 7.23.5 browserslist: 4.23.0 lru-cache: 5.1.1 semver: 6.3.1 dev: true - /@babel/helper-create-class-features-plugin@7.24.1(@babel/core@7.24.3): - resolution: {integrity: sha512-1yJa9dX9g//V6fDebXoEfEsxkZHk3Hcbm+zLhyu6qVgYFLvmTALTeV+jNU9e5RnYtioBrGEOdoI2joMSNQ/+aA==} + /@babel/helper-create-class-features-plugin@7.24.4(@babel/core@7.24.4): + resolution: {integrity: sha512-lG75yeuUSVu0pIcbhiYMXBXANHrpUPaOfu7ryAzskCgKUHuAxRQI5ssrtmF0X9UXldPlvT0XM/A4F44OXRt6iQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-annotate-as-pure': 7.22.5 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-function-name': 7.23.0 '@babel/helper-member-expression-to-functions': 7.23.0 '@babel/helper-optimise-call-expression': 7.22.5 - '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.3) + '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.4) '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 semver: 6.3.1 dev: true - /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.24.3): + /@babel/helper-create-regexp-features-plugin@7.22.15(@babel/core@7.24.4): resolution: {integrity: sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-annotate-as-pure': 7.22.5 regexpu-core: 5.3.2 semver: 6.3.1 dev: true - /@babel/helper-define-polyfill-provider@0.6.1(@babel/core@7.24.3): + /@babel/helper-define-polyfill-provider@0.6.1(@babel/core@7.24.4): resolution: {integrity: sha512-o7SDgTJuvx5vLKD6SFvkydkSMBvahDKGiNJzG22IZYXhiqoe9efY7zocICBgzHV4IRg5wdgl2nEL/tulKIEIbA==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-compilation-targets': 7.23.6 '@babel/helper-plugin-utils': 7.24.0 debug: 4.3.4 @@ -242,13 +231,13 @@ packages: '@babel/types': 7.24.0 dev: true - /@babel/helper-module-transforms@7.23.3(@babel/core@7.24.3): + /@babel/helper-module-transforms@7.23.3(@babel/core@7.24.4): resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-module-imports': 7.24.3 '@babel/helper-simple-access': 7.22.5 @@ -268,25 +257,25 @@ packages: engines: {node: '>=6.9.0'} dev: true - /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.24.3): + /@babel/helper-remap-async-to-generator@7.22.20(@babel/core@7.24.4): resolution: {integrity: sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-annotate-as-pure': 7.22.5 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-wrap-function': 7.22.20 dev: true - /@babel/helper-replace-supers@7.24.1(@babel/core@7.24.3): + /@babel/helper-replace-supers@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-QCR1UqC9BzG5vZl8BMicmZ28RuUBnHhAMddD8yHFHDRH9lLTZ9uUPehX8ctVPT8l0TKblJidqcgUUKGVrePleQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-member-expression-to-functions': 7.23.0 '@babel/helper-optimise-call-expression': 7.22.5 @@ -337,8 +326,8 @@ packages: '@babel/types': 7.24.0 dev: true - /@babel/helpers@7.24.1: - resolution: {integrity: sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==} + /@babel/helpers@7.24.4: + resolution: {integrity: sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==} engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.24.0 @@ -358,920 +347,932 @@ packages: picocolors: 1.0.0 dev: true - /@babel/parser@7.24.1: - resolution: {integrity: sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==} + /@babel/parser@7.24.4: + resolution: {integrity: sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==} engines: {node: '>=6.0.0'} hasBin: true dependencies: '@babel/types': 7.24.0 dev: true - /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.24.1(@babel/core@7.24.3): + /@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.24.4(@babel/core@7.24.4): + resolution: {integrity: sha512-qpl6vOOEEzTLLcsuqYYo8yDtrTocmu2xkGvgNebvPjT9DTtfFYGmgDqY+rBYXNlqL4s9qLDn6xkrJv4RxAPiTA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.4 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-y4HqEnkelJIOQGd+3g1bTeKsA5c6qM7eOn7VggGVbBc0y8MLSKHacwcIE2PplNlQSj0PqS9rrXL/nkPVK+kUNg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.1(@babel/core@7.24.3): + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-Hj791Ii4ci8HqnaKHAlLNs+zaLXb0EzSDhiAWp5VNlyvCNymYfacs64pxTxbH1znW/NcArSmwpmG9IKE/TUVVQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.13.0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/plugin-transform-optional-chaining': 7.24.1(@babel/core@7.24.3) + '@babel/plugin-transform-optional-chaining': 7.24.1(@babel/core@7.24.4) dev: true - /@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.24.1(@babel/core@7.24.3): + /@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-m9m/fXsXLiHfwdgydIFnpk+7jlVbnvlK5B2EKiPdLUb6WX654ZaaEWJUjk8TftRbZpK0XibovlLWX4KIZhV6jw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.3): + /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.4): resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 dev: true - /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.3): + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.4): resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.3): + /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.4): resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.3): + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.4): resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.3): + /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.4): resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.24.3): + /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.24.4): resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.3): + /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.4): resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-import-assertions@7.24.1(@babel/core@7.24.3): + /@babel/plugin-syntax-import-assertions@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-IuwnI5XnuF189t91XbxmXeCDz3qs6iDRO7GJ++wcfgeXNs/8FmIlKcpDSXNVyuLQxlwvskmI3Ct73wUODkJBlQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-import-attributes@7.24.1(@babel/core@7.24.3): + /@babel/plugin-syntax-import-attributes@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-zhQTMH0X2nVLnb04tz+s7AMuasX8U0FnpE+nHTOhSOINjWMnopoZTxtIKsd45n4GQ/HIZLyfIpoul8e2m0DnRA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.3): + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.4): resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.3): + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.4): resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-jsx@7.24.1(@babel/core@7.24.3): + /@babel/plugin-syntax-jsx@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.3): + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.4): resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.3): + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.4): resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.3): + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.4): resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.3): + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.4): resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.3): + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.4): resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.3): + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.4): resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.24.3): + /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.24.4): resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.3): + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.4): resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-typescript@7.24.1(@babel/core@7.24.3): + /@babel/plugin-syntax-typescript@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.24.3): + /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.24.4): resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.3 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.3) + '@babel/core': 7.24.4 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.4) '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-arrow-functions@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-arrow-functions@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-ngT/3NkRhsaep9ck9uj2Xhv9+xB1zShY3tM3g6om4xxCELwCDN4g4Aq5dRn48+0hasAql7s2hdBOysCfNpr4fw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-async-generator-functions@7.24.3(@babel/core@7.24.3): + /@babel/plugin-transform-async-generator-functions@7.24.3(@babel/core@7.24.4): resolution: {integrity: sha512-Qe26CMYVjpQxJ8zxM1340JFNjZaF+ISWpr1Kt/jGo+ZTUzKkfw/pphEWbRCb+lmSM6k/TOgfYLvmbHkUQ0asIg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-plugin-utils': 7.24.0 - '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.3) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.3) + '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.4) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.4) dev: true - /@babel/plugin-transform-async-to-generator@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-async-to-generator@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-AawPptitRXp1y0n4ilKcGbRYWfbbzFWz2NqNu7dacYDtFtz0CMjG64b3LQsb3KIgnf4/obcUL78hfaOS7iCUfw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-module-imports': 7.24.3 '@babel/helper-plugin-utils': 7.24.0 - '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.3) + '@babel/helper-remap-async-to-generator': 7.22.20(@babel/core@7.24.4) dev: true - /@babel/plugin-transform-block-scoped-functions@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-block-scoped-functions@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-TWWC18OShZutrv9C6mye1xwtam+uNi2bnTOCBUd5sZxyHOiWbU6ztSROofIMrK84uweEZC219POICK/sTYwfgg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-block-scoping@7.24.1(@babel/core@7.24.3): - resolution: {integrity: sha512-h71T2QQvDgM2SmT29UYU6ozjMlAt7s7CSs5Hvy8f8cf/GM/Z4a2zMfN+fjVGaieeCrXR3EdQl6C4gQG+OgmbKw==} + /@babel/plugin-transform-block-scoping@7.24.4(@babel/core@7.24.4): + resolution: {integrity: sha512-nIFUZIpGKDf9O9ttyRXpHFpKC+X3Y5mtshZONuEUYBomAKoM4y029Jr+uB1bHGPhNmK8YXHevDtKDOLmtRrp6g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-class-properties@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-class-properties@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-OMLCXi0NqvJfORTaPQBwqLXHhb93wkBKZ4aNwMl6WtehO7ar+cmp+89iPEQPqxAnxsOKTaMcs3POz3rKayJ72g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 - '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.3) + '@babel/core': 7.24.4 + '@babel/helper-create-class-features-plugin': 7.24.4(@babel/core@7.24.4) '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-class-static-block@7.24.1(@babel/core@7.24.3): - resolution: {integrity: sha512-FUHlKCn6J3ERiu8Dv+4eoz7w8+kFLSyeVG4vDAikwADGjUCoHw/JHokyGtr8OR4UjpwPVivyF+h8Q5iv/JmrtA==} + /@babel/plugin-transform-class-static-block@7.24.4(@babel/core@7.24.4): + resolution: {integrity: sha512-B8q7Pz870Hz/q9UgP8InNpY01CSLDSCyqX7zcRuv3FcPl87A2G17lASroHWaCtbdIcbYzOZ7kWmXFKbijMSmFg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 dependencies: - '@babel/core': 7.24.3 - '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.3) + '@babel/core': 7.24.4 + '@babel/helper-create-class-features-plugin': 7.24.4(@babel/core@7.24.4) '@babel/helper-plugin-utils': 7.24.0 - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.3) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.4) dev: true - /@babel/plugin-transform-classes@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-classes@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-annotate-as-pure': 7.22.5 '@babel/helper-compilation-targets': 7.23.6 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-function-name': 7.23.0 '@babel/helper-plugin-utils': 7.24.0 - '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.3) + '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.4) '@babel/helper-split-export-declaration': 7.22.6 globals: 11.12.0 dev: true - /@babel/plugin-transform-computed-properties@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-computed-properties@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-5pJGVIUfJpOS+pAqBQd+QMaTD2vCL/HcePooON6pDpHgRp4gNRmzyHTPIkXntwKsq3ayUFVfJaIKPw2pOkOcTw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 '@babel/template': 7.24.0 dev: true - /@babel/plugin-transform-destructuring@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-destructuring@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-dotall-regex@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-dotall-regex@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-p7uUxgSoZwZ2lPNMzUkqCts3xlp8n+o05ikjy7gbtFJSt9gdU88jAmtfmOxHM14noQXBxfgzf2yRWECiNVhTCw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.3) + '@babel/core': 7.24.4 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.4) '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-duplicate-keys@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-duplicate-keys@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-msyzuUnvsjsaSaocV6L7ErfNsa5nDWL1XKNnDePLgmz+WdU4w/J8+AxBMrWfi9m4IxfL5sZQKUPQKDQeeAT6lA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-dynamic-import@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-dynamic-import@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-av2gdSTyXcJVdI+8aFZsCAtR29xJt0S5tas+Ef8NvBNmD1a+N/3ecMLeMBgfcK+xzsjdLDT6oHt+DFPyeqUbDA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.4) dev: true - /@babel/plugin-transform-exponentiation-operator@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-exponentiation-operator@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-U1yX13dVBSwS23DEAqU+Z/PkwE9/m7QQy8Y9/+Tdb8UWYaGNDYwTLi19wqIAiROr8sXVum9A/rtiH5H0boUcTw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.15 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-export-namespace-from@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-export-namespace-from@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-Ft38m/KFOyzKw2UaJFkWG9QnHPG/Q/2SkOrRk4pNBPg5IPZ+dOxcmkK5IyuBcxiNPyyYowPGUReyBvrvZs7IlQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.4) dev: true - /@babel/plugin-transform-for-of@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-for-of@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-OxBdcnF04bpdQdR3i4giHZNZQn7cm8RQKcSwA17wAAqEELo1ZOwp5FFgeptWUQXFyT9kwHo10aqqauYkRZPCAg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 dev: true - /@babel/plugin-transform-function-name@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-function-name@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-BXmDZpPlh7jwicKArQASrj8n22/w6iymRnvHYYd2zO30DbE277JO20/7yXJT3QxDPtiQiOxQBbZH4TpivNXIxA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-compilation-targets': 7.23.6 '@babel/helper-function-name': 7.23.0 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-json-strings@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-json-strings@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-U7RMFmRvoasscrIFy5xA4gIp8iWnWubnKkKuUGJjsuOH7GfbMkB+XZzeslx2kLdEGdOJDamEmCqOks6e8nv8DQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.4) dev: true - /@babel/plugin-transform-literals@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-literals@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-zn9pwz8U7nCqOYIiBaOxoQOtYmMODXTJnkxG4AtX8fPmnCRYWBOHD0qcpwS9e2VDSp1zNJYpdnFMIKb8jmwu6g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-logical-assignment-operators@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-logical-assignment-operators@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-OhN6J4Bpz+hIBqItTeWJujDOfNP+unqv/NJgyhlpSqgBTPm37KkMmZV6SYcOj+pnDbdcl1qRGV/ZiIjX9Iy34w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.3) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.4) dev: true - /@babel/plugin-transform-member-expression-literals@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-member-expression-literals@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-4ojai0KysTWXzHseJKa1XPNXKRbuUrhkOPY4rEGeR+7ChlJVKxFa3H3Bz+7tWaGKgJAXUWKOGmltN+u9B3+CVg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-modules-amd@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-modules-amd@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-lAxNHi4HVtjnHd5Rxg3D5t99Xm6H7b04hUS7EHIXcUl2EV4yl1gWdqZrNzXnSrHveL9qMdbODlLF55mvgjAfaQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3) + '@babel/core': 7.24.4 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.4) '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-modules-commonjs@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-modules-commonjs@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-szog8fFTUxBfw0b98gEWPaEqF42ZUD/T3bkynW/wtgx2p/XCP55WEsb+VosKceRSd6njipdZvNogqdtI4Q0chw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3) + '@babel/core': 7.24.4 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.4) '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-simple-access': 7.22.5 dev: true - /@babel/plugin-transform-modules-systemjs@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-modules-systemjs@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-mqQ3Zh9vFO1Tpmlt8QPnbwGHzNz3lpNEMxQb1kAemn/erstyqw1r9KeOlOfo3y6xAnFEcOv2tSyrXfmMk+/YZA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3) + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.4) '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-validator-identifier': 7.22.20 dev: true - /@babel/plugin-transform-modules-umd@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-modules-umd@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-tuA3lpPj+5ITfcCluy6nWonSL7RvaG0AOTeAuvXqEKS34lnLzXpDb0dcP6K8jD0zWZFNDVly90AGFJPnm4fOYg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3) + '@babel/core': 7.24.4 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.4) '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.24.3): + /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.24.4): resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.3 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.3) + '@babel/core': 7.24.4 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.4) '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-new-target@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-new-target@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-/rurytBM34hYy0HKZQyA0nHbQgQNFm4Q/BOc9Hflxi2X3twRof7NaE5W46j4kQitm7SvACVRXsa6N/tSZxvPug==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-nullish-coalescing-operator@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-nullish-coalescing-operator@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-iQ+caew8wRrhCikO5DrUYx0mrmdhkaELgFa+7baMcVuhxIkN7oxt06CZ51D65ugIb1UWRQ8oQe+HXAVM6qHFjw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.4) dev: true - /@babel/plugin-transform-numeric-separator@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-numeric-separator@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-7GAsGlK4cNL2OExJH1DzmDeKnRv/LXq0eLUSvudrehVA5Rgg4bIrqEUW29FbKMBRT0ztSqisv7kjP+XIC4ZMNw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.3) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.4) dev: true - /@babel/plugin-transform-object-rest-spread@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-object-rest-spread@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-compilation-targets': 7.23.6 '@babel/helper-plugin-utils': 7.24.0 - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.3) - '@babel/plugin-transform-parameters': 7.24.1(@babel/core@7.24.3) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.4) + '@babel/plugin-transform-parameters': 7.24.1(@babel/core@7.24.4) dev: true - /@babel/plugin-transform-object-super@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-object-super@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-oKJqR3TeI5hSLRxudMjFQ9re9fBVUU0GICqM3J1mi8MqlhVr6hC/ZN4ttAyMuQR6EZZIY6h/exe5swqGNNIkWQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 - '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.3) + '@babel/helper-replace-supers': 7.24.1(@babel/core@7.24.4) dev: true - /@babel/plugin-transform-optional-catch-binding@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-optional-catch-binding@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-oBTH7oURV4Y+3EUrf6cWn1OHio3qG/PVwO5J03iSJmBg6m2EhKjkAu/xuaXaYwWW9miYtvbWv4LNf0AmR43LUA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.4) dev: true - /@babel/plugin-transform-optional-chaining@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-optional-chaining@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.4) dev: true - /@babel/plugin-transform-parameters@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-parameters@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-private-methods@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-private-methods@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-tGvisebwBO5em4PaYNqt4fkw56K2VALsAbAakY0FjTYqJp7gfdrgr7YX76Or8/cpik0W6+tj3rZ0uHU9Oil4tw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 - '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.3) + '@babel/core': 7.24.4 + '@babel/helper-create-class-features-plugin': 7.24.4(@babel/core@7.24.4) '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-private-property-in-object@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-private-property-in-object@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.3) + '@babel/helper-create-class-features-plugin': 7.24.4(@babel/core@7.24.4) '@babel/helper-plugin-utils': 7.24.0 - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.3) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.4) dev: true - /@babel/plugin-transform-property-literals@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-property-literals@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-LetvD7CrHmEx0G442gOomRr66d7q8HzzGGr4PMHGr+5YIm6++Yke+jxj246rpvsbyhJwCLxcTn6zW1P1BSenqA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-regenerator@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-regenerator@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-sJwZBCzIBE4t+5Q4IGLaaun5ExVMRY0lYwos/jNecjMrVCygCdph3IKv0tkP5Fc87e/1+bebAmEAGBfnRD+cnw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 regenerator-transform: 0.15.2 dev: true - /@babel/plugin-transform-reserved-words@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-reserved-words@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-JAclqStUfIwKN15HrsQADFgeZt+wexNQ0uLhuqvqAUFoqPMjEcFCYZBhq0LUdz6dZK/mD+rErhW71fbx8RYElg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-shorthand-properties@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-shorthand-properties@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-LyjVB1nsJ6gTTUKRjRWx9C1s9hE7dLfP/knKdrfeH9UPtAGjYGgxIbFfx7xyLIEWs7Xe1Gnf8EWiUqfjLhInZA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-spread@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-spread@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-KjmcIM+fxgY+KxPVbjelJC6hrH1CgtPmTvdXAfn3/a9CnWGSTY7nH4zm5+cjmWJybdcPSsD0++QssDsjcpe47g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 dev: true - /@babel/plugin-transform-sticky-regex@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-sticky-regex@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-9v0f1bRXgPVcPrngOQvLXeGNNVLc8UjMVfebo9ka0WF3/7+aVUHmaJVT3sa0XCzEFioPfPHZiOcYG9qOsH63cw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-template-literals@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-template-literals@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-WRkhROsNzriarqECASCNu/nojeXCDTE/F2HmRgOzi7NGvyfYGq1NEjKBK3ckLfRgGc6/lPAqP0vDOSw3YtG34g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-typeof-symbol@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-typeof-symbol@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-typescript@7.24.1(@babel/core@7.24.3): - resolution: {integrity: sha512-liYSESjX2fZ7JyBFkYG78nfvHlMKE6IpNdTVnxmlYUR+j5ZLsitFbaAE+eJSK2zPPkNWNw4mXL51rQ8WrvdK0w==} + /@babel/plugin-transform-typescript@7.24.4(@babel/core@7.24.4): + resolution: {integrity: sha512-79t3CQ8+oBGk/80SQ8MN3Bs3obf83zJ0YZjDmDaEZN8MqhMI760apl5z6a20kFeMXBwJX99VpKT8CKxEBp5H1g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-create-class-features-plugin': 7.24.1(@babel/core@7.24.3) + '@babel/helper-create-class-features-plugin': 7.24.4(@babel/core@7.24.4) '@babel/helper-plugin-utils': 7.24.0 - '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.3) + '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.4) dev: true - /@babel/plugin-transform-unicode-escapes@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-unicode-escapes@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-RlkVIcWT4TLI96zM660S877E7beKlQw7Ig+wqkKBiWfj0zH5Q4h50q6er4wzZKRNSYpfo6ILJ+hrJAGSX2qcNw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-unicode-property-regex@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-unicode-property-regex@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-Ss4VvlfYV5huWApFsF8/Sq0oXnGO+jB+rijFEFugTd3cwSObUSnUi88djgR5528Csl0uKlrI331kRqe56Ov2Ng==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.3) + '@babel/core': 7.24.4 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.4) '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-unicode-regex@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-unicode-regex@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-2A/94wgZgxfTsiLaQ2E36XAOdcZmGAaEEgVmxQWwZXWkGhvoHbaqXcKnU8zny4ycpu3vNqg0L/PcCiYtHtA13g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.3) + '@babel/core': 7.24.4 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.4) '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-transform-unicode-sets-regex@7.24.1(@babel/core@7.24.3): + /@babel/plugin-transform-unicode-sets-regex@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-fqj4WuzzS+ukpgerpAoOnMfQXwUHFxXUZUE84oL2Kao2N8uSlvcpnAidKASgsNgzZHBsHWvcm8s9FPWUhAb8fA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.3 - '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.3) + '@babel/core': 7.24.4 + '@babel/helper-create-regexp-features-plugin': 7.22.15(@babel/core@7.24.4) '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/preset-env@7.24.3(@babel/core@7.24.3): - resolution: {integrity: sha512-fSk430k5c2ff8536JcPvPWK4tZDwehWLGlBp0wrsBUjZVdeQV6lePbwKWZaZfK2vnh/1kQX1PzAJWsnBmVgGJA==} + /@babel/preset-env@7.24.4(@babel/core@7.24.4): + resolution: {integrity: sha512-7Kl6cSmYkak0FK/FXjSEnLJ1N9T/WA2RkMhu17gZ/dsxKJUuTYNIylahPTzqpLyJN4WhDif8X0XK1R8Wsguo/A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/compat-data': 7.24.1 - '@babel/core': 7.24.3 + '@babel/compat-data': 7.24.4 + '@babel/core': 7.24.4 '@babel/helper-compilation-targets': 7.23.6 '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-validator-option': 7.23.5 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.3) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.3) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.3) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.3) - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.3) - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.3) - '@babel/plugin-syntax-import-assertions': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-syntax-import-attributes': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.3) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.3) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.3) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.3) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.3) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.3) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.3) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.3) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.3) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.3) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.24.3) - '@babel/plugin-transform-arrow-functions': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-async-generator-functions': 7.24.3(@babel/core@7.24.3) - '@babel/plugin-transform-async-to-generator': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-block-scoped-functions': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-block-scoping': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-class-properties': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-class-static-block': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-classes': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-computed-properties': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-destructuring': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-dotall-regex': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-duplicate-keys': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-dynamic-import': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-exponentiation-operator': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-export-namespace-from': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-for-of': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-function-name': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-json-strings': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-literals': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-logical-assignment-operators': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-member-expression-literals': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-modules-amd': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-modules-commonjs': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-modules-systemjs': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-modules-umd': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.24.3) - '@babel/plugin-transform-new-target': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-nullish-coalescing-operator': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-numeric-separator': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-object-rest-spread': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-object-super': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-optional-catch-binding': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-optional-chaining': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-parameters': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-private-methods': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-private-property-in-object': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-property-literals': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-regenerator': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-reserved-words': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-shorthand-properties': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-spread': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-sticky-regex': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-template-literals': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-typeof-symbol': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-unicode-escapes': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-unicode-property-regex': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-unicode-regex': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-unicode-sets-regex': 7.24.1(@babel/core@7.24.3) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.24.3) - babel-plugin-polyfill-corejs2: 0.4.10(@babel/core@7.24.3) - babel-plugin-polyfill-corejs3: 0.10.4(@babel/core@7.24.3) - babel-plugin-polyfill-regenerator: 0.6.1(@babel/core@7.24.3) + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.24.4(@babel/core@7.24.4) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.4) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.4) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.4) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.4) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.4) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.4) + '@babel/plugin-syntax-import-assertions': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-syntax-import-attributes': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.4) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.4) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.4) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.4) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.4) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.4) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.4) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.4) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.4) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.4) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.24.4) + '@babel/plugin-transform-arrow-functions': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-async-generator-functions': 7.24.3(@babel/core@7.24.4) + '@babel/plugin-transform-async-to-generator': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-block-scoped-functions': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-block-scoping': 7.24.4(@babel/core@7.24.4) + '@babel/plugin-transform-class-properties': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-class-static-block': 7.24.4(@babel/core@7.24.4) + '@babel/plugin-transform-classes': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-computed-properties': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-destructuring': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-dotall-regex': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-duplicate-keys': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-dynamic-import': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-exponentiation-operator': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-export-namespace-from': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-for-of': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-function-name': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-json-strings': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-literals': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-logical-assignment-operators': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-member-expression-literals': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-modules-amd': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-modules-commonjs': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-modules-systemjs': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-modules-umd': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.24.4) + '@babel/plugin-transform-new-target': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-nullish-coalescing-operator': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-numeric-separator': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-object-rest-spread': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-object-super': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-optional-catch-binding': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-optional-chaining': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-parameters': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-private-methods': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-private-property-in-object': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-property-literals': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-regenerator': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-reserved-words': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-shorthand-properties': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-spread': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-sticky-regex': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-template-literals': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-typeof-symbol': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-unicode-escapes': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-unicode-property-regex': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-unicode-regex': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-unicode-sets-regex': 7.24.1(@babel/core@7.24.4) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.24.4) + babel-plugin-polyfill-corejs2: 0.4.10(@babel/core@7.24.4) + babel-plugin-polyfill-corejs3: 0.10.4(@babel/core@7.24.4) + babel-plugin-polyfill-regenerator: 0.6.1(@babel/core@7.24.4) core-js-compat: 3.36.1 semver: 6.3.1 transitivePeerDependencies: - supports-color dev: true - /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.24.3): + /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.24.4): resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} peerDependencies: '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 '@babel/types': 7.24.0 esutils: 2.0.3 dev: true - /@babel/preset-typescript@7.24.1(@babel/core@7.24.3): + /@babel/preset-typescript@7.24.1(@babel/core@7.24.4): resolution: {integrity: sha512-1DBaMmRDpuYQBPWD8Pf/WEwCrtgRHxsZnP4mIy9G/X+hFfbI47Q2G4t1Paakld84+qsk2fSsUPMKg71jkoOOaQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@babel/helper-plugin-utils': 7.24.0 '@babel/helper-validator-option': 7.23.5 - '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-modules-commonjs': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-transform-typescript': 7.24.1(@babel/core@7.24.3) + '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-modules-commonjs': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-transform-typescript': 7.24.4(@babel/core@7.24.4) dev: true /@babel/regjsgen@0.8.0: resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} dev: true - /@babel/runtime@7.24.1: - resolution: {integrity: sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==} + /@babel/runtime@7.24.4: + resolution: {integrity: sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==} engines: {node: '>=6.9.0'} dependencies: regenerator-runtime: 0.14.1 @@ -1282,7 +1283,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.24.2 - '@babel/parser': 7.24.1 + '@babel/parser': 7.24.4 '@babel/types': 7.24.0 dev: true @@ -1291,12 +1292,12 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.24.2 - '@babel/generator': 7.24.1 + '@babel/generator': 7.24.4 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-function-name': 7.23.0 '@babel/helper-hoist-variables': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.24.1 + '@babel/parser': 7.24.4 '@babel/types': 7.24.0 debug: 4.3.4 globals: 11.12.0 @@ -1330,12 +1331,12 @@ packages: eslint: '>=8.0' typescript: '>=5.0' dependencies: - '@typescript-eslint/eslint-plugin': 7.3.1(@typescript-eslint/parser@7.3.1)(eslint@8.57.0)(typescript@5.4.3) - '@typescript-eslint/parser': 7.3.1(eslint@8.57.0)(typescript@5.4.3) + '@typescript-eslint/eslint-plugin': 7.5.0(@typescript-eslint/parser@7.5.0)(eslint@8.57.0)(typescript@5.4.3) + '@typescript-eslint/parser': 7.5.0(eslint@8.57.0)(typescript@5.4.3) eslint: 8.57.0 - eslint-config-love: 43.1.0(@typescript-eslint/eslint-plugin@7.3.1)(eslint-plugin-import@2.29.1)(eslint-plugin-n@16.6.2)(eslint-plugin-promise@6.1.1)(eslint@8.57.0)(typescript@5.4.3) + eslint-config-love: 43.1.0(@typescript-eslint/eslint-plugin@7.5.0)(eslint-plugin-import@2.29.1)(eslint-plugin-n@16.6.2)(eslint-plugin-promise@6.1.1)(eslint@8.57.0)(typescript@5.4.3) eslint-config-prettier: 9.1.0(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.3.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.5.0)(eslint@8.57.0) eslint-plugin-n: 16.6.2(eslint@8.57.0) eslint-plugin-prettier: 5.1.3(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.2.5) eslint-plugin-promise: 6.1.1(eslint@8.57.0) @@ -1348,8 +1349,8 @@ packages: - supports-color dev: true - /@commercelayer/js-auth@5.2.1: - resolution: {integrity: sha512-44PMO+ug/ufDToerb+R6RBngGqFD/yjU06Z3Gj7IGWj4eVmtPhlAR7ynF6TRClAWgI0mZ2bXYx5geXWRGz/jLw==} + /@commercelayer/js-auth@6.0.0: + resolution: {integrity: sha512-RT7Kpi+lz0uJngyzuuz0g9TeAJvAlOoFe+8r8W/BPrqGZWwRgfqhcW715bf8qaaojJYTkX3Y4YSvvWUFDy3+dg==} engines: {node: '>=18.0.0'} dev: true @@ -1601,7 +1602,7 @@ packages: resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} dependencies: - '@humanwhocodes/object-schema': 2.0.2 + '@humanwhocodes/object-schema': 2.0.3 debug: 4.3.4 minimatch: 3.1.2 transitivePeerDependencies: @@ -1613,8 +1614,8 @@ packages: engines: {node: '>=12.22'} dev: true - /@humanwhocodes/object-schema@2.0.2: - resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} + /@humanwhocodes/object-schema@2.0.3: + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} dev: true /@isaacs/cliui@8.0.2: @@ -1650,7 +1651,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.30 + '@types/node': 20.12.4 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -1671,14 +1672,14 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.30 + '@types/node': 20.12.4 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.11.30) + jest-config: 29.7.0(@types/node@20.12.4) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -1706,7 +1707,7 @@ packages: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.30 + '@types/node': 20.12.4 jest-mock: 29.7.0 dev: true @@ -1733,7 +1734,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.11.30 + '@types/node': 20.12.4 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -1766,7 +1767,7 @@ packages: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 20.11.30 + '@types/node': 20.12.4 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -1828,7 +1829,7 @@ packages: resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 babel-plugin-istanbul: 6.1.1 @@ -1854,7 +1855,7 @@ packages: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 20.11.30 + '@types/node': 20.12.4 '@types/yargs': 17.0.32 chalk: 4.1.2 dev: true @@ -1910,38 +1911,38 @@ packages: fastq: 1.17.1 dev: true - /@octokit/auth-token@5.0.1: - resolution: {integrity: sha512-RTmWsLfig8SBoiSdgvCht4BXl1CHU89Co5xiQ5JF19my/sIRDFCQ1RPrmK0exgqUZuNm39C/bV8+/83+MJEjGg==} + /@octokit/auth-token@5.1.0: + resolution: {integrity: sha512-JH+5PhVMjpbBuKlykiseCHa2uZdEd8Qm/N9Kpqncx4o/wkGF38gqVjIP2gZqfaP3nxFZPpg0FwGClKzBi6nS2g==} engines: {node: '>= 18'} dev: true - /@octokit/core@6.0.1: - resolution: {integrity: sha512-MIpPQXu8Y8GjHwXM81JLveiV+DHJZtLMcB5nKekBGOl3iAtk0HT3i12Xl8Biybu+bCS1+k4qbuKEq5d0RxNRnQ==} + /@octokit/core@6.1.1: + resolution: {integrity: sha512-uVypPdnZV7YoEa69Ky2kTSw3neFLGT0PZ54OwUMDph7w6TmhF0ZnoVcvb/kYnjDHCFo2mfoeRDYifLKhLNasUg==} engines: {node: '>= 18'} dependencies: - '@octokit/auth-token': 5.0.1 - '@octokit/graphql': 8.0.1 + '@octokit/auth-token': 5.1.0 + '@octokit/graphql': 8.1.0 '@octokit/request': 9.0.1 - '@octokit/request-error': 6.0.2 - '@octokit/types': 12.6.0 + '@octokit/request-error': 6.1.0 + '@octokit/types': 13.0.0 before-after-hook: 3.0.2 universal-user-agent: 7.0.2 dev: true - /@octokit/endpoint@10.0.0: - resolution: {integrity: sha512-emBcNDxBdC1y3+knJonS5zhUB/CG6TihubxM2U1/pG/Z1y3a4oV0Gzz3lmkCvWWQI6h3tqBAX9MgCBFp+M68Jw==} + /@octokit/endpoint@10.1.0: + resolution: {integrity: sha512-ogZ5uLMeGBZUzS32fNt9j+dNw3kkEn5CSw4CVkN1EvCNdFYWrQ5diQR6Hh52VrPR0oayIoYTqQFL/l8RqkV0qw==} engines: {node: '>= 18'} dependencies: - '@octokit/types': 12.6.0 + '@octokit/types': 13.0.0 universal-user-agent: 7.0.2 dev: true - /@octokit/graphql@8.0.1: - resolution: {integrity: sha512-lLDb6LhC1gBj2CxEDa5Xk10+H/boonhs+3Mi6jpRyetskDKNHe6crMeKmUE2efoLofMP8ruannLlCUgpTFmVzQ==} + /@octokit/graphql@8.1.0: + resolution: {integrity: sha512-XDvj6GcUnQYgbCLXElt3vZDzNIPGvGiwxQO2XzsvfVUjebGh0E5eCD/1My9zUGSNKaGVZitVuO8LMziGmoFryg==} engines: {node: '>= 18'} dependencies: '@octokit/request': 9.0.1 - '@octokit/types': 12.6.0 + '@octokit/types': 13.0.0 universal-user-agent: 7.0.2 dev: true @@ -1949,52 +1950,56 @@ packages: resolution: {integrity: sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==} dev: true - /@octokit/plugin-paginate-rest@10.0.0(@octokit/core@6.0.1): + /@octokit/openapi-types@21.2.0: + resolution: {integrity: sha512-xx+Xd6I7rYvul/hgUDqv6TeGX0IOGnhSg9IOeYgd/uI7IAqUy6DE2B6Ipv2M4mWoxaMcWjIzgTIcv8pMO3F3vw==} + dev: true + + /@octokit/plugin-paginate-rest@10.0.0(@octokit/core@6.1.1): resolution: {integrity: sha512-G1Z67qOiFneKDJyMafHQkWnKm1kU3FfbRZLzxgsFg4dOa3pRNdABbdk+xo/oev6P88lnbt7GKdBNB6dJZuPphA==} engines: {node: '>= 18'} peerDependencies: '@octokit/core': '>=6' dependencies: - '@octokit/core': 6.0.1 + '@octokit/core': 6.1.1 '@octokit/types': 12.6.0 dev: true - /@octokit/plugin-retry@7.0.3(@octokit/core@6.0.1): - resolution: {integrity: sha512-T9l5Z7XnDZ7dkyNmhJPSUq0YjbqUT/xn4yQbhcSuv4WGC/LqM73/mKwkl68VDPoLw20e8oz4L7qQopWt9v6sow==} + /@octokit/plugin-retry@7.1.0(@octokit/core@6.1.1): + resolution: {integrity: sha512-6mc4xNtT6eoDBGrJJn0sFALUmIba2f7Wx+G8XV9GkBLcyX5PogBdx2mDMW5yPPqSD/y23tYagkjOLX9sT7O6jA==} engines: {node: '>= 18'} peerDependencies: '@octokit/core': '>=6' dependencies: - '@octokit/core': 6.0.1 - '@octokit/request-error': 6.0.2 - '@octokit/types': 12.6.0 + '@octokit/core': 6.1.1 + '@octokit/request-error': 6.1.0 + '@octokit/types': 13.0.0 bottleneck: 2.19.5 dev: true - /@octokit/plugin-throttling@9.0.3(@octokit/core@6.0.1): - resolution: {integrity: sha512-DReKamrLBJOzld73dmmxV2H137QKJfsxszAczEZXeAJQ/Po6bzQacKajPdodA6T1jfmP9+waImus+d/R2j+R7Q==} + /@octokit/plugin-throttling@9.1.0(@octokit/core@6.1.1): + resolution: {integrity: sha512-16lDMMhChavhvXKr2zRK7sD+hTpuVm697xZNf1a0C/MFRZU8CFkrNJEYX7Fqo2dc44lISp7V5Vm0sgJIx2bRkw==} engines: {node: '>= 18'} peerDependencies: '@octokit/core': ^6.0.0 dependencies: - '@octokit/core': 6.0.1 - '@octokit/types': 12.6.0 + '@octokit/core': 6.1.1 + '@octokit/types': 13.0.0 bottleneck: 2.19.5 dev: true - /@octokit/request-error@6.0.2: - resolution: {integrity: sha512-WtRVpoHcNXs84+s9s/wqfHaxM68NGMg8Av7h59B50OVO0PwwMx+2GgQ/OliUd0iQBSNWgR6N8afi/KjSHbXHWw==} + /@octokit/request-error@6.1.0: + resolution: {integrity: sha512-xcLJv4IgfWIOEEVZwfhUN3yHNWJL0AMw1J1Ba8BofM9RdDTbapg6MO4zNxlPS4XXX9aAIsbDRa47K57EhgeVAw==} engines: {node: '>= 18'} dependencies: - '@octokit/types': 12.6.0 + '@octokit/types': 13.0.0 dev: true /@octokit/request@9.0.1: resolution: {integrity: sha512-kL+cAcbSl3dctYLuJmLfx6Iku2MXXy0jszhaEIjQNaCp4zjHXrhVAHeuaRdNvJjW9qjl3u1MJ72+OuBP0YW/pg==} engines: {node: '>= 18'} dependencies: - '@octokit/endpoint': 10.0.0 - '@octokit/request-error': 6.0.2 + '@octokit/endpoint': 10.1.0 + '@octokit/request-error': 6.1.0 '@octokit/types': 12.6.0 universal-user-agent: 7.0.2 dev: true @@ -2005,6 +2010,12 @@ packages: '@octokit/openapi-types': 20.0.0 dev: true + /@octokit/types@13.0.0: + resolution: {integrity: sha512-jSOgEoFZvjg78txlb7cuRTAEvyyQkIEB4Nujg5ZN7E1xaICsr8A0X045Nwb1wUWNrBUHBHZNtcsDIhk8d8ipCw==} + dependencies: + '@octokit/openapi-types': 21.2.0 + dev: true + /@pkgjs/parseargs@0.11.0: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -2038,111 +2049,127 @@ packages: config-chain: 1.1.13 dev: true - /@rollup/rollup-android-arm-eabi@4.13.0: - resolution: {integrity: sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==} + /@rollup/rollup-android-arm-eabi@4.14.0: + resolution: {integrity: sha512-jwXtxYbRt1V+CdQSy6Z+uZti7JF5irRKF8hlKfEnF/xJpcNGuuiZMBvuoYM+x9sr9iWGnzrlM0+9hvQ1kgkf1w==} cpu: [arm] os: [android] requiresBuild: true dev: true optional: true - /@rollup/rollup-android-arm64@4.13.0: - resolution: {integrity: sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==} + /@rollup/rollup-android-arm64@4.14.0: + resolution: {integrity: sha512-fI9nduZhCccjzlsA/OuAwtFGWocxA4gqXGTLvOyiF8d+8o0fZUeSztixkYjcGq1fGZY3Tkq4yRvHPFxU+jdZ9Q==} cpu: [arm64] os: [android] requiresBuild: true dev: true optional: true - /@rollup/rollup-darwin-arm64@4.13.0: - resolution: {integrity: sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==} + /@rollup/rollup-darwin-arm64@4.14.0: + resolution: {integrity: sha512-BcnSPRM76/cD2gQC+rQNGBN6GStBs2pl/FpweW8JYuz5J/IEa0Fr4AtrPv766DB/6b2MZ/AfSIOSGw3nEIP8SA==} cpu: [arm64] os: [darwin] requiresBuild: true dev: true optional: true - /@rollup/rollup-darwin-x64@4.13.0: - resolution: {integrity: sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==} + /@rollup/rollup-darwin-x64@4.14.0: + resolution: {integrity: sha512-LDyFB9GRolGN7XI6955aFeI3wCdCUszFWumWU0deHA8VpR3nWRrjG6GtGjBrQxQKFevnUTHKCfPR4IvrW3kCgQ==} cpu: [x64] os: [darwin] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-arm-gnueabihf@4.13.0: - resolution: {integrity: sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==} + /@rollup/rollup-linux-arm-gnueabihf@4.14.0: + resolution: {integrity: sha512-ygrGVhQP47mRh0AAD0zl6QqCbNsf0eTo+vgwkY6LunBcg0f2Jv365GXlDUECIyoXp1kKwL5WW6rsO429DBY/bA==} cpu: [arm] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-arm64-gnu@4.13.0: - resolution: {integrity: sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==} + /@rollup/rollup-linux-arm64-gnu@4.14.0: + resolution: {integrity: sha512-x+uJ6MAYRlHGe9wi4HQjxpaKHPM3d3JjqqCkeC5gpnnI6OWovLdXTpfa8trjxPLnWKyBsSi5kne+146GAxFt4A==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-arm64-musl@4.13.0: - resolution: {integrity: sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==} + /@rollup/rollup-linux-arm64-musl@4.14.0: + resolution: {integrity: sha512-nrRw8ZTQKg6+Lttwqo6a2VxR9tOroa2m91XbdQ2sUUzHoedXlsyvY1fN4xWdqz8PKmf4orDwejxXHjh7YBGUCA==} cpu: [arm64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-riscv64-gnu@4.13.0: - resolution: {integrity: sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==} + /@rollup/rollup-linux-powerpc64le-gnu@4.14.0: + resolution: {integrity: sha512-xV0d5jDb4aFu84XKr+lcUJ9y3qpIWhttO3Qev97z8DKLXR62LC3cXT/bMZXrjLF9X+P5oSmJTzAhqwUbY96PnA==} + cpu: [ppc64le] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-riscv64-gnu@4.14.0: + resolution: {integrity: sha512-SDDhBQwZX6LPRoPYjAZWyL27LbcBo7WdBFWJi5PI9RPCzU8ijzkQn7tt8NXiXRiFMJCVpkuMkBf4OxSxVMizAw==} cpu: [riscv64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-x64-gnu@4.13.0: - resolution: {integrity: sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==} + /@rollup/rollup-linux-s390x-gnu@4.14.0: + resolution: {integrity: sha512-RxB/qez8zIDshNJDufYlTT0ZTVut5eCpAZ3bdXDU9yTxBzui3KhbGjROK2OYTTor7alM7XBhssgoO3CZ0XD3qA==} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-x64-gnu@4.14.0: + resolution: {integrity: sha512-C6y6z2eCNCfhZxT9u+jAM2Fup89ZjiG5pIzZIDycs1IwESviLxwkQcFRGLjnDrP+PT+v5i4YFvlcfAs+LnreXg==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-linux-x64-musl@4.13.0: - resolution: {integrity: sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==} + /@rollup/rollup-linux-x64-musl@4.14.0: + resolution: {integrity: sha512-i0QwbHYfnOMYsBEyjxcwGu5SMIi9sImDVjDg087hpzXqhBSosxkE7gyIYFHgfFl4mr7RrXksIBZ4DoLoP4FhJg==} cpu: [x64] os: [linux] requiresBuild: true dev: true optional: true - /@rollup/rollup-win32-arm64-msvc@4.13.0: - resolution: {integrity: sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==} + /@rollup/rollup-win32-arm64-msvc@4.14.0: + resolution: {integrity: sha512-Fq52EYb0riNHLBTAcL0cun+rRwyZ10S9vKzhGKKgeD+XbwunszSY0rVMco5KbOsTlwovP2rTOkiII/fQ4ih/zQ==} cpu: [arm64] os: [win32] requiresBuild: true dev: true optional: true - /@rollup/rollup-win32-ia32-msvc@4.13.0: - resolution: {integrity: sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==} + /@rollup/rollup-win32-ia32-msvc@4.14.0: + resolution: {integrity: sha512-e/PBHxPdJ00O9p5Ui43+vixSgVf4NlLsmV6QneGERJ3lnjIua/kim6PRFe3iDueT1rQcgSkYP8ZBBXa/h4iPvw==} cpu: [ia32] os: [win32] requiresBuild: true dev: true optional: true - /@rollup/rollup-win32-x64-msvc@4.13.0: - resolution: {integrity: sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==} + /@rollup/rollup-win32-x64-msvc@4.14.0: + resolution: {integrity: sha512-aGg7iToJjdklmxlUlJh/PaPNa4PmqHfyRMLunbL3eaMO0gp656+q1zOKkpJ/CVe9CryJv6tAN1HDoR8cNGzkag==} cpu: [x64] os: [win32] requiresBuild: true dev: true optional: true - /@semantic-release/changelog@6.0.3(semantic-release@23.0.6): + /@semantic-release/changelog@6.0.3(semantic-release@23.0.7): resolution: {integrity: sha512-dZuR5qByyfe3Y03TpmCvAxCyTnp7r5XwtHRf/8vD9EAn4ZWbavUX8adMtXYzE86EVh0gyLA7lm5yW4IV30XUag==} engines: {node: '>=14.17'} peerDependencies: @@ -2152,10 +2179,10 @@ packages: aggregate-error: 3.1.0 fs-extra: 11.2.0 lodash: 4.17.21 - semantic-release: 23.0.6(typescript@5.4.3) + semantic-release: 23.0.7(typescript@5.4.3) dev: true - /@semantic-release/commit-analyzer@12.0.0(semantic-release@23.0.6): + /@semantic-release/commit-analyzer@12.0.0(semantic-release@23.0.7): resolution: {integrity: sha512-qG+md5gdes+xa8zP7lIo1fWE17zRdO8yMCaxh9lyL65TQleoSv8WHHOqRURfghTytUh+NpkSyBprQ5hrkxOKVQ==} engines: {node: '>=20.8.1'} peerDependencies: @@ -2168,7 +2195,7 @@ packages: import-from-esm: 1.3.3 lodash-es: 4.17.21 micromatch: 4.0.5 - semantic-release: 23.0.6(typescript@5.4.3) + semantic-release: 23.0.7(typescript@5.4.3) transitivePeerDependencies: - supports-color dev: true @@ -2183,7 +2210,7 @@ packages: engines: {node: '>=18'} dev: true - /@semantic-release/git@10.0.1(semantic-release@23.0.6): + /@semantic-release/git@10.0.1(semantic-release@23.0.7): resolution: {integrity: sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==} engines: {node: '>=14.17'} peerDependencies: @@ -2197,21 +2224,21 @@ packages: lodash: 4.17.21 micromatch: 4.0.5 p-reduce: 2.1.0 - semantic-release: 23.0.6(typescript@5.4.3) + semantic-release: 23.0.7(typescript@5.4.3) transitivePeerDependencies: - supports-color dev: true - /@semantic-release/github@10.0.2(semantic-release@23.0.6): + /@semantic-release/github@10.0.2(semantic-release@23.0.7): resolution: {integrity: sha512-SP5ihhv/uQa8vPuWKmbJrrzfv8lRUkDFC6qwgaWoorrflN1DEW0IGCa9w/PxUp8Ad3dbvXZPmpXdGiP3eyTzhg==} engines: {node: '>=20.8.1'} peerDependencies: semantic-release: '>=20.1.0' dependencies: - '@octokit/core': 6.0.1 - '@octokit/plugin-paginate-rest': 10.0.0(@octokit/core@6.0.1) - '@octokit/plugin-retry': 7.0.3(@octokit/core@6.0.1) - '@octokit/plugin-throttling': 9.0.3(@octokit/core@6.0.1) + '@octokit/core': 6.1.1 + '@octokit/plugin-paginate-rest': 10.0.0(@octokit/core@6.1.1) + '@octokit/plugin-retry': 7.1.0(@octokit/core@6.1.1) + '@octokit/plugin-throttling': 9.1.0(@octokit/core@6.1.1) '@semantic-release/error': 4.0.0 aggregate-error: 5.0.0 debug: 4.3.4 @@ -2223,13 +2250,13 @@ packages: lodash-es: 4.17.21 mime: 4.0.1 p-filter: 4.1.0 - semantic-release: 23.0.6(typescript@5.4.3) + semantic-release: 23.0.7(typescript@5.4.3) url-join: 5.0.0 transitivePeerDependencies: - supports-color dev: true - /@semantic-release/npm@12.0.0(semantic-release@23.0.6): + /@semantic-release/npm@12.0.0(semantic-release@23.0.7): resolution: {integrity: sha512-72TVYQCH9NvVsO/y13eF8vE4bNnfls518+4KcFwJUKi7AtA/ZXoNgSg9gTTfw5eMZMkiH0izUrpGXgZE/cSQhA==} engines: {node: '>=20.8.1'} peerDependencies: @@ -2242,16 +2269,16 @@ packages: lodash-es: 4.17.21 nerf-dart: 1.0.0 normalize-url: 8.0.1 - npm: 10.5.0 + npm: 10.5.1 rc: 1.2.8 read-pkg: 9.0.1 registry-auth-token: 5.0.2 - semantic-release: 23.0.6(typescript@5.4.3) + semantic-release: 23.0.7(typescript@5.4.3) semver: 7.6.0 tempy: 3.1.0 dev: true - /@semantic-release/release-notes-generator@13.0.0(semantic-release@23.0.6): + /@semantic-release/release-notes-generator@13.0.0(semantic-release@23.0.7): resolution: {integrity: sha512-LEeZWb340keMYuREMyxrODPXJJ0JOL8D/mCl74B4LdzbxhtXV2LrPN2QBEcGJrlQhoqLO0RhxQb6masHytKw+A==} engines: {node: '>=20.8.1'} peerDependencies: @@ -2267,7 +2294,7 @@ packages: into-stream: 7.0.0 lodash-es: 4.17.21 read-pkg-up: 11.0.0 - semantic-release: 23.0.6(typescript@5.4.3) + semantic-release: 23.0.7(typescript@5.4.3) transitivePeerDependencies: - supports-color dev: true @@ -2301,7 +2328,7 @@ packages: /@types/babel__core@7.20.5: resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} dependencies: - '@babel/parser': 7.24.1 + '@babel/parser': 7.24.4 '@babel/types': 7.24.0 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 @@ -2317,7 +2344,7 @@ packages: /@types/babel__template@7.4.4: resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} dependencies: - '@babel/parser': 7.24.1 + '@babel/parser': 7.24.4 '@babel/types': 7.24.0 dev: true @@ -2340,7 +2367,7 @@ packages: /@types/graceful-fs@4.1.9: resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} dependencies: - '@types/node': 20.11.30 + '@types/node': 20.12.4 dev: true /@types/istanbul-lib-coverage@2.0.6: @@ -2374,16 +2401,12 @@ packages: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: true - /@types/lodash@4.17.0: - resolution: {integrity: sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==} - dev: true - /@types/ms@0.7.34: resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} dev: true - /@types/node@20.11.30: - resolution: {integrity: sha512-dHM6ZxwlmuZaRmUPfv1p+KrdD1Dci04FbdEm/9wEMouFqxYoFl5aMkt0VMAUtYRQDyYvD41WJLukhq/ha3YuTw==} + /@types/node@20.12.4: + resolution: {integrity: sha512-E+Fa9z3wSQpzgYQdYmme5X3OTuejnnTx88A6p6vkkJosR3KBz+HpE3kqNm98VE6cfLFcISx7zW7MsJkH6KwbTw==} dependencies: undici-types: 5.26.5 dev: true @@ -2410,8 +2433,8 @@ packages: '@types/yargs-parser': 21.0.3 dev: true - /@typescript-eslint/eslint-plugin@7.3.1(@typescript-eslint/parser@7.3.1)(eslint@8.57.0)(typescript@5.4.3): - resolution: {integrity: sha512-STEDMVQGww5lhCuNXVSQfbfuNII5E08QWkvAw5Qwf+bj2WT+JkG1uc+5/vXA3AOYMDHVOSpL+9rcbEUiHIm2dw==} + /@typescript-eslint/eslint-plugin@7.5.0(@typescript-eslint/parser@7.5.0)(eslint@8.57.0)(typescript@5.4.3): + resolution: {integrity: sha512-HpqNTH8Du34nLxbKgVMGljZMG0rJd2O9ecvr2QLYp+7512ty1j42KnsFwspPXg1Vh8an9YImf6CokUBltisZFQ==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: '@typescript-eslint/parser': ^7.0.0 @@ -2422,11 +2445,11 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.3.1(eslint@8.57.0)(typescript@5.4.3) - '@typescript-eslint/scope-manager': 7.3.1 - '@typescript-eslint/type-utils': 7.3.1(eslint@8.57.0)(typescript@5.4.3) - '@typescript-eslint/utils': 7.3.1(eslint@8.57.0)(typescript@5.4.3) - '@typescript-eslint/visitor-keys': 7.3.1 + '@typescript-eslint/parser': 7.5.0(eslint@8.57.0)(typescript@5.4.3) + '@typescript-eslint/scope-manager': 7.5.0 + '@typescript-eslint/type-utils': 7.5.0(eslint@8.57.0)(typescript@5.4.3) + '@typescript-eslint/utils': 7.5.0(eslint@8.57.0)(typescript@5.4.3) + '@typescript-eslint/visitor-keys': 7.5.0 debug: 4.3.4 eslint: 8.57.0 graphemer: 1.4.0 @@ -2460,8 +2483,8 @@ packages: - supports-color dev: true - /@typescript-eslint/parser@7.3.1(eslint@8.57.0)(typescript@5.4.3): - resolution: {integrity: sha512-Rq49+pq7viTRCH48XAbTA+wdLRrB/3sRq4Lpk0oGDm0VmnjBrAOVXH/Laalmwsv2VpekiEfVFwJYVk6/e8uvQw==} + /@typescript-eslint/parser@7.5.0(eslint@8.57.0)(typescript@5.4.3): + resolution: {integrity: sha512-cj+XGhNujfD2/wzR1tabNsidnYRaFfEkcULdcIyVBYcXjBvBKOes+mpMBP7hMpOyk+gBcfXsrg4NBGAStQyxjQ==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -2470,10 +2493,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 7.3.1 - '@typescript-eslint/types': 7.3.1 - '@typescript-eslint/typescript-estree': 7.3.1(typescript@5.4.3) - '@typescript-eslint/visitor-keys': 7.3.1 + '@typescript-eslint/scope-manager': 7.5.0 + '@typescript-eslint/types': 7.5.0 + '@typescript-eslint/typescript-estree': 7.5.0(typescript@5.4.3) + '@typescript-eslint/visitor-keys': 7.5.0 debug: 4.3.4 eslint: 8.57.0 typescript: 5.4.3 @@ -2489,16 +2512,16 @@ packages: '@typescript-eslint/visitor-keys': 6.21.0 dev: true - /@typescript-eslint/scope-manager@7.3.1: - resolution: {integrity: sha512-fVS6fPxldsKY2nFvyT7IP78UO1/I2huG+AYu5AMjCT9wtl6JFiDnsv4uad4jQ0GTFzcUV5HShVeN96/17bTBag==} + /@typescript-eslint/scope-manager@7.5.0: + resolution: {integrity: sha512-Z1r7uJY0MDeUlql9XJ6kRVgk/sP11sr3HKXn268HZyqL7i4cEfrdFuSSY/0tUqT37l5zT0tJOsuDP16kio85iA==} engines: {node: ^18.18.0 || >=20.0.0} dependencies: - '@typescript-eslint/types': 7.3.1 - '@typescript-eslint/visitor-keys': 7.3.1 + '@typescript-eslint/types': 7.5.0 + '@typescript-eslint/visitor-keys': 7.5.0 dev: true - /@typescript-eslint/type-utils@7.3.1(eslint@8.57.0)(typescript@5.4.3): - resolution: {integrity: sha512-iFhaysxFsMDQlzJn+vr3OrxN8NmdQkHks4WaqD4QBnt5hsq234wcYdyQ9uquzJJIDAj5W4wQne3yEsYA6OmXGw==} + /@typescript-eslint/type-utils@7.5.0(eslint@8.57.0)(typescript@5.4.3): + resolution: {integrity: sha512-A021Rj33+G8mx2Dqh0nMO9GyjjIBK3MqgVgZ2qlKf6CJy51wY/lkkFqq3TqqnH34XyAHUkq27IjlUkWlQRpLHw==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -2507,8 +2530,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 7.3.1(typescript@5.4.3) - '@typescript-eslint/utils': 7.3.1(eslint@8.57.0)(typescript@5.4.3) + '@typescript-eslint/typescript-estree': 7.5.0(typescript@5.4.3) + '@typescript-eslint/utils': 7.5.0(eslint@8.57.0)(typescript@5.4.3) debug: 4.3.4 eslint: 8.57.0 ts-api-utils: 1.3.0(typescript@5.4.3) @@ -2522,8 +2545,8 @@ packages: engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/types@7.3.1: - resolution: {integrity: sha512-2tUf3uWggBDl4S4183nivWQ2HqceOZh1U4hhu4p1tPiIJoRRXrab7Y+Y0p+dozYwZVvLPRI6r5wKe9kToF9FIw==} + /@typescript-eslint/types@7.5.0: + resolution: {integrity: sha512-tv5B4IHeAdhR7uS4+bf8Ov3k793VEVHd45viRRkehIUZxm0WF82VPiLgHzA/Xl4TGPg1ZD49vfxBKFPecD5/mg==} engines: {node: ^18.18.0 || >=20.0.0} dev: true @@ -2549,8 +2572,8 @@ packages: - supports-color dev: true - /@typescript-eslint/typescript-estree@7.3.1(typescript@5.4.3): - resolution: {integrity: sha512-tLpuqM46LVkduWP7JO7yVoWshpJuJzxDOPYIVWUUZbW+4dBpgGeUdl/fQkhuV0A8eGnphYw3pp8d2EnvPOfxmQ==} + /@typescript-eslint/typescript-estree@7.5.0(typescript@5.4.3): + resolution: {integrity: sha512-YklQQfe0Rv2PZEueLTUffiQGKQneiIEKKnfIqPIOxgM9lKSZFCjT5Ad4VqRKj/U4+kQE3fa8YQpskViL7WjdPQ==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: typescript: '*' @@ -2558,8 +2581,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 7.3.1 - '@typescript-eslint/visitor-keys': 7.3.1 + '@typescript-eslint/types': 7.5.0 + '@typescript-eslint/visitor-keys': 7.5.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -2571,8 +2594,8 @@ packages: - supports-color dev: true - /@typescript-eslint/utils@7.3.1(eslint@8.57.0)(typescript@5.4.3): - resolution: {integrity: sha512-jIERm/6bYQ9HkynYlNZvXpzmXWZGhMbrOvq3jJzOSOlKXsVjrrolzWBjDW6/TvT5Q3WqaN4EkmcfdQwi9tDjBQ==} + /@typescript-eslint/utils@7.5.0(eslint@8.57.0)(typescript@5.4.3): + resolution: {integrity: sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -2580,9 +2603,9 @@ packages: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@types/json-schema': 7.0.15 '@types/semver': 7.5.8 - '@typescript-eslint/scope-manager': 7.3.1 - '@typescript-eslint/types': 7.3.1 - '@typescript-eslint/typescript-estree': 7.3.1(typescript@5.4.3) + '@typescript-eslint/scope-manager': 7.5.0 + '@typescript-eslint/types': 7.5.0 + '@typescript-eslint/typescript-estree': 7.5.0(typescript@5.4.3) eslint: 8.57.0 semver: 7.6.0 transitivePeerDependencies: @@ -2598,11 +2621,11 @@ packages: eslint-visitor-keys: 3.4.3 dev: true - /@typescript-eslint/visitor-keys@7.3.1: - resolution: {integrity: sha512-9RMXwQF8knsZvfv9tdi+4D/j7dMG28X/wMJ8Jj6eOHyHWwDW4ngQJcqEczSsqIKKjFiLFr40Mnr7a5ulDD3vmw==} + /@typescript-eslint/visitor-keys@7.5.0: + resolution: {integrity: sha512-mcuHM/QircmA6O7fy6nn2w/3ditQkj+SgtOc8DW3uQ10Yfj42amm2i+6F2K4YAOPNNTmE6iM1ynM6lrSwdendA==} engines: {node: ^18.18.0 || >=20.0.0} dependencies: - '@typescript-eslint/types': 7.3.1 + '@typescript-eslint/types': 7.5.0 eslint-visitor-keys: 3.4.3 dev: true @@ -2632,8 +2655,8 @@ packages: hasBin: true dev: true - /agent-base@7.1.0: - resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==} + /agent-base@7.1.1: + resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} engines: {node: '>= 14'} dependencies: debug: 4.3.4 @@ -2751,7 +2774,7 @@ packages: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.23.2 + es-abstract: 1.23.3 es-object-atoms: 1.0.0 get-intrinsic: 1.2.4 is-string: 1.0.7 @@ -2768,7 +2791,7 @@ packages: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.23.2 + es-abstract: 1.23.3 es-errors: 1.3.0 es-object-atoms: 1.0.0 es-shim-unscopables: 1.0.2 @@ -2780,7 +2803,7 @@ packages: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.23.2 + es-abstract: 1.23.3 es-shim-unscopables: 1.0.2 dev: true @@ -2790,7 +2813,7 @@ packages: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.23.2 + es-abstract: 1.23.3 es-shim-unscopables: 1.0.2 dev: true @@ -2801,17 +2824,13 @@ packages: array-buffer-byte-length: 1.0.1 call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.23.2 + es-abstract: 1.23.3 es-errors: 1.3.0 get-intrinsic: 1.2.4 is-array-buffer: 3.0.4 is-shared-array-buffer: 1.0.3 dev: true - /asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: false - /available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} @@ -2819,27 +2838,17 @@ packages: possible-typed-array-names: 1.0.0 dev: true - /axios@1.6.8: - resolution: {integrity: sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==} - dependencies: - follow-redirects: 1.15.6 - form-data: 4.0.0 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - dev: false - - /babel-jest@29.7.0(@babel/core@7.24.3): + /babel-jest@29.7.0(@babel/core@7.24.4): resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.8.0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@jest/transform': 29.7.0 '@types/babel__core': 7.20.5 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.24.3) + babel-preset-jest: 29.6.3(@babel/core@7.24.4) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 @@ -2870,71 +2879,71 @@ packages: '@types/babel__traverse': 7.20.5 dev: true - /babel-plugin-polyfill-corejs2@0.4.10(@babel/core@7.24.3): + /babel-plugin-polyfill-corejs2@0.4.10(@babel/core@7.24.4): resolution: {integrity: sha512-rpIuu//y5OX6jVU+a5BCn1R5RSZYWAl2Nar76iwaOdycqb6JPxediskWFMMl7stfwNJR4b7eiQvh5fB5TEQJTQ==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/compat-data': 7.24.1 - '@babel/core': 7.24.3 - '@babel/helper-define-polyfill-provider': 0.6.1(@babel/core@7.24.3) + '@babel/compat-data': 7.24.4 + '@babel/core': 7.24.4 + '@babel/helper-define-polyfill-provider': 0.6.1(@babel/core@7.24.4) semver: 6.3.1 transitivePeerDependencies: - supports-color dev: true - /babel-plugin-polyfill-corejs3@0.10.4(@babel/core@7.24.3): + /babel-plugin-polyfill-corejs3@0.10.4(@babel/core@7.24.4): resolution: {integrity: sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/core': 7.24.3 - '@babel/helper-define-polyfill-provider': 0.6.1(@babel/core@7.24.3) + '@babel/core': 7.24.4 + '@babel/helper-define-polyfill-provider': 0.6.1(@babel/core@7.24.4) core-js-compat: 3.36.1 transitivePeerDependencies: - supports-color dev: true - /babel-plugin-polyfill-regenerator@0.6.1(@babel/core@7.24.3): + /babel-plugin-polyfill-regenerator@0.6.1(@babel/core@7.24.4): resolution: {integrity: sha512-JfTApdE++cgcTWjsiCQlLyFBMbTUft9ja17saCc93lgV33h4tuCVj7tlvu//qpLwaG+3yEz7/KhahGrUMkVq9g==} peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 dependencies: - '@babel/core': 7.24.3 - '@babel/helper-define-polyfill-provider': 0.6.1(@babel/core@7.24.3) + '@babel/core': 7.24.4 + '@babel/helper-define-polyfill-provider': 0.6.1(@babel/core@7.24.4) transitivePeerDependencies: - supports-color dev: true - /babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.3): + /babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.4): resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.3 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.3) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.24.3) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.3) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.3) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.3) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.3) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.3) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.3) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.3) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.3) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.3) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.3) - dev: true - - /babel-preset-jest@29.6.3(@babel/core@7.24.3): + '@babel/core': 7.24.4 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.4) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.24.4) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.4) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.4) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.4) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.4) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.4) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.4) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.4) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.4) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.4) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.4) + dev: true + + /babel-preset-jest@29.6.3(@babel/core@7.24.4): resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.3) + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.4) dev: true /balanced-match@1.0.2: @@ -2979,8 +2988,8 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001600 - electron-to-chromium: 1.4.715 + caniuse-lite: 1.0.30001605 + electron-to-chromium: 1.4.726 node-releases: 2.0.14 update-browserslist-db: 1.0.13(browserslist@4.23.0) dev: true @@ -3047,8 +3056,8 @@ packages: engines: {node: '>=10'} dev: true - /caniuse-lite@1.0.30001600: - resolution: {integrity: sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ==} + /caniuse-lite@1.0.30001605: + resolution: {integrity: sha512-nXwGlFWo34uliI9z3n6Qc0wZaf7zaZWA1CPZ169La5mV3I/gem7bst0vr5XQH5TJXZIMfDeZyOrZnSlVzKxxHQ==} dev: true /chalk@2.4.2: @@ -3183,13 +3192,6 @@ packages: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} dev: true - /combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - dependencies: - delayed-stream: 1.0.0 - dev: false - /commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} @@ -3249,6 +3251,11 @@ packages: split2: 4.2.0 dev: true + /convert-hrtime@5.0.0: + resolution: {integrity: sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==} + engines: {node: '>=12'} + dev: true + /convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} dev: true @@ -3279,7 +3286,7 @@ packages: typescript: 5.4.3 dev: true - /create-jest@29.7.0(@types/node@20.11.30): + /create-jest@29.7.0(@types/node@20.12.4): resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -3288,7 +3295,7 @@ packages: chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.11.30) + jest-config: 29.7.0(@types/node@20.12.4) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -3405,11 +3412,6 @@ packages: object-keys: 1.1.1 dev: true - /delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - dev: false - /detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} @@ -3463,8 +3465,8 @@ packages: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} dev: true - /electron-to-chromium@1.4.715: - resolution: {integrity: sha512-XzWNH4ZSa9BwVUQSDorPWAUQ5WGuYz7zJUNpNif40zFCiCl20t8zgylmreNmn26h5kiyw2lg7RfTmeMBsDklqg==} + /electron-to-chromium@1.4.726: + resolution: {integrity: sha512-xtjfBXn53RORwkbyKvDfTajtnTp0OJoPOIBzXvkNbb7+YYvCHJflba3L7Txyx/6Fov3ov2bGPr/n5MTixmPhdQ==} dev: true /emittery@0.13.1: @@ -3503,8 +3505,8 @@ packages: is-arrayish: 0.2.1 dev: true - /es-abstract@1.23.2: - resolution: {integrity: sha512-60s3Xv2T2p1ICykc7c+DNDPLDMm9t4QxCOUU0K9JxiLjM3C1zB9YVdN7tjxrFd4+AkZ8CdX1ovUga4P2+1e+/w==} + /es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} engines: {node: '>= 0.4'} dependencies: array-buffer-byte-length: 1.0.1 @@ -3664,7 +3666,7 @@ packages: semver: 7.6.0 dev: true - /eslint-config-love@43.1.0(@typescript-eslint/eslint-plugin@7.3.1)(eslint-plugin-import@2.29.1)(eslint-plugin-n@16.6.2)(eslint-plugin-promise@6.1.1)(eslint@8.57.0)(typescript@5.4.3): + /eslint-config-love@43.1.0(@typescript-eslint/eslint-plugin@7.5.0)(eslint-plugin-import@2.29.1)(eslint-plugin-n@16.6.2)(eslint-plugin-promise@6.1.1)(eslint@8.57.0)(typescript@5.4.3): resolution: {integrity: sha512-r3+7mSaOl0BEGf8LEntPPDbWTDw8o0Dpy9vdts7m+NAuSpmz9C/gL+64lC0Z8nKNE4uwdymPGll4czGQiR+XmQ==} peerDependencies: '@typescript-eslint/eslint-plugin': ^6.4.0 @@ -3674,11 +3676,11 @@ packages: eslint-plugin-promise: ^6.0.0 typescript: '*' dependencies: - '@typescript-eslint/eslint-plugin': 7.3.1(@typescript-eslint/parser@7.3.1)(eslint@8.57.0)(typescript@5.4.3) + '@typescript-eslint/eslint-plugin': 7.5.0(@typescript-eslint/parser@7.5.0)(eslint@8.57.0)(typescript@5.4.3) '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.4.3) eslint: 8.57.0 eslint-config-standard: 17.1.0(eslint-plugin-import@2.29.1)(eslint-plugin-n@16.6.2)(eslint-plugin-promise@6.1.1)(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.3.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.5.0)(eslint@8.57.0) eslint-plugin-n: 16.6.2(eslint@8.57.0) eslint-plugin-promise: 6.1.1(eslint@8.57.0) typescript: 5.4.3 @@ -3705,7 +3707,7 @@ packages: eslint-plugin-promise: ^6.0.0 dependencies: eslint: 8.57.0 - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.3.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.5.0)(eslint@8.57.0) eslint-plugin-n: 16.6.2(eslint@8.57.0) eslint-plugin-promise: 6.1.1(eslint@8.57.0) dev: true @@ -3720,7 +3722,7 @@ packages: - supports-color dev: true - /eslint-module-utils@2.8.1(@typescript-eslint/parser@7.3.1)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): + /eslint-module-utils@2.8.1(@typescript-eslint/parser@7.5.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} engines: {node: '>=4'} peerDependencies: @@ -3741,7 +3743,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 7.3.1(eslint@8.57.0)(typescript@5.4.3) + '@typescript-eslint/parser': 7.5.0(eslint@8.57.0)(typescript@5.4.3) debug: 3.2.7 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 @@ -3761,7 +3763,7 @@ packages: eslint-compat-utils: 0.5.0(eslint@8.57.0) dev: true - /eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.3.1)(eslint@8.57.0): + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.5.0)(eslint@8.57.0): resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} engines: {node: '>=4'} peerDependencies: @@ -3771,7 +3773,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 7.3.1(eslint@8.57.0)(typescript@5.4.3) + '@typescript-eslint/parser': 7.5.0(eslint@8.57.0)(typescript@5.4.3) array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 array.prototype.flat: 1.3.2 @@ -3780,7 +3782,7 @@ packages: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.3.1)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.5.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -4086,11 +4088,12 @@ packages: path-exists: 4.0.0 dev: true - /find-versions@5.1.0: - resolution: {integrity: sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==} - engines: {node: '>=12'} + /find-versions@6.0.0: + resolution: {integrity: sha512-2kCCtc+JvcZ86IGAz3Z2Y0A1baIz9fL31pH/0S1IqZr9Iwnjq8izfPtrCyQKO6TLMPELLsQMre7VDqeIKCsHkA==} + engines: {node: '>=18'} dependencies: semver-regex: 4.0.5 + super-regex: 1.0.0 dev: true /flat-cache@3.2.0: @@ -4106,16 +4109,6 @@ packages: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} dev: true - /follow-redirects@1.15.6: - resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dev: false - /for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} dependencies: @@ -4130,15 +4123,6 @@ packages: signal-exit: 4.1.0 dev: true - /form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: false - /from2@2.3.0: resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} dependencies: @@ -4171,13 +4155,18 @@ packages: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} dev: true + /function-timeout@1.0.1: + resolution: {integrity: sha512-6yPMImFFuaMPNaTMTBuolA8EanHJWF5Vju0NHpObRURT105J6x1Mf2a7J4P7Sqk2xDxv24N5L0RatEhTBhNmdA==} + engines: {node: '>=18'} + dev: true + /function.prototype.name@1.1.6: resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.23.2 + es-abstract: 1.23.3 functions-have-names: 1.2.3 dev: true @@ -4266,16 +4255,16 @@ packages: is-glob: 4.0.3 dev: true - /glob@10.3.10: - resolution: {integrity: sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==} + /glob@10.3.12: + resolution: {integrity: sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==} engines: {node: '>=16 || 14 >=14.17'} hasBin: true dependencies: foreground-child: 3.1.1 jackspeak: 2.3.6 - minimatch: 9.0.3 + minimatch: 9.0.4 minipass: 7.0.4 - path-scurry: 1.10.1 + path-scurry: 1.10.2 dev: true /glob@7.2.3: @@ -4431,7 +4420,7 @@ packages: resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} dependencies: - agent-base: 7.1.0 + agent-base: 7.1.1 debug: 4.3.4 transitivePeerDependencies: - supports-color @@ -4441,7 +4430,7 @@ packages: resolution: {integrity: sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==} engines: {node: '>= 14'} dependencies: - agent-base: 7.1.0 + agent-base: 7.1.1 debug: 4.3.4 transitivePeerDependencies: - supports-color @@ -4513,10 +4502,6 @@ packages: engines: {node: '>=18'} dev: true - /inflector-js@1.0.1: - resolution: {integrity: sha512-GYvCqr8mGKPoYH+08e76PV8JoIygIVC9Jxw2jA5QjBm/mK+mJqGdzEcs3L5nugnvP03yHajXpBRMRgHx0e770A==} - dev: true - /inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} dependencies: @@ -4759,8 +4744,8 @@ packages: resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} engines: {node: '>=8'} dependencies: - '@babel/core': 7.24.3 - '@babel/parser': 7.24.1 + '@babel/core': 7.24.4 + '@babel/parser': 7.24.4 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -4772,8 +4757,8 @@ packages: resolution: {integrity: sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==} engines: {node: '>=10'} dependencies: - '@babel/core': 7.24.3 - '@babel/parser': 7.24.1 + '@babel/core': 7.24.4 + '@babel/parser': 7.24.4 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 7.6.0 @@ -4840,7 +4825,7 @@ packages: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.30 + '@types/node': 20.12.4 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.1 @@ -4861,7 +4846,7 @@ packages: - supports-color dev: true - /jest-cli@29.7.0(@types/node@20.11.30): + /jest-cli@29.7.0(@types/node@20.12.4): resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -4875,10 +4860,10 @@ packages: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.11.30) + create-jest: 29.7.0(@types/node@20.12.4) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.11.30) + jest-config: 29.7.0(@types/node@20.12.4) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -4889,7 +4874,7 @@ packages: - ts-node dev: true - /jest-config@29.7.0(@types/node@20.11.30): + /jest-config@29.7.0(@types/node@20.12.4): resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -4901,11 +4886,11 @@ packages: ts-node: optional: true dependencies: - '@babel/core': 7.24.3 + '@babel/core': 7.24.4 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.30 - babel-jest: 29.7.0(@babel/core@7.24.3) + '@types/node': 20.12.4 + babel-jest: 29.7.0(@babel/core@7.24.4) chalk: 4.1.2 ci-info: 3.9.0 deepmerge: 4.3.1 @@ -4964,7 +4949,7 @@ packages: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.30 + '@types/node': 20.12.4 jest-mock: 29.7.0 jest-util: 29.7.0 dev: true @@ -4980,7 +4965,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 20.11.30 + '@types/node': 20.12.4 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -5031,7 +5016,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.30 + '@types/node': 20.12.4 jest-util: 29.7.0 dev: true @@ -5086,7 +5071,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.30 + '@types/node': 20.12.4 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -5117,7 +5102,7 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.30 + '@types/node': 20.12.4 chalk: 4.1.2 cjs-module-lexer: 1.2.3 collect-v8-coverage: 1.0.2 @@ -5140,15 +5125,15 @@ packages: resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@babel/core': 7.24.3 - '@babel/generator': 7.24.1 - '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.3) - '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.3) + '@babel/core': 7.24.4 + '@babel/generator': 7.24.4 + '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.4) + '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.4) '@babel/types': 7.24.0 '@jest/expect-utils': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.3) + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.4) chalk: 4.1.2 expect: 29.7.0 graceful-fs: 4.2.11 @@ -5169,7 +5154,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.30 + '@types/node': 20.12.4 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -5194,7 +5179,7 @@ packages: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.30 + '@types/node': 20.12.4 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -5206,13 +5191,13 @@ packages: resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 20.11.30 + '@types/node': 20.12.4 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true - /jest@29.7.0(@types/node@20.11.30): + /jest@29.7.0(@types/node@20.12.4): resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -5225,7 +5210,7 @@ packages: '@jest/core': 29.7.0 '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.11.30) + jest-cli: 29.7.0(@types/node@20.12.4) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -5414,6 +5399,10 @@ packages: resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==} dev: true + /lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + dev: true + /lodash.isplainobject@4.0.6: resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} dev: true @@ -5512,18 +5501,6 @@ packages: picomatch: 2.3.1 dev: true - /mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - dev: false - - /mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.52.0 - dev: false - /mime@4.0.1: resolution: {integrity: sha512-5lZ5tyrIfliMXzFtkYyekWbtRXObT9OWa8IwQ5uxTBDHucNNwniRqo0yInflj+iYi5CBa6qxadGzGarDfuEOxA==} engines: {node: '>=16'} @@ -5553,6 +5530,13 @@ packages: brace-expansion: 2.0.1 dev: true + /minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + /minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} dev: true @@ -5642,8 +5626,8 @@ packages: path-key: 4.0.0 dev: true - /npm@10.5.0: - resolution: {integrity: sha512-Ejxwvfh9YnWVU2yA5FzoYLTW52vxHCz+MHrOFg9Cc8IFgF/6f5AGPAvb5WTay5DIUP1NIfN3VBZ0cLlGO0Ys+A==} + /npm@10.5.1: + resolution: {integrity: sha512-RozZuGuWbbhDM2sRhOSLIRb3DLyof6TREi0TW5b3xUEBropDhDqEHv0iAjA1zsIwXKgfIkR8GvQMd4oeKKg9eQ==} engines: {node: ^18.17.0 || >=20.5.0} hasBin: true dev: true @@ -5655,6 +5639,7 @@ packages: - '@npmcli/map-workspaces' - '@npmcli/package-json' - '@npmcli/promise-spawn' + - '@npmcli/redact' - '@npmcli/run-script' - '@sigstore/tuf' - abbrev @@ -5749,7 +5734,7 @@ packages: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.23.2 + es-abstract: 1.23.3 es-object-atoms: 1.0.0 dev: true @@ -5759,7 +5744,7 @@ packages: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.23.2 + es-abstract: 1.23.3 dev: true /object.values@1.2.0: @@ -5812,7 +5797,7 @@ packages: resolution: {integrity: sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw==} engines: {node: '>=18'} dependencies: - p-map: 7.0.1 + p-map: 7.0.2 dev: true /p-is-promise@3.0.0: @@ -5862,8 +5847,8 @@ packages: p-limit: 3.1.0 dev: true - /p-map@7.0.1: - resolution: {integrity: sha512-2wnaR0XL/FDOj+TgpDuRb2KTjLnu3Fma6b1ZUwGY7LcqenMcvP/YFpjpbPKY6WVGsbuJZRuoUz8iPrt8ORnAFw==} + /p-map@7.0.2: + resolution: {integrity: sha512-z4cYYMMdKHzw4O5UkWJImbZynVIo0lSGTXc7bzB1e/rrDqkgGUNysK/o4bTr+0+xKvvLoTyGqYC4Fgljy9qe1Q==} engines: {node: '>=18'} dev: true @@ -5918,7 +5903,7 @@ packages: dependencies: '@babel/code-frame': 7.24.2 index-to-position: 0.1.2 - type-fest: 4.14.0 + type-fest: 4.15.0 dev: true /parse5-htmlparser2-tree-adapter@6.0.1: @@ -5964,8 +5949,8 @@ packages: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} dev: true - /path-scurry@1.10.1: - resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==} + /path-scurry@1.10.2: + resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==} engines: {node: '>=16 || 14 >=14.17'} dependencies: lru-cache: 10.2.0 @@ -6080,10 +6065,6 @@ packages: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} dev: true - /proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - dev: false - /punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -6118,7 +6099,7 @@ packages: dependencies: find-up-simple: 1.0.0 read-pkg: 9.0.1 - type-fest: 4.14.0 + type-fest: 4.15.0 dev: true /read-pkg@9.0.1: @@ -6128,7 +6109,7 @@ packages: '@types/normalize-package-data': 2.4.4 normalize-package-data: 6.0.0 parse-json: 8.1.0 - type-fest: 4.14.0 + type-fest: 4.15.0 unicorn-magic: 0.1.0 dev: true @@ -6169,7 +6150,7 @@ packages: /regenerator-transform@0.15.2: resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} dependencies: - '@babel/runtime': 7.24.1 + '@babel/runtime': 7.24.4 dev: true /regexp.prototype.flags@1.5.2: @@ -6260,26 +6241,28 @@ packages: glob: 7.2.3 dev: true - /rollup@4.13.0: - resolution: {integrity: sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==} + /rollup@4.14.0: + resolution: {integrity: sha512-Qe7w62TyawbDzB4yt32R0+AbIo6m1/sqO7UPzFS8Z/ksL5mrfhA0v4CavfdmFav3D+ub4QeAgsGEe84DoWe/nQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true dependencies: '@types/estree': 1.0.5 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.13.0 - '@rollup/rollup-android-arm64': 4.13.0 - '@rollup/rollup-darwin-arm64': 4.13.0 - '@rollup/rollup-darwin-x64': 4.13.0 - '@rollup/rollup-linux-arm-gnueabihf': 4.13.0 - '@rollup/rollup-linux-arm64-gnu': 4.13.0 - '@rollup/rollup-linux-arm64-musl': 4.13.0 - '@rollup/rollup-linux-riscv64-gnu': 4.13.0 - '@rollup/rollup-linux-x64-gnu': 4.13.0 - '@rollup/rollup-linux-x64-musl': 4.13.0 - '@rollup/rollup-win32-arm64-msvc': 4.13.0 - '@rollup/rollup-win32-ia32-msvc': 4.13.0 - '@rollup/rollup-win32-x64-msvc': 4.13.0 + '@rollup/rollup-android-arm-eabi': 4.14.0 + '@rollup/rollup-android-arm64': 4.14.0 + '@rollup/rollup-darwin-arm64': 4.14.0 + '@rollup/rollup-darwin-x64': 4.14.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.14.0 + '@rollup/rollup-linux-arm64-gnu': 4.14.0 + '@rollup/rollup-linux-arm64-musl': 4.14.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.14.0 + '@rollup/rollup-linux-riscv64-gnu': 4.14.0 + '@rollup/rollup-linux-s390x-gnu': 4.14.0 + '@rollup/rollup-linux-x64-gnu': 4.14.0 + '@rollup/rollup-linux-x64-musl': 4.14.0 + '@rollup/rollup-win32-arm64-msvc': 4.14.0 + '@rollup/rollup-win32-ia32-msvc': 4.14.0 + '@rollup/rollup-win32-x64-msvc': 4.14.0 fsevents: 2.3.3 dev: true @@ -6312,23 +6295,23 @@ packages: is-regex: 1.1.4 dev: true - /semantic-release@23.0.6(typescript@5.4.3): - resolution: {integrity: sha512-/r62F4PNhJZhyZYMobcpcACGwpFNQyaVcSmqZQXG50GMbHSBVZQLCvwafqxO1lDQKVgmGmyCEtOVYzwvzvyhVw==} + /semantic-release@23.0.7(typescript@5.4.3): + resolution: {integrity: sha512-PFxXQE57zrYiCbWKkdsVUF08s0SifEw3WhDhrN47ZEUWQiLl21FI9Dg/H8g7i/lPx0IkF6u7PjJbgxPceXKBeg==} engines: {node: '>=20.8.1'} hasBin: true dependencies: - '@semantic-release/commit-analyzer': 12.0.0(semantic-release@23.0.6) + '@semantic-release/commit-analyzer': 12.0.0(semantic-release@23.0.7) '@semantic-release/error': 4.0.0 - '@semantic-release/github': 10.0.2(semantic-release@23.0.6) - '@semantic-release/npm': 12.0.0(semantic-release@23.0.6) - '@semantic-release/release-notes-generator': 13.0.0(semantic-release@23.0.6) + '@semantic-release/github': 10.0.2(semantic-release@23.0.7) + '@semantic-release/npm': 12.0.0(semantic-release@23.0.7) + '@semantic-release/release-notes-generator': 13.0.0(semantic-release@23.0.7) aggregate-error: 5.0.0 cosmiconfig: 9.0.0(typescript@5.4.3) debug: 4.3.4 env-ci: 11.0.0 execa: 8.0.1 figures: 6.1.0 - find-versions: 5.1.0 + find-versions: 6.0.0 get-stream: 6.0.1 git-log-parser: 1.2.0 hook-std: 3.0.0 @@ -6565,7 +6548,7 @@ packages: dependencies: call-bind: 1.0.7 define-properties: 1.2.1 - es-abstract: 1.23.2 + es-abstract: 1.23.3 es-object-atoms: 1.0.0 dev: true @@ -6643,13 +6626,21 @@ packages: dependencies: '@jridgewell/gen-mapping': 0.3.5 commander: 4.1.1 - glob: 10.3.10 + glob: 10.3.12 lines-and-columns: 1.2.4 mz: 2.7.0 pirates: 4.0.6 ts-interface-checker: 0.1.13 dev: true + /super-regex@1.0.0: + resolution: {integrity: sha512-CY8u7DtbvucKuquCmOFEKhr9Besln7n9uN8eFbwcoGYWXOMW07u2o8njWaiXt11ylS3qoGF55pILjRmPlbodyg==} + engines: {node: '>=18'} + dependencies: + function-timeout: 1.0.1 + time-span: 5.1.0 + dev: true + /supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -6749,6 +6740,13 @@ packages: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} dev: true + /time-span@5.1.0: + resolution: {integrity: sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==} + engines: {node: '>=12'} + dependencies: + convert-hrtime: 5.0.0 + dev: true + /tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} dev: true @@ -6836,7 +6834,7 @@ packages: joycon: 3.1.1 postcss-load-config: 4.0.2 resolve-from: 5.0.0 - rollup: 4.13.0 + rollup: 4.14.0 source-map: 0.8.0-beta.0 sucrase: 3.35.0 tree-kill: 1.2.2 @@ -6846,8 +6844,8 @@ packages: - ts-node dev: true - /tsx@4.7.1: - resolution: {integrity: sha512-8d6VuibXHtlN5E3zFkgY8u4DX7Y3Z27zvvPKVmLon/D4AjuKzarkUBTLDBgj9iTQ0hg5xM7c/mYiRVM+HETf0g==} + /tsx@4.7.2: + resolution: {integrity: sha512-BCNd4kz6fz12fyrgCTEdZHGJ9fWTGeUzXmQysh0RVocDY3h4frk05ZNCXSy4kIenF7y/QnrdiVpTsyNRn6vlAw==} engines: {node: '>=18.0.0'} hasBin: true dependencies: @@ -6889,8 +6887,8 @@ packages: engines: {node: '>=12.20'} dev: true - /type-fest@4.14.0: - resolution: {integrity: sha512-on5/Cw89wwqGZQu+yWO0gGMGu8VNxsaW9SB2HE8yJjllEk7IDTwnSN1dUVldYILhYPN5HzD7WAaw2cc/jBfn0Q==} + /type-fest@4.15.0: + resolution: {integrity: sha512-tB9lu0pQpX5KJq54g+oHOLumOx+pMep4RaM6liXh2PKmVRFF+/vAtUP0ZaJ0kOySfVNjF6doBWPHhBhISKdlIA==} engines: {node: '>=16'} dev: true diff --git a/specs/commercelayer.spec.ts b/specs/commercelayer.spec.ts index 8556170..1c1348b 100644 --- a/specs/commercelayer.spec.ts +++ b/specs/commercelayer.spec.ts @@ -46,11 +46,10 @@ describe('SDK:commercelayer suite', () => { cli.removeRawResponseReader(reader.id as number) cli.removeRawResponseReader(reader) cli.removeRawResponseReader(0) - cli.removeRawResponseReader({ id: undefined } as RawResponseReader) + cli.removeRawResponseReader({ id: 1, ok: true } as RawResponseReader) clp = await getClient() }) - }) diff --git a/specs/error.spec.ts b/specs/error.spec.ts index 499b9f1..a797684 100644 --- a/specs/error.spec.ts +++ b/specs/error.spec.ts @@ -37,7 +37,7 @@ describe('SDK:error suite', () => { clp.config({ domain: 'fake.domain.xx', accessToken: 'fake-access-token' }) await clp.roles.list({ pageSize: 1}) } catch (error) { - expect(error.type).toEqual(ErrorType.RESPONSE) + expect(error.type).toEqual(ErrorType.CLIENT) } }) diff --git a/specs/headers.spec.ts b/specs/headers.spec.ts index 7e2259f..4740617 100644 --- a/specs/headers.spec.ts +++ b/specs/headers.spec.ts @@ -24,11 +24,11 @@ describe('Test headers', () => { } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.headers).toBeDefined() - if (config.headers) { - expect(config.headers['test-header']).toBe(testHeaderValue) - expect(config.headers['Content-Type']).toBe('application/vnd.api+json') + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.headers).toBeDefined() + if (request.options.headers) { + expect(request.options.headers['test-header']).toBe(testHeaderValue) + expect(request.options.headers['Content-Type']).toBe('application/vnd.api+json') } return interceptRequest() }) diff --git a/specs/jsonapi.spec.ts b/specs/jsonapi.spec.ts index cadda8a..4457f78 100644 --- a/specs/jsonapi.spec.ts +++ b/specs/jsonapi.spec.ts @@ -3,7 +3,7 @@ import { CommerceLayerProvisioningClient } from '../src' import { getClient, TestData } from '../test/common' import { normalize, denormalize } from '../src/jsonapi' import { ResourceTypeLock } from '../src/api' -import { isEqual } from 'lodash' +import isEqual from 'lodash.isequal' let clp: CommerceLayerProvisioningClient diff --git a/specs/resources/api_credentials.spec.ts b/specs/resources/api_credentials.spec.ts index 99dcf36..0c7b53f 100644 --- a/specs/resources/api_credentials.spec.ts +++ b/specs/resources/api_credentials.spec.ts @@ -4,7 +4,7 @@ **/ import { CommerceLayerProvisioningClient, ApiCredential } from '../../src' -import { isEqual } from 'lodash' +import isEqual from 'lodash.isequal' // eslint-disable-next-line @typescript-eslint/no-unused-vars import { getClient, TestData, CommonData, handleError, interceptRequest, checkCommon, checkCommonData, checkCommonParamsList, checkCommonParams, currentAccessToken, randomValue } from '../../test/common' @@ -35,15 +35,17 @@ describe('ApiCredentials resource', () => { const params = { fields: { [resourceType]: CommonData.paramsFields } } const resData = attributes - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('post') - checkCommon(config, resourceType) - checkCommonData(config, resourceType, attributes) - expect(clp[resourceType].isApiCredential(config.data.data)).toBeTruthy() + const intId = clp.addRequestInterceptor((request) => { + const data = JSON.parse(String(request.options.body)) + expect(request.options.method).toBe('POST') + checkCommon(request, resourceType) + checkCommonData(data, resourceType, attributes) + expect(clp[resourceType].isApiCredential(data.data)).toBeTruthy() return interceptRequest() }) await clp[resourceType].create(resData, params, CommonData.options) + .then((res: ApiCredential) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -57,14 +59,15 @@ describe('ApiCredentials resource', () => { const id = TestData.id const params = { fields: {[resourceType]: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken) - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken) + checkCommonParams(request, params) return interceptRequest() }) await clp[resourceType].retrieve(id, params, CommonData.options) + .then((res: ApiCredential) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -79,16 +82,18 @@ describe('ApiCredentials resource', () => { const params = { fields: { [resourceType]: CommonData.paramsFields } } const resData = { id: TestData.id, ...attributes} - const intId = clp.addRequestInterceptor((config) => { - if (config.method !== 'get') { - expect(config.method).toBe('patch') - checkCommon(config, resourceType, resData.id, currentAccessToken) - checkCommonData(config, resourceType, attributes, resData.id) + const intId = clp.addRequestInterceptor((request) => { + if (request.options.method !== 'GET') { + const data = JSON.parse(String(request.options.body)) + expect(request.options.method).toBe('PATCH') + checkCommon(request, resourceType, resData.id, currentAccessToken) + checkCommonData(data, resourceType, attributes, resData.id) } return interceptRequest() }) await clp[resourceType].update(resData, params, CommonData.options) + .then((res: ApiCredential) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -101,9 +106,9 @@ describe('ApiCredentials resource', () => { const id = TestData.id - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('delete') - checkCommon(config, resourceType, id, currentAccessToken) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('DELETE') + checkCommon(request, resourceType, id, currentAccessToken) return interceptRequest() }) @@ -120,10 +125,10 @@ describe('ApiCredentials resource', () => { const params = CommonData.paramsList - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType) - checkCommonParamsList(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType) + checkCommonParamsList(request, params) return interceptRequest() }) @@ -204,10 +209,10 @@ describe('ApiCredentials resource', () => { const id = TestData.id const params = { fields: { organizations: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'organization') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'organization') + checkCommonParams(request, params) return interceptRequest() }) @@ -225,10 +230,10 @@ describe('ApiCredentials resource', () => { const id = TestData.id const params = { fields: { roles: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'role') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'role') + checkCommonParams(request, params) return interceptRequest() }) diff --git a/specs/resources/application_memberships.spec.ts b/specs/resources/application_memberships.spec.ts index d2741da..fdf8c91 100644 --- a/specs/resources/application_memberships.spec.ts +++ b/specs/resources/application_memberships.spec.ts @@ -4,7 +4,7 @@ **/ import { CommerceLayerProvisioningClient, ApplicationMembership } from '../../src' -import { isEqual } from 'lodash' +import isEqual from 'lodash.isequal' // eslint-disable-next-line @typescript-eslint/no-unused-vars import { getClient, TestData, CommonData, handleError, interceptRequest, checkCommon, checkCommonData, checkCommonParamsList, checkCommonParams, currentAccessToken, randomValue } from '../../test/common' @@ -35,15 +35,17 @@ describe('ApplicationMemberships resource', () => { const params = { fields: { [resourceType]: CommonData.paramsFields } } const resData = attributes - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('post') - checkCommon(config, resourceType) - checkCommonData(config, resourceType, attributes) - expect(clp[resourceType].isApplicationMembership(config.data.data)).toBeTruthy() + const intId = clp.addRequestInterceptor((request) => { + const data = JSON.parse(String(request.options.body)) + expect(request.options.method).toBe('POST') + checkCommon(request, resourceType) + checkCommonData(data, resourceType, attributes) + expect(clp[resourceType].isApplicationMembership(data.data)).toBeTruthy() return interceptRequest() }) await clp[resourceType].create(resData, params, CommonData.options) + .then((res: ApplicationMembership) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -57,14 +59,15 @@ describe('ApplicationMemberships resource', () => { const id = TestData.id const params = { fields: {[resourceType]: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken) - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken) + checkCommonParams(request, params) return interceptRequest() }) await clp[resourceType].retrieve(id, params, CommonData.options) + .then((res: ApplicationMembership) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -79,16 +82,18 @@ describe('ApplicationMemberships resource', () => { const params = { fields: { [resourceType]: CommonData.paramsFields } } const resData = { id: TestData.id, ...attributes} - const intId = clp.addRequestInterceptor((config) => { - if (config.method !== 'get') { - expect(config.method).toBe('patch') - checkCommon(config, resourceType, resData.id, currentAccessToken) - checkCommonData(config, resourceType, attributes, resData.id) + const intId = clp.addRequestInterceptor((request) => { + if (request.options.method !== 'GET') { + const data = JSON.parse(String(request.options.body)) + expect(request.options.method).toBe('PATCH') + checkCommon(request, resourceType, resData.id, currentAccessToken) + checkCommonData(data, resourceType, attributes, resData.id) } return interceptRequest() }) await clp[resourceType].update(resData, params, CommonData.options) + .then((res: ApplicationMembership) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -101,9 +106,9 @@ describe('ApplicationMemberships resource', () => { const id = TestData.id - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('delete') - checkCommon(config, resourceType, id, currentAccessToken) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('DELETE') + checkCommon(request, resourceType, id, currentAccessToken) return interceptRequest() }) @@ -120,10 +125,10 @@ describe('ApplicationMemberships resource', () => { const params = CommonData.paramsList - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType) - checkCommonParamsList(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType) + checkCommonParamsList(request, params) return interceptRequest() }) @@ -204,10 +209,10 @@ describe('ApplicationMemberships resource', () => { const id = TestData.id const params = { fields: { api_credentials: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'api_credential') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'api_credential') + checkCommonParams(request, params) return interceptRequest() }) @@ -225,10 +230,10 @@ describe('ApplicationMemberships resource', () => { const id = TestData.id const params = { fields: { memberships: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'membership') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'membership') + checkCommonParams(request, params) return interceptRequest() }) @@ -246,10 +251,10 @@ describe('ApplicationMemberships resource', () => { const id = TestData.id const params = { fields: { organizations: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'organization') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'organization') + checkCommonParams(request, params) return interceptRequest() }) @@ -267,10 +272,10 @@ describe('ApplicationMemberships resource', () => { const id = TestData.id const params = { fields: { roles: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'role') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'role') + checkCommonParams(request, params) return interceptRequest() }) diff --git a/specs/resources/memberships.spec.ts b/specs/resources/memberships.spec.ts index eec6a0f..c2c17a9 100644 --- a/specs/resources/memberships.spec.ts +++ b/specs/resources/memberships.spec.ts @@ -4,7 +4,7 @@ **/ import { CommerceLayerProvisioningClient, Membership } from '../../src' -import { isEqual } from 'lodash' +import isEqual from 'lodash.isequal' // eslint-disable-next-line @typescript-eslint/no-unused-vars import { getClient, TestData, CommonData, handleError, interceptRequest, checkCommon, checkCommonData, checkCommonParamsList, checkCommonParams, currentAccessToken, randomValue } from '../../test/common' @@ -35,15 +35,17 @@ describe('Memberships resource', () => { const params = { fields: { [resourceType]: CommonData.paramsFields } } const resData = attributes - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('post') - checkCommon(config, resourceType) - checkCommonData(config, resourceType, attributes) - expect(clp[resourceType].isMembership(config.data.data)).toBeTruthy() + const intId = clp.addRequestInterceptor((request) => { + const data = JSON.parse(String(request.options.body)) + expect(request.options.method).toBe('POST') + checkCommon(request, resourceType) + checkCommonData(data, resourceType, attributes) + expect(clp[resourceType].isMembership(data.data)).toBeTruthy() return interceptRequest() }) await clp[resourceType].create(resData, params, CommonData.options) + .then((res: Membership) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -57,14 +59,15 @@ describe('Memberships resource', () => { const id = TestData.id const params = { fields: {[resourceType]: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken) - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken) + checkCommonParams(request, params) return interceptRequest() }) await clp[resourceType].retrieve(id, params, CommonData.options) + .then((res: Membership) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -79,16 +82,18 @@ describe('Memberships resource', () => { const params = { fields: { [resourceType]: CommonData.paramsFields } } const resData = { id: TestData.id, ...attributes} - const intId = clp.addRequestInterceptor((config) => { - if (config.method !== 'get') { - expect(config.method).toBe('patch') - checkCommon(config, resourceType, resData.id, currentAccessToken) - checkCommonData(config, resourceType, attributes, resData.id) + const intId = clp.addRequestInterceptor((request) => { + if (request.options.method !== 'GET') { + const data = JSON.parse(String(request.options.body)) + expect(request.options.method).toBe('PATCH') + checkCommon(request, resourceType, resData.id, currentAccessToken) + checkCommonData(data, resourceType, attributes, resData.id) } return interceptRequest() }) await clp[resourceType].update(resData, params, CommonData.options) + .then((res: Membership) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -101,9 +106,9 @@ describe('Memberships resource', () => { const id = TestData.id - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('delete') - checkCommon(config, resourceType, id, currentAccessToken) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('DELETE') + checkCommon(request, resourceType, id, currentAccessToken) return interceptRequest() }) @@ -120,10 +125,10 @@ describe('Memberships resource', () => { const params = CommonData.paramsList - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType) - checkCommonParamsList(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType) + checkCommonParamsList(request, params) return interceptRequest() }) @@ -204,10 +209,10 @@ describe('Memberships resource', () => { const id = TestData.id const params = { fields: { organizations: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'organization') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'organization') + checkCommonParams(request, params) return interceptRequest() }) @@ -225,10 +230,10 @@ describe('Memberships resource', () => { const id = TestData.id const params = { fields: { roles: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'role') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'role') + checkCommonParams(request, params) return interceptRequest() }) @@ -246,10 +251,10 @@ describe('Memberships resource', () => { const id = TestData.id const params = { fields: { application_memberships: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'application_memberships') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'application_memberships') + checkCommonParams(request, params) return interceptRequest() }) @@ -267,10 +272,10 @@ describe('Memberships resource', () => { const id = TestData.id const params = { fields: { versions: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'versions') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'versions') + checkCommonParams(request, params) return interceptRequest() }) diff --git a/specs/resources/organizations.spec.ts b/specs/resources/organizations.spec.ts index 84284b9..e6ad43f 100644 --- a/specs/resources/organizations.spec.ts +++ b/specs/resources/organizations.spec.ts @@ -4,7 +4,7 @@ **/ import { CommerceLayerProvisioningClient, Organization } from '../../src' -import { isEqual } from 'lodash' +import isEqual from 'lodash.isequal' // eslint-disable-next-line @typescript-eslint/no-unused-vars import { getClient, TestData, CommonData, handleError, interceptRequest, checkCommon, checkCommonData, checkCommonParamsList, checkCommonParams, currentAccessToken, randomValue } from '../../test/common' @@ -32,15 +32,17 @@ describe('Organizations resource', () => { const params = { fields: { [resourceType]: CommonData.paramsFields } } const resData = attributes - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('post') - checkCommon(config, resourceType) - checkCommonData(config, resourceType, attributes) - expect(clp[resourceType].isOrganization(config.data.data)).toBeTruthy() + const intId = clp.addRequestInterceptor((request) => { + const data = JSON.parse(String(request.options.body)) + expect(request.options.method).toBe('POST') + checkCommon(request, resourceType) + checkCommonData(data, resourceType, attributes) + expect(clp[resourceType].isOrganization(data.data)).toBeTruthy() return interceptRequest() }) await clp[resourceType].create(resData, params, CommonData.options) + .then((res: Organization) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -54,14 +56,15 @@ describe('Organizations resource', () => { const id = TestData.id const params = { fields: {[resourceType]: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken) - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken) + checkCommonParams(request, params) return interceptRequest() }) await clp[resourceType].retrieve(id, params, CommonData.options) + .then((res: Organization) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -76,16 +79,18 @@ describe('Organizations resource', () => { const params = { fields: { [resourceType]: CommonData.paramsFields } } const resData = { id: TestData.id, ...attributes} - const intId = clp.addRequestInterceptor((config) => { - if (config.method !== 'get') { - expect(config.method).toBe('patch') - checkCommon(config, resourceType, resData.id, currentAccessToken) - checkCommonData(config, resourceType, attributes, resData.id) + const intId = clp.addRequestInterceptor((request) => { + if (request.options.method !== 'GET') { + const data = JSON.parse(String(request.options.body)) + expect(request.options.method).toBe('PATCH') + checkCommon(request, resourceType, resData.id, currentAccessToken) + checkCommonData(data, resourceType, attributes, resData.id) } return interceptRequest() }) await clp[resourceType].update(resData, params, CommonData.options) + .then((res: Organization) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -98,10 +103,10 @@ describe('Organizations resource', () => { const params = CommonData.paramsList - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType) - checkCommonParamsList(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType) + checkCommonParamsList(request, params) return interceptRequest() }) @@ -182,10 +187,10 @@ describe('Organizations resource', () => { const id = TestData.id const params = { fields: { memberships: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'memberships') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'memberships') + checkCommonParams(request, params) return interceptRequest() }) @@ -203,10 +208,10 @@ describe('Organizations resource', () => { const id = TestData.id const params = { fields: { roles: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'roles') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'roles') + checkCommonParams(request, params) return interceptRequest() }) @@ -224,10 +229,10 @@ describe('Organizations resource', () => { const id = TestData.id const params = { fields: { permissions: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'permissions') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'permissions') + checkCommonParams(request, params) return interceptRequest() }) @@ -245,10 +250,10 @@ describe('Organizations resource', () => { const id = TestData.id const params = { fields: { api_credentials: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'api_credentials') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'api_credentials') + checkCommonParams(request, params) return interceptRequest() }) diff --git a/specs/resources/permissions.spec.ts b/specs/resources/permissions.spec.ts index 0751074..7094b55 100644 --- a/specs/resources/permissions.spec.ts +++ b/specs/resources/permissions.spec.ts @@ -4,7 +4,7 @@ **/ import { CommerceLayerProvisioningClient, Permission } from '../../src' -import { isEqual } from 'lodash' +import isEqual from 'lodash.isequal' // eslint-disable-next-line @typescript-eslint/no-unused-vars import { getClient, TestData, CommonData, handleError, interceptRequest, checkCommon, checkCommonData, checkCommonParamsList, checkCommonParams, currentAccessToken, randomValue } from '../../test/common' @@ -37,15 +37,17 @@ describe('Permissions resource', () => { const params = { fields: { [resourceType]: CommonData.paramsFields } } const resData = attributes - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('post') - checkCommon(config, resourceType) - checkCommonData(config, resourceType, attributes) - expect(clp[resourceType].isPermission(config.data.data)).toBeTruthy() + const intId = clp.addRequestInterceptor((request) => { + const data = JSON.parse(String(request.options.body)) + expect(request.options.method).toBe('POST') + checkCommon(request, resourceType) + checkCommonData(data, resourceType, attributes) + expect(clp[resourceType].isPermission(data.data)).toBeTruthy() return interceptRequest() }) await clp[resourceType].create(resData, params, CommonData.options) + .then((res: Permission) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -59,14 +61,15 @@ describe('Permissions resource', () => { const id = TestData.id const params = { fields: {[resourceType]: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken) - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken) + checkCommonParams(request, params) return interceptRequest() }) await clp[resourceType].retrieve(id, params, CommonData.options) + .then((res: Permission) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -81,16 +84,18 @@ describe('Permissions resource', () => { const params = { fields: { [resourceType]: CommonData.paramsFields } } const resData = { id: TestData.id, ...attributes} - const intId = clp.addRequestInterceptor((config) => { - if (config.method !== 'get') { - expect(config.method).toBe('patch') - checkCommon(config, resourceType, resData.id, currentAccessToken) - checkCommonData(config, resourceType, attributes, resData.id) + const intId = clp.addRequestInterceptor((request) => { + if (request.options.method !== 'GET') { + const data = JSON.parse(String(request.options.body)) + expect(request.options.method).toBe('PATCH') + checkCommon(request, resourceType, resData.id, currentAccessToken) + checkCommonData(data, resourceType, attributes, resData.id) } return interceptRequest() }) await clp[resourceType].update(resData, params, CommonData.options) + .then((res: Permission) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -103,10 +108,10 @@ describe('Permissions resource', () => { const params = CommonData.paramsList - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType) - checkCommonParamsList(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType) + checkCommonParamsList(request, params) return interceptRequest() }) @@ -187,10 +192,10 @@ describe('Permissions resource', () => { const id = TestData.id const params = { fields: { organizations: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'organization') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'organization') + checkCommonParams(request, params) return interceptRequest() }) @@ -208,10 +213,10 @@ describe('Permissions resource', () => { const id = TestData.id const params = { fields: { roles: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'role') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'role') + checkCommonParams(request, params) return interceptRequest() }) @@ -229,10 +234,10 @@ describe('Permissions resource', () => { const id = TestData.id const params = { fields: { versions: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'versions') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'versions') + checkCommonParams(request, params) return interceptRequest() }) diff --git a/specs/resources/roles.spec.ts b/specs/resources/roles.spec.ts index 486decf..4ea3571 100644 --- a/specs/resources/roles.spec.ts +++ b/specs/resources/roles.spec.ts @@ -4,7 +4,7 @@ **/ import { CommerceLayerProvisioningClient, Role } from '../../src' -import { isEqual } from 'lodash' +import isEqual from 'lodash.isequal' // eslint-disable-next-line @typescript-eslint/no-unused-vars import { getClient, TestData, CommonData, handleError, interceptRequest, checkCommon, checkCommonData, checkCommonParamsList, checkCommonParams, currentAccessToken, randomValue } from '../../test/common' @@ -33,15 +33,17 @@ describe('Roles resource', () => { const params = { fields: { [resourceType]: CommonData.paramsFields } } const resData = attributes - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('post') - checkCommon(config, resourceType) - checkCommonData(config, resourceType, attributes) - expect(clp[resourceType].isRole(config.data.data)).toBeTruthy() + const intId = clp.addRequestInterceptor((request) => { + const data = JSON.parse(String(request.options.body)) + expect(request.options.method).toBe('POST') + checkCommon(request, resourceType) + checkCommonData(data, resourceType, attributes) + expect(clp[resourceType].isRole(data.data)).toBeTruthy() return interceptRequest() }) await clp[resourceType].create(resData, params, CommonData.options) + .then((res: Role) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -55,14 +57,15 @@ describe('Roles resource', () => { const id = TestData.id const params = { fields: {[resourceType]: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken) - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken) + checkCommonParams(request, params) return interceptRequest() }) await clp[resourceType].retrieve(id, params, CommonData.options) + .then((res: Role) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -77,16 +80,18 @@ describe('Roles resource', () => { const params = { fields: { [resourceType]: CommonData.paramsFields } } const resData = { id: TestData.id, ...attributes} - const intId = clp.addRequestInterceptor((config) => { - if (config.method !== 'get') { - expect(config.method).toBe('patch') - checkCommon(config, resourceType, resData.id, currentAccessToken) - checkCommonData(config, resourceType, attributes, resData.id) + const intId = clp.addRequestInterceptor((request) => { + if (request.options.method !== 'GET') { + const data = JSON.parse(String(request.options.body)) + expect(request.options.method).toBe('PATCH') + checkCommon(request, resourceType, resData.id, currentAccessToken) + checkCommonData(data, resourceType, attributes, resData.id) } return interceptRequest() }) await clp[resourceType].update(resData, params, CommonData.options) + .then((res: Role) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -99,10 +104,10 @@ describe('Roles resource', () => { const params = CommonData.paramsList - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType) - checkCommonParamsList(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType) + checkCommonParamsList(request, params) return interceptRequest() }) @@ -183,10 +188,10 @@ describe('Roles resource', () => { const id = TestData.id const params = { fields: { organizations: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'organization') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'organization') + checkCommonParams(request, params) return interceptRequest() }) @@ -204,10 +209,10 @@ describe('Roles resource', () => { const id = TestData.id const params = { fields: { permissions: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'permissions') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'permissions') + checkCommonParams(request, params) return interceptRequest() }) @@ -225,10 +230,10 @@ describe('Roles resource', () => { const id = TestData.id const params = { fields: { memberships: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'memberships') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'memberships') + checkCommonParams(request, params) return interceptRequest() }) @@ -246,10 +251,10 @@ describe('Roles resource', () => { const id = TestData.id const params = { fields: { api_credentials: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'api_credentials') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'api_credentials') + checkCommonParams(request, params) return interceptRequest() }) @@ -267,10 +272,10 @@ describe('Roles resource', () => { const id = TestData.id const params = { fields: { versions: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken, 'versions') - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken, 'versions') + checkCommonParams(request, params) return interceptRequest() }) diff --git a/specs/resources/user.spec.ts b/specs/resources/user.spec.ts index 7b50822..5b4f632 100644 --- a/specs/resources/user.spec.ts +++ b/specs/resources/user.spec.ts @@ -4,7 +4,7 @@ **/ import { CommerceLayerProvisioningClient, User } from '../../src' -import { isEqual } from 'lodash' +import isEqual from 'lodash.isequal' // eslint-disable-next-line @typescript-eslint/no-unused-vars import { getClient, TestData, CommonData, handleError, interceptRequest, checkCommon, checkCommonData, checkCommonParamsList, checkCommonParams, currentAccessToken, randomValue } from '../../test/common' @@ -28,16 +28,18 @@ describe('Users resource', () => { const params = { fields: { [resourceType]: CommonData.paramsFields } } const resData = { id: TestData.id, ...attributes} - const intId = clp.addRequestInterceptor((config) => { - if (config.method !== 'get') { - expect(config.method).toBe('patch') - checkCommon(config, resourceType, resData.id, currentAccessToken) - checkCommonData(config, resourceType, attributes, resData.id) + const intId = clp.addRequestInterceptor((request) => { + if (request.options.method !== 'GET') { + const data = JSON.parse(String(request.options.body)) + expect(request.options.method).toBe('PATCH') + checkCommon(request, resourceType, resData.id, currentAccessToken) + checkCommonData(data, resourceType, attributes, resData.id) } return interceptRequest() }) await clp[resourceType].update(resData, params, CommonData.options) + .then((res: User) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -50,10 +52,10 @@ describe('Users resource', () => { const params = { fields: { [resourceType]: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType) - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType) + checkCommonParams(request, params) return interceptRequest() }) diff --git a/specs/resources/versions.spec.ts b/specs/resources/versions.spec.ts index a23b286..9df8e86 100644 --- a/specs/resources/versions.spec.ts +++ b/specs/resources/versions.spec.ts @@ -4,7 +4,7 @@ **/ import { CommerceLayerProvisioningClient, Version } from '../../src' -import { isEqual } from 'lodash' +import isEqual from 'lodash.isequal' // eslint-disable-next-line @typescript-eslint/no-unused-vars import { getClient, TestData, CommonData, handleError, interceptRequest, checkCommon, checkCommonData, checkCommonParamsList, checkCommonParams, currentAccessToken, randomValue } from '../../test/common' @@ -27,14 +27,15 @@ describe('Versions resource', () => { const id = TestData.id const params = { fields: {[resourceType]: CommonData.paramsFields } } - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType, id, currentAccessToken) - checkCommonParams(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType, id, currentAccessToken) + checkCommonParams(request, params) return interceptRequest() }) await clp[resourceType].retrieve(id, params, CommonData.options) + .then((res: Version) => expect(res).not.toBeNull()) .catch(handleError) .finally(() => clp.removeInterceptor('request', intId)) @@ -47,10 +48,10 @@ describe('Versions resource', () => { const params = CommonData.paramsList - const intId = clp.addRequestInterceptor((config) => { - expect(config.method).toBe('get') - checkCommon(config, resourceType) - checkCommonParamsList(config, params) + const intId = clp.addRequestInterceptor((request) => { + expect(request.options.method).toBe('GET') + checkCommon(request, resourceType) + checkCommonParamsList(request, params) return interceptRequest() }) diff --git a/specs/sdk.spec.ts b/specs/sdk.spec.ts index d5a5091..e9ff479 100644 --- a/specs/sdk.spec.ts +++ b/specs/sdk.spec.ts @@ -2,7 +2,8 @@ import { CommerceLayerProvisioningClient, Role } from '../src' import { sleep, sortObjectFields } from '../src/util' import { getClient, TestData } from '../test/common' -import { ObjectType, isResourceType } from '../src/common' +import { isResourceType } from '../src/common' +import type { ObjectType } from '../src/types' let clp: CommerceLayerProvisioningClient diff --git a/src/api.ts b/src/api.ts index 4c8c507..fc59c2a 100644 --- a/src/api.ts +++ b/src/api.ts @@ -1,5 +1,6 @@ import type { Resource, ResourceRel } from './resource' import type { VersionType } from './resources/versions' +import type * as models from './model' // ##__API_RESOURCES_START__## // ##__API_RESOURCES_TEMPLATE:: export { default as ##__RESOURCE_CLASS__## } from './resources/##__RESOURCE_TYPE__##' @@ -128,3 +129,32 @@ export type VersionableResource = Resource & { type: VersionableResourceType, versions?: Array | null } + + + +export type ResourceFields = { + // ##__API_RESOURCE_FIELDS_START__## + api_credentials: models.ApiCredential, + application_memberships: models.ApplicationMembership, + memberships: models.Membership, + organizations: models.Organization, + permissions: models.Permission, + roles: models.Role, + user: models.User, + versions: models.Version + // ##__API_RESOURCE_FIELDS_STOP__## +} + + +export type ResourceSortFields = { + // ##__API_RESOURCE_SORTABLE_FIELDS_START__## + api_credentials: models.ApiCredentialSort, + application_memberships: models.ApplicationMembershipSort, + memberships: models.MembershipSort, + organizations: models.OrganizationSort, + permissions: models.PermissionSort, + roles: models.RoleSort, + user: models.UserSort, + versions: models.VersionSort + // ##__API_RESOURCE_SORTABLE_FIELDS_STOP__## +} diff --git a/src/client.ts b/src/client.ts index 518bbb3..643259e 100644 --- a/src/client.ts +++ b/src/client.ts @@ -1,12 +1,9 @@ - -import axios from 'axios' -import type { AxiosAdapter, CreateAxiosDefaults, AxiosInstance, AxiosProxyConfig, Method } from 'axios' import { SdkError, handleError } from './error' import type { InterceptorManager } from './interceptor' import config from './config' -import type { Agent as HttpAgent } from 'http' -import type { Agent as HttpsAgent } from 'https' -// import { packageInfo } from './util' +import type { FetchResponse, FetchRequestOptions, FetchClientOptions, Fetch } from './fetch' +import { fetchURL } from './fetch' + import Debug from './debug' const debug = Debug('client') @@ -18,36 +15,32 @@ const baseURL = (domain?: string): string => { } -type ProxyConfig = AxiosProxyConfig | false -type Adapter = AxiosAdapter - type RequestParams = Record type RequestHeaders = Record -// Subset of AxiosRequestConfig + type RequestConfig = { timeout?: number params?: RequestParams - httpAgent?: HttpAgent - httpsAgent?: HttpsAgent - proxy?: ProxyConfig headers?: RequestHeaders -} - -type RequestConfigExtra = { - adapter?: Adapter userAgent?: string + fetch?: Fetch } + type ApiConfig = { domain?: string, accessToken: string } -type ApiClientInitConfig = ApiConfig & RequestConfig & RequestConfigExtra +type ApiClientInitConfig = ApiConfig & RequestConfig type ApiClientConfig = Partial +export type Method = 'GET' | 'DELETE' | 'POST' | 'PUT' | 'PATCH' + + + class ApiClient { static create(options: ApiClientInitConfig): ApiClient { @@ -56,31 +49,29 @@ class ApiClient { return new ApiClient(options) } - baseUrl: string + + #baseUrl: string #accessToken: string - readonly #client: AxiosInstance + readonly #clientConfig: RequestConfig + readonly #interceptors: InterceptorManager - public interceptors: InterceptorManager private constructor(options: ApiClientInitConfig) { debug('new client instance %O', options) - this.baseUrl = baseURL(options.domain) + this.#baseUrl = baseURL(options.domain) this.#accessToken = options.accessToken - const axiosConfig: RequestConfig = { + const fetchConfig: RequestConfig = { timeout: options.timeout || config.client.timeout, - proxy: options.proxy, - httpAgent: options.httpAgent, - httpsAgent: options.httpsAgent } // Set custom headers const customHeaders = this.customHeaders(options.headers) // Set headers - const headers: any = { + const headers: RequestHeaders = { ...customHeaders, 'Accept': 'application/vnd.api+json', 'Content-Type': 'application/vnd.api+json', @@ -88,52 +79,56 @@ class ApiClient { } // Set User-Agent - let userAgent = options.userAgent // || `SDK-provisioning axios/${axios.VERSION}` - if (userAgent) { - if (!userAgent.includes('axios/')) userAgent += ` axios/${axios.VERSION}` - headers['User-Agent'] = userAgent - } + const userAgent = options.userAgent + if (userAgent) headers['User-Agent'] = userAgent - const axiosOptions: CreateAxiosDefaults = { - baseURL: this.baseUrl, - timeout: config.client.timeout, - headers, - ...axiosConfig - } + fetchConfig.headers = headers - if (options.adapter) axiosOptions.adapter = options.adapter + this.#clientConfig = fetchConfig - debug('axios options: %O', axiosOptions) + debug('fetch config: %O', fetchConfig) - this.#client = axios.create(axiosOptions) + // Interceptors + this.#interceptors = {} + + } - this.interceptors = this.#client.interceptors + get interceptors(): InterceptorManager { return this.#interceptors } + + get requestHeaders(): RequestHeaders { + if (!this.#clientConfig.headers) this.#clientConfig.headers = {} + return this.#clientConfig.headers } + /* + set requestHeaders(headers: RequestHeaders) { + this.#clientConfig.headers = { ...this.#clientConfig.headers, ...headers } + } + */ + + config(config: ApiClientConfig): this { debug('config %o', config) - const def = this.#client.defaults + const def = this.#clientConfig + if (!def.headers) def.headers = {} - // Axios config + // Client config if (config.timeout) def.timeout = config.timeout - if (config.proxy) def.proxy = config.proxy - if (config.httpAgent) def.httpAgent = config.httpAgent - if (config.httpsAgent) def.httpsAgent = config.httpsAgent - if (config.adapter) this.adapter(config.adapter) if (config.userAgent) this.userAgent(config.userAgent) - + if (config.fetch) this.#clientConfig.fetch = config.fetch // API Client config + if (config.domain) this.#baseUrl = baseURL(config.domain) if (config.accessToken) { this.#accessToken = config.accessToken - def.headers.common.Authorization = 'Bearer ' + this.#accessToken; + def.headers.Authorization = 'Bearer ' + this.#accessToken } - if (config.headers) def.headers.common = this.customHeaders(config.headers) + if (config.headers) def.headers = { ...def.headers, ...this.customHeaders(config.headers) } return this @@ -141,50 +136,49 @@ class ApiClient { userAgent(userAgent: string): this { - if (userAgent) { - let ua = userAgent - if (!ua.includes('axios/')) { - // const axiosVer = packageInfo(['dependencies.axios'], { nestedName: true }) - if (axios.VERSION) ua += ` axios/${axios.VERSION}` - } - this.#client.defaults.headers['User-Agent'] = ua - } - return this - } - - - adapter(adapter: Adapter): this { - if (adapter) this.#client.defaults.adapter = adapter + if (userAgent) this.requestHeaders['User-Agent'] = userAgent return this } - async request(method: Method, path: string, body?: any, options?: ApiClientConfig): Promise { + async request(method: Method, path: string, body?: any, options?: ApiClientConfig): Promise { debug('request %s %s, %O, %O', method, path, body || {}, options || {}) - // Ignored params alerts (in debug mode) - if (options?.adapter) debug('Adapter ignored in request config') + // Ignored params (in debug mode) if (options?.userAgent) debug('User-Agent header ignored in request config') - const data = body ? { data: body } : undefined - const url = path + // URL + const baseUrl = options?.domain ? baseURL(options.domain) : this.#baseUrl + const url = new URL(`${baseUrl}/${path}`) - // Runtime request parameters - const accessToken = options?.accessToken || this.#accessToken + // Body + const bodyData = body ? JSON.stringify({ data: body }) : undefined + + // Headers + const headers = { ...this.requestHeaders, ...this.customHeaders(options?.headers) } - const headers = this.customHeaders(options?.headers) + // Access token + const accessToken = options?.accessToken || this.#accessToken if (accessToken) headers.Authorization = 'Bearer ' + accessToken - const requestParams = { method, url, data, ...options, headers } + const requestOptions: FetchRequestOptions = { method, body: bodyData, headers } + + // Timeout + const timeout = options?.timeout || this.#clientConfig.timeout + if (timeout) requestOptions.signal = AbortSignal.timeout(timeout) - debug('request params: %O', requestParams) + if (options?.params) Object.entries(options?.params).forEach(([name, value]) => { url.searchParams.append(name, String(value)) }) + + const clientOptions: FetchClientOptions = { + interceptors: this.interceptors, + fetch: options?.fetch || this.#clientConfig.fetch + } // const start = Date.now() - return this.#client.request(requestParams) - .then(response => response.data) + return await fetchURL(url, requestOptions, clientOptions) .catch((error: Error) => handleError(error)) - // .finally(() => console.log(`<<-- ${method} ${path} ${Date.now() - start}`)) + // .finally(() => { console.log(`<<-- ${method} ${path} ${Date.now() - start}`) }) } diff --git a/src/commercelayer.ts b/src/commercelayer.ts index 48299d1..f81efc2 100644 --- a/src/commercelayer.ts +++ b/src/commercelayer.ts @@ -1,7 +1,7 @@ import * as api from './api' import type { ApiError } from './error' -import type { ErrorInterceptor, InterceptorType, RawResponseReader, RequestInterceptor, ResponseInterceptor, ResponseObj, HeadersObj } from './interceptor' +import type { ErrorInterceptor, InterceptorType, RawResponseReader, RequestInterceptor, ResponseInterceptor, ResponseObj, HeadersObj, InterceptorManager } from './interceptor' import { CommerceLayerProvisioningStatic } from './static' import ResourceAdapter, { type ResourcesInitConfig } from './resource' @@ -33,15 +33,15 @@ class CommerceLayerProvisioningClient { // #environment: ApiMode = sdkConfig.default.environment // ##__CL_RESOURCES_DEF_START__## - // ##__CL_RESOURCES_DEF_TEMPLATE:: ##__TAB__####__RESOURCE_TYPE__##: api.##__RESOURCE_CLASS__## - api_credentials: api.ApiCredentials - application_memberships: api.ApplicationMemberships - memberships: api.Memberships - organizations: api.Organizations - permissions: api.Permissions - roles: api.Roles - user: api.Users - versions: api.Versions + // ##__CL_RESOURCES_DEF_TEMPLATE:: ##__TAB__#####__RESOURCE_TYPE__##?: api.##__RESOURCE_CLASS__## + #api_credentials?: api.ApiCredentials + #application_memberships?: api.ApplicationMemberships + #memberships?: api.Memberships + #organizations?: api.Organizations + #permissions?: api.Permissions + #roles?: api.Roles + #user?: api.Users + #versions?: api.Versions // ##__CL_RESOURCES_DEF_STOP__## @@ -54,26 +54,27 @@ class CommerceLayerProvisioningClient { // ##__CL_RESOURCES_INIT_START__## // ##__CL_RESOURCES_INIT_TEMPLATE:: ##__TAB__####__TAB__##this.##__RESOURCE_TYPE__## = new api.##__RESOURCE_CLASS__##(this.#adapter) - this.api_credentials = new api.ApiCredentials(this.#adapter) - this.application_memberships = new api.ApplicationMemberships(this.#adapter) - this.memberships = new api.Memberships(this.#adapter) - this.organizations = new api.Organizations(this.#adapter) - this.permissions = new api.Permissions(this.#adapter) - this.roles = new api.Roles(this.#adapter) - this.user = new api.Users(this.#adapter) - this.versions = new api.Versions(this.#adapter) // ##__CL_RESOURCES_INIT_STOP__## } // ##__CL_RESOURCES_LEAZY_LOADING_START__## // ##__CL_RESOURCES_LEAZY_LOADING_TEMPLATE:: ##__TAB__##get ##__RESOURCE_TYPE__##(): api.##__RESOURCE_CLASS__## { return this.###__RESOURCE_TYPE__## || (this.###__RESOURCE_TYPE__## = new api.##__RESOURCE_CLASS__##(this.#adapter)) } + get api_credentials(): api.ApiCredentials { return this.#api_credentials || (this.#api_credentials = new api.ApiCredentials(this.#adapter)) } + get application_memberships(): api.ApplicationMemberships { return this.#application_memberships || (this.#application_memberships = new api.ApplicationMemberships(this.#adapter)) } + get memberships(): api.Memberships { return this.#memberships || (this.#memberships = new api.Memberships(this.#adapter)) } + get organizations(): api.Organizations { return this.#organizations || (this.#organizations = new api.Organizations(this.#adapter)) } + get permissions(): api.Permissions { return this.#permissions || (this.#permissions = new api.Permissions(this.#adapter)) } + get roles(): api.Roles { return this.#roles || (this.#roles = new api.Roles(this.#adapter)) } + get user(): api.Users { return this.#user || (this.#user = new api.Users(this.#adapter)) } + get versions(): api.Versions { return this.#versions || (this.#versions = new api.Versions(this.#adapter)) } // ##__CL_RESOURCES_LEAZY_LOADING_STOP__## // get environment(): ApiMode { return this.#environment } + private get interceptors(): InterceptorManager { return this.#adapter.client.interceptors } private localConfig(config: SdkConfig): void { - + // } @@ -102,50 +103,61 @@ class CommerceLayerProvisioningClient { isSingleton(resource: api.ResourceTypeLock): boolean { return CommerceLayerProvisioningStatic.isSingleton(resource) } - + isApiError(error: any): error is ApiError { return CommerceLayerProvisioningStatic.isApiError(error) } - addRequestInterceptor(onFulfilled?: RequestInterceptor, onRejected?: ErrorInterceptor): number { - return this.#adapter.interceptors.request.use(onFulfilled, onRejected) + addRequestInterceptor(onSuccess?: RequestInterceptor, onFailure?: ErrorInterceptor): number { + this.interceptors.request = { onSuccess, onFailure } + return 1 } - addResponseInterceptor(onFulfilled?: ResponseInterceptor, onRejected?: ErrorInterceptor): number { - return this.#adapter.interceptors.response.use(onFulfilled, onRejected) + addResponseInterceptor(onSuccess?: ResponseInterceptor, onFailure?: ErrorInterceptor): number { + this.interceptors.response = { onSuccess, onFailure } + return 1 } - removeInterceptor(type: InterceptorType, id: number): void { - this.#adapter.interceptors[type].eject(id) + removeInterceptor(type: InterceptorType, id: number = 1): void { + this.interceptors[type] = undefined } addRawResponseReader(options?: { headers: boolean }): RawResponseReader { const reader: RawResponseReader = { - id: undefined, + id: 0, rawResponse: undefined, headers: undefined, + ok: true } - function rawResponseInterceptor(response: ResponseObj): ResponseObj { - reader.rawResponse = response?.data - if (options?.headers) reader.headers = (response.headers as HeadersObj) + async function rawResponseInterceptor(response: ResponseObj): Promise { + reader.rawResponse = await response?.clone().json().catch(() => {}) + reader.ok = response.ok + if (options?.headers) { + const ho: HeadersObj = {} + response.headers.forEach((value, key) => { ho[key] = value }) + reader.headers = ho + } return response } - const interceptor = this.addResponseInterceptor(rawResponseInterceptor) - reader.id = interceptor + /* const interceptor = */this.interceptors.rawReader = { onSuccess: rawResponseInterceptor, onFailure: rawResponseInterceptor } + reader.id = 1 // interceptor return reader } - removeRawResponseReader(reader: number | RawResponseReader): void { + removeRawResponseReader(reader: number | RawResponseReader = 1): void { + /* const id = (typeof reader === 'number') ? reader : reader?.id if (id && (id >= 0)) this.removeInterceptor('response', id) + */ + this.interceptors.rawReader = undefined } } diff --git a/src/common.ts b/src/common.ts index 25d9249..14736f6 100644 --- a/src/common.ts +++ b/src/common.ts @@ -12,6 +12,3 @@ const isResourceType = (resource: any): resource is ResourceType => { export { isResourceId, isResourceType } - - -export type ObjectType = Record diff --git a/src/error.ts b/src/error.ts index 73ec7e7..b7398b3 100644 --- a/src/error.ts +++ b/src/error.ts @@ -1,12 +1,14 @@ -import axios from 'axios' +import { FetchError } from './fetch' + enum ErrorType { - CLIENT = 'client', // Error instantiating the client - REQUEST = 'request', // Error preparing API request - RESPONSE = 'response', // Error response from API - CANCEL = 'cancel', // Forced request abort using interceptor - PARSE = 'parse', // Error parsing API resource - GENERIC = 'generic', // Other not specified errors + + CLIENT = 'client', // Generic Client error + REQUEST = 'request', // Error preparing API request + RESPONSE = 'response', // Error response from API + CANCEL = 'cancel', // Forced request abort using interceptor + PARSE = 'parse', // Error parsing API resource + TIMEOUT = 'timeout' // Timeout error } @@ -21,12 +23,11 @@ class SdkError extends Error { type: ErrorType code?: string source?: Error - request?: any constructor(error: { message: string, type?: ErrorType }) { super(error.message) - this.name = SdkError.NAME// this.constructor.name - this.type = error.type || ErrorType.GENERIC + this.name = SdkError.NAME + this.type = error.type || ErrorType.CLIENT } } @@ -46,7 +47,7 @@ class ApiError extends SdkError { constructor(error: SdkError) constructor(error: { message: string }) { super({ ...error, type: ErrorType.RESPONSE }) - this.name = ApiError.NAME// this.constructor.name + this.name = ApiError.NAME } first(): any { @@ -56,33 +57,46 @@ class ApiError extends SdkError { } +const isRequestError = (error: any): error is TypeError => { + return error instanceof TypeError +} + +const isCancelError = (error: any): boolean => { + return (error instanceof DOMException) && (error.name === 'AbortError') +} + +const isTimeoutError = (error: any): boolean => { + return (error instanceof DOMException) && (error.name === 'TimeoutError') +} + const handleError = (error: Error): never => { let sdkError = new SdkError({ message: error.message }) - if (axios.isAxiosError(error)) { - if (error.response) { - // The request was made and the server responded with a status code that falls out of the range of 2xx - const apiError = new ApiError(sdkError) - apiError.type = ErrorType.RESPONSE - apiError.status = error.response.status - apiError.statusText = error.response.statusText - apiError.code = String(apiError.status) - apiError.errors = error.response.data.errors - if (!apiError.message && apiError.statusText) apiError.message = apiError.statusText - sdkError = apiError - } else if (error.request) { - // The request was made but no response was received - // `error.request` is an instance of XMLHttpRequest in the browser and an instance of http.ClientRequest in node.js - sdkError.type = ErrorType.REQUEST - sdkError.request = error.request - } else { - // Something happened in setting up the request that triggered an Error - sdkError.type = ErrorType.CLIENT - } - } else if (axios.isCancel(error)) sdkError.type = ErrorType.CANCEL - else sdkError.source = error + if (FetchError.isFetchError(error)) { + const apiError = new ApiError(sdkError) + apiError.type = ErrorType.RESPONSE + apiError.status = error.status + apiError.statusText = error.statusText + apiError.code = String(apiError.status) + apiError.errors = error.errors || [] + if (!apiError.message && apiError.statusText) apiError.message = apiError.statusText + sdkError = apiError + } + else if (isRequestError(error)) { + sdkError.type = ErrorType.REQUEST + } + else if (isCancelError(error)) { + sdkError.type = ErrorType.CANCEL + } + else if (isTimeoutError(error)) { + sdkError.type = ErrorType.TIMEOUT + } + else { + sdkError.type = ErrorType.CLIENT + sdkError.source = error + } throw sdkError diff --git a/src/fetch.ts b/src/fetch.ts new file mode 100644 index 0000000..29eb04f --- /dev/null +++ b/src/fetch.ts @@ -0,0 +1,79 @@ + +import type { DocWithData } from 'jsonapi-typescript' +import type { InterceptorManager } from './interceptor' + + +import Debug from './debug' +const debug = Debug('fetch') + + +export type Fetch = (input: string | URL | Request, init?: RequestInit) => Promise + +export type FetchResponse = DocWithData +export type FetchRequestOptions = RequestInit +export type FetchClientOptions = { + interceptors?: InterceptorManager, + fetch?: Fetch +} + + +export class FetchError extends Error { + + static isFetchError = (error: any): error is FetchError => { + return error instanceof FetchError + } + + readonly #errors?: any[] + readonly #status: number + readonly #statusText: string + + constructor(status: number, statusText: string, body?: any) { + super(statusText) + this.#status = status + this.#statusText = statusText + if (body) this.#errors = body.errors + } + + + get errors(): any[] | undefined { return this.#errors } + + get status(): number { return this.#status } + + get statusText(): string { return this.#statusText } + +} + + + +export const fetchURL = async (url: URL, requestOptions: FetchRequestOptions, clientOptions?: FetchClientOptions): Promise => { + + debug('fetch: %s, %O, native[%s]', url, requestOptions || {}, (clientOptions?.fetch? 'no' : 'yes')) + + const interceptors = clientOptions?.interceptors + + if (interceptors?.request?.onSuccess) ( { url, options: requestOptions } = await interceptors.request.onSuccess({ url, options: requestOptions }) ) + + // const request: Request = new Request(url, requestOptions) + + const fetchClient = clientOptions?.fetch || fetch + + let response = await fetchClient(url, requestOptions) + + if (response.ok) { + if (interceptors?.rawReader?.onSuccess) await interceptors.rawReader.onSuccess(response) + if (interceptors?.response?.onSuccess) response = await interceptors.response.onSuccess(response) + } else { + if (interceptors?.rawReader?.onFailure) await interceptors.rawReader.onFailure(response) + } + + const responseBody = await response.json().catch(() => {}) + + if (!response.ok) { + let error = new FetchError(response.status, response.statusText, responseBody) + if (interceptors?.response?.onFailure) error = await interceptors.response.onFailure(error) + if (error) throw error + } + + return responseBody + +} \ No newline at end of file diff --git a/src/interceptor.ts b/src/interceptor.ts index 2422b53..c99faf7 100644 --- a/src/interceptor.ts +++ b/src/interceptor.ts @@ -1,29 +1,39 @@ +import type { FetchError, FetchRequestOptions } from "./fetch" + +type InterceptorEventManager = { + onSuccess?: S + onFailure?: F +} -import type { AxiosError, AxiosInterceptorManager, AxiosRequestConfig, AxiosResponse, AxiosResponseHeaders, RawAxiosResponseHeaders } from 'axios' + +type RequestEventManager = InterceptorEventManager +type ResponseEventManager = InterceptorEventManager +type ErrorEventManager = InterceptorEventManager type InterceptorManager = { - request: AxiosInterceptorManager; - response: AxiosInterceptorManager + request?: RequestEventManager + response?: ResponseEventManager + rawReader?: ErrorEventManager } // Request -type RequestObj = AxiosRequestConfig +type RequestObj = { url: URL, options: FetchRequestOptions } type RequestInterceptor = (request: RequestObj) => RequestObj | Promise // Response -type ResponseObj = AxiosResponse -type ResponseInterceptor = (response: ResponseObj) => ResponseObj +type ResponseObj = Response +type ResponseInterceptor = (response: ResponseObj) => ResponseObj | Promise // Headers type ApiHeadersList = 'x-ratelimit-limit' | 'x-ratelimit-count' | 'x-ratelimit-period' | 'x-ratelimit-interval' | 'x-ratelimit-remaining' type ApiHeaders = { [key in ApiHeadersList]: string | number | boolean } -type HeadersObj = (AxiosResponseHeaders | RawAxiosResponseHeaders) & ApiHeaders - +type HeadersObj = Record | ApiHeaders -type ErrorObj = AxiosError -type ErrorInterceptor = (error: ErrorObj) => ErrorObj +// Error +type ErrorObj = FetchError +type ErrorInterceptor = (error: ErrorObj) => ErrorObj | Promise type InterceptorType = 'request' | 'response' @@ -34,9 +44,10 @@ export type { RequestObj, ResponseObj, ErrorObj, HeadersObj } type RawResponseReader = { - id: number | undefined; - rawResponse: ResponseObj | undefined; - headers: HeadersObj | undefined; + id: number + rawResponse?: any + headers?: HeadersObj + ok: boolean } diff --git a/src/model.ts b/src/model.ts index 769028f..e909850 100644 --- a/src/model.ts +++ b/src/model.ts @@ -1,15 +1,15 @@ // ##__MODEL_TYPES_START__## -// ##__MODEL_TYPES_TEMPLATE:: export type { ##__RESOURCE_MODELS__## } from './resources/##__RESOURCE_TYPE__##' +// ##__MODEL_TYPES_TEMPLATE:: export type { ##__RESOURCE_MODELS__##, ##__RESOURCE_BASE_MODEL__##Sort } from './resources/##__RESOURCE_TYPE__##' /** * ©2024 Commerce Layer Inc. **/ -export type { ApiCredential, ApiCredentialCreate, ApiCredentialUpdate } from './resources/api_credentials' -export type { ApplicationMembership, ApplicationMembershipCreate, ApplicationMembershipUpdate } from './resources/application_memberships' -export type { Membership, MembershipCreate, MembershipUpdate } from './resources/memberships' -export type { Organization, OrganizationCreate, OrganizationUpdate } from './resources/organizations' -export type { Permission, PermissionCreate, PermissionUpdate } from './resources/permissions' -export type { Role, RoleCreate, RoleUpdate } from './resources/roles' -export type { User, UserUpdate } from './resources/user' -export type { Version } from './resources/versions' -// ##__MODEL_TYPES_STOP__## \ No newline at end of file +export type { ApiCredential, ApiCredentialCreate, ApiCredentialUpdate, ApiCredentialSort } from './resources/api_credentials' +export type { ApplicationMembership, ApplicationMembershipCreate, ApplicationMembershipUpdate, ApplicationMembershipSort } from './resources/application_memberships' +export type { Membership, MembershipCreate, MembershipUpdate, MembershipSort } from './resources/memberships' +export type { Organization, OrganizationCreate, OrganizationUpdate, OrganizationSort } from './resources/organizations' +export type { Permission, PermissionCreate, PermissionUpdate, PermissionSort } from './resources/permissions' +export type { Role, RoleCreate, RoleUpdate, RoleSort } from './resources/roles' +export type { User, UserUpdate, UserSort } from './resources/user' +export type { Version, VersionSort } from './resources/versions' +// ##__MODEL_TYPES_STOP__## diff --git a/src/query.ts b/src/query.ts index 483ee36..2ccd165 100644 --- a/src/query.ts +++ b/src/query.ts @@ -1,42 +1,63 @@ -import type { ResourceType } from "./resource" +import type { Resource, ResourceType } from "./resource" +import { ErrorType, SdkError } from "./error" +import type { PositiveNumberRange, StringKey } from "./types" +import type { ResourceFields, ResourceSortFields, ResourceTypeLock } from "./api" import Debug from './debug' const debug = Debug('query') -type QueryFilter = Record +const arrayFilters = ['_any', '_all', '_in'] +const objectFilters = ['_jcont'] +// type QueryResType = T extends { type: infer Type } ? Type : never +type QueryResType = T['type'] -interface QueryParamsRetrieve { - include?: string[] - fields?: string[] | Record -} +type QueryInclude = string[] +type QueryResourceFields = keyof ResourceFields[R] +type QueryArrayFields = Array>> +type QueryRecordFields = { [key in keyof ResourceFields]?: Array<(QueryResourceFields)> } +interface QueryParamsRetrieve { + include?: QueryInclude + fields?: QueryArrayFields | QueryRecordFields +} -interface QueryParamsList extends QueryParamsRetrieve { - sort?: string[] | Record +type QuerySortType = 'asc' | 'desc' +type QueryResourceSortable = ResourceSortFields[QueryResType] +type QueryResourceSortableFields = StringKey> +type QueryArraySortable = Array | `-${QueryResourceSortableFields}`> +type QueryRecordSortable = Partial, QuerySortType>> +type QueryFilter = Record> +type QueryPageNumber = number +type QueryPageSize = PositiveNumberRange<25> + +interface QueryParamsList extends QueryParamsRetrieve { + sort?: QueryArraySortable | QueryRecordSortable filters?: QueryFilter - pageNumber?: number - pageSize?: number + pageNumber?: QueryPageNumber + pageSize?: QueryPageSize } -type QueryParams = QueryParamsRetrieve | QueryParamsList +type QueryParams = QueryParamsRetrieve | QueryParamsList export type { QueryParamsRetrieve, QueryParamsList, QueryParams, QueryFilter } -const isParamsList = (params: any): params is QueryParamsList => { +const isParamsList = (params: any): params is QueryParamsList => { return params && (params.filters || params.pageNumber || params.pageSize || params.sort) } -const generateQueryStringParams = (params: QueryParamsRetrieve | QueryParamsList | undefined, res: string | ResourceType): Record => { +type QueryStringParams = Record + +const generateQueryStringParams = (params: QueryParams | undefined, res: string | ResourceType): QueryStringParams => { debug('generate query string params: %O, %O', params, res) - const qp: Record = {} + const qp: QueryStringParams = {} if (!params) return qp // Include @@ -61,7 +82,18 @@ const generateQueryStringParams = (params: QueryParamsRetrieve | QueryParamsList // Filters if (params.filters) { Object.entries(params.filters).forEach(([p, v]) => { - qp[`filter[q][${p}]`] = String(v) + const filter = p.substring(p.lastIndexOf('_')) + let val + if (Array.isArray(v)) { + if (!arrayFilters.includes(filter)) throw new SdkError({ message: `Wrong ${filter} filter: Array value is supported only for the following filters: ${arrayFilters.join(', ')}`, type: ErrorType.REQUEST }) + val = v.join(',') + } + else if (typeof v === 'object') { + if (!objectFilters.includes(filter)) throw new SdkError({ message: `Wrong ${filter} filter: Object value is supported only for the following filters: ${objectFilters.join(', ')}`, type: ErrorType.REQUEST }) + val = JSON.stringify(v) + } + else val = String(v) + qp[`filter[q][${p}]`] = val }) } } @@ -73,4 +105,10 @@ const generateQueryStringParams = (params: QueryParamsRetrieve | QueryParamsList } -export { generateQueryStringParams, isParamsList } +const generateSearchString = (params?: QueryStringParams, questionMark: boolean = true): string => { + if (!params || (Object.keys(params).length === 0)) return '' + return `${questionMark ? '?' : ''}${Object.entries(params).map(([key, val]) => `${key}=${String(val)}`).join('&')}` +} + + +export { generateQueryStringParams, isParamsList, generateSearchString } diff --git a/src/resource.ts b/src/resource.ts index 08e6fc7..1ca4269 100644 --- a/src/resource.ts +++ b/src/resource.ts @@ -1,16 +1,17 @@ -import ApiClient, { type ApiClientInitConfig } from './client' +import ApiClient, { type Method, type ApiClientInitConfig } from './client' import { denormalize, normalize, type DocWithData } from './jsonapi' import type { QueryParamsRetrieve, QueryParamsList, QueryFilter, QueryParams } from './query' import { generateQueryStringParams, isParamsList } from './query' import type { ResourceTypeLock } from './api' import config from './config' -import type { InterceptorManager } from './interceptor' -import { ErrorType, SdkError } from './error' +import type { Nullable } from './types' import { CommerceLayerProvisioningStatic } from './static' +import { isResourceId } from './common' + import Debug from './debug' -import { isResourceId } from './common' +import { ErrorType, SdkError } from './error' const debug = Debug('resource') @@ -33,8 +34,8 @@ interface ResourceId extends ResourceType { interface ResourceBase { - reference?: string | null - reference_origin?: string | null + reference?: Nullable + reference_origin?: Nullable metadata?: Metadata } @@ -62,6 +63,7 @@ type ListMeta = { readonly recordsPerPage: number } + class ListResponse extends Array { readonly meta: ListMeta @@ -86,9 +88,12 @@ class ListResponse extends Array { } - export type { Metadata, ResourceType, ResourceId, Resource, ResourceCreate, ResourceUpdate, ListResponse, ListMeta, ResourceRel } +export type ResourceSort = Pick +export type ResourceFilter = Pick + + // Resource adapters local configuration type ResourceAdapterConfig = { @@ -99,6 +104,11 @@ type ResourcesInitConfig = ResourceAdapterConfig & ApiClientInitConfig type ResourcesConfig = Partial +export const apiResourceAdapter = (config: ResourcesInitConfig): ResourceAdapter => { + return new ResourceAdapter(config) +} + + class ResourceAdapter { readonly #client: ApiClient @@ -112,9 +122,6 @@ class ResourceAdapter { } - get interceptors(): InterceptorManager { return this.#client.interceptors } - - private localConfig(config: ResourceAdapterConfig): void { // if (typeof config.xyz !== 'undefined') this.#config.xyz = config.xyz } @@ -134,11 +141,10 @@ class ResourceAdapter { } - /* - get clientInstance(): ApiClient { + + get client(): Readonly { return this.#client } - */ @@ -153,7 +159,7 @@ class ResourceAdapter { const path = `${resource.type}${singleton? '' : `/${resource.id}`}` - const res: DocWithData = await this.#client.request('get', path, undefined, { ...options, params: queryParams }) + const res: DocWithData = await this.#client.request('GET', path, undefined, { ...options, params: queryParams }) const r = denormalize(res) as R return r @@ -168,8 +174,8 @@ class ResourceAdapter { const queryParams = generateQueryStringParams(params, resource) if (options?.params) Object.assign(queryParams, options?.params) - const res: DocWithData = await this.#client.request('get', `${resource.type}`, undefined, { ...options, params: queryParams }) - const r = denormalize(res) as R[] + const res = await this.#client.request('GET', `${resource.type}`, undefined, { ...options, params: queryParams }) + const r = denormalize(res as DocWithData) as R[] const meta: ListMeta = { pageCount: Number(res.meta?.page_count), @@ -183,16 +189,16 @@ class ResourceAdapter { } - async create(resource: C & ResourceType, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { + async create(resource: C & ResourceType, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { debug('create: %o, %O, %O', resource, params || {}, options || {}) - const queryParams = generateQueryStringParams(params, resource) + const queryParams = generateQueryStringParams(params, resource) if (options?.params) Object.assign(queryParams, options?.params) const data = normalize(resource) - const res: DocWithData = await this.#client.request('post', resource.type, data, { ...options, params: queryParams }) - const r = denormalize(res) as R + const res = await this.#client.request('POST', resource.type, data, { ...options, params: queryParams }) + const r = denormalize(res as DocWithData) as R return r @@ -211,8 +217,8 @@ class ResourceAdapter { const path = `${resource.type}${singleton? '' : `/${resource.id}`}` const data = normalize(resource) - const res: DocWithData = await this.#client.request('patch', path, data, { ...options, params: queryParams }) - const r = denormalize(res) as R + const res = await this.#client.request('PATCH', path, data, { ...options, params: queryParams }) + const r = denormalize(res as DocWithData) as R return r @@ -221,22 +227,22 @@ class ResourceAdapter { async delete(resource: ResourceId, options?: ResourcesConfig): Promise { debug('delete: %o, %O', resource, options || {}) - await this.#client.request('delete', `${resource.type}/${resource.id}`, undefined, options) + await this.#client.request('DELETE', `${resource.type}/${resource.id}`, undefined, options) } - async fetch(resource: string | ResourceType, path: string, params?: QueryParams, options?: ResourcesConfig): Promise> { + async fetch(resource: string | ResourceType, path: string, params?: QueryParams, options?: ResourcesConfig): Promise> { debug('fetch: %o, %O, %O', path, params || {}, options || {}) - const queryParams = generateQueryStringParams(params, resource) + const queryParams = generateQueryStringParams(params, resource) if (options?.params) Object.assign(queryParams, options?.params) - const res: DocWithData = await this.#client.request('get', path, undefined, { ...options, params: queryParams }) - const r = denormalize(res) + const res = await this.#client.request('GET', path, undefined, { ...options, params: queryParams }) + const r = denormalize(res as DocWithData) if (Array.isArray(r)) { - const p = params as QueryParamsList + const p = params as QueryParamsList const meta: ListMeta = { pageCount: Number(res.meta?.page_count), recordCount: Number(res.meta?.record_count), @@ -250,7 +256,7 @@ class ResourceAdapter { } - async action(cmd: 'post' | 'patch', path: string, payload?: any, options?: ResourcesConfig): Promise { + async action(cmd: Extract, path: string, payload?: any, options?: ResourcesConfig): Promise { debug('action: %o %o, %O', cmd, path, options || {}) @@ -279,6 +285,14 @@ abstract class ApiResourceBase { abstract relationship(id: string | ResourceId | null): ResourceRel + protected relationshipOneToOne(id: string | ResourceId | null): RR { + return (((id === null) || (typeof id === 'string')) ? { id, type: this.type() } : { id: id.id, type: this.type() }) as RR + } + + protected relationshipOneToMany(...ids: string[]): RR[] { + return (((ids === null) || (ids.length === 0) || (ids[0] === null))? [ { id: null, type: this.type() } ] : ids.map(id => { return { id, type: this.type() } })) as RR[] + } + abstract type(): ResourceTypeLock parse(resource: string): R | R[] { diff --git a/src/resources/api_credentials.ts b/src/resources/api_credentials.ts index 4c18767..f9fa87b 100644 --- a/src/resources/api_credentials.ts +++ b/src/resources/api_credentials.ts @@ -1,5 +1,6 @@ +import type { Nullable } from '../types' import { ApiResource } from '../resource' -import type { Resource, ResourceCreate, ResourceUpdate, ResourceId, ResourcesConfig, ResourceRel } from '../resource' +import type { Resource, ResourceCreate, ResourceUpdate, ResourceId, ResourcesConfig, ResourceRel, ResourceSort, /* ResourceFilter */ } from '../resource' import type { QueryParamsRetrieve } from '../query' import type { Organization, OrganizationType } from './organizations' @@ -12,6 +13,10 @@ type OrganizationRel = ResourceRel & { type: OrganizationType } type RoleRel = ResourceRel & { type: RoleType } +export type ApiCredentialSort = Pick & ResourceSort +// export type ApiCredentialFilter = Pick & ResourceFilter + + interface ApiCredential extends Resource { readonly type: ApiCredentialType @@ -19,16 +24,16 @@ interface ApiCredential extends Resource { name: string kind: string confidential: boolean - redirect_uri?: string | null + redirect_uri?: Nullable client_id: string client_secret: string scopes: string - expires_in?: number | null - mode?: string | null - custom?: boolean | null + expires_in?: Nullable + mode?: Nullable + custom?: Nullable - organization?: Organization | null - role?: Role | null + organization?: Nullable + role?: Nullable } @@ -37,24 +42,24 @@ interface ApiCredentialCreate extends ResourceCreate { name: string kind: string - redirect_uri?: string | null - expires_in?: number | null - mode?: string | null - custom?: boolean | null + redirect_uri?: Nullable + expires_in?: Nullable + mode?: Nullable + custom?: Nullable organization: OrganizationRel - role?: RoleRel | null + role?: Nullable } interface ApiCredentialUpdate extends ResourceUpdate { - name?: string | null - redirect_uri?: string | null - expires_in?: number | null + name?: Nullable + redirect_uri?: Nullable + expires_in?: Nullable - role?: RoleRel | null + role?: Nullable } @@ -75,12 +80,12 @@ class ApiCredentials extends ApiResource { await this.resources.delete((typeof id === 'string')? { id, type: ApiCredentials.TYPE } : id, options) } - async organization(apiCredentialId: string | ApiCredential, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { + async organization(apiCredentialId: string | ApiCredential, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { const _apiCredentialId = (apiCredentialId as ApiCredential).id || apiCredentialId as string return this.resources.fetch({ type: 'organizations' }, `api_credentials/${_apiCredentialId}/organization`, params, options) as unknown as Organization } - async role(apiCredentialId: string | ApiCredential, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { + async role(apiCredentialId: string | ApiCredential, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { const _apiCredentialId = (apiCredentialId as ApiCredential).id || apiCredentialId as string return this.resources.fetch({ type: 'roles' }, `api_credentials/${_apiCredentialId}/role`, params, options) as unknown as Role } @@ -92,7 +97,11 @@ class ApiCredentials extends ApiResource { relationship(id: string | ResourceId | null): ApiCredentialRel { - return ((id === null) || (typeof id === 'string')) ? { id, type: ApiCredentials.TYPE } : { id: id.id, type: ApiCredentials.TYPE } + return super.relationshipOneToOne(id) + } + + relationshipToMany(...ids: string[]): ApiCredentialRel[] { + return super.relationshipOneToMany(...ids) } diff --git a/src/resources/application_memberships.ts b/src/resources/application_memberships.ts index acf38e8..6a68d6b 100644 --- a/src/resources/application_memberships.ts +++ b/src/resources/application_memberships.ts @@ -1,5 +1,6 @@ +import type { Nullable } from '../types' import { ApiResource } from '../resource' -import type { Resource, ResourceCreate, ResourceUpdate, ResourceId, ResourcesConfig, ResourceRel } from '../resource' +import type { Resource, ResourceCreate, ResourceUpdate, ResourceId, ResourcesConfig, ResourceRel, ResourceSort, /* ResourceFilter */ } from '../resource' import type { QueryParamsRetrieve } from '../query' import type { ApiCredential, ApiCredentialType } from './api_credentials' @@ -16,23 +17,27 @@ type OrganizationRel = ResourceRel & { type: OrganizationType } type RoleRel = ResourceRel & { type: RoleType } +export type ApplicationMembershipSort = Pick & ResourceSort +// export type ApplicationMembershipFilter = Pick & ResourceFilter + + interface ApplicationMembership extends Resource { readonly type: ApplicationMembershipType - filters?: Record | null + filters?: Nullable> - api_credential?: ApiCredential | null - membership?: Membership | null - organization?: Organization | null - role?: Role | null + api_credential?: Nullable + membership?: Nullable + organization?: Nullable + role?: Nullable } interface ApplicationMembershipCreate extends ResourceCreate { - filters?: Record | null + filters?: Nullable> api_credential: ApiCredentialRel membership: MembershipRel @@ -44,9 +49,9 @@ interface ApplicationMembershipCreate extends ResourceCreate { interface ApplicationMembershipUpdate extends ResourceUpdate { - filters?: Record | null + filters?: Nullable> - role?: RoleRel | null + role?: Nullable } @@ -67,22 +72,22 @@ class ApplicationMemberships extends ApiResource { await this.resources.delete((typeof id === 'string')? { id, type: ApplicationMemberships.TYPE } : id, options) } - async api_credential(applicationMembershipId: string | ApplicationMembership, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { + async api_credential(applicationMembershipId: string | ApplicationMembership, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { const _applicationMembershipId = (applicationMembershipId as ApplicationMembership).id || applicationMembershipId as string return this.resources.fetch({ type: 'api_credentials' }, `application_memberships/${_applicationMembershipId}/api_credential`, params, options) as unknown as ApiCredential } - async membership(applicationMembershipId: string | ApplicationMembership, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { + async membership(applicationMembershipId: string | ApplicationMembership, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { const _applicationMembershipId = (applicationMembershipId as ApplicationMembership).id || applicationMembershipId as string return this.resources.fetch({ type: 'memberships' }, `application_memberships/${_applicationMembershipId}/membership`, params, options) as unknown as Membership } - async organization(applicationMembershipId: string | ApplicationMembership, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { + async organization(applicationMembershipId: string | ApplicationMembership, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { const _applicationMembershipId = (applicationMembershipId as ApplicationMembership).id || applicationMembershipId as string return this.resources.fetch({ type: 'organizations' }, `application_memberships/${_applicationMembershipId}/organization`, params, options) as unknown as Organization } - async role(applicationMembershipId: string | ApplicationMembership, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { + async role(applicationMembershipId: string | ApplicationMembership, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { const _applicationMembershipId = (applicationMembershipId as ApplicationMembership).id || applicationMembershipId as string return this.resources.fetch({ type: 'roles' }, `application_memberships/${_applicationMembershipId}/role`, params, options) as unknown as Role } @@ -94,7 +99,11 @@ class ApplicationMemberships extends ApiResource { relationship(id: string | ResourceId | null): ApplicationMembershipRel { - return ((id === null) || (typeof id === 'string')) ? { id, type: ApplicationMemberships.TYPE } : { id: id.id, type: ApplicationMemberships.TYPE } + return super.relationshipOneToOne(id) + } + + relationshipToMany(...ids: string[]): ApplicationMembershipRel[] { + return super.relationshipOneToMany(...ids) } diff --git a/src/resources/memberships.ts b/src/resources/memberships.ts index 5ecb467..18bfd5a 100644 --- a/src/resources/memberships.ts +++ b/src/resources/memberships.ts @@ -1,5 +1,6 @@ +import type { Nullable } from '../types' import { ApiResource } from '../resource' -import type { Resource, ResourceCreate, ResourceUpdate, ResourceId, ResourcesConfig, ResourceRel, ListResponse } from '../resource' +import type { Resource, ResourceCreate, ResourceUpdate, ResourceId, ResourcesConfig, ResourceRel, ListResponse, ResourceSort, /* ResourceFilter */ } from '../resource' import type { QueryParamsRetrieve, QueryParamsList } from '../query' import type { Organization, OrganizationType } from './organizations' @@ -15,6 +16,10 @@ type RoleRel = ResourceRel & { type: RoleType } type ApplicationMembershipRel = ResourceRel & { type: ApplicationMembershipType } +export type MembershipSort = Pick & ResourceSort +// export type MembershipFilter = Pick & ResourceFilter + + interface Membership extends Resource { readonly type: MembershipType @@ -25,10 +30,10 @@ interface Membership extends Resource { status: 'pending' | 'active' owner: boolean - organization?: Organization | null - role?: Role | null - application_memberships?: ApplicationMembership[] | null - versions?: Version[] | null + organization?: Nullable + role?: Nullable + application_memberships?: Nullable + versions?: Nullable } @@ -39,15 +44,15 @@ interface MembershipCreate extends ResourceCreate { organization: OrganizationRel role: RoleRel - application_memberships?: ApplicationMembershipRel[] | null + application_memberships?: Nullable } interface MembershipUpdate extends ResourceUpdate { - role?: RoleRel | null - application_memberships?: ApplicationMembershipRel[] | null + role?: Nullable + application_memberships?: Nullable } @@ -70,25 +75,25 @@ class Memberships extends ApiResource { async resend(membershipId: string | Membership, options?: ResourcesConfig): Promise { const _membershipId = (membershipId as Membership).id || membershipId as string - await this.resources.action('post', `memberships/${_membershipId}/resend`, {}, options) + await this.resources.action('POST', `memberships/${_membershipId}/resend`, {}, options) } - async organization(membershipId: string | Membership, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { + async organization(membershipId: string | Membership, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { const _membershipId = (membershipId as Membership).id || membershipId as string return this.resources.fetch({ type: 'organizations' }, `memberships/${_membershipId}/organization`, params, options) as unknown as Organization } - async role(membershipId: string | Membership, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { + async role(membershipId: string | Membership, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { const _membershipId = (membershipId as Membership).id || membershipId as string return this.resources.fetch({ type: 'roles' }, `memberships/${_membershipId}/role`, params, options) as unknown as Role } - async application_memberships(membershipId: string | Membership, params?: QueryParamsList, options?: ResourcesConfig): Promise> { + async application_memberships(membershipId: string | Membership, params?: QueryParamsList, options?: ResourcesConfig): Promise> { const _membershipId = (membershipId as Membership).id || membershipId as string return this.resources.fetch({ type: 'application_memberships' }, `memberships/${_membershipId}/application_memberships`, params, options) as unknown as ListResponse } - async versions(membershipId: string | Membership, params?: QueryParamsList, options?: ResourcesConfig): Promise> { + async versions(membershipId: string | Membership, params?: QueryParamsList, options?: ResourcesConfig): Promise> { const _membershipId = (membershipId as Membership).id || membershipId as string return this.resources.fetch({ type: 'versions' }, `memberships/${_membershipId}/versions`, params, options) as unknown as ListResponse } @@ -100,7 +105,11 @@ class Memberships extends ApiResource { relationship(id: string | ResourceId | null): MembershipRel { - return ((id === null) || (typeof id === 'string')) ? { id, type: Memberships.TYPE } : { id: id.id, type: Memberships.TYPE } + return super.relationshipOneToOne(id) + } + + relationshipToMany(...ids: string[]): MembershipRel[] { + return super.relationshipOneToMany(...ids) } diff --git a/src/resources/organizations.ts b/src/resources/organizations.ts index d768f39..c1d0fe7 100644 --- a/src/resources/organizations.ts +++ b/src/resources/organizations.ts @@ -1,5 +1,6 @@ +import type { Nullable } from '../types' import { ApiResource } from '../resource' -import type { Resource, ResourceCreate, ResourceUpdate, ResourceId, ResourcesConfig, ResourceRel, ListResponse } from '../resource' +import type { Resource, ResourceCreate, ResourceUpdate, ResourceId, ResourcesConfig, ResourceRel, ListResponse, ResourceSort, /* ResourceFilter */ } from '../resource' import type { QueryParamsRetrieve, QueryParamsList } from '../query' import type { Membership } from './memberships' @@ -12,6 +13,10 @@ type OrganizationType = 'organizations' type OrganizationRel = ResourceRel & { type: OrganizationType } +export type OrganizationSort = Pick & ResourceSort +// export type OrganizationFilter = Pick & ResourceFilter + + interface Organization extends Resource { readonly type: OrganizationType @@ -19,28 +24,28 @@ interface Organization extends Resource { name: string slug: string domain: string - config?: Record | null - support_phone?: string | null - support_email?: string | null - logo_url?: string | null - favicon_url?: string | null - primary_color?: string | null - contrast_color?: string | null - gtm_id?: string | null - gtm_id_test?: string | null - discount_disabled?: boolean | null - account_disabled?: boolean | null - acceptance_disabled?: boolean | null + config?: Nullable> + support_phone?: Nullable + support_email?: Nullable + logo_url?: Nullable + favicon_url?: Nullable + primary_color?: Nullable + contrast_color?: Nullable + gtm_id?: Nullable + gtm_id_test?: Nullable + discount_disabled?: Nullable + account_disabled?: Nullable + acceptance_disabled?: Nullable max_concurrent_promotions: number max_concurrent_imports: number - region?: string | null + region?: Nullable can_switch_live: boolean subscription_info: Record - memberships?: Membership[] | null - roles?: Role[] | null - permissions?: Permission[] | null - api_credentials?: ApiCredential[] | null + memberships?: Nullable + roles?: Nullable + permissions?: Nullable + api_credentials?: Nullable } @@ -48,38 +53,38 @@ interface Organization extends Resource { interface OrganizationCreate extends ResourceCreate { name: string - config?: Record | null - support_phone?: string | null - support_email?: string | null - logo_url?: string | null - favicon_url?: string | null - primary_color?: string | null - contrast_color?: string | null - gtm_id?: string | null - gtm_id_test?: string | null - discount_disabled?: boolean | null - account_disabled?: boolean | null - acceptance_disabled?: boolean | null - region?: string | null + config?: Nullable> + support_phone?: Nullable + support_email?: Nullable + logo_url?: Nullable + favicon_url?: Nullable + primary_color?: Nullable + contrast_color?: Nullable + gtm_id?: Nullable + gtm_id_test?: Nullable + discount_disabled?: Nullable + account_disabled?: Nullable + acceptance_disabled?: Nullable + region?: Nullable } interface OrganizationUpdate extends ResourceUpdate { - name?: string | null - config?: Record | null - support_phone?: string | null - support_email?: string | null - logo_url?: string | null - favicon_url?: string | null - primary_color?: string | null - contrast_color?: string | null - gtm_id?: string | null - gtm_id_test?: string | null - discount_disabled?: boolean | null - account_disabled?: boolean | null - acceptance_disabled?: boolean | null + name?: Nullable + config?: Nullable> + support_phone?: Nullable + support_email?: Nullable + logo_url?: Nullable + favicon_url?: Nullable + primary_color?: Nullable + contrast_color?: Nullable + gtm_id?: Nullable + gtm_id_test?: Nullable + discount_disabled?: Nullable + account_disabled?: Nullable + acceptance_disabled?: Nullable } @@ -98,25 +103,25 @@ class Organizations extends ApiResource { async transfer_ownership(organizationId: string | Organization, payload: TransferOwnershipDataType, options?: ResourcesConfig): Promise { const _organizationId = (organizationId as Organization).id || organizationId as string - await this.resources.action('patch', `organizations/${_organizationId}/transfer_ownership`, { ...payload }, options) + await this.resources.action('PATCH', `organizations/${_organizationId}/transfer_ownership`, { ...payload }, options) } - async memberships(organizationId: string | Organization, params?: QueryParamsList, options?: ResourcesConfig): Promise> { + async memberships(organizationId: string | Organization, params?: QueryParamsList, options?: ResourcesConfig): Promise> { const _organizationId = (organizationId as Organization).id || organizationId as string return this.resources.fetch({ type: 'memberships' }, `organizations/${_organizationId}/memberships`, params, options) as unknown as ListResponse } - async roles(organizationId: string | Organization, params?: QueryParamsList, options?: ResourcesConfig): Promise> { + async roles(organizationId: string | Organization, params?: QueryParamsList, options?: ResourcesConfig): Promise> { const _organizationId = (organizationId as Organization).id || organizationId as string return this.resources.fetch({ type: 'roles' }, `organizations/${_organizationId}/roles`, params, options) as unknown as ListResponse } - async permissions(organizationId: string | Organization, params?: QueryParamsList, options?: ResourcesConfig): Promise> { + async permissions(organizationId: string | Organization, params?: QueryParamsList, options?: ResourcesConfig): Promise> { const _organizationId = (organizationId as Organization).id || organizationId as string return this.resources.fetch({ type: 'permissions' }, `organizations/${_organizationId}/permissions`, params, options) as unknown as ListResponse } - async api_credentials(organizationId: string | Organization, params?: QueryParamsList, options?: ResourcesConfig): Promise> { + async api_credentials(organizationId: string | Organization, params?: QueryParamsList, options?: ResourcesConfig): Promise> { const _organizationId = (organizationId as Organization).id || organizationId as string return this.resources.fetch({ type: 'api_credentials' }, `organizations/${_organizationId}/api_credentials`, params, options) as unknown as ListResponse } @@ -128,7 +133,11 @@ class Organizations extends ApiResource { relationship(id: string | ResourceId | null): OrganizationRel { - return ((id === null) || (typeof id === 'string')) ? { id, type: Organizations.TYPE } : { id: id.id, type: Organizations.TYPE } + return super.relationshipOneToOne(id) + } + + relationshipToMany(...ids: string[]): OrganizationRel[] { + return super.relationshipOneToMany(...ids) } diff --git a/src/resources/permissions.ts b/src/resources/permissions.ts index 48e9349..435f981 100644 --- a/src/resources/permissions.ts +++ b/src/resources/permissions.ts @@ -1,5 +1,6 @@ +import type { Nullable } from '../types' import { ApiResource } from '../resource' -import type { Resource, ResourceCreate, ResourceUpdate, ResourceId, ResourcesConfig, ResourceRel, ListResponse } from '../resource' +import type { Resource, ResourceCreate, ResourceUpdate, ResourceId, ResourcesConfig, ResourceRel, ListResponse, ResourceSort, /* ResourceFilter */ } from '../resource' import type { QueryParamsRetrieve, QueryParamsList } from '../query' import type { Organization } from './organizations' @@ -12,6 +13,10 @@ type PermissionRel = ResourceRel & { type: PermissionType } type RoleRel = ResourceRel & { type: RoleType } +export type PermissionSort = Pick & ResourceSort +// export type PermissionFilter = Pick & ResourceFilter + + interface Permission extends Resource { readonly type: PermissionType @@ -23,9 +28,9 @@ interface Permission extends Resource { subject: string restrictions: Record - organization?: Organization | null - role?: Role | null - versions?: Version[] | null + organization?: Nullable + role?: Nullable + versions?: Nullable } @@ -45,10 +50,10 @@ interface PermissionCreate extends ResourceCreate { interface PermissionUpdate extends ResourceUpdate { - can_create?: boolean | null - can_read?: boolean | null - can_update?: boolean | null - can_destroy?: boolean | null + can_create?: Nullable + can_read?: Nullable + can_update?: Nullable + can_destroy?: Nullable } @@ -65,17 +70,17 @@ class Permissions extends ApiResource { return this.resources.update({ ...resource, type: Permissions.TYPE }, params, options) } - async organization(permissionId: string | Permission, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { + async organization(permissionId: string | Permission, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { const _permissionId = (permissionId as Permission).id || permissionId as string return this.resources.fetch({ type: 'organizations' }, `permissions/${_permissionId}/organization`, params, options) as unknown as Organization } - async role(permissionId: string | Permission, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { + async role(permissionId: string | Permission, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { const _permissionId = (permissionId as Permission).id || permissionId as string return this.resources.fetch({ type: 'roles' }, `permissions/${_permissionId}/role`, params, options) as unknown as Role } - async versions(permissionId: string | Permission, params?: QueryParamsList, options?: ResourcesConfig): Promise> { + async versions(permissionId: string | Permission, params?: QueryParamsList, options?: ResourcesConfig): Promise> { const _permissionId = (permissionId as Permission).id || permissionId as string return this.resources.fetch({ type: 'versions' }, `permissions/${_permissionId}/versions`, params, options) as unknown as ListResponse } @@ -87,7 +92,11 @@ class Permissions extends ApiResource { relationship(id: string | ResourceId | null): PermissionRel { - return ((id === null) || (typeof id === 'string')) ? { id, type: Permissions.TYPE } : { id: id.id, type: Permissions.TYPE } + return super.relationshipOneToOne(id) + } + + relationshipToMany(...ids: string[]): PermissionRel[] { + return super.relationshipOneToMany(...ids) } diff --git a/src/resources/roles.ts b/src/resources/roles.ts index a2f8652..341521a 100644 --- a/src/resources/roles.ts +++ b/src/resources/roles.ts @@ -1,5 +1,6 @@ +import type { Nullable } from '../types' import { ApiResource } from '../resource' -import type { Resource, ResourceCreate, ResourceUpdate, ResourceId, ResourcesConfig, ResourceRel, ListResponse } from '../resource' +import type { Resource, ResourceCreate, ResourceUpdate, ResourceId, ResourcesConfig, ResourceRel, ListResponse, ResourceSort, /* ResourceFilter */ } from '../resource' import type { QueryParamsRetrieve, QueryParamsList } from '../query' import type { Organization, OrganizationType } from './organizations' @@ -14,6 +15,10 @@ type RoleRel = ResourceRel & { type: RoleType } type OrganizationRel = ResourceRel & { type: OrganizationType } +export type RoleSort = Pick & ResourceSort +// export type RoleFilter = Pick & ResourceFilter + + interface Role extends Resource { readonly type: RoleType @@ -21,11 +26,11 @@ interface Role extends Resource { name: string kind: string - organization?: Organization | null - permissions?: Permission[] | null - memberships?: Membership[] | null - api_credentials?: ApiCredential[] | null - versions?: Version[] | null + organization?: Nullable + permissions?: Nullable + memberships?: Nullable + api_credentials?: Nullable + versions?: Nullable } @@ -41,7 +46,7 @@ interface RoleCreate extends ResourceCreate { interface RoleUpdate extends ResourceUpdate { - name?: string | null + name?: Nullable } @@ -58,27 +63,27 @@ class Roles extends ApiResource { return this.resources.update({ ...resource, type: Roles.TYPE }, params, options) } - async organization(roleId: string | Role, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { + async organization(roleId: string | Role, params?: QueryParamsRetrieve, options?: ResourcesConfig): Promise { const _roleId = (roleId as Role).id || roleId as string return this.resources.fetch({ type: 'organizations' }, `roles/${_roleId}/organization`, params, options) as unknown as Organization } - async permissions(roleId: string | Role, params?: QueryParamsList, options?: ResourcesConfig): Promise> { + async permissions(roleId: string | Role, params?: QueryParamsList, options?: ResourcesConfig): Promise> { const _roleId = (roleId as Role).id || roleId as string return this.resources.fetch({ type: 'permissions' }, `roles/${_roleId}/permissions`, params, options) as unknown as ListResponse } - async memberships(roleId: string | Role, params?: QueryParamsList, options?: ResourcesConfig): Promise> { + async memberships(roleId: string | Role, params?: QueryParamsList, options?: ResourcesConfig): Promise> { const _roleId = (roleId as Role).id || roleId as string return this.resources.fetch({ type: 'memberships' }, `roles/${_roleId}/memberships`, params, options) as unknown as ListResponse } - async api_credentials(roleId: string | Role, params?: QueryParamsList, options?: ResourcesConfig): Promise> { + async api_credentials(roleId: string | Role, params?: QueryParamsList, options?: ResourcesConfig): Promise> { const _roleId = (roleId as Role).id || roleId as string return this.resources.fetch({ type: 'api_credentials' }, `roles/${_roleId}/api_credentials`, params, options) as unknown as ListResponse } - async versions(roleId: string | Role, params?: QueryParamsList, options?: ResourcesConfig): Promise> { + async versions(roleId: string | Role, params?: QueryParamsList, options?: ResourcesConfig): Promise> { const _roleId = (roleId as Role).id || roleId as string return this.resources.fetch({ type: 'versions' }, `roles/${_roleId}/versions`, params, options) as unknown as ListResponse } @@ -90,7 +95,11 @@ class Roles extends ApiResource { relationship(id: string | ResourceId | null): RoleRel { - return ((id === null) || (typeof id === 'string')) ? { id, type: Roles.TYPE } : { id: id.id, type: Roles.TYPE } + return super.relationshipOneToOne(id) + } + + relationshipToMany(...ids: string[]): RoleRel[] { + return super.relationshipOneToMany(...ids) } diff --git a/src/resources/user.ts b/src/resources/user.ts index 9a395d5..f9b0e6e 100644 --- a/src/resources/user.ts +++ b/src/resources/user.ts @@ -1,5 +1,6 @@ +import type { Nullable } from '../types' import { ApiSingleton } from '../resource' -import type { Resource, ResourceUpdate, ResourceId, ResourcesConfig, ResourceRel } from '../resource' +import type { Resource, ResourceUpdate, ResourceId, ResourcesConfig, ResourceRel, ResourceSort, /* ResourceFilter */ } from '../resource' import type { QueryParamsRetrieve } from '../query' @@ -8,6 +9,10 @@ type UserType = 'user' type UserRel = ResourceRel & { type: UserType } +export type UserSort = Pick & ResourceSort +// export type UserFilter = Pick & ResourceFilter + + interface User extends Resource { readonly type: UserType @@ -15,7 +20,7 @@ interface User extends Resource { email: string first_name: string last_name: string - time_zone?: string | null + time_zone?: Nullable otp_required_for_login: boolean } @@ -23,10 +28,10 @@ interface User extends Resource { interface UserUpdate extends ResourceUpdate { - email?: string | null - first_name?: string | null - last_name?: string | null - time_zone?: string | null + email?: Nullable + first_name?: Nullable + last_name?: Nullable + time_zone?: Nullable } @@ -47,7 +52,11 @@ class Users extends ApiSingleton { relationship(id: string | ResourceId | null): UserRel { - return ((id === null) || (typeof id === 'string')) ? { id, type: Users.TYPE } : { id: id.id, type: Users.TYPE } + return super.relationshipOneToOne(id) + } + + relationshipToMany(...ids: string[]): UserRel[] { + return super.relationshipOneToMany(...ids) } diff --git a/src/resources/versions.ts b/src/resources/versions.ts index e343af2..a60fc74 100644 --- a/src/resources/versions.ts +++ b/src/resources/versions.ts @@ -1,5 +1,6 @@ +import type { Nullable } from '../types' import { ApiResource } from '../resource' -import type { Resource, ResourceId, ResourceRel } from '../resource' +import type { Resource, ResourceId, ResourceRel, ResourceSort, /* ResourceFilter */ } from '../resource' @@ -8,6 +9,10 @@ type VersionType = 'versions' type VersionRel = ResourceRel & { type: VersionType } +export type VersionSort = Pick & ResourceSort +// export type VersionFilter = Pick & ResourceFilter + + interface Version extends Resource { readonly type: VersionType @@ -34,7 +39,11 @@ class Versions extends ApiResource { relationship(id: string | ResourceId | null): VersionRel { - return ((id === null) || (typeof id === 'string')) ? { id, type: Versions.TYPE } : { id: id.id, type: Versions.TYPE } + return super.relationshipOneToOne(id) + } + + relationshipToMany(...ids: string[]): VersionRel[] { + return super.relationshipOneToMany(...ids) } diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..4b3e51e --- /dev/null +++ b/src/types.ts @@ -0,0 +1,29 @@ + +export type ObjectType = Record + +export type Nullable = T | null + + +// Positive number range +type CreateArrayWithLengthX = + ACC['length'] extends LENGTH ? ACC : CreateArrayWithLengthX + +type NumericNumberRange = + START_ARR['length'] extends END ? ACC | END : NumericNumberRange<[...START_ARR, 1], END, ACC | START_ARR['length']> + +export type PositiveNumberRange = NumericNumberRange, MAX> + + +/* +JavaScript converts numbers to strings when indexing an object: +[..] when indexing with a number, JavaScript will actually convert that to a string before indexing into an object. That means that indexing with 100 (a number) is the same thing as indexing with "100" (a string), so the two need to be consistent. + +Example: +let abc: AbstractModel = { + 1: "one", +}; +console.log(abc[1] === abc["1"]); // true + +When you only want the string keys, then you could only extract the string keys from your interface like so: +*/ +export type StringKey = Extract diff --git a/test/common.ts b/test/common.ts index 7563734..a49ed9d 100644 --- a/test/common.ts +++ b/test/common.ts @@ -1,10 +1,11 @@ import getToken from './token' -import CommerceLayerProvisioning, { CommerceLayerProvisioningClient, QueryParamsList, QueryParamsRetrieve } from '../src' +import CommerceLayerProvisioning, { CommerceLayerProvisioningClient, QueryParamsList, QueryParamsRetrieve, RequestObj } from '../src' import dotenv from 'dotenv' import { inspect } from 'util' -import axios, { AxiosRequestConfig } from 'axios' -import { isEqual } from 'lodash' +import isEqual from 'lodash.isequal' import { RequestConfig } from '../src/client' +import { Resource } from '../src/resource' + dotenv.config() @@ -33,7 +34,7 @@ export const TestData = { const COMMON_PARAMS_FILTERS = { reference_eq: TestData.reference } -const COMMON_PARAMS_LIST: QueryParamsList = { +const COMMON_PARAMS_LIST: QueryParamsList = { filters: COMMON_PARAMS_FILTERS, pageSize: 25, pageNumber: 1, @@ -50,7 +51,7 @@ export const CommonData = { options: REQUEST_OPTIONS, paramsRetrieve: COMMON_PARAMS_RETRIEVE, paramsList: COMMON_PARAMS_LIST, - paramsFields: COMMON_PARAMS_FIELDS, + paramsFields: COMMON_PARAMS_FIELDS as (keyof Resource)[], } as const @@ -91,9 +92,9 @@ const handleError = (error: any) => { if (error.message !== INTERCEPTOR_CANCEL) throw error } -const interceptRequest = (config?: AxiosRequestConfig): AxiosRequestConfig => { - if (!config) throw new axios.Cancel(INTERCEPTOR_CANCEL) - return config +const interceptRequest = (request?: RequestObj): RequestObj => { + if (!request) throw new DOMException(INTERCEPTOR_CANCEL, 'AbortError') + return request } const randomValue = (type: string, name?: string): any | Array => { @@ -135,45 +136,49 @@ export { handleError, interceptRequest, randomValue } -const checkCommon = (config: AxiosRequestConfig, type: string, id?: string, token?: string, relationship?: string) => { - expect(config.url).toBe(type + (id ? `/${id}` : '') + (relationship ? `/${relationship}`: '')) - expect(config.headers?.Authorization).toContain('Bearer ' + (token || '')) - expect(config.timeout).toBe(REQUEST_TIMEOUT) +const checkCommon = (request: RequestObj, type: string, id?: string, token?: string, relationship?: string) => { + expect(request.url.pathname).toBe('/api/' + type + (id ? `/${id}` : '') + (relationship ? `/${relationship}`: '')) + expect(request.options.headers).toBeDefined() + if (request.options.headers) expect(request.options.headers['Authorization']).toContain('Bearer ' + (token || '')) + expect(request.options.signal).not.toBeNull() } -const checkCommonData = (config: AxiosRequestConfig, type: string, attributes: any, id?: string) => { - if (id) expect(config.data.data.id).toBe(id) - expect(config.data.data.type).toBe(type) +const checkCommonData = (data: any, type: string, attributes: any, id?: string) => { + if (id) expect(data.data.id).toBe(id) + expect(data.data.type).toBe(type) const relationships: { [k: string]: any } = {} - Object.entries(config.data.data.relationships).forEach(([k, v]) => relationships[k] = (v as any)['data']) + Object.entries(data.data.relationships).forEach(([k, v]) => relationships[k] = (v as any)['data']) const received = { - ...config.data.data.attributes, + ...data.data.attributes, ...relationships } expect(isEqual(received, attributes)).toBeTruthy() } -const checkParam = (params: any, name: string, value: string | number | boolean) => { - expect(params).toHaveProperty([name]) - expect(params[name]).toBe(String(value)) +const checkParam = (url: string | URL, name: string, value: string | number | boolean) => { + const params = (url instanceof URL)? url.searchParams : new URL(url).searchParams + expect(params.has(name)).toBeTruthy() + expect(params.get(name)).toBe(String(value)) } -const checkCommonParamsList = (config: AxiosRequestConfig, params: QueryParamsList) => { - if (params.pageNumber) checkParam(config.params, 'page[number]', params.pageNumber) - if (params.pageSize) checkParam(config.params, 'page[size]', params.pageSize) - if (params.filters?.reference_eq) checkParam(config.params, 'filter[q][reference_eq]', params.filters.reference_eq) +const checkCommonParamsList = (request: RequestObj, params: QueryParamsList) => { + const url = new URL(request.url) + if (params.pageNumber) checkParam(url, 'page[number]', params.pageNumber) + if (params.pageSize) checkParam(url, 'page[size]', params.pageSize) + if (params.filters?.reference_eq) checkParam(url, 'filter[q][reference_eq]', String(params.filters.reference_eq)) if (params.sort) { let value: string if (Array.isArray(params.sort)) value = params.sort.join(',') else value = Object.entries(params.sort).map(([k, v]) => `${(v === 'desc') ? '-' : ''}${k}`).join(',') - checkParam(config.params, 'sort', value) + checkParam(url, 'sort', value) } } -const checkCommonParams = (config: AxiosRequestConfig, params: QueryParamsRetrieve) => { +const checkCommonParams = (request: RequestObj, params: QueryParamsRetrieve) => { if (params.fields) { + const url = new URL(request.url) Object.entries(params.fields).forEach(([type, fields]) => { - checkParam(config.params, `fields[${type}]`, fields.join(',')) + checkParam(url, `fields[${type}]`, fields.join(',')) }) } } diff --git a/test/interceptor.ts b/test/interceptor.ts index d2ff0cf..df0d6b2 100644 --- a/test/interceptor.ts +++ b/test/interceptor.ts @@ -5,7 +5,6 @@ import getToken from './token' const requestInterceptor = (request: RequestObj): RequestObj => { console.log('INSIDE REQUEST INTERCEPTOR') - // console.log(request) return request } diff --git a/test/spot.ts b/test/spot.ts index 0adf463..f134b01 100644 --- a/test/spot.ts +++ b/test/spot.ts @@ -7,17 +7,25 @@ import getToken from './token' (async () => { const auth = await getToken('user') + + const domain = process.env.CL_SDK_DOMAIN const accessToken = auth ? auth.accessToken : '' const clp = clProvisioning({ accessToken, - timeout: 5000, + domain }) try { const organizations = await clp.organizations.list() - console.log(organizations) + const org = organizations.first() + + if (org) { + const reader = clp.addRawResponseReader() + await clp.organizations.transfer_ownership(org.id, { id: '123', type: 'organizations', new_owner_email: 'pierluigi@commercelayer.io'}) + console.log(reader.rawResponse) + } } catch (error: any) { console.log(inspect(error, false, null, true)) diff --git a/test/token.ts b/test/token.ts index 3c06272..8d5d979 100644 --- a/test/token.ts +++ b/test/token.ts @@ -1,4 +1,4 @@ -import { provisioning } from '@commercelayer/js-auth' +import { AuthenticateOptions, authenticate } from '@commercelayer/js-auth' import dotenv from 'dotenv' dotenv.config() @@ -45,12 +45,12 @@ export default async (type: TokenType): Promise => { const getAccessToken = async (auth: AuthData): Promise => { - const credentials: any = { + const credentials: AuthenticateOptions<'client_credentials'> = { clientId: auth.clientId, clientSecret: auth.clientSecret, - domain: auth.domain + domain: auth.domain || undefined } - return provisioning.authentication(credentials) + return authenticate('client_credentials', credentials) }