/** * Configuration management for Manifest CLI * * Handles loading, creating, and validating manifest.config.yaml and manifest.config.ts * * Config precedence: manifest.config.ts > manifest.config.js > manifest.config.yaml * * YAML config: Build-level settings (src, output, projections) * TS/JS config: Runtime bindings (stores, resolveUser) */ /** * Build-level configuration (YAML-based) * * These settings control compilation and code generation. */ export interface ManifestConfig { $schema?: string; src?: string; output?: string; prismaSchema?: string; /** Config G2 — CI exit policy + optional additive rule registry. */ validation?: { failOn?: 'block' | 'warn' | 'never'; rules?: { 'missing-policy'?: 'off' | 'warn' | 'error'; 'unused-entity'?: 'off' | 'warn' | 'error'; 'orphan-relationship'?: 'off' | 'warn' | 'error'; }; }; /** * Config G3 — multi-module merge collision policy for `compile --merge` / * `compile --all`. Default is strict `error` on duplicate names. */ mergeIntegrity?: { onDuplicateEntity?: 'error' | 'lastWins'; onDuplicateCommand?: 'error' | 'lastWins'; moduleOrder?: 'lexicographic'; allowCrossModuleRefs?: boolean; forbidCycles?: boolean; }; /** * Config G4 — IR provenance policy (deterministic stamps + optional lockfile). */ provenance?: { stamp?: boolean; fields?: Array<'sourceHash' | 'generatorVersion' | 'irSchemaVersion' | 'gitSha'>; deterministic?: boolean; lockfile?: string; failIfStale?: boolean; }; /** * Config G7 — central runtime knobs for generate (executionMode + * determinism.deterministicMode + stores → runtimeConfigImport). */ runtime?: { executionMode?: 'inline' | 'externalExecutor'; determinism?: { deterministicMode?: boolean; forbidWallClock?: boolean; seed?: number; }; /** Fans into projection `runtimeConfigImport` when unset. */ stores?: string; /** Merged under createManifestRuntime caller context (caller wins). */ defaultContext?: Record; }; /** Config G10 — declarative CI drift gates for `manifest ci-gate`. */ driftGates?: { effectiveConfigSnapshot?: string; failOnConfigDrift?: boolean; failOnGeneratedDrift?: boolean; pinIrSchemaVersion?: string; }; projections?: { /** When set, `manifest generate --all` runs only these projection names. */ enabled?: string[]; /** Shared options merged under each projection's own `options`. */ defaults?: Record; [name: string]: { output?: string; options?: Record; } | string[] | Record | undefined; }; /** * Identifier naming policy. Legacy: `'snake_case'` / `{ table, column, * pluralizeTables }`. Expanded: `{ normalization?: boolean, entities?, … }`. */ naming?: 'snake_case' | { table?: 'snake_case' | 'camelCase' | 'PascalCase' | 'preserve'; column?: 'snake_case' | 'camelCase' | 'preserve'; pluralizeTables?: boolean; } | Record; /** Environment variable mapping for store/auth/adapter configuration */ env?: EnvMapping; /** * Git pre-commit (`manifest install-hooks`) plus Config G8 build lifecycle * (`hooks.lifecycle.beforeCompile` / `afterGenerate`). */ hooks?: { skipInCi?: boolean; provider?: 'husky' | 'simple-git-hooks'; runFmt?: boolean; runValidate?: boolean; lifecycle?: { beforeCompile?: string[]; afterGenerate?: string[]; }; }; /** Optional: Plugin declarations for third-party extensions */ plugins?: Array<{ /** npm package name or relative file path. */ module: string; /** Plugin-specific options. */ options?: Record; /** Whether the plugin is active (default: true). */ enabled?: boolean; /** Config G9 — load priority (lower first). */ order?: number; /** Config G9 — capability tags. */ capabilities?: string[]; }>; } /** Single environment variable definition in manifest.config.yaml */ export interface EnvVarDefinition { name: string; description?: string; required?: boolean; default?: string; example?: string; } /** Environment variable mapping grouped by category */ export interface EnvMapping { stores?: Record; auth?: Record; adapters?: Record; custom?: Record; } /** * Store binding configuration for an entity */ export interface StoreBinding { /** Store implementation class or factory function */ implementation: unknown; /** Optional: Prisma model name for property alignment checks */ prismaModel?: string; /** Optional: Property mapping (manifest property -> database column) */ propertyMapping?: Record; } /** * User context resolved from authentication */ export interface UserContext { id: string; role?: string; tenantId?: string; [key: string]: unknown; } /** * Authentication context from request */ export interface AuthContext { userId?: string; claims?: Record; headers?: Record; [key: string]: unknown; } /** * Runtime-level configuration (TypeScript-based) * * These settings control store bindings and user resolution at runtime. */ export interface ManifestRuntimeConfig { /** * Store implementation bindings per entity * * Example: * ```ts * stores: { * User: { implementation: PrismaUserStore, prismaModel: 'User' }, * Order: { implementation: PrismaOrderStore, prismaModel: 'orders' }, * } * ``` */ stores?: Record; /** * User resolution function * * Called by generated routes to extract user context from authentication. * This eliminates per-route user context boilerplate. * * Example: * ```ts * resolveUser: async (auth) => { * const session = await getSession(auth.headers); * return { id: session.userId, role: session.role, tenantId: session.orgId }; * } * ``` */ resolveUser?: (auth: AuthContext) => Promise; /** * Build-level settings (shared with YAML config) */ build?: ManifestConfig; } /** * Combined configuration (build + runtime) */ export interface CombinedConfig { build: ManifestConfig; runtime: ManifestRuntimeConfig | null; } /** * Merge build config from runtime config with YAML config * Runtime config's build settings take precedence over YAML. * * Exported so tests can exercise the exact YAML+TS merge that `loadAllConfigs` * feeds to `validateConfig` (a `.ts` config's `build` block is validated by the * same JSON schema as YAML). */ export declare function mergeBuildConfig(yamlConfig: ManifestConfig | null, runtimeBuildConfig: ManifestConfig | undefined): ManifestConfig; /** * Find and load all configuration files * * Returns both build (YAML) and runtime (TS/JS) configs separately. */ export declare function loadAllConfigs(cwd?: string): Promise; /** * Load only the YAML configuration (backward compatible) */ export declare function loadConfig(cwd?: string): Promise; /** * Get config with defaults applied (backward compatible) * * For new code, prefer loadAllConfigs() which includes runtime config. */ export declare function getConfig(cwd?: string): Promise; /** * Get the runtime configuration */ export declare function getRuntimeConfig(cwd?: string): Promise; /** * Save config to YAML file * * Note: This only saves build-level settings to YAML. * Runtime config (TS/JS) must be managed manually. */ export declare function saveConfig(config: ManifestConfig, cwd?: string, options?: { dryRun?: boolean; }): Promise; /** * Check if any config file exists (YAML or TS/JS) */ export declare function configExists(cwd?: string): Promise; /** * Check which config file is being used */ export declare function getActiveConfigPath(cwd?: string): Promise; /** * Get Next.js projection options from config. * * Legacy partial-shape getter retained for back-compat with internal call * sites. New code should prefer `resolveNextJsProjectionOptions`, which * returns the full NextJsProjectionOptions surface (including dispatcher * and concreteCommandRoutes) and never invents defaults — the projection * applies them itself from src/manifest/projections/nextjs/defaults.ts. */ export declare function getNextJsOptions(cwd?: string): Promise<{ authProvider: string; authImportPath: string; databaseImportPath: string; runtimeImportPath: string; responseImportPath: string; includeTenantFilter: boolean; includeSoftDeleteFilter: boolean; tenantIdProperty: string; deletedAtProperty: string; appDir: string; }>; /** * Resolve the full Next.js projection options object from a manifest * config, without applying defaults. * * The returned shape is the user-supplied subset of NextJsProjectionOptions * (typed as `Record` here to avoid pulling the main * package's types into the CLI). The projection's `normalizeOptions` is * responsible for filling unset keys from NEXTJS_DEFAULTS / DISPATCHER_DEFAULTS * / CONCRETE_COMMAND_ROUTES_DEFAULTS so there is exactly one defaults source. * * Returning the raw user shape lets the CLI layer it under CLI flag * overrides (--auth, --database, etc.) before passing to the projection. */ export declare function resolveNextJsProjectionOptions(cwd?: string): Promise>; /** * Layer the build-level global `naming` convention UNDER a named projection's * own `options` (per-projection `options.naming` always wins). Delegates to the * main package's `resolveProjectionOptions` so this stays the single inheritance * contract shared with the projection dispatchers — the CLI never reimplements * the merge. * * Synchronous variant for callers that already hold a loaded build config (e.g. * the batch `generate --all` driver, which resolves many projections in a loop). */ export declare function layerProjectionOptions(build: ManifestConfig, projectionName: string): Record; /** * Resolve the option bag for ANY projection from manifest.config — the * single-run analogue of the `--all` batch path. Reads that projection's own * `options` block (not nextjs-only) and layers the global `naming` default * under it. CLI flag overrides (--auth, --database, …) are applied on top later * inside `generateCommand`. */ export declare function resolveProjectionOptions(projectionName: string, cwd?: string): Promise>; /** * Get output paths from config */ export declare function getOutputPaths(cwd?: string): Promise<{ irOutput: string; codeOutput: string; }>; /** * Store interface matching runtime-engine.ts */ export interface Store { getAll(): Promise; getById(id: string): Promise; create(data: Partial): Promise; update(id: string, data: Partial): Promise; delete(id: string): Promise; clear(): Promise; } /** * Store provider function type matching runtime-engine.ts RuntimeOptions */ export type StoreProvider = (entityName: string) => Store | undefined; /** * Create a store provider function from runtime config * * This enables config-driven store binding for the runtime engine. * The returned function can be passed as `storeProvider` option to RuntimeEngine. * * @example * ```typescript * // manifest.config.ts * export default { * stores: { * User: { implementation: PrismaUserStore }, * Order: { implementation: new PostgresStore({ tableName: 'orders' }) }, * } * } * * // In your application * const config = await getRuntimeConfig(); * const storeProvider = createStoreProvider(config); * const runtime = new RuntimeEngine(ir, context, { storeProvider }); * ``` */ export declare function createStoreProvider(config: ManifestRuntimeConfig | null): StoreProvider; /** * Clear the store cache (useful for testing) */ export declare function clearStoreCache(): void; /** * Get store bindings info for validation/scanning * * Returns information about configured stores without instantiating them. */ export declare function getStoreBindingsInfo(config: ManifestRuntimeConfig | null): { entityNames: string[]; hasStore: (entityName: string) => boolean; getPrismaModel: (entityName: string) => string | undefined; getPropertyMapping: (entityName: string) => Record | undefined; }; /** * Create a user resolver function from runtime config. * Same fail-soft contract as `@angriff36/manifest/config` `createUserResolver` * (errors → null). Generated runtime factories embed an equivalent inline helper * when `runtimeConfigImport` is set. * * @example * ```typescript * const resolver = createUserResolver(config); * const user = await resolver({ userId: session.user.id, headers: request.headers }); * ``` */ export declare function createUserResolver(config: ManifestRuntimeConfig | null): (auth: AuthContext) => Promise; /** * Check if a runtime config has user resolution configured */ export declare function hasUserResolver(config: ManifestRuntimeConfig | null): boolean; /** * Represents a field in a Prisma model */ export interface PrismaField { name: string; type: string; isOptional: boolean; isList: boolean; isId: boolean; isGenerated: boolean; defaultValue?: unknown; } /** * Represents a Prisma model extracted from a schema */ export interface PrismaModel { name: string; fields: PrismaField[]; } /** * Parsed Prisma schema */ export interface PrismaSchema { models: PrismaModel[]; datasources?: Array<{ name: string; url: string; }>; } /** * Find Prisma schema file in the project * * Searches in order: * 1. Config-specified path: config.build.prismaSchema * 2. Default: prisma/schema.prisma * 3. Alternative: schema.prisma */ export declare function findPrismaSchemaPath(cwd: string, config: ManifestConfig | null): Promise; /** * Parse a Prisma schema file and extract models and fields * * This is a simple parser that handles common Prisma schema patterns. * It extracts model names and their field definitions. */ export declare function parsePrismaSchema(schemaPath: string): Promise; /** * Get Prisma model by name (case-insensitive search) */ export declare function getPrismaModel(schema: PrismaSchema, modelName: string): PrismaModel | undefined; /** * Check if a property exists in a Prisma model * Considers both exact name and property mapping */ export declare function propertyExistsInModel(model: PrismaModel, propertyName: string, propertyMapping?: Record): boolean; /** * Get Prisma field names for a model */ export declare function getPrismaFieldNames(model: PrismaModel): string[]; //# sourceMappingURL=config.d.ts.map