gql.tada 1.0.0-beta.0 → 1.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/gql-tada.d.ts +23 -16
- package/dist/gql-tada.js.map +1 -1
- package/dist/gql-tada.mjs.map +1 -1
- package/package.json +1 -1
package/dist/gql-tada.d.ts
CHANGED
|
@@ -943,11 +943,11 @@ type getFragmentsOfDocumentsRec<Documents> = Documents extends readonly [
|
|
|
943
943
|
: {}) &
|
|
944
944
|
getFragmentsOfDocumentsRec<Rest>
|
|
945
945
|
: {};
|
|
946
|
-
type makeFragmentRef<Definition extends FragmentDefDecorationLike> = {
|
|
946
|
+
type makeFragmentRef<Definition extends FragmentDefDecorationLike> = obj<{
|
|
947
947
|
[$tada.fragmentRefs]?: {
|
|
948
948
|
[Name in Definition['name']['value']]: Definition[$tada.fragmentId];
|
|
949
949
|
};
|
|
950
|
-
}
|
|
950
|
+
}>;
|
|
951
951
|
type makeUndefinedFragmentRef<FragmentName extends string> = {
|
|
952
952
|
[$tada.fragmentRefs]?: {
|
|
953
953
|
[Name in FragmentName]: 'Undefined Fragment';
|
|
@@ -1249,9 +1249,17 @@ type getInputObjectTypeRec<
|
|
|
1249
1249
|
name: any;
|
|
1250
1250
|
type: any;
|
|
1251
1251
|
}
|
|
1252
|
-
? {
|
|
1253
|
-
|
|
1252
|
+
? InputField extends {
|
|
1253
|
+
type: {
|
|
1254
|
+
kind: 'NON_NULL';
|
|
1255
|
+
};
|
|
1254
1256
|
}
|
|
1257
|
+
? {
|
|
1258
|
+
[Name in InputField['name']]: unwrapType<InputField['type'], Introspection>;
|
|
1259
|
+
}
|
|
1260
|
+
: {
|
|
1261
|
+
[Name in InputField['name']]?: unwrapType<InputField['type'], Introspection>;
|
|
1262
|
+
}
|
|
1255
1263
|
: {}) &
|
|
1256
1264
|
getInputObjectTypeRec<Rest, Introspection>
|
|
1257
1265
|
: {};
|
|
@@ -1328,6 +1336,9 @@ type getVariablesRec<
|
|
|
1328
1336
|
}
|
|
1329
1337
|
? Variable extends {
|
|
1330
1338
|
defaultValue: undefined;
|
|
1339
|
+
type: {
|
|
1340
|
+
kind: Kind.NON_NULL_TYPE;
|
|
1341
|
+
};
|
|
1331
1342
|
}
|
|
1332
1343
|
? {
|
|
1333
1344
|
[Name in Variable['variable']['name']['value']]: unwrapTypeRef<
|
|
@@ -1388,9 +1399,8 @@ interface AbstractSetupSchema {
|
|
|
1388
1399
|
* @param scalars - An object type with scalar names as keys and the corresponding scalar types as values.
|
|
1389
1400
|
*
|
|
1390
1401
|
* @example
|
|
1391
|
-
*
|
|
1392
1402
|
* ```
|
|
1393
|
-
* import { myIntrospection } from './myIntrospection';
|
|
1403
|
+
* import type { myIntrospection } from './myIntrospection';
|
|
1394
1404
|
*
|
|
1395
1405
|
* declare module 'gql.tada' {
|
|
1396
1406
|
* interface setupSchema {
|
|
@@ -1422,7 +1432,6 @@ interface GraphQLTadaAPI<Schema extends IntrospectionLikeType> {
|
|
|
1422
1432
|
* which will then automatically infer the result and variables types.
|
|
1423
1433
|
*
|
|
1424
1434
|
* @example
|
|
1425
|
-
*
|
|
1426
1435
|
* ```
|
|
1427
1436
|
* import { graphql } from 'gql.tada';
|
|
1428
1437
|
*
|
|
@@ -1453,6 +1462,10 @@ interface GraphQLTadaAPI<Schema extends IntrospectionLikeType> {
|
|
|
1453
1462
|
fragments?: Fragments
|
|
1454
1463
|
): getDocumentNode<parseDocument<In>, Schema, getFragmentsOfDocumentsRec<Fragments>>;
|
|
1455
1464
|
}
|
|
1465
|
+
type schemaOfConfig<Setup extends AbstractSetupSchema> = mapIntrospection<
|
|
1466
|
+
matchOr<IntrospectionQuery, Setup['introspection'], never>,
|
|
1467
|
+
matchOr<ScalarsLike, Setup['scalars'], {}>
|
|
1468
|
+
>;
|
|
1456
1469
|
/** Setup function to create a typed `graphql` document function with.
|
|
1457
1470
|
*
|
|
1458
1471
|
* @remarks
|
|
@@ -1464,10 +1477,9 @@ interface GraphQLTadaAPI<Schema extends IntrospectionLikeType> {
|
|
|
1464
1477
|
* editor and the TypeScript language server to recognize your GraphQL documents correctly.
|
|
1465
1478
|
*
|
|
1466
1479
|
* @example
|
|
1467
|
-
*
|
|
1468
1480
|
* ```
|
|
1469
1481
|
* import { initGraphQLTada } from 'gql.tada';
|
|
1470
|
-
* import { myIntrospection } from './myIntrospection';
|
|
1482
|
+
* import type { myIntrospection } from './myIntrospection';
|
|
1471
1483
|
*
|
|
1472
1484
|
* export const graphql = initGraphQLTada<{
|
|
1473
1485
|
* introspection: typeof myIntrospection;
|
|
@@ -1481,10 +1493,7 @@ interface GraphQLTadaAPI<Schema extends IntrospectionLikeType> {
|
|
|
1481
1493
|
* ```
|
|
1482
1494
|
*/
|
|
1483
1495
|
declare function initGraphQLTada<const Setup extends AbstractSetupSchema>(): GraphQLTadaAPI<
|
|
1484
|
-
|
|
1485
|
-
matchOr<IntrospectionQuery, Setup['introspection'], never>,
|
|
1486
|
-
matchOr<ScalarsLike, Setup['scalars'], {}>
|
|
1487
|
-
>
|
|
1496
|
+
schemaOfConfig<Setup>
|
|
1488
1497
|
>;
|
|
1489
1498
|
/** Alias to a GraphQL parse function returning an exact document type.
|
|
1490
1499
|
*
|
|
@@ -1567,7 +1576,6 @@ type VariablesOf<Document> = Document extends DocumentDecoration<infer _, infer
|
|
|
1567
1576
|
* codebase that defines a fragment.
|
|
1568
1577
|
*
|
|
1569
1578
|
* @example
|
|
1570
|
-
*
|
|
1571
1579
|
* ```
|
|
1572
1580
|
* import { FragmentOf, graphql, readFragment } from 'gql.tada';
|
|
1573
1581
|
*
|
|
@@ -1623,7 +1631,6 @@ type fragmentOfTypeRec<Document extends DocumentDefDecorationLike> =
|
|
|
1623
1631
|
* a part of your codebase to require.
|
|
1624
1632
|
*
|
|
1625
1633
|
* @example
|
|
1626
|
-
*
|
|
1627
1634
|
* ```
|
|
1628
1635
|
* import { FragmentOf, graphql, readFragment } from 'gql.tada';
|
|
1629
1636
|
*
|
|
@@ -1664,7 +1671,7 @@ declare function readFragment<
|
|
|
1664
1671
|
_document: DocumentDecoration<Data, any> & Document,
|
|
1665
1672
|
fragment: Fragment
|
|
1666
1673
|
): fragmentOfTypeRec<Document> extends Fragment ? unknown : mirrorFragmentTypeRec<Fragment, Data>;
|
|
1667
|
-
declare const graphql: GraphQLTadaAPI<
|
|
1674
|
+
declare const graphql: GraphQLTadaAPI<schemaOfConfig<setupSchema>>;
|
|
1668
1675
|
|
|
1669
1676
|
export {
|
|
1670
1677
|
type AbstractSetupSchema,
|
package/dist/gql-tada.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gql-tada.js","sources":["../src/api.ts"],"sourcesContent":["import type { DocumentNode, DefinitionNode } from '@0no-co/graphql.web';\nimport { Kind, parse as _parse } from '@0no-co/graphql.web';\n\nimport type {\n IntrospectionQuery,\n ScalarsLike,\n IntrospectionLikeType,\n mapIntrospection,\n} from './introspection';\n\nimport type {\n FragmentDefDecorationLike,\n DocumentDefDecorationLike,\n getFragmentsOfDocumentsRec,\n makeFragmentDefDecoration,\n decorateFragmentDef,\n makeFragmentRef,\n $tada,\n} from './namespace';\n\nimport type { getDocumentType } from './selection';\nimport type { getVariablesType } from './variables';\nimport type { parseDocument, DocumentNodeLike } from './parser';\nimport type { stringLiteral, matchOr, DocumentDecoration } from './utils';\n\n/** Abstract configuration type input for your schema and scalars.\n *\n * @remarks\n * This is used either via {@link setupSchema} or {@link initGraphQLTada} to set\n * up your schema and scalars.\n *\n * The `scalars` option is optional and can be used to set up more scalars, apart\n * from the default ones (like: Int, Float, String, Boolean).\n * It must be an object map of scalar names to their desired TypeScript types.\n *\n * @param introspection - Introspection of your schema matching {@link IntrospectionQuery}.\n * @param scalars - An object type with scalar names as keys and the corresponding scalar types as values.\n */\ninterface AbstractSetupSchema {\n introspection: IntrospectionQuery;\n scalars?: ScalarsLike;\n}\n\n/** This is used to configure gql.tada with your introspection data and scalars.\n *\n * @remarks\n * You may extend this interface via declaration merging with your {@link IntrospectionQuery}\n * data and optionally your scalars to get proper type inference.\n * This is done by declaring a declaration for it as per the following example.\n *\n * Configuring scalars is optional and by default the standard scalrs are already\n * defined.\n *\n * This will configure the {@link graphql} export to infer types from your schema.\n * Alternatively, you may call {@link initGraphQLTada} instead.\n *\n * @param introspection - Introspection of your schema matching {@link IntrospectionQuery}.\n * @param scalars - An object type with scalar names as keys and the corresponding scalar types as values.\n *\n * @example\n *\n * ```\n * import { myIntrospection } from './myIntrospection';\n *\n * declare module 'gql.tada' {\n * interface setupSchema {\n * introspection: typeof myIntrospection;\n * scalars: {\n * DateTime: string;\n * Json: any;\n * };\n * }\n * }\n * ```\n */\ninterface setupSchema extends AbstractSetupSchema {\n /*empty*/\n}\n\ninterface GraphQLTadaAPI<Schema extends IntrospectionLikeType> {\n /** Function to create and compose GraphQL documents with result and variable types.\n *\n * @param input - A string of a GraphQL document.\n * @param fragments - An optional list of other GraphQL fragments created with this function.\n * @returns A {@link DocumentNode} with result and variables types.\n *\n * @remarks\n * This function creates a {@link DocumentNode} with result and variables types.\n * It is used with your schema in {@link setupSchema} to create a result type\n * of your queries, fragments, and variables.\n *\n * You can compose fragments into this function by passing them and a fragment\n * mask will be created for them.\n * When creating queries, the returned document of queries can be passed into GraphQL clients\n * which will then automatically infer the result and variables types.\n *\n * @example\n *\n * ```\n * import { graphql } from 'gql.tada';\n *\n * const bookFragment = graphql(`\n * fragment BookComponent on Book {\n * id\n * title\n * }\n * `);\n *\n * const bookQuery = graphql(`\n * query Book ($id: ID!) {\n * book(id: $id) {\n * id\n * ...BookComponent\n * }\n * }\n * `, [bookFragment]);\n * ```\n *\n * @see {@link readFragment} for how to read from fragment masks.\n */\n <\n const In extends stringLiteral<In>,\n const Fragments extends readonly [...DocumentDefDecorationLike[]],\n >(\n input: In,\n fragments?: Fragments\n ): getDocumentNode<parseDocument<In>, Schema, getFragmentsOfDocumentsRec<Fragments>>;\n}\n\n/** Setup function to create a typed `graphql` document function with.\n *\n * @remarks\n * `initGraphQLTada` accepts an {@link AbstractSetupSchema} configuration object as a generic\n * and returns a `graphql` function that may be used to create documents typed using your\n * GraphQL schema.\n *\n * You should use and re-export the resulting function named as `graphql` or `gql` for your\n * editor and the TypeScript language server to recognize your GraphQL documents correctly.\n *\n * @example\n *\n * ```\n * import { initGraphQLTada } from 'gql.tada';\n * import { myIntrospection } from './myIntrospection';\n *\n * export const graphql = initGraphQLTada<{\n * introspection: typeof myIntrospection;\n * scalars: {\n * DateTime: string;\n * Json: any;\n * };\n * }>();\n *\n * const query = graphql(`{ __typename }`);\n * ```\n */\nfunction initGraphQLTada<const Setup extends AbstractSetupSchema>() {\n type Schema = mapIntrospection<\n matchOr<IntrospectionQuery, Setup['introspection'], never>,\n matchOr<ScalarsLike, Setup['scalars'], {}>\n >;\n\n return function graphql(input: string, fragments?: readonly DocumentDefDecorationLike[]): any {\n const definitions = _parse(input).definitions as DefinitionNode[];\n const seen = new Set<unknown>();\n for (const document of fragments || []) {\n for (const definition of document.definitions) {\n if (definition.kind === Kind.FRAGMENT_DEFINITION && !seen.has(definition)) {\n definitions.push(definition);\n seen.add(definition);\n }\n }\n }\n return { kind: Kind.DOCUMENT, definitions: [...definitions] } as any;\n } as GraphQLTadaAPI<Schema>;\n}\n\n/** Alias to a GraphQL parse function returning an exact document type.\n *\n * @param input - A string of a GraphQL document\n * @returns A parsed {@link DocumentNode}.\n *\n * @remarks\n * This function accepts a GraphQL document string and parses it, just like\n * GraphQL’s `parse` function. However, its return type will be the exact\n * structure of the AST parsed in types.\n */\nfunction parse<const In extends stringLiteral<In>>(input: In): parseDocument<In> {\n return _parse(input) as any;\n}\n\ntype getDocumentNode<\n Document extends DocumentNodeLike,\n Introspection extends IntrospectionLikeType,\n Fragments extends { [name: string]: any } = {},\n> = getDocumentType<Document, Introspection, Fragments> extends infer Result\n ? Result extends never\n ? never\n : TadaDocumentNode<\n Result,\n getVariablesType<Document, Introspection>,\n decorateFragmentDef<Document>\n >\n : never;\n\n/** A GraphQL `DocumentNode` with attached types for results and variables.\n *\n * @remarks\n * This is a GraphQL {@link DocumentNode} with attached types for results and variables.\n * This is used by GraphQL clients to infer the types of results and variables and provide\n * type-safety in GraphQL documents.\n *\n * You can create typed GraphQL documents using the {@link graphql} function.\n *\n * `Result` is the type of GraphQL results, as returned by GraphQL APIs for a given query.\n * `Variables` is the type of variables, as accepted by GraphQL APIs for a given query.\n *\n * @see {@link https://github.com/dotansimha/graphql-typed-document-node} for more information.\n */\ninterface TadaDocumentNode<\n Result = { [key: string]: any },\n Variables = { [key: string]: any },\n Decoration = never,\n> extends DocumentNode,\n DocumentDecoration<Result, Variables>,\n makeFragmentDefDecoration<Decoration> {}\n\n/** A utility type returning the `Result` type of typed GraphQL documents.\n *\n * @remarks\n * This accepts a {@link TadaDocumentNode} and returns the attached `Result` type\n * of GraphQL documents.\n */\ntype ResultOf<Document> = Document extends DocumentDecoration<infer Result, infer _>\n ? Result\n : never;\n\n/** A utility type returning the `Variables` type of typed GraphQL documents.\n *\n * @remarks\n * This accepts a {@link TadaDocumentNode} and returns the attached `Variables` type\n * of GraphQL documents.\n */\ntype VariablesOf<Document> = Document extends DocumentDecoration<infer _, infer Variables>\n ? Variables\n : never;\n\n/** Creates a fragment mask for a given fragment document.\n *\n * @remarks\n * When {@link graphql} is used to create a fragment and is spread into another\n * fragment or query, their result types will only contain a “reference” to the\n * fragment. This encourages isolation and is known as “fragment masking.”\n *\n * While {@link readFragment} is used to unmask these fragment masks, this utility\n * creates a fragment mask, so you can accept the masked data in the part of your\n * codebase that defines a fragment.\n *\n * @example\n *\n * ```\n * import { FragmentOf, graphql, readFragment } from 'gql.tada';\n *\n * const bookFragment = graphql(`\n * fragment BookComponent on Book {\n * id\n * title\n * }\n * `);\n *\n * // May be called with any GraphQL data that contains a spread of `bookFragment`\n * const getBook = (data: FragmentOf<typeof bookFragment>) => {\n * // Unmasks the fragment and casts to the result type of `bookFragment`\n * const book = readFragment(bookFragment, data);\n * };\n * ```\n *\n * @see {@link readFragment} for how to read from fragment masks.\n */\ntype FragmentOf<Document extends DocumentDefDecorationLike> = Exclude<\n Document[$tada.fragmentDef],\n undefined\n> extends infer FragmentDef extends FragmentDefDecorationLike\n ? makeFragmentRef<FragmentDef>\n : never;\n\nexport type mirrorFragmentTypeRec<Fragment, Data> = Fragment extends (infer Value)[]\n ? mirrorFragmentTypeRec<Value, Data>[]\n : Fragment extends readonly (infer Value)[]\n ? readonly mirrorFragmentTypeRec<Value, Data>[]\n : Fragment extends null\n ? null\n : Fragment extends undefined\n ? undefined\n : Data;\n\ntype fragmentOfTypeRec<Document extends DocumentDefDecorationLike> =\n | readonly fragmentOfTypeRec<Document>[]\n | FragmentOf<Document>\n | undefined\n | null;\n\n/** Unmasks a fragment mask for a given fragment document and data.\n *\n * @param _document - A GraphQL document of a fragment, created using {@link graphql}.\n * @param fragment - A mask of the fragment, which can be wrapped in arrays, or nullable.\n * @returns The unmasked data of the fragment.\n *\n * @remarks\n * When {@link graphql} is used to create a fragment and is spread into another\n * fragment or query, their result types will only contain a “reference” to the\n * fragment. This encourages isolation and is known as “fragment masking.”\n *\n * This means that you must use {@link readFragment} to unmask these fragment masks\n * and get to the data. This encourages isolation and only using the data you define\n * a part of your codebase to require.\n *\n * @example\n *\n * ```\n * import { FragmentOf, graphql, readFragment } from 'gql.tada';\n *\n * const bookFragment = graphql(`\n * fragment BookComponent on Book {\n * id\n * title\n * }\n * `);\n *\n * const getBook = (data: FragmentOf<typeof bookFragment> | null) => {\n * // Unmasks the fragment and casts to the result type of `bookFragment`\n * // This is intersected with `| null` in this case, due to the input type.\n * const book = readFragment(bookFragment, data);\n * };\n *\n * const bookQuery = graphql(`\n * query Book ($id: ID!) {\n * book(id: $id) {\n * id\n * ...BookComponent\n * }\n * }\n * `, [bookFragment]);\n *\n * const getQuery = (data: ResultOf<typeof bookQuery>) => {\n * getBook(data?.book);\n * };\n * ```\n *\n * @see {@link readFragment} for how to read from fragment masks.\n */\nfunction readFragment<\n const Document extends DocumentDefDecorationLike,\n const Fragment extends fragmentOfTypeRec<Document>,\n const Data,\n>(\n _document: DocumentDecoration<Data, any> & Document,\n fragment: Fragment\n): fragmentOfTypeRec<Document> extends Fragment ? unknown : mirrorFragmentTypeRec<Fragment, Data> {\n return fragment as any;\n}\n\nconst graphql = initGraphQLTada<setupSchema>();\n\nexport { parse, graphql, readFragment, initGraphQLTada };\n\nexport type {\n setupSchema,\n parseDocument,\n AbstractSetupSchema,\n GraphQLTadaAPI,\n TadaDocumentNode,\n ResultOf,\n VariablesOf,\n FragmentOf,\n};\n"],"names":["initGraphQLTada","graphql","input","fragments","definitions","_parse","seen","Set","document","definition","kind","Kind","FRAGMENT_DEFINITION","has","push","add","DOCUMENT","parse","readFragment","_document","fragment"],"mappings":";;;;;;AA4JA,SAASA;EAMP,OAAO,SAASC,QAAQC,GAAeC;IACrC,IAAMC,IAAcC,EAAAA,MAAOH,GAAOE;IAClC,IAAME,IAAO,IAAIC;IACjB,KAAK,IAAMC,KAAYL,KAAa;MAClC,KAAK,IAAMM,KAAcD,EAASJ;QAChC,IAAIK,EAAWC,SAASC,OAAKC,wBAAwBN,EAAKO,IAAIJ,IAAa;UACzEL,EAAYU,KAAKL;UACjBH,EAAKS,IAAIN;AACX;;;IAGJ,OAAO;MAAEC,MAAMC,EAAIA,KAACK;MAAUZ,aAAa,KAAIA;;;AAEnD;;AA2LA,IAAMH,IAAUD;;;;;;gBA/KhB,SAASiB,MAA0Cf;EACjD,OAAOG,EAAAA,MAAOH;AAChB;;uBAkKA,SAASgB,aAKPC,GACAC;EAEA,OAAOA;AACT"}
|
|
1
|
+
{"version":3,"file":"gql-tada.js","sources":["../src/api.ts"],"sourcesContent":["import type { DocumentNode, DefinitionNode } from '@0no-co/graphql.web';\nimport { Kind, parse as _parse } from '@0no-co/graphql.web';\n\nimport type {\n IntrospectionQuery,\n ScalarsLike,\n IntrospectionLikeType,\n mapIntrospection,\n} from './introspection';\n\nimport type {\n FragmentDefDecorationLike,\n DocumentDefDecorationLike,\n getFragmentsOfDocumentsRec,\n makeFragmentDefDecoration,\n decorateFragmentDef,\n makeFragmentRef,\n $tada,\n} from './namespace';\n\nimport type { getDocumentType } from './selection';\nimport type { getVariablesType } from './variables';\nimport type { parseDocument, DocumentNodeLike } from './parser';\nimport type { stringLiteral, matchOr, DocumentDecoration } from './utils';\n\n/** Abstract configuration type input for your schema and scalars.\n *\n * @remarks\n * This is used either via {@link setupSchema} or {@link initGraphQLTada} to set\n * up your schema and scalars.\n *\n * The `scalars` option is optional and can be used to set up more scalars, apart\n * from the default ones (like: Int, Float, String, Boolean).\n * It must be an object map of scalar names to their desired TypeScript types.\n *\n * @param introspection - Introspection of your schema matching {@link IntrospectionQuery}.\n * @param scalars - An object type with scalar names as keys and the corresponding scalar types as values.\n */\ninterface AbstractSetupSchema {\n introspection: IntrospectionQuery;\n scalars?: ScalarsLike;\n}\n\n/** This is used to configure gql.tada with your introspection data and scalars.\n *\n * @remarks\n * You may extend this interface via declaration merging with your {@link IntrospectionQuery}\n * data and optionally your scalars to get proper type inference.\n * This is done by declaring a declaration for it as per the following example.\n *\n * Configuring scalars is optional and by default the standard scalrs are already\n * defined.\n *\n * This will configure the {@link graphql} export to infer types from your schema.\n * Alternatively, you may call {@link initGraphQLTada} instead.\n *\n * @param introspection - Introspection of your schema matching {@link IntrospectionQuery}.\n * @param scalars - An object type with scalar names as keys and the corresponding scalar types as values.\n *\n * @example\n * ```\n * import type { myIntrospection } from './myIntrospection';\n *\n * declare module 'gql.tada' {\n * interface setupSchema {\n * introspection: typeof myIntrospection;\n * scalars: {\n * DateTime: string;\n * Json: any;\n * };\n * }\n * }\n * ```\n */\ninterface setupSchema extends AbstractSetupSchema {\n /*empty*/\n}\n\ninterface GraphQLTadaAPI<Schema extends IntrospectionLikeType> {\n /** Function to create and compose GraphQL documents with result and variable types.\n *\n * @param input - A string of a GraphQL document.\n * @param fragments - An optional list of other GraphQL fragments created with this function.\n * @returns A {@link DocumentNode} with result and variables types.\n *\n * @remarks\n * This function creates a {@link DocumentNode} with result and variables types.\n * It is used with your schema in {@link setupSchema} to create a result type\n * of your queries, fragments, and variables.\n *\n * You can compose fragments into this function by passing them and a fragment\n * mask will be created for them.\n * When creating queries, the returned document of queries can be passed into GraphQL clients\n * which will then automatically infer the result and variables types.\n *\n * @example\n * ```\n * import { graphql } from 'gql.tada';\n *\n * const bookFragment = graphql(`\n * fragment BookComponent on Book {\n * id\n * title\n * }\n * `);\n *\n * const bookQuery = graphql(`\n * query Book ($id: ID!) {\n * book(id: $id) {\n * id\n * ...BookComponent\n * }\n * }\n * `, [bookFragment]);\n * ```\n *\n * @see {@link readFragment} for how to read from fragment masks.\n */\n <\n const In extends stringLiteral<In>,\n const Fragments extends readonly [...DocumentDefDecorationLike[]],\n >(\n input: In,\n fragments?: Fragments\n ): getDocumentNode<parseDocument<In>, Schema, getFragmentsOfDocumentsRec<Fragments>>;\n}\n\ntype schemaOfConfig<Setup extends AbstractSetupSchema> = mapIntrospection<\n matchOr<IntrospectionQuery, Setup['introspection'], never>,\n matchOr<ScalarsLike, Setup['scalars'], {}>\n>;\n\n/** Setup function to create a typed `graphql` document function with.\n *\n * @remarks\n * `initGraphQLTada` accepts an {@link AbstractSetupSchema} configuration object as a generic\n * and returns a `graphql` function that may be used to create documents typed using your\n * GraphQL schema.\n *\n * You should use and re-export the resulting function named as `graphql` or `gql` for your\n * editor and the TypeScript language server to recognize your GraphQL documents correctly.\n *\n * @example\n * ```\n * import { initGraphQLTada } from 'gql.tada';\n * import type { myIntrospection } from './myIntrospection';\n *\n * export const graphql = initGraphQLTada<{\n * introspection: typeof myIntrospection;\n * scalars: {\n * DateTime: string;\n * Json: any;\n * };\n * }>();\n *\n * const query = graphql(`{ __typename }`);\n * ```\n */\nfunction initGraphQLTada<const Setup extends AbstractSetupSchema>() {\n type Schema = schemaOfConfig<Setup>;\n\n return function graphql(input: string, fragments?: readonly DocumentDefDecorationLike[]): any {\n const definitions = _parse(input).definitions as DefinitionNode[];\n const seen = new Set<unknown>();\n for (const document of fragments || []) {\n for (const definition of document.definitions) {\n if (definition.kind === Kind.FRAGMENT_DEFINITION && !seen.has(definition)) {\n definitions.push(definition);\n seen.add(definition);\n }\n }\n }\n return { kind: Kind.DOCUMENT, definitions: [...definitions] } as any;\n } as GraphQLTadaAPI<Schema>;\n}\n\n/** Alias to a GraphQL parse function returning an exact document type.\n *\n * @param input - A string of a GraphQL document\n * @returns A parsed {@link DocumentNode}.\n *\n * @remarks\n * This function accepts a GraphQL document string and parses it, just like\n * GraphQL’s `parse` function. However, its return type will be the exact\n * structure of the AST parsed in types.\n */\nfunction parse<const In extends stringLiteral<In>>(input: In): parseDocument<In> {\n return _parse(input) as any;\n}\n\ntype getDocumentNode<\n Document extends DocumentNodeLike,\n Introspection extends IntrospectionLikeType,\n Fragments extends { [name: string]: any } = {},\n> = getDocumentType<Document, Introspection, Fragments> extends infer Result\n ? Result extends never\n ? never\n : TadaDocumentNode<\n Result,\n getVariablesType<Document, Introspection>,\n decorateFragmentDef<Document>\n >\n : never;\n\n/** A GraphQL `DocumentNode` with attached types for results and variables.\n *\n * @remarks\n * This is a GraphQL {@link DocumentNode} with attached types for results and variables.\n * This is used by GraphQL clients to infer the types of results and variables and provide\n * type-safety in GraphQL documents.\n *\n * You can create typed GraphQL documents using the {@link graphql} function.\n *\n * `Result` is the type of GraphQL results, as returned by GraphQL APIs for a given query.\n * `Variables` is the type of variables, as accepted by GraphQL APIs for a given query.\n *\n * @see {@link https://github.com/dotansimha/graphql-typed-document-node} for more information.\n */\ninterface TadaDocumentNode<\n Result = { [key: string]: any },\n Variables = { [key: string]: any },\n Decoration = never,\n> extends DocumentNode,\n DocumentDecoration<Result, Variables>,\n makeFragmentDefDecoration<Decoration> {}\n\n/** A utility type returning the `Result` type of typed GraphQL documents.\n *\n * @remarks\n * This accepts a {@link TadaDocumentNode} and returns the attached `Result` type\n * of GraphQL documents.\n */\ntype ResultOf<Document> = Document extends DocumentDecoration<infer Result, infer _>\n ? Result\n : never;\n\n/** A utility type returning the `Variables` type of typed GraphQL documents.\n *\n * @remarks\n * This accepts a {@link TadaDocumentNode} and returns the attached `Variables` type\n * of GraphQL documents.\n */\ntype VariablesOf<Document> = Document extends DocumentDecoration<infer _, infer Variables>\n ? Variables\n : never;\n\n/** Creates a fragment mask for a given fragment document.\n *\n * @remarks\n * When {@link graphql} is used to create a fragment and is spread into another\n * fragment or query, their result types will only contain a “reference” to the\n * fragment. This encourages isolation and is known as “fragment masking.”\n *\n * While {@link readFragment} is used to unmask these fragment masks, this utility\n * creates a fragment mask, so you can accept the masked data in the part of your\n * codebase that defines a fragment.\n *\n * @example\n * ```\n * import { FragmentOf, graphql, readFragment } from 'gql.tada';\n *\n * const bookFragment = graphql(`\n * fragment BookComponent on Book {\n * id\n * title\n * }\n * `);\n *\n * // May be called with any GraphQL data that contains a spread of `bookFragment`\n * const getBook = (data: FragmentOf<typeof bookFragment>) => {\n * // Unmasks the fragment and casts to the result type of `bookFragment`\n * const book = readFragment(bookFragment, data);\n * };\n * ```\n *\n * @see {@link readFragment} for how to read from fragment masks.\n */\ntype FragmentOf<Document extends DocumentDefDecorationLike> = Exclude<\n Document[$tada.fragmentDef],\n undefined\n> extends infer FragmentDef extends FragmentDefDecorationLike\n ? makeFragmentRef<FragmentDef>\n : never;\n\nexport type mirrorFragmentTypeRec<Fragment, Data> = Fragment extends (infer Value)[]\n ? mirrorFragmentTypeRec<Value, Data>[]\n : Fragment extends readonly (infer Value)[]\n ? readonly mirrorFragmentTypeRec<Value, Data>[]\n : Fragment extends null\n ? null\n : Fragment extends undefined\n ? undefined\n : Data;\n\ntype fragmentOfTypeRec<Document extends DocumentDefDecorationLike> =\n | readonly fragmentOfTypeRec<Document>[]\n | FragmentOf<Document>\n | undefined\n | null;\n\n/** Unmasks a fragment mask for a given fragment document and data.\n *\n * @param _document - A GraphQL document of a fragment, created using {@link graphql}.\n * @param fragment - A mask of the fragment, which can be wrapped in arrays, or nullable.\n * @returns The unmasked data of the fragment.\n *\n * @remarks\n * When {@link graphql} is used to create a fragment and is spread into another\n * fragment or query, their result types will only contain a “reference” to the\n * fragment. This encourages isolation and is known as “fragment masking.”\n *\n * This means that you must use {@link readFragment} to unmask these fragment masks\n * and get to the data. This encourages isolation and only using the data you define\n * a part of your codebase to require.\n *\n * @example\n * ```\n * import { FragmentOf, graphql, readFragment } from 'gql.tada';\n *\n * const bookFragment = graphql(`\n * fragment BookComponent on Book {\n * id\n * title\n * }\n * `);\n *\n * const getBook = (data: FragmentOf<typeof bookFragment> | null) => {\n * // Unmasks the fragment and casts to the result type of `bookFragment`\n * // This is intersected with `| null` in this case, due to the input type.\n * const book = readFragment(bookFragment, data);\n * };\n *\n * const bookQuery = graphql(`\n * query Book ($id: ID!) {\n * book(id: $id) {\n * id\n * ...BookComponent\n * }\n * }\n * `, [bookFragment]);\n *\n * const getQuery = (data: ResultOf<typeof bookQuery>) => {\n * getBook(data?.book);\n * };\n * ```\n *\n * @see {@link readFragment} for how to read from fragment masks.\n */\nfunction readFragment<\n const Document extends DocumentDefDecorationLike,\n const Fragment extends fragmentOfTypeRec<Document>,\n const Data,\n>(\n _document: DocumentDecoration<Data, any> & Document,\n fragment: Fragment\n): fragmentOfTypeRec<Document> extends Fragment ? unknown : mirrorFragmentTypeRec<Fragment, Data> {\n return fragment as any;\n}\n\nconst graphql: GraphQLTadaAPI<schemaOfConfig<setupSchema>> = initGraphQLTada();\n\nexport { parse, graphql, readFragment, initGraphQLTada };\n\nexport type {\n setupSchema,\n parseDocument,\n AbstractSetupSchema,\n GraphQLTadaAPI,\n TadaDocumentNode,\n ResultOf,\n VariablesOf,\n FragmentOf,\n};\n"],"names":["initGraphQLTada","graphql","input","fragments","definitions","_parse","seen","Set","document","definition","kind","Kind","FRAGMENT_DEFINITION","has","push","add","DOCUMENT","parse","readFragment","_document","fragment"],"mappings":";;;;;;AA8JA,SAASA;EAGP,OAAO,SAASC,QAAQC,GAAeC;IACrC,IAAMC,IAAcC,EAAAA,MAAOH,GAAOE;IAClC,IAAME,IAAO,IAAIC;IACjB,KAAK,IAAMC,KAAYL,KAAa;MAClC,KAAK,IAAMM,KAAcD,EAASJ;QAChC,IAAIK,EAAWC,SAASC,OAAKC,wBAAwBN,EAAKO,IAAIJ,IAAa;UACzEL,EAAYU,KAAKL;UACjBH,EAAKS,IAAIN;AACX;;;IAGJ,OAAO;MAAEC,MAAMC,EAAIA,KAACK;MAAUZ,aAAa,KAAIA;;;AAEnD;;AAyLA,IAAMH,IAAuDD;;;;;;gBA7K7D,SAASiB,MAA0Cf;EACjD,OAAOG,EAAAA,MAAOH;AAChB;;uBAgKA,SAASgB,aAKPC,GACAC;EAEA,OAAOA;AACT"}
|
package/dist/gql-tada.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gql-tada.mjs","sources":["../src/api.ts"],"sourcesContent":["import type { DocumentNode, DefinitionNode } from '@0no-co/graphql.web';\nimport { Kind, parse as _parse } from '@0no-co/graphql.web';\n\nimport type {\n IntrospectionQuery,\n ScalarsLike,\n IntrospectionLikeType,\n mapIntrospection,\n} from './introspection';\n\nimport type {\n FragmentDefDecorationLike,\n DocumentDefDecorationLike,\n getFragmentsOfDocumentsRec,\n makeFragmentDefDecoration,\n decorateFragmentDef,\n makeFragmentRef,\n $tada,\n} from './namespace';\n\nimport type { getDocumentType } from './selection';\nimport type { getVariablesType } from './variables';\nimport type { parseDocument, DocumentNodeLike } from './parser';\nimport type { stringLiteral, matchOr, DocumentDecoration } from './utils';\n\n/** Abstract configuration type input for your schema and scalars.\n *\n * @remarks\n * This is used either via {@link setupSchema} or {@link initGraphQLTada} to set\n * up your schema and scalars.\n *\n * The `scalars` option is optional and can be used to set up more scalars, apart\n * from the default ones (like: Int, Float, String, Boolean).\n * It must be an object map of scalar names to their desired TypeScript types.\n *\n * @param introspection - Introspection of your schema matching {@link IntrospectionQuery}.\n * @param scalars - An object type with scalar names as keys and the corresponding scalar types as values.\n */\ninterface AbstractSetupSchema {\n introspection: IntrospectionQuery;\n scalars?: ScalarsLike;\n}\n\n/** This is used to configure gql.tada with your introspection data and scalars.\n *\n * @remarks\n * You may extend this interface via declaration merging with your {@link IntrospectionQuery}\n * data and optionally your scalars to get proper type inference.\n * This is done by declaring a declaration for it as per the following example.\n *\n * Configuring scalars is optional and by default the standard scalrs are already\n * defined.\n *\n * This will configure the {@link graphql} export to infer types from your schema.\n * Alternatively, you may call {@link initGraphQLTada} instead.\n *\n * @param introspection - Introspection of your schema matching {@link IntrospectionQuery}.\n * @param scalars - An object type with scalar names as keys and the corresponding scalar types as values.\n *\n * @example\n *\n * ```\n * import { myIntrospection } from './myIntrospection';\n *\n * declare module 'gql.tada' {\n * interface setupSchema {\n * introspection: typeof myIntrospection;\n * scalars: {\n * DateTime: string;\n * Json: any;\n * };\n * }\n * }\n * ```\n */\ninterface setupSchema extends AbstractSetupSchema {\n /*empty*/\n}\n\ninterface GraphQLTadaAPI<Schema extends IntrospectionLikeType> {\n /** Function to create and compose GraphQL documents with result and variable types.\n *\n * @param input - A string of a GraphQL document.\n * @param fragments - An optional list of other GraphQL fragments created with this function.\n * @returns A {@link DocumentNode} with result and variables types.\n *\n * @remarks\n * This function creates a {@link DocumentNode} with result and variables types.\n * It is used with your schema in {@link setupSchema} to create a result type\n * of your queries, fragments, and variables.\n *\n * You can compose fragments into this function by passing them and a fragment\n * mask will be created for them.\n * When creating queries, the returned document of queries can be passed into GraphQL clients\n * which will then automatically infer the result and variables types.\n *\n * @example\n *\n * ```\n * import { graphql } from 'gql.tada';\n *\n * const bookFragment = graphql(`\n * fragment BookComponent on Book {\n * id\n * title\n * }\n * `);\n *\n * const bookQuery = graphql(`\n * query Book ($id: ID!) {\n * book(id: $id) {\n * id\n * ...BookComponent\n * }\n * }\n * `, [bookFragment]);\n * ```\n *\n * @see {@link readFragment} for how to read from fragment masks.\n */\n <\n const In extends stringLiteral<In>,\n const Fragments extends readonly [...DocumentDefDecorationLike[]],\n >(\n input: In,\n fragments?: Fragments\n ): getDocumentNode<parseDocument<In>, Schema, getFragmentsOfDocumentsRec<Fragments>>;\n}\n\n/** Setup function to create a typed `graphql` document function with.\n *\n * @remarks\n * `initGraphQLTada` accepts an {@link AbstractSetupSchema} configuration object as a generic\n * and returns a `graphql` function that may be used to create documents typed using your\n * GraphQL schema.\n *\n * You should use and re-export the resulting function named as `graphql` or `gql` for your\n * editor and the TypeScript language server to recognize your GraphQL documents correctly.\n *\n * @example\n *\n * ```\n * import { initGraphQLTada } from 'gql.tada';\n * import { myIntrospection } from './myIntrospection';\n *\n * export const graphql = initGraphQLTada<{\n * introspection: typeof myIntrospection;\n * scalars: {\n * DateTime: string;\n * Json: any;\n * };\n * }>();\n *\n * const query = graphql(`{ __typename }`);\n * ```\n */\nfunction initGraphQLTada<const Setup extends AbstractSetupSchema>() {\n type Schema = mapIntrospection<\n matchOr<IntrospectionQuery, Setup['introspection'], never>,\n matchOr<ScalarsLike, Setup['scalars'], {}>\n >;\n\n return function graphql(input: string, fragments?: readonly DocumentDefDecorationLike[]): any {\n const definitions = _parse(input).definitions as DefinitionNode[];\n const seen = new Set<unknown>();\n for (const document of fragments || []) {\n for (const definition of document.definitions) {\n if (definition.kind === Kind.FRAGMENT_DEFINITION && !seen.has(definition)) {\n definitions.push(definition);\n seen.add(definition);\n }\n }\n }\n return { kind: Kind.DOCUMENT, definitions: [...definitions] } as any;\n } as GraphQLTadaAPI<Schema>;\n}\n\n/** Alias to a GraphQL parse function returning an exact document type.\n *\n * @param input - A string of a GraphQL document\n * @returns A parsed {@link DocumentNode}.\n *\n * @remarks\n * This function accepts a GraphQL document string and parses it, just like\n * GraphQL’s `parse` function. However, its return type will be the exact\n * structure of the AST parsed in types.\n */\nfunction parse<const In extends stringLiteral<In>>(input: In): parseDocument<In> {\n return _parse(input) as any;\n}\n\ntype getDocumentNode<\n Document extends DocumentNodeLike,\n Introspection extends IntrospectionLikeType,\n Fragments extends { [name: string]: any } = {},\n> = getDocumentType<Document, Introspection, Fragments> extends infer Result\n ? Result extends never\n ? never\n : TadaDocumentNode<\n Result,\n getVariablesType<Document, Introspection>,\n decorateFragmentDef<Document>\n >\n : never;\n\n/** A GraphQL `DocumentNode` with attached types for results and variables.\n *\n * @remarks\n * This is a GraphQL {@link DocumentNode} with attached types for results and variables.\n * This is used by GraphQL clients to infer the types of results and variables and provide\n * type-safety in GraphQL documents.\n *\n * You can create typed GraphQL documents using the {@link graphql} function.\n *\n * `Result` is the type of GraphQL results, as returned by GraphQL APIs for a given query.\n * `Variables` is the type of variables, as accepted by GraphQL APIs for a given query.\n *\n * @see {@link https://github.com/dotansimha/graphql-typed-document-node} for more information.\n */\ninterface TadaDocumentNode<\n Result = { [key: string]: any },\n Variables = { [key: string]: any },\n Decoration = never,\n> extends DocumentNode,\n DocumentDecoration<Result, Variables>,\n makeFragmentDefDecoration<Decoration> {}\n\n/** A utility type returning the `Result` type of typed GraphQL documents.\n *\n * @remarks\n * This accepts a {@link TadaDocumentNode} and returns the attached `Result` type\n * of GraphQL documents.\n */\ntype ResultOf<Document> = Document extends DocumentDecoration<infer Result, infer _>\n ? Result\n : never;\n\n/** A utility type returning the `Variables` type of typed GraphQL documents.\n *\n * @remarks\n * This accepts a {@link TadaDocumentNode} and returns the attached `Variables` type\n * of GraphQL documents.\n */\ntype VariablesOf<Document> = Document extends DocumentDecoration<infer _, infer Variables>\n ? Variables\n : never;\n\n/** Creates a fragment mask for a given fragment document.\n *\n * @remarks\n * When {@link graphql} is used to create a fragment and is spread into another\n * fragment or query, their result types will only contain a “reference” to the\n * fragment. This encourages isolation and is known as “fragment masking.”\n *\n * While {@link readFragment} is used to unmask these fragment masks, this utility\n * creates a fragment mask, so you can accept the masked data in the part of your\n * codebase that defines a fragment.\n *\n * @example\n *\n * ```\n * import { FragmentOf, graphql, readFragment } from 'gql.tada';\n *\n * const bookFragment = graphql(`\n * fragment BookComponent on Book {\n * id\n * title\n * }\n * `);\n *\n * // May be called with any GraphQL data that contains a spread of `bookFragment`\n * const getBook = (data: FragmentOf<typeof bookFragment>) => {\n * // Unmasks the fragment and casts to the result type of `bookFragment`\n * const book = readFragment(bookFragment, data);\n * };\n * ```\n *\n * @see {@link readFragment} for how to read from fragment masks.\n */\ntype FragmentOf<Document extends DocumentDefDecorationLike> = Exclude<\n Document[$tada.fragmentDef],\n undefined\n> extends infer FragmentDef extends FragmentDefDecorationLike\n ? makeFragmentRef<FragmentDef>\n : never;\n\nexport type mirrorFragmentTypeRec<Fragment, Data> = Fragment extends (infer Value)[]\n ? mirrorFragmentTypeRec<Value, Data>[]\n : Fragment extends readonly (infer Value)[]\n ? readonly mirrorFragmentTypeRec<Value, Data>[]\n : Fragment extends null\n ? null\n : Fragment extends undefined\n ? undefined\n : Data;\n\ntype fragmentOfTypeRec<Document extends DocumentDefDecorationLike> =\n | readonly fragmentOfTypeRec<Document>[]\n | FragmentOf<Document>\n | undefined\n | null;\n\n/** Unmasks a fragment mask for a given fragment document and data.\n *\n * @param _document - A GraphQL document of a fragment, created using {@link graphql}.\n * @param fragment - A mask of the fragment, which can be wrapped in arrays, or nullable.\n * @returns The unmasked data of the fragment.\n *\n * @remarks\n * When {@link graphql} is used to create a fragment and is spread into another\n * fragment or query, their result types will only contain a “reference” to the\n * fragment. This encourages isolation and is known as “fragment masking.”\n *\n * This means that you must use {@link readFragment} to unmask these fragment masks\n * and get to the data. This encourages isolation and only using the data you define\n * a part of your codebase to require.\n *\n * @example\n *\n * ```\n * import { FragmentOf, graphql, readFragment } from 'gql.tada';\n *\n * const bookFragment = graphql(`\n * fragment BookComponent on Book {\n * id\n * title\n * }\n * `);\n *\n * const getBook = (data: FragmentOf<typeof bookFragment> | null) => {\n * // Unmasks the fragment and casts to the result type of `bookFragment`\n * // This is intersected with `| null` in this case, due to the input type.\n * const book = readFragment(bookFragment, data);\n * };\n *\n * const bookQuery = graphql(`\n * query Book ($id: ID!) {\n * book(id: $id) {\n * id\n * ...BookComponent\n * }\n * }\n * `, [bookFragment]);\n *\n * const getQuery = (data: ResultOf<typeof bookQuery>) => {\n * getBook(data?.book);\n * };\n * ```\n *\n * @see {@link readFragment} for how to read from fragment masks.\n */\nfunction readFragment<\n const Document extends DocumentDefDecorationLike,\n const Fragment extends fragmentOfTypeRec<Document>,\n const Data,\n>(\n _document: DocumentDecoration<Data, any> & Document,\n fragment: Fragment\n): fragmentOfTypeRec<Document> extends Fragment ? unknown : mirrorFragmentTypeRec<Fragment, Data> {\n return fragment as any;\n}\n\nconst graphql = initGraphQLTada<setupSchema>();\n\nexport { parse, graphql, readFragment, initGraphQLTada };\n\nexport type {\n setupSchema,\n parseDocument,\n AbstractSetupSchema,\n GraphQLTadaAPI,\n TadaDocumentNode,\n ResultOf,\n VariablesOf,\n FragmentOf,\n};\n"],"names":["initGraphQLTada","graphql","input","fragments","definitions","_parse","seen","Set","document","definition","kind","Kind","FRAGMENT_DEFINITION","has","push","add","DOCUMENT","parse","readFragment","_document","fragment"],"mappings":";;AA4JA,SAASA;EAMP,OAAO,SAASC,QAAQC,GAAeC;IACrC,IAAMC,IAAcC,EAAOH,GAAOE;IAClC,IAAME,IAAO,IAAIC;IACjB,KAAK,IAAMC,KAAYL,KAAa;MAClC,KAAK,IAAMM,KAAcD,EAASJ;QAChC,IAAIK,EAAWC,SAASC,EAAKC,wBAAwBN,EAAKO,IAAIJ,IAAa;UACzEL,EAAYU,KAAKL;UACjBH,EAAKS,IAAIN;AACX;;;IAGJ,OAAO;MAAEC,MAAMC,EAAKK;MAAUZ,aAAa,KAAIA;;;AAEnD;;AAYA,SAASa,MAA0Cf;EACjD,OAAOG,EAAOH;AAChB;;AAkKA,SAASgB,aAKPC,GACAC;EAEA,OAAOA;AACT;;AAEA,IAAMnB,IAAUD;;"}
|
|
1
|
+
{"version":3,"file":"gql-tada.mjs","sources":["../src/api.ts"],"sourcesContent":["import type { DocumentNode, DefinitionNode } from '@0no-co/graphql.web';\nimport { Kind, parse as _parse } from '@0no-co/graphql.web';\n\nimport type {\n IntrospectionQuery,\n ScalarsLike,\n IntrospectionLikeType,\n mapIntrospection,\n} from './introspection';\n\nimport type {\n FragmentDefDecorationLike,\n DocumentDefDecorationLike,\n getFragmentsOfDocumentsRec,\n makeFragmentDefDecoration,\n decorateFragmentDef,\n makeFragmentRef,\n $tada,\n} from './namespace';\n\nimport type { getDocumentType } from './selection';\nimport type { getVariablesType } from './variables';\nimport type { parseDocument, DocumentNodeLike } from './parser';\nimport type { stringLiteral, matchOr, DocumentDecoration } from './utils';\n\n/** Abstract configuration type input for your schema and scalars.\n *\n * @remarks\n * This is used either via {@link setupSchema} or {@link initGraphQLTada} to set\n * up your schema and scalars.\n *\n * The `scalars` option is optional and can be used to set up more scalars, apart\n * from the default ones (like: Int, Float, String, Boolean).\n * It must be an object map of scalar names to their desired TypeScript types.\n *\n * @param introspection - Introspection of your schema matching {@link IntrospectionQuery}.\n * @param scalars - An object type with scalar names as keys and the corresponding scalar types as values.\n */\ninterface AbstractSetupSchema {\n introspection: IntrospectionQuery;\n scalars?: ScalarsLike;\n}\n\n/** This is used to configure gql.tada with your introspection data and scalars.\n *\n * @remarks\n * You may extend this interface via declaration merging with your {@link IntrospectionQuery}\n * data and optionally your scalars to get proper type inference.\n * This is done by declaring a declaration for it as per the following example.\n *\n * Configuring scalars is optional and by default the standard scalrs are already\n * defined.\n *\n * This will configure the {@link graphql} export to infer types from your schema.\n * Alternatively, you may call {@link initGraphQLTada} instead.\n *\n * @param introspection - Introspection of your schema matching {@link IntrospectionQuery}.\n * @param scalars - An object type with scalar names as keys and the corresponding scalar types as values.\n *\n * @example\n * ```\n * import type { myIntrospection } from './myIntrospection';\n *\n * declare module 'gql.tada' {\n * interface setupSchema {\n * introspection: typeof myIntrospection;\n * scalars: {\n * DateTime: string;\n * Json: any;\n * };\n * }\n * }\n * ```\n */\ninterface setupSchema extends AbstractSetupSchema {\n /*empty*/\n}\n\ninterface GraphQLTadaAPI<Schema extends IntrospectionLikeType> {\n /** Function to create and compose GraphQL documents with result and variable types.\n *\n * @param input - A string of a GraphQL document.\n * @param fragments - An optional list of other GraphQL fragments created with this function.\n * @returns A {@link DocumentNode} with result and variables types.\n *\n * @remarks\n * This function creates a {@link DocumentNode} with result and variables types.\n * It is used with your schema in {@link setupSchema} to create a result type\n * of your queries, fragments, and variables.\n *\n * You can compose fragments into this function by passing them and a fragment\n * mask will be created for them.\n * When creating queries, the returned document of queries can be passed into GraphQL clients\n * which will then automatically infer the result and variables types.\n *\n * @example\n * ```\n * import { graphql } from 'gql.tada';\n *\n * const bookFragment = graphql(`\n * fragment BookComponent on Book {\n * id\n * title\n * }\n * `);\n *\n * const bookQuery = graphql(`\n * query Book ($id: ID!) {\n * book(id: $id) {\n * id\n * ...BookComponent\n * }\n * }\n * `, [bookFragment]);\n * ```\n *\n * @see {@link readFragment} for how to read from fragment masks.\n */\n <\n const In extends stringLiteral<In>,\n const Fragments extends readonly [...DocumentDefDecorationLike[]],\n >(\n input: In,\n fragments?: Fragments\n ): getDocumentNode<parseDocument<In>, Schema, getFragmentsOfDocumentsRec<Fragments>>;\n}\n\ntype schemaOfConfig<Setup extends AbstractSetupSchema> = mapIntrospection<\n matchOr<IntrospectionQuery, Setup['introspection'], never>,\n matchOr<ScalarsLike, Setup['scalars'], {}>\n>;\n\n/** Setup function to create a typed `graphql` document function with.\n *\n * @remarks\n * `initGraphQLTada` accepts an {@link AbstractSetupSchema} configuration object as a generic\n * and returns a `graphql` function that may be used to create documents typed using your\n * GraphQL schema.\n *\n * You should use and re-export the resulting function named as `graphql` or `gql` for your\n * editor and the TypeScript language server to recognize your GraphQL documents correctly.\n *\n * @example\n * ```\n * import { initGraphQLTada } from 'gql.tada';\n * import type { myIntrospection } from './myIntrospection';\n *\n * export const graphql = initGraphQLTada<{\n * introspection: typeof myIntrospection;\n * scalars: {\n * DateTime: string;\n * Json: any;\n * };\n * }>();\n *\n * const query = graphql(`{ __typename }`);\n * ```\n */\nfunction initGraphQLTada<const Setup extends AbstractSetupSchema>() {\n type Schema = schemaOfConfig<Setup>;\n\n return function graphql(input: string, fragments?: readonly DocumentDefDecorationLike[]): any {\n const definitions = _parse(input).definitions as DefinitionNode[];\n const seen = new Set<unknown>();\n for (const document of fragments || []) {\n for (const definition of document.definitions) {\n if (definition.kind === Kind.FRAGMENT_DEFINITION && !seen.has(definition)) {\n definitions.push(definition);\n seen.add(definition);\n }\n }\n }\n return { kind: Kind.DOCUMENT, definitions: [...definitions] } as any;\n } as GraphQLTadaAPI<Schema>;\n}\n\n/** Alias to a GraphQL parse function returning an exact document type.\n *\n * @param input - A string of a GraphQL document\n * @returns A parsed {@link DocumentNode}.\n *\n * @remarks\n * This function accepts a GraphQL document string and parses it, just like\n * GraphQL’s `parse` function. However, its return type will be the exact\n * structure of the AST parsed in types.\n */\nfunction parse<const In extends stringLiteral<In>>(input: In): parseDocument<In> {\n return _parse(input) as any;\n}\n\ntype getDocumentNode<\n Document extends DocumentNodeLike,\n Introspection extends IntrospectionLikeType,\n Fragments extends { [name: string]: any } = {},\n> = getDocumentType<Document, Introspection, Fragments> extends infer Result\n ? Result extends never\n ? never\n : TadaDocumentNode<\n Result,\n getVariablesType<Document, Introspection>,\n decorateFragmentDef<Document>\n >\n : never;\n\n/** A GraphQL `DocumentNode` with attached types for results and variables.\n *\n * @remarks\n * This is a GraphQL {@link DocumentNode} with attached types for results and variables.\n * This is used by GraphQL clients to infer the types of results and variables and provide\n * type-safety in GraphQL documents.\n *\n * You can create typed GraphQL documents using the {@link graphql} function.\n *\n * `Result` is the type of GraphQL results, as returned by GraphQL APIs for a given query.\n * `Variables` is the type of variables, as accepted by GraphQL APIs for a given query.\n *\n * @see {@link https://github.com/dotansimha/graphql-typed-document-node} for more information.\n */\ninterface TadaDocumentNode<\n Result = { [key: string]: any },\n Variables = { [key: string]: any },\n Decoration = never,\n> extends DocumentNode,\n DocumentDecoration<Result, Variables>,\n makeFragmentDefDecoration<Decoration> {}\n\n/** A utility type returning the `Result` type of typed GraphQL documents.\n *\n * @remarks\n * This accepts a {@link TadaDocumentNode} and returns the attached `Result` type\n * of GraphQL documents.\n */\ntype ResultOf<Document> = Document extends DocumentDecoration<infer Result, infer _>\n ? Result\n : never;\n\n/** A utility type returning the `Variables` type of typed GraphQL documents.\n *\n * @remarks\n * This accepts a {@link TadaDocumentNode} and returns the attached `Variables` type\n * of GraphQL documents.\n */\ntype VariablesOf<Document> = Document extends DocumentDecoration<infer _, infer Variables>\n ? Variables\n : never;\n\n/** Creates a fragment mask for a given fragment document.\n *\n * @remarks\n * When {@link graphql} is used to create a fragment and is spread into another\n * fragment or query, their result types will only contain a “reference” to the\n * fragment. This encourages isolation and is known as “fragment masking.”\n *\n * While {@link readFragment} is used to unmask these fragment masks, this utility\n * creates a fragment mask, so you can accept the masked data in the part of your\n * codebase that defines a fragment.\n *\n * @example\n * ```\n * import { FragmentOf, graphql, readFragment } from 'gql.tada';\n *\n * const bookFragment = graphql(`\n * fragment BookComponent on Book {\n * id\n * title\n * }\n * `);\n *\n * // May be called with any GraphQL data that contains a spread of `bookFragment`\n * const getBook = (data: FragmentOf<typeof bookFragment>) => {\n * // Unmasks the fragment and casts to the result type of `bookFragment`\n * const book = readFragment(bookFragment, data);\n * };\n * ```\n *\n * @see {@link readFragment} for how to read from fragment masks.\n */\ntype FragmentOf<Document extends DocumentDefDecorationLike> = Exclude<\n Document[$tada.fragmentDef],\n undefined\n> extends infer FragmentDef extends FragmentDefDecorationLike\n ? makeFragmentRef<FragmentDef>\n : never;\n\nexport type mirrorFragmentTypeRec<Fragment, Data> = Fragment extends (infer Value)[]\n ? mirrorFragmentTypeRec<Value, Data>[]\n : Fragment extends readonly (infer Value)[]\n ? readonly mirrorFragmentTypeRec<Value, Data>[]\n : Fragment extends null\n ? null\n : Fragment extends undefined\n ? undefined\n : Data;\n\ntype fragmentOfTypeRec<Document extends DocumentDefDecorationLike> =\n | readonly fragmentOfTypeRec<Document>[]\n | FragmentOf<Document>\n | undefined\n | null;\n\n/** Unmasks a fragment mask for a given fragment document and data.\n *\n * @param _document - A GraphQL document of a fragment, created using {@link graphql}.\n * @param fragment - A mask of the fragment, which can be wrapped in arrays, or nullable.\n * @returns The unmasked data of the fragment.\n *\n * @remarks\n * When {@link graphql} is used to create a fragment and is spread into another\n * fragment or query, their result types will only contain a “reference” to the\n * fragment. This encourages isolation and is known as “fragment masking.”\n *\n * This means that you must use {@link readFragment} to unmask these fragment masks\n * and get to the data. This encourages isolation and only using the data you define\n * a part of your codebase to require.\n *\n * @example\n * ```\n * import { FragmentOf, graphql, readFragment } from 'gql.tada';\n *\n * const bookFragment = graphql(`\n * fragment BookComponent on Book {\n * id\n * title\n * }\n * `);\n *\n * const getBook = (data: FragmentOf<typeof bookFragment> | null) => {\n * // Unmasks the fragment and casts to the result type of `bookFragment`\n * // This is intersected with `| null` in this case, due to the input type.\n * const book = readFragment(bookFragment, data);\n * };\n *\n * const bookQuery = graphql(`\n * query Book ($id: ID!) {\n * book(id: $id) {\n * id\n * ...BookComponent\n * }\n * }\n * `, [bookFragment]);\n *\n * const getQuery = (data: ResultOf<typeof bookQuery>) => {\n * getBook(data?.book);\n * };\n * ```\n *\n * @see {@link readFragment} for how to read from fragment masks.\n */\nfunction readFragment<\n const Document extends DocumentDefDecorationLike,\n const Fragment extends fragmentOfTypeRec<Document>,\n const Data,\n>(\n _document: DocumentDecoration<Data, any> & Document,\n fragment: Fragment\n): fragmentOfTypeRec<Document> extends Fragment ? unknown : mirrorFragmentTypeRec<Fragment, Data> {\n return fragment as any;\n}\n\nconst graphql: GraphQLTadaAPI<schemaOfConfig<setupSchema>> = initGraphQLTada();\n\nexport { parse, graphql, readFragment, initGraphQLTada };\n\nexport type {\n setupSchema,\n parseDocument,\n AbstractSetupSchema,\n GraphQLTadaAPI,\n TadaDocumentNode,\n ResultOf,\n VariablesOf,\n FragmentOf,\n};\n"],"names":["initGraphQLTada","graphql","input","fragments","definitions","_parse","seen","Set","document","definition","kind","Kind","FRAGMENT_DEFINITION","has","push","add","DOCUMENT","parse","readFragment","_document","fragment"],"mappings":";;AA8JA,SAASA;EAGP,OAAO,SAASC,QAAQC,GAAeC;IACrC,IAAMC,IAAcC,EAAOH,GAAOE;IAClC,IAAME,IAAO,IAAIC;IACjB,KAAK,IAAMC,KAAYL,KAAa;MAClC,KAAK,IAAMM,KAAcD,EAASJ;QAChC,IAAIK,EAAWC,SAASC,EAAKC,wBAAwBN,EAAKO,IAAIJ,IAAa;UACzEL,EAAYU,KAAKL;UACjBH,EAAKS,IAAIN;AACX;;;IAGJ,OAAO;MAAEC,MAAMC,EAAKK;MAAUZ,aAAa,KAAIA;;;AAEnD;;AAYA,SAASa,MAA0Cf;EACjD,OAAOG,EAAOH;AAChB;;AAgKA,SAASgB,aAKPC,GACAC;EAEA,OAAOA;AACT;;AAEA,IAAMnB,IAAuDD;;"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gql.tada",
|
|
3
3
|
"description": "The spec-compliant & magical GraphQL query language engine in the TypeScript type system",
|
|
4
|
-
"version": "1.0.0-beta.
|
|
4
|
+
"version": "1.0.0-beta.2",
|
|
5
5
|
"author": "0no.co <hi@0no.co>",
|
|
6
6
|
"source": "./src/index.ts",
|
|
7
7
|
"main": "./dist/gql-tada",
|