@514labs/moose-lib 0.6.446 → 0.6.447

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/compilerPlugin.ts","../src/compilerPluginHelper.ts","../src/dmv2/dataModelMetadata.ts","../src/dataModels/typeConvert.ts","../src/dataModels/enumConvert.ts","../src/dataModels/dataModelTypes.ts","../src/dataModels/types.ts","../src/utilities/json.ts","../src/typiaDirectIntegration.ts","../src/consumption-apis/typiaValidation.ts","../src/commons.ts"],"sourcesContent":["import ts, { factory } from \"typescript\";\nimport {\n createTransformer,\n type TransformContext,\n} from \"./compilerPluginHelper\";\nimport {\n isNewMooseResourceWithTypeParam,\n transformNewMooseResource,\n} from \"./dmv2/dataModelMetadata\";\nimport { isApiV2, transformApiV2 } from \"./consumption-apis/typiaValidation\";\nimport { createTypiaContext } from \"./typiaDirectIntegration\";\nimport { compilerLog } from \"./commons\";\n\n/**\n * Applies the appropriate transformation based on node type\n */\nconst applyTransformation = (\n node: ts.Node,\n ctx: TransformContext,\n): ts.Node | undefined => {\n if (isApiV2(node, ctx.typeChecker)) {\n compilerLog(\"[CompilerPlugin] Found API v2, transforming...\");\n return transformApiV2(node, ctx.typeChecker, ctx);\n }\n\n if (isNewMooseResourceWithTypeParam(node, ctx.typeChecker)) {\n compilerLog(\n \"[CompilerPlugin] Found Moose resource with type param, transforming...\",\n );\n return transformNewMooseResource(node, ctx.typeChecker, ctx);\n }\n\n return undefined;\n};\n\n/**\n * Main transformation function that processes TypeScript source files\n */\nconst transform =\n (typeChecker: ts.TypeChecker, program: ts.Program) =>\n (transformationContext: ts.TransformationContext) =>\n (sourceFile: ts.SourceFile): ts.SourceFile => {\n compilerLog(\n `\\n[CompilerPlugin] ========== Processing file: ${sourceFile.fileName} ==========`,\n );\n let transformationCount = 0;\n const typiaContext = createTypiaContext(\n program,\n transformationContext,\n sourceFile,\n );\n\n const ctx: TransformContext = {\n typeChecker,\n program,\n typiaContext,\n };\n\n const visitNode = (node: ts.Node): ts.Node => {\n const transformed = applyTransformation(node, ctx);\n if (transformed !== undefined) {\n transformationCount++;\n compilerLog(\n `[CompilerPlugin] Transformation #${transformationCount} applied at position ${node.pos}`,\n );\n }\n const result = transformed ?? node;\n return ts.visitEachChild(result, visitNode, transformationContext);\n };\n\n const transformedSourceFile = ts.visitEachChild(\n sourceFile,\n visitNode,\n transformationContext,\n );\n\n compilerLog(\n `[CompilerPlugin] Total transformations applied: ${transformationCount}`,\n );\n\n // Add imports from ImportProgrammer (for direct typia integration)\n const typiaImports = typiaContext.importer.toStatements();\n if (typiaImports.length === 0) {\n compilerLog(\n `[CompilerPlugin] ========== Completed processing ${sourceFile.fileName} (no import needed) ==========\\n`,\n );\n return transformedSourceFile;\n }\n\n compilerLog(\n `[CompilerPlugin] ========== Completed processing ${sourceFile.fileName} (with import) ==========\\n`,\n );\n return factory.updateSourceFile(\n transformedSourceFile,\n factory.createNodeArray([\n ...typiaImports,\n ...transformedSourceFile.statements,\n ]),\n );\n };\n\nexport default createTransformer(transform);\n","import ts from \"typescript\";\nimport path from \"path\";\nimport { PluginConfig, TransformerExtras } from \"ts-patch\";\nimport process from \"process\";\nimport fs from \"node:fs\";\n\nexport const isMooseFile = (sourceFile: ts.SourceFile): boolean => {\n const location: string = path.resolve(sourceFile.fileName);\n\n return (\n location.includes(\"@514labs/moose-lib\") ||\n // workaround for e2e test\n location.includes(\"packages/ts-moose-lib/dist\") ||\n // support local development with symlinked packages\n location.includes(\"packages/ts-moose-lib/src\")\n );\n};\n\nimport type { TypiaDirectContext } from \"./typiaDirectIntegration\";\n\n/**\n * Context passed to transformation functions\n */\nexport interface TransformContext {\n typeChecker: ts.TypeChecker;\n program: ts.Program;\n /** Shared typia context for direct code generation - created per-file */\n typiaContext: TypiaDirectContext;\n}\n\n/**\n * Creates a regular TypeScript transformer (not a program transformer).\n * This is simpler and works better with incremental compilation since\n * we're not replacing the entire program.\n */\nexport const createTransformer =\n (\n transform: (\n typeChecker: ts.TypeChecker,\n program: ts.Program,\n ) => (\n _context: ts.TransformationContext,\n ) => (sourceFile: ts.SourceFile) => ts.SourceFile,\n ) =>\n (\n program: ts.Program,\n _configOrHost: PluginConfig | ts.CompilerHost | undefined,\n _extrasOrConfig: TransformerExtras | PluginConfig,\n maybeProgramExtras?: unknown,\n ): ts.TransformerFactory<ts.SourceFile> => {\n // Detect if called with transformProgram: true (4 args) vs regular transformer (3 args)\n // transformProgram signature: (program, host, config, extras) => Program\n // regular signature: (program, config, extras) => TransformerFactory\n if (maybeProgramExtras !== undefined) {\n throw new Error(\n `[moose] Your tsconfig.json has \"transformProgram\": true for the moose plugin, ` +\n `but this version requires \"transformProgram\": false (or remove it entirely).\\n\\n` +\n `Update your tsconfig.json plugins section:\\n` +\n ` \"plugins\": [\\n` +\n ` { \"transform\": \"./node_modules/@514labs/moose-lib/dist/compilerPlugin.js\" },\\n` +\n ` { \"transform\": \"typia/lib/transform\" }\\n` +\n ` ]\\n\\n` +\n `Also remove \"isolatedModules\": true if present (incompatible with type-dependent transformations).`,\n );\n }\n\n const transformFunction = transform(program.getTypeChecker(), program);\n\n // Return a transformer factory\n return (context: ts.TransformationContext) => {\n return (sourceFile: ts.SourceFile) => {\n // Skip node_modules and declaration files\n const cwd = process.cwd();\n if (\n sourceFile.isDeclarationFile ||\n sourceFile.fileName.includes(\"/node_modules/\")\n ) {\n return sourceFile;\n }\n\n // Only transform files in the current project\n if (\n sourceFile.fileName.startsWith(\"/\") &&\n !sourceFile.fileName.startsWith(cwd)\n ) {\n return sourceFile;\n }\n\n // Apply transformation\n const result = transformFunction(context)(sourceFile);\n\n // Debug: write transformed source to .moose/api-compile-step/\n try {\n const printer = ts.createPrinter();\n const newFile = printer.printFile(result);\n const fileName =\n sourceFile.fileName.split(\"/\").pop() || sourceFile.fileName;\n const dir = `${process.cwd()}/.moose/api-compile-step/`;\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(`${dir}/${fileName}`, newFile);\n } catch (_e) {\n // this file is just for debugging purposes\n }\n\n return result;\n };\n };\n };\n\nexport const avoidTypiaNameClash = \"____moose____typia\";\n","import ts, { factory } from \"typescript\";\nimport { isMooseFile, type TransformContext } from \"../compilerPluginHelper\";\nimport { toColumns } from \"../dataModels/typeConvert\";\nimport {\n generateValidateFunction,\n generateIsFunction,\n generateAssertFunction,\n generateJsonSchemas,\n} from \"../typiaDirectIntegration\";\n\nconst typesToArgsLength = new Map([\n [\"OlapTable\", 2],\n [\"Stream\", 2],\n [\"DeadLetterQueue\", 2],\n [\"IngestPipeline\", 2],\n [\"IngestApi\", 2],\n [\"Api\", 2],\n [\"MaterializedView\", 1],\n [\"Task\", 2],\n]);\n\nexport const isNewMooseResourceWithTypeParam = (\n node: ts.Node,\n checker: ts.TypeChecker,\n): node is ts.NewExpression => {\n if (!ts.isNewExpression(node)) {\n return false;\n }\n\n const declaration: ts.Declaration | undefined =\n checker.getResolvedSignature(node)?.declaration;\n\n if (!declaration || !isMooseFile(declaration.getSourceFile())) {\n return false;\n }\n const sym = checker.getSymbolAtLocation(node.expression);\n const typeName = sym?.name ?? \"\";\n if (!typesToArgsLength.has(typeName)) {\n return false;\n }\n\n // Require arguments to be present\n if (!node.arguments) {\n return false;\n }\n\n const expectedArgLength = typesToArgsLength.get(typeName)!;\n const actualArgLength = node.arguments.length;\n\n // Check if this is an untransformed moose resource\n // Transformed resources have more arguments (schema, columns, validators, etc.)\n const isUntransformed =\n actualArgLength === expectedArgLength - 1 || // name only\n actualArgLength === expectedArgLength; // name + config\n\n return isUntransformed && node.typeArguments?.length === 1;\n};\n\nexport const parseAsAny = (s: string) =>\n factory.createAsExpression(\n factory.createCallExpression(\n factory.createPropertyAccessExpression(\n factory.createIdentifier(\"JSON\"),\n factory.createIdentifier(\"parse\"),\n ),\n undefined,\n [factory.createStringLiteral(s)],\n ),\n factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword),\n );\n\nexport const transformNewMooseResource = (\n node: ts.NewExpression,\n checker: ts.TypeChecker,\n ctx: TransformContext,\n): ts.Node => {\n const typeName = checker.getSymbolAtLocation(node.expression)!.name;\n\n const typeNode = node.typeArguments![0];\n\n // For IngestPipeline, check if table is configured in the config object\n // Index signatures are only allowed when table is false/not configured\n // (because OlapTable requires a fixed schema)\n let ingestPipelineHasTable = true; // Default to true (safe: disallows index signatures)\n if (\n typeName === \"IngestPipeline\" &&\n node.arguments &&\n node.arguments.length >= 2\n ) {\n const configArg = node.arguments[1];\n if (ts.isObjectLiteralExpression(configArg)) {\n const tableProperty = configArg.properties.find(\n (prop): prop is ts.PropertyAssignment =>\n ts.isPropertyAssignment(prop) &&\n ts.isIdentifier(prop.name) &&\n prop.name.text === \"table\",\n );\n if (tableProperty) {\n const tableValue = tableProperty.initializer;\n // Check if table value is explicitly false\n ingestPipelineHasTable = tableValue.kind !== ts.SyntaxKind.FalseKeyword;\n }\n // If table property is not found, keep default (true = has table)\n // This is the safe default since 'table' is a required property\n }\n }\n\n // Allow index signatures for IngestApi, Stream, and IngestPipeline (when table is not configured)\n // These resources accept arbitrary payload fields that pass through to streaming functions\n const allowIndexSignatures =\n [\"IngestApi\", \"Stream\"].includes(typeName) ||\n (typeName === \"IngestPipeline\" && !ingestPipelineHasTable);\n\n // Check if the type actually has an index signature\n const typeAtLocation = checker.getTypeAtLocation(typeNode);\n const indexSignatures = checker.getIndexInfosOfType(typeAtLocation);\n const hasIndexSignature = allowIndexSignatures && indexSignatures.length > 0;\n\n // Validate: IngestPipeline with table=true cannot have index signatures\n // because extra fields would be silently dropped when writing to ClickHouse\n if (\n typeName === \"IngestPipeline\" &&\n ingestPipelineHasTable &&\n indexSignatures.length > 0\n ) {\n throw new Error(\n `IngestPipeline cannot use a type with index signatures when 'table' is configured. ` +\n `Extra fields would be silently dropped when writing to the ClickHouse table. ` +\n `Either:\\n` +\n ` 1. Remove the index signature from your type to use a fixed schema, or\\n` +\n ` 2. Set 'table: false' in your IngestPipeline config if you only need the API and stream`,\n );\n }\n\n // Get the typia context for direct code generation\n const typiaCtx = ctx.typiaContext;\n\n let internalArguments: ts.Expression[];\n\n if (typeName === \"DeadLetterQueue\") {\n // DeadLetterQueue uses type guard (assert)\n internalArguments = [generateAssertFunction(typiaCtx, typeAtLocation)];\n } else {\n // Other resources use JSON schemas + columns\n internalArguments = [\n generateJsonSchemas(typiaCtx, typeAtLocation),\n parseAsAny(\n JSON.stringify(\n toColumns(typeAtLocation, checker, {\n allowIndexSignatures,\n }),\n ),\n ),\n ];\n }\n\n const resourceName = checker.getSymbolAtLocation(node.expression)!.name;\n\n const argLength = typesToArgsLength.get(resourceName)!;\n const needsExtraArg = node.arguments!.length === argLength - 1; // provide empty config if undefined\n\n let updatedArgs = [\n ...node.arguments!,\n ...(needsExtraArg ?\n [factory.createObjectLiteralExpression([], false)]\n : []),\n ...internalArguments,\n ];\n\n // For OlapTable and IngestPipeline, also inject typia validation functions\n if (resourceName === \"OlapTable\" || resourceName === \"IngestPipeline\") {\n // Create a single TypiaValidators object with all three validation functions\n // using direct typia code generation (uses shared typiaCtx for imports)\n const validatorsObject = factory.createObjectLiteralExpression(\n [\n factory.createPropertyAssignment(\n factory.createIdentifier(\"validate\"),\n wrapValidateFunction(\n generateValidateFunction(typiaCtx, typeAtLocation),\n ),\n ),\n factory.createPropertyAssignment(\n factory.createIdentifier(\"assert\"),\n generateAssertFunction(typiaCtx, typeAtLocation),\n ),\n factory.createPropertyAssignment(\n factory.createIdentifier(\"is\"),\n generateIsFunction(typiaCtx, typeAtLocation),\n ),\n ],\n true,\n );\n\n updatedArgs = [...updatedArgs, validatorsObject];\n\n // For IngestPipeline, also pass allowExtraFields so it can propagate to internal Stream/IngestApi\n if (resourceName === \"IngestPipeline\") {\n updatedArgs = [\n ...updatedArgs,\n hasIndexSignature ? factory.createTrue() : factory.createFalse(),\n ];\n }\n }\n\n // For IngestApi and Stream, add the allowExtraFields flag after undefined validators\n // This enables passing extra fields through to streaming functions when the type has an index signature\n if (resourceName === \"IngestApi\" || resourceName === \"Stream\") {\n updatedArgs = [\n ...updatedArgs,\n factory.createIdentifier(\"undefined\"), // validators (not used for these types)\n hasIndexSignature ? factory.createTrue() : factory.createFalse(),\n ];\n }\n\n return ts.factory.updateNewExpression(\n node,\n node.expression,\n node.typeArguments,\n updatedArgs,\n );\n};\n\n/**\n * Wraps a typia validate function to match our expected interface\n * Transforms typia's IValidation result to our { success, data, errors } format\n */\nconst wrapValidateFunction = (validateFn: ts.Expression): ts.Expression => {\n // (data: unknown) => {\n // const result = validateFn(data);\n // return {\n // success: result.success,\n // data: result.success ? result.data : undefined,\n // errors: result.success ? undefined : result.errors\n // };\n // }\n return factory.createArrowFunction(\n undefined,\n undefined,\n [\n factory.createParameterDeclaration(\n undefined,\n undefined,\n factory.createIdentifier(\"data\"),\n undefined,\n factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword),\n undefined,\n ),\n ],\n undefined,\n factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),\n factory.createBlock(\n [\n factory.createVariableStatement(\n undefined,\n factory.createVariableDeclarationList(\n [\n factory.createVariableDeclaration(\n factory.createIdentifier(\"result\"),\n undefined,\n undefined,\n factory.createCallExpression(validateFn, undefined, [\n factory.createIdentifier(\"data\"),\n ]),\n ),\n ],\n ts.NodeFlags.Const,\n ),\n ),\n factory.createReturnStatement(\n factory.createObjectLiteralExpression(\n [\n factory.createPropertyAssignment(\n factory.createIdentifier(\"success\"),\n factory.createPropertyAccessExpression(\n factory.createIdentifier(\"result\"),\n factory.createIdentifier(\"success\"),\n ),\n ),\n factory.createPropertyAssignment(\n factory.createIdentifier(\"data\"),\n factory.createConditionalExpression(\n factory.createPropertyAccessExpression(\n factory.createIdentifier(\"result\"),\n factory.createIdentifier(\"success\"),\n ),\n factory.createToken(ts.SyntaxKind.QuestionToken),\n factory.createPropertyAccessExpression(\n factory.createIdentifier(\"result\"),\n factory.createIdentifier(\"data\"),\n ),\n factory.createToken(ts.SyntaxKind.ColonToken),\n factory.createIdentifier(\"undefined\"),\n ),\n ),\n factory.createPropertyAssignment(\n factory.createIdentifier(\"errors\"),\n factory.createConditionalExpression(\n factory.createPropertyAccessExpression(\n factory.createIdentifier(\"result\"),\n factory.createIdentifier(\"success\"),\n ),\n factory.createToken(ts.SyntaxKind.QuestionToken),\n factory.createIdentifier(\"undefined\"),\n factory.createToken(ts.SyntaxKind.ColonToken),\n factory.createPropertyAccessExpression(\n factory.createIdentifier(\"result\"),\n factory.createIdentifier(\"errors\"),\n ),\n ),\n ),\n ],\n true,\n ),\n ),\n ],\n true,\n ),\n );\n};\n","import ts, {\n displayPartsToString,\n isIdentifier,\n isTypeReferenceNode,\n SymbolFlags,\n TupleType,\n TypeChecker,\n TypeFlags,\n} from \"typescript\";\nimport { enumConvert, isEnum } from \"./enumConvert\";\nimport {\n ArrayType,\n Column,\n DataType,\n DataEnum,\n Nested,\n NamedTupleType,\n NullType,\n UnknownType,\n UnsupportedFeature,\n IndexType,\n MapType,\n} from \"./dataModelTypes\";\nimport { ClickHouseNamedTuple, DecimalRegex } from \"./types\";\nimport { STRING_DATE_ANNOTATION } from \"../utilities/json\";\n\nconst dateType = (checker: TypeChecker) =>\n checker\n .getTypeOfSymbol(\n checker.resolveName(\"Date\", undefined, SymbolFlags.Type, false)!,\n )\n .getConstructSignatures()[0]\n .getReturnType();\n\n// making throws expressions so that they can be used in ternaries\n\nconst throwUnknownType = (\n t: ts.Type,\n fieldName: string,\n typeName: string,\n): never => {\n throw new UnknownType(t, fieldName, typeName);\n};\n\nconst throwNullType = (fieldName: string, typeName: string): never => {\n throw new NullType(fieldName, typeName);\n};\n\nconst throwIndexTypeError = (t: ts.Type, checker: TypeChecker): never => {\n const interfaceName = t.symbol?.name || \"unknown type\";\n const indexInfos = checker.getIndexInfosOfType(t);\n const signatures = indexInfos.map((info) => {\n const keyType = checker.typeToString(info.keyType);\n const valueType = checker.typeToString(info.type);\n return `[${keyType}]: ${valueType}`;\n });\n\n throw new IndexType(interfaceName, signatures);\n};\n\n/** Recursively search for a property on a type, traversing intersections */\nconst getPropertyDeep = (t: ts.Type, name: string): ts.Symbol | undefined => {\n const direct = t.getProperty(name);\n if (direct !== undefined) return direct;\n // TODO: investigate if this logic is needed.\n // the properties in types in intersection should be reachable by t.getProperty\n // Intersection constituents may carry the marker symbols\n if (t.isIntersection()) {\n for (const sub of t.types) {\n const found = getPropertyDeep(sub, name);\n if (found) return found;\n }\n }\n return undefined;\n};\n\nconst toArrayType = ([elementNullable, _, elementType]: [\n boolean,\n [string, any][],\n DataType,\n]): ArrayType => {\n return {\n elementNullable,\n elementType,\n };\n};\n\nconst isNumberType = (t: ts.Type, checker: TypeChecker): boolean => {\n return checker.isTypeAssignableTo(t, checker.getNumberType());\n};\n\nconst handleAggregated = (\n t: ts.Type,\n checker: TypeChecker,\n fieldName: string,\n typeName: string,\n): AggregationFunction | undefined => {\n const functionSymbol = t.getProperty(\"_aggregationFunction\");\n const argsTypesSymbol = t.getProperty(\"_argTypes\");\n\n if (functionSymbol === undefined || argsTypesSymbol === undefined) {\n return undefined;\n }\n const functionStringLiteral = checker.getNonNullableType(\n checker.getTypeOfSymbol(functionSymbol),\n );\n const types = checker.getNonNullableType(\n checker.getTypeOfSymbol(argsTypesSymbol),\n );\n\n if (functionStringLiteral.isStringLiteral() && checker.isTupleType(types)) {\n const argumentTypes = ((types as TupleType).typeArguments || []).map(\n (argT) => {\n return tsTypeToDataType(argT, checker, fieldName, typeName, false)[2];\n },\n );\n return { functionName: functionStringLiteral.value, argumentTypes };\n } else {\n console.log(\n \"[CompilerPlugin] Unexpected type inside Aggregated\",\n functionStringLiteral,\n );\n return undefined;\n }\n};\n\nconst getTaggedType = (\n t: ts.Type,\n checker: TypeChecker,\n propertyName: string,\n): ts.Type | null => {\n // Ensure we check the non-nullable part so the tag property is there\n const nonNull = t.getNonNullableType();\n const ttlSymbol = nonNull.getProperty(propertyName);\n if (ttlSymbol === undefined) return null;\n return checker.getNonNullableType(checker.getTypeOfSymbol(ttlSymbol));\n};\n\n// JSON mapping: recognize SomeInterface & ClickHouseJson<...>\nconst getJsonMappedType = (\n t: ts.Type,\n checker: TypeChecker,\n): DataType | null => {\n const mappingSymbol = getPropertyDeep(t, \"_clickhouse_mapped_type\");\n if (mappingSymbol === undefined) return null;\n const mappedType = checker.getNonNullableType(\n checker.getTypeOfSymbol(mappingSymbol),\n );\n if (!mappedType.isStringLiteral() || mappedType.value !== \"JSON\") {\n return null;\n }\n\n // Extract settings from the type properties\n let maxDynamicPaths: number | undefined = undefined;\n let maxDynamicTypes: number | undefined = undefined;\n let skipPaths: string[] = [];\n let skipRegexes: string[] = [];\n\n const settingsSymbol = getPropertyDeep(t, \"_clickhouse_json_settings\");\n if (settingsSymbol !== undefined) {\n const settingsType = checker.getNonNullableType(\n checker.getTypeOfSymbol(settingsSymbol),\n );\n\n const maxPathsSymbol = getPropertyDeep(settingsType, \"maxDynamicPaths\");\n if (maxPathsSymbol !== undefined) {\n const maxPathsType = checker.getNonNullableType(\n checker.getTypeOfSymbol(maxPathsSymbol),\n );\n if (maxPathsType.isNumberLiteral()) {\n maxDynamicPaths = maxPathsType.value;\n }\n }\n\n const maxTypesSymbol = getPropertyDeep(settingsType, \"maxDynamicTypes\");\n if (maxTypesSymbol !== undefined) {\n const maxTypesType = checker.getNonNullableType(\n checker.getTypeOfSymbol(maxTypesSymbol),\n );\n if (maxTypesType.isNumberLiteral()) {\n maxDynamicTypes = maxTypesType.value;\n }\n }\n\n const skipPathsSymbol = getPropertyDeep(settingsType, \"skipPaths\");\n if (skipPathsSymbol !== undefined) {\n const skipPathsType = checker.getNonNullableType(\n checker.getTypeOfSymbol(skipPathsSymbol),\n );\n if (checker.isTupleType(skipPathsType)) {\n const tuple = skipPathsType as TupleType;\n skipPaths = (tuple.typeArguments || [])\n .filter((t) => t.isStringLiteral())\n .map((t) => (t as ts.StringLiteralType).value);\n }\n }\n\n const skipRegexesSymbol = getPropertyDeep(settingsType, \"skipRegexes\");\n if (skipRegexesSymbol !== undefined) {\n const skipRegexesType = checker.getNonNullableType(\n checker.getTypeOfSymbol(skipRegexesSymbol),\n );\n if (checker.isTupleType(skipRegexesType)) {\n const tuple = skipRegexesType as TupleType;\n skipRegexes = (tuple.typeArguments || [])\n .filter((t) => t.isStringLiteral())\n .map((t) => (t as ts.StringLiteralType).value);\n }\n }\n }\n\n // For typed paths, try to find the interface part of the intersection\n let base: ts.Type = t.getNonNullableType();\n if (base.isIntersection()) {\n const candidates = base.types.filter((sub) => {\n const m = getPropertyDeep(sub, \"_clickhouse_mapped_type\");\n if (!m) return true;\n const mt = checker.getNonNullableType(checker.getTypeOfSymbol(m));\n return !(mt.isStringLiteral() && mt.value === \"JSON\");\n });\n if (candidates.length > 0) base = candidates[0];\n }\n\n // Build typed paths from the base interface's columns (top-level only)\n let typedPaths: Array<[string, DataType]> = [];\n try {\n const cols = toColumns(base, checker);\n typedPaths = cols.map((c) => [c.name, c.data_type]);\n } catch (_) {\n // Fallback silently if we cannot derive columns\n typedPaths = [];\n }\n\n const hasAnyOption =\n typeof maxDynamicPaths === \"number\" ||\n typeof maxDynamicTypes === \"number\" ||\n typedPaths.length > 0 ||\n skipPaths.length > 0 ||\n skipRegexes.length > 0;\n\n if (!hasAnyOption) return \"Json\";\n\n const result: Record<string, any> = {\n typed_paths: typedPaths,\n skip_paths: skipPaths,\n skip_regexps: skipRegexes,\n };\n\n // Only include these fields if they have actual values\n if (typeof maxDynamicPaths === \"number\") {\n result.max_dynamic_paths = maxDynamicPaths;\n }\n if (typeof maxDynamicTypes === \"number\") {\n result.max_dynamic_types = maxDynamicTypes;\n }\n\n return result as unknown as DataType;\n};\n\nconst handleSimpleAggregated = (\n t: ts.Type,\n checker: TypeChecker,\n fieldName: string,\n typeName: string,\n): SimpleAggregationFunction | undefined => {\n const functionSymbol = t.getProperty(\"_simpleAggregationFunction\");\n const argTypeSymbol = t.getProperty(\"_argType\");\n\n if (functionSymbol === undefined || argTypeSymbol === undefined) {\n return undefined;\n }\n const functionStringLiteral = checker.getNonNullableType(\n checker.getTypeOfSymbol(functionSymbol),\n );\n const argType = checker.getNonNullableType(\n checker.getTypeOfSymbol(argTypeSymbol),\n );\n\n if (functionStringLiteral.isStringLiteral()) {\n const argumentType = tsTypeToDataType(\n argType,\n checker,\n fieldName,\n typeName,\n false,\n )[2];\n return { functionName: functionStringLiteral.value, argumentType };\n } else {\n console.log(\n \"[CompilerPlugin] Unexpected type inside SimpleAggregated\",\n functionStringLiteral,\n );\n return undefined;\n }\n};\n/** Detect ClickHouse default annotation on a type and return raw sql */\nconst handleDefault = (t: ts.Type, checker: TypeChecker): string | null => {\n const defaultType = getTaggedType(t, checker, \"_clickhouse_default\");\n if (defaultType === null) {\n return null;\n }\n if (!defaultType.isStringLiteral()) {\n throw new UnsupportedFeature(\n 'ClickHouseDefault must use a string literal, e.g. ClickHouseDefault<\"now()\">',\n );\n }\n return defaultType.value;\n};\n\n/** Detect ClickHouse materialized annotation on a type and return raw sql */\nconst handleMaterialized = (\n t: ts.Type,\n checker: TypeChecker,\n): string | null => {\n const materializedType = getTaggedType(\n t,\n checker,\n \"_clickhouse_materialized\",\n );\n if (materializedType === null) {\n return null;\n }\n if (!materializedType.isStringLiteral()) {\n throw new UnsupportedFeature(\n 'ClickHouseMaterialized must use a string literal, e.g. ClickHouseMaterialized<\"toDate(timestamp)\">',\n );\n }\n return materializedType.value;\n};\n\n/** Detect ClickHouse alias annotation on a type and return raw sql */\nconst handleAlias = (t: ts.Type, checker: TypeChecker): string | null => {\n const aliasType = getTaggedType(t, checker, \"_clickhouse_alias\");\n if (aliasType === null) {\n return null;\n }\n if (!aliasType.isStringLiteral()) {\n throw new UnsupportedFeature(\n 'ClickHouseAlias must use a string literal, e.g. ClickHouseAlias<\"toDate(timestamp)\">',\n );\n }\n return aliasType.value;\n};\n\n/** Detect ClickHouse TTL annotation on a type and return raw sql */\nconst handleTtl = (t: ts.Type, checker: TypeChecker): string | null => {\n const ttlType = getTaggedType(t, checker, \"_clickhouse_ttl\");\n if (ttlType === null) {\n return null;\n }\n if (!ttlType.isStringLiteral()) {\n throw new UnsupportedFeature(\n 'ClickHouseTTL must use a string literal, e.g. ClickHouseTTL<\"timestamp + INTERVAL 1 WEEK\">',\n );\n }\n return ttlType.value;\n};\n\nconst handleNumberType = (\n t: ts.Type,\n checker: TypeChecker,\n fieldName: string,\n): string => {\n // Detect Decimal(P, S) annotation on number via ClickHouseDecimal\n const decimalPrecisionSymbol = getPropertyDeep(t, \"_clickhouse_precision\");\n const decimalScaleSymbol = getPropertyDeep(t, \"_clickhouse_scale\");\n if (\n decimalPrecisionSymbol !== undefined &&\n decimalScaleSymbol !== undefined\n ) {\n const precisionType = checker.getNonNullableType(\n checker.getTypeOfSymbol(decimalPrecisionSymbol),\n );\n const scaleType = checker.getNonNullableType(\n checker.getTypeOfSymbol(decimalScaleSymbol),\n );\n if (precisionType.isNumberLiteral() && scaleType.isNumberLiteral()) {\n return `Decimal(${precisionType.value}, ${scaleType.value})`;\n }\n }\n\n const tagSymbol = t.getProperty(\"typia.tag\");\n if (tagSymbol === undefined) {\n return \"Float64\";\n } else {\n const typiaProps = checker.getNonNullableType(\n checker.getTypeOfSymbol(tagSymbol),\n );\n const props: ts.Type[] =\n typiaProps.isIntersection() ? typiaProps.types : [typiaProps];\n\n for (const prop of props) {\n const valueSymbol = prop.getProperty(\"value\");\n if (valueSymbol === undefined) {\n console.log(\n `[CompilerPlugin] Props.value is undefined for ${fieldName}`,\n );\n } else {\n const valueTypeLiteral = checker.getTypeOfSymbol(valueSymbol);\n const numberTypeMappings = {\n float: \"Float32\",\n double: \"Float64\",\n int8: \"Int8\",\n int16: \"Int16\",\n int32: \"Int32\",\n int64: \"Int64\",\n uint8: \"UInt8\",\n uint16: \"UInt16\",\n uint32: \"UInt32\",\n uint64: \"UInt64\",\n };\n const match = Object.entries(numberTypeMappings).find(([k, _]) =>\n isStringLiteral(valueTypeLiteral, checker, k),\n );\n if (match) {\n return match[1];\n } else {\n const typeString =\n valueTypeLiteral.isStringLiteral() ?\n valueTypeLiteral.value\n : \"unknown\";\n\n console.log(\n `[CompilerPlugin] Other number types are not supported: ${typeString} in field ${fieldName}`,\n );\n }\n }\n }\n\n return \"Float64\";\n }\n};\n\nexport interface AggregationFunction {\n functionName: string;\n argumentTypes: DataType[];\n}\n\nexport interface SimpleAggregationFunction {\n functionName: string;\n argumentType: DataType;\n}\n\nconst isStringLiteral = (\n t: ts.Type,\n checker: TypeChecker,\n lit: string,\n): boolean => checker.isTypeAssignableTo(t, checker.getStringLiteralType(lit));\n\nconst handleStringType = (\n t: ts.Type,\n checker: TypeChecker,\n fieldName: string,\n annotations: [string, any][],\n): string => {\n // Check for FixedString(N) annotation\n const fixedStringSizeSymbol = getPropertyDeep(\n t,\n \"_clickhouse_fixed_string_size\",\n );\n if (fixedStringSizeSymbol !== undefined) {\n const sizeType = checker.getNonNullableType(\n checker.getTypeOfSymbol(fixedStringSizeSymbol),\n );\n if (sizeType.isNumberLiteral()) {\n return `FixedString(${sizeType.value})`;\n }\n }\n\n const tagSymbol = t.getProperty(\"typia.tag\");\n if (tagSymbol === undefined) {\n if (t.isUnion() && t.types.every((v) => v.isStringLiteral())) {\n annotations.push([\"LowCardinality\", true]);\n }\n\n return \"String\";\n } else {\n const typiaProps = checker.getNonNullableType(\n checker.getTypeOfSymbol(tagSymbol),\n );\n const props: ts.Type[] =\n typiaProps.isIntersection() ? typiaProps.types : [typiaProps];\n\n for (const prop of props) {\n const valueSymbol = prop.getProperty(\"value\");\n if (valueSymbol === undefined) {\n console.log(\n `[CompilerPlugin] Props.value is undefined for ${fieldName}`,\n );\n } else {\n const valueTypeLiteral = checker.getTypeOfSymbol(valueSymbol);\n if (isStringLiteral(valueTypeLiteral, checker, \"uuid\")) {\n return \"UUID\";\n } else if (isStringLiteral(valueTypeLiteral, checker, \"date-time\")) {\n let precision = 9;\n\n const precisionSymbol = t.getProperty(\"_clickhouse_precision\");\n if (precisionSymbol !== undefined) {\n const precisionType = checker.getNonNullableType(\n checker.getTypeOfSymbol(precisionSymbol),\n );\n if (precisionType.isNumberLiteral()) {\n precision = precisionType.value;\n }\n }\n // Mark this as a string-based date field so it won't be parsed to Date at runtime\n annotations.push([STRING_DATE_ANNOTATION, true]);\n return `DateTime(${precision})`;\n } else if (isStringLiteral(valueTypeLiteral, checker, \"date\")) {\n let size = 4;\n const sizeSymbol = t.getProperty(\"_clickhouse_byte_size\");\n if (sizeSymbol !== undefined) {\n const sizeType = checker.getNonNullableType(\n checker.getTypeOfSymbol(sizeSymbol),\n );\n if (sizeType.isNumberLiteral()) {\n size = sizeType.value;\n }\n }\n\n if (size === 4) {\n return \"Date\";\n } else if (size === 2) {\n return \"Date16\";\n } else {\n throw new UnsupportedFeature(`Date with size ${size}`);\n }\n } else if (isStringLiteral(valueTypeLiteral, checker, \"ipv4\")) {\n return \"IPv4\";\n } else if (isStringLiteral(valueTypeLiteral, checker, \"ipv6\")) {\n return \"IPv6\";\n } else if (isStringLiteral(valueTypeLiteral, checker, DecimalRegex)) {\n let precision = 10;\n let scale = 0;\n\n const precisionSymbol = t.getProperty(\"_clickhouse_precision\");\n if (precisionSymbol !== undefined) {\n const precisionType = checker.getNonNullableType(\n checker.getTypeOfSymbol(precisionSymbol),\n );\n if (precisionType.isNumberLiteral()) {\n precision = precisionType.value;\n }\n }\n\n const scaleSymbol = t.getProperty(\"_clickhouse_scale\");\n if (scaleSymbol !== undefined) {\n const scaleType = checker.getNonNullableType(\n checker.getTypeOfSymbol(scaleSymbol),\n );\n if (scaleType.isNumberLiteral()) {\n scale = scaleType.value;\n }\n }\n\n return `Decimal(${precision}, ${scale})`;\n } else {\n const typeString =\n valueTypeLiteral.isStringLiteral() ?\n valueTypeLiteral.value\n : \"unknown\";\n\n console.log(\n `[CompilerPlugin] Unknown format: ${typeString} in field ${fieldName}`,\n );\n }\n }\n }\n\n return \"String\";\n }\n};\n\nconst isStringAnyRecord = (t: ts.Type, checker: ts.TypeChecker): boolean => {\n const indexInfos = checker.getIndexInfosOfType(t);\n if (indexInfos && indexInfos.length === 1) {\n const indexInfo = indexInfos[0];\n return (\n indexInfo.keyType == checker.getStringType() &&\n indexInfo.type == checker.getAnyType()\n );\n }\n\n return false;\n};\n\n/**\n * Check if a type is a Record<K, V> type (generic map/dictionary type)\n */\nconst isRecordType = (t: ts.Type, checker: ts.TypeChecker): boolean => {\n const indexInfos = checker.getIndexInfosOfType(t);\n return indexInfos && indexInfos.length === 1;\n};\n\n/**\n * Detects a tag-like object type that only carries metadata, e.g. { _tag: ... }\n */\nconst isSingleUnderscoreMetaObject = (\n t: ts.Type,\n checker: ts.TypeChecker,\n): boolean => {\n const props = checker.getPropertiesOfType(t);\n if (props.length !== 1) return false;\n const onlyProp = props[0];\n const name = onlyProp.name;\n return typeof name === \"string\" && name.startsWith(\"_\");\n};\n\n/**\n * Handle Record<K, V> types and convert them to Map types\n */\nconst handleRecordType = (\n t: ts.Type,\n checker: ts.TypeChecker,\n fieldName: string,\n typeName: string,\n isJwt: boolean,\n): MapType => {\n const indexInfos = checker.getIndexInfosOfType(t);\n if (indexInfos && indexInfos.length !== 1) {\n throwIndexTypeError(t, checker);\n }\n const indexInfo = indexInfos[0];\n\n // Convert key type\n const [, , keyType] = tsTypeToDataType(\n indexInfo.keyType,\n checker,\n `${fieldName}_key`,\n typeName,\n isJwt,\n );\n\n // Convert value type\n const [, , valueType] = tsTypeToDataType(\n indexInfo.type,\n checker,\n `${fieldName}_value`,\n typeName,\n isJwt,\n );\n\n return {\n keyType,\n valueType,\n };\n};\n\n/**\n * see {@link ClickHouseNamedTuple}\n */\nconst isNamedTuple = (t: ts.Type, checker: ts.TypeChecker) => {\n const mappingSymbol = t.getProperty(\"_clickhouse_mapped_type\");\n if (mappingSymbol === undefined) {\n return false;\n }\n return isStringLiteral(\n checker.getNonNullableType(checker.getTypeOfSymbol(mappingSymbol)),\n checker,\n \"namedTuple\",\n );\n};\n\n// Validate that the underlying TS type matches the mapped geometry shape\nconst getGeometryMappedType = (\n t: ts.Type,\n checker: ts.TypeChecker,\n): string | null => {\n const mappingSymbol = getPropertyDeep(t, \"_clickhouse_mapped_type\");\n if (mappingSymbol === undefined) return null;\n const mapped = checker.getNonNullableType(\n checker.getTypeOfSymbol(mappingSymbol),\n );\n\n // Helper: exact tuple [number, number]\n const isPointTuple = (candidate: ts.Type): boolean => {\n if (candidate.isIntersection()) {\n return candidate.types.some(isPointTuple);\n }\n if (!checker.isTupleType(candidate)) return false;\n const tuple = candidate as TupleType;\n const args = tuple.typeArguments || [];\n if (args.length !== 2) return false;\n return isNumberType(args[0], checker) && isNumberType(args[1], checker);\n };\n\n // Helper: Array<T> predicate\n const isArrayOf = (\n arrType: ts.Type,\n elementPredicate: (elType: ts.Type) => boolean,\n ): boolean => {\n if (arrType.isIntersection()) {\n return arrType.types.some((t) => isArrayOf(t, elementPredicate));\n }\n if (!checker.isArrayType(arrType)) return false;\n const elementType = arrType.getNumberIndexType();\n if (!elementType) return false;\n return elementPredicate(elementType);\n };\n\n const expectAndValidate = (shapeName: string, validator: () => boolean) => {\n if (!validator()) {\n throw new UnsupportedFeature(\n `Type annotated as ${shapeName} must be assignable to the expected geometry shape`,\n );\n }\n return shapeName;\n };\n\n if (mapped.isStringLiteral()) {\n const v = mapped.value;\n switch (v) {\n case \"Point\":\n return expectAndValidate(\"Point\", () => isPointTuple(t));\n case \"Ring\":\n case \"LineString\":\n return expectAndValidate(v, () =>\n isArrayOf(t, (el) => isPointTuple(el)),\n );\n case \"MultiLineString\":\n case \"Polygon\":\n return expectAndValidate(v, () =>\n isArrayOf(t, (el) => isArrayOf(el, (inner) => isPointTuple(inner))),\n );\n case \"MultiPolygon\":\n return expectAndValidate(v, () =>\n isArrayOf(t, (el) =>\n isArrayOf(el, (inner) => isArrayOf(inner, isPointTuple)),\n ),\n );\n }\n }\n return null;\n};\n\nconst checkColumnHasNoDefault = (c: Column) => {\n if (c.default !== null) {\n throw new UnsupportedFeature(\n \"Default in inner field. Put ClickHouseDefault in top level field.\",\n );\n }\n};\n\nconst handleNested = (\n t: ts.Type,\n checker: ts.TypeChecker,\n fieldName: string,\n jwt: boolean,\n): Nested => {\n const columns = toColumns(t, checker);\n columns.forEach(checkColumnHasNoDefault);\n return {\n name: getNestedName(t, fieldName),\n columns,\n jwt,\n };\n};\n\nconst handleNamedTuple = (\n t: ts.Type,\n checker: ts.TypeChecker,\n): NamedTupleType => {\n return {\n fields: toColumns(t, checker).flatMap((c) => {\n if (c.name === \"_clickhouse_mapped_type\") return [];\n\n checkColumnHasNoDefault(c);\n const t = c.required ? c.data_type : { nullable: c.data_type };\n return [[c.name, t]];\n }),\n };\n};\n\nconst tsTypeToDataType = (\n t: ts.Type,\n checker: TypeChecker,\n fieldName: string,\n typeName: string,\n isJwt: boolean,\n typeNode?: ts.TypeNode,\n): [boolean, [string, any][], DataType] => {\n const nonNull = t.getNonNullableType();\n const nullable = nonNull != t;\n\n const aggregationFunction = handleAggregated(t, checker, fieldName, typeName);\n const simpleAggregationFunction = handleSimpleAggregated(\n t,\n checker,\n fieldName,\n typeName,\n );\n\n let withoutTags = nonNull;\n // clean up intersection type tags\n if (nonNull.isIntersection()) {\n const nonTagTypes = nonNull.types.filter(\n (candidate) => !isSingleUnderscoreMetaObject(candidate, checker),\n );\n\n if (nonTagTypes.length == 1) {\n withoutTags = nonTagTypes[0];\n }\n }\n\n // Recognize Date aliases (DateTime, DateTime64<P>) as DateTime-like\n let datePrecisionFromNode: number | undefined = undefined;\n if (typeNode && isTypeReferenceNode(typeNode)) {\n const tn = typeNode.typeName;\n const name = isIdentifier(tn) ? tn.text : tn.right.text;\n if (name === \"DateTime64\") {\n const arg = typeNode.typeArguments?.[0];\n if (\n arg &&\n ts.isLiteralTypeNode(arg) &&\n ts.isNumericLiteral(arg.literal)\n ) {\n datePrecisionFromNode = Number(arg.literal.text);\n }\n } else if (name === \"DateTime\") {\n datePrecisionFromNode = undefined; // DateTime without explicit precision\n }\n }\n\n const annotations: [string, any][] = [];\n\n const typeSymbolName = nonNull.symbol?.name || t.symbol?.name;\n const isDateLike =\n typeSymbolName === \"DateTime\" ||\n typeSymbolName === \"DateTime64\" ||\n checker.isTypeAssignableTo(nonNull, dateType(checker));\n\n let dataType: DataType;\n if (isEnum(nonNull)) {\n dataType = enumConvert(nonNull);\n } else {\n const jsonCandidate = getJsonMappedType(nonNull, checker);\n if (jsonCandidate !== null) {\n dataType = jsonCandidate;\n } else if (isStringAnyRecord(nonNull, checker)) {\n dataType = \"Json\";\n } else if (isDateLike) {\n // Prefer precision from AST (DateTime64<P>) if available\n if (datePrecisionFromNode !== undefined) {\n dataType = `DateTime(${datePrecisionFromNode})` as DataType;\n } else {\n // Add precision support for Date via ClickHousePrecision<P>\n const precisionSymbol =\n getPropertyDeep(nonNull, \"_clickhouse_precision\") ||\n getPropertyDeep(t, \"_clickhouse_precision\");\n if (precisionSymbol !== undefined) {\n const precisionType = checker.getNonNullableType(\n checker.getTypeOfSymbol(precisionSymbol),\n );\n if (precisionType.isNumberLiteral()) {\n dataType = `DateTime(${precisionType.value})` as DataType;\n } else {\n dataType = \"DateTime\";\n }\n } else {\n dataType = \"DateTime\";\n }\n }\n } else if (checker.isTypeAssignableTo(nonNull, checker.getStringType())) {\n dataType = handleStringType(nonNull, checker, fieldName, annotations);\n } else if (isNumberType(nonNull, checker)) {\n dataType = handleNumberType(nonNull, checker, fieldName);\n } else if (checker.isTypeAssignableTo(nonNull, checker.getBooleanType())) {\n dataType = \"Boolean\";\n } else if (getGeometryMappedType(nonNull, checker) !== null) {\n dataType = getGeometryMappedType(nonNull, checker)!;\n } else if (checker.isArrayType(withoutTags)) {\n dataType = toArrayType(\n tsTypeToDataType(\n nonNull.getNumberIndexType()!,\n checker,\n fieldName,\n typeName,\n isJwt,\n undefined,\n ),\n );\n } else if (isNamedTuple(nonNull, checker)) {\n dataType = handleNamedTuple(nonNull, checker);\n } else if (isRecordType(nonNull, checker)) {\n dataType = handleRecordType(nonNull, checker, fieldName, typeName, isJwt);\n } else if (\n withoutTags.isClassOrInterface() ||\n (withoutTags.flags & TypeFlags.Object) !== 0\n ) {\n dataType = handleNested(withoutTags, checker, fieldName, isJwt);\n } else if (nonNull == checker.getNeverType()) {\n dataType = throwNullType(fieldName, typeName);\n } else {\n dataType = throwUnknownType(t, fieldName, typeName);\n }\n }\n if (aggregationFunction !== undefined) {\n annotations.push([\"aggregationFunction\", aggregationFunction]);\n }\n if (simpleAggregationFunction !== undefined) {\n annotations.push([\"simpleAggregationFunction\", simpleAggregationFunction]);\n }\n\n const lowCardinalitySymbol = t.getProperty(\"_LowCardinality\");\n if (lowCardinalitySymbol !== undefined) {\n const lowCardinalityType = checker.getNonNullableType(\n checker.getTypeOfSymbol(lowCardinalitySymbol),\n );\n\n if (lowCardinalityType == checker.getTrueType()) {\n annotations.push([\"LowCardinality\", true]);\n }\n }\n\n return [nullable, annotations, dataType];\n};\n\nconst getNestedName = (t: ts.Type, fieldName: string) => {\n const name = t.symbol.name;\n // replace default name\n return name === \"__type\" ? fieldName : name;\n};\n\nconst hasWrapping = (\n typeNode: ts.TypeNode | undefined,\n wrapperName: string,\n) => {\n if (typeNode !== undefined && isTypeReferenceNode(typeNode)) {\n const typeName = typeNode.typeName;\n const name = isIdentifier(typeName) ? typeName.text : typeName.right.text;\n return name === wrapperName && typeNode.typeArguments?.length === 1;\n } else {\n return false;\n }\n};\n\nconst hasKeyWrapping = (typeNode: ts.TypeNode | undefined) => {\n return hasWrapping(typeNode, \"Key\");\n};\n\nconst hasJwtWrapping = (typeNode: ts.TypeNode | undefined) => {\n return hasWrapping(typeNode, \"JWT\");\n};\n\nconst handleDefaultWrapping = (\n typeNode: ts.TypeNode | undefined,\n): string | undefined => {\n if (typeNode !== undefined && isTypeReferenceNode(typeNode)) {\n const typeName = typeNode.typeName;\n const name = isIdentifier(typeName) ? typeName.text : typeName.right.text;\n if (name === \"WithDefault\" && typeNode.typeArguments?.length === 2) {\n const defaultValueType = typeNode.typeArguments[1];\n if (\n ts.isLiteralTypeNode(defaultValueType) &&\n ts.isStringLiteral(defaultValueType.literal)\n ) {\n return defaultValueType.literal.text;\n }\n }\n }\n return undefined;\n};\n\n/** Detect ClickHouse Codec annotation on a type and return codec expression */\nconst handleCodec = (t: ts.Type, checker: TypeChecker): string | null => {\n const codecType = getTaggedType(t, checker, \"_clickhouse_codec\");\n if (codecType === null) {\n return null;\n }\n if (!codecType.isStringLiteral()) {\n throw new UnsupportedFeature(\n 'ClickHouseCodec must use a string literal, e.g. ClickHouseCodec<\"ZSTD(3)\">',\n );\n }\n return codecType.value;\n};\n\nexport interface ToColumnsOptions {\n /**\n * When true, allows types with index signatures (e.g., [key: string]: any).\n * Only named properties will be extracted as columns.\n * This is useful for IngestApi where arbitrary fields should be accepted\n * and passed through to streaming functions.\n */\n allowIndexSignatures?: boolean;\n}\n\nexport const toColumns = (\n t: ts.Type,\n checker: TypeChecker,\n options?: ToColumnsOptions,\n): Column[] => {\n // Only check for index signatures if not explicitly allowed\n if (\n !options?.allowIndexSignatures &&\n checker.getIndexInfosOfType(t).length !== 0\n ) {\n console.log(\"[CompilerPlugin]\", checker.getIndexInfosOfType(t));\n throwIndexTypeError(t, checker);\n }\n\n return checker.getPropertiesOfType(t).map((prop) => {\n let declarations = prop.getDeclarations();\n const node =\n declarations && declarations.length > 0 ?\n (declarations[0] as ts.PropertyDeclaration)\n : undefined;\n const type =\n node !== undefined ?\n checker.getTypeOfSymbolAtLocation(prop, node)\n : checker.getTypeOfSymbol(prop);\n\n const isKey = hasKeyWrapping(node?.type);\n const isJwt = hasJwtWrapping(node?.type);\n\n const defaultExpression = handleDefaultWrapping(node?.type);\n\n const [nullable, annotations, dataType] = tsTypeToDataType(\n type,\n checker,\n prop.name,\n t.symbol?.name || \"inline_type\",\n isJwt,\n node?.type,\n );\n\n const defaultValue = defaultExpression ?? handleDefault(type, checker);\n const materializedValue = handleMaterialized(type, checker);\n const aliasValue = handleAlias(type, checker);\n\n // Validate mutual exclusivity of DEFAULT, MATERIALIZED, and ALIAS\n const setCount = [defaultValue, materializedValue, aliasValue].filter(\n (v) => v != null,\n ).length;\n if (setCount > 1) {\n throw new UnsupportedFeature(\n `Column '${prop.name}' can only have one of ClickHouseDefault, ClickHouseMaterialized, or ClickHouseAlias.`,\n );\n }\n if (aliasValue != null && isKey) {\n throw new UnsupportedFeature(\n `Column '${prop.name}' cannot be a primary key when using ClickHouseAlias.`,\n );\n }\n\n // Extract TSDoc comment from the property\n const docComment = prop.getDocumentationComment(checker);\n const comment =\n docComment.length > 0 ? displayPartsToString(docComment) : null;\n\n return {\n name: prop.name,\n data_type: dataType,\n primary_key: isKey,\n required: !nullable,\n unique: false,\n default: defaultValue,\n materialized: materializedValue,\n alias: aliasValue,\n ttl: handleTtl(type, checker),\n codec: handleCodec(type, checker),\n annotations,\n comment,\n };\n });\n};\n","import ts, {\n NumberLiteralType,\n StringLiteralType,\n UnionType,\n} from \"typescript\";\nimport { DataEnum, UnsupportedEnum } from \"./dataModelTypes\";\n\nexport const isEnum = (t: ts.Type): boolean =>\n !!(t.getFlags() & ts.TypeFlags.EnumLiteral);\n\nexport const enumConvert = (enumType: ts.Type): DataEnum => {\n const name = enumType.symbol.name;\n\n const values =\n enumType.isUnion() ?\n // an enum is the union of the values\n (enumType as UnionType).types\n // unless there's only one element\n : [enumType];\n const allStrings = values.every((v) => v.isStringLiteral());\n const allIntegers = values.every(\n (v) => v.isNumberLiteral() && Number.isInteger(v.value),\n );\n\n if (!allIntegers && !allStrings) {\n throw new UnsupportedEnum(name);\n }\n\n const enumMember =\n allStrings ?\n values.map((v) => ({\n name: v.symbol.name,\n value: { String: (v as StringLiteralType).value },\n }))\n : values.map((v) => ({\n name: v.symbol.name,\n value: { Int: (v as NumberLiteralType).value },\n }));\n\n return { name, values: enumMember };\n};\n","import ts from \"typescript\";\nimport { IdentifierBrandedString } from \"../sqlHelpers\";\n\nexport type EnumValues =\n | { name: string; value: { Int: number } }[]\n | { name: string; value: { String: string } }[];\nexport type DataEnum = { name: string; values: EnumValues };\nexport type Nested = { name: string; columns: Column[]; jwt: boolean };\nexport type ArrayType = { elementType: DataType; elementNullable: boolean };\nexport type NamedTupleType = { fields: Array<[string, DataType]> };\nexport type MapType = { keyType: DataType; valueType: DataType };\nexport type JsonOptions = {\n max_dynamic_paths?: number;\n max_dynamic_types?: number;\n typed_paths?: Array<[string, DataType]>;\n skip_paths?: string[];\n skip_regexps?: string[];\n};\nexport type DataType =\n | string\n | DataEnum\n | ArrayType\n | Nested\n | NamedTupleType\n | MapType\n | JsonOptions\n | { nullable: DataType };\nexport interface Column {\n name: IdentifierBrandedString;\n data_type: DataType;\n required: boolean;\n unique: false; // what is this for?\n primary_key: boolean;\n default: string | null;\n materialized: string | null;\n ttl: string | null;\n codec: string | null;\n annotations: [string, any][];\n comment: string | null;\n}\n\nexport interface DataModel {\n columns: Column[];\n name: string;\n}\n\nexport class UnknownType extends Error {\n t: ts.Type;\n fieldName: string;\n typeName: string;\n constructor(t: ts.Type, fieldName: string, typeName: string) {\n super();\n this.t = t;\n this.fieldName = fieldName;\n this.typeName = typeName;\n }\n}\n\nexport class NullType extends Error {\n fieldName: string;\n typeName: string;\n constructor(fieldName: string, typeName: string) {\n super();\n this.fieldName = fieldName;\n this.typeName = typeName;\n }\n}\n\nexport class UnsupportedEnum extends Error {\n enumName: string;\n constructor(enumName: string) {\n super();\n this.enumName = enumName;\n }\n}\n\nexport class UnsupportedFeature extends Error {\n featureName: string;\n constructor(featureName: string) {\n super();\n this.featureName = featureName;\n }\n}\n\nexport class IndexType extends Error {\n typeName: string;\n indexSignatures: string[];\n\n constructor(typeName: string, indexSignatures: string[]) {\n const explanation =\n \"Index signatures (e.g. [key: string]: value) are not supported in data models.\";\n\n const suggestion =\n \"Consider splitting this into separate types or using a single Record<K, V> type.\";\n\n const signatures = `Found index signatures: ${indexSignatures.join(\", \")}`;\n\n super(\n `${explanation}\\n\\nType: ${typeName}\\n\\n${signatures}\\n\\nSuggestion: ${suggestion}`,\n );\n\n this.typeName = typeName;\n this.indexSignatures = indexSignatures;\n }\n}\n\n/**\n * Type guard: is this DataType an Array(Nested(...))?\n * Uses the ArrayType and Nested types for type safety.\n */\nexport function isArrayNestedType(\n dt: DataType,\n): dt is ArrayType & { elementType: Nested } {\n return (\n typeof dt === \"object\" &&\n dt !== null &&\n (dt as ArrayType).elementType !== null &&\n typeof (dt as ArrayType).elementType === \"object\" &&\n (dt as ArrayType).elementType.hasOwnProperty(\"columns\") &&\n Array.isArray(((dt as ArrayType).elementType as Nested).columns)\n );\n}\n\n/**\n * Type guard: is this DataType a Nested struct (not array)?\n */\nexport function isNestedType(dt: DataType): dt is Nested {\n return (\n typeof dt === \"object\" &&\n dt !== null &&\n Array.isArray((dt as Nested).columns)\n );\n}\n","import { Pattern, TagBase } from \"typia/lib/tags\";\nimport { tags } from \"typia\";\n\nexport type ClickHousePrecision<P extends number> = {\n _clickhouse_precision?: P;\n};\n\nexport const DecimalRegex: \"^-?\\\\d+(\\\\.\\\\d+)?$\" = \"^-?\\\\d+(\\\\.\\\\d+)?$\";\n\nexport type ClickHouseDecimal<P extends number, S extends number> = {\n _clickhouse_precision?: P;\n _clickhouse_scale?: S;\n} & Pattern<typeof DecimalRegex>;\n\nexport type ClickHouseFixedStringSize<N extends number> = {\n _clickhouse_fixed_string_size?: N;\n};\n\n/**\n * FixedString(N) - Fixed-length string of exactly N bytes.\n *\n * ClickHouse stores exactly N bytes, padding shorter values with null bytes.\n * Values exceeding N bytes will throw an exception.\n *\n * Use for binary data: hashes, IP addresses, UUIDs, MAC addresses.\n *\n * @example\n * interface BinaryData {\n * md5_hash: string & FixedString<16>; // 16-byte MD5\n * sha256_hash: string & FixedString<32>; // 32-byte SHA256\n * }\n */\nexport type FixedString<N extends number> = string &\n ClickHouseFixedStringSize<N>;\n\nexport type ClickHouseByteSize<N extends number> = {\n _clickhouse_byte_size?: N;\n};\n\nexport type LowCardinality = {\n _LowCardinality?: true;\n};\n\n// ClickHouse-friendly helper aliases for clarity in user schemas\n// These are erased at compile time but guide the ClickHouse mapping logic.\nexport type DateTime = Date;\nexport type DateTime64<P extends number> = Date & ClickHousePrecision<P>;\n\nexport type DateTimeString = string & tags.Format<\"date-time\">;\n/**\n * JS Date objects cannot hold microsecond precision.\n * Use string as the runtime type to avoid losing information.\n */\nexport type DateTime64String<P extends number> = string &\n tags.Format<\"date-time\"> &\n ClickHousePrecision<P>;\n\n// Numeric convenience tags mirroring ClickHouse integer and float families\nexport type Float32 = number & ClickHouseFloat<\"float32\">;\nexport type Float64 = number & ClickHouseFloat<\"float64\">;\n\nexport type Int8 = number & ClickHouseInt<\"int8\">;\nexport type Int16 = number & ClickHouseInt<\"int16\">;\nexport type Int32 = number & ClickHouseInt<\"int32\">;\nexport type Int64 = number & ClickHouseInt<\"int64\">;\n\nexport type UInt8 = number & ClickHouseInt<\"uint8\">;\nexport type UInt16 = number & ClickHouseInt<\"uint16\">;\nexport type UInt32 = number & ClickHouseInt<\"uint32\">;\nexport type UInt64 = number & ClickHouseInt<\"uint64\">;\n\n// Decimal(P, S) annotation\nexport type Decimal<P extends number, S extends number> = string &\n ClickHouseDecimal<P, S>;\n\n/**\n * Attach compression codec to a column type.\n *\n * Any valid ClickHouse codec expression is allowed. ClickHouse validates the codec at runtime.\n *\n * @template T The base data type\n * @template CodecExpr The codec expression (single codec or chain)\n *\n * @example\n * interface Metrics {\n * // Single codec\n * log_blob: string & ClickHouseCodec<\"ZSTD(3)\">;\n *\n * // Codec chain (processed left-to-right)\n * timestamp: Date & ClickHouseCodec<\"Delta, LZ4\">;\n * temperature: number & ClickHouseCodec<\"Gorilla, ZSTD\">;\n *\n * // Specialized codecs\n * counter: number & ClickHouseCodec<\"DoubleDelta\">;\n *\n * // Can combine with other annotations\n * count: UInt64 & ClickHouseCodec<\"DoubleDelta, LZ4\">;\n * }\n */\nexport type ClickHouseCodec<CodecExpr extends string> = {\n _clickhouse_codec?: CodecExpr;\n};\n\nexport type ClickHouseFloat<Value extends \"float32\" | \"float64\"> = tags.Type<\n Value extends \"float32\" ? \"float\" : \"double\"\n>;\n\nexport type ClickHouseInt<\n Value extends\n | \"int8\"\n | \"int16\"\n | \"int32\"\n | \"int64\"\n // | \"int128\"\n // | \"int256\"\n | \"uint8\"\n | \"uint16\"\n | \"uint32\"\n | \"uint64\",\n // | \"uint128\"\n // | \"uint256\",\n> =\n Value extends \"int32\" | \"int64\" | \"uint32\" | \"uint64\" ? tags.Type<Value>\n : TagBase<{\n target: \"number\";\n kind: \"type\";\n value: Value;\n validate: Value extends \"int8\" ? \"-128 <= $input && $input <= 127\"\n : Value extends \"int16\" ? \"-32768 <= $input && $input <= 32767\"\n : Value extends \"uint8\" ? \"0 <= $input && $input <= 255\"\n : Value extends \"uint16\" ? \"0 <= $input && $input <= 65535\"\n : never;\n exclusive: true;\n schema: {\n type: \"integer\";\n };\n }>;\n\n/**\n * By default, nested objects map to the `Nested` type in clickhouse.\n * Write `nestedObject: AnotherInterfaceType & ClickHouseNamedTuple`\n * to map AnotherInterfaceType to the named tuple type.\n */\nexport type ClickHouseNamedTuple = {\n _clickhouse_mapped_type?: \"namedTuple\";\n};\n\nexport type ClickHouseJson<\n maxDynamicPaths extends number | undefined = undefined,\n maxDynamicTypes extends number | undefined = undefined,\n skipPaths extends string[] = [],\n skipRegexes extends string[] = [],\n> = {\n _clickhouse_mapped_type?: \"JSON\";\n _clickhouse_json_settings?: {\n maxDynamicPaths?: maxDynamicPaths;\n maxDynamicTypes?: maxDynamicTypes;\n skipPaths?: skipPaths;\n skipRegexes?: skipRegexes;\n };\n};\n\n// Geometry helper types\nexport type ClickHousePoint = [number, number] & {\n _clickhouse_mapped_type?: \"Point\";\n};\nexport type ClickHouseRing = ClickHousePoint[] & {\n _clickhouse_mapped_type?: \"Ring\";\n};\nexport type ClickHouseLineString = ClickHousePoint[] & {\n _clickhouse_mapped_type?: \"LineString\";\n};\nexport type ClickHouseMultiLineString = ClickHouseLineString[] & {\n _clickhouse_mapped_type?: \"MultiLineString\";\n};\nexport type ClickHousePolygon = ClickHouseRing[] & {\n _clickhouse_mapped_type?: \"Polygon\";\n};\nexport type ClickHouseMultiPolygon = ClickHousePolygon[] & {\n _clickhouse_mapped_type?: \"MultiPolygon\";\n};\n\n/**\n * typia may have trouble handling this type.\n * In which case, use {@link WithDefault} as a workaround\n *\n * @example\n * { field: number & ClickHouseDefault<\"0\"> }\n */\nexport type ClickHouseDefault<SqlExpression extends string> = {\n _clickhouse_default?: SqlExpression;\n};\n\n/**\n * @example\n * {\n * ...\n * timestamp: Date;\n * debugMessage: string & ClickHouseTTL<\"timestamp + INTERVAL 1 WEEK\">;\n * }\n */\nexport type ClickHouseTTL<SqlExpression extends string> = {\n _clickhouse_ttl?: SqlExpression;\n};\n\n/**\n * ClickHouse MATERIALIZED column annotation.\n * The column value is computed at INSERT time and physically stored.\n * Cannot be explicitly inserted by users.\n *\n * @example\n * interface Events {\n * eventTime: DateTime;\n * // Extract date component - computed and stored at insert time\n * eventDate: Date & ClickHouseMaterialized<\"toDate(event_time)\">;\n *\n * userId: string;\n * // Precompute hash for fast lookups\n * userHash: UInt64 & ClickHouseMaterialized<\"cityHash64(userId)\">;\n * }\n *\n * @remarks\n * - MATERIALIZED and DEFAULT are mutually exclusive\n * - Can be combined with ClickHouseCodec for compression\n * - Changing the expression modifies the column in-place (existing values preserved)\n */\nexport type ClickHouseMaterialized<SqlExpression extends string> = {\n _clickhouse_materialized?: SqlExpression;\n};\n\n/**\n * ClickHouse ALIAS column annotation.\n * The column value is computed on-the-fly at SELECT time and NOT physically stored.\n * Cannot be explicitly inserted by users.\n *\n * @example\n * interface Events {\n * eventTime: DateTime;\n * // Computed at query time, not stored on disk\n * eventDate: Date & ClickHouseAlias<\"toDate(event_time)\">;\n *\n * firstName: string;\n * lastName: string;\n * // Virtual computed column\n * fullName: string & ClickHouseAlias<\"concat(first_name, ' ', last_name)\">;\n * }\n *\n * @remarks\n * - ALIAS, MATERIALIZED, and DEFAULT are mutually exclusive\n * - ALIAS columns are NOT stored on disk (saves storage, costs CPU at query time)\n * - Cannot be used in ORDER BY, PRIMARY KEY, or PARTITION BY\n * - Can be combined with ClickHouseCodec (though rarely useful since not stored)\n */\nexport type ClickHouseAlias<SqlExpression extends string> = {\n _clickhouse_alias?: SqlExpression;\n};\n\n/**\n * See also {@link ClickHouseDefault}\n *\n * @example{ updated_at: WithDefault<Date, \"now()\"> }\n */\nexport type WithDefault<T, _SqlExpression extends string> = T;\n\n/**\n * ClickHouse table engine types supported by Moose.\n */\nexport enum ClickHouseEngines {\n MergeTree = \"MergeTree\",\n ReplacingMergeTree = \"ReplacingMergeTree\",\n SummingMergeTree = \"SummingMergeTree\",\n AggregatingMergeTree = \"AggregatingMergeTree\",\n CollapsingMergeTree = \"CollapsingMergeTree\",\n VersionedCollapsingMergeTree = \"VersionedCollapsingMergeTree\",\n GraphiteMergeTree = \"GraphiteMergeTree\",\n S3Queue = \"S3Queue\",\n S3 = \"S3\",\n Buffer = \"Buffer\",\n Distributed = \"Distributed\",\n IcebergS3 = \"IcebergS3\",\n Kafka = \"Kafka\",\n Merge = \"Merge\",\n ReplicatedMergeTree = \"ReplicatedMergeTree\",\n ReplicatedReplacingMergeTree = \"ReplicatedReplacingMergeTree\",\n ReplicatedAggregatingMergeTree = \"ReplicatedAggregatingMergeTree\",\n ReplicatedSummingMergeTree = \"ReplicatedSummingMergeTree\",\n ReplicatedCollapsingMergeTree = \"ReplicatedCollapsingMergeTree\",\n ReplicatedVersionedCollapsingMergeTree = \"ReplicatedVersionedCollapsingMergeTree\",\n}\n","import type {\n Column,\n DataType,\n Nested,\n ArrayType,\n} from \"../dataModels/dataModelTypes\";\n\n/**\n * Annotation key used to mark DateTime fields that should remain as strings\n * rather than being parsed into Date objects at runtime.\n */\nexport const STRING_DATE_ANNOTATION = \"stringDate\";\n\n/**\n * Type guard to check if a DataType is a nullable wrapper\n */\nfunction isNullableType(dt: DataType): dt is { nullable: DataType } {\n return (\n typeof dt === \"object\" &&\n dt !== null &&\n \"nullable\" in dt &&\n typeof dt.nullable !== \"undefined\"\n );\n}\n\n/**\n * Type guard to check if a DataType is a Nested type\n */\nfunction isNestedType(dt: DataType): dt is Nested {\n return (\n typeof dt === \"object\" &&\n dt !== null &&\n \"columns\" in dt &&\n Array.isArray(dt.columns)\n );\n}\n\n/**\n * Type guard to check if a DataType is an ArrayType\n */\nfunction isArrayType(dt: DataType): dt is ArrayType {\n return (\n typeof dt === \"object\" &&\n dt !== null &&\n \"elementType\" in dt &&\n typeof dt.elementType !== \"undefined\"\n );\n}\n\n/**\n * Revives ISO 8601 date strings into Date objects during JSON parsing\n * This is useful for automatically converting date strings to Date objects\n */\nexport function jsonDateReviver(key: string, value: unknown): unknown {\n const iso8601Format =\n /^([\\+-]?\\d{4}(?!\\d{2}\\b))((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))([T\\s]((([01]\\d|2[0-3])((:?)[0-5]\\d)?|24\\:?00)([\\.,]\\d+(?!:))?)?(\\17[0-5]\\d([\\.,]\\d+)?)?([zZ]|([\\+-])([01]\\d|2[0-3]):?([0-5]\\d)?)?)?)$/;\n\n if (typeof value === \"string\" && iso8601Format.test(value)) {\n return new Date(value);\n }\n\n return value;\n}\n\n/**\n * Checks if a DataType represents a datetime column (not just date)\n * AND if the column should be parsed from string to Date at runtime\n *\n * Note: Date and Date16 are date-only types and should remain as strings.\n * Only DateTime types are candidates for parsing to JavaScript Date objects.\n */\nfunction isDateType(dataType: DataType, annotations: [string, any][]): boolean {\n // Check if this is marked as a string-based date (from typia.tags.Format)\n // If so, it should remain as a string, not be parsed to Date\n if (\n annotations.some(\n ([key, value]) => key === STRING_DATE_ANNOTATION && value === true,\n )\n ) {\n return false;\n }\n\n if (typeof dataType === \"string\") {\n // Only DateTime types should be parsed to Date objects\n // Date and Date16 are date-only and should stay as strings\n return dataType === \"DateTime\" || dataType.startsWith(\"DateTime(\");\n }\n // Handle nullable wrapper\n if (isNullableType(dataType)) {\n return isDateType(dataType.nullable, annotations);\n }\n return false;\n}\n\n/**\n * Type of mutation to apply to a field during parsing\n */\nexport type Mutation = \"parseDate\"; // | \"parseBigInt\" - to be added later\n\n/**\n * Recursive tuple array structure representing field mutation operations\n * Each entry is [fieldName, mutation]:\n * - mutation is Mutation[] for leaf fields that need operations applied\n * - mutation is FieldMutations for nested objects/arrays (auto-applies to array elements)\n */\nexport type FieldMutations = [string, Mutation[] | FieldMutations][];\n\n/**\n * Recursively builds field mutations from column definitions\n *\n * @param columns - Array of Column definitions\n * @returns Tuple array of field mutations\n */\nfunction buildFieldMutations(columns: Column[]): FieldMutations {\n const mutations: FieldMutations = [];\n\n for (const column of columns) {\n const dataType = column.data_type;\n\n // Check if this is a date field that should be converted\n if (isDateType(dataType, column.annotations)) {\n mutations.push([column.name, [\"parseDate\"]]);\n continue;\n }\n\n // Handle nested structures\n if (typeof dataType === \"object\" && dataType !== null) {\n // Handle nullable wrapper\n let unwrappedType: DataType = dataType;\n if (isNullableType(dataType)) {\n unwrappedType = dataType.nullable;\n }\n\n // Handle nested objects\n if (isNestedType(unwrappedType)) {\n const nestedMutations = buildFieldMutations(unwrappedType.columns);\n if (nestedMutations.length > 0) {\n mutations.push([column.name, nestedMutations]);\n }\n continue;\n }\n\n // Handle arrays with nested columns\n // The mutations will be auto-applied to each array element at runtime\n if (isArrayType(unwrappedType)) {\n const elementType = unwrappedType.elementType;\n if (isNestedType(elementType)) {\n const nestedMutations = buildFieldMutations(elementType.columns);\n if (nestedMutations.length > 0) {\n mutations.push([column.name, nestedMutations]);\n }\n continue;\n }\n }\n }\n }\n\n return mutations;\n}\n\n/**\n * Applies a mutation operation to a field value\n *\n * @param value - The value to handle\n * @param mutation - The mutation operation to apply\n * @returns The handled value\n */\nfunction applyMutation(value: any, mutation: Mutation): any {\n if (mutation === \"parseDate\") {\n if (typeof value === \"string\") {\n try {\n const date = new Date(value);\n return !isNaN(date.getTime()) ? date : value;\n } catch {\n return value;\n }\n }\n }\n return value;\n}\n\n/**\n * Recursively mutates an object by applying field mutations\n *\n * @param obj - The object to mutate\n * @param mutations - The field mutations to apply\n */\nfunction applyFieldMutations(obj: any, mutations: FieldMutations): void {\n if (!obj || typeof obj !== \"object\") {\n return;\n }\n\n for (const [fieldName, mutation] of mutations) {\n if (!(fieldName in obj)) {\n continue;\n }\n\n if (Array.isArray(mutation)) {\n // Check if it's Mutation[] (leaf) or FieldMutations (nested)\n if (mutation.length > 0 && typeof mutation[0] === \"string\") {\n // It's Mutation[] - apply operations to this field\n const operations = mutation as Mutation[];\n for (const operation of operations) {\n obj[fieldName] = applyMutation(obj[fieldName], operation);\n }\n } else {\n // It's FieldMutations - recurse into nested structure\n const nestedMutations = mutation as FieldMutations;\n const fieldValue = obj[fieldName];\n\n if (Array.isArray(fieldValue)) {\n // Auto-apply to each array element\n for (const item of fieldValue) {\n applyFieldMutations(item, nestedMutations);\n }\n } else if (fieldValue && typeof fieldValue === \"object\") {\n // Apply to nested object\n applyFieldMutations(fieldValue, nestedMutations);\n }\n }\n }\n }\n}\n\n/**\n * Pre-builds field mutations from column schema for efficient reuse\n *\n * @param columns - Column definitions from the Stream schema\n * @returns Field mutations tuple array, or undefined if no columns\n *\n * @example\n * ```typescript\n * const fieldMutations = buildFieldMutationsFromColumns(stream.columnArray);\n * // Reuse fieldMutations for every message\n * ```\n */\nexport function buildFieldMutationsFromColumns(\n columns: Column[] | undefined,\n): FieldMutations | undefined {\n if (!columns || columns.length === 0) {\n return undefined;\n }\n const mutations = buildFieldMutations(columns);\n return mutations.length > 0 ? mutations : undefined;\n}\n\n/**\n * Applies field mutations to parsed data\n * Mutates the object in place for performance\n *\n * @param data - The parsed JSON object to mutate\n * @param fieldMutations - Pre-built field mutations from buildFieldMutationsFromColumns\n *\n * @example\n * ```typescript\n * const fieldMutations = buildFieldMutationsFromColumns(stream.columnArray);\n * const data = JSON.parse(jsonString);\n * mutateParsedJson(data, fieldMutations);\n * // data now has transformations applied per the field mutations\n * ```\n */\nexport function mutateParsedJson(\n data: any,\n fieldMutations: FieldMutations | undefined,\n): void {\n if (!fieldMutations || !data) {\n return;\n }\n\n applyFieldMutations(data, fieldMutations);\n}\n","/**\n * Direct integration with typia's internal programmers\n * This bypasses the need for typia's transformer plugin by directly calling\n * typia's code generation functions.\n *\n * IMPORTANT: We import from typia/lib (compiled JS) not typia/src (TypeScript)\n * to avoid issues with Node's type stripping in node_modules.\n */\nimport ts from \"typescript\";\nimport { ImportProgrammer } from \"typia/lib/programmers/ImportProgrammer\";\nimport { ValidateProgrammer } from \"typia/lib/programmers/ValidateProgrammer\";\nimport { IsProgrammer } from \"typia/lib/programmers/IsProgrammer\";\nimport { AssertProgrammer } from \"typia/lib/programmers/AssertProgrammer\";\nimport { JsonSchemasProgrammer } from \"typia/lib/programmers/json/JsonSchemasProgrammer\";\nimport { HttpAssertQueryProgrammer } from \"typia/lib/programmers/http/HttpAssertQueryProgrammer\";\nimport { MetadataCollection } from \"typia/lib/factories/MetadataCollection\";\nimport { MetadataFactory } from \"typia/lib/factories/MetadataFactory\";\nimport { LiteralFactory } from \"typia/lib/factories/LiteralFactory\";\nimport { ITypiaContext } from \"typia/lib/transformers/ITypiaContext\";\nimport { IJsonSchemaCollection } from \"typia/lib/schemas/json/IJsonSchemaCollection\";\nimport { avoidTypiaNameClash } from \"./compilerPluginHelper\";\n\n// Simple type for JSON Schema objects - we use a minimal type instead of\n// importing @samchon/openapi to avoid adding an extra dependency.\n// Based on OpenApi.IJsonSchema which includes:\n// IConstant, IBoolean, IInteger, INumber, IString, IArray, ITuple,\n// IObject, IReference, IOneOf, INull, IUnknown\ntype JsonSchema = {\n type?: string;\n format?: string;\n $ref?: string;\n // IObject\n properties?: Record<string, JsonSchema>;\n additionalProperties?: boolean | JsonSchema;\n required?: string[];\n // IArray\n items?: JsonSchema;\n // ITuple\n prefixItems?: JsonSchema[];\n additionalItems?: boolean | JsonSchema;\n // Union types\n oneOf?: JsonSchema[];\n anyOf?: JsonSchema[];\n allOf?: JsonSchema[];\n [key: string]: unknown;\n};\n\n/**\n * Context for direct typia code generation\n */\nexport interface TypiaDirectContext {\n program: ts.Program;\n checker: ts.TypeChecker;\n transformer: ts.TransformationContext;\n importer: ImportProgrammer;\n modulo: ts.LeftHandSideExpression;\n sourceFile: ts.SourceFile;\n}\n\n/**\n * Creates a synthetic identifier with a patched getText method.\n * Typia's programmers call modulo.getText() which normally requires\n * the node to be attached to a source file. We patch the method directly.\n */\nconst createSyntheticModulo = (): ts.LeftHandSideExpression => {\n const identifier = ts.factory.createIdentifier(\"typia\");\n\n // Monkey-patch getText to return \"typia\" directly\n identifier.getText = () => \"typia\";\n\n return identifier;\n};\n\n/**\n * Creates a typia context for direct code generation\n */\nexport const createTypiaContext = (\n program: ts.Program,\n transformer: ts.TransformationContext,\n sourceFile: ts.SourceFile,\n): TypiaDirectContext => {\n const importer = new ImportProgrammer({\n internalPrefix: avoidTypiaNameClash,\n });\n\n return {\n program,\n checker: program.getTypeChecker(),\n transformer,\n importer,\n modulo: createSyntheticModulo(),\n sourceFile,\n };\n};\n\n/**\n * Converts our context to typia's internal context format\n */\nconst toTypiaContext = (ctx: TypiaDirectContext): ITypiaContext => ({\n program: ctx.program,\n compilerOptions: ctx.program.getCompilerOptions(),\n checker: ctx.checker,\n printer: ts.createPrinter(),\n options: {},\n transformer: ctx.transformer,\n importer: ctx.importer,\n extras: {\n // Not used by the programmers we call directly (CheckerProgrammer,\n // HttpAssertQueryProgrammer, JsonSchemasProgrammer) - only used by\n // FileTransformer which we bypass\n addDiagnostic: () => 0,\n },\n});\n\n/**\n * Generates a validate function directly using typia's ValidateProgrammer\n */\nexport const generateValidateFunction = (\n ctx: TypiaDirectContext,\n type: ts.Type,\n typeName?: string,\n): ts.Expression => {\n const typiaCtx = toTypiaContext(ctx);\n\n return ValidateProgrammer.write({\n context: typiaCtx,\n modulo: ctx.modulo,\n type,\n name: typeName,\n config: { equals: false },\n });\n};\n\n/**\n * Generates an is function directly using typia's IsProgrammer\n */\nexport const generateIsFunction = (\n ctx: TypiaDirectContext,\n type: ts.Type,\n typeName?: string,\n): ts.Expression => {\n const typiaCtx = toTypiaContext(ctx);\n\n return IsProgrammer.write({\n context: typiaCtx,\n modulo: ctx.modulo,\n type,\n name: typeName,\n config: { equals: false },\n });\n};\n\n/**\n * Generates an assert function directly using typia's AssertProgrammer\n */\nexport const generateAssertFunction = (\n ctx: TypiaDirectContext,\n type: ts.Type,\n typeName?: string,\n): ts.Expression => {\n const typiaCtx = toTypiaContext(ctx);\n\n return AssertProgrammer.write({\n context: typiaCtx,\n modulo: ctx.modulo,\n type,\n name: typeName,\n config: { equals: false, guard: false },\n });\n};\n\n/**\n * Generates an HTTP assert query function for validating URL query parameters\n * This is used by the Api class to validate incoming query parameters\n */\nexport const generateHttpAssertQueryFunction = (\n ctx: TypiaDirectContext,\n type: ts.Type,\n typeName?: string,\n): ts.Expression => {\n const typiaCtx = toTypiaContext(ctx);\n\n return HttpAssertQueryProgrammer.write({\n context: typiaCtx,\n modulo: ctx.modulo,\n type,\n name: typeName,\n });\n};\n\n// ============================================================================\n// JSON Schema Post-Processing\n// ============================================================================\n\n/**\n * The standard JSON Schema representation for Date types.\n * Typia outputs Date as an empty object schema with a $ref, but the correct\n * representation is { type: \"string\", format: \"date-time\" }.\n */\nconst DATE_SCHEMA: JsonSchema = {\n type: \"string\",\n format: \"date-time\",\n};\n\n/**\n * Checks if a property name is an internal ClickHouse tag that should be\n * stripped from the JSON schema.\n */\nconst isClickHouseInternalProperty = (name: string): boolean =>\n name.startsWith(\"_clickhouse_\") || name === \"_LowCardinality\";\n\n/**\n * Recursively processes a JSON schema to:\n * 1. Replace $ref to Date with inline { type: \"string\", format: \"date-time\" }\n * 2. Remove internal ClickHouse properties from object schemas\n *\n * Handles all OpenApi.IJsonSchema variants:\n * IConstant, IBoolean, IInteger, INumber, IString, IArray, ITuple,\n * IObject, IReference, IOneOf, INull, IUnknown\n */\nconst cleanJsonSchema = (schema: JsonSchema): JsonSchema => {\n // Handle $ref to Date - replace with inline date-time schema\n if (schema.$ref === \"#/components/schemas/Date\") {\n // Preserve any other properties from the original schema (like description)\n const { $ref, ...rest } = schema;\n return { ...DATE_SCHEMA, ...rest };\n }\n\n // Handle object schemas (IObject) - filter out ClickHouse internal properties\n if (schema.type === \"object\") {\n const result: JsonSchema = { ...schema };\n\n // Clean properties\n if (schema.properties) {\n const cleanedProperties: Record<string, JsonSchema> = {};\n const cleanedRequired: string[] = [];\n\n for (const [key, value] of Object.entries(schema.properties)) {\n if (!isClickHouseInternalProperty(key)) {\n cleanedProperties[key] = cleanJsonSchema(value);\n if (schema.required?.includes(key)) {\n cleanedRequired.push(key);\n }\n }\n }\n\n result.properties = cleanedProperties;\n result.required =\n cleanedRequired.length > 0 ? cleanedRequired : undefined;\n }\n\n // Clean additionalProperties if it's a schema\n if (\n schema.additionalProperties &&\n typeof schema.additionalProperties === \"object\"\n ) {\n result.additionalProperties = cleanJsonSchema(\n schema.additionalProperties,\n );\n }\n\n return result;\n }\n\n // Handle array schemas (IArray)\n if (schema.type === \"array\") {\n const result: JsonSchema = { ...schema };\n\n // Clean items (IArray.items)\n if (schema.items) {\n result.items = cleanJsonSchema(schema.items);\n }\n\n // Clean prefixItems (ITuple.prefixItems)\n if (schema.prefixItems && Array.isArray(schema.prefixItems)) {\n result.prefixItems = schema.prefixItems.map(cleanJsonSchema);\n }\n\n // Clean additionalItems if it's a schema (ITuple.additionalItems)\n if (schema.additionalItems && typeof schema.additionalItems === \"object\") {\n result.additionalItems = cleanJsonSchema(schema.additionalItems);\n }\n\n return result;\n }\n\n // Handle oneOf/anyOf/allOf (IOneOf and merged types)\n if (schema.oneOf && Array.isArray(schema.oneOf)) {\n return {\n ...schema,\n oneOf: schema.oneOf.map(cleanJsonSchema),\n };\n }\n if (schema.anyOf && Array.isArray(schema.anyOf)) {\n return {\n ...schema,\n anyOf: schema.anyOf.map(cleanJsonSchema),\n };\n }\n if (schema.allOf && Array.isArray(schema.allOf)) {\n return {\n ...schema,\n allOf: schema.allOf.map(cleanJsonSchema),\n };\n }\n\n // Primitive types (IConstant, IBoolean, IInteger, INumber, IString, INull, IUnknown)\n // don't need recursion - return as-is\n return schema;\n};\n\n/**\n * Post-processes a JSON schema collection to clean up Moose-specific artifacts:\n * 1. Converts Date schemas to { type: \"string\", format: \"date-time\" }\n * 2. Removes internal ClickHouse properties (_clickhouse_*, _LowCardinality)\n */\nconst cleanJsonSchemaCollection = <V extends \"3.0\" | \"3.1\">(\n collection: IJsonSchemaCollection<V>,\n): IJsonSchemaCollection<V> => {\n // Clean component schemas\n const cleanedComponentsSchemas: Record<string, JsonSchema> = {};\n\n if (collection.components.schemas) {\n for (const [name, schema] of Object.entries(\n collection.components.schemas,\n )) {\n // Replace Date schema with proper date-time representation\n if (name === \"Date\") {\n cleanedComponentsSchemas[name] = DATE_SCHEMA;\n } else {\n cleanedComponentsSchemas[name] = cleanJsonSchema(schema as JsonSchema);\n }\n }\n }\n\n // Clean top-level schemas\n const cleanedSchemas = collection.schemas.map((s) =>\n cleanJsonSchema(s as JsonSchema),\n );\n\n return {\n ...collection,\n components: {\n ...collection.components,\n schemas: cleanedComponentsSchemas,\n },\n schemas: cleanedSchemas,\n } as IJsonSchemaCollection<V>;\n};\n\n/**\n * Generates JSON schemas directly using typia's JsonSchemasProgrammer.\n *\n * Uses the same options as CheckerProgrammer (absorb: true, escape: false)\n * to handle our custom ClickHouse type tags that typia doesn't recognize.\n *\n * Post-processes the generated schema to:\n * 1. Convert Date to { type: \"string\", format: \"date-time\" }\n * 2. Strip internal ClickHouse properties (_clickhouse_*, _LowCardinality)\n */\nexport const generateJsonSchemas = (\n ctx: TypiaDirectContext,\n type: ts.Type,\n): ts.Expression => {\n // Use same options as CheckerProgrammer for consistency\n // Key: escape: false allows intersection handling without errors\n // Note: We don't strip custom type tags here - cleanJsonSchemaCollection\n // handles removing _clickhouse_* properties from the output\n const metadataResult = MetadataFactory.analyze({\n checker: ctx.checker,\n transformer: ctx.transformer,\n options: {\n absorb: true,\n constant: true,\n escape: false, // Match CheckerProgrammer - this is key!\n },\n collection: new MetadataCollection({\n replace: MetadataCollection.replace,\n }),\n type: type,\n });\n\n if (!metadataResult.success) {\n const errors = metadataResult.errors\n .map((e) => `${e.name}: ${e.messages.join(\", \")}`)\n .join(\"; \");\n throw new Error(`Typia metadata analysis failed: ${errors}`);\n }\n\n // Generate the JSON schema collection\n const rawCollection = JsonSchemasProgrammer.write({\n version: \"3.1\",\n metadatas: [metadataResult.data],\n });\n\n // Post-process to clean up Moose-specific artifacts\n const collection = cleanJsonSchemaCollection(rawCollection);\n\n // Convert the collection to an AST literal\n return ts.factory.createAsExpression(\n LiteralFactory.write(collection),\n ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword),\n );\n};\n","import ts, { factory, SyntaxKind } from \"typescript\";\nimport { isMooseFile, type TransformContext } from \"../compilerPluginHelper\";\nimport { toColumns } from \"../dataModels/typeConvert\";\nimport { parseAsAny } from \"../dmv2/dataModelMetadata\";\nimport {\n generateHttpAssertQueryFunction,\n generateJsonSchemas,\n} from \"../typiaDirectIntegration\";\n\nexport const isApiV2 = (\n node: ts.Node,\n checker: ts.TypeChecker,\n): node is ts.NewExpression => {\n if (!ts.isNewExpression(node)) {\n return false;\n }\n\n const declaration: ts.Declaration | undefined =\n checker.getResolvedSignature(node)?.declaration;\n if (!declaration || !isMooseFile(declaration.getSourceFile())) {\n return false;\n }\n\n const sym = checker.getSymbolAtLocation(node.expression);\n return sym?.name === \"Api\" || sym?.name === \"ConsumptionApi\";\n};\n\nexport const transformApiV2 = (\n node: ts.NewExpression,\n checker: ts.TypeChecker,\n ctx: TransformContext,\n): ts.Node => {\n if (!isApiV2(node, checker)) {\n return node;\n }\n\n if (!node.arguments || node.arguments.length < 2 || !node.typeArguments) {\n return node;\n }\n\n const typiaCtx = ctx.typiaContext;\n\n // Get both type parameters from Api<T, R>\n const typeNode = node.typeArguments[0];\n const responseTypeNode =\n node.typeArguments[1] ||\n factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword);\n\n const inputType = checker.getTypeAtLocation(typeNode);\n const responseType = checker.getTypeAtLocation(responseTypeNode);\n\n // Get the handler function (second argument)\n const handlerFunc = node.arguments[1];\n\n // Generate the HTTP assert query function directly\n const assertQueryFunc = generateHttpAssertQueryFunction(typiaCtx, inputType);\n\n // Create a new handler function that includes validation\n const wrappedHandler = factory.createArrowFunction(\n undefined,\n undefined,\n [\n factory.createParameterDeclaration(\n undefined,\n undefined,\n factory.createIdentifier(\"params\"),\n undefined,\n undefined,\n undefined,\n ),\n factory.createParameterDeclaration(\n undefined,\n undefined,\n factory.createIdentifier(\"utils\"),\n undefined,\n undefined,\n undefined,\n ),\n ],\n undefined,\n factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),\n factory.createBlock(\n [\n // const assertGuard = <generated http assert query function>\n factory.createVariableStatement(\n undefined,\n factory.createVariableDeclarationList(\n [\n factory.createVariableDeclaration(\n factory.createIdentifier(\"assertGuard\"),\n undefined,\n undefined,\n assertQueryFunc,\n ),\n ],\n ts.NodeFlags.Const,\n ),\n ),\n // const searchParams = new URLSearchParams(params as any)\n factory.createVariableStatement(\n undefined,\n factory.createVariableDeclarationList(\n [\n factory.createVariableDeclaration(\n factory.createIdentifier(\"searchParams\"),\n undefined,\n undefined,\n factory.createNewExpression(\n factory.createIdentifier(\"URLSearchParams\"),\n undefined,\n [\n factory.createAsExpression(\n factory.createIdentifier(\"params\"),\n factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword),\n ),\n ],\n ),\n ),\n ],\n ts.NodeFlags.Const,\n ),\n ),\n // const processedParams = assertGuard(searchParams)\n factory.createVariableStatement(\n undefined,\n factory.createVariableDeclarationList(\n [\n factory.createVariableDeclaration(\n factory.createIdentifier(\"processedParams\"),\n undefined,\n undefined,\n factory.createCallExpression(\n factory.createIdentifier(\"assertGuard\"),\n undefined,\n [factory.createIdentifier(\"searchParams\")],\n ),\n ),\n ],\n ts.NodeFlags.Const,\n ),\n ),\n factory.createVariableStatement(\n undefined,\n factory.createVariableDeclarationList(\n [\n factory.createVariableDeclaration(\n factory.createIdentifier(\"originalHandler\"),\n undefined,\n factory.createFunctionTypeNode(\n undefined,\n [\n factory.createParameterDeclaration(\n undefined,\n undefined,\n \"params\",\n undefined,\n typeNode,\n ),\n factory.createParameterDeclaration(\n undefined,\n undefined,\n \"utils\",\n undefined,\n factory.createImportTypeNode(\n factory.createLiteralTypeNode(\n factory.createStringLiteral(\"@514labs/moose-lib\"),\n ),\n undefined,\n factory.createIdentifier(\"ApiUtil\"),\n [],\n false,\n ),\n ),\n ],\n factory.createKeywordTypeNode(SyntaxKind.AnyKeyword),\n ),\n factory.createParenthesizedExpression(handlerFunc),\n ),\n ],\n ts.NodeFlags.Const,\n ),\n ),\n // return originalHandler(processedParams, utils)\n factory.createReturnStatement(\n factory.createCallExpression(\n factory.createIdentifier(\"originalHandler\"),\n undefined,\n [\n factory.createIdentifier(\"processedParams\"),\n factory.createIdentifier(\"utils\"),\n ],\n ),\n ),\n ],\n true,\n ),\n );\n\n // Generate schemas directly\n const inputSchemaArg =\n node.arguments.length > 3 ?\n node.arguments[3]\n : generateJsonSchemas(typiaCtx, inputType);\n const responseSchemaArg = generateJsonSchemas(typiaCtx, responseType);\n\n // Create the columns argument if it doesn't exist\n const inputColumnsArg = toColumns(inputType, checker);\n\n // Create the config argument if it doesn't exist\n const configArg =\n node.arguments.length > 2 ?\n node.arguments[2]\n : factory.createObjectLiteralExpression([], false);\n\n // Update the Api constructor call with all necessary arguments\n return factory.updateNewExpression(\n node,\n node.expression,\n node.typeArguments,\n [\n node.arguments[0], // name\n wrappedHandler, // wrapped handler\n configArg, // config object\n inputSchemaArg, // input schema\n parseAsAny(JSON.stringify(inputColumnsArg)), // input columns\n responseSchemaArg, // response schema\n ],\n );\n};\n","import {\n existsSync,\n readdirSync,\n readFileSync,\n statSync,\n writeFileSync,\n} from \"fs\";\nimport nodePath from \"path\";\nimport { createClient } from \"@clickhouse/client\";\nimport { KafkaJS } from \"@514labs/kafka-javascript\";\nimport { SASLOptions } from \"@514labs/kafka-javascript/types/kafkajs\";\nconst { Kafka } = KafkaJS;\ntype Kafka = KafkaJS.Kafka;\ntype Consumer = KafkaJS.Consumer;\nexport type Producer = KafkaJS.Producer;\n\n/**\n * Utility function for compiler-related logging that can be disabled via environment variable.\n * Set MOOSE_DISABLE_COMPILER_LOGS=true to suppress these logs (useful for testing environments).\n */\n\n/**\n * Returns true if the value is a common truthy string: \"1\", \"true\", \"yes\", \"on\" (case-insensitive).\n */\nfunction isTruthy(value: string | undefined): boolean {\n if (!value) return false;\n switch (value.trim().toLowerCase()) {\n case \"1\":\n case \"true\":\n case \"yes\":\n case \"on\":\n return true;\n default:\n return false;\n }\n}\n\nexport const compilerLog = (message: string) => {\n if (!isTruthy(process.env.MOOSE_DISABLE_COMPILER_LOGS)) {\n console.log(message);\n }\n};\n\nexport const antiCachePath = (path: string) =>\n `${path}?num=${Math.random().toString()}&time=${Date.now()}`;\n\nexport const getFileName = (filePath: string) => {\n const regex = /\\/([^\\/]+)\\.ts/;\n const matches = filePath.match(regex);\n if (matches && matches.length > 1) {\n return matches[1];\n }\n return \"\";\n};\n\ninterface ClientConfig {\n username: string;\n password: string;\n database: string;\n useSSL: string;\n host: string;\n port: string;\n}\n\nexport const getClickhouseClient = ({\n username,\n password,\n database,\n useSSL,\n host,\n port,\n}: ClientConfig) => {\n const protocol =\n useSSL === \"1\" || useSSL.toLowerCase() === \"true\" ? \"https\" : \"http\";\n console.log(`Connecting to Clickhouse at ${protocol}://${host}:${port}`);\n return createClient({\n url: `${protocol}://${host}:${port}`,\n username: username,\n password: password,\n database: database,\n application: \"moose\",\n // Note: wait_end_of_query is configured per operation type, not globally\n // to preserve SELECT query performance while ensuring INSERT/DDL reliability\n });\n};\n\nexport type CliLogData = {\n message_type?: \"Info\" | \"Success\" | \"Warning\" | \"Error\" | \"Highlight\";\n action: string;\n message: string;\n};\n\nexport const cliLog: (log: CliLogData) => void = (log) => {\n const level =\n log.message_type === \"Error\" ? \"error\"\n : log.message_type === \"Warning\" ? \"warn\"\n : \"info\";\n\n const structuredLog = {\n __moose_structured_log__: true,\n level,\n message: log.message,\n resource_type: \"runtime\",\n cli_action: log.action,\n cli_message_type: log.message_type ?? \"Info\",\n timestamp: new Date().toISOString(),\n };\n\n process.stderr.write(JSON.stringify(structuredLog) + \"\\n\");\n};\n\n/**\n * Method to change .ts, .cts, and .mts to .js, .cjs, and .mjs\n * This is needed because 'import' does not support .ts, .cts, and .mts\n */\nexport function mapTstoJs(filePath: string): string {\n return filePath\n .replace(/\\.ts$/, \".js\")\n .replace(/\\.cts$/, \".cjs\")\n .replace(/\\.mts$/, \".mjs\");\n}\n\n/**\n * Walks a directory recursively and returns all files matching the given extensions.\n * Skips node_modules directories.\n *\n * @param dir - Directory to walk\n * @param extensions - File extensions to include (e.g., [\".js\", \".mjs\"])\n * @returns Array of file paths\n */\nfunction walkDirectory(dir: string, extensions: string[]): string[] {\n const results: string[] = [];\n\n if (!existsSync(dir)) {\n return results;\n }\n\n try {\n const entries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = nodePath.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n // Skip node_modules\n if (entry.name !== \"node_modules\") {\n results.push(...walkDirectory(fullPath, extensions));\n }\n } else if (entry.isFile()) {\n const ext = nodePath.extname(entry.name);\n if (extensions.includes(ext)) {\n results.push(fullPath);\n }\n }\n }\n } catch (e) {\n // Log error in case it is something the user can/should act on\n console.debug(`[moose] Failed to read directory ${dir}:`, e);\n }\n\n return results;\n}\n\n/**\n * Adds .js extension to relative import paths that don't have an extension.\n * Handles import/export from statements and dynamic imports.\n *\n * @param content - JavaScript file content\n * @param fileDir - Directory containing the file being processed (for resolving paths)\n * @returns Content with .js extensions added to relative imports\n */\nfunction addJsExtensionToImports(content: string, fileDir?: string): string {\n // Pattern for 'from' statements with relative paths\n // Matches: from './foo', from \"../bar\", from './utils/helper'\n const fromPattern = /(from\\s+['\"])(\\.\\.?\\/[^'\"]*?)(['\"])/g;\n\n // Pattern for side-effect-only imports with relative paths\n // Matches: import './foo', import \"../bar\" (no 'from' keyword, just importing for side effects)\n const bareImportPattern = /(import\\s+['\"])(\\.\\.?\\/[^'\"]*?)(['\"])/g;\n\n // Pattern for dynamic imports with relative paths\n // Matches: import('./foo'), import(\"../bar\")\n const dynamicPattern = /(import\\s*\\(\\s*['\"])(\\.\\.?\\/[^'\"]*?)(['\"])/g;\n\n let result = content;\n\n // Process 'from' statements\n result = result.replace(fromPattern, (match, prefix, importPath, quote) => {\n return rewriteImportPath(match, prefix, importPath, quote, fileDir);\n });\n\n // Process side-effect-only imports\n result = result.replace(\n bareImportPattern,\n (match, prefix, importPath, quote) => {\n return rewriteImportPath(match, prefix, importPath, quote, fileDir);\n },\n );\n\n // Process dynamic imports\n result = result.replace(\n dynamicPattern,\n (match, prefix, importPath, quote) => {\n return rewriteImportPath(match, prefix, importPath, quote, fileDir);\n },\n );\n\n return result;\n}\n\n/**\n * Rewrites a single import path to add .js extension if needed.\n * Handles directory imports with index files correctly.\n *\n * @param match - The full matched string\n * @param prefix - The prefix (from ' or import(')\n * @param importPath - The import path\n * @param quote - The closing quote\n * @param fileDir - Directory containing the file being processed (for resolving paths)\n * @returns The rewritten import or original if no change needed\n */\nfunction rewriteImportPath(\n match: string,\n prefix: string,\n importPath: string,\n quote: string,\n fileDir?: string,\n): string {\n // Skip if already has a JavaScript extension\n if (/\\.[cm]?js$/.test(importPath)) {\n return match;\n }\n\n // Skip if importing a JSON file\n if (/\\.json$/.test(importPath)) {\n return match;\n }\n\n // If we have the file directory, check if the import target is a directory with index.js\n if (fileDir) {\n const resolvedPath = nodePath.resolve(fileDir, importPath);\n\n // Check if path.js exists (regular file import)\n if (existsSync(`${resolvedPath}.js`)) {\n return `${prefix}${importPath}.js${quote}`;\n }\n\n // Check if path/index.js exists (directory import)\n if (existsSync(nodePath.join(resolvedPath, \"index.js\"))) {\n // For directory imports, rewrite to include /index.js\n return `${prefix}${importPath}/index.js${quote}`;\n }\n\n // Check for .mjs variants\n if (existsSync(`${resolvedPath}.mjs`)) {\n return `${prefix}${importPath}.mjs${quote}`;\n }\n if (existsSync(nodePath.join(resolvedPath, \"index.mjs\"))) {\n return `${prefix}${importPath}/index.mjs${quote}`;\n }\n\n // Check for .cjs variants\n if (existsSync(`${resolvedPath}.cjs`)) {\n return `${prefix}${importPath}.cjs${quote}`;\n }\n if (existsSync(nodePath.join(resolvedPath, \"index.cjs\"))) {\n return `${prefix}${importPath}/index.cjs${quote}`;\n }\n }\n\n // Default: add .js extension (fallback when no fileDir or file not found)\n return `${prefix}${importPath}.js${quote}`;\n}\n\n/**\n * Rewrites relative import paths in JavaScript files to include .js extensions.\n * This is required for Node.js ESM which requires explicit extensions.\n *\n * Handles:\n * - import statements: import { foo } from './bar' -> import { foo } from './bar.js'\n * - dynamic imports: import('./bar') -> import('./bar.js')\n * - re-exports: export { foo } from './bar' -> export { foo } from './bar.js'\n *\n * Does NOT modify:\n * - Package imports (no leading . or ..)\n * - Imports that already have extensions\n * - Imports from node_modules\n *\n * @param outDir - Directory containing compiled JavaScript files\n */\nexport function rewriteImportExtensions(outDir: string): void {\n const files = walkDirectory(outDir, [\".js\", \".mjs\"]);\n\n for (const filePath of files) {\n const content = readFileSync(filePath, \"utf-8\");\n const fileDir = nodePath.dirname(filePath);\n const rewritten = addJsExtensionToImports(content, fileDir);\n\n if (content !== rewritten) {\n writeFileSync(filePath, rewritten, \"utf-8\");\n }\n }\n}\n\nexport const MAX_RETRIES = 150;\nexport const MAX_RETRY_TIME_MS = 1000;\nexport const RETRY_INITIAL_TIME_MS = 100;\n\nexport const MAX_RETRIES_PRODUCER = 150;\nexport const RETRY_FACTOR_PRODUCER = 0.2;\n// Means all replicas need to acknowledge the message\nexport const ACKs = -1;\n\n/**\n * Creates the base producer configuration for Kafka.\n * Used by both the SDK stream publishing and streaming function workers.\n *\n * @param maxMessageBytes - Optional max message size in bytes (synced with topic config)\n * @returns Producer configuration object for the Confluent Kafka client\n */\nexport function createProducerConfig(maxMessageBytes?: number) {\n return {\n kafkaJS: {\n idempotent: false, // Not needed for at-least-once delivery\n acks: ACKs,\n retry: {\n retries: MAX_RETRIES_PRODUCER,\n maxRetryTime: MAX_RETRY_TIME_MS,\n },\n },\n \"linger.ms\": 0, // This is to make sure at least once delivery with immediate feedback on the send\n ...(maxMessageBytes && { \"message.max.bytes\": maxMessageBytes }),\n };\n}\n\n/**\n * Parses a comma-separated broker string into an array of valid broker addresses.\n * Handles whitespace trimming and filters out empty elements.\n *\n * @param brokerString - Comma-separated broker addresses (e.g., \"broker1:9092, broker2:9092, , broker3:9092\")\n * @returns Array of trimmed, non-empty broker addresses\n */\nconst parseBrokerString = (brokerString: string): string[] =>\n brokerString\n .split(\",\")\n .map((b) => b.trim())\n .filter((b) => b.length > 0);\n\nexport type KafkaClientConfig = {\n clientId: string;\n broker: string;\n securityProtocol?: string; // e.g. \"SASL_SSL\" or \"PLAINTEXT\"\n saslUsername?: string;\n saslPassword?: string;\n saslMechanism?: string; // e.g. \"scram-sha-256\", \"plain\"\n};\n\n/**\n * Dynamically creates and connects a KafkaJS producer using the provided configuration.\n * Returns a connected producer instance.\n *\n * @param cfg - Kafka client configuration\n * @param logger - Logger instance\n * @param maxMessageBytes - Optional max message size in bytes (synced with topic config)\n */\nexport async function getKafkaProducer(\n cfg: KafkaClientConfig,\n logger: Logger,\n maxMessageBytes?: number,\n): Promise<Producer> {\n const kafka = await getKafkaClient(cfg, logger);\n\n const producer = kafka.producer(createProducerConfig(maxMessageBytes));\n await producer.connect();\n return producer;\n}\n\n/**\n * Interface for logging functionality\n */\nexport interface Logger {\n logPrefix: string;\n log: (message: string) => void;\n error: (message: string) => void;\n warn: (message: string) => void;\n}\n\nexport const logError = (logger: Logger, e: Error): void => {\n logger.error(e.message);\n const stack = e.stack;\n if (stack) {\n logger.error(stack);\n }\n};\n\n/**\n * Builds SASL configuration for Kafka client authentication\n */\nconst buildSaslConfig = (\n logger: Logger,\n args: KafkaClientConfig,\n): SASLOptions | undefined => {\n const mechanism = args.saslMechanism ? args.saslMechanism.toLowerCase() : \"\";\n switch (mechanism) {\n case \"plain\":\n case \"scram-sha-256\":\n case \"scram-sha-512\":\n return {\n mechanism: mechanism,\n username: args.saslUsername || \"\",\n password: args.saslPassword || \"\",\n };\n default:\n logger.warn(`Unsupported SASL mechanism: ${args.saslMechanism}`);\n return undefined;\n }\n};\n\n/**\n * Dynamically creates a KafkaJS client configured with provided settings.\n * Use this to construct producers/consumers with custom options.\n */\nexport const getKafkaClient = async (\n cfg: KafkaClientConfig,\n logger: Logger,\n): Promise<Kafka> => {\n const brokers = parseBrokerString(cfg.broker || \"\");\n if (brokers.length === 0) {\n throw new Error(`No valid broker addresses found in: \"${cfg.broker}\"`);\n }\n\n logger.log(`Creating Kafka client with brokers: ${brokers.join(\", \")}`);\n logger.log(`Security protocol: ${cfg.securityProtocol || \"plaintext\"}`);\n logger.log(`Client ID: ${cfg.clientId}`);\n\n const saslConfig = buildSaslConfig(logger, cfg);\n\n return new Kafka({\n kafkaJS: {\n clientId: cfg.clientId,\n brokers,\n ssl: cfg.securityProtocol === \"SASL_SSL\",\n ...(saslConfig && { sasl: saslConfig }),\n retry: {\n initialRetryTime: RETRY_INITIAL_TIME_MS,\n maxRetryTime: MAX_RETRY_TIME_MS,\n retries: MAX_RETRIES,\n },\n },\n });\n};\n"],"mappings":"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","names":["ts","factory","process","transform","ts","ts","ts","ts","t","ts","ts","ts","ts","ts","factory","ts","factory","ts","factory"]}
1
+ {"version":3,"sources":["../src/compilerPlugin.ts","../src/compilerPluginHelper.ts","../src/dmv2/dataModelMetadata.ts","../src/dataModels/typeConvert.ts","../src/dataModels/enumConvert.ts","../src/dataModels/dataModelTypes.ts","../src/dataModels/types.ts","../src/utilities/json.ts","../src/typiaDirectIntegration.ts","../src/consumption-apis/typiaValidation.ts","../src/commons.ts"],"sourcesContent":["import ts, { factory } from \"typescript\";\nimport {\n createTransformer,\n type TransformContext,\n} from \"./compilerPluginHelper\";\nimport {\n isNewMooseResourceWithTypeParam,\n transformNewMooseResource,\n} from \"./dmv2/dataModelMetadata\";\nimport { isApiV2, transformApiV2 } from \"./consumption-apis/typiaValidation\";\nimport { createTypiaContext } from \"./typiaDirectIntegration\";\nimport { compilerLog } from \"./commons\";\n\n/**\n * Applies the appropriate transformation based on node type\n */\nconst applyTransformation = (\n node: ts.Node,\n ctx: TransformContext,\n): ts.Node | undefined => {\n if (isApiV2(node, ctx.typeChecker)) {\n compilerLog(\"[CompilerPlugin] Found API v2, transforming...\");\n return transformApiV2(node, ctx.typeChecker, ctx);\n }\n\n if (isNewMooseResourceWithTypeParam(node, ctx.typeChecker)) {\n compilerLog(\n \"[CompilerPlugin] Found Moose resource with type param, transforming...\",\n );\n return transformNewMooseResource(node, ctx.typeChecker, ctx);\n }\n\n return undefined;\n};\n\n/**\n * Main transformation function that processes TypeScript source files\n */\nconst transform =\n (typeChecker: ts.TypeChecker, program: ts.Program) =>\n (transformationContext: ts.TransformationContext) =>\n (sourceFile: ts.SourceFile): ts.SourceFile => {\n compilerLog(\n `\\n[CompilerPlugin] ========== Processing file: ${sourceFile.fileName} ==========`,\n );\n let transformationCount = 0;\n const typiaContext = createTypiaContext(\n program,\n transformationContext,\n sourceFile,\n );\n\n const ctx: TransformContext = {\n typeChecker,\n program,\n typiaContext,\n };\n\n const visitNode = (node: ts.Node): ts.Node => {\n const transformed = applyTransformation(node, ctx);\n if (transformed !== undefined) {\n transformationCount++;\n compilerLog(\n `[CompilerPlugin] Transformation #${transformationCount} applied at position ${node.pos}`,\n );\n }\n const result = transformed ?? node;\n return ts.visitEachChild(result, visitNode, transformationContext);\n };\n\n const transformedSourceFile = ts.visitEachChild(\n sourceFile,\n visitNode,\n transformationContext,\n );\n\n compilerLog(\n `[CompilerPlugin] Total transformations applied: ${transformationCount}`,\n );\n\n // Add imports from ImportProgrammer (for direct typia integration)\n const typiaImports = typiaContext.importer.toStatements();\n if (typiaImports.length === 0) {\n compilerLog(\n `[CompilerPlugin] ========== Completed processing ${sourceFile.fileName} (no import needed) ==========\\n`,\n );\n return transformedSourceFile;\n }\n\n compilerLog(\n `[CompilerPlugin] ========== Completed processing ${sourceFile.fileName} (with import) ==========\\n`,\n );\n return factory.updateSourceFile(\n transformedSourceFile,\n factory.createNodeArray([\n ...typiaImports,\n ...transformedSourceFile.statements,\n ]),\n );\n };\n\nexport default createTransformer(transform);\n","import ts from \"typescript\";\nimport path from \"path\";\nimport { PluginConfig, TransformerExtras } from \"ts-patch\";\nimport process from \"process\";\nimport fs from \"node:fs\";\n\nexport const isMooseFile = (sourceFile: ts.SourceFile): boolean => {\n const location: string = path.resolve(sourceFile.fileName);\n\n return (\n location.includes(\"@514labs/moose-lib\") ||\n // workaround for e2e test\n location.includes(\"packages/ts-moose-lib/dist\") ||\n // support local development with symlinked packages\n location.includes(\"packages/ts-moose-lib/src\")\n );\n};\n\nimport type { TypiaDirectContext } from \"./typiaDirectIntegration\";\n\n/**\n * Context passed to transformation functions\n */\nexport interface TransformContext {\n typeChecker: ts.TypeChecker;\n program: ts.Program;\n /** Shared typia context for direct code generation - created per-file */\n typiaContext: TypiaDirectContext;\n}\n\n/**\n * Creates a regular TypeScript transformer (not a program transformer).\n * This is simpler and works better with incremental compilation since\n * we're not replacing the entire program.\n */\nexport const createTransformer =\n (\n transform: (\n typeChecker: ts.TypeChecker,\n program: ts.Program,\n ) => (\n _context: ts.TransformationContext,\n ) => (sourceFile: ts.SourceFile) => ts.SourceFile,\n ) =>\n (\n program: ts.Program,\n _configOrHost: PluginConfig | ts.CompilerHost | undefined,\n _extrasOrConfig: TransformerExtras | PluginConfig,\n maybeProgramExtras?: unknown,\n ): ts.TransformerFactory<ts.SourceFile> => {\n // Detect if called with transformProgram: true (4 args) vs regular transformer (3 args)\n // transformProgram signature: (program, host, config, extras) => Program\n // regular signature: (program, config, extras) => TransformerFactory\n if (maybeProgramExtras !== undefined) {\n throw new Error(\n `[moose] Your tsconfig.json has \"transformProgram\": true for the moose plugin, ` +\n `but this version requires \"transformProgram\": false (or remove it entirely).\\n\\n` +\n `Update your tsconfig.json plugins section:\\n` +\n ` \"plugins\": [\\n` +\n ` { \"transform\": \"./node_modules/@514labs/moose-lib/dist/compilerPlugin.js\" },\\n` +\n ` { \"transform\": \"typia/lib/transform\" }\\n` +\n ` ]\\n\\n` +\n `Also remove \"isolatedModules\": true if present (incompatible with type-dependent transformations).`,\n );\n }\n\n const transformFunction = transform(program.getTypeChecker(), program);\n\n // Return a transformer factory\n return (context: ts.TransformationContext) => {\n return (sourceFile: ts.SourceFile) => {\n // Skip node_modules and declaration files\n const cwd = process.cwd();\n if (\n sourceFile.isDeclarationFile ||\n sourceFile.fileName.includes(\"/node_modules/\")\n ) {\n return sourceFile;\n }\n\n // Only transform files in the current project\n if (\n sourceFile.fileName.startsWith(\"/\") &&\n !sourceFile.fileName.startsWith(cwd)\n ) {\n return sourceFile;\n }\n\n // Apply transformation\n const result = transformFunction(context)(sourceFile);\n\n // Debug: write transformed source to .moose/api-compile-step/\n try {\n const printer = ts.createPrinter();\n const newFile = printer.printFile(result);\n const fileName =\n sourceFile.fileName.split(\"/\").pop() || sourceFile.fileName;\n const dir = `${process.cwd()}/.moose/api-compile-step/`;\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(`${dir}/${fileName}`, newFile);\n } catch (_e) {\n // this file is just for debugging purposes\n }\n\n return result;\n };\n };\n };\n\nexport const avoidTypiaNameClash = \"____moose____typia\";\n","import ts, { factory } from \"typescript\";\nimport { isMooseFile, type TransformContext } from \"../compilerPluginHelper\";\nimport { toColumns } from \"../dataModels/typeConvert\";\nimport type { Column } from \"../dataModels/dataModelTypes\";\nimport {\n generateValidateFunction,\n generateIsFunction,\n generateAssertFunction,\n generateJsonSchemas,\n generateInsertValidateFunction,\n generateInsertIsFunction,\n generateInsertAssertFunction,\n type InsertColumnSets,\n} from \"../typiaDirectIntegration\";\n\nconst typesToArgsLength = new Map([\n [\"OlapTable\", 2],\n [\"Stream\", 2],\n [\"DeadLetterQueue\", 2],\n [\"IngestPipeline\", 2],\n [\"IngestApi\", 2],\n [\"Api\", 2],\n [\"MaterializedView\", 1],\n [\"Task\", 2],\n]);\n\nexport const isNewMooseResourceWithTypeParam = (\n node: ts.Node,\n checker: ts.TypeChecker,\n): node is ts.NewExpression => {\n if (!ts.isNewExpression(node)) {\n return false;\n }\n\n const declaration: ts.Declaration | undefined =\n checker.getResolvedSignature(node)?.declaration;\n\n if (!declaration || !isMooseFile(declaration.getSourceFile())) {\n return false;\n }\n const sym = checker.getSymbolAtLocation(node.expression);\n const typeName = sym?.name ?? \"\";\n if (!typesToArgsLength.has(typeName)) {\n return false;\n }\n\n // Require arguments to be present\n if (!node.arguments) {\n return false;\n }\n\n const expectedArgLength = typesToArgsLength.get(typeName)!;\n const actualArgLength = node.arguments.length;\n\n // Check if this is an untransformed moose resource\n // Transformed resources have more arguments (schema, columns, validators, etc.)\n const isUntransformed =\n actualArgLength === expectedArgLength - 1 || // name only\n actualArgLength === expectedArgLength; // name + config\n\n return isUntransformed && node.typeArguments?.length === 1;\n};\n\nexport const parseAsAny = (s: string) =>\n factory.createAsExpression(\n factory.createCallExpression(\n factory.createPropertyAccessExpression(\n factory.createIdentifier(\"JSON\"),\n factory.createIdentifier(\"parse\"),\n ),\n undefined,\n [factory.createStringLiteral(s)],\n ),\n factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword),\n );\n\nexport const transformNewMooseResource = (\n node: ts.NewExpression,\n checker: ts.TypeChecker,\n ctx: TransformContext,\n): ts.Node => {\n const typeName = checker.getSymbolAtLocation(node.expression)!.name;\n\n const typeNode = node.typeArguments![0];\n\n // For IngestPipeline, check if table is configured in the config object\n // Index signatures are only allowed when table is false/not configured\n // (because OlapTable requires a fixed schema)\n let ingestPipelineHasTable = true; // Default to true (safe: disallows index signatures)\n if (\n typeName === \"IngestPipeline\" &&\n node.arguments &&\n node.arguments.length >= 2\n ) {\n const configArg = node.arguments[1];\n if (ts.isObjectLiteralExpression(configArg)) {\n const tableProperty = configArg.properties.find(\n (prop): prop is ts.PropertyAssignment =>\n ts.isPropertyAssignment(prop) &&\n ts.isIdentifier(prop.name) &&\n prop.name.text === \"table\",\n );\n if (tableProperty) {\n const tableValue = tableProperty.initializer;\n // Check if table value is explicitly false\n ingestPipelineHasTable = tableValue.kind !== ts.SyntaxKind.FalseKeyword;\n }\n // If table property is not found, keep default (true = has table)\n // This is the safe default since 'table' is a required property\n }\n }\n\n // Allow index signatures for IngestApi, Stream, and IngestPipeline (when table is not configured)\n // These resources accept arbitrary payload fields that pass through to streaming functions\n const allowIndexSignatures =\n [\"IngestApi\", \"Stream\"].includes(typeName) ||\n (typeName === \"IngestPipeline\" && !ingestPipelineHasTable);\n\n // Check if the type actually has an index signature\n const typeAtLocation = checker.getTypeAtLocation(typeNode);\n const indexSignatures = checker.getIndexInfosOfType(typeAtLocation);\n const hasIndexSignature = allowIndexSignatures && indexSignatures.length > 0;\n\n // Validate: IngestPipeline with table=true cannot have index signatures\n // because extra fields would be silently dropped when writing to ClickHouse\n if (\n typeName === \"IngestPipeline\" &&\n ingestPipelineHasTable &&\n indexSignatures.length > 0\n ) {\n throw new Error(\n `IngestPipeline cannot use a type with index signatures when 'table' is configured. ` +\n `Extra fields would be silently dropped when writing to the ClickHouse table. ` +\n `Either:\\n` +\n ` 1. Remove the index signature from your type to use a fixed schema, or\\n` +\n ` 2. Set 'table: false' in your IngestPipeline config if you only need the API and stream`,\n );\n }\n\n // Get the typia context for direct code generation\n const typiaCtx = ctx.typiaContext;\n\n let internalArguments: ts.Expression[];\n let columns: Column[] | undefined;\n\n if (typeName === \"DeadLetterQueue\") {\n // DeadLetterQueue uses type guard (assert)\n internalArguments = [generateAssertFunction(typiaCtx, typeAtLocation)];\n } else {\n columns = toColumns(typeAtLocation, checker, {\n allowIndexSignatures,\n });\n // Other resources use JSON schemas + columns\n internalArguments = [\n generateJsonSchemas(typiaCtx, typeAtLocation),\n parseAsAny(JSON.stringify(columns)),\n ];\n }\n\n const resourceName = checker.getSymbolAtLocation(node.expression)!.name;\n\n const argLength = typesToArgsLength.get(resourceName)!;\n const needsExtraArg = node.arguments!.length === argLength - 1; // provide empty config if undefined\n\n let updatedArgs = [\n ...node.arguments!,\n ...(needsExtraArg ?\n [factory.createObjectLiteralExpression([], false)]\n : []),\n ...internalArguments,\n ];\n\n // For OlapTable and IngestPipeline, also inject typia validation functions\n if (resourceName === \"OlapTable\" || resourceName === \"IngestPipeline\") {\n // Create a single TypiaValidators object with all three validation functions\n // using direct typia code generation (uses shared typiaCtx for imports)\n const validatorsObject = factory.createObjectLiteralExpression(\n [\n factory.createPropertyAssignment(\n factory.createIdentifier(\"validate\"),\n wrapValidateFunction(\n generateValidateFunction(typiaCtx, typeAtLocation),\n ),\n ),\n factory.createPropertyAssignment(\n factory.createIdentifier(\"assert\"),\n generateAssertFunction(typiaCtx, typeAtLocation),\n ),\n factory.createPropertyAssignment(\n factory.createIdentifier(\"is\"),\n generateIsFunction(typiaCtx, typeAtLocation),\n ),\n ],\n true,\n );\n\n updatedArgs = [...updatedArgs, validatorsObject];\n\n // For OlapTable, also generate insert validators with Insertable<T> semantics\n // (excludes ALIAS/MATERIALIZED fields, makes DEFAULT fields optional).\n // Uses metadata-patching: typia analyzes the original type T, but\n // MetadataFactory.analyze is intercepted to strip computed columns.\n if (resourceName === \"OlapTable\" && columns) {\n const insertColumnSets: InsertColumnSets = {\n computed: new Set(\n columns\n .filter((c) => c.alias != null || c.materialized != null)\n .map((c) => c.name),\n ),\n defaults: new Set(\n columns.filter((c) => c.default != null).map((c) => c.name),\n ),\n };\n\n const insertValidatorsObject = factory.createObjectLiteralExpression(\n [\n factory.createPropertyAssignment(\n factory.createIdentifier(\"validate\"),\n wrapValidateFunction(\n generateInsertValidateFunction(\n typiaCtx,\n typeAtLocation,\n insertColumnSets,\n ),\n ),\n ),\n factory.createPropertyAssignment(\n factory.createIdentifier(\"assert\"),\n generateInsertAssertFunction(\n typiaCtx,\n typeAtLocation,\n insertColumnSets,\n ),\n ),\n factory.createPropertyAssignment(\n factory.createIdentifier(\"is\"),\n generateInsertIsFunction(\n typiaCtx,\n typeAtLocation,\n insertColumnSets,\n ),\n ),\n ],\n true,\n );\n updatedArgs = [...updatedArgs, insertValidatorsObject];\n }\n\n // For IngestPipeline, also pass allowExtraFields so it can propagate to internal Stream/IngestApi\n if (resourceName === \"IngestPipeline\") {\n updatedArgs = [\n ...updatedArgs,\n hasIndexSignature ? factory.createTrue() : factory.createFalse(),\n ];\n }\n }\n\n // For IngestApi and Stream, add the allowExtraFields flag after undefined validators\n // This enables passing extra fields through to streaming functions when the type has an index signature\n if (resourceName === \"IngestApi\" || resourceName === \"Stream\") {\n updatedArgs = [\n ...updatedArgs,\n factory.createIdentifier(\"undefined\"), // validators (not used for these types)\n hasIndexSignature ? factory.createTrue() : factory.createFalse(),\n ];\n }\n\n return ts.factory.updateNewExpression(\n node,\n node.expression,\n node.typeArguments,\n updatedArgs,\n );\n};\n\n/**\n * Wraps a typia validate function to match our expected interface\n * Transforms typia's IValidation result to our { success, data, errors } format\n */\nconst wrapValidateFunction = (validateFn: ts.Expression): ts.Expression => {\n // (data: unknown) => {\n // const result = validateFn(data);\n // return {\n // success: result.success,\n // data: result.success ? result.data : undefined,\n // errors: result.success ? undefined : result.errors\n // };\n // }\n return factory.createArrowFunction(\n undefined,\n undefined,\n [\n factory.createParameterDeclaration(\n undefined,\n undefined,\n factory.createIdentifier(\"data\"),\n undefined,\n factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword),\n undefined,\n ),\n ],\n undefined,\n factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),\n factory.createBlock(\n [\n factory.createVariableStatement(\n undefined,\n factory.createVariableDeclarationList(\n [\n factory.createVariableDeclaration(\n factory.createIdentifier(\"result\"),\n undefined,\n undefined,\n factory.createCallExpression(validateFn, undefined, [\n factory.createIdentifier(\"data\"),\n ]),\n ),\n ],\n ts.NodeFlags.Const,\n ),\n ),\n factory.createReturnStatement(\n factory.createObjectLiteralExpression(\n [\n factory.createPropertyAssignment(\n factory.createIdentifier(\"success\"),\n factory.createPropertyAccessExpression(\n factory.createIdentifier(\"result\"),\n factory.createIdentifier(\"success\"),\n ),\n ),\n factory.createPropertyAssignment(\n factory.createIdentifier(\"data\"),\n factory.createConditionalExpression(\n factory.createPropertyAccessExpression(\n factory.createIdentifier(\"result\"),\n factory.createIdentifier(\"success\"),\n ),\n factory.createToken(ts.SyntaxKind.QuestionToken),\n factory.createPropertyAccessExpression(\n factory.createIdentifier(\"result\"),\n factory.createIdentifier(\"data\"),\n ),\n factory.createToken(ts.SyntaxKind.ColonToken),\n factory.createIdentifier(\"undefined\"),\n ),\n ),\n factory.createPropertyAssignment(\n factory.createIdentifier(\"errors\"),\n factory.createConditionalExpression(\n factory.createPropertyAccessExpression(\n factory.createIdentifier(\"result\"),\n factory.createIdentifier(\"success\"),\n ),\n factory.createToken(ts.SyntaxKind.QuestionToken),\n factory.createIdentifier(\"undefined\"),\n factory.createToken(ts.SyntaxKind.ColonToken),\n factory.createPropertyAccessExpression(\n factory.createIdentifier(\"result\"),\n factory.createIdentifier(\"errors\"),\n ),\n ),\n ),\n ],\n true,\n ),\n ),\n ],\n true,\n ),\n );\n};\n","import ts, {\n displayPartsToString,\n isIdentifier,\n isTypeReferenceNode,\n SymbolFlags,\n TupleType,\n TypeChecker,\n TypeFlags,\n} from \"typescript\";\nimport { enumConvert, isEnum } from \"./enumConvert\";\nimport {\n ArrayType,\n Column,\n DataType,\n DataEnum,\n Nested,\n NamedTupleType,\n NullType,\n UnknownType,\n UnsupportedFeature,\n IndexType,\n MapType,\n} from \"./dataModelTypes\";\nimport { ClickHouseNamedTuple, DecimalRegex } from \"./types\";\nimport { STRING_DATE_ANNOTATION } from \"../utilities/json\";\n\nconst dateType = (checker: TypeChecker) =>\n checker\n .getTypeOfSymbol(\n checker.resolveName(\"Date\", undefined, SymbolFlags.Type, false)!,\n )\n .getConstructSignatures()[0]\n .getReturnType();\n\n// making throws expressions so that they can be used in ternaries\n\nconst throwUnknownType = (\n t: ts.Type,\n fieldName: string,\n typeName: string,\n): never => {\n throw new UnknownType(t, fieldName, typeName);\n};\n\nconst throwNullType = (fieldName: string, typeName: string): never => {\n throw new NullType(fieldName, typeName);\n};\n\nconst throwIndexTypeError = (t: ts.Type, checker: TypeChecker): never => {\n const interfaceName = t.symbol?.name || \"unknown type\";\n const indexInfos = checker.getIndexInfosOfType(t);\n const signatures = indexInfos.map((info) => {\n const keyType = checker.typeToString(info.keyType);\n const valueType = checker.typeToString(info.type);\n return `[${keyType}]: ${valueType}`;\n });\n\n throw new IndexType(interfaceName, signatures);\n};\n\n/** Recursively search for a property on a type, traversing intersections */\nconst getPropertyDeep = (t: ts.Type, name: string): ts.Symbol | undefined => {\n const direct = t.getProperty(name);\n if (direct !== undefined) return direct;\n // TODO: investigate if this logic is needed.\n // the properties in types in intersection should be reachable by t.getProperty\n // Intersection constituents may carry the marker symbols\n if (t.isIntersection()) {\n for (const sub of t.types) {\n const found = getPropertyDeep(sub, name);\n if (found) return found;\n }\n }\n return undefined;\n};\n\nconst toArrayType = ([elementNullable, _, elementType]: [\n boolean,\n [string, any][],\n DataType,\n]): ArrayType => {\n return {\n elementNullable,\n elementType,\n };\n};\n\nconst isNumberType = (t: ts.Type, checker: TypeChecker): boolean => {\n return checker.isTypeAssignableTo(t, checker.getNumberType());\n};\n\nconst handleAggregated = (\n t: ts.Type,\n checker: TypeChecker,\n fieldName: string,\n typeName: string,\n): AggregationFunction | undefined => {\n const functionSymbol = t.getProperty(\"_aggregationFunction\");\n const argsTypesSymbol = t.getProperty(\"_argTypes\");\n\n if (functionSymbol === undefined || argsTypesSymbol === undefined) {\n return undefined;\n }\n const functionStringLiteral = checker.getNonNullableType(\n checker.getTypeOfSymbol(functionSymbol),\n );\n const types = checker.getNonNullableType(\n checker.getTypeOfSymbol(argsTypesSymbol),\n );\n\n if (functionStringLiteral.isStringLiteral() && checker.isTupleType(types)) {\n const argumentTypes = ((types as TupleType).typeArguments || []).map(\n (argT) => {\n return tsTypeToDataType(argT, checker, fieldName, typeName, false)[2];\n },\n );\n return { functionName: functionStringLiteral.value, argumentTypes };\n } else {\n console.log(\n \"[CompilerPlugin] Unexpected type inside Aggregated\",\n functionStringLiteral,\n );\n return undefined;\n }\n};\n\nconst getTaggedType = (\n t: ts.Type,\n checker: TypeChecker,\n propertyName: string,\n): ts.Type | null => {\n // Ensure we check the non-nullable part so the tag property is there\n const nonNull = t.getNonNullableType();\n const ttlSymbol = nonNull.getProperty(propertyName);\n if (ttlSymbol === undefined) return null;\n return checker.getNonNullableType(checker.getTypeOfSymbol(ttlSymbol));\n};\n\n// JSON mapping: recognize SomeInterface & ClickHouseJson<...>\nconst getJsonMappedType = (\n t: ts.Type,\n checker: TypeChecker,\n): DataType | null => {\n const mappingSymbol = getPropertyDeep(t, \"_clickhouse_mapped_type\");\n if (mappingSymbol === undefined) return null;\n const mappedType = checker.getNonNullableType(\n checker.getTypeOfSymbol(mappingSymbol),\n );\n if (!mappedType.isStringLiteral() || mappedType.value !== \"JSON\") {\n return null;\n }\n\n // Extract settings from the type properties\n let maxDynamicPaths: number | undefined = undefined;\n let maxDynamicTypes: number | undefined = undefined;\n let skipPaths: string[] = [];\n let skipRegexes: string[] = [];\n\n const settingsSymbol = getPropertyDeep(t, \"_clickhouse_json_settings\");\n if (settingsSymbol !== undefined) {\n const settingsType = checker.getNonNullableType(\n checker.getTypeOfSymbol(settingsSymbol),\n );\n\n const maxPathsSymbol = getPropertyDeep(settingsType, \"maxDynamicPaths\");\n if (maxPathsSymbol !== undefined) {\n const maxPathsType = checker.getNonNullableType(\n checker.getTypeOfSymbol(maxPathsSymbol),\n );\n if (maxPathsType.isNumberLiteral()) {\n maxDynamicPaths = maxPathsType.value;\n }\n }\n\n const maxTypesSymbol = getPropertyDeep(settingsType, \"maxDynamicTypes\");\n if (maxTypesSymbol !== undefined) {\n const maxTypesType = checker.getNonNullableType(\n checker.getTypeOfSymbol(maxTypesSymbol),\n );\n if (maxTypesType.isNumberLiteral()) {\n maxDynamicTypes = maxTypesType.value;\n }\n }\n\n const skipPathsSymbol = getPropertyDeep(settingsType, \"skipPaths\");\n if (skipPathsSymbol !== undefined) {\n const skipPathsType = checker.getNonNullableType(\n checker.getTypeOfSymbol(skipPathsSymbol),\n );\n if (checker.isTupleType(skipPathsType)) {\n const tuple = skipPathsType as TupleType;\n skipPaths = (tuple.typeArguments || [])\n .filter((t) => t.isStringLiteral())\n .map((t) => (t as ts.StringLiteralType).value);\n }\n }\n\n const skipRegexesSymbol = getPropertyDeep(settingsType, \"skipRegexes\");\n if (skipRegexesSymbol !== undefined) {\n const skipRegexesType = checker.getNonNullableType(\n checker.getTypeOfSymbol(skipRegexesSymbol),\n );\n if (checker.isTupleType(skipRegexesType)) {\n const tuple = skipRegexesType as TupleType;\n skipRegexes = (tuple.typeArguments || [])\n .filter((t) => t.isStringLiteral())\n .map((t) => (t as ts.StringLiteralType).value);\n }\n }\n }\n\n // For typed paths, try to find the interface part of the intersection\n let base: ts.Type = t.getNonNullableType();\n if (base.isIntersection()) {\n const candidates = base.types.filter((sub) => {\n const m = getPropertyDeep(sub, \"_clickhouse_mapped_type\");\n if (!m) return true;\n const mt = checker.getNonNullableType(checker.getTypeOfSymbol(m));\n return !(mt.isStringLiteral() && mt.value === \"JSON\");\n });\n if (candidates.length > 0) base = candidates[0];\n }\n\n // Build typed paths from the base interface's columns (top-level only)\n let typedPaths: Array<[string, DataType]> = [];\n try {\n const cols = toColumns(base, checker);\n typedPaths = cols.map((c) => [c.name, c.data_type]);\n } catch (_) {\n // Fallback silently if we cannot derive columns\n typedPaths = [];\n }\n\n const hasAnyOption =\n typeof maxDynamicPaths === \"number\" ||\n typeof maxDynamicTypes === \"number\" ||\n typedPaths.length > 0 ||\n skipPaths.length > 0 ||\n skipRegexes.length > 0;\n\n if (!hasAnyOption) return \"Json\";\n\n const result: Record<string, any> = {\n typed_paths: typedPaths,\n skip_paths: skipPaths,\n skip_regexps: skipRegexes,\n };\n\n // Only include these fields if they have actual values\n if (typeof maxDynamicPaths === \"number\") {\n result.max_dynamic_paths = maxDynamicPaths;\n }\n if (typeof maxDynamicTypes === \"number\") {\n result.max_dynamic_types = maxDynamicTypes;\n }\n\n return result as unknown as DataType;\n};\n\nconst handleSimpleAggregated = (\n t: ts.Type,\n checker: TypeChecker,\n fieldName: string,\n typeName: string,\n): SimpleAggregationFunction | undefined => {\n const functionSymbol = t.getProperty(\"_simpleAggregationFunction\");\n const argTypeSymbol = t.getProperty(\"_argType\");\n\n if (functionSymbol === undefined || argTypeSymbol === undefined) {\n return undefined;\n }\n const functionStringLiteral = checker.getNonNullableType(\n checker.getTypeOfSymbol(functionSymbol),\n );\n const argType = checker.getNonNullableType(\n checker.getTypeOfSymbol(argTypeSymbol),\n );\n\n if (functionStringLiteral.isStringLiteral()) {\n const argumentType = tsTypeToDataType(\n argType,\n checker,\n fieldName,\n typeName,\n false,\n )[2];\n return { functionName: functionStringLiteral.value, argumentType };\n } else {\n console.log(\n \"[CompilerPlugin] Unexpected type inside SimpleAggregated\",\n functionStringLiteral,\n );\n return undefined;\n }\n};\n/** Detect ClickHouse default annotation on a type and return raw sql */\nconst handleDefault = (t: ts.Type, checker: TypeChecker): string | null => {\n const defaultType = getTaggedType(t, checker, \"_clickhouse_default\");\n if (defaultType === null) {\n return null;\n }\n if (!defaultType.isStringLiteral()) {\n throw new UnsupportedFeature(\n 'ClickHouseDefault must use a string literal, e.g. ClickHouseDefault<\"now()\">',\n );\n }\n return defaultType.value;\n};\n\n/** Detect ClickHouse materialized annotation on a type and return raw sql */\nconst handleMaterialized = (\n t: ts.Type,\n checker: TypeChecker,\n): string | null => {\n const materializedType = getTaggedType(\n t,\n checker,\n \"_clickhouse_materialized\",\n );\n if (materializedType === null) {\n return null;\n }\n if (!materializedType.isStringLiteral()) {\n throw new UnsupportedFeature(\n 'ClickHouseMaterialized must use a string literal, e.g. ClickHouseMaterialized<\"toDate(timestamp)\">',\n );\n }\n return materializedType.value;\n};\n\n/** Detect ClickHouse alias annotation on a type and return raw sql */\nconst handleAlias = (t: ts.Type, checker: TypeChecker): string | null => {\n const aliasType = getTaggedType(t, checker, \"_clickhouse_alias\");\n if (aliasType === null) {\n return null;\n }\n if (!aliasType.isStringLiteral()) {\n throw new UnsupportedFeature(\n 'ClickHouseAlias must use a string literal, e.g. ClickHouseAlias<\"toDate(timestamp)\">',\n );\n }\n return aliasType.value;\n};\n\n/** Detect ClickHouse TTL annotation on a type and return raw sql */\nconst handleTtl = (t: ts.Type, checker: TypeChecker): string | null => {\n const ttlType = getTaggedType(t, checker, \"_clickhouse_ttl\");\n if (ttlType === null) {\n return null;\n }\n if (!ttlType.isStringLiteral()) {\n throw new UnsupportedFeature(\n 'ClickHouseTTL must use a string literal, e.g. ClickHouseTTL<\"timestamp + INTERVAL 1 WEEK\">',\n );\n }\n return ttlType.value;\n};\n\nconst handleNumberType = (\n t: ts.Type,\n checker: TypeChecker,\n fieldName: string,\n): string => {\n // Detect Decimal(P, S) annotation on number via ClickHouseDecimal\n const decimalPrecisionSymbol = getPropertyDeep(t, \"_clickhouse_precision\");\n const decimalScaleSymbol = getPropertyDeep(t, \"_clickhouse_scale\");\n if (\n decimalPrecisionSymbol !== undefined &&\n decimalScaleSymbol !== undefined\n ) {\n const precisionType = checker.getNonNullableType(\n checker.getTypeOfSymbol(decimalPrecisionSymbol),\n );\n const scaleType = checker.getNonNullableType(\n checker.getTypeOfSymbol(decimalScaleSymbol),\n );\n if (precisionType.isNumberLiteral() && scaleType.isNumberLiteral()) {\n return `Decimal(${precisionType.value}, ${scaleType.value})`;\n }\n }\n\n const tagSymbol = t.getProperty(\"typia.tag\");\n if (tagSymbol === undefined) {\n return \"Float64\";\n } else {\n const typiaProps = checker.getNonNullableType(\n checker.getTypeOfSymbol(tagSymbol),\n );\n const props: ts.Type[] =\n typiaProps.isIntersection() ? typiaProps.types : [typiaProps];\n\n for (const prop of props) {\n const valueSymbol = prop.getProperty(\"value\");\n if (valueSymbol === undefined) {\n console.log(\n `[CompilerPlugin] Props.value is undefined for ${fieldName}`,\n );\n } else {\n const valueTypeLiteral = checker.getTypeOfSymbol(valueSymbol);\n const numberTypeMappings = {\n float: \"Float32\",\n double: \"Float64\",\n int8: \"Int8\",\n int16: \"Int16\",\n int32: \"Int32\",\n int64: \"Int64\",\n uint8: \"UInt8\",\n uint16: \"UInt16\",\n uint32: \"UInt32\",\n uint64: \"UInt64\",\n };\n const match = Object.entries(numberTypeMappings).find(([k, _]) =>\n isStringLiteral(valueTypeLiteral, checker, k),\n );\n if (match) {\n return match[1];\n } else {\n const typeString =\n valueTypeLiteral.isStringLiteral() ?\n valueTypeLiteral.value\n : \"unknown\";\n\n console.log(\n `[CompilerPlugin] Other number types are not supported: ${typeString} in field ${fieldName}`,\n );\n }\n }\n }\n\n return \"Float64\";\n }\n};\n\nexport interface AggregationFunction {\n functionName: string;\n argumentTypes: DataType[];\n}\n\nexport interface SimpleAggregationFunction {\n functionName: string;\n argumentType: DataType;\n}\n\nconst isStringLiteral = (\n t: ts.Type,\n checker: TypeChecker,\n lit: string,\n): boolean => checker.isTypeAssignableTo(t, checker.getStringLiteralType(lit));\n\nconst handleStringType = (\n t: ts.Type,\n checker: TypeChecker,\n fieldName: string,\n annotations: [string, any][],\n): string => {\n // Check for FixedString(N) annotation\n const fixedStringSizeSymbol = getPropertyDeep(\n t,\n \"_clickhouse_fixed_string_size\",\n );\n if (fixedStringSizeSymbol !== undefined) {\n const sizeType = checker.getNonNullableType(\n checker.getTypeOfSymbol(fixedStringSizeSymbol),\n );\n if (sizeType.isNumberLiteral()) {\n return `FixedString(${sizeType.value})`;\n }\n }\n\n const tagSymbol = t.getProperty(\"typia.tag\");\n if (tagSymbol === undefined) {\n if (t.isUnion() && t.types.every((v) => v.isStringLiteral())) {\n annotations.push([\"LowCardinality\", true]);\n }\n\n return \"String\";\n } else {\n const typiaProps = checker.getNonNullableType(\n checker.getTypeOfSymbol(tagSymbol),\n );\n const props: ts.Type[] =\n typiaProps.isIntersection() ? typiaProps.types : [typiaProps];\n\n for (const prop of props) {\n const valueSymbol = prop.getProperty(\"value\");\n if (valueSymbol === undefined) {\n console.log(\n `[CompilerPlugin] Props.value is undefined for ${fieldName}`,\n );\n } else {\n const valueTypeLiteral = checker.getTypeOfSymbol(valueSymbol);\n if (isStringLiteral(valueTypeLiteral, checker, \"uuid\")) {\n return \"UUID\";\n } else if (isStringLiteral(valueTypeLiteral, checker, \"date-time\")) {\n let precision = 9;\n\n const precisionSymbol = t.getProperty(\"_clickhouse_precision\");\n if (precisionSymbol !== undefined) {\n const precisionType = checker.getNonNullableType(\n checker.getTypeOfSymbol(precisionSymbol),\n );\n if (precisionType.isNumberLiteral()) {\n precision = precisionType.value;\n }\n }\n // Mark this as a string-based date field so it won't be parsed to Date at runtime\n annotations.push([STRING_DATE_ANNOTATION, true]);\n return `DateTime(${precision})`;\n } else if (isStringLiteral(valueTypeLiteral, checker, \"date\")) {\n let size = 4;\n const sizeSymbol = t.getProperty(\"_clickhouse_byte_size\");\n if (sizeSymbol !== undefined) {\n const sizeType = checker.getNonNullableType(\n checker.getTypeOfSymbol(sizeSymbol),\n );\n if (sizeType.isNumberLiteral()) {\n size = sizeType.value;\n }\n }\n\n if (size === 4) {\n return \"Date\";\n } else if (size === 2) {\n return \"Date16\";\n } else {\n throw new UnsupportedFeature(`Date with size ${size}`);\n }\n } else if (isStringLiteral(valueTypeLiteral, checker, \"ipv4\")) {\n return \"IPv4\";\n } else if (isStringLiteral(valueTypeLiteral, checker, \"ipv6\")) {\n return \"IPv6\";\n } else if (isStringLiteral(valueTypeLiteral, checker, DecimalRegex)) {\n let precision = 10;\n let scale = 0;\n\n const precisionSymbol = t.getProperty(\"_clickhouse_precision\");\n if (precisionSymbol !== undefined) {\n const precisionType = checker.getNonNullableType(\n checker.getTypeOfSymbol(precisionSymbol),\n );\n if (precisionType.isNumberLiteral()) {\n precision = precisionType.value;\n }\n }\n\n const scaleSymbol = t.getProperty(\"_clickhouse_scale\");\n if (scaleSymbol !== undefined) {\n const scaleType = checker.getNonNullableType(\n checker.getTypeOfSymbol(scaleSymbol),\n );\n if (scaleType.isNumberLiteral()) {\n scale = scaleType.value;\n }\n }\n\n return `Decimal(${precision}, ${scale})`;\n } else {\n const typeString =\n valueTypeLiteral.isStringLiteral() ?\n valueTypeLiteral.value\n : \"unknown\";\n\n console.log(\n `[CompilerPlugin] Unknown format: ${typeString} in field ${fieldName}`,\n );\n }\n }\n }\n\n return \"String\";\n }\n};\n\nconst isStringAnyRecord = (t: ts.Type, checker: ts.TypeChecker): boolean => {\n const indexInfos = checker.getIndexInfosOfType(t);\n if (indexInfos && indexInfos.length === 1) {\n const indexInfo = indexInfos[0];\n return (\n indexInfo.keyType == checker.getStringType() &&\n indexInfo.type == checker.getAnyType()\n );\n }\n\n return false;\n};\n\n/**\n * Check if a type is a Record<K, V> type (generic map/dictionary type)\n */\nconst isRecordType = (t: ts.Type, checker: ts.TypeChecker): boolean => {\n const indexInfos = checker.getIndexInfosOfType(t);\n return indexInfos && indexInfos.length === 1;\n};\n\n/**\n * Detects a tag-like object type that only carries metadata, e.g. { _tag: ... }\n */\nconst isSingleUnderscoreMetaObject = (\n t: ts.Type,\n checker: ts.TypeChecker,\n): boolean => {\n const props = checker.getPropertiesOfType(t);\n if (props.length !== 1) return false;\n const onlyProp = props[0];\n const name = onlyProp.name;\n return typeof name === \"string\" && name.startsWith(\"_\");\n};\n\n/**\n * Handle Record<K, V> types and convert them to Map types\n */\nconst handleRecordType = (\n t: ts.Type,\n checker: ts.TypeChecker,\n fieldName: string,\n typeName: string,\n isJwt: boolean,\n): MapType => {\n const indexInfos = checker.getIndexInfosOfType(t);\n if (indexInfos && indexInfos.length !== 1) {\n throwIndexTypeError(t, checker);\n }\n const indexInfo = indexInfos[0];\n\n // Convert key type\n const [, , keyType] = tsTypeToDataType(\n indexInfo.keyType,\n checker,\n `${fieldName}_key`,\n typeName,\n isJwt,\n );\n\n // Convert value type\n const [, , valueType] = tsTypeToDataType(\n indexInfo.type,\n checker,\n `${fieldName}_value`,\n typeName,\n isJwt,\n );\n\n return {\n keyType,\n valueType,\n };\n};\n\n/**\n * see {@link ClickHouseNamedTuple}\n */\nconst isNamedTuple = (t: ts.Type, checker: ts.TypeChecker) => {\n const mappingSymbol = t.getProperty(\"_clickhouse_mapped_type\");\n if (mappingSymbol === undefined) {\n return false;\n }\n return isStringLiteral(\n checker.getNonNullableType(checker.getTypeOfSymbol(mappingSymbol)),\n checker,\n \"namedTuple\",\n );\n};\n\n// Validate that the underlying TS type matches the mapped geometry shape\nconst getGeometryMappedType = (\n t: ts.Type,\n checker: ts.TypeChecker,\n): string | null => {\n const mappingSymbol = getPropertyDeep(t, \"_clickhouse_mapped_type\");\n if (mappingSymbol === undefined) return null;\n const mapped = checker.getNonNullableType(\n checker.getTypeOfSymbol(mappingSymbol),\n );\n\n // Helper: exact tuple [number, number]\n const isPointTuple = (candidate: ts.Type): boolean => {\n if (candidate.isIntersection()) {\n return candidate.types.some(isPointTuple);\n }\n if (!checker.isTupleType(candidate)) return false;\n const tuple = candidate as TupleType;\n const args = tuple.typeArguments || [];\n if (args.length !== 2) return false;\n return isNumberType(args[0], checker) && isNumberType(args[1], checker);\n };\n\n // Helper: Array<T> predicate\n const isArrayOf = (\n arrType: ts.Type,\n elementPredicate: (elType: ts.Type) => boolean,\n ): boolean => {\n if (arrType.isIntersection()) {\n return arrType.types.some((t) => isArrayOf(t, elementPredicate));\n }\n if (!checker.isArrayType(arrType)) return false;\n const elementType = arrType.getNumberIndexType();\n if (!elementType) return false;\n return elementPredicate(elementType);\n };\n\n const expectAndValidate = (shapeName: string, validator: () => boolean) => {\n if (!validator()) {\n throw new UnsupportedFeature(\n `Type annotated as ${shapeName} must be assignable to the expected geometry shape`,\n );\n }\n return shapeName;\n };\n\n if (mapped.isStringLiteral()) {\n const v = mapped.value;\n switch (v) {\n case \"Point\":\n return expectAndValidate(\"Point\", () => isPointTuple(t));\n case \"Ring\":\n case \"LineString\":\n return expectAndValidate(v, () =>\n isArrayOf(t, (el) => isPointTuple(el)),\n );\n case \"MultiLineString\":\n case \"Polygon\":\n return expectAndValidate(v, () =>\n isArrayOf(t, (el) => isArrayOf(el, (inner) => isPointTuple(inner))),\n );\n case \"MultiPolygon\":\n return expectAndValidate(v, () =>\n isArrayOf(t, (el) =>\n isArrayOf(el, (inner) => isArrayOf(inner, isPointTuple)),\n ),\n );\n }\n }\n return null;\n};\n\nconst checkColumnHasNoDefault = (c: Column) => {\n if (c.default !== null) {\n throw new UnsupportedFeature(\n \"Default in inner field. Put ClickHouseDefault in top level field.\",\n );\n }\n};\n\nconst handleNested = (\n t: ts.Type,\n checker: ts.TypeChecker,\n fieldName: string,\n jwt: boolean,\n): Nested => {\n const columns = toColumns(t, checker);\n columns.forEach(checkColumnHasNoDefault);\n return {\n name: getNestedName(t, fieldName),\n columns,\n jwt,\n };\n};\n\nconst handleNamedTuple = (\n t: ts.Type,\n checker: ts.TypeChecker,\n): NamedTupleType => {\n return {\n fields: toColumns(t, checker).flatMap((c) => {\n if (c.name === \"_clickhouse_mapped_type\") return [];\n\n checkColumnHasNoDefault(c);\n const t = c.required ? c.data_type : { nullable: c.data_type };\n return [[c.name, t]];\n }),\n };\n};\n\nconst tsTypeToDataType = (\n t: ts.Type,\n checker: TypeChecker,\n fieldName: string,\n typeName: string,\n isJwt: boolean,\n typeNode?: ts.TypeNode,\n): [boolean, [string, any][], DataType] => {\n const nonNull = t.getNonNullableType();\n const nullable = nonNull != t;\n\n const aggregationFunction = handleAggregated(t, checker, fieldName, typeName);\n const simpleAggregationFunction = handleSimpleAggregated(\n t,\n checker,\n fieldName,\n typeName,\n );\n\n let withoutTags = nonNull;\n // clean up intersection type tags\n if (nonNull.isIntersection()) {\n const nonTagTypes = nonNull.types.filter(\n (candidate) => !isSingleUnderscoreMetaObject(candidate, checker),\n );\n\n if (nonTagTypes.length == 1) {\n withoutTags = nonTagTypes[0];\n }\n }\n\n // Recognize Date aliases (DateTime, DateTime64<P>) as DateTime-like\n let datePrecisionFromNode: number | undefined = undefined;\n if (typeNode && isTypeReferenceNode(typeNode)) {\n const tn = typeNode.typeName;\n const name = isIdentifier(tn) ? tn.text : tn.right.text;\n if (name === \"DateTime64\") {\n const arg = typeNode.typeArguments?.[0];\n if (\n arg &&\n ts.isLiteralTypeNode(arg) &&\n ts.isNumericLiteral(arg.literal)\n ) {\n datePrecisionFromNode = Number(arg.literal.text);\n }\n } else if (name === \"DateTime\") {\n datePrecisionFromNode = undefined; // DateTime without explicit precision\n }\n }\n\n const annotations: [string, any][] = [];\n\n const typeSymbolName = nonNull.symbol?.name || t.symbol?.name;\n const isDateLike =\n typeSymbolName === \"DateTime\" ||\n typeSymbolName === \"DateTime64\" ||\n checker.isTypeAssignableTo(nonNull, dateType(checker));\n\n let dataType: DataType;\n if (isEnum(nonNull)) {\n dataType = enumConvert(nonNull);\n } else {\n const jsonCandidate = getJsonMappedType(nonNull, checker);\n if (jsonCandidate !== null) {\n dataType = jsonCandidate;\n } else if (isStringAnyRecord(nonNull, checker)) {\n dataType = \"Json\";\n } else if (isDateLike) {\n // Prefer precision from AST (DateTime64<P>) if available\n if (datePrecisionFromNode !== undefined) {\n dataType = `DateTime(${datePrecisionFromNode})` as DataType;\n } else {\n // Add precision support for Date via ClickHousePrecision<P>\n const precisionSymbol =\n getPropertyDeep(nonNull, \"_clickhouse_precision\") ||\n getPropertyDeep(t, \"_clickhouse_precision\");\n if (precisionSymbol !== undefined) {\n const precisionType = checker.getNonNullableType(\n checker.getTypeOfSymbol(precisionSymbol),\n );\n if (precisionType.isNumberLiteral()) {\n dataType = `DateTime(${precisionType.value})` as DataType;\n } else {\n dataType = \"DateTime\";\n }\n } else {\n dataType = \"DateTime\";\n }\n }\n } else if (checker.isTypeAssignableTo(nonNull, checker.getStringType())) {\n dataType = handleStringType(nonNull, checker, fieldName, annotations);\n } else if (isNumberType(nonNull, checker)) {\n dataType = handleNumberType(nonNull, checker, fieldName);\n } else if (checker.isTypeAssignableTo(nonNull, checker.getBooleanType())) {\n dataType = \"Boolean\";\n } else if (getGeometryMappedType(nonNull, checker) !== null) {\n dataType = getGeometryMappedType(nonNull, checker)!;\n } else if (checker.isArrayType(withoutTags)) {\n dataType = toArrayType(\n tsTypeToDataType(\n nonNull.getNumberIndexType()!,\n checker,\n fieldName,\n typeName,\n isJwt,\n undefined,\n ),\n );\n } else if (isNamedTuple(nonNull, checker)) {\n dataType = handleNamedTuple(nonNull, checker);\n } else if (isRecordType(nonNull, checker)) {\n dataType = handleRecordType(nonNull, checker, fieldName, typeName, isJwt);\n } else if (\n withoutTags.isClassOrInterface() ||\n (withoutTags.flags & TypeFlags.Object) !== 0\n ) {\n dataType = handleNested(withoutTags, checker, fieldName, isJwt);\n } else if (nonNull == checker.getNeverType()) {\n dataType = throwNullType(fieldName, typeName);\n } else {\n dataType = throwUnknownType(t, fieldName, typeName);\n }\n }\n if (aggregationFunction !== undefined) {\n annotations.push([\"aggregationFunction\", aggregationFunction]);\n }\n if (simpleAggregationFunction !== undefined) {\n annotations.push([\"simpleAggregationFunction\", simpleAggregationFunction]);\n }\n\n const lowCardinalitySymbol = t.getProperty(\"_LowCardinality\");\n if (lowCardinalitySymbol !== undefined) {\n const lowCardinalityType = checker.getNonNullableType(\n checker.getTypeOfSymbol(lowCardinalitySymbol),\n );\n\n if (lowCardinalityType == checker.getTrueType()) {\n annotations.push([\"LowCardinality\", true]);\n }\n }\n\n return [nullable, annotations, dataType];\n};\n\nconst getNestedName = (t: ts.Type, fieldName: string) => {\n const name = t.symbol.name;\n // replace default name\n return name === \"__type\" ? fieldName : name;\n};\n\nconst hasWrapping = (\n typeNode: ts.TypeNode | undefined,\n wrapperName: string,\n) => {\n if (typeNode !== undefined && isTypeReferenceNode(typeNode)) {\n const typeName = typeNode.typeName;\n const name = isIdentifier(typeName) ? typeName.text : typeName.right.text;\n return name === wrapperName && typeNode.typeArguments?.length === 1;\n } else {\n return false;\n }\n};\n\nconst hasKeyWrapping = (typeNode: ts.TypeNode | undefined) => {\n return hasWrapping(typeNode, \"Key\");\n};\n\nconst hasJwtWrapping = (typeNode: ts.TypeNode | undefined) => {\n return hasWrapping(typeNode, \"JWT\");\n};\n\nconst handleDefaultWrapping = (\n typeNode: ts.TypeNode | undefined,\n): string | undefined => {\n if (typeNode !== undefined && isTypeReferenceNode(typeNode)) {\n const typeName = typeNode.typeName;\n const name = isIdentifier(typeName) ? typeName.text : typeName.right.text;\n if (name === \"WithDefault\" && typeNode.typeArguments?.length === 2) {\n const defaultValueType = typeNode.typeArguments[1];\n if (\n ts.isLiteralTypeNode(defaultValueType) &&\n ts.isStringLiteral(defaultValueType.literal)\n ) {\n return defaultValueType.literal.text;\n }\n }\n }\n return undefined;\n};\n\n/** Detect ClickHouse Codec annotation on a type and return codec expression */\nconst handleCodec = (t: ts.Type, checker: TypeChecker): string | null => {\n const codecType = getTaggedType(t, checker, \"_clickhouse_codec\");\n if (codecType === null) {\n return null;\n }\n if (!codecType.isStringLiteral()) {\n throw new UnsupportedFeature(\n 'ClickHouseCodec must use a string literal, e.g. ClickHouseCodec<\"ZSTD(3)\">',\n );\n }\n return codecType.value;\n};\n\nexport interface ToColumnsOptions {\n /**\n * When true, allows types with index signatures (e.g., [key: string]: any).\n * Only named properties will be extracted as columns.\n * This is useful for IngestApi where arbitrary fields should be accepted\n * and passed through to streaming functions.\n */\n allowIndexSignatures?: boolean;\n}\n\nexport const toColumns = (\n t: ts.Type,\n checker: TypeChecker,\n options?: ToColumnsOptions,\n): Column[] => {\n // Only check for index signatures if not explicitly allowed\n if (\n !options?.allowIndexSignatures &&\n checker.getIndexInfosOfType(t).length !== 0\n ) {\n console.log(\"[CompilerPlugin]\", checker.getIndexInfosOfType(t));\n throwIndexTypeError(t, checker);\n }\n\n return checker.getPropertiesOfType(t).map((prop) => {\n let declarations = prop.getDeclarations();\n const node =\n declarations && declarations.length > 0 ?\n (declarations[0] as ts.PropertyDeclaration)\n : undefined;\n const type =\n node !== undefined ?\n checker.getTypeOfSymbolAtLocation(prop, node)\n : checker.getTypeOfSymbol(prop);\n\n const isKey = hasKeyWrapping(node?.type);\n const isJwt = hasJwtWrapping(node?.type);\n\n const defaultExpression = handleDefaultWrapping(node?.type);\n\n const [nullable, annotations, dataType] = tsTypeToDataType(\n type,\n checker,\n prop.name,\n t.symbol?.name || \"inline_type\",\n isJwt,\n node?.type,\n );\n\n const defaultValue = defaultExpression ?? handleDefault(type, checker);\n const materializedValue = handleMaterialized(type, checker);\n const aliasValue = handleAlias(type, checker);\n\n // Validate mutual exclusivity of DEFAULT, MATERIALIZED, and ALIAS\n const setCount = [defaultValue, materializedValue, aliasValue].filter(\n (v) => v != null,\n ).length;\n if (setCount > 1) {\n throw new UnsupportedFeature(\n `Column '${prop.name}' can only have one of ClickHouseDefault, ClickHouseMaterialized, or ClickHouseAlias.`,\n );\n }\n if (aliasValue != null && isKey) {\n throw new UnsupportedFeature(\n `Column '${prop.name}' cannot be a primary key when using ClickHouseAlias.`,\n );\n }\n\n // Extract TSDoc comment from the property\n const docComment = prop.getDocumentationComment(checker);\n const comment =\n docComment.length > 0 ? displayPartsToString(docComment) : null;\n\n return {\n name: prop.name,\n data_type: dataType,\n primary_key: isKey,\n required: !nullable,\n unique: false,\n default: defaultValue,\n materialized: materializedValue,\n alias: aliasValue,\n ttl: handleTtl(type, checker),\n codec: handleCodec(type, checker),\n annotations,\n comment,\n };\n });\n};\n","import ts, {\n NumberLiteralType,\n StringLiteralType,\n UnionType,\n} from \"typescript\";\nimport { DataEnum, UnsupportedEnum } from \"./dataModelTypes\";\n\nexport const isEnum = (t: ts.Type): boolean =>\n !!(t.getFlags() & ts.TypeFlags.EnumLiteral);\n\nexport const enumConvert = (enumType: ts.Type): DataEnum => {\n const name = enumType.symbol.name;\n\n const values =\n enumType.isUnion() ?\n // an enum is the union of the values\n (enumType as UnionType).types\n // unless there's only one element\n : [enumType];\n const allStrings = values.every((v) => v.isStringLiteral());\n const allIntegers = values.every(\n (v) => v.isNumberLiteral() && Number.isInteger(v.value),\n );\n\n if (!allIntegers && !allStrings) {\n throw new UnsupportedEnum(name);\n }\n\n const enumMember =\n allStrings ?\n values.map((v) => ({\n name: v.symbol.name,\n value: { String: (v as StringLiteralType).value },\n }))\n : values.map((v) => ({\n name: v.symbol.name,\n value: { Int: (v as NumberLiteralType).value },\n }));\n\n return { name, values: enumMember };\n};\n","import ts from \"typescript\";\nimport { IdentifierBrandedString } from \"../sqlHelpers\";\n\nexport type EnumValues =\n | { name: string; value: { Int: number } }[]\n | { name: string; value: { String: string } }[];\nexport type DataEnum = { name: string; values: EnumValues };\nexport type Nested = { name: string; columns: Column[]; jwt: boolean };\nexport type ArrayType = { elementType: DataType; elementNullable: boolean };\nexport type NamedTupleType = { fields: Array<[string, DataType]> };\nexport type MapType = { keyType: DataType; valueType: DataType };\nexport type JsonOptions = {\n max_dynamic_paths?: number;\n max_dynamic_types?: number;\n typed_paths?: Array<[string, DataType]>;\n skip_paths?: string[];\n skip_regexps?: string[];\n};\nexport type DataType =\n | string\n | DataEnum\n | ArrayType\n | Nested\n | NamedTupleType\n | MapType\n | JsonOptions\n | { nullable: DataType };\nexport interface Column {\n name: IdentifierBrandedString;\n data_type: DataType;\n required: boolean;\n unique: false; // what is this for?\n primary_key: boolean;\n default: string | null;\n materialized: string | null;\n alias: string | null;\n ttl: string | null;\n codec: string | null;\n annotations: [string, any][];\n comment: string | null;\n}\n\nexport interface DataModel {\n columns: Column[];\n name: string;\n}\n\nexport class UnknownType extends Error {\n t: ts.Type;\n fieldName: string;\n typeName: string;\n constructor(t: ts.Type, fieldName: string, typeName: string) {\n super();\n this.t = t;\n this.fieldName = fieldName;\n this.typeName = typeName;\n }\n}\n\nexport class NullType extends Error {\n fieldName: string;\n typeName: string;\n constructor(fieldName: string, typeName: string) {\n super();\n this.fieldName = fieldName;\n this.typeName = typeName;\n }\n}\n\nexport class UnsupportedEnum extends Error {\n enumName: string;\n constructor(enumName: string) {\n super();\n this.enumName = enumName;\n }\n}\n\nexport class UnsupportedFeature extends Error {\n featureName: string;\n constructor(featureName: string) {\n super();\n this.featureName = featureName;\n }\n}\n\nexport class IndexType extends Error {\n typeName: string;\n indexSignatures: string[];\n\n constructor(typeName: string, indexSignatures: string[]) {\n const explanation =\n \"Index signatures (e.g. [key: string]: value) are not supported in data models.\";\n\n const suggestion =\n \"Consider splitting this into separate types or using a single Record<K, V> type.\";\n\n const signatures = `Found index signatures: ${indexSignatures.join(\", \")}`;\n\n super(\n `${explanation}\\n\\nType: ${typeName}\\n\\n${signatures}\\n\\nSuggestion: ${suggestion}`,\n );\n\n this.typeName = typeName;\n this.indexSignatures = indexSignatures;\n }\n}\n\n/**\n * Type guard: is this DataType an Array(Nested(...))?\n * Uses the ArrayType and Nested types for type safety.\n */\nexport function isArrayNestedType(\n dt: DataType,\n): dt is ArrayType & { elementType: Nested } {\n return (\n typeof dt === \"object\" &&\n dt !== null &&\n (dt as ArrayType).elementType !== null &&\n typeof (dt as ArrayType).elementType === \"object\" &&\n (dt as ArrayType).elementType.hasOwnProperty(\"columns\") &&\n Array.isArray(((dt as ArrayType).elementType as Nested).columns)\n );\n}\n\n/**\n * Type guard: is this DataType a Nested struct (not array)?\n */\nexport function isNestedType(dt: DataType): dt is Nested {\n return (\n typeof dt === \"object\" &&\n dt !== null &&\n Array.isArray((dt as Nested).columns)\n );\n}\n","import { Pattern, TagBase } from \"typia/lib/tags\";\nimport { tags } from \"typia\";\n\nexport type ClickHousePrecision<P extends number> = {\n _clickhouse_precision?: P;\n};\n\nexport const DecimalRegex: \"^-?\\\\d+(\\\\.\\\\d+)?$\" = \"^-?\\\\d+(\\\\.\\\\d+)?$\";\n\nexport type ClickHouseDecimal<P extends number, S extends number> = {\n _clickhouse_precision?: P;\n _clickhouse_scale?: S;\n} & Pattern<typeof DecimalRegex>;\n\nexport type ClickHouseFixedStringSize<N extends number> = {\n _clickhouse_fixed_string_size?: N;\n};\n\n/**\n * FixedString(N) - Fixed-length string of exactly N bytes.\n *\n * ClickHouse stores exactly N bytes, padding shorter values with null bytes.\n * Values exceeding N bytes will throw an exception.\n *\n * Use for binary data: hashes, IP addresses, UUIDs, MAC addresses.\n *\n * @example\n * interface BinaryData {\n * md5_hash: string & FixedString<16>; // 16-byte MD5\n * sha256_hash: string & FixedString<32>; // 32-byte SHA256\n * }\n */\nexport type FixedString<N extends number> = string &\n ClickHouseFixedStringSize<N>;\n\nexport type ClickHouseByteSize<N extends number> = {\n _clickhouse_byte_size?: N;\n};\n\nexport type LowCardinality = {\n _LowCardinality?: true;\n};\n\n// ClickHouse-friendly helper aliases for clarity in user schemas\n// These are erased at compile time but guide the ClickHouse mapping logic.\nexport type DateTime = Date;\nexport type DateTime64<P extends number> = Date & ClickHousePrecision<P>;\n\nexport type DateTimeString = string & tags.Format<\"date-time\">;\n/**\n * JS Date objects cannot hold microsecond precision.\n * Use string as the runtime type to avoid losing information.\n */\nexport type DateTime64String<P extends number> = string &\n tags.Format<\"date-time\"> &\n ClickHousePrecision<P>;\n\n// Numeric convenience tags mirroring ClickHouse integer and float families\nexport type Float32 = number & ClickHouseFloat<\"float32\">;\nexport type Float64 = number & ClickHouseFloat<\"float64\">;\n\nexport type Int8 = number & ClickHouseInt<\"int8\">;\nexport type Int16 = number & ClickHouseInt<\"int16\">;\nexport type Int32 = number & ClickHouseInt<\"int32\">;\nexport type Int64 = number & ClickHouseInt<\"int64\">;\n\nexport type UInt8 = number & ClickHouseInt<\"uint8\">;\nexport type UInt16 = number & ClickHouseInt<\"uint16\">;\nexport type UInt32 = number & ClickHouseInt<\"uint32\">;\nexport type UInt64 = number & ClickHouseInt<\"uint64\">;\n\n// Decimal(P, S) annotation\nexport type Decimal<P extends number, S extends number> = string &\n ClickHouseDecimal<P, S>;\n\n/**\n * Attach compression codec to a column type.\n *\n * Any valid ClickHouse codec expression is allowed. ClickHouse validates the codec at runtime.\n *\n * @template T The base data type\n * @template CodecExpr The codec expression (single codec or chain)\n *\n * @example\n * interface Metrics {\n * // Single codec\n * log_blob: string & ClickHouseCodec<\"ZSTD(3)\">;\n *\n * // Codec chain (processed left-to-right)\n * timestamp: Date & ClickHouseCodec<\"Delta, LZ4\">;\n * temperature: number & ClickHouseCodec<\"Gorilla, ZSTD\">;\n *\n * // Specialized codecs\n * counter: number & ClickHouseCodec<\"DoubleDelta\">;\n *\n * // Can combine with other annotations\n * count: UInt64 & ClickHouseCodec<\"DoubleDelta, LZ4\">;\n * }\n */\nexport type ClickHouseCodec<CodecExpr extends string> = {\n _clickhouse_codec?: CodecExpr;\n};\n\nexport type ClickHouseFloat<Value extends \"float32\" | \"float64\"> = tags.Type<\n Value extends \"float32\" ? \"float\" : \"double\"\n>;\n\nexport type ClickHouseInt<\n Value extends\n | \"int8\"\n | \"int16\"\n | \"int32\"\n | \"int64\"\n // | \"int128\"\n // | \"int256\"\n | \"uint8\"\n | \"uint16\"\n | \"uint32\"\n | \"uint64\",\n // | \"uint128\"\n // | \"uint256\",\n> =\n Value extends \"int32\" | \"int64\" | \"uint32\" | \"uint64\" ? tags.Type<Value>\n : TagBase<{\n target: \"number\";\n kind: \"type\";\n value: Value;\n validate: Value extends \"int8\" ? \"-128 <= $input && $input <= 127\"\n : Value extends \"int16\" ? \"-32768 <= $input && $input <= 32767\"\n : Value extends \"uint8\" ? \"0 <= $input && $input <= 255\"\n : Value extends \"uint16\" ? \"0 <= $input && $input <= 65535\"\n : never;\n exclusive: true;\n schema: {\n type: \"integer\";\n };\n }>;\n\n/**\n * By default, nested objects map to the `Nested` type in clickhouse.\n * Write `nestedObject: AnotherInterfaceType & ClickHouseNamedTuple`\n * to map AnotherInterfaceType to the named tuple type.\n */\nexport type ClickHouseNamedTuple = {\n _clickhouse_mapped_type?: \"namedTuple\";\n};\n\nexport type ClickHouseJson<\n maxDynamicPaths extends number | undefined = undefined,\n maxDynamicTypes extends number | undefined = undefined,\n skipPaths extends string[] = [],\n skipRegexes extends string[] = [],\n> = {\n _clickhouse_mapped_type?: \"JSON\";\n _clickhouse_json_settings?: {\n maxDynamicPaths?: maxDynamicPaths;\n maxDynamicTypes?: maxDynamicTypes;\n skipPaths?: skipPaths;\n skipRegexes?: skipRegexes;\n };\n};\n\n// Geometry helper types\nexport type ClickHousePoint = [number, number] & {\n _clickhouse_mapped_type?: \"Point\";\n};\nexport type ClickHouseRing = ClickHousePoint[] & {\n _clickhouse_mapped_type?: \"Ring\";\n};\nexport type ClickHouseLineString = ClickHousePoint[] & {\n _clickhouse_mapped_type?: \"LineString\";\n};\nexport type ClickHouseMultiLineString = ClickHouseLineString[] & {\n _clickhouse_mapped_type?: \"MultiLineString\";\n};\nexport type ClickHousePolygon = ClickHouseRing[] & {\n _clickhouse_mapped_type?: \"Polygon\";\n};\nexport type ClickHouseMultiPolygon = ClickHousePolygon[] & {\n _clickhouse_mapped_type?: \"MultiPolygon\";\n};\n\n/**\n * typia may have trouble handling this type.\n * In which case, use {@link WithDefault} as a workaround\n *\n * @example\n * { field: number & ClickHouseDefault<\"0\"> }\n */\nexport type ClickHouseDefault<SqlExpression extends string> = {\n _clickhouse_default?: SqlExpression;\n};\n\n/**\n * @example\n * {\n * ...\n * timestamp: Date;\n * debugMessage: string & ClickHouseTTL<\"timestamp + INTERVAL 1 WEEK\">;\n * }\n */\nexport type ClickHouseTTL<SqlExpression extends string> = {\n _clickhouse_ttl?: SqlExpression;\n};\n\n/**\n * ClickHouse MATERIALIZED column annotation.\n * The column value is computed at INSERT time and physically stored.\n * Cannot be explicitly inserted by users.\n *\n * @example\n * interface Events {\n * eventTime: DateTime;\n * // Extract date component - computed and stored at insert time\n * eventDate: Date & ClickHouseMaterialized<\"toDate(event_time)\">;\n *\n * userId: string;\n * // Precompute hash for fast lookups\n * userHash: UInt64 & ClickHouseMaterialized<\"cityHash64(userId)\">;\n * }\n *\n * @remarks\n * - MATERIALIZED and DEFAULT are mutually exclusive\n * - Can be combined with ClickHouseCodec for compression\n * - Changing the expression modifies the column in-place (existing values preserved)\n */\nexport type ClickHouseMaterialized<SqlExpression extends string> = {\n _clickhouse_materialized?: SqlExpression;\n};\n\n/**\n * ClickHouse ALIAS column annotation.\n * The column value is computed on-the-fly at SELECT time and NOT physically stored.\n * Cannot be explicitly inserted by users.\n *\n * @example\n * interface Events {\n * eventTime: DateTime;\n * // Computed at query time, not stored on disk\n * eventDate: Date & ClickHouseAlias<\"toDate(event_time)\">;\n *\n * firstName: string;\n * lastName: string;\n * // Virtual computed column\n * fullName: string & ClickHouseAlias<\"concat(first_name, ' ', last_name)\">;\n * }\n *\n * @remarks\n * - ALIAS, MATERIALIZED, and DEFAULT are mutually exclusive\n * - ALIAS columns are NOT stored on disk (saves storage, costs CPU at query time)\n * - Cannot be used in ORDER BY, PRIMARY KEY, or PARTITION BY\n * - Can be combined with ClickHouseCodec (though rarely useful since not stored)\n */\nexport type ClickHouseAlias<SqlExpression extends string> = {\n _clickhouse_alias?: SqlExpression;\n};\n\n/**\n * See also {@link ClickHouseDefault}\n *\n * @example{ updated_at: WithDefault<Date, \"now()\"> }\n */\nexport type WithDefault<T, _SqlExpression extends string> = T;\n\ntype IsComputed<T> =\n \"_clickhouse_alias\" extends keyof T ? true\n : \"_clickhouse_materialized\" extends keyof T ? true\n : false;\n\ntype HasDefault<T> = \"_clickhouse_default\" extends keyof T ? true : false;\n\n/** Keys whose columns are ALIAS or MATERIALIZED — excluded from inserts entirely. */\ntype ComputedKeys<T> = {\n [K in keyof T]: IsComputed<T[K]> extends true ? K : never;\n}[keyof T];\n\n/** Keys whose columns carry a ClickHouseDefault expression — optional during inserts. */\ntype DefaultKeys<T> = {\n [K in keyof T]: HasDefault<T[K]> extends true ? K : never;\n}[keyof T];\n\n/**\n * Derive the insert-safe shape of a model:\n * - ALIAS / MATERIALIZED columns are **omitted** (ClickHouse computes them).\n * - DEFAULT columns become **optional** (ClickHouse fills them when absent).\n * - All other columns remain **required**.\n *\n * @example\n * interface Events {\n * id: Key<string>;\n * timestamp: Date;\n * eventDate: Date & ClickHouseAlias<\"toDate(timestamp)\">;\n * createdAt: Date & ClickHouseDefault<\"now()\">;\n * }\n *\n * // Insertable<Events> ≡ { id: string; timestamp: Date; createdAt?: Date }\n * const table = new OlapTable<Events>(\"events\");\n * await table.insert([{ id: \"1\", timestamp: new Date() }]);\n */\nexport type Insertable<T> = {\n [K in Exclude<keyof T, ComputedKeys<T> | DefaultKeys<T>>]: T[K];\n} & {\n [K in Exclude<DefaultKeys<T>, ComputedKeys<T>>]?: T[K];\n};\n\n/**\n * ClickHouse table engine types supported by Moose.\n */\nexport enum ClickHouseEngines {\n MergeTree = \"MergeTree\",\n ReplacingMergeTree = \"ReplacingMergeTree\",\n SummingMergeTree = \"SummingMergeTree\",\n AggregatingMergeTree = \"AggregatingMergeTree\",\n CollapsingMergeTree = \"CollapsingMergeTree\",\n VersionedCollapsingMergeTree = \"VersionedCollapsingMergeTree\",\n GraphiteMergeTree = \"GraphiteMergeTree\",\n S3Queue = \"S3Queue\",\n S3 = \"S3\",\n Buffer = \"Buffer\",\n Distributed = \"Distributed\",\n IcebergS3 = \"IcebergS3\",\n Kafka = \"Kafka\",\n Merge = \"Merge\",\n ReplicatedMergeTree = \"ReplicatedMergeTree\",\n ReplicatedReplacingMergeTree = \"ReplicatedReplacingMergeTree\",\n ReplicatedAggregatingMergeTree = \"ReplicatedAggregatingMergeTree\",\n ReplicatedSummingMergeTree = \"ReplicatedSummingMergeTree\",\n ReplicatedCollapsingMergeTree = \"ReplicatedCollapsingMergeTree\",\n ReplicatedVersionedCollapsingMergeTree = \"ReplicatedVersionedCollapsingMergeTree\",\n}\n","import type {\n Column,\n DataType,\n Nested,\n ArrayType,\n} from \"../dataModels/dataModelTypes\";\n\n/**\n * Annotation key used to mark DateTime fields that should remain as strings\n * rather than being parsed into Date objects at runtime.\n */\nexport const STRING_DATE_ANNOTATION = \"stringDate\";\n\n/**\n * Type guard to check if a DataType is a nullable wrapper\n */\nfunction isNullableType(dt: DataType): dt is { nullable: DataType } {\n return (\n typeof dt === \"object\" &&\n dt !== null &&\n \"nullable\" in dt &&\n typeof dt.nullable !== \"undefined\"\n );\n}\n\n/**\n * Type guard to check if a DataType is a Nested type\n */\nfunction isNestedType(dt: DataType): dt is Nested {\n return (\n typeof dt === \"object\" &&\n dt !== null &&\n \"columns\" in dt &&\n Array.isArray(dt.columns)\n );\n}\n\n/**\n * Type guard to check if a DataType is an ArrayType\n */\nfunction isArrayType(dt: DataType): dt is ArrayType {\n return (\n typeof dt === \"object\" &&\n dt !== null &&\n \"elementType\" in dt &&\n typeof dt.elementType !== \"undefined\"\n );\n}\n\n/**\n * Revives ISO 8601 date strings into Date objects during JSON parsing\n * This is useful for automatically converting date strings to Date objects\n */\nexport function jsonDateReviver(key: string, value: unknown): unknown {\n const iso8601Format =\n /^([\\+-]?\\d{4}(?!\\d{2}\\b))((-?)((0[1-9]|1[0-2])(\\3([12]\\d|0[1-9]|3[01]))?|W([0-4]\\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\\d|[12]\\d{2}|3([0-5]\\d|6[1-6])))([T\\s]((([01]\\d|2[0-3])((:?)[0-5]\\d)?|24\\:?00)([\\.,]\\d+(?!:))?)?(\\17[0-5]\\d([\\.,]\\d+)?)?([zZ]|([\\+-])([01]\\d|2[0-3]):?([0-5]\\d)?)?)?)$/;\n\n if (typeof value === \"string\" && iso8601Format.test(value)) {\n return new Date(value);\n }\n\n return value;\n}\n\n/**\n * Checks if a DataType represents a datetime column (not just date)\n * AND if the column should be parsed from string to Date at runtime\n *\n * Note: Date and Date16 are date-only types and should remain as strings.\n * Only DateTime types are candidates for parsing to JavaScript Date objects.\n */\nfunction isDateType(dataType: DataType, annotations: [string, any][]): boolean {\n // Check if this is marked as a string-based date (from typia.tags.Format)\n // If so, it should remain as a string, not be parsed to Date\n if (\n annotations.some(\n ([key, value]) => key === STRING_DATE_ANNOTATION && value === true,\n )\n ) {\n return false;\n }\n\n if (typeof dataType === \"string\") {\n // Only DateTime types should be parsed to Date objects\n // Date and Date16 are date-only and should stay as strings\n return dataType === \"DateTime\" || dataType.startsWith(\"DateTime(\");\n }\n // Handle nullable wrapper\n if (isNullableType(dataType)) {\n return isDateType(dataType.nullable, annotations);\n }\n return false;\n}\n\n/**\n * Type of mutation to apply to a field during parsing\n */\nexport type Mutation = \"parseDate\"; // | \"parseBigInt\" - to be added later\n\n/**\n * Recursive tuple array structure representing field mutation operations\n * Each entry is [fieldName, mutation]:\n * - mutation is Mutation[] for leaf fields that need operations applied\n * - mutation is FieldMutations for nested objects/arrays (auto-applies to array elements)\n */\nexport type FieldMutations = [string, Mutation[] | FieldMutations][];\n\n/**\n * Recursively builds field mutations from column definitions\n *\n * @param columns - Array of Column definitions\n * @returns Tuple array of field mutations\n */\nfunction buildFieldMutations(columns: Column[]): FieldMutations {\n const mutations: FieldMutations = [];\n\n for (const column of columns) {\n const dataType = column.data_type;\n\n // Check if this is a date field that should be converted\n if (isDateType(dataType, column.annotations)) {\n mutations.push([column.name, [\"parseDate\"]]);\n continue;\n }\n\n // Handle nested structures\n if (typeof dataType === \"object\" && dataType !== null) {\n // Handle nullable wrapper\n let unwrappedType: DataType = dataType;\n if (isNullableType(dataType)) {\n unwrappedType = dataType.nullable;\n }\n\n // Handle nested objects\n if (isNestedType(unwrappedType)) {\n const nestedMutations = buildFieldMutations(unwrappedType.columns);\n if (nestedMutations.length > 0) {\n mutations.push([column.name, nestedMutations]);\n }\n continue;\n }\n\n // Handle arrays with nested columns\n // The mutations will be auto-applied to each array element at runtime\n if (isArrayType(unwrappedType)) {\n const elementType = unwrappedType.elementType;\n if (isNestedType(elementType)) {\n const nestedMutations = buildFieldMutations(elementType.columns);\n if (nestedMutations.length > 0) {\n mutations.push([column.name, nestedMutations]);\n }\n continue;\n }\n }\n }\n }\n\n return mutations;\n}\n\n/**\n * Applies a mutation operation to a field value\n *\n * @param value - The value to handle\n * @param mutation - The mutation operation to apply\n * @returns The handled value\n */\nfunction applyMutation(value: any, mutation: Mutation): any {\n if (mutation === \"parseDate\") {\n if (typeof value === \"string\") {\n try {\n const date = new Date(value);\n return !isNaN(date.getTime()) ? date : value;\n } catch {\n return value;\n }\n }\n }\n return value;\n}\n\n/**\n * Recursively mutates an object by applying field mutations\n *\n * @param obj - The object to mutate\n * @param mutations - The field mutations to apply\n */\nfunction applyFieldMutations(obj: any, mutations: FieldMutations): void {\n if (!obj || typeof obj !== \"object\") {\n return;\n }\n\n for (const [fieldName, mutation] of mutations) {\n if (!(fieldName in obj)) {\n continue;\n }\n\n if (Array.isArray(mutation)) {\n // Check if it's Mutation[] (leaf) or FieldMutations (nested)\n if (mutation.length > 0 && typeof mutation[0] === \"string\") {\n // It's Mutation[] - apply operations to this field\n const operations = mutation as Mutation[];\n for (const operation of operations) {\n obj[fieldName] = applyMutation(obj[fieldName], operation);\n }\n } else {\n // It's FieldMutations - recurse into nested structure\n const nestedMutations = mutation as FieldMutations;\n const fieldValue = obj[fieldName];\n\n if (Array.isArray(fieldValue)) {\n // Auto-apply to each array element\n for (const item of fieldValue) {\n applyFieldMutations(item, nestedMutations);\n }\n } else if (fieldValue && typeof fieldValue === \"object\") {\n // Apply to nested object\n applyFieldMutations(fieldValue, nestedMutations);\n }\n }\n }\n }\n}\n\n/**\n * Pre-builds field mutations from column schema for efficient reuse\n *\n * @param columns - Column definitions from the Stream schema\n * @returns Field mutations tuple array, or undefined if no columns\n *\n * @example\n * ```typescript\n * const fieldMutations = buildFieldMutationsFromColumns(stream.columnArray);\n * // Reuse fieldMutations for every message\n * ```\n */\nexport function buildFieldMutationsFromColumns(\n columns: Column[] | undefined,\n): FieldMutations | undefined {\n if (!columns || columns.length === 0) {\n return undefined;\n }\n const mutations = buildFieldMutations(columns);\n return mutations.length > 0 ? mutations : undefined;\n}\n\n/**\n * Applies field mutations to parsed data\n * Mutates the object in place for performance\n *\n * @param data - The parsed JSON object to mutate\n * @param fieldMutations - Pre-built field mutations from buildFieldMutationsFromColumns\n *\n * @example\n * ```typescript\n * const fieldMutations = buildFieldMutationsFromColumns(stream.columnArray);\n * const data = JSON.parse(jsonString);\n * mutateParsedJson(data, fieldMutations);\n * // data now has transformations applied per the field mutations\n * ```\n */\nexport function mutateParsedJson(\n data: any,\n fieldMutations: FieldMutations | undefined,\n): void {\n if (!fieldMutations || !data) {\n return;\n }\n\n applyFieldMutations(data, fieldMutations);\n}\n","/**\n * Direct integration with typia's internal programmers\n * This bypasses the need for typia's transformer plugin by directly calling\n * typia's code generation functions.\n *\n * IMPORTANT: We import from typia/lib (compiled JS) not typia/src (TypeScript)\n * to avoid issues with Node's type stripping in node_modules.\n */\nimport ts from \"typescript\";\nimport { ImportProgrammer } from \"typia/lib/programmers/ImportProgrammer\";\nimport { ValidateProgrammer } from \"typia/lib/programmers/ValidateProgrammer\";\nimport { IsProgrammer } from \"typia/lib/programmers/IsProgrammer\";\nimport { AssertProgrammer } from \"typia/lib/programmers/AssertProgrammer\";\nimport { JsonSchemasProgrammer } from \"typia/lib/programmers/json/JsonSchemasProgrammer\";\nimport { HttpAssertQueryProgrammer } from \"typia/lib/programmers/http/HttpAssertQueryProgrammer\";\nimport { MetadataCollection } from \"typia/lib/factories/MetadataCollection\";\nimport { MetadataFactory } from \"typia/lib/factories/MetadataFactory\";\nimport { LiteralFactory } from \"typia/lib/factories/LiteralFactory\";\nimport { ITypiaContext } from \"typia/lib/transformers/ITypiaContext\";\nimport { IJsonSchemaCollection } from \"typia/lib/schemas/json/IJsonSchemaCollection\";\nimport { avoidTypiaNameClash } from \"./compilerPluginHelper\";\nimport { Metadata } from \"typia/lib/schemas/metadata/Metadata\";\n\n// Simple type for JSON Schema objects - we use a minimal type instead of\n// importing @samchon/openapi to avoid adding an extra dependency.\n// Based on OpenApi.IJsonSchema which includes:\n// IConstant, IBoolean, IInteger, INumber, IString, IArray, ITuple,\n// IObject, IReference, IOneOf, INull, IUnknown\ntype JsonSchema = {\n type?: string;\n format?: string;\n $ref?: string;\n // IObject\n properties?: Record<string, JsonSchema>;\n additionalProperties?: boolean | JsonSchema;\n required?: string[];\n // IArray\n items?: JsonSchema;\n // ITuple\n prefixItems?: JsonSchema[];\n additionalItems?: boolean | JsonSchema;\n // Union types\n oneOf?: JsonSchema[];\n anyOf?: JsonSchema[];\n allOf?: JsonSchema[];\n [key: string]: unknown;\n};\n\n/**\n * Context for direct typia code generation\n */\nexport interface TypiaDirectContext {\n program: ts.Program;\n checker: ts.TypeChecker;\n transformer: ts.TransformationContext;\n importer: ImportProgrammer;\n modulo: ts.LeftHandSideExpression;\n sourceFile: ts.SourceFile;\n}\n\n/**\n * Creates a synthetic identifier with a patched getText method.\n * Typia's programmers call modulo.getText() which normally requires\n * the node to be attached to a source file. We patch the method directly.\n */\nconst createSyntheticModulo = (): ts.LeftHandSideExpression => {\n const identifier = ts.factory.createIdentifier(\"typia\");\n\n // Monkey-patch getText to return \"typia\" directly\n identifier.getText = () => \"typia\";\n\n return identifier;\n};\n\n/**\n * Creates a typia context for direct code generation\n */\nexport const createTypiaContext = (\n program: ts.Program,\n transformer: ts.TransformationContext,\n sourceFile: ts.SourceFile,\n): TypiaDirectContext => {\n const importer = new ImportProgrammer({\n internalPrefix: avoidTypiaNameClash,\n });\n\n return {\n program,\n checker: program.getTypeChecker(),\n transformer,\n importer,\n modulo: createSyntheticModulo(),\n sourceFile,\n };\n};\n\n/**\n * Converts our context to typia's internal context format\n */\nconst toTypiaContext = (ctx: TypiaDirectContext): ITypiaContext => ({\n program: ctx.program,\n compilerOptions: ctx.program.getCompilerOptions(),\n checker: ctx.checker,\n printer: ts.createPrinter(),\n options: {},\n transformer: ctx.transformer,\n importer: ctx.importer,\n extras: {\n // Not used by the programmers we call directly (CheckerProgrammer,\n // HttpAssertQueryProgrammer, JsonSchemasProgrammer) - only used by\n // FileTransformer which we bypass\n addDiagnostic: () => 0,\n },\n});\n\n/**\n * Generates a validate function directly using typia's ValidateProgrammer\n */\nexport const generateValidateFunction = (\n ctx: TypiaDirectContext,\n type: ts.Type,\n typeName?: string,\n): ts.Expression => {\n const typiaCtx = toTypiaContext(ctx);\n\n return ValidateProgrammer.write({\n context: typiaCtx,\n modulo: ctx.modulo,\n type,\n name: typeName,\n config: { equals: false },\n });\n};\n\n/**\n * Generates an is function directly using typia's IsProgrammer\n */\nexport const generateIsFunction = (\n ctx: TypiaDirectContext,\n type: ts.Type,\n typeName?: string,\n): ts.Expression => {\n const typiaCtx = toTypiaContext(ctx);\n\n return IsProgrammer.write({\n context: typiaCtx,\n modulo: ctx.modulo,\n type,\n name: typeName,\n config: { equals: false },\n });\n};\n\n/**\n * Generates an assert function directly using typia's AssertProgrammer\n */\nexport const generateAssertFunction = (\n ctx: TypiaDirectContext,\n type: ts.Type,\n typeName?: string,\n): ts.Expression => {\n const typiaCtx = toTypiaContext(ctx);\n\n return AssertProgrammer.write({\n context: typiaCtx,\n modulo: ctx.modulo,\n type,\n name: typeName,\n config: { equals: false, guard: false },\n });\n};\n\n// ============================================================================\n// Insert-specific validators (Insertable<T> semantics via metadata patching)\n// ============================================================================\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * Gets the string name from a MetadataProperty's key metadata.\n * Typia encodes property keys as `key.constants[0].values[0].value`.\n */\nconst getPropertyName = (prop: any): string | undefined =>\n prop.key.constants?.[0]?.values?.[0]?.value;\n\n/**\n * Modifies analyzed metadata in-place to apply Insertable<T> semantics:\n * - Properties in `computedColumns` are removed entirely\n * - Properties in `defaultColumns` become optional\n *\n * @param metadata Metadata analyzed by typia\n * @param computedColumns Names of ALIAS / MATERIALIZED columns\n * @param defaultColumns Names of DEFAULT columns\n */\nconst patchMetadataForInsert = (\n metadata: Metadata,\n computedColumns: ReadonlySet<string>,\n defaultColumns: ReadonlySet<string>,\n): void => {\n for (const obj of metadata.objects) {\n const keep: any[] = [];\n for (const prop of obj.type.properties) {\n const name = getPropertyName(prop);\n if (name !== undefined && computedColumns.has(name)) continue;\n if (name !== undefined && defaultColumns.has(name)) {\n prop.value.optional = true;\n prop.value.required = false;\n }\n keep.push(prop);\n }\n obj.type.properties.length = 0;\n obj.type.properties.push(...keep);\n }\n};\n\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\n/**\n * Generates insert-specific typia validators that apply Insertable<T> semantics.\n *\n * Works by temporarily monkey-patching MetadataFactory.analyze so the\n * programmers see a metadata tree where computed columns are removed and\n * default columns are optional.\n */\nexport interface InsertColumnSets {\n computed: ReadonlySet<string>;\n defaults: ReadonlySet<string>;\n}\n\nconst withInsertableMetadata = <R>(\n columns: InsertColumnSets,\n fn: () => R,\n): R => {\n /* eslint-disable @typescript-eslint/no-explicit-any */\n const original = MetadataFactory.analyze;\n\n (MetadataFactory as any).analyze = (props: any) => {\n const result = original(props);\n if (result.success) {\n patchMetadataForInsert(result.data, columns.computed, columns.defaults);\n }\n return result;\n };\n\n try {\n return fn();\n } finally {\n (MetadataFactory as any).analyze = original;\n }\n /* eslint-enable @typescript-eslint/no-explicit-any */\n};\n\nexport const generateInsertValidateFunction = (\n ctx: TypiaDirectContext,\n type: ts.Type,\n columns: InsertColumnSets,\n typeName?: string,\n): ts.Expression =>\n withInsertableMetadata(columns, () =>\n generateValidateFunction(ctx, type, typeName),\n );\n\nexport const generateInsertIsFunction = (\n ctx: TypiaDirectContext,\n type: ts.Type,\n columns: InsertColumnSets,\n typeName?: string,\n): ts.Expression =>\n withInsertableMetadata(columns, () =>\n generateIsFunction(ctx, type, typeName),\n );\n\nexport const generateInsertAssertFunction = (\n ctx: TypiaDirectContext,\n type: ts.Type,\n columns: InsertColumnSets,\n typeName?: string,\n): ts.Expression =>\n withInsertableMetadata(columns, () =>\n generateAssertFunction(ctx, type, typeName),\n );\n\n/**\n * Generates an HTTP assert query function for validating URL query parameters\n * This is used by the Api class to validate incoming query parameters\n */\nexport const generateHttpAssertQueryFunction = (\n ctx: TypiaDirectContext,\n type: ts.Type,\n typeName?: string,\n): ts.Expression => {\n const typiaCtx = toTypiaContext(ctx);\n\n return HttpAssertQueryProgrammer.write({\n context: typiaCtx,\n modulo: ctx.modulo,\n type,\n name: typeName,\n });\n};\n\n// ============================================================================\n// JSON Schema Post-Processing\n// ============================================================================\n\n/**\n * The standard JSON Schema representation for Date types.\n * Typia outputs Date as an empty object schema with a $ref, but the correct\n * representation is { type: \"string\", format: \"date-time\" }.\n */\nconst DATE_SCHEMA: JsonSchema = {\n type: \"string\",\n format: \"date-time\",\n};\n\n/**\n * Checks if a property name is an internal ClickHouse tag that should be\n * stripped from the JSON schema.\n */\nconst isClickHouseInternalProperty = (name: string): boolean =>\n name.startsWith(\"_clickhouse_\") || name === \"_LowCardinality\";\n\n/**\n * Recursively processes a JSON schema to:\n * 1. Replace $ref to Date with inline { type: \"string\", format: \"date-time\" }\n * 2. Remove internal ClickHouse properties from object schemas\n *\n * Handles all OpenApi.IJsonSchema variants:\n * IConstant, IBoolean, IInteger, INumber, IString, IArray, ITuple,\n * IObject, IReference, IOneOf, INull, IUnknown\n */\nconst cleanJsonSchema = (schema: JsonSchema): JsonSchema => {\n // Handle $ref to Date - replace with inline date-time schema\n if (schema.$ref === \"#/components/schemas/Date\") {\n // Preserve any other properties from the original schema (like description)\n const { $ref, ...rest } = schema;\n return { ...DATE_SCHEMA, ...rest };\n }\n\n // Handle object schemas (IObject) - filter out ClickHouse internal properties\n if (schema.type === \"object\") {\n const result: JsonSchema = { ...schema };\n\n // Clean properties\n if (schema.properties) {\n const cleanedProperties: Record<string, JsonSchema> = {};\n const cleanedRequired: string[] = [];\n\n for (const [key, value] of Object.entries(schema.properties)) {\n if (!isClickHouseInternalProperty(key)) {\n cleanedProperties[key] = cleanJsonSchema(value);\n if (schema.required?.includes(key)) {\n cleanedRequired.push(key);\n }\n }\n }\n\n result.properties = cleanedProperties;\n result.required =\n cleanedRequired.length > 0 ? cleanedRequired : undefined;\n }\n\n // Clean additionalProperties if it's a schema\n if (\n schema.additionalProperties &&\n typeof schema.additionalProperties === \"object\"\n ) {\n result.additionalProperties = cleanJsonSchema(\n schema.additionalProperties,\n );\n }\n\n return result;\n }\n\n // Handle array schemas (IArray)\n if (schema.type === \"array\") {\n const result: JsonSchema = { ...schema };\n\n // Clean items (IArray.items)\n if (schema.items) {\n result.items = cleanJsonSchema(schema.items);\n }\n\n // Clean prefixItems (ITuple.prefixItems)\n if (schema.prefixItems && Array.isArray(schema.prefixItems)) {\n result.prefixItems = schema.prefixItems.map(cleanJsonSchema);\n }\n\n // Clean additionalItems if it's a schema (ITuple.additionalItems)\n if (schema.additionalItems && typeof schema.additionalItems === \"object\") {\n result.additionalItems = cleanJsonSchema(schema.additionalItems);\n }\n\n return result;\n }\n\n // Handle oneOf/anyOf/allOf (IOneOf and merged types)\n if (schema.oneOf && Array.isArray(schema.oneOf)) {\n return {\n ...schema,\n oneOf: schema.oneOf.map(cleanJsonSchema),\n };\n }\n if (schema.anyOf && Array.isArray(schema.anyOf)) {\n return {\n ...schema,\n anyOf: schema.anyOf.map(cleanJsonSchema),\n };\n }\n if (schema.allOf && Array.isArray(schema.allOf)) {\n return {\n ...schema,\n allOf: schema.allOf.map(cleanJsonSchema),\n };\n }\n\n // Primitive types (IConstant, IBoolean, IInteger, INumber, IString, INull, IUnknown)\n // don't need recursion - return as-is\n return schema;\n};\n\n/**\n * Post-processes a JSON schema collection to clean up Moose-specific artifacts:\n * 1. Converts Date schemas to { type: \"string\", format: \"date-time\" }\n * 2. Removes internal ClickHouse properties (_clickhouse_*, _LowCardinality)\n */\nconst cleanJsonSchemaCollection = <V extends \"3.0\" | \"3.1\">(\n collection: IJsonSchemaCollection<V>,\n): IJsonSchemaCollection<V> => {\n // Clean component schemas\n const cleanedComponentsSchemas: Record<string, JsonSchema> = {};\n\n if (collection.components.schemas) {\n for (const [name, schema] of Object.entries(\n collection.components.schemas,\n )) {\n // Replace Date schema with proper date-time representation\n if (name === \"Date\") {\n cleanedComponentsSchemas[name] = DATE_SCHEMA;\n } else {\n cleanedComponentsSchemas[name] = cleanJsonSchema(schema as JsonSchema);\n }\n }\n }\n\n // Clean top-level schemas\n const cleanedSchemas = collection.schemas.map((s) =>\n cleanJsonSchema(s as JsonSchema),\n );\n\n return {\n ...collection,\n components: {\n ...collection.components,\n schemas: cleanedComponentsSchemas,\n },\n schemas: cleanedSchemas,\n } as IJsonSchemaCollection<V>;\n};\n\n/**\n * Generates JSON schemas directly using typia's JsonSchemasProgrammer.\n *\n * Uses the same options as CheckerProgrammer (absorb: true, escape: false)\n * to handle our custom ClickHouse type tags that typia doesn't recognize.\n *\n * Post-processes the generated schema to:\n * 1. Convert Date to { type: \"string\", format: \"date-time\" }\n * 2. Strip internal ClickHouse properties (_clickhouse_*, _LowCardinality)\n */\nexport const generateJsonSchemas = (\n ctx: TypiaDirectContext,\n type: ts.Type,\n): ts.Expression => {\n // Use same options as CheckerProgrammer for consistency\n // Key: escape: false allows intersection handling without errors\n // Note: We don't strip custom type tags here - cleanJsonSchemaCollection\n // handles removing _clickhouse_* properties from the output\n const metadataResult = MetadataFactory.analyze({\n checker: ctx.checker,\n transformer: ctx.transformer,\n options: {\n absorb: true,\n constant: true,\n escape: false, // Match CheckerProgrammer - this is key!\n },\n collection: new MetadataCollection({\n replace: MetadataCollection.replace,\n }),\n type: type,\n });\n\n if (!metadataResult.success) {\n const errors = metadataResult.errors\n .map((e) => `${e.name}: ${e.messages.join(\", \")}`)\n .join(\"; \");\n throw new Error(`Typia metadata analysis failed: ${errors}`);\n }\n\n // Generate the JSON schema collection\n const rawCollection = JsonSchemasProgrammer.write({\n version: \"3.1\",\n metadatas: [metadataResult.data],\n });\n\n // Post-process to clean up Moose-specific artifacts\n const collection = cleanJsonSchemaCollection(rawCollection);\n\n // Convert the collection to an AST literal\n return ts.factory.createAsExpression(\n LiteralFactory.write(collection),\n ts.factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword),\n );\n};\n","import ts, { factory, SyntaxKind } from \"typescript\";\nimport { isMooseFile, type TransformContext } from \"../compilerPluginHelper\";\nimport { toColumns } from \"../dataModels/typeConvert\";\nimport { parseAsAny } from \"../dmv2/dataModelMetadata\";\nimport {\n generateHttpAssertQueryFunction,\n generateJsonSchemas,\n} from \"../typiaDirectIntegration\";\n\nexport const isApiV2 = (\n node: ts.Node,\n checker: ts.TypeChecker,\n): node is ts.NewExpression => {\n if (!ts.isNewExpression(node)) {\n return false;\n }\n\n const declaration: ts.Declaration | undefined =\n checker.getResolvedSignature(node)?.declaration;\n if (!declaration || !isMooseFile(declaration.getSourceFile())) {\n return false;\n }\n\n const sym = checker.getSymbolAtLocation(node.expression);\n return sym?.name === \"Api\" || sym?.name === \"ConsumptionApi\";\n};\n\nexport const transformApiV2 = (\n node: ts.NewExpression,\n checker: ts.TypeChecker,\n ctx: TransformContext,\n): ts.Node => {\n if (!isApiV2(node, checker)) {\n return node;\n }\n\n if (!node.arguments || node.arguments.length < 2 || !node.typeArguments) {\n return node;\n }\n\n const typiaCtx = ctx.typiaContext;\n\n // Get both type parameters from Api<T, R>\n const typeNode = node.typeArguments[0];\n const responseTypeNode =\n node.typeArguments[1] ||\n factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword);\n\n const inputType = checker.getTypeAtLocation(typeNode);\n const responseType = checker.getTypeAtLocation(responseTypeNode);\n\n // Get the handler function (second argument)\n const handlerFunc = node.arguments[1];\n\n // Generate the HTTP assert query function directly\n const assertQueryFunc = generateHttpAssertQueryFunction(typiaCtx, inputType);\n\n // Create a new handler function that includes validation\n const wrappedHandler = factory.createArrowFunction(\n undefined,\n undefined,\n [\n factory.createParameterDeclaration(\n undefined,\n undefined,\n factory.createIdentifier(\"params\"),\n undefined,\n undefined,\n undefined,\n ),\n factory.createParameterDeclaration(\n undefined,\n undefined,\n factory.createIdentifier(\"utils\"),\n undefined,\n undefined,\n undefined,\n ),\n ],\n undefined,\n factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),\n factory.createBlock(\n [\n // const assertGuard = <generated http assert query function>\n factory.createVariableStatement(\n undefined,\n factory.createVariableDeclarationList(\n [\n factory.createVariableDeclaration(\n factory.createIdentifier(\"assertGuard\"),\n undefined,\n undefined,\n assertQueryFunc,\n ),\n ],\n ts.NodeFlags.Const,\n ),\n ),\n // const searchParams = new URLSearchParams(params as any)\n factory.createVariableStatement(\n undefined,\n factory.createVariableDeclarationList(\n [\n factory.createVariableDeclaration(\n factory.createIdentifier(\"searchParams\"),\n undefined,\n undefined,\n factory.createNewExpression(\n factory.createIdentifier(\"URLSearchParams\"),\n undefined,\n [\n factory.createAsExpression(\n factory.createIdentifier(\"params\"),\n factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword),\n ),\n ],\n ),\n ),\n ],\n ts.NodeFlags.Const,\n ),\n ),\n // const processedParams = assertGuard(searchParams)\n factory.createVariableStatement(\n undefined,\n factory.createVariableDeclarationList(\n [\n factory.createVariableDeclaration(\n factory.createIdentifier(\"processedParams\"),\n undefined,\n undefined,\n factory.createCallExpression(\n factory.createIdentifier(\"assertGuard\"),\n undefined,\n [factory.createIdentifier(\"searchParams\")],\n ),\n ),\n ],\n ts.NodeFlags.Const,\n ),\n ),\n factory.createVariableStatement(\n undefined,\n factory.createVariableDeclarationList(\n [\n factory.createVariableDeclaration(\n factory.createIdentifier(\"originalHandler\"),\n undefined,\n factory.createFunctionTypeNode(\n undefined,\n [\n factory.createParameterDeclaration(\n undefined,\n undefined,\n \"params\",\n undefined,\n typeNode,\n ),\n factory.createParameterDeclaration(\n undefined,\n undefined,\n \"utils\",\n undefined,\n factory.createImportTypeNode(\n factory.createLiteralTypeNode(\n factory.createStringLiteral(\"@514labs/moose-lib\"),\n ),\n undefined,\n factory.createIdentifier(\"ApiUtil\"),\n [],\n false,\n ),\n ),\n ],\n factory.createKeywordTypeNode(SyntaxKind.AnyKeyword),\n ),\n factory.createParenthesizedExpression(handlerFunc),\n ),\n ],\n ts.NodeFlags.Const,\n ),\n ),\n // return originalHandler(processedParams, utils)\n factory.createReturnStatement(\n factory.createCallExpression(\n factory.createIdentifier(\"originalHandler\"),\n undefined,\n [\n factory.createIdentifier(\"processedParams\"),\n factory.createIdentifier(\"utils\"),\n ],\n ),\n ),\n ],\n true,\n ),\n );\n\n // Generate schemas directly\n const inputSchemaArg =\n node.arguments.length > 3 ?\n node.arguments[3]\n : generateJsonSchemas(typiaCtx, inputType);\n const responseSchemaArg = generateJsonSchemas(typiaCtx, responseType);\n\n // Create the columns argument if it doesn't exist\n const inputColumnsArg = toColumns(inputType, checker);\n\n // Create the config argument if it doesn't exist\n const configArg =\n node.arguments.length > 2 ?\n node.arguments[2]\n : factory.createObjectLiteralExpression([], false);\n\n // Update the Api constructor call with all necessary arguments\n return factory.updateNewExpression(\n node,\n node.expression,\n node.typeArguments,\n [\n node.arguments[0], // name\n wrappedHandler, // wrapped handler\n configArg, // config object\n inputSchemaArg, // input schema\n parseAsAny(JSON.stringify(inputColumnsArg)), // input columns\n responseSchemaArg, // response schema\n ],\n );\n};\n","import {\n existsSync,\n readdirSync,\n readFileSync,\n statSync,\n writeFileSync,\n} from \"fs\";\nimport nodePath from \"path\";\nimport { createClient } from \"@clickhouse/client\";\nimport { KafkaJS } from \"@514labs/kafka-javascript\";\nimport { SASLOptions } from \"@514labs/kafka-javascript/types/kafkajs\";\nconst { Kafka } = KafkaJS;\ntype Kafka = KafkaJS.Kafka;\ntype Consumer = KafkaJS.Consumer;\nexport type Producer = KafkaJS.Producer;\n\n/**\n * Utility function for compiler-related logging that can be disabled via environment variable.\n * Set MOOSE_DISABLE_COMPILER_LOGS=true to suppress these logs (useful for testing environments).\n */\n\n/**\n * Returns true if the value is a common truthy string: \"1\", \"true\", \"yes\", \"on\" (case-insensitive).\n */\nfunction isTruthy(value: string | undefined): boolean {\n if (!value) return false;\n switch (value.trim().toLowerCase()) {\n case \"1\":\n case \"true\":\n case \"yes\":\n case \"on\":\n return true;\n default:\n return false;\n }\n}\n\nexport const compilerLog = (message: string) => {\n if (!isTruthy(process.env.MOOSE_DISABLE_COMPILER_LOGS)) {\n console.log(message);\n }\n};\n\nexport const antiCachePath = (path: string) =>\n `${path}?num=${Math.random().toString()}&time=${Date.now()}`;\n\nexport const getFileName = (filePath: string) => {\n const regex = /\\/([^\\/]+)\\.ts/;\n const matches = filePath.match(regex);\n if (matches && matches.length > 1) {\n return matches[1];\n }\n return \"\";\n};\n\ninterface ClientConfig {\n username: string;\n password: string;\n database: string;\n useSSL: string;\n host: string;\n port: string;\n}\n\nexport const getClickhouseClient = ({\n username,\n password,\n database,\n useSSL,\n host,\n port,\n}: ClientConfig) => {\n const protocol =\n useSSL === \"1\" || useSSL.toLowerCase() === \"true\" ? \"https\" : \"http\";\n console.log(`Connecting to Clickhouse at ${protocol}://${host}:${port}`);\n return createClient({\n url: `${protocol}://${host}:${port}`,\n username: username,\n password: password,\n database: database,\n application: \"moose\",\n // Note: wait_end_of_query is configured per operation type, not globally\n // to preserve SELECT query performance while ensuring INSERT/DDL reliability\n });\n};\n\nexport type CliLogData = {\n message_type?: \"Info\" | \"Success\" | \"Warning\" | \"Error\" | \"Highlight\";\n action: string;\n message: string;\n};\n\nexport const cliLog: (log: CliLogData) => void = (log) => {\n const level =\n log.message_type === \"Error\" ? \"error\"\n : log.message_type === \"Warning\" ? \"warn\"\n : \"info\";\n\n const structuredLog = {\n __moose_structured_log__: true,\n level,\n message: log.message,\n resource_type: \"runtime\",\n cli_action: log.action,\n cli_message_type: log.message_type ?? \"Info\",\n timestamp: new Date().toISOString(),\n };\n\n process.stderr.write(JSON.stringify(structuredLog) + \"\\n\");\n};\n\n/**\n * Method to change .ts, .cts, and .mts to .js, .cjs, and .mjs\n * This is needed because 'import' does not support .ts, .cts, and .mts\n */\nexport function mapTstoJs(filePath: string): string {\n return filePath\n .replace(/\\.ts$/, \".js\")\n .replace(/\\.cts$/, \".cjs\")\n .replace(/\\.mts$/, \".mjs\");\n}\n\n/**\n * Walks a directory recursively and returns all files matching the given extensions.\n * Skips node_modules directories.\n *\n * @param dir - Directory to walk\n * @param extensions - File extensions to include (e.g., [\".js\", \".mjs\"])\n * @returns Array of file paths\n */\nfunction walkDirectory(dir: string, extensions: string[]): string[] {\n const results: string[] = [];\n\n if (!existsSync(dir)) {\n return results;\n }\n\n try {\n const entries = readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = nodePath.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n // Skip node_modules\n if (entry.name !== \"node_modules\") {\n results.push(...walkDirectory(fullPath, extensions));\n }\n } else if (entry.isFile()) {\n const ext = nodePath.extname(entry.name);\n if (extensions.includes(ext)) {\n results.push(fullPath);\n }\n }\n }\n } catch (e) {\n // Log error in case it is something the user can/should act on\n console.debug(`[moose] Failed to read directory ${dir}:`, e);\n }\n\n return results;\n}\n\n/**\n * Adds .js extension to relative import paths that don't have an extension.\n * Handles import/export from statements and dynamic imports.\n *\n * @param content - JavaScript file content\n * @param fileDir - Directory containing the file being processed (for resolving paths)\n * @returns Content with .js extensions added to relative imports\n */\nfunction addJsExtensionToImports(content: string, fileDir?: string): string {\n // Pattern for 'from' statements with relative paths\n // Matches: from './foo', from \"../bar\", from './utils/helper'\n const fromPattern = /(from\\s+['\"])(\\.\\.?\\/[^'\"]*?)(['\"])/g;\n\n // Pattern for side-effect-only imports with relative paths\n // Matches: import './foo', import \"../bar\" (no 'from' keyword, just importing for side effects)\n const bareImportPattern = /(import\\s+['\"])(\\.\\.?\\/[^'\"]*?)(['\"])/g;\n\n // Pattern for dynamic imports with relative paths\n // Matches: import('./foo'), import(\"../bar\")\n const dynamicPattern = /(import\\s*\\(\\s*['\"])(\\.\\.?\\/[^'\"]*?)(['\"])/g;\n\n let result = content;\n\n // Process 'from' statements\n result = result.replace(fromPattern, (match, prefix, importPath, quote) => {\n return rewriteImportPath(match, prefix, importPath, quote, fileDir);\n });\n\n // Process side-effect-only imports\n result = result.replace(\n bareImportPattern,\n (match, prefix, importPath, quote) => {\n return rewriteImportPath(match, prefix, importPath, quote, fileDir);\n },\n );\n\n // Process dynamic imports\n result = result.replace(\n dynamicPattern,\n (match, prefix, importPath, quote) => {\n return rewriteImportPath(match, prefix, importPath, quote, fileDir);\n },\n );\n\n return result;\n}\n\n/**\n * Rewrites a single import path to add .js extension if needed.\n * Handles directory imports with index files correctly.\n *\n * @param match - The full matched string\n * @param prefix - The prefix (from ' or import(')\n * @param importPath - The import path\n * @param quote - The closing quote\n * @param fileDir - Directory containing the file being processed (for resolving paths)\n * @returns The rewritten import or original if no change needed\n */\nfunction rewriteImportPath(\n match: string,\n prefix: string,\n importPath: string,\n quote: string,\n fileDir?: string,\n): string {\n // Skip if already has a JavaScript extension\n if (/\\.[cm]?js$/.test(importPath)) {\n return match;\n }\n\n // Skip if importing a JSON file\n if (/\\.json$/.test(importPath)) {\n return match;\n }\n\n // If we have the file directory, check if the import target is a directory with index.js\n if (fileDir) {\n const resolvedPath = nodePath.resolve(fileDir, importPath);\n\n // Check if path.js exists (regular file import)\n if (existsSync(`${resolvedPath}.js`)) {\n return `${prefix}${importPath}.js${quote}`;\n }\n\n // Check if path/index.js exists (directory import)\n if (existsSync(nodePath.join(resolvedPath, \"index.js\"))) {\n // For directory imports, rewrite to include /index.js\n return `${prefix}${importPath}/index.js${quote}`;\n }\n\n // Check for .mjs variants\n if (existsSync(`${resolvedPath}.mjs`)) {\n return `${prefix}${importPath}.mjs${quote}`;\n }\n if (existsSync(nodePath.join(resolvedPath, \"index.mjs\"))) {\n return `${prefix}${importPath}/index.mjs${quote}`;\n }\n\n // Check for .cjs variants\n if (existsSync(`${resolvedPath}.cjs`)) {\n return `${prefix}${importPath}.cjs${quote}`;\n }\n if (existsSync(nodePath.join(resolvedPath, \"index.cjs\"))) {\n return `${prefix}${importPath}/index.cjs${quote}`;\n }\n }\n\n // Default: add .js extension (fallback when no fileDir or file not found)\n return `${prefix}${importPath}.js${quote}`;\n}\n\n/**\n * Rewrites relative import paths in JavaScript files to include .js extensions.\n * This is required for Node.js ESM which requires explicit extensions.\n *\n * Handles:\n * - import statements: import { foo } from './bar' -> import { foo } from './bar.js'\n * - dynamic imports: import('./bar') -> import('./bar.js')\n * - re-exports: export { foo } from './bar' -> export { foo } from './bar.js'\n *\n * Does NOT modify:\n * - Package imports (no leading . or ..)\n * - Imports that already have extensions\n * - Imports from node_modules\n *\n * @param outDir - Directory containing compiled JavaScript files\n */\nexport function rewriteImportExtensions(outDir: string): void {\n const files = walkDirectory(outDir, [\".js\", \".mjs\"]);\n\n for (const filePath of files) {\n const content = readFileSync(filePath, \"utf-8\");\n const fileDir = nodePath.dirname(filePath);\n const rewritten = addJsExtensionToImports(content, fileDir);\n\n if (content !== rewritten) {\n writeFileSync(filePath, rewritten, \"utf-8\");\n }\n }\n}\n\nexport const MAX_RETRIES = 150;\nexport const MAX_RETRY_TIME_MS = 1000;\nexport const RETRY_INITIAL_TIME_MS = 100;\n\nexport const MAX_RETRIES_PRODUCER = 150;\nexport const RETRY_FACTOR_PRODUCER = 0.2;\n// Means all replicas need to acknowledge the message\nexport const ACKs = -1;\n\n/**\n * Creates the base producer configuration for Kafka.\n * Used by both the SDK stream publishing and streaming function workers.\n *\n * @param maxMessageBytes - Optional max message size in bytes (synced with topic config)\n * @returns Producer configuration object for the Confluent Kafka client\n */\nexport function createProducerConfig(maxMessageBytes?: number) {\n return {\n kafkaJS: {\n idempotent: false, // Not needed for at-least-once delivery\n acks: ACKs,\n retry: {\n retries: MAX_RETRIES_PRODUCER,\n maxRetryTime: MAX_RETRY_TIME_MS,\n },\n },\n \"linger.ms\": 0, // This is to make sure at least once delivery with immediate feedback on the send\n ...(maxMessageBytes && { \"message.max.bytes\": maxMessageBytes }),\n };\n}\n\n/**\n * Parses a comma-separated broker string into an array of valid broker addresses.\n * Handles whitespace trimming and filters out empty elements.\n *\n * @param brokerString - Comma-separated broker addresses (e.g., \"broker1:9092, broker2:9092, , broker3:9092\")\n * @returns Array of trimmed, non-empty broker addresses\n */\nconst parseBrokerString = (brokerString: string): string[] =>\n brokerString\n .split(\",\")\n .map((b) => b.trim())\n .filter((b) => b.length > 0);\n\nexport type KafkaClientConfig = {\n clientId: string;\n broker: string;\n securityProtocol?: string; // e.g. \"SASL_SSL\" or \"PLAINTEXT\"\n saslUsername?: string;\n saslPassword?: string;\n saslMechanism?: string; // e.g. \"scram-sha-256\", \"plain\"\n};\n\n/**\n * Dynamically creates and connects a KafkaJS producer using the provided configuration.\n * Returns a connected producer instance.\n *\n * @param cfg - Kafka client configuration\n * @param logger - Logger instance\n * @param maxMessageBytes - Optional max message size in bytes (synced with topic config)\n */\nexport async function getKafkaProducer(\n cfg: KafkaClientConfig,\n logger: Logger,\n maxMessageBytes?: number,\n): Promise<Producer> {\n const kafka = await getKafkaClient(cfg, logger);\n\n const producer = kafka.producer(createProducerConfig(maxMessageBytes));\n await producer.connect();\n return producer;\n}\n\n/**\n * Interface for logging functionality\n */\nexport interface Logger {\n logPrefix: string;\n log: (message: string) => void;\n error: (message: string) => void;\n warn: (message: string) => void;\n}\n\nexport const logError = (logger: Logger, e: Error): void => {\n logger.error(e.message);\n const stack = e.stack;\n if (stack) {\n logger.error(stack);\n }\n};\n\n/**\n * Builds SASL configuration for Kafka client authentication\n */\nconst buildSaslConfig = (\n logger: Logger,\n args: KafkaClientConfig,\n): SASLOptions | undefined => {\n const mechanism = args.saslMechanism ? args.saslMechanism.toLowerCase() : \"\";\n switch (mechanism) {\n case \"plain\":\n case \"scram-sha-256\":\n case \"scram-sha-512\":\n return {\n mechanism: mechanism,\n username: args.saslUsername || \"\",\n password: args.saslPassword || \"\",\n };\n default:\n logger.warn(`Unsupported SASL mechanism: ${args.saslMechanism}`);\n return undefined;\n }\n};\n\n/**\n * Dynamically creates a KafkaJS client configured with provided settings.\n * Use this to construct producers/consumers with custom options.\n */\nexport const getKafkaClient = async (\n cfg: KafkaClientConfig,\n logger: Logger,\n): Promise<Kafka> => {\n const brokers = parseBrokerString(cfg.broker || \"\");\n if (brokers.length === 0) {\n throw new Error(`No valid broker addresses found in: \"${cfg.broker}\"`);\n }\n\n logger.log(`Creating Kafka client with brokers: ${brokers.join(\", \")}`);\n logger.log(`Security protocol: ${cfg.securityProtocol || \"plaintext\"}`);\n logger.log(`Client ID: ${cfg.clientId}`);\n\n const saslConfig = buildSaslConfig(logger, cfg);\n\n return new Kafka({\n kafkaJS: {\n clientId: cfg.clientId,\n brokers,\n ssl: cfg.securityProtocol === \"SASL_SSL\",\n ...(saslConfig && { sasl: saslConfig }),\n retry: {\n initialRetryTime: RETRY_INITIAL_TIME_MS,\n maxRetryTime: MAX_RETRY_TIME_MS,\n retries: MAX_RETRIES,\n },\n },\n });\n};\n"],"mappings":"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","names":["ts","factory","process","transform","ts","ts","ts","ts","t","ts","ts","ts","ts","ts","factory","ts","factory","ts","factory"]}