@tailor-platform/sdk 2.3.0 → 2.4.0

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.
Files changed (102) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/README.md +1 -1
  3. package/dist/{application-F-nl107y.mjs → application-C8a0UJ-z.mjs} +201 -149
  4. package/dist/application-C8a0UJ-z.mjs.map +1 -0
  5. package/dist/application-D4zOiLLa.mjs +3 -0
  6. package/dist/cli/commands/tailordb/migrate/diff-calculator.d.mts +4 -4
  7. package/dist/cli/commands/tailordb/migrate/generate.d.mts +3 -3
  8. package/dist/cli/commands/tailordb/migrate/snapshot.d.mts +5 -5
  9. package/dist/cli/commands/tailordb/truncate.d.mts +2 -2
  10. package/dist/cli/lib.mjs +2 -2
  11. package/dist/cli/lib.mjs.map +1 -1
  12. package/dist/cli/main.mjs +174 -106
  13. package/dist/cli/main.mjs.map +1 -1
  14. package/dist/cli/ts-hook.mjs +3 -1
  15. package/dist/completion/zsh-worker.zsh +19 -11
  16. package/dist/configure/config/index.d.mts +1 -1
  17. package/dist/configure/index.d.mts +2 -1
  18. package/dist/configure/index.mjs +2 -2
  19. package/dist/configure/index.mjs.map +1 -1
  20. package/dist/configure/services/aigateway/index.d.mts +5 -4
  21. package/dist/configure/services/aigateway/types.d.mts +6 -1
  22. package/dist/configure/services/auth/types.d.mts +2 -2
  23. package/dist/configure/services/tailordb/permission.d.mts +1 -1
  24. package/dist/configure/services/tailordb/schema.d.mts +1 -1
  25. package/dist/configure/services/tailordb/types.d.mts +7 -4
  26. package/dist/configure/types/auth-namespace-name.d.mts +18 -0
  27. package/dist/{crashreport-CINZ5dVN.mjs → crashreport-Cd4TqfZq.mjs} +1 -1
  28. package/dist/{crashreport-CIIfLnoO.mjs → crashreport-Q0pDAlrj.mjs} +8 -4
  29. package/dist/{crashreport-CIIfLnoO.mjs.map → crashreport-Q0pDAlrj.mjs.map} +1 -1
  30. package/dist/{errors-BVb6vYGy.mjs → errors-Bxut5_Sy.mjs} +2 -2
  31. package/dist/{errors-BVb6vYGy.mjs.map → errors-Bxut5_Sy.mjs.map} +1 -1
  32. package/dist/file-BUcmVIH2.mjs.map +1 -1
  33. package/dist/kysely/index.mjs +2 -1
  34. package/dist/kysely/index.mjs.map +1 -1
  35. package/dist/{logger-DSdExfor.mjs → logger-D0bEznPv.mjs} +9 -5
  36. package/dist/{logger-DSdExfor.mjs.map → logger-D0bEznPv.mjs.map} +1 -1
  37. package/dist/package-json-8b0O9TlX.mjs.map +1 -1
  38. package/dist/plugin/builtin/enum-constants/index.d.mts +1 -1
  39. package/dist/plugin/builtin/enum-constants/index.mjs +5 -5
  40. package/dist/plugin/builtin/enum-constants/index.mjs.map +1 -1
  41. package/dist/plugin/builtin/file-utils/index.d.mts +1 -1
  42. package/dist/plugin/builtin/file-utils/index.mjs +14 -11
  43. package/dist/plugin/builtin/file-utils/index.mjs.map +1 -1
  44. package/dist/plugin/builtin/kysely-type/index.d.mts +1 -1
  45. package/dist/plugin/builtin/kysely-type/index.mjs +9 -9
  46. package/dist/plugin/builtin/kysely-type/index.mjs.map +1 -1
  47. package/dist/plugin/builtin/seed/index.mjs +1 -1
  48. package/dist/plugin/builtin/seed/seed-type-processor.d.mts +4 -4
  49. package/dist/plugin/get-generated-type.d.mts +4 -4
  50. package/dist/plugin/index.mjs +13 -13
  51. package/dist/plugin/index.mjs.map +1 -1
  52. package/dist/plugin/types.d.mts +2 -2
  53. package/dist/plugin/with-context.d.mts +1 -1
  54. package/dist/{register-ts-hook-ClI226n2.mjs → register-ts-hook-Vqjza10T.mjs} +552 -416
  55. package/dist/register-ts-hook-Vqjza10T.mjs.map +1 -0
  56. package/dist/{repl-editor-BCozyiNq.mjs → repl-editor-F9LotMNx.mjs} +3 -2
  57. package/dist/{repl-editor-BCozyiNq.mjs.map → repl-editor-F9LotMNx.mjs.map} +1 -1
  58. package/dist/runtime/file.d.mts +14 -14
  59. package/dist/{schema--xYWRGfe.mjs → schema-D4TC4BC3.mjs} +4 -3
  60. package/dist/schema-D4TC4BC3.mjs.map +1 -0
  61. package/dist/seed/index.d.mts +4 -4
  62. package/dist/seed/index.mjs +3 -3
  63. package/dist/seed/index.mjs.map +1 -1
  64. package/dist/{seed-xqM9WIHP.mjs → seed-Cibjmtry.mjs} +46 -40
  65. package/dist/seed-Cibjmtry.mjs.map +1 -0
  66. package/dist/{service-C_WpbKHu.mjs → service-2grcAOCJ.mjs} +24 -24
  67. package/dist/service-2grcAOCJ.mjs.map +1 -0
  68. package/dist/service-CaBPNDIZ.mjs +3 -0
  69. package/dist/{service-hZskxZmg.mjs → service-LTfp03ZZ.mjs} +7 -5
  70. package/dist/{service-hZskxZmg.mjs.map → service-LTfp03ZZ.mjs.map} +1 -1
  71. package/dist/types/aigateway.generated.d.mts +2 -2
  72. package/dist/types/auth.generated.d.mts +3 -3
  73. package/dist/types/executor.generated.d.mts +1 -1
  74. package/dist/types/tailordb.generated.d.mts +12 -12
  75. package/dist/utils/test/index.d.mts +4 -4
  76. package/dist/utils/test/index.mjs +4 -4
  77. package/dist/utils/test/index.mjs.map +1 -1
  78. package/dist/vitest/index.mjs +13 -7
  79. package/dist/vitest/index.mjs.map +1 -1
  80. package/dist/vitest/mocks/file.d.mts +1 -1
  81. package/docs/cli/application.md +3 -1
  82. package/docs/cli/function.md +17 -13
  83. package/docs/cli/tailordb.md +30 -30
  84. package/docs/cli/workspace.md +2 -2
  85. package/docs/cli-reference.md +21 -21
  86. package/docs/configuration.md +2 -2
  87. package/docs/migration/v2.md +4 -4
  88. package/docs/migration/v3.md +41 -0
  89. package/docs/quickstart.md +1 -1
  90. package/docs/services/aigateway.md +33 -9
  91. package/docs/services/executor.md +5 -1
  92. package/docs/services/tailordb-migration.md +47 -47
  93. package/docs/services/tailordb.md +7 -7
  94. package/docs/testing.md +1 -1
  95. package/package.json +6 -6
  96. package/dist/application-BZfk4HKm.mjs +0 -3
  97. package/dist/application-F-nl107y.mjs.map +0 -1
  98. package/dist/register-ts-hook-ClI226n2.mjs.map +0 -1
  99. package/dist/schema--xYWRGfe.mjs.map +0 -1
  100. package/dist/seed-xqM9WIHP.mjs.map +0 -1
  101. package/dist/service-C_WpbKHu.mjs.map +0 -1
  102. package/dist/service-D1RCdzIL.mjs +0 -3
