Skip to content

Commit 9187ed0

Browse files
committed
Initial setup
0 parents  commit 9187ed0

17 files changed

+397
-0
lines changed

.circleci/config.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
version: 2.1
2+
3+
orbs:
4+
node: circleci/[email protected]
5+
6+
parameters:
7+
node_version:
8+
type: string
9+
default: '16.15.0'
10+
11+
commands:
12+
install_deps:
13+
steps:
14+
- node/install-packages:
15+
pkg-manager: yarn
16+
cache-version: v1-all
17+
cache-only-lockfile: true
18+
app-dir: ~/repo
19+
override-ci-command: yarn install --pure-lockfile --no-progress
20+
- run: sudo apt-get -q update && sudo apt-get -y install openjdk-17-jdk
21+
22+
jobs:
23+
build:
24+
executor:
25+
name: node/default
26+
tag: << pipeline.parameters.node_version >>
27+
working_directory: ~/repo
28+
steps:
29+
- checkout
30+
- install_deps
31+
- run: yarn test
32+
- run: yarn type-check
33+
- run: yarn lint:ci

.editorconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
end_of_line = lf
5+
charset = utf-8
6+
trim_trailing_whitespace = true
7+
insert_final_newline = true
8+
indent_style = space
9+
indent_size = 2

.eslintignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
coverage/
2+
lib/
3+
renovate.json
4+
tsconfig.json
5+
package.json

.eslintrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"root": true,
3+
"extends": [
4+
"@shelf/eslint-config/typescript"
5+
],
6+
"rules": {
7+
"@typescript-eslint/no-non-null-assertion": "off"
8+
}
9+
}

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.idea/
2+
.DS_Store
3+
node_modules/
4+
yarn.lock
5+
lib/
6+
!.husky/_/husky.sh
7+
!.husky/_/husky.sh

.husky/_/husky.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/bin/sh
2+
if [ -z "$husky_skip_init" ]; then
3+
debug () {
4+
if [ "$HUSKY_DEBUG" = "1" ]; then
5+
echo "husky (debug) - $1"
6+
fi
7+
}
8+
9+
readonly hook_name="$(basename "$0")"
10+
debug "starting $hook_name..."
11+
12+
if [ "$HUSKY" = "0" ]; then
13+
debug "HUSKY env variable is set to 0, skipping hook"
14+
exit 0
15+
fi
16+
17+
if [ -f ~/.huskyrc ]; then
18+
debug "sourcing ~/.huskyrc"
19+
. ~/.huskyrc
20+
fi
21+
22+
export readonly husky_skip_init=1
23+
sh -e "$0" "$@"
24+
exitCode="$?"
25+
26+
if [ $exitCode != 0 ]; then
27+
echo "husky - $hook_name hook exited with code $exitCode (error)"
28+
fi
29+
30+
exit $exitCode
31+
fi

.husky/post-commit

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/sh
2+
. "$(dirname "$0")/_/husky.sh"
3+
git update-index --again

.husky/pre-commit

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#!/bin/sh
2+
. "$(dirname "$0")/_/husky.sh"
3+
yarn lint-staged

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package-lock=false

