joist-utils 0.1.537 → 1.0.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.
@@ -1,20 +1,26 @@
1
1
  import { ConnectionConfig } from "pg";
2
- export interface ConnectionInfo {
3
- dbname: string;
4
- username: string;
5
- password: string;
6
- host: string;
7
- port: number;
8
- }
2
+ declare type DatabaseUrl = {
3
+ DATABASE_URL: string;
4
+ };
5
+ declare type DbSettings = {
6
+ DB_USER: string;
7
+ DB_PASSWORD: string;
8
+ DB_HOST: string;
9
+ DB_DATABASE: string;
10
+ DB_PORT: string;
11
+ };
12
+ export declare type ConnectionEnv = DatabaseUrl | DbSettings;
9
13
  /**
10
14
  * Returns the `ConnectionConfig` that joist will use to connect to pg.
11
15
  *
12
- * This is currently hard-coded to read the `DATABASE_CONNECTION_INFO` env variable.
16
+ * This reads environment variables, and can be either:
13
17
  *
18
+ * - A single `DATABASE_URL` variable
19
+ * - Multiple `DB_USER`, `DB_PASSWORD`, `DB_DATABASE`, `DB_HOST`, `DB_PORT` variables
14
20
  * The value can be either:
15
21
  *
16
- * - RDS-style JSON like `{"dbname":"...","host":"...",...}`
17
- * - connection-string-style like `postgres://host?...` as read by the `pg-connection-string` `parse` method
22
+ * Note that users using a library for typed / validated environment variables, i.e.
23
+ * ts-app-env, you can pass in a specific `env` variable.
18
24
  */
19
- export declare function newPgConnectionConfig(): ConnectionConfig;
20
- export declare function parsePgConnectionConfig(envVariable: string): ConnectionConfig;
25
+ export declare function newPgConnectionConfig(env?: ConnectionEnv): ConnectionConfig;
26
+ export {};
@@ -1,52 +1,46 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parsePgConnectionConfig = exports.newPgConnectionConfig = void 0;
3
+ exports.newPgConnectionConfig = void 0;
4
4
  const pg_connection_string_1 = require("pg-connection-string");
5
- const index_1 = require("./index");
6
- function readEnvVariable() {
7
- return process.env.DATABASE_CONNECTION_INFO || index_1.fail("DATABASE_CONNECTION_INFO environment variable is not set");
8
- }
9
- /** Reads the RDS-style connection information from `process.env`. */
10
- function parseAsRdsConnectionInfo(envVariable) {
11
- if (envVariable.startsWith("{")) {
12
- const { dbname: database, username: user, password, host, port } = JSON.parse(envVariable);
13
- return { database, user, password, host, port };
14
- }
15
- return undefined;
16
- }
17
5
  /**
18
6
  * Returns the `ConnectionConfig` that joist will use to connect to pg.
19
7
  *
20
- * This is currently hard-coded to read the `DATABASE_CONNECTION_INFO` env variable.
8
+ * This reads environment variables, and can be either:
21
9
  *
10
+ * - A single `DATABASE_URL` variable
11
+ * - Multiple `DB_USER`, `DB_PASSWORD`, `DB_DATABASE`, `DB_HOST`, `DB_PORT` variables
22
12
  * The value can be either:
23
13
  *
24
- * - RDS-style JSON like `{"dbname":"...","host":"...",...}`
25
- * - connection-string-style like `postgres://host?...` as read by the `pg-connection-string` `parse` method
14
+ * Note that users using a library for typed / validated environment variables, i.e.
15
+ * ts-app-env, you can pass in a specific `env` variable.
26
16
  */
