Skip to content

Commit 9bb2e4f

Browse files
committed
Merge remote-tracking branch 'origin/main' into brad/fetch-client
2 parents 66f7f00 + 3634391 commit 9bb2e4f

File tree

106 files changed

+10417
-6710
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+10417
-6710
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@ jobs:
88
steps:
99
- uses: actions/checkout@v4
1010

11-
- uses: purescript-contrib/setup-purescript@main
11+
- uses: actions/setup-node@v6
1212
with:
13-
purescript: 0.15.15
14-
psa: 0.8.2
15-
spago: unstable
13+
node-version: 22
1614

1715
- name: Cache PureScript dependencies
1816
uses: actions/cache@v4
@@ -23,7 +21,7 @@ jobs:
2321
# have changed. If you do not want to cache compiled output, remove
2422
# the `output` path.
2523
with:
26-
key: k1-${{ runner.os }}-spago-${{ hashFiles('**/*.lock') }}
24+
key: k2-${{ runner.os }}-spago-${{ hashFiles('**/*.lock') }}
2725
path: |
2826
.spago
2927
output
@@ -56,9 +54,10 @@ jobs:
5654
examples/13-error-boundaries/.spago
5755
examples/13-error-boundaries/output
5856
59-
- run: spago build
6057
- run: npm i
58+
- run: npm exec spago build
6159
- run: npm run bundle
60+
6261
- run: npm t
6362

6463
- name: Run Example Tests

.github/workflows/reviewdog.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: Reviewdog
2+
3+
on: pull_request
4+
5+
jobs:
6+
prettier:
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/checkout@v4
10+
11+
- uses: EPMatt/reviewdog-action-prettier@v1
12+
with:
13+
github_token: ${{ secrets.github_token }}
14+
reporter: github-pr-review
15+
level: error
16+
fail_level: error
17+
filter_mode: file
18+

.prettierignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
gen-schema-bundled.mjs
2+
.spago/
3+
output/
4+
node_modules/
5+
.git/
6+
.github/
7+
.claude/

.prettierrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

README.md

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,15 @@ npm install --save-dev purescript-graphql-client
117117
```
118118

119119
Then add a script to generate your schema on build. Run this script before compiling your purescript project.
120+
120121
```js
121-
const { generateSchema } = require('purescript-graphql-client')
122+
const { generateSchema } = require("purescript-graphql-client");
122123

123124
generateSchema({
124-
dir: './src/generated', // Where you want the generated code to go
125-
modulePath: ['Generated', 'Gql'], // The name of the generated module
126-
url: 'http://localhost:4892/graphql', // Your GraphQL endpoint
127-
})
125+
dir: "./src/generated", // Where you want the generated code to go
126+
modulePath: ["Generated", "Gql"], // The name of the generated module
127+
url: "http://localhost:4892/graphql", // Your GraphQL endpoint
128+
});
128129
```
129130

130131
A full example can be seen in `examples/2-codegen`
@@ -134,18 +135,22 @@ The full options for `generateSchema` can be seen in `codegen/schema/README.md`
134135
You should run this script to build your schema as part of your build, before purescript compilation.
135136

136137
If you wish to generate multiple schemas, use `generateSchemas`
138+
137139
```js
138-
const { generateSchemas } = require('purescript-graphql-client')
140+
const { generateSchemas } = require("purescript-graphql-client");
139141

140-
generateSchemas({
141-
dir: './src/generated',
142-
modulePath: ['Generated', 'Gql']
143-
}, [
142+
generateSchemas(
144143
{
145-
url: 'http://localhost:4892/graphql',
146-
moduleName: 'MySchema' // The name of the module for this single schema
147-
}
148-
])
144+
dir: "./src/generated",
145+
modulePath: ["Generated", "Gql"],
146+
},
147+
[
148+
{
149+
url: "http://localhost:4892/graphql",
150+
moduleName: "MySchema", // The name of the module for this single schema
151+
},
152+
],
153+
);
149154
```
150155

151156
A full example can be seen in `examples/2-codegen`
@@ -172,6 +177,7 @@ npm install --save @apollo/client
172177
```
173178

174179
you can then create a client using `createClient`. eg.
180+
175181
```purs
176182
import MySchema (Query, Mutation)
177183
import GraphQL.Client.BaseClients.Apollo (createClient)
@@ -195,8 +201,8 @@ import Type.Data.List (Nil')
195201
}
196202
197203
```
198-
Look in `examples/4-mutation` for a complete example.
199204

205+
Look in `examples/4-mutation` for a complete example.
200206

201207
Use `createSubscriptionClient` if you want to make subscriptions. eg.
202208

