Fixed issues with query builder
This commit is contained in:
parent
a1c95a019a
commit
f04aaca29e
@ -5,7 +5,7 @@ const nextConfig: NextConfig = {
|
|||||||
remotePatterns: [
|
remotePatterns: [
|
||||||
{
|
{
|
||||||
protocol: 'https',
|
protocol: 'https',
|
||||||
hostname: 'media.bambooapp.ai',
|
hostname: 'media.taylordb.ai',
|
||||||
pathname: '/files/**',
|
pathname: '/files/**',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@ -7,7 +7,8 @@
|
|||||||
"dev": "next dev --turbopack",
|
"dev": "next dev --turbopack",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "eslint ."
|
"lint": "eslint .",
|
||||||
|
"regenerate:types": "npx @taylordb/cli generate-schema af483cef-ec47-48fc-b186-e11022dbb0e2 src/shared/database.types.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@hookform/resolvers": "^5.0.1",
|
"@hookform/resolvers": "^5.0.1",
|
||||||
@ -25,7 +26,8 @@
|
|||||||
"@radix-ui/react-toast": "^1.2.11",
|
"@radix-ui/react-toast": "^1.2.11",
|
||||||
"@radix-ui/react-tooltip": "^1.2.6",
|
"@radix-ui/react-tooltip": "^1.2.6",
|
||||||
"@reduxjs/toolkit": "^2.7.0",
|
"@reduxjs/toolkit": "^2.7.0",
|
||||||
"@taylordb/query-builder": "^0.10.1",
|
"@taylordb/cli": "^0.18.2",
|
||||||
|
"@taylordb/query-builder": "^0.18.2",
|
||||||
"aos": "^2.3.4",
|
"aos": "^2.3.4",
|
||||||
"axios": "^1.9.0",
|
"axios": "^1.9.0",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
|
|||||||
639
pnpm-lock.yaml
generated
639
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1,32 +1,33 @@
|
|||||||
import { isEmpty } from 'lodash';
|
import { TaylorDatabase } from '@/shared/types/database.types';
|
||||||
|
|
||||||
import {
|
type TaylorColumnRaw<TColumn> = TColumn extends {
|
||||||
AttachmentColumnValue,
|
raw: infer TRaw;
|
||||||
TableRaws,
|
isRequired: true;
|
||||||
} from '@/shared/types/database.types';
|
}
|
||||||
|
? TRaw
|
||||||
|
: TColumn extends { raw: infer TRaw }
|
||||||
|
? TRaw | undefined
|
||||||
|
: never;
|
||||||
|
|
||||||
// Helper to get image URL from Attachment array
|
type TableRaws<TTableName extends keyof TaylorDatabase> = {
|
||||||
export const getAttachmentUrl = (
|
[K in keyof TaylorDatabase[TTableName]]: TaylorColumnRaw<
|
||||||
attachments: AttachmentColumnValue[] | undefined | null,
|
TaylorDatabase[TTableName][K]
|
||||||
): string | null => {
|
>;
|
||||||
if (isEmpty(attachments) || !attachments?.[0]) return null;
|
|
||||||
const attachment = attachments[0];
|
|
||||||
return `${process.env.TAYLOR_MEDIA_URL}/${attachment.url}`;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper to get link select name (link to selectTable returns object with name)
|
const getAttachmentUrl = (urls: string[] | undefined): string | null => {
|
||||||
export const getLinkSelectName = (
|
if (!urls?.length) return null;
|
||||||
link: { name: string } | undefined | null,
|
|
||||||
): string | null => {
|
|
||||||
return link?.name || null;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Helper to get multiple link select names (for arrays of links)
|
const [url] = urls;
|
||||||
export const getLinkSelectNames = (
|
if (!url) return null;
|
||||||
links: Array<{ name: string }> | undefined | null,
|
|
||||||
): string[] => {
|
if (/^https?:\/\//.test(url)) {
|
||||||
if (!links || isEmpty(links)) return [];
|
return url;
|
||||||
return links.map((link) => link.name);
|
}
|
||||||
|
|
||||||
|
return process.env.TAYLOR_MEDIA_URL
|
||||||
|
? `${process.env.TAYLOR_MEDIA_URL}/${url}`
|
||||||
|
: url;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Presenters for TaylorDB query builder results (direct array format, no wrapper)
|
// Presenters for TaylorDB query builder results (direct array format, no wrapper)
|
||||||
@ -53,13 +54,9 @@ export const presentJobsFromTaylor = (
|
|||||||
return jobs.map((job, index) => ({
|
return jobs.map((job, index) => ({
|
||||||
id: index + 1,
|
id: index + 1,
|
||||||
name: job.zagolovok || '',
|
name: job.zagolovok || '',
|
||||||
// tegi is a LinkColumnType, so it returns objects when loaded with .with()
|
tags: job.tegi || [],
|
||||||
tags: Array.isArray(job.tegi)
|
location: job.lokaciya || null,
|
||||||
? (job.tegi as Array<{ name: string }>).map((tag) => tag.name)
|
type: job.tip || null,
|
||||||
: [],
|
|
||||||
// tip and lokaciya are SingleSelectColumnType, which return arrays of strings
|
|
||||||
location: job.lokaciya?.[0] || null,
|
|
||||||
type: job.tip?.[0] || null,
|
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -108,9 +105,7 @@ export const presentStationsFromTaylor = (
|
|||||||
name: station.imya || '',
|
name: station.imya || '',
|
||||||
description: station.opisanie || '',
|
description: station.opisanie || '',
|
||||||
address: station.adress || '',
|
address: station.adress || '',
|
||||||
// chasyRaboty and region are SingleSelectColumnType, which return arrays of strings
|
workingHours: station.chasyRaboty || null,
|
||||||
workingHours: station.chasyRaboty?.[0] || null,
|
|
||||||
// Parse string coordinates to numbers
|
|
||||||
latitude: parseFloat(station.lat || '0') || 0,
|
latitude: parseFloat(station.lat || '0') || 0,
|
||||||
longitude: parseFloat(station.long || '0') || 0,
|
longitude: parseFloat(station.long || '0') || 0,
|
||||||
carWash: station.avtomojka || false,
|
carWash: station.avtomojka || false,
|
||||||
@ -122,7 +117,7 @@ export const presentStationsFromTaylor = (
|
|||||||
electricCharge: station.zaryadnayaStanciya || false,
|
electricCharge: station.zaryadnayaStanciya || false,
|
||||||
miniMarket: station.miniMarket || false,
|
miniMarket: station.miniMarket || false,
|
||||||
toilet: station.tualet || false,
|
toilet: station.tualet || false,
|
||||||
region: station.region?.[0] || null,
|
region: station.region || null,
|
||||||
image: getAttachmentUrl(station.foto),
|
image: getAttachmentUrl(station.foto),
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|||||||
@ -30,36 +30,16 @@ export async function fetchMainPageContent(): Promise<MainPageData> {
|
|||||||
await taylorQueryBuilder
|
await taylorQueryBuilder
|
||||||
.batch([
|
.batch([
|
||||||
// Fetch partners
|
// Fetch partners
|
||||||
taylorQueryBuilder
|
taylorQueryBuilder.selectFrom('partnyory').selectAll(),
|
||||||
.selectFrom('partnyory')
|
|
||||||
.selectAll()
|
|
||||||
.with({
|
|
||||||
izobrozhenie: (qb) => qb.selectAll(),
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Fetch jobs
|
// Fetch jobs
|
||||||
taylorQueryBuilder
|
taylorQueryBuilder.selectFrom('vakansii').selectAll(),
|
||||||
.selectFrom('vakansii')
|
|
||||||
.selectAll()
|
|
||||||
.with({
|
|
||||||
tegi: (qb) => qb.select(['name']),
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Fetch discounts
|
// Fetch discounts
|
||||||
taylorQueryBuilder
|
taylorQueryBuilder.selectFrom('akcii').selectAll(),
|
||||||
.selectFrom('akcii')
|
|
||||||
.selectAll()
|
|
||||||
.with({
|
|
||||||
foto: (qb) => qb.selectAll(),
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Fetch stations
|
// Fetch stations
|
||||||
taylorQueryBuilder
|
taylorQueryBuilder.selectFrom('azs').selectAll(),
|
||||||
.selectFrom('azs')
|
|
||||||
.selectAll()
|
|
||||||
.with({
|
|
||||||
foto: (qb) => qb.selectAll(),
|
|
||||||
}),
|
|
||||||
])
|
])
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
@ -82,12 +62,7 @@ export async function fetchAboutUsPageContent(): Promise<AboutUsPageData> {
|
|||||||
await taylorQueryBuilder
|
await taylorQueryBuilder
|
||||||
.batch([
|
.batch([
|
||||||
// Fetch team members
|
// Fetch team members
|
||||||
taylorQueryBuilder
|
taylorQueryBuilder.selectFrom('komanda').selectAll(),
|
||||||
.selectFrom('komanda')
|
|
||||||
.selectAll()
|
|
||||||
.with({
|
|
||||||
foto: (qb) => qb.selectAll(),
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Fetch history items
|
// Fetch history items
|
||||||
taylorQueryBuilder.selectFrom('istoriyaKompanii').selectAll(),
|
taylorQueryBuilder.selectFrom('istoriyaKompanii').selectAll(),
|
||||||
@ -96,10 +71,7 @@ export async function fetchAboutUsPageContent(): Promise<AboutUsPageData> {
|
|||||||
taylorQueryBuilder
|
taylorQueryBuilder
|
||||||
.selectFrom('azs')
|
.selectFrom('azs')
|
||||||
.selectAll()
|
.selectAll()
|
||||||
.where('foto', 'isNotEmpty')
|
.where('foto', 'isNotEmpty'),
|
||||||
.with({
|
|
||||||
foto: (qb) => qb.selectAll(),
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Fetch reviews (filtered by published status)
|
// Fetch reviews (filtered by published status)
|
||||||
taylorQueryBuilder
|
taylorQueryBuilder
|
||||||
@ -126,9 +98,6 @@ export async function fetchCharityPageContent(): Promise<CharityPageData> {
|
|||||||
const charitiesData = await taylorQueryBuilder
|
const charitiesData = await taylorQueryBuilder
|
||||||
.selectFrom('blagotvoritelnyjFond')
|
.selectFrom('blagotvoritelnyjFond')
|
||||||
.selectAll()
|
.selectAll()
|
||||||
.with({
|
|
||||||
foto: (qb) => qb.selectAll(),
|
|
||||||
})
|
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
console.log('Loading charity page content...');
|
console.log('Loading charity page content...');
|
||||||
@ -145,9 +114,6 @@ export async function fetchCertificatesPageContent(): Promise<CertificatesPageDa
|
|||||||
const certificatesData = await taylorQueryBuilder
|
const certificatesData = await taylorQueryBuilder
|
||||||
.selectFrom('sertifikaty')
|
.selectFrom('sertifikaty')
|
||||||
.selectAll()
|
.selectAll()
|
||||||
.with({
|
|
||||||
foto: (qb) => qb.selectAll(),
|
|
||||||
})
|
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
console.log('Loading certificates page content...');
|
console.log('Loading certificates page content...');
|
||||||
@ -182,9 +148,6 @@ export async function fetchMediaContent(): Promise<
|
|||||||
const mediaData = await taylorQueryBuilder
|
const mediaData = await taylorQueryBuilder
|
||||||
.selectFrom('mediaKontentSajta')
|
.selectFrom('mediaKontentSajta')
|
||||||
.selectAll()
|
.selectAll()
|
||||||
.with({
|
|
||||||
foto: (qb) => qb.selectAll(),
|
|
||||||
})
|
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
console.log('Loading media content...');
|
console.log('Loading media content...');
|
||||||
|
|||||||
@ -4,545 +4,235 @@
|
|||||||
* This source code is licensed under the MIT license found in the
|
* This source code is licensed under the MIT license found in the
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
import {
|
||||||
|
attachmentField,
|
||||||
|
autoDateField,
|
||||||
|
autoNumberField,
|
||||||
|
checkboxField,
|
||||||
|
dateField,
|
||||||
|
defineTaylorSchema,
|
||||||
|
linkField,
|
||||||
|
numberField,
|
||||||
|
searchField,
|
||||||
|
selectField,
|
||||||
|
textField,
|
||||||
|
} from '@taylordb/query-builder';
|
||||||
|
import type { InferTaylorDatabase } from '@taylordb/query-builder';
|
||||||
|
|
||||||
interface FileInformation {
|
export const taylorSchema = defineTaylorSchema({
|
||||||
fieldname: string;
|
attachmentTable: {
|
||||||
originalname: string;
|
id: autoNumberField(),
|
||||||
encoding: string;
|
name: textField({ required: true }),
|
||||||
mimetype: string;
|
metadata: textField({ required: true }),
|
||||||
destination: string;
|
size: numberField({ required: true }),
|
||||||
filename: string;
|
fileType: textField({ required: true }),
|
||||||
path: string;
|
url: textField({ required: true }),
|
||||||
size: number;
|
searchText: searchField(),
|
||||||
format: string;
|
},
|
||||||
width: number;
|
collaborators: {
|
||||||
height: number;
|
id: autoNumberField(),
|
||||||
}
|
name: textField({ required: true }),
|
||||||
|
emailAddress: textField({ required: true }),
|
||||||
|
avatar: textField({ required: true }),
|
||||||
|
searchText: searchField(),
|
||||||
|
},
|
||||||
|
vakansii: {
|
||||||
|
id: autoNumberField(),
|
||||||
|
createdAt: autoDateField(),
|
||||||
|
updatedAt: autoDateField(),
|
||||||
|
searchText: searchField(),
|
||||||
|
zagolovok: textField({ required: false }),
|
||||||
|
tip: selectField({
|
||||||
|
required: false,
|
||||||
|
mode: 'single',
|
||||||
|
options: ['Офис', 'Заправки'] as const,
|
||||||
|
}),
|
||||||
|
lokaciya: selectField({
|
||||||
|
required: false,
|
||||||
|
mode: 'single',
|
||||||
|
options: ['Душанбе'] as const,
|
||||||
|
}),
|
||||||
|
tegi: selectField({
|
||||||
|
required: false,
|
||||||
|
mode: 'multi',
|
||||||
|
options: ['Полный день', 'Опыт от 1 года', 'Мужчины'] as const,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
partnyory: {
|
||||||
|
id: autoNumberField(),
|
||||||
|
createdAt: autoDateField(),
|
||||||
|
updatedAt: autoDateField(),
|
||||||
|
searchText: searchField(),
|
||||||
|
nazvanie: textField({ required: false }),
|
||||||
|
tt: linkField({
|
||||||
|
linkedTo: 'ff',
|
||||||
|
required: false
|
||||||
|
}),
|
||||||
|
izobrozhenie: attachmentField({ required: false }),
|
||||||
|
},
|
||||||
|
azs: {
|
||||||
|
id: autoNumberField(),
|
||||||
|
createdAt: autoDateField(),
|
||||||
|
updatedAt: autoDateField(),
|
||||||
|
searchText: searchField(),
|
||||||
|
imya: textField({ required: false }),
|
||||||
|
adress: textField({ required: false }),
|
||||||
|
opisanie: textField({ required: false }),
|
||||||
|
chasyRaboty: selectField({
|
||||||
|
required: false,
|
||||||
|
mode: 'single',
|
||||||
|
options: ['Круглосуточно'] as const,
|
||||||
|
}),
|
||||||
|
lat: textField({ required: false }),
|
||||||
|
long: textField({ required: false }),
|
||||||
|
avtomojka: checkboxField({ required: false }),
|
||||||
|
dt: checkboxField({ required: false }),
|
||||||
|
ai92: checkboxField({ required: false }),
|
||||||
|
ai95: checkboxField({ required: false }),
|
||||||
|
z100: checkboxField({ required: false }),
|
||||||
|
propan: checkboxField({ required: false }),
|
||||||
|
zaryadnayaStanciya: checkboxField({ required: false }),
|
||||||
|
miniMarket: checkboxField({ required: false }),
|
||||||
|
tualet: checkboxField({ required: false }),
|
||||||
|
region: selectField({
|
||||||
|
required: false,
|
||||||
|
mode: 'single',
|
||||||
|
options: [
|
||||||
|
'Душанбе',
|
||||||
|
'Бохтар',
|
||||||
|
'Худжанд',
|
||||||
|
'Регар',
|
||||||
|
'Вахдат',
|
||||||
|
'А.Джоми',
|
||||||
|
'Обикиик',
|
||||||
|
'Кулоб',
|
||||||
|
'Дахана',
|
||||||
|
'Ёвон',
|
||||||
|
'Панч',
|
||||||
|
'Исфара',
|
||||||
|
'Мастчох',
|
||||||
|
'Хисор',
|
||||||
|
] as const,
|
||||||
|
}),
|
||||||
|
foto: attachmentField({ required: false }),
|
||||||
|
},
|
||||||
|
akcii: {
|
||||||
|
id: autoNumberField(),
|
||||||
|
createdAt: autoDateField(),
|
||||||
|
updatedAt: autoDateField(),
|
||||||
|
searchText: searchField(),
|
||||||
|
zagolovok: textField({ required: false }),
|
||||||
|
opisanie: textField({ required: false }),
|
||||||
|
do: dateField({ required: false }),
|
||||||
|
foto: attachmentField({ required: false }),
|
||||||
|
},
|
||||||
|
istoriyaKompanii: {
|
||||||
|
id: autoNumberField(),
|
||||||
|
createdAt: autoDateField(),
|
||||||
|
updatedAt: autoDateField(),
|
||||||
|
searchText: searchField(),
|
||||||
|
zagolovok: textField({ required: false }),
|
||||||
|
god: numberField({ required: false }),
|
||||||
|
opisanie: textField({ required: false }),
|
||||||
|
},
|
||||||
|
komanda: {
|
||||||
|
id: autoNumberField(),
|
||||||
|
createdAt: autoDateField(),
|
||||||
|
updatedAt: autoDateField(),
|
||||||
|
searchText: searchField(),
|
||||||
|
polnoeImya: textField({ required: false }),
|
||||||
|
foto: attachmentField({ required: false }),
|
||||||
|
zvanie: textField({ required: false }),
|
||||||
|
},
|
||||||
|
otzyvy: {
|
||||||
|
id: autoNumberField(),
|
||||||
|
createdAt: autoDateField(),
|
||||||
|
updatedAt: autoDateField(),
|
||||||
|
searchText: searchField(),
|
||||||
|
polnoeImya: textField({ required: false }),
|
||||||
|
otzyv: textField({ required: false }),
|
||||||
|
rejting: numberField({ required: false }),
|
||||||
|
status: selectField({
|
||||||
|
required: false,
|
||||||
|
mode: 'single',
|
||||||
|
options: ['Опубликовано', 'Не публиковать'] as const,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
tekstovyjKontentSajta: {
|
||||||
|
id: autoNumberField(),
|
||||||
|
createdAt: autoDateField(),
|
||||||
|
updatedAt: autoDateField(),
|
||||||
|
searchText: searchField(),
|
||||||
|
klyuchNeIzmenyat: textField({ required: true }),
|
||||||
|
znachenie: textField({ required: true }),
|
||||||
|
opisanie: selectField({
|
||||||
|
required: false,
|
||||||
|
mode: 'multi',
|
||||||
|
options: [
|
||||||
|
'Общая',
|
||||||
|
'Домашняя страница',
|
||||||
|
'О нас',
|
||||||
|
'Благотворительность',
|
||||||
|
'Клиенты',
|
||||||
|
'Почты',
|
||||||
|
'Соц сети',
|
||||||
|
'Карты',
|
||||||
|
'Лояльность',
|
||||||
|
'Авторизация',
|
||||||
|
'Сертификаты',
|
||||||
|
'Бонусный клиент',
|
||||||
|
'Корпоративный клиент',
|
||||||
|
'Транзакции',
|
||||||
|
] as const,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
sertifikaty: {
|
||||||
|
id: autoNumberField(),
|
||||||
|
createdAt: autoDateField(),
|
||||||
|
updatedAt: autoDateField(),
|
||||||
|
searchText: searchField(),
|
||||||
|
nazvanie: textField({ required: false }),
|
||||||
|
opisanie: textField({ required: false }),
|
||||||
|
dataVydachi: dateField({ required: false }),
|
||||||
|
dejstvitelenDo: dateField({ required: false }),
|
||||||
|
foto: attachmentField({ required: false }),
|
||||||
|
},
|
||||||
|
mediaKontentSajta: {
|
||||||
|
id: autoNumberField(),
|
||||||
|
createdAt: autoDateField(),
|
||||||
|
updatedAt: autoDateField(),
|
||||||
|
searchText: searchField(),
|
||||||
|
mestopolozheniya: textField({ required: false }),
|
||||||
|
klyuchNeIzmenyat: textField({ required: true }),
|
||||||
|
foto: attachmentField({ required: false }),
|
||||||
|
stranica: selectField({
|
||||||
|
required: false,
|
||||||
|
mode: 'single',
|
||||||
|
options: [
|
||||||
|
'Главная',
|
||||||
|
'О нас',
|
||||||
|
'Благотворительность',
|
||||||
|
'Общая',
|
||||||
|
'Клиенты',
|
||||||
|
'Программа лояльности',
|
||||||
|
] as const,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
blagotvoritelnyjFond: {
|
||||||
|
id: autoNumberField(),
|
||||||
|
createdAt: autoDateField(),
|
||||||
|
updatedAt: autoDateField(),
|
||||||
|
searchText: searchField(),
|
||||||
|
zagolovok: textField({ required: false }),
|
||||||
|
opisanie: textField({ required: false }),
|
||||||
|
data: dateField({ required: false }),
|
||||||
|
lokaciya: textField({ required: false }),
|
||||||
|
foto: attachmentField({ required: false }),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
interface UploadResponse {
|
/** Generic type for plugin actions */
|
||||||
collectionName: string;
|
export type PluginActionType<I, O> = { input: I; result: O };
|
||||||
fileInformation: FileInformation;
|
export type TaylorDatabase = InferTaylorDatabase<typeof taylorSchema> & {
|
||||||
metadata: {
|
_plugins: {};
|
||||||
thumbnails: any[];
|
|
||||||
clips: any[];
|
|
||||||
};
|
|
||||||
baseId: string;
|
|
||||||
storageAdaptor: string;
|
|
||||||
_id: string;
|
|
||||||
__v: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AttachmentColumnValue {
|
|
||||||
url: string;
|
|
||||||
fileType: string;
|
|
||||||
size: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Attachment {
|
|
||||||
public readonly collectionName: string;
|
|
||||||
public readonly fileInformation: FileInformation;
|
|
||||||
public readonly metadata: { thumbnails: any[]; clips: any[] };
|
|
||||||
public readonly baseId: string;
|
|
||||||
public readonly storageAdaptor: string;
|
|
||||||
public readonly _id: string;
|
|
||||||
|
|
||||||
constructor(data: UploadResponse) {
|
|
||||||
this.collectionName = data.collectionName;
|
|
||||||
this.fileInformation = data.fileInformation;
|
|
||||||
this.metadata = data.metadata;
|
|
||||||
this.baseId = data.baseId;
|
|
||||||
this.storageAdaptor = data.storageAdaptor;
|
|
||||||
this._id = data._id;
|
|
||||||
}
|
|
||||||
|
|
||||||
toColumnValue(): AttachmentColumnValue {
|
|
||||||
return {
|
|
||||||
url: this.fileInformation.path,
|
|
||||||
fileType: this.fileInformation.mimetype,
|
|
||||||
size: this.fileInformation.size,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type IsWithinOperatorValue =
|
|
||||||
| 'pastWeek'
|
|
||||||
| 'pastMonth'
|
|
||||||
| 'pastYear'
|
|
||||||
| 'nextWeek'
|
|
||||||
| 'nextMonth'
|
|
||||||
| 'nextYear'
|
|
||||||
| 'daysFromNow'
|
|
||||||
| 'daysAgo'
|
|
||||||
| 'currentWeek'
|
|
||||||
| 'currentMonth'
|
|
||||||
| 'currentYear';
|
|
||||||
|
|
||||||
type DefaultDateFilterValue =
|
|
||||||
| (
|
|
||||||
| 'today'
|
|
||||||
| 'tomorrow'
|
|
||||||
| 'yesterday'
|
|
||||||
| 'oneWeekAgo'
|
|
||||||
| 'oneWeekFromNow'
|
|
||||||
| 'oneMonthAgo'
|
|
||||||
| 'oneMonthFromNow'
|
|
||||||
)
|
|
||||||
| ['exactDay' | 'exactTimestamp', string]
|
|
||||||
| ['daysAgo' | 'daysFromNow', number];
|
|
||||||
|
|
||||||
type DateFilters = {
|
|
||||||
'=': DefaultDateFilterValue;
|
|
||||||
'!=': DefaultDateFilterValue;
|
|
||||||
'<': DefaultDateFilterValue;
|
|
||||||
'>': DefaultDateFilterValue;
|
|
||||||
'<=': DefaultDateFilterValue;
|
|
||||||
'>=': DefaultDateFilterValue;
|
|
||||||
isWithIn:
|
|
||||||
| IsWithinOperatorValue
|
|
||||||
| { value: 'daysAgo' | 'daysFromNow'; date: number };
|
|
||||||
isEmpty: boolean;
|
|
||||||
isNotEmpty: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
type DateAggregations = {
|
|
||||||
empty: number;
|
|
||||||
filled: number;
|
|
||||||
unique: number;
|
|
||||||
percentEmpty: number;
|
|
||||||
percentFilled: number;
|
|
||||||
percentUnique: number;
|
|
||||||
min: number | null;
|
|
||||||
max: number | null;
|
|
||||||
daysRange: number | null;
|
|
||||||
monthRange: number | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
type TextFilters = {
|
|
||||||
'=': string;
|
|
||||||
'!=': string;
|
|
||||||
caseEqual: string;
|
|
||||||
hasAnyOf: string[];
|
|
||||||
contains: string;
|
|
||||||
startsWith: string;
|
|
||||||
endsWith: string;
|
|
||||||
doesNotContain: string;
|
|
||||||
isEmpty: never;
|
|
||||||
isNotEmpty: never;
|
|
||||||
};
|
|
||||||
|
|
||||||
type LinkFilters = {
|
|
||||||
hasAnyOf: number[];
|
|
||||||
hasAllOf: number[];
|
|
||||||
isExactly: number[];
|
|
||||||
'=': number;
|
|
||||||
hasNoneOf: number[];
|
|
||||||
contains: string;
|
|
||||||
doesNotContain: string;
|
|
||||||
isEmpty: never;
|
|
||||||
isNotEmpty: never;
|
|
||||||
};
|
|
||||||
|
|
||||||
type SelectFilters<O extends readonly string[]> = {
|
|
||||||
hasAnyOf: O[number][];
|
|
||||||
hasAllOf: O[number][];
|
|
||||||
isExactly: O[number][];
|
|
||||||
'=': O[number];
|
|
||||||
hasNoneOf: O[number][];
|
|
||||||
contains: string;
|
|
||||||
doesNotContain: string;
|
|
||||||
isEmpty: never;
|
|
||||||
isNotEmpty: never;
|
|
||||||
};
|
|
||||||
|
|
||||||
type LinkAggregations = {
|
|
||||||
empty: number;
|
|
||||||
filled: number;
|
|
||||||
percentEmpty: number;
|
|
||||||
percentFilled: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type NumberFilters = {
|
|
||||||
'=': number;
|
|
||||||
'!=': number;
|
|
||||||
'>': number;
|
|
||||||
'>=': number;
|
|
||||||
'<': number;
|
|
||||||
'<=': number;
|
|
||||||
hasAnyOf: number[];
|
|
||||||
hasNoneOf: number[];
|
|
||||||
isEmpty: never;
|
|
||||||
isNotEmpty: never;
|
|
||||||
};
|
|
||||||
|
|
||||||
type NumberAggregations = {
|
|
||||||
sum: number;
|
|
||||||
average: number;
|
|
||||||
median: number;
|
|
||||||
min: number | null;
|
|
||||||
max: number | null;
|
|
||||||
range: number;
|
|
||||||
standardDeviation: number;
|
|
||||||
histogram: Record<string, number>;
|
|
||||||
empty: number;
|
|
||||||
filled: number;
|
|
||||||
unique: number;
|
|
||||||
percentEmpty: number;
|
|
||||||
percentFilled: number;
|
|
||||||
percentUnique: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
type CheckboxFilters = {
|
|
||||||
'=': number;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* Column types
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
export type ColumnType<
|
|
||||||
S,
|
|
||||||
U,
|
|
||||||
I,
|
|
||||||
R extends boolean,
|
|
||||||
F extends { [key: string]: any } = object,
|
|
||||||
A extends { [key: string]: any } = object,
|
|
||||||
> = {
|
|
||||||
raw: S;
|
|
||||||
insert: I;
|
|
||||||
update: U;
|
|
||||||
filters: F;
|
|
||||||
aggregations: A;
|
|
||||||
isRequired: R;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type DateColumnType<R extends boolean> = ColumnType<
|
|
||||||
string,
|
|
||||||
string,
|
|
||||||
string,
|
|
||||||
R,
|
|
||||||
DateFilters,
|
|
||||||
DateAggregations
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type TextColumnType<R extends boolean> = ColumnType<
|
|
||||||
string,
|
|
||||||
string,
|
|
||||||
string,
|
|
||||||
R,
|
|
||||||
TextFilters
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type ALinkColumnType<
|
|
||||||
T extends string,
|
|
||||||
S,
|
|
||||||
U,
|
|
||||||
I,
|
|
||||||
R extends boolean,
|
|
||||||
F extends { [key: string]: any } = LinkFilters,
|
|
||||||
A extends LinkAggregations = LinkAggregations,
|
|
||||||
> = ColumnType<S, U, I, R, F, A> & {
|
|
||||||
linkedTo: T;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type LinkColumnType<
|
|
||||||
T extends string,
|
|
||||||
R extends boolean,
|
|
||||||
> = ALinkColumnType<
|
|
||||||
T,
|
|
||||||
object,
|
|
||||||
number | number[] | { newIds: number[]; deletedIds: number[] },
|
|
||||||
number | number[],
|
|
||||||
R
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type AttachmentColumnType<R extends boolean> = ALinkColumnType<
|
|
||||||
'attachmentTable',
|
|
||||||
AttachmentColumnValue[],
|
|
||||||
Attachment[] | { newIds: number[]; deletedIds: number[] } | number[],
|
|
||||||
Attachment[] | number[],
|
|
||||||
R
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type NumberColumnType<R extends boolean> = ColumnType<
|
|
||||||
number,
|
|
||||||
number,
|
|
||||||
number,
|
|
||||||
R,
|
|
||||||
NumberFilters,
|
|
||||||
NumberAggregations
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type CheckboxColumnType<R extends boolean> = ColumnType<
|
|
||||||
boolean,
|
|
||||||
boolean,
|
|
||||||
boolean,
|
|
||||||
R,
|
|
||||||
CheckboxFilters
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type AutoGeneratedNumberColumnType = ColumnType<
|
|
||||||
number,
|
|
||||||
never,
|
|
||||||
never,
|
|
||||||
false,
|
|
||||||
NumberFilters,
|
|
||||||
NumberAggregations
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type AutoGeneratedDateColumnType = ColumnType<
|
|
||||||
string,
|
|
||||||
never,
|
|
||||||
never,
|
|
||||||
false,
|
|
||||||
DateFilters,
|
|
||||||
DateAggregations
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type SingleSelectColumnType<
|
|
||||||
O extends readonly string[],
|
|
||||||
R extends boolean,
|
|
||||||
> = ALinkColumnType<
|
|
||||||
'selectTable',
|
|
||||||
O[number],
|
|
||||||
O[number] | O[number][],
|
|
||||||
O[number] | O[number][],
|
|
||||||
R,
|
|
||||||
SelectFilters<O>
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type TableRaws<T extends keyof TaylorDatabase> = {
|
|
||||||
[K in keyof TaylorDatabase[T]]: TaylorDatabase[T][K] extends ColumnType<
|
|
||||||
infer S,
|
|
||||||
any,
|
|
||||||
any,
|
|
||||||
infer R,
|
|
||||||
any,
|
|
||||||
any
|
|
||||||
>
|
|
||||||
? R extends true
|
|
||||||
? S
|
|
||||||
: S | undefined
|
|
||||||
: never;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TableInserts<T extends keyof TaylorDatabase> = {
|
|
||||||
[K in keyof TaylorDatabase[T]]: TaylorDatabase[T][K] extends ColumnType<
|
|
||||||
any,
|
|
||||||
infer I,
|
|
||||||
any,
|
|
||||||
infer R,
|
|
||||||
any,
|
|
||||||
any
|
|
||||||
>
|
|
||||||
? R extends true
|
|
||||||
? I
|
|
||||||
: I | undefined
|
|
||||||
: never;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TableUpdates<T extends keyof TaylorDatabase> = {
|
|
||||||
[K in keyof TaylorDatabase[T]]: TaylorDatabase[T][K] extends ColumnType<
|
|
||||||
any,
|
|
||||||
any,
|
|
||||||
infer U,
|
|
||||||
any,
|
|
||||||
any,
|
|
||||||
any
|
|
||||||
>
|
|
||||||
? U
|
|
||||||
: never;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type SelectTable = {
|
|
||||||
id: AutoGeneratedNumberColumnType;
|
|
||||||
name: TextColumnType<true>;
|
|
||||||
color: TextColumnType<true>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type AttachmentTable = {
|
|
||||||
id: AutoGeneratedNumberColumnType;
|
|
||||||
name: TextColumnType<true>;
|
|
||||||
metadata: TextColumnType<true>;
|
|
||||||
size: NumberColumnType<true>;
|
|
||||||
fileType: TextColumnType<true>;
|
|
||||||
url: TextColumnType<true>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type CollaboratorsTable = {
|
|
||||||
id: AutoGeneratedNumberColumnType;
|
|
||||||
name: TextColumnType<true>;
|
|
||||||
emailAddress: TextColumnType<true>;
|
|
||||||
avatar: TextColumnType<true>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TaylorDatabase = {
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* Internal tables, these tables can not be queried directly.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
selectTable: SelectTable;
|
|
||||||
attachmentTable: AttachmentTable;
|
|
||||||
collaboratorsTable: CollaboratorsTable;
|
|
||||||
vakansii: VakansiiTable;
|
|
||||||
partnyory: PartnyoryTable;
|
|
||||||
azs: AzsTable;
|
|
||||||
akcii: AkciiTable;
|
|
||||||
istoriyaKompanii: IstoriyaKompaniiTable;
|
|
||||||
komanda: KomandaTable;
|
|
||||||
otzyvy: OtzyvyTable;
|
|
||||||
tekstovyjKontentSajta: TekstovyjKontentSajtaTable;
|
|
||||||
sertifikaty: SertifikatyTable;
|
|
||||||
mediaKontentSajta: MediaKontentSajtaTable;
|
|
||||||
blagotvoritelnyjFond: BlagotvoritelnyjFondTable;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const VakansiiTipOptions = ['Офис', 'Заправки'] as const;
|
|
||||||
export const VakansiiLokaciyaOptions = ['Душанбе'] as const;
|
|
||||||
|
|
||||||
type VakansiiTable = {
|
|
||||||
id: NumberColumnType<false>;
|
|
||||||
createdAt: AutoGeneratedDateColumnType;
|
|
||||||
updatedAt: AutoGeneratedDateColumnType;
|
|
||||||
zagolovok: TextColumnType<false>;
|
|
||||||
tip: SingleSelectColumnType<typeof VakansiiTipOptions, false>;
|
|
||||||
lokaciya: SingleSelectColumnType<typeof VakansiiLokaciyaOptions, false>;
|
|
||||||
tegi: LinkColumnType<'selectTable', false>;
|
|
||||||
};
|
|
||||||
type PartnyoryTable = {
|
|
||||||
id: NumberColumnType<false>;
|
|
||||||
createdAt: AutoGeneratedDateColumnType;
|
|
||||||
updatedAt: AutoGeneratedDateColumnType;
|
|
||||||
nazvanie: TextColumnType<false>;
|
|
||||||
izobrozhenie: AttachmentColumnType<false>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const AzsChasyRabotyOptions = ['Круглосуточно'] as const;
|
|
||||||
export const AzsRegionOptions = [
|
|
||||||
'Душанбе',
|
|
||||||
'Бохтар',
|
|
||||||
'Худжанд',
|
|
||||||
'Регар',
|
|
||||||
'Вахдат',
|
|
||||||
'А.Джоми',
|
|
||||||
'Обикиик',
|
|
||||||
'Кулоб',
|
|
||||||
'Дахана',
|
|
||||||
'Ёвон',
|
|
||||||
'Панч',
|
|
||||||
'Исфара',
|
|
||||||
'Мастчох',
|
|
||||||
'Хисор',
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
type AzsTable = {
|
|
||||||
id: NumberColumnType<false>;
|
|
||||||
createdAt: AutoGeneratedDateColumnType;
|
|
||||||
updatedAt: AutoGeneratedDateColumnType;
|
|
||||||
imya: TextColumnType<false>;
|
|
||||||
adress: TextColumnType<false>;
|
|
||||||
opisanie: TextColumnType<false>;
|
|
||||||
chasyRaboty: SingleSelectColumnType<typeof AzsChasyRabotyOptions, false>;
|
|
||||||
lat: TextColumnType<false>;
|
|
||||||
long: TextColumnType<false>;
|
|
||||||
avtomojka: CheckboxColumnType<false>;
|
|
||||||
dt: CheckboxColumnType<false>;
|
|
||||||
ai92: CheckboxColumnType<false>;
|
|
||||||
ai95: CheckboxColumnType<false>;
|
|
||||||
z100: CheckboxColumnType<false>;
|
|
||||||
propan: CheckboxColumnType<false>;
|
|
||||||
zaryadnayaStanciya: CheckboxColumnType<false>;
|
|
||||||
miniMarket: CheckboxColumnType<false>;
|
|
||||||
tualet: CheckboxColumnType<false>;
|
|
||||||
region: SingleSelectColumnType<typeof AzsRegionOptions, false>;
|
|
||||||
foto: AttachmentColumnType<false>;
|
|
||||||
};
|
|
||||||
type AkciiTable = {
|
|
||||||
id: NumberColumnType<false>;
|
|
||||||
createdAt: AutoGeneratedDateColumnType;
|
|
||||||
updatedAt: AutoGeneratedDateColumnType;
|
|
||||||
zagolovok: TextColumnType<false>;
|
|
||||||
opisanie: TextColumnType<false>;
|
|
||||||
do: DateColumnType<false>;
|
|
||||||
foto: AttachmentColumnType<false>;
|
|
||||||
};
|
|
||||||
type IstoriyaKompaniiTable = {
|
|
||||||
id: NumberColumnType<false>;
|
|
||||||
createdAt: AutoGeneratedDateColumnType;
|
|
||||||
updatedAt: AutoGeneratedDateColumnType;
|
|
||||||
zagolovok: TextColumnType<false>;
|
|
||||||
god: NumberColumnType<false>;
|
|
||||||
opisanie: TextColumnType<false>;
|
|
||||||
};
|
|
||||||
type KomandaTable = {
|
|
||||||
id: NumberColumnType<false>;
|
|
||||||
createdAt: AutoGeneratedDateColumnType;
|
|
||||||
updatedAt: AutoGeneratedDateColumnType;
|
|
||||||
polnoeImya: TextColumnType<false>;
|
|
||||||
foto: AttachmentColumnType<false>;
|
|
||||||
zvanie: TextColumnType<false>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const OtzyvyStatusOptions = ['Опубликовано', 'Не публиковать'] as const;
|
|
||||||
|
|
||||||
type OtzyvyTable = {
|
|
||||||
id: NumberColumnType<false>;
|
|
||||||
createdAt: AutoGeneratedDateColumnType;
|
|
||||||
updatedAt: AutoGeneratedDateColumnType;
|
|
||||||
polnoeImya: TextColumnType<false>;
|
|
||||||
otzyv: TextColumnType<false>;
|
|
||||||
rejting: NumberColumnType<false>;
|
|
||||||
status: SingleSelectColumnType<typeof OtzyvyStatusOptions, false>;
|
|
||||||
};
|
|
||||||
type TekstovyjKontentSajtaTable = {
|
|
||||||
id: NumberColumnType<false>;
|
|
||||||
createdAt: AutoGeneratedDateColumnType;
|
|
||||||
updatedAt: AutoGeneratedDateColumnType;
|
|
||||||
klyuchNeIzmenyat: TextColumnType<true>;
|
|
||||||
znachenie: TextColumnType<true>;
|
|
||||||
opisanie: LinkColumnType<'selectTable', false>;
|
|
||||||
};
|
|
||||||
type SertifikatyTable = {
|
|
||||||
id: NumberColumnType<false>;
|
|
||||||
createdAt: AutoGeneratedDateColumnType;
|
|
||||||
updatedAt: AutoGeneratedDateColumnType;
|
|
||||||
nazvanie: TextColumnType<false>;
|
|
||||||
opisanie: TextColumnType<false>;
|
|
||||||
dataVydachi: DateColumnType<false>;
|
|
||||||
dejstvitelenDo: DateColumnType<false>;
|
|
||||||
foto: AttachmentColumnType<false>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const MediaKontentSajtaStranicaOptions = [
|
|
||||||
'Главная',
|
|
||||||
'О нас',
|
|
||||||
'Благотворительность',
|
|
||||||
'Общая',
|
|
||||||
'Клиенты',
|
|
||||||
'Программа лояльности',
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
type MediaKontentSajtaTable = {
|
|
||||||
id: NumberColumnType<false>;
|
|
||||||
createdAt: AutoGeneratedDateColumnType;
|
|
||||||
updatedAt: AutoGeneratedDateColumnType;
|
|
||||||
mestopolozheniya: TextColumnType<false>;
|
|
||||||
klyuchNeIzmenyat: TextColumnType<true>;
|
|
||||||
foto: AttachmentColumnType<false>;
|
|
||||||
stranica: SingleSelectColumnType<
|
|
||||||
typeof MediaKontentSajtaStranicaOptions,
|
|
||||||
false
|
|
||||||
>;
|
|
||||||
};
|
|
||||||
type BlagotvoritelnyjFondTable = {
|
|
||||||
id: NumberColumnType<false>;
|
|
||||||
createdAt: AutoGeneratedDateColumnType;
|
|
||||||
updatedAt: AutoGeneratedDateColumnType;
|
|
||||||
zagolovok: TextColumnType<false>;
|
|
||||||
opisanie: TextColumnType<false>;
|
|
||||||
data: DateColumnType<false>;
|
|
||||||
lokaciya: TextColumnType<false>;
|
|
||||||
foto: AttachmentColumnType<false>;
|
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user