@constructive-io/graphql-query 3.15.1 → 3.15.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/esm/runtime/index.js +5 -2
- package/esm/runtime/localhost-fetch.js +108 -0
- package/package.json +3 -3
- package/runtime/index.d.ts +5 -2
- package/runtime/index.js +7 -3
- package/runtime/localhost-fetch.d.ts +27 -0
- package/runtime/localhost-fetch.js +112 -0
package/esm/runtime/index.js
CHANGED
|
@@ -2,18 +2,21 @@
|
|
|
2
2
|
* Runtime sub-export for generated ORM code.
|
|
3
3
|
*
|
|
4
4
|
* Generated ORM clients need runtime dependencies at execution time.
|
|
5
|
-
* This module re-exports
|
|
5
|
+
* This module re-exports so generated code can consolidate imports:
|
|
6
6
|
* - @0no-co/graphql.web — parseType, print
|
|
7
7
|
* - @constructive-io/graphql-types — GraphQLAdapter, GraphQLError, QueryResult
|
|
8
|
+
* - ./localhost-fetch — createFetch (isomorphic *.localhost-aware fetch)
|
|
8
9
|
*
|
|
9
10
|
* gql-ast is intentionally NOT re-exported here because the templates
|
|
10
11
|
* use `import * as t from 'gql-ast'` — mixing it into this namespace
|
|
11
12
|
* would pollute `t` with unrelated symbols like parseType and print.
|
|
12
13
|
*
|
|
13
14
|
* Usage in generated templates:
|
|
14
|
-
* import { parseType, print } from '@constructive-io/graphql-query/runtime';
|
|
15
|
+
* import { parseType, print, createFetch } from '@constructive-io/graphql-query/runtime';
|
|
15
16
|
* import * as t from 'gql-ast';
|
|
16
17
|
* import type { GraphQLAdapter } from '@constructive-io/graphql-query/runtime';
|
|
17
18
|
*/
|
|
18
19
|
// From @0no-co/graphql.web — GraphQL parsing/printing
|
|
19
20
|
export { parseType, print } from '@0no-co/graphql.web';
|
|
21
|
+
// Isomorphic fetch with *.localhost DNS + Host header fix for Node.js
|
|
22
|
+
export { createFetch } from './localhost-fetch';
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Isomorphic fetch that resolves *.localhost subdomains and preserves
|
|
3
|
+
* Host headers across Node.js and browsers.
|
|
4
|
+
*
|
|
5
|
+
* Node.js has two issues with *.localhost subdomains:
|
|
6
|
+
* 1. DNS — fetch('http://auth.localhost:3000/') throws ENOTFOUND
|
|
7
|
+
* because undici doesn't resolve *.localhost to loopback.
|
|
8
|
+
* 2. Host header — Node's fetch treats Host as forbidden and silently
|
|
9
|
+
* drops it, breaking server-side subdomain routing.
|
|
10
|
+
*
|
|
11
|
+
* In browsers *.localhost resolves natively, so createFetch() returns
|
|
12
|
+
* globalThis.fetch as-is.
|
|
13
|
+
*/
|
|
14
|
+
export function isLocalhostSubdomain(hostname) {
|
|
15
|
+
return hostname.endsWith('.localhost') && hostname !== 'localhost';
|
|
16
|
+
}
|
|
17
|
+
function buildNodeFetch(http, https) {
|
|
18
|
+
return (input, init) => {
|
|
19
|
+
const url = new URL(typeof input === 'string'
|
|
20
|
+
? input
|
|
21
|
+
: input instanceof URL
|
|
22
|
+
? input.href
|
|
23
|
+
: input.url);
|
|
24
|
+
if (!isLocalhostSubdomain(url.hostname)) {
|
|
25
|
+
return globalThis.fetch(input, init);
|
|
26
|
+
}
|
|
27
|
+
const originalHost = url.host;
|
|
28
|
+
url.hostname = 'localhost';
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
const headers = {
|
|
31
|
+
Host: originalHost,
|
|
32
|
+
};
|
|
33
|
+
if (init?.headers) {
|
|
34
|
+
const entries = init.headers instanceof Headers
|
|
35
|
+
? Array.from(init.headers.entries())
|
|
36
|
+
: Array.isArray(init.headers)
|
|
37
|
+
? init.headers
|
|
38
|
+
: Object.entries(init.headers);
|
|
39
|
+
for (const [key, value] of entries) {
|
|
40
|
+
headers[key] = value;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const protocol = url.protocol === 'https:' ? https : http;
|
|
44
|
+
const req = protocol.request(url, {
|
|
45
|
+
method: init?.method ?? 'GET',
|
|
46
|
+
headers,
|
|
47
|
+
}, (res) => {
|
|
48
|
+
const chunks = [];
|
|
49
|
+
res.on('data', (chunk) => chunks.push(chunk));
|
|
50
|
+
res.on('end', () => {
|
|
51
|
+
const body = Buffer.concat(chunks);
|
|
52
|
+
resolve(new Response(body, {
|
|
53
|
+
status: res.statusCode ?? 0,
|
|
54
|
+
statusText: res.statusMessage ?? '',
|
|
55
|
+
headers: res.headers,
|
|
56
|
+
}));
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
req.on('error', reject);
|
|
60
|
+
if (init?.signal) {
|
|
61
|
+
const onAbort = () => {
|
|
62
|
+
req.destroy(new Error('The operation was aborted'));
|
|
63
|
+
};
|
|
64
|
+
init.signal.addEventListener('abort', onAbort, { once: true });
|
|
65
|
+
req.on('close', () => {
|
|
66
|
+
init.signal.removeEventListener('abort', onAbort);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
if (init?.body != null) {
|
|
70
|
+
req.write(typeof init.body === 'string' || init.body instanceof Uint8Array
|
|
71
|
+
? init.body
|
|
72
|
+
: String(init.body));
|
|
73
|
+
}
|
|
74
|
+
req.end();
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
let _fetch;
|
|
79
|
+
/**
|
|
80
|
+
* Create an isomorphic fetch function.
|
|
81
|
+
*
|
|
82
|
+
* - In browsers (and Deno/Bun/edge): returns globalThis.fetch as-is.
|
|
83
|
+
* - In Node.js: returns a wrapper that uses node:http/node:https for
|
|
84
|
+
* *.localhost URLs (fixing DNS + Host header) and delegates everything
|
|
85
|
+
* else to globalThis.fetch.
|
|
86
|
+
*
|
|
87
|
+
* The result is cached — calling createFetch() multiple times returns
|
|
88
|
+
* the same function instance.
|
|
89
|
+
*/
|
|
90
|
+
export function createFetch() {
|
|
91
|
+
if (_fetch)
|
|
92
|
+
return _fetch;
|
|
93
|
+
if (typeof process !== 'undefined' && process.versions?.node) {
|
|
94
|
+
try {
|
|
95
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
96
|
+
const http = require('node:http');
|
|
97
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
98
|
+
const https = require('node:https');
|
|
99
|
+
_fetch = buildNodeFetch(http, https);
|
|
100
|
+
return _fetch;
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// node:http unavailable — fall through
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
_fetch = globalThis.fetch;
|
|
107
|
+
return _fetch;
|
|
108
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@constructive-io/graphql-query",
|
|
3
|
-
"version": "3.15.
|
|
3
|
+
"version": "3.15.2",
|
|
4
4
|
"description": "Constructive GraphQL Query",
|
|
5
5
|
"author": "Constructive <developers@constructive.io>",
|
|
6
6
|
"main": "index.js",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"grafast": "1.0.0",
|
|
37
37
|
"graphile-build-pg": "5.0.0",
|
|
38
38
|
"graphile-config": "1.0.0",
|
|
39
|
-
"graphile-settings": "^4.22.
|
|
39
|
+
"graphile-settings": "^4.22.2",
|
|
40
40
|
"graphql": "16.13.0",
|
|
41
41
|
"inflection": "^3.0.0",
|
|
42
42
|
"inflekt": "^0.7.1",
|
|
@@ -53,5 +53,5 @@
|
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"makage": "^0.3.0"
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "a8ccaed4f3a7c6c82495241ee1581700db9dd2dd"
|
|
57
57
|
}
|
package/runtime/index.d.ts
CHANGED
|
@@ -2,18 +2,21 @@
|
|
|
2
2
|
* Runtime sub-export for generated ORM code.
|
|
3
3
|
*
|
|
4
4
|
* Generated ORM clients need runtime dependencies at execution time.
|
|
5
|
-
* This module re-exports
|
|
5
|
+
* This module re-exports so generated code can consolidate imports:
|
|
6
6
|
* - @0no-co/graphql.web — parseType, print
|
|
7
7
|
* - @constructive-io/graphql-types — GraphQLAdapter, GraphQLError, QueryResult
|
|
8
|
+
* - ./localhost-fetch — createFetch (isomorphic *.localhost-aware fetch)
|
|
8
9
|
*
|
|
9
10
|
* gql-ast is intentionally NOT re-exported here because the templates
|
|
10
11
|
* use `import * as t from 'gql-ast'` — mixing it into this namespace
|
|
11
12
|
* would pollute `t` with unrelated symbols like parseType and print.
|
|
12
13
|
*
|
|
13
14
|
* Usage in generated templates:
|
|
14
|
-
* import { parseType, print } from '@constructive-io/graphql-query/runtime';
|
|
15
|
+
* import { parseType, print, createFetch } from '@constructive-io/graphql-query/runtime';
|
|
15
16
|
* import * as t from 'gql-ast';
|
|
16
17
|
* import type { GraphQLAdapter } from '@constructive-io/graphql-query/runtime';
|
|
17
18
|
*/
|
|
18
19
|
export { parseType, print } from '@0no-co/graphql.web';
|
|
19
20
|
export type { GraphQLAdapter, GraphQLError, QueryResult } from '@constructive-io/graphql-types';
|
|
21
|
+
export { createFetch } from './localhost-fetch';
|
|
22
|
+
export type { FetchFunction } from './localhost-fetch';
|
package/runtime/index.js
CHANGED
|
@@ -3,22 +3,26 @@
|
|
|
3
3
|
* Runtime sub-export for generated ORM code.
|
|
4
4
|
*
|
|
5
5
|
* Generated ORM clients need runtime dependencies at execution time.
|
|
6
|
-
* This module re-exports
|
|
6
|
+
* This module re-exports so generated code can consolidate imports:
|
|
7
7
|
* - @0no-co/graphql.web — parseType, print
|
|
8
8
|
* - @constructive-io/graphql-types — GraphQLAdapter, GraphQLError, QueryResult
|
|
9
|
+
* - ./localhost-fetch — createFetch (isomorphic *.localhost-aware fetch)
|
|
9
10
|
*
|
|
10
11
|
* gql-ast is intentionally NOT re-exported here because the templates
|
|
11
12
|
* use `import * as t from 'gql-ast'` — mixing it into this namespace
|
|
12
13
|
* would pollute `t` with unrelated symbols like parseType and print.
|
|
13
14
|
*
|
|
14
15
|
* Usage in generated templates:
|
|
15
|
-
* import { parseType, print } from '@constructive-io/graphql-query/runtime';
|
|
16
|
+
* import { parseType, print, createFetch } from '@constructive-io/graphql-query/runtime';
|
|
16
17
|
* import * as t from 'gql-ast';
|
|
17
18
|
* import type { GraphQLAdapter } from '@constructive-io/graphql-query/runtime';
|
|
18
19
|
*/
|
|
19
20
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.parseType = void 0;
|
|
21
|
+
exports.createFetch = exports.parseType = void 0;
|
|
21
22
|
// From @0no-co/graphql.web — GraphQL parsing/printing
|
|
22
23
|
var graphql_web_1 = require("@0no-co/graphql.web");
|
|
23
24
|
Object.defineProperty(exports, "parseType", { enumerable: true, get: function () { return graphql_web_1.parseType; } });
|
|
24
25
|
Object.defineProperty(exports, "print", { enumerable: true, get: function () { return graphql_web_1.print; } });
|
|
26
|
+
// Isomorphic fetch with *.localhost DNS + Host header fix for Node.js
|
|
27
|
+
var localhost_fetch_1 = require("./localhost-fetch");
|
|
28
|
+
Object.defineProperty(exports, "createFetch", { enumerable: true, get: function () { return localhost_fetch_1.createFetch; } });
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Isomorphic fetch that resolves *.localhost subdomains and preserves
|
|
3
|
+
* Host headers across Node.js and browsers.
|
|
4
|
+
*
|
|
5
|
+
* Node.js has two issues with *.localhost subdomains:
|
|
6
|
+
* 1. DNS — fetch('http://auth.localhost:3000/') throws ENOTFOUND
|
|
7
|
+
* because undici doesn't resolve *.localhost to loopback.
|
|
8
|
+
* 2. Host header — Node's fetch treats Host as forbidden and silently
|
|
9
|
+
* drops it, breaking server-side subdomain routing.
|
|
10
|
+
*
|
|
11
|
+
* In browsers *.localhost resolves natively, so createFetch() returns
|
|
12
|
+
* globalThis.fetch as-is.
|
|
13
|
+
*/
|
|
14
|
+
export type FetchFunction = typeof globalThis.fetch;
|
|
15
|
+
export declare function isLocalhostSubdomain(hostname: string): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Create an isomorphic fetch function.
|
|
18
|
+
*
|
|
19
|
+
* - In browsers (and Deno/Bun/edge): returns globalThis.fetch as-is.
|
|
20
|
+
* - In Node.js: returns a wrapper that uses node:http/node:https for
|
|
21
|
+
* *.localhost URLs (fixing DNS + Host header) and delegates everything
|
|
22
|
+
* else to globalThis.fetch.
|
|
23
|
+
*
|
|
24
|
+
* The result is cached — calling createFetch() multiple times returns
|
|
25
|
+
* the same function instance.
|
|
26
|
+
*/
|
|
27
|
+
export declare function createFetch(): FetchFunction;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Isomorphic fetch that resolves *.localhost subdomains and preserves
|
|
4
|
+
* Host headers across Node.js and browsers.
|
|
5
|
+
*
|
|
6
|
+
* Node.js has two issues with *.localhost subdomains:
|
|
7
|
+
* 1. DNS — fetch('http://auth.localhost:3000/') throws ENOTFOUND
|
|
8
|
+
* because undici doesn't resolve *.localhost to loopback.
|
|
9
|
+
* 2. Host header — Node's fetch treats Host as forbidden and silently
|
|
10
|
+
* drops it, breaking server-side subdomain routing.
|
|
11
|
+
*
|
|
12
|
+
* In browsers *.localhost resolves natively, so createFetch() returns
|
|
13
|
+
* globalThis.fetch as-is.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.isLocalhostSubdomain = isLocalhostSubdomain;
|
|
17
|
+
exports.createFetch = createFetch;
|
|
18
|
+
function isLocalhostSubdomain(hostname) {
|
|
19
|
+
return hostname.endsWith('.localhost') && hostname !== 'localhost';
|
|
20
|
+
}
|
|
21
|
+
function buildNodeFetch(http, https) {
|
|
22
|
+
return (input, init) => {
|
|
23
|
+
const url = new URL(typeof input === 'string'
|
|
24
|
+
? input
|
|
25
|
+
: input instanceof URL
|
|
26
|
+
? input.href
|
|
27
|
+
: input.url);
|
|
28
|
+
if (!isLocalhostSubdomain(url.hostname)) {
|
|
29
|
+
return globalThis.fetch(input, init);
|
|
30
|
+
}
|
|
31
|
+
const originalHost = url.host;
|
|
32
|
+
url.hostname = 'localhost';
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
const headers = {
|
|
35
|
+
Host: originalHost,
|
|
36
|
+
};
|
|
37
|
+
if (init?.headers) {
|
|
38
|
+
const entries = init.headers instanceof Headers
|
|
39
|
+
? Array.from(init.headers.entries())
|
|
40
|
+
: Array.isArray(init.headers)
|
|
41
|
+
? init.headers
|
|
42
|
+
: Object.entries(init.headers);
|
|
43
|
+
for (const [key, value] of entries) {
|
|
44
|
+
headers[key] = value;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const protocol = url.protocol === 'https:' ? https : http;
|
|
48
|
+
const req = protocol.request(url, {
|
|
49
|
+
method: init?.method ?? 'GET',
|
|
50
|
+
headers,
|
|
51
|
+
}, (res) => {
|
|
52
|
+
const chunks = [];
|
|
53
|
+
res.on('data', (chunk) => chunks.push(chunk));
|
|
54
|
+
res.on('end', () => {
|
|
55
|
+
const body = Buffer.concat(chunks);
|
|
56
|
+
resolve(new Response(body, {
|
|
57
|
+
status: res.statusCode ?? 0,
|
|
58
|
+
statusText: res.statusMessage ?? '',
|
|
59
|
+
headers: res.headers,
|
|
60
|
+
}));
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
req.on('error', reject);
|
|
64
|
+
if (init?.signal) {
|
|
65
|
+
const onAbort = () => {
|
|
66
|
+
req.destroy(new Error('The operation was aborted'));
|
|
67
|
+
};
|
|
68
|
+
init.signal.addEventListener('abort', onAbort, { once: true });
|
|
69
|
+
req.on('close', () => {
|
|
70
|
+
init.signal.removeEventListener('abort', onAbort);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
if (init?.body != null) {
|
|
74
|
+
req.write(typeof init.body === 'string' || init.body instanceof Uint8Array
|
|
75
|
+
? init.body
|
|
76
|
+
: String(init.body));
|
|
77
|
+
}
|
|
78
|
+
req.end();
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
let _fetch;
|
|
83
|
+
/**
|
|
84
|
+
* Create an isomorphic fetch function.
|
|
85
|
+
*
|
|
86
|
+
* - In browsers (and Deno/Bun/edge): returns globalThis.fetch as-is.
|
|
87
|
+
* - In Node.js: returns a wrapper that uses node:http/node:https for
|
|
88
|
+
* *.localhost URLs (fixing DNS + Host header) and delegates everything
|
|
89
|
+
* else to globalThis.fetch.
|
|
90
|
+
*
|
|
91
|
+
* The result is cached — calling createFetch() multiple times returns
|
|
92
|
+
* the same function instance.
|
|
93
|
+
*/
|
|
94
|
+
function createFetch() {
|
|
95
|
+
if (_fetch)
|
|
96
|
+
return _fetch;
|
|
97
|
+
if (typeof process !== 'undefined' && process.versions?.node) {
|
|
98
|
+
try {
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
100
|
+
const http = require('node:http');
|
|
101
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
102
|
+
const https = require('node:https');
|
|
103
|
+
_fetch = buildNodeFetch(http, https);
|
|
104
|
+
return _fetch;
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
// node:http unavailable — fall through
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
_fetch = globalThis.fetch;
|
|
111
|
+
return _fetch;
|
|
112
|
+
}
|