@takeshape/ssg 11.144.1 → 11.154.1

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.
Files changed (77) hide show
  1. package/package.json +5 -5
  2. package/dist/compress-html.d.ts +0 -3
  3. package/dist/compress-html.js +0 -20
  4. package/dist/config.d.ts +0 -76
  5. package/dist/config.js +0 -106
  6. package/dist/errors/formatting.d.ts +0 -4
  7. package/dist/errors/formatting.js +0 -8
  8. package/dist/errors/graphql-error.d.ts +0 -6
  9. package/dist/errors/graphql-error.js +0 -22
  10. package/dist/errors/index.d.ts +0 -5
  11. package/dist/errors/index.js +0 -5
  12. package/dist/errors/pagination-error.d.ts +0 -3
  13. package/dist/errors/pagination-error.js +0 -6
  14. package/dist/errors/template-render-error.d.ts +0 -4
  15. package/dist/errors/template-render-error.js +0 -11
  16. package/dist/files.d.ts +0 -3
  17. package/dist/files.js +0 -11
  18. package/dist/filters/array-filters.d.ts +0 -2
  19. package/dist/filters/array-filters.js +0 -2
  20. package/dist/filters/code-filter.d.ts +0 -1
  21. package/dist/filters/code-filter.js +0 -13
  22. package/dist/filters/create-asset-filter.d.ts +0 -1
  23. package/dist/filters/create-asset-filter.js +0 -5
  24. package/dist/filters/create-date-filter.d.ts +0 -2
  25. package/dist/filters/create-date-filter.js +0 -12
  26. package/dist/filters/create-image-filter.d.ts +0 -2
  27. package/dist/filters/create-image-filter.js +0 -7
  28. package/dist/filters/create-number-filter.d.ts +0 -3
  29. package/dist/filters/create-number-filter.js +0 -120
  30. package/dist/filters/create-route-filter.d.ts +0 -3
  31. package/dist/filters/create-route-filter.js +0 -24
  32. package/dist/filters/markdown-filter.d.ts +0 -1
  33. package/dist/filters/markdown-filter.js +0 -6
  34. package/dist/filters/pluralize-filter.d.ts +0 -1
  35. package/dist/filters/pluralize-filter.js +0 -4
  36. package/dist/generate/context.d.ts +0 -8
  37. package/dist/generate/context.js +0 -49
  38. package/dist/generate/generate.d.ts +0 -21
  39. package/dist/generate/generate.js +0 -300
  40. package/dist/generate/index.d.ts +0 -1
  41. package/dist/generate/index.js +0 -1
  42. package/dist/generate/streams.d.ts +0 -7
  43. package/dist/generate/streams.js +0 -88
  44. package/dist/generate/types.d.ts +0 -54
  45. package/dist/generate/types.js +0 -1
  46. package/dist/graphql/analyze.d.ts +0 -28
  47. package/dist/graphql/analyze.js +0 -87
  48. package/dist/graphql/ast.d.ts +0 -19
  49. package/dist/graphql/ast.js +0 -122
  50. package/dist/graphql/client-schema.d.ts +0 -3
  51. package/dist/graphql/client-schema.js +0 -8
  52. package/dist/graphql/index.d.ts +0 -6
  53. package/dist/graphql/index.js +0 -6
  54. package/dist/graphql/migrate.d.ts +0 -19
  55. package/dist/graphql/migrate.js +0 -111
  56. package/dist/graphql/pagination.d.ts +0 -36
  57. package/dist/graphql/pagination.js +0 -268
  58. package/dist/graphql/query.d.ts +0 -20
  59. package/dist/graphql/query.js +0 -141
  60. package/dist/graphql/schema-connector-factory.d.ts +0 -10
  61. package/dist/graphql/schema-connector-factory.js +0 -90
  62. package/dist/gzip.d.ts +0 -3
  63. package/dist/gzip.js +0 -14
  64. package/dist/index.d.ts +0 -6
  65. package/dist/index.js +0 -6
  66. package/dist/nunjucks.d.ts +0 -7
  67. package/dist/nunjucks.js +0 -88
  68. package/dist/paths.d.ts +0 -2
  69. package/dist/paths.js +0 -10
  70. package/dist/resolve-context.d.ts +0 -34
  71. package/dist/resolve-context.js +0 -115
  72. package/dist/stats.d.ts +0 -4
  73. package/dist/stats.js +0 -39
  74. package/dist/types.d.ts +0 -53
  75. package/dist/types.js +0 -1
  76. package/dist/util.d.ts +0 -2
  77. package/dist/util.js +0 -17