@@ -1 +1 @@
1
- {"version":3,"file":"logger-DSdExfor.mjs","names":[],"sources":["../../shared/src/color.ts","../src/cli/shared/ascii-table.ts","../src/cli/shared/parse-boolean.ts","../src/cli/shared/logger.ts"],"sourcesContent":["import { stripVTControlCharacters, styleText } from \"node:util\";\n\n/** Applies a style to text */\nexport type StyleFn = (text: string) => string;\n\ntype StyleName = Exclude<Parameters<typeof styleText>[0], readonly unknown[] | unknown[]>;\n\nconst style =\n (name: StyleName): StyleFn =>\n (text) =>\n styleText(name, text, { validateStream: false });\n\n/**\n * Style functions by name, so call sites read `color.bold(text)`. Styling is\n * always applied; `renderFor` drops it again when the destination stream has no\n * color support. Add a name here when a package needs one that is not listed.\n */\nexport const color = {\n bold: style(\"bold\"),\n dim: style(\"dim\"),\n italic: style(\"italic\"),\n gray: style(\"gray\"),\n white: style(\"white\"),\n red: style(\"red\"),\n green: style(\"green\"),\n yellow: style(\"yellow\"),\n cyan: style(\"cyan\"),\n magenta: style(\"magenta\"),\n redBright: style(\"redBright\"),\n greenBright: style(\"greenBright\"),\n cyanBright: style(\"cyanBright\"),\n};\n\n// Node's rules for whether a destination gets colors, applied by hand. Asking\n// styleText instead would be shorter but only correct on Node: Bun ignores both\n// the stream option and NO_COLOR (reproduced on 1.3.14), so it reports every\n// destination as color-capable and escapes end up in redirected output.\n//\n// FORCE_COLOR decides on its own when set, which is how CI keeps colors through\n// a pipe. NO_COLOR counts as set at any non-empty value, \"0\" included.\nconst supportsColor = (stream: NodeJS.WriteStream): boolean => {\n const forced = process.env.FORCE_COLOR;\n if (forced !== undefined) return forced !== \"0\" && forced !== \"false\";\n if (process.env.NODE_DISABLE_COLORS !== undefined) return false;\n if ((process.env.NO_COLOR ?? \"\") !== \"\") return false;\n if (process.env.TERM === \"dumb\") return false;\n return stream.isTTY === true;\n};\n\n/**\n * Prepares styled text for the stream it is written to.\n * @param stream - Stream the text is written to\n * @param text - Styled text\n * @returns Text with styling removed when the stream has no color support\n */\nexport function renderFor(stream: NodeJS.WriteStream, text: string): string {\n return supportsColor(stream) ? text : stripVTControlCharacters(text);\n}\n","import { eastAsianWidth } from \"get-east-asian-width\";\n\n// eslint-disable-next-line no-control-regex\nconst ANSI_ESCAPE_PATTERN = /\\x1b\\[[0-9;]*m/g;\nconst CARRIAGE_RETURN_PATTERN = /\\r\\n?/g;\n\nconst graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: \"grapheme\" });\n\nexport interface AsciiTableConfig {\n /** Suppress horizontal lines between rows, keeping only the outer border. */\n singleLine?: boolean;\n /** Decide whether to draw the horizontal line at `lineIndex` (range `[0, rowCount]` inclusive). */\n drawHorizontalLine?: (lineIndex: number, rowCount: number) => boolean;\n}\n\ninterface CellLine {\n text: string;\n width: number;\n}\n\nfunction maxOf(values: number[], fallback = 0): number {\n return values.reduce((max, value) => (value > max ? value : max), fallback);\n}\n\nconst TAB_WIDTH = 8;\n\nfunction isStrippableControlCharacter(char: string): boolean {\n const codePoint = char.codePointAt(0) ?? 0;\n if (char === \"\\n\") {\n return false;\n }\n return codePoint <= 0x1f || codePoint === 0x7f;\n}\n\n// Only SGR (color/style) escape sequences are meant to survive; a bare ESC\n// that isn't part of a recognized SGR sequence (e.g. a screen-clear CSI\n// sequence, or a BEL-terminated OSC sequence) is treated like any other\n// control character below and stripped, rather than passed through to the\n// terminal or left with its terminator removed.\nfunction normalizeControlCharacters(value: string): string {\n const sgrSequences = value.match(ANSI_ESCAPE_PATTERN) ?? [];\n return value\n .split(ANSI_ESCAPE_PATTERN)\n .map((segment) => {\n const chars: string[] = [];\n for (const char of segment) {\n if (char === \"\\t\") {\n chars.push(\" \".repeat(TAB_WIDTH));\n } else if (!isStrippableControlCharacter(char)) {\n chars.push(char);\n }\n }\n return chars.join(\"\");\n })\n .reduce((result, segment, i) => result + segment + (sgrSequences[i] ?? \"\"), \"\");\n}\n\nfunction sanitizeCell(cell: unknown): string {\n return normalizeControlCharacters(String(cell ?? \"\").replace(CARRIAGE_RETURN_PATTERN, \"\\n\"));\n}\n\n// Clusters made up entirely of non-printing code points (lone joiners,\n// variation selectors, combining marks, etc.) render with no visible glyph.\nconst ZERO_WIDTH_CLUSTER_PATTERN =\n /^(?:\\p{Default_Ignorable_Code_Point}|\\p{Control}|\\p{Format}|\\p{Nonspacing_Mark}|\\p{Enclosing_Mark}|\\p{Surrogate})+$/v;\n// RGI_Emoji covers flags, keycaps, and VS16-forced presentation sequences,\n// which render as 2 columns in terminals even though their first code point\n// alone would measure as narrow/neutral.\nconst RGI_EMOJI_PATTERN = /^\\p{RGI_Emoji}$/v;\n\nfunction displayWidth(value: string): number {\n let width = 0;\n for (const { segment } of graphemeSegmenter.segment(value.replace(ANSI_ESCAPE_PATTERN, \"\"))) {\n if (ZERO_WIDTH_CLUSTER_PATTERN.test(segment)) {\n continue;\n }\n if (RGI_EMOJI_PATTERN.test(segment)) {\n width += 2;\n continue;\n }\n const codePoint = segment.codePointAt(0);\n width += codePoint === undefined ? 0 : eastAsianWidth(codePoint);\n }\n return width;\n}\n\nfunction toCellLines(cell: string): CellLine[] {\n return cell.split(\"\\n\").map((text) => ({ text, width: displayWidth(text) }));\n}\n\nfunction padCell(cellLine: CellLine, width: number): string {\n return cellLine.text + \" \".repeat(Math.max(0, width - cellLine.width));\n}\n\nfunction renderBorder(left: string, join: string, right: string, columnWidths: number[]): string {\n return left + columnWidths.map((width) => \"─\".repeat(width + 2)).join(join) + right;\n}\n\nfunction validateConsistentColumnCount(rows: string[][]): void {\n const columnCount = rows[0]?.length;\n if (columnCount === undefined) {\n return;\n }\n rows.forEach((row, index) => {\n if (row.length !== columnCount) {\n throw new Error(\n `renderTable: all rows must have the same number of columns (expected ${columnCount}, row ${index} has ${row.length}).`,\n );\n }\n });\n}\n\n/**\n * Renders a 2D array of values as a table using single-line Unicode box-drawing borders.\n * Column widths account for East Asian wide characters (measured per grapheme cluster,\n * so combining marks and ZWJ emoji sequences aren't overcounted, non-printing clusters\n * such as a lone joiner or combining mark measure as 0, and flags, keycaps, and\n * VS16-forced emoji presentation are measured as 2 columns) and strip ANSI SGR (color/style)\n * escape codes before measuring. Use this instead of importing a table-rendering package\n * directly.\n * @param data - Table rows; every row must have the same number of columns. Each cell is\n * stringified (`null`/`undefined` become an empty string rather than the literal text\n * \"null\"/\"undefined\"), may contain embedded newlines, has `\\r`/`\\r\\n` normalized to `\\n`,\n * has tabs expanded to spaces, and has other control characters stripped.\n * @param config - Rendering options\n * @returns The rendered table terminated with a trailing newline, or `\"\"` when there are no\n * rows or no columns to display\n */\nexport function renderTable(data: unknown[][], config: AsciiTableConfig = {}): string {\n const rows = data.map((row) => row.map(sanitizeCell));\n validateConsistentColumnCount(rows);\n\n const rowCount = rows.length;\n const columnCount = rows[0]?.length ?? 0;\n if (rowCount === 0 || columnCount === 0) {\n return \"\";\n }\n\n const rowsCellLines = rows.map((row) =>\n Array.from({ length: columnCount }, (_, col) => toCellLines(row[col] ?? \"\")),\n );\n const columnWidths = Array.from({ length: columnCount }, (_, col) =>\n maxOf(rowsCellLines.map((row) => maxOf((row[col] ?? []).map((line) => line.width)))),\n );\n\n const shouldDrawLine = (lineIndex: number): boolean =>\n config.singleLine\n ? lineIndex === 0 || lineIndex === rowCount\n : (config.drawHorizontalLine ?? (() => true))(lineIndex, rowCount);\n\n const lines: string[] = [];\n if (shouldDrawLine(0)) {\n lines.push(renderBorder(\"┌\", \"┬\", \"┐\", columnWidths));\n }\n\n rowsCellLines.forEach((cellLines, rowIndex) => {\n const rowHeight = maxOf(\n cellLines.map((columnLines) => columnLines.length),\n 1,\n );\n for (let line = 0; line < rowHeight; line++) {\n const cells = cellLines.map((columnLines, col) =>\n padCell(columnLines[line] ?? { text: \"\", width: 0 }, columnWidths[col] ?? 0),\n );\n lines.push(`│ ${cells.join(\" │ \")} │`);\n }\n if (rowIndex < rowCount - 1 && shouldDrawLine(rowIndex + 1)) {\n lines.push(renderBorder(\"├\", \"┼\", \"┤\", columnWidths));\n }\n });\n\n if (shouldDrawLine(rowCount)) {\n lines.push(renderBorder(\"└\", \"┴\", \"┘\", columnWidths));\n }\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n","const TRUTHY_VALUES = new Set([\"true\", \"t\", \"yes\", \"y\", \"on\", \"1\"]);\nconst FALSY_VALUES = new Set([\"false\", \"f\", \"no\", \"n\", \"off\", \"0\"]);\n\n/**\n * Parse a string value as a boolean.\n *\n * Recognized values (case-insensitive, trimmed) follow Python's\n * `distutils.util.strtobool` convention:\n * - truthy: `true, t, yes, y, on, 1`\n * - falsy: `false, f, no, n, off, 0`\n *\n * Undefined, empty strings, and unrecognized values return `undefined` so\n * that callers can fall back to their own defaults.\n * @param value - The input string (e.g. an environment variable or CLI flag value)\n * @returns `true`, `false`, or `undefined` when the value is unset or unrecognized\n */\nexport function parseBoolean(value: string | undefined): boolean | undefined {\n if (value === undefined) return undefined;\n const normalized = value.trim().toLowerCase();\n if (normalized === \"\") return undefined;\n if (TRUTHY_VALUES.has(normalized)) return true;\n if (FALSY_VALUES.has(normalized)) return false;\n return undefined;\n}\n","import { formatWithOptions, type InspectOptions } from \"node:util\";\nimport { color, renderFor } from \"@tailor-platform/shared/color\";\nimport { formatDistanceToNowStrict } from \"date-fns\";\nimport { renderTable } from \"./ascii-table\";\nimport { parseBoolean } from \"./parse-boolean\";\n\n/**\n * Error thrown when a prompt is attempted in a non-interactive environment\n */\nexport class CIPromptError extends Error {\n constructor(message?: string) {\n super(\n message ??\n \"Interactive prompts are not available in this environment. Provide the required options explicitly.\",\n );\n this.name = \"CIPromptError\";\n }\n}\n\n/**\n * Semantic style functions for inline text styling\n */\nexport const styles = {\n // Status colors\n success: color.green,\n error: color.red,\n warning: color.yellow,\n info: color.cyan,\n\n // Action colors (for change sets)\n create: color.green,\n update: color.yellow,\n delete: color.red,\n replace: color.magenta,\n unchanged: color.gray,\n\n // Emphasis\n bold: color.bold,\n dim: color.gray,\n highlight: color.cyanBright,\n successBright: color.greenBright,\n errorBright: color.redBright,\n\n // Resource types\n resourceType: color.bold,\n resourceName: color.cyan,\n\n // File paths\n path: color.cyan,\n\n // Values\n value: color.white,\n placeholder: (text: string) => color.italic(color.gray(text)),\n};\n\n/**\n * Standardized symbols for CLI output\n */\nexport const symbols = {\n success: styles.success(\"\\u2713\"),\n error: styles.error(\"\\u2716\"),\n warning: styles.warning(\"\\u26a0\"),\n info: styles.info(\"i\"),\n create: styles.create(\"+\"),\n update: styles.update(\"~\"),\n delete: styles.delete(\"-\"),\n replace: styles.replace(\"\\u00b1\"),\n bullet: styles.dim(\"\\u2022\"),\n arrow: styles.dim(\"\\u2192\"),\n};\n\n/**\n * Log output modes\n */\nexport type LogMode = \"default\" | \"stream\" | \"plain\";\n\nexport interface LogOptions {\n /** Output mode (default: \"default\") */\n mode?: LogMode;\n /** Number of spaces to indent the entire line (default: 0) */\n indent?: number;\n}\n\n/** Field transformer function. null excludes the field from table output. */\nexport type FieldTransformer = ((value: unknown, item: object) => string) | null;\n\nexport interface OutOptions {\n /** Table display field transform/exclude settings. Only applied in table mode (not JSON). */\n display?: Record<string, FieldTransformer>;\n\n /** Show null values in table output (default: false) */\n showNull?: boolean;\n}\n\n// In JSON mode, all logs go to stderr to keep stdout clean for JSON data\nlet _jsonMode = false;\n\n// Type icons for log output\nconst TYPE_ICONS: Record<string, string> = {\n info: \"ℹ\",\n success: \"✔\",\n warn: \"⚠\",\n error: \"✖\",\n debug: \"⚙\",\n trace: \"→\",\n log: \"\",\n};\n\n// Color functions for icon and message text\nconst TYPE_COLORS: Record<string, (text: string) => string> = {\n info: styles.info,\n success: styles.success,\n warn: styles.warning,\n error: styles.error,\n debug: styles.dim,\n trace: styles.dim,\n log: (text) => text,\n};\n\ninterface FormatLogLineOptions {\n mode: string;\n indent: number;\n type: string;\n message: string;\n timestamp?: string;\n}\n\n/**\n * Formats a log line with the appropriate prefix and indentation\n * @param opts - Formatting options\n * @returns Formatted log line\n */\nexport function formatLogLine(opts: FormatLogLineOptions): string {\n const { mode, indent, type, message, timestamp } = opts;\n const indentPrefix = indent > 0 ? \" \".repeat(indent) : \"\";\n const colorFn = TYPE_COLORS[type] || ((text: string) => text);\n\n // Plain mode: color only, no icon, no timestamp\n if (mode === \"plain\") {\n return `${indentPrefix}${colorFn(message)}\\n`;\n }\n\n // Default/Stream mode: with icon and color\n const icon = TYPE_ICONS[type] || \"\";\n const prefix = icon ? `${icon} ` : \"\";\n const coloredOutput = colorFn(`${prefix}${message}`);\n const timestampPrefix = timestamp ?? \"\";\n\n return `${indentPrefix}${timestampPrefix}${coloredOutput}\\n`;\n}\n\n/**\n * Writes a formatted log line to stderr.\n * @param type - Log type (info, success, warn, error, log)\n * @param message - Log message\n * @param opts - Log options (mode and indent)\n */\nfunction writeLog(type: string, message: string, opts?: LogOptions): void {\n const mode = opts?.mode ?? \"default\";\n const indent = opts?.indent ?? 0;\n const inspectOpts: InspectOptions = {\n breakLength: process.stdout.columns || 80,\n };\n const formattedMessage = formatWithOptions(inspectOpts, message);\n const timestamp = mode === \"stream\" ? `${new Date().toLocaleTimeString()} ` : \"\";\n const output = formatLogLine({ mode, indent, type, message: formattedMessage, timestamp });\n process.stderr.write(renderFor(process.stderr, output));\n}\n\nexport const logger = {\n get jsonMode(): boolean {\n return _jsonMode;\n },\n set jsonMode(value: boolean) {\n _jsonMode = value;\n },\n\n info(message: string, opts?: LogOptions): void {\n writeLog(\"info\", message, opts);\n },\n\n success(message: string, opts?: LogOptions): void {\n writeLog(\"success\", message, opts);\n },\n\n warn(message: string, opts?: LogOptions): void {\n writeLog(\"warn\", message, opts);\n },\n\n error(message: string, opts?: LogOptions): void {\n writeLog(\"error\", message, opts);\n },\n\n log(message: string): void {\n writeLog(\"log\", message, { mode: \"plain\" });\n },\n\n newline(): void {\n process.stderr.write(\"\\n\");\n },\n\n debug(message: string): void {\n if (parseBoolean(process.env.DEBUG) === true) {\n writeLog(\"log\", styles.dim(message), { mode: \"plain\" });\n }\n },\n\n out(data: string | object | object[], options?: OutOptions): void {\n if (typeof data === \"string\") {\n process.stdout.write(renderFor(process.stdout, data.endsWith(\"\\n\") ? data : data + \"\\n\"));\n return;\n }\n\n if (this.jsonMode) {\n // eslint-disable-next-line no-restricted-syntax\n console.log(JSON.stringify(data));\n return;\n }\n\n const display = options?.display;\n\n // Helper to format a value for table display\n const formatValue = (value: unknown, pretty = false): string => {\n if (options?.showNull && value === null) return \"NULL\";\n if (value === null || value === undefined) return \"N/A\";\n if (value instanceof Date) {\n return formatDistanceToNowStrict(value, { addSuffix: true });\n }\n if (typeof value === \"object\") {\n return pretty ? JSON.stringify(value, null, 2) : JSON.stringify(value);\n }\n return String(value);\n };\n\n // Helper to check if field should be excluded\n const isExcluded = (key: string): boolean => {\n return display !== undefined && key in display && display[key] === null;\n };\n\n // Helper to apply transformer or default formatting\n const transformValue = (key: string, value: unknown, item: object, pretty = false): string => {\n if (display && key in display) {\n const transformer = display[key];\n if (transformer) {\n return transformer(value, item);\n }\n }\n return formatValue(value, pretty);\n };\n\n if (!Array.isArray(data)) {\n const entries = Object.entries(data).filter(([key]) => !isExcluded(key));\n const formattedEntries = entries.map(([key, value]) => [\n key,\n transformValue(key, value, data, true),\n ]);\n const t = renderTable(formattedEntries, { singleLine: false });\n process.stdout.write(renderFor(process.stdout, t));\n return;\n }\n\n if (data.length === 0) {\n return;\n }\n\n const allHeaders = Array.from(new Set(data.flatMap((item) => Object.keys(item))));\n const headers = allHeaders.filter((h) => !isExcluded(h));\n if (headers.length === 0) {\n return;\n }\n const rows = data.map((item) =>\n headers.map((header) =>\n transformValue(header, (item as Record<string, unknown>)[header], item),\n ),\n );\n\n const t = renderTable([headers, ...rows], {\n drawHorizontalLine: (lineIndex, rowCount) => {\n return lineIndex === 0 || lineIndex === 1 || lineIndex === rowCount;\n },\n });\n process.stdout.write(renderFor(process.stdout, t));\n },\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"logger-D0bEznPv.mjs","names":[],"sources":["../../shared/src/color.ts","../src/cli/shared/ascii-table.ts","../src/cli/shared/parse-boolean.ts","../src/cli/shared/logger.ts"],"sourcesContent":["import { stripVTControlCharacters, styleText } from \"node:util\";\n\n/** Applies a style to text */\nexport type StyleFn = (text: string) => string;\n\ntype StyleName = Exclude<Parameters<typeof styleText>[0], readonly unknown[] | unknown[]>;\n\nconst style =\n (name: StyleName): StyleFn =>\n (text) =>\n styleText(name, text, { validateStream: false });\n\n/**\n * Style functions by name, so call sites read `color.bold(text)`. Styling is\n * always applied; `renderFor` drops it again when the destination stream has no\n * color support. Add a name here when a package needs one that is not listed.\n */\nexport const color = {\n bold: style(\"bold\"),\n dim: style(\"dim\"),\n italic: style(\"italic\"),\n gray: style(\"gray\"),\n white: style(\"white\"),\n red: style(\"red\"),\n green: style(\"green\"),\n yellow: style(\"yellow\"),\n cyan: style(\"cyan\"),\n magenta: style(\"magenta\"),\n redBright: style(\"redBright\"),\n greenBright: style(\"greenBright\"),\n cyanBright: style(\"cyanBright\"),\n};\n\n// Node's rules for whether a destination gets colors, applied by hand. Asking\n// styleText instead would be shorter but only correct on Node: Bun ignores both\n// the stream option and NO_COLOR (reproduced on 1.3.14), so it reports every\n// destination as color-capable and escapes end up in redirected output.\n//\n// FORCE_COLOR decides on its own when set, which is how CI keeps colors through\n// a pipe. NO_COLOR counts as set at any non-empty value, \"0\" included.\nconst supportsColor = (stream: NodeJS.WriteStream): boolean => {\n const forced = process.env.FORCE_COLOR;\n if (forced !== undefined) return forced !== \"0\" && forced !== \"false\";\n if (process.env.NODE_DISABLE_COLORS !== undefined) return false;\n if ((process.env.NO_COLOR ?? \"\") !== \"\") return false;\n if (process.env.TERM === \"dumb\") return false;\n return stream.isTTY === true;\n};\n\n/**\n * Prepares styled text for the stream it is written to.\n * @param stream - Stream the text is written to\n * @param text - Styled text\n * @returns Text with styling removed when the stream has no color support\n */\nexport function renderFor(stream: NodeJS.WriteStream, text: string): string {\n return supportsColor(stream) ? text : stripVTControlCharacters(text);\n}\n","import { eastAsianWidth } from \"get-east-asian-width\";\n\n// eslint-disable-next-line no-control-regex\nconst ANSI_ESCAPE_PATTERN = /\\x1b\\[[0-9;]*m/g;\nconst CARRIAGE_RETURN_PATTERN = /\\r\\n?/g;\n\nconst graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: \"grapheme\" });\n\nexport interface AsciiTableConfig {\n /** Suppress horizontal lines between rows, keeping only the outer border. */\n singleLine?: boolean;\n /** Decide whether to draw the horizontal line at `lineIndex` (range `[0, rowCount]` inclusive). */\n drawHorizontalLine?: (lineIndex: number, rowCount: number) => boolean;\n}\n\ninterface CellLine {\n text: string;\n width: number;\n}\n\nfunction maxOf(values: number[], fallback = 0): number {\n return values.reduce((max, value) => (value > max ? value : max), fallback);\n}\n\nconst TAB_WIDTH = 8;\n\nfunction isStrippableControlCharacter(char: string): boolean {\n const codePoint = char.codePointAt(0) ?? 0;\n if (char === \"\\n\") {\n return false;\n }\n return codePoint <= 0x1f || codePoint === 0x7f;\n}\n\n// Only SGR (color/style) escape sequences are meant to survive; a bare ESC\n// that isn't part of a recognized SGR sequence (e.g. a screen-clear CSI\n// sequence, or a BEL-terminated OSC sequence) is treated like any other\n// control character below and stripped, rather than passed through to the\n// terminal or left with its terminator removed.\nfunction normalizeControlCharacters(value: string): string {\n const sgrSequences = value.match(ANSI_ESCAPE_PATTERN) ?? [];\n return value\n .split(ANSI_ESCAPE_PATTERN)\n .map((segment) => {\n const chars: string[] = [];\n for (const char of segment) {\n if (char === \"\\t\") {\n chars.push(\" \".repeat(TAB_WIDTH));\n } else if (!isStrippableControlCharacter(char)) {\n chars.push(char);\n }\n }\n return chars.join(\"\");\n })\n .reduce((result, segment, i) => result + segment + (sgrSequences[i] ?? \"\"), \"\");\n}\n\nfunction sanitizeCell(cell: unknown): string {\n return normalizeControlCharacters(String(cell ?? \"\").replace(CARRIAGE_RETURN_PATTERN, \"\\n\"));\n}\n\n// Clusters made up entirely of non-printing code points (lone joiners,\n// variation selectors, combining marks, etc.) render with no visible glyph.\nconst ZERO_WIDTH_CLUSTER_PATTERN =\n /^(?:\\p{Default_Ignorable_Code_Point}|\\p{Control}|\\p{Format}|\\p{Nonspacing_Mark}|\\p{Enclosing_Mark}|\\p{Surrogate})+$/v;\n// RGI_Emoji covers flags, keycaps, and VS16-forced presentation sequences,\n// which render as 2 columns in terminals even though their first code point\n// alone would measure as narrow/neutral.\nconst RGI_EMOJI_PATTERN = /^\\p{RGI_Emoji}$/v;\n\nfunction displayWidth(value: string): number {\n let width = 0;\n for (const { segment } of graphemeSegmenter.segment(value.replace(ANSI_ESCAPE_PATTERN, \"\"))) {\n if (ZERO_WIDTH_CLUSTER_PATTERN.test(segment)) {\n continue;\n }\n if (RGI_EMOJI_PATTERN.test(segment)) {\n width += 2;\n continue;\n }\n const codePoint = segment.codePointAt(0);\n width += codePoint === undefined ? 0 : eastAsianWidth(codePoint);\n }\n return width;\n}\n\nfunction toCellLines(cell: string): CellLine[] {\n return cell.split(\"\\n\").map((text) => ({ text, width: displayWidth(text) }));\n}\n\nfunction padCell(cellLine: CellLine, width: number): string {\n return cellLine.text + \" \".repeat(Math.max(0, width - cellLine.width));\n}\n\nfunction renderBorder(left: string, join: string, right: string, columnWidths: number[]): string {\n return left + columnWidths.map((width) => \"─\".repeat(width + 2)).join(join) + right;\n}\n\nfunction validateConsistentColumnCount(rows: string[][]): void {\n const columnCount = rows[0]?.length;\n if (columnCount === undefined) {\n return;\n }\n rows.forEach((row, index) => {\n if (row.length !== columnCount) {\n throw new Error(\n `renderTable: all rows must have the same number of columns (expected ${columnCount}, row ${index} has ${row.length}).`,\n );\n }\n });\n}\n\n/**\n * Renders a 2D array of values as a table using single-line Unicode box-drawing borders.\n * Column widths account for East Asian wide characters (measured per grapheme cluster,\n * so combining marks and ZWJ emoji sequences aren't overcounted, non-printing clusters\n * such as a lone joiner or combining mark measure as 0, and flags, keycaps, and\n * VS16-forced emoji presentation are measured as 2 columns) and strip ANSI SGR (color/style)\n * escape codes before measuring. Use this instead of importing a table-rendering package\n * directly.\n * @param data - Table rows; every row must have the same number of columns. Each cell is\n * stringified (`null`/`undefined` become an empty string rather than the literal text\n * \"null\"/\"undefined\"), may contain embedded newlines, has `\\r`/`\\r\\n` normalized to `\\n`,\n * has tabs expanded to spaces, and has other control characters stripped.\n * @param config - Rendering options\n * @returns The rendered table terminated with a trailing newline, or `\"\"` when there are no\n * rows or no columns to display\n */\nexport function renderTable(data: unknown[][], config: AsciiTableConfig = {}): string {\n const rows = data.map((row) => row.map(sanitizeCell));\n validateConsistentColumnCount(rows);\n\n const rowCount = rows.length;\n const columnCount = rows[0]?.length ?? 0;\n if (rowCount === 0 || columnCount === 0) {\n return \"\";\n }\n\n const rowsCellLines = rows.map((row) =>\n Array.from({ length: columnCount }, (_, col) => toCellLines(row[col] ?? \"\")),\n );\n const columnWidths = Array.from({ length: columnCount }, (_, col) =>\n maxOf(rowsCellLines.map((row) => maxOf((row[col] ?? []).map((line) => line.width)))),\n );\n\n const shouldDrawLine = (lineIndex: number): boolean =>\n config.singleLine\n ? lineIndex === 0 || lineIndex === rowCount\n : (config.drawHorizontalLine ?? (() => true))(lineIndex, rowCount);\n\n const lines: string[] = [];\n if (shouldDrawLine(0)) {\n lines.push(renderBorder(\"┌\", \"┬\", \"┐\", columnWidths));\n }\n\n rowsCellLines.forEach((cellLines, rowIndex) => {\n const rowHeight = maxOf(\n cellLines.map((columnLines) => columnLines.length),\n 1,\n );\n for (let line = 0; line < rowHeight; line++) {\n const cells = cellLines.map((columnLines, col) =>\n padCell(columnLines[line] ?? { text: \"\", width: 0 }, columnWidths[col] ?? 0),\n );\n lines.push(`│ ${cells.join(\" │ \")} │`);\n }\n if (rowIndex < rowCount - 1 && shouldDrawLine(rowIndex + 1)) {\n lines.push(renderBorder(\"├\", \"┼\", \"┤\", columnWidths));\n }\n });\n\n if (shouldDrawLine(rowCount)) {\n lines.push(renderBorder(\"└\", \"┴\", \"┘\", columnWidths));\n }\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n","const TRUTHY_VALUES = new Set([\"true\", \"t\", \"yes\", \"y\", \"on\", \"1\"]);\nconst FALSY_VALUES = new Set([\"false\", \"f\", \"no\", \"n\", \"off\", \"0\"]);\n\n/**\n * Parse a string value as a boolean.\n *\n * Recognized values (case-insensitive, trimmed) follow Python's\n * `distutils.util.strtobool` convention:\n * - truthy: `true, t, yes, y, on, 1`\n * - falsy: `false, f, no, n, off, 0`\n *\n * Undefined, empty strings, and unrecognized values return `undefined` so\n * that callers can fall back to their own defaults.\n * @param value - The input string (e.g. an environment variable or CLI flag value)\n * @returns `true`, `false`, or `undefined` when the value is unset or unrecognized\n */\nexport function parseBoolean(value: string | undefined): boolean | undefined {\n if (value === undefined) return undefined;\n const normalized = value.trim().toLowerCase();\n if (normalized === \"\") return undefined;\n if (TRUTHY_VALUES.has(normalized)) return true;\n if (FALSY_VALUES.has(normalized)) return false;\n return undefined;\n}\n","import { formatWithOptions, type InspectOptions } from \"node:util\";\nimport { color, renderFor } from \"@tailor-platform/shared/color\";\nimport { formatDistanceToNowStrict } from \"date-fns\";\nimport { renderTable } from \"./ascii-table\";\nimport { parseBoolean } from \"./parse-boolean\";\n\n/**\n * Error thrown when a prompt is attempted in a non-interactive environment\n */\nexport class CIPromptError extends Error {\n constructor(message?: string) {\n super(\n message ??\n \"Interactive prompts are not available in this environment. Provide the required options explicitly.\",\n );\n this.name = \"CIPromptError\";\n }\n}\n\n/**\n * Semantic style functions for inline text styling\n */\nexport const styles = {\n // Status colors\n success: color.green,\n error: color.red,\n warning: color.yellow,\n info: color.cyan,\n\n // Action colors (for change sets)\n create: color.green,\n update: color.yellow,\n delete: color.red,\n replace: color.magenta,\n unchanged: color.gray,\n\n // Emphasis\n bold: color.bold,\n dim: color.gray,\n highlight: color.cyanBright,\n successBright: color.greenBright,\n errorBright: color.redBright,\n\n // Resource types\n resourceType: color.bold,\n resourceName: color.cyan,\n\n // File paths\n path: color.cyan,\n\n // Values\n value: color.white,\n placeholder: (text: string) => color.italic(color.gray(text)),\n};\n\n/**\n * Standardized symbols for CLI output\n */\nexport const symbols = {\n success: styles.success(\"\\u2713\"),\n error: styles.error(\"\\u2716\"),\n warning: styles.warning(\"\\u26a0\"),\n info: styles.info(\"i\"),\n create: styles.create(\"+\"),\n update: styles.update(\"~\"),\n delete: styles.delete(\"-\"),\n replace: styles.replace(\"\\u00b1\"),\n bullet: styles.dim(\"\\u2022\"),\n arrow: styles.dim(\"\\u2192\"),\n};\n\n/**\n * Log output modes\n */\nexport type LogMode = \"default\" | \"stream\" | \"plain\";\n\nexport interface LogOptions {\n /** Output mode (default: \"default\") */\n mode?: LogMode;\n /** Number of spaces to indent the entire line (default: 0) */\n indent?: number;\n}\n\n/** Field transformer function. null excludes the field from table output. */\nexport type FieldTransformer = ((value: unknown, item: object) => string) | null;\n\nexport interface OutOptions {\n /** Table display field transform/exclude settings. Only applied in table mode (not JSON). */\n display?: Record<string, FieldTransformer>;\n\n /** Show null values in table output (default: false) */\n showNull?: boolean;\n}\n\n// In JSON mode, all logs go to stderr to keep stdout clean for JSON data\nlet _jsonMode = false;\n\n// Type icons for log output\nconst TYPE_ICONS: Record<string, string> = {\n info: \"ℹ\",\n success: \"✔\",\n warn: \"⚠\",\n error: \"✖\",\n debug: \"⚙\",\n trace: \"→\",\n log: \"\",\n};\n\n// Color functions for icon and message text\nconst TYPE_COLORS: Record<string, (text: string) => string> = {\n info: styles.info,\n success: styles.success,\n warn: styles.warning,\n error: styles.error,\n debug: styles.dim,\n trace: styles.dim,\n log: (text) => text,\n};\n\ninterface FormatLogLineOptions {\n mode: string;\n indent: number;\n type: string;\n message: string;\n timestamp?: string;\n}\n\n/**\n * Formats a log line with the appropriate prefix and indentation\n * @param opts - Formatting options\n * @returns Formatted log line\n */\nexport function formatLogLine(opts: FormatLogLineOptions): string {\n const { mode, indent, type, message, timestamp } = opts;\n const indentPrefix = indent > 0 ? \" \".repeat(indent) : \"\";\n const colorFn = TYPE_COLORS[type] || ((text: string) => text);\n\n // Plain mode: color only, no icon, no timestamp\n if (mode === \"plain\") {\n return `${indentPrefix}${colorFn(message)}\\n`;\n }\n\n // Default/Stream mode: with icon and color\n const icon = TYPE_ICONS[type] || \"\";\n const prefix = icon ? `${icon} ` : \"\";\n const coloredOutput = colorFn(`${prefix}${message}`);\n const timestampPrefix = timestamp ?? \"\";\n\n return `${indentPrefix}${timestampPrefix}${coloredOutput}\\n`;\n}\n\n/**\n * Writes a formatted log line to stderr.\n * @param type - Log type (info, success, warn, error, log)\n * @param message - Log message\n * @param opts - Log options (mode and indent)\n */\nfunction writeLog(type: string, message: string, opts?: LogOptions): void {\n const mode = opts?.mode ?? \"default\";\n const indent = opts?.indent ?? 0;\n const inspectOpts: InspectOptions = {\n breakLength: process.stdout.columns || 80,\n };\n const formattedMessage = formatWithOptions(inspectOpts, message);\n const timestamp = mode === \"stream\" ? `${new Date().toLocaleTimeString()} ` : \"\";\n const output = formatLogLine({ mode, indent, type, message: formattedMessage, timestamp });\n process.stderr.write(renderFor(process.stderr, output));\n}\n\nexport const logger = {\n get jsonMode(): boolean {\n return _jsonMode;\n },\n set jsonMode(value: boolean) {\n _jsonMode = value;\n },\n\n info(message: string, opts?: LogOptions): void {\n writeLog(\"info\", message, opts);\n },\n\n success(message: string, opts?: LogOptions): void {\n writeLog(\"success\", message, opts);\n },\n\n warn(message: string, opts?: LogOptions): void {\n writeLog(\"warn\", message, opts);\n },\n\n error(message: string, opts?: LogOptions): void {\n writeLog(\"error\", message, opts);\n },\n\n log(message: string): void {\n writeLog(\"log\", message, { mode: \"plain\" });\n },\n\n newline(): void {\n process.stderr.write(\"\\n\");\n },\n\n debug(message: string): void {\n if (parseBoolean(process.env.DEBUG) === true) {\n writeLog(\"log\", styles.dim(message), { mode: \"plain\" });\n }\n },\n\n out(data: string | object | object[], options?: OutOptions): void {\n if (typeof data === \"string\") {\n process.stdout.write(renderFor(process.stdout, data.endsWith(\"\\n\") ? data : data + \"\\n\"));\n return;\n }\n\n if (this.jsonMode) {\n // eslint-disable-next-line no-restricted-syntax\n console.log(JSON.stringify(data));\n return;\n }\n\n const display = options?.display;\n\n // Helper to format a value for table display\n const formatValue = (value: unknown, pretty = false): string => {\n if (options?.showNull && value === null) return \"NULL\";\n if (value === null || value === undefined) return \"N/A\";\n if (value instanceof Date) {\n return formatDistanceToNowStrict(value, { addSuffix: true });\n }\n if (typeof value === \"object\") {\n return pretty ? JSON.stringify(value, null, 2) : JSON.stringify(value);\n }\n return String(value);\n };\n\n // Helper to check if field should be excluded\n const isExcluded = (key: string): boolean => {\n return display !== undefined && key in display && display[key] === null;\n };\n\n // Helper to apply transformer or default formatting\n const transformValue = (key: string, value: unknown, item: object, pretty = false): string => {\n if (display && key in display) {\n const transformer = display[key];\n if (transformer) {\n return transformer(value, item);\n }\n }\n return formatValue(value, pretty);\n };\n\n if (!Array.isArray(data)) {\n const entries = Object.entries(data).filter(([key]) => !isExcluded(key));\n const formattedEntries = entries.map(([key, value]) => [\n key,\n transformValue(key, value, data, true),\n ]);\n const t = renderTable(formattedEntries, { singleLine: false });\n process.stdout.write(renderFor(process.stdout, t));\n return;\n }\n\n if (data.length === 0) {\n return;\n }\n\n const allHeaders = Array.from(new Set(data.flatMap((item) => Object.keys(item))));\n const headers = allHeaders.filter((h) => !isExcluded(h));\n if (headers.length === 0) {\n return;\n }\n const rows = data.map((item) =>\n headers.map((header) =>\n transformValue(header, (item as Record<string, unknown>)[header], item),\n ),\n );\n\n const t = renderTable([headers, ...rows], {\n drawHorizontalLine: (lineIndex, rowCount) => {\n return lineIndex === 0 || lineIndex === 1 || lineIndex === rowCount;\n },\n });\n process.stdout.write(renderFor(process.stdout, t));\n },\n};\n"],"mappings":";;;;;AAOA,MAAM,SACH,UACA,SACC,UAAU,MAAM,MAAM,EAAE,gBAAgB,MAAM,CAAC;;;;;;AAOnD,MAAa,QAAQ;CACnB,MAAM,MAAM,MAAM;CAClB,KAAK,MAAM,KAAK;CAChB,QAAQ,MAAM,QAAQ;CACtB,MAAM,MAAM,MAAM;CAClB,OAAO,MAAM,OAAO;CACpB,KAAK,MAAM,KAAK;CAChB,OAAO,MAAM,OAAO;CACpB,QAAQ,MAAM,QAAQ;CACtB,MAAM,MAAM,MAAM;CAClB,SAAS,MAAM,SAAS;CACxB,WAAW,MAAM,WAAW;CAC5B,aAAa,MAAM,aAAa;CAChC,YAAY,MAAM,YAAY;AAChC;AASA,MAAM,iBAAiB,WAAwC;CAC7D,MAAM,SAAS,QAAQ,IAAI;CAC3B,IAAI,WAAW,QAAW,OAAO,WAAW,OAAO,WAAW;CAC9D,IAAI,QAAQ,IAAI,wBAAwB,QAAW,OAAO;CAC1D,KAAK,QAAQ,IAAI,YAAY,QAAQ,IAAI,OAAO;CAChD,IAAI,QAAQ,IAAI,SAAS,QAAQ,OAAO;CACxC,OAAO,OAAO,UAAU;AAC1B;;;;;;;AAQA,SAAgB,UAAU,QAA4B,MAAsB;CAC1E,OAAO,cAAc,MAAM,IAAI,OAAO,yBAAyB,IAAI;AACrE;;;;ACtDA,MAAM,sBAAsB;AAC5B,MAAM,0BAA0B;AAEhC,MAAM,oBAAoB,IAAI,KAAK,UAAU,QAAW,EAAE,aAAa,WAAW,CAAC;AAcnF,SAAS,MAAM,QAAkB,WAAW,GAAW;CACrD,OAAO,OAAO,QAAQ,KAAK,UAAW,QAAQ,MAAM,QAAQ,KAAM,QAAQ;AAC5E;AAEA,MAAM,YAAY;AAElB,SAAS,6BAA6B,MAAuB;CAC3D,MAAM,YAAY,KAAK,YAAY,CAAC,KAAK;CACzC,IAAI,SAAS,MACX,OAAO;CAET,OAAO,aAAa,MAAQ,cAAc;AAC5C;AAOA,SAAS,2BAA2B,OAAuB;CACzD,MAAM,eAAe,MAAM,MAAM,mBAAmB,KAAK,CAAC;CAC1D,OAAO,MACJ,MAAM,mBAAmB,CAAC,CAC1B,KAAK,YAAY;EAChB,MAAM,QAAkB,CAAC;EACzB,KAAK,MAAM,QAAQ,SACjB,IAAI,SAAS,KACX,MAAM,KAAK,IAAI,OAAO,SAAS,CAAC;OAC3B,IAAI,CAAC,6BAA6B,IAAI,GAC3C,MAAM,KAAK,IAAI;EAGnB,OAAO,MAAM,KAAK,EAAE;CACtB,CAAC,CAAC,CACD,QAAQ,QAAQ,SAAS,MAAM,SAAS,WAAW,aAAa,MAAM,KAAK,EAAE;AAClF;AAEA,SAAS,aAAa,MAAuB;CAC3C,OAAO,2BAA2B,OAAO,QAAQ,EAAE,CAAC,CAAC,QAAQ,yBAAyB,IAAI,CAAC;AAC7F;AAIA,MAAM,6BACJ;AAIF,MAAM,oBAAoB;AAE1B,SAAS,aAAa,OAAuB;CAC3C,IAAI,QAAQ;CACZ,KAAK,MAAM,EAAE,aAAa,kBAAkB,QAAQ,MAAM,QAAQ,qBAAqB,EAAE,CAAC,GAAG;EAC3F,IAAI,2BAA2B,KAAK,OAAO,GACzC;EAEF,IAAI,kBAAkB,KAAK,OAAO,GAAG;GACnC,SAAS;GACT;EACF;EACA,MAAM,YAAY,QAAQ,YAAY,CAAC;EACvC,SAAS,cAAc,SAAY,IAAI,eAAe,SAAS;CACjE;CACA,OAAO;AACT;AAEA,SAAS,YAAY,MAA0B;CAC7C,OAAO,KAAK,MAAM,IAAI,CAAC,CAAC,KAAK,UAAU;EAAE;EAAM,OAAO,aAAa,IAAI;CAAE,EAAE;AAC7E;AAEA,SAAS,QAAQ,UAAoB,OAAuB;CAC1D,OAAO,SAAS,OAAO,IAAI,OAAO,KAAK,IAAI,GAAG,QAAQ,SAAS,KAAK,CAAC;AACvE;AAEA,SAAS,aAAa,MAAc,MAAc,OAAe,cAAgC;CAC/F,OAAO,OAAO,aAAa,KAAK,UAAU,IAAI,OAAO,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI;AAChF;AAEA,SAAS,8BAA8B,MAAwB;CAC7D,MAAM,cAAc,KAAK,EAAE,EAAE;CAC7B,IAAI,gBAAgB,QAClB;CAEF,KAAK,SAAS,KAAK,UAAU;EAC3B,IAAI,IAAI,WAAW,aACjB,MAAM,IAAI,MACR,wEAAwE,YAAY,QAAQ,MAAM,OAAO,IAAI,OAAO,GACtH;CAEJ,CAAC;AACH;;;;;;;;;;;;;;;;;AAkBA,SAAgB,YAAY,MAAmB,SAA2B,CAAC,GAAW;CACpF,MAAM,OAAO,KAAK,KAAK,QAAQ,IAAI,IAAI,YAAY,CAAC;CACpD,8BAA8B,IAAI;CAElC,MAAM,WAAW,KAAK;CACtB,MAAM,cAAc,KAAK,EAAE,EAAE,UAAU;CACvC,IAAI,aAAa,KAAK,gBAAgB,GACpC,OAAO;CAGT,MAAM,gBAAgB,KAAK,KAAK,QAC9B,MAAM,KAAK,EAAE,QAAQ,YAAY,IAAI,GAAG,QAAQ,YAAY,IAAI,QAAQ,EAAE,CAAC,CAC7E;CACA,MAAM,eAAe,MAAM,KAAK,EAAE,QAAQ,YAAY,IAAI,GAAG,QAC3D,MAAM,cAAc,KAAK,QAAQ,OAAO,IAAI,QAAQ,CAAC,EAAC,CAAE,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,CACrF;CAEA,MAAM,kBAAkB,cACtB,OAAO,aACH,cAAc,KAAK,cAAc,YAChC,OAAO,6BAA6B,MAAK,CAAE,WAAW,QAAQ;CAErE,MAAM,QAAkB,CAAC;CACzB,IAAI,eAAe,CAAC,GAClB,MAAM,KAAK,aAAa,KAAK,KAAK,KAAK,YAAY,CAAC;CAGtD,cAAc,SAAS,WAAW,aAAa;EAC7C,MAAM,YAAY,MAChB,UAAU,KAAK,gBAAgB,YAAY,MAAM,GACjD,CACF;EACA,KAAK,IAAI,OAAO,GAAG,OAAO,WAAW,QAAQ;GAC3C,MAAM,QAAQ,UAAU,KAAK,aAAa,QACxC,QAAQ,YAAY,SAAS;IAAE,MAAM;IAAI,OAAO;GAAE,GAAG,aAAa,QAAQ,CAAC,CAC7E;GACA,MAAM,KAAK,KAAK,MAAM,KAAK,KAAK,EAAE,GAAG;EACvC;EACA,IAAI,WAAW,WAAW,KAAK,eAAe,WAAW,CAAC,GACxD,MAAM,KAAK,aAAa,KAAK,KAAK,KAAK,YAAY,CAAC;CAExD,CAAC;CAED,IAAI,eAAe,QAAQ,GACzB,MAAM,KAAK,aAAa,KAAK,KAAK,KAAK,YAAY,CAAC;CAGtD,OAAO,GAAG,MAAM,KAAK,IAAI,EAAE;AAC7B;;;;AChLA,MAAM,gCAAgB,IAAI,IAAI;CAAC;CAAQ;CAAK;CAAO;CAAK;CAAM;AAAG,CAAC;AAClE,MAAM,+BAAe,IAAI,IAAI;CAAC;CAAS;CAAK;CAAM;CAAK;CAAO;AAAG,CAAC;;;;;;;;;;;;;;AAelE,SAAgB,aAAa,OAAgD;CAC3E,IAAI,UAAU,QAAW,OAAO;CAChC,MAAM,aAAa,MAAM,KAAK,CAAC,CAAC,YAAY;CAC5C,IAAI,eAAe,IAAI,OAAO;CAC9B,IAAI,cAAc,IAAI,UAAU,GAAG,OAAO;CAC1C,IAAI,aAAa,IAAI,UAAU,GAAG,OAAO;AAE3C;;;;;;;ACdA,IAAa,gBAAb,cAAmC,MAAM;CACvC,YAAY,SAAkB;EAC5B,MACE,WACE,qGACJ;EACA,KAAK,OAAO;CACd;AACF;;;;AAKA,MAAa,SAAS;CAEpB,SAAS,MAAM;CACf,OAAO,MAAM;CACb,SAAS,MAAM;CACf,MAAM,MAAM;CAGZ,QAAQ,MAAM;CACd,QAAQ,MAAM;CACd,QAAQ,MAAM;CACd,SAAS,MAAM;CACf,WAAW,MAAM;CAGjB,MAAM,MAAM;CACZ,KAAK,MAAM;CACX,WAAW,MAAM;CACjB,eAAe,MAAM;CACrB,aAAa,MAAM;CAGnB,cAAc,MAAM;CACpB,cAAc,MAAM;CAGpB,MAAM,MAAM;CAGZ,OAAO,MAAM;CACb,cAAc,SAAiB,MAAM,OAAO,MAAM,KAAK,IAAI,CAAC;AAC9D;;;;AAKA,MAAa,UAAU;CACrB,SAAS,OAAO,QAAQ,GAAQ;CAChC,OAAO,OAAO,MAAM,GAAQ;CAC5B,SAAS,OAAO,QAAQ,GAAQ;CAChC,MAAM,OAAO,KAAK,GAAG;CACrB,QAAQ,OAAO,OAAO,GAAG;CACzB,QAAQ,OAAO,OAAO,GAAG;CACzB,QAAQ,OAAO,OAAO,GAAG;CACzB,SAAS,OAAO,QAAQ,GAAQ;CAChC,QAAQ,OAAO,IAAI,GAAQ;CAC3B,OAAO,OAAO,IAAI,GAAQ;AAC5B;AA0BA,IAAI,YAAY;AAGhB,MAAM,aAAqC;CACzC,MAAM;CACN,SAAS;CACT,MAAM;CACN,OAAO;CACP,OAAO;CACP,OAAO;CACP,KAAK;AACP;AAGA,MAAM,cAAwD;CAC5D,MAAM,OAAO;CACb,SAAS,OAAO;CAChB,MAAM,OAAO;CACb,OAAO,OAAO;CACd,OAAO,OAAO;CACd,OAAO,OAAO;CACd,MAAM,SAAS;AACjB;;;;;;AAeA,SAAgB,cAAc,MAAoC;CAChE,MAAM,EAAE,MAAM,QAAQ,MAAM,SAAS,cAAc;CACnD,MAAM,eAAe,SAAS,IAAI,IAAI,OAAO,MAAM,IAAI;CACvD,MAAM,UAAU,YAAY,WAAW,SAAiB;CAGxD,IAAI,SAAS,SACX,OAAO,GAAG,eAAe,QAAQ,OAAO,EAAE;CAI5C,MAAM,OAAO,WAAW,SAAS;CAEjC,MAAM,gBAAgB,QAAQ,GADf,OAAO,GAAG,KAAK,KAAK,KACO,SAAS;CAGnD,OAAO,GAAG,eAFc,aAAa,KAEM,cAAc;AAC3D;;;;;;;AAQA,SAAS,SAAS,MAAc,SAAiB,MAAyB;CACxE,MAAM,OAAO,MAAM,QAAQ;CAC3B,MAAM,SAAS,MAAM,UAAU;CAC/B,MAAM,cAA8B,EAClC,aAAa,QAAQ,OAAO,WAAW,GACzC;CAGA,MAAM,SAAS,cAAc;EAAE;EAAM;EAAQ;EAAM,SAF1B,kBAAkB,aAAa,OAEmB;EAAG,WAD5D,SAAS,WAAW,oBAAG,IAAI,KAAK,EAAC,CAAC,mBAAmB,EAAE,KAAK;CACU,CAAC;CACzF,QAAQ,OAAO,MAAM,UAAU,QAAQ,QAAQ,MAAM,CAAC;AACxD;AAEA,MAAa,SAAS;CACpB,IAAI,WAAoB;EACtB,OAAO;CACT;CACA,IAAI,SAAS,OAAgB;EAC3B,YAAY;CACd;CAEA,KAAK,SAAiB,MAAyB;EAC7C,SAAS,QAAQ,SAAS,IAAI;CAChC;CAEA,QAAQ,SAAiB,MAAyB;EAChD,SAAS,WAAW,SAAS,IAAI;CACnC;CAEA,KAAK,SAAiB,MAAyB;EAC7C,SAAS,QAAQ,SAAS,IAAI;CAChC;CAEA,MAAM,SAAiB,MAAyB;EAC9C,SAAS,SAAS,SAAS,IAAI;CACjC;CAEA,IAAI,SAAuB;EACzB,SAAS,OAAO,SAAS,EAAE,MAAM,QAAQ,CAAC;CAC5C;CAEA,UAAgB;EACd,QAAQ,OAAO,MAAM,IAAI;CAC3B;CAEA,MAAM,SAAuB;EAC3B,IAAI,aAAa,QAAQ,IAAI,KAAK,MAAM,MACtC,SAAS,OAAO,OAAO,IAAI,OAAO,GAAG,EAAE,MAAM,QAAQ,CAAC;CAE1D;CAEA,IAAI,MAAkC,SAA4B;EAChE,IAAI,OAAO,SAAS,UAAU;GAC5B,QAAQ,OAAO,MAAM,UAAU,QAAQ,QAAQ,KAAK,SAAS,IAAI,IAAI,OAAO,OAAO,IAAI,CAAC;GACxF;EACF;EAEA,IAAI,KAAK,UAAU;GAEjB,QAAQ,IAAI,KAAK,UAAU,IAAI,CAAC;GAChC;EACF;EAEA,MAAM,UAAU,SAAS;EAGzB,MAAM,eAAe,OAAgB,SAAS,UAAkB;GAC9D,IAAI,SAAS,YAAY,UAAU,MAAM,OAAO;GAChD,IAAI,UAAU,QAAQ,UAAU,QAAW,OAAO;GAClD,IAAI,iBAAiB,MACnB,OAAO,0BAA0B,OAAO,EAAE,WAAW,KAAK,CAAC;GAE7D,IAAI,OAAO,UAAU,UACnB,OAAO,SAAS,KAAK,UAAU,OAAO,MAAM,CAAC,IAAI,KAAK,UAAU,KAAK;GAEvE,OAAO,OAAO,KAAK;EACrB;EAGA,MAAM,cAAc,QAAyB;GAC3C,OAAO,YAAY,UAAa,OAAO,WAAW,QAAQ,SAAS;EACrE;EAGA,MAAM,kBAAkB,KAAa,OAAgB,MAAc,SAAS,UAAkB;GAC5F,IAAI,WAAW,OAAO,SAAS;IAC7B,MAAM,cAAc,QAAQ;IAC5B,IAAI,aACF,OAAO,YAAY,OAAO,IAAI;GAElC;GACA,OAAO,YAAY,OAAO,MAAM;EAClC;EAEA,IAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;GAExB,MAAM,mBADU,OAAO,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,WAAW,GAAG,CACvC,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CACrD,KACA,eAAe,KAAK,OAAO,MAAM,IAAI,CACvC,CAAC;GACD,MAAM,IAAI,YAAY,kBAAkB,EAAE,YAAY,MAAM,CAAC;GAC7D,QAAQ,OAAO,MAAM,UAAU,QAAQ,QAAQ,CAAC,CAAC;GACjD;EACF;EAEA,IAAI,KAAK,WAAW,GAClB;EAIF,MAAM,UADa,MAAM,KAAK,IAAI,IAAI,KAAK,SAAS,SAAS,OAAO,KAAK,IAAI,CAAC,CAAC,CACtD,CAAC,CAAC,QAAQ,MAAM,CAAC,WAAW,CAAC,CAAC;EACvD,IAAI,QAAQ,WAAW,GACrB;EAEF,MAAM,OAAO,KAAK,KAAK,SACrB,QAAQ,KAAK,WACX,eAAe,QAAS,KAAiC,SAAS,IAAI,CACxE,CACF;EAEA,MAAM,IAAI,YAAY,CAAC,SAAS,GAAG,IAAI,GAAG,EACxC,qBAAqB,WAAW,aAAa;GAC3C,OAAO,cAAc,KAAK,cAAc,KAAK,cAAc;EAC7D,EACF,CAAC;EACD,QAAQ,OAAO,MAAM,UAAU,QAAQ,QAAQ,CAAC,CAAC;CACnD;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"package-json-8b0O9TlX.mjs","names":[],"sources":["../src/cli/shared/package-json.ts"],"sourcesContent":["import { readPackageJSON, type PackageJson } from \"pkg-types\";\n\nlet packageJson: PackageJson | null = null;\n\n/**\n * Read and cache the package.json of the SDK package.\n * @returns Parsed package.json contents\n */\nexport async function readPackageJson() {\n if (packageJson) {\n return packageJson;\n }\n packageJson = await readPackageJSON(import.meta.url);\n return packageJson;\n}\n"],"mappings":";;;AAEA,IAAI,cAAkC;;;;;AAMtC,eAAsB,kBAAkB;CACtC,IAAI,aACF,OAAO;CAET,cAAc,MAAM,gBAAgB,OAAO,KAAK,GAAG;CACnD,OAAO;AACT"}
1
+ {"version":3,"file":"package-json-8b0O9TlX.mjs","names":[],"sources":["../src/cli/shared/package-json.ts"],"sourcesContent":["import { readPackageJSON, type PackageJson } from \"pkg-types\";\n\nlet packageJson: PackageJson | null = null;\n\n/**\n * Read and cache the package.json of the SDK package.\n * @returns Parsed package.json contents\n */\nexport async function readPackageJson() {\n if (packageJson) {\n return packageJson;\n }\n packageJson = await readPackageJSON(import.meta.url);\n return packageJson;\n}\n"],"mappings":";;;AAEA,IAAI,cAAkC;;;;;AAMtC,eAAsB,kBAAkB;CACtC,IAAI,aACF,OAAO;CAET,cAAc,MAAM,gBAAgB,YAAY,GAAG;CACnD,OAAO;AACT"}
@@ -6,7 +6,7 @@ type EnumConstantsPluginOptions = {
6
6
  distPath: string;
7
7
  };
