ForbesLindesay/atdatabases

[Postgres] Support bigIntMode for pg-schema-cli, pg-schema-print-types

Closed this issue · 0 comments

Summary

Support bigIntMode properly for packages: pg-schema-cli, pg-schema-print-types

Situation

Currently, using pg-schema-cli will generate TypeScript schema based on pg-schema-introspect package and TypeScript type mapping based on DefaultTypeScriptMapping.js file in pg-schema-print-types.
I think migration related packages also should support a bigIntMode-like option in @databases/pg.

Suggestions

New DATABASE_URL-ish environment variable for bigIntMode

Since packages on atdatabases are highly separated, it can be easily done with TypeScript environment variable too.
I set it to DATABASE_INT8_MAPPING in the following workaround.

New option: bigIntMode for other packages

Introduce new bigIntMode-like option for other packages: pg-schema-cli and pg-schema-print-types

Workarounds

The following workarounds are able to apply by using pnpm.
This is not for production.

@databases__pg-schema-cli@4.3.1.patch

Add --bigIntMode parameter support on pg-schema-cli.

diff --git a/lib/index.js b/lib/index.js
index fc2aa8d2635756c4b285d4300154ca3110de9256..a79f7e307ecf801c243acb4fd60f5e089c101385 100644
--- a/lib/index.js
+++ b/lib/index.js
@@ -12,11 +12,12 @@ const parameterParser = (0, parameter_reducers_1.startChain)()
     .addParam(parameter_reducers_1.param.string(['-c', '--database'], 'database'))
     .addParam(parameter_reducers_1.param.string(['-d', '--directory'], 'directory'))
     .addParam(parameter_reducers_1.param.string(['--config'], 'configFilename'))
