From 0101d848c864af9225de298ab8c181e158a7a62e Mon Sep 17 00:00:00 2001 From: Vladislav Zimnikov Date: Tue, 27 Sep 2022 13:17:48 +0300 Subject: [PATCH 1/4] Improved TS typing capabilities - Added possibility to explicitly define type of field added using `addField` method through passing third generic argument - Added possibility to explicitly define type definition of list of fields added using `addFieldList` method through passing second generic argument - To `addFieldList` added typesafety check if type definition's keys does not match the ones provided to method as an argument - Updated typescript dependency to latest version - Installed type-fest library to use custom utility types like EmptyObject and StringKeyOf --- package.json | 5 +++-- src/builder/AbstractField.ts | 19 +++++++++++++------ yarn.lock | 13 +++++++++---- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index c64aa6f..d6be7b4 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ }, "dependencies": { "node-fetch": "^2.6.2", - "tslib": "^2.2.0" + "tslib": "^2.2.0", + "type-fest": "^3.0.0" }, "devDependencies": { "@babel/core": "^7.13.15", @@ -33,6 +34,6 @@ "rollup-plugin-terser": "^7.0.2", "rollup-plugin-typescript2": "^0.30.0", "ts-jest": "^26.5.4", - "typescript": "^4.2.3" + "typescript": "^4.8.3" } } diff --git a/src/builder/AbstractField.ts b/src/builder/AbstractField.ts index c4df77a..71f6ca4 100644 --- a/src/builder/AbstractField.ts +++ b/src/builder/AbstractField.ts @@ -1,3 +1,4 @@ +import { EmptyObject, StringKeyOf } from 'type-fest'; import type { HigherKindType, FieldDescendantStore } from './hkt'; import type { InlineFragment } from './InlineFragment'; @@ -121,7 +122,8 @@ export abstract class AbstractField< // STRING addField< NewFieldName extends string, - IsArray extends boolean = false + IsArray extends boolean = false, + NewFieldType = FetchedFieldItemType >( field: NewFieldName, isArray?: IsArray @@ -130,8 +132,8 @@ export abstract class AbstractField< Name, FieldReturnType & { [k in NewFieldName]: IsArray extends true - ? FetchedFieldItemType[] - : FetchedFieldItemType + ? NewFieldType[] + : NewFieldType }, ArrayExpected > @@ -175,13 +177,18 @@ export abstract class AbstractField< } addFieldList< - NewField extends string + NewField extends string, + TypeDefinitions extends Record = EmptyObject, >( - fieldList: readonly NewField[] + fieldList: TypeDefinitions extends EmptyObject + ? readonly NewField[] + : StringKeyOf[] ): HigherKindType< this['tag'], Name, - FieldReturnType & { [K in NewField]: FetchedFieldItemType }, + FieldReturnType & TypeDefinitions extends EmptyObject + ? FieldReturnType & { [K in NewField]: FetchedFieldItemType } + : FieldReturnType & TypeDefinitions, ArrayExpected > { fieldList.forEach(this.addField.bind(this)); diff --git a/yarn.lock b/yarn.lock index 0359760..5763ecf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3699,6 +3699,11 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +type-fest@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.0.0.tgz#678e2e8d916e3b7dc1c3a6591d399ba3f7521584" + integrity sha512-MINvUN5ug9u+0hJDzSZNSnuKXI8M4F5Yvb6SQZ2CYqe7SgKXKOosEcU5R7tRgo85I6eAVBbkVF7TCvB4AUK2xQ== + typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -3706,10 +3711,10 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.3.tgz#39062d8019912d43726298f09493d598048c1ce3" - integrity sha512-qOcYwxaByStAWrBf4x0fibwZvMRG+r4cQoTjbPtUlrWjBHbmCAww1i448U0GJ+3cNNEtebDteo/cHOR3xJ4wEw== +typescript@^4.8.3: + version "4.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.3.tgz#d59344522c4bc464a65a730ac695007fdb66dd88" + integrity sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig== union-value@^1.0.0: version "1.0.1" From 2c54597b68bb20895c6a78ab4129e56dc5a37ab4 Mon Sep 17 00:00:00 2001 From: Vladislav Zimnikov Date: Tue, 27 Sep 2022 13:27:23 +0300 Subject: [PATCH 2/4] Improved TS typing capabilities - Fixed import paths in tests - Skipped one test as it relies on mutation that does not exist anymore --- src/__tests__/Calculated.test.ts | 2 +- src/__tests__/Client.test.ts | 5 +++-- src/__tests__/Client2.test.ts | 2 +- src/__tests__/CombinedField.test.ts | 2 +- src/__tests__/DataType.test.ts | 2 +- src/__tests__/Field.test.ts | 2 +- src/__tests__/InlineFragment.test.ts | 2 +- src/__tests__/Mutation.test.ts | 2 +- src/__tests__/Query.test.ts | 2 +- 9 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/__tests__/Calculated.test.ts b/src/__tests__/Calculated.test.ts index 26b7407..384129e 100644 --- a/src/__tests__/Calculated.test.ts +++ b/src/__tests__/Calculated.test.ts @@ -1,4 +1,4 @@ -import { client, Query, Field } from '../..'; +import { client, Query, Field } from '../index'; const ONE_KG_IN_LBS = 2.20462; diff --git a/src/__tests__/Client.test.ts b/src/__tests__/Client.test.ts index d779893..1a8396e 100644 --- a/src/__tests__/Client.test.ts +++ b/src/__tests__/Client.test.ts @@ -5,7 +5,7 @@ import { Query, CombinedField, InlineFragment -} from '../../src'; +} from '../'; client.setEndpoint('https://api.spacex.land/graphql/'); @@ -55,7 +55,8 @@ describe('data is fetched correctly', () => { } }); - it('is able to fetch mutations', async () => { + // Used service does not provide mutations anymore + it.skip('is able to fetch mutations', async () => { const result = await client.post(insertUserMutation); expect(result).toBeDefined(); diff --git a/src/__tests__/Client2.test.ts b/src/__tests__/Client2.test.ts index b553cf4..ca1c64a 100644 --- a/src/__tests__/Client2.test.ts +++ b/src/__tests__/Client2.test.ts @@ -2,7 +2,7 @@ import { client, Field, Query, -} from '../../src'; +} from '../'; /** * diff --git a/src/__tests__/CombinedField.test.ts b/src/__tests__/CombinedField.test.ts index 7d5cf4e..422effd 100644 --- a/src/__tests__/CombinedField.test.ts +++ b/src/__tests__/CombinedField.test.ts @@ -1,4 +1,4 @@ -import { Mutation, Query, CombinedField } from "../.."; +import { Mutation, Query, CombinedField } from "../"; describe('combined fields are built', () => { it('builds combined queries', () => { diff --git a/src/__tests__/DataType.test.ts b/src/__tests__/DataType.test.ts index 027d8b8..94461c5 100644 --- a/src/__tests__/DataType.test.ts +++ b/src/__tests__/DataType.test.ts @@ -1,4 +1,4 @@ -import { DataType, Mutation, Query, Field, CombinedField } from "../.."; +import { DataType, Mutation, Query, Field, CombinedField } from "../"; const query = new Query('person') .addField('name') diff --git a/src/__tests__/Field.test.ts b/src/__tests__/Field.test.ts index 022b55f..6172f11 100644 --- a/src/__tests__/Field.test.ts +++ b/src/__tests__/Field.test.ts @@ -1,4 +1,4 @@ -import { Field, InlineFragment } from "../.."; +import { Field, InlineFragment } from "../"; describe('field is built', () => { it('adds array fields', () => { diff --git a/src/__tests__/InlineFragment.test.ts b/src/__tests__/InlineFragment.test.ts index 32fd727..ebf866e 100644 --- a/src/__tests__/InlineFragment.test.ts +++ b/src/__tests__/InlineFragment.test.ts @@ -1,4 +1,4 @@ -import { InlineFragment } from "../.."; +import { InlineFragment } from "../"; describe('inline fragment is built', () => { it('builds inline fragments', () => { diff --git a/src/__tests__/Mutation.test.ts b/src/__tests__/Mutation.test.ts index 017c608..36d6e47 100644 --- a/src/__tests__/Mutation.test.ts +++ b/src/__tests__/Mutation.test.ts @@ -1,4 +1,4 @@ -import { Mutation } from "../.."; +import { Mutation } from "../"; describe('mutations are built', () => { it('builds a mutation', () => { diff --git a/src/__tests__/Query.test.ts b/src/__tests__/Query.test.ts index 719f9a0..7174b40 100644 --- a/src/__tests__/Query.test.ts +++ b/src/__tests__/Query.test.ts @@ -1,4 +1,4 @@ -import { Query } from "../.."; +import { Query } from "../"; describe('queries are built', () => { it('builds a query', () => { From d0215541f0b295fc781d2aee7ab77e57c84a31ac Mon Sep 17 00:00:00 2001 From: Vladislav Zimnikov Date: Tue, 27 Sep 2022 15:57:42 +0300 Subject: [PATCH 3/4] Reverted import paths of tests --- src/__tests__/Calculated.test.ts | 2 +- src/__tests__/Client.test.ts | 2 +- src/__tests__/Client2.test.ts | 2 +- src/__tests__/CombinedField.test.ts | 2 +- src/__tests__/DataType.test.ts | 2 +- src/__tests__/Field.test.ts | 2 +- src/__tests__/InlineFragment.test.ts | 2 +- src/__tests__/Mutation.test.ts | 2 +- src/__tests__/Query.test.ts | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/__tests__/Calculated.test.ts b/src/__tests__/Calculated.test.ts index 384129e..26b7407 100644 --- a/src/__tests__/Calculated.test.ts +++ b/src/__tests__/Calculated.test.ts @@ -1,4 +1,4 @@ -import { client, Query, Field } from '../index'; +import { client, Query, Field } from '../..'; const ONE_KG_IN_LBS = 2.20462; diff --git a/src/__tests__/Client.test.ts b/src/__tests__/Client.test.ts index 1a8396e..2c938b8 100644 --- a/src/__tests__/Client.test.ts +++ b/src/__tests__/Client.test.ts @@ -5,7 +5,7 @@ import { Query, CombinedField, InlineFragment -} from '../'; +} from '../../src'; client.setEndpoint('https://api.spacex.land/graphql/'); diff --git a/src/__tests__/Client2.test.ts b/src/__tests__/Client2.test.ts index ca1c64a..b553cf4 100644 --- a/src/__tests__/Client2.test.ts +++ b/src/__tests__/Client2.test.ts @@ -2,7 +2,7 @@ import { client, Field, Query, -} from '../'; +} from '../../src'; /** * diff --git a/src/__tests__/CombinedField.test.ts b/src/__tests__/CombinedField.test.ts index 422effd..7d5cf4e 100644 --- a/src/__tests__/CombinedField.test.ts +++ b/src/__tests__/CombinedField.test.ts @@ -1,4 +1,4 @@ -import { Mutation, Query, CombinedField } from "../"; +import { Mutation, Query, CombinedField } from "../.."; describe('combined fields are built', () => { it('builds combined queries', () => { diff --git a/src/__tests__/DataType.test.ts b/src/__tests__/DataType.test.ts index 94461c5..027d8b8 100644 --- a/src/__tests__/DataType.test.ts +++ b/src/__tests__/DataType.test.ts @@ -1,4 +1,4 @@ -import { DataType, Mutation, Query, Field, CombinedField } from "../"; +import { DataType, Mutation, Query, Field, CombinedField } from "../.."; const query = new Query('person') .addField('name') diff --git a/src/__tests__/Field.test.ts b/src/__tests__/Field.test.ts index 6172f11..022b55f 100644 --- a/src/__tests__/Field.test.ts +++ b/src/__tests__/Field.test.ts @@ -1,4 +1,4 @@ -import { Field, InlineFragment } from "../"; +import { Field, InlineFragment } from "../.."; describe('field is built', () => { it('adds array fields', () => { diff --git a/src/__tests__/InlineFragment.test.ts b/src/__tests__/InlineFragment.test.ts index ebf866e..32fd727 100644 --- a/src/__tests__/InlineFragment.test.ts +++ b/src/__tests__/InlineFragment.test.ts @@ -1,4 +1,4 @@ -import { InlineFragment } from "../"; +import { InlineFragment } from "../.."; describe('inline fragment is built', () => { it('builds inline fragments', () => { diff --git a/src/__tests__/Mutation.test.ts b/src/__tests__/Mutation.test.ts index 36d6e47..017c608 100644 --- a/src/__tests__/Mutation.test.ts +++ b/src/__tests__/Mutation.test.ts @@ -1,4 +1,4 @@ -import { Mutation } from "../"; +import { Mutation } from "../.."; describe('mutations are built', () => { it('builds a mutation', () => { diff --git a/src/__tests__/Query.test.ts b/src/__tests__/Query.test.ts index 7174b40..719f9a0 100644 --- a/src/__tests__/Query.test.ts +++ b/src/__tests__/Query.test.ts @@ -1,4 +1,4 @@ -import { Query } from "../"; +import { Query } from "../.."; describe('queries are built', () => { it('builds a query', () => { From e7176d3a361fb588b77c84239d047796c16c3922 Mon Sep 17 00:00:00 2001 From: Vladislav Zimnikov Date: Tue, 27 Sep 2022 16:08:22 +0300 Subject: [PATCH 4/4] Removed type-fest library and simply copied over utility types' declaration --- package.json | 3 +-- src/builder/AbstractField.ts | 2 +- src/types/index.ts | 4 ++++ yarn.lock | 5 ----- 4 files changed, 6 insertions(+), 8 deletions(-) create mode 100644 src/types/index.ts diff --git a/package.json b/package.json index d6be7b4..28f5717 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,7 @@ }, "dependencies": { "node-fetch": "^2.6.2", - "tslib": "^2.2.0", - "type-fest": "^3.0.0" + "tslib": "^2.2.0" }, "devDependencies": { "@babel/core": "^7.13.15", diff --git a/src/builder/AbstractField.ts b/src/builder/AbstractField.ts index 71f6ca4..c108255 100644 --- a/src/builder/AbstractField.ts +++ b/src/builder/AbstractField.ts @@ -1,4 +1,4 @@ -import { EmptyObject, StringKeyOf } from 'type-fest'; +import { EmptyObject, StringKeyOf } from '../types'; import type { HigherKindType, FieldDescendantStore } from './hkt'; import type { InlineFragment } from './InlineFragment'; diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..9d9109b --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,4 @@ +export type StringKeyOf = `${Extract}`; + +declare const emptyObjectSymbol: unique symbol; +export type EmptyObject = {[emptyObjectSymbol]?: never}; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 5763ecf..725fa85 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3699,11 +3699,6 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== -type-fest@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.0.0.tgz#678e2e8d916e3b7dc1c3a6591d399ba3f7521584" - integrity sha512-MINvUN5ug9u+0hJDzSZNSnuKXI8M4F5Yvb6SQZ2CYqe7SgKXKOosEcU5R7tRgo85I6eAVBbkVF7TCvB4AUK2xQ== - typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"