@@ -243,7 +249,6 @@ You can see an examples of this in `examples/1-simple` and `e2e/1-affjax` .
243249

244250
You can then write queries and mutations just as you would in the browser.
245251

246-
247252
## Examples
248253

249254
To view examples of what can be done with this library look at the `examples` and `e2e` directories.
@@ -255,6 +260,7 @@ API documentation can be found at https://pursuit.purescript.org/packages/puresc
255260
## Guide
256261

257262
### Query syntax
263+
258264
Once you are set up and have generated your purescript schema. You can write your queries.
259265

260266
The easiest way to do this is to go to https://gql-query-to-purs.herokuapp.com/query and paste your
@@ -292,6 +298,7 @@ As GraphQL arguments may have mixed types, the library provides tools to help ha
292298
`ArgL` and `ArgR` allow you to have different types for different code branches in arguments.
293299

294300
eg.
301+
295302
```purs
296303
let condition = true
297304
@@ -301,11 +308,13 @@ result <- query client "args_of_differing_types"
301308
{ prop1, prop2 }
302309
}
303310
```
311+
304312
`IgnoreArg` can be used to ignore both the label and value on a record.
305313

306314
This is most commonly used with `guardArg` to ignore an argument property unless a condition is met.
307315

308316
eg.
317+
309318
```purs
310319
let condition = true
311320
@@ -320,6 +329,7 @@ GraphQL arrays can be written as purescript arrays if they are homogenous, but f
320329
you can use `AndArgs`/`andArg` or the `+++`/`++` operator.
321330

322331
eg.
332+
323333
```purs
324334
325335
result <- query client "mixed_args_query"
@@ -358,15 +368,22 @@ In a dynamic language you might fold a collection of users to create a graphql q
358368

359369
```gql
360370
mutation myUpdates {
361-
_1: update_users(where: {id : 1}, _set: { value: 10 }) { affected_rows }
362-
_2: update_users(where: {id : 2}, _set: { value: 15 }) { affected_rows }
363-
_3: update_users(where: {id : 3}, _set: { value: 20 }) { affected_rows }
371+
_1: update_users(where: { id: 1 }, _set: { value: 10 }) {
372+
affected_rows
373+
}
374+
_2: update_users(where: { id: 2 }, _set: { value: 15 }) {
375+
affected_rows
376+
}
377+
_3: update_users(where: { id: 3 }, _set: { value: 20 }) {
378+
affected_rows
379+
}
364380
}
365381
```
366382

367383
To do this in this library there is there is the `Spread` constructor that creates these aliases for you and decodes the response as an array.
368384

369385
eg.
386+
370387
```purs
371388
372389
import GraphQL.Client.Alias.Dynamic (Spread(..))
@@ -401,6 +418,7 @@ query client "widget_names_with_id_1"
401418
`withVars`
402419
{ idVar: 1 }
403420
```
421+
404422
`withVars` uses `encodeJson` to turn the variables in json. If you
405423
wish to use a custom encoder, use `withVarsEncode`.
406424

@@ -415,7 +433,6 @@ Only top level directives, that have a query, mutation or subscription location
415433

416434
Please look in the example/12-directives to see an example of this.
417435

418-
419436
### Full responses
420437

