mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-17 08:31:47 +03:00
multi tenant schemas poc (#1569)
* Multi-tenant db schemas POC * fix tests and use query builders * remove synchronize * restore updatedAt * remove unnecessary import * use queryRunner * fix camelcase * add migrations for standard objects * Multi-tenant db schemas POC * fix tests and use query builders * remove synchronize * restore updatedAt * remove unnecessary import * use queryRunner * fix camelcase * add migrations for standard objects * add metadata * add comments * remove migrations for now * do not allow connection to public schema for non-remote workspace connection * rename getLastDataSourceMetadataFromWorkspaceIdOrFail * remove schema creation * remove module import
This commit is contained in:
parent
e96f2ece7c
commit
d98ddc3dbe
@ -25,7 +25,8 @@
|
||||
"prisma:generate": "yarn prisma:generate-client && yarn prisma:generate-gql-select && yarn prisma:generate-nest-graphql",
|
||||
"prisma:migrate": "npx prisma migrate deploy",
|
||||
"prisma:seed": "npx prisma db seed",
|
||||
"prisma:reset": "npx prisma migrate reset && yarn prisma:generate"
|
||||
"prisma:reset": "npx prisma migrate reset && yarn prisma:generate",
|
||||
"typeorm": "typeorm-ts-node-commonjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/server": "^4.7.3",
|
||||
@ -73,11 +74,13 @@
|
||||
"passport-google-oauth20": "^2.0.0",
|
||||
"passport-jwt": "^4.0.1",
|
||||
"passport-local": "^1.0.0",
|
||||
"pg": "^8.11.3",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rimraf": "^3.0.2",
|
||||
"rxjs": "^7.2.0",
|
||||
"sharp": "^0.32.1",
|
||||
"type-fest": "^3.12.0",
|
||||
"typeorm": "^0.3.17",
|
||||
"uuid": "^9.0.0",
|
||||
"yarn": "^1.22.19"
|
||||
},
|
||||
|
@ -14,6 +14,7 @@ import { AttachmentModule } from './attachment/attachment.module';
|
||||
import { ActivityModule } from './activity/activity.module';
|
||||
import { ViewModule } from './view/view.module';
|
||||
import { FavoriteModule } from './favorite/favorite.module';
|
||||
import { TenantModule } from './tenant/tenant.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@ -31,6 +32,7 @@ import { FavoriteModule } from './favorite/favorite.module';
|
||||
ActivityModule,
|
||||
ViewModule,
|
||||
FavoriteModule,
|
||||
TenantModule,
|
||||
],
|
||||
exports: [
|
||||
AuthModule,
|
||||
|
9
server/src/core/tenant/datasource/datasource.module.ts
Normal file
9
server/src/core/tenant/datasource/datasource.module.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { DataSourceService } from './services/datasource.service';
|
||||
|
||||
@Module({
|
||||
exports: [DataSourceService],
|
||||
providers: [DataSourceService],
|
||||
})
|
||||
export class DataSourceModule {}
|
@ -0,0 +1,7 @@
|
||||
export const baseColumns = {
|
||||
id: {
|
||||
primary: true,
|
||||
type: 'uuid',
|
||||
generated: 'uuid',
|
||||
},
|
||||
};
|
@ -0,0 +1,73 @@
|
||||
import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
Entity,
|
||||
PrimaryGeneratedColumn,
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
|
||||
// export const dataSourceEntity = new EntitySchema({
|
||||
// name: 'data_sources',
|
||||
// columns: {
|
||||
// id: {
|
||||
// primary: true,
|
||||
// type: 'uuid',
|
||||
// generated: 'uuid',
|
||||
// },
|
||||
// url: {
|
||||
// type: 'text',
|
||||
// nullable: true,
|
||||
// },
|
||||
// schema: {
|
||||
// type: 'text',
|
||||
// nullable: true,
|
||||
// },
|
||||
// type: {
|
||||
// type: 'text',
|
||||
// nullable: true,
|
||||
// },
|
||||
// name: {
|
||||
// type: 'text',
|
||||
// nullable: true,
|
||||
// },
|
||||
// is_remote: {
|
||||
// type: 'boolean',
|
||||
// nullable: true,
|
||||
// default: false,
|
||||
// },
|
||||
// workspace_id: {
|
||||
// type: 'uuid',
|
||||
// nullable: true,
|
||||
// },
|
||||
// },
|
||||
// });
|
||||
|
||||
@Entity('data_source_metadata')
|
||||
export class DataSourceMetadata {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@CreateDateColumn()
|
||||
created_at: Date;
|
||||
|
||||
@UpdateDateColumn()
|
||||
updated_at: Date;
|
||||
|
||||
@Column({ nullable: true })
|
||||
url: string;
|
||||
|
||||
@Column({ nullable: true })
|
||||
schema: string;
|
||||
|
||||
@Column({ default: 'postgres' })
|
||||
type: string;
|
||||
|
||||
@Column({ nullable: true })
|
||||
name: string;
|
||||
|
||||
@Column({ default: false })
|
||||
is_remote: boolean;
|
||||
|
||||
@Column({ nullable: false })
|
||||
workspace_id: string;
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
Entity,
|
||||
JoinColumn,
|
||||
ManyToOne,
|
||||
PrimaryGeneratedColumn,
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
|
||||
import { ObjectMetadata } from './object-metadata';
|
||||
|
||||
// export const fieldMetadataEntity = new EntitySchema({
|
||||
// name: 'field_metadata',
|
||||
// columns: {
|
||||
// id: {
|
||||
// primary: true,
|
||||
// type: 'uuid',
|
||||
// generated: 'uuid',
|
||||
// },
|
||||
// object_id: {
|
||||
// type: 'uuid',
|
||||
// nullable: true,
|
||||
// },
|
||||
// type: {
|
||||
// type: 'text',
|
||||
// nullable: true,
|
||||
// },
|
||||
// name: {
|
||||
// type: 'text',
|
||||
// nullable: true,
|
||||
// },
|
||||
// is_custom: {
|
||||
// type: 'boolean',
|
||||
// nullable: true,
|
||||
// default: false,
|
||||
// },
|
||||
// workspace_id: {
|
||||
// type: 'uuid',
|
||||
// nullable: true,
|
||||
// },
|
||||
// },
|
||||
// relations: {
|
||||
// object: {
|
||||
// type: 'many-to-one',
|
||||
// target: 'object_metadata',
|
||||
// joinColumn: {
|
||||
// name: 'object_id',
|
||||
// referencedColumnName: 'id',
|
||||
// },
|
||||
// inverseSide: 'fields',
|
||||
// },
|
||||
// } as any,
|
||||
// });
|
||||
|
||||
@Entity('field_metadata')
|
||||
export class FieldMetadata {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@CreateDateColumn()
|
||||
created_at: Date;
|
||||
|
||||
@UpdateDateColumn()
|
||||
updated_at: Date;
|
||||
|
||||
@Column({ nullable: false })
|
||||
object_id: string;
|
||||
|
||||
@Column({ nullable: false })
|
||||
type: string;
|
||||
|
||||
@Column({ nullable: false })
|
||||
name: string;
|
||||
|
||||
@Column({ default: false })
|
||||
is_custom: boolean;
|
||||
|
||||
@Column({ nullable: false })
|
||||
workspace_id: string;
|
||||
|
||||
@ManyToOne(() => ObjectMetadata, (object) => object.fields)
|
||||
@JoinColumn({ name: 'object_id' })
|
||||
object: ObjectMetadata;
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
Entity,
|
||||
OneToMany,
|
||||
PrimaryGeneratedColumn,
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
|
||||
import { FieldMetadata } from './field-metadata.entity';
|
||||
|
||||
// export const objectMetadataEntity = new EntitySchema({
|
||||
// name: 'object_metadata',
|
||||
// columns: {
|
||||
// id: {
|
||||
// primary: true,
|
||||
// type: 'uuid',
|
||||
// generated: 'uuid',
|
||||
// },
|
||||
// data_source_id: {
|
||||
// type: 'uuid',
|
||||
// nullable: true,
|
||||
// },
|
||||
// name: {
|
||||
// type: 'text',
|
||||
// nullable: true,
|
||||
// },
|
||||
// is_custom: {
|
||||
// type: 'boolean',
|
||||
// nullable: true,
|
||||
// default: false,
|
||||
// },
|
||||
// workspace_id: {
|
||||
// type: 'uuid',
|
||||
// nullable: true,
|
||||
// },
|
||||
// },
|
||||
// relations: {
|
||||
// fields: {
|
||||
// type: 'one-to-many',
|
||||
// target: 'field_metadata',
|
||||
// inverseSide: 'object',
|
||||
// },
|
||||
// } as any,
|
||||
// });
|
||||
|
||||
@Entity('object_metadata')
|
||||
export class ObjectMetadata {
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
@CreateDateColumn()
|
||||
created_at: Date;
|
||||
|
||||
@UpdateDateColumn()
|
||||
updated_at: Date;
|
||||
|
||||
@Column({ nullable: false })
|
||||
data_source_id: string;
|
||||
|
||||
@Column({ nullable: false })
|
||||
name: string;
|
||||
|
||||
@Column({ default: false })
|
||||
is_custom: boolean;
|
||||
|
||||
@Column({ nullable: false })
|
||||
workspace_id: string;
|
||||
|
||||
@OneToMany(() => FieldMetadata, (field) => field.object)
|
||||
fields: FieldMetadata[];
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
// export const relationMetadataEntity = new EntitySchema({
|
||||
// name: 'relation_metadata',
|
||||
// columns: {
|
||||
// id: {
|
||||
// primary: true,
|
||||
// type: 'uuid',
|
||||
// generated: 'uuid',
|
||||
// },
|
||||
// source_field_id: {
|
||||
// type: 'uuid',
|
||||
// nullable: true,
|
||||
// },
|
||||
// target_object_id: {
|
||||
// type: 'uuid',
|
||||
// nullable: true,
|
||||
// },
|
||||
// target_foreign_key: {
|
||||
// type: 'uuid',
|
||||
// nullable: true,
|
||||
// },
|
||||
// type: {
|
||||
// type: 'text',
|
||||
// nullable: true,
|
||||
// },
|
||||
// workspace_id: {
|
||||
// type: 'uuid',
|
||||
// nullable: true,
|
||||
// },
|
||||
// },
|
||||
// });
|
210
server/src/core/tenant/datasource/services/datasource.service.ts
Normal file
210
server/src/core/tenant/datasource/services/datasource.service.ts
Normal file
@ -0,0 +1,210 @@
|
||||
import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
|
||||
|
||||
import { DataSource, EntitySchema } from 'typeorm';
|
||||
import { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions';
|
||||
|
||||
import { EnvironmentService } from 'src/integrations/environment/environment.service';
|
||||
import { DataSourceMetadata } from 'src/core/tenant/datasource/entities/data-source-metadata.entity';
|
||||
import { ObjectMetadata } from 'src/core/tenant/datasource/entities/object-metadata';
|
||||
import { FieldMetadata } from 'src/core/tenant/datasource/entities/field-metadata.entity';
|
||||
import { baseColumns } from 'src/core/tenant/datasource/entities/base.entity';
|
||||
import {
|
||||
convertFieldTypeToPostgresType,
|
||||
sanitizeColumnName,
|
||||
uuidToBase36,
|
||||
} from 'src/core/tenant/datasource/utils/datasource.util';
|
||||
|
||||
@Injectable()
|
||||
export class DataSourceService implements OnModuleInit, OnModuleDestroy {
|
||||
private mainDataSource: DataSource;
|
||||
private metadataDataSource: DataSource;
|
||||
private connectionOptions: PostgresConnectionOptions;
|
||||
private dataSources = new Map<string, DataSource>();
|
||||
|
||||
constructor(environmentService: EnvironmentService) {
|
||||
this.connectionOptions = {
|
||||
url: environmentService.getPGDatabaseUrl(),
|
||||
type: 'postgres',
|
||||
logging: false,
|
||||
schema: 'public',
|
||||
};
|
||||
this.mainDataSource = new DataSource(this.connectionOptions);
|
||||
this.metadataDataSource = new DataSource({
|
||||
...this.connectionOptions,
|
||||
schema: 'metadata',
|
||||
synchronize: true, // TODO: remove this in production
|
||||
entities: [DataSourceMetadata, ObjectMetadata, FieldMetadata],
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns the schema name for a given workspaceId
|
||||
* @param workspaceId
|
||||
* @returns string
|
||||
*/
|
||||
public getSchemaName(workspaceId: string): string {
|
||||
return `workspace_${uuidToBase36(workspaceId)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new schema for a given workspaceId
|
||||
* @param workspaceId
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
public async createWorkspaceSchema(workspaceId: string): Promise<void> {
|
||||
const schemaName = this.getSchemaName(workspaceId);
|
||||
|
||||
const queryRunner = this.mainDataSource.createQueryRunner();
|
||||
await queryRunner.createSchema(schemaName, true);
|
||||
await queryRunner.release();
|
||||
|
||||
await this.insertNewDataSourceMetadata(workspaceId, schemaName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a new data source
|
||||
* @param workspaceId
|
||||
* @param workspaceSchema this can be computed from the workspaceId but it won't be the case for remote data sources
|
||||
* @returns Promise<void>
|
||||
*/
|
||||
private async insertNewDataSourceMetadata(
|
||||
workspaceId: string,
|
||||
workspaceSchema: string,
|
||||
): Promise<void> {
|
||||
await this.metadataDataSource
|
||||
?.createQueryBuilder()
|
||||
.insert()
|
||||
.into(DataSourceMetadata)
|
||||
.values({
|
||||
workspace_id: workspaceId,
|
||||
schema: workspaceSchema,
|
||||
})
|
||||
.execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to a workspace data source using the workspace metadata. Returns a cached connection if it exists.
|
||||
* @param workspaceId
|
||||
* @returns Promise<DataSource | undefined>
|
||||
*/
|
||||
public async connectToWorkspaceDataSource(
|
||||
workspaceId: string,
|
||||
): Promise<DataSource | undefined> {
|
||||
// if (this.dataSources.has(workspaceId)) {
|
||||
// const cachedDataSource = this.dataSources.get(workspaceId);
|
||||
// return cachedDataSource;
|
||||
// }
|
||||
|
||||
const dataSourceMetadata =
|
||||
await this.getLastDataSourceMetadataFromWorkspaceIdOrFail(workspaceId);
|
||||
|
||||
const schema = dataSourceMetadata.schema;
|
||||
|
||||
// Probably not needed as we will ask for the schema name OR store public by default if it's remote
|
||||
if (!schema && !dataSourceMetadata.is_remote) {
|
||||
throw Error(
|
||||
"No schema found for this non-remote data source, we don't want to fallback to public for workspace data sources.",
|
||||
);
|
||||
}
|
||||
|
||||
const metadata = await this.fetchObjectsAndFieldsFromMetadata(workspaceId);
|
||||
|
||||
const entities = this.convertMetadataToEntities(metadata);
|
||||
|
||||
const workspaceDataSource = new DataSource({
|
||||
...this.connectionOptions,
|
||||
schema,
|
||||
entities: entities,
|
||||
synchronize: true, // TODO: remove this in production
|
||||
});
|
||||
|
||||
await workspaceDataSource.initialize();
|
||||
|
||||
return workspaceDataSource;
|
||||
// this.dataSources.set(workspaceId, workspaceDataSource);
|
||||
|
||||
// return this.dataSources.get(workspaceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last data source metadata for a given workspaceId
|
||||
* In the future we should handle multiple data sources.
|
||||
* Most likely the twenty workspace connection and n remote connections should be fetched.
|
||||
*
|
||||
* @param workspaceId
|
||||
* @returns Promise<DataSourceMetadata>
|
||||
*/
|
||||
private async getLastDataSourceMetadataFromWorkspaceIdOrFail(
|
||||
workspaceId: string,
|
||||
): Promise<DataSourceMetadata> {
|
||||
return this.metadataDataSource
|
||||
?.createQueryBuilder()
|
||||
.select('data_source')
|
||||
.from(DataSourceMetadata, 'data_source')
|
||||
.where('data_source.workspace_id = :workspaceId', { workspaceId })
|
||||
.orderBy('data_source.created_at', 'DESC')
|
||||
.getOneOrFail();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the objects and fields for a given workspaceId and the first associated data source metadata registered.
|
||||
*
|
||||
* @param workspaceId
|
||||
* @returns
|
||||
*/
|
||||
public async fetchObjectsAndFieldsFromMetadata(workspaceId: string) {
|
||||
const dataSource =
|
||||
await this.getLastDataSourceMetadataFromWorkspaceIdOrFail(workspaceId);
|
||||
|
||||
const objectRepository =
|
||||
this.metadataDataSource.getRepository(ObjectMetadata);
|
||||
|
||||
return await objectRepository
|
||||
.createQueryBuilder('object_metadata')
|
||||
.select(['object_metadata.id', 'object_metadata.name'])
|
||||
.leftJoinAndSelect('object_metadata.fields', 'field')
|
||||
.where('object_metadata.data_source_id = :dataSourceId', {
|
||||
dataSourceId: dataSource?.id,
|
||||
})
|
||||
.getMany();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the metadata to entities that can be interpreted by typeorm.
|
||||
* @param metadata
|
||||
* @returns EntitySchema[]
|
||||
*
|
||||
*/
|
||||
public convertMetadataToEntities(metadata): EntitySchema[] {
|
||||
const entities = metadata.map((object) => {
|
||||
return new EntitySchema({
|
||||
name: object.name,
|
||||
columns: {
|
||||
...baseColumns,
|
||||
...object.fields.reduce((columns, field) => {
|
||||
return {
|
||||
...columns,
|
||||
[sanitizeColumnName(field.name)]: {
|
||||
type: convertFieldTypeToPostgresType(field.type),
|
||||
nullable: true,
|
||||
},
|
||||
};
|
||||
}, {}),
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
return entities;
|
||||
}
|
||||
|
||||
async onModuleInit() {
|
||||
await this.mainDataSource.initialize();
|
||||
await this.metadataDataSource.initialize();
|
||||
}
|
||||
|
||||
async onModuleDestroy(): Promise<void> {
|
||||
await this.mainDataSource.destroy();
|
||||
await this.metadataDataSource.destroy();
|
||||
}
|
||||
}
|
47
server/src/core/tenant/datasource/utils/datasource.util.ts
Normal file
47
server/src/core/tenant/datasource/utils/datasource.util.ts
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Converts a UUID to a base 36 string.
|
||||
* This is used to generate the schema name since hyphens from workspace uuid are not allowed in postgres schema names.
|
||||
*
|
||||
* @param uuid
|
||||
* @returns
|
||||
*/
|
||||
export function uuidToBase36(uuid: string): string {
|
||||
const hexString = uuid.replace(/-/g, '');
|
||||
const base10Number = BigInt('0x' + hexString);
|
||||
const base36String = base10Number.toString(36);
|
||||
return base36String;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes a column name by replacing all non-alphanumeric characters with an underscore.
|
||||
* Note: Probablay not the best way to do this, leaving it here as a placeholder for now.
|
||||
*
|
||||
* @param columnName
|
||||
* @returns string
|
||||
*/
|
||||
export function sanitizeColumnName(columnName: string): string {
|
||||
return columnName.replace(/[^a-zA-Z0-9]/g, '_');
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a field type to a postgres type. Field types are defined in the UI.
|
||||
*
|
||||
* @param fieldType
|
||||
* @returns string
|
||||
*/
|
||||
export function convertFieldTypeToPostgresType(fieldType: string): string {
|
||||
switch (fieldType) {
|
||||
case 'text':
|
||||
return 'text';
|
||||
case 'url':
|
||||
return 'text';
|
||||
case 'number':
|
||||
return 'numeric';
|
||||
case 'boolean':
|
||||
return 'boolean';
|
||||
case 'date':
|
||||
return 'timestamp';
|
||||
default:
|
||||
return 'text';
|
||||
}
|
||||
}
|
19
server/src/core/tenant/metadata/metadata.controller.ts
Normal file
19
server/src/core/tenant/metadata/metadata.controller.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { Controller, Get, UseGuards } from '@nestjs/common';
|
||||
|
||||
import { Workspace } from '@prisma/client';
|
||||
|
||||
import { AuthWorkspace } from 'src/decorators/auth-workspace.decorator';
|
||||
import { JwtAuthGuard } from 'src/guards/jwt.auth.guard';
|
||||
|
||||
import { MetadataService } from './metadata.service';
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Controller('metadata')
|
||||
export class MetadataController {
|
||||
constructor(private readonly metadataService: MetadataService) {}
|
||||
|
||||
@Get()
|
||||
async getMetadata(@AuthWorkspace() workspace: Workspace) {
|
||||
return this.metadataService.fetchMetadataFromWorkspaceId(workspace.id);
|
||||
}
|
||||
}
|
13
server/src/core/tenant/metadata/metadata.module.ts
Normal file
13
server/src/core/tenant/metadata/metadata.module.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { DataSourceModule } from 'src/core/tenant/datasource/datasource.module';
|
||||
|
||||
import { MetadataController } from './metadata.controller';
|
||||
import { MetadataService } from './metadata.service';
|
||||
|
||||
@Module({
|
||||
imports: [DataSourceModule],
|
||||
controllers: [MetadataController],
|
||||
providers: [MetadataService],
|
||||
})
|
||||
export class MetadataModule {}
|
16
server/src/core/tenant/metadata/metadata.service.ts
Normal file
16
server/src/core/tenant/metadata/metadata.service.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { DataSourceService } from 'src/core/tenant/datasource/services/datasource.service';
|
||||
|
||||
@Injectable()
|
||||
export class MetadataService {
|
||||
constructor(private readonly dataSourceService: DataSourceService) {}
|
||||
|
||||
public async fetchMetadataFromWorkspaceId(workspaceId: string) {
|
||||
await this.dataSourceService.connectToWorkspaceDataSource(workspaceId);
|
||||
|
||||
return await this.dataSourceService.fetchObjectsAndFieldsFromMetadata(
|
||||
workspaceId,
|
||||
);
|
||||
}
|
||||
}
|
10
server/src/core/tenant/tenant.module.ts
Normal file
10
server/src/core/tenant/tenant.module.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { DataSourceModule } from './datasource/datasource.module';
|
||||
import { MetadataModule } from './metadata/metadata.module';
|
||||
|
||||
@Module({
|
||||
imports: [DataSourceModule, MetadataModule],
|
||||
exports: [DataSourceModule],
|
||||
})
|
||||
export class TenantModule {}
|
238
server/yarn.lock
238
server/yarn.lock
@ -2607,7 +2607,7 @@
|
||||
"@smithy/types" "^1.1.0"
|
||||
tslib "^2.5.0"
|
||||
|
||||
"@sqltools/formatter@^1.2.3":
|
||||
"@sqltools/formatter@^1.2.3", "@sqltools/formatter@^1.2.5":
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/@sqltools/formatter/-/formatter-1.2.5.tgz#3abc203c79b8c3e90fd6c156a0c62d5403520e12"
|
||||
integrity sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==
|
||||
@ -3515,6 +3515,11 @@ ansi-styles@^5.0.0:
|
||||
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz"
|
||||
integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==
|
||||
|
||||
any-promise@^1.0.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
|
||||
integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==
|
||||
|
||||
anymatch@^3.0.3, anymatch@~3.1.2:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz"
|
||||
@ -3613,6 +3618,11 @@ apollo-server-types@^3.8.0:
|
||||
apollo-reporting-protobuf "^3.4.0"
|
||||
apollo-server-env "^4.2.1"
|
||||
|
||||
app-root-path@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-3.1.0.tgz#5971a2fc12ba170369a7a1ef018c71e6e47c2e86"
|
||||
integrity sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==
|
||||
|
||||
append-field@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz"
|
||||
@ -4009,6 +4019,11 @@ buffer-from@^1.0.0:
|
||||
resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz"
|
||||
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
|
||||
|
||||
buffer-writer@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04"
|
||||
integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==
|
||||
|
||||
buffer@^5.5.0:
|
||||
version "5.7.1"
|
||||
resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz"
|
||||
@ -4017,6 +4032,14 @@ buffer@^5.5.0:
|
||||
base64-js "^1.3.1"
|
||||
ieee754 "^1.1.13"
|
||||
|
||||
buffer@^6.0.3:
|
||||
version "6.0.3"
|
||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
|
||||
integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
|
||||
dependencies:
|
||||
base64-js "^1.3.1"
|
||||
ieee754 "^1.2.1"
|
||||
|
||||
busboy@^0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.3.1.tgz#170899274c5bf38aae27d5c62b71268cd585fd1b"
|
||||
@ -4180,6 +4203,18 @@ cli-cursor@^3.1.0:
|
||||
dependencies:
|
||||
restore-cursor "^3.1.0"
|
||||
|
||||
cli-highlight@^2.1.11:
|
||||
version "2.1.11"
|
||||
resolved "https://registry.yarnpkg.com/cli-highlight/-/cli-highlight-2.1.11.tgz#49736fa452f0aaf4fae580e30acb26828d2dc1bf"
|
||||
integrity sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==
|
||||
dependencies:
|
||||
chalk "^4.0.0"
|
||||
highlight.js "^10.7.1"
|
||||
mz "^2.4.0"
|
||||
parse5 "^5.1.1"
|
||||
parse5-htmlparser2-tree-adapter "^6.0.0"
|
||||
yargs "^16.0.0"
|
||||
|
||||
cli-spinners@^2.5.0:
|
||||
version "2.9.0"
|
||||
resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz"
|
||||
@ -4207,6 +4242,15 @@ cli-width@^3.0.0:
|
||||
resolved "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz"
|
||||
integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==
|
||||
|
||||
cliui@^7.0.2:
|
||||
version "7.0.4"
|
||||
resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
|
||||
integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
|
||||
dependencies:
|
||||
string-width "^4.2.0"
|
||||
strip-ansi "^6.0.0"
|
||||
wrap-ansi "^7.0.0"
|
||||
|
||||
cliui@^8.0.1:
|
||||
version "8.0.1"
|
||||
resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz"
|
||||
@ -4441,7 +4485,7 @@ cssfilter@0.0.10:
|
||||
resolved "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz"
|
||||
integrity sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==
|
||||
|
||||
date-fns@*, date-fns@^2.30.0:
|
||||
date-fns@*, date-fns@^2.29.3, date-fns@^2.30.0:
|
||||
version "2.30.0"
|
||||
resolved "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz"
|
||||
integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==
|
||||
@ -4621,6 +4665,11 @@ dotenv@16.1.4:
|
||||
resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.1.4.tgz"
|
||||
integrity sha512-m55RtE8AsPeJBpOIFKihEmqUcoVncQIwo7x9U8ZwLEZw9ZpXboz2c+rvog+jUaJvVrZ5kBOeYQBX5+8Aa/OZQw==
|
||||
|
||||
dotenv@^16.0.3:
|
||||
version "16.3.1"
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e"
|
||||
integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==
|
||||
|
||||
ecdsa-sig-formatter@1.0.11:
|
||||
version "1.0.11"
|
||||
resolved "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz"
|
||||
@ -5485,7 +5534,7 @@ glob@^7.0.0, glob@^7.1.3, glob@^7.1.4:
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@^8.0.1:
|
||||
glob@^8.0.1, glob@^8.1.0:
|
||||
version "8.1.0"
|
||||
resolved "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz"
|
||||
integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==
|
||||
@ -5670,6 +5719,11 @@ hexoid@^1.0.0:
|
||||
resolved "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz"
|
||||
integrity sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==
|
||||
|
||||
highlight.js@^10.7.1:
|
||||
version "10.7.3"
|
||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531"
|
||||
integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==
|
||||
|
||||
hosted-git-info@^2.1.4:
|
||||
version "2.8.9"
|
||||
resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz"
|
||||
@ -6955,6 +7009,11 @@ mkdirp@^1.0.3, mkdirp@^1.0.4:
|
||||
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz"
|
||||
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
|
||||
|
||||
mkdirp@^2.1.3:
|
||||
version "2.1.6"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.6.tgz#964fbcb12b2d8c5d6fbc62a963ac95a273e2cc19"
|
||||
integrity sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"
|
||||
@ -6988,6 +7047,15 @@ mute-stream@0.0.8:
|
||||
resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz"
|
||||
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
|
||||
|
||||
mz@^2.4.0:
|
||||
version "2.7.0"
|
||||
resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
|
||||
integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==
|
||||
dependencies:
|
||||
any-promise "^1.0.0"
|
||||
object-assign "^4.0.1"
|
||||
thenify-all "^1.0.0"
|
||||
|
||||
napi-build-utils@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806"
|
||||
@ -7130,7 +7198,7 @@ oauth@0.9.x:
|
||||
resolved "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz"
|
||||
integrity sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==
|
||||
|
||||
object-assign@^4, object-assign@^4.1.1:
|
||||
object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"
|
||||
integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
|
||||
@ -7303,6 +7371,11 @@ p-try@^2.0.0:
|
||||
resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz"
|
||||
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
|
||||
|
||||
packet-reader@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74"
|
||||
integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==
|
||||
|
||||
parent-module@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz"
|
||||
@ -7320,6 +7393,23 @@ parse-json@^5.0.0, parse-json@^5.2.0:
|
||||
json-parse-even-better-errors "^2.3.0"
|
||||
lines-and-columns "^1.1.6"
|
||||
|
||||
parse5-htmlparser2-tree-adapter@^6.0.0:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6"
|
||||
integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==
|
||||
dependencies:
|
||||
parse5 "^6.0.1"
|
||||
|
||||
parse5@^5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178"
|
||||
integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==
|
||||
|
||||
parse5@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
|
||||
integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
|
||||
|
||||
parseurl@^1.3.3, parseurl@~1.3.3:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz"
|
||||
@ -7435,6 +7525,64 @@ peek-readable@^4.1.0:
|
||||
resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.1.0.tgz#4ece1111bf5c2ad8867c314c81356847e8a62e72"
|
||||
integrity sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==
|
||||
|
||||
pg-cloudflare@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz#e6d5833015b170e23ae819e8c5d7eaedb472ca98"
|
||||
integrity sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==
|
||||
|
||||
pg-connection-string@^2.6.2:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.6.2.tgz#713d82053de4e2bd166fab70cd4f26ad36aab475"
|
||||
integrity sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==
|
||||
|
||||
pg-int8@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c"
|
||||
integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==
|
||||
|
||||
pg-pool@^3.6.1:
|
||||
version "3.6.1"
|
||||
resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.6.1.tgz#5a902eda79a8d7e3c928b77abf776b3cb7d351f7"
|
||||
integrity sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==
|
||||
|
||||
pg-protocol@^1.6.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.6.0.tgz#4c91613c0315349363af2084608db843502f8833"
|
||||
integrity sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==
|
||||
|
||||
pg-types@^2.1.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3"
|
||||
integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==
|
||||
dependencies:
|
||||
pg-int8 "1.0.1"
|
||||
postgres-array "~2.0.0"
|
||||
postgres-bytea "~1.0.0"
|
||||
postgres-date "~1.0.4"
|
||||
postgres-interval "^1.1.0"
|
||||
|
||||
pg@^8.11.3:
|
||||
version "8.11.3"
|
||||
resolved "https://registry.yarnpkg.com/pg/-/pg-8.11.3.tgz#d7db6e3fe268fcedd65b8e4599cda0b8b4bf76cb"
|
||||
integrity sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g==
|
||||
dependencies:
|
||||
buffer-writer "2.0.0"
|
||||
packet-reader "1.0.0"
|
||||
pg-connection-string "^2.6.2"
|
||||
pg-pool "^3.6.1"
|
||||
pg-protocol "^1.6.0"
|
||||
pg-types "^2.1.0"
|
||||
pgpass "1.x"
|
||||
optionalDependencies:
|
||||
pg-cloudflare "^1.1.1"
|
||||
|
||||
pgpass@1.x:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.5.tgz#9b873e4a564bb10fa7a7dbd55312728d422a223d"
|
||||
integrity sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==
|
||||
dependencies:
|
||||
split2 "^4.1.0"
|
||||
|
||||
picocolors@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz"
|
||||
@ -7462,6 +7610,28 @@ pluralize@8.0.0, pluralize@^8.0.0:
|
||||
resolved "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz"
|
||||
integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==
|
||||
|
||||
postgres-array@~2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e"
|
||||
integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==
|
||||
|
||||
postgres-bytea@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35"
|
||||
integrity sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==
|
||||
|
||||
postgres-date@~1.0.4:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8"
|
||||
integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==
|
||||
|
||||
postgres-interval@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695"
|
||||
integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==
|
||||
dependencies:
|
||||
xtend "^4.0.0"
|
||||
|
||||
prebuild-install@^7.1.1:
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45"
|
||||
@ -8108,6 +8278,11 @@ spdx-license-ids@^3.0.0:
|
||||
resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz"
|
||||
integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==
|
||||
|
||||
split2@^4.1.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4"
|
||||
integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==
|
||||
|
||||
sprintf-js@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz"
|
||||
@ -8449,6 +8624,20 @@ text-table@^0.2.0:
|
||||
resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz"
|
||||
integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
|
||||
|
||||
thenify-all@^1.0.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
|
||||
integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==
|
||||
dependencies:
|
||||
thenify ">= 3.1.0 < 4"
|
||||
|
||||
"thenify@>= 3.1.0 < 4":
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f"
|
||||
integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==
|
||||
dependencies:
|
||||
any-promise "^1.0.0"
|
||||
|
||||
through@^2.3.6:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz"
|
||||
@ -8746,6 +8935,27 @@ typedarray@^0.0.6:
|
||||
resolved "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz"
|
||||
integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==
|
||||
|
||||
typeorm@^0.3.17:
|
||||
version "0.3.17"
|
||||
resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.3.17.tgz#a73c121a52e4fbe419b596b244777be4e4b57949"
|
||||
integrity sha512-UDjUEwIQalO9tWw9O2A4GU+sT3oyoUXheHJy4ft+RFdnRdQctdQ34L9SqE2p7LdwzafHx1maxT+bqXON+Qnmig==
|
||||
dependencies:
|
||||
"@sqltools/formatter" "^1.2.5"
|
||||
app-root-path "^3.1.0"
|
||||
buffer "^6.0.3"
|
||||
chalk "^4.1.2"
|
||||
cli-highlight "^2.1.11"
|
||||
date-fns "^2.29.3"
|
||||
debug "^4.3.4"
|
||||
dotenv "^16.0.3"
|
||||
glob "^8.1.0"
|
||||
mkdirp "^2.1.3"
|
||||
reflect-metadata "^0.1.13"
|
||||
sha.js "^2.4.11"
|
||||
tslib "^2.5.0"
|
||||
uuid "^9.0.0"
|
||||
yargs "^17.6.2"
|
||||
|
||||
typescript@4.9.5, typescript@^4.9.4:
|
||||
version "4.9.5"
|
||||
resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz"
|
||||
@ -9077,7 +9287,25 @@ yargs-parser@21.1.1, yargs-parser@^21.0.1, yargs-parser@^21.1.1:
|
||||
resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz"
|
||||
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
|
||||
|
||||
yargs@^17.3.1:
|
||||
yargs-parser@^20.2.2:
|
||||
version "20.2.9"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
|
||||
integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
|
||||
|
||||
yargs@^16.0.0:
|
||||
version "16.2.0"
|
||||
resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
|
||||
integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
|
||||
dependencies:
|
||||
cliui "^7.0.2"
|
||||
escalade "^3.1.1"
|
||||
get-caller-file "^2.0.5"
|
||||
require-directory "^2.1.1"
|
||||
string-width "^4.2.0"
|
||||
y18n "^5.0.5"
|
||||
yargs-parser "^20.2.2"
|
||||
|
||||
yargs@^17.3.1, yargs@^17.6.2:
|
||||
version "17.7.2"
|
||||
resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz"
|
||||
integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
|
||||
|
Loading…
Reference in New Issue
Block a user