-    .addParam(parameter_reducers_1.param.string(['-s', '--schemaName'], 'schemaName'));
+    .addParam(parameter_reducers_1.param.string(['-s', '--schemaName'], 'schemaName'))
+    .addParam(parameter_reducers_1.param.string(['--bigIntMode'], 'bigIntMode'));
 async function run(cwd, args) {
     var _a, _b;
     const params = (0, parameter_reducers_1.parse)(parameterParser, args).extract();
-    const { connectionStringEnvironmentVariable, types: { directory, ...types }, } = params.configFilename
+    const { connectionStringEnvironmentVariable, types: { directory, ...types } } = params.configFilename
         ? (0, pg_config_1.readPgConfigSync)((0, path_1.resolve)(cwd, params.configFilename))
         : (0, pg_config_1.getPgConfigSync)(cwd);
     let database = (_a = params.database) !== null && _a !== void 0 ? _a : process.env[connectionStringEnvironmentVariable];
@@ -33,7 +34,20 @@ async function run(cwd, args) {
     if (!database) {
         return 1;
     }
-    const connection = (0, pg_schema_introspect_1.connect)({ connectionString: database, poolSize: 1 });
+    // bigIntMode patch
+    console.warn('The current version of pg-schema-cli has been patched to support dynamic bigIntMode.');
+    const bigIntMode = params.bigIntMode;
+    if (bigIntMode) {
+        const isValid = bigIntMode === 'string' || bigIntMode === 'bigint' || bigIntMode === 'number';
+        if (!isValid) {
+            console.error(`You must supply a bigIntMode parameter as string, bigint, or number but got: ${bigIntMode}.`);
+            return 1;
+        }
+        console.log(`Detected valid parameter for bigIntMode config declaration! Using bigIntMode: ${bigIntMode}.`);
+        process.env.DATABASE_INT8_MAPPING = bigIntMode
+        console.log('Set DATABASE_INT8_MAPPING environment variable for type integrity service.')
+    }
+    const connection = (0, pg_schema_introspect_1.connect)({ connectionString: database, poolSize: 1, bigIntMode });
     let schema;
     try {
         schema = await (0, pg_schema_introspect_1.default)(connection, { schemaName: params.schemaName });

@databases__pg-schema-print-types@4.4.1.patch

Use dynamic loading of preconfigured environment variable.

diff --git a/lib/DefaultTypeScriptMapping.js b/lib/DefaultTypeScriptMapping.js
index 866dd69a5c60f131382f012da1fc868e962386ea..ab1b0ff2edf186bd62b3a4eba6b55c0bf6faf1eb 100644
--- a/lib/DefaultTypeScriptMapping.js
+++ b/lib/DefaultTypeScriptMapping.js
@@ -2,53 +2,68 @@
 // auto generated by test suite of pg-schema-introspect
 Object.defineProperty(exports, "__esModule", { value: true });
 const pg_data_type_id_1 = require("@databases/pg-data-type-id");
-const DefaultTypeScriptMapping = new Map([
-    [pg_data_type_id_1.default._bool, 'Array<boolean | nul>'],
-    [pg_data_type_id_1.default._bpchar, 'Array<string | null>'],
-    [pg_data_type_id_1.default._bytea, 'Array<Buffer | null>'],
-    [pg_data_type_id_1.default._cidr, 'Array<string | null>'],
-    [pg_data_type_id_1.default._date, 'Array<Date | null>'],
-    [pg_data_type_id_1.default._float4, 'Array<number | null>'],
-    [pg_data_type_id_1.default._float8, 'Array<number | null>'],
-    [pg_data_type_id_1.default._inet, 'Array<string | null>'],
-    [pg_data_type_id_1.default._int2, 'Array<number | null>'],
-    [pg_data_type_id_1.default._int4, 'Array<number | null>'],
-    [pg_data_type_id_1.default._int8, 'Array<number | null>'],
-    [pg_data_type_id_1.default._json, 'Array<any | null>'],
-    [pg_data_type_id_1.default._jsonb, 'Array<any | null>'],
-    [pg_data_type_id_1.default._macaddr, 'Array<string | null>'],
-    [pg_data_type_id_1.default._money, 'Array<string | null>'],
-    [pg_data_type_id_1.default._numeric, 'Array<number | null>'],
-    [pg_data_type_id_1.default._numrange, 'Array<string | null>'],
-    [pg_data_type_id_1.default._oid, 'Array<number | null>'],
-    [pg_data_type_id_1.default._point, 'Array<{x: number, y: number} | null>'],
-    [pg_data_type_id_1.default._regproc, 'Array<string | null>'],
-    [pg_data_type_id_1.default._text, 'Array<string | null>'],
-    [pg_data_type_id_1.default._time, 'Array<string | null>'],
-    [pg_data_type_id_1.default._timestamp, 'Array<Date | null>'],
-    [pg_data_type_id_1.default._timestamptz, 'Array<Date | null>'],
-    [pg_data_type_id_1.default._timetz, 'Array<string | null>'],
-    [pg_data_type_id_1.default._uuid, 'Array<string | null>'],
-    [pg_data_type_id_1.default._varchar, 'Array<string | null>'],
-    [pg_data_type_id_1.default.bool, 'boolean'],
-    [pg_data_type_id_1.default.bytea, 'Buffer'],
-    [pg_data_type_id_1.default.circle, '{x: number, y: number, radius: number}'],
-    [pg_data_type_id_1.default.date, 'Date'],
-    [pg_data_type_id_1.default.float4, 'number'],
-    [pg_data_type_id_1.default.float8, 'number'],
-    [pg_data_type_id_1.default.int2, 'number'],
-    [pg_data_type_id_1.default.int4, 'number'],
-    [pg_data_type_id_1.default.int8, 'number'],
-    [
-        pg_data_type_id_1.default.interval,
-        '{years: number,months: number,days: number,hours: number,minutes: number,seconds: number,milliseconds: number, toPostgres: () => string, toISO: () => string}',
-    ],
-    [pg_data_type_id_1.default.json, 'any'],
-    [pg_data_type_id_1.default.jsonb, 'any'],
-    [pg_data_type_id_1.default.oid, 'number'],
-    [pg_data_type_id_1.default.point, '{x: number, y: number}'],
-    [pg_data_type_id_1.default.timestamp, 'Date'],
-    [pg_data_type_id_1.default.timestamptz, 'Date'],
-]);
-exports.default = DefaultTypeScriptMapping;
+Object.defineProperty(exports, 'default', {
+    get() {
+        const int8Mapping = process.env.DATABASE_INT8_MAPPING;
+        console.log('@databases/pg-schema-print-types is patched to support dynamic bigIntMode type integrity.')
+        if (int8Mapping) {
+            if (int8Mapping !== 'number' && int8Mapping !== 'bigint' && int8Mapping !== 'string') {
+                throw new Error('Failed to check integrity of DATABASE_INT8_MAPPING environment variable for bigIntMode type generation!');
+            }
+            if (int8Mapping === 'bigint') {
+                int8Mapping = 'BigInt';
+            }
+            console.log(`Using custom integrity to match schema generation for bigIntMode configuration: INT8 to ${int8Mapping}`);
+        }
+        const DefaultTypeScriptMapping = new Map([
+            [pg_data_type_id_1.default._bool, 'Array<boolean | nul>'],
+            [pg_data_type_id_1.default._bpchar, 'Array<string | null>'],
+            [pg_data_type_id_1.default._bytea, 'Array<Buffer | null>'],
+            [pg_data_type_id_1.default._cidr, 'Array<string | null>'],
+            [pg_data_type_id_1.default._date, 'Array<Date | null>'],
+            [pg_data_type_id_1.default._float4, 'Array<number | null>'],
+            [pg_data_type_id_1.default._float8, 'Array<number | null>'],
+            [pg_data_type_id_1.default._inet, 'Array<string | null>'],
+            [pg_data_type_id_1.default._int2, 'Array<number | null>'],
+            [pg_data_type_id_1.default._int4, 'Array<number | null>'],
+            [pg_data_type_id_1.default._int8, 'Array<number | null>'],
+            [pg_data_type_id_1.default._json, 'Array<any | null>'],
+            [pg_data_type_id_1.default._jsonb, 'Array<any | null>'],
+            [pg_data_type_id_1.default._macaddr, 'Array<string | null>'],
+            [pg_data_type_id_1.default._money, 'Array<string | null>'],
+            [pg_data_type_id_1.default._numeric, 'Array<number | null>'],
+            [pg_data_type_id_1.default._numrange, 'Array<string | null>'],
+            [pg_data_type_id_1.default._oid, 'Array<number | null>'],
+            [pg_data_type_id_1.default._point, 'Array<{x: number, y: number} | null>'],
+            [pg_data_type_id_1.default._regproc, 'Array<string | null>'],
+            [pg_data_type_id_1.default._text, 'Array<string | null>'],
+            [pg_data_type_id_1.default._time, 'Array<string | null>'],
+            [pg_data_type_id_1.default._timestamp, 'Array<Date | null>'],
+            [pg_data_type_id_1.default._timestamptz, 'Array<Date | null>'],
+            [pg_data_type_id_1.default._timetz, 'Array<string | null>'],
+            [pg_data_type_id_1.default._uuid, 'Array<string | null>'],
+            [pg_data_type_id_1.default._varchar, 'Array<string | null>'],
+            [pg_data_type_id_1.default.bool, 'boolean'],
+            [pg_data_type_id_1.default.bytea, 'Buffer'],
+            [pg_data_type_id_1.default.circle, '{x: number, y: number, radius: number}'],
+            [pg_data_type_id_1.default.date, 'Date'],
+            [pg_data_type_id_1.default.float4, 'number'],
+            [pg_data_type_id_1.default.float8, 'number'],
+            [pg_data_type_id_1.default.int2, 'number'],
+            [pg_data_type_id_1.default.int4, 'number'],
+            [pg_data_type_id_1.default.int8, int8Mapping ?? 'number'],
+            [
+                pg_data_type_id_1.default.interval,
+                '{years: number,months: number,days: number,hours: number,minutes: number,seconds: number,milliseconds: number, toPostgres: () => string, toISO: () => string}',
+            ],
+            [pg_data_type_id_1.default.json, 'any'],
+            [pg_data_type_id_1.default.jsonb, 'any'],
+            [pg_data_type_id_1.default.oid, 'number'],
+            [pg_data_type_id_1.default.point, '{x: number, y: number}'],
+            [pg_data_type_id_1.default.timestamp, 'Date'],
+            [pg_data_type_id_1.default.timestamptz, 'Date'],
+        ]);
+        return DefaultTypeScriptMapping;
+    }
+})
 //# sourceMappingURL=DefaultTypeScriptMapping.js.map

package.json

{"pnpm":{"patchedDependencies":{"@databases/pg-schema-cli@4.3.1":"patches/@databases__pg-schema-cli@4.3.1.patch","@databases/pg-schema-print-types@4.4.1":"patches/@databases__pg-schema-print-types@4.4.1.patch"}}}