@embracesql/postgres
Advanced tools
Comparing version 0.0.3 to 0.0.4
{ | ||
"name": "@embracesql/postgres", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"description": "EmbraceSQL shared library for talking to postgres. Used in Node.", | ||
@@ -13,4 +13,5 @@ "type": "module", | ||
"dependencies": { | ||
"@embracesql/shared": "^0.0.3", | ||
"@embracesql/shared": "^0.0.4", | ||
"glob": "^10.3.10", | ||
"object-hash": "^3.0.0", | ||
"pg-connection-string": "^2.6.2", | ||
@@ -20,3 +21,6 @@ "postgres": "^3.4.3", | ||
}, | ||
"gitHead": "ce8c43da83ab6e340d337431a8d18e652a127cbd" | ||
"devDependencies": { | ||
"@types/object-hash": "^3.0.6" | ||
}, | ||
"gitHead": "343e5761ee3ff99619a2ba34c18139d0ef6240ad" | ||
} |
@@ -9,3 +9,14 @@ import { PGAttributes } from "./generator/pgtype/pgattribute"; | ||
import { PGTypeEnumValues } from "./generator/pgtype/pgtypeenum"; | ||
import { DatabaseNode } from "@embracesql/shared"; | ||
import { | ||
ColumnNode, | ||
DatabaseNode, | ||
IndexColumnNode, | ||
IndexNode, | ||
IsNamed, | ||
SchemaNode, | ||
TableNode, | ||
TablesNode, | ||
TypeNode, | ||
TypesNode, | ||
} from "@embracesql/shared"; | ||
import pgconnectionstring from "pg-connection-string"; | ||
@@ -161,3 +172,65 @@ import postgres from "postgres"; | ||
const database = new DatabaseNode(databaseName); | ||
namespaces.forEach((n) => n.addToAST(database)); | ||
// ok, this is a bit tricky since - tables and types can cross namespaces | ||
// so the first pass will set up all the schemas from catalog namespaces | ||
// along with their types | ||
namespaces.forEach((n) => { | ||
const schema = new SchemaNode(database, n.namespace); | ||
database.children.push(schema); | ||
const types = new TypesNode(schema); | ||
schema.children.push(types); | ||
// all types in the namespace | ||
n.types.forEach((t) => { | ||
const type = new TypeNode(t.typescriptName, types, t.oid, t); | ||
database.registerType(type.id, type); | ||
types.children.push(type); | ||
}); | ||
}); | ||
// ok -- we now know all types -- now we have enough information to make tables | ||
namespaces.forEach((n) => { | ||
const schema = database.children.find( | ||
(c) => (c as unknown as IsNamed)?.name === n.namespace, | ||
) as SchemaNode; | ||
if (schema) { | ||
const tables = new TablesNode(schema); | ||
schema.children.push(tables); | ||
n.tables.forEach((t) => { | ||
// the table and ... | ||
const table = new TableNode(tables, t.table.relname); | ||
tables.children.push(table); | ||
// it's columns | ||
t.tableType.attributes.forEach((a) => { | ||
const typeNode = database.resolveType(a.attribute.atttypid); | ||
if (typeNode) { | ||
table.children.push(new ColumnNode(table, a.name, typeNode)); | ||
} else { | ||
throw new Error( | ||
`${a.name} cannot find type ${a.attribute.atttypid}`, | ||
); | ||
} | ||
}); | ||
// indexes go on the table as well | ||
t.indexes.forEach((i) => { | ||
const index = new IndexNode( | ||
table, | ||
i.name, | ||
i.index.indisunique, | ||
i.index.indisprimary, | ||
); | ||
i.attributes.forEach((a) => { | ||
const typeNode = database.resolveType(a.attribute.atttypid); | ||
if (typeNode) { | ||
index.children.push(new IndexColumnNode(index, a.name, typeNode)); | ||
} else { | ||
throw new Error( | ||
`${a.name} cannot find type ${a.attribute.atttypid}`, | ||
); | ||
} | ||
}); | ||
table.children.push(index); | ||
}); | ||
}); | ||
} else { | ||
throw new Error(`cannot find namespace ${n.namespace}`); | ||
} | ||
}); | ||
@@ -164,0 +237,0 @@ // now we set up a new sql that can do type marshalling - runtime data |
@@ -12,3 +12,3 @@ import { Context } from "../../.."; | ||
return ` | ||
parse${this.typescriptName}(from: string) { | ||
if (from === null) return null; | ||
if(['t', 'T', 'true', 'True'].includes(from)) return true; | ||
@@ -21,3 +21,2 @@ try { | ||
return false; | ||
} | ||
`; | ||
@@ -31,4 +30,4 @@ } | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
serializeToPostgres(context: Context, x: any) { | ||
serializeToPostgres(context: Context, x: unknown) { | ||
console.assert(context); | ||
// string it -- yeah I know this is strange -- but it is how the | ||
@@ -35,0 +34,0 @@ // postges protocol works |
@@ -22,13 +22,12 @@ import { Context } from "../../../context"; | ||
return ` | ||
parse${this.typescriptName}(from: string) { | ||
if (from === null) return null; | ||
return Number.parseFloat(from); | ||
} | ||
`; | ||
} | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
serializeToPostgres(context: Context, x: any) { | ||
serializeToPostgres(context: Context, x: unknown) { | ||
console.assert(context); | ||
// string it | ||
if (!(x === undefined) && !(x === null)) { | ||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions | ||
// eslint-disable-next-line @typescript-eslint/no-base-to-string, @typescript-eslint/restrict-template-expressions | ||
return `${x}`; | ||
@@ -41,3 +40,3 @@ } else { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
parseFromPostgres(context: Context, x: any) { | ||
parseFromPostgres(context: Context, x: any): bigint | number | null { | ||
if (!(x === undefined) && !(x === null)) { | ||
@@ -58,5 +57,5 @@ return +x; | ||
return ` | ||
parse${this.typescriptName}(from: string) { | ||
if (from === null) return null; | ||
if (from === '') return null; | ||
return BigInt(from); | ||
} | ||
`; | ||
@@ -68,31 +67,20 @@ } | ||
return ` | ||
export type ${this.typescriptName} = BigInt; | ||
export type ${this.typescriptName} = bigint; | ||
`; | ||
} | ||
} | ||
export class PGTypeBytea extends PGCatalogType { | ||
typescriptTypeParser(context: GenerationContext) { | ||
console.assert(context); | ||
return ` | ||
parse${this.typescriptName}(from: string) { | ||
return new Uint8Array(JSON.parse(from)); | ||
parseFromPostgres(context: Context, x: unknown) { | ||
if (!(x === undefined) && !(x === null)) { | ||
return BigInt(+x); | ||
} else { | ||
return null; | ||
} | ||
`; | ||
} | ||
typescriptTypeDefinition(context: Context) { | ||
console.assert(context); | ||
return ` | ||
export type ${this.typescriptName} = Uint8Array; | ||
`; | ||
} | ||
} | ||
export class PGTypeVector extends PGCatalogType { | ||
export class PGTypeBytea extends PGCatalogType { | ||
typescriptTypeParser(context: GenerationContext) { | ||
console.assert(context); | ||
return ` | ||
parse${this.typescriptName}(from: string) { | ||
return new Float32Array(JSON.parse(from)); | ||
} | ||
return from ? new Uint8Array(JSON.parse(from)) : null; | ||
`; | ||
@@ -103,5 +91,5 @@ } | ||
return ` | ||
export type ${this.typescriptName} = Float32Array; | ||
export type ${this.typescriptName} = Uint8Array; | ||
`; | ||
} | ||
} |
@@ -9,5 +9,3 @@ import { GenerationContext } from "../.."; | ||
return ` | ||
parse${this.typescriptName}(from: string) { | ||
return new URL(from); | ||
} | ||
return from ? new URL(from) : null; | ||
`; | ||
@@ -14,0 +12,0 @@ } |
@@ -7,4 +7,13 @@ /* eslint-disable @typescript-eslint/no-unsafe-return */ | ||
import { registerOverride } from "./_overrides"; | ||
import { GenerationContext, commaSeparatedNumbers } from "@embracesql/shared"; | ||
class PGCube extends PGCatalogType { | ||
class PGTypeCube extends PGCatalogType { | ||
typescriptTypeParser(context: GenerationContext) { | ||
console.assert(context); | ||
return ` | ||
if (from === null) return null; | ||
const source = Array.isArray(from) ? new Float32Array(from) : JSON.parse(from); | ||
return new Float32Array(source); | ||
`; | ||
} | ||
typescriptTypeDefinition(context: Context) { | ||
@@ -21,4 +30,3 @@ console.assert(context); | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
serializeToPostgres(context: Context, x: any) { | ||
serializeToPostgres(context: Context, x: unknown) { | ||
console.assert(context); | ||
@@ -29,6 +37,8 @@ // default is just 'a string of it' | ||
// postgres array literal | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return | ||
return `${Object.values(x) | ||
.map((x) => (x ? x : 0)) | ||
.join(",")}`; | ||
if (Array.isArray(x)) | ||
return `${Object.values(x) | ||
.map((x) => (x ? x : 0)) | ||
.join(",")}`; | ||
// wing it 🪽 | ||
return `${x}`; | ||
} | ||
@@ -40,3 +50,3 @@ | ||
if (x) { | ||
return JSON.parse(`${x}`); | ||
return new Float32Array(commaSeparatedNumbers.tryParse(`${x}`)); | ||
} else { | ||
@@ -48,2 +58,2 @@ return null; | ||
registerOverride("cube", PGCube); | ||
registerOverride("cube", PGTypeCube); |
import { Context } from "../../../context"; | ||
import { PGCatalogType } from "../pgcatalogtype"; | ||
import { registerOverride } from "./_overrides"; | ||
import { GenerationContext } from "@embracesql/shared"; | ||
class PGDate extends PGCatalogType { | ||
typescriptTypeParser(context: GenerationContext) { | ||
console.assert(context); | ||
return ` | ||
if (from === null) return null; | ||
if ((from as unknown) instanceof global.Date) return from; | ||
return new global.Date(from); | ||
`; | ||
} | ||
typescriptTypeDefinition(context: Context) { | ||
console.assert(context); | ||
// date ends up with a type alias | ||
return ` | ||
@@ -13,7 +23,7 @@ export type ${this.typescriptName} = JsDate; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
serializeToPostgres(context: Context, x: any) { | ||
serializeToPostgres(context: Context, x: unknown) { | ||
console.assert(context); | ||
// string it | ||
if (x) { | ||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions | ||
// eslint-disable-next-line @typescript-eslint/no-base-to-string, @typescript-eslint/restrict-template-expressions | ||
return (x instanceof Date ? x : new Date(`${x}`)).toISOString(); | ||
@@ -40,3 +50,5 @@ } else { | ||
registerOverride("date", PGDate); | ||
// TODO: gonna need a real JS 'time' type | ||
registerOverride("time", PGDate); | ||
registerOverride("timetz", PGDate); |
@@ -7,11 +7,11 @@ import { PGTypeNumber } from "../base/number"; | ||
// yeah -- looks odd -- but registerOverride needs to be defined first | ||
export * from "./name"; | ||
export * from "./oid"; | ||
export * from "./oidvector"; | ||
export * from "./uuid"; | ||
export * from "./point"; | ||
export * from "./box"; | ||
export * from "./line"; | ||
export * from "./lseg"; | ||
export * from "./int2vector"; | ||
// TODO: geometric types need real use cases and parsers to match docs at | ||
// https://www.postgresql.org/docs/current/datatype-geometric.html | ||
export * from "./geometric/point"; | ||
export * from "./geometric/box"; | ||
export * from "./geometric/circle"; | ||
export * from "./geometric/line"; | ||
export * from "./geometric/lseg"; | ||
export * from "./vector"; | ||
export * from "./date"; | ||
@@ -18,0 +18,0 @@ export * from "./json"; |
@@ -16,4 +16,4 @@ /* eslint-disable @typescript-eslint/no-unsafe-return */ | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
serializeToPostgres(context: Context, x: any) { | ||
serializeToPostgres(context: Context, x: unknown) { | ||
console.assert(context); | ||
// string it if we need it | ||
@@ -20,0 +20,0 @@ if (x) { |
@@ -10,5 +10,3 @@ import { Context } from "../../../context"; | ||
return ` | ||
parse${this.typescriptName}(from: string) { | ||
return new UUID(from); | ||
} | ||
return from ? new UUID(from) : null; | ||
`; | ||
@@ -23,5 +21,7 @@ } | ||
serializeToPostgres(context: Context, x: UUID) { | ||
serializeToPostgres(context: Context, x: unknown) { | ||
if (x === null) return null; | ||
if ((x as UUID).uuid) return (x as UUID).uuid; | ||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions | ||
return x ? x.uuid : null; | ||
return `${x}`; | ||
} | ||
@@ -28,0 +28,0 @@ |
@@ -1,6 +0,9 @@ | ||
import { GeneratesTypeScriptParser, GenerationContext } from "@embracesql/shared"; | ||
import { Context, PostgresTypecast } from "../../context"; | ||
import { asDocComment } from "../../util"; | ||
import { CatalogRow } from "./pgtype"; | ||
import { | ||
GeneratesTypeScriptParser, | ||
GenerationContext, | ||
} from "@embracesql/shared"; | ||
import { pascalCase } from "change-case"; | ||
import { CatalogRow } from "./pgtype"; | ||
@@ -32,8 +35,6 @@ /** | ||
typescriptTypeParser(context: GenerationContext) { | ||
console.assert(context) | ||
console.assert(context); | ||
return ` | ||
parse${this.typescriptName}(from: string) { | ||
return from; | ||
} | ||
` | ||
`; | ||
} | ||
@@ -98,12 +99,10 @@ | ||
/** | ||
* Override this to get 'to' postgres and interface with the database. | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
serializeToPostgres(context: Context, x: any) { | ||
serializeToPostgres(context: Context, x: unknown) { | ||
console.assert(context); | ||
// default is just 'a string of it' | ||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions | ||
if (x === null) return null; | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-return | ||
return x; | ||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions | ||
return `${x}`; | ||
} | ||
@@ -110,0 +109,0 @@ |
@@ -6,3 +6,2 @@ import { Context, TypeFactoryContext } from "../../context"; | ||
import { PGTypeComposite } from "./pgtypecomposite"; | ||
import { IndexColumnNode, IndexNode, TableNode } from "@embracesql/shared"; | ||
import { pascalCase } from "change-case"; | ||
@@ -70,15 +69,2 @@ import path from "path"; | ||
addToAST(table: TableNode) { | ||
const index = new IndexNode( | ||
table, | ||
this.name, | ||
this.index.indisunique, | ||
this.index.indisprimary, | ||
); | ||
this.attributes.forEach((a) => | ||
index.children.push(new IndexColumnNode(index, a.name)), | ||
); | ||
table.children.push(index); | ||
} | ||
get name() { | ||
@@ -85,0 +71,0 @@ return `by_${this.attributes.map((a) => a.typescriptName).join("_")}`; |
@@ -7,3 +7,2 @@ import { Context } from "../../context"; | ||
import { PGTypes } from "./pgtype"; | ||
import { DatabaseNode, SchemaNode, TablesNode, TypeNode } from "@embracesql/shared"; | ||
import { pascalCase } from "change-case"; | ||
@@ -66,13 +65,2 @@ | ||
addToAST(database: DatabaseNode) { | ||
// each namespace joins the tree | ||
const schema = new SchemaNode(database, this.namespace); | ||
database.children.push(schema); | ||
const tables = new TablesNode(schema); | ||
schema.children.push(tables); | ||
this.tables.forEach((t) => t.addToAST(tables)); | ||
// all types in the namespace | ||
this.types.forEach(t => schema.children.push(new TypeNode(schema, t))) | ||
} | ||
get typescriptName() { | ||
@@ -79,0 +67,0 @@ return PGNamespace.typescriptName(this.namespace); |
@@ -12,2 +12,3 @@ import { Context, PostgresProcTypecast } from "../../../context"; | ||
import { camelCase, pascalCase } from "change-case"; | ||
import hash from "object-hash"; | ||
import parsimmon from "parsimmon"; | ||
@@ -30,2 +31,3 @@ import path from "path"; | ||
pronargdefaults: number; | ||
overloads: number; | ||
}; | ||
@@ -69,2 +71,6 @@ | ||
get overloaded() { | ||
return Number.parseInt(`${this.proc.overloads}`) > 1; | ||
} | ||
get nspname() { | ||
@@ -75,3 +81,5 @@ return this.proc.nspname; | ||
get typescriptName() { | ||
return pascalCase(this.proc.proname); | ||
const seed = pascalCase(this.proc.proname); | ||
const stem = hash(this.proc.proargtypes.flatMap((x) => x)).substring(0, 4); | ||
return this.overloaded ? `${seed}${stem}` : seed; | ||
} | ||
@@ -78,0 +86,0 @@ |
@@ -5,3 +5,2 @@ import { Context, TypeFactoryContext } from "../../context"; | ||
import { PGTypeComposite } from "./pgtypecomposite"; | ||
import { ColumnNode, TableNode, TablesNode } from "@embracesql/shared"; | ||
import { pascalCase } from "change-case"; | ||
@@ -61,11 +60,2 @@ import path from "path"; | ||
addToAST(tables: TablesNode) { | ||
const table = new TableNode(tables, this.table.relname); | ||
tables.children.push(table); | ||
this.tableType.attributes.forEach((a) => | ||
table.children.push(new ColumnNode(table, a.name)), | ||
); | ||
this.indexes.forEach((i) => i.addToAST(table)); | ||
} | ||
get typescriptName() { | ||
@@ -72,0 +62,0 @@ return pascalCase(this.table.relname); |
import { TypeFactoryContext } from "../../context"; | ||
import { PGTypeText } from "./base/text"; | ||
import { overrides } from "./overrides"; | ||
@@ -70,2 +71,10 @@ import { PGCatalogType } from "./pgcatalogtype"; | ||
} | ||
// there are 'odd' base types that are arrays of scalars but when you | ||
// but are not named like other arrays | ||
// TODO: update registerOverride to allow a function expression | ||
if (catalog.typname === "oidvector") | ||
return PGTypeBase.factory(context, catalog); | ||
if (catalog.typname === "name") return new PGTypeText(catalog); | ||
if (catalog.typtype === "c") return new PGTypeComposite(context, catalog); | ||
@@ -72,0 +81,0 @@ if (catalog.typtype === "e") return new PGTypeEnum(context, catalog); |
@@ -6,2 +6,3 @@ import { Context, TypeFactoryContext } from "../../context"; | ||
DELIMITER, | ||
GenerationContext, | ||
arrayAttribute, | ||
@@ -12,2 +13,6 @@ escapeArrayValue, | ||
type Props = { | ||
arraySuffix: boolean; | ||
}; | ||
/** | ||
@@ -17,11 +22,34 @@ * Arrays of other types are somewhat simple to declare - it is just Array<...>. | ||
export class PGTypeArray extends PGCatalogType { | ||
constructor(context: TypeFactoryContext, catalog: CatalogRow) { | ||
constructor( | ||
context: TypeFactoryContext, | ||
catalog: CatalogRow, | ||
private props: Props = { arraySuffix: true }, | ||
) { | ||
super(catalog); | ||
} | ||
/** | ||
* Arrays have ... the word Array... | ||
*/ | ||
typescriptTypeParser(context: GenerationContext) { | ||
const elementType = context.database.resolveType(this.catalog.typelem); | ||
if (elementType) { | ||
return ` | ||
if (from === null) return null; | ||
const rawArray = JSON.parse(from); | ||
return rawArray.map((e:unknown) => { | ||
return ${elementType.typescriptName}.parse( | ||
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions | ||
\`\${e}\` | ||
); | ||
}); | ||
`; | ||
} else { | ||
throw new Error( | ||
`${this.catalog.typname} could not resolve type of element`, | ||
); | ||
} | ||
} | ||
get typescriptName() { | ||
return `${pascalCase(this.catalog.typname)}Array`; | ||
return `${pascalCase(this.catalog.typname)}${ | ||
this.props.arraySuffix ? "Array" : "" | ||
}`; | ||
} | ||
@@ -40,4 +68,3 @@ | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
serializeToPostgres(context: Context, x: any) { | ||
serializeToPostgres(context: Context, x: unknown) { | ||
// passed object | ||
@@ -44,0 +71,0 @@ if (x) { |
import { Context, TypeFactoryContext } from "../../context"; | ||
import { asDocComment } from "../../util"; | ||
import { PGTypeBool } from "./base/bool"; | ||
import { | ||
PGTypeBigInt, | ||
PGTypeBytea, | ||
PGTypeNumber, | ||
PGTypeVector, | ||
} from "./base/number"; | ||
import { PGTypeBigInt, PGTypeBytea, PGTypeNumber } from "./base/number"; | ||
import { PGTypeText, PGTypeTextArray } from "./base/text"; | ||
@@ -14,2 +9,3 @@ import { PGTypeUri } from "./base/uri"; | ||
import { CatalogRow } from "./pgtype"; | ||
import { PGTypeArray } from "./pgtypearray"; | ||
@@ -52,4 +48,2 @@ /** | ||
return new PGTypeBytea(catalog); | ||
case "vector": | ||
return new PGTypeVector(catalog); | ||
case "inet": | ||
@@ -59,12 +53,2 @@ return new PGTypeInet(catalog); | ||
return new PGTypeText(catalog); | ||
case "point": | ||
return new PGTypePoint(catalog); | ||
case "box": | ||
return new PGTypePointPair(catalog); | ||
case "path": | ||
return new PGTypePointArray(catalog); | ||
case "polygon": | ||
return new PGTypePointArray(catalog); | ||
case "circle": | ||
return new PGTypeCircle(catalog); | ||
case "aclitem": | ||
@@ -74,6 +58,6 @@ return new PGTypeText(catalog); | ||
return new PGTypeText(catalog); | ||
case "lsn": | ||
case "pg_lsn": | ||
return new PGTypeBigInt(catalog); | ||
case "tsvector": | ||
return new PGTypeTextArray(catalog); | ||
return new PGTypeText(catalog); | ||
case "gtsvector": | ||
@@ -85,2 +69,4 @@ return new PGTypeTextArray(catalog); | ||
return new PGTypeUri(catalog); | ||
case "oidvector": | ||
return new PGTypeArray(context, catalog, { arraySuffix: false }); | ||
default: | ||
@@ -126,49 +112,1 @@ // if the db wants to code it as text, so do we | ||
} | ||
class PGTypePoint extends PGTypeBase { | ||
typescriptTypeDefinition(context: Context) { | ||
console.assert(context); | ||
return ` | ||
${asDocComment(this.comment)} | ||
export type ${this.typescriptName} = { | ||
x: number; | ||
y: number; | ||
}; | ||
`; | ||
} | ||
} | ||
class PGTypePointPair extends PGTypeBase { | ||
typescriptTypeDefinition(context: Context) { | ||
console.assert(context); | ||
return ` | ||
${asDocComment(this.comment)} | ||
export type ${this.typescriptName} = { | ||
from: Point; | ||
to: Point; | ||
}; | ||
`; | ||
} | ||
} | ||
class PGTypePointArray extends PGTypeBase { | ||
typescriptTypeDefinition(context: Context) { | ||
console.assert(context); | ||
return ` | ||
${asDocComment(this.comment)} | ||
export type ${this.typescriptName} = Array<Point>; | ||
`; | ||
} | ||
} | ||
class PGTypeCircle extends PGTypeBase { | ||
typescriptTypeDefinition(context: Context) { | ||
console.assert(context); | ||
return ` | ||
${asDocComment(this.comment)} | ||
export type ${this.typescriptName} = { | ||
center: Point; | ||
radius: number; | ||
}; | ||
`; | ||
} | ||
} |
@@ -137,7 +137,6 @@ import { Context, TypeFactoryContext } from "../../context"; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
serializeToPostgres(context: Context, x: any) { | ||
serializeToPostgres(context: Context, x: unknown) { | ||
// make a composite type -- escape the values looked up from the | ||
// passed object | ||
if (x) { | ||
if (typeof x === "object") { | ||
const attributes = this.attributes.map((a) => { | ||
@@ -150,3 +149,3 @@ // hand off the the serializer | ||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access | ||
x[camelCase(a.attribute.attname)], | ||
(x as Record<string, object>)[camelCase(a.attribute.attname)], | ||
); | ||
@@ -153,0 +152,0 @@ // quick escape with regex |
@@ -34,4 +34,3 @@ import { Context, TypeFactoryContext } from "../../context"; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
serializeToPostgres(context: Context, x: any) { | ||
serializeToPostgres(context: Context, x: unknown) { | ||
// delegate to the base type | ||
@@ -38,0 +37,0 @@ // eslint-disable-next-line @typescript-eslint/no-unsafe-return |
@@ -6,4 +6,4 @@ import { GenerationContext } from ".."; | ||
} from "../operations/sqlscript"; | ||
import { ASTKind, IsNamed, NamespaceVisitor } from "@embracesql/shared"; | ||
import { camelCase, pascalCase } from "change-case"; | ||
import { generatePrimaryKeyPickers } from "./generatePrimaryKeyPickers"; | ||
import { generateTypeParsers } from "./generateTypeParsers"; | ||
@@ -84,48 +84,6 @@ /** | ||
// parsing from strings into TS types. | ||
generationBuffer.push(`// begin string parsers`); | ||
context.handlers = { | ||
[ASTKind.Schema]: NamespaceVisitor, | ||
[ASTKind.Type]: { | ||
before: async (context, node) => { | ||
return `export function ${node.parser.typescriptTypeParser(context)}`; | ||
}, | ||
}, | ||
}; | ||
// no skipping schemas for parsing | ||
generationBuffer.push(await context.database.visit({ ...context, skipSchemas: [] })); | ||
generationBuffer.push(`// end string parsers`); | ||
generationBuffer.push(await generateTypeParsers(context)); | ||
generationBuffer.push(await generatePrimaryKeyPickers(context)); | ||
// primary key 'pickers' used to debounce and hash objects | ||
generationBuffer.push(`// begin primary key pickers`); | ||
context.handlers = { | ||
[ASTKind.Schema]: NamespaceVisitor, | ||
[ASTKind.Table]: { | ||
before: async (_, node) => { | ||
const tableTypeName = `${pascalCase( | ||
(node as unknown as IsNamed)?.name, | ||
)}`; | ||
const generationBuffer = [""]; | ||
const primaryKey = node.primaryKey; | ||
if (primaryKey) { | ||
generationBuffer.push( | ||
`export function pickPrimaryKeyFrom${tableTypeName}(value: ${tableTypeName}) : string {`, | ||
); | ||
generationBuffer.push(`return JSON.stringify({`); | ||
primaryKey.columns.forEach((c) => | ||
generationBuffer.push( | ||
`${camelCase(c.name)}: value.${camelCase(c.name)},`, | ||
), | ||
); | ||
generationBuffer.push(`});`); | ||
generationBuffer.push(`}`); | ||
} | ||
return generationBuffer.join("\n"); | ||
}, | ||
}, | ||
}; | ||
generationBuffer.push(await context.database.visit(context)); | ||
generationBuffer.push(`// end primary key pickers`); | ||
return generationBuffer.join("\n"); | ||
}; |
export { initializeContext } from "./context"; | ||
export type { Context } from "./context"; | ||
export * from "./generator"; |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
117527
3468
6
1
+ Addedobject-hash@^3.0.0
+ Added@embracesql/shared@0.0.4(transitive)
+ Addedobject-hash@3.0.0(transitive)
- Removed@embracesql/shared@0.0.3(transitive)
Updated@embracesql/shared@^0.0.4