/** * PZG Pro - Policies Generator (DMMF-based) * * Generate field-level security and PII redaction from DMMF data with comment annotations */ import { DMMF } from '@prisma/generator-helper'; import { ProFeatureBase } from '../../core/ProFeatureBase'; import { ProGeneratorContext } from '../../core/ProGeneratorContext'; export interface PolicyConfig { outputPath?: string; enableRedaction?: boolean; enableRLS?: boolean; roles?: string[]; } export interface PolicyRule { type: 'read' | 'write' | 'deny' | 'update' | 'delete' | 'create'; subtype?: 'where' | 'fields' | 'values'; condition: string; field?: string; fields?: string[]; modelName?: string; operator?: 'in' | 'not_in' | 'equals' | 'not_equals' | 'contains' | 'starts_with' | 'ends_with' | '==' | '!='; contextVariable?: string; } export interface PIIRule { type: 'pii'; dataType: 'email' | 'phone' | 'ssn' | 'credit_card' | 'custom'; redactLogs?: boolean; maskType?: 'partial' | 'full' | 'hash'; field?: string; modelName?: string; } export interface ModelPolicies { modelName: string; model: DMMF.Model; policies: PolicyRule[]; piiRules: PIIRule[]; } export declare class PoliciesGenerator extends ProFeatureBase { private config; constructor(context: ProGeneratorContext, config?: PolicyConfig); protected getFeatureName(): string; protected generateFeature(): Promise; /** * Report policies that were parsed but cannot be enforced. * * The annotation parser accepts any text after `read:where`, while the generated evaluator * implements exactly three condition forms. A condition outside that set used to be parsed, * emitted, iterated over at query time and then ignored, leaving the query unscoped — a security * annotation that reads as active in the schema and does nothing. The generated code now refuses * such a condition at runtime, but a build-time warning is the useful half: it names the model and * the condition while someone is still editing the schema, rather than at the first query. * * `fields` and `values` subtypes are listed separately. They parse, and nothing in this pack * implements them, so they are silently inert rather than misinterpreted. */ private warnAboutUnenforceablePolicies; /** * Extract policy and PII annotations from DMMF models */ private extractModelPolicies; /** * Extract policy rules from model and field documentation */ private extractModelPolicyRules; /** * Extract PII rules from model and field documentation */ private extractModelPIIRules; /** * Parse policy annotation text into PolicyRule */ private parsePolicyAnnotation; /** * Parse PII annotation text into PIIRule */ private parsePIIAnnotation; /** * Generate policy files for a model */ private generateModelPolicyFiles; /** * Generate safe CRUD module for a model */ private generateSafeCRUDModule; /** * Generate redaction middleware for a model */ private generateRedactionMiddleware; /** * Generate DTO schemas for a model */ private generateDTOSchemas; /** * Get Zod type for a DMMF field */ private getZodTypeForField; /** * Get Zod scalar type */ private getZodScalarType; /** * Generate PII exclusions for public schema */ private generatePIIExclusions; /** * Generate role-based exclusions */ private generateRoleBasedExclusions; /** * Generate index files */ /** * The only pack that shipped no documentation at all. * * That matters more here than elsewhere, because none of this API is guessable: SafeCRUD takes a * context on the constructor *and* on every call, redaction is per model with a channel argument, * and the convenience `redactPII` export deliberately throws. Reading the generated code to work * that out is not a reasonable ask of someone who paid for the pack. */ private generatePoliciesReadme; private generateIndexFiles; }