@cedarjs/cli 2.3.0 → 2.3.1-next.79

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.
Files changed (36) hide show
  1. package/dist/commands/{buildHandler.js → build/buildHandler.js} +42 -34
  2. package/dist/commands/build/buildPackagesTask.js +46 -0
  3. package/dist/commands/build.js +22 -8
  4. package/dist/commands/dev/apiDebugFlag.js +18 -0
  5. package/dist/commands/{devHandler.js → dev/devHandler.js} +60 -64
  6. package/dist/commands/dev/packageWatchCommands.js +54 -0
  7. package/dist/commands/dev.js +25 -7
  8. package/dist/commands/generate/cell/cellHandler.js +3 -1
  9. package/dist/commands/generate/component/templates/test.tsx.template +1 -1
  10. package/dist/commands/generate/function/functionHandler.js +1 -1
  11. package/dist/commands/generate/function/templates/function.ts.template +1 -1
  12. package/dist/commands/generate/function/templates/test.ts.template +11 -11
  13. package/dist/commands/generate/layout/templates/test.tsx.template +1 -1
  14. package/dist/commands/generate/package/packageHandler.js +23 -0
  15. package/dist/commands/generate/package/templates/README.md.template +1 -1
  16. package/dist/commands/generate/package/templates/package.json.template +7 -0
  17. package/dist/commands/generate/package/templates/tsconfig.json.template +1 -0
  18. package/dist/commands/generate/page/templates/test.tsx.template +1 -1
  19. package/dist/commands/setup/deploy/templates/netlify.js +7 -6
  20. package/dist/commands/setup/mailer/templates/mailer.ts.template +2 -1
  21. package/dist/commands/studio.js +1 -1
  22. package/dist/commands/studioHandler.js +1 -29
  23. package/dist/commands/test.js +2 -2
  24. package/dist/commands/testEsm.js +2 -2
  25. package/dist/commands/testHandler.js +3 -3
  26. package/dist/commands/testHandlerEsm.js +3 -3
  27. package/dist/commands/type-check.js +2 -2
  28. package/dist/index.js +39 -18
  29. package/dist/lib/generatePrismaClient.js +6 -2
  30. package/dist/lib/index.js +2 -3
  31. package/dist/lib/merge/algorithms.js +1 -1
  32. package/dist/lib/merge/index.js +3 -2
  33. package/dist/lib/merge/strategy.js +4 -4
  34. package/dist/lib/project.js +24 -10
  35. package/dist/lib/test.js +1 -1
  36. package/package.json +13 -12
@@ -1,11 +1,11 @@
1
1
  import { mockHttpEvent, mockContext } from '@cedarjs/testing/api'
2
2
 
3
- import { handler } from './${name}'
3
+ import { handler } from './${camelName}'
4
4
 
5
- // Improve this test with help from the Redwood Testing Doc:
6
- // https://cedarjs.com/docs/testing#testing-functions
5
+ // Improve this test with help from the CedarJS Testing Doc:
6
+ // https://cedarjs.com/docs/testing#testing-functions
7
7
 
