Skip to content

Commit

Permalink
refactor: reorganize repo (#75)
Browse files Browse the repository at this point in the history
* unit test

* refactor

* pass test

* add mutation tests

* fix integration test

* refactor

* reorganize

* separate field definition functions

* pull out boolean arg

* pull out other boolean arg

* refactor

* refactor

* bun version

* set up docs workspace

* undo

* fix copywright headers
  • Loading branch information
danadajian authored May 27, 2024
1 parent 11097d5 commit ff1811a
Show file tree
Hide file tree
Showing 34 changed files with 602 additions and 392 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,6 @@ jobs:

- name: Integration Test
run: bun integration

- name: Build Docs
run: bun docs:build
8 changes: 0 additions & 8 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,8 @@ jobs:
- name: Install Dependencies
run: bun install

- name: Build Plugin
run: bun run build

- name: Install Docs Dependencies
run: bun install
working-directory: docs

- name: Build Docs
run: bun docs:build
working-directory: docs

- name: Setup Pages
uses: actions/configure-pages@v5
Expand Down
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1 +1 @@
bun lint && bun format && git add .
bun lint:fix && bun format && git add .
Binary file modified bun.lockb
Binary file not shown.
Binary file removed docs/bun.lockb
Binary file not shown.
7 changes: 4 additions & 3 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
"name": "docs",
"private": true,
"scripts": {
"docs:start": "docusaurus start",
"docs:build": "tsc && bun generate && docusaurus build",
"generate": "jsdoc2md --files ../dist/plugin.cjs --partial partials/main.hbs --partial partials/scope.hbs -c jsdoc.conf > docs/configuration.md"
"build": "tsc && bun generate && docusaurus build",
"generate": "jsdoc2md --files ../dist/plugin.cjs --partial partials/main.hbs --partial partials/scope.hbs -c jsdoc.conf > docs/configuration.md",
"start": "docusaurus start"
},
"devDependencies": {
"@docusaurus/core": "3.3.2",
Expand All @@ -13,6 +13,7 @@
"@docusaurus/tsconfig": "3.3.2",
"@docusaurus/types": "3.3.2",
"@mdx-js/react": "3.0.1",
"ajv": "8.14.0",
"clsx": "2.1.1",
"jsdoc-to-markdown": "8.0.1",
"prism-react-renderer": "2.3.1",
Expand Down
2 changes: 1 addition & 1 deletion eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ export default [
},
},
{
ignores: ["build", "dist", "docs"],
ignores: ["build", "dist", "docs", "scripts"],
},
];
13 changes: 10 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@expediagroup/graphql-kotlin-codegen",
"packageManager": "bun@1.1.6",
"packageManager": "bun@1.1.10",
"main": "dist/plugin.cjs",
"types": "dist/plugin.d.cts",
"files": [
Expand All @@ -22,6 +22,7 @@
"@graphql-codegen/java-common": "3.0.0",
"@graphql-codegen/plugin-helpers": "5.0.4",
"@graphql-codegen/visitor-plugin-common": "5.2.0",
"ts-deepmerge": "7.0.0",
"valibot": "0.30.0"
},
"devDependencies": {
Expand All @@ -37,13 +38,19 @@
},
"scripts": {
"build": "tsup src/plugin.ts --clean --dts --external graphql",
"docs:build": "bun run build && bun --filter docs build",
"docs:start": "bun --filter docs start",
"format": "prettier --write .",
"format-check": "prettier --check .",
"integration": "bun run build && graphql-codegen && ./gradlew graphqlGenerateSDL && bun test ./test/integration.test.ts",
"lint": "eslint .",
"lint": "bun ./scripts/check-headers.ts && eslint .",
"lint:fix": "bun ./scripts/fix-headers.ts && eslint --fix .",
"prepack": "bun run build",
"prepare": "husky",
"unit": "bun test ./test/plugin.test.ts"
},
"type": "module"
"type": "module",
"workspaces": [
"docs"
]
}
18 changes: 18 additions & 0 deletions scripts/check-headers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Glob } from "bun";