README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# postgres-local [![CircleCI](https://circleci.com/gh/shelfio/postgres-local/tree/master.svg?style=svg)](https://circleci.com/gh/shelfio/postgres-local/tree/master) ![](https://img.shields.io/badge/code_style-prettier-ff69b4.svg) [![npm (scoped)](https://img.shields.io/npm/v/@shelf/postgres-local.svg)](https://www.npmjs.com/package/@shelf/postgres-local)
2+
3+
> Run any version of Postgres locally
4+
5+
## Usage
6+
7+
### 0. Install
8+
9+
```
10+
$ yarn add @shelf/postgres-local --dev
11+
```
12+
13+
### 1. Start Postgres - TO BE DONE
14+
15+
```js
16+
import {start} from '@shelf/postgres-local';
17+
18+
await start({});
19+
```
20+
21+
### 2. Stop Postgres - TO BE DONE
22+
23+
```js
24+
import {stop} from '@shelf/postgres-local';
25+
26+
stop();
27+
```
28+
29+
## Publish
30+
31+
```sh
32+
$ git checkout master
33+
$ yarn version
34+
$ yarn publish
35+
$ git push origin master --tags
36+
```
37+
38+
## License
39+
40+
MIT © [Shelf](https://shelf.io)

licence

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
MIT License
2+
3+
Copyright (c) Gemshelf Inc. (shelf.io)
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6+
7+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8+
9+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

package.json

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
{
2+
"name": "@shelf/postgres-local",
3+
"version": "1.0.0",
4+
"description": "Run 14 version of Postgres locally",
5+
"keywords": [
6+
"postgres",
7+
"postgres local"
8+
],
9+
"homepage": "https://github.com/shelfio/postgres-local#readme",
10+
"bugs": {
11+
"url": "https://github.com/shelfio/postgres-local/issues"
12+
},
13+
"repository": {
14+
"type": "git",
15+
"url": "git+https://github.com/shelfio/postgres-local.git"
16+
},
17+
"license": "MIT",
18+
"author": "Dmytro Harazdovskyi",
19+
"files": [
20+
"lib"
21+
],
22+
"main": "lib/index.js",
23+
"types": "./lib/index.d.ts",
24+
"scripts": {
25+
"build": "rm -rf lib/ && yarn build:types && yarn build:code",
26+
"build:code": "babel src --out-dir lib --ignore '**/*.test.ts' --extensions '.ts' && find ./lib -name '*.test.d.ts' -delete",
27+
"build:types": "tsc --emitDeclarationOnly --declaration --isolatedModules false --declarationDir lib",
28+
"coverage": "yarn test --coverage",
29+
"lint": "eslint . --ext .js,.ts,.json --fix",
30+
"lint:ci": "eslint . --ext .js,.ts,.json",
31+
"prepack": "yarn build",
32+
"test": "jest src --runInBand",
33+
"type-check": "tsc --noEmit",
34+
"type-check:watch": "npm run type-check -- --watch"
35+
},
36+
"lint-staged": {
37+
"*.{html,md,yml}": [
38+
"prettier --write"
39+
],
40+
"*.{js,ts,json}": [
41+
"eslint --fix"
42+
]
43+
},
44+
"babel": {
45+
"extends": "@shelf/babel-config/backend"
46+
},
47+
"prettier": "@shelf/prettier-config",
48+
"dependencies": {
49+
"cwd": "0.10.0",
50+
"debug": "4.3.4",
51+
"postgres": "3.3.2"
52+
},
53+
"devDependencies": {
54+
"@babel/cli": "7.19.3",
55+
"@babel/core": "7.20.2",
56+
"@shelf/babel-config": "1.2.0",
57+
"@shelf/eslint-config": "2.16.0",
58+
"@shelf/prettier-config": "1.0.0",
59+
"@shelf/tsconfig": "0.0.9",
60+
"@types/cwd": "0.10.0",
61+
"@types/debug": "4.1.7",
62+
"@types/jest": "29.2.3",
63+
"@types/js-yaml": "4.0.5",
64+
"@types/node": "16",
65+
"babel-jest": "29.3.1",
66+
"eslint": "8.28.0",
67+
"husky": "8.0.2",
68+
"jest": "29.3.1",
69+
"lint-staged": "13.0.3",
70+
"prettier": "2.7.1",
71+
"typescript": "4.9.3"
72+
},
73+
"engines": {
74+
"node": ">=16"
75+
},
76+
"publishConfig": {
77+
"access": "public"
78+
}
79+
}

renovate.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"extends": ["config:base"],
3+
"labels": ["dependencies", "backend"],
4+
"ignoreDeps": [
5+
"cimg/node",
6+
"@types/node"
7+
]
8+
}

