@cedarjs/internal 8.0.0-canary.3587 → 8.0.0-canary.3589
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/generate/graphqlCodeGen.d.ts.map +1 -1
- package/dist/generate/graphqlCodeGen.js +5 -1
- package/dist/generate/serviceFieldResolvers.d.ts +33 -0
- package/dist/generate/serviceFieldResolvers.d.ts.map +1 -0
- package/dist/generate/serviceFieldResolvers.js +85 -0
- package/dist/generate/watch.js +26 -0
- package/package.json +10 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphqlCodeGen.d.ts","sourceRoot":"","sources":["../../src/generate/graphqlCodeGen.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"graphqlCodeGen.d.ts","sourceRoot":"","sources":["../../src/generate/graphqlCodeGen.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAqB9D,KAAK,aAAa,GAAG;IACnB,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;CAC9C,CAAA;AAED,eAAO,MAAM,yBAAyB,QAAa,OAAO,CAAC,aAAa,CAiFvE,CAAA;AAED,eAAO,MAAM,yBAAyB,QAAa,OAAO,CAAC,aAAa,CA2DvE,CAAA;AAyFD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM;SACD,MAAM;GAQ5D;AAgRD,eAAO,MAAM,iBAAiB,4RAe7B,CAAA"}
|
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
import { getPackageManager } from "@cedarjs/project-config/packageManager";
|
|
21
21
|
import { getTsConfigs } from "../project.js";
|
|
22
22
|
import * as rwTypescriptResolvers from "./plugins/rw-typescript-resolvers/index.js";
|
|
23
|
+
import { getServiceFieldResolvers } from "./serviceFieldResolvers.js";
|
|
23
24
|
var CodegenSide = /* @__PURE__ */ ((CodegenSide2) => {
|
|
24
25
|
CodegenSide2[CodegenSide2["API"] = 0] = "API";
|
|
25
26
|
CodegenSide2[CodegenSide2["WEB"] = 1] = "WEB";
|
|
@@ -297,8 +298,11 @@ async function getPrismaModels() {
|
|
|
297
298
|
}
|
|
298
299
|
async function getPluginConfig(side) {
|
|
299
300
|
const prismaModels = await getPrismaModels();
|
|
301
|
+
const fieldResolvers = side === 0 /* API */ ? getServiceFieldResolvers() : {};
|
|
300
302
|
Object.keys(prismaModels).forEach((key) => {
|
|
301
|
-
|
|
303
|
+
const resolvedFields = fieldResolvers[key] ?? [];
|
|
304
|
+
const resolvedFieldsArg = resolvedFields.length ? `, ${resolvedFields.map((field) => JSON.stringify(field)).join(" | ")}` : "";
|
|
305
|
+
prismaModels[key] = `MergePrismaWithSdlTypes<Prisma${key}, MakeRelationsOptional<${key}, AllMappedModels>, AllMappedModels${resolvedFieldsArg}>`;
|
|
302
306
|
});
|
|
303
307
|
const scalars = {
|
|
304
308
|
// We need these, otherwise these scalars are mapped to any
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { types } from '@babel/core';
|
|
2
|
+
/**
|
|
3
|
+
* Field names, per GraphQL type, that services provide field resolvers for.
|
|
4
|
+
*
|
|
5
|
+
* Services provide field resolvers for a type by exporting an object named
|
|
6
|
+
* after the type, e.g. `export const Post = { author: (_args, { root }) => … }`.
|
|
7
|
+
* GraphQL server merges these exports from all services, so the field names
|
|
8
|
+
* here are merged the same way.
|
|
9
|
+
*/
|
|
10
|
+
export type ServiceFieldResolvers = Record<string, string[]>;
|
|
11
|
+
/**
|
|
12
|
+
* Whether GraphQL server loads this file as a service. This matches the
|
|
13
|
+
* filters of the `src/services/**\/*.{js,ts}` glob import, in both
|
|
14
|
+
* vite-plugin-cedar-import-dir and babel-plugin-redwood-import-dir, so field
|
|
15
|
+
* resolvers in files that aren't loaded don't affect the generated types.
|
|
16
|
+
*/
|
|
17
|
+
export declare const isLoadedServiceFile: (filePath: string) => boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Finds the field resolvers in a single service file.
|
|
20
|
+
*
|
|
21
|
+
* Only object literals exported directly (`export const Post = { … }`) are
|
|
22
|
+
* recognized. Keys that can't be determined statically, like spread or
|
|
23
|
+
* computed keys, are skipped. A skipped field stays required on resolver
|
|
24
|
+
* results, which is the safe side to err on.
|
|
25
|
+
*/
|
|
26
|
+
export declare const getFieldResolversFromAst: (ast: types.File) => ServiceFieldResolvers;
|
|
27
|
+
/**
|
|
28
|
+
* Finds the field resolvers that all the project's services provide, keyed by
|
|
29
|
+
* GraphQL type name. Field names are sorted and de-duplicated so the result
|
|
30
|
+
* is stable across runs.
|
|
31
|
+
*/
|
|
32
|
+
export declare const getServiceFieldResolvers: (serviceFiles?: string[]) => ServiceFieldResolvers;
|
|
33
|
+
//# sourceMappingURL=serviceFieldResolvers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceFieldResolvers.d.ts","sourceRoot":"","sources":["../../src/generate/serviceFieldResolvers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAMxC;;;;;;;GAOG;AACH,MAAM,MAAM,qBAAqB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;AAI5D;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,UAAU,MAAM,YAOnD,CAAA;AAyCD;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,GACnC,KAAK,KAAK,CAAC,IAAI,KACd,qBAwCF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GACnC,eAAc,MAAM,EAAuB,KAC1C,qBAkCF,CAAA"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { parse } from "@babel/parser";
|
|
3
|
+
import fg from "fast-glob";
|
|
4
|
+
import { getPaths } from "@cedarjs/project-config";
|
|
5
|
+
const ROOT_TYPES = ["Query", "Mutation", "Subscription"];
|
|
6
|
+
const isLoadedServiceFile = (filePath) => {
|
|
7
|
+
return /\.(js|ts)$/.test(filePath) && !filePath.includes(".test.") && !filePath.includes(".scenarios.") && !filePath.includes(".d.ts");
|
|
8
|
+
};
|
|
9
|
+
const findServiceFiles = (cwd = getPaths().api.services) => {
|
|
10
|
+
return fg.sync("**/*.{js,ts}", { cwd, absolute: true }).filter(isLoadedServiceFile);
|
|
11
|
+
};
|
|
12
|
+
const unwrapExpression = (node) => {
|
|
13
|
+
if (node.type === "TSSatisfiesExpression" || node.type === "TSAsExpression" || node.type === "TSNonNullExpression" || node.type === "ParenthesizedExpression") {
|
|
14
|
+
return unwrapExpression(node.expression);
|
|
15
|
+
}
|
|
16
|
+
return node;
|
|
17
|
+
};
|
|
18
|
+
const getPropertyName = (property) => {
|
|
19
|
+
if (property.type === "SpreadElement" || property.computed) {
|
|
20
|
+
return void 0;
|
|
21
|
+
}
|
|
22
|
+
if (property.key.type === "Identifier") {
|
|
23
|
+
return property.key.name;
|
|
24
|
+
}
|
|
25
|
+
if (property.key.type === "StringLiteral") {
|
|
26
|
+
return property.key.value;
|
|
27
|
+
}
|
|
28
|
+
return void 0;
|
|
29
|
+
};
|
|
30
|
+
const getFieldResolversFromAst = (ast) => {
|
|
31
|
+
const fieldResolvers = {};
|
|
32
|
+
for (const statement of ast.program.body) {
|
|
33
|
+
if (statement.type !== "ExportNamedDeclaration" || statement.declaration?.type !== "VariableDeclaration") {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
for (const declarator of statement.declaration.declarations) {
|
|
37
|
+
if (declarator.id.type !== "Identifier" || !declarator.init) {
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
const typeName = declarator.id.name;
|
|
41
|
+
if (ROOT_TYPES.includes(typeName)) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const init = unwrapExpression(declarator.init);
|
|
45
|
+
if (init.type !== "ObjectExpression") {
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
const fieldNames = init.properties.map(getPropertyName).filter((name) => name !== void 0);
|
|
49
|
+
fieldResolvers[typeName] = [
|
|
50
|
+
...fieldResolvers[typeName] ?? [],
|
|
51
|
+
...fieldNames
|
|
52
|
+
];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return fieldResolvers;
|
|
56
|
+
};
|
|
57
|
+
const getServiceFieldResolvers = (serviceFiles = findServiceFiles()) => {
|
|
58
|
+
const merged = {};
|
|
59
|
+
for (const file of serviceFiles) {
|
|
60
|
+
let ast;
|
|
61
|
+
try {
|
|
62
|
+
ast = parse(fs.readFileSync(file, "utf-8"), {
|
|
63
|
+
sourceType: "module",
|
|
64
|
+
plugins: ["typescript"]
|
|
65
|
+
});
|
|
66
|
+
} catch {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const fieldResolvers = getFieldResolversFromAst(ast);
|
|
70
|
+
for (const [typeName, fieldNames] of Object.entries(fieldResolvers)) {
|
|
71
|
+
merged[typeName] ??= /* @__PURE__ */ new Set();
|
|
72
|
+
for (const fieldName of fieldNames) {
|
|
73
|
+
merged[typeName].add(fieldName);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return Object.fromEntries(
|
|
78
|
+
Object.keys(merged).sort().map((typeName) => [typeName, [...merged[typeName]].sort()])
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
export {
|
|
82
|
+
getFieldResolversFromAst,
|
|
83
|
+
getServiceFieldResolvers,
|
|
84
|
+
isLoadedServiceFile
|
|
85
|
+
};
|
package/dist/generate/watch.js
CHANGED
|
@@ -20,6 +20,10 @@ import {
|
|
|
20
20
|
generateTypeDefGraphQLWeb
|
|
21
21
|
} from "./graphqlCodeGen.js";
|
|
22
22
|
import { generateGraphQLSchema } from "./graphqlSchema.js";
|
|
23
|
+
import {
|
|
24
|
+
getServiceFieldResolvers,
|
|
25
|
+
isLoadedServiceFile
|
|
26
|
+
} from "./serviceFieldResolvers.js";
|
|
23
27
|
import {
|
|
24
28
|
generateMirrorCell,
|
|
25
29
|
generateMirrorDirectoryNamedModule,
|
|
@@ -46,6 +50,10 @@ const action = {
|
|
|
46
50
|
change: "Modified"
|
|
47
51
|
};
|
|
48
52
|
let routesWarningMessage = "";
|
|
53
|
+
let serviceFieldResolvers = JSON.stringify(getServiceFieldResolvers());
|
|
54
|
+
const isServiceFile = (p) => {
|
|
55
|
+
return p.startsWith(rwjsPaths.api.services + path.sep) && isLoadedServiceFile(p);
|
|
56
|
+
};
|
|
49
57
|
process.stdin.on("data", async (data) => {
|
|
50
58
|
const str = data.toString().trim().toLowerCase();
|
|
51
59
|
if (str === "g" || str === "rs") {
|
|
@@ -118,6 +126,24 @@ Created ${files.length} in ${Date.now() - start} ms`);
|
|
|
118
126
|
await generateGqlormArtifacts();
|
|
119
127
|
finished("Prisma Schema");
|
|
120
128
|
}
|
|
129
|
+
if (isServiceFile(absPath)) {
|
|
130
|
+
const nextServiceFieldResolvers = JSON.stringify(
|
|
131
|
+
getServiceFieldResolvers()
|
|
132
|
+
);
|
|
133
|
+
if (nextServiceFieldResolvers !== serviceFieldResolvers) {
|
|
134
|
+
const { errors } = await generateTypeDefGraphQLApi();
|
|
135
|
+
if (errors.length > 0) {
|
|
136
|
+
for (const { message, error } of errors) {
|
|
137
|
+
console.error(message);
|
|
138
|
+
console.error(error);
|
|
139
|
+
console.log();
|
|
140
|
+
}
|
|
141
|
+
} else {
|
|
142
|
+
serviceFieldResolvers = nextServiceFieldResolvers;
|
|
143
|
+
finished("Service field resolvers");
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
121
147
|
if (routesWarningMessage) {
|
|
122
148
|
console.warn(routesWarningMessage);
|
|
123
149
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cedarjs/internal",
|
|
3
|
-
"version": "8.0.0-canary.
|
|
3
|
+
"version": "8.0.0-canary.3589",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/cedarjs/cedar.git",
|
|
@@ -126,14 +126,14 @@
|
|
|
126
126
|
"@babel/core": "^7.26.10",
|
|
127
127
|
"@babel/parser": "7.29.12",
|
|
128
128
|
"@babel/traverse": "7.29.12",
|
|
129
|
-
"@cedarjs/api": "8.0.0-canary.
|
|
130
|
-
"@cedarjs/babel-config": "8.0.0-canary.
|
|
131
|
-
"@cedarjs/cli-helpers": "8.0.0-canary.
|
|
132
|
-
"@cedarjs/graphql-server": "8.0.0-canary.
|
|
133
|
-
"@cedarjs/project-config": "8.0.0-canary.
|
|
134
|
-
"@cedarjs/router": "8.0.0-canary.
|
|
135
|
-
"@cedarjs/structure": "8.0.0-canary.
|
|
136
|
-
"@cedarjs/utils": "8.0.0-canary.
|
|
129
|
+
"@cedarjs/api": "8.0.0-canary.3589",
|
|
130
|
+
"@cedarjs/babel-config": "8.0.0-canary.3589",
|
|
131
|
+
"@cedarjs/cli-helpers": "8.0.0-canary.3589",
|
|
132
|
+
"@cedarjs/graphql-server": "8.0.0-canary.3589",
|
|
133
|
+
"@cedarjs/project-config": "8.0.0-canary.3589",
|
|
134
|
+
"@cedarjs/router": "8.0.0-canary.3589",
|
|
135
|
+
"@cedarjs/structure": "8.0.0-canary.3589",
|
|
136
|
+
"@cedarjs/utils": "8.0.0-canary.3589",
|
|
137
137
|
"@graphql-codegen/add": "6.0.1",
|
|
138
138
|
"@graphql-codegen/cli": "6.3.1",
|
|
139
139
|
"@graphql-codegen/client-preset": "5.3.0",
|
|
@@ -171,7 +171,7 @@
|
|
|
171
171
|
"vite-tsconfig-paths": "6.1.1"
|
|
172
172
|
},
|
|
173
173
|
"devDependencies": {
|
|
174
|
-
"@cedarjs/framework-tools": "8.0.0-canary.
|
|
174
|
+
"@cedarjs/framework-tools": "8.0.0-canary.3589",
|
|
175
175
|
"@jridgewell/trace-mapping": "0.3.31",
|
|
176
176
|
"@oxc-project/types": "^0.155.0",
|
|
177
177
|
"concurrently": "9.2.5",
|