@tailor-platform/sdk 2.37.0 → 2.38.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.
- package/CHANGELOG.md +60 -0
- package/dist/{application-83WVdH85.mjs → application-Bz80INH4.mjs} +1 -1
- package/dist/application-CeqD1OK-.mjs +207 -0
- package/dist/application-CeqD1OK-.mjs.map +1 -0
- package/dist/cli/commands/deploy/deploy.d.mts +1 -0
- package/dist/cli/commands/deploy/tailordb/migration-validation.d.mts +2 -0
- package/dist/cli/lib.d.mts +2 -2
- package/dist/cli/lib.mjs +1 -1
- package/dist/cli/lib.mjs.map +1 -1
- package/dist/cli/main.mjs +66 -60
- package/dist/cli/main.mjs.map +1 -1
- package/dist/cli/shared/args.d.mts +14 -5
- package/dist/cli/shared/client.d.mts +14 -3
- package/dist/cli/shared/error-json.d.mts +12 -26
- package/dist/client-CHXix4LD.mjs +1 -0
- package/dist/client-DOQv-BP8.mjs +2 -0
- package/dist/client-DOQv-BP8.mjs.map +1 -0
- package/dist/completion/zsh-worker.zsh +133 -69
- package/dist/configure/services/executor/operation.d.mts +5 -4
- package/dist/configure/services/http-adapter/http-adapter.d.mts +1 -1
- package/dist/configure/services/index.d.mts +0 -1
- package/dist/configure/services/tailordb/types.d.mts +9 -0
- package/dist/context-DSi5kfqr.mjs +23 -0
- package/dist/context-DSi5kfqr.mjs.map +1 -0
- package/dist/context-OOASEQLA.mjs +1 -0
- package/dist/{crashreport-D_wf4GZh.mjs → crashreport-CQTAlnbA.mjs} +2 -2
- package/dist/{crashreport-D_wf4GZh.mjs.map → crashreport-CQTAlnbA.mjs.map} +1 -1
- package/dist/crashreport-GRnWyDnF.mjs +1 -0
- package/dist/{errors-Dmdnq0zi.mjs → errors-9OOL3xOM.mjs} +6 -5
- package/dist/errors-9OOL3xOM.mjs.map +1 -0
- package/dist/field_behavior_pb-B196sUx6.mjs +2 -0
- package/dist/field_behavior_pb-B196sUx6.mjs.map +1 -0
- package/dist/{kysely-type-DVL90_oX.mjs → kysely-type-DhAZqdQg.mjs} +14 -10
- package/dist/kysely-type-DhAZqdQg.mjs.map +1 -0
- package/dist/notification_resource_pb-BZ0hCA01.mjs +1 -0
- package/dist/notification_resource_pb-Dwzah7gO.mjs +2 -0
- package/dist/notification_resource_pb-Dwzah7gO.mjs.map +1 -0
- package/dist/plugin/builtin/kysely-type/index.mjs +1 -1
- package/dist/register-ts-hook-CXYYYgCl.mjs +1094 -0
- package/dist/register-ts-hook-CXYYYgCl.mjs.map +1 -0
- package/dist/repl-editor-Bposemei.mjs +2 -0
- package/dist/repl-editor-Bposemei.mjs.map +1 -0
- package/dist/resource_pb-elY668ZB.mjs +2 -0
- package/dist/resource_pb-elY668ZB.mjs.map +1 -0
- package/dist/{secret-file-DiuEcLFP.mjs → secret-file-CSXzcg4c.mjs} +2 -2
- package/dist/{secret-file-DiuEcLFP.mjs.map → secret-file-CSXzcg4c.mjs.map} +1 -1
- package/dist/service-B2vx6CGM.mjs +2 -0
- package/dist/{service-DDrbdyd-.mjs.map → service-B2vx6CGM.mjs.map} +1 -1
- package/dist/service-DB-RHn25.mjs +9 -0
- package/dist/service-DB-RHn25.mjs.map +1 -0
- package/dist/service-DsAWXbVX.mjs +1 -0
- package/dist/service_pb-Bethc2NW.mjs +1 -0
- package/dist/service_pb-CfpSriCy.mjs +2 -0
- package/dist/service_pb-CfpSriCy.mjs.map +1 -0
- package/dist/validation-errors-DqCeUW4L.mjs +3 -0
- package/dist/validation-errors-DqCeUW4L.mjs.map +1 -0
- package/{LICENSE → dist/vendor/graphql/LICENSE} +6 -6
- package/dist/vendor/graphql/language/KindTypeMap.d.mts +3 -0
- package/dist/vendor/graphql/language/ast.d.mts +784 -0
- package/dist/vendor/graphql/language/kinds_.d.mts +203 -0
- package/dist/vendor/graphql/language/source.d.mts +46 -0
- package/dist/vendor/graphql/language/tokenKind.d.mts +35 -0
- package/dist/workspace_resource_pb-Cow7mrJY.mjs +2 -0
- package/dist/workspace_resource_pb-Cow7mrJY.mjs.map +1 -0
- package/docs/cli/application.md +13 -9
- package/docs/cli/notification.md +128 -0
- package/docs/cli/tailordb.md +26 -57
- package/docs/cli/workspace.md +1 -1
- package/docs/cli-reference.md +228 -48
- package/docs/github-actions.md +162 -26
- package/docs/services/tailordb/index.md +6 -2
- package/docs/services/tailordb/migration.md +53 -56
- package/docs/testing.md +0 -1
- package/package.json +14 -10
- package/dist/application-Cida-j1g.mjs +0 -207
- package/dist/application-Cida-j1g.mjs.map +0 -1
- package/dist/configure/services/http-adapter/index.d.mts +0 -2
- package/dist/crashreport-C2AcQNTe.mjs +0 -1
- package/dist/errors-Dmdnq0zi.mjs.map +0 -1
- package/dist/kysely-type-DVL90_oX.mjs.map +0 -1
- package/dist/register-ts-hook-Ht4zCseV.mjs +0 -1115
- package/dist/register-ts-hook-Ht4zCseV.mjs.map +0 -1
- package/dist/repl-editor-DkrCZmmg.mjs +0 -2
- package/dist/repl-editor-DkrCZmmg.mjs.map +0 -1
- package/dist/service-CZ0EdD2-.mjs +0 -10
- package/dist/service-CZ0EdD2-.mjs.map +0 -1
- package/dist/service-DDrbdyd-.mjs +0 -2
- package/dist/service-WhSyhaho.mjs +0 -1
- package/dist/service_pb-BMHhVot2.mjs +0 -1
- package/dist/service_pb-BxMSK0gg.mjs +0 -2
- package/dist/service_pb-BxMSK0gg.mjs.map +0 -1
- package/dist/workspace_resource_pb-7smKERdZ.mjs +0 -2
- package/dist/workspace_resource_pb-7smKERdZ.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors-9OOL3xOM.mjs","names":["styleText","name","text","color","forced","stream","stripVTControlCharacters","ANSI_ESCAPE_PATTERN","CARRIAGE_RETURN_PATTERN","graphemeSegmenter","values","value","max","fallback","codePoint","char","sgrSequences","chars","segment","result","i","cell","ZERO_WIDTH_CLUSTER_PATTERN","RGI_EMOJI_PATTERN","width","eastAsianWidth","cellLine","left","columnWidths","join","right","columnCount","rows","row","index","data","rowCount","rowsCellLines","col","line","config","lineIndex","lines","rowHeight","cellLines","columnLines","cells","rowIndex","TRUTHY_VALUES","FALSY_VALUES","normalized","JSON_OUTPUT_ENV_VAR","isCI","agent","_jsonDefaultAgent","source","reason","_jsonMode","_jsonModeSource","message","styles","symbols","_verbose","_secrets","REDACTED_PLACEHOLDER","root","secret","secrets","node","ch","next","queue","head","parent","child","fail","_automaton","spans","protectedSpans","from","start","end","pStart","pEnd","a","b","merged","span","last","cursor","rendered","render","plain","redactedPlain","styled","TERMINAL_CONTROL_CHARACTERS","TYPE_ICONS","TYPE_COLORS","opts","indentPrefix","indent","colorFn","type","mode","icon","coloredOutput","timestamp","inspectOpts","output","formatWithOptions","logger","sizeBefore","jsonEscaped","formEncoded","display","options","formatDistanceToNowStrict","pretty","key","transformer","item","headers","h","t","header","POSIX_BARE_ARG","CMD_BARE_ARG","WINDOWS_DOUBLE_QUOTE_UNSAFE","POWERSHELL_VERSION_SENSITIVE","quoted","backslashes","argv","cmd","commandLines","action","arg","parts","error","profile","MISSING_NAMED_EXPORT_PATTERN"],"sources":["../../shared/src/color.ts","../src/cli/shared/ascii-table.ts","../src/cli/shared/parse-boolean.ts","../src/cli/shared/logger.ts","../src/cli/shared/shell-quote.ts","../src/cli/shared/errors.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\nexport function 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, stripVTControlCharacters, type InspectOptions } from \"node:util\";\nimport { color, renderFor } from \"@tailor-platform/shared/color\";\nimport { formatDistanceToNowStrict } from \"date-fns\";\nimport { isCI } from \"std-env\";\nimport { renderTable } from \"./ascii-table\";\nimport { parseBoolean } from \"./parse-boolean\";\n\n/** Environment variable selecting JSON as the default output for every command. */\nexport const JSON_OUTPUT_ENV_VAR = \"TAILOR_JSON_OUTPUT\";\n\n/**\n * Whether the process is attached to an interactive terminal outside CI.\n * @returns True when both stdin and stdout are TTYs and CI is not detected\n */\nexport function interactiveTerminal(): boolean {\n return !isCI && process.stdin.isTTY === true && process.stdout.isTTY === true;\n}\n\n/**\n * What selected JSON output: an explicit `--json`, the environment, both, or\n * the AI coding agent running the CLI.\n */\nexport type JsonModeSource = \"flag\" | \"env\" | \"both\" | \"agent\";\n\n/**\n * Explain what selected JSON output and how to turn it off. Under an AI coding\n * agent, dropping `--json` or unsetting the variable falls back to JSON again,\n * so the remedy names the explicit `false` values instead.\n * @param source - What selected JSON output\n * @returns Sentence appended to the prompt refusal\n */\nfunction jsonModeRemedy(source: JsonModeSource): string {\n const agent = _jsonDefaultAgent;\n switch (source) {\n case \"agent\":\n return ` JSON output is enabled because an AI coding agent${agent ? ` (${agent})` : \"\"} was detected; pass --json=false or set ${JSON_OUTPUT_ENV_VAR}=false to restore prompts.`;\n case \"flag\":\n return agent\n ? \" JSON output is enabled by --json; pass --json=false instead to restore prompts.\"\n : \" JSON output is enabled by --json; drop it to restore prompts.\";\n case \"env\":\n return agent\n ? ` JSON output is enabled by ${JSON_OUTPUT_ENV_VAR}; set it to false to restore prompts.`\n : ` JSON output is enabled by ${JSON_OUTPUT_ENV_VAR}; unset it to restore prompts.`;\n case \"both\":\n return agent\n ? ` JSON output is enabled by --json and ${JSON_OUTPUT_ENV_VAR}; pass --json=false instead of the flag to restore prompts.`\n : ` JSON output is enabled by --json and ${JSON_OUTPUT_ENV_VAR}; drop the flag and unset the variable to restore prompts.`;\n }\n}\n\n/**\n * Error thrown when a prompt is attempted in a non-interactive environment.\n *\n * JSON mode suppresses prompts, so name whatever selected it: an explicit\n * `--json` stays enabled however the environment is set, while\n * `TAILOR_JSON_OUTPUT` or a detected AI coding agent leaves nothing in the\n * command line to explain the refusal.\n */\nexport class CIPromptError extends Error {\n constructor(message?: string) {\n const reason =\n _jsonMode && _jsonModeSource !== undefined && interactiveTerminal()\n ? jsonModeRemedy(_jsonModeSource)\n : \"\";\n super(\n (message ??\n \"Interactive prompts are not available in this environment. Provide the required options explicitly.\") +\n reason,\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;\nlet _jsonModeSource: JsonModeSource | undefined;\nlet _jsonDefaultAgent: string | undefined;\nlet _verbose: boolean | undefined;\n\n// Values registered via `logger.registerSecret()`, redacted from diagnostic log output\nconst _secrets = new Set<string>();\nconst REDACTED_PLACEHOLDER = \"<redacted>\";\n// Below this length, a registered value is too likely to match unrelated text.\nconst MIN_SECRET_LENGTH = 4;\n\n/**\n * Aho-Corasick trie node. Indexed by individual UTF-16 code units (not Unicode code\n * points), matching how `string.indexOf`/`.slice` already index this file's strings — a\n * surrogate-pair character occupies two nodes, same as it occupies two `string` indices.\n */\ninterface TrieNode {\n children: Map<string, TrieNode>;\n fail: TrieNode;\n /** Secrets ending at this node, including those reached via `fail` links (precomputed). */\n outputs: string[];\n}\n\n/**\n * Builds a multi-pattern matcher for every registered secret, so `findSecretSpans` below\n * can find all of their occurrences in one pass over the text (`O(text.length + matches)`)\n * instead of scanning the full text once per registered secret. Rebuilt only when\n * `registerSecret` adds a genuinely new value (see `_automaton` below), so its\n * `O(total secret length)` construction cost is amortized across every log line redacted\n * while the secret set doesn't change.\n * @param secrets - Currently registered secrets\n * @returns Root of the built trie\n */\nfunction buildAutomaton(secrets: ReadonlySet<string>): TrieNode {\n const root: TrieNode = {\n children: new Map(),\n fail: undefined as unknown as TrieNode,\n outputs: [],\n };\n root.fail = root;\n\n for (const secret of secrets) {\n let node = root;\n for (let i = 0; i < secret.length; i++) {\n const ch = secret[i] as string;\n let next = node.children.get(ch);\n if (!next) {\n next = { children: new Map(), fail: root, outputs: [] };\n node.children.set(ch, next);\n }\n node = next;\n }\n node.outputs.push(secret);\n }\n\n // A head index instead of Array#shift(): shift() re-indexes every remaining element on\n // each call, which would make this loop quadratic in the number of trie nodes rather than\n // the linear BFS this is meant to be.\n const queue: TrieNode[] = [...root.children.values()];\n for (let head = 0; head < queue.length; head++) {\n const parent = queue[head] as TrieNode;\n for (const [ch, child] of parent.children) {\n let fail = parent.fail;\n while (fail !== root && !fail.children.has(ch)) fail = fail.fail;\n child.fail = fail.children.get(ch) ?? root;\n child.outputs = child.outputs.concat(child.fail.outputs);\n queue.push(child);\n }\n }\n return root;\n}\n\n// Cached automaton for the current `_secrets` contents; `null` means rebuild on next use.\n// Invalidated only when `registerSecret` actually grows `_secrets` (Set#add on an existing\n// value is a no-op), so re-registering an already-known secret never triggers a rebuild.\nlet _automaton: TrieNode | null = null;\n\nfunction getAutomaton(): TrieNode {\n _automaton ??= buildAutomaton(_secrets);\n return _automaton;\n}\n\n/**\n * Finds every occurrence of every registered secret in `text`, including overlapping ones,\n * in a single pass over `text` via the Aho-Corasick automaton.\n * @param text - Text to search\n * @returns Match spans as `[start, end)` pairs, in the order found\n */\nfunction findSecretSpans(text: string): Array<[start: number, end: number]> {\n const spans: Array<[start: number, end: number]> = [];\n const root = getAutomaton();\n let node = root;\n for (let i = 0; i < text.length; i++) {\n const ch = text[i] as string;\n while (node !== root && !node.children.has(ch)) node = node.fail;\n node = node.children.get(ch) ?? root;\n for (const secret of node.outputs) {\n spans.push([i + 1 - secret.length, i + 1]);\n }\n }\n return spans;\n}\n\n/**\n * Redacts every registered secret from `text` in a single pass over the original text.\n *\n * Matches are found against the original text only - never against text a previous\n * replacement produced - and overlapping/adjacent matches (whether one secret contains\n * another, or two secrets merely cross, e.g. registering \"abcde\" and \"defghi\" against\n * \"abcdefghi\") are merged into one contiguous span before any substitution happens. This\n * avoids two failure modes an iterative \"replace one secret, then the next\" approach has:\n * a later secret re-matching inside a placeholder a previous replacement already inserted,\n * and a crossing (non-nested) overlap leaving a fragment of one secret unredacted.\n *\n * Idempotent: a match that falls inside an occurrence of `<redacted>` already present in\n * `text` is discarded rather than substituted again. Without this, calling this function\n * twice on the same text (which happens whenever something already redacted, such as a\n * `--json` error envelope, is later passed to a diagnostic log call) could corrupt the\n * placeholder itself if a registered secret happens to be one of its substrings (e.g. a\n * secret literally containing \"redact\").\n * @param text - Text to redact\n * @returns `text` with every registered secret occurrence replaced by `<redacted>`\n */\nexport function redactSecrets(text: string): string {\n if (_secrets.size === 0) return text;\n\n const protectedSpans: Array<[start: number, end: number]> = [];\n for (let from = 0, index: number; (index = text.indexOf(REDACTED_PLACEHOLDER, from)) !== -1;) {\n protectedSpans.push([index, index + REDACTED_PLACEHOLDER.length]);\n from = index + REDACTED_PLACEHOLDER.length;\n }\n\n // Only a match wholly inside a protected placeholder is discarded (it can only be the\n // placeholder's own text, e.g. a registered secret that is a substring of \"redacted\").\n // A match that merely overlaps one — extending outside it, e.g. a registered secret that\n // happens to be \"leak<redacted>\" — still has real secret content outside the placeholder\n // and must still be replaced.\n //\n // A registered secret wholly contained in the placeholder (up to and including a secret\n // equal to \"<redacted>\" itself) is indistinguishable from the placeholder in rendered\n // output either way: substituting REDACTED_PLACEHOLDER for text that already reads\n // REDACTED_PLACEHOLDER is a no-op. Discarding the match here (rather than \"fixing\" it to\n // substitute anyway) isn't a redaction gap — it just skips redundant work on text that's\n // already the safe, masked form.\n const spans = findSecretSpans(text).filter(\n ([start, end]) => !protectedSpans.some(([pStart, pEnd]) => start >= pStart && end <= pEnd),\n );\n if (spans.length === 0) return text;\n spans.sort(([a], [b]) => a - b);\n\n const merged: Array<[start: number, end: number]> = [];\n for (const span of spans) {\n const last = merged.at(-1);\n if (last && span[0] <= last[1]) {\n last[1] = Math.max(last[1], span[1]);\n } else {\n merged.push(span);\n }\n }\n\n let result = \"\";\n let cursor = 0;\n for (const [start, end] of merged) {\n result += text.slice(cursor, start) + REDACTED_PLACEHOLDER;\n cursor = end;\n }\n return result + text.slice(cursor);\n}\n\n/**\n * Renders styled text with registered secrets redacted.\n *\n * Redacts the styled text first, so a secret that itself contains a control sequence\n * matches its raw form, then checks the text again without colors, so inline colors\n * cannot split a secret out of a match. When they do, the text is returned without\n * colors, since redacting around the escapes would leave fragments of the secret visible.\n * @param text - Styled text\n * @param render - Removes styling from `text`, or keeps it\n * @returns Rendered text with registered secrets redacted\n */\nfunction renderWithRedaction(text: string, render: (text: string) => string): string {\n const rendered = render(redactSecrets(text));\n const plain = stripVTControlCharacters(rendered);\n const redactedPlain = redactSecrets(plain);\n return redactedPlain === plain ? rendered : redactedPlain;\n}\n\n/**\n * Prepares styled diagnostic text for the stream it is written to, with registered\n * secrets redacted.\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, and registered secrets redacted\n */\nexport function renderRedacted(stream: NodeJS.WriteStream, text: string): string {\n return renderWithRedaction(text, (styled) => renderFor(stream, styled));\n}\n\n/**\n * Removes styling from text, with registered secrets redacted.\n * @param text - Styled text\n * @returns Plain text with registered secrets redacted\n */\nexport function plainRedacted(text: string): string {\n return renderWithRedaction(text, stripVTControlCharacters);\n}\n\n// C0 controls other than tab and newline, DEL, C1 controls, and the Unicode line and paragraph\n// separators. Tab and newline are handled as whitespace below so they become a single space.\n// The control characters are the point of this expression.\n// oxlint-disable-next-line no-control-regex\nconst TERMINAL_CONTROL_CHARACTERS = /[\\u0000-\\u0008\\u000b-\\u001f\\u007f-\\u009f\\u2028\\u2029]/g;\n\n/**\n * Makes text that came from a remote source safe to print on a terminal: strips ANSI escape and\n * OSC sequences and every control character, and collapses whitespace runs into one space.\n * Use it on server-provided free text (titles, bodies) before it reaches `logger`.\n * @param text - Text received from a remote source\n * @returns Single-line text with no terminal escapes or control characters\n */\nexport function sanitizeTerminalText(text: string): string {\n return stripVTControlCharacters(text)\n .replace(TERMINAL_CONTROL_CHARACTERS, \"\")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\n/**\n * Makes multi-line text that came from a remote source safe to print on a terminal: strips ANSI\n * escape and OSC sequences and every control character except tab and newline, and normalizes\n * CRLF to LF. Line structure and indentation are kept, so Markdown bodies stay readable.\n * @param text - Text received from a remote source\n * @returns The text with no terminal escapes or control characters, newlines kept\n */\nexport function sanitizeTerminalBlock(text: string): string {\n return stripVTControlCharacters(text)\n .replace(/\\r\\n?/g, \"\\n\")\n .replace(TERMINAL_CONTROL_CHARACTERS, \"\");\n}\n\n/**\n * Reset the registered-secret redaction state. Used for testing.\n *\n * `_secrets` is process-lifetime, module-level state with no production unregister API\n * (a real process should never stop hiding a secret it once saw). Test files that call\n * `logger.registerSecret()` and run in a Vitest project with `isolate: false` share this\n * state across files, so a value registered in one file's test can still be redacted in an\n * unrelated later file's assertions unless cleared between tests.\n */\nexport function resetSecretRegistry(): void {\n _secrets.clear();\n _automaton = null;\n}\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(renderRedacted(process.stderr, output));\n}\n\n/**\n * Record the AI coding agent running the Tailor CLI, which makes JSON the\n * default output. CLI plugins never record one, so they keep table output.\n * @param agent - Detected agent id (e.g. `\"claude_code\"`), or undefined when none runs the CLI\n */\nexport function setJsonDefaultAgent(agent: string | undefined): void {\n _jsonDefaultAgent = agent;\n}\n\n/**\n * The AI coding agent recorded by {@link setJsonDefaultAgent}.\n * @returns Detected agent id, or undefined when none was recorded\n */\nexport function jsonDefaultAgent(): string | undefined {\n return _jsonDefaultAgent;\n}\n\n/**\n * The CLI logger. Diagnostics go to stderr; `out()` writes primary output to\n * stdout as a table, or as JSON when `jsonMode` is on. `--json` and\n * `--verbose` feed the `jsonMode` / `verbose` state, which CLI plugins share\n * with the SDK code paths they call.\n */\nexport const logger = {\n get jsonMode(): boolean {\n return _jsonMode;\n },\n set jsonMode(value: boolean) {\n _jsonMode = value;\n if (!value) _jsonModeSource = undefined;\n },\n\n /**\n * Enable or disable JSON mode, recording what selected it so a suppressed\n * prompt can name the right remedy.\n * @param value - Whether JSON output is on\n * @param source - What turned it on; omit when turning it off\n */\n setJsonMode(value: boolean, source?: JsonModeSource): void {\n _jsonMode = value;\n _jsonModeSource = value ? source : undefined;\n },\n\n get verbose(): boolean {\n return (\n _verbose ?? (parseBoolean(process.env.DEBUG) === true || process.env.RUNNER_DEBUG === \"1\")\n );\n },\n /**\n * Turn verbose output on or off, overriding `DEBUG` and `RUNNER_DEBUG`.\n * @param value - Whether verbose output is on, or undefined to defer to `DEBUG` and `RUNNER_DEBUG`\n */\n set verbose(value: boolean | undefined) {\n _verbose = 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 (logger.verbose) {\n writeLog(\"log\", styles.dim(message), { mode: \"plain\" });\n }\n },\n\n /**\n * Registers a value to be redacted from diagnostic log output (`info`/`success`/`warn`/\n * `error`/`log`/`debug`). Any occurrence of `value` — or of its JSON-string-escaped form\n * (so a value embedded in `JSON.stringify`d output, e.g. `--json` mode error envelopes, is\n * also caught) or its `application/x-www-form-urlencoded` form (so a value that reached the\n * process via a URL query string, e.g. an OAuth authorization code decoded from a callback\n * URL via `URLSearchParams`, is still caught if that same URL — still encoded — is later\n * echoed into a diagnostic message) — is replaced with `<redacted>` before it reaches\n * stderr. Does not affect `out()`, since some commands intentionally print secret values as\n * their primary result.\n *\n * Values shorter than 4 characters are ignored, since they are too likely to match\n * unrelated text. A non-string value (e.g. `undefined` from an unvalidated external\n * payload cast to a typed shape) is ignored the same way, rather than throwing, since a\n * logging call must never be what crashes the process.\n * @param value - The secret value to redact from future log output\n */\n registerSecret(value: string): void {\n // Counts Unicode code points, not UTF-16 code units, so a value made of surrogate-pair\n // characters (e.g. emoji) isn't undercounted as longer than it actually is.\n if (typeof value !== \"string\" || [...value].length < MIN_SECRET_LENGTH) return;\n const sizeBefore = _secrets.size;\n _secrets.add(value);\n const jsonEscaped = JSON.stringify(value).slice(1, -1);\n if (jsonEscaped !== value) _secrets.add(jsonEscaped);\n // Uses URLSearchParams rather than encodeURIComponent: form-urlencoding (what\n // URLSearchParams produces, and what a URL query string actually contains) encodes a\n // space as \"+\", not \"%20\", and unlike encodeURIComponent it never throws on a lone\n // surrogate (invalid UTF-16) — it substitutes U+FFFD instead, matching how the URL\n // itself would already have encoded that same malformed input.\n const formEncoded = new URLSearchParams([[\"v\", value]]).toString().slice(2);\n if (formEncoded !== value) _secrets.add(formEncoded);\n // Set#add on an already-registered value is a no-op, so this only invalidates the\n // cached automaton (see findSecretSpans) when a genuinely new secret was added.\n if (_secrets.size !== sizeBefore) _automaton = null;\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","/**\n * Command lines for a suggested command: one line when every supported shell reads it the same\n * way, otherwise one line per Windows shell.\n */\nexport type ShellCommandLines =\n | { kind: \"shared\"; commandLine: string }\n | { kind: \"perShell\"; powershell: string; cmd: string };\n\nconst POSIX_BARE_ARG = /^[A-Za-z0-9_./:=@+-]+$/;\nconst CMD_BARE_ARG = /^[A-Za-z0-9_./:=@+\\\\-]+$/;\n// PowerShell expands `$` and backtick escapes inside double quotes and reads `“ ” „` as `\"`,\n// cmd.exe expands `%` even inside quotes, a `\"` or a trailing backslash changes where the\n// quoted argument ends, and a leading `~` is version-sensitive (below).\nconst WINDOWS_DOUBLE_QUOTE_UNSAFE = /[%$\"`“”„\\p{Cc}]|\\\\$|^~(?:[\\\\/]|$)/u;\n// PowerShell versions pass these to programs differently: Windows PowerShell 5.1 and 7.3+\n// disagree on quotes and trailing backslashes, and 7.6+ expands a leading `~` inside the `.ps1`\n// shim however it was quoted.\nconst POWERSHELL_VERSION_SENSITIVE = /\"|\\s.*\\\\$|^~(?:[\\\\/]|$)/;\n\nfunction quotePosixArg(value: string): string {\n if (POSIX_BARE_ARG.test(value)) return value;\n return `'${value.replaceAll(\"'\", `'\"'\"'`)}'`;\n}\n\nfunction isPowerShellBare(value: string): boolean {\n // A leading `@` splats, a lone `--` ends parameters, a leading digit reads as a number, and a\n // single-dash token with `.` or `:` reads as parameter syntax.\n return (\n CMD_BARE_ARG.test(value) &&\n !/^(@|[+-]?\\.?\\d)/.test(value) &&\n value !== \"--\" &&\n !/^-[^-].*[.:]/.test(value)\n );\n}\n\nfunction quotePowerShellArg(value: string): string {\n if (isPowerShellBare(value)) return value;\n return `'${value.replace(/['‘’‚‛]/g, \"$&$&\")}'`;\n}\n\nfunction quoteCmdArg(value: string): string {\n // Quoting a trailing backslash keeps a command routed through `cmd /c` from ending in one,\n // which PowerShell 7 doubles when it quotes the line.\n if (CMD_BARE_ARG.test(value) && !value.endsWith(\"\\\\\")) return value;\n let quoted = '\"';\n let backslashes = 0;\n for (const char of value) {\n if (char === \"\\\\\") {\n backslashes++;\n continue;\n }\n if (char === '\"') {\n quoted += `${\"\\\\\".repeat(backslashes * 2)}\"\"`;\n } else {\n // `%%cd:~,%` reads back as a literal `%` without cmd.exe expanding a `%NAME%` around it.\n quoted += `${\"\\\\\".repeat(backslashes)}${char === \"%\" ? \"%%cd:~,%\" : char}`;\n }\n backslashes = 0;\n }\n return `${quoted}${\"\\\\\".repeat(backslashes * 2)}\"`;\n}\n\nfunction formatWindowsCommandLines(argv: readonly string[]): ShellCommandLines {\n if (\n argv.every(\n (value) =>\n isPowerShellBare(value) || (value !== \"\" && !WINDOWS_DOUBLE_QUOTE_UNSAFE.test(value)),\n )\n ) {\n return {\n kind: \"shared\",\n commandLine: argv.map((value) => (isPowerShellBare(value) ? value : `\"${value}\"`)).join(\" \"),\n };\n }\n const cmd = argv.map(quoteCmdArg).join(\" \");\n // Both PowerShell versions pass a `cmd` argument the same legacy way, so routing the cmd.exe\n // line through `cmd /c` keeps the arguments identical where their native quoting differs.\n const powershell = argv.some((value) => value === \"\" || POWERSHELL_VERSION_SENSITIVE.test(value))\n ? `cmd /d /s /c ${quotePowerShellArg(cmd)}`\n : argv.map(quotePowerShellArg).join(\" \");\n return { kind: \"perShell\", powershell, cmd };\n}\n\n/**\n * Render an argv array as command lines that the current platform's shells run with every\n * argument delivered unchanged\n * @param {readonly string[]} argv - Executable name followed by its arguments\n * @returns {ShellCommandLines} One shared command line, or one per Windows shell\n */\nexport function formatShellCommandLines(argv: readonly string[]): ShellCommandLines {\n if (process.platform === \"win32\") return formatWindowsCommandLines(argv);\n return { kind: \"shared\", commandLine: argv.map(quotePosixArg).join(\" \") };\n}\n","import { redactSecrets, styles } from \"./logger\";\nimport { formatShellCommandLines } from \"./shell-quote\";\nimport type { Jsonifiable } from \"type-fest\";\n\n/**\n * Options for creating a CLI error\n */\ninterface CLIErrorOptions {\n /** Stable machine-readable failure code, such as `WORKSPACE_NOT_FOUND`. */\n code: string;\n message: string;\n details?: string;\n suggestion?: string;\n command?: string;\n next?: CLIErrorNextAction;\n context?: Readonly<Record<string, Jsonifiable | undefined>>;\n cause?: unknown;\n}\n\nexport type CLIErrorNextAction = {\n /** Executable name, such as `tailor`. */\n command: string;\n /** Arguments passed directly to the executable. */\n args: readonly string[];\n};\n\n/**\n * CLI error interface with formatted output\n */\nexport interface CLIError extends Error {\n readonly code: string;\n readonly details?: string;\n readonly suggestion?: string;\n readonly command?: string;\n readonly next?: CLIErrorNextAction;\n readonly context?: Readonly<Record<string, Jsonifiable | undefined>>;\n format(): string;\n}\n\ntype CLIErrorInternal = Error & {\n code: string;\n details?: string;\n suggestion?: string;\n command?: string;\n next?: CLIErrorNextAction;\n context?: Readonly<Record<string, Jsonifiable | undefined>>;\n format(): string;\n};\n\n/**\n * Render a command as a user-facing hint that can be copied into the current platform's shells:\n * one backticked command line, or on Windows, when no single quoting suits both shells, a\n * PowerShell and a cmd.exe line (`` `…` in PowerShell or `…` in cmd.exe ``).\n * Registered secrets are redacted before quoting, which could otherwise split them.\n * @param {CLIErrorNextAction} action - Executable and arguments to suggest\n * @returns {string} The command part of the hint, to follow a verb such as \"Run\"\n */\nexport function formatCommandHint(action: CLIErrorNextAction): string {\n const commandLines = formatShellCommandLines(\n [action.command, ...action.args].map((arg) => redactSecrets(arg)),\n );\n if (commandLines.kind === \"shared\") {\n return `\\`${commandLines.commandLine}\\``;\n }\n return `\\`${commandLines.powershell}\\` in PowerShell or \\`${commandLines.cmd}\\` in cmd.exe`;\n}\n\n/**\n * Redact registered secrets, then indent every line after the first.\n * Redacting first keeps the indent from splitting a multi-line secret.\n * @param text - Details or suggestion text\n * @returns Redacted text with its continuation lines indented\n */\nfunction redactAndIndent(text: string): string {\n return redactSecrets(text).split(\"\\n\").join(\"\\n \");\n}\n\n/**\n * Format CLI error for output\n * @param error - CLIError instance to format\n * @returns Formatted error message\n */\nfunction formatError(error: CLIError): string {\n const parts: string[] = [\n styles.error(`Error${error.code ? ` [${error.code}]` : \"\"}: ${error.message}`),\n ];\n\n if (error.details) {\n parts.push(`\\n ${styles.dim(\"Details:\")} ${redactAndIndent(error.details)}`);\n }\n\n if (error.suggestion) {\n parts.push(`\\n ${styles.info(\"Suggestion:\")} ${redactAndIndent(error.suggestion)}`);\n }\n\n if (error.command) {\n parts.push(\n `\\n ${styles.dim(\"Help:\")} Run \\`tailor ${error.command} --help\\` for usage information.`,\n );\n }\n\n if (error.next) {\n parts.push(`\\n ${styles.info(\"Next:\")} Run ${formatCommandHint(error.next)}.`);\n }\n\n return parts.join(\"\");\n}\n\n/**\n * Create a CLI error with formatted output\n * @param options - Options to construct a CLIError\n * @returns Constructed CLIError instance\n */\nexport function CLIError(options: CLIErrorOptions): CLIError {\n const error = new Error(\n options.message,\n options.cause === undefined ? undefined : { cause: options.cause },\n ) as CLIErrorInternal;\n error.name = \"CLIError\";\n error.code = options.code;\n error.details = options.details;\n error.suggestion = options.suggestion;\n error.command = options.command;\n error.next = options.next;\n error.context = options.context;\n error.format = () => formatError(error);\n return error;\n}\n\n/**\n * Type guard to check if an error is a CLIError\n * @param error - Error to check\n * @returns True if the error is a CLIError\n */\nexport function isCLIError(error: unknown): error is CLIError {\n return error instanceof Error && error.name === \"CLIError\";\n}\n\n/**\n * Summarize a failure as plain text for reports that carry a single error string.\n * CLI errors contribute their details and suggestion so the remediation survives.\n * @param error - Failure to summarize\n * @returns Message followed by any details and suggestion, one per line\n */\nexport function errorSummary(error: unknown): string {\n if (isCLIError(error)) {\n return [error.message, error.details, error.suggestion].filter(Boolean).join(\"\\n\");\n }\n return error instanceof Error ? error.message : String(error);\n}\n\n/**\n * Create an error for an SDK invariant violation that no user action can fix.\n * The result is a plain Error, so JSON output reports it as `UNEXPECTED_ERROR`\n * and crash reporting treats it like any other unexpected failure.\n * @param message - Description of the violated invariant\n * @param options - Standard Error options, such as `cause`\n * @returns Plain Error instance\n */\nexport function internalError(message: string, options?: ErrorOptions): Error {\n return new Error(message, options);\n}\n\n/**\n * Create the error for a profile name that the platform config does not define.\n * @param profile - Requested profile name\n * @returns CLIError with code `PROFILE_NOT_FOUND`\n */\nexport function profileNotFoundError(profile: string): CLIError {\n return CLIError({\n code: \"PROFILE_NOT_FOUND\",\n message: `Profile \"${profile}\" not found`,\n suggestion: `Run ${formatCommandHint({ command: \"tailor\", args: [\"profile\", \"list\"] })} to see the configured profiles.`,\n });\n}\n\n/**\n * Convert a caught value into an Error, keeping Error instances as-is\n * @param value - Caught value\n * @returns The value itself when it is an Error, otherwise an Error of its string form with the value as `cause`\n */\nexport function toError(value: unknown): Error {\n return value instanceof Error ? value : new Error(String(value), { cause: value });\n}\n\nconst MISSING_NAMED_EXPORT_PATTERN = /does not provide an export named '(?!default')([^']+)'/;\n\n/**\n * Suggest `import type` when importing user code fails on a missing named\n * export. The CLI strips types from each file in isolation, so a type-only\n * export does not exist at runtime and a plain import of it fails to link.\n * @param error - Error thrown while importing user modules\n * @returns Suggestion text, or undefined when the error is not that failure\n */\nexport function typeOnlyImportHint(error: unknown): string | undefined {\n if (!(error instanceof SyntaxError)) return undefined;\n const name = MISSING_NAMED_EXPORT_PATTERN.exec(error.message)?.[1];\n if (!name) return undefined;\n return (\n `If '${name}' is a type, import it with \\`import type\\` (or the inline \\`type\\` modifier). ` +\n \"The CLI runs TypeScript by stripping types from each file in isolation, so type-only exports do not exist at runtime. \" +\n 'Set \"verbatimModuleSyntax\": true in tsconfig.json to catch this at typecheck.'\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{fileDesc as e}from"@bufbuild/protobuf/codegenv2";import{file_google_protobuf_descriptor as t}from"@bufbuild/protobuf/wkt";const n=/*@__PURE__*/ e(`Ch9nb29nbGUvYXBpL2ZpZWxkX2JlaGF2aW9yLnByb3RvEgpnb29nbGUuYXBpKrYBCg1GaWVsZEJlaGF2aW9yEh4KGkZJRUxEX0JFSEFWSU9SX1VOU1BFQ0lGSUVEEAASDAoIT1BUSU9OQUwQARIMCghSRVFVSVJFRBACEg8KC09VVFBVVF9PTkxZEAMSDgoKSU5QVVRfT05MWRAEEg0KCUlNTVVUQUJMRRAFEhIKDlVOT1JERVJFRF9MSVNUEAYSFQoRTk9OX0VNUFRZX0RFRkFVTFQQBxIOCgpJREVOVElGSUVSEAg6ZAoOZmllbGRfYmVoYXZpb3ISHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGJwIIAMoDjIZLmdvb2dsZS5hcGkuRmllbGRCZWhhdmlvckICEABSDWZpZWxkQmVoYXZpb3JCcAoOY29tLmdvb2dsZS5hcGlCEkZpZWxkQmVoYXZpb3JQcm90b1ABWkFnb29nbGUuZ29sYW5nLm9yZy9nZW5wcm90by9nb29nbGVhcGlzL2FwaS9hbm5vdGF0aW9uczthbm5vdGF0aW9uc6ICBEdBUEliBnByb3RvMw`,[t]);export{n as t};
|
|
2
|
+
//# sourceMappingURL=field_behavior_pb-B196sUx6.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field_behavior_pb-B196sUx6.mjs","names":["file_google_api_field_behavior","file_google_protobuf_descriptor"],"sources":["../../tailor-proto/src/google/api/field_behavior_pb.js"],"sourcesContent":["// Copyright 2025 Google LLC\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// @generated by protoc-gen-es v2.6.3\n// @generated from file google/api/field_behavior.proto (package google.api, syntax proto3)\n/* eslint-disable */\n\nimport { enumDesc, extDesc, fileDesc, tsEnum } from \"@bufbuild/protobuf/codegenv2\";\nimport { file_google_protobuf_descriptor } from \"@bufbuild/protobuf/wkt\";\n\n/**\n * Describes the file google/api/field_behavior.proto.\n */\nexport const file_google_api_field_behavior = /*@__PURE__*/\n fileDesc(\"Ch9nb29nbGUvYXBpL2ZpZWxkX2JlaGF2aW9yLnByb3RvEgpnb29nbGUuYXBpKrYBCg1GaWVsZEJlaGF2aW9yEh4KGkZJRUxEX0JFSEFWSU9SX1VOU1BFQ0lGSUVEEAASDAoIT1BUSU9OQUwQARIMCghSRVFVSVJFRBACEg8KC09VVFBVVF9PTkxZEAMSDgoKSU5QVVRfT05MWRAEEg0KCUlNTVVUQUJMRRAFEhIKDlVOT1JERVJFRF9MSVNUEAYSFQoRTk9OX0VNUFRZX0RFRkFVTFQQBxIOCgpJREVOVElGSUVSEAg6ZAoOZmllbGRfYmVoYXZpb3ISHS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGJwIIAMoDjIZLmdvb2dsZS5hcGkuRmllbGRCZWhhdmlvckICEABSDWZpZWxkQmVoYXZpb3JCcAoOY29tLmdvb2dsZS5hcGlCEkZpZWxkQmVoYXZpb3JQcm90b1ABWkFnb29nbGUuZ29sYW5nLm9yZy9nZW5wcm90by9nb29nbGVhcGlzL2FwaS9hbm5vdGF0aW9uczthbm5vdGF0aW9uc6ICBEdBUEliBnByb3RvMw\", [file_google_protobuf_descriptor]);\n\n/**\n * Describes the enum google.api.FieldBehavior.\n */\nexport const FieldBehaviorSchema = /*@__PURE__*/\n enumDesc(file_google_api_field_behavior, 0);\n\n/**\n * An indicator of the behavior of a given field (for example, that a field\n * is required in requests, or given as output but ignored as input).\n * This **does not** change the behavior in protocol buffers itself; it only\n * denotes the behavior and may affect how API tooling handles the field.\n *\n * Note: This enum **may** receive new values in the future.\n *\n * @generated from enum google.api.FieldBehavior\n */\nexport const FieldBehavior = /*@__PURE__*/\n tsEnum(FieldBehaviorSchema);\n\n/**\n * A designation of a specific field behavior (required, output only, etc.)\n * in protobuf messages.\n *\n * Examples:\n *\n * string name = 1 [(google.api.field_behavior) = REQUIRED];\n * State state = 1 [(google.api.field_behavior) = OUTPUT_ONLY];\n * google.protobuf.Duration ttl = 1\n * [(google.api.field_behavior) = INPUT_ONLY];\n * google.protobuf.Timestamp expire_time = 1\n * [(google.api.field_behavior) = OUTPUT_ONLY,\n * (google.api.field_behavior) = IMMUTABLE];\n *\n * @generated from extension: repeated google.api.FieldBehavior field_behavior = 1052 [packed = false];\n */\nexport const field_behavior = /*@__PURE__*/\n extDesc(file_google_api_field_behavior, 0);\n\n"],"mappings":"A,iIAwBA,MAAaA,EACX,gBAAS,imBAAkmB,CAACC,CAA+B,CAAC,E"}
|
|
@@ -1,15 +1,19 @@
|
|
|
1
|
-
import{t as e}from"./multiline-EyzjEwn9.mjs";import{resolve as t}from"pathe";const n=new TextEncoder;function mapFieldTypeToPostgresType(e){switch(e){case`uuid`:return`uuid`;case`string`:case`enum`:return`text`;case`boolean`:case`bool`:return`boolean`;case`integer`:return`integer`;case`float`:return`double precision`;case`decimal`:return`numeric`;case`date`:return`date`;case`datetime`:return`timestamptz`;case`time`:return`time`;case`nested`:return`jsonb`;default:throw Error(`Field type "${e}" has no PostgreSQL column type.`)}}function identifier(e){return`"${e.replaceAll(`"`,`""`)}"`}function fnv1aHex(e){let t=2166136261;for(let r of n.encode(e))t=Math.imul(t^r,16777619)>>>0;return t.toString(16).padStart(8,`0`)}function derivedName(e,t,r){let i=`_${fnv1aHex(JSON.stringify([e,t,r]))}_${r}`,a=`${e}_${t}`;for(;n.encode(a+i).length>63;)a=a.slice(0,-1);return a+i}function derivedIdentifier(e,t,n){return identifier(derivedName(e,t,n))}function dollarQuoted(e){let t=`$fk$`;for(;e.includes(t);)t=`${t.slice(0,-1)}_$`;return`${t}\n${e}\n${t}`}function stringLiteral(e){return`'${e.replaceAll(`'`,`''`)}'`}function columnType(e){let t=e.type===`decimal`?`numeric(1000, ${e.scale??6})`:mapFieldTypeToPostgresType(e.type);return e.array&&e.type!==`nested`?`${t}[]`:t}function scalarLiteral(e,t,n){let r=mapFieldTypeToPostgresType(t.type);if(e instanceof Date){if(Number.isNaN(e.getTime()))throw Error(`Default of field ${n} is an invalid Date.`);return`${stringLiteral(e.toISOString())}::${r}`}switch(typeof e){case`string`:return r===`text`?stringLiteral(e):`${stringLiteral(e)}::${r}`;case`number`:if(!Number.isFinite(e))throw Error(`Default of field ${n} is not a finite number.`);return String(e);case`boolean`:return e?`TRUE`:`FALSE`;default:throw Error(`Default of field ${n} cannot be rendered as a SQL literal.`)}}const r=/* @__PURE__ */ new Map([[`datetime`,`now()`],[`date`,`CURRENT_DATE`],[`time`,`LOCALTIME`]]);function defaultExpression(e,t){let n=e.default,i=r.get(e.type);if(n===`now`&&i!==void 0)return i;if(e.array){if(!Array.isArray(n))throw Error(`Default of array field ${t} must be an array.`);let r=columnType(e);return n.length===0?`'{}'::${r}`:`ARRAY[${n.map(n=>scalarLiteral(n,e,t)).join(`, `)}]::${r}`}return scalarLiteral(n,e,t)}
|
|
1
|
+
import{t as e}from"./multiline-EyzjEwn9.mjs";import{resolve as t}from"pathe";const n=new TextEncoder;function mapFieldTypeToPostgresType(e){switch(e){case`uuid`:return`uuid`;case`string`:case`enum`:return`text`;case`boolean`:case`bool`:return`boolean`;case`integer`:return`integer`;case`float`:return`double precision`;case`decimal`:return`numeric`;case`date`:return`date`;case`datetime`:return`timestamptz`;case`time`:return`time`;case`nested`:return`jsonb`;default:throw Error(`Field type "${e}" has no PostgreSQL column type.`)}}function identifier(e){return`"${e.replaceAll(`"`,`""`)}"`}function fnv1aHex(e){let t=2166136261;for(let r of n.encode(e))t=Math.imul(t^r,16777619)>>>0;return t.toString(16).padStart(8,`0`)}function derivedName(e,t,r){let i=`_${fnv1aHex(JSON.stringify([e,t,r]))}_${r}`,a=`${e}_${t}`;for(;n.encode(a+i).length>63;)a=a.slice(0,-1);return a+i}function derivedIdentifier(e,t,n){return identifier(derivedName(e,t,n))}function dollarQuoted(e){let t=`$fk$`;for(;e.includes(t);)t=`${t.slice(0,-1)}_$`;return`${t}\n${e}\n${t}`}function stringLiteral(e){return`'${e.replaceAll(`'`,`''`)}'`}function columnType(e){let t=e.type===`decimal`?`numeric(1000, ${e.scale??6})`:mapFieldTypeToPostgresType(e.type);return e.array&&e.type!==`nested`?`${t}[]`:t}function scalarLiteral(e,t,n){let r=mapFieldTypeToPostgresType(t.type);if(e instanceof Date){if(Number.isNaN(e.getTime()))throw Error(`Default of field ${n} is an invalid Date.`);return`${stringLiteral(e.toISOString())}::${r}`}switch(typeof e){case`string`:return r===`text`?stringLiteral(e):`${stringLiteral(e)}::${r}`;case`number`:if(!Number.isFinite(e))throw Error(`Default of field ${n} is not a finite number.`);return String(e);case`boolean`:return e?`TRUE`:`FALSE`;default:throw Error(`Default of field ${n} cannot be rendered as a SQL literal.`)}}const r=/* @__PURE__ */ new Map([[`datetime`,`now()`],[`date`,`CURRENT_DATE`],[`time`,`LOCALTIME`]]);function defaultExpression(e,t){let n=e.default,i=r.get(e.type);if(n===`now`&&i!==void 0)return i;if(e.array){if(!Array.isArray(n))throw Error(`Default of array field ${t} must be an array.`);let r=columnType(e);return n.length===0?`'{}'::${r}`:`ARRAY[${n.map(n=>scalarLiteral(n,e,t)).join(`, `)}]::${r}`}return scalarLiteral(n,e,t)}const i=`tailor_to_oct`,a={d:{render:e=>e,functions:[]},o:{render:e=>`${i}(${e})`,functions:[`CREATE OR REPLACE FUNCTION ${i}(n bigint) RETURNS text LANGUAGE sql IMMUTABLE AS ${dollarQuoted(`WITH RECURSIVE o(q, s) AS (
|
|
2
|
+
SELECT n / 8, (n % 8)::text
|
|
3
|
+
UNION ALL SELECT q / 8, (q % 8)::text || s FROM o WHERE q > 0
|
|
4
|
+
)
|
|
5
|
+
SELECT s FROM o WHERE q = 0`)}`]},x:{render:e=>`to_hex(${e})`,functions:[]},X:{render:e=>`upper(to_hex(${e}))`,functions:[]}};function isSerialConversion(e){return Object.hasOwn(a,e)}function parseSerialFormat(e,t){let n=/^(?<prefix>(?:%%|[^%])*)%(?<zero>0?)(?<width>\d*)(?<conversion>[a-zA-Z])(?<suffix>(?:%%|[^%])*)$/.exec(e)?.groups,r=n?.conversion;if(!n||r===void 0||!isSerialConversion(r))throw Error(`Serial format "${e}" of field ${t} is not supported; use a single %d, %o, %x, or %X specifier with an optional width (e.g. "INV-%05d"), and %% for a literal %.`);return{prefix:(n.prefix??``).replaceAll(`%%`,`%`),zeroPad:n.zero===`0`,width:n.width?Number(n.width):0,conversion:r,suffix:(n.suffix??``).replaceAll(`%%`,`%`)}}function sequenceName(e,t){return derivedIdentifier(e,t,`seq`)}function sequenceRange(e){let t=[`START WITH ${e.start}`,`MINVALUE ${e.start}`];return e.maxValue!==void 0&&t.push(`MAXVALUE ${e.maxValue}`),t.join(` `)}function serialStringDefault(e,t,n){let r=`nextval(${stringLiteral(e)})`;if(t===void 0)return{sql:`(${r}::text)`,functions:[]};let{prefix:i,width:o,zeroPad:s,conversion:c,suffix:l}=parseSerialFormat(t,n),{render:u,functions:d}=a[c],f=u(r),p=c===`d`?`${f}::text`:f;return o>0&&(p=`format('%${o}s', ${f})`,s&&(p=`translate(${p}, ' ', '0')`)),{sql:`(${[...i?[stringLiteral(i)]:[],p,...l?[stringLiteral(l)]:[]].join(` || `)})`,functions:d}}function columnDefinition(e,t,n){let r=identifier(t),i=`${identifier(e)}.${r}`,a=[r,columnType(n)];if(n.serial){if(n.type===`integer`)return a.push(`GENERATED BY DEFAULT AS IDENTITY (${sequenceRange(n.serial)})`),n.unique&&a.push(`UNIQUE`),{sql:a.join(` `),functions:[]};n.required&&a.push(`NOT NULL`),n.unique&&a.push(`UNIQUE`);let r=serialStringDefault(sequenceName(e,t),n.serial.format,i);return a.push(`DEFAULT ${r.sql}`),{sql:a.join(` `),functions:r.functions}}let o=n.default!==void 0,s=n.hooks?.create!==void 0||n.optionalOnCreate===!0;return n.required&&(o||!s)&&a.push(`NOT NULL`),n.unique&&a.push(`UNIQUE`),o&&a.push(`DEFAULT ${defaultExpression(n,i)}`),{sql:a.join(` `),functions:[]}}function jsonPathKey(e){return`"${e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`)}"`}function referencesWithin(e,t,n){let r=t.array?`${n}[*]`:n;return t.type===`nested`?Object.entries(t.fields??{}).flatMap(([t,n])=>referencesWithin(e,n,`${r}.${jsonPathKey(t)}`)):!t.foreignKey||t.foreignKeyType===void 0?[]:[{column:e,path:r,table:t.foreignKeyType,field:t.foreignKeyField??`id`,type:t.type}]}const o=/* @__PURE__ */ new Set([`integer`,`float`,`decimal`,`boolean`,`bool`,`uuid`]);function nestedUniqueMembers(e,t,n){return t.array?[]:t.type===`nested`?Object.entries(t.fields??{}).flatMap(([t,r])=>nestedUniqueMembers(e,r,[...n,t])):t.unique&&n.length>0?[{column:e,path:n,field:t}]:[]}function nestedUniqueIndex(e,t){let n=t.path.map(stringLiteral).join(`, `),r=`${identifier(t.column)} #>> ARRAY[${n}]`,i=o.has(t.field.type)?`CAST(${r} AS ${mapFieldTypeToPostgresType(t.field.type)})`:r;return`CREATE UNIQUE INDEX IF NOT EXISTS ${derivedIdentifier(e,`${t.column}.${t.path.join(`.`)}`,`nested_idx`)} ON ${identifier(e)} ((${i}))`}function tableReferences(e){return Object.entries(e.fields).filter(([e])=>e!==`id`).flatMap(([e,t])=>referencesWithin(e,t,`$`))}function isConstraintReference(e){return e.path===`$`}function referenceClause(e){return`REFERENCES ${identifier(e.table)} (${identifier(e.field)})`}function declaredType(e){return e===`bool`?`boolean`:e}function checkReference(e,t){let n=t.get(e.table);if(!n)return{problem:`references unknown table "${e.table}".`};let r=e.field===`id`?{type:`uuid`,unique:!0}:n.fields[e.field];return r?!r.unique||declaredType(r.type)!==declaredType(e.type)?{problem:`references "${e.table}"."${e.field}", which must be unique and of the same type as the referencing field.`}:{pgType:mapFieldTypeToPostgresType(r.type)}:{problem:`references unknown field "${e.field}" of table "${e.table}".`}}function referencedColumnType(e,t,n){let r=checkReference(e,t);if(`problem`in r)throw Error(`Field ${n} ${r.problem}`);return r.pgType}function withoutReference(e){let{foreignKey:t,foreignKeyType:n,foreignKeyField:r,...i}=e;return i}function withoutUnresolvableReference(e,t){return e.fields?{...e,fields:Object.fromEntries(Object.entries(e.fields).map(([e,n])=>[e,withoutUnresolvableReference(n,t)]))}:!e.foreignKey||e.foreignKeyType===void 0?e:`problem`in checkReference({column:``,path:`$`,table:e.foreignKeyType,field:e.foreignKeyField??`id`,type:e.type},t)?withoutReference(e):e}function dropUnresolvableReferences(e){let t=new Map(e.map(e=>[e.name,e]));return e.map(e=>({...e,fields:Object.fromEntries(Object.entries(e.fields).map(([e,n])=>[e,withoutUnresolvableReference(n,t)]))}))}function referenceCheck(e,t,n){let r=referencedColumnType(e,t,n),i=`violates foreign key constraints: % not found in ${`${identifier(e.table)}.${identifier(e.field)}`.replaceAll(`%`,`%%`)}`;return[` FOR v IN SELECT jsonb_path_query(to_jsonb(NEW.${identifier(e.column)}), ${stringLiteral(e.path)}) LOOP`,` IF jsonb_typeof(fk_check.v) <> 'null' AND NOT EXISTS (SELECT 1 FROM ${identifier(e.table)} AS parent WHERE parent.${identifier(e.field)} = (fk_check.v #>> '{}')::${r}) THEN`,` RAISE EXCEPTION ${stringLiteral(i)}, fk_check.v #>> '{}' USING ERRCODE = 'foreign_key_violation';`,` END IF;`,` END LOOP;`].join(`
|
|
2
6
|
`)}function referenceTrigger(e,t,n){if(t.length===0)return[];let r=derivedIdentifier(e.name,`references`,`fk`);return[`CREATE OR REPLACE FUNCTION ${r}() RETURNS trigger LANGUAGE plpgsql AS ${dollarQuoted([`<<fk_check>>`,`DECLARE v jsonb;`,`BEGIN`,...t.map(t=>referenceCheck(t,n,`${e.name}.${t.column}`)),` RETURN NULL;`,`END`].join(`
|
|
3
|
-
`))}`,`CREATE OR REPLACE TRIGGER ${r} AFTER INSERT OR UPDATE ON ${identifier(e.name)} FOR EACH ROW EXECUTE FUNCTION ${r}()`]}function incomingReferences(e,t){return[...t.values()].flatMap(n=>tableReferences(n).filter(t=>!isConstraintReference(t)&&t.table===e.name).flatMap(e=>{let r=checkReference(e,t);return`pgType`in r?[{...e,child:n.name,pgType:r.pgType}]:[]}))}function holdsParent(e){let t=`child.${identifier(e.column)}`,n=`OLD.${identifier(e.field)}`;return e.path===`$[*]`?`${n} = ANY(${t})`:`EXISTS (SELECT 1 FROM jsonb_path_query(to_jsonb(${t}), ${stringLiteral(e.path)}) AS held(v) WHERE CASE WHEN jsonb_typeof(held.v) = 'null' THEN false WHEN NOT pg_input_is_valid(held.v #>> '{}', ${stringLiteral(e.pgType)}) THEN false ELSE (held.v #>> '{}')::${e.pgType} = ${n} END)`}const
|
|
4
|
-
`)}function referencedDeleteCheck(e,t){let n=holds(t,identifier(t.child));return refuseWhen(e,t,t.child===e.name?`${n} OR ${holds(t,
|
|
5
|
-
`))}`,`CREATE OR REPLACE TRIGGER ${o} AFTER ${r} ON ${identifier(e.name)}${i} FOR EACH ROW EXECUTE FUNCTION ${o}()`]})}function generateTableDDL(e,t={}){let n=identifier(e.name),r=new Map((t.tables??[e]).map(e=>[e.name,e])),i=[],
|
|
6
|
-
`)}\n)`,...
|
|
7
|
-
`))}`}function planCreation(e){let t=new Set(e.map(e=>e.name)),n=/* @__PURE__ */ new Set,r=[...e],i=[],a=/* @__PURE__ */ new Map,pendingOf=e=>tableReferences(e).filter(isConstraintReference).filter(r=>t.has(r.table)&&r.table!==e.name&&!n.has(r.table));for(;r.length>0;){let e=r.findIndex(e=>pendingOf(e).length===0),[t]=r.splice(Math.max(e,0),1),o=pendingOf(t);o.length>0&&a.set(t,o),n.add(t.name),i.push(t)}return{ordered:i,deferred:a}}function generateSchemaDDL(e){let{ordered:t,deferred:n}=planCreation(e),r=t.map(t=>generateTableDDL(t,{tables:e,deferredReferences:new Set(n.get(t)?.map(e=>e.column))})),i=t.flatMap(e=>(n.get(e)??[]).map(t=>addForeignKey(e,t)));return[
|
|
7
|
+
`))}`,`CREATE OR REPLACE TRIGGER ${r} AFTER INSERT OR UPDATE ON ${identifier(e.name)} FOR EACH ROW EXECUTE FUNCTION ${r}()`]}function incomingReferences(e,t){return[...t.values()].flatMap(n=>tableReferences(n).filter(t=>!isConstraintReference(t)&&t.table===e.name).flatMap(e=>{let r=checkReference(e,t);return`pgType`in r?[{...e,child:n.name,pgType:r.pgType}]:[]}))}function holdsParent(e){let t=`child.${identifier(e.column)}`,n=`OLD.${identifier(e.field)}`;return e.path===`$[*]`?`${n} = ANY(${t})`:`EXISTS (SELECT 1 FROM jsonb_path_query(to_jsonb(${t}), ${stringLiteral(e.path)}) AS held(v) WHERE CASE WHEN jsonb_typeof(held.v) = 'null' THEN false WHEN NOT pg_input_is_valid(held.v #>> '{}', ${stringLiteral(e.pgType)}) THEN false ELSE (held.v #>> '{}')::${e.pgType} = ${n} END)`}const s=`old_rows`;function holds(e,t){return`EXISTS (SELECT 1 FROM ${t} AS child WHERE ${holdsParent(e)})`}function refuseWhen(e,t,n){let r=`update or delete on table \`${e.name}\` violates foreign key constraint: some record is still referenced from table \`${t.child}\``;return[` IF ${n} THEN`,` RAISE EXCEPTION ${stringLiteral(r.replaceAll(`%`,`%%`))} USING ERRCODE = 'foreign_key_violation';`,` END IF;`].join(`
|
|
8
|
+
`)}function referencedDeleteCheck(e,t){let n=holds(t,identifier(t.child));return refuseWhen(e,t,t.child===e.name?`${n} OR ${holds(t,s)}`:n)}function referencedUpdateCheck(e,t){let n=identifier(t.field);return refuseWhen(e,t,`NEW.${n} IS DISTINCT FROM OLD.${n} AND ${holds(t,identifier(t.child))}`)}function referencedTrigger(e,t){let n=incomingReferences(e,t);return n.length===0?[]:[[`referenced_delete`,`DELETE`,n.some(t=>t.child===e.name)?` REFERENCING OLD TABLE AS ${s}`:``,referencedDeleteCheck],[`referenced_update`,`UPDATE`,``,referencedUpdateCheck]].flatMap(([t,r,i,a])=>{let o=derivedIdentifier(e.name,t,`fk`);return[`CREATE OR REPLACE FUNCTION ${o}() RETURNS trigger LANGUAGE plpgsql AS ${dollarQuoted([`BEGIN`,...n.map(t=>a(e,t)),` RETURN NULL;`,`END`].join(`
|
|
9
|
+
`))}`,`CREATE OR REPLACE TRIGGER ${o} AFTER ${r} ON ${identifier(e.name)}${i} FOR EACH ROW EXECUTE FUNCTION ${o}()`]})}function generateTableDDL(e,t={}){let n=identifier(e.name),r=new Map((t.tables??[e]).map(e=>[e.name,e])),i=/* @__PURE__ */ new Set,a=[],o=[],s=[` "id" uuid PRIMARY KEY DEFAULT gen_random_uuid()`],c=tableReferences(e),l=new Map(c.filter(isConstraintReference).map(e=>[e.column,e]));for(let[r,c]of Object.entries(e.fields)){if(r===`id`)continue;if(c.serial&&c.type!==`integer`){let t=sequenceName(e.name,r);a.push(`CREATE SEQUENCE IF NOT EXISTS ${t} ${sequenceRange(c.serial)}`),o.push(`ALTER SEQUENCE ${t} OWNED BY ${n}.${identifier(r)}`)}let u=l.get(r),d=u&&!t.deferredReferences?.has(r)?` ${referenceClause(u)}`:``,f=columnDefinition(e.name,r,c);for(let e of f.functions)i.add(e);s.push(` ${f.sql}${d}`)}let u=[...Object.entries(e.indexes??{}).filter(([,e])=>e.unique).map(([t,r])=>`CREATE UNIQUE INDEX IF NOT EXISTS ${derivedIdentifier(e.name,t,`idx`)} ON ${n} (${r.fields.map(identifier).join(`, `)})`),...Object.entries(e.fields).filter(([e])=>e!==`id`).flatMap(([e,t])=>nestedUniqueMembers(e,t,[])).map(t=>nestedUniqueIndex(e.name,t))];for(let t of l.values())referencedColumnType(t,r,`${e.name}.${t.column}`);return{functions:[...i],statements:[...a,`CREATE TABLE IF NOT EXISTS ${n} (\n${s.join(`,
|
|
10
|
+
`)}\n)`,...o,...u,...referenceTrigger(e,c.filter(e=>!isConstraintReference(e)),r),...referencedTrigger(e,r)]}}function addForeignKey(e,t){let n=derivedName(e.name,t.column,`fk`),r=identifier(e.name);return`DO ${dollarQuoted([`BEGIN`,`IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = ${stringLiteral(n)} AND conrelid = ${stringLiteral(r)}::regclass) THEN`,`ALTER TABLE ${r} ADD CONSTRAINT ${identifier(n)} FOREIGN KEY (${identifier(t.column)}) ${referenceClause(t)};`,`END IF;`,`END`].join(`
|
|
11
|
+
`))}`}function planCreation(e){let t=new Set(e.map(e=>e.name)),n=/* @__PURE__ */ new Set,r=[...e],i=[],a=/* @__PURE__ */ new Map,pendingOf=e=>tableReferences(e).filter(isConstraintReference).filter(r=>t.has(r.table)&&r.table!==e.name&&!n.has(r.table));for(;r.length>0;){let e=r.findIndex(e=>pendingOf(e).length===0),[t]=r.splice(Math.max(e,0),1),o=pendingOf(t);o.length>0&&a.set(t,o),n.add(t.name),i.push(t)}return{ordered:i,deferred:a}}function generateSchemaDDL(e){let{ordered:t,deferred:n}=planCreation(e),r=t.map(t=>generateTableDDL(t,{tables:e,deferredReferences:new Set(n.get(t)?.map(e=>e.column))})),i=[...new Set(r.flatMap(e=>e.functions))],a=t.flatMap(e=>(n.get(e)??[]).map(t=>addForeignKey(e,t)));return[i,...r.map(e=>e.statements),a].filter(e=>e.length>0).map(e=>e.map(e=>`${e};`).join(`
|
|
8
12
|
`)).join(`
|
|
9
13
|
|
|
10
14
|
`)}function templateLiteral(e){return`\`${e.replaceAll(`\\`,`\\\\`).replaceAll("`","\\`").replaceAll("${","\\${").replaceAll(`\r`,`\\r`)}\``}function generatePgliteSchemaModule(e,t){let n=e.map(({namespace:e,tables:t})=>` ${JSON.stringify(e)}: ${templateLiteral(generateSchemaDDL(t))},`);return[`/**`,` * Auto-generated PGlite schema for TailorDB tables.`," * Create a namespace's tables in a test with `pglite.exec(pgliteSchema[namespace])`.",` *`,` * DO NOT EDIT - This file is auto-generated by ${t.generatedBy}.`,` */`,``,`export const pgliteSchema = {`,...n,`} as const;`,``].join(`
|
|
11
|
-
`)}function toDDLTables(e){return Object.values(e).map(e=>({name:e.name,fields:Object.fromEntries(Object.entries(e.fields).map(([e,t])=>[e,t.config])),indexes:e.indexes}))}function generatePGliteSchemaModule(e){return generatePgliteSchemaModule(e.map(({namespace:e,tables:t})=>({namespace:e,tables:toDDLTables(t)})),{generatedBy:`the kysely-type plugin`})}function mapFieldTypeToColumnType(e,t=!1){switch(e){case`uuid`:case`string`:case`decimal`:return`string`;case`integer`:case`float`:return`number`;case`date`:return t?`TemporalDate`:`Timestamp`;case`datetime`:return t?`TemporalInstant`:`Timestamp`;case`time`:return t?`TemporalTime`:`string`;case`bool`:case`boolean`:return`boolean`;case`enum`:case`nested`:throw Error(`Field type "${e}" has no scalar column type; resolve it before mapping.`);default:return`string`}}const
|
|
12
|
-
`)}${a.length>0?`;`:``}\n}`,s=Object.values(n).some(e=>e.required!==!0),c=Object.values(n).some(e=>e.hooks?.create||e.default!==void 0||e.optionalOnCreate===!0);return usesColumnTypeAlias(i)||s||c?{type:`ObjectColumnType<${o}>`,usedUtilityTypes:{...i,ObjectColumnType:!0}}:{type:o,usedUtilityTypes:i}}function getBaseType(e,t,n){let r=e.type,i=emptyUsedUtilityTypes();if(r===`enum`)return{type:getEnumType(e),usedUtilityTypes:i};if(r===`nested`)return getNestedType(e,t);let a=mapFieldTypeToColumnType(r,t&&!(n&&r===`time`));switch(a){case`Timestamp`:i.Timestamp=!0;break;case`TemporalDate`:i.TemporalDate=!0;break;case`TemporalInstant`:i.TemporalInstant=!0;break;case`TemporalTime`:i.TemporalTime=!0}return{type:a,usedUtilityTypes:i}}function generateFieldType(e,t,n=!1){let r=getBaseType(e,t,n),i={...r.usedUtilityTypes},a=e.array===!0,o=e.required!==!0,c
|
|
15
|
+
`)}function toDDLTables(e){return Object.values(e).map(e=>({name:e.name,fields:Object.fromEntries(Object.entries(e.fields).map(([e,t])=>[e,t.config])),indexes:e.indexes}))}function generatePGliteSchemaModule(e){return generatePgliteSchemaModule(e.map(({namespace:e,tables:t})=>({namespace:e,tables:toDDLTables(t)})),{generatedBy:`the kysely-type plugin`})}function mapFieldTypeToColumnType(e,t=!1){switch(e){case`uuid`:case`string`:case`decimal`:return`string`;case`integer`:case`float`:return`number`;case`date`:return t?`TemporalDate`:`Timestamp`;case`datetime`:return t?`TemporalInstant`:`Timestamp`;case`time`:return t?`TemporalTime`:`string`;case`bool`:case`boolean`:return`boolean`;case`enum`:case`nested`:throw Error(`Field type "${e}" has no scalar column type; resolve it before mapping.`);default:return`string`}}const c=/* @__PURE__ */ new Map([[`Timestamp`,{select:`Date`,write:`Date | string`}],[`TemporalDate`,{select:`Temporal.PlainDate`,write:`Temporal.PlainDate | string`}],[`TemporalInstant`,{select:`Temporal.Instant`,write:`Temporal.Instant | string`}],[`TemporalTime`,{select:`Temporal.PlainTime`,write:`Temporal.PlainTime | string`}]]);function emptyUsedUtilityTypes(){return{Timestamp:!1,TemporalDate:!1,TemporalInstant:!1,TemporalTime:!1,Serial:!1,ObjectColumnType:!1,ArrayColumnType:!1}}function mergeUsedUtilityTypes(e,t){return{Timestamp:e.Timestamp||t.Timestamp,TemporalDate:e.TemporalDate||t.TemporalDate,TemporalInstant:e.TemporalInstant||t.TemporalInstant,TemporalTime:e.TemporalTime||t.TemporalTime,Serial:e.Serial||t.Serial,ObjectColumnType:e.ObjectColumnType||t.ObjectColumnType,ArrayColumnType:e.ArrayColumnType||t.ArrayColumnType}}function usesColumnTypeAlias(e){return e.Timestamp||e.TemporalDate||e.TemporalInstant||e.TemporalTime}function getEnumType(e){let t=e.allowedValues;return t&&Array.isArray(t)?t.map(e=>`"${typeof e==`string`?e:e.value}"`).join(` | `):`string`}function getNestedType(e,t){let n=e.fields;if(!n||typeof n!=`object`)return{type:`string`,usedUtilityTypes:emptyUsedUtilityTypes()};let r=Object.entries(n).map(([e,n])=>{let r=generateFieldType(n,t,!0);return{fieldType:`${e}${n.required===!0?``:`?`}: ${r.type}`,usedUtilityTypes:r.usedUtilityTypes}}),i=r.reduce((e,t)=>mergeUsedUtilityTypes(e,t.usedUtilityTypes),emptyUsedUtilityTypes()),a=r.map(e=>e.fieldType),o=`{\n ${a.join(`;
|
|
16
|
+
`)}${a.length>0?`;`:``}\n}`,s=Object.values(n).some(e=>e.required!==!0),c=Object.values(n).some(e=>e.hooks?.create||e.default!==void 0||e.optionalOnCreate===!0);return usesColumnTypeAlias(i)||s||c?{type:`ObjectColumnType<${o}>`,usedUtilityTypes:{...i,ObjectColumnType:!0}}:{type:o,usedUtilityTypes:i}}function getBaseType(e,t,n){let r=e.type,i=emptyUsedUtilityTypes();if(r===`enum`)return{type:getEnumType(e),usedUtilityTypes:i};if(r===`nested`)return getNestedType(e,t);let a=mapFieldTypeToColumnType(r,t&&!(n&&r===`time`));switch(a){case`Timestamp`:i.Timestamp=!0;break;case`TemporalDate`:i.TemporalDate=!0;break;case`TemporalInstant`:i.TemporalInstant=!0;break;case`TemporalTime`:i.TemporalTime=!0}return{type:a,usedUtilityTypes:i}}function generateFieldType(e,t,n=!1){let r=getBaseType(e,t,n),i={...r.usedUtilityTypes},a=e.array===!0,o=e.required!==!0,s=c.has(r.type),l=r.type;return a&&(s||l.startsWith(`ObjectColumnType<`)?(l=`ArrayColumnType<${r.type}>`,i.ArrayColumnType=!0):l=e.type===`enum`?`(${r.type})[]`:`${r.type}[]`),o&&(l=`${l} | null`),e.serial&&(i.Serial=!0,l=`Serial<${l}>`),(e.hooks?.create||e.default!==void 0||e.optionalOnCreate===!0)&&(l=`Generated<${l}>`),{type:l,usedUtilityTypes:i}}function generateTableInterface(t,n,r){let i=Object.entries(n).filter(([e])=>e!==`id`).map(([e,t])=>({fieldName:e,...generateFieldType(t,r)})),a=[`id: Generated<string>;`,...i.map(e=>`${e.fieldName}: ${e.type};`)],o=i.reduce((e,t)=>mergeUsedUtilityTypes(e,t.usedUtilityTypes),emptyUsedUtilityTypes());return{typeDef:e`
|
|
13
17
|
${t}: {
|
|
14
18
|
${a.join(`
|
|
15
19
|
`)}
|
|
@@ -49,5 +53,5 @@ import{t as e}from"./multiline-EyzjEwn9.mjs";import{resolve as t}from"pathe";con
|
|
|
49
53
|
`].join(`
|
|
50
54
|
|
|
51
55
|
`)+`
|
|
52
|
-
`}const
|
|
53
|
-
//# sourceMappingURL=kysely-type-
|
|
56
|
+
`}const l=`@tailor-platform/kysely-type`,u=`./generated/tailordb.ts`;function kyselyTypePlugin(e){return{id:l,description:`Generates Kysely type definitions for TailorDB tables`,pluginConfig:e,async onTailorDBReady(e){let{distPath:n,pgliteSchemaPath:r,temporal:i}=e.pluginConfig;if(r&&t(n)===t(r))throw Error(`distPath and pgliteSchemaPath must resolve to different files.`);let a=[];for(let t of e.tailordb){let e=[];for(let n of Object.values(t.tables)){let t=await processKyselyType(n,i);e.push(t)}e.length!==0&&a.push({namespace:t.namespace,types:e})}let o=[];if(a.length>0){let t=generateUnifiedKyselyTypes(a,i);o.push({path:e.pluginConfig.distPath,content:t}),e.pluginConfig.pgliteSchemaPath&&o.push({path:e.pluginConfig.pgliteSchemaPath,content:generatePGliteSchemaModule(e.tailordb.filter(e=>Object.keys(e.tables).length>0))})}return{files:o}}}}export{processKyselyFields as a,dropUnresolvableReferences as c,generateUnifiedKyselyTypes as i,generatePgliteSchemaModule as l,l as n,c as o,kyselyTypePlugin as r,mapFieldTypeToColumnType as s,u as t,withoutReference as u};
|
|
57
|
+
//# sourceMappingURL=kysely-type-DhAZqdQg.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kysely-type-DhAZqdQg.mjs","names":["multiline","utf8","fieldType","name","hash","byte","value","suffix","tableName","memberName","kind","head","tag","body","base","field","pgType","label","CURRENT_TIME_EXPRESSIONS","currentTime","v","OCTAL_FUNCTION_NAME","SERIAL_CONVERSIONS","nextval","groups","format","conversion","fieldName","range","serial","sequence","number","render","width","zeroPad","prefix","column","parts","serialDefault","hasDefault","filledOnCreate","key","here","path","child","CASTABLE_UNIQUE_TYPES","keys","member","indexed","table","reference","type","target","tables","targetField","check","_foreignKey","_type","_field","rest","byName","message","references","parentValue","DELETED_ROWS","source","condition","remaining","event","transition","tableIdentifier","options","t","functions","sequences","ownerships","columns","constraintReferences","r","constraint","inline","statement","indexes","index","names","created","ordered","deferred","pending","tableDDLs","ddl","constraints","group","entries","namespaces","namespace","temporal","COLUMN_TYPE_ALIASES","a","b","usedUtilityTypes","allowedValues","fieldConfig","fields","fieldResults","config","result","aggregatedUtilityTypes","acc","fieldTypes","obj","hasOptionalFields","hasGeneratedFields","nested","baseTypeResult","isArray","isNullable","isColumnTypeBase","finalType","fieldLines","parsedField","namespaceData","globalUsedUtilityTypes","ns","utilityTypeImports","types","line","KyselyGeneratorID","DEFAULT_KYSELY_TYPES_DIST_PATH","ctx","pgliteSchemaPath","resolve","distPath","allNamespaceData","typeMetadataList","metadata","files","content"],"sources":["../src/utils/tailordb-ddl.ts","../src/plugin/builtin/kysely-type/pglite-schema.ts","../src/utils/field-column-type.ts","../src/plugin/builtin/kysely-type/type-processor.ts","../src/plugin/builtin/kysely-type/index.ts"],"sourcesContent":["/**\n * PostgreSQL DDL derived from TailorDB table definitions, for creating the\n * tables a PGlite-backed test needs. The columns match the flat shape the\n * Kysely type generators emit, not TailorDB's storage layout.\n */\n\n/** The field shape the DDL generator reads; parsed and snapshot field configs are both assignable. */\nexport interface DDLFieldConfig {\n type: string;\n required?: boolean;\n array?: boolean;\n unique?: boolean;\n serial?: { start: number; maxValue?: number; format?: string };\n scale?: number;\n default?: unknown;\n optionalOnCreate?: boolean;\n foreignKey?: boolean;\n foreignKeyType?: string;\n foreignKeyField?: string;\n hooks?: { create?: unknown; update?: unknown };\n fields?: Record<string, DDLFieldConfig>;\n}\n\n/** A table to emit DDL for. */\nexport interface DDLTableConfig {\n name: string;\n fields: Record<string, DDLFieldConfig>;\n indexes?: Record<string, { fields: string[]; unique?: boolean }>;\n}\n\nconst MAX_IDENTIFIER_BYTES = 63;\n// The platform rounds decimals to their scale (6 unless configured); numeric\n// needs a precision to carry a scale, and the maximum leaves it unconstrained.\nconst DECIMAL_PRECISION = 1000;\nconst DEFAULT_DECIMAL_SCALE = 6;\nconst utf8 = new TextEncoder();\n\n/**\n * Map a TailorDB field type to the PostgreSQL column type PGlite tests use for it.\n * @param fieldType - TailorDB field type name\n * @returns The PostgreSQL type name\n * @throws If the type is not a TailorDB field type\n */\nexport function mapFieldTypeToPostgresType(fieldType: string): string {\n switch (fieldType) {\n case \"uuid\":\n return \"uuid\";\n case \"string\":\n case \"enum\":\n return \"text\";\n case \"boolean\":\n case \"bool\":\n return \"boolean\";\n case \"integer\":\n return \"integer\";\n case \"float\":\n return \"double precision\";\n case \"decimal\":\n return \"numeric\";\n case \"date\":\n return \"date\";\n case \"datetime\":\n return \"timestamptz\";\n case \"time\":\n return \"time\";\n case \"nested\":\n return \"jsonb\";\n default:\n throw new Error(`Field type \"${fieldType}\" has no PostgreSQL column type.`);\n }\n}\n\nfunction identifier(name: string): string {\n return `\"${name.replaceAll('\"', '\"\"')}\"`;\n}\n\nfunction fnv1aHex(value: string): string {\n let hash = 0x811c9dc5;\n for (const byte of utf8.encode(value)) {\n hash = Math.imul(hash ^ byte, 0x01000193) >>> 0;\n }\n return hash.toString(16).padStart(8, \"0\");\n}\n\ntype DerivedNameKind = \"seq\" | \"idx\" | \"nested_idx\" | \"fk\";\n\nfunction derivedName(tableName: string, memberName: string, kind: DerivedNameKind): string {\n const suffix = `_${fnv1aHex(JSON.stringify([tableName, memberName, kind]))}_${kind}`;\n let head = `${tableName}_${memberName}`;\n while (utf8.encode(head + suffix).length > MAX_IDENTIFIER_BYTES) head = head.slice(0, -1);\n return head + suffix;\n}\n\nfunction derivedIdentifier(tableName: string, memberName: string, kind: DerivedNameKind): string {\n return identifier(derivedName(tableName, memberName, kind));\n}\n\nfunction dollarQuoted(body: string): string {\n let tag = \"$fk$\";\n while (body.includes(tag)) tag = `${tag.slice(0, -1)}_$`;\n return `${tag}\\n${body}\\n${tag}`;\n}\n\nfunction stringLiteral(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`;\n}\n\nfunction columnType(field: DDLFieldConfig): string {\n const base =\n field.type === \"decimal\"\n ? `numeric(${DECIMAL_PRECISION}, ${field.scale ?? DEFAULT_DECIMAL_SCALE})`\n : mapFieldTypeToPostgresType(field.type);\n return field.array && field.type !== \"nested\" ? `${base}[]` : base;\n}\n\nfunction scalarLiteral(value: unknown, field: DDLFieldConfig, label: string): string {\n const pgType = mapFieldTypeToPostgresType(field.type);\n if (value instanceof Date) {\n if (Number.isNaN(value.getTime())) {\n throw new Error(`Default of field ${label} is an invalid Date.`);\n }\n return `${stringLiteral(value.toISOString())}::${pgType}`;\n }\n switch (typeof value) {\n case \"string\":\n return pgType === \"text\" ? stringLiteral(value) : `${stringLiteral(value)}::${pgType}`;\n case \"number\":\n if (!Number.isFinite(value)) {\n throw new Error(`Default of field ${label} is not a finite number.`);\n }\n return String(value);\n case \"boolean\":\n return value ? \"TRUE\" : \"FALSE\";\n default:\n throw new Error(`Default of field ${label} cannot be rendered as a SQL literal.`);\n }\n}\n\nconst CURRENT_TIME_EXPRESSIONS = new Map([\n [\"datetime\", \"now()\"],\n [\"date\", \"CURRENT_DATE\"],\n [\"time\", \"LOCALTIME\"],\n]);\n\nfunction defaultExpression(field: DDLFieldConfig, label: string): string {\n const value = field.default;\n const currentTime = CURRENT_TIME_EXPRESSIONS.get(field.type);\n if (value === \"now\" && currentTime !== undefined) {\n return currentTime;\n }\n if (field.array) {\n if (!Array.isArray(value)) {\n throw new Error(`Default of array field ${label} must be an array.`);\n }\n const pgType = columnType(field);\n if (value.length === 0) return `'{}'::${pgType}`;\n return `ARRAY[${value.map((v) => scalarLiteral(v, field, label)).join(\", \")}]::${pgType}`;\n }\n return scalarLiteral(value, field, label);\n}\n\nconst OCTAL_FUNCTION_NAME = \"tailor_to_oct\";\n\n// to_oct() needs Postgres 17; PGlite 0.2 runs Postgres 16.\nconst OCTAL_FUNCTION_DDL = `CREATE OR REPLACE FUNCTION ${OCTAL_FUNCTION_NAME}(n bigint) RETURNS text LANGUAGE sql IMMUTABLE AS ${dollarQuoted(\n [\n \"WITH RECURSIVE o(q, s) AS (\",\n \" SELECT n / 8, (n % 8)::text\",\n \" UNION ALL SELECT q / 8, (q % 8)::text || s FROM o WHERE q > 0\",\n \")\",\n \"SELECT s FROM o WHERE q = 0\",\n ].join(\"\\n\"),\n)}`;\n\ninterface SerialConversion {\n /** Expression rendering the sequence's next value in this conversion's base */\n render: (nextval: string) => string;\n /** Statements creating the functions `render` calls */\n functions: readonly string[];\n}\n\nconst SERIAL_CONVERSIONS = {\n d: { render: (nextval) => nextval, functions: [] },\n o: {\n render: (nextval) => `${OCTAL_FUNCTION_NAME}(${nextval})`,\n functions: [OCTAL_FUNCTION_DDL],\n },\n x: { render: (nextval) => `to_hex(${nextval})`, functions: [] },\n X: { render: (nextval) => `upper(to_hex(${nextval}))`, functions: [] },\n} satisfies Record<string, SerialConversion>;\n\ntype SerialConversionName = keyof typeof SERIAL_CONVERSIONS;\n\nfunction isSerialConversion(name: string): name is SerialConversionName {\n return Object.hasOwn(SERIAL_CONVERSIONS, name);\n}\n\ninterface SerialFormat {\n prefix: string;\n width: number;\n zeroPad: boolean;\n conversion: SerialConversionName;\n suffix: string;\n}\n\n// printf-style with exactly one conversion specifier.\nfunction parseSerialFormat(format: string, label: string): SerialFormat {\n const match =\n /^(?<prefix>(?:%%|[^%])*)%(?<zero>0?)(?<width>\\d*)(?<conversion>[a-zA-Z])(?<suffix>(?:%%|[^%])*)$/.exec(\n format,\n );\n const groups = match?.groups;\n const conversion = groups?.conversion;\n if (!groups || conversion === undefined || !isSerialConversion(conversion)) {\n throw new Error(\n `Serial format \"${format}\" of field ${label} is not supported; use a single %d, %o, %x, or %X specifier with an optional width (e.g. \"INV-%05d\"), and %% for a literal %.`,\n );\n }\n return {\n prefix: (groups.prefix ?? \"\").replaceAll(\"%%\", \"%\"),\n zeroPad: groups.zero === \"0\",\n width: groups.width ? Number(groups.width) : 0,\n conversion,\n suffix: (groups.suffix ?? \"\").replaceAll(\"%%\", \"%\"),\n };\n}\n\nfunction sequenceName(tableName: string, fieldName: string): string {\n return derivedIdentifier(tableName, fieldName, \"seq\");\n}\n\n// A sequence's minimum defaults to 1, which rejects a start of 0.\nfunction sequenceRange(serial: NonNullable<DDLFieldConfig[\"serial\"]>): string {\n const range = [`START WITH ${serial.start}`, `MINVALUE ${serial.start}`];\n if (serial.maxValue !== undefined) range.push(`MAXVALUE ${serial.maxValue}`);\n return range.join(\" \");\n}\n\ninterface SqlWithFunctions {\n sql: string;\n /** Statements creating the functions `sql` calls */\n functions: readonly string[];\n}\n\nfunction serialStringDefault(\n sequence: string,\n format: string | undefined,\n label: string,\n): SqlWithFunctions {\n const nextval = `nextval(${stringLiteral(sequence)})`;\n if (format === undefined) return { sql: `(${nextval}::text)`, functions: [] };\n const { prefix, width, zeroPad, conversion, suffix } = parseSerialFormat(format, label);\n const { render, functions } = SERIAL_CONVERSIONS[conversion];\n const number = render(nextval);\n let value = conversion === \"d\" ? `${number}::text` : number;\n if (width > 0) {\n value = `format('%${width}s', ${number})`;\n if (zeroPad) value = `translate(${value}, ' ', '0')`;\n }\n const parts = [\n ...(prefix ? [stringLiteral(prefix)] : []),\n value,\n ...(suffix ? [stringLiteral(suffix)] : []),\n ];\n return { sql: `(${parts.join(\" || \")})`, functions };\n}\n\nfunction columnDefinition(\n tableName: string,\n fieldName: string,\n field: DDLFieldConfig,\n): SqlWithFunctions {\n const column = identifier(fieldName);\n const label = `${identifier(tableName)}.${column}`;\n const parts = [column, columnType(field)];\n\n if (field.serial) {\n if (field.type === \"integer\") {\n parts.push(`GENERATED BY DEFAULT AS IDENTITY (${sequenceRange(field.serial)})`);\n if (field.unique) parts.push(\"UNIQUE\");\n return { sql: parts.join(\" \"), functions: [] };\n }\n if (field.required) parts.push(\"NOT NULL\");\n if (field.unique) parts.push(\"UNIQUE\");\n const serialDefault = serialStringDefault(\n sequenceName(tableName, fieldName),\n field.serial.format,\n label,\n );\n parts.push(`DEFAULT ${serialDefault.sql}`);\n return { sql: parts.join(\" \"), functions: serialDefault.functions };\n }\n\n const hasDefault = field.default !== undefined;\n const filledOnCreate = field.hooks?.create !== undefined || field.optionalOnCreate === true;\n if (field.required && (hasDefault || !filledOnCreate)) parts.push(\"NOT NULL\");\n if (field.unique) parts.push(\"UNIQUE\");\n if (hasDefault) parts.push(`DEFAULT ${defaultExpression(field, label)}`);\n return { sql: parts.join(\" \"), functions: [] };\n}\n\ninterface Reference {\n /** Column holding the reference */\n column: string;\n /** JSONPath from the column value to each referencing value; `$` for a scalar column */\n path: string;\n table: string;\n field: string;\n /** TailorDB type of the referencing value */\n type: string;\n}\n\nfunction jsonPathKey(key: string): string {\n return `\"${key.replaceAll(\"\\\\\", \"\\\\\\\\\").replaceAll('\"', '\\\\\"')}\"`;\n}\n\nfunction referencesWithin(column: string, field: DDLFieldConfig, path: string): Reference[] {\n const here = field.array ? `${path}[*]` : path;\n if (field.type === \"nested\") {\n return Object.entries(field.fields ?? {}).flatMap(([key, child]) =>\n referencesWithin(column, child, `${here}.${jsonPathKey(key)}`),\n );\n }\n if (!field.foreignKey || field.foreignKeyType === undefined) return [];\n return [\n {\n column,\n path: here,\n table: field.foreignKeyType,\n field: field.foreignKeyField ?? \"id\",\n type: field.type,\n },\n ];\n}\n\n// The platform indexes a unique member of a nested object by the value at its\n// path, cast to the member's type. Members inside an array have no single value\n// to index, so they are left out.\nconst CASTABLE_UNIQUE_TYPES = new Set([\"integer\", \"float\", \"decimal\", \"boolean\", \"bool\", \"uuid\"]);\n\ninterface NestedUniqueMember {\n column: string;\n path: string[];\n field: DDLFieldConfig;\n}\n\nfunction nestedUniqueMembers(\n column: string,\n field: DDLFieldConfig,\n path: string[],\n): NestedUniqueMember[] {\n if (field.array) return [];\n if (field.type === \"nested\") {\n return Object.entries(field.fields ?? {}).flatMap(([key, child]) =>\n nestedUniqueMembers(column, child, [...path, key]),\n );\n }\n return field.unique && path.length > 0 ? [{ column, path, field }] : [];\n}\n\nfunction nestedUniqueIndex(tableName: string, member: NestedUniqueMember): string {\n const keys = member.path.map(stringLiteral).join(\", \");\n const value = `${identifier(member.column)} #>> ARRAY[${keys}]`;\n const indexed = CASTABLE_UNIQUE_TYPES.has(member.field.type)\n ? `CAST(${value} AS ${mapFieldTypeToPostgresType(member.field.type)})`\n : value;\n const name = derivedIdentifier(\n tableName,\n `${member.column}.${member.path.join(\".\")}`,\n \"nested_idx\",\n );\n return `CREATE UNIQUE INDEX IF NOT EXISTS ${name} ON ${identifier(tableName)} ((${indexed}))`;\n}\n\nfunction tableReferences(table: DDLTableConfig): Reference[] {\n return Object.entries(table.fields)\n .filter(([fieldName]) => fieldName !== \"id\")\n .flatMap(([fieldName, field]) => referencesWithin(fieldName, field, \"$\"));\n}\n\n// Postgres cannot reference from an array or jsonb column, so only a plain\n// column's reference becomes a FOREIGN KEY constraint.\nfunction isConstraintReference(reference: Reference): boolean {\n return reference.path === \"$\";\n}\n\nfunction referenceClause(reference: Reference): string {\n return `REFERENCES ${identifier(reference.table)} (${identifier(reference.field)})`;\n}\n\nfunction declaredType(type: string): string {\n return type === \"bool\" ? \"boolean\" : type;\n}\n\ntype ReferenceCheck = { pgType: string } | { problem: string };\n\nfunction checkReference(\n reference: Reference,\n tables: ReadonlyMap<string, DDLTableConfig>,\n): ReferenceCheck {\n const target = tables.get(reference.table);\n if (!target) return { problem: `references unknown table \"${reference.table}\".` };\n const targetField =\n reference.field === \"id\" ? { type: \"uuid\", unique: true } : target.fields[reference.field];\n if (!targetField) {\n return {\n problem: `references unknown field \"${reference.field}\" of table \"${reference.table}\".`,\n };\n }\n if (!targetField.unique || declaredType(targetField.type) !== declaredType(reference.type)) {\n return {\n problem: `references \"${reference.table}\".\"${reference.field}\", which must be unique and of the same type as the referencing field.`,\n };\n }\n return { pgType: mapFieldTypeToPostgresType(targetField.type) };\n}\n\nfunction referencedColumnType(\n reference: Reference,\n tables: ReadonlyMap<string, DDLTableConfig>,\n label: string,\n): string {\n const check = checkReference(reference, tables);\n if (\"problem\" in check) throw new Error(`Field ${label} ${check.problem}`);\n return check.pgType;\n}\n\n/**\n * The field without the relation it declares.\n * @param field - A field config\n * @returns The field with its foreign key settings removed\n */\nexport function withoutReference(field: DDLFieldConfig): DDLFieldConfig {\n const {\n foreignKey: _foreignKey,\n foreignKeyType: _type,\n foreignKeyField: _field,\n ...rest\n } = field;\n return rest;\n}\n\nfunction withoutUnresolvableReference(\n field: DDLFieldConfig,\n tables: ReadonlyMap<string, DDLTableConfig>,\n): DDLFieldConfig {\n if (field.fields) {\n return {\n ...field,\n fields: Object.fromEntries(\n Object.entries(field.fields).map(([name, child]) => [\n name,\n withoutUnresolvableReference(child, tables),\n ]),\n ),\n };\n }\n if (!field.foreignKey || field.foreignKeyType === undefined) return field;\n const reference = {\n column: \"\",\n path: \"$\",\n table: field.foreignKeyType,\n field: field.foreignKeyField ?? \"id\",\n type: field.type,\n };\n return \"problem\" in checkReference(reference, tables) ? withoutReference(field) : field;\n}\n\n/**\n * Remove the references the given tables cannot satisfy: a target table or\n * field that is missing, not unique, or of another type than the referencing\n * field. {@link generateSchemaDDL} rejects such references, so this lets a\n * schema that is only partly consistent still render, minus those references.\n * @param tables - Tables of one schema\n * @returns The tables, with unsatisfiable references removed from their fields\n */\nexport function dropUnresolvableReferences(tables: readonly DDLTableConfig[]): DDLTableConfig[] {\n const byName = new Map(tables.map((table) => [table.name, table]));\n return tables.map((table) => ({\n ...table,\n fields: Object.fromEntries(\n Object.entries(table.fields).map(([name, field]) => [\n name,\n withoutUnresolvableReference(field, byName),\n ]),\n ),\n }));\n}\n\nfunction referenceCheck(\n reference: Reference,\n tables: ReadonlyMap<string, DDLTableConfig>,\n label: string,\n): string {\n const pgType = referencedColumnType(reference, tables, label);\n const target = `${identifier(reference.table)}.${identifier(reference.field)}`;\n const message = `violates foreign key constraints: % not found in ${target.replaceAll(\"%\", \"%%\")}`;\n return [\n ` FOR v IN SELECT jsonb_path_query(to_jsonb(NEW.${identifier(reference.column)}), ${stringLiteral(reference.path)}) LOOP`,\n ` IF jsonb_typeof(fk_check.v) <> 'null' AND NOT EXISTS (SELECT 1 FROM ${identifier(reference.table)} AS parent WHERE parent.${identifier(reference.field)} = (fk_check.v #>> '{}')::${pgType}) THEN`,\n ` RAISE EXCEPTION ${stringLiteral(message)}, fk_check.v #>> '{}' USING ERRCODE = 'foreign_key_violation';`,\n \" END IF;\",\n \" END LOOP;\",\n ].join(\"\\n\");\n}\n\nfunction referenceTrigger(\n table: DDLTableConfig,\n references: readonly Reference[],\n tables: ReadonlyMap<string, DDLTableConfig>,\n): string[] {\n if (references.length === 0) return [];\n const name = derivedIdentifier(table.name, \"references\", \"fk\");\n const checks = references.map((reference) =>\n referenceCheck(reference, tables, `${table.name}.${reference.column}`),\n );\n const body = [\n \"<<fk_check>>\",\n \"DECLARE v jsonb;\",\n \"BEGIN\",\n ...checks,\n \" RETURN NULL;\",\n \"END\",\n ].join(\"\\n\");\n return [\n `CREATE OR REPLACE FUNCTION ${name}() RETURNS trigger LANGUAGE plpgsql AS ${dollarQuoted(body)}`,\n `CREATE OR REPLACE TRIGGER ${name} AFTER INSERT OR UPDATE ON ${identifier(table.name)} FOR EACH ROW EXECUTE FUNCTION ${name}()`,\n ];\n}\n\ninterface IncomingReference extends Reference {\n /** Table whose array or nested column holds the reference */\n child: string;\n pgType: string;\n}\n\nfunction incomingReferences(\n table: DDLTableConfig,\n tables: ReadonlyMap<string, DDLTableConfig>,\n): IncomingReference[] {\n return [...tables.values()].flatMap((child) =>\n tableReferences(child)\n .filter((reference) => !isConstraintReference(reference) && reference.table === table.name)\n .flatMap((reference) => {\n const check = checkReference(reference, tables);\n return \"pgType\" in check ? [{ ...reference, child: child.name, pgType: check.pgType }] : [];\n }),\n );\n}\n\nfunction holdsParent(reference: IncomingReference): string {\n const column = `child.${identifier(reference.column)}`;\n const parentValue = `OLD.${identifier(reference.field)}`;\n if (reference.path === \"$[*]\") return `${parentValue} = ANY(${column})`;\n return `EXISTS (SELECT 1 FROM jsonb_path_query(to_jsonb(${column}), ${stringLiteral(reference.path)}) AS held(v) WHERE CASE WHEN jsonb_typeof(held.v) = 'null' THEN false WHEN NOT pg_input_is_valid(held.v #>> '{}', ${stringLiteral(reference.pgType)}) THEN false ELSE (held.v #>> '{}')::${reference.pgType} = ${parentValue} END)`;\n}\n\nconst DELETED_ROWS = \"old_rows\";\n\nfunction holds(reference: IncomingReference, source: string): string {\n return `EXISTS (SELECT 1 FROM ${source} AS child WHERE ${holdsParent(reference)})`;\n}\n\nfunction refuseWhen(\n table: DDLTableConfig,\n reference: IncomingReference,\n condition: string,\n): string {\n const message = `update or delete on table \\`${table.name}\\` violates foreign key constraint: some record is still referenced from table \\`${reference.child}\\``;\n return [\n ` IF ${condition} THEN`,\n ` RAISE EXCEPTION ${stringLiteral(message.replaceAll(\"%\", \"%%\"))} USING ERRCODE = 'foreign_key_violation';`,\n \" END IF;\",\n ].join(\"\\n\");\n}\n\nfunction referencedDeleteCheck(table: DDLTableConfig, reference: IncomingReference): string {\n const remaining = holds(reference, identifier(reference.child));\n const condition =\n reference.child === table.name\n ? `${remaining} OR ${holds(reference, DELETED_ROWS)}`\n : remaining;\n return refuseWhen(table, reference, condition);\n}\n\nfunction referencedUpdateCheck(table: DDLTableConfig, reference: IncomingReference): string {\n const field = identifier(reference.field);\n return refuseWhen(\n table,\n reference,\n `NEW.${field} IS DISTINCT FROM OLD.${field} AND ${holds(reference, identifier(reference.child))}`,\n );\n}\n\nfunction referencedTrigger(\n table: DDLTableConfig,\n tables: ReadonlyMap<string, DDLTableConfig>,\n): string[] {\n const references = incomingReferences(table, tables);\n if (references.length === 0) return [];\n const selfReferencing = references.some((reference) => reference.child === table.name);\n const deletedRows = selfReferencing ? ` REFERENCING OLD TABLE AS ${DELETED_ROWS}` : \"\";\n return (\n [\n [\"referenced_delete\", \"DELETE\", deletedRows, referencedDeleteCheck],\n [\"referenced_update\", \"UPDATE\", \"\", referencedUpdateCheck],\n ] as const\n ).flatMap(([member, event, transition, check]) => {\n const name = derivedIdentifier(table.name, member, \"fk\");\n const body = [\n \"BEGIN\",\n ...references.map((reference) => check(table, reference)),\n \" RETURN NULL;\",\n \"END\",\n ].join(\"\\n\");\n return [\n `CREATE OR REPLACE FUNCTION ${name}() RETURNS trigger LANGUAGE plpgsql AS ${dollarQuoted(body)}`,\n `CREATE OR REPLACE TRIGGER ${name} AFTER ${event} ON ${identifier(table.name)}${transition} FOR EACH ROW EXECUTE FUNCTION ${name}()`,\n ];\n });\n}\n\n/** What {@link generateTableDDL} needs to know about the other tables of the schema. */\nexport interface TableDDLOptions {\n /** Every table of the schema, to resolve the types referenced columns point at */\n tables?: readonly DDLTableConfig[];\n /** Columns whose FOREIGN KEY is added after all tables exist, because the target is created later */\n deferredReferences?: ReadonlySet<string>;\n}\n\n/** DDL statements of one table, without trailing semicolons. */\ninterface TableDDL {\n /** Statements creating the functions that the table's statements call, to run before them */\n functions: readonly string[];\n /** Statements creating the table and everything it owns, in execution order */\n statements: string[];\n}\n\n/**\n * DDL statements that create one table: the functions its string serial\n * formats call, any sequences its string serial fields draw from, the table,\n * the sequences' ownership of their columns, its unique indexes, then the\n * triggers that enforce the references Postgres cannot express as a FOREIGN\n * KEY (inside array and nested columns): one checking the references the table\n * holds, one refusing to delete a row, and one refusing to change the key of a\n * row, that another table's array or nested value still points at. Every\n * statement is `IF NOT EXISTS` or otherwise idempotent, so re-applying the\n * script on a database that already has the table is a no-op. Owning a\n * sequence makes `DROP TABLE` drop it and `TRUNCATE ... RESTART IDENTITY`\n * reset it to the configured start. Index names end in `_idx` so they cannot\n * take the `<table>_<column>_key` name Postgres gives a UNIQUE column, which\n * `IF NOT EXISTS` would otherwise silently skip.\n * @param table - Table name, fields, and indexes\n * @param options - The schema's other tables, and references to leave to later statements\n * @returns The functions apart from the other statements, so a schema creates each function once\n * @throws If a field type, default, or serial format cannot be expressed\n */\nexport function generateTableDDL(table: DDLTableConfig, options: TableDDLOptions = {}): TableDDL {\n const tableIdentifier = identifier(table.name);\n const tables = new Map((options.tables ?? [table]).map((t) => [t.name, t]));\n const functions = new Set<string>();\n const sequences: string[] = [];\n const ownerships: string[] = [];\n const columns = [` \"id\" uuid PRIMARY KEY DEFAULT gen_random_uuid()`];\n const references = tableReferences(table);\n const constraintReferences = new Map(\n references.filter(isConstraintReference).map((r) => [r.column, r]),\n );\n\n for (const [fieldName, field] of Object.entries(table.fields)) {\n if (fieldName === \"id\") continue;\n if (field.serial && field.type !== \"integer\") {\n const sequence = sequenceName(table.name, fieldName);\n sequences.push(`CREATE SEQUENCE IF NOT EXISTS ${sequence} ${sequenceRange(field.serial)}`);\n ownerships.push(\n `ALTER SEQUENCE ${sequence} OWNED BY ${tableIdentifier}.${identifier(fieldName)}`,\n );\n }\n const constraint = constraintReferences.get(fieldName);\n const inline =\n constraint && !options.deferredReferences?.has(fieldName)\n ? ` ${referenceClause(constraint)}`\n : \"\";\n const column = columnDefinition(table.name, fieldName, field);\n for (const statement of column.functions) functions.add(statement);\n columns.push(` ${column.sql}${inline}`);\n }\n\n const indexes = [\n ...Object.entries(table.indexes ?? {})\n .filter(([, index]) => index.unique)\n .map(\n ([name, index]) =>\n `CREATE UNIQUE INDEX IF NOT EXISTS ${derivedIdentifier(table.name, name, \"idx\")} ON ${tableIdentifier} (${index.fields.map(identifier).join(\", \")})`,\n ),\n ...Object.entries(table.fields)\n .filter(([fieldName]) => fieldName !== \"id\")\n .flatMap(([fieldName, field]) => nestedUniqueMembers(fieldName, field, []))\n .map((member) => nestedUniqueIndex(table.name, member)),\n ];\n\n for (const reference of constraintReferences.values()) {\n referencedColumnType(reference, tables, `${table.name}.${reference.column}`);\n }\n\n return {\n functions: [...functions],\n statements: [\n ...sequences,\n `CREATE TABLE IF NOT EXISTS ${tableIdentifier} (\\n${columns.join(\",\\n\")}\\n)`,\n ...ownerships,\n ...indexes,\n ...referenceTrigger(\n table,\n references.filter((r) => !isConstraintReference(r)),\n tables,\n ),\n ...referencedTrigger(table, tables),\n ],\n };\n}\n\nfunction addForeignKey(table: DDLTableConfig, reference: Reference): string {\n const name = derivedName(table.name, reference.column, \"fk\");\n const tableIdentifier = identifier(table.name);\n const body = [\n \"BEGIN\",\n `IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = ${stringLiteral(name)} AND conrelid = ${stringLiteral(tableIdentifier)}::regclass) THEN`,\n `ALTER TABLE ${tableIdentifier} ADD CONSTRAINT ${identifier(name)} FOREIGN KEY (${identifier(reference.column)}) ${referenceClause(reference)};`,\n \"END IF;\",\n \"END\",\n ].join(\"\\n\");\n return `DO ${dollarQuoted(body)}`;\n}\n\n// Tables come after the tables they reference. Where references form a cycle,\n// the first table of the cycle is created without the constraint that points\n// at a table not yet created, and the constraint is added once all tables exist.\nfunction planCreation(tables: readonly DDLTableConfig[]): {\n ordered: DDLTableConfig[];\n deferred: Map<DDLTableConfig, Reference[]>;\n} {\n const names = new Set(tables.map((table) => table.name));\n const created = new Set<string>();\n const remaining = [...tables];\n const ordered: DDLTableConfig[] = [];\n const deferred = new Map<DDLTableConfig, Reference[]>();\n const pendingOf = (table: DDLTableConfig) =>\n tableReferences(table)\n .filter(isConstraintReference)\n .filter((r) => names.has(r.table) && r.table !== table.name && !created.has(r.table));\n while (remaining.length > 0) {\n const index = remaining.findIndex((table) => pendingOf(table).length === 0);\n const [table] = remaining.splice(Math.max(index, 0), 1) as [DDLTableConfig];\n const pending = pendingOf(table);\n if (pending.length > 0) deferred.set(table, pending);\n created.add(table.name);\n ordered.push(table);\n }\n return { ordered, deferred };\n}\n\n/**\n * A single SQL script creating every given table, for `pglite.exec()`. The\n * functions that serial formats call are created first, once, and tables are\n * created after the tables they reference.\n * @param tables - Tables to create\n * @returns The script, empty when there are no tables\n * @throws If a field references a table or field that is not among the tables\n */\nexport function generateSchemaDDL(tables: readonly DDLTableConfig[]): string {\n const { ordered, deferred } = planCreation(tables);\n const tableDDLs = ordered.map((table) =>\n generateTableDDL(table, {\n tables,\n deferredReferences: new Set(deferred.get(table)?.map((r) => r.column)),\n }),\n );\n const functions = [...new Set(tableDDLs.flatMap((ddl) => ddl.functions))];\n const constraints = ordered.flatMap((table) =>\n (deferred.get(table) ?? []).map((reference) => addForeignKey(table, reference)),\n );\n return [functions, ...tableDDLs.map((ddl) => ddl.statements), constraints]\n .filter((group) => group.length > 0)\n .map((group) => group.map((statement) => `${statement};`).join(\"\\n\"))\n .join(\"\\n\\n\");\n}\n\n/** One namespace's tables, as the schema module groups them. */\nexport interface PgliteSchemaNamespace {\n namespace: string;\n tables: readonly DDLTableConfig[];\n}\n\n/** Options for {@link generatePgliteSchemaModule}. */\nexport interface PgliteSchemaModuleOptions {\n /** Named in the generated header as the producer users must not edit around. */\n generatedBy: string;\n}\n\n// A template literal keeps line feeds but folds a carriage return into one.\nfunction templateLiteral(value: string): string {\n const escaped = value\n .replaceAll(\"\\\\\", \"\\\\\\\\\")\n .replaceAll(\"`\", \"\\\\`\")\n .replaceAll(\"${\", \"\\\\${\")\n .replaceAll(\"\\r\", \"\\\\r\");\n return `\\`${escaped}\\``;\n}\n\n/**\n * Render the module that exports each namespace's `CREATE TABLE` script for\n * `pglite.exec()`.\n * @param namespaces - Namespaces with the tables to create\n * @param options - Header wording\n * @returns TypeScript source of the schema module\n */\nexport function generatePgliteSchemaModule(\n namespaces: readonly PgliteSchemaNamespace[],\n options: PgliteSchemaModuleOptions,\n): string {\n const entries = namespaces.map(\n ({ namespace, tables }) =>\n ` ${JSON.stringify(namespace)}: ${templateLiteral(generateSchemaDDL(tables))},`,\n );\n return [\n \"/**\",\n \" * Auto-generated PGlite schema for TailorDB tables.\",\n \" * Create a namespace's tables in a test with `pglite.exec(pgliteSchema[namespace])`.\",\n \" *\",\n ` * DO NOT EDIT - This file is auto-generated by ${options.generatedBy}.`,\n \" */\",\n \"\",\n \"export const pgliteSchema = {\",\n ...entries,\n \"} as const;\",\n \"\",\n ].join(\"\\n\");\n}\n","import { generatePgliteSchemaModule, type DDLTableConfig } from \"#/utils/tailordb-ddl\";\nimport type { TailorDBType } from \"#/parser/service/tailordb/types\";\n\n/** Tables of one namespace, as the schema module groups them. */\nexport interface PGliteSchemaNamespace {\n namespace: string;\n tables: Record<string, TailorDBType>;\n}\n\n/**\n * Reduce parsed tables to what the DDL generator reads.\n * @param tables - Parsed TailorDB tables keyed by name\n * @returns DDL table configs in the same order\n */\nexport function toDDLTables(tables: Record<string, TailorDBType>): DDLTableConfig[] {\n return Object.values(tables).map((type) => ({\n name: type.name,\n fields: Object.fromEntries(\n Object.entries(type.fields).map(([fieldName, field]) => [fieldName, field.config]),\n ),\n indexes: type.indexes,\n }));\n}\n\n/**\n * Render the module that exports each namespace's `CREATE TABLE` script for\n * `pglite.exec()`.\n * @param namespaces - Namespaces with their parsed tables\n * @returns TypeScript source of the schema module\n */\nexport function generatePGliteSchemaModule(namespaces: readonly PGliteSchemaNamespace[]): string {\n return generatePgliteSchemaModule(\n namespaces.map(({ namespace, tables }) => ({ namespace, tables: toDDLTables(tables) })),\n { generatedBy: \"the kysely-type plugin\" },\n );\n}\n","/** The Kysely column type a TailorDB field maps to, before array/null modifiers. */\nexport type FieldColumnType =\n | \"string\"\n | \"number\"\n | \"boolean\"\n | \"Timestamp\"\n | \"TemporalDate\"\n | \"TemporalInstant\"\n | \"TemporalTime\";\n\n/**\n * Map a scalar TailorDB field type to the column type generated code uses for it.\n *\n * With `temporal: false` (the default), `date`/`datetime` resolve to `Timestamp` and\n * `time` to `string`, because that's what the function runtime hands back for them by\n * default. With `temporal: true`, `date`/`datetime`/`time` resolve to their\n * `Temporal.PlainDate`/`Temporal.Instant`/`Temporal.PlainTime` counterparts instead,\n * matching a `getDB` created with `createGetDB({ temporal: true })`.\n *\n * `enum` and `nested` carry their own shape, so each generator resolves them\n * before reaching here; passing either is a caller bug rather than a `string`\n * column.\n * @param fieldType - TailorDB scalar field type name\n * @param temporal - Whether to map date/datetime/time fields to their Temporal column\n * types instead of their `Date`/`string` defaults\n * @returns The column type for the field, defaulting to `string`\n * @throws If given `enum` or `nested`\n */\nexport function mapFieldTypeToColumnType(fieldType: string, temporal = false): FieldColumnType {\n switch (fieldType) {\n case \"uuid\":\n case \"string\":\n case \"decimal\":\n return \"string\";\n case \"integer\":\n case \"float\":\n return \"number\";\n case \"date\":\n return temporal ? \"TemporalDate\" : \"Timestamp\";\n case \"datetime\":\n return temporal ? \"TemporalInstant\" : \"Timestamp\";\n case \"time\":\n return temporal ? \"TemporalTime\" : \"string\";\n case \"bool\":\n case \"boolean\":\n return \"boolean\";\n case \"enum\":\n case \"nested\":\n throw new Error(\n `Field type \"${fieldType}\" has no scalar column type; resolve it before mapping.`,\n );\n default:\n return \"string\";\n }\n}\n\n/** The select and write types a `ColumnType`-shaped alias expands to. */\nexport type ColumnTypeAliasExpansion = {\n /** Type the alias reads back as. */\n readonly select: string;\n /** Type the alias accepts on insert and update. */\n readonly write: string;\n};\n\n/**\n * Column types whose alias expands to a `ColumnType`, mapped to that expansion.\n *\n * Kysely only unwraps a `ColumnType` at the top level of a table property, so an\n * array of one of these stays wrapped in `ArrayColumnType<...>` rather than taking\n * a `[]` suffix, which would nest the `ColumnType` out of Kysely's reach. Where a\n * generator has to spell out the slots itself, it reads the expansion from here\n * rather than inlining the alias, which would nest just the same.\n *\n * Both type generators track alias usage per alias to decide which declarations to\n * emit, so adding an entry here also means teaching them to report the new alias.\n */\nexport const COLUMN_TYPE_ALIASES: ReadonlyMap<string, ColumnTypeAliasExpansion> = new Map<\n FieldColumnType,\n ColumnTypeAliasExpansion\n>([\n [\"Timestamp\", { select: \"Date\", write: \"Date | string\" }],\n [\"TemporalDate\", { select: \"Temporal.PlainDate\", write: \"Temporal.PlainDate | string\" }],\n [\"TemporalInstant\", { select: \"Temporal.Instant\", write: \"Temporal.Instant | string\" }],\n [\"TemporalTime\", { select: \"Temporal.PlainTime\", write: \"Temporal.PlainTime | string\" }],\n]);\n","import { COLUMN_TYPE_ALIASES, mapFieldTypeToColumnType } from \"#/utils/field-column-type\";\nimport multiline from \"#/utils/multiline\";\nimport {\n type KyselyFieldConfig,\n type KyselyNamespaceMetadata,\n type KyselyTypeMetadata,\n type UsedUtilityTypes,\n} from \"./types\";\nimport type { TailorDBType } from \"#/parser/service/tailordb/types\";\n\ntype FieldTypeResult = {\n type: string;\n usedUtilityTypes: UsedUtilityTypes;\n};\n\nfunction emptyUsedUtilityTypes(): UsedUtilityTypes {\n return {\n Timestamp: false,\n TemporalDate: false,\n TemporalInstant: false,\n TemporalTime: false,\n Serial: false,\n ObjectColumnType: false,\n ArrayColumnType: false,\n };\n}\n\nfunction mergeUsedUtilityTypes(a: UsedUtilityTypes, b: UsedUtilityTypes): UsedUtilityTypes {\n return {\n Timestamp: a.Timestamp || b.Timestamp,\n TemporalDate: a.TemporalDate || b.TemporalDate,\n TemporalInstant: a.TemporalInstant || b.TemporalInstant,\n TemporalTime: a.TemporalTime || b.TemporalTime,\n Serial: a.Serial || b.Serial,\n ObjectColumnType: a.ObjectColumnType || b.ObjectColumnType,\n ArrayColumnType: a.ArrayColumnType || b.ArrayColumnType,\n };\n}\n\n/**\n * Whether a utility-type usage record uses any `ColumnType`-shaped alias.\n * @param usedUtilityTypes - Utility-type usage record to check\n * @returns Whether any `ColumnType`-shaped alias is used\n */\nfunction usesColumnTypeAlias(usedUtilityTypes: UsedUtilityTypes): boolean {\n return (\n usedUtilityTypes.Timestamp ||\n usedUtilityTypes.TemporalDate ||\n usedUtilityTypes.TemporalInstant ||\n usedUtilityTypes.TemporalTime\n );\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: KyselyFieldConfig): 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 * @param temporal - Whether date/datetime/time fields resolve to their Temporal column\n * types instead of their `Date`/`string` defaults\n * @returns The nested type with used utility types\n */\nfunction getNestedType(fieldConfig: KyselyFieldConfig, temporal: boolean): FieldTypeResult {\n const fields = fieldConfig.fields;\n if (!fields || typeof fields !== \"object\") {\n return {\n type: \"string\",\n usedUtilityTypes: emptyUsedUtilityTypes(),\n };\n }\n\n const fieldResults = Object.entries(fields).map(([fieldName, config]) => {\n const result = generateFieldType(config, temporal, true);\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) => mergeUsedUtilityTypes(acc, result.usedUtilityTypes),\n emptyUsedUtilityTypes(),\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) =>\n config.hooks?.create || config.default !== undefined || config.optionalOnCreate === true,\n );\n if (usesColumnTypeAlias(aggregatedUtilityTypes) || hasOptionalFields || hasGeneratedFields) {\n return {\n type: `ObjectColumnType<${obj}>`,\n usedUtilityTypes: { ...aggregatedUtilityTypes, ObjectColumnType: true },\n };\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 * @param temporal - Whether date/datetime/time fields resolve to their Temporal column\n * types instead of their `Date`/`string` defaults\n * @param nested - Whether the field is inside an object\n * @returns The base type with used utility types\n */\nfunction getBaseType(\n fieldConfig: KyselyFieldConfig,\n temporal: boolean,\n nested: boolean,\n): FieldTypeResult {\n const fieldType = fieldConfig.type;\n const usedUtilityTypes = emptyUsedUtilityTypes();\n\n if (fieldType === \"enum\") {\n return { type: getEnumType(fieldConfig), usedUtilityTypes };\n }\n if (fieldType === \"nested\") {\n return getNestedType(fieldConfig, temporal);\n }\n\n const type = mapFieldTypeToColumnType(fieldType, temporal && !(nested && fieldType === \"time\"));\n switch (type) {\n case \"Timestamp\":\n usedUtilityTypes.Timestamp = true;\n break;\n case \"TemporalDate\":\n usedUtilityTypes.TemporalDate = true;\n break;\n case \"TemporalInstant\":\n usedUtilityTypes.TemporalInstant = true;\n break;\n case \"TemporalTime\":\n usedUtilityTypes.TemporalTime = true;\n break;\n case \"string\":\n case \"number\":\n case \"boolean\":\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 * @param temporal - Whether date/datetime/time fields resolve to their Temporal column\n * types instead of their `Date`/`string` defaults\n * @param nested - Whether the field is inside an object\n * @returns The complete field type with used utility types\n */\nfunction generateFieldType(\n fieldConfig: KyselyFieldConfig,\n temporal: boolean,\n nested = false,\n): FieldTypeResult {\n const baseTypeResult = getBaseType(fieldConfig, temporal, nested);\n const usedUtilityTypes = { ...baseTypeResult.usedUtilityTypes };\n\n const isArray = fieldConfig.array === true;\n const isNullable = fieldConfig.required !== true;\n\n // A ColumnType-shaped alias and ObjectColumnType cannot be wrapped with [] for\n // arrays, because Kysely only resolves ColumnType at the top-level table\n // property. Use ArrayColumnType to keep the ColumnType at the top level.\n const isColumnTypeBase = COLUMN_TYPE_ALIASES.has(baseTypeResult.type);\n\n let finalType = baseTypeResult.type;\n if (isArray) {\n if (isColumnTypeBase || finalType.startsWith(\"ObjectColumnType<\")) {\n finalType = `ArrayColumnType<${baseTypeResult.type}>`;\n usedUtilityTypes.ArrayColumnType = true;\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 (\n fieldConfig.hooks?.create ||\n fieldConfig.default !== undefined ||\n fieldConfig.optionalOnCreate === true\n ) {\n finalType = `Generated<${finalType}>`;\n }\n\n return { type: finalType, usedUtilityTypes };\n}\n\n/**\n * Generate the table interface.\n * @param name - Table name\n * @param fields - Field configurations keyed by field name\n * @param temporal - Whether date/datetime/time fields resolve to their Temporal column\n * types instead of their `Date`/`string` defaults\n * @returns The type definition and used utility types\n */\nfunction generateTableInterface(\n name: string,\n fields: Record<string, KyselyFieldConfig>,\n temporal: boolean,\n): {\n typeDef: string;\n usedUtilityTypes: UsedUtilityTypes;\n} {\n const fieldEntries = Object.entries(fields).filter(([fieldName]) => fieldName !== \"id\");\n\n const fieldResults = fieldEntries.map(([fieldName, fieldConfig]) => ({\n fieldName,\n ...generateFieldType(fieldConfig, temporal),\n }));\n\n const fieldLines = [\n \"id: Generated<string>;\",\n ...fieldResults.map((result) => `${result.fieldName}: ${result.type};`),\n ];\n\n const aggregatedUtilityTypes = fieldResults.reduce(\n (acc, result) => mergeUsedUtilityTypes(acc, result.usedUtilityTypes),\n emptyUsedUtilityTypes(),\n );\n\n const typeDef = multiline /* ts */ `\n ${name}: {\n ${fieldLines.join(\"\\n\")}\n }\n `;\n\n return { typeDef, usedUtilityTypes: aggregatedUtilityTypes };\n}\n\n/**\n * Generate KyselyTypeMetadata from field configurations.\n * @param name - Table name\n * @param fields - Field configurations keyed by field name\n * @param temporal - Whether date/datetime/time fields resolve to their Temporal column\n * types instead of their `Date`/`string` defaults. Defaults to `false`.\n * @returns Generated Kysely type metadata\n */\nexport function processKyselyFields(\n name: string,\n fields: Record<string, KyselyFieldConfig>,\n temporal = false,\n): KyselyTypeMetadata {\n const result = generateTableInterface(name, fields, temporal);\n\n return {\n name,\n typeDef: result.typeDef,\n usedUtilityTypes: result.usedUtilityTypes,\n };\n}\n\n/**\n * Convert a TailorDBType into KyselyTypeMetadata.\n * @param type - Parsed TailorDB table\n * @param temporal - Whether date/datetime/time fields resolve to their Temporal column\n * types instead of their `Date`/`string` defaults. Defaults to `false`.\n * @returns Generated Kysely type metadata\n */\nexport async function processKyselyType(\n type: TailorDBType,\n temporal = false,\n): Promise<KyselyTypeMetadata> {\n return processKyselyFields(\n type.name,\n Object.fromEntries(\n Object.entries(type.fields).map(([fieldName, parsedField]) => [\n fieldName,\n parsedField.config,\n ]),\n ),\n temporal,\n );\n}\n\n/**\n * Generate unified types file from multiple namespaces.\n * @param namespaceData - Namespace metadata\n * @param temporal - Whether `kyselyTypePlugin` was configured with `{ temporal: true }`;\n * passed to `createGetDB` so the generated `getDB` always reads back the Temporal values\n * the tables above are typed with. Defaults to `false`.\n * @returns Generated types file contents\n */\nexport function generateUnifiedKyselyTypes(\n namespaceData: KyselyNamespaceMetadata[],\n temporal = false,\n): string {\n if (namespaceData.length === 0) {\n return \"\";\n }\n\n // Aggregate used utility types from all namespaces\n const globalUsedUtilityTypes = namespaceData\n .flatMap((ns) => ns.types)\n .reduce(\n (acc, type) => mergeUsedUtilityTypes(acc, type.usedUtilityTypes),\n emptyUsedUtilityTypes(),\n );\n\n const utilityTypeImports: string[] = [\"type Generated\"];\n if (globalUsedUtilityTypes.Timestamp) {\n utilityTypeImports.push(\"type Timestamp\");\n }\n if (globalUsedUtilityTypes.TemporalDate) {\n utilityTypeImports.push(\"type TemporalDate\");\n }\n if (globalUsedUtilityTypes.TemporalInstant) {\n utilityTypeImports.push(\"type TemporalInstant\");\n }\n if (globalUsedUtilityTypes.TemporalTime) {\n utilityTypeImports.push(\"type TemporalTime\");\n }\n if (globalUsedUtilityTypes.ObjectColumnType) {\n utilityTypeImports.push(\"type ObjectColumnType\");\n }\n if (globalUsedUtilityTypes.ArrayColumnType) {\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>(${temporal ? \"{ temporal: true }\" : \"\"});\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 { resolve } from \"pathe\";\nimport { generatePGliteSchemaModule } from \"./pglite-schema\";\nimport { 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 pgliteSchemaPath?: string;\n /**\n * When `true`, generated tables map date/datetime fields and top-level time fields to\n * `Temporal.PlainDate`/`Temporal.Instant`/`Temporal.PlainTime` columns instead of\n * their `Date`/`string` defaults, and the generated `getDB` reads them back as those\n * Temporal values. Nested time fields remain strings. Defaults to `false`.\n */\n temporal?: boolean;\n};\n\n// Register this plugin's config type under its own id, via the package's\n// real public specifier, so callers can resolve it type-safely from a\n// `Plugin[]` array (see plugin/get-plugin-config.ts's resolvePluginConfig)\n// without importing KyselyTypePluginOptions, which stays unexported.\ndeclare module \"@tailor-platform/sdk/plugin\" {\n interface PluginConfigRegistry {\n \"@tailor-platform/kysely-type\": KyselyTypePluginOptions;\n }\n}\n\n/** Conventional output path used when `kyselyTypePlugin` has no `distPath` configured. */\nexport const DEFAULT_KYSELY_TYPES_DIST_PATH = \"./generated/tailordb.ts\";\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 * @param options.pgliteSchemaPath - Output file path for the PGlite `CREATE TABLE` script module; omit to skip it\n * @param options.temporal - When `true`, generated tables map date/datetime fields and\n * top-level time fields to their `Temporal.PlainDate`/`Temporal.Instant`/\n * `Temporal.PlainTime` counterparts instead of `Date`/`string`. Nested time fields\n * remain strings. Defaults to `false`.\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 { distPath, pgliteSchemaPath, temporal } = ctx.pluginConfig;\n if (pgliteSchemaPath && resolve(distPath) === resolve(pgliteSchemaPath)) {\n throw new Error(\"distPath and pgliteSchemaPath must resolve to different files.\");\n }\n\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.tables)) {\n const metadata = await processKyselyType(type, temporal);\n typeMetadataList.push(metadata);\n }\n\n if (typeMetadataList.length === 0) continue;\n\n allNamespaceData.push({\n namespace: ns.namespace,\n types: typeMetadataList,\n });\n }\n\n const files: GeneratorResult[\"files\"] = [];\n if (allNamespaceData.length > 0) {\n const content = generateUnifiedKyselyTypes(allNamespaceData, temporal);\n files.push({\n path: ctx.pluginConfig.distPath,\n content,\n });\n if (ctx.pluginConfig.pgliteSchemaPath) {\n files.push({\n path: ctx.pluginConfig.pgliteSchemaPath,\n content: generatePGliteSchemaModule(\n ctx.tailordb.filter((ns) => Object.keys(ns.tables).length > 0),\n ),\n });\n }\n }\n\n return { files };\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{t as NotificationActionSchema,n as NotificationCategory,r as NotificationCategorySchema,i as NotificationSchema,a as NotificationScopeRefSchema,o as NotificationSeverity,s as NotificationSeveritySchema,c as file_tailor_v1_notification_resource}from"./notification_resource_pb-Dwzah7gO.mjs";
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{t as e}from"./field_behavior_pb-B196sUx6.mjs";import{enumDesc as t,fileDesc as n,messageDesc as r,tsEnum as i}from"@bufbuild/protobuf/codegenv2";import{file_google_protobuf_timestamp as a}from"@bufbuild/protobuf/wkt";const o=/*@__PURE__*/ n(`CiV0YWlsb3IvdjEvbm90aWZpY2F0aW9uX3Jlc291cmNlLnByb3RvEgl0YWlsb3IudjEiMAoSTm90aWZpY2F0aW9uQWN0aW9uEg0KBWxhYmVsGAEgASgJEgsKA3VybBgCIAEoCSJiChROb3RpZmljYXRpb25TY29wZVJlZhIWCgx3b3Jrc3BhY2VfaWQYASABKAlIABIZCg9vcmdhbml6YXRpb25faWQYAiABKAlIABIQCgZyZWdpb24YAyABKAlIAEIFCgNyZWYi4QMKDE5vdGlmaWNhdGlvbhIPCgJpZBgBIAEoCUID4EEDEjEKCGNhdGVnb3J5GAIgASgOMh8udGFpbG9yLnYxLk5vdGlmaWNhdGlvbkNhdGVnb3J5EjEKCHNldmVyaXR5GAMgASgOMh8udGFpbG9yLnYxLk5vdGlmaWNhdGlvblNldmVyaXR5Eg0KBXRpdGxlGAQgASgJEhUKDWJvZHlfbWFya2Rvd24YBSABKAkSLgoHYWN0aW9ucxgGIAMoCzIdLnRhaWxvci52MS5Ob3RpZmljYXRpb25BY3Rpb24SMwoKc2NvcGVfcmVmcxgHIAMoCzIfLnRhaWxvci52MS5Ob3RpZmljYXRpb25TY29wZVJlZhIzCgphcnJpdmVkX2F0GAggASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEDEjAKB3JlYWRfYXQYCSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQMSMwoKY3JlYXRlZF9hdBgKIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAxIzCgpleHBpcmVzX2F0GAsgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEDKtEBChROb3RpZmljYXRpb25DYXRlZ29yeRIlCiFOT1RJRklDQVRJT05fQ0FURUdPUllfVU5TUEVDSUZJRUQQABIfChtOT1RJRklDQVRJT05fQ0FURUdPUllfQUxFUlQQARIiCh5OT1RJRklDQVRJT05fQ0FURUdPUllfSU5DSURFTlQQAhIlCiFOT1RJRklDQVRJT05fQ0FURUdPUllfTUFJTlRFTkFOQ0UQAxImCiJOT1RJRklDQVRJT05fQ0FURUdPUllfQU5OT1VOQ0VNRU5UEAQqpAEKFE5vdGlmaWNhdGlvblNldmVyaXR5EiUKIU5PVElGSUNBVElPTl9TRVZFUklUWV9VTlNQRUNJRklFRBAAEh4KGk5PVElGSUNBVElPTl9TRVZFUklUWV9JTkZPEAESIQodTk9USUZJQ0FUSU9OX1NFVkVSSVRZX1dBUk5JTkcQAhIiCh5OT1RJRklDQVRJT05fU0VWRVJJVFlfQ1JJVElDQUwQA2IGcHJvdG8z`,[e,a]),s=/*@__PURE__*/ r(o,0),c=/*@__PURE__*/ r(o,1),l=/*@__PURE__*/ r(o,2),u=/*@__PURE__*/ t(o,0),d=/*@__PURE__*/ i(u),f=/*@__PURE__*/ t(o,1),p=/*@__PURE__*/ i(f);export{c as a,o as c,l as i,d as n,p as o,u as r,f as s,s as t};
|
|
2
|
+
//# sourceMappingURL=notification_resource_pb-Dwzah7gO.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notification_resource_pb-Dwzah7gO.mjs","names":["file_google_api_field_behavior","file_tailor_v1_notification_resource","file_google_protobuf_timestamp","NotificationActionSchema","NotificationScopeRefSchema","NotificationSchema","NotificationCategorySchema","NotificationCategory","NotificationSeveritySchema","NotificationSeverity"],"sources":["../../tailor-proto/src/tailor/v1/notification_resource_pb.js"],"sourcesContent":["// @generated by protoc-gen-es v2.6.3\n// @generated from file tailor/v1/notification_resource.proto (package tailor.v1, syntax proto3)\n/* eslint-disable */\n\nimport { enumDesc, fileDesc, messageDesc, tsEnum } from \"@bufbuild/protobuf/codegenv2\";\nimport { file_google_api_field_behavior } from \"../../google/api/field_behavior_pb\";\nimport { file_google_protobuf_timestamp } from \"@bufbuild/protobuf/wkt\";\n\n/**\n * Describes the file tailor/v1/notification_resource.proto.\n */\nexport const file_tailor_v1_notification_resource = /*@__PURE__*/\n fileDesc(\"CiV0YWlsb3IvdjEvbm90aWZpY2F0aW9uX3Jlc291cmNlLnByb3RvEgl0YWlsb3IudjEiMAoSTm90aWZpY2F0aW9uQWN0aW9uEg0KBWxhYmVsGAEgASgJEgsKA3VybBgCIAEoCSJiChROb3RpZmljYXRpb25TY29wZVJlZhIWCgx3b3Jrc3BhY2VfaWQYASABKAlIABIZCg9vcmdhbml6YXRpb25faWQYAiABKAlIABIQCgZyZWdpb24YAyABKAlIAEIFCgNyZWYi4QMKDE5vdGlmaWNhdGlvbhIPCgJpZBgBIAEoCUID4EEDEjEKCGNhdGVnb3J5GAIgASgOMh8udGFpbG9yLnYxLk5vdGlmaWNhdGlvbkNhdGVnb3J5EjEKCHNldmVyaXR5GAMgASgOMh8udGFpbG9yLnYxLk5vdGlmaWNhdGlvblNldmVyaXR5Eg0KBXRpdGxlGAQgASgJEhUKDWJvZHlfbWFya2Rvd24YBSABKAkSLgoHYWN0aW9ucxgGIAMoCzIdLnRhaWxvci52MS5Ob3RpZmljYXRpb25BY3Rpb24SMwoKc2NvcGVfcmVmcxgHIAMoCzIfLnRhaWxvci52MS5Ob3RpZmljYXRpb25TY29wZVJlZhIzCgphcnJpdmVkX2F0GAggASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEDEjAKB3JlYWRfYXQYCSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQMSMwoKY3JlYXRlZF9hdBgKIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAxIzCgpleHBpcmVzX2F0GAsgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEDKtEBChROb3RpZmljYXRpb25DYXRlZ29yeRIlCiFOT1RJRklDQVRJT05fQ0FURUdPUllfVU5TUEVDSUZJRUQQABIfChtOT1RJRklDQVRJT05fQ0FURUdPUllfQUxFUlQQARIiCh5OT1RJRklDQVRJT05fQ0FURUdPUllfSU5DSURFTlQQAhIlCiFOT1RJRklDQVRJT05fQ0FURUdPUllfTUFJTlRFTkFOQ0UQAxImCiJOT1RJRklDQVRJT05fQ0FURUdPUllfQU5OT1VOQ0VNRU5UEAQqpAEKFE5vdGlmaWNhdGlvblNldmVyaXR5EiUKIU5PVElGSUNBVElPTl9TRVZFUklUWV9VTlNQRUNJRklFRBAAEh4KGk5PVElGSUNBVElPTl9TRVZFUklUWV9JTkZPEAESIQodTk9USUZJQ0FUSU9OX1NFVkVSSVRZX1dBUk5JTkcQAhIiCh5OT1RJRklDQVRJT05fU0VWRVJJVFlfQ1JJVElDQUwQA2IGcHJvdG8z\", [file_google_api_field_behavior, file_google_protobuf_timestamp]);\n\n/**\n * Describes the message tailor.v1.NotificationAction.\n * Use `create(NotificationActionSchema)` to create a new message.\n */\nexport const NotificationActionSchema = /*@__PURE__*/\n messageDesc(file_tailor_v1_notification_resource, 0);\n\n/**\n * Describes the message tailor.v1.NotificationScopeRef.\n * Use `create(NotificationScopeRefSchema)` to create a new message.\n */\nexport const NotificationScopeRefSchema = /*@__PURE__*/\n messageDesc(file_tailor_v1_notification_resource, 1);\n\n/**\n * Describes the message tailor.v1.Notification.\n * Use `create(NotificationSchema)` to create a new message.\n */\nexport const NotificationSchema = /*@__PURE__*/\n messageDesc(file_tailor_v1_notification_resource, 2);\n\n/**\n * Describes the enum tailor.v1.NotificationCategory.\n */\nexport const NotificationCategorySchema = /*@__PURE__*/\n enumDesc(file_tailor_v1_notification_resource, 0);\n\n/**\n * NotificationCategory is what kind of notice this is.\n *\n * @generated from enum tailor.v1.NotificationCategory\n */\nexport const NotificationCategory = /*@__PURE__*/\n tsEnum(NotificationCategorySchema);\n\n/**\n * Describes the enum tailor.v1.NotificationSeverity.\n */\nexport const NotificationSeveritySchema = /*@__PURE__*/\n enumDesc(file_tailor_v1_notification_resource, 1);\n\n/**\n * NotificationSeverity drives the Console badge colour and whether the SDK\n * CLI prints the notification after a command (WARNING and above).\n *\n * @generated from enum tailor.v1.NotificationSeverity\n */\nexport const NotificationSeverity = /*@__PURE__*/\n tsEnum(NotificationSeveritySchema);\n\n"],"mappings":"A,gOAWA,MAAaC,EACX,gBAAS,u5CAAw5C,CAACD,EAAgCE,CAA8B,CAAC,EAMt9CC,EACX,gBAAYF,EAAsC,CAAC,EAMxCG,EACX,gBAAYH,EAAsC,CAAC,EAMxCI,EACX,gBAAYJ,EAAsC,CAAC,EAKxCK,EACX,gBAASL,EAAsC,CAAC,EAOrCM,EACX,gBAAOD,CAA0B,EAKtBE,EACX,gBAASP,EAAsC,CAAC,EAQrCQ,EACX,gBAAOD,CAA0B,E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{t as DEFAULT_KYSELY_TYPES_DIST_PATH,n as KyselyGeneratorID,r as kyselyTypePlugin}from"../../../kysely-type-
|
|
1
|
+
export{t as DEFAULT_KYSELY_TYPES_DIST_PATH,n as KyselyGeneratorID,r as kyselyTypePlugin}from"../../../kysely-type-DhAZqdQg.mjs";
|