@cedarjs/internal 4.2.0 → 4.2.1-next.258

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.
@@ -3,4 +3,5 @@ export declare const buildApi: () => Promise<import("esbuild").BuildResult<Build
3
3
  export declare const rebuildApi: () => Promise<import("esbuild").BuildResult<BuildOptions>>;
4
4
  export declare const cleanApiBuild: () => Promise<void>;
5
5
  export declare const buildApiWithVite: () => Promise<import("rollup").RollupOutput | import("rollup").RollupOutput[] | import("rollup").RollupWatcher>;
6
+ export declare function fixSourceMaps(distDir: string, srcDir: string): Promise<void>;
6
7
  //# sourceMappingURL=api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/build/api.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAgB,YAAY,EAAe,MAAM,SAAS,CAAA;AAetE,eAAO,MAAM,QAAQ,4DAIpB,CAAA;AAED,eAAO,MAAM,UAAU,4DAMtB,CAAA;AAED,eAAO,MAAM,aAAa,qBAGzB,CAAA;AAqED,eAAO,MAAM,gBAAgB,iHAiD5B,CAAA"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/build/api.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAgB,YAAY,EAAe,MAAM,SAAS,CAAA;AAetE,eAAO,MAAM,QAAQ,4DAIpB,CAAA;AAED,eAAO,MAAM,UAAU,4DAStB,CAAA;AAED,eAAO,MAAM,aAAa,qBAGzB,CAAA;AA0ED,eAAO,MAAM,gBAAgB,iHAqD5B,CAAA;AAcD,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAoDf"}
package/dist/build/api.js CHANGED
@@ -19,7 +19,10 @@ const rebuildApi = async () => {
19
19
  if (!BUILD_CTX) {
20
20
  BUILD_CTX = await context(getEsbuildOptions(apiFiles));
21
21
  }
22
- return BUILD_CTX.rebuild();
22
+ const result = await BUILD_CTX.rebuild();
23
+ const cedarPaths = getPaths();
24
+ await fixSourceMaps(cedarPaths.api.dist, cedarPaths.api.src);
25
+ return result;
23
26
  };