@@ -1,21 +0,0 @@
1
- import { type Config, type FileLoader, type PaginateConfig, type RouteConfig, type SyncFileLoader } from '../config.ts';
2
- import type { Data, GraphQLConnector, RenderedPage } from '../types.ts';
3
- import type { GenerateResult, GetPaginatedData, RenderContext } from './types.ts';
4
- export declare function calculatePages(total: number, pageSize: number): number;
5
- export declare function hasListPageConfig(paginate: PaginateConfig): boolean;
6
- export declare function hasItemPageConfig(route: RouteConfig): boolean;
7
- type RenderPaginatedRoute = (route: RouteConfig, context: Data) => Promise<RenderedPage[]>;
8
- export declare function renderPaginatedTemplate(generateContext: RenderContext, getPaginatedData: GetPaginatedData): RenderPaginatedRoute;
9
- export type GenerateParams = {
10
- fileLoader: FileLoader;
11
- connector: GraphQLConnector;
12
- templateFileLoader: SyncFileLoader;
13
- };
14
- export type GenerateRouteParams = {
15
- routeName: string;
16
- locale?: string;
17
- contentId?: string;
18
- } & GenerateParams;
19
- export declare function generateRoute(config: Config, params: GenerateRouteParams): Promise<GenerateResult>;
20
- export default function generate(config: Config, params: GenerateParams): Promise<GenerateResult>;
21
- export {};
@@ -1,300 +0,0 @@
1
- import { createAsyncWritable, pump } from '@takeshape/streams';
2
- import asyncIteratorToStream from 'async-iterator-to-stream';
3
- import BbPromise from 'bluebird';
4
- import compose from 'lodash/fp/compose.js';
5
- import flatten from 'lodash/fp/flatten.js';
6
- import partition from 'lodash/partition.js';
7
- import uniqBy from 'lodash/uniqBy.js';
8
- import { obj as Pumpify } from 'pumpify';
9
- import compressHtml from "../compress-html.js";
10
- import { localizeConfig } from "../config.js";
11
- import GraphQLError from "../errors/graphql-error.js";
12
- import PaginationError from "../errors/pagination-error.js";
13
- import { getClientSchema, getQueryIterator, withQueryTransforms } from "../graphql/index.js";
14
- import gzipContents from "../gzip.js";
15
- import nunjucks from "../nunjucks.js";
16
- import { joinPath } from "../paths.js";
17
- import resolveContext, { resolveGraphQLConfig } from "../resolve-context.js";
18
- import { combineContext, getItemContext, getListPageContext } from "./context.js";
19
- import { createItemRenderArgs, createListRenderArgs } from "./streams.js";
20
- const pageSize = Number(process.env.TS_EXPERIMENTAL_PAGE_SIZE) || 100;
21
- const getPaginatedData = async (generateContext, paginate, context) => {
22
- const { connector, fileLoader, srcPath, clientSchema, stats } = generateContext;
23
- if (paginate.data) {
24
- const config = await resolveGraphQLConfig(paginate.data, {
25
- fileLoader,
26
- srcPath
27
- });
28
- const res = await getQueryIterator(clientSchema, config.query, connector, {
29
- pageSize,
30
- variables: config.variables,
31
- source: config.source,
32
- stats
33
- });
34
- return {
35
- iterable: res.iterator(),
36
- total: res.total
37
- };
38
- }
39
- if (paginate.property) {
40
- const itemsArray = context[paginate.property];
41
- if (itemsArray) {
42
- const filtered = itemsArray.filter(Boolean);
43
- return {
44
- iterable: filtered,
45
- total: filtered.length
46
- };
47
- }
48
- }
49
- return null;
50
- };
51
- export function calculatePages(total, pageSize) {
52
- return Math.ceil(total / pageSize);
53
- }
54
- export function hasListPageConfig(paginate) {
55
- return Boolean(paginate.pageSize && paginate.template && paginate.path);
56
- }
57
- export function hasItemPageConfig(route) {
58
- return Boolean(route.path && route.template);
59
- }
60
- export function renderPaginatedTemplate(generateContext, getPaginatedData) {
61
- const { renderTemplate, stats, pathPrefix } = generateContext;
62
- return async (route, context) => {
63
- const { paginate } = route;
64
- if (!paginate) {
65
- throw new Error('Route missing paginate');
66
- }
67
- const shouldRenderItemPage = hasItemPageConfig(route);
68
- const shouldRenderListPage = hasListPageConfig(paginate);
69
- try {
70
- const paginatedData = await getPaginatedData(generateContext, paginate, context);
71
- if (!paginatedData) {
72
- return [];
73
- }
74
- const totalPages = calculatePages(paginatedData.total, paginate.pageSize);
75
- const routeContext = {
76
- pathPrefix,
77
- totalPages,
78
- renderTemplate,
79
- route,
80
- context
81
- };
82
- const pages = [];
83
- const writePages = () => createAsyncWritable(async (args) => {
84
- pages.push(await renderTemplate.apply(null, args));
85
- }, 100);
86
- const writeStreams = [];
87
- if (shouldRenderItemPage) {
88
- writeStreams.push(new Pumpify(createItemRenderArgs(routeContext, getItemContext, stats), writePages()));
89
- }
90
- if (shouldRenderListPage) {
91
- writeStreams.push(new Pumpify(createListRenderArgs(routeContext, getListPageContext), writePages()));
92
- }
93
- const data = asyncIteratorToStream.obj(paginatedData.iterable);
94
- await BbPromise.map(writeStreams, async (writeStream) => pump(data, writeStream));
95
- return pages;
96
- }
97
- catch (e) {
98
- if (e instanceof GraphQLError || e instanceof PaginationError) {
99
- throw e;
100
- }
101
- throw new Error(`Failed to render paginated route ${route.path}\n ${e.name}: ${e.message}`);
102
- }
103
- };
104
- }
105
- async function resolveRouteContext(generateContext, route) {
106
- const { srcPath, connector, fileLoader, stats } = generateContext;
107
- const contextConfig = route.context;
108
- return contextConfig
109
- ? resolveContext({
110
- contextConfig,
111
- srcPath,
112
- connector,
113
- fileLoader,
114
- stats,
115
- route
116
- })
117
- : {};
118
- }
119
- function renderTemplates(generateContext) {
120
- const { renderTemplate, config, globalContext, pathPrefix } = generateContext;
121
- return async (routes) => BbPromise.map(routes, async (route) => {
122
- const routeContext = await resolveRouteContext(generateContext, route);
123
- const context = combineContext(config.env, globalContext, route, routeContext);
124
- const path = joinPath(pathPrefix, route.path);
125
- const page = await renderTemplate(path, route.template, context);
126
- return {
127
- pages: [page],
128
- order: route._routeOrder
129
- };
130
- });
131
- }
132
- function renderPaginatedTemplates(generateContext) {
133
- const render = renderPaginatedTemplate(generateContext, getPaginatedData);
134
- return async (routes) => {
135
- const { config, globalContext } = generateContext;
136
- return BbPromise.map(routes, async (route) => {
137
- const routeContext = await resolveRouteContext(generateContext, route);
138
- const renderedPages = await render(route, combineContext(config.env, globalContext, route, routeContext));
139
- return {
140
- pages: renderedPages,
141
- order: route._routeOrder
142
- };
143
- });
144
- };
145
- }
146
- async function generatePages(config, generateContext) {
147
- const routeEntries = Object.entries(config.routes);
148
- const routesWithOrder = routeEntries.map(([, route], index) => ({ ...route, _routeOrder: index }));
149
- const [paginatedRouteConfigs, singleRouteConfigs] = partition(routesWithOrder, 'paginate');
150
- const renderContext = {
151
- ...generateContext,
152
- globalContext: {
153
- ...(config.context
154
- ? await resolveContext({
155
- contextConfig: config.context,
156
- srcPath: generateContext.srcPath,
157
- connector: generateContext.connector,
158
- fileLoader: generateContext.fileLoader,
159
- stats: generateContext.stats
160
- })
161
- : {}),
162
- locale: config.locale
163
- }
164
- };
165
- const singleRoutes = await renderTemplates(renderContext)(singleRouteConfigs);
166
- const paginatedRoutes = await renderPaginatedTemplates(renderContext)(paginatedRouteConfigs);
167
- const allRoutes = singleRoutes.concat(paginatedRoutes);
168
- const sortedRoutes = allRoutes.sort((a, b) => a.order - b.order);
169
- const allPages = sortedRoutes.flatMap((route) => route.pages);
170
- // First route wins
171
- return uniqBy(allPages, 'path');
172
- }
173
- function removeListingPageConfig(routeConfig) {
174
- if (routeConfig.paginate) {
175
- const { template, ...rest } = routeConfig.paginate;
176
- if (template) {
177
- return {
178
- ...routeConfig,
179
- paginate: {
180
- ...rest
181
- }
182
- };
183
- }
184
- }
185
- return routeConfig;
186
- }
187
- export async function generateRoute(config, params) {
188
- const { connector, fileLoader, templateFileLoader, routeName, locale, contentId } = params;
189
- const srcPath = config.templatePath;
190
- const stats = {
191
- pagesGenerated: 0,
192
- warnings: []
193
- };
194
- if (config.usageStats) {
195
- stats.contentUsage = {};
196
- }
197
- const clientSchema = await getClientSchema(connector);
198
- const { locales } = config;
199
- const localizedConfig = locales && locale && locales[locale] ? localizeConfig(config, locale) : config;
200
- const routeConfig = config.routes[routeName];
201
- if (!routeConfig) {
202
- return { pages: [], stats };
203
- }
204
- const globalContext = config.context
205
- ? await resolveContext({
206
- contextConfig: config.context,
207
- srcPath,
208
- connector,
209
- fileLoader,
210
- stats
211
- })
212
- : {};
213
- const renderContext = {
214
- renderTemplate: nunjucks(templateFileLoader, localizedConfig, stats),
215
- pathPrefix: localizedConfig.pathPrefix || '',
216
- fileLoader,
217
- connector: withQueryTransforms(connector, clientSchema, {
218
- locale,
219
- contentId,
220
- usage: config.usageStats
221
- }),
222
- clientSchema,
223
- srcPath,
224
- stats,
225
- config,
226
- globalContext
227
- };
228
- const routeWithOrder = { ...routeConfig, _routeOrder: 0 };
229
- const routes = await (routeConfig.paginate
230
- ? renderPaginatedTemplates(renderContext)([{ ...removeListingPageConfig(routeConfig), _routeOrder: 0 }])
231
- : renderTemplates(renderContext)([routeWithOrder]));
232
- // Flatten routes to pages since there's only one route
233
- const pages = routes.flatMap((route) => route.pages);
234
- return {
235
- pages,
236
- stats
237
- };
238
- }
239
- const identity = (obj) => obj;
240
- function getRenderTemplateDecorator(config) {
241
- const decorators = [];
242
- if (config.gzip) {
243
- decorators.push(gzipContents);
244
- }
245
- if (config.htmlCompression?.enabled) {
246
- decorators.push(compressHtml(config.htmlCompression));
247
- }
248
- return decorators.length ? compose(decorators) : identity;
249
- }
250
- export default async function generate(config, params) {
251
- const { connector, fileLoader, templateFileLoader } = params;
252
- const srcPath = config.templatePath;
253
- const stats = {
254
- pagesGenerated: 0,
255
- warnings: []
256
- };
257
- if (config.usageStats) {
258
- stats.contentUsage = {};
259
- }
260
- const clientSchema = await getClientSchema(connector);
261
- const generateContext = {
262
- pathPrefix: '',
263
- clientSchema,
264
- srcPath,
265
- stats,
266
- config,
267
- fileLoader
268
- };
269
- let pages;
270
- const renderTemplateDecorator = getRenderTemplateDecorator(config);
271
- const { locales } = config;
272
- if (locales) {
273
- const localizedPages = await BbPromise.map(Object.keys(locales), async (locale) => {
274
- const localizedConfig = localizeConfig(config, locale);
275
- return generatePages(localizedConfig, {
276
- ...generateContext,
277
- renderTemplate: renderTemplateDecorator(nunjucks(templateFileLoader, localizedConfig, stats)),
278
- pathPrefix: localizedConfig.pathPrefix,
279
- connector: withQueryTransforms(connector, clientSchema, {
280
- locale,
281
- usage: config.usageStats
282
- })
283
- });
284
- });
285
- pages = flatten(localizedPages);
286
- }
287
- else {
288
- pages = await generatePages(config, {
289
- ...generateContext,
290
- renderTemplate: renderTemplateDecorator(nunjucks(templateFileLoader, config, stats)),
291
- connector: withQueryTransforms(connector, clientSchema, {
292
- usage: config.usageStats
293
- })
294
- });
295
- }
296
- return {
297
- pages,
298
- stats
299
- };
300
- }
@@ -1 +0,0 @@
1
- export { default, generateRoute } from './generate.ts';
@@ -1 +0,0 @@
1
- export { default, generateRoute } from "./generate.js";
@@ -1,7 +0,0 @@
1
- import { Transform } from 'node:stream';
2
- import type { Stats } from '../types.ts';
3
- import type { GetItemContext, GetListPageContext } from './context.ts';
4
- import type { PathItem, PathItemContext, RouteContext } from './types.ts';
5
- export declare function readPageBuffer(buffer: PathItem[], last: boolean): PathItemContext;
6
- export declare function createItemRenderArgs(routeContext: RouteContext, getItemContext: GetItemContext, stats: Stats): Transform;
7
- export declare function createListRenderArgs(routeContext: RouteContext, getListPageContext: GetListPageContext): Transform;
@@ -1,88 +0,0 @@
1
- import { Transform } from 'node:stream';
2
- import { formatPath } from '@takeshape/routing';
3
- import { joinPath } from "../paths.js";
4
- import { generateWarning, recordContentUsage } from "../stats.js";
5
- export function readPageBuffer(buffer, last) {
6
- const { length } = buffer;
7
- const offset = length === 1 || (length < 3 && !last) ? -1 : 0;
8
- return {
9
- previous: buffer[offset],
10
- current: buffer[1 + offset],
11
- next: buffer[2 + offset]
12
- };
13
- }
14
- function handlePathWarnings(stats, warnings, route) {
15
- for (const variable of warnings) {
16
- generateWarning(stats, 'renderPaginatedTemplate', `${route.path} variable ${variable} resolves to undefined.`);
17
- }
18
- }
19
- export function createItemRenderArgs(routeContext, getItemContext, stats) {
20
- const { route, context, pathPrefix } = routeContext;
21
- const buffer = [];
22
- const createArgs = (last) => {
23
- const itemContext = getItemContext(route, context, readPageBuffer(buffer, last));
24
- return [itemContext.currentPath, route.template, itemContext];
25
- };
26
- return new Transform({
27
- objectMode: true,
28
- transform(obj, _, next) {
29
- const { path, warnings } = formatPath(route.path, obj);
30
- const currentPath = joinPath(pathPrefix, path);
31
- if (warnings.length) {
32
- handlePathWarnings(stats, warnings, route);
33
- }
34
- else {
35
- buffer.push({ item: obj, path: currentPath });
36
- if (buffer.length > 1) {
37
- this.push(createArgs(false));
38
- if (buffer.length > 2) {
39
- buffer.shift();
40
- }
41
- }
42
- recordContentUsage(stats, obj, currentPath);
43
- }
44
- next();
45
- },
46
- flush(done) {
47
- if (buffer.length) {
48
- this.push(createArgs(true));
49
- }
50
- done();
51
- }
52
- });
53
- }
54
- export function createListRenderArgs(routeContext, getListPageContext) {
55
- const { pathPrefix, route } = routeContext;
56
- const { paginate } = route;
57
- if (!paginate) {
58
- throw new Error('Cannot create list page for non-paginated route');
59
- }
60
- const { template, pageSize } = paginate;
61
- if (!template) {
62
- throw new Error('Cannot create list page missing paginate.template');
63
- }
64
- let buffer = [];
65
- let page = 1;
66
- const createArgs = () => {
67
- const context = getListPageContext(buffer, page, routeContext);
68
- page++;
69
- buffer = [];
70
- return [joinPath(pathPrefix, context.currentPath), template, context];
71
- };
72
- return new Transform({
73
- objectMode: true,
74
- transform(obj, _, next) {
75
- buffer.push(obj);
76
- if (buffer.length === pageSize) {
77
- this.push(createArgs());
78
- }
79
- next();
80
- },
81
- flush(done) {
82
- if (buffer.length) {
83
- this.push(createArgs());
84
- }
85
- done();
86
- }
87
- });
88
- }
@@ -1,54 +0,0 @@
1
- import type { GraphQLSchema } from 'graphql';
2
- import type { Config, FileLoader, PaginateConfig, RouteConfig, RoutesMap } from '../config.ts';
3
- import type { Data, GraphQLConnector, RenderedPage, RenderTemplate, Stats } from '../types.ts';
4
- export type GenerateResult = {
5
- pages: RenderedPage[];
6
- stats: Stats;
7
- };
8
- export type GenerateContext = {
9
- config: Config;
10
- pathPrefix: string;
11
- clientSchema: GraphQLSchema;
12
- srcPath: string;
13
- stats: Stats;
14
- renderTemplate: RenderTemplate;
15
- connector: GraphQLConnector;
16
- fileLoader: FileLoader;
17
- };
18
- export type RenderContext = {
19
- globalContext: Data;
20
- } & GenerateContext;
21
- export type RouteContext = {
22
- pathPrefix: string;
23
- totalPages: number;
24
- renderTemplate: RenderTemplate;
25
- route: RouteConfig;
26
- context: Data;
27
- };
28
- export type PathItem = {
29
- item: Data;
30
- path: string;
31
- };
32
- export type PathItemContext = {
33
- previous?: PathItem;
34
- current: PathItem;
35
- next?: PathItem;
36
- };
37
- export type ItemBuffer = {
38
- push(item: Data, path: string): void;
39
- done(): Promise<RenderedPage[]>;
40
- };
41
- export type ListPageBuffer = {
42
- push(item: Data): void;
43
- done(): Promise<RenderedPage[]>;
44
- };
45
- export type ResolveRoutesContextParams = {
46
- routes: RoutesMap;
47
- srcPath: string;
48
- connector: GraphQLConnector;
49
- stats: Stats;
50
- };
51
- export type GetPaginatedData = (generateContext: GenerateContext, paginate: PaginateConfig, context: Data) => Promise<{
52
- iterable: Iterable<Data>;
53
- total: number;
54
- } | null>;
@@ -1 +0,0 @@
1
- export {};
@@ -1,28 +0,0 @@
1
- import { type DocumentNode, type GraphQLSchema } from 'graphql';
2
- import { type Config, type FileLoader, type RouteInfo } from '../config.ts';
3
- type FileInfo = {
4
- body: string;
5
- name: string;
6
- };
7
- type Usage = {
8
- file: string;
9
- location: {
10
- line: number;
11
- column: number;
12
- };
13
- };
14
- type UsageInfo = {
15
- type: string;
16
- usage: Usage[];
17
- };
18
- type UsageInfoMap = Record<string, Record<string, UsageInfo>>;
19
- export declare function getFieldUsage(queryAst: DocumentNode, schema: GraphQLSchema, fileInfo: FileInfo): UsageInfoMap;
20
- export declare function detectTypes(queryAst: DocumentNode, schema: GraphQLSchema): Set<string>;
21
- export type TypeUsage = Record<string, RouteInfo[]>;
22
- export type GetTypeUsageParams = {
23
- config: Config;
24
- schema: GraphQLSchema;
25
- fileLoader: FileLoader;
26
- };
27
- export declare function getTypeUsage({ config, schema, fileLoader }: GetTypeUsageParams): Promise<TypeUsage>;
28
- export {};
@@ -1,87 +0,0 @@
1
- import path from 'node:path';
2
- import BbPromise from 'bluebird';
3
- import { getLocation, isListType, isObjectType, parse, Source, TypeInfo, visit, visitWithTypeInfo } from 'graphql';
4
- import { getGraphQLQueries } from "../config.js";
5
- import { getFields, getItemType } from "./query.js";
6
- const startLocation = { line: 1, column: 1 };
7
- export function getFieldUsage(queryAst, schema, fileInfo) {
8
- const typeInfo = new TypeInfo(schema);
9
- const result = {};
10
- const visitor = {
11
- Field: {
12
- enter(node) {
13
- const field = typeInfo.getFieldDef();
14
- if (!field) {
15
- return;
16
- }
17
- const type = getItemType(field.type);
18
- const fields = getFields(type);
19
- const fieldInfo = result[type.toString()] || {};
20
- if (fields && node.selectionSet) {
21
- for (const selection of node.selectionSet.selections) {
22
- if (selection.kind === 'Field' || selection.kind === 'FragmentSpread') {
23
- const name = selection.name.value;
24
- const usage = fieldInfo[name] ? fieldInfo[name].usage : [];
25
- const source = new Source(fileInfo.body, fileInfo.name, startLocation);
26
- fieldInfo[name] = {
27
- type: fields[name].type.toString(),
28
- usage: usage.concat({
29
- file: fileInfo.name,
30
- location: selection.loc ? getLocation(source, selection.loc.start) : startLocation
31
- })
32
- };
33
- }
34
- }
35
- result[type.toString()] = fieldInfo;
36
- }
37
- }
38
- }
39
- };
40
- visit(queryAst, visitWithTypeInfo(typeInfo, visitor));
41
- return result;
42
- }
43
- export function detectTypes(queryAst, schema) {
44
- const typeInfo = new TypeInfo(schema);
45
- const result = new Set();
46
- const queryType = schema.getQueryType();
47
- if (!queryType) {
48
- throw new Error('Invalid schema has no queries');
49
- }
50
- const topLevelQueries = new Set(Object.keys(queryType.getFields()));
51
- const visitor = {
52
- Field: {
53
- enter(node) {
54
- if (topLevelQueries.has(node.name.value)) {
55
- const field = typeInfo.getFieldDef();
56
- if (field) {
57
- const fieldType = field.type;
58
- if (isObjectType(fieldType)) {
59
- const fields = fieldType.getFields();
60
- if (fields.items && isListType(fields.items.type)) {
61
- result.add(fields.items.type.ofType.toString());
62
- }
63
- else {
64
- result.add(fieldType.toString());
65
- }
66
- }
67
- }
68
- }
69
- }
70
- }
71
- };
72
- visit(queryAst, visitWithTypeInfo(typeInfo, visitor));
73
- return result;
74
- }
75
- export async function getTypeUsage({ config, schema, fileLoader }) {
76
- const queries = getGraphQLQueries(config);
77
- return BbPromise.reduce(queries, async (result, routeQuery) => {
78
- const { filePath, ...info } = routeQuery;
79
- const queryString = await fileLoader(path.join(config.templatePath, filePath));
80
- const types = detectTypes(parse(queryString), schema);
81
- for (const type of types) {
82
- result[type] ||= [];
83
- result[type].push(info);
84
- }
85
- return result;
86
- }, {});
87
- }
@@ -1,19 +0,0 @@
1
- import type { ArgumentNode, DefinitionNode, DocumentNode, FieldNode, OperationDefinitionNode, SelectionNode, SelectionSetNode, VariableDefinitionNode } from 'graphql';
2
- export type Arg = {
3
- name: string;
4
- value: string;
5
- };
6
- export type Var = {
7
- name: string;
8
- type: string;
9
- };
10
- export declare function createArgument({ name, value }: Arg): ArgumentNode;
11
- export declare function createVariableDefinition({ name, type }: Var): VariableDefinitionNode;
12
- export declare function createSelectionSet(selections: SelectionNode[]): SelectionSetNode;
13
- export declare function createField(name: string): FieldNode;
14
- export declare function isQueryNode(node: DefinitionNode): node is OperationDefinitionNode;
15
- export declare function findQuery(ast: DocumentNode): OperationDefinitionNode | undefined;
16
- export declare function updateQuery(ast: DocumentNode, update: (query: OperationDefinitionNode) => OperationDefinitionNode): DocumentNode;
17
- export declare function addQueryVariables(variables: Var[], ast: DocumentNode): DocumentNode;
18
- export declare function wrapSelectionSet(selectionSet: SelectionSetNode, name: string, args?: ArgumentNode[]): SelectionSetNode;
19
- export declare function wrapQuery(name: string, args: Arg[], ast: DocumentNode): DocumentNode;