const filePaths = new Glob("src/**/*.ts").scan();

let filesWithoutCopyrightHeader: string[] = [];
for await (const filePath of filePaths) {
const fileContents = await Bun.file(filePath).text();
if (!fileContents.startsWith("/*\nCopyright")) {
filesWithoutCopyrightHeader.push(filePath);
}
}

if (filesWithoutCopyrightHeader.length) {
console.error(
`\nThe following files are missing a valid copyright header:${filesWithoutCopyrightHeader.map((file) => `\n • ${file}`).join()}`,
);
process.exit(1);
}
24 changes: 24 additions & 0 deletions scripts/fix-headers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Glob } from "bun";

const copyrightHeader = `/*
Copyright 2024 Expedia, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
`;

const filePaths = new Glob("src/**/*.ts").scan();
for await (const filePath of filePaths) {
const fileContents = await Bun.file(filePath).text();
if (!fileContents.startsWith("/*\nCopyright")) {
await Bun.write(filePath, `${copyrightHeader}${fileContents}`);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import {
} from "graphql";
import { buildDescriptionAnnotation } from "./build-description-annotation";
import { buildDirectiveAnnotations } from "./build-directive-annotations";
import { CodegenConfigWithDefaults } from "./build-config-with-defaults";
import { TypeMetadata } from "./build-type-metadata";
import { CodegenConfigWithDefaults } from "../config/build-config-with-defaults";
import { TypeMetadata } from "../utils/build-type-metadata";

export type DefinitionNode =
| TypeDefinitionNode
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
import { CodegenConfigWithDefaults } from "./build-config-with-defaults";
import { TypeMetadata } from "./build-type-metadata";
/*
Copyright 2024 Expedia, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import { CodegenConfigWithDefaults } from "../config/build-config-with-defaults";
import { TypeMetadata } from "../utils/build-type-metadata";
import { indent } from "@graphql-codegen/visitor-plugin-common";
import { Kind } from "graphql/index";
import { DefinitionNode, trimDescription } from "./build-annotations";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

import { CodegenConfigWithDefaults } from "./build-config-with-defaults";
import { CodegenConfigWithDefaults } from "../config/build-config-with-defaults";
import { DefinitionNode } from "./build-annotations";
import { getFederationDirectiveReplacement } from "./get-federation-directive-replacement";
import { ConstDirectiveNode } from "graphql/language";
import { Kind } from "graphql";

Expand Down Expand Up @@ -75,3 +74,23 @@ function buildKotlinAnnotations(
return `@${kotlinAnnotation.annotationName}(${directiveArguments})`;
});
}

function getFederationDirectiveReplacement(directive: ConstDirectiveNode) {
const federationDirectivePrefix =
"com.expediagroup.graphql.generator.federation.directives.";
switch (directive.name.value) {
case "key":
if (
directive.arguments?.[0] &&
directive.arguments[0].value.kind === Kind.STRING
) {
const fieldArg = directive.arguments[0]?.value.value;
return `@${federationDirectivePrefix}KeyDirective(${federationDirectivePrefix}FieldSet("${fieldArg}"))`;
}
return undefined;
case "extends":
return `@${federationDirectivePrefix}ExtendsDirective`;
case "external":
return `@${federationDirectivePrefix}ExternalDirective`;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ limitations under the License.
*/

import { CodegenConfigWithDefaults } from "./build-config-with-defaults";
import { getDependentTypeNames } from "./get-dependent-type-names";
import { GraphQLSchema } from "graphql";
import { TypeDefinitionNode } from "graphql/index";
import {
getDependentFieldTypeNames,
getDependentInterfaceNames,
getDependentUnionNames,
} from "../utils/dependent-type-utils";

export function addDependentTypesToOnlyTypes(
config: CodegenConfigWithDefaults,
Expand All @@ -34,3 +39,18 @@ export function addDependentTypesToOnlyTypes(
: dependentTypeNames;
config.onlyTypes.push(...dependentTypesInScope);
}

function getDependentTypeNames(
schema: GraphQLSchema,
node: TypeDefinitionNode,
config: CodegenConfigWithDefaults,
): string[] {
const namedTypes = getDependentFieldTypeNames(node, config)
.concat(getDependentUnionNames(node))
.concat(getDependentInterfaceNames(node));
const recursivelyFoundTypes = namedTypes
.map((typeName) => schema.getType(typeName)?.astNode)
.filter(Boolean)
.flatMap((node) => getDependentTypeNames(schema, node, config));
return namedTypes.concat(recursivelyFoundTypes);
}
36 changes: 36 additions & 0 deletions src/config/build-config-with-defaults.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
Copyright 2024 Expedia, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import { GraphQLKotlinCodegenConfig } from "../plugin";
import { buildPackageNameFromPath } from "@graphql-codegen/java-common";
import { dirname, normalize } from "path";
import { merge } from "ts-deepmerge";

export function buildConfigWithDefaults(
config: GraphQLKotlinCodegenConfig,
outputFile: string,
) {
const defaultConfig = {
packageName: buildPackageNameFromPath(dirname(normalize(outputFile))),
includeDependentTypes: true,
unionGeneration: "MARKER_INTERFACE",
extraImports: ["com.expediagroup.graphql.generator.annotations.*"],
} as const satisfies GraphQLKotlinCodegenConfig;

return merge(defaultConfig, config) as GraphQLKotlinCodegenConfig &
typeof defaultConfig;
}

export type CodegenConfigWithDefaults = ReturnType<
typeof buildConfigWithDefaults
>;
24 changes: 24 additions & 0 deletions src/config/find-type-in-resolver-interfaces-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
Copyright 2024 Expedia, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import { InterfaceTypeDefinitionNode, ObjectTypeDefinitionNode } from "graphql";
import { CodegenConfigWithDefaults } from "./build-config-with-defaults";

export function findTypeInResolverInterfacesConfig(
node: ObjectTypeDefinitionNode | InterfaceTypeDefinitionNode,
config: CodegenConfigWithDefaults,
) {
return config.resolverInterfaces?.findLast(
(resolverInterface) => resolverInterface.typeName === node.name.value,
);
}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ limitations under the License.
import { TypeDefinitionNode } from "graphql";
import { CodegenConfigWithDefaults } from "./build-config-with-defaults";

export function shouldIncludeTypeDefinition(
export function shouldExcludeTypeDefinition(
node: TypeDefinitionNode,
config: CodegenConfigWithDefaults,
) {
return !config.onlyTypes || config.onlyTypes.includes(node.name.value);
return config.onlyTypes && !config.onlyTypes.includes(node.name.value);
}
8 changes: 4 additions & 4 deletions src/definitions/enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ limitations under the License.

import { EnumTypeDefinitionNode, EnumValueDefinitionNode } from "graphql";
import { indentMultiline } from "@graphql-codegen/visitor-plugin-common";
import { buildAnnotations } from "../helpers/build-annotations";
import { shouldIncludeTypeDefinition } from "../helpers/should-include-type-definition";
import { CodegenConfigWithDefaults } from "../helpers/build-config-with-defaults";
import { buildAnnotations } from "../annotations/build-annotations";
import { shouldExcludeTypeDefinition } from "../config/should-exclude-type-definition";
import { CodegenConfigWithDefaults } from "../config/build-config-with-defaults";

export function buildEnumTypeDefinition(
node: EnumTypeDefinitionNode,
config: CodegenConfigWithDefaults,
) {
if (!shouldIncludeTypeDefinition(node, config)) {
if (shouldExcludeTypeDefinition(node, config)) {
return "";
}

Expand Down
Loading

0 comments on commit ff1811a

Please sign in to comment.