24
27
  const cleanApiBuild = async () => {
25
28
  const cedarPaths = getPaths();
@@ -30,7 +33,9 @@ const runCedarBabelTransformsPlugin = {
30
33
  setup(build2) {
31
34
  const cedarConfig = getConfig();
32
35
  build2.onLoad({ filter: /\.(js|ts|tsx|jsx)$/ }, async (args) => {
36
+ const fileContents = await fs.promises.readFile(args.path, "utf-8");
33
37
  const transformedCode = await transformWithBabel(
38
+ fileContents,
34
39
  args.path,
35
40
  getApiSideBabelPlugins({
36
41
  openTelemetry: cedarConfig.experimental.opentelemetry.enabled && cedarConfig.experimental.opentelemetry.wrapApi,
@@ -52,7 +57,8 @@ function createCedarViteApiPlugin() {
52
57
  const isEsm = projectSideIsEsm("api");
53
58
  return {
54
59
  name: "cedar-vite-api-babel-transform",
55
- async transform(_code, id) {
60
+ enforce: "pre",
61
+ async transform(code, id) {
56
62
  if (!/\.(js|ts|tsx|jsx)$/.test(id)) {
57
63
  return null;
58
64
  }
@@ -64,11 +70,13 @@ function createCedarViteApiPlugin() {
64
70
  return null;
65
71
  }
66
72
  const transformedCode = await transformWithBabel(
73
+ code,
67
74
  id,
68
75
  getApiSideBabelPlugins({
69
76
  openTelemetry: cedarConfig.experimental.opentelemetry.enabled && cedarConfig.experimental.opentelemetry.wrapApi,
70
77
  projectIsEsm: isEsm
71
- })
78
+ }),
79
+ true
72
80
  );
73
81
  if (transformedCode?.code) {
74
82
  return {
@@ -103,7 +111,11 @@ const buildApiWithVite = async () => {
103
111
  format,
104
112
  preserveModules: true,
105
113
  preserveModulesRoot: cedarPaths.api.src,
106
- entryFileNames: "[name].js"
114
+ entryFileNames: "[name].js",
115
+ // Directives (and other entry modules) intentionally use both named
116
+ // and default exports (e.g. `export const schema` + `export default`).
117
+ // Tell Rollup to expect this so it doesn't warn about mixed exports.
118
+ exports: "named"
107
119
  },
108
120
  external: (id) => {
109
121
  if (id.startsWith("node:")) {
@@ -120,8 +132,49 @@ const buildApiWithVite = async () => {
120
132
  });
121
133
  };
122
134
  const transpileApi = async (files) => {
123
- return build(getEsbuildOptions(files));
135
+ const result = await build(getEsbuildOptions(files));
136
+ const cedarPaths = getPaths();
137
+ await fixSourceMaps(cedarPaths.api.dist, cedarPaths.api.src);
138
+ return result;
124
139
  };
140
+ async function fixSourceMaps(distDir, srcDir) {
141
+ let entries;
142
+ try {
143
+ entries = await fs.promises.readdir(distDir, {
144
+ recursive: true,
145
+ withFileTypes: true
146
+ });
147
+ } catch {
148
+ return;
149
+ }
150
+ const mapFiles = entries.filter((e) => e.isFile() && e.name.endsWith(".js.map")).map((e) => path.join(e.parentPath ?? e.path, e.name));
151
+ await Promise.all(
152
+ mapFiles.map(async (mapFile) => {
153
+ try {
154
+ const raw = await fs.promises.readFile(mapFile, "utf8");
155
+ const map = JSON.parse(raw);
156
+ if (!Array.isArray(map.sources) || map.sources.length === 0) {
157
+ return;
158
+ }
159
+ const jsFile = mapFile.slice(0, -4);
160
+ const baseName = path.relative(distDir, jsFile).replace(/\.js$/, "");
161
+ const srcFile = [".ts", ".tsx", ".jsx", ".js"].map((ext) => path.join(srcDir, baseName + ext)).find((f) => fs.existsSync(f));
162
+ if (!srcFile) {
163
+ return;
164
+ }
165
+ const correctRelPath = normalizePath(
166
+ path.relative(path.dirname(mapFile), srcFile)
167
+ );
168
+ if (map.sources[0] === correctRelPath) {
169
+ return;
170
+ }
171
+ map.sources = [correctRelPath];
172
+ await fs.promises.writeFile(mapFile, JSON.stringify(map), "utf8");
173
+ } catch {
174
+ }
175
+ })
176
+ );
177
+ }
125
178
  function getEsbuildOptions(files) {
126
179
  const cedarPaths = getPaths();
127
180
  const format = projectSideIsEsm("api") ? "esm" : "cjs";
@@ -145,5 +198,6 @@ export {
145
198
  buildApi,
146
199
  buildApiWithVite,
147
200
  cleanApiBuild,
201
+ fixSourceMaps,
148
202
  rebuildApi
149
203
  };
@@ -3,4 +3,5 @@ export declare const buildApi: () => Promise<import("esbuild").BuildResult<Build
3
3
  export declare const rebuildApi: () => Promise<import("esbuild").BuildResult<BuildOptions>>;
4
4
  export declare const cleanApiBuild: () => Promise<void>;
5
5
  export declare const buildApiWithVite: () => Promise<import("rollup").RollupOutput | import("rollup").RollupOutput[] | import("rollup").RollupWatcher>;
6
+ export declare function fixSourceMaps(distDir: string, srcDir: string): Promise<void>;
6
7
  //# sourceMappingURL=api.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/build/api.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAgB,YAAY,EAAe,MAAM,SAAS,CAAA;AAetE,eAAO,MAAM,QAAQ,4DAIpB,CAAA;AAED,eAAO,MAAM,UAAU,4DAMtB,CAAA;AAED,eAAO,MAAM,aAAa,qBAGzB,CAAA;AAqED,eAAO,MAAM,gBAAgB,iHAiD5B,CAAA"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/build/api.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAgB,YAAY,EAAe,MAAM,SAAS,CAAA;AAetE,eAAO,MAAM,QAAQ,4DAIpB,CAAA;AAED,eAAO,MAAM,UAAU,4DAStB,CAAA;AAED,eAAO,MAAM,aAAa,qBAGzB,CAAA;AA0ED,eAAO,MAAM,gBAAgB,iHAqD5B,CAAA;AAcD,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAoDf"}
@@ -31,6 +31,7 @@ __export(api_exports, {
31
31
  buildApi: () => buildApi,
32
32
  buildApiWithVite: () => buildApiWithVite,
33
33
  cleanApiBuild: () => cleanApiBuild,
34
+ fixSourceMaps: () => fixSourceMaps,
34
35
  rebuildApi: () => rebuildApi
35
36
  });
36
37
  module.exports = __toCommonJS(api_exports);
@@ -52,7 +53,10 @@ const rebuildApi = async () => {
52
53
  if (!BUILD_CTX) {
53
54
  BUILD_CTX = await (0, import_esbuild.context)(getEsbuildOptions(apiFiles));
54
55
  }
55
- return BUILD_CTX.rebuild();
56
+ const result = await BUILD_CTX.rebuild();
57
+ const cedarPaths = (0, import_project_config.getPaths)();
58
+ await fixSourceMaps(cedarPaths.api.dist, cedarPaths.api.src);
59
+ return result;
56
60
  };
57
61
  const cleanApiBuild = async () => {
58
62
  const cedarPaths = (0, import_project_config.getPaths)();
@@ -63,7 +67,9 @@ const runCedarBabelTransformsPlugin = {
63
67
  setup(build2) {
64
68
  const cedarConfig = (0, import_project_config.getConfig)();
65
69
  build2.onLoad({ filter: /\.(js|ts|tsx|jsx)$/ }, async (args) => {
70
+ const fileContents = await import_node_fs.default.promises.readFile(args.path, "utf-8");
66
71
  const transformedCode = await (0, import_babel_config.transformWithBabel)(
72
+ fileContents,
67
73
  args.path,
68
74
  (0, import_babel_config.getApiSideBabelPlugins)({
69
75
  openTelemetry: cedarConfig.experimental.opentelemetry.enabled && cedarConfig.experimental.opentelemetry.wrapApi,
@@ -85,7 +91,8 @@ function createCedarViteApiPlugin() {
85
91
  const isEsm = (0, import_project_config.projectSideIsEsm)("api");
86
92
  return {
87
93
  name: "cedar-vite-api-babel-transform",
88
- async transform(_code, id) {
94
+ enforce: "pre",
95
+ async transform(code, id) {
89
96
  if (!/\.(js|ts|tsx|jsx)$/.test(id)) {
90
97
  return null;
91
98
  }
@@ -97,11 +104,13 @@ function createCedarViteApiPlugin() {
97
104
  return null;
98
105
  }
99
106
  const transformedCode = await (0, import_babel_config.transformWithBabel)(
107
+ code,
100
108
  id,
101
109
  (0, import_babel_config.getApiSideBabelPlugins)({
102
110
  openTelemetry: cedarConfig.experimental.opentelemetry.enabled && cedarConfig.experimental.opentelemetry.wrapApi,
103
111
  projectIsEsm: isEsm
104
- })
112
+ }),
113
+ true
105
114
  );
106
115
  if (transformedCode?.code) {
107
116
  return {
@@ -136,7 +145,11 @@ const buildApiWithVite = async () => {
136
145
  format,
137
146
  preserveModules: true,
138
147
  preserveModulesRoot: cedarPaths.api.src,
139
- entryFileNames: "[name].js"
148
+ entryFileNames: "[name].js",
149
+ // Directives (and other entry modules) intentionally use both named
150
+ // and default exports (e.g. `export const schema` + `export default`).
151
+ // Tell Rollup to expect this so it doesn't warn about mixed exports.
152
+ exports: "named"
140
153
  },
141
154
  external: (id) => {
142
155
  if (id.startsWith("node:")) {
@@ -153,8 +166,49 @@ const buildApiWithVite = async () => {
153
166
  });
154
167
  };
155
168
  const transpileApi = async (files) => {
156
- return (0, import_esbuild.build)(getEsbuildOptions(files));
169
+ const result = await (0, import_esbuild.build)(getEsbuildOptions(files));
170
+ const cedarPaths = (0, import_project_config.getPaths)();
171
+ await fixSourceMaps(cedarPaths.api.dist, cedarPaths.api.src);
172
+ return result;
157
173
  };
174
+ async function fixSourceMaps(distDir, srcDir) {
175
+ let entries;
176
+ try {
177
+ entries = await import_node_fs.default.promises.readdir(distDir, {
178
+ recursive: true,
179
+ withFileTypes: true
180
+ });
181
+ } catch {
182
+ return;
183
+ }
184
+ const mapFiles = entries.filter((e) => e.isFile() && e.name.endsWith(".js.map")).map((e) => import_node_path.default.join(e.parentPath ?? e.path, e.name));
185
+ await Promise.all(
186
+ mapFiles.map(async (mapFile) => {
187
+ try {
188
+ const raw = await import_node_fs.default.promises.readFile(mapFile, "utf8");
189
+ const map = JSON.parse(raw);
190
+ if (!Array.isArray(map.sources) || map.sources.length === 0) {
191
+ return;
192
+ }
193
+ const jsFile = mapFile.slice(0, -4);
194
+ const baseName = import_node_path.default.relative(distDir, jsFile).replace(/\.js$/, "");
195
+ const srcFile = [".ts", ".tsx", ".jsx", ".js"].map((ext) => import_node_path.default.join(srcDir, baseName + ext)).find((f) => import_node_fs.default.existsSync(f));
196
+ if (!srcFile) {
197
+ return;
198
+ }
199
+ const correctRelPath = (0, import_vite.normalizePath)(
200
+ import_node_path.default.relative(import_node_path.default.dirname(mapFile), srcFile)
201
+ );
202
+ if (map.sources[0] === correctRelPath) {
203
+ return;
204
+ }
205
+ map.sources = [correctRelPath];
206
+ await import_node_fs.default.promises.writeFile(mapFile, JSON.stringify(map), "utf8");
207
+ } catch {
208
+ }
209
+ })
210
+ );
211
+ }
158
212
  function getEsbuildOptions(files) {
159
213
  const cedarPaths = (0, import_project_config.getPaths)();
160
214
  const format = (0, import_project_config.projectSideIsEsm)("api") ? "esm" : "cjs";
@@ -179,5 +233,6 @@ function getEsbuildOptions(files) {
179
233
  buildApi,
180
234
  buildApiWithVite,
181
235
  cleanApiBuild,
236
+ fixSourceMaps,
182
237
  rebuildApi
183
238
  });
@@ -14,6 +14,8 @@ export interface BackendFieldInfo {
14
14
  graphqlType: string;
15
15
  isRequired: boolean;
16
16
  isId: boolean;
17
+ hasDefaultValue: boolean;
18
+ isUpdatedAt: boolean;
17
19
  }
18
20
  export interface BackendModelInfo {
19
21
  modelName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"gqlormSchema.d.ts","sourceRoot":"","sources":["../../../src/generate/gqlormSchema.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,IAAI,MAAM,cAAc,CAAA;AA8BzC,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;AAE3C,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,iBAAiB;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,iBAAiB,EAAE,CAAA;CAC5B;AAMD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,OAAO,CAAA;IACnB,IAAI,EAAE,OAAO,CAAA;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,gBAAgB,EAAE,CAAA;IAC1B,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAAA;CACtC;AAED,MAAM,WAAW,mBAAmB;IAClC,eAAe,EAAE,MAAM,CAAA;IACvB,oBAAoB,EAAE,MAAM,CAAA;IAC5B,mBAAmB,EAAE,MAAM,CAAA;IAC3B,2BAA2B,EAAE,MAAM,CAAA;IACnC,qBAAqB,EAAE,OAAO,CAAA;CAC/B;AA6DD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMvE;AAoGD,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,IAAI,CAAC,QAAQ,GAClB,iBAAiB,EAAE,CAiDrB;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,iBAAiB,EAAE,GAC1B,MAAM,CA2CR;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,GAAG,WAAW,CAkDjE;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,GAAG,gBAAgB,EAAE,CA2D7E;AAkBD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CA6BvE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,gBAAgB,EAAE,EAC1B,MAAM,GAAE,mBAAmD,GAC1D,MAAM,CA0VR;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC;IACvD,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;CAC9C,CAAC,CAkID"}
1
+ {"version":3,"file":"gqlormSchema.d.ts","sourceRoot":"","sources":["../../../src/generate/gqlormSchema.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,IAAI,MAAM,cAAc,CAAA;AA8BzC,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;AAE3C,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,iBAAiB;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,iBAAiB,EAAE,CAAA;CAC5B;AAMD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,OAAO,CAAA;IACnB,IAAI,EAAE,OAAO,CAAA;IACb,eAAe,EAAE,OAAO,CAAA;IACxB,WAAW,EAAE,OAAO,CAAA;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,gBAAgB,EAAE,CAAA;IAC1B,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAAA;CACtC;AAED,MAAM,WAAW,mBAAmB;IAClC,eAAe,EAAE,MAAM,CAAA;IACvB,oBAAoB,EAAE,MAAM,CAAA;IAC5B,mBAAmB,EAAE,MAAM,CAAA;IAC3B,2BAA2B,EAAE,MAAM,CAAA;IACnC,qBAAqB,EAAE,OAAO,CAAA;CAC/B;AA6DD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMvE;AAoGD,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,IAAI,CAAC,QAAQ,GAClB,iBAAiB,EAAE,CAiDrB;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,iBAAiB,EAAE,GAC1B,MAAM,CA2CR;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,GAAG,WAAW,CAkDjE;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,GAAG,gBAAgB,EAAE,CA6D7E;AAkBD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CA6BvE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,gBAAgB,EAAE,EAC1B,MAAM,GAAE,mBAAmD,GAC1D,MAAM,CA+rBR;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC;IACvD,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;CAC9C,CAAC,CAkID"}
@@ -308,7 +308,9 @@ function buildBackendModelInfo(dmmf) {
308
308
  name: field.name,
309
309
  graphqlType: mapDmmfTypeToGraphql(field.type, field.kind),
310
310
  isRequired: field.isRequired,
311
- isId: field.isId
311
+ isId: field.isId,
312
+ hasDefaultValue: field.hasDefaultValue,
313
+ isUpdatedAt: field.isUpdatedAt ?? false
312
314
  });
313
315
  }
314
316
  if (fields.length > 0) {
@@ -423,6 +425,46 @@ function generateGqlormBackendContent(models, config = DEFAULT_GQLORM_BACKEND_CO
423
425
  lines.push(" where: Record<string, unknown>");
424
426
  lines.push(" }): Promise<Record<string, unknown> | null>");
425
427
  }
428
+ lines.push(" create(args: {");
429
+ lines.push(" data: Record<string, unknown>");
430
+ lines.push(` select: { ${selectType} }`);
431
+ lines.push(" }): Promise<{");
432
+ for (const field of model.fields) {
433
+ const tsType = graphqlTypeToTsInterfaceType(
434
+ field.graphqlType,
435
+ field.isRequired
436
+ );
437
+ lines.push(` ${field.name}: ${tsType}`);
438
+ }
439
+ lines.push(" }>");
440
+ if (model.idField) {
441
+ const idTsType = graphqlTypeToTsType(model.idField.graphqlType);
442
+ lines.push(" update(args: {");
443
+ lines.push(` where: { ${model.idField.name}: ${idTsType} }`);
444
+ lines.push(" data: Record<string, unknown>");
445
+ lines.push(` select: { ${selectType} }`);
446
+ lines.push(" }): Promise<{");
447
+ for (const field of model.fields) {
448
+ const tsType = graphqlTypeToTsInterfaceType(
449
+ field.graphqlType,
450
+ field.isRequired
451
+ );
452
+ lines.push(` ${field.name}: ${tsType}`);
453
+ }
454
+ lines.push(" }>");
455
+ lines.push(" delete(args: {");
456
+ lines.push(` where: { ${model.idField.name}: ${idTsType} }`);
457
+ lines.push(` select: { ${selectType} }`);
458
+ lines.push(" }): Promise<{");
459
+ for (const field of model.fields) {
460
+ const tsType = graphqlTypeToTsInterfaceType(
461
+ field.graphqlType,
462
+ field.isRequired
463
+ );
464
+ lines.push(` ${field.name}: ${tsType}`);
465
+ }
466
+ lines.push(" }>");
467
+ }
426
468
  lines.push(" }");
427
469
  }
428
470
  const membershipAlreadyInModels = models.some(
@@ -454,6 +496,26 @@ function generateGqlormBackendContent(models, config = DEFAULT_GQLORM_BACKEND_CO
454
496
  }
455
497
  lines.push(" }");
456
498
  lines.push("");
499
+ if (!model.idField) {
500
+ continue;
501
+ }
502
+ const writableFields = model.fields.filter(
503
+ (field) => !field.isId && !field.isUpdatedAt && field.name !== config.membershipUserField
504
+ );
505
+ lines.push(` input Create${model.modelName}Input {`);
506
+ for (const field of writableFields) {
507
+ const isClientRequired = field.isRequired && !field.hasDefaultValue;
508
+ const nullMark = isClientRequired ? "!" : "";
509
+ lines.push(` ${field.name}: ${field.graphqlType}${nullMark}`);
510
+ }
511
+ lines.push(" }");
512
+ lines.push("");
513
+ lines.push(` input Update${model.modelName}Input {`);
514
+ for (const field of writableFields) {
515
+ lines.push(` ${field.name}: ${field.graphqlType}`);
516
+ }
517
+ lines.push(" }");
518
+ lines.push("");
457
519
  }
458
520
  lines.push(" type Query {");
459
521
  for (const model of models) {
@@ -477,6 +539,32 @@ function generateGqlormBackendContent(models, config = DEFAULT_GQLORM_BACKEND_CO
477
539
  }
478
540
  }
479
541
  lines.push(" }");
542
+ lines.push("");
543
+ lines.push(" type Mutation {");
544
+ for (const model of models) {
545
+ if (model.idField) {
546
+ const hasUserField = model.fields.some(
547
+ (f) => f.name === config.membershipUserField
548
+ );
549
+ const hasOrgField = model.fields.some(
550
+ (f) => f.name === config.membershipOrganizationField
551
+ );
552
+ const isMembershipModel = model.camelName === config.membershipModelCamel;
553
+ const needsAuth = hasUserField || hasOrgField && config.membershipModelExists && !isMembershipModel;
554
+ const authDirective = needsAuth ? "@requireAuth" : "@skipAuth";
555
+ const idNullMark = model.idField.isRequired ? "!" : "";
556
+ lines.push(
557
+ ` create${model.modelName}(input: Create${model.modelName}Input!): ${model.modelName}! ${authDirective}`
558
+ );
559
+ lines.push(
560
+ ` update${model.modelName}(${model.idField.name}: ${model.idField.graphqlType}${idNullMark}, input: Update${model.modelName}Input!): ${model.modelName}! ${authDirective}`
561
+ );
562
+ lines.push(
563
+ ` delete${model.modelName}(${model.idField.name}: ${model.idField.graphqlType}${idNullMark}): ${model.modelName}! ${authDirective}`
564
+ );
565
+ }
566
+ }
567
+ lines.push(" }");
480
568
  lines.push("`");
481
569
  lines.push("");
482
570
  lines.push(
@@ -625,6 +713,242 @@ function generateGqlormBackendContent(models, config = DEFAULT_GQLORM_BACKEND_CO
625
713
  }
626
714
  }
627
715
  lines.push(" },");
716
+ lines.push(" Mutation: {");
717
+ for (const model of models) {
718
+ if (!model.idField) {
719
+ continue;
720
+ }
721
+ const selectObj = model.fields.map((f) => `${f.name}: true`).join(", ");
722
+ const hasUserField = model.fields.some(
723
+ (f) => f.name === config.membershipUserField
724
+ );
725
+ const hasOrgField = model.fields.some(
726
+ (f) => f.name === config.membershipOrganizationField
727
+ );
728
+ const isMembershipModel = model.camelName === config.membershipModelCamel;
729
+ const useOrgScoping = hasOrgField && config.membershipModelExists && !isMembershipModel;
730
+ const idFieldName = model.idField.name;
731
+ const idTsType = graphqlTypeToTsType(model.idField.graphqlType);
732
+ lines.push(
733
+ ` create${model.modelName}: async (_root: unknown, { input }: { input: Record<string, unknown> }, ${hasUserField || useOrgScoping ? "context" : "_context"}: GqlormContext) => {`
734
+ );
735
+ if (hasUserField || useOrgScoping) {
736
+ lines.push(" if (!context.currentUser) {");
737
+ lines.push(
738
+ ` throw new AuthenticationError("You don't have permission to do that.")`
739
+ );
740
+ lines.push(" }");
741
+ lines.push(" const currentUserId = context.currentUser['id']");
742
+ lines.push(
743
+ " if (currentUserId === undefined || currentUserId === null) {"
744
+ );
745
+ lines.push(
746
+ ` throw new AuthenticationError("Could not determine the current user's ID.")`
747
+ );
748
+ lines.push(" }");
749
+ }
750
+ lines.push(" const data: Record<string, unknown> = { ...input }");
751
+ if (hasUserField) {
752
+ lines.push(
753
+ ` data['${config.membershipUserField}'] = currentUserId`
754
+ );
755
+ }
756
+ if (useOrgScoping) {
757
+ lines.push(
758
+ ` const organizationId = data['${config.membershipOrganizationField}']`
759
+ );
760
+ lines.push(
761
+ " if (organizationId === undefined || organizationId === null) {"
762
+ );
763
+ lines.push(
764
+ ` throw new ForbiddenError('Organization membership is required for this operation')`
765
+ );
766
+ lines.push(" }");
767
+ lines.push(
768
+ ` const membership = await db.${config.membershipModelCamel}.findFirst({`
769
+ );
770
+ lines.push(" where: {");
771
+ lines.push(` ${config.membershipUserField}: currentUserId,`);
772
+ lines.push(
773
+ ` ${config.membershipOrganizationField}: organizationId,`
774
+ );
775
+ lines.push(" },");
776
+ lines.push(" })");
777
+ lines.push(" if (!membership) {");
778
+ lines.push(
779
+ ` throw new ForbiddenError('Not authorized to access this resource')`
780
+ );
781
+ lines.push(" }");
782
+ }
783
+ lines.push(` return db.${model.camelName}.create({`);
784
+ lines.push(" data,");
785
+ lines.push(` select: { ${selectObj} },`);
786
+ lines.push(" })");
787
+ lines.push(" },");
788
+ lines.push(
789
+ ` update${model.modelName}: async (_root: unknown, { ${idFieldName}, input }: { ${idFieldName}: ${idTsType}; input: Record<string, unknown> }, ${hasUserField || useOrgScoping ? "context" : "_context"}: GqlormContext) => {`
790
+ );
791
+ if (hasUserField || useOrgScoping) {
792
+ lines.push(" if (!context.currentUser) {");
793
+ lines.push(
794
+ ` throw new AuthenticationError("You don't have permission to do that.")`
795
+ );
796
+ lines.push(" }");
797
+ lines.push(" const currentUserId = context.currentUser['id']");
798
+ lines.push(
799
+ " if (currentUserId === undefined || currentUserId === null) {"
800
+ );
801
+ lines.push(
802
+ ` throw new AuthenticationError("Could not determine the current user's ID.")`
803
+ );
804
+ lines.push(" }");
805
+ lines.push(
806
+ ` const existingRecord = await db.${model.camelName}.findUnique({`
807
+ );
808
+ lines.push(` where: { ${idFieldName} },`);
809
+ lines.push(` select: { ${selectObj} },`);
810
+ lines.push(" })");
811
+ lines.push(" if (!existingRecord) {");
812
+ lines.push(
813
+ ` throw new ForbiddenError('Not authorized to access this resource')`
814
+ );
815
+ lines.push(" }");
816
+ lines.push(" const data: Record<string, unknown> = { ...input }");
817
+ if (hasUserField) {
818
+ lines.push(
819
+ ` if (existingRecord.${config.membershipUserField} !== currentUserId) {`
820
+ );
821
+ lines.push(
822
+ ` throw new ForbiddenError('Not authorized to access this resource')`
823
+ );
824
+ lines.push(" }");
825
+ lines.push(` delete data['${config.membershipUserField}']`);
826
+ }
827
+ if (useOrgScoping) {
828
+ lines.push(
829
+ ` const currentOrganizationId = existingRecord.${config.membershipOrganizationField}`
830
+ );
831
+ lines.push(
832
+ ` const currentOrganizationMembership = await db.${config.membershipModelCamel}.findFirst({`
833
+ );
834
+ lines.push(" where: {");
835
+ lines.push(` ${config.membershipUserField}: currentUserId,`);
836
+ lines.push(
837
+ ` ${config.membershipOrganizationField}: currentOrganizationId,`
838
+ );
839
+ lines.push(" },");
840
+ lines.push(" })");
841
+ lines.push(" if (!currentOrganizationMembership) {");
842
+ lines.push(
843
+ ` throw new ForbiddenError('Not authorized to access this resource')`
844
+ );
845
+ lines.push(" }");
846
+ lines.push(
847
+ ` const requestedOrganizationId = input['${config.membershipOrganizationField}'] ?? currentOrganizationId`
848
+ );
849
+ lines.push(
850
+ ` const requestedOrganizationMembership = await db.${config.membershipModelCamel}.findFirst({`
851
+ );
852
+ lines.push(" where: {");
853
+ lines.push(` ${config.membershipUserField}: currentUserId,`);
854
+ lines.push(
855
+ ` ${config.membershipOrganizationField}: requestedOrganizationId,`
856
+ );
857
+ lines.push(" },");
858
+ lines.push(" })");
859
+ lines.push(" if (!requestedOrganizationMembership) {");
860
+ lines.push(
861
+ ` throw new ForbiddenError('Not authorized to access this resource')`
862
+ );
863
+ lines.push(" }");
864
+ }
865
+ }
866
+ if (!(hasUserField || useOrgScoping)) {
867
+ lines.push(
868
+ ` const existingRecord = await db.${model.camelName}.findUnique({`
869
+ );
870
+ lines.push(` where: { ${idFieldName} },`);
871
+ lines.push(` select: { ${selectObj} },`);
872
+ lines.push(" })");
873
+ lines.push(" if (!existingRecord) {");
874
+ lines.push(
875
+ ` throw new ForbiddenError('Not authorized to access this resource')`
876
+ );
877
+ lines.push(" }");
878
+ lines.push(" const data: Record<string, unknown> = { ...input }");
879
+ }
880
+ lines.push(` return db.${model.camelName}.update({`);
881
+ lines.push(` where: { ${idFieldName} },`);
882
+ lines.push(" data,");
883
+ lines.push(` select: { ${selectObj} },`);
884
+ lines.push(" })");
885
+ lines.push(" },");
886
+ lines.push(
887
+ ` delete${model.modelName}: async (_root: unknown, { ${idFieldName} }: { ${idFieldName}: ${idTsType} }, ${hasUserField || useOrgScoping ? "context" : "_context"}: GqlormContext) => {`
888
+ );
889
+ lines.push(
890
+ ` const existingRecord = await db.${model.camelName}.findUnique({`
891
+ );
892
+ lines.push(` where: { ${idFieldName} },`);
893
+ lines.push(` select: { ${selectObj} },`);
894
+ lines.push(" })");
895
+ lines.push(" if (!existingRecord) {");
896
+ lines.push(
897
+ ` throw new ForbiddenError('Not authorized to access this resource')`
898
+ );
899
+ lines.push(" }");
900
+ if (hasUserField || useOrgScoping) {
901
+ lines.push(" if (!context.currentUser) {");
902
+ lines.push(
903
+ ` throw new AuthenticationError("You don't have permission to do that.")`
904
+ );
905
+ lines.push(" }");
906
+ lines.push(" const currentUserId = context.currentUser['id']");
907
+ lines.push(
908
+ " if (currentUserId === undefined || currentUserId === null) {"
909
+ );
910
+ lines.push(
911
+ ` throw new AuthenticationError("Could not determine the current user's ID.")`
912
+ );
913
+ lines.push(" }");
914
+ if (hasUserField) {
915
+ lines.push(
916
+ ` if (existingRecord.${config.membershipUserField} !== currentUserId) {`
917
+ );
918
+ lines.push(
919
+ ` throw new ForbiddenError('Not authorized to access this resource')`
920
+ );
921
+ lines.push(" }");
922
+ }
923
+ if (useOrgScoping) {
924
+ lines.push(
925
+ ` const membership = await db.${config.membershipModelCamel}.findFirst({`
926
+ );
927
+ lines.push(" where: {");
928
+ lines.push(` ${config.membershipUserField}: currentUserId,`);
929
+ lines.push(
930
+ ` ${config.membershipOrganizationField}: existingRecord.${config.membershipOrganizationField},`
931
+ );
932
+ lines.push(" },");
933
+ lines.push(" })");
934
+ lines.push(" if (!membership) {");
935
+ lines.push(
936
+ ` throw new ForbiddenError('Not authorized to access this resource')`
937
+ );
938
+ lines.push(" }");
939
+ }
940
+ }
941
+ lines.push(` return db.${model.camelName}.delete({`);
942
+ lines.push(` where: { ${idFieldName} },`);
943
+ lines.push(` select: { ${selectObj} },`);
944
+ lines.push(" })");
945
+ lines.push(" },");
946
+ lines.push("");
947
+ }
948
+ while (lines[lines.length - 1] === "") {
949
+ lines.pop();
950
+ }
951
+ lines.push(" },");
628
952
  lines.push(" }");
629
953
  lines.push("}");
630
954
  lines.push("");
@@ -1 +1 @@
1
- {"version":3,"file":"visitor.d.ts","sourceRoot":"","sources":["../../../../../src/generate/plugins/rw-typescript-resolvers/visitor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,uCAAuC,CAAA;AAC5F,OAAO,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAA;AAElF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAA;AACnF,OAAO,KAAK,EACV,mBAAmB,EACnB,aAAa,EACb,wBAAwB,EACzB,MAAM,SAAS,CAAA;AAEhB,qBAAa,4BAA6B,SAAQ,0BAA0B;gBAExE,YAAY,EAAE,+BAA+B,EAC7C,MAAM,EAAE,aAAa;IAMvB,eAAe,CACb,IAAI,EAAE,mBAAmB,EACzB,GAAG,EAAE,MAAM,GAAG,MAAM,EACpB,MAAM,EAAE,GAAG,GACV,qBAAqB;IAgCxB,oBAAoB,CAAC,IAAI,EAAE,wBAAwB,GAAG,MAAM,GAAG,IAAI;CA6FpE"}
1
+ {"version":3,"file":"visitor.d.ts","sourceRoot":"","sources":["../../../../../src/generate/plugins/rw-typescript-resolvers/visitor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,uCAAuC,CAAA;AAC5F,OAAO,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAA;AAElF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAA;AACnF,OAAO,KAAK,EACV,mBAAmB,EACnB,aAAa,EACb,wBAAwB,EACzB,MAAM,SAAS,CAAA;AAEhB,qBAAa,4BAA6B,SAAQ,0BAA0B;gBAExE,YAAY,EAAE,+BAA+B,EAC7C,MAAM,EAAE,aAAa;IAMvB,eAAe,CACb,IAAI,EAAE,mBAAmB,EACzB,GAAG,EAAE,MAAM,GAAG,MAAM,EACpB,MAAM,EAAE,GAAG,GACV,qBAAqB;IAgCxB,oBAAoB,CAAC,IAAI,EAAE,wBAAwB,GAAG,MAAM,GAAG,IAAI;CA6FpE"}
@@ -320,9 +320,9 @@ const generateTypeDefGlobalContext = () => {
320
320
  };
321
321
  const generateViteClientTypesDirective = () => {
322
322
  const viteClientDirective = `/// <reference types="vite/client" />`;
323
- const redwoodProjectPaths = (0, import_project_config.getPaths)();
323
+ const cedarProjectPaths = (0, import_project_config.getPaths)();
324
324
  const viteClientDirectivePath = import_path.default.join(
325
- redwoodProjectPaths.generated.types.includes,
325
+ cedarProjectPaths.generated.types.includes,
326
326
  "web-vite-client.d.ts"
327
327
  );
328
328
  import_node_fs.default.writeFileSync(viteClientDirectivePath, viteClientDirective);
@@ -334,12 +334,9 @@ function generateStubStorybookTypes() {
334
334
  export type StoryObj<T = any> = any
335
335
  }
336
336
  `;
337
- const redwoodProjectPaths = (0, import_project_config.getPaths)();
337
+ const cedarProjectPaths = (0, import_project_config.getPaths)();
338
338
  const packageJson = JSON.parse(
339
- import_node_fs.default.readFileSync(
340
- import_path.default.join(redwoodProjectPaths.base, "package.json"),
341
- "utf-8"
342
- )
339
+ import_node_fs.default.readFileSync(import_path.default.join(cedarProjectPaths.base, "package.json"), "utf-8")
343
340
  );
344
341
  const hasCliStorybookVite = Object.keys(
345
342
  packageJson["devDependencies"]
@@ -348,7 +345,7 @@ function generateStubStorybookTypes() {
348
345
  return [];
349
346
  }
350
347
  const stubStorybookTypesFilePath = import_path.default.join(
351
- redwoodProjectPaths.generated.types.includes,
348
+ cedarProjectPaths.generated.types.includes,
352
349
  "web-storybook.d.ts"
353
350
  );
354
351
  import_node_fs.default.writeFileSync(stubStorybookTypesFilePath, stubStorybookTypesFileContent);
@@ -79,11 +79,11 @@ function validateSchema(schemaDocumentNode, typesToCheck = ["Query", "Mutation"]
79
79
  for (const field of typeNode.fields || []) {
80
80
  const fieldName = field.name.value;
81
81
  const fieldTypeName = typeNode.name.value;
82
- const isRedwoodQuery = fieldName === "redwood" && fieldTypeName === "Query";
82
+ const isLegacyRedwoodQuery = fieldName === "redwood" && fieldTypeName === "Query";
83
83
  const isCedarQuery = fieldName === "cedar" && fieldTypeName === "Query" || // TODO: Remove this when I remove the root schema
84
84
  fieldName === "cedarjs" && fieldTypeName === "Query";
85
85
  const isCurrentUserQuery = fieldName === "currentUser" && fieldTypeName === "Query";
86
- if (!(isRedwoodQuery || isCedarQuery || isCurrentUserQuery)) {
86
+ if (!(isCedarQuery || isCurrentUserQuery || isLegacyRedwoodQuery)) {
87
87
  const hasDirective = field.directives?.length;
88
88
  if (!hasDirective) {
89
89
  validationOutput.push(`${fieldName} ${fieldTypeName}`);
@@ -14,6 +14,8 @@ export interface BackendFieldInfo {
14
14
  graphqlType: string;
15
15
  isRequired: boolean;
16
16
  isId: boolean;
17
+ hasDefaultValue: boolean;
18
+ isUpdatedAt: boolean;
17
19
  }
18
20
  export interface BackendModelInfo {
19
21
  modelName: string;
@@ -1 +1 @@
1
- {"version":3,"file":"gqlormSchema.d.ts","sourceRoot":"","sources":["../../src/generate/gqlormSchema.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,IAAI,MAAM,cAAc,CAAA;AA8BzC,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;AAE3C,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,iBAAiB;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,iBAAiB,EAAE,CAAA;CAC5B;AAMD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,OAAO,CAAA;IACnB,IAAI,EAAE,OAAO,CAAA;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,gBAAgB,EAAE,CAAA;IAC1B,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAAA;CACtC;AAED,MAAM,WAAW,mBAAmB;IAClC,eAAe,EAAE,MAAM,CAAA;IACvB,oBAAoB,EAAE,MAAM,CAAA;IAC5B,mBAAmB,EAAE,MAAM,CAAA;IAC3B,2BAA2B,EAAE,MAAM,CAAA;IACnC,qBAAqB,EAAE,OAAO,CAAA;CAC/B;AA6DD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMvE;AAoGD,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,IAAI,CAAC,QAAQ,GAClB,iBAAiB,EAAE,CAiDrB;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,iBAAiB,EAAE,GAC1B,MAAM,CA2CR;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,GAAG,WAAW,CAkDjE;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,GAAG,gBAAgB,EAAE,CA2D7E;AAkBD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CA6BvE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,gBAAgB,EAAE,EAC1B,MAAM,GAAE,mBAAmD,GAC1D,MAAM,CA0VR;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC;IACvD,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;CAC9C,CAAC,CAkID"}
1
+ {"version":3,"file":"gqlormSchema.d.ts","sourceRoot":"","sources":["../../src/generate/gqlormSchema.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,IAAI,MAAM,cAAc,CAAA;AA8BzC,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;AAE3C,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,iBAAiB;IACzB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,iBAAiB,EAAE,CAAA;CAC5B;AAMD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,OAAO,CAAA;IACnB,IAAI,EAAE,OAAO,CAAA;IACb,eAAe,EAAE,OAAO,CAAA;IACxB,WAAW,EAAE,OAAO,CAAA;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,gBAAgB,EAAE,CAAA;IAC1B,OAAO,EAAE,gBAAgB,GAAG,SAAS,CAAA;CACtC;AAED,MAAM,WAAW,mBAAmB;IAClC,eAAe,EAAE,MAAM,CAAA;IACvB,oBAAoB,EAAE,MAAM,CAAA;IAC5B,mBAAmB,EAAE,MAAM,CAAA;IAC3B,2BAA2B,EAAE,MAAM,CAAA;IACnC,qBAAqB,EAAE,OAAO,CAAA;CAC/B;AA6DD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMvE;AAoGD,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,IAAI,CAAC,QAAQ,GAClB,iBAAiB,EAAE,CAiDrB;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,iBAAiB,EAAE,GAC1B,MAAM,CA2CR;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,GAAG,WAAW,CAkDjE;AAMD;;;;;;;;;;;;GAYG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,GAAG,gBAAgB,EAAE,CA6D7E;AAkBD;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CA6BvE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,gBAAgB,EAAE,EAC1B,MAAM,GAAE,mBAAmD,GAC1D,MAAM,CA+rBR;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC;IACvD,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,EAAE,CAAA;CAC9C,CAAC,CAkID"}
@@ -268,7 +268,9 @@ function buildBackendModelInfo(dmmf) {
268
268
  name: field.name,
269
269
  graphqlType: mapDmmfTypeToGraphql(field.type, field.kind),
270
270
  isRequired: field.isRequired,
271
- isId: field.isId
271
+ isId: field.isId,
272
+ hasDefaultValue: field.hasDefaultValue,
273
+ isUpdatedAt: field.isUpdatedAt ?? false
272
274
  });
273
275
  }
274
276
  if (fields.length > 0) {
@@ -383,6 +385,46 @@ function generateGqlormBackendContent(models, config = DEFAULT_GQLORM_BACKEND_CO
383
385
  lines.push(" where: Record<string, unknown>");
384
386
  lines.push(" }): Promise<Record<string, unknown> | null>");
385
387
  }
388
+ lines.push(" create(args: {");
389
+ lines.push(" data: Record<string, unknown>");
390
+ lines.push(` select: { ${selectType} }`);
391
+ lines.push(" }): Promise<{");
392
+ for (const field of model.fields) {
393
+ const tsType = graphqlTypeToTsInterfaceType(
394
+ field.graphqlType,
395
+ field.isRequired
396
+ );
397
+ lines.push(` ${field.name}: ${tsType}`);
398
+ }
399
+ lines.push(" }>");
400
+ if (model.idField) {
401
+ const idTsType = graphqlTypeToTsType(model.idField.graphqlType);
402
+ lines.push(" update(args: {");
403
+ lines.push(` where: { ${model.idField.name}: ${idTsType} }`);
404
+ lines.push(" data: Record<string, unknown>");
405
+ lines.push(` select: { ${selectType} }`);
406
+ lines.push(" }): Promise<{");
407
+ for (const field of model.fields) {
408
+ const tsType = graphqlTypeToTsInterfaceType(
409
+ field.graphqlType,
410
+ field.isRequired
411
+ );
412
+ lines.push(` ${field.name}: ${tsType}`);
413
+ }
414
+ lines.push(" }>");
415
+ lines.push(" delete(args: {");
416
+ lines.push(` where: { ${model.idField.name}: ${idTsType} }`);
417
+ lines.push(` select: { ${selectType} }`);
418
+ lines.push(" }): Promise<{");
419
+ for (const field of model.fields) {
420
+ const tsType = graphqlTypeToTsInterfaceType(
421
+ field.graphqlType,
422
+ field.isRequired
423
+ );
424
+ lines.push(` ${field.name}: ${tsType}`);
425
+ }
426
+ lines.push(" }>");
427
+ }
386
428
  lines.push(" }");
387
429
  }
388
430
  const membershipAlreadyInModels = models.some(
@@ -414,6 +456,26 @@ function generateGqlormBackendContent(models, config = DEFAULT_GQLORM_BACKEND_CO
414
456
  }
415
457
  lines.push(" }");
416
458
  lines.push("");
459
+ if (!model.idField) {
460
+ continue;
461
+ }
462
+ const writableFields = model.fields.filter(
463
+ (field) => !field.isId && !field.isUpdatedAt && field.name !== config.membershipUserField
464
+ );
465
+ lines.push(` input Create${model.modelName}Input {`);
466
+ for (const field of writableFields) {
467
+ const isClientRequired = field.isRequired && !field.hasDefaultValue;
468
+ const nullMark = isClientRequired ? "!" : "";
469
+ lines.push(` ${field.name}: ${field.graphqlType}${nullMark}`);
470
+ }
471
+ lines.push(" }");
472
+ lines.push("");
473
+ lines.push(` input Update${model.modelName}Input {`);
474
+ for (const field of writableFields) {
475
+ lines.push(` ${field.name}: ${field.graphqlType}`);
476
+ }
477
+ lines.push(" }");
478
+ lines.push("");
417
479
  }
418
480
  lines.push(" type Query {");
419
481
  for (const model of models) {
@@ -437,6 +499,32 @@ function generateGqlormBackendContent(models, config = DEFAULT_GQLORM_BACKEND_CO
437
499
  }
438
500
  }
439
501
  lines.push(" }");
502
+ lines.push("");
503
+ lines.push(" type Mutation {");
504
+ for (const model of models) {
505
+ if (model.idField) {
506
+ const hasUserField = model.fields.some(
507
+ (f) => f.name === config.membershipUserField
508
+ );
509
+ const hasOrgField = model.fields.some(
510
+ (f) => f.name === config.membershipOrganizationField
511
+ );
512
+ const isMembershipModel = model.camelName === config.membershipModelCamel;
513
+ const needsAuth = hasUserField || hasOrgField && config.membershipModelExists && !isMembershipModel;
514
+ const authDirective = needsAuth ? "@requireAuth" : "@skipAuth";
515
+ const idNullMark = model.idField.isRequired ? "!" : "";
516
+ lines.push(
517
+ ` create${model.modelName}(input: Create${model.modelName}Input!): ${model.modelName}! ${authDirective}`
518
+ );
519
+ lines.push(
520
+ ` update${model.modelName}(${model.idField.name}: ${model.idField.graphqlType}${idNullMark}, input: Update${model.modelName}Input!): ${model.modelName}! ${authDirective}`
521
+ );
522
+ lines.push(
523
+ ` delete${model.modelName}(${model.idField.name}: ${model.idField.graphqlType}${idNullMark}): ${model.modelName}! ${authDirective}`
524
+ );
525
+ }
526
+ }
527
+ lines.push(" }");
440
528
  lines.push("`");
441
529
  lines.push("");
442
530
  lines.push(
@@ -585,6 +673,242 @@ function generateGqlormBackendContent(models, config = DEFAULT_GQLORM_BACKEND_CO
585
673
  }
586
674
  }
587
675
  lines.push(" },");
676
+ lines.push(" Mutation: {");
677
+ for (const model of models) {
678
+ if (!model.idField) {
679
+ continue;
680
+ }
681
+ const selectObj = model.fields.map((f) => `${f.name}: true`).join(", ");
682
+ const hasUserField = model.fields.some(
683
+ (f) => f.name === config.membershipUserField
684
+ );
685
+ const hasOrgField = model.fields.some(
686
+ (f) => f.name === config.membershipOrganizationField
687
+ );
688
+ const isMembershipModel = model.camelName === config.membershipModelCamel;
689
+ const useOrgScoping = hasOrgField && config.membershipModelExists && !isMembershipModel;
690
+ const idFieldName = model.idField.name;
691
+ const idTsType = graphqlTypeToTsType(model.idField.graphqlType);
692
+ lines.push(
693
+ ` create${model.modelName}: async (_root: unknown, { input }: { input: Record<string, unknown> }, ${hasUserField || useOrgScoping ? "context" : "_context"}: GqlormContext) => {`
694
+ );
695
+ if (hasUserField || useOrgScoping) {
696
+ lines.push(" if (!context.currentUser) {");
697
+ lines.push(
698
+ ` throw new AuthenticationError("You don't have permission to do that.")`
699
+ );
700
+ lines.push(" }");
701
+ lines.push(" const currentUserId = context.currentUser['id']");
702
+ lines.push(
703
+ " if (currentUserId === undefined || currentUserId === null) {"
704
+ );
705
+ lines.push(
706
+ ` throw new AuthenticationError("Could not determine the current user's ID.")`
707
+ );
708
+ lines.push(" }");
709
+ }
710
+ lines.push(" const data: Record<string, unknown> = { ...input }");
711
+ if (hasUserField) {
712
+ lines.push(
713
+ ` data['${config.membershipUserField}'] = currentUserId`
714
+ );
715
+ }
716
+ if (useOrgScoping) {
717
+ lines.push(
718
+ ` const organizationId = data['${config.membershipOrganizationField}']`
719
+ );
720
+ lines.push(
721
+ " if (organizationId === undefined || organizationId === null) {"
722
+ );
723
+ lines.push(
724
+ ` throw new ForbiddenError('Organization membership is required for this operation')`
725
+ );
726
+ lines.push(" }");
727
+ lines.push(
728
+ ` const membership = await db.${config.membershipModelCamel}.findFirst({`
729
+ );
730
+ lines.push(" where: {");
731
+ lines.push(` ${config.membershipUserField}: currentUserId,`);
732
+ lines.push(
733
+ ` ${config.membershipOrganizationField}: organizationId,`
734
+ );
735
+ lines.push(" },");
736
+ lines.push(" })");
737
+ lines.push(" if (!membership) {");
738
+ lines.push(
739
+ ` throw new ForbiddenError('Not authorized to access this resource')`
740
+ );
741
+ lines.push(" }");
742
+ }
743
+ lines.push(` return db.${model.camelName}.create({`);
744
+ lines.push(" data,");
745
+ lines.push(` select: { ${selectObj} },`);
746
+ lines.push(" })");
747
+ lines.push(" },");
748
+ lines.push(
749
+ ` update${model.modelName}: async (_root: unknown, { ${idFieldName}, input }: { ${idFieldName}: ${idTsType}; input: Record<string, unknown> }, ${hasUserField || useOrgScoping ? "context" : "_context"}: GqlormContext) => {`
750
+ );
751
+ if (hasUserField || useOrgScoping) {
752
+ lines.push(" if (!context.currentUser) {");
753
+ lines.push(
754
+ ` throw new AuthenticationError("You don't have permission to do that.")`
755
+ );
756
+ lines.push(" }");
757
+ lines.push(" const currentUserId = context.currentUser['id']");
758
+ lines.push(
759
+ " if (currentUserId === undefined || currentUserId === null) {"
760
+ );
761
+ lines.push(
762
+ ` throw new AuthenticationError("Could not determine the current user's ID.")`
763
+ );
764
+ lines.push(" }");
765
+ lines.push(
766
+ ` const existingRecord = await db.${model.camelName}.findUnique({`
767
+ );
768
+ lines.push(` where: { ${idFieldName} },`);
769
+ lines.push(` select: { ${selectObj} },`);
770
+ lines.push(" })");
771
+ lines.push(" if (!existingRecord) {");
772
+ lines.push(
773
+ ` throw new ForbiddenError('Not authorized to access this resource')`
774
+ );
775
+ lines.push(" }");
776
+ lines.push(" const data: Record<string, unknown> = { ...input }");
777
+ if (hasUserField) {
778
+ lines.push(
779
+ ` if (existingRecord.${config.membershipUserField} !== currentUserId) {`
780
+ );
781
+ lines.push(
782
+ ` throw new ForbiddenError('Not authorized to access this resource')`
783
+ );
784
+ lines.push(" }");
785
+ lines.push(` delete data['${config.membershipUserField}']`);
786
+ }
787
+ if (useOrgScoping) {
788
+ lines.push(
789
+ ` const currentOrganizationId = existingRecord.${config.membershipOrganizationField}`
790
+ );
791
+ lines.push(
792
+ ` const currentOrganizationMembership = await db.${config.membershipModelCamel}.findFirst({`
793
+ );
794
+ lines.push(" where: {");
795
+ lines.push(` ${config.membershipUserField}: currentUserId,`);
796
+ lines.push(
797
+ ` ${config.membershipOrganizationField}: currentOrganizationId,`
798
+ );
799
+ lines.push(" },");
800
+ lines.push(" })");
801
+ lines.push(" if (!currentOrganizationMembership) {");
802
+ lines.push(
803
+ ` throw new ForbiddenError('Not authorized to access this resource')`
804
+ );
805
+ lines.push(" }");
806
+ lines.push(
807
+ ` const requestedOrganizationId = input['${config.membershipOrganizationField}'] ?? currentOrganizationId`
808
+ );
809
+ lines.push(
810
+ ` const requestedOrganizationMembership = await db.${config.membershipModelCamel}.findFirst({`
811
+ );
812
+ lines.push(" where: {");
813
+ lines.push(` ${config.membershipUserField}: currentUserId,`);
814
+ lines.push(
815
+ ` ${config.membershipOrganizationField}: requestedOrganizationId,`
816
+ );
817
+ lines.push(" },");
818
+ lines.push(" })");
819
+ lines.push(" if (!requestedOrganizationMembership) {");
820
+ lines.push(
821
+ ` throw new ForbiddenError('Not authorized to access this resource')`
822
+ );
823
+ lines.push(" }");
824
+ }
825
+ }
826
+ if (!(hasUserField || useOrgScoping)) {
827
+ lines.push(
828
+ ` const existingRecord = await db.${model.camelName}.findUnique({`
829
+ );
830
+ lines.push(` where: { ${idFieldName} },`);
831
+ lines.push(` select: { ${selectObj} },`);
832
+ lines.push(" })");
833
+ lines.push(" if (!existingRecord) {");
834
+ lines.push(
835
+ ` throw new ForbiddenError('Not authorized to access this resource')`
836
+ );
837
+ lines.push(" }");
838
+ lines.push(" const data: Record<string, unknown> = { ...input }");
839
+ }
840
+ lines.push(` return db.${model.camelName}.update({`);
841
+ lines.push(` where: { ${idFieldName} },`);
842
+ lines.push(" data,");
843
+ lines.push(` select: { ${selectObj} },`);
844
+ lines.push(" })");
845
+ lines.push(" },");
846
+ lines.push(
847
+ ` delete${model.modelName}: async (_root: unknown, { ${idFieldName} }: { ${idFieldName}: ${idTsType} }, ${hasUserField || useOrgScoping ? "context" : "_context"}: GqlormContext) => {`
848
+ );
849
+ lines.push(
850
+ ` const existingRecord = await db.${model.camelName}.findUnique({`
851
+ );
852
+ lines.push(` where: { ${idFieldName} },`);
853
+ lines.push(` select: { ${selectObj} },`);
854
+ lines.push(" })");
855
+ lines.push(" if (!existingRecord) {");
856
+ lines.push(
857
+ ` throw new ForbiddenError('Not authorized to access this resource')`
858
+ );
859
+ lines.push(" }");
860
+ if (hasUserField || useOrgScoping) {
861
+ lines.push(" if (!context.currentUser) {");
862
+ lines.push(
863
+ ` throw new AuthenticationError("You don't have permission to do that.")`
864
+ );
865
+ lines.push(" }");
866
+ lines.push(" const currentUserId = context.currentUser['id']");
867
+ lines.push(
868
+ " if (currentUserId === undefined || currentUserId === null) {"
869
+ );
870
+ lines.push(
871
+ ` throw new AuthenticationError("Could not determine the current user's ID.")`
872
+ );
873
+ lines.push(" }");
874
+ if (hasUserField) {
875
+ lines.push(
876
+ ` if (existingRecord.${config.membershipUserField} !== currentUserId) {`
877
+ );
878
+ lines.push(
879
+ ` throw new ForbiddenError('Not authorized to access this resource')`
880
+ );
881
+ lines.push(" }");
882
+ }
883
+ if (useOrgScoping) {
884
+ lines.push(
885
+ ` const membership = await db.${config.membershipModelCamel}.findFirst({`
886
+ );
887
+ lines.push(" where: {");
888
+ lines.push(` ${config.membershipUserField}: currentUserId,`);
889
+ lines.push(
890
+ ` ${config.membershipOrganizationField}: existingRecord.${config.membershipOrganizationField},`
891
+ );
892
+ lines.push(" },");
893
+ lines.push(" })");
894
+ lines.push(" if (!membership) {");
895
+ lines.push(
896
+ ` throw new ForbiddenError('Not authorized to access this resource')`
897
+ );
898
+ lines.push(" }");
899
+ }
900
+ }
901
+ lines.push(` return db.${model.camelName}.delete({`);
902
+ lines.push(` where: { ${idFieldName} },`);
903
+ lines.push(` select: { ${selectObj} },`);
904
+ lines.push(" })");
905
+ lines.push(" },");
906
+ lines.push("");
907
+ }
908
+ while (lines[lines.length - 1] === "") {
909
+ lines.pop();
910
+ }
911
+ lines.push(" },");
588
912
  lines.push(" }");
589
913
  lines.push("}");
590
914
  lines.push("");
@@ -1 +1 @@
1
- {"version":3,"file":"visitor.d.ts","sourceRoot":"","sources":["../../../../src/generate/plugins/rw-typescript-resolvers/visitor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,uCAAuC,CAAA;AAC5F,OAAO,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAA;AAElF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAA;AACnF,OAAO,KAAK,EACV,mBAAmB,EACnB,aAAa,EACb,wBAAwB,EACzB,MAAM,SAAS,CAAA;AAEhB,qBAAa,4BAA6B,SAAQ,0BAA0B;gBAExE,YAAY,EAAE,+BAA+B,EAC7C,MAAM,EAAE,aAAa;IAMvB,eAAe,CACb,IAAI,EAAE,mBAAmB,EACzB,GAAG,EAAE,MAAM,GAAG,MAAM,EACpB,MAAM,EAAE,GAAG,GACV,qBAAqB;IAgCxB,oBAAoB,CAAC,IAAI,EAAE,wBAAwB,GAAG,MAAM,GAAG,IAAI;CA6FpE"}
1
+ {"version":3,"file":"visitor.d.ts","sourceRoot":"","sources":["../../../../src/generate/plugins/rw-typescript-resolvers/visitor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,uCAAuC,CAAA;AAC5F,OAAO,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAA;AAElF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wCAAwC,CAAA;AACnF,OAAO,KAAK,EACV,mBAAmB,EACnB,aAAa,EACb,wBAAwB,EACzB,MAAM,SAAS,CAAA;AAEhB,qBAAa,4BAA6B,SAAQ,0BAA0B;gBAExE,YAAY,EAAE,+BAA+B,EAC7C,MAAM,EAAE,aAAa;IAMvB,eAAe,CACb,IAAI,EAAE,mBAAmB,EACzB,GAAG,EAAE,MAAM,GAAG,MAAM,EACpB,MAAM,EAAE,GAAG,GACV,qBAAqB;IAgCxB,oBAAoB,CAAC,IAAI,EAAE,wBAAwB,GAAG,MAAM,GAAG,IAAI;CA6FpE"}
@@ -280,9 +280,9 @@ const generateTypeDefGlobalContext = () => {
280
280
  };
281
281
  const generateViteClientTypesDirective = () => {
282
282
  const viteClientDirective = `/// <reference types="vite/client" />`;
283
- const redwoodProjectPaths = getPaths();
283
+ const cedarProjectPaths = getPaths();
284
284
  const viteClientDirectivePath = path.join(
285
- redwoodProjectPaths.generated.types.includes,
285
+ cedarProjectPaths.generated.types.includes,
286
286
  "web-vite-client.d.ts"
287
287
  );
288
288
  fs.writeFileSync(viteClientDirectivePath, viteClientDirective);
@@ -294,12 +294,9 @@ function generateStubStorybookTypes() {
294
294
  export type StoryObj<T = any> = any
295
295
  }
296
296
  `;
297
- const redwoodProjectPaths = getPaths();
297
+ const cedarProjectPaths = getPaths();
298
298
  const packageJson = JSON.parse(
299
- fs.readFileSync(
300
- path.join(redwoodProjectPaths.base, "package.json"),
301
- "utf-8"
302
- )
299
+ fs.readFileSync(path.join(cedarProjectPaths.base, "package.json"), "utf-8")
303
300
  );
304
301
  const hasCliStorybookVite = Object.keys(
305
302
  packageJson["devDependencies"]
@@ -308,7 +305,7 @@ function generateStubStorybookTypes() {
308
305
  return [];
309
306
  }
310
307
  const stubStorybookTypesFilePath = path.join(
311
- redwoodProjectPaths.generated.types.includes,
308
+ cedarProjectPaths.generated.types.includes,
312
309
  "web-storybook.d.ts"
313
310
  );
314
311
  fs.writeFileSync(stubStorybookTypesFilePath, stubStorybookTypesFileContent);
@@ -52,11 +52,11 @@ function validateSchema(schemaDocumentNode, typesToCheck = ["Query", "Mutation"]
52
52
  for (const field of typeNode.fields || []) {
53
53
  const fieldName = field.name.value;
54
54
  const fieldTypeName = typeNode.name.value;
55
- const isRedwoodQuery = fieldName === "redwood" && fieldTypeName === "Query";
55
+ const isLegacyRedwoodQuery = fieldName === "redwood" && fieldTypeName === "Query";
56
56
  const isCedarQuery = fieldName === "cedar" && fieldTypeName === "Query" || // TODO: Remove this when I remove the root schema
57
57
  fieldName === "cedarjs" && fieldTypeName === "Query";
58
58
  const isCurrentUserQuery = fieldName === "currentUser" && fieldTypeName === "Query";
59
- if (!(isRedwoodQuery || isCedarQuery || isCurrentUserQuery)) {
59
+ if (!(isCedarQuery || isCurrentUserQuery || isLegacyRedwoodQuery)) {
60
60
  const hasDirective = field.directives?.length;
61
61
  if (!hasDirective) {
62
62
  validationOutput.push(`${fieldName} ${fieldTypeName}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cedarjs/internal",
3
- "version": "4.2.0",
3
+ "version": "4.2.1-next.258",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/cedarjs/cedar.git",
@@ -146,7 +146,7 @@
146
146
  "build:types": "tsc --build --verbose ./tsconfig.build.json",
147
147
  "build:types-cjs": "tsc --build --verbose ./tsconfig.cjs.json",
148
148
  "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx\" --ignore dist --exec \"yarn build\"",
149
- "check:attw": "yarn attw -P",
149
+ "check:attw": "yarn cedar-fwtools-attw",
150
150
  "check:package": "concurrently npm:check:attw yarn:publint",
151
151
  "fix:permissions": "chmod +x dist/generate/generate.js dist/generate/watch.js",
152
152
  "prepublishOnly": "NODE_ENV=production yarn build",
@@ -155,10 +155,10 @@
155
155
  },
156
156
  "dependencies": {
157
157
  "@babel/core": "^7.26.10",
158
- "@babel/parser": "7.29.3",
159
- "@babel/plugin-transform-react-jsx": "7.28.6",
158
+ "@babel/parser": "7.29.7",
159
+ "@babel/plugin-transform-react-jsx": "7.29.7",
160
160
  "@babel/plugin-transform-typescript": "^7.26.8",
161
- "@babel/traverse": "7.29.0",
161
+ "@babel/traverse": "7.29.7",
162
162
  "@cedarjs/babel-config": "4.2.0",
163
163
  "@cedarjs/cli-helpers": "4.2.0",
164
164
  "@cedarjs/graphql-server": "4.2.0",
@@ -171,40 +171,47 @@
171
171
  "@graphql-codegen/client-preset": "5.3.0",
172
172
  "@graphql-codegen/core": "5.0.2",
173
173
  "@graphql-codegen/fragment-matcher": "6.0.1",
174
+ "@graphql-codegen/plugin-helpers": "6.3.0",
174
175
  "@graphql-codegen/schema-ast": "5.0.2",
175
176
  "@graphql-codegen/typed-document-node": "6.1.8",
176
177
  "@graphql-codegen/typescript": "5.0.10",
177
178
  "@graphql-codegen/typescript-operations": "5.1.0",
178
179
  "@graphql-codegen/typescript-react-apollo": "4.4.2",
179
180
  "@graphql-codegen/typescript-resolvers": "5.1.8",
181
+ "@graphql-codegen/visitor-plugin-common": "6.3.0",
182
+ "@graphql-tools/code-file-loader": "8.1.29",
180
183
  "@graphql-tools/documents": "1.0.1",
184
+ "@graphql-tools/graphql-file-loader": "8.1.12",
185
+ "@graphql-tools/load": "8.1.8",
186
+ "@graphql-tools/merge": "9.1.9",
181
187
  "@prisma/dmmf": "7.8.0",
182
188
  "@prisma/internals": "7.8.0",
183
189
  "@sdl-codegen/node": "2.0.1",
184
190
  "ansis": "4.2.0",
185
191
  "deepmerge": "4.3.1",
186
192
  "esbuild": "0.27.7",
193
+ "execa": "5.1.1",
187
194
  "fast-glob": "3.3.3",
188
195
  "graphql": "16.13.2",
189
196
  "kill-port": "1.6.1",
190
- "prettier": "3.8.3",
197
+ "prettier": "3.8.4",
191
198
  "rimraf": "6.1.3",
192
199
  "source-map": "0.7.6",
193
200
  "string-env-interpolation": "1.0.1",
194
- "systeminformation": "5.31.5",
201
+ "systeminformation": "5.31.7",
195
202
  "termi-link": "1.1.0",
196
203
  "ts-node": "10.9.2",
197
204
  "typescript": "5.9.3",
198
- "vite": "7.3.2"
205
+ "vite": "7.3.5"
199
206
  },
200
207
  "devDependencies": {
201
- "@arethetypeswrong/cli": "0.18.2",
208
+ "@arethetypeswrong/cli": "0.18.4",
202
209
  "@cedarjs/framework-tools": "4.2.0",
203
210
  "concurrently": "9.2.1",
204
211
  "graphql-tag": "2.12.6",
205
- "publint": "0.3.20",
206
- "tsx": "4.21.0",
207
- "vitest": "3.2.4"
212
+ "publint": "0.3.21",
213
+ "tsx": "4.22.4",
214
+ "vitest": "3.2.6"
208
215
  },
209
216
  "engines": {
210
217
  "node": ">=24"