generate-graphql-types.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import { spawn } from 'child_process';
  2. import * as fs from 'fs';
  3. import { API_PATH, API_PORT } from '../shared/shared-constants';
  4. // tslint:disable:no-console
  5. const API_URL = `http://localhost:${API_PORT}/${API_PATH}`;
  6. const SCHEMA_JSON_FILE = '../schema.json';
  7. const CLIENT_SCHEMA_FILES = './src/app/data/types/client-types.graphql';
  8. const CLIENT_QUERY_FILES = '"./src/app/data/{queries,mutations,fragments}/**/*.ts"';
  9. const TYPESCRIPT_DEFINITIONS_FILE = './src/app/data/types/gql-generated-types.ts';
  10. main().catch(e => {
  11. console.log('Could not generate types!', e);
  12. process.exitCode = 1;
  13. });
  14. /**
  15. * This script uses apollo-codegen to generate TypeScript interfaces for all
  16. * GraphQL queries defined in the admin-ui app. Run it via the package.json
  17. * script "generate-gql-types".
  18. */
  19. async function main(): Promise<void> {
  20. await downloadSchemaFromApi(API_URL, SCHEMA_JSON_FILE);
  21. await generateTypeScriptTypesFromSchema(
  22. SCHEMA_JSON_FILE,
  23. CLIENT_SCHEMA_FILES,
  24. CLIENT_QUERY_FILES,
  25. TYPESCRIPT_DEFINITIONS_FILE,
  26. );
  27. }
  28. /**
  29. * Downloads the schema from the provided GraphQL endpoint using the `apollo schema:download`
  30. * cli command and returns the result as an IntrospectionQuery object.
  31. */
  32. async function downloadSchemaFromApi(apiEndpoint: string, outputFile: string): Promise<void> {
  33. console.log(`Downloading schema from ${API_URL}`);
  34. const TEMP_API_SCHEMA = '../schema.temp.json';
  35. await runCommand('yarn', ['apollo', 'schema:download', TEMP_API_SCHEMA, `--endpoint=${API_URL}`]);
  36. console.log(`Downloaded schema from ${API_URL}`);
  37. const schemaFromApi = fs.readFileSync(TEMP_API_SCHEMA, { encoding: 'utf8' });
  38. fs.unlinkSync(TEMP_API_SCHEMA);
  39. const introspectionSchema = JSON.parse(schemaFromApi);
  40. fs.writeFileSync(
  41. SCHEMA_JSON_FILE,
  42. JSON.stringify({
  43. __schema: introspectionSchema,
  44. }),
  45. );
  46. }
  47. /**
  48. * Generates TypeScript definitions from the provided schema json file sing the `apollo codegen:generate` cli command.
  49. */
  50. async function generateTypeScriptTypesFromSchema(
  51. schemaFile: string,
  52. clientSchemaFiles: string,
  53. queryFiles: string,
  54. outputFile: string,
  55. ): Promise<number> {
  56. return runCommand('yarn', [
  57. 'apollo',
  58. 'codegen:generate',
  59. outputFile,
  60. '--addTypename',
  61. '--outputFlat',
  62. '--target=typescript',
  63. `--clientSchema=${clientSchemaFiles}`,
  64. `--queries=${queryFiles}`,
  65. `--schema=${schemaFile}`,
  66. ]);
  67. }
  68. /**
  69. * Runs a command-line command and resolves when completed.
  70. */
  71. function runCommand(command: string, args: string[]): Promise<number> {
  72. return new Promise((resolve, reject) => {
  73. const cp = spawn(command, args, { shell: true });
  74. cp.on('error', reject);
  75. cp.stdout.on('data', data => {
  76. if (4 < data.length) {
  77. console.log(`${data}`);
  78. }
  79. });
  80. cp.stderr.on('data', data => {
  81. if (4 < data.length) {
  82. console.log(`${data}`);
  83. }
  84. });
  85. cp.on('close', code => {
  86. if (code !== 0) {
  87. reject(code);
  88. }
  89. resolve(code);
  90. });
  91. });
  92. }