@takeshape/ssg 11.144.1 → 11.154.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/package.json +5 -5
- package/dist/compress-html.d.ts +0 -3
- package/dist/compress-html.js +0 -20
- package/dist/config.d.ts +0 -76
- package/dist/config.js +0 -106
- package/dist/errors/formatting.d.ts +0 -4
- package/dist/errors/formatting.js +0 -8
- package/dist/errors/graphql-error.d.ts +0 -6
- package/dist/errors/graphql-error.js +0 -22
- package/dist/errors/index.d.ts +0 -5
- package/dist/errors/index.js +0 -5
- package/dist/errors/pagination-error.d.ts +0 -3
- package/dist/errors/pagination-error.js +0 -6
- package/dist/errors/template-render-error.d.ts +0 -4
- package/dist/errors/template-render-error.js +0 -11
- package/dist/files.d.ts +0 -3
- package/dist/files.js +0 -11
- package/dist/filters/array-filters.d.ts +0 -2
- package/dist/filters/array-filters.js +0 -2
- package/dist/filters/code-filter.d.ts +0 -1
- package/dist/filters/code-filter.js +0 -13
- package/dist/filters/create-asset-filter.d.ts +0 -1
- package/dist/filters/create-asset-filter.js +0 -5
- package/dist/filters/create-date-filter.d.ts +0 -2
- package/dist/filters/create-date-filter.js +0 -12
- package/dist/filters/create-image-filter.d.ts +0 -2
- package/dist/filters/create-image-filter.js +0 -7
- package/dist/filters/create-number-filter.d.ts +0 -3
- package/dist/filters/create-number-filter.js +0 -120
- package/dist/filters/create-route-filter.d.ts +0 -3
- package/dist/filters/create-route-filter.js +0 -24
- package/dist/filters/markdown-filter.d.ts +0 -1
- package/dist/filters/markdown-filter.js +0 -6
- package/dist/filters/pluralize-filter.d.ts +0 -1
- package/dist/filters/pluralize-filter.js +0 -4
- package/dist/generate/context.d.ts +0 -8
- package/dist/generate/context.js +0 -49
- package/dist/generate/generate.d.ts +0 -21
- package/dist/generate/generate.js +0 -300
- package/dist/generate/index.d.ts +0 -1
- package/dist/generate/index.js +0 -1
- package/dist/generate/streams.d.ts +0 -7
- package/dist/generate/streams.js +0 -88
- package/dist/generate/types.d.ts +0 -54
- package/dist/generate/types.js +0 -1
- package/dist/graphql/analyze.d.ts +0 -28
- package/dist/graphql/analyze.js +0 -87
- package/dist/graphql/ast.d.ts +0 -19
- package/dist/graphql/ast.js +0 -122
- package/dist/graphql/client-schema.d.ts +0 -3
- package/dist/graphql/client-schema.js +0 -8
- package/dist/graphql/index.d.ts +0 -6
- package/dist/graphql/index.js +0 -6
- package/dist/graphql/migrate.d.ts +0 -19
- package/dist/graphql/migrate.js +0 -111
- package/dist/graphql/pagination.d.ts +0 -36
- package/dist/graphql/pagination.js +0 -268
- package/dist/graphql/query.d.ts +0 -20
- package/dist/graphql/query.js +0 -141
- package/dist/graphql/schema-connector-factory.d.ts +0 -10
- package/dist/graphql/schema-connector-factory.js +0 -90
- package/dist/gzip.d.ts +0 -3
- package/dist/gzip.js +0 -14
- package/dist/index.d.ts +0 -6
- package/dist/index.js +0 -6
- package/dist/nunjucks.d.ts +0 -7
- package/dist/nunjucks.js +0 -88
- package/dist/paths.d.ts +0 -2
- package/dist/paths.js +0 -10
- package/dist/resolve-context.d.ts +0 -34
- package/dist/resolve-context.js +0 -115
- package/dist/stats.d.ts +0 -4
- package/dist/stats.js +0 -39
- package/dist/types.d.ts +0 -53
- package/dist/types.js +0 -1
- package/dist/util.d.ts +0 -2
- package/dist/util.js +0 -17
package/dist/graphql/ast.js
DELETED
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
import { Kind } from 'graphql/language';
|
|
2
|
-
export function createArgument({ name, value }) {
|
|
3
|
-
return {
|
|
4
|
-
kind: Kind.ARGUMENT,
|
|
5
|
-
name: {
|
|
6
|
-
kind: Kind.NAME,
|
|
7
|
-
value: name
|
|
8
|
-
},
|
|
9
|
-
value: {
|
|
10
|
-
kind: Kind.VARIABLE,
|
|
11
|
-
name: {
|
|
12
|
-
kind: Kind.NAME,
|
|
13
|
-
value
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
function notNull(type) {
|
|
19
|
-
return {
|
|
20
|
-
kind: Kind.NON_NULL_TYPE,
|
|
21
|
-
type
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
function createType(typeString) {
|
|
25
|
-
const isNotNull = typeString.endsWith('!');
|
|
26
|
-
const value = isNotNull ? typeString.slice(0, typeString.length - 1) : typeString;
|
|
27
|
-
const namedType = {
|
|
28
|
-
kind: Kind.NAMED_TYPE,
|
|
29
|
-
name: {
|
|
30
|
-
kind: Kind.NAME,
|
|
31
|
-
value
|
|
32
|
-
}
|
|
33
|
-
};
|
|
34
|
-
return isNotNull ? notNull(namedType) : namedType;
|
|
35
|
-
}
|
|
36
|
-
export function createVariableDefinition({ name, type }) {
|
|
37
|
-
return {
|
|
38
|
-
kind: Kind.VARIABLE_DEFINITION,
|
|
39
|
-
directives: [],
|
|
40
|
-
variable: {
|
|
41
|
-
kind: Kind.VARIABLE,
|
|
42
|
-
name: {
|
|
43
|
-
kind: Kind.NAME,
|
|
44
|
-
value: name
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
type: createType(type)
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
export function createSelectionSet(selections) {
|
|
51
|
-
return {
|
|
52
|
-
kind: Kind.SELECTION_SET,
|
|
53
|
-
selections
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
export function createField(name) {
|
|
57
|
-
return {
|
|
58
|
-
kind: Kind.FIELD,
|
|
59
|
-
name: {
|
|
60
|
-
kind: Kind.NAME,
|
|
61
|
-
value: name
|
|
62
|
-
},
|
|
63
|
-
arguments: [],
|
|
64
|
-
directives: []
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
export function isQueryNode(node) {
|
|
68
|
-
return node.kind === 'OperationDefinition' && node.operation === 'query';
|
|
69
|
-
}
|
|
70
|
-
export function findQuery(ast) {
|
|
71
|
-
return ast.definitions.find(isQueryNode);
|
|
72
|
-
}
|
|
73
|
-
export function updateQuery(ast, update) {
|
|
74
|
-
const index = ast.definitions.findIndex(isQueryNode);
|
|
75
|
-
if (index !== -1) {
|
|
76
|
-
const { definitions, ...rest } = ast;
|
|
77
|
-
const updatedDefinitions = [...definitions];
|
|
78
|
-
updatedDefinitions[index] = update(definitions[index]);
|
|
79
|
-
return { ...rest, definitions: updatedDefinitions };
|
|
80
|
-
}
|
|
81
|
-
return ast;
|
|
82
|
-
}
|
|
83
|
-
export function addQueryVariables(variables, ast) {
|
|
84
|
-
return updateQuery(ast, (query) => {
|
|
85
|
-
const variableNames = new Set(variables.map((variable) => variable.name));
|
|
86
|
-
if (query.variableDefinitions) {
|
|
87
|
-
return {
|
|
88
|
-
...query,
|
|
89
|
-
variableDefinitions: query.variableDefinitions
|
|
90
|
-
.filter((def) => !variableNames.has(def.variable.name.value))
|
|
91
|
-
.concat(variables.map(createVariableDefinition))
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
return query;
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
export function wrapSelectionSet(selectionSet, name, args = []) {
|
|
98
|
-
return {
|
|
99
|
-
kind: Kind.SELECTION_SET,
|
|
100
|
-
selections: [
|
|
101
|
-
{
|
|
102
|
-
kind: Kind.FIELD,
|
|
103
|
-
name: {
|
|
104
|
-
kind: Kind.NAME,
|
|
105
|
-
value: name
|
|
106
|
-
},
|
|
107
|
-
arguments: args,
|
|
108
|
-
directives: [],
|
|
109
|
-
selectionSet
|
|
110
|
-
}
|
|
111
|
-
]
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
export function wrapQuery(name, args, ast) {
|
|
115
|
-
return updateQuery(ast, (query) => {
|
|
116
|
-
const argsAst = args.map(createArgument);
|
|
117
|
-
return {
|
|
118
|
-
...query,
|
|
119
|
-
selectionSet: wrapSelectionSet(query.selectionSet, name, argsAst)
|
|
120
|
-
};
|
|
121
|
-
});
|
|
122
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { buildClientSchema, getIntrospectionQuery } from 'graphql';
|
|
2
|
-
export async function getClientSchema(connector) {
|
|
3
|
-
const res = await connector({ query: getIntrospectionQuery() }, { applyMigrations: false });
|
|
4
|
-
if (!res.data) {
|
|
5
|
-
throw new Error('Failed to fetch client schema');
|
|
6
|
-
}
|
|
7
|
-
return buildClientSchema(res.data);
|
|
8
|
-
}
|
package/dist/graphql/index.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export { getFieldUsage, getTypeUsage, type TypeUsage } from './analyze.ts';
|
|
2
|
-
export { getClientSchema } from './client-schema.ts';
|
|
3
|
-
export { connectorWithMigrations } from './migrate.ts';
|
|
4
|
-
export { getQueryIterator } from './pagination.ts';
|
|
5
|
-
export { withQueryTransforms } from './query.ts';
|
|
6
|
-
export { schemaConnectorFactory } from './schema-connector-factory.ts';
|
package/dist/graphql/index.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export { getFieldUsage, getTypeUsage } from "./analyze.js";
|
|
2
|
-
export { getClientSchema } from "./client-schema.js";
|
|
3
|
-
export { connectorWithMigrations } from "./migrate.js";
|
|
4
|
-
export { getQueryIterator } from "./pagination.js";
|
|
5
|
-
export { withQueryTransforms } from "./query.js";
|
|
6
|
-
export { schemaConnectorFactory } from "./schema-connector-factory.js";
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { type DocumentNode } from 'graphql';
|
|
2
|
-
import { type Location, type SourceLocation } from 'graphql/language';
|
|
3
|
-
import type { GraphQLConnector, GraphQLResult } from '../types.ts';
|
|
4
|
-
export declare function formatWarning(name: string, loc?: Location, queryStr?: string, source?: string): Warning;
|
|
5
|
-
export type MapGraphQLResponse = (res: GraphQLResult) => GraphQLResult;
|
|
6
|
-
export declare function getMapResponse(props: string[]): MapGraphQLResponse;
|
|
7
|
-
export type Warning = {
|
|
8
|
-
message: string;
|
|
9
|
-
location: SourceLocation;
|
|
10
|
-
source: string;
|
|
11
|
-
};
|
|
12
|
-
export type MigrateListQueriesResult = {
|
|
13
|
-
ast: DocumentNode;
|
|
14
|
-
warnings: Warning[];
|
|
15
|
-
migrated: boolean;
|
|
16
|
-
mapResponse: MapGraphQLResponse | null;
|
|
17
|
-
};
|
|
18
|
-
export declare function migrateListQueries(ast: DocumentNode, queryStr?: string, source?: string): MigrateListQueriesResult;
|
|
19
|
-
export declare function connectorWithMigrations(connector: GraphQLConnector): GraphQLConnector;
|
package/dist/graphql/migrate.js
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { parse, Source } from 'graphql';
|
|
2
|
-
import { getLocation, Kind, print } from 'graphql/language';
|
|
3
|
-
import { updateQuery } from "./ast.js";
|
|
4
|
-
function wrapListQuerySelection(selectionSet) {
|
|
5
|
-
return {
|
|
6
|
-
kind: Kind.SELECTION_SET,
|
|
7
|
-
selections: [
|
|
8
|
-
{
|
|
9
|
-
kind: Kind.FIELD,
|
|
10
|
-
name: {
|
|
11
|
-
kind: Kind.NAME,
|
|
12
|
-
value: 'items'
|
|
13
|
-
},
|
|
14
|
-
arguments: [],
|
|
15
|
-
directives: [],
|
|
16
|
-
selectionSet
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
kind: Kind.FIELD,
|
|
20
|
-
name: {
|
|
21
|
-
kind: Kind.NAME,
|
|
22
|
-
value: 'total'
|
|
23
|
-
},
|
|
24
|
-
arguments: [],
|
|
25
|
-
directives: []
|
|
26
|
-
}
|
|
27
|
-
]
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
function isOldListQuery(selection) {
|
|
31
|
-
if (selection.kind !== 'Field') {
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
const { name, selectionSet } = selection;
|
|
35
|
-
return Boolean(/^get.+List$/.exec(name.value) &&
|
|
36
|
-
selectionSet &&
|
|
37
|
-
!selectionSet.selections.find((selection) => selection.kind === 'Field' && (selection.name.value === 'items' || selection.name.value === 'total')));
|
|
38
|
-
}
|
|
39
|
-
const startLocation = { line: 1, column: 1 };
|
|
40
|
-
export function formatWarning(name, loc, queryStr, source) {
|
|
41
|
-
const location = queryStr && loc && source
|
|
42
|
-
? getLocation(new Source(queryStr, source, startLocation), loc.start)
|
|
43
|
-
: { line: 1, column: 1 };
|
|
44
|
-
return {
|
|
45
|
-
message: `Using old format of ${name} Line ${location.line} Column ${location.column}`,
|
|
46
|
-
location,
|
|
47
|
-
source: source ?? ''
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
export function getMapResponse(props) {
|
|
51
|
-
return (res) => {
|
|
52
|
-
// Shallow clone res
|
|
53
|
-
const newRes = { ...res };
|
|
54
|
-
newRes.data = { ...res.data };
|
|
55
|
-
for (const prop of props) {
|
|
56
|
-
if (res.data?.[prop]) {
|
|
57
|
-
newRes.data[prop] = res.data[prop].items;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return newRes;
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
export function migrateListQueries(ast, queryStr, source) {
|
|
64
|
-
let migrated = false;
|
|
65
|
-
const migratedProps = [];
|
|
66
|
-
const warnings = [];
|
|
67
|
-
const updatedAst = updateQuery(ast, (queryDef) => {
|
|
68
|
-
return {
|
|
69
|
-
...queryDef,
|
|
70
|
-
selectionSet: {
|
|
71
|
-
...queryDef.selectionSet,
|
|
72
|
-
selections: queryDef.selectionSet.selections.map((selection) => {
|
|
73
|
-
if (isOldListQuery(selection) && selection.selectionSet) {
|
|
74
|
-
migratedProps.push(selection.alias ? selection.alias.value : selection.name.value);
|
|
75
|
-
migrated = true;
|
|
76
|
-
warnings.push(formatWarning(selection.name.value, selection.loc, queryStr, source));
|
|
77
|
-
return {
|
|
78
|
-
...selection,
|
|
79
|
-
selectionSet: wrapListQuerySelection(selection.selectionSet)
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
return selection;
|
|
83
|
-
})
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
});
|
|
87
|
-
return {
|
|
88
|
-
ast: updatedAst,
|
|
89
|
-
warnings,
|
|
90
|
-
migrated,
|
|
91
|
-
mapResponse: migrated ? getMapResponse(migratedProps) : null
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
export function connectorWithMigrations(connector) {
|
|
95
|
-
return async (gqlParams, { stats, source = 'query.graphql', applyMigrations = true } = {}) => {
|
|
96
|
-
if (!applyMigrations) {
|
|
97
|
-
return connector(gqlParams);
|
|
98
|
-
}
|
|
99
|
-
let { query } = gqlParams;
|
|
100
|
-
const queryAst = parse(query);
|
|
101
|
-
const { migrated, warnings, ast, mapResponse } = migrateListQueries(queryAst, query, source);
|
|
102
|
-
if (migrated) {
|
|
103
|
-
query = print(ast);
|
|
104
|
-
}
|
|
105
|
-
if (warnings && stats?.warnings) {
|
|
106
|
-
stats.warnings = stats.warnings.concat(warnings);
|
|
107
|
-
}
|
|
108
|
-
const res = await connector({ query, variables: gqlParams.variables });
|
|
109
|
-
return migrated && mapResponse ? mapResponse(res) : res;
|
|
110
|
-
};
|
|
111
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { type DocumentNode, type GraphQLSchema } from 'graphql';
|
|
2
|
-
import type { Data, GraphQLConnector, Stats } from '../types.ts';
|
|
3
|
-
export type PaginationStrategy = {
|
|
4
|
-
type: string;
|
|
5
|
-
fromName: string;
|
|
6
|
-
sizeName: string;
|
|
7
|
-
hasNextPath?: string[];
|
|
8
|
-
cursorPath?: string[];
|
|
9
|
-
totalPath?: string[];
|
|
10
|
-
itemsPath: string[];
|
|
11
|
-
};
|
|
12
|
-
export type PaginatedField = {
|
|
13
|
-
strategy: PaginationStrategy;
|
|
14
|
-
fromVarName: string;
|
|
15
|
-
sizeVarName: string;
|
|
16
|
-
astPath: string[];
|
|
17
|
-
queryPath: string[];
|
|
18
|
-
};
|
|
19
|
-
export declare function findPaginatedFields(ast: DocumentNode, schema: GraphQLSchema): PaginatedField[];
|
|
20
|
-
export declare function removeNonPaginated(ast: DocumentNode, paginatedFields: PaginatedField[]): DocumentNode;
|
|
21
|
-
export declare function addPaginationVariables(ast: DocumentNode, paginatedFields: PaginatedField[]): DocumentNode;
|
|
22
|
-
export declare function hasField(ast: Record<string, any>, queryPath: string[]): boolean;
|
|
23
|
-
export declare function ensureField(ast: any, queryPath: string[]): DocumentNode;
|
|
24
|
-
export declare function ensurePaginationFields(ast: DocumentNode, paginatedFields: PaginatedField[], source?: string): DocumentNode;
|
|
25
|
-
export declare function isDone(queryArgs: Data, queryData: Data, paginatedField: PaginatedField): boolean;
|
|
26
|
-
export type GetQueryIteratorOptions = {
|
|
27
|
-
variables?: Data;
|
|
28
|
-
pageSize?: number;
|
|
29
|
-
source?: string;
|
|
30
|
-
stats?: Stats;
|
|
31
|
-
};
|
|
32
|
-
export type QueryIteratorResult = {
|
|
33
|
-
iterator: () => AsyncGenerator;
|
|
34
|
-
total?: number;
|
|
35
|
-
};
|
|
36
|
-
export declare function getQueryIterator(schema: GraphQLSchema, query: string, connector: GraphQLConnector, { variables, pageSize, source, stats }?: GetQueryIteratorOptions): Promise<QueryIteratorResult>;
|
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
import { parse, print, TypeInfo, visit, visitWithTypeInfo } from 'graphql';
|
|
2
|
-
import get from 'lodash/get.js';
|
|
3
|
-
import keyBy from 'lodash/keyBy.js';
|
|
4
|
-
import GraphQLError from "../errors/graphql-error.js";
|
|
5
|
-
import PaginationError from "../errors/pagination-error.js";
|
|
6
|
-
import { updateIn } from "../util.js";
|
|
7
|
-
import { createArgument, createField, createSelectionSet, createVariableDefinition } from "./ast.js";
|
|
8
|
-
const paginationStrategies = [
|
|
9
|
-
{
|
|
10
|
-
type: 'cursor',
|
|
11
|
-
fromName: 'after',
|
|
12
|
-
sizeName: 'first',
|
|
13
|
-
hasNextPath: ['pageInfo', 'hasNextPage'],
|
|
14
|
-
cursorPath: ['pageInfo', 'endCursor'],
|
|
15
|
-
itemsPath: ['items']
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
type: 'offset',
|
|
19
|
-
fromName: 'from',
|
|
20
|
-
sizeName: 'size',
|
|
21
|
-
totalPath: ['total'],
|
|
22
|
-
itemsPath: ['items']
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
type: 'offset',
|
|
26
|
-
fromName: 'offset',
|
|
27
|
-
sizeName: 'limit',
|
|
28
|
-
totalPath: ['total'],
|
|
29
|
-
itemsPath: ['items']
|
|
30
|
-
}
|
|
31
|
-
];
|
|
32
|
-
function getPaginationStrategy(fieldDef) {
|
|
33
|
-
if (fieldDef) {
|
|
34
|
-
const { args } = fieldDef;
|
|
35
|
-
if (args?.length) {
|
|
36
|
-
const keyedArgs = keyBy(args, 'name');
|
|
37
|
-
return paginationStrategies.find((strategy) => {
|
|
38
|
-
const { fromName, sizeName } = strategy;
|
|
39
|
-
return keyedArgs[fromName] && keyedArgs[sizeName];
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
function getVariableName(path, name) {
|
|
45
|
-
return path.concat([name]).join('_');
|
|
46
|
-
}
|
|
47
|
-
export function findPaginatedFields(ast, schema) {
|
|
48
|
-
const typeInfo = new TypeInfo(schema);
|
|
49
|
-
const result = [];
|
|
50
|
-
const queryPath = [];
|
|
51
|
-
const visitor = {
|
|
52
|
-
Field: {
|
|
53
|
-
enter(node, _, __, path) {
|
|
54
|
-
queryPath.push(node.alias ? node.alias.value : node.name.value);
|
|
55
|
-
const fieldDef = typeInfo.getFieldDef();
|
|
56
|
-
if (fieldDef) {
|
|
57
|
-
const strategy = getPaginationStrategy(fieldDef);
|
|
58
|
-
if (strategy) {
|
|
59
|
-
result.push({
|
|
60
|
-
strategy,
|
|
61
|
-
fromVarName: getVariableName(queryPath, strategy.fromName),
|
|
62
|
-
sizeVarName: getVariableName(queryPath, strategy.sizeName),
|
|
63
|
-
astPath: path.map(String),
|
|
64
|
-
queryPath: queryPath.slice()
|
|
65
|
-
});
|
|
66
|
-
// Skip child nodes
|
|
67
|
-
queryPath.pop();
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
leave() {
|
|
73
|
-
queryPath.pop();
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
visit(ast, visitWithTypeInfo(typeInfo, visitor));
|
|
78
|
-
return result;
|
|
79
|
-
}
|
|
80
|
-
export function removeNonPaginated(ast, paginatedFields) {
|
|
81
|
-
const paths = new Set();
|
|
82
|
-
for (const field of paginatedFields) {
|
|
83
|
-
paths.add(field.astPath.join('.'));
|
|
84
|
-
}
|
|
85
|
-
const visitor = {
|
|
86
|
-
Field: {
|
|
87
|
-
enter(_, __, ___, path) {
|
|
88
|
-
return paths.has(path.join('.')) ? false : null;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
return visit(ast, visitor);
|
|
93
|
-
}
|
|
94
|
-
export function addPaginationVariables(ast, paginatedFields) {
|
|
95
|
-
const variablesToReplace = Object.create(null);
|
|
96
|
-
const variables = [];
|
|
97
|
-
for (const paginatedField of paginatedFields) {
|
|
98
|
-
const { fromVarName, sizeVarName, strategy } = paginatedField;
|
|
99
|
-
const { sizeName, fromName } = strategy;
|
|
100
|
-
updateIn(ast, paginatedField.astPath, (field) => {
|
|
101
|
-
let args;
|
|
102
|
-
if (field.arguments) {
|
|
103
|
-
args = field.arguments.filter((arg) => {
|
|
104
|
-
const name = arg.name.value;
|
|
105
|
-
if (name === sizeName || name === fromName) {
|
|
106
|
-
if (arg.value.kind === 'Variable') {
|
|
107
|
-
variablesToReplace[arg.value.name.value] = true;
|
|
108
|
-
}
|
|
109
|
-
return false;
|
|
110
|
-
}
|
|
111
|
-
return true;
|
|
112
|
-
});
|
|
113
|
-
args.push(createArgument({ name: fromName, value: fromVarName }));
|
|
114
|
-
args.push(createArgument({ name: sizeName, value: sizeVarName }));
|
|
115
|
-
}
|
|
116
|
-
variables.push({
|
|
117
|
-
name: fromVarName,
|
|
118
|
-
type: paginatedField.strategy.type === 'cursor' ? 'String' : 'Int'
|
|
119
|
-
});
|
|
120
|
-
variables.push({ name: sizeVarName, type: 'Int' });
|
|
121
|
-
return args ? { ...field, arguments: args } : field;
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
const queryPath = paginatedFields[0].astPath.slice(0, 2);
|
|
125
|
-
updateIn(ast, queryPath, (query) => {
|
|
126
|
-
if (query.variableDefinitions) {
|
|
127
|
-
return {
|
|
128
|
-
...query,
|
|
129
|
-
variableDefinitions: query.variableDefinitions
|
|
130
|
-
.filter((def) => !variablesToReplace[def.variable.name.value])
|
|
131
|
-
.concat(variables.map(createVariableDefinition))
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
return query;
|
|
135
|
-
});
|
|
136
|
-
return ast;
|
|
137
|
-
}
|
|
138
|
-
export function hasField(ast, queryPath) {
|
|
139
|
-
let node = ast;
|
|
140
|
-
for (const name of queryPath) {
|
|
141
|
-
if (!node.selectionSet) {
|
|
142
|
-
return false;
|
|
143
|
-
}
|
|
144
|
-
const field = node.selectionSet.selections.find((selection) => selection.kind === 'Field' && selection.name.value === name);
|
|
145
|
-
if (field) {
|
|
146
|
-
node = field;
|
|
147
|
-
}
|
|
148
|
-
else {
|
|
149
|
-
return false;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
return true;
|
|
153
|
-
}
|
|
154
|
-
export function ensureField(ast, queryPath) {
|
|
155
|
-
let node = ast;
|
|
156
|
-
for (const name of queryPath) {
|
|
157
|
-
if (node.selectionSet) {
|
|
158
|
-
let { selections } = node.selectionSet;
|
|
159
|
-
const field = selections.find((selection) => selection.kind === 'Field' && selection.name.value === name);
|
|
160
|
-
if (field) {
|
|
161
|
-
node = field;
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
selections = selections.concat([createField(name)]);
|
|
165
|
-
node.selectionSet.selections = selections;
|
|
166
|
-
node = selections[selections.length - 1];
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
node.selectionSet = createSelectionSet([createField(name)]);
|
|
171
|
-
node = node.selectionSet.selections[0];
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
return ast;
|
|
175
|
-
}
|
|
176
|
-
export function ensurePaginationFields(ast, paginatedFields, source = '') {
|
|
177
|
-
for (const paginatedField of paginatedFields) {
|
|
178
|
-
const { strategy, astPath, queryPath } = paginatedField;
|
|
179
|
-
const { type } = strategy;
|
|
180
|
-
const field = get(ast, astPath);
|
|
181
|
-
if (!hasField(field, strategy.itemsPath)) {
|
|
182
|
-
const missingPath = queryPath.concat(strategy.itemsPath).join('.');
|
|
183
|
-
throw new PaginationError(`Expected ${missingPath} to be specified: ${source}`);
|
|
184
|
-
}
|
|
185
|
-
if (type === 'cursor' && strategy.hasNextPath && strategy.cursorPath) {
|
|
186
|
-
ensureField(field, strategy.hasNextPath);
|
|
187
|
-
ensureField(field, strategy.cursorPath);
|
|
188
|
-
}
|
|
189
|
-
else if (strategy.totalPath) {
|
|
190
|
-
ensureField(field, strategy.totalPath);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
return ast;
|
|
194
|
-
}
|
|
195
|
-
export function isDone(queryArgs, queryData, paginatedField) {
|
|
196
|
-
const { strategy, queryPath, fromVarName, sizeVarName } = paginatedField;
|
|
197
|
-
const { hasNextPath, totalPath } = strategy;
|
|
198
|
-
if (hasNextPath) {
|
|
199
|
-
return !get(queryData, queryPath.concat(hasNextPath));
|
|
200
|
-
}
|
|
201
|
-
if (totalPath) {
|
|
202
|
-
return queryArgs[fromVarName] + queryArgs[sizeVarName] >= get(queryData, queryPath.concat(totalPath));
|
|
203
|
-
}
|
|
204
|
-
throw Error('Invalid pagination strategy');
|
|
205
|
-
}
|
|
206
|
-
function incrementVariables(variables, data, paginatedField) {
|
|
207
|
-
const { strategy, queryPath, fromVarName, sizeVarName } = paginatedField;
|
|
208
|
-
const { cursorPath, type } = strategy;
|
|
209
|
-
if (type === 'cursor' && cursorPath) {
|
|
210
|
-
variables[fromVarName] = get(data, queryPath.concat(cursorPath));
|
|
211
|
-
}
|
|
212
|
-
else {
|
|
213
|
-
variables[fromVarName] += variables[sizeVarName];
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
function handleErrors(res, source) {
|
|
217
|
-
if (res.errors) {
|
|
218
|
-
throw new GraphQLError(`An error occurred ${source ?? 'unknown source'}`, res.errors);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
export async function getQueryIterator(schema, query, connector, { variables, pageSize = 100, source, stats } = {}) {
|
|
222
|
-
const queryAst = parse(query);
|
|
223
|
-
const paginatedFields = findPaginatedFields(queryAst, schema);
|
|
224
|
-
if (paginatedFields.length !== 1) {
|
|
225
|
-
throw new PaginationError(`No paginated fields: ${source ?? 'unknown source'}`);
|
|
226
|
-
}
|
|
227
|
-
const astWithVars = addPaginationVariables(queryAst, paginatedFields);
|
|
228
|
-
const astNormalized = ensurePaginationFields(astWithVars, paginatedFields, source);
|
|
229
|
-
const queryWithVars = print(astNormalized);
|
|
230
|
-
const vars = { ...variables };
|
|
231
|
-
// Initialize pagination vars
|
|
232
|
-
const paginatedField = paginatedFields[0];
|
|
233
|
-
if (paginatedField.strategy.type === 'offset') {
|
|
234
|
-
vars[paginatedField.fromVarName] = 0;
|
|
235
|
-
}
|
|
236
|
-
vars[paginatedField.sizeVarName] = pageSize;
|
|
237
|
-
const itemsPath = paginatedField.queryPath.concat(paginatedField.strategy.itemsPath);
|
|
238
|
-
let total;
|
|
239
|
-
let first;
|
|
240
|
-
const connectorContext = {
|
|
241
|
-
source,
|
|
242
|
-
stats,
|
|
243
|
-
applyMigrations: false,
|
|
244
|
-
isPaginated: true
|
|
245
|
-
};
|
|
246
|
-
if (paginatedField.strategy.type === 'offset' && paginatedField.strategy.totalPath) {
|
|
247
|
-
const totalPath = paginatedField.queryPath.concat(paginatedField.strategy.totalPath);
|
|
248
|
-
first = await connector({ query: queryWithVars, variables: vars }, connectorContext);
|
|
249
|
-
handleErrors(first, source);
|
|
250
|
-
total = get(first.data, totalPath);
|
|
251
|
-
}
|
|
252
|
-
const iterator = async function* () {
|
|
253
|
-
while (true) {
|
|
254
|
-
const res = first ?? (await connector({ query: queryWithVars, variables: vars }, connectorContext));
|
|
255
|
-
first &&= null;
|
|
256
|
-
handleErrors(res, source);
|
|
257
|
-
const data = res.data;
|
|
258
|
-
for (const item of get(data, itemsPath).filter(Boolean)) {
|
|
259
|
-
yield item;
|
|
260
|
-
}
|
|
261
|
-
if (isDone(vars, data, paginatedField)) {
|
|
262
|
-
break;
|
|
263
|
-
}
|
|
264
|
-
incrementVariables(vars, data, paginatedField);
|
|
265
|
-
}
|
|
266
|
-
};
|
|
267
|
-
return { total, iterator };
|
|
268
|
-
}
|
package/dist/graphql/query.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { GraphQLFieldMap } from 'graphql';
|
|
2
|
-
import { type DocumentNode, type GraphQLOutputType, type GraphQLSchema } from 'graphql';
|
|
3
|
-
import type { GraphQLConnector } from '../types.ts';
|
|
4
|
-
export declare function getItemType(fieldType: GraphQLOutputType): GraphQLOutputType;
|
|
5
|
-
export declare function getFields(type: GraphQLOutputType): GraphQLFieldMap<any, any> | undefined;
|
|
6
|
-
export declare function ensureIds(queryAst: DocumentNode, schema: GraphQLSchema): DocumentNode;
|
|
7
|
-
export declare function wrapWithLocaleContext(ast: DocumentNode): DocumentNode;
|
|
8
|
-
export declare const FILTER_VAR_NAME = "__filter";
|
|
9
|
-
export type AddContentIdFilterResult = {
|
|
10
|
-
ast: DocumentNode;
|
|
11
|
-
varName: string;
|
|
12
|
-
modified: boolean;
|
|
13
|
-
};
|
|
14
|
-
export declare function addContentIdFilter(ast: DocumentNode, schema: GraphQLSchema): AddContentIdFilterResult;
|
|
15
|
-
export type WithQueryTransformsParams = {
|
|
16
|
-
locale?: string;
|
|
17
|
-
usage?: boolean;
|
|
18
|
-
contentId?: string;
|
|
19
|
-
};
|
|
20
|
-
export declare function withQueryTransforms(connector: GraphQLConnector, schema: GraphQLSchema, { locale, usage, contentId }?: WithQueryTransformsParams): GraphQLConnector;
|