From 2f0758661e32dfb2fdea7834689666ca2dbc4670 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 27 May 2025 01:53:01 +0000 Subject: [PATCH 1/6] refactor: simplify Request interface by replacing apiInfo.data.api with api Co-Authored-By: Dan Lynch --- packages/server/src/middleware/api.ts | 24 +++++++++- packages/server/src/middleware/auth.ts | 2 +- packages/server/src/middleware/cors.ts | 8 ++-- packages/server/src/middleware/graphile.ts | 16 +++---- packages/types/src/launchql.ts | 51 +++++++++++----------- 5 files changed, 59 insertions(+), 42 deletions(-) diff --git a/packages/server/src/middleware/api.ts b/packages/server/src/middleware/api.ts index c315a472c9..a4b6a0ec09 100644 --- a/packages/server/src/middleware/api.ts +++ b/packages/server/src/middleware/api.ts @@ -9,6 +9,27 @@ import { LaunchQLOptions } from '@launchql/types'; import { Response, Request, NextFunction } from 'express'; import { Pool } from 'pg'; +/** + * Transforms the old service structure to the new api structure + */ +const transformServiceToApi = (svc: any): any => { + const api = svc.data.api; + const schemaNames = api.schemaNamesFromExt?.nodes?.map((n: any) => n.schemaName) || []; + const additionalSchemas = api.schemaNames?.nodes?.map((n: any) => n.schemaName) || []; + + return { + dbname: api.dbname, + anonRole: api.anonRole, + roleName: api.roleName, + schema: [...schemaNames, ...additionalSchemas], + apiModules: api.apiModules?.nodes || [], + rlsModule: api.rlsModule, + database: api.database, + databaseId: api.databaseId, + isPublic: api.isPublic + }; +}; + const getPortFromRequest = (req: Request): string | null => { const host = req.headers.host; if (!host) return null; @@ -34,7 +55,8 @@ export const createApiMiddleware = (opts: LaunchQLOptions) => { res.status(404).send(errorPage404Message('API service not found for the given domain/subdomain.')); return; } - req.apiInfo = svc; + req.api = transformServiceToApi(svc); + req.apiInfo = svc; // Keep for backward compatibility req.databaseId = svc.data.api.databaseId; next(); } catch (e: any) { diff --git a/packages/server/src/middleware/auth.ts b/packages/server/src/middleware/auth.ts index ed33d5a099..bb3b2812b3 100644 --- a/packages/server/src/middleware/auth.ts +++ b/packages/server/src/middleware/auth.ts @@ -6,7 +6,7 @@ import { LaunchQLOptions } from '@launchql/types'; export const createAuthenticateMiddleware = (opts: LaunchQLOptions): RequestHandler => { return async (req: Request, res: Response, next: NextFunction): Promise => { - const api = req.apiInfo?.data?.api; + const api = req.api; if (!api) { res.status(500).send('Missing API info'); return; diff --git a/packages/server/src/middleware/cors.ts b/packages/server/src/middleware/cors.ts index 428d3fcc4b..6c4402ebd7 100644 --- a/packages/server/src/middleware/cors.ts +++ b/packages/server/src/middleware/cors.ts @@ -60,9 +60,9 @@ const getSiteUrls = (sites: Sites): string[] => { return siteUrls; }; -export const cors = async (req: Request & { apiInfo: ApiInfo }, res: Response, next: NextFunction) => { - const api = req.apiInfo.data.api; - const corsModules = api.apiModules.nodes.filter((mod) => mod.name === 'cors'); +export const cors = async (req: Request, res: Response, next: NextFunction) => { + const api = req.api; + const corsModules = api.apiModules.filter((mod: any) => mod.name === 'cors'); let corsOptions = { origin: false as boolean | string | RegExp | (string | RegExp)[] }; // default: disabled if (!api.database?.sites) { @@ -76,7 +76,7 @@ export const cors = async (req: Request & { apiInfo: ApiInfo }, res: Response, n const sites = api.database.sites; const siteUrls = getSiteUrls(sites); - const listOfDomains = corsModules.reduce((m, mod) => { + const listOfDomains = corsModules.reduce((m: string[], mod: any) => { return [...mod.data.urls, ...m]; }, siteUrls); diff --git a/packages/server/src/middleware/graphile.ts b/packages/server/src/middleware/graphile.ts index 816516cfe9..d32ffd081b 100644 --- a/packages/server/src/middleware/graphile.ts +++ b/packages/server/src/middleware/graphile.ts @@ -10,15 +10,9 @@ export const graphile = (lOpts: LaunchQLOptions): RequestHandler => { // @ts-ignore return async (req: Request, res: Response, next: NextFunction) => { try { - const api = req.apiInfo.data.api; + const api = req.api; const key = req.svc_key; - const { dbname } = api; - const { anonRole, roleName } = api; - - const { schemaNamesFromExt, schemaNames } = api; - const schemas = [] - .concat(schemaNamesFromExt.nodes.map(({ schemaName }: any) => schemaName)) - .concat(schemaNames.nodes.map(({ schemaName }: any) => schemaName)); + const { dbname, anonRole, roleName, schema } = api; if (graphileCache.has(key)) { const { handler } = graphileCache.get(key)! @@ -29,11 +23,11 @@ export const graphile = (lOpts: LaunchQLOptions): RequestHandler => { ...lOpts, graphile: { ...lOpts.graphile, - schema: schemas + schema: schema } }); - const pubkey_challenge = api.apiModules.nodes.find( + const pubkey_challenge = api.apiModules.find( (mod: any) => mod.name === 'pubkey_challenge' ); @@ -87,7 +81,7 @@ export const graphile = (lOpts: LaunchQLOptions): RequestHandler => { ...lOpts.pg, database: dbname }); - const handler = postgraphile(pgPool, schemas, opts); + const handler = postgraphile(pgPool, schema, opts); graphileCache.set(key, { pgPool, diff --git a/packages/types/src/launchql.ts b/packages/types/src/launchql.ts index 1fae477fac..6003073fb2 100644 --- a/packages/types/src/launchql.ts +++ b/packages/types/src/launchql.ts @@ -3,33 +3,34 @@ import type { Plugin } from 'graphile-build'; import { execSync } from 'child_process'; declare module 'express-serve-static-core' { interface Request { - apiInfo: { - data: { - api: { - dbname: string; - anonRole: string; - roleName: string; - schemaNames: { - nodes: { schemaName: string }[]; - }; - schemaNamesFromExt: { - nodes: { schemaName: string }[]; - }; - apiModules: { - nodes: { - name: string; - data?: any; - }[]; - }; - rlsModule?: { - authenticate?: string; - authenticateStrict?: string; - privateSchema: { - schemaName: string; - }; - }; + api: { + dbname: string; + anonRole: string; + roleName: string; + schema: string[]; // Pre-processed schema names + apiModules: { + name: string; + data?: any; + }[]; + rlsModule?: { + authenticate?: string; + authenticateStrict?: string; + privateSchema: { + schemaName: string; + }; + }; + database?: { + sites?: { + nodes?: any[]; }; }; + databaseId?: string; + isPublic?: boolean; + }; + apiInfo?: { + data: { + api: any; + }; }; svc_key: string; clientIp?: string; From db7e64359e110924388ea1fc477d1af76b039022 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 27 May 2025 05:15:44 +0000 Subject: [PATCH 2/6] refactor: remove apiInfo completely and add typed interfaces for api modules Co-Authored-By: Dan Lynch --- packages/server/src/middleware/api.ts | 23 +++++++-- packages/server/src/middleware/cors.ts | 68 ++------------------------ packages/types/src/launchql.ts | 38 ++++++++------ 3 files changed, 48 insertions(+), 81 deletions(-) diff --git a/packages/server/src/middleware/api.ts b/packages/server/src/middleware/api.ts index a4b6a0ec09..66c5ad8205 100644 --- a/packages/server/src/middleware/api.ts +++ b/packages/server/src/middleware/api.ts @@ -17,6 +17,21 @@ const transformServiceToApi = (svc: any): any => { const schemaNames = api.schemaNamesFromExt?.nodes?.map((n: any) => n.schemaName) || []; const additionalSchemas = api.schemaNames?.nodes?.map((n: any) => n.schemaName) || []; + let domains: string[] = []; + if (api.database?.sites?.nodes) { + domains = api.database.sites.nodes.reduce((acc: string[], site: any) => { + if (site.domains?.nodes && site.domains.nodes.length) { + const siteUrls = site.domains.nodes.map((domain: any) => { + const hostname = domain.subdomain ? `${domain.subdomain}.${domain.domain}` : domain.domain; + const protocol = domain.domain === 'localhost' ? 'http://' : 'https://'; + return protocol + hostname; + }); + return [...acc, ...siteUrls]; + } + return acc; + }, []); + } + return { dbname: api.dbname, anonRole: api.anonRole, @@ -24,7 +39,7 @@ const transformServiceToApi = (svc: any): any => { schema: [...schemaNames, ...additionalSchemas], apiModules: api.apiModules?.nodes || [], rlsModule: api.rlsModule, - database: api.database, + domains, databaseId: api.databaseId, isPublic: api.isPublic }; @@ -55,9 +70,9 @@ export const createApiMiddleware = (opts: LaunchQLOptions) => { res.status(404).send(errorPage404Message('API service not found for the given domain/subdomain.')); return; } - req.api = transformServiceToApi(svc); - req.apiInfo = svc; // Keep for backward compatibility - req.databaseId = svc.data.api.databaseId; + const api = transformServiceToApi(svc); + req.api = api; + req.databaseId = api.databaseId; next(); } catch (e: any) { if (e.code === 'NO_VALID_SCHEMAS') { diff --git a/packages/server/src/middleware/cors.ts b/packages/server/src/middleware/cors.ts index 6c4402ebd7..ff9d2a3f59 100644 --- a/packages/server/src/middleware/cors.ts +++ b/packages/server/src/middleware/cors.ts @@ -1,71 +1,14 @@ import corsPlugin from 'cors'; import { parseUrl } from '@launchql/url-domains'; import { Request, Response, NextFunction } from 'express'; - -interface Domain { - subdomain?: string; - domain: string; -} - -interface SiteDomainNode { - nodes: Domain[]; -} - -interface Site { - domains: SiteDomainNode; -} - -interface Sites { - nodes?: Site[]; -} - -interface ApiModule { - name: string; - data: { - urls: string[]; - }; -} - -interface ApiInfo { - data: { - api: { - apiModules: { - nodes: ApiModule[]; - }; - database?: { - sites: Sites; - }; - }; - }; -} - -const getUrlsFromDomains = (domains: Domain[]): string[] => { - return domains.reduce((m, { subdomain, domain }) => { - const hostname = subdomain ? `${subdomain}.${domain}` : domain; - const protocol = domain === 'localhost' ? 'http://' : 'https://'; - return [...m, protocol + hostname]; - }, []); -}; - -const getSiteUrls = (sites: Sites): string[] => { - let siteUrls: string[] = []; - if (sites.nodes) { - siteUrls = sites.nodes.reduce((m, site) => { - if (site.domains.nodes && site.domains.nodes.length) { - return [...m, ...getUrlsFromDomains(site.domains.nodes)]; - } - return m; - }, []); - } - return siteUrls; -}; +import { CorsModuleData } from '@launchql/types'; export const cors = async (req: Request, res: Response, next: NextFunction) => { const api = req.api; - const corsModules = api.apiModules.filter((mod: any) => mod.name === 'cors'); + const corsModules = api.apiModules.filter((mod) => mod.name === 'cors') as { name: 'cors'; data: CorsModuleData }[]; let corsOptions = { origin: false as boolean | string | RegExp | (string | RegExp)[] }; // default: disabled - if (!api.database?.sites) { + if (!api.domains || api.domains.length === 0) { return corsPlugin({ ...corsOptions, credentials: true, @@ -73,10 +16,9 @@ export const cors = async (req: Request, res: Response, next: NextFunction) => { })(req, res, next); } - const sites = api.database.sites; - const siteUrls = getSiteUrls(sites); + const siteUrls = api.domains; - const listOfDomains = corsModules.reduce((m: string[], mod: any) => { + const listOfDomains = corsModules.reduce((m, mod) => { return [...mod.data.urls, ...m]; }, siteUrls); diff --git a/packages/types/src/launchql.ts b/packages/types/src/launchql.ts index 6003073fb2..a8a491f140 100644 --- a/packages/types/src/launchql.ts +++ b/packages/types/src/launchql.ts @@ -1,6 +1,28 @@ import { PostGraphileOptions } from 'postgraphile'; import type { Plugin } from 'graphile-build'; import { execSync } from 'child_process'; +export interface CorsModuleData { + urls: string[]; +} + +export interface PublicKeyChallengeData { + schema: string; + crypto_network: string; + sign_up_with_key: string; + sign_in_request_challenge: string; + sign_in_record_failure: string; + sign_in_with_challenge: string; +} + +export interface GenericModuleData { + [key: string]: any; +} + +export type ApiModule = + | { name: 'cors'; data: CorsModuleData } + | { name: 'pubkey_challenge'; data: PublicKeyChallengeData } + | { name: string; data?: GenericModuleData }; + declare module 'express-serve-static-core' { interface Request { api: { @@ -8,10 +30,7 @@ declare module 'express-serve-static-core' { anonRole: string; roleName: string; schema: string[]; // Pre-processed schema names - apiModules: { - name: string; - data?: any; - }[]; + apiModules: ApiModule[]; rlsModule?: { authenticate?: string; authenticateStrict?: string; @@ -19,19 +38,10 @@ declare module 'express-serve-static-core' { schemaName: string; }; }; - database?: { - sites?: { - nodes?: any[]; - }; - }; + domains?: string[]; // Simplified from database.sites.nodes databaseId?: string; isPublic?: boolean; }; - apiInfo?: { - data: { - api: any; - }; - }; svc_key: string; clientIp?: string; databaseId?: string; From 5ecc3694c8cf395b41e536938d3a5aa06c4865f5 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 27 May 2025 05:45:28 +0000 Subject: [PATCH 3/6] refactor: add proper TypeScript interfaces for service transformation Co-Authored-By: Dan Lynch --- packages/server/src/middleware/api.ts | 14 +++-- packages/types/src/launchql.ts | 80 +++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 6 deletions(-) diff --git a/packages/server/src/middleware/api.ts b/packages/server/src/middleware/api.ts index 66c5ad8205..1524ef05f5 100644 --- a/packages/server/src/middleware/api.ts +++ b/packages/server/src/middleware/api.ts @@ -12,16 +12,18 @@ import { Pool } from 'pg'; /** * Transforms the old service structure to the new api structure */ -const transformServiceToApi = (svc: any): any => { +import { Service, ApiStructure, SchemaNode, Domain, Site } from '@launchql/types'; + +const transformServiceToApi = (svc: Service): ApiStructure => { const api = svc.data.api; - const schemaNames = api.schemaNamesFromExt?.nodes?.map((n: any) => n.schemaName) || []; - const additionalSchemas = api.schemaNames?.nodes?.map((n: any) => n.schemaName) || []; + const schemaNames = api.schemaNamesFromExt?.nodes?.map((n: SchemaNode) => n.schemaName) || []; + const additionalSchemas = api.schemaNames?.nodes?.map((n: SchemaNode) => n.schemaName) || []; let domains: string[] = []; if (api.database?.sites?.nodes) { - domains = api.database.sites.nodes.reduce((acc: string[], site: any) => { + domains = api.database.sites.nodes.reduce((acc: string[], site: Site) => { if (site.domains?.nodes && site.domains.nodes.length) { - const siteUrls = site.domains.nodes.map((domain: any) => { + const siteUrls = site.domains.nodes.map((domain: Domain) => { const hostname = domain.subdomain ? `${domain.subdomain}.${domain.domain}` : domain.domain; const protocol = domain.domain === 'localhost' ? 'http://' : 'https://'; return protocol + hostname; @@ -246,7 +248,7 @@ const validateSchemata = async (pool: Pool, schemata: string[]): Promise row.schema_name); + return result.rows.map((row: { schema_name: string }) => row.schema_name); }; export const getApiConfig = async (opts: LaunchQLOptions, req: Request): Promise => { diff --git a/packages/types/src/launchql.ts b/packages/types/src/launchql.ts index a8a491f140..fcf121d51b 100644 --- a/packages/types/src/launchql.ts +++ b/packages/types/src/launchql.ts @@ -1,6 +1,7 @@ import { PostGraphileOptions } from 'postgraphile'; import type { Plugin } from 'graphile-build'; import { execSync } from 'child_process'; + export interface CorsModuleData { urls: string[]; } @@ -23,6 +24,85 @@ export type ApiModule = | { name: 'pubkey_challenge'; data: PublicKeyChallengeData } | { name: string; data?: GenericModuleData }; +export interface SchemaNode { + schemaName: string; +} + +export interface SchemaNodes { + nodes: SchemaNode[]; +} + +export interface Domain { + subdomain?: string; + domain: string; +} + +export interface DomainNodes { + nodes: Domain[]; +} + +export interface Site { + domains: DomainNodes; +} + +export interface SiteNodes { + nodes: Site[]; +} + +export interface Database { + sites: SiteNodes; +} + +export interface ApiModuleNode { + name: string; + data?: any; +} + +export interface ApiModuleNodes { + nodes: ApiModuleNode[]; +} + +export interface RlsModule { + authenticate?: string; + authenticateStrict?: string; + privateSchema: { + schemaName: string; + }; +} + +export interface OldApiStructure { + dbname: string; + anonRole: string; + roleName: string; + schemaNames: SchemaNodes; + schemaNamesFromExt: SchemaNodes; + apiModules: ApiModuleNodes; + rlsModule?: RlsModule; + database?: Database; + databaseId?: string; + isPublic?: boolean; +} + +export interface ServiceData { + api: OldApiStructure; +} + +export interface Service { + data: ServiceData; +} + +export interface ApiStructure { + dbname: string; + anonRole: string; + roleName: string; + schema: string[]; + apiModules: ApiModule[]; + rlsModule?: RlsModule; + domains?: string[]; + databaseId?: string; + isPublic?: boolean; +} + declare module 'express-serve-static-core' { interface Request { api: { From 985a9977fb6ca78fab998a78e85e5e1ca67fe376 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 27 May 2025 05:51:57 +0000 Subject: [PATCH 4/6] refactor: move server-specific types to server package Co-Authored-By: Dan Lynch --- packages/server/src/middleware/api.ts | 2 +- packages/server/src/types.ts | 72 +++++++++++++++++++++++++++ packages/types/src/launchql.ts | 71 -------------------------- 3 files changed, 73 insertions(+), 72 deletions(-) create mode 100644 packages/server/src/types.ts diff --git a/packages/server/src/middleware/api.ts b/packages/server/src/middleware/api.ts index 1524ef05f5..a81b037e13 100644 --- a/packages/server/src/middleware/api.ts +++ b/packages/server/src/middleware/api.ts @@ -12,7 +12,7 @@ import { Pool } from 'pg'; /** * Transforms the old service structure to the new api structure */ -import { Service, ApiStructure, SchemaNode, Domain, Site } from '@launchql/types'; +import { Service, ApiStructure, SchemaNode, Domain, Site } from '../types'; const transformServiceToApi = (svc: Service): ApiStructure => { const api = svc.data.api; diff --git a/packages/server/src/types.ts b/packages/server/src/types.ts new file mode 100644 index 0000000000..cc17ee7754 --- /dev/null +++ b/packages/server/src/types.ts @@ -0,0 +1,72 @@ +import { ApiModule, RlsModule } from '@launchql/types'; + +export interface SchemaNode { + schemaName: string; +} + +export interface SchemaNodes { + nodes: SchemaNode[]; +} + +export interface Domain { + subdomain?: string; + domain: string; +} + +export interface DomainNodes { + nodes: Domain[]; +} + +export interface Site { + domains: DomainNodes; +} + +export interface SiteNodes { + nodes: Site[]; +} + +export interface Database { + sites: SiteNodes; +} + +export interface ApiModuleNode { + name: string; + data?: any; +} + +export interface ApiModuleNodes { + nodes: ApiModuleNode[]; +} + +export interface OldApiStructure { + dbname: string; + anonRole: string; + roleName: string; + schemaNames: SchemaNodes; + schemaNamesFromExt: SchemaNodes; + apiModules: ApiModuleNodes; + rlsModule?: RlsModule; + database?: Database; + databaseId?: string; + isPublic?: boolean; +} + +export interface ServiceData { + api: OldApiStructure; +} + +export interface Service { + data: ServiceData; +} + +export interface ApiStructure { + dbname: string; + anonRole: string; + roleName: string; + schema: string[]; + apiModules: ApiModule[]; + rlsModule?: RlsModule; + domains?: string[]; + databaseId?: string; + isPublic?: boolean; +} diff --git a/packages/types/src/launchql.ts b/packages/types/src/launchql.ts index fcf121d51b..5809fcbbb6 100644 --- a/packages/types/src/launchql.ts +++ b/packages/types/src/launchql.ts @@ -24,44 +24,6 @@ export type ApiModule = | { name: 'pubkey_challenge'; data: PublicKeyChallengeData } | { name: string; data?: GenericModuleData }; -export interface SchemaNode { - schemaName: string; -} - -export interface SchemaNodes { - nodes: SchemaNode[]; -} - -export interface Domain { - subdomain?: string; - domain: string; -} - -export interface DomainNodes { - nodes: Domain[]; -} - -export interface Site { - domains: DomainNodes; -} - -export interface SiteNodes { - nodes: Site[]; -} - -export interface Database { - sites: SiteNodes; -} - -export interface ApiModuleNode { - name: string; - data?: any; -} - -export interface ApiModuleNodes { - nodes: ApiModuleNode[]; -} - export interface RlsModule { authenticate?: string; authenticateStrict?: string; @@ -70,39 +32,6 @@ export interface RlsModule { }; } -export interface OldApiStructure { - dbname: string; - anonRole: string; - roleName: string; - schemaNames: SchemaNodes; - schemaNamesFromExt: SchemaNodes; - apiModules: ApiModuleNodes; - rlsModule?: RlsModule; - database?: Database; - databaseId?: string; - isPublic?: boolean; -} - -export interface ServiceData { - api: OldApiStructure; -} - -export interface Service { - data: ServiceData; -} - -export interface ApiStructure { - dbname: string; - anonRole: string; - roleName: string; - schema: string[]; - apiModules: ApiModule[]; - rlsModule?: RlsModule; - domains?: string[]; - databaseId?: string; - isPublic?: boolean; -} - declare module 'express-serve-static-core' { interface Request { api: { From f8015751308f0a4649395d4f3d07fc8aca98f434 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 27 May 2025 08:12:25 +0000 Subject: [PATCH 5/6] refactor: move req object and ApiModule to server/src/types Co-Authored-By: Dan Lynch --- packages/server/src/middleware/cors.ts | 2 +- packages/server/src/types.ts | 63 +++++++++++++++++++++++++- packages/types/src/launchql.ts | 60 ------------------------ 3 files changed, 63 insertions(+), 62 deletions(-) diff --git a/packages/server/src/middleware/cors.ts b/packages/server/src/middleware/cors.ts index ff9d2a3f59..0fce6126d1 100644 --- a/packages/server/src/middleware/cors.ts +++ b/packages/server/src/middleware/cors.ts @@ -1,7 +1,7 @@ import corsPlugin from 'cors'; import { parseUrl } from '@launchql/url-domains'; import { Request, Response, NextFunction } from 'express'; -import { CorsModuleData } from '@launchql/types'; +import { CorsModuleData } from '../types'; export const cors = async (req: Request, res: Response, next: NextFunction) => { const api = req.api; diff --git a/packages/server/src/types.ts b/packages/server/src/types.ts index cc17ee7754..6db8e24a23 100644 --- a/packages/server/src/types.ts +++ b/packages/server/src/types.ts @@ -1,4 +1,65 @@ -import { ApiModule, RlsModule } from '@launchql/types'; +import { PostGraphileOptions } from 'postgraphile'; +import type { Plugin } from 'graphile-build'; + +export interface CorsModuleData { + urls: string[]; +} + +export interface PublicKeyChallengeData { + schema: string; + crypto_network: string; + sign_up_with_key: string; + sign_in_request_challenge: string; + sign_in_record_failure: string; + sign_in_with_challenge: string; +} + +export interface GenericModuleData { + [key: string]: any; +} + +export type ApiModule = + | { name: 'cors'; data: CorsModuleData } + | { name: 'pubkey_challenge'; data: PublicKeyChallengeData } + | { name: string; data?: GenericModuleData }; + +export interface RlsModule { + authenticate?: string; + authenticateStrict?: string; + privateSchema: { + schemaName: string; + }; +} + +declare module 'express-serve-static-core' { + interface Request { + api: { + dbname: string; + anonRole: string; + roleName: string; + schema: string[]; // Pre-processed schema names + apiModules: ApiModule[]; + rlsModule?: { + authenticate?: string; + authenticateStrict?: string; + privateSchema: { + schemaName: string; + }; + }; + domains?: string[]; // Simplified from database.sites.nodes + databaseId?: string; + isPublic?: boolean; + }; + svc_key: string; + clientIp?: string; + databaseId?: string; + token?: { + id: string; + user_id: string; + [key: string]: any; + }; + } +} export interface SchemaNode { schemaName: string; diff --git a/packages/types/src/launchql.ts b/packages/types/src/launchql.ts index 5809fcbbb6..d8d076419b 100644 --- a/packages/types/src/launchql.ts +++ b/packages/types/src/launchql.ts @@ -2,66 +2,6 @@ import { PostGraphileOptions } from 'postgraphile'; import type { Plugin } from 'graphile-build'; import { execSync } from 'child_process'; -export interface CorsModuleData { - urls: string[]; -} - -export interface PublicKeyChallengeData { - schema: string; - crypto_network: string; - sign_up_with_key: string; - sign_in_request_challenge: string; - sign_in_record_failure: string; - sign_in_with_challenge: string; -} - -export interface GenericModuleData { - [key: string]: any; -} - -export type ApiModule = - | { name: 'cors'; data: CorsModuleData } - | { name: 'pubkey_challenge'; data: PublicKeyChallengeData } - | { name: string; data?: GenericModuleData }; - -export interface RlsModule { - authenticate?: string; - authenticateStrict?: string; - privateSchema: { - schemaName: string; - }; -} - -declare module 'express-serve-static-core' { - interface Request { - api: { - dbname: string; - anonRole: string; - roleName: string; - schema: string[]; // Pre-processed schema names - apiModules: ApiModule[]; - rlsModule?: { - authenticate?: string; - authenticateStrict?: string; - privateSchema: { - schemaName: string; - }; - }; - domains?: string[]; // Simplified from database.sites.nodes - databaseId?: string; - isPublic?: boolean; - }; - svc_key: string; - clientIp?: string; - databaseId?: string; - token?: { - id: string; - user_id: string; - [key: string]: any; - }; - } -} - export interface PgConfig { host: string; port: number; From a139fb64ba6594bb127d68341b5233d726ca3c8d Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 27 May 2025 21:24:10 +0000 Subject: [PATCH 6/6] refactor: flatten apiModules structure by removing nested nodes property Co-Authored-By: Dan Lynch --- packages/server/src/middleware/api.ts | 6 +++--- packages/server/src/middleware/gql.ts | 14 +++++--------- packages/server/src/types.ts | 10 +--------- 3 files changed, 9 insertions(+), 21 deletions(-) diff --git a/packages/server/src/middleware/api.ts b/packages/server/src/middleware/api.ts index a81b037e13..68e53f7150 100644 --- a/packages/server/src/middleware/api.ts +++ b/packages/server/src/middleware/api.ts @@ -39,7 +39,7 @@ const transformServiceToApi = (svc: Service): ApiStructure => { anonRole: api.anonRole, roleName: api.roleName, schema: [...schemaNames, ...additionalSchemas], - apiModules: api.apiModules?.nodes || [], + apiModules: api.apiModules || [], rlsModule: api.rlsModule, domains, databaseId: api.databaseId, @@ -115,7 +115,7 @@ const getHardCodedSchemata = ({ .map((schemaName) => ({ schemaName })) }, schemaNames: { nodes: [] as Array<{ schemaName: string }> }, - apiModules: { nodes: [] as Array } + apiModules: [] as Array } } }; @@ -145,7 +145,7 @@ const getMetaSchema = ({ nodes: schemata.map((schemaName: string) => ({ schemaName })) }, schemaNames: { nodes: [] as Array<{ schemaName: string }> }, - apiModules: { nodes: [] as Array } + apiModules: [] as Array } } }; diff --git a/packages/server/src/middleware/gql.ts b/packages/server/src/middleware/gql.ts index 651778c18f..66fe68bd2b 100644 --- a/packages/server/src/middleware/gql.ts +++ b/packages/server/src/middleware/gql.ts @@ -45,10 +45,8 @@ export const ApiQuery = gql` } } # for now keep this for patches apiModules { - nodes { - name - data - } + name + data } } } @@ -96,10 +94,8 @@ export const ApiByNameQuery = gql` } } # for now keep this for patches apiModules { - nodes { - name - data - } + name + data } } } @@ -125,4 +121,4 @@ export const ListOfAllDomainsOfDb = gql` } } } -`; \ No newline at end of file +`; diff --git a/packages/server/src/types.ts b/packages/server/src/types.ts index 6db8e24a23..85691e95b5 100644 --- a/packages/server/src/types.ts +++ b/packages/server/src/types.ts @@ -90,14 +90,6 @@ export interface Database { sites: SiteNodes; } -export interface ApiModuleNode { - name: string; - data?: any; -} - -export interface ApiModuleNodes { - nodes: ApiModuleNode[]; -} export interface OldApiStructure { dbname: string; @@ -105,7 +97,7 @@ export interface OldApiStructure { roleName: string; schemaNames: SchemaNodes; schemaNamesFromExt: SchemaNodes; - apiModules: ApiModuleNodes; + apiModules: ApiModule[]; rlsModule?: RlsModule; database?: Database; databaseId?: string;