@cedarjs/cli 5.0.0-canary.0 → 5.0.0-canary.13874

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cfw.js CHANGED
@@ -6,7 +6,7 @@ import execa from "execa";
6
6
  import { terminalLink } from "termi-link";
7
7
  import { getConfigPath } from "@cedarjs/project-config";
8
8
  const config = new Configstore("@cedarjs/cli");
9
- const CFW_PATH = process.env.CFW_PATH || process.env.RWFW_PATH || process.env.RW_PATH || config.get("CFW_PATH") || config.get("RWFW_PATH");
9
+ const CFW_PATH = process.env.CFW_PATH || config.get("CFW_PATH");
10
10
  if (!CFW_PATH) {
11
11
  console.error("Error: You must specify the path to Cedar Framework");
12
12
  console.error("Usage: `CFW_PATH=~/gh/cedarjs/cedar yarn cfw <command>");
@@ -10,13 +10,17 @@ import {
10
10
  formatRunWorkspaceScriptCommand
11
11
  } from "@cedarjs/cli-helpers/packageManager/display";
12
12
  import { runBin } from "@cedarjs/cli-helpers/packageManager/exec";
13
- import { buildApi, cleanApiBuild } from "@cedarjs/internal/dist/build/api";
13
+ import {
14
+ buildApiWithVite,
15
+ cleanApiBuild
16
+ } from "@cedarjs/internal/dist/build/api";
14
17
  import { generate } from "@cedarjs/internal/dist/generate/generate";
15
18
  import { generateGqlormArtifacts } from "@cedarjs/internal/dist/generate/gqlormSchema";
16
19
  import { loadAndValidateSdls } from "@cedarjs/internal/dist/validateSchema";
17
20
  import { detectPrerenderRoutes } from "@cedarjs/prerender/detection";
18
21
  import {} from "@cedarjs/project-config";
19
22
  import { timedTelemetry } from "@cedarjs/telemetry";
23
+ import { buildUDApiServer } from "@cedarjs/vite/buildUDApiServer";
20
24
  import { generatePrismaCommand } from "../../lib/generatePrismaClient.js";
21
25
  import { getPaths, getConfig } from "../../lib/index.js";
22
26
  import { buildPackagesTask } from "./buildPackagesTask.js";
@@ -73,7 +77,8 @@ const handler = async ({
73
77
  workspace = ["api", "web", "packages/*"],
74
78
  verbose = false,
75
79
  prisma = true,
76
- prerender = true
80
+ prerender = true,
81
+ ud = false
77
82
  }) => {
78
83
  recordTelemetryAttributes({
79
84
  command: "build",
@@ -158,17 +163,22 @@ Run ` + c.info(formatCedarCommand(["build"])) + " (without specifying a workspac
158
163
  title: "Verifying graphql schema...",
159
164
  task: loadAndValidateSdls
160
165
  },
166
+ // The API build has two sequential steps:
167
+ // 1. esbuild compiles api/src/** → api/dist/ (functions, services, etc.)
168
+ // 2. Vite wraps api/dist/functions/ into a self-contained UD Node server
169
+ // entry at api/dist/ud/index.js for `cedar serve api`
170
+ // Step 2 depends on step 1 having completed.
161
171
  workspace.includes("api") && {
162
172
  title: "Building API...",
163
173
  task: async () => {
164
174
  await cleanApiBuild();
165
- const { errors, warnings } = await buildApi();
166
- if (errors.length) {
167
- console.error(errors);
168
- }
169
- if (warnings.length) {
170
- console.warn(warnings);
171
- }
175
+ await buildApiWithVite();
176
+ }
177
+ },
178
+ ud && workspace.includes("api") && {
179
+ title: "Bundling API server entry (Universal Deploy)...",
180
+ task: async () => {
181
+ await buildUDApiServer({ verbose });
172
182
  }
173
183
  },
174
184
  workspace.includes("web") && {
@@ -177,14 +187,14 @@ Run ` + c.info(formatCedarCommand(["build"])) + " (without specifying a workspac
177
187
  process.env.VITE_CJS_IGNORE_WARNING = "true";
178
188
  const createdRequire = createRequire(import.meta.url);
179
189
  const buildBinPath = createdRequire.resolve(
180
- "@cedarjs/vite/bins/rw-vite-build.mjs"
190
+ "@cedarjs/vite/bins/cedar-vite-build.mjs"
181
191
  );
182
192
  await execa(
183
193
  `node ${buildBinPath} --webDir="${cedarPaths.web.base}" --verbose=${verbose}`,
184
194
  {
185
195
  stdio: verbose ? "inherit" : "pipe",
186
196
  shell: true,
187
- // `cwd` is needed for yarn to find the rw-vite-build binary
197
+ // `cwd` is needed for yarn to find the cedar-vite-build binary
188
198
  // It won't change process.cwd for anything else here, in this
189
199
  // process
190
200
  cwd: cedarPaths.web.base
@@ -25,6 +25,10 @@ const builder = (yargs) => {
25
25
  alias: "db",
26
26
  default: true,
27
27
  description: "Generate the Prisma client"
28
+ }).option("ud", {
29
+ type: "boolean",
30
+ default: false,
31
+ description: "Build the Universal Deploy server entry (api/dist/ud/index.js)."
28
32
  }).middleware(() => {
29
33
  const check = checkNodeVersion();
30
34
  if (check.ok) {
@@ -18,7 +18,8 @@ const handler = async ({
18
18
  workspace = ["api", "web", "packages/*"],
19
19
  forward = "",
20
20
  generate = true,
21
- apiDebugPort
21
+ apiDebugPort,
22
+ ud = false
22
23
  }) => {
23
24
  recordTelemetryAttributes({
24
25
  command: "dev",
@@ -28,22 +29,26 @@ const handler = async ({
28
29
  const cedarPaths = getPaths();
29
30
  const serverFile = serverFileExists();
30
31
  const apiPreferredPort = parseInt(String(getConfig().api.port));
32
+ let apiAvailablePort;
33
+ let apiPortChangeNeeded = false;
34
+ if (workspace.includes("api")) {
35
+ if (!serverFile) {
36
+ apiAvailablePort = await getFreePort(apiPreferredPort);
37
+ if (apiAvailablePort === -1) {
38
+ exitWithError(void 0, {
39
+ message: `Could not determine a free port for the api server`
40
+ });
41
+ }
42
+ apiPortChangeNeeded = apiAvailablePort !== apiPreferredPort;
43
+ } else {
44
+ apiAvailablePort = apiPreferredPort;
45
+ }
46
+ }
31
47
  let webPreferredPort = parseInt(
32
48
  String(getConfig().web.port)
33
49
  );
34
- let apiAvailablePort = apiPreferredPort;
35
- let apiPortChangeNeeded = false;
36
50
  let webAvailablePort = webPreferredPort;
37
51
  let webPortChangeNeeded = false;
38
- if (workspace.includes("api") && !serverFile) {
39
- apiAvailablePort = await getFreePort(apiPreferredPort);
40
- if (apiAvailablePort === -1) {
41
- exitWithError(void 0, {
42
- message: `Could not determine a free port for the api server`
43
- });
44
- }
45
- apiPortChangeNeeded = apiAvailablePort !== apiPreferredPort;
46
- }
47
52
  if (workspace.includes("web")) {
48
53
  const forwardedPortMatches = [
49
54
  ...forward.matchAll(/\-\-port(\=|\s)(?<port>[^\s]*)/g)
@@ -52,10 +57,10 @@ const handler = async ({
52
57
  const port = forwardedPortMatches.pop()?.groups?.port;
53
58
  webPreferredPort = port ? parseInt(port, 10) : void 0;
54
59
  }
55
- webAvailablePort = await getFreePort(webPreferredPort, [
56
- apiPreferredPort,
57
- apiAvailablePort
58
- ]);
60
+ webAvailablePort = await getFreePort(
61
+ webPreferredPort,
62
+ apiAvailablePort !== void 0 ? [apiPreferredPort, apiAvailablePort] : [apiPreferredPort]
63
+ );
59
64
  if (webAvailablePort === -1) {
60
65
  exitWithError(void 0, {
61
66
  message: `Could not determine a free port for the web server`
@@ -63,21 +68,17 @@ const handler = async ({
63
68
  }
64
69
  webPortChangeNeeded = webAvailablePort !== webPreferredPort;
65
70
  }
66
- if (apiPortChangeNeeded || webPortChangeNeeded) {
71
+ if (webPortChangeNeeded) {
67
72
  const message = [
68
- "The currently configured ports for the development server are",
69
- "unavailable. Suggested changes to your ports, which can be changed in",
70
- "cedar.toml (or redwood.toml), are:\n",
71
- apiPortChangeNeeded && ` - API to use port ${apiAvailablePort} instead`,
72
- apiPortChangeNeeded && "of your currently configured",
73
- apiPortChangeNeeded && `${apiPreferredPort}
74
- `,
75
- webPortChangeNeeded && ` - Web to use port ${webAvailablePort} instead`,
76
- webPortChangeNeeded && "of your currently configured",
77
- webPortChangeNeeded && `${webPreferredPort}
73
+ "The currently configured port for the development server is",
74
+ "unavailable. Suggested change to your port, which can be changed in",
75
+ "cedar.toml (or redwood.toml):\n",
76
+ ` - Web to use port ${webAvailablePort} instead`,
77
+ "of your currently configured",
78
+ `${webPreferredPort}
78
79
  `,
79
- "\nCannot run the development server until your configured ports are",
80
- "changed or become available."
80
+ "\nCannot run the development server until your configured port is",
81
+ "changed or becomes available."
81
82
  ].filter(Boolean).join(" ");
82
83
  exitWithError(void 0, { message });
83
84
  }
@@ -89,19 +90,8 @@ const handler = async ({
89
90
  errorTelemetry(process.argv, `Error generating prisma client: ${message}`);
90
91
  console.error(c.error(message));
91
92
  }
92
- if (!serverFile) {
93
- try {
94
- await shutdownPort(apiAvailablePort);
95
- } catch (e) {
96
- const message = getErrorMessage(e);
97
- errorTelemetry(process.argv, `Error shutting down "api": ${message}`);
98
- console.error(
99
- `Error whilst shutting down "api" port: ${c.error(message)}`
100
- );
101
- }
102
- }
103
93
  }
104
- if (workspace.includes("web")) {
94
+ if (workspace.includes("web") && webAvailablePort !== void 0) {
105
95
  try {
106
96
  await shutdownPort(webAvailablePort);
107
97
  } catch (e) {
@@ -120,48 +110,101 @@ const handler = async ({
120
110
  console.error(c.error(`Error generating gqlorm schema: ${message}`));
121
111
  }
122
112
  }
123
- const cedarConfigPath = getConfigPath();
124
113
  const streamingSsrEnabled = getConfig().experimental?.streamingSsr?.enabled;
125
114
  process.env.VITE_CJS_IGNORE_WARNING = "true";
126
- let webCommand = `yarn cross-env NODE_ENV=development rw-vite-dev ${forward}`;
127
- if (streamingSsrEnabled) {
128
- webCommand = `yarn cross-env NODE_ENV=development rw-dev-fe ${forward}`;
129
- }
130
115
  const rootPackageJsonPath = path.join(cedarPaths.base, "package.json");
131
116
  const rootPackageJson = JSON.parse(
132
117
  fs.readFileSync(rootPackageJsonPath, "utf8")
133
118
  );
134
- const isEsm = rootPackageJson.type === "module";
135
- const serverWatchCommand = isEsm ? `cedarjs-api-server-watch` : `rw-api-server-watch`;
119
+ const buildUnifiedDevCommand = () => {
120
+ if (!ud) {
121
+ return null;
122
+ }
123
+ if (streamingSsrEnabled) {
124
+ return null;
125
+ }
126
+ if (!workspace.includes("api") || !workspace.includes("web")) {
127
+ return null;
128
+ }
129
+ if (serverFile) {
130
+ return null;
131
+ }
132
+ if (!fs.existsSync(cedarPaths.api.src) || !fs.existsSync(cedarPaths.web.src)) {
133
+ console.log("api.src or web.src does not exist");
134
+ return null;
135
+ }
136
+ return [
137
+ `yarn cross-env NODE_ENV=development cedar-unified-dev`,
138
+ ` --port ${webAvailablePort}`,
139
+ ` --apiPort ${apiAvailablePort}`,
140
+ getApiDebugFlag(apiDebugPort, apiAvailablePort),
141
+ forward
142
+ ].join(" ").replace(/\s+/g, " ").trim();
143
+ };
144
+ const unifiedDevCommand = buildUnifiedDevCommand();
145
+ if (!unifiedDevCommand && apiPortChangeNeeded) {
146
+ const message = [
147
+ "The currently configured port for the development server is",
148
+ "unavailable. Suggested change to your port, which can be changed in",
149
+ "cedar.toml (or redwood.toml):\n",
150
+ ` - API to use port ${apiAvailablePort} instead`,
151
+ "of your currently configured",
152
+ `${apiPreferredPort}
153
+ `,
154
+ "\nCannot run the development server until your configured port is",
155
+ "changed or becomes available."
156
+ ].filter(Boolean).join(" ");
157
+ exitWithError(void 0, { message });
158
+ }
136
159
  const jobs = [];
137
- if (workspace.includes("api")) {
160
+ if (unifiedDevCommand) {
138
161
  jobs.push({
139
- name: "api",
140
- command: [
141
- "yarn nodemon",
142
- " --quiet",
143
- ` --watch "${cedarConfigPath}"`,
144
- ` --exec "yarn ${serverWatchCommand}`,
145
- ` --port ${apiAvailablePort}`,
146
- ` ${getApiDebugFlag(apiDebugPort, apiAvailablePort)}`,
147
- ' | rw-log-formatter"'
148
- ].join(" ").replace(/\s+/g, " "),
162
+ name: "dev",
163
+ command: unifiedDevCommand,
149
164
  env: {
150
165
  NODE_ENV: "development",
151
166
  NODE_OPTIONS: getDevNodeOptions()
152
167
  },
153
168
  prefixColor: "cyan",
154
- runWhen: () => fs.existsSync(cedarPaths.api.src)
155
- });
156
- }
157
- if (workspace.includes("web")) {
158
- jobs.push({
159
- name: "web",
160
- command: webCommand,
161
- prefixColor: "blue",
162
- cwd: cedarPaths.web.base,
163
- runWhen: () => fs.existsSync(cedarPaths.web.src)
169
+ cwd: cedarPaths.web.base
164
170
  });
171
+ } else {
172
+ if (workspace.includes("api")) {
173
+ const isEsm = rootPackageJson.type === "module";
174
+ const serverWatchCommand = isEsm ? `cedarjs-api-server-watch` : `cedar-api-server-watch`;
175
+ const cedarConfigPath = getConfigPath();
176
+ jobs.push({
177
+ name: "api",
178
+ command: [
179
+ "yarn nodemon",
180
+ " --quiet",
181
+ ` --watch "${cedarConfigPath}"`,
182
+ ` --exec "yarn ${serverWatchCommand}`,
183
+ ` --port ${apiAvailablePort}`,
184
+ ` ${getApiDebugFlag(apiDebugPort, apiAvailablePort)}`,
185
+ ` | cedar-log-formatter"`
186
+ ].join(" ").replace(/\s+/g, " "),
187
+ env: {
188
+ NODE_ENV: "development",
189
+ NODE_OPTIONS: getDevNodeOptions()
190
+ },
191
+ prefixColor: "cyan",
192
+ runWhen: () => fs.existsSync(cedarPaths.api.src)
193
+ });
194
+ }
195
+ if (workspace.includes("web")) {
196
+ let webCommand = `yarn cross-env NODE_ENV=development cedar-vite-dev ${forward}`;
197
+ if (streamingSsrEnabled) {
198
+ webCommand = `yarn cross-env NODE_ENV=development cedar-dev-fe ${forward}`;
199
+ }
200
+ jobs.push({
201
+ name: "web",
202
+ command: webCommand,
203
+ prefixColor: "blue",
204
+ cwd: cedarPaths.web.base,
205
+ runWhen: () => fs.existsSync(cedarPaths.web.src)
206
+ });
207
+ }
165
208
  }
166
209
  if (generate) {
167
210
  jobs.push({
@@ -24,6 +24,10 @@ const builder = (yargs) => {
24
24
  }).option("apiDebugPort", {
25
25
  type: "number",
26
26
  description: "Port on which to expose API server debugger. If you supply the flag with no value it defaults to 1 prepended to the api port (e.g. api port 8913 -> debug port 18913)."
27
+ }).option("ud", {
28
+ type: "boolean",
29
+ default: false,
30
+ description: "Use the unified Vite dev server that handles both web and API in a single process (experimental)."
27
31
  }).middleware(() => {
28
32
  const check = checkNodeVersion();
29
33
  if (check.ok) {
@@ -56,11 +56,13 @@ DECLARE
56
56
  cmd record;
57
57
  schema_name text;
58
58
  table_name text;
59
+ ident_parts text[];
59
60
  BEGIN
60
61
  FOR cmd IN SELECT * FROM pg_event_trigger_ddl_commands() LOOP
61
62
  IF cmd.object_type = 'table' THEN
62
63
  schema_name := cmd.schema_name;
63
- table_name := regexp_replace(cmd.object_identity, '^.*\\.', '');
64
+ ident_parts := parse_ident(cmd.object_identity);
65
+ table_name := ident_parts[array_length(ident_parts, 1)];
64
66
 
65
67
  IF schema_name IS NULL THEN
66
68
  CONTINUE;
@@ -24,11 +24,12 @@ const resource = Resource.default().merge(
24
24
  )
25
25
 
26
26
  const studioPort = getConfig().studio.basePort
27
+ const apiUrl = getConfig().web.apiUrl.replace(/\/$/, '')
27
28
  const exporter = new OTLPTraceExporter({
28
29
  // Update this URL to point to where your OTLP compatible collector is listening
29
30
  // The redwood development studio (`yarn cedar exp studio`) can collect your
30
31
  // telemetry at `http://127.0.0.1:<PORT>/v1/traces` (default PORT is 4318)
31
- url: `http://127.0.0.1:${studioPort}/.redwood/functions/otel-trace`,
32
+ url: `http://127.0.0.1:${studioPort}${apiUrl}/otel-trace`,
32
33
  concurrencyLimit: 64,
33
34
  })
34
35
 
@@ -13,11 +13,11 @@ const handler = async ({
13
13
  args.push(name.length > 1 ? `--${name}` : `-${name}`);
14
14
  args.push(String(value));
15
15
  }
16
- let command = `yarn rw-jobs ${args.join(" ")}`;
16
+ let command = `yarn cedar-jobs ${args.join(" ")}`;
17
17
  const originalLogLevel = process.env.LOG_LEVEL;
18
18
  process.env.LOG_LEVEL = originalLogLevel || "warn";
19
19
  if (process.env.NODE_ENV !== "production") {
20
- command += " | yarn rw-log-formatter";
20
+ command += " | yarn cedar-log-formatter";
21
21
  process.env.LOG_LEVEL = originalLogLevel || "debug";
22
22
  }
23
23
  execa.commandSync(command, {
@@ -1,5 +1,6 @@
1
+ import { fork } from "node:child_process";
1
2
  import fs from "node:fs";
2
- import path from "path";
3
+ import path from "node:path";
3
4
  import { terminalLink } from "termi-link";
4
5
  import * as apiServerCLIConfig from "@cedarjs/api-server/apiCliConfig";
5
6
  import * as bothServerCLIConfig from "@cedarjs/api-server/bothCliConfig";
@@ -43,7 +44,18 @@ const builder = async (yargs) => {
43
44
  }).command({
44
45
  command: "api",
45
46
  description: apiServerCLIConfig.description,
46
- builder: apiServerCLIConfig.builder,
47
+ builder: (yargs2) => {
48
+ if (typeof apiServerCLIConfig.builder === "function") {
49
+ apiServerCLIConfig.builder(yargs2);
50
+ }
51
+ return yargs2.option("ud", {
52
+ // UD serving is opt-in. Pass --ud to use the new srvx server instead
53
+ // of the legacy Fastify server.
54
+ description: "Use the Universal Deploy server (srvx). Pass --ud to opt in; the default is Fastify.",
55
+ type: "boolean",
56
+ default: false
57
+ });
58
+ },
47
59
  handler: async (argv) => {
48
60
  recordTelemetryAttributes({
49
61
  command: "serve",
@@ -52,6 +64,47 @@ const builder = async (yargs) => {
52
64
  socket: argv.socket,
53
65
  apiRootPath: argv.apiRootPath
54
66
  });
67
+ if (argv.ud) {
68
+ const udEntryPath = path.join(getPaths().api.dist, "ud", "index.js");
69
+ if (!fs.existsSync(udEntryPath)) {
70
+ console.error(
71
+ c.error(
72
+ `
73
+ Universal Deploy server entry not found at ${udEntryPath}.
74
+ Please run \`yarn cedar build api\` before serving.
75
+ `
76
+ )
77
+ );
78
+ process.exit(1);
79
+ }
80
+ const udArgs = [];
81
+ if (argv.port) {
82
+ udArgs.push("--port", String(argv.port));
83
+ }
84
+ if (argv.host) {
85
+ udArgs.push("--host", argv.host);
86
+ }
87
+ await new Promise((resolve, reject) => {
88
+ const child = fork(udEntryPath, udArgs, {
89
+ execArgv: process.execArgv,
90
+ env: {
91
+ ...process.env,
92
+ NODE_ENV: process.env.NODE_ENV ?? "production",
93
+ PORT: argv.port ? String(argv.port) : process.env.PORT,
94
+ HOST: argv.host ?? process.env.HOST
95
+ }
96
+ });
97
+ child.on("error", reject);
98
+ child.on("exit", (code) => {
99
+ if (code !== 0) {
100
+ reject(new Error(`UD server exited with code ${code}`));
101
+ } else {
102
+ resolve();
103
+ }
104
+ });
105
+ });
106
+ return;
107
+ }
55
108
  if (serverFileExists()) {
56
109
  const { apiServerFileHandler } = await import("./serveApiHandler.js");
57
110
  await apiServerFileHandler(argv);
@@ -18,7 +18,7 @@ const hasStringMessage = (error) => {
18
18
  const bothServerFileHandler = async (argv) => {
19
19
  if (getConfig().experimental?.rsc?.enabled || getConfig().experimental?.streamingSsr?.enabled) {
20
20
  logSkippingFastifyWebServer();
21
- await execa("yarn", ["rw-serve-fe"], {
21
+ await execa("yarn", ["cedar-serve-fe"], {
22
22
  cwd: getPaths().web.base,
23
23
  stdio: "inherit"
24
24
  });
@@ -44,7 +44,7 @@ const bothServerFileHandler = async (argv) => {
44
44
  },
45
45
  {
46
46
  name: "web",
47
- command: `yarn rw-web-server --port ${argv.webPort} --host ${argv.webHost} --api-proxy-target ${apiProxyTarget}`,
47
+ command: `yarn cedar-web-server --port ${argv.webPort} --host ${argv.webHost} --api-proxy-target ${apiProxyTarget}`,
48
48
  cwd: getPaths().base,
49
49
  prefixColor: "blue"
50
50
  }
@@ -75,7 +75,7 @@ const bothSsrRscServerHandler = async (argv, rscEnabled) => {
75
75
  host: argv.apiHost,
76
76
  port: argv.apiPort
77
77
  });
78
- const fePromise = execa("yarn", ["rw-serve-fe"], {
78
+ const fePromise = execa("yarn", ["cedar-serve-fe"], {
79
79
  cwd: getPaths().web.base,
80
80
  stdio: "inherit",
81
81
  env: rscEnabled ? {
@@ -1,7 +1,7 @@
1
1
  import execa from "execa";
2
2
  import { getPaths } from "@cedarjs/project-config";
3
3
  const webSsrServerHandler = async (rscEnabled) => {
4
- await execa("yarn", ["rw-serve-fe"], {
4
+ await execa("yarn", ["cedar-serve-fe"], {
5
5
  cwd: getPaths().web.base,
6
6
  stdio: "inherit",
7
7
  env: rscEnabled ? {
@@ -2,7 +2,7 @@ import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import execa from "execa";
4
4
  import { Listr } from "listr2";
5
- import { getConfigPath } from "@cedarjs/project-config";
5
+ import { getConfigPath, getConfig } from "@cedarjs/project-config";
6
6
  import { getPaths, writeFilesTask } from "../../../../lib/index.js";
7
7
  const updateApiURLTask = (apiUrl) => {
8
8
  const configTomlPath = getConfigPath();
@@ -25,6 +25,9 @@ const updateApiURLTask = (apiUrl) => {
25
25
  }
26
26
  };
27
27
  };
28
+ function getUserApiUrl() {
29
+ return getConfig().web.apiUrl;
30
+ }
28
31
  const preRequisiteCheckTask = (preRequisites) => {
29
32
  return {
30
33
  title: "Checking pre-requisites",
@@ -101,6 +104,7 @@ export {
101
104
  addFilesTask,
102
105
  addToDotEnvTask,
103
106
  addToGitIgnoreTask,
107
+ getUserApiUrl,
104
108
  preRequisiteCheckTask,
105
109
  updateApiURLTask
106
110
  };
@@ -7,7 +7,7 @@ import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
7
7
  import { getPaths, getPrismaSchemas } from "@cedarjs/project-config";
8
8
  import { errorTelemetry } from "@cedarjs/telemetry";
9
9
  import { writeFilesTask, printSetupNotes } from "../../../../lib/index.js";
10
- import { updateApiURLTask } from "../helpers/index.js";
10
+ import { getUserApiUrl, updateApiURLTask } from "../helpers/index.js";
11
11
  import {
12
12
  flightcontrolConfig,
13
13
  databaseEnvVariables,
@@ -47,7 +47,7 @@ const getFlightcontrolJson = async (database) => {
47
47
  ...flightcontrolConfig.environments[0],
48
48
  services: [
49
49
  ...flightcontrolConfig.environments[0].services.map((service) => {
50
- if (service.id === "redwood-api") {
50
+ if (service.id === "cedar-api") {
51
51
  return {
52
52
  ...service,
53
53
  envVariables: {
@@ -96,7 +96,7 @@ const updateGraphQLFunction = () => {
96
96
  Couldn't find graphql handler in api/src/functions/graphql.js.
97
97
  You'll have to add the following cors config manually:
98
98
 
99
- cors: { origin: process.env.REDWOOD_WEB_URL, credentials: true}
99
+ cors: { origin: process.env.CEDAR_WEB_URL, credentials: true}
100
100
  `);
101
101
  return;
102
102
  }
@@ -109,14 +109,14 @@ const updateGraphQLFunction = () => {
109
109
  Couldn't find graphql handler in api/src/functions/graphql.js.
110
110
  You'll have to add the following cors config manually:
111
111
 
112
- cors: { origin: process.env.REDWOOD_WEB_URL, credentials: true}
112
+ cors: { origin: process.env.CEDAR_WEB_URL, credentials: true}
113
113
  `);
114
114
  return;
115
115
  }
116
116
  graphqlContent.splice(
117
117
  graphqlHanderIndex + 1,
118
118
  0,
119
- " cors: { origin: process.env.REDWOOD_WEB_URL, credentials: true },"
119
+ " cors: { origin: process.env.CEDAR_WEB_URL, credentials: true },"
120
120
  );
121
121
  fs.writeFileSync(graphqlFunctionsPath, graphqlContent.join(EOL));
122
122
  }
@@ -158,14 +158,14 @@ const updateDbAuth = () => {
158
158
  Couldn't find DbAuthHandler in api/src/functions/auth.js.
159
159
  You'll have to add the following cors config manually:
160
160
 
161
- cors: { origin: process.env.REDWOOD_WEB_URL, credentials: true}
161
+ cors: { origin: process.env.CEDAR_WEB_URL, credentials: true}
162
162
  `);
163
163
  return;
164
164
  }
165
165
  authContent.splice(
166
166
  dbHandlerIndex + 1,
167
167
  0,
168
- " cors: { origin: process.env.REDWOOD_WEB_URL, credentials: true },"
168
+ " cors: { origin: process.env.CEDAR_WEB_URL, credentials: true },"
169
169
  );
170
170
  fs.writeFileSync(authFnPath, authContent.join(EOL));
171
171
  }
@@ -229,13 +229,17 @@ const addToDotEnvDefaultTask = () => {
229
229
 
230
230
  You'll have to add the following env var manually:
231
231
 
232
- REDWOOD_API_URL=/.redwood/functions
232
+ CEDAR_API_URL=${getUserApiUrl()}
233
233
  `;
234
234
  }
235
235
  },
236
236
  task: async (_ctx) => {
237
237
  const env = path.resolve(getPaths().base, ".env.defaults");
238
- const line = "\n\nREDWOOD_API_URL=/.redwood/functions\n";
238
+ const apiUrl = getUserApiUrl();
239
+ const line = `
240
+
241
+ CEDAR_API_URL=${apiUrl}
242
+ `;
239
243
  fs.appendFileSync(env, line);
240
244
  }
241
245
  };
@@ -266,7 +270,7 @@ const handler = async ({ force, database }) => {
266
270
  updateGraphQLFunction(),
267
271
  updateDbAuth(),
268
272
  updateApp(),
269
- updateApiURLTask("${REDWOOD_API_URL}"),
273
+ updateApiURLTask("${CEDAR_API_URL}"),
270
274
  addToDotEnvDefaultTask(),
271
275
  printSetupNotes(notes)
272
276
  ],
@@ -5,7 +5,7 @@ import { recordTelemetryAttributes, colors as c } from "@cedarjs/cli-helpers";
5
5
  import { getPaths, getPrismaSchemas } from "@cedarjs/project-config";
6
6
  import { errorTelemetry } from "@cedarjs/telemetry";
7
7
  import { writeFilesTask, printSetupNotes } from "../../../../lib/index.js";
8
- import { addFilesTask, updateApiURLTask } from "../helpers/index.js";
8
+ import { addFilesTask } from "../helpers/index.js";
9
9
  import {
10
10
  POSTGRES_YAML,
11
11
  RENDER_HEALTH_CHECK,
@@ -80,7 +80,6 @@ const handler = async ({ force, database }) => {
80
80
  return writeFilesTask(files, { overwriteExisting: force });
81
81
  }
82
82
  },
83
- updateApiURLTask("/.redwood/functions"),
84
83
  // Add health check api function
85
84
  addFilesTask({
86
85
  files: additionalFiles,
@@ -10,8 +10,8 @@ const flightcontrolConfig = {
10
10
  },
11
11
  services: [
12
12
  {
13
- id: "redwood-api",
14
- name: "Redwood API",
13
+ id: "cedar-api",
14
+ name: "Cedar API",
15
15
  type: "web",
16
16
  buildType: "nixpacks",
17
17
  cpu: 0.5,
@@ -24,14 +24,14 @@ const flightcontrolConfig = {
24
24
  type: "ec2"
25
25
  },
26
26
  envVariables: {
27
- REDWOOD_WEB_URL: {
28
- fromService: { id: "redwood-web", value: "origin" }
27
+ CEDAR_WEB_URL: {
28
+ fromService: { id: "cedar-web", value: "origin" }
29
29
  }
30
30
  }
31
31
  },
32
32
  {
33
- id: "redwood-web",
34
- name: "Redwood Web",
33
+ id: "cedar-web",
34
+ name: "Cedar Web",
35
35
  type: "static",
36
36
  buildType: "nixpacks",
37
37
  singlePageApp: true,
@@ -41,8 +41,8 @@ const flightcontrolConfig = {
41
41
  type: "ec2"
42
42
  },
43
43
  envVariables: {
44
- REDWOOD_API_URL: {
45
- fromService: { id: "redwood-api", value: "origin" }
44
+ CEDAR_API_URL: {
45
+ fromService: { id: "cedar-api", value: "origin" }
46
46
  }
47
47
  }
48
48
  }
@@ -1,7 +1,9 @@
1
1
  import path from "path";
2
2
  import { getPaths } from "../../../../lib/index.js";
3
+ import { getUserApiUrl } from "../helpers/index.js";
3
4
  const PROJECT_NAME = path.basename(getPaths().base);
4
5
  const RENDER_YAML = (database) => {
6
+ const apiUrl = getUserApiUrl().replace(/\/$/, "");
5
7
  return `# Quick links to the docs:
6
8
  # - Redwood on Render: https://render.com/docs/deploy-redwood
7
9
  # - Render's Blueprint spec: https://render.com/docs/yaml-spec
@@ -19,7 +21,7 @@ services:
19
21
 
20
22
  routes:
21
23
  - type: rewrite
22
- source: /.redwood/functions/*
24
+ source: ${apiUrl}/*
23
25
  # Replace \`destination\` here after your first deploy:
24
26
  #
25
27
  # \`\`\`
@@ -99,7 +99,7 @@ ENV NODE_ENV=production
99
99
  # This is important if you intend to configure GraphQL to use Realtime.
100
100
  #
101
101
  # CMD [ "./api/dist/server.js" ]
102
- CMD [ "node_modules/.bin/cedarjs-server", "api" ]
102
+ CMD ["node_modules/.bin/cedarjs-server", "api"]
103
103
 
104
104
  # web serve
105
105
  # ---------
package/dist/index.js CHANGED
@@ -51,7 +51,6 @@ cwd ??= process.env.CEDAR_CWD;
51
51
  cwd ??= process.env.RWJS_CWD;
52
52
  cwd = getTomlDir(cwd);
53
53
  process.env.CEDAR_CWD = cwd;
54
- process.env.RWJS_CWD = cwd;
55
54
  if (process.argv[1]?.endsWith("redwood.js")) {
56
55
  const tomlPath = getConfigPath(cwd);
57
56
  const toml = fs.readFileSync(tomlPath, "utf8");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cedarjs/cli",
3
- "version": "5.0.0-canary.0+0428bd91ab",
3
+ "version": "5.0.0-canary.13874+8e13ad8024",
4
4
  "description": "The CedarJS Command Line",
5
5
  "repository": {
6
6
  "type": "git",
@@ -33,16 +33,16 @@
33
33
  "dependencies": {
34
34
  "@babel/parser": "7.29.2",
35
35
  "@babel/preset-typescript": "7.28.5",
36
- "@cedarjs/api-server": "5.0.0-canary.1",
37
- "@cedarjs/cli-helpers": "5.0.0-canary.1",
38
- "@cedarjs/fastify-web": "5.0.0-canary.1",
39
- "@cedarjs/internal": "5.0.0-canary.1",
40
- "@cedarjs/prerender": "5.0.0-canary.1",
41
- "@cedarjs/project-config": "5.0.0-canary.1",
42
- "@cedarjs/structure": "5.0.0-canary.1",
43
- "@cedarjs/telemetry": "5.0.0-canary.1",
44
- "@cedarjs/utils": "5.0.0-canary.1",
45
- "@cedarjs/web-server": "5.0.0-canary.1",
36
+ "@cedarjs/api-server": "5.0.0-canary.13874",
37
+ "@cedarjs/cli-helpers": "5.0.0-canary.13874",
38
+ "@cedarjs/fastify-web": "5.0.0-canary.13874",
39
+ "@cedarjs/internal": "5.0.0-canary.13874",
40
+ "@cedarjs/prerender": "5.0.0-canary.13874",
41
+ "@cedarjs/project-config": "5.0.0-canary.13874",
42
+ "@cedarjs/structure": "5.0.0-canary.13874",
43
+ "@cedarjs/telemetry": "5.0.0-canary.13874",
44
+ "@cedarjs/utils": "5.0.0-canary.13874",
45
+ "@cedarjs/web-server": "5.0.0-canary.13874",
46
46
  "@listr2/prompt-adapter-enquirer": "4.2.1",
47
47
  "@opentelemetry/api": "1.9.0",
48
48
  "@opentelemetry/core": "1.30.1",
@@ -50,7 +50,7 @@
50
50
  "@opentelemetry/resources": "1.30.1",
51
51
  "@opentelemetry/sdk-trace-node": "1.30.1",
52
52
  "@opentelemetry/semantic-conventions": "1.38.0",
53
- "@prisma/internals": "7.7.0",
53
+ "@prisma/internals": "7.8.0",
54
54
  "ansis": "4.2.0",
55
55
  "archiver": "7.0.1",
56
56
  "boxen": "5.1.2",
@@ -75,8 +75,8 @@
75
75
  "pascalcase": "1.0.0",
76
76
  "pluralize": "8.0.0",
77
77
  "portfinder": "1.0.38",
78
- "prettier": "3.8.1",
79
- "prisma": "7.7.0",
78
+ "prettier": "3.8.3",
79
+ "prisma": "7.8.0",
80
80
  "prompts": "2.4.2",
81
81
  "recast": "0.23.11",
82
82
  "rimraf": "6.1.3",
@@ -95,7 +95,7 @@
95
95
  "@babel/cli": "7.28.6",
96
96
  "@babel/core": "^7.26.10",
97
97
  "@types/archiver": "^7.0.0",
98
- "memfs": "4.57.1",
98
+ "memfs": "4.57.2",
99
99
  "node-ssh": "13.2.1",
100
100
  "ts-dedent": "2.2.0",
101
101
  "tsx": "4.21.0",
@@ -108,5 +108,5 @@
108
108
  "publishConfig": {
109
109
  "access": "public"
110
110
  },
111
- "gitHead": "0428bd91ab99f03f58990e119d30f1ef9db8b8c5"
111
+ "gitHead": "8e13ad80246a92eda7120fd66b98d3052daae274"
112
112
  }