pgsql-deparser 13.15.0 → 13.18.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.
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Auto-generated file with types stripped for better tree-shaking
3
+ * DO NOT EDIT - Generated by strip-deparser-types.ts
4
+ */
5
+
6
+ import { Deparser, DeparserOptions } from "./deparser";
7
+ const deparseMethod = Deparser.deparse;
8
+ // Export the original sync version as deparseSync
9
+ export const deparseSync = deparseMethod;
10
+ // Create an async wrapper for deparse
11
+ export const deparse = async (...args: Parameters<typeof deparseMethod>): Promise<ReturnType<typeof deparseMethod>> => {
12
+ return deparseMethod(...args);
13
+ };
14
+ export { Deparser, DeparserOptions };
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Auto-generated file with types stripped for better tree-shaking
3
+ * DO NOT EDIT - Generated by strip-deparser-types.ts
4
+ */
5
+
6
+ export class ListUtils {
7
+ static unwrapList(obj: any): any[] {
8
+ if (obj === undefined || obj === null) {
9
+ return [];
10
+ }
11
+ if (obj.List !== undefined) {
12
+ return obj.List.items || [];
13
+ }
14
+ if (Array.isArray(obj)) {
15
+ return obj;
16
+ }
17
+ return [obj];
18
+ }
19
+ static formatList(items: any[], separator: string = ', ', prefix: string = '', formatter: (item: any) => string): string {
20
+ if (!items || items.length === 0) {
21
+ return '';
22
+ }
23
+ return items
24
+ .map(item => `${prefix}${formatter(item)}`)
25
+ .join(separator);
26
+ }
27
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Auto-generated file with types stripped for better tree-shaking
3
+ * DO NOT EDIT - Generated by strip-deparser-types.ts
4
+ */
5
+
6
+ const RESERVED_WORDS = new Set([
7
+ 'all', 'analyse', 'analyze', 'and', 'any', 'array', 'as', 'asc', 'asymmetric',
8
+ 'authorization', 'binary', 'both', 'case', 'cast', 'check', 'collate', 'collation',
9
+ 'column', 'concurrently', 'constraint', 'create', 'cross', 'current_catalog',
10
+ 'current_date', 'current_role', 'current_schema', 'current_time', 'current_timestamp',
11
+ 'current_user', 'default', 'deferrable', 'desc', 'distinct', 'do', 'else', 'end',
12
+ 'except', 'false', 'fetch', 'for', 'foreign', 'freeze', 'from', 'full', 'grant',
13
+ 'group', 'having', 'ilike', 'in', 'initially', 'inner', 'intersect', 'into', 'is',
14
+ 'isnull', 'join', 'lateral', 'leading', 'left', 'like', 'limit', 'localtime',
15
+ 'localtimestamp', 'natural', 'not', 'notnull', 'null', 'offset', 'on', 'only',
16
+ 'or', 'order', 'outer', 'overlaps', 'placing', 'primary', 'references', 'returning',
17
+ 'right', 'select', 'session_user', 'similar', 'some', 'symmetric', 'table', 'tablesample',
18
+ 'then', 'to', 'trailing', 'true', 'union', 'unique', 'user', 'using', 'variadic',
19
+ 'verbose', 'when', 'where', 'window', 'with'
20
+ ]);
21
+ export class QuoteUtils {
22
+ static needsQuotes(value: string): boolean {
23
+ if (!value || typeof value !== 'string') {
24
+ return false;
25
+ }
26
+ const lowerValue = value.toLowerCase();
27
+ if (RESERVED_WORDS.has(lowerValue)) {
28
+ return true;
29
+ }
30
+ if (!/^[a-z_][a-z0-9_$]*$/i.test(value)) {
31
+ return true;
32
+ }
33
+ if (value !== value.toLowerCase()) {
34
+ return true;
35
+ }
36
+ return false;
37
+ }
38
+ static quote(value: any): any {
39
+ if (value == null) {
40
+ return null;
41
+ }
42
+ if (Array.isArray(value)) {
43
+ return value.map(v => this.quote(v));
44
+ }
45
+ if (typeof value !== 'string') {
46
+ return value;
47
+ }
48
+ if (this.needsQuotes(value)) {
49
+ return `"${value}"`;
50
+ }
51
+ return value;
52
+ }
53
+ static escape(literal: string): string {
54
+ return `'${literal.replace(/'/g, "''")}'`;
55
+ }
56
+ /**
57
+ * Escapes a string value for use in E-prefixed string literals
58
+ * Handles both backslashes and single quotes properly
59
+ */
60
+ static escapeEString(value: string): string {
61
+ return value.replace(/\\/g, '\\\\').replace(/'/g, "''");
62
+ }
63
+ /**
64
+ * Formats a string as an E-prefixed string literal with proper escaping
65
+ * This wraps the complete E-prefix logic including detection and formatting
66
+ */
67
+ static formatEString(value: string): string {
68
+ const needsEscape = QuoteUtils.needsEscapePrefix(value);
69
+ if (needsEscape) {
70
+ const escapedValue = QuoteUtils.escapeEString(value);
71
+ return `E'${escapedValue}'`;
72
+ }
73
+ else {
74
+ return QuoteUtils.escape(value);
75
+ }
76
+ }
77
+ /**
78
+ * Determines if a string value needs E-prefix for escaped string literals
79
+ * Detects backslash escape sequences that require E-prefix in PostgreSQL
80
+ */
81
+ static needsEscapePrefix(value: string): boolean {
82
+ // Always use E'' if the string contains any backslashes,
83
+ // unless it's a raw \x... bytea-style literal.
84
+ return !/^\\x[0-9a-fA-F]+$/i.test(value) && value.includes('\\');
85
+ }
86
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Auto-generated file with types stripped for better tree-shaking
3
+ * DO NOT EDIT - Generated by strip-deparser-types.ts
4
+ */
5
+
6
+ export class SqlFormatter {
7
+ private newlineChar: string;
8
+ private tabChar: string;
9
+ private prettyMode: boolean;
10
+ constructor(newlineChar: string = '\n', tabChar: string = ' ', prettyMode: boolean = true) {
11
+ this.newlineChar = newlineChar;
12
+ this.tabChar = tabChar;
13
+ this.prettyMode = prettyMode;
14
+ }
15
+ format(parts: string[], separator: string = ' '): string {
16
+ return parts.filter(part => part !== null && part !== undefined && part !== '').join(separator);
17
+ }
18
+ indent(text: string, count: number = 1): string {
19
+ if (!this.prettyMode) {
20
+ return text;
21
+ }
22
+ const indentation = this.tabChar.repeat(count);
23
+ return text.split(this.newlineChar).map(line => line.trim() ? indentation + line : line).join(this.newlineChar);
24
+ }
25
+ parens(content: string): string {
26
+ return `(${content})`;
27
+ }
28
+ newline(): string {
29
+ return this.newlineChar;
30
+ }
31
+ tab(): string {
32
+ return this.tabChar;
33
+ }
34
+ isPretty(): boolean {
35
+ return this.prettyMode;
36
+ }
37
+ }
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Auto-generated file with types stripped for better tree-shaking
3
+ * DO NOT EDIT - Generated by strip-deparser-types.ts
4
+ */
5
+
6
+ import { SqlFormatter } from '../utils/sql-formatter';
7
+ export interface DeparserContextOptions {
8
+ isStringLiteral?: boolean;
9
+ parentNodeTypes?: string[];
10
+ indentLevel?: number;
11
+ prettyMode?: boolean;
12
+ formatter?: SqlFormatter;
13
+ select?: boolean;
14
+ from?: boolean;
15
+ group?: boolean;
16
+ sort?: boolean;
17
+ insertColumns?: boolean;
18
+ update?: boolean;
19
+ bool?: boolean;
20
+ isColumnConstraint?: boolean;
21
+ isDomainConstraint?: boolean;
22
+ alterColumnOptions?: boolean;
23
+ alterTableOptions?: boolean;
24
+ isEnumValue?: boolean;
25
+ objtype?: string;
26
+ subtype?: string;
27
+ [key: string]: any;
28
+ }
29
+ export class DeparserContext {
30
+ readonly indentLevel: number;
31
+ readonly prettyMode: boolean;
32
+ readonly isStringLiteral?: boolean;
33
+ readonly parentNodeTypes: string[];
34
+ private readonly formatter: SqlFormatter;
35
+ readonly select?: boolean;
36
+ readonly from?: boolean;
37
+ readonly group?: boolean;
38
+ readonly sort?: boolean;
39
+ readonly insertColumns?: boolean;
40
+ readonly update?: boolean;
41
+ readonly bool?: boolean;
42
+ readonly isColumnConstraint?: boolean;
43
+ readonly isDomainConstraint?: boolean;
44
+ readonly alterColumnOptions?: boolean;
45
+ readonly alterTableOptions?: boolean;
46
+ readonly isEnumValue?: boolean;
47
+ readonly objtype?: string;
48
+ readonly subtype?: string;
49
+ readonly [key: string]: any;
50
+ constructor({ indentLevel = 0, prettyMode = true, isStringLiteral, parentNodeTypes = [], formatter, select, from, group, sort, insertColumns, update, bool, isColumnConstraint, isDomainConstraint, alterColumnOptions, alterTableOptions, isEnumValue, objtype, subtype, ...rest }: DeparserContextOptions = {}) {
51
+ this.indentLevel = indentLevel;
52
+ this.prettyMode = prettyMode;
53
+ this.isStringLiteral = isStringLiteral;
54
+ this.parentNodeTypes = parentNodeTypes;
55
+ this.formatter = formatter || new SqlFormatter('\n', ' ', prettyMode);
56
+ this.select = select;
57
+ this.from = from;
58
+ this.group = group;
59
+ this.sort = sort;
60
+ this.insertColumns = insertColumns;
61
+ this.update = update;
62
+ this.bool = bool;
63
+ this.isColumnConstraint = isColumnConstraint;
64
+ this.isDomainConstraint = isDomainConstraint;
65
+ this.alterColumnOptions = alterColumnOptions;
66
+ this.alterTableOptions = alterTableOptions;
67
+ this.isEnumValue = isEnumValue;
68
+ this.objtype = objtype;
69
+ this.subtype = subtype;
70
+ Object.assign(this, rest);
71
+ }
72
+ spawn(nodeType: string, overrides: Partial<DeparserContextOptions> = {}): DeparserContext {
73
+ return new DeparserContext({
74
+ indentLevel: this.indentLevel,
75
+ prettyMode: this.prettyMode,
76
+ isStringLiteral: this.isStringLiteral,
77
+ parentNodeTypes: [...this.parentNodeTypes, nodeType],
78
+ formatter: this.formatter,
79
+ select: this.select,
80
+ from: this.from,
81
+ group: this.group,
82
+ sort: this.sort,
83
+ insertColumns: this.insertColumns,
84
+ update: this.update,
85
+ bool: this.bool,
86
+ isColumnConstraint: this.isColumnConstraint,
87
+ isDomainConstraint: this.isDomainConstraint,
88
+ alterColumnOptions: this.alterColumnOptions,
89
+ alterTableOptions: this.alterTableOptions,
90
+ isEnumValue: this.isEnumValue,
91
+ objtype: this.objtype,
92
+ subtype: this.subtype,
93
+ ...overrides,
94
+ });
95
+ }
96
+ indent(text: string, count?: number): string {
97
+ if (!this.prettyMode) {
98
+ return text;
99
+ }
100
+ const indentCount = count !== undefined ? count : this.indentLevel + 1;
101
+ return this.formatter.indent(text, indentCount);
102
+ }
103
+ newline(): string {
104
+ return this.formatter.newline();
105
+ }
106
+ parens(content: string): string {
107
+ return this.formatter.parens(content);
108
+ }
109
+ format(parts: string[], separator?: string): string {
110
+ return this.formatter.format(parts, separator);
111
+ }
112
+ isPretty(): boolean {
113
+ return this.formatter.isPretty();
114
+ }
115
+ }
116
+ export interface DeparserVisitor {
117
+ visit(node: any, context?: DeparserContext): string;
118
+ }
119
+ export abstract class BaseVisitor implements DeparserVisitor {
120
+ abstract visit(node: any, context?: DeparserContext): string;
121
+ protected getNodeType(node: any): string {
122
+ return Object.keys(node)[0];
123
+ }
124
+ protected getNodeData(node: any): any {
125
+ const type = this.getNodeType(node);
126
+ return (node as any)[type];
127
+ }
128
+ protected formatList(items: any[], separator: string = ', ', prefix: string = '', formatter: (item: any) => string): string {
129
+ if (!items || items.length === 0) {
130
+ return '';
131
+ }
132
+ return items
133
+ .map(item => `${prefix}${formatter(item)}`)
134
+ .join(separator);
135
+ }
136
+ protected formatParts(parts: string[], separator: string = ' '): string {
137
+ return parts.filter(part => part !== null && part !== undefined && part !== '').join(separator);
138
+ }
139
+ protected formatParens(content: string): string {
140
+ return `(${content})`;
141
+ }
142
+ protected formatIndent(text: string, count: number = 1): string {
143
+ return text;
144
+ }
145
+ }
package/src/index.ts CHANGED
@@ -1,3 +1,27 @@
1
- import Deparser from './deparser';
2
- const deparse = Deparser.deparse;
3
- export { deparse, Deparser };
1
+ /**
2
+ * Deparser for PostgreSQL version 13
3
+ * Auto-generated by generate-version-deparsers.ts
4
+ */
5
+
6
+ import { Node, ParseResult } from '@pgsql/types';
7
+ import {
8
+ deparse as deparse17,
9
+ deparseSync as deparseSync17,
10
+ DeparserOptions
11
+ } from './deparser';
12
+ import { PG13ToPG17Transformer } from './v13-to-v17-direct';
13
+
14
+ const tx = new PG13ToPG17Transformer();
15
+
16
+ export async function deparse(query: Node | Node[] | ParseResult, opts?: DeparserOptions): Promise<string> {
17
+ const ast17 = tx.transform(query);
18
+ return await deparse17(ast17, opts);
19
+ }
20
+
21
+ export function deparseSync(query: Node | Node[] | ParseResult, opts?: DeparserOptions): string {
22
+ const ast17 = tx.transform(query);
23
+ return deparseSync17(ast17, opts);
24
+ }
25
+
26
+ // Re-export DeparserOptions for convenience
27
+ export { DeparserOptions } from './deparser';