diff --git a/examples/$/generated-clients/pokemon/_.ts b/examples/$/generated-clients/pokemon/_.ts index 36750f260..0d3b8d175 100644 --- a/examples/$/generated-clients/pokemon/_.ts +++ b/examples/$/generated-clients/pokemon/_.ts @@ -6,6 +6,4 @@ import './modules/Global.js' export { create } from './modules/Client.js' export { isError } from './modules/Error.js' -export { $Index as schemaModel } from './modules/SchemaRuntime.js' export { Select } from './modules/Select.js' -export * as SelectionSets from './modules/SelectionSets.js' diff --git a/examples/$/generated-clients/pokemon/modules/SchemaBuildtime.ts b/examples/$/generated-clients/pokemon/modules/SchemaBuildtime.ts index 343c6d033..4a79c1377 100644 --- a/examples/$/generated-clients/pokemon/modules/SchemaBuildtime.ts +++ b/examples/$/generated-clients/pokemon/modules/SchemaBuildtime.ts @@ -50,7 +50,13 @@ export namespace Enum { // InputObject // // ------------------------------------------------------------ // export namespace InputObject { + export type DateFilter = $.InputObject<'DateFilter', { + gte: $.Input.Field<$.Input.Nullable<$Scalar.Float>> + lte: $.Input.Field<$.Input.Nullable<$Scalar.Float>> + }, true> + export type PokemonFilter = $.InputObject<'PokemonFilter', { + birthday: $.Input.Field<$.Input.Nullable> name: $.Input.Field<$.Input.Nullable> }, true> @@ -71,6 +77,7 @@ export namespace Interface { export namespace Object { export type Pokemon = $.Object$2<'Pokemon', { attack: $.Field<$.Output.Nullable<$Scalar.Int>, null> + birthday: $.Field<$.Output.Nullable<$Scalar.Int>, null> defense: $.Field<$.Output.Nullable<$Scalar.Int>, null> hp: $.Field<$.Output.Nullable<$Scalar.Int>, null> id: $.Field<$.Output.Nullable<$Scalar.Int>, null> diff --git a/examples/$/generated-clients/pokemon/modules/SchemaRuntime.ts b/examples/$/generated-clients/pokemon/modules/SchemaRuntime.ts index 8d37e8d03..133252885 100644 --- a/examples/$/generated-clients/pokemon/modules/SchemaRuntime.ts +++ b/examples/$/generated-clients/pokemon/modules/SchemaRuntime.ts @@ -5,7 +5,13 @@ import * as $Scalar from './Scalar.js' import type { Index } from './SchemaIndex.js' export const $defaultSchemaUrl = new URL('http://localhost:3000/graphql') +export const DateFilter = $.InputObject(`DateFilter`, { + gte: $.Input.Field($.Input.Nullable($Scalar.Float)), + lte: $.Input.Field($.Input.Nullable($Scalar.Float)), +}, true) + export const PokemonFilter = $.InputObject(`PokemonFilter`, { + birthday: $.Input.Field(() => $.Input.Nullable(DateFilter)), name: $.Input.Field(() => $.Input.Nullable(StringFilter)), }, true) @@ -16,6 +22,7 @@ export const StringFilter = $.InputObject(`StringFilter`, { // @ts-ignore - circular types cannot infer. Ignore in case there are any. This comment is always added, it does not indicate if this particular type could infer or not. export const Pokemon = $.Object$(`Pokemon`, { attack: $.field($.Output.Nullable($Scalar.Int)), + birthday: $.field($.Output.Nullable($Scalar.Int)), defense: $.field($.Output.Nullable($Scalar.Int)), hp: $.field($.Output.Nullable($Scalar.Int)), id: $.field($.Output.Nullable($Scalar.Int)), diff --git a/examples/$/generated-clients/pokemon/modules/SelectionSets.ts b/examples/$/generated-clients/pokemon/modules/SelectionSets.ts index d7fb35ab5..153c91458 100644 --- a/examples/$/generated-clients/pokemon/modules/SelectionSets.ts +++ b/examples/$/generated-clients/pokemon/modules/SelectionSets.ts @@ -186,7 +186,13 @@ export namespace Query { // // +export interface DateFilter { + gte?: number | undefined | null + lte?: number | undefined | null +} + export interface PokemonFilter { + birthday?: _RefDefs._DateFilter | undefined | null name?: _RefDefs._StringFilter | undefined | null } @@ -230,6 +236,10 @@ export interface Pokemon extends $SelectionSet.Bases.ObjectLike { * Select the `attack` field on the `Pokemon` object. Its type is `Int` (a `Scalar`). */ attack?: Pokemon.attack$Expanded | $SelectionSet.AliasInput + /** + * Select the `birthday` field on the `Pokemon` object. Its type is `Int` (a `Scalar`). + */ + birthday?: Pokemon.birthday$Expanded | $SelectionSet.AliasInput /** * Select the `defense` field on the `Pokemon` object. Its type is `Int` (a `Scalar`). */ @@ -278,6 +288,10 @@ export namespace Pokemon { export type attack = $SelectionSet.Indicator.NoArgsIndicator + export type birthday$Expanded = $SelectionSet.Indicator.NoArgsIndicator$Expanded + + export type birthday = $SelectionSet.Indicator.NoArgsIndicator + export type defense$Expanded = $SelectionSet.Indicator.NoArgsIndicator$Expanded export type defense = $SelectionSet.Indicator.NoArgsIndicator @@ -371,6 +385,7 @@ export namespace Trainer { export namespace _RefDefs { export type _Mutation = Mutation export type _Query = Query + export type _DateFilter = DateFilter export type _PokemonFilter = PokemonFilter export type _StringFilter = StringFilter export type _Pokemon = Pokemon diff --git a/examples/$/schemas/pokemon/data.ts b/examples/$/schemas/pokemon/data.ts index 52c505b12..0310690ad 100644 --- a/examples/$/schemas/pokemon/data.ts +++ b/examples/$/schemas/pokemon/data.ts @@ -1,3 +1,6 @@ +const day = 1000 * 60 * 60 * 24 +const year = day * 365.25 + export namespace DatabaseServer { export interface Trainer { id: number @@ -10,6 +13,10 @@ export namespace DatabaseServer { hp: number attack: number defense: number + /** + * Milliseconds since Unix epoch. + */ + birthday: number trainerId: number | null // Nullable, as a Pokémon may not be captured by a trainer } @@ -50,11 +57,12 @@ export namespace DatabaseServer { database.trainers.push(ash, misty) + // dprint-ignore database.pokemon.push( - { id: 1, name: `Pikachu`, hp: 35, attack: 55, defense: 40, trainerId: 1 }, - { id: 2, name: `Charizard`, hp: 78, attack: 84, defense: 78, trainerId: 1 }, - { id: 3, name: `Squirtle`, hp: 44, attack: 48, defense: 65, trainerId: 2 }, - { id: 4, name: `Bulbasaur`, hp: 45, attack: 49, defense: 49, trainerId: null }, + { id: 1, name: `Pikachu`, hp: 35, attack: 55, defense: 40, trainerId: 1, birthday: new Date('1850').getTime() }, + { id: 2, name: `Charizard`, hp: 78, attack: 84, defense: 78, trainerId: 1, birthday: new Date(Date.now() - day * 5).getTime() }, + { id: 3, name: `Squirtle`, hp: 44, attack: 48, defense: 65, trainerId: 2, birthday: new Date('1910').getTime() }, + { id: 4, name: `Bulbasaur`, hp: 45, attack: 49, defense: 49, trainerId: null, birthday: new Date('2000').getTime() }, ) } } diff --git a/examples/$/schemas/pokemon/schema.graphql b/examples/$/schemas/pokemon/schema.graphql index f946996d8..24a29e947 100644 --- a/examples/$/schemas/pokemon/schema.graphql +++ b/examples/$/schemas/pokemon/schema.graphql @@ -1,9 +1,15 @@ +input DateFilter { + gte: Float + lte: Float +} + type Mutation { addPokemon(attack: Int!, defense: Int!, hp: Int!, name: String!): Pokemon } type Pokemon { attack: Int + birthday: Int defense: Int hp: Int id: Int @@ -12,6 +18,7 @@ type Pokemon { } input PokemonFilter { + birthday: DateFilter name: StringFilter } diff --git a/examples/$/schemas/pokemon/schema.ts b/examples/$/schemas/pokemon/schema.ts index f0b2234b4..f70c6c808 100644 --- a/examples/$/schemas/pokemon/schema.ts +++ b/examples/$/schemas/pokemon/schema.ts @@ -31,6 +31,7 @@ const Pokemon = builder.objectRef(`Pokemon`).implement({ hp: t.int({ resolve: (pokemon) => pokemon.hp }), attack: t.int({ resolve: (pokemon) => pokemon.attack }), defense: t.int({ resolve: (pokemon) => pokemon.defense }), + birthday: t.int({ resolve: (pokemon) => pokemon.birthday }), trainer: t.field({ type: Trainer, nullable: true, @@ -58,9 +59,17 @@ const StringFilter = builder.inputType(`StringFilter`, { }), }) +const DateFilter = builder.inputType(`DateFilter`, { + fields: (t) => ({ + lte: t.float(), + gte: t.float(), + }), +}) + const PokemonFilter = builder.inputType(`PokemonFilter`, { fields: (t) => ({ name: t.field({ type: StringFilter }), + birthday: t.field({ type: DateFilter }), }), }) @@ -80,6 +89,14 @@ builder.queryField(`pokemons`, (t) => return args.filter.name.in.includes(p.name) } } + if (args.filter?.birthday) { + if (args.filter.birthday.lte) { + return p.birthday <= args.filter.birthday.lte + } + if (args.filter.birthday.gte) { + return p.birthday >= args.filter.birthday.gte + } + } return true }), })) @@ -135,6 +152,7 @@ builder.mutationField(`addPokemon`, (t) => attack, defense, trainerId: null, + birthday: new Date().getTime(), } DatabaseServer.tenant(ctx.tenant).pokemon.push(newPokemon) return newPokemon diff --git a/examples/55_generated/generated_alias__alias.ts b/examples/55_generated/generated_alias__alias.ts new file mode 100644 index 000000000..1a973577b --- /dev/null +++ b/examples/55_generated/generated_alias__alias.ts @@ -0,0 +1,28 @@ +/** + * This example shows how to write GraphQL aliases in the TypeScript interface. + */ + +import { Pokemon } from '../$/generated-clients/pokemon/__.js' +import { showJson } from '../$/helpers.js' + +const pokemon = Pokemon.create() + +const day = 1000 * 60 * 60 * 24 +const year = day * 365.25 +const yearsAgo100 = new Date(Date.now() - year * 100).getTime() +const yearsAgo1 = new Date(Date.now() - year).getTime() + +const pokemons = await pokemon.query.$batch({ + pokemons: [ + [`elderPokemons`, { + $: { filter: { birthday: { lte: yearsAgo100 } } }, + name: true, + }], + [`babyPokemons`, { + $: { filter: { birthday: { gte: yearsAgo1 } } }, + name: true, + }], + ], +}) + +showJson(pokemons) diff --git a/examples/55_generated/generated_arguments__arguments.ts b/examples/55_generated/generated_arguments__arguments.ts index 0e4957c58..4ae137701 100644 --- a/examples/55_generated/generated_arguments__arguments.ts +++ b/examples/55_generated/generated_arguments__arguments.ts @@ -1,5 +1,5 @@ /** - * This example shows how to use the TypeScript interface for GraphQL arguments. + * This example shows how to write field arguments in TypeScript interface. */ import { Pokemon } from '../$/generated-clients/pokemon/__.js' diff --git a/examples/55_generated/generated_document__document.ts b/examples/55_generated/generated_document__document.ts index 97dfdd4d2..10d1482d7 100644 --- a/examples/55_generated/generated_document__document.ts +++ b/examples/55_generated/generated_document__document.ts @@ -1,5 +1,5 @@ /** - * This example shows how to use the TypeScript interface for whole GraphQL documents. + * This example shows how to write whole GraphQL documents in the TypeScript interface. */ import { Pokemon } from '../$/generated-clients/pokemon/__.js' diff --git a/examples/__outputs__/10_transport-http/transport-http_extension_headers__dynamicHeaders.output.txt b/examples/__outputs__/10_transport-http/transport-http_extension_headers__dynamicHeaders.output.txt index 903ca652f..84eb21300 100644 --- a/examples/__outputs__/10_transport-http/transport-http_extension_headers__dynamicHeaders.output.txt +++ b/examples/__outputs__/10_transport-http/transport-http_extension_headers__dynamicHeaders.output.txt @@ -4,7 +4,7 @@ headers: Headers { accept: 'application/graphql-response+json; charset=utf-8, application/json; charset=utf-8', 'content-type': 'application/json', - 'x-sent-at-time': '1727365576054' + 'x-sent-at-time': '1727369127674' }, signal: undefined, method: 'post', diff --git a/examples/__outputs__/20_output/output_envelope.output.txt b/examples/__outputs__/20_output/output_envelope.output.txt index 233b5675a..96410999d 100644 --- a/examples/__outputs__/20_output/output_envelope.output.txt +++ b/examples/__outputs__/20_output/output_envelope.output.txt @@ -16,7 +16,7 @@ headers: Headers { 'content-type': 'application/graphql-response+json; charset=utf-8', 'content-length': '104', - date: 'Thu, 26 Sep 2024 15:46:16 GMT', + date: 'Thu, 26 Sep 2024 16:45:27 GMT', connection: 'keep-alive', 'keep-alive': 'timeout=5' }, diff --git a/examples/__outputs__/55_generated/generated_alias__alias.output.txt b/examples/__outputs__/55_generated/generated_alias__alias.output.txt new file mode 100644 index 000000000..395b487de --- /dev/null +++ b/examples/__outputs__/55_generated/generated_alias__alias.output.txt @@ -0,0 +1,16 @@ +---------------------------------------- SHOW ---------------------------------------- +{ + "elderPokemons": [ + { + "name": "Pikachu" + }, + { + "name": "Squirtle" + } + ], + "babyPokemons": [ + { + "name": "Charizard" + } + ] +} \ No newline at end of file diff --git a/examples/__outputs__/60_extension/extension_opentelemetry__opentelemetry.output.txt b/examples/__outputs__/60_extension/extension_opentelemetry__opentelemetry.output.txt index 485a9e71a..259b5c8b2 100644 --- a/examples/__outputs__/60_extension/extension_opentelemetry__opentelemetry.output.txt +++ b/examples/__outputs__/60_extension/extension_opentelemetry__opentelemetry.output.txt @@ -9,14 +9,14 @@ } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', - parentId: 'fb04e4436519eebf', + traceId: '660addf19135864ad1ddc84d4197c202', + parentId: '4c9f8b8bd265ed58', traceState: undefined, name: 'encode', - id: 'b9cc31cb6dcef7bb', + id: 'c6d3e0add3fd1ca9', kind: 0, - timestamp: 1727365576823000, - duration: 586.292, + timestamp: 1727369128233000, + duration: 695.792, attributes: {}, status: { code: 0 }, events: [], @@ -33,14 +33,14 @@ } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', - parentId: 'fb04e4436519eebf', + traceId: '660addf19135864ad1ddc84d4197c202', + parentId: '4c9f8b8bd265ed58', traceState: undefined, name: 'pack', - id: 'fb77c65e19244b1f', + id: 'd5d5a381568322a1', kind: 0, - timestamp: 1727365576831000, - duration: 19896.75, + timestamp: 1727369128235000, + duration: 11409.958, attributes: {}, status: { code: 0 }, events: [], @@ -57,14 +57,14 @@ } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', - parentId: 'fb04e4436519eebf', + traceId: '660addf19135864ad1ddc84d4197c202', + parentId: '4c9f8b8bd265ed58', traceState: undefined, name: 'exchange', - id: '7e3a75386432d606', + id: 'ed3488dc296fd725', kind: 0, - timestamp: 1727365576852000, - duration: 29439.625, + timestamp: 1727369128247000, + duration: 21327.5, attributes: {}, status: { code: 0 }, events: [], @@ -81,14 +81,14 @@ } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', - parentId: 'fb04e4436519eebf', + traceId: '660addf19135864ad1ddc84d4197c202', + parentId: '4c9f8b8bd265ed58', traceState: undefined, name: 'unpack', - id: '6263aef06e4164d0', + id: 'f279d86c6c9fa36f', kind: 0, - timestamp: 1727365576881000, - duration: 1157, + timestamp: 1727369128269000, + duration: 1252.958, attributes: {}, status: { code: 0 }, events: [], @@ -105,14 +105,14 @@ } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', - parentId: 'fb04e4436519eebf', + traceId: '660addf19135864ad1ddc84d4197c202', + parentId: '4c9f8b8bd265ed58', traceState: undefined, name: 'decode', - id: 'f6e875f59111e613', + id: 'e10efeff511097b9', kind: 0, - timestamp: 1727365576883000, - duration: 193.042, + timestamp: 1727369128271000, + duration: 302.166, attributes: {}, status: { code: 0 }, events: [], @@ -129,14 +129,14 @@ } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', + traceId: '660addf19135864ad1ddc84d4197c202', parentId: undefined, traceState: undefined, name: 'request', - id: 'fb04e4436519eebf', + id: '4c9f8b8bd265ed58', kind: 0, - timestamp: 1727365576822000, - duration: 61277.208, + timestamp: 1727369128232000, + duration: 39141.875, attributes: {}, status: { code: 0 }, events: [], diff --git a/tests/examples/55_generated/generated_alias__alias.test.ts b/tests/examples/55_generated/generated_alias__alias.test.ts new file mode 100644 index 000000000..619a3918d --- /dev/null +++ b/tests/examples/55_generated/generated_alias__alias.test.ts @@ -0,0 +1,19 @@ +// @vitest-environment node + +// WARNING: +// This test is generated by scripts/generate-example-derivatives/generate.ts +// Do not modify this file directly. + +import { expect, test } from 'vitest' +import { runExample } from '../../../scripts/generate-examples-derivatives/helpers.js' + +test(`generated_alias__alias`, async () => { + const exampleResult = await runExample(`./examples/55_generated/generated_alias__alias.ts`) + // Examples should output their data results. + const exampleResultMaybeEncoded = exampleResult + // If ever outputs vary by Node version, you can use this to snapshot by Node version. + // const nodeMajor = process.version.match(/v(\d+)/)?.[1] ?? `unknown` + await expect(exampleResultMaybeEncoded).toMatchFileSnapshot( + `../../../examples/__outputs__/55_generated/generated_alias__alias.output.txt`, + ) +}) diff --git a/website/content/_snippets/example-links/alias.md b/website/content/_snippets/example-links/alias.md new file mode 100644 index 000000000..102306e1a --- /dev/null +++ b/website/content/_snippets/example-links/alias.md @@ -0,0 +1 @@ + diff --git a/website/content/_snippets/example-links/generated.md b/website/content/_snippets/example-links/generated.md index d01922a9e..8b5c08a70 100644 --- a/website/content/_snippets/example-links/generated.md +++ b/website/content/_snippets/example-links/generated.md @@ -1 +1 @@ - + diff --git a/website/content/_snippets/example-links/generated_alias.md b/website/content/_snippets/example-links/generated_alias.md new file mode 100644 index 000000000..102306e1a --- /dev/null +++ b/website/content/_snippets/example-links/generated_alias.md @@ -0,0 +1 @@ + diff --git a/website/content/_snippets/examples/extension/opentelemetry.detail.md b/website/content/_snippets/examples/extension/opentelemetry.detail.md index e2af1bd7a..7641e0851 100644 --- a/website/content/_snippets/examples/extension/opentelemetry.detail.md +++ b/website/content/_snippets/examples/extension/opentelemetry.detail.md @@ -38,14 +38,14 @@ console.log(data) } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', - parentId: 'fb04e4436519eebf', + traceId: '660addf19135864ad1ddc84d4197c202', + parentId: '4c9f8b8bd265ed58', traceState: undefined, name: 'encode', - id: 'b9cc31cb6dcef7bb', + id: 'c6d3e0add3fd1ca9', kind: 0, - timestamp: 1727365576823000, - duration: 586.292, + timestamp: 1727369128233000, + duration: 695.792, attributes: {}, status: { code: 0 }, events: [], @@ -65,14 +65,14 @@ console.log(data) } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', - parentId: 'fb04e4436519eebf', + traceId: '660addf19135864ad1ddc84d4197c202', + parentId: '4c9f8b8bd265ed58', traceState: undefined, name: 'pack', - id: 'fb77c65e19244b1f', + id: 'd5d5a381568322a1', kind: 0, - timestamp: 1727365576831000, - duration: 19896.75, + timestamp: 1727369128235000, + duration: 11409.958, attributes: {}, status: { code: 0 }, events: [], @@ -92,14 +92,14 @@ console.log(data) } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', - parentId: 'fb04e4436519eebf', + traceId: '660addf19135864ad1ddc84d4197c202', + parentId: '4c9f8b8bd265ed58', traceState: undefined, name: 'exchange', - id: '7e3a75386432d606', + id: 'ed3488dc296fd725', kind: 0, - timestamp: 1727365576852000, - duration: 29439.625, + timestamp: 1727369128247000, + duration: 21327.5, attributes: {}, status: { code: 0 }, events: [], @@ -119,14 +119,14 @@ console.log(data) } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', - parentId: 'fb04e4436519eebf', + traceId: '660addf19135864ad1ddc84d4197c202', + parentId: '4c9f8b8bd265ed58', traceState: undefined, name: 'unpack', - id: '6263aef06e4164d0', + id: 'f279d86c6c9fa36f', kind: 0, - timestamp: 1727365576881000, - duration: 1157, + timestamp: 1727369128269000, + duration: 1252.958, attributes: {}, status: { code: 0 }, events: [], @@ -146,14 +146,14 @@ console.log(data) } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', - parentId: 'fb04e4436519eebf', + traceId: '660addf19135864ad1ddc84d4197c202', + parentId: '4c9f8b8bd265ed58', traceState: undefined, name: 'decode', - id: 'f6e875f59111e613', + id: 'e10efeff511097b9', kind: 0, - timestamp: 1727365576883000, - duration: 193.042, + timestamp: 1727369128271000, + duration: 302.166, attributes: {}, status: { code: 0 }, events: [], @@ -173,14 +173,14 @@ console.log(data) } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', + traceId: '660addf19135864ad1ddc84d4197c202', parentId: undefined, traceState: undefined, name: 'request', - id: 'fb04e4436519eebf', + id: '4c9f8b8bd265ed58', kind: 0, - timestamp: 1727365576822000, - duration: 61277.208, + timestamp: 1727369128232000, + duration: 39141.875, attributes: {}, status: { code: 0 }, events: [], diff --git a/website/content/_snippets/examples/extension/opentelemetry.md b/website/content/_snippets/examples/extension/opentelemetry.md index e0f04bf97..f4eab63ed 100644 --- a/website/content/_snippets/examples/extension/opentelemetry.md +++ b/website/content/_snippets/examples/extension/opentelemetry.md @@ -36,14 +36,14 @@ console.log(data) } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', - parentId: 'fb04e4436519eebf', + traceId: '660addf19135864ad1ddc84d4197c202', + parentId: '4c9f8b8bd265ed58', traceState: undefined, name: 'encode', - id: 'b9cc31cb6dcef7bb', + id: 'c6d3e0add3fd1ca9', kind: 0, - timestamp: 1727365576823000, - duration: 586.292, + timestamp: 1727369128233000, + duration: 695.792, attributes: {}, status: { code: 0 }, events: [], @@ -63,14 +63,14 @@ console.log(data) } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', - parentId: 'fb04e4436519eebf', + traceId: '660addf19135864ad1ddc84d4197c202', + parentId: '4c9f8b8bd265ed58', traceState: undefined, name: 'pack', - id: 'fb77c65e19244b1f', + id: 'd5d5a381568322a1', kind: 0, - timestamp: 1727365576831000, - duration: 19896.75, + timestamp: 1727369128235000, + duration: 11409.958, attributes: {}, status: { code: 0 }, events: [], @@ -90,14 +90,14 @@ console.log(data) } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', - parentId: 'fb04e4436519eebf', + traceId: '660addf19135864ad1ddc84d4197c202', + parentId: '4c9f8b8bd265ed58', traceState: undefined, name: 'exchange', - id: '7e3a75386432d606', + id: 'ed3488dc296fd725', kind: 0, - timestamp: 1727365576852000, - duration: 29439.625, + timestamp: 1727369128247000, + duration: 21327.5, attributes: {}, status: { code: 0 }, events: [], @@ -117,14 +117,14 @@ console.log(data) } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', - parentId: 'fb04e4436519eebf', + traceId: '660addf19135864ad1ddc84d4197c202', + parentId: '4c9f8b8bd265ed58', traceState: undefined, name: 'unpack', - id: '6263aef06e4164d0', + id: 'f279d86c6c9fa36f', kind: 0, - timestamp: 1727365576881000, - duration: 1157, + timestamp: 1727369128269000, + duration: 1252.958, attributes: {}, status: { code: 0 }, events: [], @@ -144,14 +144,14 @@ console.log(data) } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', - parentId: 'fb04e4436519eebf', + traceId: '660addf19135864ad1ddc84d4197c202', + parentId: '4c9f8b8bd265ed58', traceState: undefined, name: 'decode', - id: 'f6e875f59111e613', + id: 'e10efeff511097b9', kind: 0, - timestamp: 1727365576883000, - duration: 193.042, + timestamp: 1727369128271000, + duration: 302.166, attributes: {}, status: { code: 0 }, events: [], @@ -171,14 +171,14 @@ console.log(data) } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', + traceId: '660addf19135864ad1ddc84d4197c202', parentId: undefined, traceState: undefined, name: 'request', - id: 'fb04e4436519eebf', + id: '4c9f8b8bd265ed58', kind: 0, - timestamp: 1727365576822000, - duration: 61277.208, + timestamp: 1727369128232000, + duration: 39141.875, attributes: {}, status: { code: 0 }, events: [], diff --git a/website/content/_snippets/examples/generated/alias.detail.md b/website/content/_snippets/examples/generated/alias.detail.md new file mode 100644 index 000000000..2df974b58 --- /dev/null +++ b/website/content/_snippets/examples/generated/alias.detail.md @@ -0,0 +1,56 @@ +::: details Example + +
+Alias + + +```ts twoslash +// ---cut--- +import { Pokemon } from './pokemon/__.js' + +const pokemon = Pokemon.create() + +const day = 1000 * 60 * 60 * 24 +const year = day * 365.25 +const yearsAgo100 = new Date(Date.now() - year * 100).getTime() +const yearsAgo1 = new Date(Date.now() - year).getTime() + +const pokemons = await pokemon.query.$batch({ + pokemons: [ + [`elderPokemons`, { + $: { filter: { birthday: { lte: yearsAgo100 } } }, + name: true, + }], + [`babyPokemons`, { + $: { filter: { birthday: { gte: yearsAgo1 } } }, + name: true, + }], + ], +}) + +console.log(pokemons) +``` + + + +```json +{ + "elderPokemons": [ + { + "name": "Pikachu" + }, + { + "name": "Squirtle" + } + ], + "babyPokemons": [ + { + "name": "Charizard" + } + ] +} +``` + + +
+::: diff --git a/website/content/_snippets/examples/generated/alias.md b/website/content/_snippets/examples/generated/alias.md new file mode 100644 index 000000000..6f1e3fd46 --- /dev/null +++ b/website/content/_snippets/examples/generated/alias.md @@ -0,0 +1,53 @@ +
+Alias + + +```ts twoslash +// ---cut--- +import { Pokemon } from './pokemon/__.js' + +const pokemon = Pokemon.create() + +const day = 1000 * 60 * 60 * 24 +const year = day * 365.25 +const yearsAgo100 = new Date(Date.now() - year * 100).getTime() +const yearsAgo1 = new Date(Date.now() - year).getTime() + +const pokemons = await pokemon.query.$batch({ + pokemons: [ + [`elderPokemons`, { + $: { filter: { birthday: { lte: yearsAgo100 } } }, + name: true, + }], + [`babyPokemons`, { + $: { filter: { birthday: { gte: yearsAgo1 } } }, + name: true, + }], + ], +}) + +console.log(pokemons) +``` + + + +```json +{ + "elderPokemons": [ + { + "name": "Pikachu" + }, + { + "name": "Squirtle" + } + ], + "babyPokemons": [ + { + "name": "Charizard" + } + ] +} +``` + + +
diff --git a/website/content/_snippets/examples/output/envelope.detail.md b/website/content/_snippets/examples/output/envelope.detail.md index f315fced4..b9efc0377 100644 --- a/website/content/_snippets/examples/output/envelope.detail.md +++ b/website/content/_snippets/examples/output/envelope.detail.md @@ -39,7 +39,7 @@ console.log(result) headers: Headers { 'content-type': 'application/graphql-response+json; charset=utf-8', 'content-length': '104', - date: 'Thu, 26 Sep 2024 15:46:16 GMT', + date: 'Thu, 26 Sep 2024 16:45:27 GMT', connection: 'keep-alive', 'keep-alive': 'timeout=5' }, diff --git a/website/content/_snippets/examples/output/envelope.md b/website/content/_snippets/examples/output/envelope.md index ddd0322b3..a8ea3aa54 100644 --- a/website/content/_snippets/examples/output/envelope.md +++ b/website/content/_snippets/examples/output/envelope.md @@ -37,7 +37,7 @@ console.log(result) headers: Headers { 'content-type': 'application/graphql-response+json; charset=utf-8', 'content-length': '104', - date: 'Thu, 26 Sep 2024 15:46:16 GMT', + date: 'Thu, 26 Sep 2024 16:45:27 GMT', connection: 'keep-alive', 'keep-alive': 'timeout=5' }, diff --git a/website/content/_snippets/examples/transport-http/dynamic-headers.detail.md b/website/content/_snippets/examples/transport-http/dynamic-headers.detail.md index 4bc21d9be..3c6e4545a 100644 --- a/website/content/_snippets/examples/transport-http/dynamic-headers.detail.md +++ b/website/content/_snippets/examples/transport-http/dynamic-headers.detail.md @@ -38,7 +38,7 @@ await graffle.rawString({ document: `{ pokemons { name } }` }) headers: Headers { accept: 'application/graphql-response+json; charset=utf-8, application/json; charset=utf-8', 'content-type': 'application/json', - 'x-sent-at-time': '1727365576054' + 'x-sent-at-time': '1727369127674' }, signal: undefined, method: 'post', diff --git a/website/content/_snippets/examples/transport-http/dynamic-headers.md b/website/content/_snippets/examples/transport-http/dynamic-headers.md index ee7e707c3..a42082a94 100644 --- a/website/content/_snippets/examples/transport-http/dynamic-headers.md +++ b/website/content/_snippets/examples/transport-http/dynamic-headers.md @@ -36,7 +36,7 @@ await graffle.rawString({ document: `{ pokemons { name } }` }) headers: Headers { accept: 'application/graphql-response+json; charset=utf-8, application/json; charset=utf-8', 'content-type': 'application/json', - 'x-sent-at-time': '1727365576054' + 'x-sent-at-time': '1727369127674' }, signal: undefined, method: 'post', diff --git a/website/content/examples/10_transport-http/dynamic-headers.md b/website/content/examples/10_transport-http/dynamic-headers.md index e0d97693b..cb0f10559 100644 --- a/website/content/examples/10_transport-http/dynamic-headers.md +++ b/website/content/examples/10_transport-http/dynamic-headers.md @@ -43,7 +43,7 @@ await graffle.rawString({ document: `{ pokemons { name } }` }) headers: Headers { accept: 'application/graphql-response+json; charset=utf-8, application/json; charset=utf-8', 'content-type': 'application/json', - 'x-sent-at-time': '1727365576054' + 'x-sent-at-time': '1727369127674' }, signal: undefined, method: 'post', diff --git a/website/content/examples/20_output/envelope.md b/website/content/examples/20_output/envelope.md index 1c1245700..cd7653bc1 100644 --- a/website/content/examples/20_output/envelope.md +++ b/website/content/examples/20_output/envelope.md @@ -44,7 +44,7 @@ console.log(result) headers: Headers { 'content-type': 'application/graphql-response+json; charset=utf-8', 'content-length': '104', - date: 'Thu, 26 Sep 2024 15:46:16 GMT', + date: 'Thu, 26 Sep 2024 16:45:27 GMT', connection: 'keep-alive', 'keep-alive': 'timeout=5' }, diff --git a/website/content/examples/55_generated/alias.md b/website/content/examples/55_generated/alias.md new file mode 100644 index 000000000..d62de334c --- /dev/null +++ b/website/content/examples/55_generated/alias.md @@ -0,0 +1,58 @@ +--- +aside: false +--- + +# Alias + +This example shows how to write GraphQL aliases in the TypeScript interface. + + +```ts twoslash +// ---cut--- +import { Pokemon } from './pokemon/__.js' + +const pokemon = Pokemon.create() + +const day = 1000 * 60 * 60 * 24 +const year = day * 365.25 +const yearsAgo100 = new Date(Date.now() - year * 100).getTime() +const yearsAgo1 = new Date(Date.now() - year).getTime() + +const pokemons = await pokemon.query.$batch({ + pokemons: [ + [`elderPokemons`, { + $: { filter: { birthday: { lte: yearsAgo100 } } }, + name: true, + }], + [`babyPokemons`, { + $: { filter: { birthday: { gte: yearsAgo1 } } }, + name: true, + }], + ], +}) + +console.log(pokemons) +``` + + +#### Outputs + + +```json +{ + "elderPokemons": [ + { + "name": "Pikachu" + }, + { + "name": "Squirtle" + } + ], + "babyPokemons": [ + { + "name": "Charizard" + } + ] +} +``` + diff --git a/website/content/examples/55_generated/arguments.md b/website/content/examples/55_generated/arguments.md index 1241f97fc..3408f8c96 100644 --- a/website/content/examples/55_generated/arguments.md +++ b/website/content/examples/55_generated/arguments.md @@ -4,7 +4,7 @@ aside: false # Arguments -This example shows how to use the TypeScript interface for GraphQL arguments. +This example shows how to write field arguments in TypeScript interface. ```ts twoslash diff --git a/website/content/examples/55_generated/document.md b/website/content/examples/55_generated/document.md index 54e8450d6..298eaf156 100644 --- a/website/content/examples/55_generated/document.md +++ b/website/content/examples/55_generated/document.md @@ -4,7 +4,7 @@ aside: false # Document -This example shows how to use the TypeScript interface for whole GraphQL documents. +This example shows how to write whole GraphQL documents in the TypeScript interface. ```ts twoslash diff --git a/website/content/examples/60_extension/opentelemetry.md b/website/content/examples/60_extension/opentelemetry.md index b67953677..eccc1c2fb 100644 --- a/website/content/examples/60_extension/opentelemetry.md +++ b/website/content/examples/60_extension/opentelemetry.md @@ -41,14 +41,14 @@ console.log(data) } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', - parentId: 'fb04e4436519eebf', + traceId: '660addf19135864ad1ddc84d4197c202', + parentId: '4c9f8b8bd265ed58', traceState: undefined, name: 'encode', - id: 'b9cc31cb6dcef7bb', + id: 'c6d3e0add3fd1ca9', kind: 0, - timestamp: 1727365576823000, - duration: 586.292, + timestamp: 1727369128233000, + duration: 695.792, attributes: {}, status: { code: 0 }, events: [], @@ -68,14 +68,14 @@ console.log(data) } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', - parentId: 'fb04e4436519eebf', + traceId: '660addf19135864ad1ddc84d4197c202', + parentId: '4c9f8b8bd265ed58', traceState: undefined, name: 'pack', - id: 'fb77c65e19244b1f', + id: 'd5d5a381568322a1', kind: 0, - timestamp: 1727365576831000, - duration: 19896.75, + timestamp: 1727369128235000, + duration: 11409.958, attributes: {}, status: { code: 0 }, events: [], @@ -95,14 +95,14 @@ console.log(data) } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', - parentId: 'fb04e4436519eebf', + traceId: '660addf19135864ad1ddc84d4197c202', + parentId: '4c9f8b8bd265ed58', traceState: undefined, name: 'exchange', - id: '7e3a75386432d606', + id: 'ed3488dc296fd725', kind: 0, - timestamp: 1727365576852000, - duration: 29439.625, + timestamp: 1727369128247000, + duration: 21327.5, attributes: {}, status: { code: 0 }, events: [], @@ -122,14 +122,14 @@ console.log(data) } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', - parentId: 'fb04e4436519eebf', + traceId: '660addf19135864ad1ddc84d4197c202', + parentId: '4c9f8b8bd265ed58', traceState: undefined, name: 'unpack', - id: '6263aef06e4164d0', + id: 'f279d86c6c9fa36f', kind: 0, - timestamp: 1727365576881000, - duration: 1157, + timestamp: 1727369128269000, + duration: 1252.958, attributes: {}, status: { code: 0 }, events: [], @@ -149,14 +149,14 @@ console.log(data) } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', - parentId: 'fb04e4436519eebf', + traceId: '660addf19135864ad1ddc84d4197c202', + parentId: '4c9f8b8bd265ed58', traceState: undefined, name: 'decode', - id: 'f6e875f59111e613', + id: 'e10efeff511097b9', kind: 0, - timestamp: 1727365576883000, - duration: 193.042, + timestamp: 1727369128271000, + duration: 302.166, attributes: {}, status: { code: 0 }, events: [], @@ -176,14 +176,14 @@ console.log(data) } }, instrumentationScope: { name: 'graffle', version: undefined, schemaUrl: undefined }, - traceId: '99a1b00f220469bd559f6fdc09b75cfc', + traceId: '660addf19135864ad1ddc84d4197c202', parentId: undefined, traceState: undefined, name: 'request', - id: 'fb04e4436519eebf', + id: '4c9f8b8bd265ed58', kind: 0, - timestamp: 1727365576822000, - duration: 61277.208, + timestamp: 1727369128232000, + duration: 39141.875, attributes: {}, status: { code: 0 }, events: [], diff --git a/website/pokemon/modules/SchemaBuildtime.ts b/website/pokemon/modules/SchemaBuildtime.ts index e61d929e1..97f06c6a3 100644 --- a/website/pokemon/modules/SchemaBuildtime.ts +++ b/website/pokemon/modules/SchemaBuildtime.ts @@ -50,7 +50,13 @@ export namespace Enum { // InputObject // // ------------------------------------------------------------ // export namespace InputObject { + export type DateFilter = $.InputObject<'DateFilter', { + gte: $.Input.Field<$.Input.Nullable<$Scalar.Float>> + lte: $.Input.Field<$.Input.Nullable<$Scalar.Float>> + }, true> + export type PokemonFilter = $.InputObject<'PokemonFilter', { + birthday: $.Input.Field<$.Input.Nullable> name: $.Input.Field<$.Input.Nullable> }, true> @@ -71,6 +77,7 @@ export namespace Interface { export namespace Object { export type Pokemon = $.Object$2<'Pokemon', { attack: $.Field<$.Output.Nullable<$Scalar.Int>, null> + birthday: $.Field<$.Output.Nullable<$Scalar.Int>, null> defense: $.Field<$.Output.Nullable<$Scalar.Int>, null> hp: $.Field<$.Output.Nullable<$Scalar.Int>, null> id: $.Field<$.Output.Nullable<$Scalar.Int>, null> diff --git a/website/pokemon/modules/SchemaRuntime.ts b/website/pokemon/modules/SchemaRuntime.ts index b0a269804..bdedefe01 100644 --- a/website/pokemon/modules/SchemaRuntime.ts +++ b/website/pokemon/modules/SchemaRuntime.ts @@ -5,7 +5,13 @@ import * as $Scalar from './Scalar.js' import type { Index } from './SchemaIndex.js' export const $defaultSchemaUrl = new URL('http://localhost:3000/graphql') +export const DateFilter = $.InputObject(`DateFilter`, { + gte: $.Input.Field($.Input.Nullable($Scalar.Float)), + lte: $.Input.Field($.Input.Nullable($Scalar.Float)), +}, true) + export const PokemonFilter = $.InputObject(`PokemonFilter`, { + birthday: $.Input.Field(() => $.Input.Nullable(DateFilter)), name: $.Input.Field(() => $.Input.Nullable(StringFilter)), }, true) @@ -16,6 +22,7 @@ export const StringFilter = $.InputObject(`StringFilter`, { // @ts-ignore - circular types cannot infer. Ignore in case there are any. This comment is always added, it does not indicate if this particular type could infer or not. export const Pokemon = $.Object$(`Pokemon`, { attack: $.field($.Output.Nullable($Scalar.Int)), + birthday: $.field($.Output.Nullable($Scalar.Int)), defense: $.field($.Output.Nullable($Scalar.Int)), hp: $.field($.Output.Nullable($Scalar.Int)), id: $.field($.Output.Nullable($Scalar.Int)), diff --git a/website/pokemon/modules/SelectionSets.ts b/website/pokemon/modules/SelectionSets.ts index cb759948c..4bce05ff6 100644 --- a/website/pokemon/modules/SelectionSets.ts +++ b/website/pokemon/modules/SelectionSets.ts @@ -186,7 +186,13 @@ export namespace Query { // // +export interface DateFilter { + gte?: number | undefined | null + lte?: number | undefined | null +} + export interface PokemonFilter { + birthday?: _RefDefs._DateFilter | undefined | null name?: _RefDefs._StringFilter | undefined | null } @@ -230,6 +236,10 @@ export interface Pokemon extends $SelectionSet.Bases.ObjectLike { * Select the `attack` field on the `Pokemon` object. Its type is `Int` (a `Scalar`). */ attack?: Pokemon.attack$Expanded | $SelectionSet.AliasInput + /** + * Select the `birthday` field on the `Pokemon` object. Its type is `Int` (a `Scalar`). + */ + birthday?: Pokemon.birthday$Expanded | $SelectionSet.AliasInput /** * Select the `defense` field on the `Pokemon` object. Its type is `Int` (a `Scalar`). */ @@ -278,6 +288,10 @@ export namespace Pokemon { export type attack = $SelectionSet.Indicator.NoArgsIndicator + export type birthday$Expanded = $SelectionSet.Indicator.NoArgsIndicator$Expanded + + export type birthday = $SelectionSet.Indicator.NoArgsIndicator + export type defense$Expanded = $SelectionSet.Indicator.NoArgsIndicator$Expanded export type defense = $SelectionSet.Indicator.NoArgsIndicator @@ -371,6 +385,7 @@ export namespace Trainer { export namespace _RefDefs { export type _Mutation = Mutation export type _Query = Query + export type _DateFilter = DateFilter export type _PokemonFilter = PokemonFilter export type _StringFilter = StringFilter export type _Pokemon = Pokemon