src/index.test.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
jest.setTimeout(10 * 60 * 1000);
2+
import cwd from 'cwd';
3+
import postgres from 'postgres';
4+
import {start, stop} from '.';
5+
6+
describe('#postgres', () => {
7+
it('should start postgres@14 locally', async () => {
8+
const returnedUrl = await start({seedPath: `${cwd()}/src/schema.sql`});
9+
10+
const sql = postgres('postgres://localhost:5432/postgres');
11+
12+
const data = await sql`
13+
SELECT attname, format_type(atttypid, atttypmod)
14+
FROM pg_catalog.pg_attribute
15+
WHERE attrelid = 'test.model1'::regclass
16+
AND attnum > 0
17+
AND NOT attisdropped;
18+
`;
19+
20+
expect(data).toEqual([
21+
{
22+
attname: 'id',
23+
format_type: 'character varying(36)',
24+
},
25+
{
26+
attname: 'type',
27+
format_type: 'text',
28+
},
29+
{
30+
attname: 'text',
31+
format_type: 'text',
32+
},
33+
{
34+
attname: 'vector',
35+
format_type: 'double precision[]',
36+
},
37+
{
38+
attname: 'json',
39+
format_type: 'jsonb',
40+
},
41+
{
42+
attname: 'updated_at',
43+
format_type: 'timestamp without time zone',
44+
},
45+
{
46+
attname: 'somebool',
47+
format_type: 'boolean',
48+
},
49+
]);
50+
51+
expect(returnedUrl).toEqual('postgres://localhost:5432/postgres');
52+
});
53+
54+
it('should stop postgres@14 locally', async () => {
55+
await stop();
56+
try {
57+
const sql = postgres('postgres://localhost:5432/postgres');
58+
59+
await sql`create schema supertest`;
60+
} catch (e) {
61+
// @ts-ignore
62+
expect(e.name).toEqual('Error');
63+
}
64+
});
65+
});

src/index.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import getDebug from 'debug';
2+
import {exec} from 'child_process';
3+
import postgres from 'postgres';
4+
import {promisify} from 'util';
5+
6+
const asyncExec = promisify(exec);
7+
import cwd from 'cwd';
8+
import {platform} from 'os';
9+
10+
const debug = getDebug('postgres-local');
11+
const FILEPATH_PREFIX = `${cwd()}/node_modules/.cache/@shelf/postgres-local`;
12+
13+
type StartESOptions = {
14+
seedPath?: string;
15+
version?: string;
16+
};
17+
18+
export async function start(options: StartESOptions): Promise<string> {
19+
const {seedPath, version = '14'} = options;
20+
21+
const url = 'postgres://localhost:5432/postgres';
22+
23+
try {
24+
await asyncExec(`
25+
${getInstallationScript(version)}
26+
mkdir ${FILEPATH_PREFIX}/data;
27+
initdb -D ${FILEPATH_PREFIX}/data;
28+
pg_ctl -D ${FILEPATH_PREFIX}/data -l logfile start;
29+
`);
30+
31+
debug('Connecting to postgres...');
32+
const sql = postgres(url);
33+
debug('Postgres available!');
34+
process.env.PSQL = url;
35+
36+
if (seedPath?.length) {
37+
debug('Found seed file, seeding...');
38+
await sql.file(seedPath);
39+
debug('Seed done available!');
40+
}
41+
42+
return url;
43+
} catch (e) {
44+
console.error(e);
45+
throw e;
46+
}
47+
}
48+
49+
export async function stop(): Promise<{stdout: string; stderr: string}> {
50+
return asyncExec(`
51+
pg_ctl stop -D ${FILEPATH_PREFIX}/data
52+
rm -rf ${FILEPATH_PREFIX}
53+
`);
54+
}
55+
56+
export function getInstallationScript(version: string): string {
57+
switch (platform()) {
58+
case 'darwin': {
59+
return `brew install postgresql@${version}`;
60+
}
61+
case 'win32': {
62+
throw new Error('Unsupported OS, try run on OS X or Linux');
63+
}
64+
default: {
65+
return `
66+
apt-get update
67+
apt-get install -y postgresql-${version}
68+
`;
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)