Open History to see the last commit
1#!/usr/bin/env node
2/**
3 * Refreshes `schema/expo.graphql` from Expo's API, which answers introspection
4 * without a credential. eas-cli generates its own client from the same
5 * endpoint. Run `vp run generate` afterwards to regenerate the operations.
6 */
7import { pipe } from "effect/Function";
8import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
9import * as NodeServices from "@effect/platform-node/NodeServices";
10import * as Effect from "effect/Effect";
11import * as FileSystem from "effect/FileSystem";
12import * as Layer from "effect/Layer";
13import * as Path from "effect/Path";
14import * as Schema from "effect/Schema";
15import { FetchHttpClient, HttpClient, HttpClientRequest, HttpClientResponse } from "effect/http";
16import {
17 buildClientSchema,
18 getIntrospectionQuery,
19 lexicographicSortSchema,
20 printSchema,
21 type IntrospectionQuery,
22} from "graphql";
23
24const EXPO_GRAPHQL_URL = "https://api.expo.dev/graphql";
25
26const IntrospectionResponse = Schema.Struct({
27 data: Schema.Struct({ __schema: Schema.Unknown }),
28});
29
30const program = Effect.gen(function* () {
31 const fs = yield* FileSystem.FileSystem;
32 const path = yield* Path.Path;
33 const client = (yield* HttpClient.HttpClient).pipe(HttpClient.filterStatusOk);
34 const response = yield* HttpClientRequest.post(EXPO_GRAPHQL_URL).pipe(
35 HttpClientRequest.bodyJson({ query: getIntrospectionQuery() }),
36 Effect.flatMap(client.execute),
37 Effect.flatMap(HttpClientResponse.schemaBodyJson(IntrospectionResponse)),
38 );
39 // Sorted so a refresh diffs by what Expo changed, not by its declaration order.
40 const sdl = pipe(
41 buildClientSchema(response.data as unknown as IntrospectionQuery),
42 lexicographicSortSchema,
43 printSchema,
44 );
45 const target = path.join(import.meta.dirname, "..", "schema", "expo.graphql");
46 yield* fs.makeDirectory(path.dirname(target), { recursive: true });
47 yield* fs.writeFileString(target, `${sdl}\n`);
48 yield* Effect.log(`Wrote ${target}`);
49});
50
51program.pipe(
52 Effect.provide(Layer.mergeAll(NodeServices.layer, FetchHttpClient.layer)),
53 NodeRuntime.runMain,
54);