@quilted/rollup 0.1.18 → 0.2.0
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/CHANGELOG.md +25 -0
- package/build/esm/app.mjs +442 -233
- package/build/esm/constants.mjs +5 -5
- package/build/esm/features/assets.mjs +93 -81
- package/build/esm/features/async.mjs +186 -0
- package/build/esm/features/css.mjs +26 -39
- package/build/esm/features/env.mjs +47 -44
- package/build/esm/features/esnext.mjs +57 -0
- package/build/esm/features/graphql/transform.mjs +60 -56
- package/build/esm/features/graphql.mjs +65 -47
- package/build/esm/features/request-router.mjs +6 -4
- package/build/esm/features/source-code.mjs +54 -28
- package/build/esm/features/system-js.mjs +13 -18
- package/build/esm/features/typescript.mjs +13 -10
- package/build/esm/features/workers.mjs +173 -0
- package/build/esm/index.mjs +3 -2
- package/build/esm/module.mjs +69 -62
- package/build/esm/package.mjs +275 -84
- package/build/esm/server.mjs +118 -0
- package/build/esm/shared/browserslist.mjs +141 -16
- package/build/esm/shared/magic-module.mjs +9 -7
- package/build/esm/shared/package-json.mjs +7 -1
- package/build/esm/shared/path.mjs +7 -0
- package/build/esm/shared/rollup.mjs +89 -25
- package/build/esm/shared/strings.mjs +7 -6
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/typescript/app.d.ts +126 -27
- package/build/typescript/app.d.ts.map +1 -1
- package/build/typescript/features/assets.d.ts +1 -2
- package/build/typescript/features/assets.d.ts.map +1 -1
- package/build/typescript/features/async.d.ts +10 -0
- package/build/typescript/features/async.d.ts.map +1 -0
- package/build/typescript/features/css.d.ts +2 -1
- package/build/typescript/features/css.d.ts.map +1 -1
- package/build/typescript/features/env.d.ts +1 -0
- package/build/typescript/features/env.d.ts.map +1 -1
- package/build/typescript/features/esnext.d.ts +9 -0
- package/build/typescript/features/esnext.d.ts.map +1 -0
- package/build/typescript/features/graphql.d.ts +2 -2
- package/build/typescript/features/graphql.d.ts.map +1 -1
- package/build/typescript/features/source-code.d.ts +9 -3
- package/build/typescript/features/source-code.d.ts.map +1 -1
- package/build/typescript/features/workers.d.ts +52 -0
- package/build/typescript/features/workers.d.ts.map +1 -0
- package/build/typescript/index.d.ts +3 -2
- package/build/typescript/index.d.ts.map +1 -1
- package/build/typescript/module.d.ts +24 -6
- package/build/typescript/module.d.ts.map +1 -1
- package/build/typescript/package.d.ts +196 -4
- package/build/typescript/package.d.ts.map +1 -1
- package/build/typescript/server.d.ts +98 -0
- package/build/typescript/server.d.ts.map +1 -0
- package/build/typescript/shared/browserslist.d.ts +20 -3
- package/build/typescript/shared/browserslist.d.ts.map +1 -1
- package/build/typescript/shared/path.d.ts +2 -0
- package/build/typescript/shared/path.d.ts.map +1 -0
- package/build/typescript/shared/rollup.d.ts +27 -1
- package/build/typescript/shared/rollup.d.ts.map +1 -1
- package/configuration/rollup.config.js +40 -0
- package/package.json +61 -8
- package/source/app.ts +472 -109
- package/source/features/assets.ts +5 -7
- package/source/features/async.ts +249 -0
- package/source/features/css.ts +4 -2
- package/source/features/env.ts +6 -0
- package/source/features/esnext.ts +70 -0
- package/source/features/graphql.ts +4 -2
- package/source/features/source-code.ts +26 -8
- package/source/features/workers.ts +292 -0
- package/source/index.ts +4 -0
- package/source/module.ts +45 -19
- package/source/package.ts +394 -36
- package/source/server.ts +245 -0
- package/source/shared/browserslist.ts +208 -18
- package/source/shared/path.ts +5 -0
- package/source/shared/rollup.ts +102 -4
- package/tsconfig.json +6 -2
- package/build/cjs/app.cjs +0 -456
- package/build/cjs/constants.cjs +0 -13
- package/build/cjs/features/assets.cjs +0 -240
- package/build/cjs/features/css.cjs +0 -71
- package/build/cjs/features/env.cjs +0 -135
- package/build/cjs/features/graphql/transform.cjs +0 -186
- package/build/cjs/features/graphql.cjs +0 -86
- package/build/cjs/features/request-router.cjs +0 -31
- package/build/cjs/features/source-code.cjs +0 -54
- package/build/cjs/features/system-js.cjs +0 -36
- package/build/cjs/features/typescript.cjs +0 -56
- package/build/cjs/index.cjs +0 -13
- package/build/cjs/module.cjs +0 -121
- package/build/cjs/package.cjs +0 -170
- package/build/cjs/shared/browserslist.cjs +0 -25
- package/build/cjs/shared/magic-module.cjs +0 -32
- package/build/cjs/shared/package-json.cjs +0 -31
- package/build/cjs/shared/rollup.cjs +0 -72
- package/build/cjs/shared/strings.cjs +0 -16
- package/build/esnext/app.esnext +0 -429
- package/build/esnext/constants.esnext +0 -7
- package/build/esnext/features/assets.esnext +0 -215
- package/build/esnext/features/css.esnext +0 -69
- package/build/esnext/features/env.esnext +0 -112
- package/build/esnext/features/graphql/transform.esnext +0 -181
- package/build/esnext/features/graphql.esnext +0 -84
- package/build/esnext/features/request-router.esnext +0 -29
- package/build/esnext/features/source-code.esnext +0 -51
- package/build/esnext/features/system-js.esnext +0 -33
- package/build/esnext/features/typescript.esnext +0 -34
- package/build/esnext/index.esnext +0 -3
- package/build/esnext/module.esnext +0 -100
- package/build/esnext/package.esnext +0 -148
- package/build/esnext/shared/browserslist.esnext +0 -23
- package/build/esnext/shared/magic-module.esnext +0 -30
- package/build/esnext/shared/package-json.esnext +0 -10
- package/build/esnext/shared/rollup.esnext +0 -49
- package/build/esnext/shared/strings.esnext +0 -14
- package/build/typescript/env.d.ts +0 -55
- package/build/typescript/env.d.ts.map +0 -1
- package/build/typescript/graphql/transform.d.ts +0 -17
- package/build/typescript/graphql/transform.d.ts.map +0 -1
- package/build/typescript/graphql.d.ts +0 -6
- package/build/typescript/graphql.d.ts.map +0 -1
- package/build/typescript/request-router.d.ts +0 -15
- package/build/typescript/request-router.d.ts.map +0 -1
- package/build/typescript/shared/source-code.d.ts +0 -5
- package/build/typescript/shared/source-code.d.ts.map +0 -1
- package/quilt.project.ts +0 -5
|
@@ -6,9 +6,9 @@ import { smartReplace } from '../shared/rollup.mjs';
|
|
|
6
6
|
import { createMagicModulePlugin } from '../shared/magic-module.mjs';
|
|
7
7
|
|
|
8
8
|
const EMPTY_PROCESS_ENV_OBJECT = {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
"globalThis.process.env.": `({}).`,
|
|
10
|
+
"global.process.env.": `({}).`,
|
|
11
|
+
"process.env.": `({}).`
|
|
12
12
|
};
|
|
13
13
|
function replaceProcessEnv({
|
|
14
14
|
mode,
|
|
@@ -16,37 +16,37 @@ function replaceProcessEnv({
|
|
|
16
16
|
}) {
|
|
17
17
|
return smartReplace({
|
|
18
18
|
// @see https://github.com/vitejs/vite/blob/2b1ffe86328f9d06ef9528ee117b61889893ddcc/packages/vite/src/node/plugins/define.ts#L112
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
...
|
|
19
|
+
"globalThis.process.env.NODE_ENV": JSON.stringify(mode),
|
|
20
|
+
"global.process.env.NODE_ENV": JSON.stringify(mode),
|
|
21
|
+
"process.env.NODE_ENV": JSON.stringify(mode),
|
|
22
|
+
...preserve ? {} : EMPTY_PROCESS_ENV_OBJECT
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
|
+
function resolveEnvOption(option) {
|
|
26
|
+
return typeof option === "string" ? { mode: option } : option ?? {};
|
|
27
|
+
}
|
|
25
28
|
function magicModuleEnv({
|
|
26
29
|
mode,
|
|
27
|
-
dotenv = {
|
|
28
|
-
roots: ['.', 'configuration']
|
|
29
|
-
},
|
|
30
|
+
dotenv = { roots: [".", "configuration"] },
|
|
30
31
|
inline = [],
|
|
31
|
-
runtime =
|
|
32
|
+
runtime = "{}"
|
|
32
33
|
} = {}) {
|
|
33
34
|
return createMagicModulePlugin({
|
|
34
|
-
name:
|
|
35
|
+
name: "@quilted/magic-module/env",
|
|
35
36
|
module: MAGIC_MODULE_ENV,
|
|
36
37
|
async source() {
|
|
37
38
|
const inlineEnv = {};
|
|
38
39
|
if (mode) {
|
|
39
40
|
inlineEnv.MODE = mode;
|
|
40
41
|
}
|
|
41
|
-
const loadedEnv = await loadEnv.call(this, {
|
|
42
|
-
mode,
|
|
43
|
-
dotenv
|
|
44
|
-
});
|
|
42
|
+
const loadedEnv = await loadEnv.call(this, { mode, dotenv });
|
|
45
43
|
for (const inlineVariable of inline.sort()) {
|
|
46
|
-
if (inlineVariable in inlineEnv)
|
|
44
|
+
if (inlineVariable in inlineEnv)
|
|
45
|
+
continue;
|
|
47
46
|
const value = process.env[inlineVariable] ?? loadedEnv[inlineVariable];
|
|
48
|
-
if (value == null)
|
|
49
|
-
|
|
47
|
+
if (value == null)
|
|
48
|
+
continue;
|
|
49
|
+
inlineEnv[inlineVariable] = typeof value === "string" && value[0] === '"' && value[value.length - 1] === '"' ? JSON.parse(value) : value;
|
|
50
50
|
}
|
|
51
51
|
return multiline`
|
|
52
52
|
const runtime = (${runtime});
|
|
@@ -66,47 +66,50 @@ function magicModuleEnv({
|
|
|
66
66
|
}
|
|
67
67
|
});
|
|
68
68
|
}
|
|
69
|
-
|
|
70
|
-
// Inspired by https://github.com/vitejs/vite/blob/e0a4d810598d1834933ed437ac5a2168cbbbf2f8/packages/vite/source/node/config.ts#L1050-L1113
|
|
71
69
|
async function loadEnv({
|
|
72
70
|
mode,
|
|
73
71
|
dotenv
|
|
74
72
|
}) {
|
|
75
|
-
const env = {
|
|
76
|
-
...process.env
|
|
77
|
-
};
|
|
73
|
+
const env = { ...process.env };
|
|
78
74
|
if (dotenv !== false) {
|
|
79
|
-
const {
|
|
80
|
-
parse
|
|
81
|
-
} = await import('dotenv');
|
|
75
|
+
const { parse } = await import('dotenv');
|
|
82
76
|
let files = dotenv.files;
|
|
83
77
|
if (files == null) {
|
|
84
78
|
const testFiles = [
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
79
|
+
// default file
|
|
80
|
+
`.env`,
|
|
81
|
+
// local file
|
|
82
|
+
`.env.local`
|
|
83
|
+
];
|
|
89
84
|
if (mode) {
|
|
90
85
|
testFiles.push(
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
86
|
+
// mode file
|
|
87
|
+
`.env.${mode}`,
|
|
88
|
+
// mode local file
|
|
89
|
+
`.env.${mode}.local`
|
|
90
|
+
);
|
|
95
91
|
}
|
|
96
|
-
files = testFiles.flatMap(
|
|
92
|
+
files = testFiles.flatMap(
|
|
93
|
+
(file) => (dotenv.roots ?? [".", "configuration"]).map(
|
|
94
|
+
(root) => path.resolve(root, file)
|
|
95
|
+
)
|
|
96
|
+
);
|
|
97
97
|
}
|
|
98
|
-
const envFileResults = await Promise.all(
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
98
|
+
const envFileResults = await Promise.all(
|
|
99
|
+
files.map(async (file) => {
|
|
100
|
+
if (fs.existsSync(file)) {
|
|
101
|
+
this.addWatchFile(file);
|
|
102
|
+
return parse(await fs.promises.readFile(file, "utf-8"));
|
|
103
|
+
}
|
|
104
|
+
})
|
|
105
|
+
);
|
|
104
106
|
for (const envFileResult of envFileResults) {
|
|
105
|
-
if (envFileResult == null)
|
|
107
|
+
if (envFileResult == null)
|
|
108
|
+
continue;
|
|
106
109
|
Object.assign(env, envFileResult);
|
|
107
110
|
}
|
|
108
111
|
}
|
|
109
112
|
return env;
|
|
110
113
|
}
|
|
111
114
|
|
|
112
|
-
export { magicModuleEnv, replaceProcessEnv };
|
|
115
|
+
export { magicModuleEnv, replaceProcessEnv, resolveEnvOption };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
import babel from '@rollup/plugin-babel';
|
|
3
|
+
import esbuild from 'rollup-plugin-esbuild';
|
|
4
|
+
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
function esnext({
|
|
7
|
+
mode,
|
|
8
|
+
targets,
|
|
9
|
+
babel: useBabel = true
|
|
10
|
+
}) {
|
|
11
|
+
if (!useBabel) {
|
|
12
|
+
return esbuild({
|
|
13
|
+
// Support very modern features
|
|
14
|
+
include: /\.esnext$/,
|
|
15
|
+
target: "es2022",
|
|
16
|
+
loaders: {
|
|
17
|
+
".esnext": "js"
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
let babelOptions = {
|
|
22
|
+
envName: mode,
|
|
23
|
+
configFile: false,
|
|
24
|
+
babelrc: false,
|
|
25
|
+
presets: [
|
|
26
|
+
[
|
|
27
|
+
require.resolve("@babel/preset-env"),
|
|
28
|
+
{
|
|
29
|
+
useBuiltIns: false,
|
|
30
|
+
bugfixes: true,
|
|
31
|
+
shippedProposals: true
|
|
32
|
+
// I thought I wanted this, but it seems to break the `targets` option
|
|
33
|
+
// passed as a root argument.
|
|
34
|
+
// ignoreBrowserslistConfig: targets != null,
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
],
|
|
38
|
+
plugins: [
|
|
39
|
+
[
|
|
40
|
+
require.resolve("@babel/plugin-proposal-decorators"),
|
|
41
|
+
{ version: "2023-01" }
|
|
42
|
+
]
|
|
43
|
+
],
|
|
44
|
+
include: /\.esnext$/,
|
|
45
|
+
extensions: [".esnext"],
|
|
46
|
+
babelHelpers: "bundled",
|
|
47
|
+
skipPreflightCheck: true,
|
|
48
|
+
// Babel doesn’t like this option being set to `undefined`.
|
|
49
|
+
...targets ? { targets } : {}
|
|
50
|
+
};
|
|
51
|
+
if (typeof useBabel === "object") {
|
|
52
|
+
babelOptions = useBabel.options?.(babelOptions) ?? babelOptions;
|
|
53
|
+
}
|
|
54
|
+
return babel(babelOptions);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export { esnext };
|
|
@@ -2,13 +2,11 @@ import { createHash } from 'node:crypto';
|
|
|
2
2
|
import { print, parse } from 'graphql';
|
|
3
3
|
|
|
4
4
|
const IMPORT_REGEX = /^#import\s+['"]([^'"]*)['"];?[\s\n]*/gm;
|
|
5
|
-
const DEFAULT_NAME =
|
|
6
|
-
function cleanGraphQLDocument(document, {
|
|
7
|
-
removeUnused = true
|
|
8
|
-
} = {}) {
|
|
5
|
+
const DEFAULT_NAME = "Operation";
|
|
6
|
+
function cleanGraphQLDocument(document, { removeUnused = true } = {}) {
|
|
9
7
|
if (removeUnused) {
|
|
10
8
|
removeUnusedDefinitions(document, {
|
|
11
|
-
exclude: removeUnused === true ? new Set() : removeUnused.exclude
|
|
9
|
+
exclude: removeUnused === true ? /* @__PURE__ */ new Set() : removeUnused.exclude
|
|
12
10
|
});
|
|
13
11
|
}
|
|
14
12
|
for (const definition of document.definitions) {
|
|
@@ -19,18 +17,14 @@ function cleanGraphQLDocument(document, {
|
|
|
19
17
|
for (const definition of normalizedDocument.definitions) {
|
|
20
18
|
stripLoc(definition);
|
|
21
19
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
// including other documents that are injected in, but excluding any unused
|
|
25
|
-
// fragments. This is useful for things like persisted queries.
|
|
26
|
-
const id = createHash('sha256').update(normalizedSource).digest('hex');
|
|
27
|
-
Reflect.defineProperty(normalizedDocument, 'id', {
|
|
20
|
+
const id = createHash("sha256").update(normalizedSource).digest("hex");
|
|
21
|
+
Reflect.defineProperty(normalizedDocument, "id", {
|
|
28
22
|
value: id,
|
|
29
23
|
enumerable: true,
|
|
30
24
|
writable: false,
|
|
31
25
|
configurable: false
|
|
32
26
|
});
|
|
33
|
-
Reflect.defineProperty(normalizedDocument,
|
|
27
|
+
Reflect.defineProperty(normalizedDocument, "loc", {
|
|
34
28
|
value: stripDocumentLoc(normalizedDocument.loc),
|
|
35
29
|
enumerable: true,
|
|
36
30
|
writable: false,
|
|
@@ -39,18 +33,15 @@ function cleanGraphQLDocument(document, {
|
|
|
39
33
|
return normalizedDocument;
|
|
40
34
|
}
|
|
41
35
|
function extractGraphQLImports(rawSource) {
|
|
42
|
-
const imports = new Set();
|
|
36
|
+
const imports = /* @__PURE__ */ new Set();
|
|
43
37
|
const source = rawSource.replace(IMPORT_REGEX, (_, imported) => {
|
|
44
38
|
imports.add(imported);
|
|
45
|
-
return
|
|
39
|
+
return "";
|
|
46
40
|
});
|
|
47
|
-
return {
|
|
48
|
-
imports: [...imports],
|
|
49
|
-
source
|
|
50
|
-
};
|
|
41
|
+
return { imports: [...imports], source };
|
|
51
42
|
}
|
|
52
43
|
function toGraphQLOperation(documentOrSource) {
|
|
53
|
-
const document = typeof documentOrSource ===
|
|
44
|
+
const document = typeof documentOrSource === "string" ? cleanGraphQLDocument(parse(documentOrSource)) : documentOrSource;
|
|
54
45
|
return {
|
|
55
46
|
id: document.id,
|
|
56
47
|
name: operationNameForDocument(document),
|
|
@@ -58,14 +49,14 @@ function toGraphQLOperation(documentOrSource) {
|
|
|
58
49
|
};
|
|
59
50
|
}
|
|
60
51
|
function operationNameForDocument(document) {
|
|
61
|
-
return document.definitions.find(
|
|
52
|
+
return document.definitions.find(
|
|
53
|
+
(definition) => definition.kind === "OperationDefinition"
|
|
54
|
+
)?.name?.value;
|
|
62
55
|
}
|
|
63
|
-
function removeUnusedDefinitions(document, {
|
|
64
|
-
|
|
65
|
-
}) {
|
|
66
|
-
const usedDefinitions = new Set();
|
|
56
|
+
function removeUnusedDefinitions(document, { exclude }) {
|
|
57
|
+
const usedDefinitions = /* @__PURE__ */ new Set();
|
|
67
58
|
const dependencies = definitionDependencies(document.definitions);
|
|
68
|
-
const markAsUsed = definition => {
|
|
59
|
+
const markAsUsed = (definition) => {
|
|
69
60
|
if (usedDefinitions.has(definition)) {
|
|
70
61
|
return;
|
|
71
62
|
}
|
|
@@ -75,7 +66,7 @@ function removeUnusedDefinitions(document, {
|
|
|
75
66
|
}
|
|
76
67
|
};
|
|
77
68
|
for (const definition of document.definitions) {
|
|
78
|
-
if (definition.kind ===
|
|
69
|
+
if (definition.kind === "FragmentDefinition") {
|
|
79
70
|
if (exclude.has(definition.name.value)) {
|
|
80
71
|
markAsUsed(definition);
|
|
81
72
|
}
|
|
@@ -86,29 +77,44 @@ function removeUnusedDefinitions(document, {
|
|
|
86
77
|
document.definitions = [...usedDefinitions];
|
|
87
78
|
}
|
|
88
79
|
function definitionDependencies(definitions) {
|
|
89
|
-
const executableDefinitions = definitions.filter(
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
80
|
+
const executableDefinitions = definitions.filter(
|
|
81
|
+
(definition) => definition.kind === "OperationDefinition" || definition.kind === "FragmentDefinition"
|
|
82
|
+
);
|
|
83
|
+
const definitionsByName = new Map(
|
|
84
|
+
executableDefinitions.map((definition) => [
|
|
85
|
+
definition.name ? definition.name.value : DEFAULT_NAME,
|
|
86
|
+
definition
|
|
87
|
+
])
|
|
88
|
+
);
|
|
89
|
+
return new Map(
|
|
90
|
+
executableDefinitions.map(
|
|
91
|
+
(executableNode) => [
|
|
92
|
+
executableNode,
|
|
93
|
+
[...collectUsedFragmentSpreads(executableNode, /* @__PURE__ */ new Set())].map(
|
|
94
|
+
(usedFragment) => {
|
|
95
|
+
const definition = definitionsByName.get(usedFragment);
|
|
96
|
+
if (definition == null) {
|
|
97
|
+
throw new Error(
|
|
98
|
+
`You attempted to use the fragment '${usedFragment}' (in '${executableNode.name ? executableNode.name.value : DEFAULT_NAME}'), but it does not exist. Maybe you forgot to import it from another document?`
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
return definition;
|
|
102
|
+
}
|
|
103
|
+
)
|
|
104
|
+
]
|
|
105
|
+
)
|
|
106
|
+
);
|
|
98
107
|
}
|
|
99
108
|
const TYPENAME_FIELD = {
|
|
100
|
-
kind:
|
|
109
|
+
kind: "Field",
|
|
101
110
|
alias: null,
|
|
102
|
-
name: {
|
|
103
|
-
kind: 'Name',
|
|
104
|
-
value: '__typename'
|
|
105
|
-
}
|
|
111
|
+
name: { kind: "Name", value: "__typename" }
|
|
106
112
|
};
|
|
107
113
|
function addTypename(definition) {
|
|
108
|
-
for (const {
|
|
109
|
-
selections
|
|
110
|
-
|
|
111
|
-
|
|
114
|
+
for (const { selections } of selectionSetsForDefinition(definition)) {
|
|
115
|
+
const hasTypename = selections.some(
|
|
116
|
+
(selection) => selection.kind === "Field" && selection.name.value === "__typename"
|
|
117
|
+
);
|
|
112
118
|
if (!hasTypename) {
|
|
113
119
|
selections.push(TYPENAME_FIELD);
|
|
114
120
|
}
|
|
@@ -116,27 +122,27 @@ function addTypename(definition) {
|
|
|
116
122
|
}
|
|
117
123
|
function collectUsedFragmentSpreads(definition, usedSpreads) {
|
|
118
124
|
for (const selection of selectionsForDefinition(definition)) {
|
|
119
|
-
if (selection.kind ===
|
|
125
|
+
if (selection.kind === "FragmentSpread") {
|
|
120
126
|
usedSpreads.add(selection.name.value);
|
|
121
127
|
}
|
|
122
128
|
}
|
|
123
129
|
return usedSpreads;
|
|
124
130
|
}
|
|
125
131
|
function selectionsForDefinition(definition) {
|
|
126
|
-
if (!(
|
|
132
|
+
if (!("selectionSet" in definition) || definition.selectionSet == null) {
|
|
127
133
|
return [][Symbol.iterator]();
|
|
128
134
|
}
|
|
129
135
|
return selectionsForSelectionSet(definition.selectionSet);
|
|
130
136
|
}
|
|
131
137
|
function* selectionSetsForDefinition(definition) {
|
|
132
|
-
if (!(
|
|
138
|
+
if (!("selectionSet" in definition) || definition.selectionSet == null) {
|
|
133
139
|
return [][Symbol.iterator]();
|
|
134
140
|
}
|
|
135
|
-
if (definition.kind !==
|
|
141
|
+
if (definition.kind !== "OperationDefinition") {
|
|
136
142
|
yield definition.selectionSet;
|
|
137
143
|
}
|
|
138
144
|
for (const nestedSelection of selectionsForDefinition(definition)) {
|
|
139
|
-
if (
|
|
145
|
+
if ("selectionSet" in nestedSelection && nestedSelection.selectionSet != null) {
|
|
140
146
|
yield nestedSelection.selectionSet;
|
|
141
147
|
}
|
|
142
148
|
}
|
|
@@ -146,15 +152,13 @@ function* selectionsForSelectionSet({
|
|
|
146
152
|
}) {
|
|
147
153
|
for (const selection of selections) {
|
|
148
154
|
yield selection;
|
|
149
|
-
if (
|
|
155
|
+
if ("selectionSet" in selection && selection.selectionSet != null) {
|
|
150
156
|
yield* selectionsForSelectionSet(selection.selectionSet);
|
|
151
157
|
}
|
|
152
158
|
}
|
|
153
159
|
}
|
|
154
160
|
function stripDocumentLoc(loc) {
|
|
155
|
-
const normalizedLoc = {
|
|
156
|
-
...loc
|
|
157
|
-
};
|
|
161
|
+
const normalizedLoc = { ...loc };
|
|
158
162
|
delete normalizedLoc.endToken;
|
|
159
163
|
delete normalizedLoc.startToken;
|
|
160
164
|
return normalizedLoc;
|
|
@@ -162,11 +166,11 @@ function stripDocumentLoc(loc) {
|
|
|
162
166
|
function stripLoc(value) {
|
|
163
167
|
if (Array.isArray(value)) {
|
|
164
168
|
value.forEach(stripLoc);
|
|
165
|
-
} else if (typeof value ===
|
|
169
|
+
} else if (typeof value === "object") {
|
|
166
170
|
if (value == null) {
|
|
167
171
|
return;
|
|
168
172
|
}
|
|
169
|
-
if (
|
|
173
|
+
if ("loc" in value) {
|
|
170
174
|
delete value.loc;
|
|
171
175
|
}
|
|
172
176
|
for (const key of Object.keys(value)) {
|
|
@@ -175,7 +179,7 @@ function stripLoc(value) {
|
|
|
175
179
|
}
|
|
176
180
|
}
|
|
177
181
|
function minifyGraphQLSource(source) {
|
|
178
|
-
return source.replace(/#.*/g,
|
|
182
|
+
return source.replace(/#.*/g, "").replace(/\\n/g, " ").replace(/\s\s+/g, " ").replace(/\s*({|}|\(|\)|\.|:|,)\s*/g, "$1");
|
|
179
183
|
}
|
|
180
184
|
|
|
181
185
|
export { cleanGraphQLDocument, extractGraphQLImports, minifyGraphQLSource, toGraphQLOperation };
|
|
@@ -3,79 +3,97 @@ import { mkdir, writeFile, readFile } from 'node:fs/promises';
|
|
|
3
3
|
import { parse } from 'graphql';
|
|
4
4
|
import { toGraphQLOperation, cleanGraphQLDocument, extractGraphQLImports } from './graphql/transform.mjs';
|
|
5
5
|
|
|
6
|
-
function graphql({
|
|
7
|
-
manifest
|
|
8
|
-
} = {}) {
|
|
6
|
+
function graphql({ manifest } = {}) {
|
|
9
7
|
const shouldWriteManifest = Boolean(manifest);
|
|
10
|
-
const manifestPath = typeof manifest ===
|
|
8
|
+
const manifestPath = typeof manifest === "string" ? manifest : `manifests/graphql.json`;
|
|
11
9
|
return {
|
|
12
|
-
name:
|
|
10
|
+
name: "@quilted/graphql",
|
|
13
11
|
async transform(code, id) {
|
|
14
|
-
if (!id.endsWith(
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
if (!id.endsWith(".graphql") && !id.endsWith(".gql"))
|
|
13
|
+
return null;
|
|
14
|
+
const topLevelDefinitions = /* @__PURE__ */ new Set();
|
|
15
|
+
const loadedDocument = await loadDocument(
|
|
16
|
+
code,
|
|
17
|
+
id,
|
|
18
|
+
this,
|
|
19
|
+
(document2, level) => {
|
|
20
|
+
if (level !== 0)
|
|
21
|
+
return;
|
|
22
|
+
for (const definition of document2.definitions) {
|
|
23
|
+
if ("name" in definition && definition.name != null) {
|
|
24
|
+
topLevelDefinitions.add(definition.name.value);
|
|
25
|
+
}
|
|
21
26
|
}
|
|
22
27
|
}
|
|
23
|
-
|
|
24
|
-
const document = toGraphQLOperation(
|
|
25
|
-
|
|
26
|
-
exclude: topLevelDefinitions
|
|
27
|
-
}
|
|
28
|
-
|
|
28
|
+
);
|
|
29
|
+
const document = toGraphQLOperation(
|
|
30
|
+
cleanGraphQLDocument(loadedDocument, {
|
|
31
|
+
removeUnused: { exclude: topLevelDefinitions }
|
|
32
|
+
})
|
|
33
|
+
);
|
|
29
34
|
return {
|
|
30
|
-
code: `export default JSON.parse(${JSON.stringify(
|
|
35
|
+
code: `export default JSON.parse(${JSON.stringify(
|
|
36
|
+
JSON.stringify(document)
|
|
37
|
+
)})`,
|
|
31
38
|
meta: shouldWriteManifest ? {
|
|
32
|
-
quilt: {
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
} : undefined
|
|
39
|
+
quilt: { graphql: document }
|
|
40
|
+
} : void 0
|
|
36
41
|
};
|
|
37
42
|
},
|
|
38
43
|
async generateBundle() {
|
|
39
|
-
if (!shouldWriteManifest)
|
|
44
|
+
if (!shouldWriteManifest)
|
|
45
|
+
return;
|
|
40
46
|
const operations = {};
|
|
41
47
|
for (const moduleId of this.getModuleIds()) {
|
|
42
48
|
const operation = this.getModuleInfo(moduleId)?.meta?.quilt?.graphql;
|
|
43
|
-
if (operation != null && typeof operation.id ===
|
|
49
|
+
if (operation != null && typeof operation.id === "string" && typeof operation.source === "string") {
|
|
44
50
|
operations[operation.id] = operation.source;
|
|
45
51
|
}
|
|
46
52
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
});
|
|
53
|
+
if (Object.keys(operations).length === 0)
|
|
54
|
+
return;
|
|
55
|
+
await mkdir(dirname(manifestPath), { recursive: true });
|
|
50
56
|
await writeFile(manifestPath, JSON.stringify(operations, null, 2));
|
|
51
57
|
}
|
|
52
58
|
};
|
|
53
59
|
}
|
|
54
|
-
async function loadDocument(code, file, plugin, add, level = 0, seen = new Set()) {
|
|
55
|
-
const {
|
|
56
|
-
imports,
|
|
57
|
-
source
|
|
58
|
-
} = extractGraphQLImports(code);
|
|
60
|
+
async function loadDocument(code, file, plugin, add, level = 0, seen = /* @__PURE__ */ new Set()) {
|
|
61
|
+
const { imports, source } = extractGraphQLImports(code);
|
|
59
62
|
const document = parse(source);
|
|
60
63
|
add?.(document, level);
|
|
61
64
|
if (imports.length === 0) {
|
|
62
65
|
return document;
|
|
63
66
|
}
|
|
64
|
-
const resolvedImports = await Promise.all(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
67
|
+
const resolvedImports = await Promise.all(
|
|
68
|
+
imports.map(async (imported) => {
|
|
69
|
+
if (seen.has(imported))
|
|
70
|
+
return;
|
|
71
|
+
seen.add(imported);
|
|
72
|
+
const resolvedId = await plugin.resolve(imported, file);
|
|
73
|
+
if (resolvedId == null) {
|
|
74
|
+
throw new Error(
|
|
75
|
+
`Could not find ${JSON.stringify(imported)} from ${JSON.stringify(
|
|
76
|
+
file
|
|
77
|
+
)}`
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
plugin.addWatchFile(resolvedId.id);
|
|
81
|
+
const contents = await readFile(resolvedId.id, {
|
|
82
|
+
encoding: "utf8"
|
|
83
|
+
});
|
|
84
|
+
return loadDocument(
|
|
85
|
+
contents,
|
|
86
|
+
resolvedId.id,
|
|
87
|
+
plugin,
|
|
88
|
+
add,
|
|
89
|
+
level + 1,
|
|
90
|
+
seen
|
|
91
|
+
);
|
|
92
|
+
})
|
|
93
|
+
);
|
|
77
94
|
for (const importedDocument of resolvedImports) {
|
|
78
|
-
if (importedDocument == null)
|
|
95
|
+
if (importedDocument == null)
|
|
96
|
+
continue;
|
|
79
97
|
document.definitions.push(...importedDocument.definitions);
|
|
80
98
|
}
|
|
81
99
|
return document;
|
|
@@ -7,17 +7,19 @@ function magicModuleRequestRouterEntry({
|
|
|
7
7
|
port
|
|
8
8
|
} = {}) {
|
|
9
9
|
return createMagicModulePlugin({
|
|
10
|
-
name:
|
|
10
|
+
name: "@quilted/request-router",
|
|
11
11
|
sideEffects: true,
|
|
12
12
|
module: MAGIC_MODULE_ENTRY,
|
|
13
13
|
async source() {
|
|
14
14
|
const initialContent = multiline`
|
|
15
|
-
import requestRouter from ${JSON.stringify(
|
|
15
|
+
import requestRouter from ${JSON.stringify(
|
|
16
|
+
MAGIC_MODULE_REQUEST_ROUTER
|
|
17
|
+
)};
|
|
16
18
|
|
|
17
19
|
import {createHttpServer} from '@quilted/quilt/request-router/node';
|
|
18
20
|
|
|
19
|
-
const port = ${port ??
|
|
20
|
-
const host = ${host ? JSON.stringify(host) :
|
|
21
|
+
const port = ${port ?? "Number.parseInt(process.env.PORT, 10)"};
|
|
22
|
+
const host = ${host ? JSON.stringify(host) : "process.env.HOST"};
|
|
21
23
|
|
|
22
24
|
createHttpServer(requestRouter).listen(port, host);
|
|
23
25
|
`;
|