8
- describe('${name} function', () => {
8
+ describe('${camelName} function', () => {
9
9
 
10
10
  it('Should respond with 200', async () => {
11
11
  const httpEvent = mockHttpEvent({
@@ -18,13 +18,13 @@ describe('${name} function', () => {
18
18
  const { data } = JSON.parse(response.body)
19
19
 
20
20
  expect(response.statusCode).toBe(200)
21
- expect(data).toBe('${name} function')
21
+ expect(data).toBe('${camelName} function')
22
22
  })
23
23
 
24
- // You can also use scenarios to test your api functions
25
- // See guide here: https://cedarjs.com/docs/testing#scenarios
26
- //
27
- // scenario('Scenario test', async () => {
28
- //
29
- // })
24
+ // You can also use scenarios to test your api functions
25
+ // See guide here: https://cedarjs.com/docs/testing#scenarios
26
+ //
27
+ // scenario('Scenario test', async () => {
28
+ //
29
+ // })
30
30
  })
@@ -2,7 +2,7 @@ import { render } from '@cedarjs/testing/web'
2
2
 
3
3
  import ${pascalName}Layout from './${pascalName}Layout'
4
4
 
5
- // Improve this test with help from the Redwood Testing Doc:
5
+ // Improve this test with help from the CedarJS Testing Doc:
6
6
  // https://cedarjs.com/docs/testing#testing-pages-layouts
7
7
 
8
8
  describe('${pascalName}Layout', () => {
@@ -39,6 +39,24 @@ async function updateTsconfig(task) {
39
39
  );
40
40
  await fs.promises.writeFile(tsconfigPath, tsconfigLines.join("\n"));
41
41
  }
42
+ async function updateGitignore(task) {
43
+ const gitignorePath = path.join(getPaths().base, ".gitignore");
44
+ const gitignore = await fs.promises.readFile(gitignorePath, "utf8");
45
+ const gitignoreLines = gitignore.split("\n");
46
+ if (gitignoreLines.some((line) => line === "tsconfig.tsbuildinfo")) {
47
+ task.skip("tsconfig already up to date");
48
+ return;
49
+ }
50
+ const yarnErrorLogLineIndex = gitignoreLines.findIndex(
51
+ (line) => line === "yarn-error.log"
52
+ );
53
+ if (yarnErrorLogLineIndex === -1) {
54
+ gitignoreLines.push("tsconfig.tsbuildinfo");
55
+ } else {
56
+ gitignoreLines.splice(yarnErrorLogLineIndex, 0, "tsconfig.tsbuildinfo");
57
+ }
58
+ await fs.promises.writeFile(gitignorePath, gitignoreLines.join("\n"));
59
+ }
42
60
  async function installAndBuild(folderName) {
43
61
  const packagePath = path.join("packages", folderName);
44
62
  await execa("yarn", ["install"], { stdio: "inherit", cwd: getPaths().base });
@@ -114,6 +132,10 @@ const handler = async ({ name, force, ...rest }) => {
114
132
  title: "Updating api side tsconfig file...",
115
133
  task: (_ctx, task) => updateTsconfig(task)
116
134
  },
135
+ {
136
+ title: "Updating .gitignore...",
137
+ task: (_ctx, task) => updateGitignore(task)
138
+ },
117
139
  {
118
140
  title: "Generating package files...",
119
141
  task: async (ctx) => {
@@ -154,5 +176,6 @@ const handler = async ({ name, force, ...rest }) => {
154
176
  export {
155
177
  handler,
156
178
  nameVariants,
179
+ updateGitignore,
157
180
  updateTsconfig
158
181
  };
@@ -11,5 +11,5 @@ into your code:
11
11
  ```
12
12
 
13
13
  ```javascript
14
- import { ${camelName} } from '${packageName}';
14
+ import { ${camelName} } from '${packageName}'
15
15
  ```
@@ -4,6 +4,13 @@
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ }
13
+ },
7
14
  "scripts": {
8
15
  "build": "tsc",
9
16
  "watch": "tsc --watch"
@@ -13,4 +13,5 @@
13
13
  "declarationMap": true,
14
14
  },
15
15
  "include": ["src"],
16
+ "exclude": ["**/*.test.ts"],
16
17
  }
@@ -2,7 +2,7 @@ import { render } from '@cedarjs/testing/web'
2
2
 
3
3
  import ${pascalName}Page from './${pascalName}Page'
4
4
 
5
- // Improve this test with help from the Redwood Testing Doc:
5
+ // Improve this test with help from the CedarJS Testing Doc:
6
6
  // https://cedarjs.com/docs/testing#testing-pages-layouts
7
7
 
8
8
  describe('${pascalName}Page', () => {
@@ -6,20 +6,21 @@ const NETLIFY_TOML = `[build]
6
6
  functions = "api/dist/functions"
7
7
 
8
8
  [build.environment]
9
- NODE_VERSION = "20"
9
+ NODE_VERSION = "24"
10
10
 
11
11
  [[redirects]]
12
12
  from = "/*"
13
13
  to = "/200.html"
14
14
  status = 200
15
15
 
16
- # To use Netlify Dev, install Netlify's CLI (\`netlify-cli\`) from NPM and use \`netlify link\`
17
- # to connect your local project to a site on Netlify. Then run \`netlify dev\`.
16
+ # To use Netlify Dev, install Netlify's CLI (\`netlify-cli\`) from NPM and use
17
+ # \`netlify link\` to connect your local project to a site on Netlify. Then run
18
+ # \`netlify dev\`.
18
19
  #
19
20
  # Quick links to the docs:
20
- # - Netlfy Dev https://www.netlify.com/products/dev
21
- # - Netlify's CLI https://docs.netlify.com/cli/get-started/#installation
22
- # - \`netlify link\` https://docs.netlify.com/cli/get-started/#link-and-unlink-sites
21
+ # - Netlify Dev https://docs.netlify.com/api-and-cli-guides/cli-guides/local-development
22
+ # - Netlify's CLI https://docs.netlify.com/api-and-cli-guides/cli-guides/get-started-with-cli/
23
+ # - \`netlify link\` https://cli.netlify.com/commands/link/
23
24
  [dev]
24
25
  framework = "redwoodjs"
25
26
  # Make sure \`targetPort\` matches \`web.port\` in the \`redwood.toml\`:
@@ -7,7 +7,8 @@ import { logger } from 'src/lib/logger'
7
7
  export const mailer = new Mailer({
8
8
  handling: {
9
9
  handlers: {
10
- // TODO: Update this handler config or switch it out for a different handler completely
10
+ // TODO: Update this handler config or switch it out for a different
11
+ // handler completely
11
12
  nodemailer: new NodemailerMailHandler({
12
13
  transport: {
13
14
  host: 'localhost',
@@ -1,6 +1,6 @@
1
1
  import { recordTelemetryAttributes } from "@cedarjs/cli-helpers";
2
2
  const command = "studio";
3
- const description = "Run the Redwood development studio";
3
+ const description = "Run the CedarJS development studio";
4
4
  function builder(yargs) {
5
5
  yargs.option("open", {
6
6
  default: true,
@@ -1,17 +1,11 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- import semver from "semver";
4
- import { getPaths } from "@cedarjs/project-config";
5
1
  import { isModuleInstalled, installModule } from "../lib/packages.js";
6
2
  const handler = async (options) => {
7
3
  try {
8
4
  if (!isModuleInstalled("@cedarjs/studio")) {
9
- const minVersions = ["7.0.0-canary.889", "7.x", "8.0.0-0"];
10
- assertRedwoodVersion(minVersions);
11
5
  console.log(
12
6
  "The studio package is not installed, installing it for you, this may take a moment..."
13
7
  );
14
- await installModule("@cedarjs/studio", "12");
8
+ await installModule("@cedarjs/studio", "2");
15
9
  console.log("Studio package installed successfully.");
16
10
  const installedRealtime = await installModule("@cedarjs/realtime");
17
11
  if (installedRealtime) {
@@ -34,28 +28,6 @@ const handler = async (options) => {
34
28
  process.exit(1);
35
29
  }
36
30
  };
37
- function assertRedwoodVersion(minVersions) {
38
- const rwVersion = getProjectRedwoodVersion();
39
- const coercedRwVersion = semver.coerce(rwVersion);
40
- if (minVersions.some((minVersion) => {
41
- const v = semver.valid(minVersion) || semver.coerce(minVersion);
42
- const coercedMin = semver.coerce(minVersion);
43
- return semver.gte(rwVersion, v) && (coercedRwVersion.major === coercedMin.major ? semver.prerelease(rwVersion)?.[0] === semver.prerelease(v)?.[0] : true);
44
- })) {
45
- return;
46
- }
47
- console.error(
48
- `The studio command requires Redwood version ${minVersions[0]} or greater, you are using ${rwVersion}.`
49
- );
50
- process.exit(1);
51
- }
52
- function getProjectRedwoodVersion() {
53
- const { devDependencies } = JSON.parse(
54
- fs.readFileSync(path.join(getPaths().base, "package.json"), "utf-8")
55
- );
56
- return devDependencies["@cedarjs/core"];
57
- }
58
31
  export {
59
- assertRedwoodVersion,
60
32
  handler
61
33
  };
@@ -1,11 +1,11 @@
1
1
  import { terminalLink } from "termi-link";
2
2
  import c from "../lib/colors.js";
3
- import { sides } from "../lib/project.js";
3
+ import { workspaces } from "../lib/project.js";
4
4
  const command = "test [filter..]";
5
5
  const description = "Run Jest tests. Defaults to watch mode";
6
6
  const builder = (yargs) => {
7
7
  yargs.strict(false).positional("filter", {
8
- default: sides(),
8
+ default: workspaces(),
9
9
  description: "Which side(s) to test, and/or a regular expression to match against your test files to filter by",
10
10
  type: "array"
11
11
  }).option("watch", {
@@ -1,6 +1,6 @@
1
1
  import { terminalLink } from "termi-link";
2
2
  import c from "../lib/colors.js";
3
- import { sides } from "../lib/project.js";
3
+ import { workspaces } from "../lib/project.js";
4
4
  const command = "test [filter..]";
5
5
  const description = "Run Vitest tests. Defaults to watch mode";
6
6
  const builder = (yargs) => {
@@ -10,7 +10,7 @@ const builder = (yargs) => {
10
10
  );
11
11
  const vitestTip = c.tip("yarn vitest --help");
12
12
  yargs.strict(false).positional("filter", {
13
- default: sides(),
13
+ default: workspaces(),
14
14
  description: "Which side(s) to test, and/or a regular expression to match against your test files to filter by",
15
15
  type: "array"
16
16
  }).option("db-push", {
@@ -81,11 +81,11 @@ const handler = async ({
81
81
  }
82
82
  });
83
83
  const sides = filterParams.filter(
84
- (filterString) => project.sides().includes(filterString)
84
+ (filterString) => project.workspaces().includes(filterString)
85
85
  );
86
86
  const jestFilterArgs = [
87
87
  ...filterParams.filter(
88
- (filterString) => !project.sides().includes(filterString)
88
+ (filterString) => !project.workspaces().includes(filterString)
89
89
  )
90
90
  ];
91
91
  const jestArgs = [
@@ -99,7 +99,7 @@ const handler = async ({
99
99
  jestArgs.push(hasSourceControl ? "--watch" : "--watchAll");
100
100
  }
101
101
  if (!sides.length) {
102
- project.sides().forEach((side) => sides.push(side));
102
+ project.workspaces().forEach((side) => sides.push(side));
103
103
  }
104
104
  if (sides.length > 0) {
105
105
  jestArgs.push("--projects", ...sides);
@@ -34,11 +34,11 @@ const handler = async ({
34
34
  }
35
35
  });
36
36
  const sides = filterParams.filter(
37
- (filterString) => project.sides().includes(filterString)
37
+ (filterString) => project.workspaces().includes(filterString)
38
38
  );
39
39
  const vitestFilterArgs = [
40
40
  ...filterParams.filter(
41
- (filterString) => !project.sides().includes(filterString)
41
+ (filterString) => !project.workspaces().includes(filterString)
42
42
  )
43
43
  ];
44
44
  const vitestArgs = [
@@ -50,7 +50,7 @@ const handler = async ({
50
50
  vitestArgs.push("--run");
51
51
  }
52
52
  if (!sides.length) {
53
- project.sides().forEach((side) => sides.push(side));
53
+ project.workspaces().forEach((side) => sides.push(side));
54
54
  }
55
55
  sides.forEach((side) => vitestArgs.push("--project", side));
56
56
  try {
@@ -1,11 +1,11 @@
1
1
  import { terminalLink } from "termi-link";
2
- import { sides } from "../lib/project.js";
2
+ import { workspaces } from "../lib/project.js";
3
3
  const command = "type-check [sides..]";
4
4
  const aliases = ["tsc", "tc"];
5
5
  const description = "Run a TypeScript compiler check on your project";
6
6
  const builder = (yargs) => {
7
7
  yargs.strict(false).positional("sides", {
8
- default: sides(),
8
+ default: workspaces(),
9
9
  description: "Which side(s) to run a typecheck on",
10
10
  type: "array"
11
11
  }).option("prisma", {
package/dist/index.js CHANGED
@@ -30,6 +30,7 @@ import * as testCommandEsm from "./commands/testEsm.js";
30
30
  import * as tstojsCommand from "./commands/ts-to-js.js";
31
31
  import * as typeCheckCommand from "./commands/type-check.js";
32
32
  import * as upgradeCommand from "./commands/upgrade/upgrade.js";
33
+ import c from "./lib/colors.js";
33
34
  import { exitWithError } from "./lib/exit.js";
34
35
  import { findUp } from "./lib/index.js";
35
36
  import * as updateCheck from "./lib/updateCheck.js";
@@ -45,25 +46,22 @@ let { cwd, telemetry, help, version } = Parser(hideBin(process.argv), {
45
46
  }
46
47
  });
47
48
  cwd ??= process.env.RWJS_CWD;
48
- try {
49
- if (cwd) {
50
- if (!fs.existsSync(path.join(cwd, "redwood.toml"))) {
51
- throw new Error(`Couldn't find a "redwood.toml" file in ${cwd}`);
52
- }
53
- } else {
54
- const redwoodTOMLPath = findUp("redwood.toml");
55
- if (!redwoodTOMLPath) {
56
- throw new Error(
57
- `Couldn't find up a "redwood.toml" file from ${process.cwd()}`
58
- );
59
- }
60
- cwd = path.dirname(redwoodTOMLPath);
49
+ cwd = getTomlDir(cwd);
50
+ process.env.RWJS_CWD = cwd;
51
+ if (process.argv[1]?.endsWith("redwood.js")) {
52
+ const tomlPath = path.join(cwd, "redwood.toml");
53
+ const toml = fs.readFileSync(tomlPath, "utf8");
54
+ const disableWarning = /^\s*rwBinWarning\s*=\s*false/m.test(toml);
55
+ if (!disableWarning) {
56
+ console.warn();
57
+ console.warn(
58
+ c.warning(
59
+ "'yarn rw' and 'yarn redwood' have been deprecated. Please use 'yarn cedar' instead."
60
+ )
61
+ );
62
+ console.warn();
61
63
  }
62
- } catch (error) {
63
- console.error(error.message);
64
- process.exit(1);
65
64
  }
66
- process.env.RWJS_CWD = cwd;
67
65
  if (process.cwd() !== cwd) {
68
66
  process.chdir(cwd);
69
67
  }
@@ -99,7 +97,7 @@ async function main() {
99
97
  }
100
98
  }
101
99
  async function runYargs() {
102
- const yarg = yargs(hideBin(process.argv)).scriptName("rw").middleware(
100
+ const yarg = yargs(hideBin(process.argv)).scriptName("cedar").middleware(
103
101
  [
104
102
  // We've already handled `cwd` above, but it may still be in `argv`.
105
103
  // We don't need it anymore so let's get rid of it.
@@ -145,4 +143,27 @@ async function runYargs() {
145
143
  }
146
144
  });
147
145
  }
146
+ function getTomlDir(cwd2) {
147
+ let tomlDir = "";
148
+ try {
149
+ if (cwd2) {
150
+ if (!fs.existsSync(path.join(cwd2, "redwood.toml"))) {
151
+ throw new Error(`Couldn't find a "redwood.toml" file in ${cwd2}`);
152
+ }
153
+ tomlDir = cwd2;
154
+ } else {
155
+ const redwoodTomlPath = findUp("redwood.toml");
156
+ if (!redwoodTomlPath) {
157
+ throw new Error(
158
+ `Couldn't find up a "redwood.toml" file from ${process.cwd()}`
159
+ );
160
+ }
161
+ tomlDir = path.dirname(redwoodTomlPath);
162
+ }
163
+ } catch (error) {
164
+ console.error(error.message);
165
+ process.exit(1);
166
+ }
167
+ return tomlDir;
168
+ }
148
169
  main();
@@ -6,8 +6,12 @@ const generatePrismaCommand = async () => {
6
6
  const createdRequire = createRequire(import.meta.url);
7
7
  const prismaIndexPath = createdRequire.resolve("prisma/build/index.js");
8
8
  return {
9
- cmd: `node "${prismaIndexPath}"`,
10
- args: ["generate", `--config="${getPaths().api.prismaConfig}"`]
9
+ cmd: "node",
10
+ args: [
11
+ prismaIndexPath,
12
+ "generate",
13
+ `--config=${getPaths().api.prismaConfig}`
14
+ ]
11
15
  };
12
16
  };
13
17
  const generatePrismaClient = async ({
package/dist/lib/index.js CHANGED
@@ -8,7 +8,8 @@ import { paramCase } from "change-case";
8
8
  import decamelize from "decamelize";
9
9
  import execa from "execa";
10
10
  import { Listr } from "listr2";
11
- import lodash from "lodash";
11
+ import memoize from "lodash/memoize.js";
12
+ import template from "lodash/template.js";
12
13
  import pascalcase from "pascalcase";
13
14
  import { format } from "prettier";
14
15
  import {
@@ -20,7 +21,6 @@ import {
20
21
  import { pluralize, singularize } from "./cedarPluralize.js";
21
22
  import c from "./colors.js";
22
23
  import { addFileToRollback } from "./rollback.js";
23
- const { memoize, template } = lodash;
24
24
  const nameVariants = (name) => {
25
25
  const normalizedName = pascalcase(paramCase(singularize(name)));
26
26
  return {
@@ -394,7 +394,6 @@ const runCommandTask = async (commands, { verbose, silent }) => {
394
394
  title,
395
395
  task: async () => {
396
396
  return execa(cmd, args, {
397
- shell: true,
398
397
  cwd,
399
398
  stdio: verbose && !silent ? "inherit" : "pipe",
400
399
  extendEnv: true,
@@ -1,4 +1,4 @@
1
- import { forOwn } from "lodash";
1
+ import forOwn from "lodash/forOwn.js";
2
2
  const nodeIs = (type) => (node) => node.type === type;
3
3
  function sieve(...listRulePairs) {
4
4
  const result = [[]];
@@ -1,7 +1,8 @@
1
1
  import { parse, traverse } from "@babel/core";
2
- import generate from "@babel/generator";
2
+ import { generate } from "@babel/generator";
3
3
  import { VISITOR_KEYS } from "@babel/types";
4
- import { partition, forEachRight } from "lodash";
4
+ import forEachRight from "lodash/forEachRight.js";
5
+ import partition from "lodash/partition.js";
5
6
  import prettier from "prettier";
6
7
  import { forEachFunctionOn, nodeIs } from "./algorithms.js";
7
8
  import { semanticIdentity } from "./semanticIdentity.js";
@@ -1,5 +1,5 @@
1
1
  import * as t from "@babel/types";
2
- import _ from "lodash";
2
+ import uniqWith from "lodash/uniqWith.js";
3
3
  import { nodeIs, sieve } from "./algorithms.js";
4
4
  const OPAQUE_UID_TAG = "RW_MERGE_OPAQUE_UID_Q2xldmVyIHlvdSEgSGF2ZSBhIGNvb2tpZS4=";
5
5
  function requireSameType(base, ext) {
@@ -55,7 +55,7 @@ const interleaveStrategy = {
55
55
  const baseSpecs = baseImport.specifiers;
56
56
  const extSpecs = extImport.specifiers;
57
57
  const importSpecifierEquality = (lhs, rhs) => lhs.type === rhs.type && lhs.imported?.name === rhs.imported?.name && lhs.local?.name == rhs.local?.name;
58
- const uniqueSpecifiersOfType = (type) => _.uniqWith(
58
+ const uniqueSpecifiersOfType = (type) => uniqWith(
59
59
  [...baseSpecs, ...extSpecs].filter(nodeIs(type)),
60
60
  importSpecifierEquality
61
61
  );
@@ -102,11 +102,11 @@ function concat(base, ext) {
102
102
  const concatUniqueStrategy = {
103
103
  ArrayExpression(base, ext, eq) {
104
104
  eq ||= defaultEquality(base.elements, ext.elements);
105
- base.elements = _.uniqWith([...base.elements, ...ext.elements], eq);
105
+ base.elements = uniqWith([...base.elements, ...ext.elements], eq);
106
106
  },
107
107
  ObjectExpression(base, ext, eq) {
108
108
  eq ||= defaultEquality(base.properties, ext.properties);
109
- base.properties = _.uniqWith([...base.properties, ...ext.properties], eq);
109
+ base.properties = uniqWith([...base.properties, ...ext.properties], eq);
110
110
  }
111
111
  };
112
112
  function concatUnique(baseOrEq, ext) {
@@ -5,17 +5,31 @@ const isTypeScriptProject = () => {
5
5
  const paths = getPaths();
6
6
  return fs.existsSync(path.join(paths.web.base, "tsconfig.json")) || fs.existsSync(path.join(paths.api.base, "tsconfig.json"));
7
7
  };
8
- const sides = () => {
9
- const paths = getPaths();
10
- let sides2 = [];
11
- if (fs.existsSync(path.join(paths.web.base, "package.json"))) {
12
- sides2 = [...sides2, "web"];
8
+ function workspaces({ includePackages = false } = {}) {
9
+ const cedarPaths = getPaths();
10
+ let workspaces2 = [];
11
+ if (fs.existsSync(path.join(cedarPaths.web.base, "package.json"))) {
12
+ workspaces2 = [...workspaces2, "web"];
13
13
  }
14
- if (fs.existsSync(path.join(paths.api.base, "package.json"))) {
15
- sides2 = [...sides2, "api"];
14
+ if (fs.existsSync(path.join(cedarPaths.api.base, "package.json"))) {
15
+ workspaces2 = [...workspaces2, "api"];
16
16
  }
17
- return sides2;
18
- };
17
+ if (includePackages) {
18
+ const globPattern = path.join(cedarPaths.packages, "*").replaceAll("\\", "/");
19
+ const allPackagePaths = fs.globSync(globPattern);
20
+ workspaces2 = [
21
+ ...workspaces2,
22
+ "packages/*",
23
+ ...allPackagePaths.map((p) => p.split("/").at(-1)),
24
+ ...allPackagePaths.map((p) => p.split("/").slice(-2).join("/")),
25
+ ...allPackagePaths.map((p) => {
26
+ const packageJsonPath = path.join(p, "package.json");
27
+ return JSON.parse(fs.readFileSync(packageJsonPath, "utf8")).name;
28
+ })
29
+ ];
30
+ }
31
+ return workspaces2;
32
+ }
19
33
  const serverFileExists = () => {
20
34
  const serverFilePath = path.join(
21
35
  getPaths().api.src,
@@ -26,5 +40,5 @@ const serverFileExists = () => {
26
40
  export {
27
41
  isTypeScriptProject,
28
42
  serverFileExists,
29
- sides
43
+ workspaces
30
44
  };
package/dist/lib/test.js CHANGED
@@ -74,7 +74,7 @@ vi.mock("@cedarjs/cli-helpers", async (importOriginal) => {
74
74
  });
75
75
  vi.mock("./project", () => ({
76
76
  isTypeScriptProject: () => false,
77
- sides: () => ["web", "api"]
77
+ workspaces: () => ["web", "api"]
78
78
  }));
79
79
  globalThis.__prettierPath = path.resolve(
80
80
  import.meta.dirname,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cedarjs/cli",
3
- "version": "2.3.0",
3
+ "version": "2.3.1-next.79+a599dc0f9",
4
4
  "description": "The CedarJS Command Line",
5
5
  "repository": {
6
6
  "type": "git",
@@ -10,6 +10,7 @@
10
10
  "license": "MIT",
11
11
  "type": "module",
12
12
  "bin": {
13
+ "cedar": "./dist/index.js",
13
14
  "cedarjs": "./dist/index.js",
14
15
  "cfw": "./dist/cfw.js",
15
16
  "redwood": "./dist/index.js",
@@ -32,15 +33,15 @@
32
33
  "dependencies": {
33
34
  "@babel/preset-typescript": "7.28.5",
34
35
  "@babel/runtime-corejs3": "7.28.4",
35
- "@cedarjs/api-server": "2.3.0",
36
- "@cedarjs/cli-helpers": "2.3.0",
37
- "@cedarjs/fastify-web": "2.3.0",
38
- "@cedarjs/internal": "2.3.0",
39
- "@cedarjs/prerender": "2.3.0",
40
- "@cedarjs/project-config": "2.3.0",
41
- "@cedarjs/structure": "2.3.0",
42
- "@cedarjs/telemetry": "2.3.0",
43
- "@cedarjs/web-server": "2.3.0",
36
+ "@cedarjs/api-server": "2.3.1-next.79+a599dc0f9",
37
+ "@cedarjs/cli-helpers": "2.3.1-next.79+a599dc0f9",
38
+ "@cedarjs/fastify-web": "2.3.1-next.79+a599dc0f9",
39
+ "@cedarjs/internal": "2.3.1-next.79+a599dc0f9",
40
+ "@cedarjs/prerender": "2.3.1-next.79+a599dc0f9",
41
+ "@cedarjs/project-config": "2.3.1-next.79+a599dc0f9",
42
+ "@cedarjs/structure": "2.3.1-next.79+a599dc0f9",
43
+ "@cedarjs/telemetry": "2.3.1-next.79+a599dc0f9",
44
+ "@cedarjs/web-server": "2.3.1-next.79+a599dc0f9",
44
45
  "@listr2/prompt-adapter-enquirer": "2.0.16",
45
46
  "@opentelemetry/api": "1.8.0",
46
47
  "@opentelemetry/core": "1.22.0",
@@ -80,7 +81,7 @@
80
81
  "semver": "7.7.3",
81
82
  "smol-toml": "1.6.0",
82
83
  "string-env-interpolation": "1.0.1",
83
- "systeminformation": "5.28.3",
84
+ "systeminformation": "5.30.2",
84
85
  "termi-link": "1.1.0",
85
86
  "title-case": "3.0.3",
86
87
  "unionfs": "4.6.0",
@@ -102,5 +103,5 @@
102
103
  "publishConfig": {
103
104
  "access": "public"
104
105
  },
105
- "gitHead": "510b35f25fcee3577246502a9e1b6f16f5682f9f"
106
+ "gitHead": "a599dc0f911b124b122d1862cabf32635e53540a"
106
107
  }