crelte 0.5.9 → 0.5.11
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/blocks/Blocks.d.ts +6 -5
- package/dist/blocks/Blocks.d.ts.map +1 -1
- package/dist/blocks/Blocks.js +5 -2
- package/dist/blocks/Blocks.svelte +1 -1
- package/dist/blocks/Blocks.svelte.d.ts +1 -1
- package/dist/blocks/Blocks.svelte.d.ts.map +1 -1
- package/dist/init/client.d.ts +1 -8
- package/dist/init/client.d.ts.map +1 -1
- package/dist/init/client.js +3 -10
- package/dist/init/server.js +1 -1
- package/dist/plugins/Events.d.ts +6 -6
- package/dist/plugins/Events.d.ts.map +1 -1
- package/dist/queries/Queries.d.ts +30 -5
- package/dist/queries/Queries.d.ts.map +1 -1
- package/dist/queries/Queries.js +19 -2
- package/dist/queries/gql.d.ts +2 -2
- package/dist/queries/gql.d.ts.map +1 -1
- package/dist/queries/index.d.ts +47 -2
- package/dist/queries/index.d.ts.map +1 -1
- package/dist/queries/index.js +2 -2
- package/dist/queries/vars.d.ts +2 -0
- package/dist/queries/vars.d.ts.map +1 -1
- package/dist/queries/vars.js +10 -0
- package/dist/routing/router/BaseRouter.d.ts +2 -1
- package/dist/routing/router/BaseRouter.d.ts.map +1 -1
- package/dist/routing/router/BaseRouter.js +4 -2
- package/dist/routing/router/ClientRouter.d.ts.map +1 -1
- package/dist/routing/router/ClientRouter.js +3 -4
- package/dist/routing/router/Router.d.ts +2 -1
- package/dist/routing/router/Router.d.ts.map +1 -1
- package/dist/routing/router/Router.js +2 -1
- package/dist/routing/utils.d.ts +1 -0
- package/dist/routing/utils.d.ts.map +1 -1
- package/dist/routing/utils.js +1 -1
- package/dist/server/ServerRouter.d.ts.map +1 -1
- package/dist/server/ServerRouter.js +17 -7
- package/dist/server/queries/QueryGqlRoute.d.ts +28 -0
- package/dist/server/queries/QueryGqlRoute.d.ts.map +1 -0
- package/dist/server/queries/QueryGqlRoute.js +194 -0
- package/dist/server/queries/QueryHandleRoute.d.ts +12 -0
- package/dist/server/queries/QueryHandleRoute.d.ts.map +1 -0
- package/dist/server/queries/QueryHandleRoute.js +24 -0
- package/dist/server/queries/queries.d.ts.map +1 -1
- package/dist/server/queries/queries.js +42 -19
- package/dist/server/queries/routes.d.ts +7 -30
- package/dist/server/queries/routes.d.ts.map +1 -1
- package/dist/server/queries/routes.js +13 -199
- package/package.json +1 -1
- package/src/blocks/Blocks.svelte +1 -17
- package/src/blocks/Blocks.ts +11 -7
- package/src/init/client.ts +3 -10
- package/src/init/server.ts +1 -1
- package/src/plugins/Events.ts +10 -6
- package/src/queries/Queries.ts +47 -14
- package/src/queries/gql.ts +2 -2
- package/src/queries/index.ts +71 -0
- package/src/queries/vars.ts +13 -0
- package/src/routing/router/BaseRouter.ts +4 -2
- package/src/routing/router/ClientRouter.ts +3 -4
- package/src/routing/router/Router.ts +2 -1
- package/src/routing/utils.ts +1 -1
- package/src/server/ServerRouter.ts +18 -7
- package/src/server/queries/QueryGqlRoute.ts +224 -0
- package/src/server/queries/QueryHandleRoute.ts +37 -0
- package/src/server/queries/queries.ts +57 -21
- package/src/server/queries/routes.ts +25 -229
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServerRouter.d.ts","sourceRoot":"","sources":["../../src/server/ServerRouter.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ServerRouter.d.ts","sourceRoot":"","sources":["../../src/server/ServerRouter.ts"],"names":[],"mappings":"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"}
|
|
@@ -89,9 +89,7 @@ export default class ServerRouter {
|
|
|
89
89
|
this.primarySite();
|
|
90
90
|
const nReq = new ServerRequest(req, new Map(Object.entries(params)), site);
|
|
91
91
|
// we create a new Queries here, because each request should have its own SsrCache
|
|
92
|
-
const queries = Queries.new(this.endpointUrl, this.frontendUrl, new SsrCache(), {
|
|
93
|
-
bearerToken: this.endpointToken,
|
|
94
|
-
});
|
|
92
|
+
const queries = Queries.new(this.endpointUrl, this.frontendUrl, new SsrCache(), { bearerToken: this.endpointToken });
|
|
95
93
|
const csr = new CrelteServerRequest(nReq, {
|
|
96
94
|
env: this.env,
|
|
97
95
|
sites: this.sites,
|
|
@@ -99,12 +97,24 @@ export default class ServerRouter {
|
|
|
99
97
|
preferredSite: prefSite,
|
|
100
98
|
queries,
|
|
101
99
|
});
|
|
100
|
+
let resp = null;
|
|
102
101
|
for (const handler of handlers) {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
102
|
+
try {
|
|
103
|
+
const res = await handler(csr);
|
|
104
|
+
if (!res)
|
|
105
|
+
continue;
|
|
106
|
+
resp = res;
|
|
107
107
|
}
|
|
108
|
+
catch (e) {
|
|
109
|
+
if (!(e instanceof Response))
|
|
110
|
+
throw e;
|
|
111
|
+
resp = e;
|
|
112
|
+
}
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
if (resp) {
|
|
116
|
+
csr.z_finishResponse(resp);
|
|
117
|
+
return resp;
|
|
108
118
|
}
|
|
109
119
|
return null;
|
|
110
120
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import CrelteServerRequest from '../CrelteServer.js';
|
|
2
|
+
import QueriesCaching from './QueriesCaching.js';
|
|
3
|
+
import { QueryVar } from '../../queries/vars.js';
|
|
4
|
+
import { CacheIfFn, TransformFn } from './routes.js';
|
|
5
|
+
export type QueryGqlArgs = {
|
|
6
|
+
vars: Record<string, QueryVar> | null;
|
|
7
|
+
cacheIfFn: CacheIfFn | null;
|
|
8
|
+
preventCaching: boolean;
|
|
9
|
+
transformFn: TransformFn | null;
|
|
10
|
+
};
|
|
11
|
+
export default class QueryGqlRoute {
|
|
12
|
+
name: string;
|
|
13
|
+
query: string;
|
|
14
|
+
vars: Record<string, QueryVar> | null;
|
|
15
|
+
cacheIfFn: CacheIfFn | null;
|
|
16
|
+
transformFn: TransformFn | null;
|
|
17
|
+
constructor(name: string, query: string, args: QueryGqlArgs);
|
|
18
|
+
private fillEntryDefaults;
|
|
19
|
+
private fillGlobalDefaults;
|
|
20
|
+
/**
|
|
21
|
+
* This adds caching to queries containing `query {` or
|
|
22
|
+
* `query ($siteId: [QueryArgument) {` without any additional vars
|
|
23
|
+
*/
|
|
24
|
+
private fillBasicDefaults;
|
|
25
|
+
private transform;
|
|
26
|
+
handle(caching: QueriesCaching, csr: CrelteServerRequest): Promise<Response>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=QueryGqlRoute.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueryGqlRoute.d.ts","sourceRoot":"","sources":["../../../src/server/queries/QueryGqlRoute.ts"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,MAAM,oBAAoB,CAAC;AACrD,OAAO,cAAc,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAQ,MAAM,uBAAuB,CAAC;AAGvD,OAAO,EAAE,SAAS,EAAY,WAAW,EAAgB,MAAM,aAAa,CAAC;AAE7E,MAAM,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC;IACtC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,cAAc,EAAE,OAAO,CAAC;IACxB,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;CAChC,CAAC;AAGF,MAAM,CAAC,OAAO,OAAO,aAAa;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC;IACtC,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,WAAW,GAAG,IAAI,CAAC;gBAEpB,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY;IA2B3D,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,kBAAkB;IAO1B;;;OAGG;IACH,OAAO,CAAC,iBAAiB;YAuBX,SAAS;IAUjB,MAAM,CACX,OAAO,EAAE,cAAc,EACvB,GAAG,EAAE,mBAAmB,GACtB,OAAO,CAAC,QAAQ,CAAC;CAkHpB"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { vars } from '../../queries/vars.js';
|
|
2
|
+
import { extractEntry } from '../../loadData/index.js';
|
|
3
|
+
import { calcKey } from '../../ssr/index.js';
|
|
4
|
+
import { newError, validateVars } from './routes.js';
|
|
5
|
+
// only internal
|
|
6
|
+
export default class QueryGqlRoute {
|
|
7
|
+
name;
|
|
8
|
+
query;
|
|
9
|
+
vars;
|
|
10
|
+
cacheIfFn;
|
|
11
|
+
transformFn;
|
|
12
|
+
constructor(name, query, args) {
|
|
13
|
+
if (args.cacheIfFn && !vars)
|
|
14
|
+
throw new Error('queryRoute: ' +
|
|
15
|
+
name +
|
|
16
|
+
' cannot have caching function if there are no ' +
|
|
17
|
+
'variables defined');
|
|
18
|
+
this.name = name;
|
|
19
|
+
this.query = query;
|
|
20
|
+
this.vars = args.vars;
|
|
21
|
+
this.cacheIfFn = args.cacheIfFn;
|
|
22
|
+
this.transformFn = args.transformFn;
|
|
23
|
+
if (args.preventCaching) {
|
|
24
|
+
if (this.cacheIfFn)
|
|
25
|
+
throw new Error('unreachable');
|
|
26
|
+
// prevent filling defaults
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
// add default vars and cacheIfFn if we know the route
|
|
30
|
+
if (this.name === 'entry')
|
|
31
|
+
this.fillEntryDefaults();
|
|
32
|
+
else if (this.name === 'global')
|
|
33
|
+
this.fillGlobalDefaults();
|
|
34
|
+
else
|
|
35
|
+
this.fillBasicDefaults();
|
|
36
|
+
}
|
|
37
|
+
fillEntryDefaults() {
|
|
38
|
+
if (this.vars)
|
|
39
|
+
return;
|
|
40
|
+
// the _setName step happens in parseVars which happens before setting
|
|
41
|
+
// the defaults, so since we're adding vars here we need to set the name
|
|
42
|
+
// manually
|
|
43
|
+
this.vars = {
|
|
44
|
+
siteId: vars.siteId().z_setName('siteId'),
|
|
45
|
+
uri: vars.string().z_setName('uri'),
|
|
46
|
+
};
|
|
47
|
+
this.cacheIfFn = res => !!extractEntry(res);
|
|
48
|
+
}
|
|
49
|
+
fillGlobalDefaults() {
|
|
50
|
+
if (this.vars)
|
|
51
|
+
return;
|
|
52
|
+
this.vars = { siteId: vars.siteId().z_setName('siteId') };
|
|
53
|
+
this.cacheIfFn = () => true;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* This adds caching to queries containing `query {` or
|
|
57
|
+
* `query ($siteId: [QueryArgument) {` without any additional vars
|
|
58
|
+
*/
|
|
59
|
+
fillBasicDefaults() {
|
|
60
|
+
if (this.vars)
|
|
61
|
+
return;
|
|
62
|
+
const NO_VAR_TEST = /(^|\s)query\s*{/;
|
|
63
|
+
const SITE_ID_VAR_TEST = /(^|\s)query\s*\(\s*\$siteId\s*:\s*\[\s*QueryArgument\s*\]\s*\)\s*{/;
|
|
64
|
+
if (NO_VAR_TEST.test(this.query)) {
|
|
65
|
+
this.vars = {};
|
|
66
|
+
this.cacheIfFn = () => true;
|
|
67
|
+
}
|
|
68
|
+
else if (SITE_ID_VAR_TEST.test(this.query)) {
|
|
69
|
+
this.vars = { siteId: vars.siteId().z_setName('siteId') };
|
|
70
|
+
this.cacheIfFn = () => true;
|
|
71
|
+
}
|
|
72
|
+
else if (!this.query.includes('query')) {
|
|
73
|
+
// this warning might be shown to mutation queries or subscriptions
|
|
74
|
+
// in that case, the user should explicitly set caching to false
|
|
75
|
+
console.warn(`cannot determine if query (${this.name}) is cacheable, see` +
|
|
76
|
+
' https://github.com/crelte/crelte/issues/114 for infos');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async transform(jsonResp, vars) {
|
|
80
|
+
if (!this.transformFn || !jsonResp.data)
|
|
81
|
+
return;
|
|
82
|
+
const transformed = await this.transformFn(jsonResp.data, vars);
|
|
83
|
+
if (typeof transformed !== 'undefined')
|
|
84
|
+
jsonResp.data = transformed;
|
|
85
|
+
}
|
|
86
|
+
async handle(caching, csr) {
|
|
87
|
+
let vars;
|
|
88
|
+
try {
|
|
89
|
+
const reqVars = await csr.req.json();
|
|
90
|
+
vars = validateVars(this.vars, reqVars, caching.router);
|
|
91
|
+
if ('qName' in vars || 'xCraftSite' in vars)
|
|
92
|
+
throw new Error('qName and xCraftSite are reserved variable names');
|
|
93
|
+
}
|
|
94
|
+
catch (e) {
|
|
95
|
+
return newError(e, 400);
|
|
96
|
+
}
|
|
97
|
+
let logInfo = null;
|
|
98
|
+
if (caching.debug) {
|
|
99
|
+
logInfo = `[queries: ${this.name}] vars: ${JSON.stringify(vars)}`;
|
|
100
|
+
}
|
|
101
|
+
let previewToken = null;
|
|
102
|
+
let siteToken = null;
|
|
103
|
+
const reqSearch = new URL(csr.req.url).searchParams;
|
|
104
|
+
if (reqSearch.has('token')) {
|
|
105
|
+
previewToken = reqSearch.get('token');
|
|
106
|
+
}
|
|
107
|
+
else if (reqSearch.has('siteToken')) {
|
|
108
|
+
siteToken = reqSearch.get('siteToken');
|
|
109
|
+
}
|
|
110
|
+
// check for x-craft-site header and pass it on
|
|
111
|
+
const xCraftSite = csr.req.headers.get('X-Craft-Site');
|
|
112
|
+
let cacheKey = null;
|
|
113
|
+
const useCache = !previewToken && caching.isEnabled();
|
|
114
|
+
if (useCache) {
|
|
115
|
+
cacheKey = await calcKey({ ...vars, qName: this.name, xCraftSite });
|
|
116
|
+
const cached = await caching.getCache(cacheKey);
|
|
117
|
+
if (logInfo)
|
|
118
|
+
console.log(`${logInfo} ${cached ? 'hit' : 'miss'}`);
|
|
119
|
+
// we found something in the cache
|
|
120
|
+
if (cached)
|
|
121
|
+
return Response.json(cached);
|
|
122
|
+
}
|
|
123
|
+
const headers = {
|
|
124
|
+
'Content-Type': 'application/json',
|
|
125
|
+
};
|
|
126
|
+
const auth = csr.getEnv('ENDPOINT_TOKEN');
|
|
127
|
+
if (auth)
|
|
128
|
+
headers['Authorization'] = 'Bearer ' + auth;
|
|
129
|
+
const url = new URL(csr.getEnv('ENDPOINT_URL'));
|
|
130
|
+
if (previewToken)
|
|
131
|
+
url.searchParams.set('token', previewToken);
|
|
132
|
+
if (siteToken)
|
|
133
|
+
url.searchParams.set('siteToken', siteToken);
|
|
134
|
+
const xDebug = csr.req.headers.get('X-Debug');
|
|
135
|
+
if (xDebug)
|
|
136
|
+
headers['X-Debug'] = xDebug;
|
|
137
|
+
if (xCraftSite)
|
|
138
|
+
headers['X-Craft-Site'] = xCraftSite;
|
|
139
|
+
// now execute the gql request
|
|
140
|
+
let resp;
|
|
141
|
+
try {
|
|
142
|
+
resp = await fetch(url, {
|
|
143
|
+
method: 'POST',
|
|
144
|
+
headers,
|
|
145
|
+
body: JSON.stringify({
|
|
146
|
+
query: this.query,
|
|
147
|
+
variables: vars,
|
|
148
|
+
}),
|
|
149
|
+
});
|
|
150
|
+
// if the response is not ok we don't cache anything
|
|
151
|
+
// and just return the response
|
|
152
|
+
if (!resp.ok)
|
|
153
|
+
return resp;
|
|
154
|
+
}
|
|
155
|
+
catch (e) {
|
|
156
|
+
return newError(e, 500);
|
|
157
|
+
}
|
|
158
|
+
const respHeaders = {};
|
|
159
|
+
const xDebugLink = resp.headers.get('X-Debug-Link');
|
|
160
|
+
if (xDebugLink)
|
|
161
|
+
respHeaders['X-Debug'] = xDebugLink;
|
|
162
|
+
let jsonResp;
|
|
163
|
+
try {
|
|
164
|
+
jsonResp = await resp.json();
|
|
165
|
+
if (!jsonResp || typeof jsonResp !== 'object')
|
|
166
|
+
throw new Error('invalid json response');
|
|
167
|
+
await this.transform(jsonResp, vars);
|
|
168
|
+
}
|
|
169
|
+
catch (e) {
|
|
170
|
+
return newError(e, 500);
|
|
171
|
+
}
|
|
172
|
+
// also no caching for errors
|
|
173
|
+
if (jsonResp.errors) {
|
|
174
|
+
return Response.json(jsonResp, { headers: respHeaders });
|
|
175
|
+
}
|
|
176
|
+
// now we have a valid json resp.
|
|
177
|
+
// should we cache it?
|
|
178
|
+
if (cacheKey && this.cacheIfFn?.(jsonResp.data, vars)) {
|
|
179
|
+
try {
|
|
180
|
+
await caching.setCache(cacheKey, jsonResp);
|
|
181
|
+
if (logInfo)
|
|
182
|
+
console.log(logInfo + ' set cache');
|
|
183
|
+
}
|
|
184
|
+
catch (e) {
|
|
185
|
+
console.error('could not cache gql response', e);
|
|
186
|
+
}
|
|
187
|
+
// if caching is enabled but not used we warn
|
|
188
|
+
}
|
|
189
|
+
else if (cacheKey && logInfo) {
|
|
190
|
+
console.warn('!! ' + logInfo + ' caching not allowed');
|
|
191
|
+
}
|
|
192
|
+
return Response.json(jsonResp, { headers: respHeaders });
|
|
193
|
+
}
|
|
194
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { QueryVar } from '../../queries/vars.js';
|
|
2
|
+
import CrelteServerRequest from '../CrelteServer.js';
|
|
3
|
+
import ServerRouter from '../ServerRouter.js';
|
|
4
|
+
import { HandleFn } from './routes.js';
|
|
5
|
+
export default class QueryHandleRoute {
|
|
6
|
+
name: string;
|
|
7
|
+
handleFn: HandleFn;
|
|
8
|
+
vars: Record<string, QueryVar> | null;
|
|
9
|
+
constructor(name: string, handleFn: HandleFn, vars: Record<string, QueryVar> | null);
|
|
10
|
+
handle(cs: ServerRouter, csr: CrelteServerRequest): Promise<Response>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=QueryHandleRoute.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QueryHandleRoute.d.ts","sourceRoot":"","sources":["../../../src/server/queries/QueryHandleRoute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,mBAAmB,MAAM,oBAAoB,CAAC;AACrD,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAA0B,MAAM,aAAa,CAAC;AAG/D,MAAM,CAAC,OAAO,OAAO,gBAAgB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC;gBAGrC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,IAAI;IAOhC,MAAM,CACX,EAAE,EAAE,YAAY,EAChB,GAAG,EAAE,mBAAmB,GACtB,OAAO,CAAC,QAAQ,CAAC;CAYpB"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { newError, validateVars } from './routes.js';
|
|
2
|
+
// only internal
|
|
3
|
+
export default class QueryHandleRoute {
|
|
4
|
+
name;
|
|
5
|
+
handleFn;
|
|
6
|
+
vars;
|
|
7
|
+
constructor(name, handleFn, vars) {
|
|
8
|
+
this.name = name;
|
|
9
|
+
this.handleFn = handleFn;
|
|
10
|
+
this.vars = vars;
|
|
11
|
+
}
|
|
12
|
+
async handle(cs, csr) {
|
|
13
|
+
let vars;
|
|
14
|
+
try {
|
|
15
|
+
const reqVars = await csr.req.json();
|
|
16
|
+
vars = validateVars(this.vars, reqVars, cs);
|
|
17
|
+
}
|
|
18
|
+
catch (e) {
|
|
19
|
+
return newError(e, 400);
|
|
20
|
+
}
|
|
21
|
+
const res = await this.handleFn(csr, vars);
|
|
22
|
+
return Response.json({ data: res });
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../../src/server/queries/queries.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAI9C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../../src/server/queries/queries.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAI9C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AA6B1C,wBAAsB,eAAe,CACpC,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,CAAC,CAgGf"}
|
|
@@ -1,60 +1,78 @@
|
|
|
1
1
|
import QueriesCaching from './QueriesCaching.js';
|
|
2
|
-
import { QueryRoute } from './routes.js';
|
|
3
2
|
import { isQueryVar } from '../../queries/vars.js';
|
|
3
|
+
import QueryHandleRoute from './QueryHandleRoute.js';
|
|
4
|
+
import QueryGqlRoute from './QueryGqlRoute.js';
|
|
4
5
|
export async function initQueryRoutes(platform, mod, router) {
|
|
5
6
|
if (typeof mod.queries !== 'object') {
|
|
6
|
-
throw new Error(
|
|
7
|
+
throw new Error('expected `export const queries = import.meta.glob(' +
|
|
8
|
+
"'@/queries/*', { eager: true });` in server.js");
|
|
7
9
|
}
|
|
8
10
|
const debugCaching = !!mod?.debugCaching;
|
|
9
11
|
const modQueries = mod.queries;
|
|
10
|
-
const
|
|
12
|
+
const routeBuilders = new Map();
|
|
11
13
|
for (const [file, mq] of Object.entries(modQueries)) {
|
|
12
14
|
const filename = file.split('/').pop();
|
|
13
15
|
const dotPos = filename.lastIndexOf('.');
|
|
14
16
|
const name = filename.substring(0, dotPos);
|
|
15
|
-
let
|
|
16
|
-
if (!
|
|
17
|
-
|
|
17
|
+
let routeBuilder = routeBuilders.get(name);
|
|
18
|
+
if (!routeBuilder) {
|
|
19
|
+
routeBuilder = {
|
|
18
20
|
query: null,
|
|
19
21
|
jsFile: null,
|
|
20
22
|
vars: null,
|
|
21
23
|
cacheIfFn: null,
|
|
22
24
|
preventCaching: false,
|
|
23
25
|
transformFn: null,
|
|
26
|
+
handleFn: null,
|
|
24
27
|
};
|
|
25
|
-
|
|
28
|
+
routeBuilders.set(name, routeBuilder);
|
|
26
29
|
}
|
|
27
30
|
// set the gql query (this can only happen once)
|
|
28
31
|
if (filename.endsWith('.graphql')) {
|
|
29
|
-
|
|
32
|
+
routeBuilder.query = mq.query.query;
|
|
30
33
|
continue;
|
|
31
34
|
}
|
|
32
35
|
// now check that only one file matches
|
|
33
|
-
if (
|
|
34
|
-
throw new Error(`cannot have two files for the same query ${
|
|
36
|
+
if (routeBuilder.jsFile) {
|
|
37
|
+
throw new Error(`cannot have two files for the same query ${routeBuilder.jsFile} and ${filename}`);
|
|
35
38
|
}
|
|
36
39
|
const mts = mq;
|
|
37
40
|
if (mts.variables) {
|
|
38
|
-
|
|
41
|
+
routeBuilder.vars = parseVars(mts.variables);
|
|
39
42
|
}
|
|
40
43
|
if (mts.caching) {
|
|
41
|
-
|
|
44
|
+
routeBuilder.cacheIfFn = parseCaching(mts.caching);
|
|
42
45
|
}
|
|
43
46
|
else if (typeof mts.caching === 'boolean') {
|
|
44
|
-
|
|
47
|
+
routeBuilder.preventCaching = true;
|
|
45
48
|
}
|
|
46
49
|
if (mts.transform) {
|
|
47
|
-
|
|
50
|
+
routeBuilder.transformFn = parseTransform(mts.transform);
|
|
51
|
+
}
|
|
52
|
+
if (mts.handle) {
|
|
53
|
+
routeBuilder.handleFn = parseHandle(mts.handle);
|
|
48
54
|
}
|
|
49
55
|
}
|
|
50
56
|
const caching = new QueriesCaching(platform, router, {
|
|
51
57
|
debug: debugCaching,
|
|
52
58
|
});
|
|
53
|
-
for (const [name,
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
for (const [name, rb] of routeBuilders.entries()) {
|
|
60
|
+
if (rb.query) {
|
|
61
|
+
if (rb.handleFn)
|
|
62
|
+
throw new Error('handle function not supported');
|
|
63
|
+
const route = new QueryGqlRoute(name, rb.query, rb);
|
|
64
|
+
router.post('/queries/' + route.name, csr => route.handle(caching, csr));
|
|
65
|
+
}
|
|
66
|
+
else if (rb.handleFn) {
|
|
67
|
+
if (rb.cacheIfFn || rb.transformFn || rb.preventCaching)
|
|
68
|
+
throw new Error('caching or transform not supported');
|
|
69
|
+
const route = new QueryHandleRoute(name, rb.handleFn, rb.vars);
|
|
70
|
+
router.post('/queries/' + route.name, csr => route.handle(caching.router, csr));
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
throw new Error(`query js/ts ${name} file needs to either have ` +
|
|
74
|
+
'a .graphql file or a handle function');
|
|
75
|
+
}
|
|
58
76
|
}
|
|
59
77
|
}
|
|
60
78
|
function parseVars(vars) {
|
|
@@ -81,3 +99,8 @@ function parseTransform(transform) {
|
|
|
81
99
|
throw new Error('transform should be a function');
|
|
82
100
|
return transform;
|
|
83
101
|
}
|
|
102
|
+
function parseHandle(handle) {
|
|
103
|
+
if (typeof handle !== 'function')
|
|
104
|
+
throw new Error('handle should be a function');
|
|
105
|
+
return handle;
|
|
106
|
+
}
|
|
@@ -1,36 +1,13 @@
|
|
|
1
|
-
import CrelteServerRequest from '../CrelteServer.js';
|
|
2
|
-
import QueriesCaching from './QueriesCaching.js';
|
|
3
1
|
import { QueryVar } from '../../queries/vars.js';
|
|
2
|
+
import CrelteServerRequest from '../CrelteServer.js';
|
|
4
3
|
import ServerRouter from '../ServerRouter.js';
|
|
5
4
|
export type CacheIfFn = (response: any, vars: Record<string, any>) => boolean;
|
|
6
5
|
export type TransformFn = (response: any, vars: Record<string, any>) => void | any | Promise<void | any>;
|
|
7
|
-
export type
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
export declare class QueryRoute {
|
|
14
|
-
name: string;
|
|
15
|
-
query: string;
|
|
16
|
-
vars: Record<string, QueryVar> | null;
|
|
17
|
-
cacheIfFn: CacheIfFn | null;
|
|
18
|
-
transformFn: TransformFn | null;
|
|
19
|
-
constructor(name: string, query: string, args: QueryRouteArgs);
|
|
20
|
-
private fillEntryDefaults;
|
|
21
|
-
private fillGlobalDefaults;
|
|
22
|
-
/**
|
|
23
|
-
* This adds caching to queries containing `query {` or
|
|
24
|
-
* `query ($siteId: [QueryArgument) {` without any additional vars
|
|
25
|
-
*/
|
|
26
|
-
private fillBasicDefaults;
|
|
27
|
-
/**
|
|
28
|
-
* Returns the validated variables if some vars where defined
|
|
29
|
-
* else just returns all vars
|
|
30
|
-
*/
|
|
31
|
-
validateVars(vars: any, cs: ServerRouter): Record<string, any>;
|
|
32
|
-
private transform;
|
|
33
|
-
handle(caching: QueriesCaching, csr: CrelteServerRequest): Promise<Response>;
|
|
34
|
-
}
|
|
6
|
+
export type HandleFn = (csr: CrelteServerRequest, vars: Record<string, any>) => Promise<any> | any;
|
|
7
|
+
/**
|
|
8
|
+
* Returns the validated variables if some vars where defined
|
|
9
|
+
* else just returns all vars
|
|
10
|
+
*/
|
|
11
|
+
export declare function validateVars(qvars: Record<string, QueryVar> | null, vars: any, cs: ServerRouter): Record<string, any>;
|
|
35
12
|
export declare function newError(e: any, status: number): Response;
|
|
36
13
|
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/server/queries/routes.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../../src/server/queries/routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,mBAAmB,MAAM,oBAAoB,CAAC;AACrD,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAE9C,MAAM,MAAM,SAAS,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC;AAM9E,MAAM,MAAM,WAAW,GAAG,CACzB,QAAQ,EAAE,GAAG,EACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KACrB,IAAI,GAAG,GAAG,GAAG,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC;AAEtC,MAAM,MAAM,QAAQ,GAAG,CACtB,GAAG,EAAE,mBAAmB,EACxB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KACrB,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AAExB;;;GAGG;AACH,wBAAgB,YAAY,CAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,IAAI,EACtC,IAAI,EAAE,GAAG,EACT,EAAE,EAAE,YAAY,GACd,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAarB;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,CAEzD"}
|