@platformatic/sql-mapper 3.63.0-alpha.3 → 3.63.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/index.d.ts CHANGED
@@ -59,6 +59,11 @@ export interface DBEntityField {
59
59
  * An option that is true if field is a foreignKey key.
60
60
  */
61
61
  foreignKey?: boolean,
62
+ /**
63
+ * An option that is true if a foreign key field is stringified in mapper output
64
+ * because it references a primary key.
65
+ */
66
+ stringifyOutput?: boolean,
62
67
  /**
63
68
  * An option that is true if field is nullable.
64
69
  */
package/index.js CHANGED
@@ -80,6 +80,29 @@ const defaultAutoTimestampFields = {
80
80
  updatedAt: 'updated_at'
81
81
  }
82
82
 
83
+ function physicalEntityKey (schema, table) {
84
+ return `${schema ?? ''}\0${table}`
85
+ }
86
+
87
+ function markForeignKeysReferencingPrimaryKeys (entities) {
88
+ const entitiesByTable = new Map()
89
+
90
+ for (const entity of Object.values(entities)) {
91
+ entitiesByTable.set(physicalEntityKey(entity.schema, entity.table), entity)
92
+ }
93
+
94
+ for (const entity of Object.values(entities)) {
95
+ for (const relation of entity.relations) {
96
+ const foreignSchema = relation.foreign_table_schema ?? entity.schema
97
+ const foreignEntity = entitiesByTable.get(physicalEntityKey(foreignSchema, relation.foreign_table_name))
98
+
99
+ if (foreignEntity?.primaryKeys.has(relation.foreign_column_name)) {
100
+ entity.fields[relation.column_name].stringifyOutput = true
101
+ }
102
+ }
103
+ }
104
+ }
105
+
83
106
  async function registerPostgreSQLExtensionTypes (db) {
84
107
  try {
85
108
  await db.registerTypeParser('vector', parseVector)
@@ -375,6 +398,8 @@ export async function connect ({
375
398
  }
376
399
  }
377
400
 
401
+ markForeignKeysReferencingPrimaryKeys(entities)
402
+
378
403
  const res = {
379
404
  db,
380
405
  sql,
package/lib/entity.js CHANGED
@@ -104,8 +104,13 @@ function createMapper (
104
104
  let value = output[key]
105
105
  const newKey = fieldMapToRetrieve[key]
106
106
  // Do not convert Date objects: they are serialized according to the
107
- // schema of the field, like non primary key columns
108
- if (primaryKeys.has(key) && value !== null && value !== undefined && !(value instanceof Date)) {
107
+ // schema of the field, like other non-stringified columns
108
+ if (
109
+ (primaryKeys.has(key) || fields[key]?.stringifyOutput) &&
110
+ value !== null &&
111
+ value !== undefined &&
112
+ !(value instanceof Date)
113
+ ) {
109
114
  value = value.toString()
110
115
  }
111
116
  if (newKey && isVectorType(fields[key].sqlType)) {
package/lib/queries/pg.js CHANGED
@@ -80,16 +80,27 @@ export async function listColumns (db, sql, table, schema) {
80
80
 
81
81
  export async function listConstraints (db, sql, table, schema) {
82
82
  const query = sql`
83
- SELECT constraints.*, usage.*, usage2.table_name AS foreign_table_name, usage2.column_name AS foreign_column_name, usage2.table_schema AS foreign_table_schema
83
+ SELECT constraints.*, usage.*, foreign_usage.table_name AS foreign_table_name,
84
+ foreign_usage.column_name AS foreign_column_name, foreign_usage.table_schema AS foreign_table_schema
84
85
  FROM information_schema.table_constraints constraints
85
86
  JOIN information_schema.key_column_usage usage
86
- ON constraints.constraint_name = usage.constraint_name
87
- AND constraints.table_name = ${table}
88
- JOIN information_schema.constraint_column_usage usage2
89
- ON usage.constraint_name = usage2.constraint_name
90
- AND ( usage.table_name = ${table}
91
- AND usage.table_schema = ${schema} )
92
- ORDER BY usage.constraint_name, usage.ordinal_position, usage2.table_name, usage2.column_name
87
+ ON constraints.constraint_catalog = usage.constraint_catalog
88
+ AND constraints.constraint_schema = usage.constraint_schema
89
+ AND constraints.constraint_name = usage.constraint_name
90
+ AND constraints.table_schema = usage.table_schema
91
+ AND constraints.table_name = usage.table_name
92
+ LEFT JOIN information_schema.referential_constraints referential
93
+ ON constraints.constraint_catalog = referential.constraint_catalog
94
+ AND constraints.constraint_schema = referential.constraint_schema
95
+ AND constraints.constraint_name = referential.constraint_name
96
+ LEFT JOIN information_schema.key_column_usage foreign_usage
97
+ ON referential.unique_constraint_catalog = foreign_usage.constraint_catalog
98
+ AND referential.unique_constraint_schema = foreign_usage.constraint_schema
99
+ AND referential.unique_constraint_name = foreign_usage.constraint_name
100
+ AND usage.position_in_unique_constraint = foreign_usage.ordinal_position
101
+ WHERE constraints.table_name = ${table}
102
+ AND constraints.table_schema = ${schema}
103
+ ORDER BY usage.constraint_name, usage.ordinal_position
93
104
  `
94
105
  const constraintsList = await db.query(query)
95
106
  return constraintsList
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@platformatic/sql-mapper",
3
- "version": "3.63.0-alpha.3",
3
+ "version": "3.63.0",
4
4
  "description": "A data mapper utility for SQL databases",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -19,7 +19,7 @@
19
19
  "@opentelemetry/api": "^1.9.0",
20
20
  "cleaner-spec-reporter": "^0.5.0",
21
21
  "eslint": "9",
22
- "fastify": "^5.7.0",
22
+ "fastify": "^5.0.0",
23
23
  "neostandard": "^0.12.0",
24
24
  "tstyche": "^6.2.0",
25
25
  "typescript": "^5.9.3"
@@ -33,10 +33,10 @@
33
33
  "@matteo.collina/sqlite-pool": "^0.7.0",
34
34
  "async-cache-dedupe": "^2.1.0",
35
35
  "camelcase": "^6.3.0",
36
- "fastify-plugin": "^5.0.0",
36
+ "fastify-plugin": "^6.0.0",
37
37
  "inflected": "^2.1.0",
38
- "@platformatic/foundation": "3.63.0-alpha.3",
39
- "@platformatic/telemetry": "3.63.0-alpha.3"
38
+ "@platformatic/telemetry": "3.63.0",
39
+ "@platformatic/foundation": "3.63.0"
40
40
  },
41
41
  "engines": {
42
42
  "node": ">=22.19.0"