@vritti/api-sdk 0.4.6 → 0.4.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth.cjs +70 -4
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +16 -1
- package/dist/auth.d.ts +16 -1
- package/dist/auth.js +70 -4
- package/dist/auth.js.map +1 -1
- package/dist/bad-request.exception-D-KmhiXQ.d.cts +18 -0
- package/dist/bad-request.exception-Db94kZxY.d.ts +18 -0
- package/dist/data-table.cjs +3 -4
- package/dist/data-table.cjs.map +1 -1
- package/dist/data-table.js +3 -4
- package/dist/data-table.js.map +1 -1
- package/dist/database.cjs +11 -2
- package/dist/database.cjs.map +1 -1
- package/dist/database.d.cts +1 -0
- package/dist/database.d.ts +1 -0
- package/dist/database.js +26 -17
- package/dist/database.js.map +1 -1
- package/dist/decimal.d.cts +1 -0
- package/dist/decimal.d.ts +1 -0
- package/dist/exceptions.d.cts +4 -17
- package/dist/exceptions.d.ts +4 -17
- package/dist/index.d.cts +16 -2
- package/dist/index.d.ts +16 -2
- package/dist/mcp.cjs +814 -0
- package/dist/mcp.cjs.map +1 -0
- package/dist/mcp.d.cts +135 -0
- package/dist/mcp.d.ts +135 -0
- package/dist/mcp.js +771 -0
- package/dist/mcp.js.map +1 -0
- package/dist/root.cjs +1 -0
- package/dist/root.cjs.map +1 -1
- package/dist/root.js +1 -0
- package/dist/root.js.map +1 -1
- package/dist/zod.cjs +25 -0
- package/dist/zod.cjs.map +1 -0
- package/dist/zod.d.cts +1 -0
- package/dist/zod.d.ts +1 -0
- package/dist/zod.js +3 -0
- package/dist/zod.js.map +1 -0
- package/package.json +24 -2
package/dist/data-table.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/data-table/data-table.module.ts","../src/data-table/data-table.constants.ts","../src/data-table/state/controllers/data-table-state.controller.ts","../src/auth/decorators/user-id.decorator.ts","../src/context/extractors/graphql.extractor.ts","../src/context/extractors/http.extractor.ts","../src/context/context.registry.ts","../src/context/get-request.ts","../src/data-table/state/docs/data-table-state.docs.ts","../src/data-table/state/dto/request/upsert-data-table-state.dto.ts","../src/data-table/state/services/data-table-state.service.ts","../src/data-table/views/controllers/data-table-views.controller.ts","../src/data-table/views/docs/data-table-views.docs.ts","../src/data-table/views/dto/entity/data-table-view.dto.ts","../src/data-table/views/dto/request/create-data-table-view.dto.ts","../src/data-table/views/dto/request/rename-data-table-view.dto.ts","../src/data-table/views/dto/request/toggle-share-data-table-view.dto.ts","../src/data-table/views/dto/request/update-data-table-view.dto.ts","../src/data-table/views/services/data-table-views.service.ts","../src/exceptions/bad-gateway.exception.ts","../src/exceptions/base-field.exception.ts","../src/exceptions/bad-request.exception.ts","../src/exceptions/conflict.exception.ts","../src/exceptions/forbidden.exception.ts","../src/exceptions/gone.exception.ts","../src/exceptions/internal-server-error.exception.ts","../src/exceptions/method-not-allowed.exception.ts","../src/exceptions/not-acceptable.exception.ts","../src/exceptions/not-found.exception.ts","../src/exceptions/not-implemented.exception.ts","../src/exceptions/payload-too-large.exception.ts","../src/exceptions/request-timeout.exception.ts","../src/exceptions/service-unavailable.exception.ts","../src/exceptions/too-many-requests.exception.ts","../src/exceptions/unauthorized.exception.ts","../src/exceptions/unprocessable-entity.exception.ts","../src/exceptions/unsupported-media-type.exception.ts","../src/exceptions/validation.exception.ts","../src/data-table/views/repositories/data-table-views.repository.ts","../src/drizzle-pg-core.ts","../src/decorators/code-pattern.ts","../src/data-table/schema/data-table-views.table.ts"],"sourcesContent":["import { type DynamicModule, Module } from '@nestjs/common';\nimport { ConfigModule } from '@nestjs/config';\nimport { CacheModule } from '@vritti/api-sdk/cache';\nimport type { PgTable } from 'drizzle-orm/pg-core';\nimport { DATA_TABLE_VIEWS_TABLE } from './data-table.constants';\nimport { DataTableStateController } from './state/controllers/data-table-state.controller';\nimport { DataTableStateService } from './state/services/data-table-state.service';\nimport { DataTableViewsController } from './views/controllers/data-table-views.controller';\nimport { DataTableViewsRepository } from './views/repositories/data-table-views.repository';\nimport { DataTableViewsService } from './views/services/data-table-views.service';\n\nexport { DATA_TABLE_VIEWS_TABLE };\n\nexport interface DataTableModuleOptions {\n tableViews: PgTable;\n}\n\n@Module({})\nexport class DataTableModule {\n static forRoot(options: DataTableModuleOptions): DynamicModule {\n return {\n global: true,\n module: DataTableModule,\n imports: [ConfigModule, CacheModule],\n controllers: [DataTableStateController, DataTableViewsController],\n providers: [\n {\n provide: DATA_TABLE_VIEWS_TABLE,\n useValue: options.tableViews,\n },\n DataTableViewsService,\n DataTableViewsRepository,\n DataTableStateService,\n ],\n exports: [DataTableViewsService, DataTableStateService],\n };\n }\n}\n","export const DATA_TABLE_VIEWS_TABLE = Symbol('DATA_TABLE_VIEWS_TABLE');\n","import { Body, Controller, HttpCode, HttpStatus, Logger, Post } from '@nestjs/common';\nimport { ApiBearerAuth, ApiTags } from '@nestjs/swagger';\nimport { UserId } from '../../../auth/decorators/user-id.decorator';\nimport { ApiUpsertDataTableState } from '../docs/data-table-state.docs';\nimport { UpsertDataTableStateDto } from '../dto/request/upsert-data-table-state.dto';\nimport { DataTableStateService } from '../services/data-table-state.service';\n\n@ApiTags('Table States')\n@ApiBearerAuth()\n@Controller('table-states')\nexport class DataTableStateController {\n private readonly logger = new Logger(DataTableStateController.name);\n\n constructor(private readonly dataTableStateService: DataTableStateService) {}\n\n // Saves live table state to Redis cache for the authenticated user's table\n @Post()\n @HttpCode(HttpStatus.OK)\n @ApiUpsertDataTableState()\n upsertCurrentState(@UserId() userId: string, @Body() dto: UpsertDataTableStateDto): Promise<void> {\n this.logger.log(`POST /table-states - User: ${userId}, table: ${dto.tableSlug}`);\n return this.dataTableStateService.upsertCurrentState(userId, dto);\n }\n}\n","import { createParamDecorator, type ExecutionContext } from '@nestjs/common';\nimport { getRequestFromContext } from '../../context';\nimport '../../types/fastify-augmentation';\n\n// Extracts userId from request.auth (set by VrittiAuthGuard).\n//\n// Only a session has one. An app request acts for a credential and a cloud request for the\n// control plane, so asking for a user on either is a mistake at the call site — it throws\n// rather than returning a stand-in that would be recorded as if a person had acted.\nexport const UserId = createParamDecorator((_data: unknown, ctx: ExecutionContext): string => {\n const auth = getRequestFromContext(ctx).auth;\n\n if (auth?.kind !== 'session') {\n throw new Error(`No user on this request (auth: ${auth?.kind ?? 'none'}). @UserId() is session-only.`);\n }\n\n return auth.userId;\n});\n","import type { ArgumentsHost } from '@nestjs/common';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\nimport type { RequestExtractor } from '../context.types';\n\ninterface GqlContext {\n req: FastifyRequest;\n reply?: FastifyReply;\n}\n\nexport const graphqlExtractor: RequestExtractor = {\n getRequest: (host: ArgumentsHost) => host.getArgByIndex<GqlContext>(2).req,\n getResponse: (host: ArgumentsHost) => host.getArgByIndex<GqlContext>(2).reply as FastifyReply,\n};\n","import type { FastifyReply, FastifyRequest } from 'fastify';\nimport type { RequestExtractor } from '../context.types';\n\n// Default transport: standard HTTP via the Fastify adapter.\nexport const httpExtractor: RequestExtractor = {\n getRequest: (host) => host.switchToHttp().getRequest<FastifyRequest>(),\n getResponse: (host) => host.switchToHttp().getResponse<FastifyReply>(),\n};\n","import type { RequestExtractor, TransportType } from './context.types';\nimport { graphqlExtractor } from './extractors/graphql.extractor';\nimport { httpExtractor } from './extractors/http.extractor';\n\nconst registry = new Map<TransportType, RequestExtractor>([\n ['http', httpExtractor],\n ['graphql', graphqlExtractor],\n]);\n\n// Registers (or overrides) the extractor for a transport type without modifying the SDK\nexport function registerTransport(type: TransportType, extractor: RequestExtractor): void {\n registry.set(type, extractor);\n}\n\n// Resolves the extractor for the host's reported transport, falling back to HTTP.\nexport function resolveExtractor(type: string): RequestExtractor {\n return registry.get(type as TransportType) ?? httpExtractor;\n}\n","import type { ArgumentsHost } from '@nestjs/common';\nimport type { FastifyRequest } from 'fastify';\nimport { resolveExtractor } from './context.registry';\n\n// Returns the underlying Fastify request for any registered transport, via the transport registry.\nexport function getRequestFromContext(host: ArgumentsHost): FastifyRequest {\n return resolveExtractor(host.getType()).getRequest(host);\n}\n","import { applyDecorators } from '@nestjs/common';\nimport { ApiBody, ApiOperation, ApiResponse } from '@nestjs/swagger';\nimport { UpsertDataTableStateDto } from '../dto/request/upsert-data-table-state.dto';\n\nexport function ApiUpsertDataTableState() {\n return applyDecorators(\n ApiOperation({\n summary: 'Save live table state',\n description:\n 'Stores the current filter, sort, and column visibility state in Redis cache. Called on filter Apply and sort column click. State expires after TABLE_STATE_CACHE_TTL seconds.',\n }),\n ApiBody({ type: UpsertDataTableStateDto }),\n ApiResponse({ status: 200, description: 'Live state cached.' }),\n ApiResponse({ status: 400, description: 'Invalid request body.' }),\n ApiResponse({ status: 401, description: 'Unauthorized.' }),\n );\n}\n","import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';\nimport { IsObject, IsOptional, IsString, IsUUID, MaxLength } from 'class-validator';\nimport type { TableViewState } from '../../../../database/filter/filter.types';\n\nexport class UpsertDataTableStateDto {\n @ApiProperty({ description: 'Unique slug identifying the table', example: 'cloud-providers' })\n @IsString()\n @MaxLength(200)\n tableSlug: string;\n\n @ApiProperty({ description: 'Full table view state including filters, sort, and column visibility' })\n @IsObject()\n state: TableViewState;\n\n @ApiPropertyOptional()\n @IsOptional()\n @IsUUID()\n activeViewId?: string | null;\n}\n","import { Injectable, Logger } from '@nestjs/common';\nimport { ConfigService } from '@nestjs/config';\nimport { CacheService } from '@vritti/api-sdk/cache';\nimport type { TableViewState } from '../../../database/filter/filter.types';\nimport type { UpsertDataTableStateDto } from '../dto/request/upsert-data-table-state.dto';\n\nconst EMPTY_TABLE_STATE: TableViewState = {\n filters: [],\n sort: [],\n columnVisibility: {},\n columnOrder: [],\n columnSizing: {},\n columnPinning: { left: [], right: [] },\n lockedColumnSizing: false,\n density: 'normal',\n filterOrder: [],\n filterVisibility: {},\n search: null,\n pagination: { limit: 20, offset: 0 },\n};\n\n@Injectable()\nexport class DataTableStateService {\n private readonly logger = new Logger(DataTableStateService.name);\n\n constructor(\n private readonly cacheService: CacheService,\n private readonly configService: ConfigService,\n ) {}\n\n // Returns configured TTL for live table state in seconds, defaulting to 3600 (1h)\n private get stateTtl(): number {\n return this.configService.get<number>('TABLE_STATE_CACHE_TTL') ?? 3600;\n }\n\n // Saves live table state and active view ID to Redis; DB is not written\n async upsertCurrentState(userId: string, dto: UpsertDataTableStateDto): Promise<void> {\n const key = `dt:${userId}:${dto.tableSlug}`;\n await this.cacheService.set(key, { state: dto.state, activeViewId: dto.activeViewId ?? null }, this.stateTtl);\n this.logger.log(`Cached live state for user: ${userId}, table: ${dto.tableSlug}`);\n }\n\n // Returns live table state and active view ID from Redis; returns empty state on miss — no DB query\n async getCurrentState(\n userId: string,\n tableSlug: string,\n ): Promise<{ state: TableViewState; activeViewId: string | null }> {\n const key = `dt:${userId}:${tableSlug}`;\n const cached = await this.cacheService.get<{ state: TableViewState; activeViewId: string | null }>(key);\n return cached ?? { state: EMPTY_TABLE_STATE, activeViewId: null };\n }\n}\n","import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Logger, Param, Patch, Post, Query } from '@nestjs/common';\nimport { ApiBearerAuth, ApiTags } from '@nestjs/swagger';\nimport { UserId } from '../../../auth/decorators/user-id.decorator';\nimport {\n ApiCreateDataTableView,\n ApiDeleteDataTableView,\n ApiListDataTableViews,\n ApiRenameDataTableView,\n ApiToggleShareDataTableView,\n ApiUpdateDataTableView,\n} from '../docs/data-table-views.docs';\nimport { DataTableViewDto } from '../dto/entity/data-table-view.dto';\nimport { CreateDataTableViewDto } from '../dto/request/create-data-table-view.dto';\nimport { RenameDataTableViewDto } from '../dto/request/rename-data-table-view.dto';\nimport { ToggleShareDataTableViewDto } from '../dto/request/toggle-share-data-table-view.dto';\nimport { UpdateDataTableViewDto } from '../dto/request/update-data-table-view.dto';\nimport { DataTableViewsService } from '../services/data-table-views.service';\n\n@ApiTags('Table Views')\n@ApiBearerAuth()\n@Controller('table-views')\nexport class DataTableViewsController {\n private readonly logger = new Logger(DataTableViewsController.name);\n\n constructor(private readonly dataTableViewsService: DataTableViewsService) {}\n\n // Returns all named views for the given table — own plus shared\n @Get()\n @ApiListDataTableViews()\n findViews(@UserId() userId: string, @Query('tableSlug') tableSlug: string): Promise<DataTableViewDto[]> {\n this.logger.log(`GET /table-views?tableSlug=${tableSlug} - User: ${userId}`);\n return this.dataTableViewsService.findViews(userId, tableSlug);\n }\n\n // Creates a named snapshot of the current table state\n @Post()\n @HttpCode(HttpStatus.CREATED)\n @ApiCreateDataTableView()\n createView(@UserId() userId: string, @Body() dto: CreateDataTableViewDto): Promise<DataTableViewDto> {\n this.logger.log(`POST /table-views - User: ${userId}, table: ${dto.tableSlug}`);\n return this.dataTableViewsService.createView(userId, dto);\n }\n\n // Updates state of an existing named view\n @Patch(':id')\n @ApiUpdateDataTableView()\n updateView(\n @UserId() userId: string,\n @Param('id') id: string,\n @Body() dto: UpdateDataTableViewDto,\n ): Promise<DataTableViewDto> {\n this.logger.log(`PATCH /table-views/${id} - User: ${userId}`);\n return this.dataTableViewsService.updateView(userId, id, dto);\n }\n\n // Renames an existing named view — enforces unique name per user+table\n @Patch(':id/rename')\n @ApiRenameDataTableView()\n renameView(\n @UserId() userId: string,\n @Param('id') id: string,\n @Body() dto: RenameDataTableViewDto,\n ): Promise<DataTableViewDto> {\n this.logger.log(`PATCH /table-views/${id}/rename - User: ${userId}`);\n return this.dataTableViewsService.renameView(userId, id, dto.name);\n }\n\n // Toggles sharing visibility of a named view\n @Patch(':id/share')\n @ApiToggleShareDataTableView()\n toggleShareView(\n @UserId() userId: string,\n @Param('id') id: string,\n @Body() dto: ToggleShareDataTableViewDto,\n ): Promise<DataTableViewDto> {\n this.logger.log(`PATCH /table-views/${id}/share - User: ${userId}`);\n return this.dataTableViewsService.toggleShareView(userId, id, dto.isShared);\n }\n\n // Deletes a named view owned by the authenticated user\n @Delete(':id')\n @ApiDeleteDataTableView()\n deleteView(@UserId() userId: string, @Param('id') id: string): Promise<DataTableViewDto> {\n this.logger.log(`DELETE /table-views/${id} - User: ${userId}`);\n return this.dataTableViewsService.deleteView(userId, id);\n }\n}\n","import { applyDecorators } from '@nestjs/common';\nimport { ApiBody, ApiOperation, ApiParam, ApiQuery, ApiResponse } from '@nestjs/swagger';\nimport { DataTableViewDto } from '../dto/entity/data-table-view.dto';\nimport { CreateDataTableViewDto } from '../dto/request/create-data-table-view.dto';\nimport { RenameDataTableViewDto } from '../dto/request/rename-data-table-view.dto';\nimport { ToggleShareDataTableViewDto } from '../dto/request/toggle-share-data-table-view.dto';\nimport { UpdateDataTableViewDto } from '../dto/request/update-data-table-view.dto';\n\nexport function ApiListDataTableViews() {\n return applyDecorators(\n ApiOperation({\n summary: 'List named table views',\n description: \"Returns the authenticated user's own named views plus all shared views for the given table slug.\",\n }),\n ApiQuery({\n name: 'tableSlug',\n description: 'Slug of the table to fetch views for',\n example: 'cloud-providers',\n required: true,\n }),\n ApiResponse({ status: 200, description: 'Named views retrieved.', type: [DataTableViewDto] }),\n ApiResponse({ status: 401, description: 'Unauthorized.' }),\n );\n}\n\nexport function ApiCreateDataTableView() {\n return applyDecorators(\n ApiOperation({\n summary: 'Create named table view',\n description: 'Saves the current table state as a named view snapshot. The name must be unique per user+table.',\n }),\n ApiBody({ type: CreateDataTableViewDto }),\n ApiResponse({ status: 201, description: 'Named view created.', type: DataTableViewDto }),\n ApiResponse({ status: 400, description: 'Invalid request body.' }),\n ApiResponse({ status: 401, description: 'Unauthorized.' }),\n );\n}\n\nexport function ApiUpdateDataTableView() {\n return applyDecorators(\n ApiOperation({\n summary: 'Update named table view',\n description: 'Updates the state of an existing named view. Only the owner can update.',\n }),\n ApiParam({ name: 'id', description: 'UUID of the table view to update' }),\n ApiBody({ type: UpdateDataTableViewDto }),\n ApiResponse({ status: 200, description: 'View updated.', type: DataTableViewDto }),\n ApiResponse({ status: 400, description: 'Validation failed or not owned by caller.' }),\n ApiResponse({ status: 401, description: 'Unauthorized.' }),\n ApiResponse({ status: 404, description: 'View not found.' }),\n );\n}\n\nexport function ApiRenameDataTableView() {\n return applyDecorators(\n ApiOperation({\n summary: 'Rename a named table view',\n description:\n 'Updates the display name of an existing view. The new name must be unique per user+table. Only the owner can rename.',\n }),\n ApiParam({ name: 'id', description: 'UUID of the table view to rename' }),\n ApiBody({ type: RenameDataTableViewDto }),\n ApiResponse({ status: 200, description: 'View renamed.', type: DataTableViewDto }),\n ApiResponse({ status: 400, description: 'Not owned by caller.' }),\n ApiResponse({ status: 401, description: 'Unauthorized.' }),\n ApiResponse({ status: 404, description: 'View not found.' }),\n ApiResponse({ status: 409, description: 'A view with this name already exists.' }),\n );\n}\n\nexport function ApiToggleShareDataTableView() {\n return applyDecorators(\n ApiOperation({\n summary: 'Toggle view sharing',\n description:\n 'Makes a view visible to all users (shared) or restricts it to the owner only (private). Only the owner can toggle sharing.',\n }),\n ApiParam({ name: 'id', description: 'UUID of the table view' }),\n ApiBody({ type: ToggleShareDataTableViewDto }),\n ApiResponse({ status: 200, description: 'Sharing status updated.', type: DataTableViewDto }),\n ApiResponse({ status: 400, description: 'Not owned by caller.' }),\n ApiResponse({ status: 401, description: 'Unauthorized.' }),\n ApiResponse({ status: 404, description: 'View not found.' }),\n );\n}\n\nexport function ApiDeleteDataTableView() {\n return applyDecorators(\n ApiOperation({\n summary: 'Delete named table view',\n description: 'Permanently deletes a named view. Only the owner can delete their own views.',\n }),\n ApiParam({ name: 'id', description: 'UUID of the table view to delete' }),\n ApiResponse({ status: 200, description: 'View deleted.', type: DataTableViewDto }),\n ApiResponse({ status: 400, description: 'Not owned by caller.' }),\n ApiResponse({ status: 401, description: 'Unauthorized.' }),\n ApiResponse({ status: 404, description: 'View not found.' }),\n );\n}\n","import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';\nimport type { TableViewState } from '../../../../database/filter/filter.types';\nimport type { DataTableViewRecord } from '../../../schema/data-table-views.table';\n\nexport class DataTableViewDto {\n @ApiProperty({ description: 'View unique identifier' })\n id: string;\n\n @ApiPropertyOptional({ description: 'Display name of the view', nullable: true })\n name: string | null;\n\n @ApiProperty({ description: 'Slug of the table this view belongs to', example: 'cloud-providers' })\n tableSlug: string;\n\n @ApiProperty({ description: 'Stored filter, sort, and column visibility state' })\n state: TableViewState;\n\n @ApiProperty({ description: 'Whether the view is visible to all users', example: false })\n isShared: boolean;\n\n @ApiProperty({ description: 'Whether the requesting user owns this view', example: true })\n isOwn: boolean;\n\n @ApiProperty({ description: 'Creation timestamp' })\n createdAt: Date;\n\n @ApiPropertyOptional({ description: 'Last updated timestamp', nullable: true })\n updatedAt: Date | null;\n\n // Creates a response DTO from a DataTableView entity, computing isOwn by comparing userId\n static from(view: DataTableViewRecord, userId: string): DataTableViewDto {\n const dto = new DataTableViewDto();\n dto.id = view.id;\n dto.name = view.name ?? null;\n dto.tableSlug = view.tableSlug;\n dto.state = view.state;\n dto.isShared = view.isShared;\n dto.isOwn = view.userId === userId;\n dto.createdAt = view.createdAt;\n dto.updatedAt = view.updatedAt ?? null;\n return dto;\n }\n}\n","import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';\nimport { IsBoolean, IsObject, IsOptional, IsString, MaxLength } from 'class-validator';\nimport type { TableViewState } from '../../../../database/filter/filter.types';\n\nexport class CreateDataTableViewDto {\n @ApiProperty({ description: 'Display name for the saved view', example: 'AWS Only' })\n @IsString()\n @MaxLength(100)\n name: string;\n\n @ApiProperty({ description: 'Unique slug identifying the table', example: 'cloud-providers' })\n @IsString()\n @MaxLength(200)\n tableSlug: string;\n\n @ApiProperty({ description: 'Full table view state including filters, sort, and column visibility' })\n @IsObject()\n state: TableViewState;\n\n @ApiPropertyOptional({ description: 'Whether this view is visible to all users', example: false })\n @IsBoolean()\n @IsOptional()\n isShared?: boolean;\n}\n","import { ApiProperty } from '@nestjs/swagger';\nimport { IsString, MaxLength, MinLength } from 'class-validator';\n\nexport class RenameDataTableViewDto {\n @ApiProperty({ description: 'New display name for the view', example: 'AWS Only' })\n @IsString()\n @MinLength(1)\n @MaxLength(100)\n name: string;\n}\n","import { ApiProperty } from '@nestjs/swagger';\nimport { IsBoolean } from 'class-validator';\n\nexport class ToggleShareDataTableViewDto {\n @ApiProperty({ description: 'Whether the view should be visible to all users', example: true })\n @IsBoolean()\n isShared: boolean;\n}\n","import { ApiProperty } from '@nestjs/swagger';\nimport { IsObject } from 'class-validator';\nimport type { TableViewState } from '../../../../database/filter/filter.types';\n\n// State-only update — name, tableSlug, and isShared are not updatable via this DTO\nexport class UpdateDataTableViewDto {\n @ApiProperty({ description: 'Updated filter, sort, and column visibility state' })\n @IsObject()\n state: TableViewState;\n}\n","import { createHash } from 'node:crypto';\nimport { Injectable, Logger } from '@nestjs/common';\nimport { ConfigService } from '@nestjs/config';\nimport { CacheService } from '@vritti/api-sdk/cache';\nimport { BadRequestException, ConflictException, NotFoundException } from '../../../exceptions';\nimport type { DataTableViewRecord } from '../../schema/data-table-views.table';\nimport { DataTableViewDto } from '../dto/entity/data-table-view.dto';\nimport type { CreateDataTableViewDto } from '../dto/request/create-data-table-view.dto';\nimport type { UpdateDataTableViewDto } from '../dto/request/update-data-table-view.dto';\nimport { DataTableViewsRepository } from '../repositories/data-table-views.repository';\n\n// Computes a deterministic SHA-256 checksum of a value for equality comparison\nfunction computeChecksum(value: unknown): string {\n return createHash('sha256').update(JSON.stringify(value)).digest('hex');\n}\n\n@Injectable()\nexport class DataTableViewsService {\n private readonly logger = new Logger(DataTableViewsService.name);\n\n constructor(\n private readonly dataTableViewsRepository: DataTableViewsRepository,\n private readonly cacheService: CacheService,\n private readonly configService: ConfigService,\n ) {}\n\n // Builds the Redis key for a user's personal (non-shared) views for a given table\n private personalViewsKey(userId: string, tableSlug: string): string {\n return `views:personal:${userId}:${tableSlug}`;\n }\n\n // Builds the Redis key for all shared views for a given table — same key for all users\n private sharedViewsKey(tableSlug: string): string {\n return `views:shared:${tableSlug}`;\n }\n\n // Returns configured TTL for named views in seconds, defaulting to 86400 (24h)\n private get viewsTtl(): number {\n return this.configService.get<number>('TABLE_VIEWS_CACHE_TTL') ?? 86400;\n }\n\n // Fetches personal views from cache; falls back to DB and warms cache on miss\n private async getOrCachePersonalViews(userId: string, tableSlug: string): Promise<DataTableViewRecord[]> {\n const key = this.personalViewsKey(userId, tableSlug);\n const cached = await this.cacheService.get<DataTableViewRecord[]>(key);\n if (cached) {\n this.logger.debug(`Cache hit for personal views: user=${userId}, table=${tableSlug}`);\n return cached;\n }\n const rows = await this.dataTableViewsRepository.findPersonalViewsBySlug(userId, tableSlug);\n await this.cacheService.set(key, rows, this.viewsTtl);\n return rows;\n }\n\n // Fetches shared views from cache; falls back to DB and warms cache on miss\n private async getOrCacheSharedViews(tableSlug: string): Promise<DataTableViewRecord[]> {\n const key = this.sharedViewsKey(tableSlug);\n const cached = await this.cacheService.get<DataTableViewRecord[]>(key);\n if (cached) {\n this.logger.debug(`Cache hit for shared views: table=${tableSlug}`);\n return cached;\n }\n const rows = await this.dataTableViewsRepository.findSharedViewsBySlug(tableSlug);\n await this.cacheService.set(key, rows, this.viewsTtl);\n return rows;\n }\n\n // Deletes personal and/or shared cache keys based on which pools the mutation affects\n private async invalidateViewsCache(\n userId: string,\n tableSlug: string,\n affectsPersonal: boolean,\n affectsShared: boolean,\n ): Promise<void> {\n const toDelete: string[] = [];\n if (affectsPersonal) toDelete.push(this.personalViewsKey(userId, tableSlug));\n if (affectsShared) toDelete.push(this.sharedViewsKey(tableSlug));\n if (toDelete.length > 0) await this.cacheService.del(...toDelete);\n }\n\n // Returns personal + shared named views — each pool fetched from cache or DB in parallel\n async findViews(userId: string, tableSlug: string): Promise<DataTableViewDto[]> {\n const [personalRows, sharedRows] = await Promise.all([\n this.getOrCachePersonalViews(userId, tableSlug),\n this.getOrCacheSharedViews(tableSlug),\n ]);\n return [...personalRows, ...sharedRows].map((row) => DataTableViewDto.from(row, userId));\n }\n\n // Creates a named snapshot and invalidates the relevant cache pool\n async createView(userId: string, dto: CreateDataTableViewDto): Promise<DataTableViewDto> {\n const view = await this.dataTableViewsRepository.create({\n userId,\n tableSlug: dto.tableSlug,\n name: dto.name,\n state: dto.state,\n isShared: dto.isShared ?? false,\n });\n this.logger.log(`Created view \"${dto.name}\" for user: ${userId}, table: ${dto.tableSlug}`);\n const isShared = dto.isShared ?? false;\n await this.invalidateViewsCache(userId, dto.tableSlug, !isShared, isShared);\n return DataTableViewDto.from(view, userId);\n }\n\n // Updates the state of a named view — skips DB write if state is unchanged\n async updateView(userId: string, id: string, dto: UpdateDataTableViewDto): Promise<DataTableViewDto> {\n const view = await this.dataTableViewsRepository.findById(id);\n if (!view) throw new NotFoundException('Table view not found.');\n if (view.userId !== userId) throw new BadRequestException('You do not have permission to update this view.');\n\n // Skip DB write if the state has not changed\n if (computeChecksum(dto.state) === computeChecksum(view.state)) {\n this.logger.log(`State unchanged for view ${id} — skipping DB write`);\n return DataTableViewDto.from(view, userId);\n }\n\n const updated = await this.dataTableViewsRepository.update(id, { state: dto.state });\n this.logger.log(`Updated state for view ${id}, user: ${userId}`);\n await this.invalidateViewsCache(userId, view.tableSlug, !view.isShared, view.isShared);\n return DataTableViewDto.from(updated, userId);\n }\n\n // Toggles the sharing status of a named view — updates both personal and shared cache\n async toggleShareView(userId: string, id: string, isShared: boolean): Promise<DataTableViewDto> {\n const view = await this.dataTableViewsRepository.findById(id);\n if (!view) throw new NotFoundException('Table view not found.');\n if (view.userId !== userId) throw new BadRequestException('You do not have permission to share this view.');\n\n const updated = await this.dataTableViewsRepository.update(id, { isShared });\n this.logger.log(`Set isShared=${isShared} for view ${id}, user: ${userId}`);\n // Invalidate both pools — the view moves from one to the other\n await this.invalidateViewsCache(userId, view.tableSlug, true, true);\n return DataTableViewDto.from(updated, userId);\n }\n\n // Renames a named view — enforces unique name per user+table, invalidates personal cache\n async renameView(userId: string, id: string, name: string): Promise<DataTableViewDto> {\n const view = await this.dataTableViewsRepository.findById(id);\n if (!view) throw new NotFoundException('Table view not found.');\n if (view.userId !== userId) throw new BadRequestException('You do not have permission to rename this view.');\n\n // Check for duplicate name within the same user+table\n const existing = await this.dataTableViewsRepository.findOne({\n userId,\n tableSlug: view.tableSlug,\n name,\n isShared: false,\n });\n if (existing && existing.id !== id) {\n throw new ConflictException({\n label: 'Name Already Taken',\n detail: 'A view with this name already exists for this table.',\n errors: [{ field: 'name', message: 'Name already taken' }],\n });\n }\n\n const updated = await this.dataTableViewsRepository.update(id, { name });\n this.logger.log(`Renamed view ${id} to \"${name}\" for user: ${userId}`);\n // Rename only affects personal views (shared views are owned by a user too, but visible to all)\n await this.invalidateViewsCache(userId, view.tableSlug, !view.isShared, view.isShared);\n return DataTableViewDto.from(updated, userId);\n }\n\n // Deletes a named view and invalidates the relevant cache pool\n async deleteView(userId: string, id: string): Promise<DataTableViewDto> {\n const view = await this.dataTableViewsRepository.findById(id);\n if (!view) throw new NotFoundException('Table view not found.');\n if (view.userId !== userId) throw new BadRequestException('You do not have permission to delete this view.');\n\n await this.dataTableViewsRepository.delete(id);\n this.logger.log(`Deleted view ${id} for user: ${userId}`);\n await this.invalidateViewsCache(userId, view.tableSlug, !view.isShared, view.isShared);\n return DataTableViewDto.from(view, userId);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class BadGatewayException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Bad Gateway', HttpStatus.BAD_GATEWAY);\n }\n}\n","import { HttpException, HttpStatus } from '@nestjs/common';\nimport type { FieldError } from '../types/error-response.types';\n\n// Re-export FieldError for backwards compatibility\nexport type { FieldError } from '../types/error-response.types';\n\nexport interface ProblemOptions {\n type?: string;\n label?: string;\n detail?: string;\n errors?: FieldError[];\n}\n\nexport abstract class HttpProblemException extends HttpException {\n constructor(detailOrOptions: string | ProblemOptions, httpStatus: HttpStatus) {\n const options = typeof detailOrOptions === 'string' ? { detail: detailOrOptions } : detailOrOptions;\n\n super(\n {\n type: options.type ?? 'about:blank',\n label: options.label,\n detail: options.detail,\n errors: options.errors ?? [],\n },\n httpStatus,\n );\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class BadRequestException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Bad Request', HttpStatus.BAD_REQUEST);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ConflictException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Conflict', HttpStatus.CONFLICT);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ForbiddenException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Forbidden', HttpStatus.FORBIDDEN);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class GoneException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Gone', HttpStatus.GONE);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class InternalServerErrorException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Internal Server Error', HttpStatus.INTERNAL_SERVER_ERROR);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class MethodNotAllowedException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Method Not Allowed', HttpStatus.METHOD_NOT_ALLOWED);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class NotAcceptableException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Not Acceptable', HttpStatus.NOT_ACCEPTABLE);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class NotFoundException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Not Found', HttpStatus.NOT_FOUND);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class NotImplementedException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Not Implemented', HttpStatus.NOT_IMPLEMENTED);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class PayloadTooLargeException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Payload Too Large', HttpStatus.PAYLOAD_TOO_LARGE);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class RequestTimeoutException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Request Timeout', HttpStatus.REQUEST_TIMEOUT);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ServiceUnavailableException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Service Unavailable', HttpStatus.SERVICE_UNAVAILABLE);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class TooManyRequestsException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Too Many Requests', HttpStatus.TOO_MANY_REQUESTS);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class UnauthorizedException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Unauthorized', HttpStatus.UNAUTHORIZED);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class UnprocessableEntityException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Unprocessable Entity', HttpStatus.UNPROCESSABLE_ENTITY);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class UnsupportedMediaTypeException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Unsupported Media Type', HttpStatus.UNSUPPORTED_MEDIA_TYPE);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ValidationException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Validation Failed', HttpStatus.UNPROCESSABLE_ENTITY);\n }\n}\n","import { Inject, Injectable } from '@nestjs/common';\nimport { and, eq } from 'drizzle-orm';\nimport type { PgTable } from 'drizzle-orm/pg-core';\nimport { PrimaryBaseRepository, PrimaryDatabaseService } from '@vritti/api-sdk/database';\nimport { DATA_TABLE_VIEWS_TABLE } from '../../data-table.constants';\nimport type { DataTableViewRecord, NewDataTableViewRecord } from '../../schema/data-table-views.table';\n\nconst NAMED_VIEWS_LIMIT = 100;\n\n@Injectable()\nexport class DataTableViewsRepository extends PrimaryBaseRepository<\n PgTable,\n NewDataTableViewRecord,\n DataTableViewRecord\n> {\n constructor(database: PrimaryDatabaseService, @Inject(DATA_TABLE_VIEWS_TABLE) table: PgTable) {\n super(database, table);\n }\n\n // Returns personal (non-shared) named views owned by the user for a given table\n async findPersonalViewsBySlug(userId: string, tableSlug: string): Promise<DataTableViewRecord[]> {\n // biome-ignore lint/suspicious/noExplicitAny: table columns are typed at runtime via the injected schema-qualified table\n const t = this.table as any;\n return this.db\n .select()\n .from(this.table)\n .where(and(eq(t.tableSlug, tableSlug), eq(t.userId, userId), eq(t.isShared, false)))\n .orderBy(t.createdAt)\n .limit(NAMED_VIEWS_LIMIT) as unknown as Promise<DataTableViewRecord[]>;\n }\n\n // Returns all shared named views for a given table — visible to all users\n async findSharedViewsBySlug(tableSlug: string): Promise<DataTableViewRecord[]> {\n // biome-ignore lint/suspicious/noExplicitAny: table columns are typed at runtime via the injected schema-qualified table\n const t = this.table as any;\n return this.db\n .select()\n .from(this.table)\n .where(and(eq(t.tableSlug, tableSlug), eq(t.isShared, true)))\n .orderBy(t.createdAt)\n .limit(NAMED_VIEWS_LIMIT) as unknown as Promise<DataTableViewRecord[]>;\n }\n}\n","// Re-export all of drizzle-orm/pg-core\nexport * from 'drizzle-orm/pg-core';\n\nimport { sql } from 'drizzle-orm';\nimport { type AnyPgColumn, check } from 'drizzle-orm/pg-core';\nimport { CODE_PATTERN_SOURCE, type CodeOptions, DOTTED_CODE_PATTERN_SOURCE } from './decorators/code-pattern';\n\n// Builds a Postgres CHECK constraint enforcing the canonical code format on a column\nexport function codeCheck(name: string, column: AnyPgColumn, options?: CodeOptions) {\n const source = options?.dotted ? DOTTED_CODE_PATTERN_SOURCE : CODE_PATTERN_SOURCE;\n return check(name, sql`${column} ~ ${sql.raw(`'${source}'`)}`);\n}\n","// Canonical entity \"code\" format — the single source of truth for DTOs, DB checks, and frontend forms.\n// A code is a single lowercase word of letters, digits, and hyphens, starting with a letter or digit.\n// Real-world codes lead with a digit often enough (pack sizes \"62g\", sizes \"5xl\") that requiring a\n// leading letter forced callers to mangle them.\n// The dotted variant allows dot-separated segments (e.g. permission codes like \"add.salt\").\n\nconst SEGMENT = '[a-z0-9][a-z0-9-]*';\n\nexport const CODE_PATTERN_SOURCE = `^${SEGMENT}$`;\nexport const DOTTED_CODE_PATTERN_SOURCE = `^${SEGMENT}(\\\\.${SEGMENT})*$`;\n\nexport const CODE_PATTERN = new RegExp(CODE_PATTERN_SOURCE);\nexport const DOTTED_CODE_PATTERN = new RegExp(DOTTED_CODE_PATTERN_SOURCE);\n\nexport interface CodeOptions {\n dotted?: boolean;\n}\n\n// Returns the regex for the requested code variant\nexport function codePattern(options?: CodeOptions): RegExp {\n return options?.dotted ? DOTTED_CODE_PATTERN : CODE_PATTERN;\n}\n\n// Returns the Postgres regex source string for the requested code variant (for CHECK constraints)\nexport function codePatternSource(options?: CodeOptions): string {\n return options?.dotted ? DOTTED_CODE_PATTERN_SOURCE : CODE_PATTERN_SOURCE;\n}\n\n// Human-readable validation message for the requested code variant\nexport function codeMessage(property: string, options?: CodeOptions): string {\n return options?.dotted\n ? `${property} must be lowercase words separated by dots.`\n : `${property} must be lowercase letters, numbers, and hyphens only.`;\n}\n","import type { TableViewState } from '../../database/filter/filter.types';\nimport { boolean, index, jsonb, timestamp, uniqueIndex, uuid, varchar } from '../../drizzle-pg-core';\n\n// Returns a fresh set of column builder instances — call once per table declaration\nexport function dataTableViewsColumns() {\n return {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull(),\n tableSlug: varchar('table_slug', { length: 200 }).notNull(),\n name: varchar('name', { length: 100 }).notNull(),\n state: jsonb('state').notNull().$type<TableViewState>(),\n isShared: boolean('is_shared').notNull().default(false),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).$onUpdate(() => new Date()),\n };\n}\n\n// Index definitions — reusable callback, works with any table that has the same column names\n// biome-ignore lint/suspicious/noExplicitAny: receives Drizzle-bound columns, not raw builders\nexport function dataTableViewsIndexes(table: any) {\n return [\n index('table_views_user_table_idx').on(table.userId, table.tableSlug),\n index('table_views_shared_slug_idx').on(table.tableSlug, table.isShared),\n uniqueIndex('table_views_user_table_name_shared_unique').on(\n table.userId,\n table.tableSlug,\n table.name,\n table.isShared,\n ),\n ];\n}\n\nexport interface DataTableViewRecord {\n id: string;\n userId: string;\n tableSlug: string;\n name: string;\n state: TableViewState;\n isShared: boolean;\n createdAt: Date;\n updatedAt: Date | null | undefined;\n}\n\nexport interface NewDataTableViewRecord {\n userId: string;\n tableSlug: string;\n name: string;\n state: TableViewState;\n isShared?: boolean;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA,SAA6BA,cAAc;AAC3C,SAASC,oBAAoB;AAC7B,SAASC,mBAAmB;;;ACFrB,IAAMC,yBAAyBC,uBAAO,wBAAA;;;ACA7C,SAASC,MAAMC,YAAYC,UAAUC,YAAYC,UAAAA,SAAQC,YAAY;AACrE,SAASC,eAAeC,eAAe;;;ACDvC,SAASC,4BAAmD;;;ACSrD,IAAMC,mBAAqC;EAChDC,YAAY,wBAACC,SAAwBA,KAAKC,cAA0B,CAAA,EAAGC,KAA3D;EACZC,aAAa,wBAACH,SAAwBA,KAAKC,cAA0B,CAAA,EAAGG,OAA3D;AACf;;;ACRO,IAAMC,gBAAkC;EAC7CC,YAAY,wBAACC,SAASA,KAAKC,aAAY,EAAGF,WAAU,GAAxC;EACZG,aAAa,wBAACF,SAASA,KAAKC,aAAY,EAAGC,YAAW,GAAzC;AACf;;;ACHA,IAAMC,WAAW,oBAAIC,IAAqC;EACxD;IAAC;IAAQC;;EACT;IAAC;IAAWC;;CACb;AAQM,SAASC,iBAAiBC,MAAY;AAC3C,SAAOC,SAASC,IAAIF,IAAAA,KAA0BG;AAChD;AAFgBJ;;;ACVT,SAASK,sBAAsBC,MAAmB;AACvD,SAAOC,iBAAiBD,KAAKE,QAAO,CAAA,EAAIC,WAAWH,IAAAA;AACrD;AAFgBD;;;AJIT,IAAMK,SAASC,qBAAqB,CAACC,OAAgBC,QAAAA;AAC1D,QAAMC,OAAOC,sBAAsBF,GAAAA,EAAKC;AAExC,MAAIA,MAAME,SAAS,WAAW;AAC5B,UAAM,IAAIC,MAAM,kCAAkCH,MAAME,QAAQ,MAAA,+BAAqC;EACvG;AAEA,SAAOF,KAAKI;AACd,CAAA;;;AKjBA,SAASC,uBAAuB;AAChC,SAASC,SAASC,cAAcC,mBAAmB;;;ACDnD,SAASC,aAAaC,2BAA2B;AACjD,SAASC,UAAUC,YAAYC,UAAUC,QAAQC,iBAAiB;;;;;;;;;;;;;;;;;;;;;AAG3D,IAAMC,0BAAN,MAAMA;SAAAA;;;EAIXC;EAIAC;EAKAC;AACF;;;IAbiBC,aAAa;IAAqCC,SAAS;;;;;;;;IAK3DD,aAAa;;;;;;;;;;;;;ADNvB,SAASE,0BAAAA;AACd,SAAOC,gBACLC,aAAa;IACXC,SAAS;IACTC,aACE;EACJ,CAAA,GACAC,QAAQ;IAAEC,MAAMC;EAAwB,CAAA,GACxCC,YAAY;IAAEC,QAAQ;IAAKL,aAAa;EAAqB,CAAA,GAC7DI,YAAY;IAAEC,QAAQ;IAAKL,aAAa;EAAwB,CAAA,GAChEI,YAAY;IAAEC,QAAQ;IAAKL,aAAa;EAAgB,CAAA,CAAA;AAE5D;AAZgBJ;;;AEJhB,SAASU,YAAYC,cAAc;AACnC,SAASC,qBAAqB;AAC9B,SAASC,oBAAoB;;;;;;;;;;;;;;;;;;;;;AAI7B,IAAMC,oBAAoC;EACxCC,SAAS,CAAA;EACTC,MAAM,CAAA;EACNC,kBAAkB,CAAC;EACnBC,aAAa,CAAA;EACbC,cAAc,CAAC;EACfC,eAAe;IAAEC,MAAM,CAAA;IAAIC,OAAO,CAAA;EAAG;EACrCC,oBAAoB;EACpBC,SAAS;EACTC,aAAa,CAAA;EACbC,kBAAkB,CAAC;EACnBC,QAAQ;EACRC,YAAY;IAAEC,OAAO;IAAIC,QAAQ;EAAE;AACrC;AAGO,IAAMC,wBAAN,MAAMA,uBAAAA;SAAAA;;;;;EACMC,SAAS,IAAIC,OAAOF,uBAAsBG,IAAI;EAE/D,YACmBC,cACAC,eACjB;SAFiBD,eAAAA;SACAC,gBAAAA;EAChB;;EAGH,IAAYC,WAAmB;AAC7B,WAAO,KAAKD,cAAcE,IAAY,uBAAA,KAA4B;EACpE;;EAGA,MAAMC,mBAAmBC,QAAgBC,KAA6C;AACpF,UAAMC,MAAM,MAAMF,MAAAA,IAAUC,IAAIE,SAAS;AACzC,UAAM,KAAKR,aAAaS,IAAIF,KAAK;MAAEG,OAAOJ,IAAII;MAAOC,cAAcL,IAAIK,gBAAgB;IAAK,GAAG,KAAKT,QAAQ;AAC5G,SAAKL,OAAOe,IAAI,+BAA+BP,MAAAA,YAAkBC,IAAIE,SAAS,EAAE;EAClF;;EAGA,MAAMK,gBACJR,QACAG,WACiE;AACjE,UAAMD,MAAM,MAAMF,MAAAA,IAAUG,SAAAA;AAC5B,UAAMM,SAAS,MAAM,KAAKd,aAAaG,IAA4DI,GAAAA;AACnG,WAAOO,UAAU;MAAEJ,OAAO/B;MAAmBgC,cAAc;IAAK;EAClE;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ARzCO,IAAMI,2BAAN,MAAMA,0BAAAA;SAAAA;;;;EACMC,SAAS,IAAIC,QAAOF,0BAAyBG,IAAI;EAElE,YAA6BC,uBAA8C;SAA9CA,wBAAAA;EAA+C;;EAM5EC,mBAA6BC,QAAwBC,KAA6C;AAChG,SAAKN,OAAOO,IAAI,8BAA8BF,MAAAA,YAAkBC,IAAIE,SAAS,EAAE;AAC/E,WAAO,KAAKL,sBAAsBC,mBAAmBC,QAAQC,GAAAA;EAC/D;AACF;;;sBANuBG,EAAAA;;;;;;;;;;;;;;;;;;;;;;ASjBvB,SAASC,QAAAA,OAAMC,cAAAA,aAAYC,QAAQC,KAAKC,YAAAA,WAAUC,cAAAA,cAAYC,UAAAA,SAAQC,OAAOC,OAAOC,QAAAA,OAAMC,aAAa;AACvG,SAASC,iBAAAA,gBAAeC,WAAAA,gBAAe;;;ACDvC,SAASC,mBAAAA,wBAAuB;AAChC,SAASC,WAAAA,UAASC,gBAAAA,eAAcC,UAAUC,UAAUC,eAAAA,oBAAmB;;;ACDvE,SAASC,eAAAA,cAAaC,uBAAAA,4BAA2B;;;;;;;;;;;;;;;;;;;;;AAI1C,IAAMC,mBAAN,MAAMA,kBAAAA;SAAAA;;;EAEXC;EAGAC;EAGAC;EAGAC;EAGAC;EAGAC;EAGAC;EAGAC;;EAGA,OAAOC,KAAKC,MAA2BC,QAAkC;AACvE,UAAMC,MAAM,IAAIZ,kBAAAA;AAChBY,QAAIX,KAAKS,KAAKT;AACdW,QAAIV,OAAOQ,KAAKR,QAAQ;AACxBU,QAAIT,YAAYO,KAAKP;AACrBS,QAAIR,QAAQM,KAAKN;AACjBQ,QAAIP,WAAWK,KAAKL;AACpBO,QAAIN,QAAQI,KAAKC,WAAWA;AAC5BC,QAAIL,YAAYG,KAAKH;AACrBK,QAAIJ,YAAYE,KAAKF,aAAa;AAClC,WAAOI;EACT;AACF;;;IArCiBC,aAAa;;;;;;IAGLA,aAAa;IAA4BC,UAAU;;;;;;IAG3DD,aAAa;IAA0CE,SAAS;;;;;;IAGhEF,aAAa;;;;;;IAGbA,aAAa;IAA4CE,SAAS;;;;;;IAGlEF,aAAa;IAA8CE,SAAS;;;;;;IAGpEF,aAAa;;;;;;IAGLA,aAAa;IAA0BC,UAAU;;;;;;AC1B1E,SAASE,eAAAA,cAAaC,uBAAAA,4BAA2B;AACjD,SAASC,WAAWC,YAAAA,WAAUC,cAAAA,aAAYC,YAAAA,WAAUC,aAAAA,kBAAiB;;;;;;;;;;;;;;;;;;;;;AAG9D,IAAMC,yBAAN,MAAMA;SAAAA;;;EAIXC;EAKAC;EAIAC;EAKAC;AACF;;;IAlBiBC,aAAa;IAAmCC,SAAS;;;;;;;;IAKzDD,aAAa;IAAqCC,SAAS;;;;;;;;IAK3DD,aAAa;;;;;;;IAILA,aAAa;IAA6CC,SAAS;;;;;;;;ACnB5F,SAASC,eAAAA,oBAAmB;AAC5B,SAASC,YAAAA,WAAUC,aAAAA,YAAWC,iBAAiB;;;;;;;;;;;;;;;;;;;;;AAExC,IAAMC,yBAAN,MAAMA;SAAAA;;;EAKXC;AACF;;;IALiBC,aAAa;IAAiCC,SAAS;;;;;;;;;ACJxE,SAASC,eAAAA,oBAAmB;AAC5B,SAASC,aAAAA,kBAAiB;;;;;;;;;;;;;;;;;;;;;AAEnB,IAAMC,8BAAN,MAAMA;SAAAA;;;EAGXC;AACF;;;IAHiBC,aAAa;IAAmDC,SAAS;;;;;;;ACJ1F,SAASC,eAAAA,oBAAmB;AAC5B,SAASC,YAAAA,iBAAgB;;;;;;;;;;;;;;;;;;;;;AAIlB,IAAMC,yBAAN,MAAMA;SAAAA;;;EAGXC;AACF;;;IAHiBC,aAAa;;;;;;;ALEvB,SAASC,wBAAAA;AACd,SAAOC,iBACLC,cAAa;IACXC,SAAS;IACTC,aAAa;EACf,CAAA,GACAC,SAAS;IACPC,MAAM;IACNF,aAAa;IACbG,SAAS;IACTC,UAAU;EACZ,CAAA,GACAC,aAAY;IAAEC,QAAQ;IAAKN,aAAa;IAA0BO,MAAM;MAACC;;EAAkB,CAAA,GAC3FH,aAAY;IAAEC,QAAQ;IAAKN,aAAa;EAAgB,CAAA,CAAA;AAE5D;AAfgBJ;AAiBT,SAASa,yBAAAA;AACd,SAAOZ,iBACLC,cAAa;IACXC,SAAS;IACTC,aAAa;EACf,CAAA,GACAU,SAAQ;IAAEH,MAAMI;EAAuB,CAAA,GACvCN,aAAY;IAAEC,QAAQ;IAAKN,aAAa;IAAuBO,MAAMC;EAAiB,CAAA,GACtFH,aAAY;IAAEC,QAAQ;IAAKN,aAAa;EAAwB,CAAA,GAChEK,aAAY;IAAEC,QAAQ;IAAKN,aAAa;EAAgB,CAAA,CAAA;AAE5D;AAXgBS;AAaT,SAASG,yBAAAA;AACd,SAAOf,iBACLC,cAAa;IACXC,SAAS;IACTC,aAAa;EACf,CAAA,GACAa,SAAS;IAAEX,MAAM;IAAMF,aAAa;EAAmC,CAAA,GACvEU,SAAQ;IAAEH,MAAMO;EAAuB,CAAA,GACvCT,aAAY;IAAEC,QAAQ;IAAKN,aAAa;IAAiBO,MAAMC;EAAiB,CAAA,GAChFH,aAAY;IAAEC,QAAQ;IAAKN,aAAa;EAA4C,CAAA,GACpFK,aAAY;IAAEC,QAAQ;IAAKN,aAAa;EAAgB,CAAA,GACxDK,aAAY;IAAEC,QAAQ;IAAKN,aAAa;EAAkB,CAAA,CAAA;AAE9D;AAbgBY;AAeT,SAASG,yBAAAA;AACd,SAAOlB,iBACLC,cAAa;IACXC,SAAS;IACTC,aACE;EACJ,CAAA,GACAa,SAAS;IAAEX,MAAM;IAAMF,aAAa;EAAmC,CAAA,GACvEU,SAAQ;IAAEH,MAAMS;EAAuB,CAAA,GACvCX,aAAY;IAAEC,QAAQ;IAAKN,aAAa;IAAiBO,MAAMC;EAAiB,CAAA,GAChFH,aAAY;IAAEC,QAAQ;IAAKN,aAAa;EAAuB,CAAA,GAC/DK,aAAY;IAAEC,QAAQ;IAAKN,aAAa;EAAgB,CAAA,GACxDK,aAAY;IAAEC,QAAQ;IAAKN,aAAa;EAAkB,CAAA,GAC1DK,aAAY;IAAEC,QAAQ;IAAKN,aAAa;EAAwC,CAAA,CAAA;AAEpF;AAfgBe;AAiBT,SAASE,8BAAAA;AACd,SAAOpB,iBACLC,cAAa;IACXC,SAAS;IACTC,aACE;EACJ,CAAA,GACAa,SAAS;IAAEX,MAAM;IAAMF,aAAa;EAAyB,CAAA,GAC7DU,SAAQ;IAAEH,MAAMW;EAA4B,CAAA,GAC5Cb,aAAY;IAAEC,QAAQ;IAAKN,aAAa;IAA2BO,MAAMC;EAAiB,CAAA,GAC1FH,aAAY;IAAEC,QAAQ;IAAKN,aAAa;EAAuB,CAAA,GAC/DK,aAAY;IAAEC,QAAQ;IAAKN,aAAa;EAAgB,CAAA,GACxDK,aAAY;IAAEC,QAAQ;IAAKN,aAAa;EAAkB,CAAA,CAAA;AAE9D;AAdgBiB;AAgBT,SAASE,yBAAAA;AACd,SAAOtB,iBACLC,cAAa;IACXC,SAAS;IACTC,aAAa;EACf,CAAA,GACAa,SAAS;IAAEX,MAAM;IAAMF,aAAa;EAAmC,CAAA,GACvEK,aAAY;IAAEC,QAAQ;IAAKN,aAAa;IAAiBO,MAAMC;EAAiB,CAAA,GAChFH,aAAY;IAAEC,QAAQ;IAAKN,aAAa;EAAuB,CAAA,GAC/DK,aAAY;IAAEC,QAAQ;IAAKN,aAAa;EAAgB,CAAA,GACxDK,aAAY;IAAEC,QAAQ;IAAKN,aAAa;EAAkB,CAAA,CAAA;AAE9D;AAZgBmB;;;AMtFhB,SAASC,kBAAkB;AAC3B,SAASC,cAAAA,aAAYC,UAAAA,eAAc;AACnC,SAASC,iBAAAA,sBAAqB;AAC9B,SAASC,gBAAAA,qBAAoB;;;ACH7B,SAASC,cAAAA,mBAAkB;;;ACA3B,SAASC,qBAAiC;AAanC,IAAeC,uBAAf,cAA4CC,cAAAA;EAbnD,OAamDA;;;EACjD,YAAYC,iBAA0CC,YAAwB;AAC5E,UAAMC,UAAU,OAAOF,oBAAoB,WAAW;MAAEG,QAAQH;IAAgB,IAAIA;AAEpF,UACE;MACEI,MAAMF,QAAQE,QAAQ;MACtBC,OAAOH,QAAQG;MACfF,QAAQD,QAAQC;MAChBG,QAAQJ,QAAQI,UAAU,CAAA;IAC5B,GACAL,UAAAA;EAEJ;AACF;;;AC3BA,SAASM,cAAAA,mBAAkB;AAGpB,IAAMC,sBAAN,cAAkCC,qBAAAA;EAHzC,OAGyCA;;;EACvC,YAAYC,iBAA2C;AACrD,UAAMA,mBAAmB,eAAeC,YAAWC,WAAW;EAChE;AACF;;;ACPA,SAASC,cAAAA,mBAAkB;AAGpB,IAAMC,oBAAN,cAAgCC,qBAAAA;EAHvC,OAGuCA;;;EACrC,YAAYC,iBAA2C;AACrD,UAAMA,mBAAmB,YAAYC,YAAWC,QAAQ;EAC1D;AACF;;;ACPA,SAASC,cAAAA,mBAAkB;;;ACA3B,SAASC,cAAAA,mBAAkB;;;ACA3B,SAASC,cAAAA,mBAAkB;;;ACA3B,SAASC,cAAAA,mBAAkB;;;ACA3B,SAASC,cAAAA,mBAAkB;;;ACA3B,SAASC,cAAAA,oBAAkB;AAGpB,IAAMC,oBAAN,cAAgCC,qBAAAA;EAHvC,OAGuCA;;;EACrC,YAAYC,iBAA2C;AACrD,UAAMA,mBAAmB,aAAaC,aAAWC,SAAS;EAC5D;AACF;;;ACPA,SAASC,cAAAA,oBAAkB;;;ACA3B,SAASC,cAAAA,oBAAkB;;;ACA3B,SAASC,cAAAA,oBAAkB;;;ACA3B,SAASC,cAAAA,oBAAkB;;;ACA3B,SAASC,cAAAA,oBAAkB;;;ACA3B,SAASC,cAAAA,oBAAkB;;;ACA3B,SAASC,cAAAA,oBAAkB;;;ACA3B,SAASC,cAAAA,oBAAkB;;;ACA3B,SAASC,cAAAA,oBAAkB;;;ACA3B,SAASC,QAAQC,cAAAA,mBAAkB;AACnC,SAASC,KAAKC,UAAU;AAExB,SAASC,uBAAuBC,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;AAI9D,IAAMC,oBAAoB;AAGnB,IAAMC,2BAAN,cAAuCC,sBAAAA;SAAAA;;;EAK5C,YAAYC,UAAkEC,OAAgB;AAC5F,UAAMD,UAAUC,KAAAA;EAClB;;EAGA,MAAMC,wBAAwBC,QAAgBC,WAAmD;AAE/F,UAAMC,IAAI,KAAKJ;AACf,WAAO,KAAKK,GACTC,OAAM,EACNC,KAAK,KAAKP,KAAK,EACfQ,MAAMC,IAAIC,GAAGN,EAAED,WAAWA,SAAAA,GAAYO,GAAGN,EAAEF,QAAQA,MAAAA,GAASQ,GAAGN,EAAEO,UAAU,KAAA,CAAA,CAAA,EAC3EC,QAAQR,EAAES,SAAS,EACnBC,MAAMlB,iBAAAA;EACX;;EAGA,MAAMmB,sBAAsBZ,WAAmD;AAE7E,UAAMC,IAAI,KAAKJ;AACf,WAAO,KAAKK,GACTC,OAAM,EACNC,KAAK,KAAKP,KAAK,EACfQ,MAAMC,IAAIC,GAAGN,EAAED,WAAWA,SAAAA,GAAYO,GAAGN,EAAEO,UAAU,IAAA,CAAA,CAAA,EACrDC,QAAQR,EAAES,SAAS,EACnBC,MAAMlB,iBAAAA;EACX;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ApB9BA,SAASoB,gBAAgBC,OAAc;AACrC,SAAOC,WAAW,QAAA,EAAUC,OAAOC,KAAKC,UAAUJ,KAAAA,CAAAA,EAAQK,OAAO,KAAA;AACnE;AAFSN;AAKF,IAAMO,wBAAN,MAAMA,uBAAAA;SAAAA;;;;;;EACMC,SAAS,IAAIC,QAAOF,uBAAsBG,IAAI;EAE/D,YACmBC,0BACAC,cACAC,eACjB;SAHiBF,2BAAAA;SACAC,eAAAA;SACAC,gBAAAA;EAChB;;EAGKC,iBAAiBC,QAAgBC,WAA2B;AAClE,WAAO,kBAAkBD,MAAAA,IAAUC,SAAAA;EACrC;;EAGQC,eAAeD,WAA2B;AAChD,WAAO,gBAAgBA,SAAAA;EACzB;;EAGA,IAAYE,WAAmB;AAC7B,WAAO,KAAKL,cAAcM,IAAY,uBAAA,KAA4B;EACpE;;EAGA,MAAcC,wBAAwBL,QAAgBC,WAAmD;AACvG,UAAMK,MAAM,KAAKP,iBAAiBC,QAAQC,SAAAA;AAC1C,UAAMM,SAAS,MAAM,KAAKV,aAAaO,IAA2BE,GAAAA;AAClE,QAAIC,QAAQ;AACV,WAAKd,OAAOe,MAAM,sCAAsCR,MAAAA,WAAiBC,SAAAA,EAAW;AACpF,aAAOM;IACT;AACA,UAAME,OAAO,MAAM,KAAKb,yBAAyBc,wBAAwBV,QAAQC,SAAAA;AACjF,UAAM,KAAKJ,aAAac,IAAIL,KAAKG,MAAM,KAAKN,QAAQ;AACpD,WAAOM;EACT;;EAGA,MAAcG,sBAAsBX,WAAmD;AACrF,UAAMK,MAAM,KAAKJ,eAAeD,SAAAA;AAChC,UAAMM,SAAS,MAAM,KAAKV,aAAaO,IAA2BE,GAAAA;AAClE,QAAIC,QAAQ;AACV,WAAKd,OAAOe,MAAM,qCAAqCP,SAAAA,EAAW;AAClE,aAAOM;IACT;AACA,UAAME,OAAO,MAAM,KAAKb,yBAAyBiB,sBAAsBZ,SAAAA;AACvE,UAAM,KAAKJ,aAAac,IAAIL,KAAKG,MAAM,KAAKN,QAAQ;AACpD,WAAOM;EACT;;EAGA,MAAcK,qBACZd,QACAC,WACAc,iBACAC,eACe;AACf,UAAMC,WAAqB,CAAA;AAC3B,QAAIF,gBAAiBE,UAASC,KAAK,KAAKnB,iBAAiBC,QAAQC,SAAAA,CAAAA;AACjE,QAAIe,cAAeC,UAASC,KAAK,KAAKhB,eAAeD,SAAAA,CAAAA;AACrD,QAAIgB,SAASE,SAAS,EAAG,OAAM,KAAKtB,aAAauB,IAAG,GAAIH,QAAAA;EAC1D;;EAGA,MAAMI,UAAUrB,QAAgBC,WAAgD;AAC9E,UAAM,CAACqB,cAAcC,UAAAA,IAAc,MAAMC,QAAQC,IAAI;MACnD,KAAKpB,wBAAwBL,QAAQC,SAAAA;MACrC,KAAKW,sBAAsBX,SAAAA;KAC5B;AACD,WAAO;SAAIqB;SAAiBC;MAAYG,IAAI,CAACC,QAAQC,iBAAiBC,KAAKF,KAAK3B,MAAAA,CAAAA;EAClF;;EAGA,MAAM8B,WAAW9B,QAAgB+B,KAAwD;AACvF,UAAMC,OAAO,MAAM,KAAKpC,yBAAyBqC,OAAO;MACtDjC;MACAC,WAAW8B,IAAI9B;MACfN,MAAMoC,IAAIpC;MACVuC,OAAOH,IAAIG;MACXC,UAAUJ,IAAII,YAAY;IAC5B,CAAA;AACA,SAAK1C,OAAO2C,IAAI,iBAAiBL,IAAIpC,IAAI,eAAeK,MAAAA,YAAkB+B,IAAI9B,SAAS,EAAE;AACzF,UAAMkC,WAAWJ,IAAII,YAAY;AACjC,UAAM,KAAKrB,qBAAqBd,QAAQ+B,IAAI9B,WAAW,CAACkC,UAAUA,QAAAA;AAClE,WAAOP,iBAAiBC,KAAKG,MAAMhC,MAAAA;EACrC;;EAGA,MAAMqC,WAAWrC,QAAgBsC,IAAYP,KAAwD;AACnG,UAAMC,OAAO,MAAM,KAAKpC,yBAAyB2C,SAASD,EAAAA;AAC1D,QAAI,CAACN,KAAM,OAAM,IAAIQ,kBAAkB,uBAAA;AACvC,QAAIR,KAAKhC,WAAWA,OAAQ,OAAM,IAAIyC,oBAAoB,iDAAA;AAG1D,QAAIxD,gBAAgB8C,IAAIG,KAAK,MAAMjD,gBAAgB+C,KAAKE,KAAK,GAAG;AAC9D,WAAKzC,OAAO2C,IAAI,4BAA4BE,EAAAA,2BAAwB;AACpE,aAAOV,iBAAiBC,KAAKG,MAAMhC,MAAAA;IACrC;AAEA,UAAM0C,UAAU,MAAM,KAAK9C,yBAAyBR,OAAOkD,IAAI;MAAEJ,OAAOH,IAAIG;IAAM,CAAA;AAClF,SAAKzC,OAAO2C,IAAI,0BAA0BE,EAAAA,WAAatC,MAAAA,EAAQ;AAC/D,UAAM,KAAKc,qBAAqBd,QAAQgC,KAAK/B,WAAW,CAAC+B,KAAKG,UAAUH,KAAKG,QAAQ;AACrF,WAAOP,iBAAiBC,KAAKa,SAAS1C,MAAAA;EACxC;;EAGA,MAAM2C,gBAAgB3C,QAAgBsC,IAAYH,UAA8C;AAC9F,UAAMH,OAAO,MAAM,KAAKpC,yBAAyB2C,SAASD,EAAAA;AAC1D,QAAI,CAACN,KAAM,OAAM,IAAIQ,kBAAkB,uBAAA;AACvC,QAAIR,KAAKhC,WAAWA,OAAQ,OAAM,IAAIyC,oBAAoB,gDAAA;AAE1D,UAAMC,UAAU,MAAM,KAAK9C,yBAAyBR,OAAOkD,IAAI;MAAEH;IAAS,CAAA;AAC1E,SAAK1C,OAAO2C,IAAI,gBAAgBD,QAAAA,aAAqBG,EAAAA,WAAatC,MAAAA,EAAQ;AAE1E,UAAM,KAAKc,qBAAqBd,QAAQgC,KAAK/B,WAAW,MAAM,IAAA;AAC9D,WAAO2B,iBAAiBC,KAAKa,SAAS1C,MAAAA;EACxC;;EAGA,MAAM4C,WAAW5C,QAAgBsC,IAAY3C,MAAyC;AACpF,UAAMqC,OAAO,MAAM,KAAKpC,yBAAyB2C,SAASD,EAAAA;AAC1D,QAAI,CAACN,KAAM,OAAM,IAAIQ,kBAAkB,uBAAA;AACvC,QAAIR,KAAKhC,WAAWA,OAAQ,OAAM,IAAIyC,oBAAoB,iDAAA;AAG1D,UAAMI,WAAW,MAAM,KAAKjD,yBAAyBkD,QAAQ;MAC3D9C;MACAC,WAAW+B,KAAK/B;MAChBN;MACAwC,UAAU;IACZ,CAAA;AACA,QAAIU,YAAYA,SAASP,OAAOA,IAAI;AAClC,YAAM,IAAIS,kBAAkB;QAC1BC,OAAO;QACPC,QAAQ;QACRC,QAAQ;UAAC;YAAEC,OAAO;YAAQC,SAAS;UAAqB;;MAC1D,CAAA;IACF;AAEA,UAAMV,UAAU,MAAM,KAAK9C,yBAAyBR,OAAOkD,IAAI;MAAE3C;IAAK,CAAA;AACtE,SAAKF,OAAO2C,IAAI,gBAAgBE,EAAAA,QAAU3C,IAAAA,eAAmBK,MAAAA,EAAQ;AAErE,UAAM,KAAKc,qBAAqBd,QAAQgC,KAAK/B,WAAW,CAAC+B,KAAKG,UAAUH,KAAKG,QAAQ;AACrF,WAAOP,iBAAiBC,KAAKa,SAAS1C,MAAAA;EACxC;;EAGA,MAAMqD,WAAWrD,QAAgBsC,IAAuC;AACtE,UAAMN,OAAO,MAAM,KAAKpC,yBAAyB2C,SAASD,EAAAA;AAC1D,QAAI,CAACN,KAAM,OAAM,IAAIQ,kBAAkB,uBAAA;AACvC,QAAIR,KAAKhC,WAAWA,OAAQ,OAAM,IAAIyC,oBAAoB,iDAAA;AAE1D,UAAM,KAAK7C,yBAAyB0D,OAAOhB,EAAAA;AAC3C,SAAK7C,OAAO2C,IAAI,gBAAgBE,EAAAA,cAAgBtC,MAAAA,EAAQ;AACxD,UAAM,KAAKc,qBAAqBd,QAAQgC,KAAK/B,WAAW,CAAC+B,KAAKG,UAAUH,KAAKG,QAAQ;AACrF,WAAOP,iBAAiBC,KAAKG,MAAMhC,MAAAA;EACrC;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;APzJO,IAAMuD,2BAAN,MAAMA,0BAAAA;SAAAA;;;;EACMC,SAAS,IAAIC,QAAOF,0BAAyBG,IAAI;EAElE,YAA6BC,uBAA8C;SAA9CA,wBAAAA;EAA+C;;EAK5EC,UAAoBC,QAAoCC,WAAgD;AACtG,SAAKN,OAAOO,IAAI,8BAA8BD,SAAAA,YAAqBD,MAAAA,EAAQ;AAC3E,WAAO,KAAKF,sBAAsBC,UAAUC,QAAQC,SAAAA;EACtD;;EAMAE,WAAqBH,QAAwBI,KAAwD;AACnG,SAAKT,OAAOO,IAAI,6BAA6BF,MAAAA,YAAkBI,IAAIH,SAAS,EAAE;AAC9E,WAAO,KAAKH,sBAAsBK,WAAWH,QAAQI,GAAAA;EACvD;;EAKAC,WACYL,QACGM,IACLF,KACmB;AAC3B,SAAKT,OAAOO,IAAI,sBAAsBI,EAAAA,YAAcN,MAAAA,EAAQ;AAC5D,WAAO,KAAKF,sBAAsBO,WAAWL,QAAQM,IAAIF,GAAAA;EAC3D;;EAKAG,WACYP,QACGM,IACLF,KACmB;AAC3B,SAAKT,OAAOO,IAAI,sBAAsBI,EAAAA,mBAAqBN,MAAAA,EAAQ;AACnE,WAAO,KAAKF,sBAAsBS,WAAWP,QAAQM,IAAIF,IAAIP,IAAI;EACnE;;EAKAW,gBACYR,QACGM,IACLF,KACmB;AAC3B,SAAKT,OAAOO,IAAI,sBAAsBI,EAAAA,kBAAoBN,MAAAA,EAAQ;AAClE,WAAO,KAAKF,sBAAsBU,gBAAgBR,QAAQM,IAAIF,IAAIK,QAAQ;EAC5E;;EAKAC,WAAqBV,QAA6BM,IAAuC;AACvF,SAAKX,OAAOO,IAAI,uBAAuBI,EAAAA,YAAcN,MAAAA,EAAQ;AAC7D,WAAO,KAAKF,sBAAsBY,WAAWV,QAAQM,EAAAA;EACvD;AACF;;;;;;;;;;;;;;;yBAlDuBK,OAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;A;;;;;;;;;;;;;;;;AXlBhB,IAAMC,kBAAN,MAAMA,iBAAAA;SAAAA;;;EACX,OAAOC,QAAQC,SAAgD;AAC7D,WAAO;MACLC,QAAQ;MACRC,QAAQJ;MACRK,SAAS;QAACC;QAAcC;;MACxBC,aAAa;QAACC;QAA0BC;;MACxCC,WAAW;QACT;UACEC,SAASC;UACTC,UAAUZ,QAAQa;QACpB;QACAC;QACAC;QACAC;;MAEFC,SAAS;QAACH;QAAuBE;;IACnC;EACF;AACF;;;;;;AuCrCA;;;;AACA;8BAAc;AAEd,SAASE,WAAW;AACpB,SAA2BC,aAAa;;;ACExC,IAAMC,UAAU;AAET,IAAMC,sBAAsB,IAAID,OAAAA;AAChC,IAAME,6BAA6B,IAAIF,OAAAA,OAAcA,OAAAA;AAErD,IAAMG,eAAe,IAAIC,OAAOH,mBAAAA;AAChC,IAAMI,sBAAsB,IAAID,OAAOF,0BAAAA;;;ADJvC,SAASI,UAAUC,MAAcC,QAAqBC,SAAqB;AAChF,QAAMC,SAASD,SAASE,SAASC,6BAA6BC;AAC9D,SAAOC,MAAMP,MAAMQ,MAAMP,MAAAA,MAAYO,IAAIC,IAAI,IAAIN,MAAAA,GAAS,CAAA,EAAG;AAC/D;AAHgBJ;;;AEJT,SAASW,wBAAAA;AACd,SAAO;IACLC,QAAIC,8BAAK,IAAA,EAAMC,WAAU,EAAGC,cAAa;IACzCC,YAAQH,8BAAK,SAAA,EAAWI,QAAO;IAC/BC,eAAWC,iCAAQ,cAAc;MAAEC,QAAQ;IAAI,CAAA,EAAGH,QAAO;IACzDI,UAAMF,iCAAQ,QAAQ;MAAEC,QAAQ;IAAI,CAAA,EAAGH,QAAO;IAC9CK,WAAOC,+BAAM,OAAA,EAASN,QAAO,EAAGO,MAAK;IACrCC,cAAUC,iCAAQ,WAAA,EAAaT,QAAO,EAAGU,QAAQ,KAAA;IACjDC,eAAWC,mCAAU,cAAc;MAAEC,cAAc;IAAK,CAAA,EAAGb,QAAO,EAAGc,WAAU;IAC/EC,eAAWH,mCAAU,cAAc;MAAEC,cAAc;IAAK,CAAA,EAAGG,UAAU,MAAM,oBAAIC,KAAAA,CAAAA;EACjF;AACF;AAXgBvB;AAeT,SAASwB,sBAAsBC,OAAU;AAC9C,SAAO;QACLC,+BAAM,4BAAA,EAA8BC,GAAGF,MAAMpB,QAAQoB,MAAMlB,SAAS;QACpEmB,+BAAM,6BAAA,EAA+BC,GAAGF,MAAMlB,WAAWkB,MAAMX,QAAQ;QACvEc,qCAAY,2CAAA,EAA6CD,GACvDF,MAAMpB,QACNoB,MAAMlB,WACNkB,MAAMf,MACNe,MAAMX,QAAQ;;AAGpB;AAXgBU;","names":["Module","ConfigModule","CacheModule","DATA_TABLE_VIEWS_TABLE","Symbol","Body","Controller","HttpCode","HttpStatus","Logger","Post","ApiBearerAuth","ApiTags","createParamDecorator","graphqlExtractor","getRequest","host","getArgByIndex","req","getResponse","reply","httpExtractor","getRequest","host","switchToHttp","getResponse","registry","Map","httpExtractor","graphqlExtractor","resolveExtractor","type","registry","get","httpExtractor","getRequestFromContext","host","resolveExtractor","getType","getRequest","UserId","createParamDecorator","_data","ctx","auth","getRequestFromContext","kind","Error","userId","applyDecorators","ApiBody","ApiOperation","ApiResponse","ApiProperty","ApiPropertyOptional","IsObject","IsOptional","IsString","IsUUID","MaxLength","UpsertDataTableStateDto","tableSlug","state","activeViewId","description","example","ApiUpsertDataTableState","applyDecorators","ApiOperation","summary","description","ApiBody","type","UpsertDataTableStateDto","ApiResponse","status","Injectable","Logger","ConfigService","CacheService","EMPTY_TABLE_STATE","filters","sort","columnVisibility","columnOrder","columnSizing","columnPinning","left","right","lockedColumnSizing","density","filterOrder","filterVisibility","search","pagination","limit","offset","DataTableStateService","logger","Logger","name","cacheService","configService","stateTtl","get","upsertCurrentState","userId","dto","key","tableSlug","set","state","activeViewId","log","getCurrentState","cached","DataTableStateController","logger","Logger","name","dataTableStateService","upsertCurrentState","userId","dto","log","tableSlug","OK","Body","Controller","Delete","Get","HttpCode","HttpStatus","Logger","Param","Patch","Post","Query","ApiBearerAuth","ApiTags","applyDecorators","ApiBody","ApiOperation","ApiParam","ApiQuery","ApiResponse","ApiProperty","ApiPropertyOptional","DataTableViewDto","id","name","tableSlug","state","isShared","isOwn","createdAt","updatedAt","from","view","userId","dto","description","nullable","example","ApiProperty","ApiPropertyOptional","IsBoolean","IsObject","IsOptional","IsString","MaxLength","CreateDataTableViewDto","name","tableSlug","state","isShared","description","example","ApiProperty","IsString","MaxLength","MinLength","RenameDataTableViewDto","name","description","example","ApiProperty","IsBoolean","ToggleShareDataTableViewDto","isShared","description","example","ApiProperty","IsObject","UpdateDataTableViewDto","state","description","ApiListDataTableViews","applyDecorators","ApiOperation","summary","description","ApiQuery","name","example","required","ApiResponse","status","type","DataTableViewDto","ApiCreateDataTableView","ApiBody","CreateDataTableViewDto","ApiUpdateDataTableView","ApiParam","UpdateDataTableViewDto","ApiRenameDataTableView","RenameDataTableViewDto","ApiToggleShareDataTableView","ToggleShareDataTableViewDto","ApiDeleteDataTableView","createHash","Injectable","Logger","ConfigService","CacheService","HttpStatus","HttpException","HttpProblemException","HttpException","detailOrOptions","httpStatus","options","detail","type","label","errors","HttpStatus","BadRequestException","HttpProblemException","detailOrOptions","HttpStatus","BAD_REQUEST","HttpStatus","ConflictException","HttpProblemException","detailOrOptions","HttpStatus","CONFLICT","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","NotFoundException","HttpProblemException","detailOrOptions","HttpStatus","NOT_FOUND","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","Inject","Injectable","and","eq","PrimaryBaseRepository","PrimaryDatabaseService","NAMED_VIEWS_LIMIT","DataTableViewsRepository","PrimaryBaseRepository","database","table","findPersonalViewsBySlug","userId","tableSlug","t","db","select","from","where","and","eq","isShared","orderBy","createdAt","limit","findSharedViewsBySlug","computeChecksum","value","createHash","update","JSON","stringify","digest","DataTableViewsService","logger","Logger","name","dataTableViewsRepository","cacheService","configService","personalViewsKey","userId","tableSlug","sharedViewsKey","viewsTtl","get","getOrCachePersonalViews","key","cached","debug","rows","findPersonalViewsBySlug","set","getOrCacheSharedViews","findSharedViewsBySlug","invalidateViewsCache","affectsPersonal","affectsShared","toDelete","push","length","del","findViews","personalRows","sharedRows","Promise","all","map","row","DataTableViewDto","from","createView","dto","view","create","state","isShared","log","updateView","id","findById","NotFoundException","BadRequestException","updated","toggleShareView","renameView","existing","findOne","ConflictException","label","detail","errors","field","message","deleteView","delete","DataTableViewsController","logger","Logger","name","dataTableViewsService","findViews","userId","tableSlug","log","createView","dto","updateView","id","renameView","toggleShareView","isShared","deleteView","CREATED","DataTableModule","forRoot","options","global","module","imports","ConfigModule","CacheModule","controllers","DataTableStateController","DataTableViewsController","providers","provide","DATA_TABLE_VIEWS_TABLE","useValue","tableViews","DataTableViewsService","DataTableViewsRepository","DataTableStateService","exports","sql","check","SEGMENT","CODE_PATTERN_SOURCE","DOTTED_CODE_PATTERN_SOURCE","CODE_PATTERN","RegExp","DOTTED_CODE_PATTERN","codeCheck","name","column","options","source","dotted","DOTTED_CODE_PATTERN_SOURCE","CODE_PATTERN_SOURCE","check","sql","raw","dataTableViewsColumns","id","uuid","primaryKey","defaultRandom","userId","notNull","tableSlug","varchar","length","name","state","jsonb","$type","isShared","boolean","default","createdAt","timestamp","withTimezone","defaultNow","updatedAt","$onUpdate","Date","dataTableViewsIndexes","table","index","on","uniqueIndex"]}
|
|
1
|
+
{"version":3,"sources":["../src/data-table/data-table.module.ts","../src/data-table/data-table.constants.ts","../src/data-table/state/controllers/data-table-state.controller.ts","../src/auth/decorators/user-id.decorator.ts","../src/context/extractors/graphql.extractor.ts","../src/context/extractors/http.extractor.ts","../src/context/context.registry.ts","../src/context/get-request.ts","../src/data-table/state/docs/data-table-state.docs.ts","../src/data-table/state/dto/request/upsert-data-table-state.dto.ts","../src/data-table/state/services/data-table-state.service.ts","../src/data-table/views/controllers/data-table-views.controller.ts","../src/data-table/views/docs/data-table-views.docs.ts","../src/data-table/views/dto/entity/data-table-view.dto.ts","../src/data-table/views/dto/request/create-data-table-view.dto.ts","../src/data-table/views/dto/request/rename-data-table-view.dto.ts","../src/data-table/views/dto/request/toggle-share-data-table-view.dto.ts","../src/data-table/views/dto/request/update-data-table-view.dto.ts","../src/data-table/views/services/data-table-views.service.ts","../src/exceptions/bad-gateway.exception.ts","../src/exceptions/base-field.exception.ts","../src/exceptions/bad-request.exception.ts","../src/exceptions/conflict.exception.ts","../src/exceptions/forbidden.exception.ts","../src/exceptions/gone.exception.ts","../src/exceptions/internal-server-error.exception.ts","../src/exceptions/method-not-allowed.exception.ts","../src/exceptions/not-acceptable.exception.ts","../src/exceptions/not-found.exception.ts","../src/exceptions/not-implemented.exception.ts","../src/exceptions/payload-too-large.exception.ts","../src/exceptions/request-timeout.exception.ts","../src/exceptions/service-unavailable.exception.ts","../src/exceptions/too-many-requests.exception.ts","../src/exceptions/unauthorized.exception.ts","../src/exceptions/unprocessable-entity.exception.ts","../src/exceptions/unsupported-media-type.exception.ts","../src/exceptions/validation.exception.ts","../src/data-table/views/repositories/data-table-views.repository.ts","../src/drizzle-pg-core.ts","../src/decorators/code-pattern.ts","../src/data-table/schema/data-table-views.table.ts"],"sourcesContent":["import { type DynamicModule, Module } from '@nestjs/common';\nimport { ConfigModule } from '@nestjs/config';\nimport { CacheModule } from '@vritti/api-sdk/cache';\nimport type { PgTable } from 'drizzle-orm/pg-core';\nimport { DATA_TABLE_VIEWS_TABLE } from './data-table.constants';\nimport { DataTableStateController } from './state/controllers/data-table-state.controller';\nimport { DataTableStateService } from './state/services/data-table-state.service';\nimport { DataTableViewsController } from './views/controllers/data-table-views.controller';\nimport { DataTableViewsRepository } from './views/repositories/data-table-views.repository';\nimport { DataTableViewsService } from './views/services/data-table-views.service';\n\nexport { DATA_TABLE_VIEWS_TABLE };\n\nexport interface DataTableModuleOptions {\n tableViews: PgTable;\n}\n\n@Module({})\nexport class DataTableModule {\n static forRoot(options: DataTableModuleOptions): DynamicModule {\n return {\n global: true,\n module: DataTableModule,\n imports: [ConfigModule, CacheModule],\n controllers: [DataTableStateController, DataTableViewsController],\n providers: [\n {\n provide: DATA_TABLE_VIEWS_TABLE,\n useValue: options.tableViews,\n },\n DataTableViewsService,\n DataTableViewsRepository,\n DataTableStateService,\n ],\n exports: [DataTableViewsService, DataTableStateService],\n };\n }\n}\n","export const DATA_TABLE_VIEWS_TABLE = Symbol('DATA_TABLE_VIEWS_TABLE');\n","import { Body, Controller, HttpCode, HttpStatus, Logger, Post } from '@nestjs/common';\nimport { ApiBearerAuth, ApiTags } from '@nestjs/swagger';\nimport { UserId } from '../../../auth/decorators/user-id.decorator';\nimport { ApiUpsertDataTableState } from '../docs/data-table-state.docs';\nimport { UpsertDataTableStateDto } from '../dto/request/upsert-data-table-state.dto';\nimport { DataTableStateService } from '../services/data-table-state.service';\n\n@ApiTags('Table States')\n@ApiBearerAuth()\n@Controller('table-states')\nexport class DataTableStateController {\n private readonly logger = new Logger(DataTableStateController.name);\n\n constructor(private readonly dataTableStateService: DataTableStateService) {}\n\n // Saves live table state to Redis cache for the authenticated user's table\n @Post()\n @HttpCode(HttpStatus.OK)\n @ApiUpsertDataTableState()\n upsertCurrentState(@UserId() userId: string, @Body() dto: UpsertDataTableStateDto): Promise<void> {\n this.logger.log(`POST /table-states - User: ${userId}, table: ${dto.tableSlug}`);\n return this.dataTableStateService.upsertCurrentState(userId, dto);\n }\n}\n","import { createParamDecorator, type ExecutionContext } from '@nestjs/common';\nimport { getRequestFromContext } from '../../context';\nimport '../../types/fastify-augmentation';\n\n// Extracts userId from request.auth (set by VrittiAuthGuard).\n//\n// A session has one, and so does an OAuth bearer token once the server has resolved whom it was granted to.\n// An app request acts for a credential and a cloud request for the control plane, so asking for a user on\n// either is a mistake at the call site — it throws rather than returning a stand-in that would be recorded\n// as if a person had acted.\nexport const UserId = createParamDecorator((_data: unknown, ctx: ExecutionContext): string => {\n const auth = getRequestFromContext(ctx).auth;\n\n if (auth?.kind === 'session') return auth.userId;\n if (auth?.kind === 'oauth' && auth.userId) return auth.userId;\n\n throw new Error(\n `No user on this request (auth: ${auth?.kind ?? 'none'}). @UserId() needs a session or an OAuth bearer.`,\n );\n});\n","import type { ArgumentsHost } from '@nestjs/common';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\nimport type { RequestExtractor } from '../context.types';\n\ninterface GqlContext {\n req: FastifyRequest;\n reply?: FastifyReply;\n}\n\nexport const graphqlExtractor: RequestExtractor = {\n getRequest: (host: ArgumentsHost) => host.getArgByIndex<GqlContext>(2).req,\n getResponse: (host: ArgumentsHost) => host.getArgByIndex<GqlContext>(2).reply as FastifyReply,\n};\n","import type { FastifyReply, FastifyRequest } from 'fastify';\nimport type { RequestExtractor } from '../context.types';\n\n// Default transport: standard HTTP via the Fastify adapter.\nexport const httpExtractor: RequestExtractor = {\n getRequest: (host) => host.switchToHttp().getRequest<FastifyRequest>(),\n getResponse: (host) => host.switchToHttp().getResponse<FastifyReply>(),\n};\n","import type { RequestExtractor, TransportType } from './context.types';\nimport { graphqlExtractor } from './extractors/graphql.extractor';\nimport { httpExtractor } from './extractors/http.extractor';\n\nconst registry = new Map<TransportType, RequestExtractor>([\n ['http', httpExtractor],\n ['graphql', graphqlExtractor],\n]);\n\n// Registers (or overrides) the extractor for a transport type without modifying the SDK\nexport function registerTransport(type: TransportType, extractor: RequestExtractor): void {\n registry.set(type, extractor);\n}\n\n// Resolves the extractor for the host's reported transport, falling back to HTTP.\nexport function resolveExtractor(type: string): RequestExtractor {\n return registry.get(type as TransportType) ?? httpExtractor;\n}\n","import type { ArgumentsHost } from '@nestjs/common';\nimport type { FastifyRequest } from 'fastify';\nimport { resolveExtractor } from './context.registry';\n\n// Returns the underlying Fastify request for any registered transport, via the transport registry.\nexport function getRequestFromContext(host: ArgumentsHost): FastifyRequest {\n return resolveExtractor(host.getType()).getRequest(host);\n}\n","import { applyDecorators } from '@nestjs/common';\nimport { ApiBody, ApiOperation, ApiResponse } from '@nestjs/swagger';\nimport { UpsertDataTableStateDto } from '../dto/request/upsert-data-table-state.dto';\n\nexport function ApiUpsertDataTableState() {\n return applyDecorators(\n ApiOperation({\n summary: 'Save live table state',\n description:\n 'Stores the current filter, sort, and column visibility state in Redis cache. Called on filter Apply and sort column click. State expires after TABLE_STATE_CACHE_TTL seconds.',\n }),\n ApiBody({ type: UpsertDataTableStateDto }),\n ApiResponse({ status: 200, description: 'Live state cached.' }),\n ApiResponse({ status: 400, description: 'Invalid request body.' }),\n ApiResponse({ status: 401, description: 'Unauthorized.' }),\n );\n}\n","import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';\nimport { IsObject, IsOptional, IsString, IsUUID, MaxLength } from 'class-validator';\nimport type { TableViewState } from '../../../../database/filter/filter.types';\n\nexport class UpsertDataTableStateDto {\n @ApiProperty({ description: 'Unique slug identifying the table', example: 'cloud-providers' })\n @IsString()\n @MaxLength(200)\n tableSlug: string;\n\n @ApiProperty({ description: 'Full table view state including filters, sort, and column visibility' })\n @IsObject()\n state: TableViewState;\n\n @ApiPropertyOptional()\n @IsOptional()\n @IsUUID()\n activeViewId?: string | null;\n}\n","import { Injectable, Logger } from '@nestjs/common';\nimport { ConfigService } from '@nestjs/config';\nimport { CacheService } from '@vritti/api-sdk/cache';\nimport type { TableViewState } from '../../../database/filter/filter.types';\nimport type { UpsertDataTableStateDto } from '../dto/request/upsert-data-table-state.dto';\n\nconst EMPTY_TABLE_STATE: TableViewState = {\n filters: [],\n sort: [],\n columnVisibility: {},\n columnOrder: [],\n columnSizing: {},\n columnPinning: { left: [], right: [] },\n lockedColumnSizing: false,\n density: 'normal',\n filterOrder: [],\n filterVisibility: {},\n search: null,\n pagination: { limit: 20, offset: 0 },\n};\n\n@Injectable()\nexport class DataTableStateService {\n private readonly logger = new Logger(DataTableStateService.name);\n\n constructor(\n private readonly cacheService: CacheService,\n private readonly configService: ConfigService,\n ) {}\n\n // Returns configured TTL for live table state in seconds, defaulting to 3600 (1h)\n private get stateTtl(): number {\n return this.configService.get<number>('TABLE_STATE_CACHE_TTL') ?? 3600;\n }\n\n // Saves live table state and active view ID to Redis; DB is not written\n async upsertCurrentState(userId: string, dto: UpsertDataTableStateDto): Promise<void> {\n const key = `dt:${userId}:${dto.tableSlug}`;\n await this.cacheService.set(key, { state: dto.state, activeViewId: dto.activeViewId ?? null }, this.stateTtl);\n this.logger.log(`Cached live state for user: ${userId}, table: ${dto.tableSlug}`);\n }\n\n // Returns live table state and active view ID from Redis; returns empty state on miss — no DB query\n async getCurrentState(\n userId: string,\n tableSlug: string,\n ): Promise<{ state: TableViewState; activeViewId: string | null }> {\n const key = `dt:${userId}:${tableSlug}`;\n const cached = await this.cacheService.get<{ state: TableViewState; activeViewId: string | null }>(key);\n return cached ?? { state: EMPTY_TABLE_STATE, activeViewId: null };\n }\n}\n","import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Logger, Param, Patch, Post, Query } from '@nestjs/common';\nimport { ApiBearerAuth, ApiTags } from '@nestjs/swagger';\nimport { UserId } from '../../../auth/decorators/user-id.decorator';\nimport {\n ApiCreateDataTableView,\n ApiDeleteDataTableView,\n ApiListDataTableViews,\n ApiRenameDataTableView,\n ApiToggleShareDataTableView,\n ApiUpdateDataTableView,\n} from '../docs/data-table-views.docs';\nimport { DataTableViewDto } from '../dto/entity/data-table-view.dto';\nimport { CreateDataTableViewDto } from '../dto/request/create-data-table-view.dto';\nimport { RenameDataTableViewDto } from '../dto/request/rename-data-table-view.dto';\nimport { ToggleShareDataTableViewDto } from '../dto/request/toggle-share-data-table-view.dto';\nimport { UpdateDataTableViewDto } from '../dto/request/update-data-table-view.dto';\nimport { DataTableViewsService } from '../services/data-table-views.service';\n\n@ApiTags('Table Views')\n@ApiBearerAuth()\n@Controller('table-views')\nexport class DataTableViewsController {\n private readonly logger = new Logger(DataTableViewsController.name);\n\n constructor(private readonly dataTableViewsService: DataTableViewsService) {}\n\n // Returns all named views for the given table — own plus shared\n @Get()\n @ApiListDataTableViews()\n findViews(@UserId() userId: string, @Query('tableSlug') tableSlug: string): Promise<DataTableViewDto[]> {\n this.logger.log(`GET /table-views?tableSlug=${tableSlug} - User: ${userId}`);\n return this.dataTableViewsService.findViews(userId, tableSlug);\n }\n\n // Creates a named snapshot of the current table state\n @Post()\n @HttpCode(HttpStatus.CREATED)\n @ApiCreateDataTableView()\n createView(@UserId() userId: string, @Body() dto: CreateDataTableViewDto): Promise<DataTableViewDto> {\n this.logger.log(`POST /table-views - User: ${userId}, table: ${dto.tableSlug}`);\n return this.dataTableViewsService.createView(userId, dto);\n }\n\n // Updates state of an existing named view\n @Patch(':id')\n @ApiUpdateDataTableView()\n updateView(\n @UserId() userId: string,\n @Param('id') id: string,\n @Body() dto: UpdateDataTableViewDto,\n ): Promise<DataTableViewDto> {\n this.logger.log(`PATCH /table-views/${id} - User: ${userId}`);\n return this.dataTableViewsService.updateView(userId, id, dto);\n }\n\n // Renames an existing named view — enforces unique name per user+table\n @Patch(':id/rename')\n @ApiRenameDataTableView()\n renameView(\n @UserId() userId: string,\n @Param('id') id: string,\n @Body() dto: RenameDataTableViewDto,\n ): Promise<DataTableViewDto> {\n this.logger.log(`PATCH /table-views/${id}/rename - User: ${userId}`);\n return this.dataTableViewsService.renameView(userId, id, dto.name);\n }\n\n // Toggles sharing visibility of a named view\n @Patch(':id/share')\n @ApiToggleShareDataTableView()\n toggleShareView(\n @UserId() userId: string,\n @Param('id') id: string,\n @Body() dto: ToggleShareDataTableViewDto,\n ): Promise<DataTableViewDto> {\n this.logger.log(`PATCH /table-views/${id}/share - User: ${userId}`);\n return this.dataTableViewsService.toggleShareView(userId, id, dto.isShared);\n }\n\n // Deletes a named view owned by the authenticated user\n @Delete(':id')\n @ApiDeleteDataTableView()\n deleteView(@UserId() userId: string, @Param('id') id: string): Promise<DataTableViewDto> {\n this.logger.log(`DELETE /table-views/${id} - User: ${userId}`);\n return this.dataTableViewsService.deleteView(userId, id);\n }\n}\n","import { applyDecorators } from '@nestjs/common';\nimport { ApiBody, ApiOperation, ApiParam, ApiQuery, ApiResponse } from '@nestjs/swagger';\nimport { DataTableViewDto } from '../dto/entity/data-table-view.dto';\nimport { CreateDataTableViewDto } from '../dto/request/create-data-table-view.dto';\nimport { RenameDataTableViewDto } from '../dto/request/rename-data-table-view.dto';\nimport { ToggleShareDataTableViewDto } from '../dto/request/toggle-share-data-table-view.dto';\nimport { UpdateDataTableViewDto } from '../dto/request/update-data-table-view.dto';\n\nexport function ApiListDataTableViews() {\n return applyDecorators(\n ApiOperation({\n summary: 'List named table views',\n description: \"Returns the authenticated user's own named views plus all shared views for the given table slug.\",\n }),\n ApiQuery({\n name: 'tableSlug',\n description: 'Slug of the table to fetch views for',\n example: 'cloud-providers',\n required: true,\n }),\n ApiResponse({ status: 200, description: 'Named views retrieved.', type: [DataTableViewDto] }),\n ApiResponse({ status: 401, description: 'Unauthorized.' }),\n );\n}\n\nexport function ApiCreateDataTableView() {\n return applyDecorators(\n ApiOperation({\n summary: 'Create named table view',\n description: 'Saves the current table state as a named view snapshot. The name must be unique per user+table.',\n }),\n ApiBody({ type: CreateDataTableViewDto }),\n ApiResponse({ status: 201, description: 'Named view created.', type: DataTableViewDto }),\n ApiResponse({ status: 400, description: 'Invalid request body.' }),\n ApiResponse({ status: 401, description: 'Unauthorized.' }),\n );\n}\n\nexport function ApiUpdateDataTableView() {\n return applyDecorators(\n ApiOperation({\n summary: 'Update named table view',\n description: 'Updates the state of an existing named view. Only the owner can update.',\n }),\n ApiParam({ name: 'id', description: 'UUID of the table view to update' }),\n ApiBody({ type: UpdateDataTableViewDto }),\n ApiResponse({ status: 200, description: 'View updated.', type: DataTableViewDto }),\n ApiResponse({ status: 400, description: 'Validation failed or not owned by caller.' }),\n ApiResponse({ status: 401, description: 'Unauthorized.' }),\n ApiResponse({ status: 404, description: 'View not found.' }),\n );\n}\n\nexport function ApiRenameDataTableView() {\n return applyDecorators(\n ApiOperation({\n summary: 'Rename a named table view',\n description:\n 'Updates the display name of an existing view. The new name must be unique per user+table. Only the owner can rename.',\n }),\n ApiParam({ name: 'id', description: 'UUID of the table view to rename' }),\n ApiBody({ type: RenameDataTableViewDto }),\n ApiResponse({ status: 200, description: 'View renamed.', type: DataTableViewDto }),\n ApiResponse({ status: 400, description: 'Not owned by caller.' }),\n ApiResponse({ status: 401, description: 'Unauthorized.' }),\n ApiResponse({ status: 404, description: 'View not found.' }),\n ApiResponse({ status: 409, description: 'A view with this name already exists.' }),\n );\n}\n\nexport function ApiToggleShareDataTableView() {\n return applyDecorators(\n ApiOperation({\n summary: 'Toggle view sharing',\n description:\n 'Makes a view visible to all users (shared) or restricts it to the owner only (private). Only the owner can toggle sharing.',\n }),\n ApiParam({ name: 'id', description: 'UUID of the table view' }),\n ApiBody({ type: ToggleShareDataTableViewDto }),\n ApiResponse({ status: 200, description: 'Sharing status updated.', type: DataTableViewDto }),\n ApiResponse({ status: 400, description: 'Not owned by caller.' }),\n ApiResponse({ status: 401, description: 'Unauthorized.' }),\n ApiResponse({ status: 404, description: 'View not found.' }),\n );\n}\n\nexport function ApiDeleteDataTableView() {\n return applyDecorators(\n ApiOperation({\n summary: 'Delete named table view',\n description: 'Permanently deletes a named view. Only the owner can delete their own views.',\n }),\n ApiParam({ name: 'id', description: 'UUID of the table view to delete' }),\n ApiResponse({ status: 200, description: 'View deleted.', type: DataTableViewDto }),\n ApiResponse({ status: 400, description: 'Not owned by caller.' }),\n ApiResponse({ status: 401, description: 'Unauthorized.' }),\n ApiResponse({ status: 404, description: 'View not found.' }),\n );\n}\n","import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';\nimport type { TableViewState } from '../../../../database/filter/filter.types';\nimport type { DataTableViewRecord } from '../../../schema/data-table-views.table';\n\nexport class DataTableViewDto {\n @ApiProperty({ description: 'View unique identifier' })\n id: string;\n\n @ApiPropertyOptional({ description: 'Display name of the view', nullable: true })\n name: string | null;\n\n @ApiProperty({ description: 'Slug of the table this view belongs to', example: 'cloud-providers' })\n tableSlug: string;\n\n @ApiProperty({ description: 'Stored filter, sort, and column visibility state' })\n state: TableViewState;\n\n @ApiProperty({ description: 'Whether the view is visible to all users', example: false })\n isShared: boolean;\n\n @ApiProperty({ description: 'Whether the requesting user owns this view', example: true })\n isOwn: boolean;\n\n @ApiProperty({ description: 'Creation timestamp' })\n createdAt: Date;\n\n @ApiPropertyOptional({ description: 'Last updated timestamp', nullable: true })\n updatedAt: Date | null;\n\n // Creates a response DTO from a DataTableView entity, computing isOwn by comparing userId\n static from(view: DataTableViewRecord, userId: string): DataTableViewDto {\n const dto = new DataTableViewDto();\n dto.id = view.id;\n dto.name = view.name ?? null;\n dto.tableSlug = view.tableSlug;\n dto.state = view.state;\n dto.isShared = view.isShared;\n dto.isOwn = view.userId === userId;\n dto.createdAt = view.createdAt;\n dto.updatedAt = view.updatedAt ?? null;\n return dto;\n }\n}\n","import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';\nimport { IsBoolean, IsObject, IsOptional, IsString, MaxLength } from 'class-validator';\nimport type { TableViewState } from '../../../../database/filter/filter.types';\n\nexport class CreateDataTableViewDto {\n @ApiProperty({ description: 'Display name for the saved view', example: 'AWS Only' })\n @IsString()\n @MaxLength(100)\n name: string;\n\n @ApiProperty({ description: 'Unique slug identifying the table', example: 'cloud-providers' })\n @IsString()\n @MaxLength(200)\n tableSlug: string;\n\n @ApiProperty({ description: 'Full table view state including filters, sort, and column visibility' })\n @IsObject()\n state: TableViewState;\n\n @ApiPropertyOptional({ description: 'Whether this view is visible to all users', example: false })\n @IsBoolean()\n @IsOptional()\n isShared?: boolean;\n}\n","import { ApiProperty } from '@nestjs/swagger';\nimport { IsString, MaxLength, MinLength } from 'class-validator';\n\nexport class RenameDataTableViewDto {\n @ApiProperty({ description: 'New display name for the view', example: 'AWS Only' })\n @IsString()\n @MinLength(1)\n @MaxLength(100)\n name: string;\n}\n","import { ApiProperty } from '@nestjs/swagger';\nimport { IsBoolean } from 'class-validator';\n\nexport class ToggleShareDataTableViewDto {\n @ApiProperty({ description: 'Whether the view should be visible to all users', example: true })\n @IsBoolean()\n isShared: boolean;\n}\n","import { ApiProperty } from '@nestjs/swagger';\nimport { IsObject } from 'class-validator';\nimport type { TableViewState } from '../../../../database/filter/filter.types';\n\n// State-only update — name, tableSlug, and isShared are not updatable via this DTO\nexport class UpdateDataTableViewDto {\n @ApiProperty({ description: 'Updated filter, sort, and column visibility state' })\n @IsObject()\n state: TableViewState;\n}\n","import { createHash } from 'node:crypto';\nimport { Injectable, Logger } from '@nestjs/common';\nimport { ConfigService } from '@nestjs/config';\nimport { CacheService } from '@vritti/api-sdk/cache';\nimport { BadRequestException, ConflictException, NotFoundException } from '../../../exceptions';\nimport type { DataTableViewRecord } from '../../schema/data-table-views.table';\nimport { DataTableViewDto } from '../dto/entity/data-table-view.dto';\nimport type { CreateDataTableViewDto } from '../dto/request/create-data-table-view.dto';\nimport type { UpdateDataTableViewDto } from '../dto/request/update-data-table-view.dto';\nimport { DataTableViewsRepository } from '../repositories/data-table-views.repository';\n\n// Computes a deterministic SHA-256 checksum of a value for equality comparison\nfunction computeChecksum(value: unknown): string {\n return createHash('sha256').update(JSON.stringify(value)).digest('hex');\n}\n\n@Injectable()\nexport class DataTableViewsService {\n private readonly logger = new Logger(DataTableViewsService.name);\n\n constructor(\n private readonly dataTableViewsRepository: DataTableViewsRepository,\n private readonly cacheService: CacheService,\n private readonly configService: ConfigService,\n ) {}\n\n // Builds the Redis key for a user's personal (non-shared) views for a given table\n private personalViewsKey(userId: string, tableSlug: string): string {\n return `views:personal:${userId}:${tableSlug}`;\n }\n\n // Builds the Redis key for all shared views for a given table — same key for all users\n private sharedViewsKey(tableSlug: string): string {\n return `views:shared:${tableSlug}`;\n }\n\n // Returns configured TTL for named views in seconds, defaulting to 86400 (24h)\n private get viewsTtl(): number {\n return this.configService.get<number>('TABLE_VIEWS_CACHE_TTL') ?? 86400;\n }\n\n // Fetches personal views from cache; falls back to DB and warms cache on miss\n private async getOrCachePersonalViews(userId: string, tableSlug: string): Promise<DataTableViewRecord[]> {\n const key = this.personalViewsKey(userId, tableSlug);\n const cached = await this.cacheService.get<DataTableViewRecord[]>(key);\n if (cached) {\n this.logger.debug(`Cache hit for personal views: user=${userId}, table=${tableSlug}`);\n return cached;\n }\n const rows = await this.dataTableViewsRepository.findPersonalViewsBySlug(userId, tableSlug);\n await this.cacheService.set(key, rows, this.viewsTtl);\n return rows;\n }\n\n // Fetches shared views from cache; falls back to DB and warms cache on miss\n private async getOrCacheSharedViews(tableSlug: string): Promise<DataTableViewRecord[]> {\n const key = this.sharedViewsKey(tableSlug);\n const cached = await this.cacheService.get<DataTableViewRecord[]>(key);\n if (cached) {\n this.logger.debug(`Cache hit for shared views: table=${tableSlug}`);\n return cached;\n }\n const rows = await this.dataTableViewsRepository.findSharedViewsBySlug(tableSlug);\n await this.cacheService.set(key, rows, this.viewsTtl);\n return rows;\n }\n\n // Deletes personal and/or shared cache keys based on which pools the mutation affects\n private async invalidateViewsCache(\n userId: string,\n tableSlug: string,\n affectsPersonal: boolean,\n affectsShared: boolean,\n ): Promise<void> {\n const toDelete: string[] = [];\n if (affectsPersonal) toDelete.push(this.personalViewsKey(userId, tableSlug));\n if (affectsShared) toDelete.push(this.sharedViewsKey(tableSlug));\n if (toDelete.length > 0) await this.cacheService.del(...toDelete);\n }\n\n // Returns personal + shared named views — each pool fetched from cache or DB in parallel\n async findViews(userId: string, tableSlug: string): Promise<DataTableViewDto[]> {\n const [personalRows, sharedRows] = await Promise.all([\n this.getOrCachePersonalViews(userId, tableSlug),\n this.getOrCacheSharedViews(tableSlug),\n ]);\n return [...personalRows, ...sharedRows].map((row) => DataTableViewDto.from(row, userId));\n }\n\n // Creates a named snapshot and invalidates the relevant cache pool\n async createView(userId: string, dto: CreateDataTableViewDto): Promise<DataTableViewDto> {\n const view = await this.dataTableViewsRepository.create({\n userId,\n tableSlug: dto.tableSlug,\n name: dto.name,\n state: dto.state,\n isShared: dto.isShared ?? false,\n });\n this.logger.log(`Created view \"${dto.name}\" for user: ${userId}, table: ${dto.tableSlug}`);\n const isShared = dto.isShared ?? false;\n await this.invalidateViewsCache(userId, dto.tableSlug, !isShared, isShared);\n return DataTableViewDto.from(view, userId);\n }\n\n // Updates the state of a named view — skips DB write if state is unchanged\n async updateView(userId: string, id: string, dto: UpdateDataTableViewDto): Promise<DataTableViewDto> {\n const view = await this.dataTableViewsRepository.findById(id);\n if (!view) throw new NotFoundException('Table view not found.');\n if (view.userId !== userId) throw new BadRequestException('You do not have permission to update this view.');\n\n // Skip DB write if the state has not changed\n if (computeChecksum(dto.state) === computeChecksum(view.state)) {\n this.logger.log(`State unchanged for view ${id} — skipping DB write`);\n return DataTableViewDto.from(view, userId);\n }\n\n const updated = await this.dataTableViewsRepository.update(id, { state: dto.state });\n this.logger.log(`Updated state for view ${id}, user: ${userId}`);\n await this.invalidateViewsCache(userId, view.tableSlug, !view.isShared, view.isShared);\n return DataTableViewDto.from(updated, userId);\n }\n\n // Toggles the sharing status of a named view — updates both personal and shared cache\n async toggleShareView(userId: string, id: string, isShared: boolean): Promise<DataTableViewDto> {\n const view = await this.dataTableViewsRepository.findById(id);\n if (!view) throw new NotFoundException('Table view not found.');\n if (view.userId !== userId) throw new BadRequestException('You do not have permission to share this view.');\n\n const updated = await this.dataTableViewsRepository.update(id, { isShared });\n this.logger.log(`Set isShared=${isShared} for view ${id}, user: ${userId}`);\n // Invalidate both pools — the view moves from one to the other\n await this.invalidateViewsCache(userId, view.tableSlug, true, true);\n return DataTableViewDto.from(updated, userId);\n }\n\n // Renames a named view — enforces unique name per user+table, invalidates personal cache\n async renameView(userId: string, id: string, name: string): Promise<DataTableViewDto> {\n const view = await this.dataTableViewsRepository.findById(id);\n if (!view) throw new NotFoundException('Table view not found.');\n if (view.userId !== userId) throw new BadRequestException('You do not have permission to rename this view.');\n\n // Check for duplicate name within the same user+table\n const existing = await this.dataTableViewsRepository.findOne({\n userId,\n tableSlug: view.tableSlug,\n name,\n isShared: false,\n });\n if (existing && existing.id !== id) {\n throw new ConflictException({\n label: 'Name Already Taken',\n detail: 'A view with this name already exists for this table.',\n errors: [{ field: 'name', message: 'Name already taken' }],\n });\n }\n\n const updated = await this.dataTableViewsRepository.update(id, { name });\n this.logger.log(`Renamed view ${id} to \"${name}\" for user: ${userId}`);\n // Rename only affects personal views (shared views are owned by a user too, but visible to all)\n await this.invalidateViewsCache(userId, view.tableSlug, !view.isShared, view.isShared);\n return DataTableViewDto.from(updated, userId);\n }\n\n // Deletes a named view and invalidates the relevant cache pool\n async deleteView(userId: string, id: string): Promise<DataTableViewDto> {\n const view = await this.dataTableViewsRepository.findById(id);\n if (!view) throw new NotFoundException('Table view not found.');\n if (view.userId !== userId) throw new BadRequestException('You do not have permission to delete this view.');\n\n await this.dataTableViewsRepository.delete(id);\n this.logger.log(`Deleted view ${id} for user: ${userId}`);\n await this.invalidateViewsCache(userId, view.tableSlug, !view.isShared, view.isShared);\n return DataTableViewDto.from(view, userId);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class BadGatewayException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Bad Gateway', HttpStatus.BAD_GATEWAY);\n }\n}\n","import { HttpException, HttpStatus } from '@nestjs/common';\nimport type { FieldError } from '../types/error-response.types';\n\n// Re-export FieldError for backwards compatibility\nexport type { FieldError } from '../types/error-response.types';\n\nexport interface ProblemOptions {\n type?: string;\n label?: string;\n detail?: string;\n errors?: FieldError[];\n}\n\nexport abstract class HttpProblemException extends HttpException {\n constructor(detailOrOptions: string | ProblemOptions, httpStatus: HttpStatus) {\n const options = typeof detailOrOptions === 'string' ? { detail: detailOrOptions } : detailOrOptions;\n\n super(\n {\n type: options.type ?? 'about:blank',\n label: options.label,\n detail: options.detail,\n errors: options.errors ?? [],\n },\n httpStatus,\n );\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class BadRequestException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Bad Request', HttpStatus.BAD_REQUEST);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ConflictException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Conflict', HttpStatus.CONFLICT);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ForbiddenException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Forbidden', HttpStatus.FORBIDDEN);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class GoneException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Gone', HttpStatus.GONE);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class InternalServerErrorException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Internal Server Error', HttpStatus.INTERNAL_SERVER_ERROR);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class MethodNotAllowedException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Method Not Allowed', HttpStatus.METHOD_NOT_ALLOWED);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class NotAcceptableException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Not Acceptable', HttpStatus.NOT_ACCEPTABLE);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class NotFoundException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Not Found', HttpStatus.NOT_FOUND);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class NotImplementedException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Not Implemented', HttpStatus.NOT_IMPLEMENTED);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class PayloadTooLargeException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Payload Too Large', HttpStatus.PAYLOAD_TOO_LARGE);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class RequestTimeoutException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Request Timeout', HttpStatus.REQUEST_TIMEOUT);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ServiceUnavailableException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Service Unavailable', HttpStatus.SERVICE_UNAVAILABLE);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class TooManyRequestsException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Too Many Requests', HttpStatus.TOO_MANY_REQUESTS);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class UnauthorizedException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Unauthorized', HttpStatus.UNAUTHORIZED);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class UnprocessableEntityException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Unprocessable Entity', HttpStatus.UNPROCESSABLE_ENTITY);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class UnsupportedMediaTypeException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Unsupported Media Type', HttpStatus.UNSUPPORTED_MEDIA_TYPE);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ValidationException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Validation Failed', HttpStatus.UNPROCESSABLE_ENTITY);\n }\n}\n","import { Inject, Injectable } from '@nestjs/common';\nimport { and, eq } from 'drizzle-orm';\nimport type { PgTable } from 'drizzle-orm/pg-core';\nimport { PrimaryBaseRepository, PrimaryDatabaseService } from '@vritti/api-sdk/database';\nimport { DATA_TABLE_VIEWS_TABLE } from '../../data-table.constants';\nimport type { DataTableViewRecord, NewDataTableViewRecord } from '../../schema/data-table-views.table';\n\nconst NAMED_VIEWS_LIMIT = 100;\n\n@Injectable()\nexport class DataTableViewsRepository extends PrimaryBaseRepository<\n PgTable,\n NewDataTableViewRecord,\n DataTableViewRecord\n> {\n constructor(database: PrimaryDatabaseService, @Inject(DATA_TABLE_VIEWS_TABLE) table: PgTable) {\n super(database, table);\n }\n\n // Returns personal (non-shared) named views owned by the user for a given table\n async findPersonalViewsBySlug(userId: string, tableSlug: string): Promise<DataTableViewRecord[]> {\n // biome-ignore lint/suspicious/noExplicitAny: table columns are typed at runtime via the injected schema-qualified table\n const t = this.table as any;\n return this.db\n .select()\n .from(this.table)\n .where(and(eq(t.tableSlug, tableSlug), eq(t.userId, userId), eq(t.isShared, false)))\n .orderBy(t.createdAt)\n .limit(NAMED_VIEWS_LIMIT) as unknown as Promise<DataTableViewRecord[]>;\n }\n\n // Returns all shared named views for a given table — visible to all users\n async findSharedViewsBySlug(tableSlug: string): Promise<DataTableViewRecord[]> {\n // biome-ignore lint/suspicious/noExplicitAny: table columns are typed at runtime via the injected schema-qualified table\n const t = this.table as any;\n return this.db\n .select()\n .from(this.table)\n .where(and(eq(t.tableSlug, tableSlug), eq(t.isShared, true)))\n .orderBy(t.createdAt)\n .limit(NAMED_VIEWS_LIMIT) as unknown as Promise<DataTableViewRecord[]>;\n }\n}\n","// Re-export all of drizzle-orm/pg-core\nexport * from 'drizzle-orm/pg-core';\n\nimport { sql } from 'drizzle-orm';\nimport { type AnyPgColumn, check } from 'drizzle-orm/pg-core';\nimport { CODE_PATTERN_SOURCE, type CodeOptions, DOTTED_CODE_PATTERN_SOURCE } from './decorators/code-pattern';\n\n// Builds a Postgres CHECK constraint enforcing the canonical code format on a column\nexport function codeCheck(name: string, column: AnyPgColumn, options?: CodeOptions) {\n const source = options?.dotted ? DOTTED_CODE_PATTERN_SOURCE : CODE_PATTERN_SOURCE;\n return check(name, sql`${column} ~ ${sql.raw(`'${source}'`)}`);\n}\n","// Canonical entity \"code\" format — the single source of truth for DTOs, DB checks, and frontend forms.\n// A code is a single lowercase word of letters, digits, and hyphens, starting with a letter or digit.\n// Real-world codes lead with a digit often enough (pack sizes \"62g\", sizes \"5xl\") that requiring a\n// leading letter forced callers to mangle them.\n// The dotted variant allows dot-separated segments (e.g. permission codes like \"add.salt\").\n\nconst SEGMENT = '[a-z0-9][a-z0-9-]*';\n\nexport const CODE_PATTERN_SOURCE = `^${SEGMENT}$`;\nexport const DOTTED_CODE_PATTERN_SOURCE = `^${SEGMENT}(\\\\.${SEGMENT})*$`;\n\nexport const CODE_PATTERN = new RegExp(CODE_PATTERN_SOURCE);\nexport const DOTTED_CODE_PATTERN = new RegExp(DOTTED_CODE_PATTERN_SOURCE);\n\nexport interface CodeOptions {\n dotted?: boolean;\n}\n\n// Returns the regex for the requested code variant\nexport function codePattern(options?: CodeOptions): RegExp {\n return options?.dotted ? DOTTED_CODE_PATTERN : CODE_PATTERN;\n}\n\n// Returns the Postgres regex source string for the requested code variant (for CHECK constraints)\nexport function codePatternSource(options?: CodeOptions): string {\n return options?.dotted ? DOTTED_CODE_PATTERN_SOURCE : CODE_PATTERN_SOURCE;\n}\n\n// Human-readable validation message for the requested code variant\nexport function codeMessage(property: string, options?: CodeOptions): string {\n return options?.dotted\n ? `${property} must be lowercase words separated by dots.`\n : `${property} must be lowercase letters, numbers, and hyphens only.`;\n}\n","import type { TableViewState } from '../../database/filter/filter.types';\nimport { boolean, index, jsonb, timestamp, uniqueIndex, uuid, varchar } from '../../drizzle-pg-core';\n\n// Returns a fresh set of column builder instances — call once per table declaration\nexport function dataTableViewsColumns() {\n return {\n id: uuid('id').primaryKey().defaultRandom(),\n userId: uuid('user_id').notNull(),\n tableSlug: varchar('table_slug', { length: 200 }).notNull(),\n name: varchar('name', { length: 100 }).notNull(),\n state: jsonb('state').notNull().$type<TableViewState>(),\n isShared: boolean('is_shared').notNull().default(false),\n createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),\n updatedAt: timestamp('updated_at', { withTimezone: true }).$onUpdate(() => new Date()),\n };\n}\n\n// Index definitions — reusable callback, works with any table that has the same column names\n// biome-ignore lint/suspicious/noExplicitAny: receives Drizzle-bound columns, not raw builders\nexport function dataTableViewsIndexes(table: any) {\n return [\n index('table_views_user_table_idx').on(table.userId, table.tableSlug),\n index('table_views_shared_slug_idx').on(table.tableSlug, table.isShared),\n uniqueIndex('table_views_user_table_name_shared_unique').on(\n table.userId,\n table.tableSlug,\n table.name,\n table.isShared,\n ),\n ];\n}\n\nexport interface DataTableViewRecord {\n id: string;\n userId: string;\n tableSlug: string;\n name: string;\n state: TableViewState;\n isShared: boolean;\n createdAt: Date;\n updatedAt: Date | null | undefined;\n}\n\nexport interface NewDataTableViewRecord {\n userId: string;\n tableSlug: string;\n name: string;\n state: TableViewState;\n isShared?: boolean;\n}\n"],"mappings":"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","names":["Module","ConfigModule","CacheModule","DATA_TABLE_VIEWS_TABLE","Symbol","Body","Controller","HttpCode","HttpStatus","Logger","Post","ApiBearerAuth","ApiTags","createParamDecorator","graphqlExtractor","getRequest","host","getArgByIndex","req","getResponse","reply","httpExtractor","getRequest","host","switchToHttp","getResponse","registry","Map","httpExtractor","graphqlExtractor","resolveExtractor","type","registry","get","httpExtractor","getRequestFromContext","host","resolveExtractor","getType","getRequest","UserId","createParamDecorator","_data","ctx","auth","getRequestFromContext","kind","userId","Error","applyDecorators","ApiBody","ApiOperation","ApiResponse","ApiProperty","ApiPropertyOptional","IsObject","IsOptional","IsString","IsUUID","MaxLength","UpsertDataTableStateDto","tableSlug","state","activeViewId","description","example","ApiUpsertDataTableState","applyDecorators","ApiOperation","summary","description","ApiBody","type","UpsertDataTableStateDto","ApiResponse","status","Injectable","Logger","ConfigService","CacheService","EMPTY_TABLE_STATE","filters","sort","columnVisibility","columnOrder","columnSizing","columnPinning","left","right","lockedColumnSizing","density","filterOrder","filterVisibility","search","pagination","limit","offset","DataTableStateService","logger","Logger","name","cacheService","configService","stateTtl","get","upsertCurrentState","userId","dto","key","tableSlug","set","state","activeViewId","log","getCurrentState","cached","DataTableStateController","logger","Logger","name","dataTableStateService","upsertCurrentState","userId","dto","log","tableSlug","OK","Body","Controller","Delete","Get","HttpCode","HttpStatus","Logger","Param","Patch","Post","Query","ApiBearerAuth","ApiTags","applyDecorators","ApiBody","ApiOperation","ApiParam","ApiQuery","ApiResponse","ApiProperty","ApiPropertyOptional","DataTableViewDto","id","name","tableSlug","state","isShared","isOwn","createdAt","updatedAt","from","view","userId","dto","description","nullable","example","ApiProperty","ApiPropertyOptional","IsBoolean","IsObject","IsOptional","IsString","MaxLength","CreateDataTableViewDto","name","tableSlug","state","isShared","description","example","ApiProperty","IsString","MaxLength","MinLength","RenameDataTableViewDto","name","description","example","ApiProperty","IsBoolean","ToggleShareDataTableViewDto","isShared","description","example","ApiProperty","IsObject","UpdateDataTableViewDto","state","description","ApiListDataTableViews","applyDecorators","ApiOperation","summary","description","ApiQuery","name","example","required","ApiResponse","status","type","DataTableViewDto","ApiCreateDataTableView","ApiBody","CreateDataTableViewDto","ApiUpdateDataTableView","ApiParam","UpdateDataTableViewDto","ApiRenameDataTableView","RenameDataTableViewDto","ApiToggleShareDataTableView","ToggleShareDataTableViewDto","ApiDeleteDataTableView","createHash","Injectable","Logger","ConfigService","CacheService","HttpStatus","HttpException","HttpProblemException","HttpException","detailOrOptions","httpStatus","options","detail","type","label","errors","HttpStatus","BadRequestException","HttpProblemException","detailOrOptions","HttpStatus","BAD_REQUEST","HttpStatus","ConflictException","HttpProblemException","detailOrOptions","HttpStatus","CONFLICT","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","NotFoundException","HttpProblemException","detailOrOptions","HttpStatus","NOT_FOUND","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","Inject","Injectable","and","eq","PrimaryBaseRepository","PrimaryDatabaseService","NAMED_VIEWS_LIMIT","DataTableViewsRepository","PrimaryBaseRepository","database","table","findPersonalViewsBySlug","userId","tableSlug","t","db","select","from","where","and","eq","isShared","orderBy","createdAt","limit","findSharedViewsBySlug","computeChecksum","value","createHash","update","JSON","stringify","digest","DataTableViewsService","logger","Logger","name","dataTableViewsRepository","cacheService","configService","personalViewsKey","userId","tableSlug","sharedViewsKey","viewsTtl","get","getOrCachePersonalViews","key","cached","debug","rows","findPersonalViewsBySlug","set","getOrCacheSharedViews","findSharedViewsBySlug","invalidateViewsCache","affectsPersonal","affectsShared","toDelete","push","length","del","findViews","personalRows","sharedRows","Promise","all","map","row","DataTableViewDto","from","createView","dto","view","create","state","isShared","log","updateView","id","findById","NotFoundException","BadRequestException","updated","toggleShareView","renameView","existing","findOne","ConflictException","label","detail","errors","field","message","deleteView","delete","DataTableViewsController","logger","Logger","name","dataTableViewsService","findViews","userId","tableSlug","log","createView","dto","updateView","id","renameView","toggleShareView","isShared","deleteView","CREATED","DataTableModule","forRoot","options","global","module","imports","ConfigModule","CacheModule","controllers","DataTableStateController","DataTableViewsController","providers","provide","DATA_TABLE_VIEWS_TABLE","useValue","tableViews","DataTableViewsService","DataTableViewsRepository","DataTableStateService","exports","sql","check","SEGMENT","CODE_PATTERN_SOURCE","DOTTED_CODE_PATTERN_SOURCE","CODE_PATTERN","RegExp","DOTTED_CODE_PATTERN","codeCheck","name","column","options","source","dotted","DOTTED_CODE_PATTERN_SOURCE","CODE_PATTERN_SOURCE","check","sql","raw","dataTableViewsColumns","id","uuid","primaryKey","defaultRandom","userId","notNull","tableSlug","varchar","length","name","state","jsonb","$type","isShared","boolean","default","createdAt","timestamp","withTimezone","defaultNow","updatedAt","$onUpdate","Date","dataTableViewsIndexes","table","index","on","uniqueIndex"]}
|
package/dist/database.cjs
CHANGED
|
@@ -946,7 +946,8 @@ var CursorCodec = class {
|
|
|
946
946
|
|
|
947
947
|
// src/database/filter/filter.processor.ts
|
|
948
948
|
var import_drizzle_orm = require("drizzle-orm");
|
|
949
|
-
var
|
|
949
|
+
var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
950
|
+
var FilterProcessor = class _FilterProcessor {
|
|
950
951
|
static {
|
|
951
952
|
__name(this, "FilterProcessor");
|
|
952
953
|
}
|
|
@@ -1018,16 +1019,24 @@ var FilterProcessor = class {
|
|
|
1018
1019
|
return conditions.length ? (0, import_drizzle_orm.and)(...conditions) : void 0;
|
|
1019
1020
|
}
|
|
1020
1021
|
// Builds a search WHERE — OR across all string fields when columnId is 'all', otherwise a single ilike
|
|
1022
|
+
// Field maps expose uuid columns as 'string' so the multi-select filters (isAnyOf → inArray) work, but Postgres has
|
|
1023
|
+
// no ILIKE for uuid: an "all columns" search must skip them, and a search aimed at one can only be an exact match.
|
|
1021
1024
|
static buildSearch(search, fieldMap) {
|
|
1022
1025
|
if (!search?.value) return void 0;
|
|
1023
1026
|
if (search.columnId === "all") {
|
|
1024
|
-
const conditions = Object.values(fieldMap).filter((def2) => "column" in def2 && def2.type === "string").map((def2) => (0, import_drizzle_orm.ilike)(def2.column, `%${search.value}%`));
|
|
1027
|
+
const conditions = Object.values(fieldMap).filter((def2) => "column" in def2 && def2.type === "string" && !_FilterProcessor.isUuidColumn(def2.column)).map((def2) => (0, import_drizzle_orm.ilike)(def2.column, `%${search.value}%`));
|
|
1025
1028
|
return conditions.length ? (0, import_drizzle_orm.or)(...conditions) : void 0;
|
|
1026
1029
|
}
|
|
1027
1030
|
const def = fieldMap[search.columnId];
|
|
1028
1031
|
if (!def || !("column" in def)) return void 0;
|
|
1032
|
+
if (_FilterProcessor.isUuidColumn(def.column)) {
|
|
1033
|
+
return UUID_PATTERN.test(search.value) ? (0, import_drizzle_orm.eq)(def.column, search.value) : import_drizzle_orm.sql`false`;
|
|
1034
|
+
}
|
|
1029
1035
|
return (0, import_drizzle_orm.ilike)(def.column, `%${search.value}%`);
|
|
1030
1036
|
}
|
|
1037
|
+
static isUuidColumn(column) {
|
|
1038
|
+
return column.columnType === "PgUUID";
|
|
1039
|
+
}
|
|
1031
1040
|
// Maps each SortCondition to an asc/desc SQL expression
|
|
1032
1041
|
static buildOrderBy(sort = [], fieldMap) {
|
|
1033
1042
|
return sort.flatMap((s) => {
|