houdini 1.2.11 → 1.2.13
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/build/cmd/init.d.ts +1 -0
- package/build/cmd-cjs/index.js +1563 -16182
- package/build/cmd-esm/index.js +1563 -16182
- package/build/codegen/transforms/collectDefinitions.d.ts +1 -1
- package/build/codegen/utils/flattenSelections.d.ts +1 -1
- package/build/codegen-cjs/index.js +298 -14974
- package/build/codegen-esm/index.js +300 -14976
- package/build/lib/config.d.ts +4 -0
- package/build/lib/index.d.ts +1 -1
- package/build/{router → lib/router}/conventions.d.ts +2 -1
- package/build/{router → lib/router}/index.d.ts +2 -1
- package/build/lib/router/manifest.d.ts +12 -0
- package/build/lib/router/server.d.ts +4 -0
- package/build/{router → lib/router}/types.d.ts +3 -2
- package/build/lib/types.d.ts +2 -2
- package/build/lib-cjs/index.js +1348 -15895
- package/build/lib-esm/index.js +1344 -15895
- package/build/runtime/client/documentStore.d.ts +1 -0
- package/build/runtime/client/index.d.ts +14 -2
- package/build/runtime/lib/config.d.ts +19 -0
- package/build/runtime/lib/types.d.ts +39 -0
- package/build/runtime-cjs/client/documentStore.d.ts +1 -0
- package/build/runtime-cjs/client/documentStore.js +42 -2
- package/build/runtime-cjs/client/index.d.ts +14 -2
- package/build/runtime-cjs/client/index.js +8 -2
- package/build/runtime-cjs/lib/config.d.ts +19 -0
- package/build/runtime-cjs/lib/config.js +10 -0
- package/build/runtime-cjs/lib/types.d.ts +39 -0
- package/build/runtime-cjs/router/server.js +1 -1
- package/build/runtime-esm/client/documentStore.d.ts +1 -0
- package/build/runtime-esm/client/documentStore.js +42 -2
- package/build/runtime-esm/client/index.d.ts +14 -2
- package/build/runtime-esm/client/index.js +8 -2
- package/build/runtime-esm/lib/config.d.ts +19 -0
- package/build/runtime-esm/lib/config.js +8 -0
- package/build/runtime-esm/lib/types.d.ts +39 -0
- package/build/runtime-esm/router/server.js +1 -1
- package/build/test-cjs/index.js +325 -14977
- package/build/test-esm/index.js +327 -14979
- package/build/vite-cjs/index.js +1825 -16189
- package/build/vite-esm/index.js +1825 -16189
- package/package.json +2 -9
- package/build/router/manifest.d.ts +0 -45
- package/build/router-cjs/index.js +0 -72353
- package/build/router-cjs/package.json +0 -1
- package/build/router-esm/index.js +0 -72345
- package/build/router-esm/package.json +0 -1
|
@@ -25,6 +25,7 @@ export declare class DocumentStore<_Data extends GraphQLObject, _Input extends G
|
|
|
25
25
|
});
|
|
26
26
|
send({ metadata, session, fetch, variables, policy, stuff, cacheParams, setup, silenceEcho, }?: SendParams): Promise<QueryResult<_Data, _Input>>;
|
|
27
27
|
cleanup(): Promise<void>;
|
|
28
|
+
getFetch(getSession: () => App.Session | null | undefined): (input: RequestInfo | URL, init?: RequestInit | undefined) => Promise<Response>;
|
|
28
29
|
}
|
|
29
30
|
declare function marshalVariables<_Data extends GraphQLObject, _Input extends GraphQLVariables>(ctx: ClientPluginContext): Record<string, any>;
|
|
30
31
|
export type ClientPlugin = () => ClientHooks | null | (ClientHooks | ClientPlugin | null)[];
|
|
@@ -7,7 +7,7 @@ import type { FetchParamFn, ThrowOnErrorOperations, ThrowOnErrorParams } from '.
|
|
|
7
7
|
export { DocumentStore, type ClientPlugin, type SendParams } from './documentStore';
|
|
8
8
|
export { fetch, mutation, query, subscription } from './plugins';
|
|
9
9
|
export type HoudiniClientConstructorArgs = {
|
|
10
|
-
url
|
|
10
|
+
url?: string;
|
|
11
11
|
fetchParams?: FetchParamFn;
|
|
12
12
|
plugins?: NestedList<ClientPlugin>;
|
|
13
13
|
pipeline?: NestedList<ClientPlugin>;
|
|
@@ -25,7 +25,19 @@ export declare class HoudiniClient {
|
|
|
25
25
|
url: string;
|
|
26
26
|
readonly plugins: ClientPlugin[];
|
|
27
27
|
readonly throwOnError_operations: ThrowOnErrorOperations[];
|
|
28
|
-
|
|
28
|
+
proxies: Record<string, (operation: {
|
|
29
|
+
query: string;
|
|
30
|
+
variables: any;
|
|
31
|
+
operationName: string;
|
|
32
|
+
session: App.Session | null | undefined;
|
|
33
|
+
}) => Promise<any>>;
|
|
34
|
+
constructor({ url, fetchParams, plugins, pipeline, throwOnError, }?: HoudiniClientConstructorArgs);
|
|
29
35
|
observe<_Data extends GraphQLObject, _Input extends GraphQLVariables>({ enableCache, fetching, ...rest }: ObserveParams<_Data, DocumentArtifact, _Input>): DocumentStore<_Data, _Input>;
|
|
36
|
+
registerProxy(url: string, handler: (operation: {
|
|
37
|
+
query: string;
|
|
38
|
+
variables: any;
|
|
39
|
+
operationName: string;
|
|
40
|
+
session: App.Session | null | undefined;
|
|
41
|
+
}) => Promise<any>): void;
|
|
30
42
|
}
|
|
31
43
|
export declare function createPluginHooks(plugins: ClientPlugin[]): ClientHooks[];
|
|
@@ -5,6 +5,8 @@ export declare function setMockConfig(config: ConfigFile | null): void;
|
|
|
5
5
|
export declare function defaultConfigValues(file: ConfigFile): ConfigFile;
|
|
6
6
|
export declare function keyFieldsForType(configFile: ConfigFile, type: string): string[];
|
|
7
7
|
export declare function computeID(configFile: ConfigFile, type: string, data: any): string;
|
|
8
|
+
export declare function localApiEndpoint(configFile: ConfigFile): string;
|
|
9
|
+
export declare function localApiSessionKeys(configFile: ConfigFile): string[];
|
|
8
10
|
export declare function getCurrentConfig(): ConfigFile;
|
|
9
11
|
export type ConfigFile = {
|
|
10
12
|
/**
|
|
@@ -110,6 +112,23 @@ export type ConfigFile = {
|
|
|
110
112
|
* you must enable this flag.
|
|
111
113
|
*/
|
|
112
114
|
acceptImperativeInstability?: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Configure the router
|
|
117
|
+
*/
|
|
118
|
+
router?: RouterConfig;
|
|
119
|
+
};
|
|
120
|
+
type RouterConfig = {
|
|
121
|
+
auth?: AuthStrategy;
|
|
122
|
+
apiEndpoint?: string;
|
|
123
|
+
};
|
|
124
|
+
type AuthStrategy = {
|
|
125
|
+
redirect: string;
|
|
126
|
+
sessionKeys: string[];
|
|
127
|
+
url: string;
|
|
128
|
+
} | {
|
|
129
|
+
mutation: string;
|
|
130
|
+
sessionKeys: string[];
|
|
131
|
+
url: string;
|
|
113
132
|
};
|
|
114
133
|
type ScalarMap = {
|
|
115
134
|
[typeName: string]: ScalarSpec;
|
|
@@ -317,4 +317,43 @@ interface VariableNode {
|
|
|
317
317
|
export declare const PendingValue: unique symbol;
|
|
318
318
|
export type LoadingType = typeof PendingValue;
|
|
319
319
|
export declare function isPending(value: any): value is LoadingType;
|
|
320
|
+
export type ProjectManifest = {
|
|
321
|
+
/** All of the pages in the project */
|
|
322
|
+
pages: Record<string, PageManifest>;
|
|
323
|
+
/** All of the layouts in the project */
|
|
324
|
+
layouts: Record<string, PageManifest>;
|
|
325
|
+
/** All of the page queries in the project */
|
|
326
|
+
page_queries: Record<string, QueryManifest>;
|
|
327
|
+
/** All of the layout queries in the project */
|
|
328
|
+
layout_queries: Record<string, QueryManifest>;
|
|
329
|
+
/** All of the artifacts in the project */
|
|
330
|
+
artifacts: string[];
|
|
331
|
+
/** Whether or not there is a local schema defined */
|
|
332
|
+
local_schema: boolean;
|
|
333
|
+
/** Whether or not there is a custom instance of yoga defined */
|
|
334
|
+
local_yoga: boolean;
|
|
335
|
+
};
|
|
336
|
+
export type PageManifest = {
|
|
337
|
+
id: string;
|
|
338
|
+
/** the name of every query that the page depends on */
|
|
339
|
+
queries: string[];
|
|
340
|
+
/** the list of queries that this page could potentially ask for */
|
|
341
|
+
query_options: string[];
|
|
342
|
+
/** the full url pattern of the page */
|
|
343
|
+
url: string;
|
|
344
|
+
/** the ids of layouts that wrap this page */
|
|
345
|
+
layouts: string[];
|
|
346
|
+
/** The filepath of the unit */
|
|
347
|
+
path: string;
|
|
348
|
+
};
|
|
349
|
+
export type QueryManifest = {
|
|
350
|
+
/** the name of the query */
|
|
351
|
+
name: string;
|
|
352
|
+
/** the url tied with the query */
|
|
353
|
+
url: string;
|
|
354
|
+
/** wether the query uses the loading directive (ie, wants a fallback) */
|
|
355
|
+
loading: boolean;
|
|
356
|
+
/** The filepath of the unit */
|
|
357
|
+
path: string;
|
|
358
|
+
};
|
|
320
359
|
export {};
|
|
@@ -25,6 +25,7 @@ export declare class DocumentStore<_Data extends GraphQLObject, _Input extends G
|
|
|
25
25
|
});
|
|
26
26
|
send({ metadata, session, fetch, variables, policy, stuff, cacheParams, setup, silenceEcho, }?: SendParams): Promise<QueryResult<_Data, _Input>>;
|
|
27
27
|
cleanup(): Promise<void>;
|
|
28
|
+
getFetch(getSession: () => App.Session | null | undefined): (input: RequestInfo | URL, init?: RequestInit | undefined) => Promise<Response>;
|
|
28
29
|
}
|
|
29
30
|
declare function marshalVariables<_Data extends GraphQLObject, _Input extends GraphQLVariables>(ctx: ClientPluginContext): Record<string, any>;
|
|
30
31
|
export type ClientPlugin = () => ClientHooks | null | (ClientHooks | ClientPlugin | null)[];
|
|
@@ -91,7 +91,7 @@ class DocumentStore extends import_store.Writable {
|
|
|
91
91
|
async send({
|
|
92
92
|
metadata,
|
|
93
93
|
session,
|
|
94
|
-
fetch
|
|
94
|
+
fetch,
|
|
95
95
|
variables,
|
|
96
96
|
policy,
|
|
97
97
|
stuff,
|
|
@@ -108,7 +108,7 @@ class DocumentStore extends import_store.Writable {
|
|
|
108
108
|
variables: null,
|
|
109
109
|
metadata,
|
|
110
110
|
session,
|
|
111
|
-
fetch,
|
|
111
|
+
fetch: fetch ?? this.getFetch(() => session),
|
|
112
112
|
stuff: {
|
|
113
113
|
inputs: {
|
|
114
114
|
changed: false,
|
|
@@ -150,6 +150,46 @@ class DocumentStore extends import_store.Writable {
|
|
|
150
150
|
plugin.cleanup?.(this.#lastContext);
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
|
+
getFetch(getSession) {
|
|
154
|
+
return async (input, init) => {
|
|
155
|
+
let url = "";
|
|
156
|
+
let queries = [];
|
|
157
|
+
if (typeof input === "string") {
|
|
158
|
+
url = input.startsWith("http") ? new URL(input).pathname : input;
|
|
159
|
+
}
|
|
160
|
+
if (input instanceof URL) {
|
|
161
|
+
url = input.pathname;
|
|
162
|
+
} else if (input instanceof Request) {
|
|
163
|
+
url = new URL(input.url).pathname;
|
|
164
|
+
}
|
|
165
|
+
if (input instanceof Request) {
|
|
166
|
+
const body = await input.json();
|
|
167
|
+
if (!Array.isArray(body)) {
|
|
168
|
+
queries = [body];
|
|
169
|
+
}
|
|
170
|
+
} else {
|
|
171
|
+
const body = JSON.parse(init?.body);
|
|
172
|
+
if (!Array.isArray(body)) {
|
|
173
|
+
queries = [body];
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (!url || queries.length === 0) {
|
|
177
|
+
return await globalThis.fetch(input, init);
|
|
178
|
+
}
|
|
179
|
+
if (this.#client?.proxies[url]) {
|
|
180
|
+
const result = await Promise.all(
|
|
181
|
+
queries.map(
|
|
182
|
+
(q) => this.#client?.proxies[url]({
|
|
183
|
+
...q,
|
|
184
|
+
session: getSession()
|
|
185
|
+
})
|
|
186
|
+
)
|
|
187
|
+
);
|
|
188
|
+
return new Response(JSON.stringify(result.length === 1 ? result[0] : result));
|
|
189
|
+
}
|
|
190
|
+
return await globalThis.fetch(input, init);
|
|
191
|
+
};
|
|
192
|
+
}
|
|
153
193
|
#step(direction, ctx, value) {
|
|
154
194
|
const hook = direction === "error" ? "catch" : steps[direction][ctx.currentStep];
|
|
155
195
|
let valid = (i) => i <= this.#plugins.length;
|
|
@@ -7,7 +7,7 @@ import type { FetchParamFn, ThrowOnErrorOperations, ThrowOnErrorParams } from '.
|
|
|
7
7
|
export { DocumentStore, type ClientPlugin, type SendParams } from './documentStore';
|
|
8
8
|
export { fetch, mutation, query, subscription } from './plugins';
|
|
9
9
|
export type HoudiniClientConstructorArgs = {
|
|
10
|
-
url
|
|
10
|
+
url?: string;
|
|
11
11
|
fetchParams?: FetchParamFn;
|
|
12
12
|
plugins?: NestedList<ClientPlugin>;
|
|
13
13
|
pipeline?: NestedList<ClientPlugin>;
|
|
@@ -25,7 +25,19 @@ export declare class HoudiniClient {
|
|
|
25
25
|
url: string;
|
|
26
26
|
readonly plugins: ClientPlugin[];
|
|
27
27
|
readonly throwOnError_operations: ThrowOnErrorOperations[];
|
|
28
|
-
|
|
28
|
+
proxies: Record<string, (operation: {
|
|
29
|
+
query: string;
|
|
30
|
+
variables: any;
|
|
31
|
+
operationName: string;
|
|
32
|
+
session: App.Session | null | undefined;
|
|
33
|
+
}) => Promise<any>>;
|
|
34
|
+
constructor({ url, fetchParams, plugins, pipeline, throwOnError, }?: HoudiniClientConstructorArgs);
|
|
29
35
|
observe<_Data extends GraphQLObject, _Input extends GraphQLVariables>({ enableCache, fetching, ...rest }: ObserveParams<_Data, DocumentArtifact, _Input>): DocumentStore<_Data, _Input>;
|
|
36
|
+
registerProxy(url: string, handler: (operation: {
|
|
37
|
+
query: string;
|
|
38
|
+
variables: any;
|
|
39
|
+
operationName: string;
|
|
40
|
+
session: App.Session | null | undefined;
|
|
41
|
+
}) => Promise<any>): void;
|
|
30
42
|
}
|
|
31
43
|
export declare function createPluginHooks(plugins: ClientPlugin[]): ClientHooks[];
|
|
@@ -33,6 +33,7 @@ __export(client_exports, {
|
|
|
33
33
|
subscription: () => import_plugins2.subscription
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(client_exports);
|
|
36
|
+
var import_lib = require("../lib");
|
|
36
37
|
var import_flatten = require("../lib/flatten");
|
|
37
38
|
var import_documentStore = require("./documentStore");
|
|
38
39
|
var import_plugins = require("./plugins");
|
|
@@ -43,13 +44,14 @@ class HoudiniClient {
|
|
|
43
44
|
url;
|
|
44
45
|
plugins;
|
|
45
46
|
throwOnError_operations;
|
|
47
|
+
proxies = {};
|
|
46
48
|
constructor({
|
|
47
49
|
url,
|
|
48
50
|
fetchParams,
|
|
49
51
|
plugins,
|
|
50
52
|
pipeline,
|
|
51
53
|
throwOnError
|
|
52
|
-
}) {
|
|
54
|
+
} = {}) {
|
|
53
55
|
if (plugins && pipeline) {
|
|
54
56
|
throw new Error(
|
|
55
57
|
"A client cannot be given a pipeline and a list of plugins at the same time."
|
|
@@ -71,7 +73,8 @@ class HoudiniClient {
|
|
|
71
73
|
)
|
|
72
74
|
)
|
|
73
75
|
);
|
|
74
|
-
|
|
76
|
+
let serverPort = globalThis.process?.env?.HOUDINI_PORT ?? "5173";
|
|
77
|
+
this.url = url ?? (globalThis.window ? "" : `https://localhost:${serverPort}`) + (0, import_lib.localApiEndpoint)((0, import_lib.getCurrentConfig)());
|
|
75
78
|
}
|
|
76
79
|
observe({
|
|
77
80
|
enableCache = true,
|
|
@@ -86,6 +89,9 @@ class HoudiniClient {
|
|
|
86
89
|
...rest
|
|
87
90
|
});
|
|
88
91
|
}
|
|
92
|
+
registerProxy(url, handler) {
|
|
93
|
+
this.proxies[url] = handler;
|
|
94
|
+
}
|
|
89
95
|
}
|
|
90
96
|
function createPluginHooks(plugins) {
|
|
91
97
|
return plugins.reduce((hooks, plugin) => {
|
|
@@ -5,6 +5,8 @@ export declare function setMockConfig(config: ConfigFile | null): void;
|
|
|
5
5
|
export declare function defaultConfigValues(file: ConfigFile): ConfigFile;
|
|
6
6
|
export declare function keyFieldsForType(configFile: ConfigFile, type: string): string[];
|
|
7
7
|
export declare function computeID(configFile: ConfigFile, type: string, data: any): string;
|
|
8
|
+
export declare function localApiEndpoint(configFile: ConfigFile): string;
|
|
9
|
+
export declare function localApiSessionKeys(configFile: ConfigFile): string[];
|
|
8
10
|
export declare function getCurrentConfig(): ConfigFile;
|
|
9
11
|
export type ConfigFile = {
|
|
10
12
|
/**
|
|
@@ -110,6 +112,23 @@ export type ConfigFile = {
|
|
|
110
112
|
* you must enable this flag.
|
|
111
113
|
*/
|
|
112
114
|
acceptImperativeInstability?: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Configure the router
|
|
117
|
+
*/
|
|
118
|
+
router?: RouterConfig;
|
|
119
|
+
};
|
|
120
|
+
type RouterConfig = {
|
|
121
|
+
auth?: AuthStrategy;
|
|
122
|
+
apiEndpoint?: string;
|
|
123
|
+
};
|
|
124
|
+
type AuthStrategy = {
|
|
125
|
+
redirect: string;
|
|
126
|
+
sessionKeys: string[];
|
|
127
|
+
url: string;
|
|
128
|
+
} | {
|
|
129
|
+
mutation: string;
|
|
130
|
+
sessionKeys: string[];
|
|
131
|
+
url: string;
|
|
113
132
|
};
|
|
114
133
|
type ScalarMap = {
|
|
115
134
|
[typeName: string]: ScalarSpec;
|
|
@@ -29,6 +29,8 @@ __export(config_exports, {
|
|
|
29
29
|
getCurrentConfig: () => getCurrentConfig,
|
|
30
30
|
getMockConfig: () => getMockConfig,
|
|
31
31
|
keyFieldsForType: () => keyFieldsForType,
|
|
32
|
+
localApiEndpoint: () => localApiEndpoint,
|
|
33
|
+
localApiSessionKeys: () => localApiSessionKeys,
|
|
32
34
|
setMockConfig: () => setMockConfig
|
|
33
35
|
});
|
|
34
36
|
module.exports = __toCommonJS(config_exports);
|
|
@@ -70,6 +72,12 @@ function computeID(configFile, type, data) {
|
|
|
70
72
|
return id.slice(0, -2);
|
|
71
73
|
}
|
|
72
74
|
let _configFile = null;
|
|
75
|
+
function localApiEndpoint(configFile) {
|
|
76
|
+
return configFile.router?.apiEndpoint ?? "/_api";
|
|
77
|
+
}
|
|
78
|
+
function localApiSessionKeys(configFile) {
|
|
79
|
+
return configFile.router?.auth?.sessionKeys ?? [];
|
|
80
|
+
}
|
|
73
81
|
function getCurrentConfig() {
|
|
74
82
|
const mockConfig2 = getMockConfig();
|
|
75
83
|
if (mockConfig2) {
|
|
@@ -92,5 +100,7 @@ function getCurrentConfig() {
|
|
|
92
100
|
getCurrentConfig,
|
|
93
101
|
getMockConfig,
|
|
94
102
|
keyFieldsForType,
|
|
103
|
+
localApiEndpoint,
|
|
104
|
+
localApiSessionKeys,
|
|
95
105
|
setMockConfig
|
|
96
106
|
});
|
|
@@ -317,4 +317,43 @@ interface VariableNode {
|
|
|
317
317
|
export declare const PendingValue: unique symbol;
|
|
318
318
|
export type LoadingType = typeof PendingValue;
|
|
319
319
|
export declare function isPending(value: any): value is LoadingType;
|
|
320
|
+
export type ProjectManifest = {
|
|
321
|
+
/** All of the pages in the project */
|
|
322
|
+
pages: Record<string, PageManifest>;
|
|
323
|
+
/** All of the layouts in the project */
|
|
324
|
+
layouts: Record<string, PageManifest>;
|
|
325
|
+
/** All of the page queries in the project */
|
|
326
|
+
page_queries: Record<string, QueryManifest>;
|
|
327
|
+
/** All of the layout queries in the project */
|
|
328
|
+
layout_queries: Record<string, QueryManifest>;
|
|
329
|
+
/** All of the artifacts in the project */
|
|
330
|
+
artifacts: string[];
|
|
331
|
+
/** Whether or not there is a local schema defined */
|
|
332
|
+
local_schema: boolean;
|
|
333
|
+
/** Whether or not there is a custom instance of yoga defined */
|
|
334
|
+
local_yoga: boolean;
|
|
335
|
+
};
|
|
336
|
+
export type PageManifest = {
|
|
337
|
+
id: string;
|
|
338
|
+
/** the name of every query that the page depends on */
|
|
339
|
+
queries: string[];
|
|
340
|
+
/** the list of queries that this page could potentially ask for */
|
|
341
|
+
query_options: string[];
|
|
342
|
+
/** the full url pattern of the page */
|
|
343
|
+
url: string;
|
|
344
|
+
/** the ids of layouts that wrap this page */
|
|
345
|
+
layouts: string[];
|
|
346
|
+
/** The filepath of the unit */
|
|
347
|
+
path: string;
|
|
348
|
+
};
|
|
349
|
+
export type QueryManifest = {
|
|
350
|
+
/** the name of the query */
|
|
351
|
+
name: string;
|
|
352
|
+
/** the url tied with the query */
|
|
353
|
+
url: string;
|
|
354
|
+
/** wether the query uses the loading directive (ie, wants a fallback) */
|
|
355
|
+
loading: boolean;
|
|
356
|
+
/** The filepath of the unit */
|
|
357
|
+
path: string;
|
|
358
|
+
};
|
|
320
359
|
export {};
|
|
@@ -25,7 +25,7 @@ module.exports = __toCommonJS(server_exports);
|
|
|
25
25
|
var import_cookies = require("./cookies");
|
|
26
26
|
var import_jwt = require("./jwt");
|
|
27
27
|
async function handle_request(args) {
|
|
28
|
-
const plugin_config = args.config.
|
|
28
|
+
const plugin_config = args.config.router ?? {};
|
|
29
29
|
if (plugin_config.auth && "redirect" in plugin_config.auth && args.url.startsWith(plugin_config.auth.redirect)) {
|
|
30
30
|
return await redirect_auth(args);
|
|
31
31
|
}
|
|
@@ -25,6 +25,7 @@ export declare class DocumentStore<_Data extends GraphQLObject, _Input extends G
|
|
|
25
25
|
});
|
|
26
26
|
send({ metadata, session, fetch, variables, policy, stuff, cacheParams, setup, silenceEcho, }?: SendParams): Promise<QueryResult<_Data, _Input>>;
|
|
27
27
|
cleanup(): Promise<void>;
|
|
28
|
+
getFetch(getSession: () => App.Session | null | undefined): (input: RequestInfo | URL, init?: RequestInit | undefined) => Promise<Response>;
|
|
28
29
|
}
|
|
29
30
|
declare function marshalVariables<_Data extends GraphQLObject, _Input extends GraphQLVariables>(ctx: ClientPluginContext): Record<string, any>;
|
|
30
31
|
export type ClientPlugin = () => ClientHooks | null | (ClientHooks | ClientPlugin | null)[];
|
|
@@ -68,7 +68,7 @@ class DocumentStore extends Writable {
|
|
|
68
68
|
async send({
|
|
69
69
|
metadata,
|
|
70
70
|
session,
|
|
71
|
-
fetch
|
|
71
|
+
fetch,
|
|
72
72
|
variables,
|
|
73
73
|
policy,
|
|
74
74
|
stuff,
|
|
@@ -85,7 +85,7 @@ class DocumentStore extends Writable {
|
|
|
85
85
|
variables: null,
|
|
86
86
|
metadata,
|
|
87
87
|
session,
|
|
88
|
-
fetch,
|
|
88
|
+
fetch: fetch ?? this.getFetch(() => session),
|
|
89
89
|
stuff: {
|
|
90
90
|
inputs: {
|
|
91
91
|
changed: false,
|
|
@@ -127,6 +127,46 @@ class DocumentStore extends Writable {
|
|
|
127
127
|
plugin.cleanup?.(this.#lastContext);
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
|
+
getFetch(getSession) {
|
|
131
|
+
return async (input, init) => {
|
|
132
|
+
let url = "";
|
|
133
|
+
let queries = [];
|
|
134
|
+
if (typeof input === "string") {
|
|
135
|
+
url = input.startsWith("http") ? new URL(input).pathname : input;
|
|
136
|
+
}
|
|
137
|
+
if (input instanceof URL) {
|
|
138
|
+
url = input.pathname;
|
|
139
|
+
} else if (input instanceof Request) {
|
|
140
|
+
url = new URL(input.url).pathname;
|
|
141
|
+
}
|
|
142
|
+
if (input instanceof Request) {
|
|
143
|
+
const body = await input.json();
|
|
144
|
+
if (!Array.isArray(body)) {
|
|
145
|
+
queries = [body];
|
|
146
|
+
}
|
|
147
|
+
} else {
|
|
148
|
+
const body = JSON.parse(init?.body);
|
|
149
|
+
if (!Array.isArray(body)) {
|
|
150
|
+
queries = [body];
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (!url || queries.length === 0) {
|
|
154
|
+
return await globalThis.fetch(input, init);
|
|
155
|
+
}
|
|
156
|
+
if (this.#client?.proxies[url]) {
|
|
157
|
+
const result = await Promise.all(
|
|
158
|
+
queries.map(
|
|
159
|
+
(q) => this.#client?.proxies[url]({
|
|
160
|
+
...q,
|
|
161
|
+
session: getSession()
|
|
162
|
+
})
|
|
163
|
+
)
|
|
164
|
+
);
|
|
165
|
+
return new Response(JSON.stringify(result.length === 1 ? result[0] : result));
|
|
166
|
+
}
|
|
167
|
+
return await globalThis.fetch(input, init);
|
|
168
|
+
};
|
|
169
|
+
}
|
|
130
170
|
#step(direction, ctx, value) {
|
|
131
171
|
const hook = direction === "error" ? "catch" : steps[direction][ctx.currentStep];
|
|
132
172
|
let valid = (i) => i <= this.#plugins.length;
|
|
@@ -7,7 +7,7 @@ import type { FetchParamFn, ThrowOnErrorOperations, ThrowOnErrorParams } from '.
|
|
|
7
7
|
export { DocumentStore, type ClientPlugin, type SendParams } from './documentStore';
|
|
8
8
|
export { fetch, mutation, query, subscription } from './plugins';
|
|
9
9
|
export type HoudiniClientConstructorArgs = {
|
|
10
|
-
url
|
|
10
|
+
url?: string;
|
|
11
11
|
fetchParams?: FetchParamFn;
|
|
12
12
|
plugins?: NestedList<ClientPlugin>;
|
|
13
13
|
pipeline?: NestedList<ClientPlugin>;
|
|
@@ -25,7 +25,19 @@ export declare class HoudiniClient {
|
|
|
25
25
|
url: string;
|
|
26
26
|
readonly plugins: ClientPlugin[];
|
|
27
27
|
readonly throwOnError_operations: ThrowOnErrorOperations[];
|
|
28
|
-
|
|
28
|
+
proxies: Record<string, (operation: {
|
|
29
|
+
query: string;
|
|
30
|
+
variables: any;
|
|
31
|
+
operationName: string;
|
|
32
|
+
session: App.Session | null | undefined;
|
|
33
|
+
}) => Promise<any>>;
|
|
34
|
+
constructor({ url, fetchParams, plugins, pipeline, throwOnError, }?: HoudiniClientConstructorArgs);
|
|
29
35
|
observe<_Data extends GraphQLObject, _Input extends GraphQLVariables>({ enableCache, fetching, ...rest }: ObserveParams<_Data, DocumentArtifact, _Input>): DocumentStore<_Data, _Input>;
|
|
36
|
+
registerProxy(url: string, handler: (operation: {
|
|
37
|
+
query: string;
|
|
38
|
+
variables: any;
|
|
39
|
+
operationName: string;
|
|
40
|
+
session: App.Session | null | undefined;
|
|
41
|
+
}) => Promise<any>): void;
|
|
30
42
|
}
|
|
31
43
|
export declare function createPluginHooks(plugins: ClientPlugin[]): ClientHooks[];
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getCurrentConfig, localApiEndpoint } from "../lib";
|
|
1
2
|
import { flatten } from "../lib/flatten";
|
|
2
3
|
import { DocumentStore } from "./documentStore";
|
|
3
4
|
import {
|
|
@@ -15,13 +16,14 @@ class HoudiniClient {
|
|
|
15
16
|
url;
|
|
16
17
|
plugins;
|
|
17
18
|
throwOnError_operations;
|
|
19
|
+
proxies = {};
|
|
18
20
|
constructor({
|
|
19
21
|
url,
|
|
20
22
|
fetchParams,
|
|
21
23
|
plugins,
|
|
22
24
|
pipeline,
|
|
23
25
|
throwOnError
|
|
24
|
-
}) {
|
|
26
|
+
} = {}) {
|
|
25
27
|
if (plugins && pipeline) {
|
|
26
28
|
throw new Error(
|
|
27
29
|
"A client cannot be given a pipeline and a list of plugins at the same time."
|
|
@@ -43,7 +45,8 @@ class HoudiniClient {
|
|
|
43
45
|
)
|
|
44
46
|
)
|
|
45
47
|
);
|
|
46
|
-
|
|
48
|
+
let serverPort = globalThis.process?.env?.HOUDINI_PORT ?? "5173";
|
|
49
|
+
this.url = url ?? (globalThis.window ? "" : `https://localhost:${serverPort}`) + localApiEndpoint(getCurrentConfig());
|
|
47
50
|
}
|
|
48
51
|
observe({
|
|
49
52
|
enableCache = true,
|
|
@@ -58,6 +61,9 @@ class HoudiniClient {
|
|
|
58
61
|
...rest
|
|
59
62
|
});
|
|
60
63
|
}
|
|
64
|
+
registerProxy(url, handler) {
|
|
65
|
+
this.proxies[url] = handler;
|
|
66
|
+
}
|
|
61
67
|
}
|
|
62
68
|
function createPluginHooks(plugins) {
|
|
63
69
|
return plugins.reduce((hooks, plugin) => {
|
|
@@ -5,6 +5,8 @@ export declare function setMockConfig(config: ConfigFile | null): void;
|
|
|
5
5
|
export declare function defaultConfigValues(file: ConfigFile): ConfigFile;
|
|
6
6
|
export declare function keyFieldsForType(configFile: ConfigFile, type: string): string[];
|
|
7
7
|
export declare function computeID(configFile: ConfigFile, type: string, data: any): string;
|
|
8
|
+
export declare function localApiEndpoint(configFile: ConfigFile): string;
|
|
9
|
+
export declare function localApiSessionKeys(configFile: ConfigFile): string[];
|
|
8
10
|
export declare function getCurrentConfig(): ConfigFile;
|
|
9
11
|
export type ConfigFile = {
|
|
10
12
|
/**
|
|
@@ -110,6 +112,23 @@ export type ConfigFile = {
|
|
|
110
112
|
* you must enable this flag.
|
|
111
113
|
*/
|
|
112
114
|
acceptImperativeInstability?: boolean;
|
|
115
|
+
/**
|
|
116
|
+
* Configure the router
|
|
117
|
+
*/
|
|
118
|
+
router?: RouterConfig;
|
|
119
|
+
};
|
|
120
|
+
type RouterConfig = {
|
|
121
|
+
auth?: AuthStrategy;
|
|
122
|
+
apiEndpoint?: string;
|
|
123
|
+
};
|
|
124
|
+
type AuthStrategy = {
|
|
125
|
+
redirect: string;
|
|
126
|
+
sessionKeys: string[];
|
|
127
|
+
url: string;
|
|
128
|
+
} | {
|
|
129
|
+
mutation: string;
|
|
130
|
+
sessionKeys: string[];
|
|
131
|
+
url: string;
|
|
113
132
|
};
|
|
114
133
|
type ScalarMap = {
|
|
115
134
|
[typeName: string]: ScalarSpec;
|
|
@@ -36,6 +36,12 @@ function computeID(configFile, type, data) {
|
|
|
36
36
|
return id.slice(0, -2);
|
|
37
37
|
}
|
|
38
38
|
let _configFile = null;
|
|
39
|
+
function localApiEndpoint(configFile) {
|
|
40
|
+
return configFile.router?.apiEndpoint ?? "/_api";
|
|
41
|
+
}
|
|
42
|
+
function localApiSessionKeys(configFile) {
|
|
43
|
+
return configFile.router?.auth?.sessionKeys ?? [];
|
|
44
|
+
}
|
|
39
45
|
function getCurrentConfig() {
|
|
40
46
|
const mockConfig2 = getMockConfig();
|
|
41
47
|
if (mockConfig2) {
|
|
@@ -57,5 +63,7 @@ export {
|
|
|
57
63
|
getCurrentConfig,
|
|
58
64
|
getMockConfig,
|
|
59
65
|
keyFieldsForType,
|
|
66
|
+
localApiEndpoint,
|
|
67
|
+
localApiSessionKeys,
|
|
60
68
|
setMockConfig
|
|
61
69
|
};
|
|
@@ -317,4 +317,43 @@ interface VariableNode {
|
|
|
317
317
|
export declare const PendingValue: unique symbol;
|
|
318
318
|
export type LoadingType = typeof PendingValue;
|
|
319
319
|
export declare function isPending(value: any): value is LoadingType;
|
|
320
|
+
export type ProjectManifest = {
|
|
321
|
+
/** All of the pages in the project */
|
|
322
|
+
pages: Record<string, PageManifest>;
|
|
323
|
+
/** All of the layouts in the project */
|
|
324
|
+
layouts: Record<string, PageManifest>;
|
|
325
|
+
/** All of the page queries in the project */
|
|
326
|
+
page_queries: Record<string, QueryManifest>;
|
|
327
|
+
/** All of the layout queries in the project */
|
|
328
|
+
layout_queries: Record<string, QueryManifest>;
|
|
329
|
+
/** All of the artifacts in the project */
|
|
330
|
+
artifacts: string[];
|
|
331
|
+
/** Whether or not there is a local schema defined */
|
|
332
|
+
local_schema: boolean;
|
|
333
|
+
/** Whether or not there is a custom instance of yoga defined */
|
|
334
|
+
local_yoga: boolean;
|
|
335
|
+
};
|
|
336
|
+
export type PageManifest = {
|
|
337
|
+
id: string;
|
|
338
|
+
/** the name of every query that the page depends on */
|
|
339
|
+
queries: string[];
|
|
340
|
+
/** the list of queries that this page could potentially ask for */
|
|
341
|
+
query_options: string[];
|
|
342
|
+
/** the full url pattern of the page */
|
|
343
|
+
url: string;
|
|
344
|
+
/** the ids of layouts that wrap this page */
|
|
345
|
+
layouts: string[];
|
|
346
|
+
/** The filepath of the unit */
|
|
347
|
+
path: string;
|
|
348
|
+
};
|
|
349
|
+
export type QueryManifest = {
|
|
350
|
+
/** the name of the query */
|
|
351
|
+
name: string;
|
|
352
|
+
/** the url tied with the query */
|
|
353
|
+
url: string;
|
|
354
|
+
/** wether the query uses the loading directive (ie, wants a fallback) */
|
|
355
|
+
loading: boolean;
|
|
356
|
+
/** The filepath of the unit */
|
|
357
|
+
path: string;
|
|
358
|
+
};
|
|
320
359
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { parse } from "./cookies";
|
|
2
2
|
import { decode, encode, verify } from "./jwt";
|
|
3
3
|
async function handle_request(args) {
|
|
4
|
-
const plugin_config = args.config.
|
|
4
|
+
const plugin_config = args.config.router ?? {};
|
|
5
5
|
if (plugin_config.auth && "redirect" in plugin_config.auth && args.url.startsWith(plugin_config.auth.redirect)) {
|
|
6
6
|
return await redirect_auth(args);
|
|
7
7
|
}
|