@supabase/postgrest-typegen 0.2.0 → 0.2.2
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/README.md +12 -0
- package/dist/collation.d.ts +2 -0
- package/dist/collation.js +15 -0
- package/dist/generation/go.js +30 -2
- package/dist/generation/index.d.ts +1 -1
- package/dist/generation/python.js +24 -10
- package/dist/generation/swift.js +52 -3
- package/dist/generation/typescript.d.ts +18 -7
- package/dist/generation/typescript.js +122 -82
- package/dist/introspection/index.js +6 -23
- package/dist/introspection/relationships.d.ts +4 -4
- package/dist/introspection/relationships.js +4 -11
- package/dist/introspection/sql/columns.sql.d.ts +2 -7
- package/dist/introspection/sql/columns.sql.js +32 -9
- package/dist/introspection/sql/common.d.ts +7 -15
- package/dist/introspection/sql/foreign_tables.sql.d.ts +2 -6
- package/dist/introspection/sql/foreign_tables.sql.js +0 -5
- package/dist/introspection/sql/functions.sql.d.ts +2 -5
- package/dist/introspection/sql/functions.sql.js +0 -33
- package/dist/introspection/sql/helpers.d.ts +1 -1
- package/dist/introspection/sql/helpers.js +2 -2
- package/dist/introspection/sql/materialized_views.sql.d.ts +2 -4
- package/dist/introspection/sql/materialized_views.sql.js +0 -5
- package/dist/introspection/sql/pg-format.d.ts +21 -0
- package/dist/introspection/sql/pg-format.js +92 -0
- package/dist/introspection/sql/primary_keys.sql.d.ts +2 -4
- package/dist/introspection/sql/primary_keys.sql.js +0 -4
- package/dist/introspection/sql/schemas.sql.d.ts +2 -6
- package/dist/introspection/sql/schemas.sql.js +2 -6
- package/dist/introspection/sql/table.sql.d.ts +2 -4
- package/dist/introspection/sql/table.sql.js +0 -5
- package/dist/introspection/sql/table_relationships.sql.d.ts +2 -2
- package/dist/introspection/sql/types.sql.d.ts +5 -5
- package/dist/introspection/sql/types.sql.js +6 -17
- package/dist/introspection/sql/views.sql.d.ts +2 -4
- package/dist/introspection/sql/views.sql.js +6 -5
- package/dist/introspection/sql/views_key_dependencies.sql.d.ts +2 -2
- package/dist/introspection/sql/views_key_dependencies.sql.js +64 -75
- package/dist/sort.js +16 -15
- package/dist/types.d.ts +4 -0
- package/dist/types.js +11 -0
- package/package.json +3 -5
- package/src/collation.ts +16 -0
- package/src/generation/go.ts +31 -2
- package/src/generation/index.ts +1 -0
- package/src/generation/python.ts +25 -10
- package/src/generation/swift.ts +53 -3
- package/src/generation/typescript.ts +187 -107
- package/src/introspection/index.ts +7 -32
- package/src/introspection/relationships.ts +10 -19
- package/src/introspection/sql/columns.sql.ts +34 -18
- package/src/introspection/sql/common.ts +7 -17
- package/src/introspection/sql/foreign_tables.sql.ts +2 -13
- package/src/introspection/sql/functions.sql.ts +2 -44
- package/src/introspection/sql/helpers.ts +2 -2
- package/src/introspection/sql/materialized_views.sql.ts +2 -11
- package/src/introspection/sql/pg-format.ts +101 -0
- package/src/introspection/sql/primary_keys.sql.ts +2 -10
- package/src/introspection/sql/schemas.sql.ts +4 -14
- package/src/introspection/sql/table.sql.ts +2 -11
- package/src/introspection/sql/table_relationships.sql.ts +2 -4
- package/src/introspection/sql/types.sql.ts +6 -26
- package/src/introspection/sql/views.sql.ts +8 -11
- package/src/introspection/sql/views_key_dependencies.sql.ts +83 -77
- package/src/sort.ts +20 -15
- package/src/types.ts +11 -0
package/README.md
CHANGED
|
@@ -23,6 +23,14 @@ deprecated in favor of this package. It's decided that all four eventually
|
|
|
23
23
|
move out to their own SDK repos too (tracked in SDK-1641), not yet scheduled
|
|
24
24
|
— sequenced after postgres-meta's cutover to this package settles.
|
|
25
25
|
|
|
26
|
+
> [!IMPORTANT]
|
|
27
|
+
> **We are no longer accepting contributions that fix the bundled generators.**
|
|
28
|
+
> Because each of the four is moving out to its own language's SDK repository,
|
|
29
|
+
> a fix landed here would have to be made a second time in the destination
|
|
30
|
+
> repository, and it also breaks byte parity with postgres-meta until a release
|
|
31
|
+
> propagates. Please open an issue describing the bug instead, so it can be
|
|
32
|
+
> tracked and carried across the move.
|
|
33
|
+
|
|
26
34
|
## Design
|
|
27
35
|
|
|
28
36
|
There is a hard split between **introspection** (database → metadata) and
|
|
@@ -128,6 +136,10 @@ Not yet published; consumed in-repo for now (`packages/postgrest-typegen`).
|
|
|
128
136
|
npm install pg
|
|
129
137
|
```
|
|
130
138
|
|
|
139
|
+
## Releasing
|
|
140
|
+
|
|
141
|
+
Unlike the rest of this repo, merging a change here does not open a release pull request on its own. Releases are cut on demand: run the `Release postgrest-typegen` workflow from the Actions tab, which runs release-please against `release-please-config.postgrest-typegen.json` and opens (or updates) the release pull request for this package. Merging that pull request tags the release and publishes to npm.
|
|
142
|
+
|
|
131
143
|
## License
|
|
132
144
|
|
|
133
145
|
MIT
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one string comparison every ordering in this package uses.
|
|
3
|
+
*
|
|
4
|
+
* Generated output is ordered by name, and `String.prototype.localeCompare`
|
|
5
|
+
* without a locale follows the host's default locale, so the same database
|
|
6
|
+
* produced differently ordered code on differently configured machines (a
|
|
7
|
+
* Swedish host sorts `ä` after `z`, an English one next to `a`). Pinning the
|
|
8
|
+
* collator to English keeps the order postgres-meta's output has on the
|
|
9
|
+
* English CI runners and makes it the same everywhere else.
|
|
10
|
+
*/
|
|
11
|
+
const collator = new Intl.Collator("en");
|
|
12
|
+
/** Compare two strings with the pinned English collation. */
|
|
13
|
+
export function compareStrings(a, b) {
|
|
14
|
+
return collator.compare(a, b);
|
|
15
|
+
}
|
package/dist/generation/go.js
CHANGED
|
@@ -58,6 +58,34 @@ function formatForGoTypeName(name) {
|
|
|
58
58
|
})
|
|
59
59
|
.join("");
|
|
60
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Renders the `json` struct tag for a column or composite attribute name.
|
|
63
|
+
*
|
|
64
|
+
* The name is quoted with `JSON.stringify`, whose escape sequences are a
|
|
65
|
+
* subset of Go's, so `reflect.StructTag.Get("json")` recovers the exact name
|
|
66
|
+
* via `strconv.Unquote` even when it contains quotes, backslashes or control
|
|
67
|
+
* characters. The tag is emitted as a raw string literal like before, except
|
|
68
|
+
* when the name contains a backtick: Go raw literals cannot contain one, so
|
|
69
|
+
* such tags fall back to an interpreted literal with a second round of
|
|
70
|
+
* escaping. Names the marshaler cannot represent still compile and
|
|
71
|
+
* round-trip through `reflect.StructTag`, but `encoding/json` applies its
|
|
72
|
+
* own tag rules at runtime: a comma splits the name from tag options (so
|
|
73
|
+
* only the part before it is used as the JSON name), and a name it rejects
|
|
74
|
+
* outright (for example one containing a quote) falls back to the Go field
|
|
75
|
+
* name. That is a limitation of the struct tag convention itself, not of
|
|
76
|
+
* the generated source.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```ts
|
|
80
|
+
* formatForGoStructTag('name') // `json:"name"`
|
|
81
|
+
* formatForGoStructTag('a"b') // `json:"a\"b"`
|
|
82
|
+
* formatForGoStructTag('back`tick') // "json:\"back`tick\""
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
function formatForGoStructTag(name) {
|
|
86
|
+
const tag = `json:${JSON.stringify(name)}`;
|
|
87
|
+
return tag.includes("`") ? JSON.stringify(tag) : `\`${tag}\``;
|
|
88
|
+
}
|
|
61
89
|
function generateTableStruct(schema, table, columns, types, operation) {
|
|
62
90
|
// Storing columns as a tuple of [formattedName, type, name] rather than creating the string
|
|
63
91
|
// representation of the line allows us to pre-format the entries. Go formats
|
|
@@ -97,7 +125,7 @@ function generateTableStruct(schema, table, columns, types, operation) {
|
|
|
97
125
|
// Pad the formatted name and type to align the struct fields, then join
|
|
98
126
|
// create the final string representation of the struct fields.
|
|
99
127
|
const formattedColumnEntries = columnEntries.map(([formattedName, type, name]) => {
|
|
100
|
-
return ` ${formattedName.padEnd(maxFormattedNameLength)} ${type.padEnd(maxTypeLength)}
|
|
128
|
+
return ` ${formattedName.padEnd(maxFormattedNameLength)} ${type.padEnd(maxTypeLength)} ${formatForGoStructTag(name)}`;
|
|
101
129
|
});
|
|
102
130
|
return `
|
|
103
131
|
type ${formatForGoTypeName(schema.name)}${formatForGoTypeName(table.name)}${operation} struct {
|
|
@@ -134,7 +162,7 @@ function generateCompositeTypeStruct(schema, type, types) {
|
|
|
134
162
|
// Pad the formatted name and type to align the struct fields, then join
|
|
135
163
|
// create the final string representation of the struct fields.
|
|
136
164
|
const formattedAttributeEntries = attributeEntries.map(([formattedName, type, name]) => {
|
|
137
|
-
return ` ${formattedName.padEnd(maxFormattedNameLength)} ${type.padEnd(maxTypeLength)}
|
|
165
|
+
return ` ${formattedName.padEnd(maxFormattedNameLength)} ${type.padEnd(maxTypeLength)} ${formatForGoStructTag(name)}`;
|
|
138
166
|
});
|
|
139
167
|
return `
|
|
140
168
|
type ${formatForGoTypeName(schema.name)}${formatForGoTypeName(type.name)} struct {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { sortGeneratorMetadata } from "../sort.ts";
|
|
2
2
|
export { generateGo } from "./go.ts";
|
|
3
3
|
export { generatePython } from "./python.ts";
|
|
4
|
-
export { generateTypescript, type GenerateTypescriptOptions, pgTypeToTsType, } from "./typescript.ts";
|
|
4
|
+
export { generateTypescript, type GenerateTypescriptOptions, pgTypeToTsType, type TypeResolutionContext, } from "./typescript.ts";
|
|
5
5
|
export { type AccessControl, generateSwift, type GenerateSwiftOptions, } from "./swift.ts";
|
|
@@ -26,13 +26,12 @@ from typing import (
|
|
|
26
26
|
Any,
|
|
27
27
|
List,
|
|
28
28
|
Literal,
|
|
29
|
-
NotRequired,
|
|
30
29
|
Optional,
|
|
31
|
-
TypeAlias,
|
|
32
30
|
TypedDict,
|
|
33
31
|
)
|
|
32
|
+
from typing_extensions import NotRequired, TypeAlias
|
|
34
33
|
|
|
35
|
-
from pydantic import BaseModel, Field,
|
|
34
|
+
from pydantic import BaseModel, Field, JsonValue
|
|
36
35
|
|
|
37
36
|
${concatLines(Object.values(ctx.user_enums))}
|
|
38
37
|
|
|
@@ -100,7 +99,9 @@ class PythonContext {
|
|
|
100
99
|
});
|
|
101
100
|
const attributeEntries = attributes.map((attribute) => {
|
|
102
101
|
const type = this.parsePgType(attribute.type.name);
|
|
103
|
-
|
|
102
|
+
// Composite type attributes cannot carry NOT NULL constraints in
|
|
103
|
+
// Postgres, so every field is inherently nullable.
|
|
104
|
+
return new PythonBaseModelAttr(attribute.name, type, true);
|
|
104
105
|
});
|
|
105
106
|
const schema = this.schemas[type.schema];
|
|
106
107
|
return new PythonBaseModel(type.name, schema, attributeEntries);
|
|
@@ -146,7 +147,9 @@ class PythonEnum {
|
|
|
146
147
|
this.variants = type.enums;
|
|
147
148
|
}
|
|
148
149
|
serialize() {
|
|
149
|
-
const variants = this.variants
|
|
150
|
+
const variants = this.variants
|
|
151
|
+
.map((item) => escapePythonString(item))
|
|
152
|
+
.join(", ");
|
|
150
153
|
return `${this.name}: TypeAlias = Literal[${variants}]`;
|
|
151
154
|
}
|
|
152
155
|
}
|
|
@@ -183,7 +186,7 @@ class PythonBaseModelAttr {
|
|
|
183
186
|
const py_type = this.nullable
|
|
184
187
|
? `Optional[${this.py_type.serialize()}]`
|
|
185
188
|
: this.py_type.serialize();
|
|
186
|
-
return ` ${this.name}: ${py_type} = Field(alias
|
|
189
|
+
return ` ${this.name}: ${py_type} = Field(alias=${escapePythonString(this.pg_name)})`;
|
|
187
190
|
}
|
|
188
191
|
}
|
|
189
192
|
class PythonBaseModel {
|
|
@@ -221,7 +224,7 @@ class PythonTypedDictAttr {
|
|
|
221
224
|
const py_type = this.nullable
|
|
222
225
|
? `Optional[${this.py_type.serialize()}]`
|
|
223
226
|
: this.py_type.serialize();
|
|
224
|
-
const annotation = `Annotated[${py_type}, Field(alias
|
|
227
|
+
const annotation = `Annotated[${py_type}, Field(alias=${escapePythonString(this.pg_name)})]`;
|
|
225
228
|
const rhs = this.not_required ? `NotRequired[${annotation}]` : annotation;
|
|
226
229
|
return ` ${this.name}: ${rhs}`;
|
|
227
230
|
}
|
|
@@ -251,6 +254,15 @@ class PythonTypedDict {
|
|
|
251
254
|
function concatLines(items) {
|
|
252
255
|
return items.map((item) => item.serialize()).join("\n\n");
|
|
253
256
|
}
|
|
257
|
+
/**
|
|
258
|
+
* Emits a Postgres name as a double-quoted Python string literal. JSON string
|
|
259
|
+
* escaping is a subset of Python's (`\"`, `\\`, `\n`, `\uXXXX`), so
|
|
260
|
+
* `JSON.stringify` yields a literal Python parses to the exact original name
|
|
261
|
+
* and keeps quotes, backslashes and newlines from breaking out of it.
|
|
262
|
+
*/
|
|
263
|
+
function escapePythonString(value) {
|
|
264
|
+
return JSON.stringify(value);
|
|
265
|
+
}
|
|
254
266
|
const PY_TYPE_MAP = {
|
|
255
267
|
// Bool
|
|
256
268
|
bool: "bool",
|
|
@@ -276,9 +288,11 @@ const PY_TYPE_MAP = {
|
|
|
276
288
|
uuid: "uuid.UUID",
|
|
277
289
|
vector: "list[Any]",
|
|
278
290
|
interval: "str",
|
|
279
|
-
// JSON
|
|
280
|
-
|
|
281
|
-
|
|
291
|
+
// JSON. PostgREST returns these columns already deserialized, so the
|
|
292
|
+
// generated models must accept parsed values (JsonValue), not JSON strings
|
|
293
|
+
// (which is what pydantic's Json[...] validates and parses).
|
|
294
|
+
json: "JsonValue",
|
|
295
|
+
jsonb: "JsonValue",
|
|
282
296
|
// Range types (can be adjusted to more complex types if needed)
|
|
283
297
|
int4range: "str",
|
|
284
298
|
int4multirange: "str",
|
package/dist/generation/swift.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { compareStrings } from "../collation.js";
|
|
1
2
|
function formatForSwiftSchemaName(schema) {
|
|
2
3
|
return `${formatForSwiftTypeName(schema)}Schema`;
|
|
3
4
|
}
|
|
@@ -94,10 +95,52 @@ function pgCompositeTypeToSwiftStruct(type, { types, views, tables, }) {
|
|
|
94
95
|
function generateProtocolConformances(protocols) {
|
|
95
96
|
return protocols.length === 0 ? "" : `: ${protocols.join(", ")}`;
|
|
96
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Serializes a database-provided value as a Swift string literal. Backslashes
|
|
100
|
+
* would otherwise start escape or interpolation sequences (`\(`), double
|
|
101
|
+
* quotes would terminate the literal early, and line breaks or control
|
|
102
|
+
* characters are not allowed in single-line literals, so all of them are
|
|
103
|
+
* escaped per Swift's string literal grammar. U+2028 and U+2029 are legal in
|
|
104
|
+
* Swift literals but are escaped anyway because other tooling mishandles
|
|
105
|
+
* them. Swift unescapes at compile time, so raw values round-trip unchanged.
|
|
106
|
+
*/
|
|
107
|
+
function swiftStringLiteral(value) {
|
|
108
|
+
let escaped = "";
|
|
109
|
+
for (const character of value) {
|
|
110
|
+
switch (character) {
|
|
111
|
+
case "\\":
|
|
112
|
+
escaped += "\\\\";
|
|
113
|
+
break;
|
|
114
|
+
case '"':
|
|
115
|
+
escaped += '\\"';
|
|
116
|
+
break;
|
|
117
|
+
case "\t":
|
|
118
|
+
escaped += "\\t";
|
|
119
|
+
break;
|
|
120
|
+
case "\n":
|
|
121
|
+
escaped += "\\n";
|
|
122
|
+
break;
|
|
123
|
+
case "\r":
|
|
124
|
+
escaped += "\\r";
|
|
125
|
+
break;
|
|
126
|
+
default: {
|
|
127
|
+
const codePoint = character.codePointAt(0);
|
|
128
|
+
escaped +=
|
|
129
|
+
codePoint < 0x20 ||
|
|
130
|
+
codePoint === 0x7f ||
|
|
131
|
+
codePoint === 0x2028 ||
|
|
132
|
+
codePoint === 0x2029
|
|
133
|
+
? `\\u{${codePoint.toString(16)}}`
|
|
134
|
+
: character;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return `"${escaped}"`;
|
|
139
|
+
}
|
|
97
140
|
function generateEnum(enum_, { accessControl, level }) {
|
|
98
141
|
return [
|
|
99
142
|
`${ident(level)}${accessControl} enum ${enum_.formattedEnumName}${generateProtocolConformances(enum_.protocolConformances)} {`,
|
|
100
|
-
...enum_.cases.map((case_) => `${ident(level + 1)}case ${case_.formattedName} =
|
|
143
|
+
...enum_.cases.map((case_) => `${ident(level + 1)}case ${case_.formattedName} = ${swiftStringLiteral(case_.rawValue)}`),
|
|
101
144
|
`${ident(level)}}`,
|
|
102
145
|
];
|
|
103
146
|
}
|
|
@@ -144,10 +187,10 @@ export const generateSwift = (metadata, opts = {}) => {
|
|
|
144
187
|
...schemas.flatMap((schema) => {
|
|
145
188
|
const schemaTables = [...tables, ...foreignTables]
|
|
146
189
|
.filter((table) => table.schema === schema.name)
|
|
147
|
-
.sort(({ name: a }, { name: b }) => a
|
|
190
|
+
.sort(({ name: a }, { name: b }) => compareStrings(a, b));
|
|
148
191
|
const schemaViews = [...views, ...materializedViews]
|
|
149
192
|
.filter((table) => table.schema === schema.name)
|
|
150
|
-
.sort(({ name: a }, { name: b }) => a
|
|
193
|
+
.sort(({ name: a }, { name: b }) => compareStrings(a, b));
|
|
151
194
|
const schemaEnums = types.filter((type) => type.schema === schema.name && type.enums.length > 0);
|
|
152
195
|
const schemaCompositeTypes = types.filter((type) => type.schema === schema.name && type.attributes.length > 0);
|
|
153
196
|
return [
|
|
@@ -220,6 +263,12 @@ const pgTypeToSwiftType = (pgType, nullable, { types, views, tables, }) => {
|
|
|
220
263
|
}
|
|
221
264
|
else if (["json", "jsonb"].includes(pgType)) {
|
|
222
265
|
swiftType = "AnyJSON";
|
|
266
|
+
// `void` and `record` are pseudo-types: Postgres rejects them as a column or
|
|
267
|
+
// composite attribute type ("column has pseudo-type void"), and this
|
|
268
|
+
// generator only renders columns and attributes, never functions. So these
|
|
269
|
+
// two arms are unreachable today and deliberately untested. They are kept
|
|
270
|
+
// because they are the mappings to use if Swift ever emits functions, which
|
|
271
|
+
// is where these types do appear.
|
|
223
272
|
}
|
|
224
273
|
else if (pgType === "void") {
|
|
225
274
|
swiftType = "Void";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { GeneratorMetadata, PostgresSchema, PostgresTable, PostgresType, PostgresView } from "../types.ts";
|
|
1
|
+
import type { GeneratorMetadata, PostgresForeignTable, PostgresMaterializedView, PostgresSchema, PostgresTable, PostgresType, PostgresView } from "../types.ts";
|
|
2
2
|
export interface GenerateTypescriptOptions {
|
|
3
3
|
/**
|
|
4
4
|
* Emit `isOneToOne` on each relationship entry. Mirrors postgres-meta's
|
|
@@ -24,6 +24,22 @@ export interface GenerateTypescriptOptions {
|
|
|
24
24
|
*/
|
|
25
25
|
format?: (code: string) => Promise<string>;
|
|
26
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* Collections `pgTypeToTsType` resolves a relation-typed value against.
|
|
29
|
+
*
|
|
30
|
+
* Foreign tables are generated under `Tables` and materialized views under
|
|
31
|
+
* `Views`, exactly like their plain counterparts, so a value typed as one has
|
|
32
|
+
* a `Row` to point at and belongs here. Both are optional so the exported
|
|
33
|
+
* `pgTypeToTsType` signature stays backwards compatible.
|
|
34
|
+
*/
|
|
35
|
+
export type TypeResolutionContext = {
|
|
36
|
+
types: PostgresType[];
|
|
37
|
+
schemas: PostgresSchema[];
|
|
38
|
+
tables: PostgresTable[];
|
|
39
|
+
views: PostgresView[];
|
|
40
|
+
foreignTables?: PostgresForeignTable[];
|
|
41
|
+
materializedViews?: PostgresMaterializedView[];
|
|
42
|
+
};
|
|
27
43
|
/**
|
|
28
44
|
* Does not re-sort collections; pass input pre-sorted with
|
|
29
45
|
* `sortGeneratorMetadata` first. Still merge-sorts tables+foreign tables and
|
|
@@ -31,9 +47,4 @@ export interface GenerateTypescriptOptions {
|
|
|
31
47
|
* can't be expressed by the single-collection `sortGeneratorMetadata` pass.
|
|
32
48
|
*/
|
|
33
49
|
export declare const generateTypescript: (metadata: GeneratorMetadata, opts?: GenerateTypescriptOptions) => Promise<string>;
|
|
34
|
-
export declare const pgTypeToTsType: (schema: PostgresSchema, pgType: string,
|
|
35
|
-
types: PostgresType[];
|
|
36
|
-
schemas: PostgresSchema[];
|
|
37
|
-
tables: PostgresTable[];
|
|
38
|
-
views: PostgresView[];
|
|
39
|
-
}, typeSchema?: string) => string;
|
|
50
|
+
export declare const pgTypeToTsType: (schema: PostgresSchema, pgType: string, context: TypeResolutionContext, typeSchema?: string) => string;
|