Skip to content

Commit 4a559fb

Browse files
committed
Import /Users/zhizhen/Projects/cosmology-tech/src/agents/pg-many-to-many:master into constructive/graphile/graphile-many-to-many/
2 parents 99c9b11 + dace069 commit 4a559fb

77 files changed

Lines changed: 14490 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module.exports = {
2+
env: {
3+
node: true,
4+
es6: true,
5+
"jest/globals": true,
6+
},
7+
parserOptions: {
8+
ecmaVersion: 9,
9+
},
10+
plugins: ["jest"],
11+
extends: [
12+
"eslint:recommended",
13+
"plugin:jest/recommended",
14+
"plugin:prettier/recommended",
15+
],
16+
rules: {
17+
"jest/expect-expect": ["off"],
18+
},
19+
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* text=auto
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
name: CI
2+
3+
on: push
4+
5+
jobs:
6+
lint:
7+
runs-on: ubuntu-latest
8+
9+
env:
10+
TERM: xterm
11+
FORCE_COLOR: 1
12+
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v3
16+
17+
- name: Use Node.js 18
18+
uses: actions/setup-node@v3
19+
with:
20+
node-version: 18
21+
22+
- name: Install
23+
run: yarn --immutable --ignore-engines
24+
25+
- name: Check Code Format
26+
run: yarn format:check
27+
28+
- name: Lint Code
29+
run: yarn lint
30+
31+
test:
32+
runs-on: ubuntu-latest
33+
34+
env:
35+
CI: true
36+
PGVERSION: ${{ matrix.postgres-version}}
37+
TEST_DATABASE_URL: postgres://postgres:postgres@127.0.0.1:5432/graphile_test
38+
TERM: xterm
39+
FORCE_COLOR: 1
40+
41+
strategy:
42+
fail-fast: false
43+
matrix:
44+
postgres-version:
45+
- 11
46+
- 12
47+
- 13
48+
- 14
49+
- 15
50+
node-version:
51+
- 14
52+
- 16
53+
- 18
54+
55+
name: test (node:${{ matrix.node-version }}, postgres:${{ matrix.postgres-version }})
56+
57+
services:
58+
postgres:
59+
image: postgres:${{ matrix.postgres-version }}
60+
env:
61+
POSTGRES_USER: postgres
62+
POSTGRES_PASSWORD: postgres
63+
POSTGRES_DB: postgres
64+
ports:
65+
- "0.0.0.0:5432:5432"
66+
# needed because the postgres container does not provide a healthcheck
67+
options:
68+
--health-cmd pg_isready --health-interval 10s --health-timeout 5s
69+
--health-retries 5 --name postgres
70+
71+
steps:
72+
- name: Checkout
73+
uses: actions/checkout@v3
74+
75+
- name: Use Node.js ${{ matrix.node-version }}
76+
uses: actions/setup-node@v3
77+
with:
78+
node-version: ${{ matrix.node-version }}
79+
80+
- name: Configure PostgreSQL
81+
run: |
82+
cat .github/workflows/ci/docker-entrypoint-initdb.d/010-setup.sh | docker exec -i postgres bash
83+
84+
- name: Install
85+
run: yarn --immutable --ignore-engines
86+
87+
- name: Test
88+
run: yarn test
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env bash
2+
set -e
3+
4+
createdb graphile_test -U postgres
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
.env
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"trailingComma": "es5"
3+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2018 Graphile Contrib
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
# @graphile-contrib/pg-many-to-many
2+
3+
[![Package on npm](https://img.shields.io/npm/v/@graphile-contrib/pg-many-to-many.svg)](https://www.npmjs.com/package/@graphile-contrib/pg-many-to-many)
4+
5+
This Graphile Engine plugin adds connection fields for many-to-many relations.
6+
7+
> Requires `postgraphile@^4.5.0` or `graphile-build-pg@^4.5.0`
8+
9+
Example:
10+
11+
```graphql
12+
{
13+
allPeople {
14+
nodes {
15+
personName
16+
# 👇 many-to-many relation
17+
teamsByTeamMemberPersonIdAndTeamId {
18+
nodes {
19+
teamName
20+
}
21+
}
22+
}
23+
}
24+
}
25+
```
26+
27+
## Usage
28+
29+
Append this plugin and the additional fields will be added to your schema.
30+
31+
### CLI
32+
33+
```bash
34+
yarn add postgraphile
35+
yarn add @graphile-contrib/pg-many-to-many
36+
npx postgraphile --append-plugins @graphile-contrib/pg-many-to-many
37+
```
38+
39+
### Library
40+
41+
```js
42+
const express = require("express");
43+
const { postgraphile } = require("postgraphile");
44+
const PgManyToManyPlugin = require("@graphile-contrib/pg-many-to-many");
45+
46+
const app = express();
47+
48+
app.use(
49+
postgraphile(process.env.DATABASE_URL, "app_public", {
50+
appendPlugins: [PgManyToManyPlugin],
51+
graphiql: true,
52+
})
53+
);
54+
55+
app.listen(5000);
56+
```
57+
58+
## Excluding Fields
59+
60+
To exclude certain many-to-many fields from appearing in your GraphQL schema, you can use `@omit manyToMany` [smart comments](https://www.graphile.org/postgraphile/smart-comments/) on constraints and tables.
61+
62+
Here is an example of using a smart comment on a constraint:
63+
64+
```
65+
create table p.foo (
66+
id serial primary key,
67+
name text not null
68+
);
69+
70+
create table p.bar (
71+
id serial primary key,
72+
name text not null
73+
);
74+
75+
create table p.qux (
76+
foo_id int constraint qux_foo_id_fkey references p.foo (id),
77+
bar_id int constraint qux_bar_id_fkey references p.bar (id),
78+
primary key (foo_id, bar_id)
79+
);
80+
81+
-- `Foo` and `Bar` would normally have `barsBy...` and `foosBy...` fields,
82+
-- but this smart comment causes the constraint between `qux` and `bar`
83+
-- to be ignored, preventing the fields from being generated.
84+
comment on constraint qux_bar_id_fkey on p.qux is E'@omit manyToMany';
85+
```
86+
87+
Here is an example of using a smart comment on a table:
88+
89+
```
90+
create table p.foo (
91+
id serial primary key,
92+
name text not null
93+
);
94+
95+
create table p.bar (
96+
id serial primary key,
97+
name text not null
98+
);
99+
100+
create table p.corge (
101+
foo_id int constraint corge_foo_id_fkey references p.foo (id),
102+
bar_id int constraint corge_bar_id_fkey references p.bar (id),
103+
primary key (foo_id, bar_id)
104+
);
105+
106+
-- `Foo` and `Bar` would normally have `barsBy...` and `foosBy...` fields,
107+
-- but this smart comment causes `corge` to be excluded from consideration
108+
-- as a junction table, preventing the fields from being generated.
109+
comment on table p.corge is E'@omit manyToMany';
110+
```
111+
112+
## Inflection
113+
114+
To avoid naming conflicts, this plugin uses a verbose naming convention (e.g. `teamsByTeamMemberTeamId`), similar to how related fields are named by default in PostGraphile v4. You can override this by writing a custom inflector plugin or by using smart comments in your SQL schema.
115+
116+
### Inflector Plugin
117+
118+
Writing a custom inflector plugin gives you full control over the GraphQL field names. Here is an example plugin that shortens the field names to just the table name (producing e.g. `teams`):
119+
120+
> :warning: Warning: Simplifying the field names as shown below will lead to field name conflicts if your junction table has multiple foreign keys referencing the same table. You will need to customize the inflector function to resolve the conflicts.
121+
122+
```js
123+
const { makeAddInflectorsPlugin } = require("graphile-utils");
124+
125+
module.exports = makeAddInflectorsPlugin(
126+
{
127+
manyToManyRelationByKeys(
128+
_leftKeyAttributes,
129+
_junctionLeftKeyAttributes,
130+
_junctionRightKeyAttributes,
131+
_rightKeyAttributes,
132+
_junctionTable,
133+
rightTable,
134+
_junctionLeftConstraint,
135+
junctionRightConstraint
136+
) {
137+
if (junctionRightConstraint.tags.manyToManyFieldName) {
138+
return junctionRightConstraint.tags.manyToManyFieldName;
139+
}
140+
return this.camelCase(
141+
`${this.pluralize(this._singularizedTableName(rightTable))}`
142+
);
143+
},
144+
manyToManyRelationByKeysSimple(
145+
_leftKeyAttributes,
146+
_junctionLeftKeyAttributes,
147+
_junctionRightKeyAttributes,
148+
_rightKeyAttributes,
149+
_junctionTable,
150+
rightTable,
151+
_junctionLeftConstraint,
152+
junctionRightConstraint
153+
) {
154+
if (junctionRightConstraint.tags.manyToManySimpleFieldName) {
155+
return junctionRightConstraint.tags.manyToManySimpleFieldName;
156+
}
157+
return this.camelCase(
158+
`${this.pluralize(this._singularizedTableName(rightTable))}-list`
159+
);
160+
},
161+
},
162+
true // Passing true here allows the plugin to overwrite existing inflectors.
163+
);
164+
```
165+
166+
For more information on custom inflector plugins, see the [makeAddInflectorsPlugin documentation](https://www.graphile.org/postgraphile/make-add-inflectors-plugin/).
167+
168+
### Smart Comments
169+
170+
The `@manyToManyFieldName` and `@manyToManySimpleFieldName` smart comments allow you to override the field names generated by this plugin.
171+
172+
For example, to rename the Connection field from `teamsByTeamMemberTeamId` to `teams`:
173+
174+
```sql
175+
comment on constraint membership_team_id_fkey on p.membership is E'@manyToManyFieldName teams';
176+
```
177+
178+
To rename both the Connection and simple collection fields (assuming simple collections are enabled):
179+
180+
```sql
181+
comment on constraint membership_team_id_fkey on p.membership is E'@manyToManyFieldName teams\n@manyToManySimpleFieldName teamsList';
182+
```

0 commit comments

Comments
 (0)