@cedarjs/cli 5.0.0-canary.2341 → 5.0.0-canary.2347
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/commands/build.js
CHANGED
|
@@ -28,7 +28,7 @@ const builder = (yargs) => {
|
|
|
28
28
|
}).option("ud", {
|
|
29
29
|
type: "boolean",
|
|
30
30
|
default: false,
|
|
31
|
-
description: "Build the Universal Deploy server entry (api/dist/ud/
|
|
31
|
+
description: "Build the Universal Deploy server entry (api/dist/ud/)."
|
|
32
32
|
}).middleware(() => {
|
|
33
33
|
const check = checkNodeVersion();
|
|
34
34
|
if (check.ok) {
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { Listr } from "listr2";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
addApiPackages,
|
|
6
|
+
addWebPackages,
|
|
7
|
+
colors as c
|
|
8
|
+
} from "@cedarjs/cli-helpers";
|
|
5
9
|
import {
|
|
6
10
|
getConfigPath,
|
|
7
11
|
getMigrationsPath,
|
|
@@ -14,6 +18,10 @@ function getApiPackageJson() {
|
|
|
14
18
|
const apiPackageJsonPath = path.join(getPaths().api.base, "package.json");
|
|
15
19
|
return JSON.parse(fs.readFileSync(apiPackageJsonPath, "utf-8"));
|
|
16
20
|
}
|
|
21
|
+
function getWebPackageJson() {
|
|
22
|
+
const webPackageJsonPath = path.join(getPaths().web.base, "package.json");
|
|
23
|
+
return JSON.parse(fs.readFileSync(webPackageJsonPath, "utf-8"));
|
|
24
|
+
}
|
|
17
25
|
function hasPackage(packageJson, packageName) {
|
|
18
26
|
return Boolean(
|
|
19
27
|
packageJson.dependencies?.[packageName] || packageJson.devDependencies?.[packageName]
|
|
@@ -147,12 +155,88 @@ function addLiveQueryListenerToGraphqlHandler({ force }) {
|
|
|
147
155
|
skipped: false
|
|
148
156
|
};
|
|
149
157
|
}
|
|
158
|
+
function addConfigureGqlormToApp({ force }) {
|
|
159
|
+
const appPath = getPaths().web.app;
|
|
160
|
+
if (!fs.existsSync(appPath)) {
|
|
161
|
+
return {
|
|
162
|
+
skipped: true,
|
|
163
|
+
reason: `${path.basename(appPath)} not found`
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
const content = fs.readFileSync(appPath, "utf-8");
|
|
167
|
+
const contentLines = content.split("\n");
|
|
168
|
+
const hasGqlormImport = contentLines.some(
|
|
169
|
+
(line) => line.includes("from '@cedarjs/gqlorm/setup'")
|
|
170
|
+
);
|
|
171
|
+
const hasSchemaImport = contentLines.some(
|
|
172
|
+
(line) => line.includes("from '../../.cedar/gqlorm-schema.json'")
|
|
173
|
+
);
|
|
174
|
+
const hasConfigureCall = contentLines.some(
|
|
175
|
+
(line) => line.includes("configureGqlorm({ schema })")
|
|
176
|
+
);
|
|
177
|
+
if (hasGqlormImport && hasSchemaImport && hasConfigureCall && !force) {
|
|
178
|
+
return {
|
|
179
|
+
skipped: true,
|
|
180
|
+
reason: "configureGqlorm is already wired into App"
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
if (!hasGqlormImport) {
|
|
184
|
+
const redwoodWebImportIndex = contentLines.findIndex(
|
|
185
|
+
(line) => line.includes("from '@cedarjs/web'")
|
|
186
|
+
);
|
|
187
|
+
if (redwoodWebImportIndex === -1) {
|
|
188
|
+
return {
|
|
189
|
+
skipped: true,
|
|
190
|
+
reason: "Unexpected syntax. Could not find @cedarjs/web import to insert gqlorm import"
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
contentLines.splice(
|
|
194
|
+
redwoodWebImportIndex,
|
|
195
|
+
0,
|
|
196
|
+
"import { configureGqlorm } from '@cedarjs/gqlorm/setup'"
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
if (!hasSchemaImport) {
|
|
200
|
+
const fatalErrorPageIndex = contentLines.findIndex(
|
|
201
|
+
(line) => line.includes("import FatalErrorPage from 'src/pages/FatalErrorPage'")
|
|
202
|
+
);
|
|
203
|
+
if (fatalErrorPageIndex === -1) {
|
|
204
|
+
return {
|
|
205
|
+
skipped: true,
|
|
206
|
+
reason: "Unexpected syntax. Could not find FatalErrorPage import to insert schema import"
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
contentLines.splice(
|
|
210
|
+
fatalErrorPageIndex + 1,
|
|
211
|
+
0,
|
|
212
|
+
"import schema from '../../.cedar/gqlorm-schema.json' with { type: 'json' }"
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
if (!hasConfigureCall) {
|
|
216
|
+
const appComponentIndex = contentLines.findIndex(
|
|
217
|
+
(line) => /^const App\s*=/.test(line)
|
|
218
|
+
);
|
|
219
|
+
if (appComponentIndex === -1) {
|
|
220
|
+
return {
|
|
221
|
+
skipped: true,
|
|
222
|
+
reason: "Unexpected syntax. Could not find `const App =` to insert configureGqlorm call"
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
contentLines.splice(appComponentIndex, 0, "configureGqlorm({ schema })", "");
|
|
226
|
+
}
|
|
227
|
+
fs.writeFileSync(appPath, contentLines.join("\n"));
|
|
228
|
+
return {
|
|
229
|
+
skipped: false
|
|
230
|
+
};
|
|
231
|
+
}
|
|
150
232
|
async function handler({ force, verbose }) {
|
|
151
233
|
const projectIsTypescript = isTypeScriptProject();
|
|
152
234
|
const apiPackageJson = getApiPackageJson();
|
|
153
235
|
const migrationsPath = await getMigrationsPath(getPaths().api.prismaConfig);
|
|
154
236
|
const hasRealtimeDependency = hasPackage(apiPackageJson, "@cedarjs/realtime");
|
|
155
237
|
const hasPgDependency = hasPackage(apiPackageJson, "pg");
|
|
238
|
+
const webPackageJson = getWebPackageJson();
|
|
239
|
+
const hasGqlormDependency = hasPackage(webPackageJson, "@cedarjs/gqlorm");
|
|
156
240
|
const ext = projectIsTypescript ? "ts" : "js";
|
|
157
241
|
const migrationTemplatePath = path.resolve(
|
|
158
242
|
import.meta.dirname,
|
|
@@ -244,7 +328,7 @@ async function handler({ force, verbose }) {
|
|
|
244
328
|
},
|
|
245
329
|
{
|
|
246
330
|
...addApiPackages(["pg@^8.18.0"]),
|
|
247
|
-
title: "Adding pg dependency to your api
|
|
331
|
+
title: "Adding pg dependency to your api workspace...",
|
|
248
332
|
skip: () => {
|
|
249
333
|
if (hasPgDependency) {
|
|
250
334
|
return "pg is already installed";
|
|
@@ -297,6 +381,25 @@ async function handler({ force, verbose }) {
|
|
|
297
381
|
}
|
|
298
382
|
}
|
|
299
383
|
},
|
|
384
|
+
{
|
|
385
|
+
...addWebPackages(["@cedarjs/gqlorm"]),
|
|
386
|
+
title: "Adding @cedarjs/gqlorm to your web workspace...",
|
|
387
|
+
skip: () => {
|
|
388
|
+
if (hasGqlormDependency) {
|
|
389
|
+
return "@cedarjs/gqlorm is already installed";
|
|
390
|
+
}
|
|
391
|
+
return false;
|
|
392
|
+
}
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
title: "Wiring configureGqlorm into App.tsx...",
|
|
396
|
+
task: (_ctx, task) => {
|
|
397
|
+
const result = addConfigureGqlormToApp({ force });
|
|
398
|
+
if (result.skipped) {
|
|
399
|
+
task.skip(result.reason);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
},
|
|
300
403
|
{
|
|
301
404
|
title: "One more thing...",
|
|
302
405
|
task: (_ctx, task) => {
|
package/dist/commands/serve.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { fork } from "node:child_process";
|
|
2
1
|
import fs from "node:fs";
|
|
3
|
-
import net from "node:net";
|
|
4
2
|
import path from "node:path";
|
|
3
|
+
import { pathToFileURL } from "node:url";
|
|
4
|
+
import { serve as serveSrvx } from "srvx";
|
|
5
5
|
import { terminalLink } from "termi-link";
|
|
6
6
|
import * as apiServerCLIConfig from "@cedarjs/api-server/apiCliConfig";
|
|
7
7
|
import * as bothServerCLIConfig from "@cedarjs/api-server/bothCliConfig";
|
|
@@ -11,6 +11,35 @@ import * as webServerCLIConfig from "@cedarjs/web-server";
|
|
|
11
11
|
import { getPaths, getConfig } from "../lib/index.js";
|
|
12
12
|
import { serverFileExists } from "../lib/project.js";
|
|
13
13
|
import { webSsrServerHandler } from "./serveWebHandler.js";
|
|
14
|
+
function resolveUDEntryPath() {
|
|
15
|
+
const base = path.join(getPaths().api.dist, "ud", "index");
|
|
16
|
+
for (const ext of [".mjs", ".js"]) {
|
|
17
|
+
const entryPath = base + ext;
|
|
18
|
+
if (fs.existsSync(entryPath)) {
|
|
19
|
+
return entryPath;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
async function startUDServer(entryPath, host, port) {
|
|
25
|
+
const mod = await import(pathToFileURL(entryPath).href);
|
|
26
|
+
const fetchable = mod.default ?? mod;
|
|
27
|
+
if (!fetchable || typeof fetchable.fetch !== "function") {
|
|
28
|
+
throw new Error(
|
|
29
|
+
`UD entry at ${entryPath} does not export a Fetchable (\`export default { fetch }\`).`
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
const server = serveSrvx({
|
|
33
|
+
...fetchable,
|
|
34
|
+
port,
|
|
35
|
+
hostname: host,
|
|
36
|
+
gracefulShutdown: false,
|
|
37
|
+
manual: true
|
|
38
|
+
});
|
|
39
|
+
server.serve();
|
|
40
|
+
await server.ready();
|
|
41
|
+
return server;
|
|
42
|
+
}
|
|
14
43
|
const command = "serve [side]";
|
|
15
44
|
const description = "Start a server for serving both the api and web sides";
|
|
16
45
|
const builder = async (yargs) => {
|
|
@@ -43,14 +72,11 @@ const builder = async (yargs) => {
|
|
|
43
72
|
);
|
|
44
73
|
process.exit(1);
|
|
45
74
|
}
|
|
46
|
-
const udEntryPath =
|
|
47
|
-
if (!
|
|
75
|
+
const udEntryPath = resolveUDEntryPath();
|
|
76
|
+
if (!udEntryPath) {
|
|
48
77
|
console.error(
|
|
49
78
|
c.error(
|
|
50
|
-
`
|
|
51
|
-
Universal Deploy server entry not found at ${udEntryPath}.
|
|
52
|
-
Please run \`yarn cedar build --ud\` before serving.
|
|
53
|
-
`
|
|
79
|
+
"\n Universal Deploy server entry not found. Please run `yarn cedar build --ud` before serving.\n"
|
|
54
80
|
)
|
|
55
81
|
);
|
|
56
82
|
process.exit(1);
|
|
@@ -96,42 +122,11 @@ const builder = async (yargs) => {
|
|
|
96
122
|
port: webPort,
|
|
97
123
|
host: webHost
|
|
98
124
|
});
|
|
99
|
-
const child = fork(
|
|
100
|
-
udEntryPath,
|
|
101
|
-
["--port", String(apiPort), "--host", apiHost],
|
|
102
|
-
{
|
|
103
|
-
execArgv: process.execArgv,
|
|
104
|
-
env: {
|
|
105
|
-
...process.env,
|
|
106
|
-
NODE_ENV: process.env.NODE_ENV ?? "production",
|
|
107
|
-
PORT: String(apiPort),
|
|
108
|
-
HOST: apiHost
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
);
|
|
112
|
-
child.on("error", (err) => {
|
|
113
|
-
console.error(
|
|
114
|
-
c.error(`
|
|
115
|
-
Failed to start UD API server: ${err.message}
|
|
116
|
-
`)
|
|
117
|
-
);
|
|
118
|
-
process.exit(1);
|
|
119
|
-
});
|
|
120
|
-
child.on("exit", (code) => {
|
|
121
|
-
if (code !== 0) {
|
|
122
|
-
console.error(
|
|
123
|
-
c.error(`
|
|
124
|
-
UD API server exited with code ${code}
|
|
125
|
-
`)
|
|
126
|
-
);
|
|
127
|
-
process.exit(1);
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
125
|
console.log(`Web server listening at http://${webHost}:${webPort}`);
|
|
131
126
|
process.stdout.write(
|
|
132
127
|
`API server starting at http://${apiHost}:${apiPort}...`
|
|
133
128
|
);
|
|
134
|
-
await
|
|
129
|
+
await startUDServer(udEntryPath, apiHost, apiPort);
|
|
135
130
|
process.stdout.write(
|
|
136
131
|
`\rAPI server listening at http://${apiHost}:${apiPort}
|
|
137
132
|
`
|
|
@@ -177,61 +172,25 @@ const builder = async (yargs) => {
|
|
|
177
172
|
apiRootPath: argv.apiRootPath
|
|
178
173
|
});
|
|
179
174
|
if (argv.ud) {
|
|
180
|
-
const udEntryPath =
|
|
181
|
-
if (!
|
|
175
|
+
const udEntryPath = resolveUDEntryPath();
|
|
176
|
+
if (!udEntryPath) {
|
|
182
177
|
console.error(
|
|
183
178
|
c.error(
|
|
184
|
-
`
|
|
185
|
-
Universal Deploy server entry not found at ${udEntryPath}.
|
|
186
|
-
Please run \`yarn cedar build --ud\` before serving.
|
|
187
|
-
`
|
|
179
|
+
"\n Universal Deploy server entry not found. Please run `yarn cedar build --ud` before serving.\n"
|
|
188
180
|
)
|
|
189
181
|
);
|
|
190
182
|
process.exit(1);
|
|
191
183
|
}
|
|
192
|
-
const udArgs = [];
|
|
193
|
-
if (argv.port) {
|
|
194
|
-
udArgs.push("--port", String(argv.port));
|
|
195
|
-
}
|
|
196
|
-
if (argv.host) {
|
|
197
|
-
udArgs.push("--host", argv.host);
|
|
198
|
-
}
|
|
199
|
-
const child = fork(udEntryPath, udArgs, {
|
|
200
|
-
execArgv: process.execArgv,
|
|
201
|
-
env: {
|
|
202
|
-
...process.env,
|
|
203
|
-
NODE_ENV: process.env.NODE_ENV ?? "production",
|
|
204
|
-
PORT: argv.port ? String(argv.port) : process.env.PORT,
|
|
205
|
-
HOST: argv.host ?? process.env.HOST
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
child.on("error", (err) => {
|
|
209
|
-
console.error(
|
|
210
|
-
c.error(`
|
|
211
|
-
Failed to start UD server: ${err.message}
|
|
212
|
-
`)
|
|
213
|
-
);
|
|
214
|
-
process.exit(1);
|
|
215
|
-
});
|
|
216
184
|
const apiPort = argv.port ?? parseInt(process.env.PORT ?? "8911", 10);
|
|
217
185
|
const apiHost = argv.host ?? process.env.HOST ?? "localhost";
|
|
218
186
|
process.stdout.write(
|
|
219
187
|
`API server starting at http://${apiHost}:${apiPort}...`
|
|
220
188
|
);
|
|
221
|
-
await
|
|
189
|
+
await startUDServer(udEntryPath, apiHost, apiPort);
|
|
222
190
|
process.stdout.write(
|
|
223
191
|
`\rAPI server listening at http://${apiHost}:${apiPort}
|
|
224
192
|
`
|
|
225
193
|
);
|
|
226
|
-
await new Promise((resolve, reject) => {
|
|
227
|
-
child.on("exit", (code) => {
|
|
228
|
-
if (code !== 0) {
|
|
229
|
-
reject(new Error(`UD server exited with code ${code}`));
|
|
230
|
-
} else {
|
|
231
|
-
resolve();
|
|
232
|
-
}
|
|
233
|
-
});
|
|
234
|
-
});
|
|
235
194
|
return;
|
|
236
195
|
}
|
|
237
196
|
if (serverFileExists()) {
|
|
@@ -296,14 +255,11 @@ const builder = async (yargs) => {
|
|
|
296
255
|
process.exit(1);
|
|
297
256
|
}
|
|
298
257
|
if (argv.ud) {
|
|
299
|
-
const udEntryPath =
|
|
300
|
-
if (!
|
|
258
|
+
const udEntryPath = resolveUDEntryPath();
|
|
259
|
+
if (!udEntryPath) {
|
|
301
260
|
console.error(
|
|
302
261
|
c.error(
|
|
303
|
-
`
|
|
304
|
-
Universal Deploy server entry not found at ${udEntryPath}.
|
|
305
|
-
Please run \`yarn cedar build --ud\` before serving.
|
|
306
|
-
`
|
|
262
|
+
"\n Universal Deploy server entry not found. Please run `yarn cedar build --ud` before serving.\n"
|
|
307
263
|
)
|
|
308
264
|
);
|
|
309
265
|
process.exit(1);
|
|
@@ -320,14 +276,11 @@ const builder = async (yargs) => {
|
|
|
320
276
|
process.exit(1);
|
|
321
277
|
}
|
|
322
278
|
if (argv.ud) {
|
|
323
|
-
const udEntryPath =
|
|
324
|
-
if (!
|
|
279
|
+
const udEntryPath = resolveUDEntryPath();
|
|
280
|
+
if (!udEntryPath) {
|
|
325
281
|
console.error(
|
|
326
282
|
c.error(
|
|
327
|
-
`
|
|
328
|
-
Universal Deploy server entry not found at ${udEntryPath}.
|
|
329
|
-
Please run \`yarn cedar build --ud\` before serving.
|
|
330
|
-
`
|
|
283
|
+
"\n Universal Deploy server entry not found. Please run `yarn cedar build --ud` before serving.\n"
|
|
331
284
|
)
|
|
332
285
|
);
|
|
333
286
|
process.exit(1);
|
|
@@ -372,34 +325,6 @@ function webSideIsBuilt(isStreamingOrRSC) {
|
|
|
372
325
|
return fs.existsSync(path.join(getPaths().web.dist, "index.html"));
|
|
373
326
|
}
|
|
374
327
|
}
|
|
375
|
-
function waitForPort(host, port) {
|
|
376
|
-
const maxAttempts = 50;
|
|
377
|
-
const intervalMs = 200;
|
|
378
|
-
return new Promise((resolve, reject) => {
|
|
379
|
-
let attempts = 0;
|
|
380
|
-
const tryConnect = () => {
|
|
381
|
-
attempts++;
|
|
382
|
-
const socket = net.createConnection({ host, port });
|
|
383
|
-
socket.on("connect", () => {
|
|
384
|
-
socket.destroy();
|
|
385
|
-
resolve();
|
|
386
|
-
});
|
|
387
|
-
socket.on("error", () => {
|
|
388
|
-
socket.destroy();
|
|
389
|
-
if (attempts >= maxAttempts) {
|
|
390
|
-
reject(
|
|
391
|
-
new Error(
|
|
392
|
-
`API server did not become ready on port ${port} after ${maxAttempts * intervalMs}ms`
|
|
393
|
-
)
|
|
394
|
-
);
|
|
395
|
-
} else {
|
|
396
|
-
setTimeout(tryConnect, intervalMs);
|
|
397
|
-
}
|
|
398
|
-
});
|
|
399
|
-
};
|
|
400
|
-
tryConnect();
|
|
401
|
-
});
|
|
402
|
-
}
|
|
403
328
|
export {
|
|
404
329
|
builder,
|
|
405
330
|
command,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cedarjs/cli",
|
|
3
|
-
"version": "5.0.0-canary.
|
|
3
|
+
"version": "5.0.0-canary.2347",
|
|
4
4
|
"description": "The CedarJS Command Line",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -33,17 +33,17 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@babel/parser": "7.29.3",
|
|
35
35
|
"@babel/preset-typescript": "7.28.5",
|
|
36
|
-
"@cedarjs/api-server": "5.0.0-canary.
|
|
37
|
-
"@cedarjs/cli-helpers": "5.0.0-canary.
|
|
38
|
-
"@cedarjs/fastify-web": "5.0.0-canary.
|
|
39
|
-
"@cedarjs/internal": "5.0.0-canary.
|
|
40
|
-
"@cedarjs/prerender": "5.0.0-canary.
|
|
41
|
-
"@cedarjs/project-config": "5.0.0-canary.
|
|
42
|
-
"@cedarjs/structure": "5.0.0-canary.
|
|
43
|
-
"@cedarjs/telemetry": "5.0.0-canary.
|
|
44
|
-
"@cedarjs/utils": "5.0.0-canary.
|
|
45
|
-
"@cedarjs/vite": "5.0.0-canary.
|
|
46
|
-
"@cedarjs/web-server": "5.0.0-canary.
|
|
36
|
+
"@cedarjs/api-server": "5.0.0-canary.2347",
|
|
37
|
+
"@cedarjs/cli-helpers": "5.0.0-canary.2347",
|
|
38
|
+
"@cedarjs/fastify-web": "5.0.0-canary.2347",
|
|
39
|
+
"@cedarjs/internal": "5.0.0-canary.2347",
|
|
40
|
+
"@cedarjs/prerender": "5.0.0-canary.2347",
|
|
41
|
+
"@cedarjs/project-config": "5.0.0-canary.2347",
|
|
42
|
+
"@cedarjs/structure": "5.0.0-canary.2347",
|
|
43
|
+
"@cedarjs/telemetry": "5.0.0-canary.2347",
|
|
44
|
+
"@cedarjs/utils": "5.0.0-canary.2347",
|
|
45
|
+
"@cedarjs/vite": "5.0.0-canary.2347",
|
|
46
|
+
"@cedarjs/web-server": "5.0.0-canary.2347",
|
|
47
47
|
"@listr2/prompt-adapter-enquirer": "4.2.1",
|
|
48
48
|
"@opentelemetry/api": "1.9.0",
|
|
49
49
|
"@opentelemetry/core": "1.30.1",
|