@cedarjs/cli 2.5.1 → 2.5.2-next.16

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.
@@ -58,10 +58,10 @@ function showLegacyEslintDeprecationWarning(legacyFiles) {
58
58
  console.warn(" See more here: https://github.com/cedarjs/cedar/pull/629");
59
59
  console.warn("");
60
60
  }
61
- const command = "lint [path..]";
61
+ const command = "lint [paths..]";
62
62
  const description = "Lint your files";
63
63
  const builder = (yargs) => {
64
- yargs.positional("path", {
64
+ yargs.positional("paths", {
65
65
  description: "Specify file(s) or directory(ies) to lint relative to project root",
66
66
  type: "array"
67
67
  }).option("fix", {
@@ -79,7 +79,7 @@ const builder = (yargs) => {
79
79
  )}`
80
80
  );
81
81
  };
82
- const handler = async ({ path: path2, fix, format }) => {
82
+ const handler = async ({ paths, fix, format }) => {
83
83
  recordTelemetryAttributes({ command: "lint", fix, format });
84
84
  const config = getConfig();
85
85
  const legacyConfigFiles = detectLegacyEslintConfig();
@@ -87,21 +87,18 @@ const handler = async ({ path: path2, fix, format }) => {
87
87
  showLegacyEslintDeprecationWarning(legacyConfigFiles);
88
88
  }
89
89
  try {
90
- const pathString = path2?.join(" ");
91
90
  const sbPath = getPaths().web.storybook;
92
- const args = [
93
- "eslint",
94
- fix && "--fix",
95
- "--format",
96
- format,
97
- !pathString && fs.existsSync(getPaths().web.src) && "web/src",
98
- !pathString && fs.existsSync(getPaths().web.config) && "web/config",
99
- !pathString && fs.existsSync(sbPath) && "web/.storybook",
100
- !pathString && fs.existsSync(getPaths().scripts) && "scripts",
101
- !pathString && fs.existsSync(getPaths().api.src) && "api/src",
102
- pathString
103
- ].filter(Boolean);
104
- const result = await execa("yarn", args, {
91
+ const args = ["eslint", fix && "--fix", "--format", format, ...paths];
92
+ if (paths.length === 0) {
93
+ args.push(
94
+ fs.existsSync(getPaths().web.src) && "web/src",
95
+ fs.existsSync(getPaths().web.config) && "web/config",
96
+ fs.existsSync(sbPath) && "web/.storybook",
97
+ fs.existsSync(getPaths().scripts) && "scripts",
98
+ fs.existsSync(getPaths().api.src) && "api/src"
99
+ );
100
+ }
101
+ const result = await execa("yarn", args.filter(Boolean), {
105
102
  cwd: getPaths().base,
106
103
  stdio: "inherit"
107
104
  });
@@ -0,0 +1,68 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { isTypeScriptProject } from "@cedarjs/cli-helpers";
4
+ import { getPaths } from "@cedarjs/project-config";
5
+ function addRealtimeToGraphqlHandler(ctx, task, force) {
6
+ const graphqlHandlerPath = path.join(
7
+ getPaths().api.functions,
8
+ `graphql.${isTypeScriptProject() ? "ts" : "js"}`
9
+ );
10
+ if (!fs.existsSync(graphqlHandlerPath)) {
11
+ ctx.realtimeHandlerSkipped = true;
12
+ task.skip("GraphQL handler not found");
13
+ return;
14
+ }
15
+ const contentLines = fs.readFileSync(graphqlHandlerPath).toString().split("\n");
16
+ const importLineRegex = /^import {.*realtime.*} from ['"]src\/lib\/realtime['"];?$/;
17
+ const multilineImportRegex = /^} from ['"]src\/lib\/realtime['"];?$/;
18
+ const hasRealtimeImport = contentLines.some((line) => {
19
+ return importLineRegex.test(line) || multilineImportRegex.test(line);
20
+ });
21
+ if (hasRealtimeImport && !force) {
22
+ ctx.realtimeHandlerSkipped = true;
23
+ task.skip("Realtime import already exists");
24
+ return;
25
+ }
26
+ const handlerIndex = contentLines.findLastIndex(
27
+ (line) => line === "export const handler = createGraphQLHandler({"
28
+ );
29
+ if (handlerIndex === -1) {
30
+ ctx.realtimeHandlerSkipped = true;
31
+ task.skip("Unexpected syntax. Handler not found");
32
+ return;
33
+ }
34
+ const handlerLines = contentLines.slice(handlerIndex);
35
+ const hasRealtimeOption = handlerLines.some(
36
+ (line) => /^\s*realtime\b/.test(line)
37
+ );
38
+ if (hasRealtimeOption && !force) {
39
+ ctx.realtimeHandlerSkipped = true;
40
+ task.skip("Realtime option already exists");
41
+ return;
42
+ }
43
+ const lastImportIndex = contentLines.slice(0, handlerIndex).findLastIndex((line) => line.startsWith("import "));
44
+ if (lastImportIndex === -1) {
45
+ ctx.realtimeHandlerSkipped = true;
46
+ task.skip("Unexpected syntax. No imports found");
47
+ return;
48
+ }
49
+ contentLines.splice(
50
+ lastImportIndex + 1,
51
+ 0,
52
+ "import { realtime } from 'src/lib/realtime'"
53
+ );
54
+ const handlerIndexAfterSplice = handlerIndex + 1;
55
+ const sdlsIndex = handlerLines.findLastIndex(
56
+ (line) => /^\s*sdls,$/.test(line)
57
+ );
58
+ if (sdlsIndex === -1) {
59
+ ctx.realtimeHandlerSkipped = true;
60
+ task.skip("Unexpected syntax. `sdls` option not found");
61
+ return;
62
+ }
63
+ contentLines.splice(handlerIndexAfterSplice + sdlsIndex, 0, " realtime,");
64
+ fs.writeFileSync(graphqlHandlerPath, contentLines.join("\n"));
65
+ }
66
+ export {
67
+ addRealtimeToGraphqlHandler
68
+ };
@@ -1,5 +1,6 @@
1
1
  import fs from "node:fs";
2
2
  import path from "path";
3
+ import execa from "execa";
3
4
  import { Listr } from "listr2";
4
5
  import { addApiPackages } from "@cedarjs/cli-helpers";
5
6
  import { generate as generateTypes } from "@cedarjs/internal/dist/generate/generate";
@@ -9,6 +10,7 @@ import c from "../../../lib/colors.js";
9
10
  import { getPaths, transformTSToJS, writeFile } from "../../../lib/index.js";
10
11
  import { isTypeScriptProject, serverFileExists } from "../../../lib/project.js";
11
12
  import { setupServerFileTasks } from "../server-file/serverFileHandler.js";
13
+ import { addRealtimeToGraphqlHandler } from "./addRealtimeToGraphql.js";
12
14
  const { version } = JSON.parse(
13
15
  fs.readFileSync(
14
16
  path.resolve(import.meta.dirname, "../../../../package.json"),
@@ -26,7 +28,7 @@ async function handler({ force, includeExamples, verbose }) {
26
28
  [
27
29
  addApiPackages(["ioredis@^5", `@cedarjs/realtime@${version}`]),
28
30
  {
29
- title: "Adding the realtime api lib ...",
31
+ title: "Adding the realtime api lib...",
30
32
  task: async () => {
31
33
  const serverFileTemplateContent = fs.readFileSync(
32
34
  path.resolve(
@@ -48,7 +50,13 @@ async function handler({ force, includeExamples, verbose }) {
48
50
  }
49
51
  },
50
52
  {
51
- title: "Adding Countdown example subscription ...",
53
+ title: "Enabling realtime support in the GraphQL handler...",
54
+ task: (ctx, task) => {
55
+ addRealtimeToGraphqlHandler(ctx, task, force);
56
+ }
57
+ },
58
+ {
59
+ title: "Adding Countdown example subscription...",
52
60
  enabled: () => includeExamples,
53
61
  task: async () => {
54
62
  let exampleSubscriptionTemplateContent = fs.readFileSync(
@@ -84,7 +92,7 @@ async function handler({ force, includeExamples, verbose }) {
84
92
  }
85
93
  },
86
94
  {
87
- title: "Adding NewMessage example subscription ...",
95
+ title: "Adding NewMessage example subscription...",
88
96
  enabled: () => includeExamples,
89
97
  task: async () => {
90
98
  const exampleSdlTemplateContent = fs.readFileSync(
@@ -157,7 +165,7 @@ async function handler({ force, includeExamples, verbose }) {
157
165
  }
158
166
  },
159
167
  {
160
- title: "Adding Auctions example live query ...",
168
+ title: "Adding Auctions example live query...",
161
169
  enabled: () => includeExamples,
162
170
  task: async () => {
163
171
  const exampleSdlTemplateContent = fs.readFileSync(
@@ -202,7 +210,7 @@ async function handler({ force, includeExamples, verbose }) {
202
210
  }
203
211
  },
204
212
  {
205
- title: "Adding Defer example queries ...",
213
+ title: "Adding Defer example queries...",
206
214
  enabled: () => includeExamples,
207
215
  task: async () => {
208
216
  const exampleSdlTemplateContent = fs.readFileSync(
@@ -247,7 +255,7 @@ async function handler({ force, includeExamples, verbose }) {
247
255
  }
248
256
  },
249
257
  {
250
- title: "Adding Stream example queries ...",
258
+ title: "Adding Stream example queries...",
251
259
  enabled: () => includeExamples,
252
260
  task: async () => {
253
261
  const exampleSdlTemplateContent = fs.readFileSync(
@@ -292,13 +300,31 @@ async function handler({ force, includeExamples, verbose }) {
292
300
  }
293
301
  },
294
302
  {
295
- title: `Generating types ...`,
303
+ title: `Generating types...`,
296
304
  task: async () => {
297
305
  await generateTypes();
298
306
  console.log(
299
307
  "Note: You may need to manually restart GraphQL in VSCode to see the new types take effect.\n\n"
300
308
  );
301
309
  }
310
+ },
311
+ {
312
+ title: "Cleaning up...",
313
+ task: () => {
314
+ const graphqlHandlerPath = path.join(
315
+ getPaths().api.functions,
316
+ `graphql.${isTypeScriptProject() ? "ts" : "js"}`
317
+ );
318
+ execa.sync(
319
+ "yarn",
320
+ ["cedar", "lint", "--fix", graphqlHandlerPath, realtimeLibFilePath],
321
+ {
322
+ cwd: getPaths().base,
323
+ // Silently ignore errors
324
+ reject: false
325
+ }
326
+ );
327
+ }
302
328
  }
303
329
  ],
304
330
  {
@@ -311,6 +337,22 @@ async function handler({ force, includeExamples, verbose }) {
311
337
  tasks.add(setupServerFileTasks({ force }));
312
338
  }
313
339
  await tasks.run();
340
+ if (tasks.ctx?.realtimeHandlerSkipped) {
341
+ const graphqlHandlerPath = path.join(
342
+ getPaths().api.functions,
343
+ `graphql.${isTypeScriptProject() ? "ts" : "js"}`
344
+ );
345
+ const relativePath = path.relative(getPaths().base, graphqlHandlerPath);
346
+ console.log();
347
+ console.log(
348
+ c.warning(
349
+ `Note: The setup command skipped adding realtime to your GraphQL handler. Please review ${relativePath}, and manually add it if needed.`
350
+ )
351
+ );
352
+ console.log(
353
+ "You want to make sure you have an import like `import { realtime } from '@cedarjs/realtime'`, and that you pass `realtime` to the call to `createGraphQLHandler`."
354
+ );
355
+ }
314
356
  } catch (e) {
315
357
  errorTelemetry(process.argv, e.message);
316
358
  console.error(c.error(e.message));
@@ -1,5 +1,3 @@
1
- // api/src/graphql/auctions.sdl.ts
2
-
3
1
  export const schema = gql`
4
2
  type Query {
5
3
  auction(id: ID!): Auction @requireAuth
@@ -1,4 +1,3 @@
1
- // api/src/services/auctions/auctions.ts
2
1
  import type { LiveQueryStorageMechanism } from '@cedarjs/realtime'
3
2
 
4
3
  import { logger } from 'src/lib/logger'
@@ -1,4 +1,4 @@
1
- import { RedwoodRealtimeOptions } from '@cedarjs/realtime'
1
+ import { CedarRealtimeOptions } from '@cedarjs/realtime'
2
2
 
3
3
  import subscriptions from 'src/subscriptions/**/*.{js,ts}'
4
4
 
@@ -14,21 +14,23 @@ import subscriptions from 'src/subscriptions/**/*.{js,ts}'
14
14
  *
15
15
  * Realtime supports Live Queries and Subscriptions over GraphQL SSE.
16
16
  *
17
- * Live Queries are GraphQL queries that are automatically re-run when the data they depend on changes.
17
+ * Live Queries are GraphQL queries that are automatically re-run when the data
18
+ * they depend on changes.
18
19
  *
19
- * Subscriptions are GraphQL queries that are run when a client subscribes to a channel.
20
+ * Subscriptions are GraphQL queries that are run when a client subscribes to a
21
+ * channel.
20
22
  *
21
23
  * CedarJS Realtime
22
24
  * - uses a publish/subscribe model to broadcast data to clients.
23
25
  * - uses a store to persist Live Query and Subscription data.
24
- * - and enable defer and stream directives to improve latency
25
- * for clients by sending data the most important data as soon as it's ready.
26
+ * - and enable defer and stream directives to improve latency for clients by
27
+ * sending data the most important data as soon as it's ready.
26
28
  *
27
29
  * CedarJS Realtime supports in-memory and Redis stores:
28
30
  * - In-memory stores are useful for development and testing.
29
31
  * - Redis stores are useful for production.
30
32
  */
31
- export const realtime: RedwoodRealtimeOptions = {
33
+ export const realtime: CedarRealtimeOptions = {
32
34
  subscriptions: {
33
35
  subscriptions,
34
36
  store: 'in-memory',
package/dist/lib/exec.js CHANGED
@@ -8,7 +8,9 @@ import {
8
8
  cedarCellTransform,
9
9
  cedarjsDirectoryNamedImportPlugin,
10
10
  cedarjsJobPathInjectorPlugin,
11
- cedarSwapApolloProvider
11
+ cedarSwapApolloProvider,
12
+ cedarImportDirPlugin,
13
+ cedarAutoImportsPlugin
12
14
  } from "@cedarjs/vite";
13
15
  async function runScriptFunction({
14
16
  path: scriptPath,
@@ -72,7 +74,9 @@ async function runScriptFunction({
72
74
  cedarjsDirectoryNamedImportPlugin(),
73
75
  cedarCellTransform(),
74
76
  cedarjsJobPathInjectorPlugin(),
75
- cedarSwapApolloProvider()
77
+ cedarSwapApolloProvider(),
78
+ cedarImportDirPlugin(),
79
+ cedarAutoImportsPlugin()
76
80
  ]
77
81
  });
78
82
  if (Number(viteVersion.split(".")[0]) < 6) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cedarjs/cli",
3
- "version": "2.5.1",
3
+ "version": "2.5.2-next.16+a27a893fb",
4
4
  "description": "The CedarJS Command Line",
5
5
  "repository": {
6
6
  "type": "git",
@@ -31,17 +31,18 @@
31
31
  "test:watch": "vitest watch"
32
32
  },
33
33
  "dependencies": {
34
+ "@babel/parser": "7.29.0",
34
35
  "@babel/preset-typescript": "7.28.5",
35
36
  "@babel/runtime-corejs3": "7.29.0",
36
- "@cedarjs/api-server": "2.5.1",
37
- "@cedarjs/cli-helpers": "2.5.1",
38
- "@cedarjs/fastify-web": "2.5.1",
39
- "@cedarjs/internal": "2.5.1",
40
- "@cedarjs/prerender": "2.5.1",
41
- "@cedarjs/project-config": "2.5.1",
42
- "@cedarjs/structure": "2.5.1",
43
- "@cedarjs/telemetry": "2.5.1",
44
- "@cedarjs/web-server": "2.5.1",
37
+ "@cedarjs/api-server": "2.5.2-next.16+a27a893fb",
38
+ "@cedarjs/cli-helpers": "2.5.2-next.16+a27a893fb",
39
+ "@cedarjs/fastify-web": "2.5.2-next.16+a27a893fb",
40
+ "@cedarjs/internal": "2.5.2-next.16+a27a893fb",
41
+ "@cedarjs/prerender": "2.5.2-next.16+a27a893fb",
42
+ "@cedarjs/project-config": "2.5.2-next.16+a27a893fb",
43
+ "@cedarjs/structure": "2.5.2-next.16+a27a893fb",
44
+ "@cedarjs/telemetry": "2.5.2-next.16+a27a893fb",
45
+ "@cedarjs/web-server": "2.5.2-next.16+a27a893fb",
45
46
  "@listr2/prompt-adapter-enquirer": "2.0.16",
46
47
  "@opentelemetry/api": "1.9.0",
47
48
  "@opentelemetry/core": "1.30.1",
@@ -78,6 +79,7 @@
78
79
  "prettier": "3.8.1",
79
80
  "prisma": "6.19.2",
80
81
  "prompts": "2.4.2",
82
+ "recast": "0.23.11",
81
83
  "rimraf": "6.1.2",
82
84
  "semver": "7.7.3",
83
85
  "smol-toml": "1.6.0",
@@ -104,5 +106,5 @@
104
106
  "publishConfig": {
105
107
  "access": "public"
106
108
  },
107
- "gitHead": "376b27018be4efd01664bce326be74dfde0d650a"
109
+ "gitHead": "a27a893fb8f6883f3bf121dad4d3edf7696484fe"
108
110
  }