diff --git a/client/shared/dev/generateGraphQlOperations.ts b/client/shared/dev/generateGraphQlOperations.ts index 841081ab2c5..f4fec804bf5 100644 --- a/client/shared/dev/generateGraphQlOperations.ts +++ b/client/shared/dev/generateGraphQlOperations.ts @@ -1,14 +1,13 @@ import { readFileSync } from 'fs' import path from 'path' -import { CodegenConfig, generate } from '@graphql-codegen/cli' +import { type CodegenConfig, generate } from '@graphql-codegen/cli' import { glob } from 'glob' import { GraphQLError } from 'graphql' const ROOT_FOLDER = path.resolve(__dirname, '../../../') const WEB_FOLDER = path.resolve(ROOT_FOLDER, './client/web') -const SVELTEKIT_FOLDER = path.resolve(ROOT_FOLDER, './client/web-sveltekit') const BROWSER_FOLDER = path.resolve(ROOT_FOLDER, './client/browser') const SHARED_FOLDER = path.resolve(ROOT_FOLDER, './client/shared') const VSCODE_FOLDER = path.resolve(ROOT_FOLDER, './client/vscode') @@ -23,8 +22,6 @@ const WEB_DOCUMENTS_GLOB = [ `!${WEB_FOLDER}/src/end-to-end/**/*.*`, // TODO(bazel): can remove when non-bazel dropped ] -const SVELTEKIT_DOCUMENTS_GLOB = [`${SVELTEKIT_FOLDER}/src/lib/**/*.ts`] - const BROWSER_DOCUMENTS_GLOB = [ `${BROWSER_FOLDER}/src/**/*.{ts,tsx}`, `!${BROWSER_FOLDER}/src/end-to-end/**/*.*`, // TODO(bazel): can remove when non-bazel dropped @@ -41,11 +38,11 @@ const GLOBS: Record = { SharedGraphQlOperations: SHARED_DOCUMENTS_GLOB, VSCodeGraphQlOperations: VSCODE_DOCUMENTS_GLOB, WebGraphQlOperations: WEB_DOCUMENTS_GLOB, - SvelteKitGraphQlOperations: SVELTEKIT_DOCUMENTS_GLOB, } const EXTRA_PLUGINS: Record = { SharedGraphQlOperations: ['typescript-apollo-client-helpers'], + SvelteKitGraphQlOperations: ['typed-document-node'], } const SHARED_PLUGINS = [ @@ -67,10 +64,6 @@ export const ALL_INPUTS: Input[] = [ interfaceNameForOperations: 'WebGraphQlOperations', outputPath: path.join(WEB_FOLDER, './src/graphql-operations.ts'), }, - { - interfaceNameForOperations: 'SvelteKitGraphQlOperations', - outputPath: path.join(SVELTEKIT_FOLDER, './src/lib/graphql-operations.ts'), - }, { interfaceNameForOperations: 'SharedGraphQlOperations', outputPath: path.join(SHARED_FOLDER, './src/graphql-operations.ts'), @@ -152,7 +145,7 @@ function createCodegenConfig(operations: Input[]): CodegenConfig { if (require.main === module) { // Entry point to generate all GraphQL operations files, or a single one. - async function main(args: string[]) { + async function main(args: string[]): Promise { if (args.length !== 0 && args.length !== 2) { throw new Error('Usage: [ ]') } diff --git a/client/web-sveltekit/.eslintignore b/client/web-sveltekit/.eslintignore index 9d64338ba8f..6b0cd631d84 100644 --- a/client/web-sveltekit/.eslintignore +++ b/client/web-sveltekit/.eslintignore @@ -9,10 +9,14 @@ node_modules vite.config.ts svelte.config.js playwright.config.ts -src/lib/graphql-operations.ts /server.js # Ignore files for PNPM, NPM and YARN pnpm-lock.yaml package-lock.json yarn.lock + +# Generated files +*.gql.d.ts +src/lib/graphql-operations.ts +src/lib/graphql-types.ts diff --git a/client/web-sveltekit/.gitignore b/client/web-sveltekit/.gitignore index 78b7e47bb69..f0ac60b83d9 100644 --- a/client/web-sveltekit/.gitignore +++ b/client/web-sveltekit/.gitignore @@ -7,3 +7,8 @@ node_modules .env.*.local vite.config.js.timestamp-* vite.config.ts.timestamp-* + +# Generated TypeScript type definitions and GraphQL documents +*.gql.d.ts +src/lib/graphql-types.ts +src/lib/graphql-operations.ts diff --git a/client/web-sveltekit/BUILD.bazel b/client/web-sveltekit/BUILD.bazel index b02cf418394..1d78917426f 100644 --- a/client/web-sveltekit/BUILD.bazel +++ b/client/web-sveltekit/BUILD.bazel @@ -6,30 +6,6 @@ load("@npm//:vite/package_json.bzl", vite_bin = "bin") # gazelle:ignore -js_library( - name = "graphql_operations_files", - # Keep in sync with glob in client/shared/dev/generateGraphQlOperations.js - srcs = glob( - ["src/**/*.ts"], - [ - # TODO: Ignore legacy build generated file as it conflicts with the Bazel - # build. This can be removed after the migration. - "src/lib/graphql-operations.ts", - ], - ), - visibility = ["//visibility:private"], -) - -generate_graphql_operations( - name = "graphql_operations_ts", - srcs = [ - ":graphql_operations_files", - ], - out = "src/lib/graphql-operations.ts", - interface_name = "SvelteKitGraphQlOperations", - visibility = ["//visibility:private"], -) - SRCS = [ "package.json", "vite.config.ts", @@ -51,18 +27,26 @@ SRCS = [ "**/*.svelte", "**/*.html", "**/*.tsx", + "**/*.gql", ]], [ "src/lib/graphql-operations.ts", + "src/lib/graphql-types.ts", + "src/**/*.gql.d.ts", ], -) +) + glob(["dev/**/*.cjs"]) BUILD_DEPS = [ - ":graphql_operations_ts", ":node_modules/@faker-js/faker", + ":node_modules/@graphql-codegen/cli", + ":node_modules/@graphql-codegen/typescript", + ":node_modules/@graphql-codegen/typescript-operations", + ":node_modules/@graphql-codegen/near-operation-file-preset", + ":node_modules/@graphql-tools/utils", ":node_modules/@melt-ui/svelte", ":node_modules/@popperjs/core", ":node_modules/@remix-run/router", + ":node_modules/@rollup/plugin-graphql", ":node_modules/@sourcegraph/branded", ":node_modules/@sourcegraph/common", ":node_modules/@sourcegraph/http-client", @@ -74,6 +58,7 @@ BUILD_DEPS = [ ":node_modules/@sveltejs/kit", ":node_modules/@types/prismjs", ":node_modules/lodash-es", + ":node_modules/graphql", ":node_modules/prismjs", ":node_modules/react", ":node_modules/svelte", @@ -102,6 +87,7 @@ BUILD_DEPS = [ "//:node_modules/react-router-dom", "//:node_modules/rxjs", "//:node_modules/uuid", + "//cmd/frontend/graphqlbackend:graphql_schema", ] CONFIGS = [ diff --git a/client/web-sveltekit/dev/typed-document-node.cjs b/client/web-sveltekit/dev/typed-document-node.cjs new file mode 100644 index 00000000000..305e9f77209 --- /dev/null +++ b/client/web-sveltekit/dev/typed-document-node.cjs @@ -0,0 +1,49 @@ +// @ts-check + +const { visit } = require('graphql') + +/** + * Custom version of the `typed-document-node` plugin that only generates the type definitions + * for the documents without generating a parsed version. This is all we need because the + * `@rollup/plugin-graphql` plugin already parses the documents for us. + * + * @param {import('graphql').GraphQLSchema} _schema + * @param {import('@graphql-codegen/plugin-helpers').Types.DocumentFile[]} documents + * @param {{operationResultSuffix?: string}} config + */ +const plugin = (_schema, documents, config) => { + const { operationResultSuffix = '' } = config + + /** @type {{name: string}[]} */ + const allOperations = [] + + for (const item of documents) { + if (item.document) { + visit(item.document, { + OperationDefinition: { + enter: node => { + if (node.name && node.name.value) { + allOperations.push({ + name: node.name.value, + }) + } + }, + }, + }) + } + } + + const documentNodes = allOperations.map( + ({ name }) => + `export declare const ${name}: TypedDocumentNode<${name}${operationResultSuffix}, ${name}Variables>` + ) + if (documentNodes.length === 0) { + return '' + } + return { + prepend: ["import type { TypedDocumentNode } from '@graphql-typed-document-node/core'\n"], + content: documentNodes.join('\n'), + } +} + +module.exports = { plugin } diff --git a/client/web-sveltekit/package.json b/client/web-sveltekit/package.json index dec2fd10aac..b1326b371f6 100644 --- a/client/web-sveltekit/package.json +++ b/client/web-sveltekit/package.json @@ -18,7 +18,14 @@ }, "devDependencies": { "@faker-js/faker": "^8.0.2", + "@graphql-codegen/cli": "^5.0.0", + "@graphql-codegen/near-operation-file-preset": "^3.0.0", + "@graphql-codegen/typescript": "^4.0.1", + "@graphql-codegen/typescript-operations": "^4.0.1", + "@graphql-tools/utils": "^10.0.11", + "@graphql-typed-document-node/core": "^3.2.0", "@playwright/test": "1.25.0", + "@rollup/plugin-graphql": "^2.0.4", "@storybook/addon-essentials": "^7.2.0", "@storybook/addon-interactions": "^7.2.0", "@storybook/addon-links": "^7.2.0", @@ -37,6 +44,7 @@ "@types/prismjs": "^1.26.0", "eslint-plugin-storybook": "^0.6.12", "eslint-plugin-svelte3": "^4.0.0", + "graphql": "^15.0.0", "msw": "^1.2.3", "msw-storybook-addon": "^1.8.0", "prettier": "^3.0.0", @@ -50,7 +58,6 @@ "svelte-check": "^3.4.6", "tslib": "2.1.0", "vite": "^4.4.7", - "vite-plugin-graphql-codegen": "^3.2.3", "vite-plugin-inspect": "^0.7.35", "vitest": "^0.33.0" }, @@ -60,12 +67,12 @@ "@popperjs/core": "^2.11.8", "@remix-run/router": "~1.3.3", "@sourcegraph/branded": "workspace:*", + "@sourcegraph/client-api": "workspace:*", "@sourcegraph/common": "workspace:*", "@sourcegraph/http-client": "workspace:*", "@sourcegraph/shared": "workspace:*", "@sourcegraph/web": "workspace:*", "@sourcegraph/wildcard": "workspace:*", - "@sourcegraph/client-api": "workspace:*", "highlight.js": "^10.0.0", "lodash-es": "^4.17.21", "prismjs": "^1.29.0", diff --git a/client/web-sveltekit/src/lib/Commit.gql b/client/web-sveltekit/src/lib/Commit.gql new file mode 100644 index 00000000000..12b26650b76 --- /dev/null +++ b/client/web-sveltekit/src/lib/Commit.gql @@ -0,0 +1,25 @@ +fragment Commit on GitCommit { + id + abbreviatedOID + canonicalURL + subject + body + author { + date + person { + name + displayName + email + avatarURL + } + } + committer { + date + person { + name + displayName + email + avatarURL + } + } +} diff --git a/client/web-sveltekit/src/lib/Commit.svelte b/client/web-sveltekit/src/lib/Commit.svelte index 6b67f74a995..a6c3a58e25c 100644 --- a/client/web-sveltekit/src/lib/Commit.svelte +++ b/client/web-sveltekit/src/lib/Commit.svelte @@ -1,25 +1,44 @@
- + + +
- {#if commit.committer} + {#if committer && committer.name !== author.name}
- + + +
{/if}
diff --git a/client/web-sveltekit/src/lib/LoadingSpinner.svelte b/client/web-sveltekit/src/lib/LoadingSpinner.svelte index 3cb2026b402..75bb1cd1b83 100644 --- a/client/web-sveltekit/src/lib/LoadingSpinner.svelte +++ b/client/web-sveltekit/src/lib/LoadingSpinner.svelte @@ -4,7 +4,7 @@
-
+