421438
If you wish to get the full response, as per the [GraphQL Spec](https://spec.graphql.org/June2018/#sec-Response) use the "FullRes" versions of the query functions
@@ -444,6 +461,7 @@ To see how these options work, I recommend looking at the [Apollo core docs](htt
444461
The options are usually set using record updates or `identity` for default options.
445462

446463
eg.
464+
447465
```purs
448466
mutationOpts _
449467
{ update = Just update
@@ -458,7 +476,6 @@ eg.
458476

459477
## Alternatives to this package
460478

461-
462479
### [purescript-graphql-fundeps](https://github.com/meeshkan/purescript-graphql-fundeps)
463480

464481
A much more lightweight graphql client. This package does not infer query types and does not support subscriptions or caching but allows writing in
@@ -469,6 +486,7 @@ graphql syntax and has much less source code. Probably preferable if your query
469486
A port of [elm-graphql](https://github.com/dillonkearns/elm-graphql/).
470487

471488
Although the names and scope of the 2 packages are very similar they are not connected and there are a few differences:
489+
472490
- This package uses record syntax to make queries whereas purescript-graphqlclient uses applicative/ado syntax
473491
- This package allows use of Apollo if you wish (or other lower level graphQL clients)
474492
- This package supports subscriptions, watch queries and client caching

codegen/schema/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
Argument for generateSchema
22

3-
43
```purs
54
-- | URL for your graphql endpoint
65
{ url :: String
@@ -108,9 +107,11 @@ Argument for generateSchema
108107
```
109108

110109
2nd argument for generateSchemas
110+
111111
```
112112
Array
113113
-- | URL for your graphql endpoint
114114
{ url :: String
115115
, moduleName :: String
116116
}
117+
```

codegen/schema/get-gql-schema.mjs

Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,31 @@
1-
import fetch from 'node-fetch';
2-
import {
3-
getIntrospectionQuery,
4-
} from 'graphql';
1+
import { getIntrospectionQuery } from "graphql";
52

6-
export async function getGqlSchema ({ moduleName, cache, url, token }) {
3+
export async function getGqlSchema({ moduleName, cache, url, token }) {
74
try {
8-
const introspectionQuery = getIntrospectionQuery()
5+
const introspectionQuery = getIntrospectionQuery();
96

10-
const response = await fetch(
11-
url,
12-
{
13-
method: 'POST',
14-
headers:
15-
token
16-
? {
17-
'Content-Type': 'application/json',
18-
Authorization: `Bearer ${token}`
19-
}
20-
: {
21-
'Content-Type': 'application/json'
22-
},
23-
body: JSON.stringify({ query: introspectionQuery })
24-
}
25-
)
7+
const response = await fetch(url, {
8+
method: "POST",
9+
headers: token
10+
? {
11+
"Content-Type": "application/json",
12+
Authorization: `Bearer ${token}`,
13+
}
14+
: {
15+
"Content-Type": "application/json",
16+
},
17+
body: JSON.stringify({ query: introspectionQuery }),
18+
});
2619

27-
const { data: schema, errors } = await response.json()
20+
const { data: schema, errors } = await response.json();
2821

2922
if (errors) {
30-
throw new Error(errors
31-
.map(err => "- " + err.message)
32-
.join('\n')
33-
)
23+
throw new Error(errors.map((err) => "- " + err.message).join("\n"));
3424
}
3525

36-
return { moduleName, cache, schema }
26+
return { moduleName, cache, schema };
3727
} catch (err) {
38-
console.error('failed to get gql schema', err)
39-
throw (err)
28+
console.error("failed to get gql schema", err);
29+
throw err;
4030
}
4131
}

codegen/schema/index.mjs

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
1-
import { writePursSchemas } from './write-purs-schema.mjs'
2-
import { getGqlSchema } from './get-gql-schema.mjs'
3-
import { promisify } from 'util'
4-
import mkdirp from 'mkdirp'
5-
import rimraf from 'rimraf'
6-
const rm = promisify(rimraf)
1+
import fs from "node:fs/promises";
2+
import { writePursSchemas } from "./write-purs-schema.mjs";
3+
import { getGqlSchema } from "./get-gql-schema.mjs";
4+
const mkdirp = (path) => fs.mkdir(path, { recursive: true });
75

8-
export async function generateSchemas (opts, gqlEndpoints) {
6+
export async function generateSchemas(opts, gqlEndpoints) {
97
if (!Array.isArray(gqlEndpoints)) {
10-
gqlEndpoints = [gqlEndpoints]
8+
gqlEndpoints = [gqlEndpoints];
119
}
12-
await rm(opts.dir)
13-
await mkdirp(opts.dir)
14-
await mkdirp(opts.dir + '/Schema')
15-
await mkdirp(opts.dir + '/Enum')
16-
await mkdirp(opts.dir + '/Directives')
17-
const schemas = await Promise.all(gqlEndpoints.map(getGqlSchema))
10+
await fs.rm(opts.dir, { recursive: true, force: true });
11+
await mkdirp(opts.dir);
12+
await mkdirp(opts.dir + "/Schema");
13+
await mkdirp(opts.dir + "/Enum");
14+
await mkdirp(opts.dir + "/Directives");
15+
const schemas = await Promise.all(gqlEndpoints.map(getGqlSchema));
1816

19-
return await writePursSchemas(opts, schemas)
17+
return await writePursSchemas(opts, schemas);
2018
}
2119

22-
export async function generateSchema (opts) {
23-
const { modulePath, url } = opts
24-
const moduleName = modulePath[modulePath.length - 1]
20+
export async function generateSchema(opts) {
21+
const { modulePath, url } = opts;
22+
const moduleName = modulePath[modulePath.length - 1];
2523

26-
return generateSchemas({ ...opts, modulePath: modulePath.slice(0, -1) }, [{ moduleName, url }])
24+
return generateSchemas({ ...opts, modulePath: modulePath.slice(0, -1) }, [
25+
{ moduleName, url },
26+
]);
2727
}

codegen/schema/spago.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,4 +157,3 @@ workspace:
157157
- safe-coerce
158158
- strings
159159
- tuples
160-

0 commit comments

Comments
 (0)