27
- function newPgConnectionConfig() {
28
- return parsePgConnectionConfig(readEnvVariable());
29
- }
30
- exports.newPgConnectionConfig = newPgConnectionConfig;
31
- // exported for testing
32
- function parsePgConnectionConfig(envVariable) {
33
- const rdsConfig = parseAsRdsConnectionInfo(envVariable);
34
- if (rdsConfig) {
35
- return rdsConfig;
17
+ function newPgConnectionConfig(env) {
18
+ if (process.env.DATABASE_URL || (env && "DATABASE_URL" in env)) {
19
+ const url = process.env.DATABASE_URL ?? env.DATABASE_URL;
20
+ // It'd be great if `parse` returned ConnectionConfig directly
21
+ const options = (0, pg_connection_string_1.parse)(url);
22
+ const { database, port, host, user, password } = options;
23
+ return {
24
+ user,
25
+ password,
26
+ database: database ?? undefined,
27
+ host: host ?? undefined,
28
+ port: port ? Number(port) : undefined,
29
+ };
30
+ }
31
+ else if (process.env.DB_DATABASE || (env && "DB_DATABASE" in env)) {
32
+ const e = process.env.DB_DATABASE ? process.env : env;
33
+ return {
34
+ user: e.DB_USER,
35
+ password: e.DB_PASSWORD,
36
+ database: e.DB_DATABASE,
37
+ host: e.DB_HOST,
38
+ port: e.DB_PORT ? Number(e.DB_PORT) : undefined,
39
+ };
40
+ }
41
+ else {
42
+ throw new Error("No DATABASE_URL or DB_DATABASE/etc. environment variable found");
36
43
  }
37
- const opts = pg_connection_string_1.parse(envVariable);
38
- return {
39
- ...opts,
40
- // Drop `| null` from the parse return type
41
- database: opts.database || undefined,
42
- host: opts.host || undefined,
43
- port: opts.port !== undefined && opts.port !== null ? Number(opts.port) : undefined,
44
- ssl: typeof opts.ssl === "boolean"
45
- ? opts.ssl
46
- : typeof opts.ssl === "string"
47
- ? index_1.fail("parsing string ssl not implemented")
48
- : undefined,
49
- };
50
44
  }
51
- exports.parsePgConnectionConfig = parsePgConnectionConfig;
45
+ exports.newPgConnectionConfig = newPgConnectionConfig;
52
46
  //# sourceMappingURL=connection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":";;;AACA,+DAA6C;AAC7C,mCAA+B;AAW/B,SAAS,eAAe;IACtB,OAAO,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,YAAI,CAAC,0DAA0D,CAAC,CAAC;AAClH,CAAC;AAED,qEAAqE;AACrE,SAAS,wBAAwB,CAAC,WAAmB;IACnD,IAAI,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;QAC/B,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAmB,CAAC;QAC7G,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;KACjD;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,qBAAqB;IACnC,OAAO,uBAAuB,CAAC,eAAe,EAAE,CAAC,CAAC;AACpD,CAAC;AAFD,sDAEC;AAED,uBAAuB;AACvB,SAAgB,uBAAuB,CAAC,WAAmB;IACzD,MAAM,SAAS,GAAG,wBAAwB,CAAC,WAAW,CAAC,CAAC;IACxD,IAAI,SAAS,EAAE;QACb,OAAO,SAAS,CAAC;KAClB;IACD,MAAM,IAAI,GAAG,4BAAK,CAAC,WAAW,CAAC,CAAC;IAChC,OAAO;QACL,GAAG,IAAI;QACP,2CAA2C;QAC3C,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,SAAS;QACpC,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,SAAS;QAC5B,IAAI,EAAE,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;QACnF,GAAG,EACD,OAAO,IAAI,CAAC,GAAG,KAAK,SAAS;YAC3B,CAAC,CAAC,IAAI,CAAC,GAAG;YACV,CAAC,CAAC,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ;gBAC9B,CAAC,CAAC,YAAI,CAAC,oCAAoC,CAAC;gBAC5C,CAAC,CAAC,SAAS;KAChB,CAAC;AACJ,CAAC;AAnBD,0DAmBC"}
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":";;;AACA,+DAA6C;AAO7C;;;;;;;;;;;GAWG;AACH,SAAgB,qBAAqB,CAAC,GAAmB;IACvD,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,GAAG,IAAI,cAAc,IAAI,GAAG,CAAC,EAAE;QAC9D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAK,GAAmB,CAAC,YAAY,CAAC;QAC1E,8DAA8D;QAC9D,MAAM,OAAO,GAAG,IAAA,4BAAK,EAAC,GAAG,CAAC,CAAC;QAC3B,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QACzD,OAAO;YACL,IAAI;YACJ,QAAQ;YACR,QAAQ,EAAE,QAAQ,IAAI,SAAS;YAC/B,IAAI,EAAE,IAAI,IAAI,SAAS;YACvB,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;SACtC,CAAC;KACH;SAAM,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,GAAG,IAAI,aAAa,IAAI,GAAG,CAAC,EAAE;QACnE,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAE,GAAkB,CAAC;QACtE,OAAO;YACL,IAAI,EAAE,CAAC,CAAC,OAAO;YACf,QAAQ,EAAE,CAAC,CAAC,WAAW;YACvB,QAAQ,EAAE,CAAC,CAAC,WAAW;YACvB,IAAI,EAAE,CAAC,CAAC,OAAO;YACf,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS;SAChD,CAAC;KACH;SAAM;QACL,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;KACnF;AACH,CAAC;AAzBD,sDAyBC"}
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const connection_1 = require("./connection");
4
4
  describe("connection", () => {
5
- it("should parse RDS-style json", () => {
6
- const info = connection_1.parsePgConnectionConfig(`{"host":"db","port":5432,"username":"joist","password":"local","dbname":"joist"}`);
5
+ it("should parse single DATABASE_URL", () => {
6
+ const info = (0, connection_1.newPgConnectionConfig)({ DATABASE_URL: "postgres://joist:local@db:5432/joist" });
7
7
  expect(info).toEqual({
8
8
  database: "joist",
9
9
  host: "db",
@@ -12,8 +12,14 @@ describe("connection", () => {
12
12
  user: "joist",
13
13
  });
14
14
  });
15
- it("should parse connection-string-style", () => {
16
- const info = connection_1.parsePgConnectionConfig("postgres://joist:local@db:5432/joist");
15
+ it("should parse multiple DB variables", () => {
16
+ const info = (0, connection_1.newPgConnectionConfig)({
17
+ DB_USER: "joist",
18
+ DB_PASSWORD: "local",
19
+ DB_DATABASE: "joist",
20
+ DB_HOST: "db",
21
+ DB_PORT: "5432",
22
+ });
17
23
  expect(info).toEqual({
18
24
  database: "joist",
19
25
  host: "db",
@@ -1 +1 @@
1
- {"version":3,"file":"connection.test.js","sourceRoot":"","sources":["../src/connection.test.ts"],"names":[],"mappings":";;AAAA,6CAAuD;AAEvD,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,EAAE,CAAC,6BAA6B,EAAE,GAAG,EAAE;QACrC,MAAM,IAAI,GAAG,oCAAuB,CAClC,kFAAkF,CACnF,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;YACnB,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,OAAO;SACd,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,IAAI,GAAG,oCAAuB,CAAC,sCAAsC,CAAC,CAAC;QAC7E,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;YACnB,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,IAAI;YACV,GAAG,EAAE,SAAS;YACd,IAAI,EAAE,OAAO;SACd,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"connection.test.js","sourceRoot":"","sources":["../src/connection.test.ts"],"names":[],"mappings":";;AAAA,6CAAqD;AAErD,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,IAAI,GAAG,IAAA,kCAAqB,EAAC,EAAE,YAAY,EAAE,sCAAsC,EAAE,CAAC,CAAC;QAC7F,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;YACnB,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,IAAI;YACV,IAAI,EAAE,OAAO;SACd,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,IAAI,GAAG,IAAA,kCAAqB,EAAC;YACjC,OAAO,EAAE,OAAO;YAChB,WAAW,EAAE,OAAO;YACpB,WAAW,EAAE,OAAO;YACpB,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,MAAM;SAChB,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC;YACnB,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,IAAI;YACV,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,IAAI;YACV,GAAG,EAAE,SAAS;YACd,IAAI,EAAE,OAAO;SACd,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/build/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.groupBy = exports.fail = void 0;
3
+ exports.groupBy = exports.fail = exports.newPgConnectionConfig = void 0;
4
4
  var connection_1 = require("./connection");
5
5
  Object.defineProperty(exports, "newPgConnectionConfig", { enumerable: true, get: function () { return connection_1.newPgConnectionConfig; } });
6
6
  function fail(message) {
package/package.json CHANGED
@@ -1,21 +1,29 @@
1
1
  {
2
2
  "name": "joist-utils",
3
- "version": "0.1.537",
3
+ "version": "1.0.0",
4
4
  "license": "MIT",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
7
+ "files": [
8
+ "build"
9
+ ],
7
10
  "dependencies": {
8
- "pg": "^8.3.0",
11
+ "pg": "^8.7.1",
9
12
  "pg-connection-string": "^2.2.3"
10
13
  },
14
+ "scripts": {
15
+ "format": "prettier --write '{schema,migrations,src}/**/*.{ts,js,tsx,jsx,graphql}'"
16
+ },
11
17
  "devDependencies": {
12
- "@types/jest": "^25.2.1",
13
- "@types/node": "^13.13.4",
14
- "jest": "^25.5.3",
15
- "prettier": "^2.0.5",
16
- "ts-jest": "^25.4.0",
17
- "ts-node-dev": "^1.0.0-pre.44",
18
- "tsconfig-paths": "^3.9.0",
19
- "typescript": "^3.9.5"
18
+ "@swc/core": "^1.2.124",
19
+ "@swc/jest": "^0.2.16",
20
+ "@types/jest": "^26.0.24",
21
+ "@types/node": "^16.4.10",
22
+ "jest": "^27.0.6",
23
+ "prettier": "^2.5.1",
24
+ "prettier-plugin-organize-imports": "^2.3.4",
25
+ "ts-node-dev": "^1.1.8",
26
+ "tsconfig-paths": "^3.10.1",
27
+ "typescript": "^4.5.2"
20
28
  }
21
29
  }
package/jest.config.js DELETED
@@ -1,10 +0,0 @@
1
- module.exports = {
2
- preset: "ts-jest",
3
- moduleNameMapper: {
4
- "^@src/(.*)": "<rootDir>/src/$1",
5
- },
6
- // globalSetup: "<rootDir>/src/setupTestEnv.js",
7
- testMatch: ["<rootDir>/src/**/*.test.(ts|tsx)"],
8
- testEnvironment: "node",
9
- maxConcurrency: 1,
10
- };
package/package.json.bak DELETED
@@ -1,21 +0,0 @@
1
- {
2
- "name": "joist-utils",
3
- "version": "0.1.0-bump",
4
- "license": "MIT",
5
- "main": "build/index.js",
6
- "types": "build/index.d.ts",
7
- "dependencies": {
8
- "pg": "^8.3.0",
9
- "pg-connection-string": "^2.2.3"
10
- },
11
- "devDependencies": {
12
- "@types/jest": "^25.2.1",
13
- "@types/node": "^13.13.4",
14
- "jest": "^25.5.3",
15
- "prettier": "^2.0.5",
16
- "ts-jest": "^25.4.0",
17
- "ts-node-dev": "^1.0.0-pre.44",
18
- "tsconfig-paths": "^3.9.0",
19
- "typescript": "^3.9.5"
20
- }
21
- }
@@ -1,28 +0,0 @@
1
- import { parsePgConnectionConfig } from "./connection";
2
-
3
- describe("connection", () => {
4
- it("should parse RDS-style json", () => {
5
- const info = parsePgConnectionConfig(
6
- `{"host":"db","port":5432,"username":"joist","password":"local","dbname":"joist"}`,
7
- );
8
- expect(info).toEqual({
9
- database: "joist",
10
- host: "db",
11
- password: "local",
12
- port: 5432,
13
- user: "joist",
14
- });
15
- });
16
-
17
- it("should parse connection-string-style", () => {
18
- const info = parsePgConnectionConfig("postgres://joist:local@db:5432/joist");
19
- expect(info).toEqual({
20
- database: "joist",
21
- host: "db",
22
- password: "local",
23
- port: 5432,
24
- ssl: undefined,
25
- user: "joist",
26
- });
27
- });
28
- });
package/src/connection.ts DELETED
@@ -1,61 +0,0 @@
1
- import { ConnectionConfig } from "pg";
2
- import { parse } from "pg-connection-string";
3
- import { fail } from "./index";
4
-
5
- // Matches the AWS RDS/ECS JSON config that is stored/auto-created in ECS. */
6
- export interface ConnectionInfo {
7
- dbname: string;
8
- username: string;
9
- password: string;
10
- host: string;
11
- port: number;
12
- }
13
-
14
- function readEnvVariable(): string {
15
- return process.env.DATABASE_CONNECTION_INFO || fail("DATABASE_CONNECTION_INFO environment variable is not set");
16
- }
17
-
18
- /** Reads the RDS-style connection information from `process.env`. */
19
- function parseAsRdsConnectionInfo(envVariable: string): ConnectionConfig | undefined {
20
- if (envVariable.startsWith("{")) {
21
- const { dbname: database, username: user, password, host, port } = JSON.parse(envVariable) as ConnectionInfo;
22
- return { database, user, password, host, port };
23
- }
24
- return undefined;
25
- }
26
-
27
- /**
28
- * Returns the `ConnectionConfig` that joist will use to connect to pg.
29
- *
30
- * This is currently hard-coded to read the `DATABASE_CONNECTION_INFO` env variable.
31
- *
32
- * The value can be either:
33
- *
34
- * - RDS-style JSON like `{"dbname":"...","host":"...",...}`
35
- * - connection-string-style like `postgres://host?...` as read by the `pg-connection-string` `parse` method
36
- */
37
- export function newPgConnectionConfig(): ConnectionConfig {
38
- return parsePgConnectionConfig(readEnvVariable());
39
- }
40
-
41
- // exported for testing
42
- export function parsePgConnectionConfig(envVariable: string): ConnectionConfig {
43
- const rdsConfig = parseAsRdsConnectionInfo(envVariable);
44
- if (rdsConfig) {
45
- return rdsConfig;
46
- }
47
- const opts = parse(envVariable);
48
- return {
49
- ...opts,
50
- // Drop `| null` from the parse return type
51
- database: opts.database || undefined,
52
- host: opts.host || undefined,
53
- port: opts.port !== undefined && opts.port !== null ? Number(opts.port) : undefined,
54
- ssl:
55
- typeof opts.ssl === "boolean"
56
- ? opts.ssl
57
- : typeof opts.ssl === "string"
58
- ? fail("parsing string ssl not implemented")
59
- : undefined,
60
- };
61
- }
package/src/index.ts DELETED
@@ -1,17 +0,0 @@
1
- export { newPgConnectionConfig } from "./connection";
2
-
3
- export function fail(message?: string): never {
4
- throw new Error(message || "Failed");
5
- }
6
-
7
- export function groupBy<T, Y = T>(list: T[], fn: (x: T) => string, valueFn?: (x: T) => Y): Record<string, Y[]> {
8
- const result: Record<string, Y[]> = {};
9
- list.forEach((o) => {
10
- const group = fn(o);
11
- if (result[group] === undefined) {
12
- result[group] = [];
13
- }
14
- result[group].push(valueFn === undefined ? ((o as any) as Y) : valueFn(o));
15
- });
16
- return result;
17
- }
package/tsconfig.json DELETED
@@ -1,17 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "es2019",
4
- "module": "commonjs",
5
- "lib": ["es2019"],
6
- "strict": true,
7
- "noImplicitReturns": true,
8
- "types": ["jest", "node"],
9
- "esModuleInterop": true,
10
- "skipLibCheck": true,
11
- "composite": true,
12
- "sourceMap": true,
13
- "outDir": "./build",
14
- "rootDir": "./src",
15
- "baseUrl": "./src"
16
- }
17
- }