Compare commits
18 Commits
1da2dc9c26
...
master
Author | SHA1 | Date | |
---|---|---|---|
e6e67c2f47 | |||
9be52f1f9a | |||
cf5827bab1 | |||
36bdd23de4 | |||
146d14a1b8 | |||
acda0ff525 | |||
17f05dd9e2 | |||
b1a4be4cf8 | |||
31235b363c | |||
a68f3964e1 | |||
5cc8f45f90 | |||
55f9050dc9 | |||
4e7d00db9b | |||
13e639fa8d | |||
20c21ea73d | |||
a6c220b499 | |||
58770bf89f | |||
4bc155683b |
30
package.json
30
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "axp-ts",
|
"name": "axp-ts",
|
||||||
"version": "1.9.6",
|
"version": "1.13.0",
|
||||||
"description": "TypeScript helper library",
|
"description": "TypeScript helper library",
|
||||||
"author": "AntoXa PRO <info@antoxa.pro>",
|
"author": "AntoXa PRO <info@antoxa.pro>",
|
||||||
"homepage": "https://antoxahub.ru/antoxa/axp-ts",
|
"homepage": "https://antoxahub.ru/antoxa/axp-ts",
|
||||||
@@ -8,20 +8,36 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://antoxahub.ru/antoxa/axp-ts.git"
|
"url": "https://antoxahub.ru/antoxa/axp-ts.git"
|
||||||
},
|
},
|
||||||
"main": "dist/index.js",
|
"module": "./dist/index.mjs",
|
||||||
|
"main": "./dist/index.umd.js",
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"types": "./dist/index.d.ts",
|
||||||
|
"import": "./dist/index.mjs",
|
||||||
|
"requier": "./dist/index.umd.js"
|
||||||
|
},
|
||||||
|
"./dist/*": "./dist/*",
|
||||||
|
"./src/*": "./src/*",
|
||||||
|
"./package.json": "./package.json",
|
||||||
|
"./tsconfig.json": "./tsconfig.json"
|
||||||
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist",
|
"dist",
|
||||||
"tsconfig.ts"
|
"src",
|
||||||
|
"tsconfig.json"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "vite build",
|
||||||
"prepare": "npm run build"
|
"prepare": "npm run build"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"peerDependencies": {
|
||||||
"zod": "^3.21.4"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prettier": "^2.8.8",
|
"prettier": "^2.8.8",
|
||||||
"typescript": "^4.9.5"
|
"typescript": "^5.6.2",
|
||||||
|
"vite": "^4.5.5",
|
||||||
|
"vite-plugin-dts": "^3.9.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -12,12 +12,17 @@ import {
|
|||||||
} from './helpers'
|
} from './helpers'
|
||||||
import { FormSchemaCtrl } from './ctrl'
|
import { FormSchemaCtrl } from './ctrl'
|
||||||
|
|
||||||
|
export type TUiFieldSelectOption = {
|
||||||
|
text: string
|
||||||
|
value: string
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create field schema.
|
* Create field schema.
|
||||||
*/
|
*/
|
||||||
export const fieldSchema = <T extends ZodTypeAny>(
|
export const fieldSchema = <T extends ZodTypeAny>(
|
||||||
base: T,
|
base: T,
|
||||||
args?: TFormSchemaCtrlArgs
|
args: TFormSchemaCtrlArgs = {}
|
||||||
) => base.describe(FormSchemaCtrl.toString(args, base.description))
|
) => base.describe(FormSchemaCtrl.toString(args, base.description))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,8 +41,6 @@ export const bFieldsSchema = {
|
|||||||
string: z
|
string: z
|
||||||
.string()
|
.string()
|
||||||
.trim()
|
.trim()
|
||||||
.min(2)
|
|
||||||
.max(64)
|
|
||||||
.describe(
|
.describe(
|
||||||
FormSchemaCtrl.toString({
|
FormSchemaCtrl.toString({
|
||||||
label: 'Строка',
|
label: 'Строка',
|
||||||
@@ -79,16 +82,6 @@ export const cFieldsSchema = z.object({
|
|||||||
dateUpdate: fieldSchema(bFieldsSchema.date, {
|
dateUpdate: fieldSchema(bFieldsSchema.date, {
|
||||||
label: 'Дата изменения'
|
label: 'Дата изменения'
|
||||||
}),
|
}),
|
||||||
q: fieldSchema(
|
|
||||||
z.preprocess(
|
|
||||||
val => String(val).replace(regexSearch, ''),
|
|
||||||
bFieldsSchema.string
|
|
||||||
),
|
|
||||||
{
|
|
||||||
label: 'Поиск',
|
|
||||||
component: 'ui-field-search'
|
|
||||||
}
|
|
||||||
),
|
|
||||||
name: fieldSchema(bFieldsSchema.string, {
|
name: fieldSchema(bFieldsSchema.string, {
|
||||||
label: 'Название'
|
label: 'Название'
|
||||||
}),
|
}),
|
||||||
@@ -187,5 +180,23 @@ export const cFieldsSchema = z.object({
|
|||||||
days: fieldSchema(bFieldsSchema.number.array(), {
|
days: fieldSchema(bFieldsSchema.number.array(), {
|
||||||
label: 'Дни недели',
|
label: 'Дни недели',
|
||||||
component: 'ui-picker-days'
|
component: 'ui-picker-days'
|
||||||
})
|
}),
|
||||||
|
q: fieldSchema(
|
||||||
|
z.preprocess(
|
||||||
|
val => String(val).replace(regexSearch, ''),
|
||||||
|
bFieldsSchema.string
|
||||||
|
),
|
||||||
|
{
|
||||||
|
label: 'Поиск',
|
||||||
|
component: 'ui-field-search'
|
||||||
|
}
|
||||||
|
),
|
||||||
|
page: fieldSchema(
|
||||||
|
z.preprocess(val => Math.abs(Number(val)), bFieldsSchema.number),
|
||||||
|
{ label: 'Страница' }
|
||||||
|
),
|
||||||
|
limit: fieldSchema(
|
||||||
|
z.preprocess(val => Math.abs(Number(val)), bFieldsSchema.number),
|
||||||
|
{ label: 'Лимит' }
|
||||||
|
)
|
||||||
})
|
})
|
@@ -3,7 +3,6 @@ import type { TNotificationItem } from '../notification'
|
|||||||
|
|
||||||
import { FormSchemaCtrl } from './ctrl'
|
import { FormSchemaCtrl } from './ctrl'
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Интерфейс базовой формы для сущностей в БД.
|
* Интерфейс базовой формы для сущностей в БД.
|
||||||
*/
|
*/
|
||||||
@@ -27,7 +26,7 @@ export interface IFormModel<T> {
|
|||||||
/**
|
/**
|
||||||
* Базовая модель для валидирования форм.
|
* Базовая модель для валидирования форм.
|
||||||
*/
|
*/
|
||||||
export class BaseFormModel<T extends Object = {}> implements IFormModel<T> {
|
export class BaseFormModel<T extends object = {}> implements IFormModel<T> {
|
||||||
_id: string
|
_id: string
|
||||||
|
|
||||||
dateCreate?: Date
|
dateCreate?: Date
|
||||||
@@ -74,7 +73,7 @@ export class BaseFormModel<T extends Object = {}> implements IFormModel<T> {
|
|||||||
let items: TNotificationItem[] = []
|
let items: TNotificationItem[] = []
|
||||||
for (const code in this._errors) {
|
for (const code in this._errors) {
|
||||||
const text = this._errors[code]
|
const text = this._errors[code]
|
||||||
items.push({ code, text })
|
if (text) items.push({ code, text })
|
||||||
}
|
}
|
||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
@@ -95,6 +94,17 @@ export class BaseFormModel<T extends Object = {}> implements IFormModel<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setValidError(code: string, text: string) {
|
setValidError(code: string, text: string) {
|
||||||
this._errors[code] = code + ' - ' + text
|
let obj:any = {}
|
||||||
|
obj[code] = code + ' - ' + text
|
||||||
|
this._errors = Object.assign(this._errors, obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
mergeObj(obj: any) {
|
||||||
|
this.obj = Object.assign(this.obj, obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCtrl(key: keyof T, ctrl: Partial<FormSchemaCtrl>) {
|
||||||
|
const fieldIndex = this.ctrls.findIndex(e => e.key === key)
|
||||||
|
this.ctrls[fieldIndex] = Object.assign(this.ctrls[fieldIndex], ctrl)
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -1,5 +1,5 @@
|
|||||||
export * from './entities'
|
export * from './utils'
|
||||||
export * from './form'
|
|
||||||
export * from './notification'
|
export * from './notification'
|
||||||
export * from './pagination'
|
export * from './entities'
|
||||||
export * from './data-result'
|
export * from './requests'
|
||||||
|
export * from './forms'
|
||||||
|
@@ -7,8 +7,8 @@ export class NotificationItem implements TNotificationItem {
|
|||||||
code: string
|
code: string
|
||||||
text: string
|
text: string
|
||||||
|
|
||||||
constructor(args: {code: string, text: string }) {
|
constructor(args: { text: string, code?: string }) {
|
||||||
this.code = args.code
|
|
||||||
this.text = args.text
|
this.text = args.text
|
||||||
|
this.code = args.code || 'info'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import type { TPagination } from './pagination'
|
import type { TPagination } from './pagination'
|
||||||
import type { TNotificationItem } from './notification'
|
import type { TNotificationItem } from '../notification'
|
||||||
|
|
||||||
import { Pagination } from './pagination'
|
import { Pagination } from './pagination'
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ export class DataResultEntity<T> implements IDataResult<T> {
|
|||||||
this.setData()
|
this.setData()
|
||||||
}
|
}
|
||||||
|
|
||||||
setData(data: T = null, pagination?: TPagination): void {
|
setData(data: T | null = null, pagination?: TPagination): void {
|
||||||
if (data !== null) {
|
if (data !== null) {
|
||||||
this.data = data
|
this.data = data
|
||||||
}
|
}
|
122
src/requests/find-filter.ts
Normal file
122
src/requests/find-filter.ts
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
import type { TPaginationQuery } from './pagination'
|
||||||
|
|
||||||
|
import { z } from 'zod'
|
||||||
|
import { isEqual } from '../utils'
|
||||||
|
import { Pagination, paginationQuerySchema } from './pagination'
|
||||||
|
import { bFieldsSchema, cFieldsSchema, fieldSchema } from '../forms'
|
||||||
|
|
||||||
|
export const querySchema = cFieldsSchema
|
||||||
|
.pick({ q: true })
|
||||||
|
.extend(paginationQuerySchema.shape)
|
||||||
|
.extend({
|
||||||
|
sort: fieldSchema(bFieldsSchema.string.min(1).max(64), {
|
||||||
|
label: 'Сортировка'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.partial()
|
||||||
|
.describe('Параметры базового запроса')
|
||||||
|
|
||||||
|
export type TQuery = z.infer<typeof querySchema>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Класс для работы с запросами (для удобства).
|
||||||
|
*/
|
||||||
|
export type TFindFilter<T extends TQuery> = {
|
||||||
|
obj?: Omit<T, 'page' | 'limit' | 'sort'>
|
||||||
|
pagination?: TPaginationQuery
|
||||||
|
sort?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Класс для работы с запросами (для удобства).
|
||||||
|
*/
|
||||||
|
export class FindFilter<T extends TQuery> implements TFindFilter<T> {
|
||||||
|
obj?: Omit<T, 'page' | 'limit' | 'sort'>
|
||||||
|
pagination?: TPaginationQuery
|
||||||
|
sort?: string
|
||||||
|
|
||||||
|
static getQuery<T extends TQuery>(filter: TFindFilter<T>): T {
|
||||||
|
return Object.assign(
|
||||||
|
{ ...filter.obj, ...filter.pagination },
|
||||||
|
{ sort: filter.sort }
|
||||||
|
) as T
|
||||||
|
}
|
||||||
|
|
||||||
|
static parse<T extends TQuery>(filter: TFindFilter<T>): FindFilter<T> {
|
||||||
|
return new FindFilter<T>(this.getQuery(filter))
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(query?: T) {
|
||||||
|
// Copy fiends.
|
||||||
|
let queryCopy: T = Object.assign({}, query)
|
||||||
|
|
||||||
|
// Pagination.
|
||||||
|
this.pagination = new Pagination(queryCopy).getQuery()
|
||||||
|
// Delete pagination fields.
|
||||||
|
if (this.pagination as TPaginationQuery) {
|
||||||
|
const paginationKeys = Object.keys(this.pagination) as [keyof T]
|
||||||
|
for (const key of paginationKeys) {
|
||||||
|
if (queryCopy[key]) delete queryCopy[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort.
|
||||||
|
if (queryCopy.sort) {
|
||||||
|
this.sort = queryCopy.sort
|
||||||
|
delete queryCopy.sort
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obj.
|
||||||
|
this.obj = queryCopy
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated.
|
||||||
|
*/
|
||||||
|
setPagination(pagination?: TPaginationQuery) {
|
||||||
|
this.pagination = new Pagination(pagination).getQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
toObject(): TFindFilter<T> {
|
||||||
|
return {
|
||||||
|
obj: this.obj,
|
||||||
|
pagination: this.pagination,
|
||||||
|
sort: this.sort
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toString(opt?: { base?: string }): string {
|
||||||
|
let url = opt?.base?.replace(/[?]$/, '') || ''
|
||||||
|
|
||||||
|
const query: string[] = []
|
||||||
|
|
||||||
|
// Params and Pagination.
|
||||||
|
for (const [key, val] of Object.entries({
|
||||||
|
...this.obj,
|
||||||
|
...this.pagination
|
||||||
|
})) {
|
||||||
|
if (val) {
|
||||||
|
const keyEncode = encodeURIComponent(key)
|
||||||
|
const valEncode = encodeURIComponent(val)
|
||||||
|
query.push(keyEncode + '=' + valEncode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort.
|
||||||
|
if (this.sort) {
|
||||||
|
try {
|
||||||
|
query.push('sort=' + encodeURIComponent(this.sort))
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.length) {
|
||||||
|
url += query.join('&')
|
||||||
|
}
|
||||||
|
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
|
||||||
|
isEqual(filters: TFindFilter<T>[]) {
|
||||||
|
return isEqual([this, ...filters])
|
||||||
|
}
|
||||||
|
}
|
3
src/requests/index.ts
Normal file
3
src/requests/index.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export * from './pagination'
|
||||||
|
export * from './data-result'
|
||||||
|
export * from './find-filter'
|
@@ -1,13 +1,15 @@
|
|||||||
import { z } from 'zod'
|
import { z } from 'zod'
|
||||||
import { cFieldsSchema, fieldSchema } from './form'
|
import { cFieldsSchema, fieldSchema } from '../forms'
|
||||||
|
|
||||||
export const paginationSchema = z.object({
|
/**
|
||||||
page: fieldSchema(cFieldsSchema.shape.number, {
|
* Модель данных для пагинайи.
|
||||||
label: 'Номер страницы'
|
*/
|
||||||
}),
|
export const paginationSchema = cFieldsSchema
|
||||||
limit: fieldSchema(cFieldsSchema.shape.number, {
|
.pick({
|
||||||
label: 'Лимит на странице'
|
page: true,
|
||||||
}),
|
limit: true
|
||||||
|
})
|
||||||
|
.extend({
|
||||||
total: fieldSchema(cFieldsSchema.shape.number, {
|
total: fieldSchema(cFieldsSchema.shape.number, {
|
||||||
label: 'Общее кол-во'
|
label: 'Общее кол-во'
|
||||||
}),
|
}),
|
||||||
@@ -18,57 +20,48 @@ export const paginationSchema = z.object({
|
|||||||
label: 'Кол-во всех страниц'
|
label: 'Кол-во всех страниц'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
.describe('Данные пагинации')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Модель данных для пагинайи.
|
||||||
|
*/
|
||||||
export type TPagination = z.infer<typeof paginationSchema>
|
export type TPagination = z.infer<typeof paginationSchema>
|
||||||
|
|
||||||
// Константы.
|
/**
|
||||||
|
* Модель данных для пагинайи для запросе.
|
||||||
|
*/
|
||||||
|
export const paginationQuerySchema = paginationSchema
|
||||||
|
.pick({
|
||||||
|
page: true,
|
||||||
|
limit: true
|
||||||
|
})
|
||||||
|
.partial()
|
||||||
|
.describe('Параметры разбиения на страницы')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Модель данных для пагинайи для запросе.
|
||||||
|
*/
|
||||||
|
export type TPaginationQuery = z.infer<typeof paginationQuerySchema>
|
||||||
|
|
||||||
|
//
|
||||||
|
// Переделать.
|
||||||
|
//
|
||||||
const DEFAULTS = { page: 1, limit: 10, maxLimit: 100 }
|
const DEFAULTS = { page: 1, limit: 10, maxLimit: 100 }
|
||||||
|
|
||||||
export type TPaginationParseArg = number | string | undefined
|
export type TPaginationParseArg = number | string | undefined
|
||||||
|
|
||||||
export type TPaginationArguments = {
|
export type TPaginationArguments = {
|
||||||
page?: TPaginationParseArg
|
page?: TPaginationParseArg
|
||||||
limit?: TPaginationParseArg
|
limit?: TPaginationParseArg
|
||||||
total?: number
|
total?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPagination extends TPagination {
|
/**
|
||||||
|
* @todo Переделать логику.
|
||||||
|
*/
|
||||||
|
export class Pagination implements TPagination {
|
||||||
/**
|
/**
|
||||||
* Максимальный лимит элементов.
|
* Максимальный лимит элементов.
|
||||||
*/
|
*/
|
||||||
get maxLimit(): number
|
#maxLimit: number
|
||||||
|
|
||||||
/**
|
|
||||||
* Парсинг аргументов.
|
|
||||||
* @param arg - Значение аргумента для парсинга.
|
|
||||||
* @param defaultReturnValue - Возвращаемое значение по умолчанию.
|
|
||||||
* @returns Возвращает абсолютное значение числа аргумента.
|
|
||||||
*/
|
|
||||||
parseArg(
|
|
||||||
arg: number | string | undefined,
|
|
||||||
defaultReturnValue: number
|
|
||||||
): number
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Присваивает значения для основных свойств класса и считает кол-во
|
|
||||||
* пропускаемых элементов в зависимости от полученных аргументов.
|
|
||||||
* @param args - Аргументы пагинации.
|
|
||||||
* @returns Возвращает текущий экземпляр класса.
|
|
||||||
*/
|
|
||||||
set(args: TPaginationArguments): this
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Возвращает простой объект пагинации.
|
|
||||||
* @returns Объект пагинации.
|
|
||||||
*/
|
|
||||||
toObject(): TPagination
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Pagination implements IPagination {
|
|
||||||
/**
|
|
||||||
* Максимальный лимит элементов.
|
|
||||||
*/
|
|
||||||
private _maxLimit: number
|
|
||||||
|
|
||||||
page: number = DEFAULTS.page
|
page: number = DEFAULTS.page
|
||||||
limit: number = DEFAULTS.limit
|
limit: number = DEFAULTS.limit
|
||||||
@@ -89,14 +82,10 @@ export class Pagination implements IPagination {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constructor(args: TPaginationArguments = {}, maxLimit?: number) {
|
constructor(args: TPaginationArguments = {}, maxLimit?: number) {
|
||||||
this._maxLimit = this.parseArg(maxLimit, DEFAULTS.maxLimit)
|
this.#maxLimit = this.parseArg(maxLimit, DEFAULTS.maxLimit)
|
||||||
this.set(args)
|
this.set(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
get maxLimit() {
|
|
||||||
return this._maxLimit
|
|
||||||
}
|
|
||||||
|
|
||||||
parseArg(arg: TPaginationParseArg, defaultReturnValue: number): number {
|
parseArg(arg: TPaginationParseArg, defaultReturnValue: number): number {
|
||||||
return Pagination.parseArg(arg, defaultReturnValue)
|
return Pagination.parseArg(arg, defaultReturnValue)
|
||||||
}
|
}
|
||||||
@@ -118,7 +107,7 @@ export class Pagination implements IPagination {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Проверка лимита.
|
// Проверка лимита.
|
||||||
if (this.limit > this.maxLimit) this.limit = this.maxLimit
|
if (this.limit > this.#maxLimit) this.limit = this.#maxLimit
|
||||||
|
|
||||||
// Общее кол-во.
|
// Общее кол-во.
|
||||||
if (args.total && args.total !== this.total) {
|
if (args.total && args.total !== this.total) {
|
||||||
@@ -143,9 +132,12 @@ export class Pagination implements IPagination {
|
|||||||
page: this.page,
|
page: this.page,
|
||||||
limit: this.limit,
|
limit: this.limit,
|
||||||
total: this.total,
|
total: this.total,
|
||||||
|
|
||||||
skip: this.skip,
|
skip: this.skip,
|
||||||
pages: this.pages
|
pages: this.pages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getQuery(): TPaginationQuery {
|
||||||
|
return { page: this.page, limit: this.limit }
|
||||||
|
}
|
||||||
}
|
}
|
1
src/utils/index.ts
Normal file
1
src/utils/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './objects'
|
30
src/utils/objects.ts
Normal file
30
src/utils/objects.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
export const isEqual = <T extends object>(objects: T[]) => {
|
||||||
|
for (let i = 0; i < objects.length; i++) {
|
||||||
|
|
||||||
|
const obj1: T = objects[i]
|
||||||
|
const obj2: T = objects[i + 1]
|
||||||
|
|
||||||
|
if (obj2) {
|
||||||
|
const keys1 = Object.keys(obj1) as [keyof T]
|
||||||
|
const keys2 = Object.keys(obj2) as [keyof T]
|
||||||
|
|
||||||
|
if (keys1.length !== keys2.length) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const key of keys1) {
|
||||||
|
if (typeof obj1[key] !== 'object') {
|
||||||
|
if (obj1[key] !== obj2[key]) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!isEqual([obj1[key], obj2[key]] as T[])) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
@@ -1,13 +1,15 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"rootDir": "src",
|
"target": "ESNext",
|
||||||
"outDir": "dist",
|
"module": "ESNext",
|
||||||
"target": "ES6",
|
|
||||||
"module": "CommonJS",
|
"strict": true,
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "Node",
|
||||||
"lib": ["es2017"],
|
"isolatedModules": true,
|
||||||
"declaration": true,
|
"esModuleInterop": true,
|
||||||
"sourceMap": true
|
"useDefineForClassFields": true,
|
||||||
|
|
||||||
|
"declaration": true
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules", "dist"]
|
"include": ["src/**/*.ts", "src/**/*.d.ts"]
|
||||||
}
|
}
|
||||||
|
13
vite.config.ts
Normal file
13
vite.config.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import dts from 'vite-plugin-dts'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [dts()],
|
||||||
|
build: {
|
||||||
|
lib: {
|
||||||
|
entry: 'src/index.ts',
|
||||||
|
name: 'axp-ts',
|
||||||
|
fileName: 'index'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
Reference in New Issue
Block a user