8
8
  /**
9
- * Plugin that generates enum constants from TailorDB type definitions.
9
+ * Plugin that generates enum constants from TailorDB table definitions.
10
10
  * @param options - Plugin options
11
11
  * @param options.distPath - Output file path for generated constants
12
12
  * @returns Plugin instance with onTailorDBReady hook
@@ -65,9 +65,9 @@ function collectEnums(type) {
65
65
  return enums;
66
66
  }
67
67
  /**
68
- * Process a TailorDB type and extract enum metadata.
69
- * @param type - The parsed TailorDB type to process
70
- * @returns Enum constant metadata for the type
68
+ * Process a TailorDB table and extract enum metadata.
69
+ * @param type - The parsed TailorDB table to process
70
+ * @returns Enum constant metadata for the table
71
71
  */
72
72
  async function processEnumType(type) {
73
73
  const enums = collectEnums(type);
@@ -82,7 +82,7 @@ async function processEnumType(type) {
82
82
  /** Unique identifier for the enum constants generator plugin. */
83
83
  const EnumConstantsGeneratorID = "@tailor-platform/enum-constants";
84
84
  /**
85
- * Plugin that generates enum constants from TailorDB type definitions.
85
+ * Plugin that generates enum constants from TailorDB table definitions.
86
86
  * @param options - Plugin options
87
87
  * @param options.distPath - Output file path for generated constants
88
88
  * @returns Plugin instance with onTailorDBReady hook
@@ -90,7 +90,7 @@ const EnumConstantsGeneratorID = "@tailor-platform/enum-constants";
90
90
  function enumConstantsPlugin(options) {
91
91
  return {
92
92
  id: EnumConstantsGeneratorID,
93
- description: "Generates enum constants from TailorDB type definitions",
93
+ description: "Generates enum constants from TailorDB table definitions",
94
94
  pluginConfig: options,
95
95
  async onTailorDBReady(ctx) {
96
96
  const allEnums = [];
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/plugin/builtin/enum-constants/generate-enum-constants.ts","../../../../src/plugin/builtin/enum-constants/process-enum-type.ts","../../../../src/plugin/builtin/enum-constants/index.ts"],"sourcesContent":["import type { EnumDefinition } from \"./types\";\n\n/**\n * Generate enum constant definitions from collected metadata.\n * @param allEnums - All collected enum definitions\n * @returns Generated enum constant definitions\n */\nexport function generateUnifiedEnumConstants(allEnums: EnumDefinition[]): string {\n if (allEnums.length === 0) {\n return \"\";\n }\n\n const enumMap = new Map<string, EnumDefinition>();\n for (const enumDef of allEnums) {\n enumMap.set(enumDef.name, enumDef);\n }\n\n const enumDefs = Array.from(enumMap.values())\n .map((e) => {\n const members = e.values\n .map((v) => {\n const key = v.value.replace(/[-\\s]/g, \"_\");\n return ` \"${key}\": \"${v.value}\"`;\n })\n .join(\",\\n\");\n\n const hasDescriptions = e.values.some((v) => v.description);\n let jsDoc = \"\";\n if (e.fieldDescription || hasDescriptions) {\n const lines: string[] = [];\n\n if (e.fieldDescription) {\n lines.push(` * ${e.fieldDescription}`);\n if (hasDescriptions) {\n lines.push(\" *\");\n }\n }\n\n if (hasDescriptions) {\n const propertyDocs = e.values.map((v) => {\n const key = v.value.replace(/[-\\s]/g, \"_\");\n return ` * @property ${[key, v.description].filter(Boolean).join(\" - \")}`;\n });\n lines.push(...propertyDocs);\n }\n\n if (lines.length > 0) {\n jsDoc = `/**\\n${lines.join(\"\\n\")}\\n */\\n`;\n }\n }\n\n const constDef = `${jsDoc}export const ${e.name} = {\\n${members}\\n} as const;`;\n const typeDef = `export type ${e.name} = (typeof ${e.name})[keyof typeof ${e.name}];`;\n return `${constDef}\\n${typeDef}`;\n })\n .join(\"\\n\\n\");\n\n if (!enumDefs) {\n return \"\";\n }\n\n return enumDefs + \"\\n\";\n}\n","import type { TailorDBType } from \"#/parser/service/tailordb/types\";\nimport type { EnumConstantMetadata } from \"./types\";\n\nfunction capitalizeFirst(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\nfunction collectEnums(type: TailorDBType): EnumConstantMetadata[\"enums\"] {\n const enums: EnumConstantMetadata[\"enums\"] = [];\n\n for (const [fieldName, parsedField] of Object.entries(type.fields)) {\n if (parsedField.config.type === \"enum\" && parsedField.config.allowedValues) {\n const enumTypeName = `${type.name}${capitalizeFirst(fieldName)}`;\n enums.push({\n name: enumTypeName,\n values: parsedField.config.allowedValues,\n fieldDescription: parsedField.config.description,\n });\n }\n\n // Process nested fields\n if (parsedField.config.type === \"nested\" && parsedField.config.fields) {\n for (const [nestedFieldName, nestedFieldConfig] of Object.entries(\n parsedField.config.fields,\n )) {\n if (nestedFieldConfig.type === \"enum\" && nestedFieldConfig.allowedValues) {\n const fullFieldName = `${fieldName}${capitalizeFirst(nestedFieldName)}`;\n const enumTypeName = `${type.name}${capitalizeFirst(fullFieldName)}`;\n enums.push({\n name: enumTypeName,\n values: nestedFieldConfig.allowedValues,\n fieldDescription: nestedFieldConfig.description,\n });\n }\n }\n }\n }\n\n return enums;\n}\n\n/**\n * Process a TailorDB type and extract enum metadata.\n * @param type - The parsed TailorDB type to process\n * @returns Enum constant metadata for the type\n */\nexport async function processEnumType(type: TailorDBType): Promise<EnumConstantMetadata> {\n const enums = collectEnums(type);\n\n return {\n name: type.name,\n enums,\n };\n}\n","import { generateUnifiedEnumConstants } from \"./generate-enum-constants\";\nimport { processEnumType } from \"./process-enum-type\";\nimport type { Plugin, GeneratorResult, TailorDBReadyContext } from \"#/plugin/types\";\nimport type { EnumDefinition } from \"./types\";\n\n/** Unique identifier for the enum constants generator plugin. */\nexport const EnumConstantsGeneratorID = \"@tailor-platform/enum-constants\";\n\ntype EnumConstantsPluginOptions = {\n distPath: string;\n};\n\n/**\n * Plugin that generates enum constants from TailorDB type definitions.\n * @param options - Plugin options\n * @param options.distPath - Output file path for generated constants\n * @returns Plugin instance with onTailorDBReady hook\n */\nexport function enumConstantsPlugin(\n options: EnumConstantsPluginOptions,\n): Plugin<unknown, EnumConstantsPluginOptions> {\n return {\n id: EnumConstantsGeneratorID,\n description: \"Generates enum constants from TailorDB type definitions\",\n pluginConfig: options,\n\n async onTailorDBReady(\n ctx: TailorDBReadyContext<EnumConstantsPluginOptions>,\n ): Promise<GeneratorResult> {\n const allEnums: EnumDefinition[] = [];\n\n for (const ns of ctx.tailordb) {\n for (const type of Object.values(ns.types)) {\n const metadata = await processEnumType(type);\n allEnums.push(...metadata.enums);\n }\n }\n\n const files: GeneratorResult[\"files\"] = [];\n if (allEnums.length > 0) {\n const content = generateUnifiedEnumConstants(allEnums);\n files.push({\n path: ctx.pluginConfig.distPath,\n content,\n });\n }\n\n return { files };\n },\n };\n}\n"],"mappings":";;;;;;AAOA,SAAgB,6BAA6B,UAAoC;CAC/E,IAAI,SAAS,WAAW,GACtB,OAAO;CAGT,MAAM,0BAAU,IAAI,IAA4B;CAChD,KAAK,MAAM,WAAW,UACpB,QAAQ,IAAI,QAAQ,MAAM,OAAO;CAGnC,MAAM,WAAW,MAAM,KAAK,QAAQ,OAAO,CAAC,CAAC,CAC1C,KAAK,MAAM;EACV,MAAM,UAAU,EAAE,OACf,KAAK,MAAM;GAEV,OAAO,MADK,EAAE,MAAM,QAAQ,UAAU,GACvB,EAAE,MAAM,EAAE,MAAM;EACjC,CAAC,CAAC,CACD,KAAK,KAAK;EAEb,MAAM,kBAAkB,EAAE,OAAO,MAAM,MAAM,EAAE,WAAW;EAC1D,IAAI,QAAQ;EACZ,IAAI,EAAE,oBAAoB,iBAAiB;GACzC,MAAM,QAAkB,CAAC;GAEzB,IAAI,EAAE,kBAAkB;IACtB,MAAM,KAAK,MAAM,EAAE,kBAAkB;IACrC,IAAI,iBACF,MAAM,KAAK,IAAI;GAEnB;GAEA,IAAI,iBAAiB;IACnB,MAAM,eAAe,EAAE,OAAO,KAAK,MAAM;KAEvC,OAAO,gBAAgB,CADX,EAAE,MAAM,QAAQ,UAAU,GACZ,GAAG,EAAE,WAAW,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,KAAK;IACxE,CAAC;IACD,MAAM,KAAK,GAAG,YAAY;GAC5B;GAEA,IAAI,MAAM,SAAS,GACjB,QAAQ,QAAQ,MAAM,KAAK,IAAI,EAAE;EAErC;EAIA,OAAO,GAAG,GAFU,MAAM,eAAe,EAAE,KAAK,QAAQ,QAAQ,eAE7C,IAAI,eADQ,EAAE,KAAK,aAAa,EAAE,KAAK,iBAAiB,EAAE,KAAK;CAEpF,CAAC,CAAC,CACD,KAAK,MAAM;CAEd,IAAI,CAAC,UACH,OAAO;CAGT,OAAO,WAAW;AACpB;;;;AC3DA,SAAS,gBAAgB,KAAqB;CAC5C,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,IAAI,MAAM,CAAC;AAClD;AAEA,SAAS,aAAa,MAAmD;CACvE,MAAM,QAAuC,CAAC;CAE9C,KAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,KAAK,MAAM,GAAG;EAClE,IAAI,YAAY,OAAO,SAAS,UAAU,YAAY,OAAO,eAAe;GAC1E,MAAM,eAAe,GAAG,KAAK,OAAO,gBAAgB,SAAS;GAC7D,MAAM,KAAK;IACT,MAAM;IACN,QAAQ,YAAY,OAAO;IAC3B,kBAAkB,YAAY,OAAO;GACvC,CAAC;EACH;EAGA,IAAI,YAAY,OAAO,SAAS,YAAY,YAAY,OAAO,QAC7D;QAAK,MAAM,CAAC,iBAAiB,sBAAsB,OAAO,QACxD,YAAY,OAAO,MACrB,GACE,IAAI,kBAAkB,SAAS,UAAU,kBAAkB,eAAe;IACxE,MAAM,gBAAgB,GAAG,YAAY,gBAAgB,eAAe;IACpE,MAAM,eAAe,GAAG,KAAK,OAAO,gBAAgB,aAAa;IACjE,MAAM,KAAK;KACT,MAAM;KACN,QAAQ,kBAAkB;KAC1B,kBAAkB,kBAAkB;IACtC,CAAC;GACH;EACF;CAEJ;CAEA,OAAO;AACT;;;;;;AAOA,eAAsB,gBAAgB,MAAmD;CACvF,MAAM,QAAQ,aAAa,IAAI;CAE/B,OAAO;EACL,MAAM,KAAK;EACX;CACF;AACF;;;;;AC/CA,MAAa,2BAA2B;;;;;;;AAYxC,SAAgB,oBACd,SAC6C;CAC7C,OAAO;EACL,IAAI;EACJ,aAAa;EACb,cAAc;EAEd,MAAM,gBACJ,KAC0B;GAC1B,MAAM,WAA6B,CAAC;GAEpC,KAAK,MAAM,MAAM,IAAI,UACnB,KAAK,MAAM,QAAQ,OAAO,OAAO,GAAG,KAAK,GAAG;IAC1C,MAAM,WAAW,MAAM,gBAAgB,IAAI;IAC3C,SAAS,KAAK,GAAG,SAAS,KAAK;GACjC;GAGF,MAAM,QAAkC,CAAC;GACzC,IAAI,SAAS,SAAS,GAAG;IACvB,MAAM,UAAU,6BAA6B,QAAQ;IACrD,MAAM,KAAK;KACT,MAAM,IAAI,aAAa;KACvB;IACF,CAAC;GACH;GAEA,OAAO,EAAE,MAAM;EACjB;CACF;AACF"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/plugin/builtin/enum-constants/generate-enum-constants.ts","../../../../src/plugin/builtin/enum-constants/process-enum-type.ts","../../../../src/plugin/builtin/enum-constants/index.ts"],"sourcesContent":["import type { EnumDefinition } from \"./types\";\n\n/**\n * Generate enum constant definitions from collected metadata.\n * @param allEnums - All collected enum definitions\n * @returns Generated enum constant definitions\n */\nexport function generateUnifiedEnumConstants(allEnums: EnumDefinition[]): string {\n if (allEnums.length === 0) {\n return \"\";\n }\n\n const enumMap = new Map<string, EnumDefinition>();\n for (const enumDef of allEnums) {\n enumMap.set(enumDef.name, enumDef);\n }\n\n const enumDefs = Array.from(enumMap.values())\n .map((e) => {\n const members = e.values\n .map((v) => {\n const key = v.value.replace(/[-\\s]/g, \"_\");\n return ` \"${key}\": \"${v.value}\"`;\n })\n .join(\",\\n\");\n\n const hasDescriptions = e.values.some((v) => v.description);\n let jsDoc = \"\";\n if (e.fieldDescription || hasDescriptions) {\n const lines: string[] = [];\n\n if (e.fieldDescription) {\n lines.push(` * ${e.fieldDescription}`);\n if (hasDescriptions) {\n lines.push(\" *\");\n }\n }\n\n if (hasDescriptions) {\n const propertyDocs = e.values.map((v) => {\n const key = v.value.replace(/[-\\s]/g, \"_\");\n return ` * @property ${[key, v.description].filter(Boolean).join(\" - \")}`;\n });\n lines.push(...propertyDocs);\n }\n\n if (lines.length > 0) {\n jsDoc = `/**\\n${lines.join(\"\\n\")}\\n */\\n`;\n }\n }\n\n const constDef = `${jsDoc}export const ${e.name} = {\\n${members}\\n} as const;`;\n const typeDef = `export type ${e.name} = (typeof ${e.name})[keyof typeof ${e.name}];`;\n return `${constDef}\\n${typeDef}`;\n })\n .join(\"\\n\\n\");\n\n if (!enumDefs) {\n return \"\";\n }\n\n return enumDefs + \"\\n\";\n}\n","import type { TailorDBType } from \"#/parser/service/tailordb/types\";\nimport type { EnumConstantMetadata } from \"./types\";\n\nfunction capitalizeFirst(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\nfunction collectEnums(type: TailorDBType): EnumConstantMetadata[\"enums\"] {\n const enums: EnumConstantMetadata[\"enums\"] = [];\n\n for (const [fieldName, parsedField] of Object.entries(type.fields)) {\n if (parsedField.config.type === \"enum\" && parsedField.config.allowedValues) {\n const enumTypeName = `${type.name}${capitalizeFirst(fieldName)}`;\n enums.push({\n name: enumTypeName,\n values: parsedField.config.allowedValues,\n fieldDescription: parsedField.config.description,\n });\n }\n\n // Process nested fields\n if (parsedField.config.type === \"nested\" && parsedField.config.fields) {\n for (const [nestedFieldName, nestedFieldConfig] of Object.entries(\n parsedField.config.fields,\n )) {\n if (nestedFieldConfig.type === \"enum\" && nestedFieldConfig.allowedValues) {\n const fullFieldName = `${fieldName}${capitalizeFirst(nestedFieldName)}`;\n const enumTypeName = `${type.name}${capitalizeFirst(fullFieldName)}`;\n enums.push({\n name: enumTypeName,\n values: nestedFieldConfig.allowedValues,\n fieldDescription: nestedFieldConfig.description,\n });\n }\n }\n }\n }\n\n return enums;\n}\n\n/**\n * Process a TailorDB table and extract enum metadata.\n * @param type - The parsed TailorDB table to process\n * @returns Enum constant metadata for the table\n */\nexport async function processEnumType(type: TailorDBType): Promise<EnumConstantMetadata> {\n const enums = collectEnums(type);\n\n return {\n name: type.name,\n enums,\n };\n}\n","import { generateUnifiedEnumConstants } from \"./generate-enum-constants\";\nimport { processEnumType } from \"./process-enum-type\";\nimport type { Plugin, GeneratorResult, TailorDBReadyContext } from \"#/plugin/types\";\nimport type { EnumDefinition } from \"./types\";\n\n/** Unique identifier for the enum constants generator plugin. */\nexport const EnumConstantsGeneratorID = \"@tailor-platform/enum-constants\";\n\ntype EnumConstantsPluginOptions = {\n distPath: string;\n};\n\n/**\n * Plugin that generates enum constants from TailorDB table definitions.\n * @param options - Plugin options\n * @param options.distPath - Output file path for generated constants\n * @returns Plugin instance with onTailorDBReady hook\n */\nexport function enumConstantsPlugin(\n options: EnumConstantsPluginOptions,\n): Plugin<unknown, EnumConstantsPluginOptions> {\n return {\n id: EnumConstantsGeneratorID,\n description: \"Generates enum constants from TailorDB table definitions\",\n pluginConfig: options,\n\n async onTailorDBReady(\n ctx: TailorDBReadyContext<EnumConstantsPluginOptions>,\n ): Promise<GeneratorResult> {\n const allEnums: EnumDefinition[] = [];\n\n for (const ns of ctx.tailordb) {\n for (const type of Object.values(ns.types)) {\n const metadata = await processEnumType(type);\n allEnums.push(...metadata.enums);\n }\n }\n\n const files: GeneratorResult[\"files\"] = [];\n if (allEnums.length > 0) {\n const content = generateUnifiedEnumConstants(allEnums);\n files.push({\n path: ctx.pluginConfig.distPath,\n content,\n });\n }\n\n return { files };\n },\n };\n}\n"],"mappings":"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"}
@@ -6,7 +6,7 @@ type FileUtilsPluginOptions = {
6
6
  distPath: string;
7
7
  };
8
8
  /**
9
- * Plugin that generates TypeWithFiles interface from TailorDB type definitions.
9
+ * Plugin that generates TypeWithFiles interface from TailorDB table definitions.
10
10
  * @param options - Plugin options
11
11
  * @param options.distPath - Output file path for generated file utilities
12
12
  * @returns Plugin instance with onTailorDBReady hook
@@ -18,8 +18,7 @@ function generateUnifiedFileUtils(namespaceData) {
18
18
  const interfaceFields = Array.from(typeFieldsMap.entries()).map(([typeName, fields]) => {
19
19
  return ` ${typeName}: {\n fields: ${fields.map((field) => `"${field}"`).join(" | ")};\n };`;
20
20
  }).join("\n");
21
- return [
22
- multiline`
21
+ const importStatement = multiline`
23
22
  import { file } from "@tailor-platform/sdk/runtime/file";
24
23
  import type {
25
24
  FileUploadOptions,
@@ -27,15 +26,19 @@ function generateUnifiedFileUtils(namespaceData) {
27
26
  FileMetadata,
28
27
  FileDownloadStreamResponse,
29
28
  } from "@tailor-platform/sdk/runtime/file";
30
- ` + "\n",
31
- multiline`
29
+ ` + "\n";
30
+ const interfaceDefinition = multiline`
32
31
  export interface TypeWithFiles {
33
32
  ${interfaceFields}
34
33
  }
35
- ` + "\n",
34
+ ` + "\n";
35
+ const namespaceEntries = Array.from(typeNamespaceMap.entries()).map(([typeName, namespace]) => ` ${typeName}: "${namespace}"`).join(",\n");
36
+ return [
37
+ importStatement,
38
+ interfaceDefinition,
36
39
  multiline`
37
40
  const namespaces: Record<keyof TypeWithFiles, string> = {
38
- ${Array.from(typeNamespaceMap.entries()).map(([typeName, namespace]) => ` ${typeName}: "${namespace}"`).join(",\n")},
41
+ ${namespaceEntries},
39
42
  };
40
43
  ` + "\n",
41
44
  multiline`
@@ -91,9 +94,9 @@ function generateUnifiedFileUtils(namespaceData) {
91
94
  //#endregion
92
95
  //#region src/plugin/builtin/file-utils/process-file-type.ts
93
96
  /**
94
- * Process a TailorDB type and extract file field metadata.
95
- * @param type - The parsed TailorDB type to process
96
- * @returns File utility metadata for the type
97
+ * Process a TailorDB table and extract file field metadata.
98
+ * @param type - The parsed TailorDB table to process
99
+ * @returns File utility metadata for the table
97
100
  */
98
101
  async function processFileType(type) {
99
102
  const fileFields = [];
@@ -109,7 +112,7 @@ async function processFileType(type) {
109
112
  /** Unique identifier for the file utilities generator plugin. */
110
113
  const FileUtilsGeneratorID = "@tailor-platform/file-utils";
111
114
  /**
112
- * Plugin that generates TypeWithFiles interface from TailorDB type definitions.
115
+ * Plugin that generates TypeWithFiles interface from TailorDB table definitions.
113
116
  * @param options - Plugin options
114
117
  * @param options.distPath - Output file path for generated file utilities
115
118
  * @returns Plugin instance with onTailorDBReady hook
@@ -117,7 +120,7 @@ const FileUtilsGeneratorID = "@tailor-platform/file-utils";
117
120
  function fileUtilsPlugin(options) {
118
121
  return {
119
122
  id: FileUtilsGeneratorID,
120
- description: "Generates TypeWithFiles interface from TailorDB type definitions",
123
+ description: "Generates TypeWithFiles interface from TailorDB table definitions",
121
124
  pluginConfig: options,
122
125
  async onTailorDBReady(ctx) {
123
126
  const namespaceData = [];
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/plugin/builtin/file-utils/generate-file-utils.ts","../../../../src/plugin/builtin/file-utils/process-file-type.ts","../../../../src/plugin/builtin/file-utils/index.ts"],"sourcesContent":["import multiline from \"#/utils/multiline\";\nimport type { FileUtilMetadata } from \"./types\";\n\n/**\n * Generate unified file utility functions from collected metadata.\n * @param namespaceData - Namespace data with file utility metadata\n * @returns Generated file utility code\n */\nexport function generateUnifiedFileUtils(\n namespaceData: { namespace: string; types: FileUtilMetadata[] }[],\n): string {\n if (namespaceData.length === 0) {\n return \"\";\n }\n\n // Collect all types with their namespace\n const typeNamespaceMap = new Map<string, string>();\n const typeFieldsMap = new Map<string, string[]>();\n\n for (const { namespace, types } of namespaceData) {\n for (const type of types) {\n typeNamespaceMap.set(type.name, namespace);\n typeFieldsMap.set(type.name, type.fileFields);\n }\n }\n\n if (typeNamespaceMap.size === 0) {\n return \"\";\n }\n\n // Generate interface fields\n const interfaceFields = Array.from(typeFieldsMap.entries())\n .map(([typeName, fields]) => {\n const fieldNamesUnion = fields.map((field) => `\"${field}\"`).join(\" | \");\n return ` ${typeName}: {\\n fields: ${fieldNamesUnion};\\n };`;\n })\n .join(\"\\n\");\n\n const importStatement =\n multiline /* ts */ `\n import { file } from \"@tailor-platform/sdk/runtime/file\";\n import type {\n FileUploadOptions,\n FileUploadResponse,\n FileMetadata,\n FileDownloadStreamResponse,\n } from \"@tailor-platform/sdk/runtime/file\";\n ` + \"\\n\";\n\n const interfaceDefinition =\n multiline /* ts */ `\n export interface TypeWithFiles {\n ${interfaceFields}\n }\n ` + \"\\n\";\n\n // Generate namespaces object\n const namespaceEntries = Array.from(typeNamespaceMap.entries())\n .map(([typeName, namespace]) => ` ${typeName}: \"${namespace}\"`)\n .join(\",\\n\");\n\n const namespacesDefinition =\n multiline /* ts */ `\n const namespaces: Record<keyof TypeWithFiles, string> = {\n ${namespaceEntries},\n };\n ` + \"\\n\";\n\n // Generate downloadFile helper function\n const downloadFunction =\n multiline /* ts */ `\n export async function downloadFile<T extends keyof TypeWithFiles>(\n type: T,\n field: TypeWithFiles[T][\"fields\"],\n recordId: string,\n ) {\n return await file.download(namespaces[type], type, field, recordId);\n }\n ` + \"\\n\";\n\n // Generate uploadFile helper function\n const uploadFunction =\n multiline /* ts */ `\n export async function uploadFile<T extends keyof TypeWithFiles>(\n type: T,\n field: TypeWithFiles[T][\"fields\"],\n recordId: string,\n data: string | ArrayBuffer | Uint8Array<ArrayBufferLike> | number[],\n options?: FileUploadOptions,\n ): Promise<FileUploadResponse> {\n return await file.upload(namespaces[type], type, field, recordId, data, options);\n }\n ` + \"\\n\";\n\n // Generate deleteFile helper function\n const deleteFunction =\n multiline /* ts */ `\n export async function deleteFile<T extends keyof TypeWithFiles>(\n type: T,\n field: TypeWithFiles[T][\"fields\"],\n recordId: string,\n ): Promise<void> {\n return await file.delete(namespaces[type], type, field, recordId);\n }\n ` + \"\\n\";\n\n // Generate getFileMetadata helper function\n const getMetadataFunction =\n multiline /* ts */ `\n export async function getFileMetadata<T extends keyof TypeWithFiles>(\n type: T,\n field: TypeWithFiles[T][\"fields\"],\n recordId: string,\n ): Promise<FileMetadata> {\n return await file.getMetadata(namespaces[type], type, field, recordId);\n }\n ` + \"\\n\";\n\n // Generate downloadFileStream helper function\n const downloadStreamFunction =\n multiline /* ts */ `\n export async function downloadFileStream<T extends keyof TypeWithFiles>(\n type: T,\n field: TypeWithFiles[T][\"fields\"],\n recordId: string,\n ): Promise<FileDownloadStreamResponse> {\n return await file.downloadStream(namespaces[type], type, field, recordId);\n }\n ` + \"\\n\";\n\n return [\n importStatement,\n interfaceDefinition,\n namespacesDefinition,\n downloadFunction,\n uploadFunction,\n deleteFunction,\n getMetadataFunction,\n downloadStreamFunction,\n ].join(\"\\n\");\n}\n","import type { TailorDBType } from \"#/parser/service/tailordb/types\";\nimport type { FileUtilMetadata } from \"./types\";\n\n/**\n * Process a TailorDB type and extract file field metadata.\n * @param type - The parsed TailorDB type to process\n * @returns File utility metadata for the type\n */\nexport async function processFileType(type: TailorDBType): Promise<FileUtilMetadata> {\n const fileFields: string[] = [];\n\n if (type.files) {\n for (const fileFieldName of Object.keys(type.files)) {\n fileFields.push(fileFieldName);\n }\n }\n\n return {\n name: type.name,\n fileFields,\n };\n}\n","import { generateUnifiedFileUtils } from \"./generate-file-utils\";\nimport { processFileType } from \"./process-file-type\";\nimport type { Plugin, GeneratorResult, TailorDBReadyContext } from \"#/plugin/types\";\nimport type { FileUtilMetadata } from \"./types\";\n\n/** Unique identifier for the file utilities generator plugin. */\nexport const FileUtilsGeneratorID = \"@tailor-platform/file-utils\";\n\ntype FileUtilsPluginOptions = {\n distPath: string;\n};\n\n/**\n * Plugin that generates TypeWithFiles interface from TailorDB type definitions.\n * @param options - Plugin options\n * @param options.distPath - Output file path for generated file utilities\n * @returns Plugin instance with onTailorDBReady hook\n */\nexport function fileUtilsPlugin(\n options: FileUtilsPluginOptions,\n): Plugin<unknown, FileUtilsPluginOptions> {\n return {\n id: FileUtilsGeneratorID,\n description: \"Generates TypeWithFiles interface from TailorDB type definitions\",\n pluginConfig: options,\n\n async onTailorDBReady(\n ctx: TailorDBReadyContext<FileUtilsPluginOptions>,\n ): Promise<GeneratorResult> {\n const namespaceData: { namespace: string; types: FileUtilMetadata[] }[] = [];\n\n for (const ns of ctx.tailordb) {\n const typesWithFiles: FileUtilMetadata[] = [];\n\n for (const type of Object.values(ns.types)) {\n const metadata = await processFileType(type);\n if (metadata.fileFields.length > 0) {\n typesWithFiles.push(metadata);\n }\n }\n\n if (typesWithFiles.length > 0) {\n namespaceData.push({\n namespace: ns.namespace,\n types: typesWithFiles,\n });\n }\n }\n\n const files: GeneratorResult[\"files\"] = [];\n if (namespaceData.length > 0) {\n const content = generateUnifiedFileUtils(namespaceData);\n if (content) {\n files.push({\n path: ctx.pluginConfig.distPath,\n content,\n });\n }\n }\n\n return { files };\n },\n };\n}\n"],"mappings":";;;;;;;;AAQA,SAAgB,yBACd,eACQ;CACR,IAAI,cAAc,WAAW,GAC3B,OAAO;CAIT,MAAM,mCAAmB,IAAI,IAAoB;CACjD,MAAM,gCAAgB,IAAI,IAAsB;CAEhD,KAAK,MAAM,EAAE,WAAW,WAAW,eACjC,KAAK,MAAM,QAAQ,OAAO;EACxB,iBAAiB,IAAI,KAAK,MAAM,SAAS;EACzC,cAAc,IAAI,KAAK,MAAM,KAAK,UAAU;CAC9C;CAGF,IAAI,iBAAiB,SAAS,GAC5B,OAAO;CAIT,MAAM,kBAAkB,MAAM,KAAK,cAAc,QAAQ,CAAC,CAAC,CACxD,KAAK,CAAC,UAAU,YAAY;EAE3B,OAAO,KAAK,SAAS,mBADG,OAAO,KAAK,UAAU,IAAI,MAAM,EAAE,CAAC,CAAC,KAAK,KACX,EAAE;CAC1D,CAAC,CAAC,CACD,KAAK,IAAI;CA8FZ,OAAO;EA3FL,SAAmB;;;;;;;;QAQf;EAGJ,SAAmB;;QAEf,gBAAgB;;QAEhB;EAQJ,SAAmB;;QALI,MAAM,KAAK,iBAAiB,QAAQ,CAAC,CAAC,CAC5D,KAAK,CAAC,UAAU,eAAe,KAAK,SAAS,KAAK,UAAU,EAAE,CAAC,CAC/D,KAAK,KAKa,EAAE;;QAEjB;EAIJ,SAAmB;;;;;;;;QAQf;EAIJ,SAAmB;;;;;;;;;;QAUf;EAIJ,SAAmB;;;;;;;;QAQf;EAIJ,SAAmB;;;;;;;;QAQf;EAIJ,SAAmB;;;;;;;;QAQf;CAWN,CAAC,CAAC,KAAK,IAAI;AACb;;;;;;;;;ACpIA,eAAsB,gBAAgB,MAA+C;CACnF,MAAM,aAAuB,CAAC;CAE9B,IAAI,KAAK,OACP,KAAK,MAAM,iBAAiB,OAAO,KAAK,KAAK,KAAK,GAChD,WAAW,KAAK,aAAa;CAIjC,OAAO;EACL,MAAM,KAAK;EACX;CACF;AACF;;;;;ACfA,MAAa,uBAAuB;;;;;;;AAYpC,SAAgB,gBACd,SACyC;CACzC,OAAO;EACL,IAAI;EACJ,aAAa;EACb,cAAc;EAEd,MAAM,gBACJ,KAC0B;GAC1B,MAAM,gBAAoE,CAAC;GAE3E,KAAK,MAAM,MAAM,IAAI,UAAU;IAC7B,MAAM,iBAAqC,CAAC;IAE5C,KAAK,MAAM,QAAQ,OAAO,OAAO,GAAG,KAAK,GAAG;KAC1C,MAAM,WAAW,MAAM,gBAAgB,IAAI;KAC3C,IAAI,SAAS,WAAW,SAAS,GAC/B,eAAe,KAAK,QAAQ;IAEhC;IAEA,IAAI,eAAe,SAAS,GAC1B,cAAc,KAAK;KACjB,WAAW,GAAG;KACd,OAAO;IACT,CAAC;GAEL;GAEA,MAAM,QAAkC,CAAC;GACzC,IAAI,cAAc,SAAS,GAAG;IAC5B,MAAM,UAAU,yBAAyB,aAAa;IACtD,IAAI,SACF,MAAM,KAAK;KACT,MAAM,IAAI,aAAa;KACvB;IACF,CAAC;GAEL;GAEA,OAAO,EAAE,MAAM;EACjB;CACF;AACF"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/plugin/builtin/file-utils/generate-file-utils.ts","../../../../src/plugin/builtin/file-utils/process-file-type.ts","../../../../src/plugin/builtin/file-utils/index.ts"],"sourcesContent":["import multiline from \"#/utils/multiline\";\nimport type { FileUtilMetadata } from \"./types\";\n\n/**\n * Generate unified file utility functions from collected metadata.\n * @param namespaceData - Namespace data with file utility metadata\n * @returns Generated file utility code\n */\nexport function generateUnifiedFileUtils(\n namespaceData: { namespace: string; types: FileUtilMetadata[] }[],\n): string {\n if (namespaceData.length === 0) {\n return \"\";\n }\n\n // Collect all types with their namespace\n const typeNamespaceMap = new Map<string, string>();\n const typeFieldsMap = new Map<string, string[]>();\n\n for (const { namespace, types } of namespaceData) {\n for (const type of types) {\n typeNamespaceMap.set(type.name, namespace);\n typeFieldsMap.set(type.name, type.fileFields);\n }\n }\n\n if (typeNamespaceMap.size === 0) {\n return \"\";\n }\n\n // Generate interface fields\n const interfaceFields = Array.from(typeFieldsMap.entries())\n .map(([typeName, fields]) => {\n const fieldNamesUnion = fields.map((field) => `\"${field}\"`).join(\" | \");\n return ` ${typeName}: {\\n fields: ${fieldNamesUnion};\\n };`;\n })\n .join(\"\\n\");\n\n const importStatement =\n multiline /* ts */ `\n import { file } from \"@tailor-platform/sdk/runtime/file\";\n import type {\n FileUploadOptions,\n FileUploadResponse,\n FileMetadata,\n FileDownloadStreamResponse,\n } from \"@tailor-platform/sdk/runtime/file\";\n ` + \"\\n\";\n\n const interfaceDefinition =\n multiline /* ts */ `\n export interface TypeWithFiles {\n ${interfaceFields}\n }\n ` + \"\\n\";\n\n // Generate namespaces object\n const namespaceEntries = Array.from(typeNamespaceMap.entries())\n .map(([typeName, namespace]) => ` ${typeName}: \"${namespace}\"`)\n .join(\",\\n\");\n\n const namespacesDefinition =\n multiline /* ts */ `\n const namespaces: Record<keyof TypeWithFiles, string> = {\n ${namespaceEntries},\n };\n ` + \"\\n\";\n\n // Generate downloadFile helper function\n const downloadFunction =\n multiline /* ts */ `\n export async function downloadFile<T extends keyof TypeWithFiles>(\n type: T,\n field: TypeWithFiles[T][\"fields\"],\n recordId: string,\n ) {\n return await file.download(namespaces[type], type, field, recordId);\n }\n ` + \"\\n\";\n\n // Generate uploadFile helper function\n const uploadFunction =\n multiline /* ts */ `\n export async function uploadFile<T extends keyof TypeWithFiles>(\n type: T,\n field: TypeWithFiles[T][\"fields\"],\n recordId: string,\n data: string | ArrayBuffer | Uint8Array<ArrayBufferLike> | number[],\n options?: FileUploadOptions,\n ): Promise<FileUploadResponse> {\n return await file.upload(namespaces[type], type, field, recordId, data, options);\n }\n ` + \"\\n\";\n\n // Generate deleteFile helper function\n const deleteFunction =\n multiline /* ts */ `\n export async function deleteFile<T extends keyof TypeWithFiles>(\n type: T,\n field: TypeWithFiles[T][\"fields\"],\n recordId: string,\n ): Promise<void> {\n return await file.delete(namespaces[type], type, field, recordId);\n }\n ` + \"\\n\";\n\n // Generate getFileMetadata helper function\n const getMetadataFunction =\n multiline /* ts */ `\n export async function getFileMetadata<T extends keyof TypeWithFiles>(\n type: T,\n field: TypeWithFiles[T][\"fields\"],\n recordId: string,\n ): Promise<FileMetadata> {\n return await file.getMetadata(namespaces[type], type, field, recordId);\n }\n ` + \"\\n\";\n\n // Generate downloadFileStream helper function\n const downloadStreamFunction =\n multiline /* ts */ `\n export async function downloadFileStream<T extends keyof TypeWithFiles>(\n type: T,\n field: TypeWithFiles[T][\"fields\"],\n recordId: string,\n ): Promise<FileDownloadStreamResponse> {\n return await file.downloadStream(namespaces[type], type, field, recordId);\n }\n ` + \"\\n\";\n\n return [\n importStatement,\n interfaceDefinition,\n namespacesDefinition,\n downloadFunction,\n uploadFunction,\n deleteFunction,\n getMetadataFunction,\n downloadStreamFunction,\n ].join(\"\\n\");\n}\n","import type { TailorDBType } from \"#/parser/service/tailordb/types\";\nimport type { FileUtilMetadata } from \"./types\";\n\n/**\n * Process a TailorDB table and extract file field metadata.\n * @param type - The parsed TailorDB table to process\n * @returns File utility metadata for the table\n */\nexport async function processFileType(type: TailorDBType): Promise<FileUtilMetadata> {\n const fileFields: string[] = [];\n\n if (type.files) {\n for (const fileFieldName of Object.keys(type.files)) {\n fileFields.push(fileFieldName);\n }\n }\n\n return {\n name: type.name,\n fileFields,\n };\n}\n","import { generateUnifiedFileUtils } from \"./generate-file-utils\";\nimport { processFileType } from \"./process-file-type\";\nimport type { Plugin, GeneratorResult, TailorDBReadyContext } from \"#/plugin/types\";\nimport type { FileUtilMetadata } from \"./types\";\n\n/** Unique identifier for the file utilities generator plugin. */\nexport const FileUtilsGeneratorID = \"@tailor-platform/file-utils\";\n\ntype FileUtilsPluginOptions = {\n distPath: string;\n};\n\n/**\n * Plugin that generates TypeWithFiles interface from TailorDB table definitions.\n * @param options - Plugin options\n * @param options.distPath - Output file path for generated file utilities\n * @returns Plugin instance with onTailorDBReady hook\n */\nexport function fileUtilsPlugin(\n options: FileUtilsPluginOptions,\n): Plugin<unknown, FileUtilsPluginOptions> {\n return {\n id: FileUtilsGeneratorID,\n description: \"Generates TypeWithFiles interface from TailorDB table definitions\",\n pluginConfig: options,\n\n async onTailorDBReady(\n ctx: TailorDBReadyContext<FileUtilsPluginOptions>,\n ): Promise<GeneratorResult> {\n const namespaceData: { namespace: string; types: FileUtilMetadata[] }[] = [];\n\n for (const ns of ctx.tailordb) {\n const typesWithFiles: FileUtilMetadata[] = [];\n\n for (const type of Object.values(ns.types)) {\n const metadata = await processFileType(type);\n if (metadata.fileFields.length > 0) {\n typesWithFiles.push(metadata);\n }\n }\n\n if (typesWithFiles.length > 0) {\n namespaceData.push({\n namespace: ns.namespace,\n types: typesWithFiles,\n });\n }\n }\n\n const files: GeneratorResult[\"files\"] = [];\n if (namespaceData.length > 0) {\n const content = generateUnifiedFileUtils(namespaceData);\n if (content) {\n files.push({\n path: ctx.pluginConfig.distPath,\n content,\n });\n }\n }\n\n return { files };\n },\n };\n}\n"],"mappings":";;;;;;;;AAQA,SAAgB,yBACd,eACQ;CACR,IAAI,cAAc,WAAW,GAC3B,OAAO;CAIT,MAAM,mCAAmB,IAAI,IAAoB;CACjD,MAAM,gCAAgB,IAAI,IAAsB;CAEhD,KAAK,MAAM,EAAE,WAAW,WAAW,eACjC,KAAK,MAAM,QAAQ,OAAO;EACxB,iBAAiB,IAAI,KAAK,MAAM,SAAS;EACzC,cAAc,IAAI,KAAK,MAAM,KAAK,UAAU;CAC9C;CAGF,IAAI,iBAAiB,SAAS,GAC5B,OAAO;CAIT,MAAM,kBAAkB,MAAM,KAAK,cAAc,QAAQ,CAAC,CAAC,CACxD,KAAK,CAAC,UAAU,YAAY;EAE3B,OAAO,KAAK,SAAS,mBADG,OAAO,KAAK,UAAU,IAAI,MAAM,EAAE,CAAC,CAAC,KAAK,KACX,EAAE;CAC1D,CAAC,CAAC,CACD,KAAK,IAAI;CAEZ,MAAM,kBACJ,SAAmB;;;;;;;;QAQf;CAEN,MAAM,sBACJ,SAAmB;;QAEf,gBAAgB;;QAEhB;CAGN,MAAM,mBAAmB,MAAM,KAAK,iBAAiB,QAAQ,CAAC,CAAC,CAC5D,KAAK,CAAC,UAAU,eAAe,KAAK,SAAS,KAAK,UAAU,EAAE,CAAC,CAC/D,KAAK,KAAK;CAuEb,OAAO;EACL;EACA;EAtEA,SAAmB;;QAEf,iBAAiB;;QAEjB;EAIJ,SAAmB;;;;;;;;QAQf;EAIJ,SAAmB;;;;;;;;;;QAUf;EAIJ,SAAmB;;;;;;;;QAQf;EAIJ,SAAmB;;;;;;;;QAQf;EAIJ,SAAmB;;;;;;;;QAQf;CAWN,CAAC,CAAC,KAAK,IAAI;AACb;;;;;;;;;ACpIA,eAAsB,gBAAgB,MAA+C;CACnF,MAAM,aAAuB,CAAC;CAE9B,IAAI,KAAK,OACP,KAAK,MAAM,iBAAiB,OAAO,KAAK,KAAK,KAAK,GAChD,WAAW,KAAK,aAAa;CAIjC,OAAO;EACL,MAAM,KAAK;EACX;CACF;AACF;;;;;ACfA,MAAa,uBAAuB;;;;;;;AAYpC,SAAgB,gBACd,SACyC;CACzC,OAAO;EACL,IAAI;EACJ,aAAa;EACb,cAAc;EAEd,MAAM,gBACJ,KAC0B;GAC1B,MAAM,gBAAoE,CAAC;GAE3E,KAAK,MAAM,MAAM,IAAI,UAAU;IAC7B,MAAM,iBAAqC,CAAC;IAE5C,KAAK,MAAM,QAAQ,OAAO,OAAO,GAAG,KAAK,GAAG;KAC1C,MAAM,WAAW,MAAM,gBAAgB,IAAI;KAC3C,IAAI,SAAS,WAAW,SAAS,GAC/B,eAAe,KAAK,QAAQ;IAEhC;IAEA,IAAI,eAAe,SAAS,GAC1B,cAAc,KAAK;KACjB,WAAW,GAAG;KACd,OAAO;IACT,CAAC;GAEL;GAEA,MAAM,QAAkC,CAAC;GACzC,IAAI,cAAc,SAAS,GAAG;IAC5B,MAAM,UAAU,yBAAyB,aAAa;IACtD,IAAI,SACF,MAAM,KAAK;KACT,MAAM,IAAI,aAAa;KACvB;IACF,CAAC;GAEL;GAEA,OAAO,EAAE,MAAM;EACjB;CACF;AACF"}
@@ -6,7 +6,7 @@ type KyselyTypePluginOptions = {
6
6
  distPath: string;
7
7
  };
8
8
  /**
9
- * Plugin that generates Kysely type definitions for TailorDB types.
9
+ * Plugin that generates Kysely type definitions for TailorDB tables.
10
10
  * @param options - Plugin options
11
11
  * @param options.distPath - Output file path for generated types
12
12
  * @returns Plugin instance with onTailorDBReady hook
@@ -89,9 +89,7 @@ function getBaseType(fieldConfig) {
89
89
  type = getEnumType(fieldConfig);
90
90
  break;
91
91
  case "nested": return getNestedType(fieldConfig);
92
- default:
93
- type = "string";
94
- break;
92
+ default: type = "string";
95
93
  }
96
94
  return {
97
95
  type,
@@ -110,8 +108,10 @@ function generateFieldType(fieldConfig) {
110
108
  const isNullable = fieldConfig.required !== true;
111
109
  const isColumnTypeBase = (/* @__PURE__ */ new Set(["Timestamp"])).has(baseTypeResult.type);
112
110
  let finalType = baseTypeResult.type;
113
- if (isArray) if (isColumnTypeBase || finalType.startsWith("ObjectColumnType<")) finalType = `ArrayColumnType<${baseTypeResult.type}>`;
114
- else finalType = fieldConfig.type === "enum" ? `(${baseTypeResult.type})[]` : `${baseTypeResult.type}[]`;
111
+ if (isArray) {
112
+ if (isColumnTypeBase || finalType.startsWith("ObjectColumnType<")) finalType = `ArrayColumnType<${baseTypeResult.type}>`;
113
+ else finalType = fieldConfig.type === "enum" ? `(${baseTypeResult.type})[]` : `${baseTypeResult.type}[]`;
114
+ }
115
115
  if (isNullable) finalType = `${finalType} | null`;
116
116
  if (fieldConfig.serial) {
117
117
  usedUtilityTypes.Serial = true;
@@ -125,7 +125,7 @@ function generateFieldType(fieldConfig) {
125
125
  }
126
126
  /**
127
127
  * Generate the table interface.
128
- * @param type - The parsed TailorDB type
128
+ * @param type - The parsed TailorDB table
129
129
  * @returns The type definition and used utility types
130
130
  */
131
131
  function generateTableInterface(type) {
@@ -152,7 +152,7 @@ function generateTableInterface(type) {
152
152
  }
153
153
  /**
154
154
  * Convert a TailorDBType into KyselyTypeMetadata.
155
- * @param type - Parsed TailorDB type
155
+ * @param type - Parsed TailorDB table
156
156
  * @returns Generated Kysely type metadata
157
157
  */
158
158
  async function processKyselyType(type) {
@@ -225,7 +225,7 @@ function generateUnifiedKyselyTypes(namespaceData) {
225
225
  /** Unique identifier for the Kysely type generator plugin. */
226
226
  const KyselyGeneratorID = "@tailor-platform/kysely-type";
227
227
  /**
228
- * Plugin that generates Kysely type definitions for TailorDB types.
228
+ * Plugin that generates Kysely type definitions for TailorDB tables.
229
229
  * @param options - Plugin options
230
230
  * @param options.distPath - Output file path for generated types
231
231
  * @returns Plugin instance with onTailorDBReady hook
@@ -233,7 +233,7 @@ const KyselyGeneratorID = "@tailor-platform/kysely-type";
233
233
  function kyselyTypePlugin(options) {
234
234
  return {
235
235
  id: KyselyGeneratorID,
236
- description: "Generates Kysely type definitions for TailorDB types",
236
+ description: "Generates Kysely type definitions for TailorDB tables",
237
237
  pluginConfig: options,
238
238
  async onTailorDBReady(ctx) {
239
239
  const allNamespaceData = [];
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/plugin/builtin/kysely-type/type-processor.ts","../../../../src/plugin/builtin/kysely-type/index.ts"],"sourcesContent":["import multiline from \"#/utils/multiline\";\nimport { type KyselyNamespaceMetadata, type KyselyTypeMetadata } from \"./types\";\nimport type { OperatorFieldConfig, TailorDBType } from \"#/parser/service/tailordb/types\";\n\ntype UsedUtilityTypes = { Timestamp: boolean; Serial: boolean };\n\ntype FieldTypeResult = {\n type: string;\n usedUtilityTypes: UsedUtilityTypes;\n};\n\n/**\n * Get the enum type definition.\n * @param fieldConfig - The field configuration\n * @returns The enum type as a string union\n */\nfunction getEnumType(fieldConfig: OperatorFieldConfig): string {\n const allowedValues = fieldConfig.allowedValues;\n\n if (allowedValues && Array.isArray(allowedValues)) {\n return allowedValues\n .map((v: string | { value: string }) => {\n const value = typeof v === \"string\" ? v : v.value;\n return `\"${value}\"`;\n })\n .join(\" | \");\n }\n return \"string\";\n}\n\n/**\n * Get the nested object type definition.\n * @param fieldConfig - The field configuration\n * @returns The nested type with used utility types\n */\nfunction getNestedType(fieldConfig: OperatorFieldConfig): FieldTypeResult {\n const fields = fieldConfig.fields;\n if (!fields || typeof fields !== \"object\") {\n return {\n type: \"string\",\n usedUtilityTypes: { Timestamp: false, Serial: false },\n };\n }\n\n const fieldResults = Object.entries(fields).map(([fieldName, config]) => {\n const result = generateFieldType(config);\n const optional = config.required !== true ? \"?\" : \"\";\n return {\n fieldType: `${fieldName}${optional}: ${result.type}`,\n usedUtilityTypes: result.usedUtilityTypes,\n };\n });\n\n const aggregatedUtilityTypes = fieldResults.reduce(\n (acc, result) => ({\n Timestamp: acc.Timestamp || result.usedUtilityTypes.Timestamp,\n Serial: acc.Serial || result.usedUtilityTypes.Serial,\n }),\n { Timestamp: false, Serial: false },\n );\n\n const fieldTypes = fieldResults.map((r) => r.fieldType);\n const obj = `{\\n ${fieldTypes.join(\";\\n \")}${fieldTypes.length > 0 ? \";\" : \"\"}\\n}`;\n\n const hasOptionalFields = Object.values(fields).some((config) => config.required !== true);\n const hasGeneratedFields = Object.values(fields).some(\n (config) => config.hooks?.create || config.default !== undefined,\n );\n if (aggregatedUtilityTypes.Timestamp || hasOptionalFields || hasGeneratedFields) {\n return { type: `ObjectColumnType<${obj}>`, usedUtilityTypes: aggregatedUtilityTypes };\n }\n return { type: obj, usedUtilityTypes: aggregatedUtilityTypes };\n}\n\n/**\n * Get the base Kysely type for a field (without array/null modifiers).\n * @param fieldConfig - The field configuration\n * @returns The base type with used utility types\n */\nfunction getBaseType(fieldConfig: OperatorFieldConfig): FieldTypeResult {\n const fieldType = fieldConfig.type;\n const usedUtilityTypes = { Timestamp: false, Serial: false };\n\n let type: string;\n switch (fieldType) {\n case \"uuid\":\n case \"string\":\n case \"decimal\":\n type = \"string\";\n break;\n case \"integer\":\n case \"float\":\n type = \"number\";\n break;\n case \"date\":\n case \"datetime\":\n usedUtilityTypes.Timestamp = true;\n type = \"Timestamp\";\n break;\n case \"bool\":\n case \"boolean\":\n type = \"boolean\";\n break;\n case \"enum\":\n type = getEnumType(fieldConfig);\n break;\n case \"nested\": {\n const nestedResult = getNestedType(fieldConfig);\n return nestedResult;\n }\n default:\n type = \"string\";\n break;\n }\n\n return { type, usedUtilityTypes };\n}\n\n/**\n * Generate the complete field type including array and null modifiers.\n * @param fieldConfig - The field configuration\n * @returns The complete field type with used utility types\n */\nfunction generateFieldType(fieldConfig: OperatorFieldConfig): FieldTypeResult {\n const baseTypeResult = getBaseType(fieldConfig);\n const usedUtilityTypes = { ...baseTypeResult.usedUtilityTypes };\n\n const isArray = fieldConfig.array === true;\n const isNullable = fieldConfig.required !== true;\n\n // Types that use ColumnType internally (Timestamp, ObjectColumnType) cannot be\n // directly wrapped with [] for arrays, because Kysely only resolves ColumnType at\n // the top-level table property. Use ArrayColumnType/ObjectArrayColumnType to keep\n // the ColumnType at the top level with arrays inside.\n const columnTypeBaseTypes = new Set([\"Timestamp\"]);\n const isColumnTypeBase = columnTypeBaseTypes.has(baseTypeResult.type);\n\n let finalType = baseTypeResult.type;\n if (isArray) {\n if (isColumnTypeBase || finalType.startsWith(\"ObjectColumnType<\")) {\n finalType = `ArrayColumnType<${baseTypeResult.type}>`;\n } else {\n const needsParens = fieldConfig.type === \"enum\";\n finalType = needsParens ? `(${baseTypeResult.type})[]` : `${baseTypeResult.type}[]`;\n }\n }\n if (isNullable) {\n finalType = `${finalType} | null`;\n }\n\n if (fieldConfig.serial) {\n usedUtilityTypes.Serial = true;\n finalType = `Serial<${finalType}>`;\n }\n if (fieldConfig.hooks?.create || fieldConfig.default !== undefined) {\n finalType = `Generated<${finalType}>`;\n }\n\n return { type: finalType, usedUtilityTypes };\n}\n\n/**\n * Generate the table interface.\n * @param type - The parsed TailorDB type\n * @returns The type definition and used utility types\n */\nfunction generateTableInterface(type: TailorDBType): {\n typeDef: string;\n usedUtilityTypes: UsedUtilityTypes;\n} {\n const fieldEntries = Object.entries(type.fields).filter(([fieldName]) => fieldName !== \"id\");\n\n const fieldResults = fieldEntries.map(([fieldName, parsedField]) => ({\n fieldName,\n ...generateFieldType(parsedField.config),\n }));\n\n const fields = [\n \"id: Generated<string>;\",\n ...fieldResults.map((result) => `${result.fieldName}: ${result.type};`),\n ];\n\n const aggregatedUtilityTypes = fieldResults.reduce(\n (acc, result) => ({\n Timestamp: acc.Timestamp || result.usedUtilityTypes.Timestamp,\n\n Serial: acc.Serial || result.usedUtilityTypes.Serial,\n }),\n { Timestamp: false, Serial: false },\n );\n\n const typeDef = multiline /* ts */ `\n ${type.name}: {\n ${fields.join(\"\\n\")}\n }\n `;\n\n return { typeDef, usedUtilityTypes: aggregatedUtilityTypes };\n}\n\n/**\n * Convert a TailorDBType into KyselyTypeMetadata.\n * @param type - Parsed TailorDB type\n * @returns Generated Kysely type metadata\n */\nexport async function processKyselyType(type: TailorDBType): Promise<KyselyTypeMetadata> {\n const result = generateTableInterface(type);\n\n return {\n name: type.name,\n typeDef: result.typeDef,\n usedUtilityTypes: result.usedUtilityTypes,\n };\n}\n\n/**\n * Generate unified types file from multiple namespaces.\n * @param namespaceData - Namespace metadata\n * @returns Generated types file contents\n */\nexport function generateUnifiedKyselyTypes(namespaceData: KyselyNamespaceMetadata[]): string {\n if (namespaceData.length === 0) {\n return \"\";\n }\n\n // Aggregate used utility types from all namespaces\n const globalUsedUtilityTypes = namespaceData.reduce(\n (acc, ns) => ({\n Timestamp: acc.Timestamp || ns.usedUtilityTypes.Timestamp,\n Serial: acc.Serial || ns.usedUtilityTypes.Serial,\n }),\n { Timestamp: false, Serial: false },\n );\n\n const utilityTypeImports: string[] = [\"type Generated\"];\n if (globalUsedUtilityTypes.Timestamp) {\n utilityTypeImports.push(\"type Timestamp\");\n }\n const hasObjectColumnType = namespaceData.some((ns) =>\n ns.types.some((t) => t.typeDef.includes(\"ObjectColumnType<\")),\n );\n if (hasObjectColumnType) {\n utilityTypeImports.push(\"type ObjectColumnType\");\n }\n const hasArrayColumnType = namespaceData.some((ns) =>\n ns.types.some((t) => t.typeDef.includes(\"ArrayColumnType<\")),\n );\n if (hasArrayColumnType) {\n utilityTypeImports.push(\"type ArrayColumnType\");\n }\n if (globalUsedUtilityTypes.Serial) {\n utilityTypeImports.push(\"type Serial\");\n }\n\n const importsSection = multiline /* ts */ `\n import {\n createGetDB,\n ${utilityTypeImports.join(\",\\n\")},\n type NamespaceDB,\n type NamespaceInsertable,\n type NamespaceSelectable,\n type NamespaceTable,\n type NamespaceTableName,\n type NamespaceTransaction,\n type NamespaceUpdateable,\n } from \"@tailor-platform/sdk/kysely\";\n `;\n\n // Generate Namespace interface with multiple namespaces\n const namespaceInterfaces = namespaceData\n .map(({ namespace, types }) => {\n const typeDefsWithIndent = types\n .map((type) => {\n return type.typeDef\n .split(\"\\n\")\n .map((line) => (line.trim() ? ` ${line}` : \"\"))\n .join(\"\\n\");\n })\n .join(\"\\n\\n\");\n\n return ` \"${namespace}\": {\\n${typeDefsWithIndent}\\n }`;\n })\n .join(\",\\n\");\n\n const namespaceInterface = `export interface Namespace {\\n${namespaceInterfaces}\\n}`;\n\n const getDBFunction = multiline /* ts */ `\n export const getDB = createGetDB<Namespace>();\n\n export type DB<N extends keyof Namespace = keyof Namespace> = NamespaceDB<Namespace, N>;\n `;\n\n const utilityTypeExports = multiline /* ts */ `\n export type Transaction<K extends keyof Namespace | DB = keyof Namespace> =\n NamespaceTransaction<Namespace, K>;\n\n type TableName = NamespaceTableName<Namespace>;\n export type Table<T extends TableName> = NamespaceTable<Namespace, T>;\n\n export type Insertable<T extends TableName> = NamespaceInsertable<Namespace, T>;\n export type Selectable<T extends TableName> = NamespaceSelectable<Namespace, T>;\n export type Updateable<T extends TableName> = NamespaceUpdateable<Namespace, T>;\n `;\n\n return (\n [importsSection, namespaceInterface, getDBFunction, utilityTypeExports].join(\"\\n\\n\") + \"\\n\"\n );\n}\n","import { processKyselyType, generateUnifiedKyselyTypes } from \"./type-processor\";\nimport type { Plugin, GeneratorResult, TailorDBReadyContext } from \"#/plugin/types\";\nimport type { KyselyTypeMetadata, KyselyNamespaceMetadata } from \"./types\";\n\n/** Unique identifier for the Kysely type generator plugin. */\nexport const KyselyGeneratorID = \"@tailor-platform/kysely-type\";\n\ntype KyselyTypePluginOptions = {\n distPath: string;\n};\n\n/**\n * Plugin that generates Kysely type definitions for TailorDB types.\n * @param options - Plugin options\n * @param options.distPath - Output file path for generated types\n * @returns Plugin instance with onTailorDBReady hook\n */\nexport function kyselyTypePlugin(\n options: KyselyTypePluginOptions,\n): Plugin<unknown, KyselyTypePluginOptions> {\n return {\n id: KyselyGeneratorID,\n description: \"Generates Kysely type definitions for TailorDB types\",\n pluginConfig: options,\n\n async onTailorDBReady(\n ctx: TailorDBReadyContext<KyselyTypePluginOptions>,\n ): Promise<GeneratorResult> {\n const allNamespaceData: KyselyNamespaceMetadata[] = [];\n\n for (const ns of ctx.tailordb) {\n const typeMetadataList: KyselyTypeMetadata[] = [];\n\n for (const type of Object.values(ns.types)) {\n const metadata = await processKyselyType(type);\n typeMetadataList.push(metadata);\n }\n\n if (typeMetadataList.length === 0) continue;\n\n const usedUtilityTypes = typeMetadataList.reduce(\n (acc, type) => ({\n Timestamp: acc.Timestamp || type.usedUtilityTypes.Timestamp,\n Serial: acc.Serial || type.usedUtilityTypes.Serial,\n }),\n { Timestamp: false, Serial: false },\n );\n\n allNamespaceData.push({\n namespace: ns.namespace,\n types: typeMetadataList,\n usedUtilityTypes,\n });\n }\n\n const files: GeneratorResult[\"files\"] = [];\n if (allNamespaceData.length > 0) {\n const content = generateUnifiedKyselyTypes(allNamespaceData);\n files.push({\n path: ctx.pluginConfig.distPath,\n content,\n });\n }\n\n return { files };\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../../../src/plugin/builtin/kysely-type/type-processor.ts","../../../../src/plugin/builtin/kysely-type/index.ts"],"sourcesContent":["import multiline from \"#/utils/multiline\";\nimport { type KyselyNamespaceMetadata, type KyselyTypeMetadata } from \"./types\";\nimport type { OperatorFieldConfig, TailorDBType } from \"#/parser/service/tailordb/types\";\n\ntype UsedUtilityTypes = { Timestamp: boolean; Serial: boolean };\n\ntype FieldTypeResult = {\n type: string;\n usedUtilityTypes: UsedUtilityTypes;\n};\n\n/**\n * Get the enum type definition.\n * @param fieldConfig - The field configuration\n * @returns The enum type as a string union\n */\nfunction getEnumType(fieldConfig: OperatorFieldConfig): string {\n const allowedValues = fieldConfig.allowedValues;\n\n if (allowedValues && Array.isArray(allowedValues)) {\n return allowedValues\n .map((v: string | { value: string }) => {\n const value = typeof v === \"string\" ? v : v.value;\n return `\"${value}\"`;\n })\n .join(\" | \");\n }\n return \"string\";\n}\n\n/**\n * Get the nested object type definition.\n * @param fieldConfig - The field configuration\n * @returns The nested type with used utility types\n */\nfunction getNestedType(fieldConfig: OperatorFieldConfig): FieldTypeResult {\n const fields = fieldConfig.fields;\n if (!fields || typeof fields !== \"object\") {\n return {\n type: \"string\",\n usedUtilityTypes: { Timestamp: false, Serial: false },\n };\n }\n\n const fieldResults = Object.entries(fields).map(([fieldName, config]) => {\n const result = generateFieldType(config);\n const optional = config.required !== true ? \"?\" : \"\";\n return {\n fieldType: `${fieldName}${optional}: ${result.type}`,\n usedUtilityTypes: result.usedUtilityTypes,\n };\n });\n\n const aggregatedUtilityTypes = fieldResults.reduce(\n (acc, result) => ({\n Timestamp: acc.Timestamp || result.usedUtilityTypes.Timestamp,\n Serial: acc.Serial || result.usedUtilityTypes.Serial,\n }),\n { Timestamp: false, Serial: false },\n );\n\n const fieldTypes = fieldResults.map((r) => r.fieldType);\n const obj = `{\\n ${fieldTypes.join(\";\\n \")}${fieldTypes.length > 0 ? \";\" : \"\"}\\n}`;\n\n const hasOptionalFields = Object.values(fields).some((config) => config.required !== true);\n const hasGeneratedFields = Object.values(fields).some(\n (config) => config.hooks?.create || config.default !== undefined,\n );\n if (aggregatedUtilityTypes.Timestamp || hasOptionalFields || hasGeneratedFields) {\n return { type: `ObjectColumnType<${obj}>`, usedUtilityTypes: aggregatedUtilityTypes };\n }\n return { type: obj, usedUtilityTypes: aggregatedUtilityTypes };\n}\n\n/**\n * Get the base Kysely type for a field (without array/null modifiers).\n * @param fieldConfig - The field configuration\n * @returns The base type with used utility types\n */\nfunction getBaseType(fieldConfig: OperatorFieldConfig): FieldTypeResult {\n const fieldType = fieldConfig.type;\n const usedUtilityTypes = { Timestamp: false, Serial: false };\n\n let type: string;\n switch (fieldType) {\n case \"uuid\":\n case \"string\":\n case \"decimal\":\n type = \"string\";\n break;\n case \"integer\":\n case \"float\":\n type = \"number\";\n break;\n case \"date\":\n case \"datetime\":\n usedUtilityTypes.Timestamp = true;\n type = \"Timestamp\";\n break;\n case \"bool\":\n case \"boolean\":\n type = \"boolean\";\n break;\n case \"enum\":\n type = getEnumType(fieldConfig);\n break;\n case \"nested\": {\n const nestedResult = getNestedType(fieldConfig);\n return nestedResult;\n }\n default:\n type = \"string\";\n break;\n }\n\n return { type, usedUtilityTypes };\n}\n\n/**\n * Generate the complete field type including array and null modifiers.\n * @param fieldConfig - The field configuration\n * @returns The complete field type with used utility types\n */\nfunction generateFieldType(fieldConfig: OperatorFieldConfig): FieldTypeResult {\n const baseTypeResult = getBaseType(fieldConfig);\n const usedUtilityTypes = { ...baseTypeResult.usedUtilityTypes };\n\n const isArray = fieldConfig.array === true;\n const isNullable = fieldConfig.required !== true;\n\n // Types that use ColumnType internally (Timestamp, ObjectColumnType) cannot be\n // directly wrapped with [] for arrays, because Kysely only resolves ColumnType at\n // the top-level table property. Use ArrayColumnType/ObjectArrayColumnType to keep\n // the ColumnType at the top level with arrays inside.\n const columnTypeBaseTypes = new Set([\"Timestamp\"]);\n const isColumnTypeBase = columnTypeBaseTypes.has(baseTypeResult.type);\n\n let finalType = baseTypeResult.type;\n if (isArray) {\n if (isColumnTypeBase || finalType.startsWith(\"ObjectColumnType<\")) {\n finalType = `ArrayColumnType<${baseTypeResult.type}>`;\n } else {\n const needsParens = fieldConfig.type === \"enum\";\n finalType = needsParens ? `(${baseTypeResult.type})[]` : `${baseTypeResult.type}[]`;\n }\n }\n if (isNullable) {\n finalType = `${finalType} | null`;\n }\n\n if (fieldConfig.serial) {\n usedUtilityTypes.Serial = true;\n finalType = `Serial<${finalType}>`;\n }\n if (fieldConfig.hooks?.create || fieldConfig.default !== undefined) {\n finalType = `Generated<${finalType}>`;\n }\n\n return { type: finalType, usedUtilityTypes };\n}\n\n/**\n * Generate the table interface.\n * @param type - The parsed TailorDB table\n * @returns The type definition and used utility types\n */\nfunction generateTableInterface(type: TailorDBType): {\n typeDef: string;\n usedUtilityTypes: UsedUtilityTypes;\n} {\n const fieldEntries = Object.entries(type.fields).filter(([fieldName]) => fieldName !== \"id\");\n\n const fieldResults = fieldEntries.map(([fieldName, parsedField]) => ({\n fieldName,\n ...generateFieldType(parsedField.config),\n }));\n\n const fields = [\n \"id: Generated<string>;\",\n ...fieldResults.map((result) => `${result.fieldName}: ${result.type};`),\n ];\n\n const aggregatedUtilityTypes = fieldResults.reduce(\n (acc, result) => ({\n Timestamp: acc.Timestamp || result.usedUtilityTypes.Timestamp,\n\n Serial: acc.Serial || result.usedUtilityTypes.Serial,\n }),\n { Timestamp: false, Serial: false },\n );\n\n const typeDef = multiline /* ts */ `\n ${type.name}: {\n ${fields.join(\"\\n\")}\n }\n `;\n\n return { typeDef, usedUtilityTypes: aggregatedUtilityTypes };\n}\n\n/**\n * Convert a TailorDBType into KyselyTypeMetadata.\n * @param type - Parsed TailorDB table\n * @returns Generated Kysely type metadata\n */\nexport async function processKyselyType(type: TailorDBType): Promise<KyselyTypeMetadata> {\n const result = generateTableInterface(type);\n\n return {\n name: type.name,\n typeDef: result.typeDef,\n usedUtilityTypes: result.usedUtilityTypes,\n };\n}\n\n/**\n * Generate unified types file from multiple namespaces.\n * @param namespaceData - Namespace metadata\n * @returns Generated types file contents\n */\nexport function generateUnifiedKyselyTypes(namespaceData: KyselyNamespaceMetadata[]): string {\n if (namespaceData.length === 0) {\n return \"\";\n }\n\n // Aggregate used utility types from all namespaces\n const globalUsedUtilityTypes = namespaceData.reduce(\n (acc, ns) => ({\n Timestamp: acc.Timestamp || ns.usedUtilityTypes.Timestamp,\n Serial: acc.Serial || ns.usedUtilityTypes.Serial,\n }),\n { Timestamp: false, Serial: false },\n );\n\n const utilityTypeImports: string[] = [\"type Generated\"];\n if (globalUsedUtilityTypes.Timestamp) {\n utilityTypeImports.push(\"type Timestamp\");\n }\n const hasObjectColumnType = namespaceData.some((ns) =>\n ns.types.some((t) => t.typeDef.includes(\"ObjectColumnType<\")),\n );\n if (hasObjectColumnType) {\n utilityTypeImports.push(\"type ObjectColumnType\");\n }\n const hasArrayColumnType = namespaceData.some((ns) =>\n ns.types.some((t) => t.typeDef.includes(\"ArrayColumnType<\")),\n );\n if (hasArrayColumnType) {\n utilityTypeImports.push(\"type ArrayColumnType\");\n }\n if (globalUsedUtilityTypes.Serial) {\n utilityTypeImports.push(\"type Serial\");\n }\n\n const importsSection = multiline /* ts */ `\n import {\n createGetDB,\n ${utilityTypeImports.join(\",\\n\")},\n type NamespaceDB,\n type NamespaceInsertable,\n type NamespaceSelectable,\n type NamespaceTable,\n type NamespaceTableName,\n type NamespaceTransaction,\n type NamespaceUpdateable,\n } from \"@tailor-platform/sdk/kysely\";\n `;\n\n // Generate Namespace interface with multiple namespaces\n const namespaceInterfaces = namespaceData\n .map(({ namespace, types }) => {\n const typeDefsWithIndent = types\n .map((type) => {\n return type.typeDef\n .split(\"\\n\")\n .map((line) => (line.trim() ? ` ${line}` : \"\"))\n .join(\"\\n\");\n })\n .join(\"\\n\\n\");\n\n return ` \"${namespace}\": {\\n${typeDefsWithIndent}\\n }`;\n })\n .join(\",\\n\");\n\n const namespaceInterface = `export interface Namespace {\\n${namespaceInterfaces}\\n}`;\n\n const getDBFunction = multiline /* ts */ `\n export const getDB = createGetDB<Namespace>();\n\n export type DB<N extends keyof Namespace = keyof Namespace> = NamespaceDB<Namespace, N>;\n `;\n\n const utilityTypeExports = multiline /* ts */ `\n export type Transaction<K extends keyof Namespace | DB = keyof Namespace> =\n NamespaceTransaction<Namespace, K>;\n\n type TableName = NamespaceTableName<Namespace>;\n export type Table<T extends TableName> = NamespaceTable<Namespace, T>;\n\n export type Insertable<T extends TableName> = NamespaceInsertable<Namespace, T>;\n export type Selectable<T extends TableName> = NamespaceSelectable<Namespace, T>;\n export type Updateable<T extends TableName> = NamespaceUpdateable<Namespace, T>;\n `;\n\n return (\n [importsSection, namespaceInterface, getDBFunction, utilityTypeExports].join(\"\\n\\n\") + \"\\n\"\n );\n}\n","import { processKyselyType, generateUnifiedKyselyTypes } from \"./type-processor\";\nimport type { Plugin, GeneratorResult, TailorDBReadyContext } from \"#/plugin/types\";\nimport type { KyselyTypeMetadata, KyselyNamespaceMetadata } from \"./types\";\n\n/** Unique identifier for the Kysely type generator plugin. */\nexport const KyselyGeneratorID = \"@tailor-platform/kysely-type\";\n\ntype KyselyTypePluginOptions = {\n distPath: string;\n};\n\n/**\n * Plugin that generates Kysely type definitions for TailorDB tables.\n * @param options - Plugin options\n * @param options.distPath - Output file path for generated types\n * @returns Plugin instance with onTailorDBReady hook\n */\nexport function kyselyTypePlugin(\n options: KyselyTypePluginOptions,\n): Plugin<unknown, KyselyTypePluginOptions> {\n return {\n id: KyselyGeneratorID,\n description: \"Generates Kysely type definitions for TailorDB tables\",\n pluginConfig: options,\n\n async onTailorDBReady(\n ctx: TailorDBReadyContext<KyselyTypePluginOptions>,\n ): Promise<GeneratorResult> {\n const allNamespaceData: KyselyNamespaceMetadata[] = [];\n\n for (const ns of ctx.tailordb) {\n const typeMetadataList: KyselyTypeMetadata[] = [];\n\n for (const type of Object.values(ns.types)) {\n const metadata = await processKyselyType(type);\n typeMetadataList.push(metadata);\n }\n\n if (typeMetadataList.length === 0) continue;\n\n const usedUtilityTypes = typeMetadataList.reduce(\n (acc, type) => ({\n Timestamp: acc.Timestamp || type.usedUtilityTypes.Timestamp,\n Serial: acc.Serial || type.usedUtilityTypes.Serial,\n }),\n { Timestamp: false, Serial: false },\n );\n\n allNamespaceData.push({\n namespace: ns.namespace,\n types: typeMetadataList,\n usedUtilityTypes,\n });\n }\n\n const files: GeneratorResult[\"files\"] = [];\n if (allNamespaceData.length > 0) {\n const content = generateUnifiedKyselyTypes(allNamespaceData);\n files.push({\n path: ctx.pluginConfig.distPath,\n content,\n });\n }\n\n return { files };\n },\n };\n}\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- import { n as seedPlugin, t as SeedGeneratorID } from "../../../seed-xqM9WIHP.mjs";
1
+ import { n as seedPlugin, t as SeedGeneratorID } from "../../../seed-Cibjmtry.mjs";
2
2
 
3
3
  export { SeedGeneratorID, seedPlugin };
@@ -8,13 +8,13 @@ import "./types.mjs";
8
8
  interface SeedNamespaceConfig {
9
9
  /** TailorDB namespace name. */
10
10
  namespace: string;
11
- /** Type names in the namespace, in definition order. */
11
+ /** Table names in the namespace, in definition order. */
12
12
  types: string[];
13
- /** Seed dependencies (referenced type names) per type. */
13
+ /** Seed dependencies (referenced table names) per table. */
14
14
  dependencies: Record<string, string[]>;
15
- /** Types with self-referencing fields, seeded in two passes. */
15
+ /** Tables with self-referencing fields, seeded in two passes. */
16
16
  selfRefTypes: string[];
17
- /** Field names a seed row must supply per type, enforced with `--upsert`. */
17
+ /** Field names a seed row must supply per table, enforced with `--upsert`. */
18
18
  requiredFields: Record<string, string[]>;
19
19
  }
20
20
  //#endregion
@@ -1,15 +1,15 @@
1
1
  import { TailorAnyDBType } from "../configure/services/tailordb/types.mjs";
2
2
  //#region src/plugin/get-generated-type.d.ts
3
3
  /**
4
- * Get a generated type from a plugin by loading the config and resolving everything automatically.
4
+ * Get a generated table from a plugin by loading the config and resolving everything automatically.
5
5
  * For type-attached plugins, calls onTypeLoaded() with the sourceType.
6
6
  * For namespace plugins, calls onNamespaceLoaded() with auto-resolved namespace.
7
7
  * Results are cached per config path, plugin, namespace, and pluginConfig to avoid redundant processing.
8
8
  * @param configPath - Path to tailor.config.ts (absolute or relative to cwd)
9
9
  * @param pluginId - The plugin's unique identifier
10
- * @param sourceType - The source TailorDB type (null for namespace plugins)
11
- * @param kind - The generated type kind (e.g., "request", "step")
12
- * @returns The generated TailorDB type
10
+ * @param sourceType - The source TailorDB table (null for namespace plugins)
11
+ * @param kind - The generated table kind (e.g., "request", "step")
12
+ * @returns The generated TailorDB table
13
13
  */
14
14
  declare function getGeneratedType(configPath: string, pluginId: string, sourceType: TailorAnyDBType | null, kind: string): Promise<TailorAnyDBType>;
15
15
  //#endregion