/** * File Loader * * Loads configuration and feature definitions from disk. * This is CLI-side only - reads files and prepares them for the API. * * Loads defineTable() definitions from *.ts feature files. */ /** * Report a typescript module that can't parse — once per process. * * The fallback is a REGEX table detector feeding schema sync, firewall * analysis, masking detection and migration generation. Degrading quietly * there means shipping security-pillar analysis from a weaker parser with one * scrollback line as the only evidence, so `QUICKBACK_STRICT_PARSE=1` turns it * into a hard failure for CI. An env var rather than a flag: it needs to reach * every command that loads features without threading a parameter through all * of them, and CI is where it matters. */ export declare function reportUnusableTypescript(version: string | null): void; /** Exported for tests, like `parseTableDefinitionsWithRegex` below it. */ export declare function parseTableDefinitions(source: string): Promise<{ tableNames: string[]; hasResourceConfig: boolean; }>; /** * Fallback used when no TypeScript compiler API is available. Matches * pgTable / sqliteTable / q.table export shapes. Exported for tests: this * path must stay in step with the AST path above, and it once silently * dropped all but the first table export per file. */ export declare function parseTableDefinitionsWithRegex(source: string): { tableNames: string[]; hasResourceConfig: boolean; }; export interface LoadedConfig { name: string; preset: string; template?: string; providers?: any; build?: { outputDir?: string; }; features?: { organizations?: boolean; pinnedOrganizationId?: string; }; schemaRegistry?: { generate?: boolean; }; openapi?: { generate?: boolean; publish?: boolean; }; [key: string]: unknown; } /** * A table definition from a single file using defineTable() */ export interface LoadedTableDefinition { /** Original filename, e.g., "claims.ts", "claim-versions.ts" */ fileName: string; /** Export name (camelCase), e.g., "claims", "claimVersions" */ tableName: string; /** Full file source code */ source: string; /** Has defineTable default export (generates routes) */ hasResourceConfig: boolean; } /** * A page definition from features/{feature}/pages/*.ts */ export interface LoadedPageDefinition { /** File name (e.g., "bank-reconciliation.ts") */ fileName: string; /** Page slug (from definePage) */ slug: string; /** Feature this page belongs to */ feature: string; /** Page title */ title: string; /** Full source code */ source: string; } /** * A loaded feature containing one or more tables. * * Action authoring uses the one-file-per-action shape exclusively: every * action lives in `/actions/.ts` (or * `/actions//.ts` for multi-table features) and is * AST-parsed compiler-side via the feature-walker discovery + per-action * parser. The legacy `defineActions(...)` / `actions.ts` / `_feature.ts` / * `handlers/` shapes are retired; the loader rejects them at discovery * time with a migration error. */ export interface LoadedFeature { name: string; /** * Ancestor AREA directory names, outermost first (feature areas). E.g. * `['events']` for `features/events/travel/`. Absent for top-level flat * features. Feature identity stays the LEAF folder name. */ areaPath?: string[]; /** * The AUTHORED feature directory relative to `featuresDir`, POSIX-normalized, * exactly as discovered on disk (e.g. `todos` for a flat feature, `events` * for an area folder that is itself a feature, `events/conversations` for a * leaf nested under an area). This is the source-lookup path — distinct from * `name`, which stays the global LEAF identity and drives the compiler * staging key. Consumers that reconstruct an on-disk source path (notably the * v2 action-schema harvest) MUST use this, not `name`, or nested-area actions * resolve to a directory that does not contain the file. */ sourceDir?: string; /** Primary schema (first table with defineTable) */ schema: { tableName: string; columns: Record; source: string; }; /** All tables in this feature */ tables?: LoadedTableDefinition[]; resource?: any; resourceSource?: string; /** * One file per action, AST-parsed by the compiler. Keyed by relative path * from the feature root, e.g. `actions/advance.ts` or * `actions/profiles/publish.ts`. Each file is `export default defineAction(...)`. */ actionFiles?: Record; /** * Feature-local `/lib/` files keyed by relative path * (e.g. `lib/inputs.ts`). Copied verbatim into the generated output; * action files import them via `../lib/...`. */ featureLibFiles?: Record; /** Page definitions from pages/ subdirectory */ pageFiles?: LoadedPageDefinition[]; } /** * Queue handler definition from services/queues/*.ts */ export interface LoadedQueueHandler { /** File name (e.g., "ingest.ts") */ fileName: string; /** Handler name (from defineQueue) */ name: string; /** Message type to match */ messageType: string; /** Full source code */ source: string; } export interface LoadedScheduleHandler { /** File name (e.g., "sweepDigests.ts") */ fileName: string; /** Handler name (from defineSchedule) */ name: string; /** Cron pattern (from defineSchedule) */ cron: string; /** Full source code */ source: string; } export interface LoadedEmailHandler { /** File name (e.g., "inbound.ts") */ fileName: string; /** Handler name (from defineEmail) */ name: string; /** Optional envelope recipient (from defineEmail `to`) */ to?: string; /** Full source code */ source: string; } /** * Realtime definition from services/realtime/*.ts */ export interface LoadedRealtimeDefinition { /** File name (e.g., "extraction.ts") */ fileName: string; /** Namespace name (from defineRealtime) */ name: string; /** Event names */ events: string[]; /** Full source code */ source: string; } /** * Embedding definition from services/embeddings/*.ts */ export interface LoadedEmbeddingDefinition { /** File name (e.g., "claim-similarity.ts") */ fileName: string; /** Config name (from defineEmbedding) */ name: string; /** Source table */ source: string; /** Full source code */ sourceCode: string; } /** * Live view definition from services/views/*.ts (defineView) */ export interface LoadedViewDefinition { /** File name (e.g., "person-detail.ts") */ fileName: string; /** View name (from defineView) */ name: string; /** Root table name */ root: string; /** Full source code */ source: string; } /** * Services definitions */ export interface LoadedServices { queues?: LoadedQueueHandler[]; schedules?: LoadedScheduleHandler[]; email?: LoadedEmailHandler[]; realtime?: LoadedRealtimeDefinition[]; embeddings?: LoadedEmbeddingDefinition[]; views?: LoadedViewDefinition[]; } /** * Load quickback.config.ts from disk */ export declare function loadConfig(configPath: string): Promise; /** * One `_area.ts` node discovered under features/ (feature areas). * `definition` is the executed default export of the file — the same * passthrough-stub treatment `quickback.config.ts` gets; the compiler * validates the transported definition server-side. */ export interface LoadedArea { /** Folder names from features/ down to the area, e.g. ['events']. */ dirPath: string[]; definition: Record; } export interface LoadedFeatureTree { features: LoadedFeature[]; areas: LoadedArea[]; } /** * Load all features from quickback/features/ — RECURSIVE tree walk * (feature areas). A directory carrying `_area.ts` is an AREA: it may * itself be a feature (root tables + actions/) and every unreserved child * directory is a child feature (or a child area — arbitrary depth). A * directory WITHOUT `_area.ts` is a leaf feature; its unreserved subdirs * are NOT loaded — a subdir carrying defineTable(...)/defineAction(...) * fails the load (silent route/table disappearance after a mis-move is the * worst failure mode areas can introduce). * * Feature leaf names must be unique project-wide (they key generated * src/features// paths). * * After each feature loads, conflicts are batched and thrown as one error * block — keeps migration of an existing project to a single round-trip * instead of N. */ export declare function loadFeatures(featuresDir: string): Promise; /** * Find the config file path */ export declare function findConfigPath(startDir?: string): Promise; /** * Find the features directory */ export declare function findFeaturesDir(projectRoot?: string): Promise; /** * Load project-level shared lib at `quickback/lib/`. * * Cross-feature TypeScript that any feature can import via the `~/lib/*` * alias. Returns relative paths keyed from `lib/` (e.g. `lib/inputs.ts`) * with their source contents. Empty object when the directory is missing. * * Discipline (enforced compiler-side, not here): files in `quickback/lib/` * must not import from `quickback/features/`. Keeps lib genuinely shared * and cycle-free. */ export declare function loadProjectLib(projectRoot: string): Promise>; /** * Load project-level auth hooks from `quickback/hooks/`. * * Flat one-file-per-event convention matching `services/queues/`, * `services/realtime/`, `services/embeddings/`. Filename grammar: * `(before|after)--.ts` where (subject, verb) is one of * the recognized Better Auth `databaseHooks` paths. Returns relative * paths keyed from `hooks/` (e.g. `hooks/after-user-create.ts`) with * their source contents. Empty object when the directory is missing. * * Throws on unknown filenames so projects fail compile-fast on typos. */ export declare function loadProjectHooks(projectRoot: string): Promise>; /** * Load user-authored Better Auth plugin source files from `quickback/plugins/`. * * Each `.ts` file is uploaded to the compiler verbatim. Files only flow * through the build when referenced from a `customPlugins[].from` entry on * the auth config — unreferenced files are quietly ignored server-side. * * Returns relative paths keyed from `plugins/` (e.g. `plugins/long-session.ts`), * matching the path the BA provider rewrites imports against. */ export declare function loadProjectPlugins(projectRoot: string): Promise>; /** * Load project-supplied email templates from `quickback/email-templates/`. * * Referenced from `defineAuth("better-auth", { plugins: { emailOtp: { templates: { 'forget-password': './email-templates/...' } } } })`. * Each `.ts` file is uploaded verbatim; the better-auth provider stages * referenced files into `src/email-templates/.ts` and emits the * default import in `src/lib/auth.ts`. Files not referenced by any * template entry are ignored — the CLI uploads the directory, the * compiler picks only what's needed. * * Returns relative paths keyed from `email-templates/` (e.g. * `email-templates/welcome.ts`), matching the path the BA provider * rewrites imports against. */ export declare function loadProjectEmailTemplates(projectRoot: string): Promise>; /** * Load project-level Hono middlewares from `quickback/middlewares/`. * * v0.19+: declarative cross-cutting slot for non-authz middleware (request * logging, debug headers, response transforms). Each `.ts` file is uploaded * verbatim; the compiler mounts them via `app.use('*', mw)` between * platform middleware (auth/db/services) and route registration. * * Returns relative paths keyed from `middlewares/` (e.g. * `middlewares/request-logger.ts`), matching the path the compiler emits * into the generated `src/middlewares/` directory. */ export declare function loadProjectMiddlewares(projectRoot: string): Promise>; /** * Find the services directory */ export declare function findServicesDir(projectRoot?: string): Promise; /** * Load all services from definitions/services/ */ export declare function loadServices(servicesDir: string): Promise; /** * Keep journals and non-snapshot metadata, but upload only Drizzle's latest * full-schema snapshot. Forward generation diffs against that one snapshot; * older snapshots are cumulative history and otherwise make every compile * payload grow linearly with migration count. */ export declare function selectDrizzleMetaFilesForUpload(files: string[]): string[]; /** * Load existing drizzle migration state (historical SQL + journal + latest * cumulative snapshot) so the compiler can generate incremental migrations * (ALTER vs CREATE) and run provider-specific safety passes against historical * SQL without re-uploading every full-schema snapshot. * * Migration state lives in ONE place: `/quickback/drizzle/...`. * Quickback owns this state — it's never mirrored to or read from a * project-root `drizzle/` folder. * * The keys returned include the `quickback/` prefix so the server stages * the files at the same on-disk path that drizzle.config.ts's `out:` * resolves to (`/output/quickback/drizzle//...`). Without that * alignment, drizzle-kit can't find existing journals on recompile and * provider hooks cannot sanitize historical migrations already checked into * the project tree. */ export declare function loadDrizzleMeta(projectRoot: string): Promise | undefined>; //# sourceMappingURL=file-loader.d.ts.map