@cedarjs/api-server 6.0.0-rc.189 → 6.0.0-rc.221

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 (44) hide show
  1. package/README.md +0 -1
  2. package/dist/apiCLIConfig.d.ts.map +1 -1
  3. package/dist/apiCLIConfig.js +1 -1
  4. package/dist/apiCLIConfigHandler.d.ts.map +1 -1
  5. package/dist/apiCLIConfigHandler.js +5 -0
  6. package/dist/bin.js +121 -39
  7. package/dist/bothCLIConfig.d.ts.map +1 -1
  8. package/dist/bothCLIConfig.js +2 -2
  9. package/dist/bothCLIConfigHandler.d.ts.map +1 -1
  10. package/dist/bothCLIConfigHandler.js +8 -2
  11. package/dist/cliHelpers.d.ts +21 -4
  12. package/dist/cliHelpers.d.ts.map +1 -1
  13. package/dist/cliHelpers.js +39 -11
  14. package/dist/createServer.d.ts.map +1 -1
  15. package/dist/createServer.js +4 -4
  16. package/dist/createServerHelpers.d.ts.map +1 -1
  17. package/dist/createServerHelpers.js +6 -2
  18. package/dist/plugins/api.d.ts +1 -1
  19. package/dist/plugins/api.d.ts.map +1 -1
  20. package/dist/plugins/api.js +1 -1
  21. package/dist/plugins/graphql.d.ts +3 -3
  22. package/dist/plugins/graphql.d.ts.map +1 -1
  23. package/dist/plugins/graphql.js +12 -10
  24. package/dist/serverFile.d.ts +23 -0
  25. package/dist/serverFile.d.ts.map +1 -0
  26. package/dist/serverFile.js +35 -0
  27. package/dist/types.d.ts +3 -3
  28. package/dist/types.d.ts.map +1 -1
  29. package/dist/utils.d.ts +0 -3
  30. package/dist/utils.d.ts.map +1 -1
  31. package/dist/utils.js +0 -20
  32. package/package.json +9 -19
  33. package/dist/buildManager.d.ts +0 -15
  34. package/dist/buildManager.d.ts.map +0 -1
  35. package/dist/buildManager.js +0 -55
  36. package/dist/serverManager.d.ts +0 -8
  37. package/dist/serverManager.d.ts.map +0 -1
  38. package/dist/serverManager.js +0 -102
  39. package/dist/watch.d.ts +0 -10
  40. package/dist/watch.d.ts.map +0 -1
  41. package/dist/watch.js +0 -375
  42. package/dist/watchPaths.d.ts +0 -3
  43. package/dist/watchPaths.d.ts.map +0 -1
  44. package/dist/watchPaths.js +0 -109
package/README.md CHANGED
@@ -16,7 +16,6 @@ From package.json
16
16
 
17
17
  ```
18
18
  "bin": {
19
- "cedarjs-api-server-watch": "./dist/watch.js",
20
19
  "cedarjs-log-formatter": "./dist/logFormatter/bin.js",
21
20
  "cedarjs-server": "./dist/bin.js",
22
21
  },
@@ -1 +1 @@
1
- {"version":3,"file":"apiCLIConfig.d.ts","sourceRoot":"","sources":["../src/apiCLIConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAEjC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD,eAAO,MAAM,WAAW,4CAA4C,CAAA;AAEpE,wBAAgB,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,gBAAgB,CAAC,QA0BpD;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,gBAAgB,iBAGtD"}
1
+ {"version":3,"file":"apiCLIConfig.d.ts","sourceRoot":"","sources":["../src/apiCLIConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAEjC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD,eAAO,MAAM,WAAW,4CAA4C,CAAA;AAEpE,wBAAgB,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,gBAAgB,CAAC,QAwBpD;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,gBAAgB,iBAGtD"}
@@ -7,7 +7,7 @@ function builder(yargs) {
7
7
  alias: "p"
8
8
  },
9
9
  host: {
10
- description: "The host to listen at. Note that you most likely want this to be '0.0.0.0' in production",
10
+ description: "The host to listen at",
11
11
  type: "string"
12
12
  },
13
13
  apiRootPath: {
@@ -1 +1 @@
1
- {"version":3,"file":"apiCLIConfigHandler.d.ts","sourceRoot":"","sources":["../src/apiCLIConfigHandler.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD,wBAAsB,OAAO,CAAC,OAAO,GAAE,gBAAqB,iBAoC3D"}
1
+ {"version":3,"file":"apiCLIConfigHandler.d.ts","sourceRoot":"","sources":["../src/apiCLIConfigHandler.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD,wBAAsB,OAAO,CAAC,OAAO,GAAE,gBAAqB,iBA4C3D"}
@@ -1,7 +1,12 @@
1
1
  import ansis from "ansis";
2
2
  import { coerceRootPath } from "@cedarjs/fastify-web";
3
3
  import { createServer } from "./createServer.js";
4
+ import { apiDistServerFileExists, runApiDistServerFile } from "./serverFile.js";
4
5
  async function handler(options = {}) {
6
+ if (apiDistServerFileExists()) {
7
+ await runApiDistServerFile(options);
8
+ return;
9
+ }
5
10
  const timeStart = Date.now();
6
11
  console.log(ansis.dim.italic("Starting API Server..."));
7
12
  options.apiRootPath = coerceRootPath(options.apiRootPath ?? "/");
package/dist/bin.js CHANGED
@@ -15,27 +15,55 @@ var __export = (target, all) => {
15
15
  };
16
16
 
17
17
  // src/cliHelpers.ts
18
- import { getConfig } from "@cedarjs/project-config";
19
- function getAPIHost() {
20
- let host = process.env.REDWOOD_API_HOST;
18
+ import { getConfig, parsePort, readEnvVar } from "@cedarjs/project-config";
19
+ function getAPIHost({ isPublicSide = false } = {}) {
20
+ let host = readEnvVar("CEDAR_API_HOST", {
21
+ deprecatedAlias: "REDWOOD_API_HOST"
22
+ });
23
+ if (isPublicSide) {
24
+ host ??= process.env.HOST;
25
+ }
21
26
  host ??= getConfig().api.host;
22
- host ??= process.env.NODE_ENV === "production" ? "0.0.0.0" : "::";
27
+ host ??= "::";
23
28
  return host;
24
29
  }
25
- function getAPIPort() {
26
- return process.env.REDWOOD_API_PORT ? parseInt(process.env.REDWOOD_API_PORT) : getConfig().api.port;
30
+ function getAPIPort({ isPublicSide = false } = {}) {
31
+ const apiPort = readEnvVar("CEDAR_API_PORT", {
32
+ deprecatedAlias: "REDWOOD_API_PORT"
33
+ });
34
+ if (apiPort) {
35
+ return parsePort(apiPort, "CEDAR_API_PORT");
36
+ }
37
+ if (isPublicSide && process.env.PORT) {
38
+ return parsePort(process.env.PORT, "PORT");
39
+ }
40
+ return getConfig().api.port;
27
41
  }
28
42
  function getAPIRootPath() {
29
43
  return process.env.CEDAR_API_ROOT_PATH ?? "/";
30
44
  }
31
- function getWebHost() {
32
- let host = process.env.REDWOOD_WEB_HOST;
45
+ function getWebHost({ isPublicSide = false } = {}) {
46
+ let host = readEnvVar("CEDAR_WEB_HOST", {
47
+ deprecatedAlias: "REDWOOD_WEB_HOST"
48
+ });
49
+ if (isPublicSide) {
50
+ host ??= process.env.HOST;
51
+ }
33
52
  host ??= getConfig().web.host;
34
- host ??= process.env.NODE_ENV === "production" ? "0.0.0.0" : "::";
53
+ host ??= "::";
35
54
  return host;
36
55
  }
37
- function getWebPort() {
38
- return process.env.REDWOOD_WEB_PORT ? parseInt(process.env.REDWOOD_WEB_PORT) : getConfig().web.port;
56
+ function getWebPort({ isPublicSide = false } = {}) {
57
+ const webPort = readEnvVar("CEDAR_WEB_PORT", {
58
+ deprecatedAlias: "REDWOOD_WEB_PORT"
59
+ });
60
+ if (webPort) {
61
+ return parsePort(webPort, "CEDAR_WEB_PORT");
62
+ }
63
+ if (isPublicSide && process.env.PORT) {
64
+ return parsePort(process.env.PORT, "PORT");
65
+ }
66
+ return getConfig().web.port;
39
67
  }
40
68
  var init_cliHelpers = __esm({
41
69
  "src/cliHelpers.ts"() {
@@ -128,8 +156,12 @@ var init_createServerHelpers = __esm({
128
156
  configureApiServer: () => {
129
157
  },
130
158
  parseArgs: true,
131
- apiHost: getAPIHost(),
132
- apiPort: getAPIPort()
159
+ // `createServer()`'s only callers are `cedarjs-server api` and custom
160
+ // `api/src/server.ts` files — both only ever run with the api side
161
+ // serving public traffic on its own, so they get to use the host's
162
+ // `HOST`/`PORT` env vars.
163
+ apiHost: getAPIHost({ isPublicSide: true }),
164
+ apiPort: getAPIPort({ isPublicSide: true })
133
165
  });
134
166
  }
135
167
  });
@@ -496,7 +528,7 @@ import fastifyRawBody from "fastify-raw-body";
496
528
  import { getAsyncStoreInstance as getAsyncStoreInstance2 } from "@cedarjs/context/dist/store";
497
529
  import { coerceRootPath as coerceRootPath2 } from "@cedarjs/fastify-web/dist/helpers.js";
498
530
  async function cedarFastifyAPI(fastify2, opts) {
499
- const cedarOptions = opts.redwood ?? {};
531
+ const cedarOptions = opts.cedar ?? {};
500
532
  cedarOptions.apiRootPath ??= "/";
501
533
  cedarOptions.apiRootPath = coerceRootPath2(cedarOptions.apiRootPath);
502
534
  cedarOptions.fastGlobOptions ??= {};
@@ -541,7 +573,7 @@ var init_api = __esm({
541
573
  // src/plugins/graphql.ts
542
574
  var graphql_exports = {};
543
575
  __export(graphql_exports, {
544
- redwoodFastifyGraphQLServer: () => redwoodFastifyGraphQLServer
576
+ cedarFastifyGraphQLServer: () => cedarFastifyGraphQLServer
545
577
  });
546
578
  import { pathToFileURL as pathToFileURL3 } from "node:url";
547
579
  import fastifyMultiPart from "@fastify/multipart";
@@ -552,10 +584,10 @@ import { getAsyncStoreInstance as getAsyncStoreInstance3 } from "@cedarjs/contex
552
584
  import { coerceRootPath as coerceRootPath3 } from "@cedarjs/fastify-web/dist/helpers.js";
553
585
  import { createGraphQLYoga } from "@cedarjs/graphql-server";
554
586
  import { getPaths as getPaths3 } from "@cedarjs/project-config";
555
- async function redwoodFastifyGraphQLServer(fastify2, options) {
556
- const redwoodOptions = options.redwood ?? {};
557
- redwoodOptions.apiRootPath ??= "/";
558
- redwoodOptions.apiRootPath = coerceRootPath3(redwoodOptions.apiRootPath);
587
+ async function cedarFastifyGraphQLServer(fastify2, options) {
588
+ const cedarOptions = options.cedar ?? {};
589
+ cedarOptions.apiRootPath ??= "/";
590
+ cedarOptions.apiRootPath = coerceRootPath3(cedarOptions.apiRootPath);
559
591
  fastify2.register(fastifyUrlData2);
560
592
  fastify2.register(fastifyMultiPart);
561
593
  const method = ["GET", "POST", "OPTIONS"];
@@ -563,7 +595,7 @@ async function redwoodFastifyGraphQLServer(fastify2, options) {
563
595
  getAsyncStoreInstance3().run(/* @__PURE__ */ new Map(), done);
564
596
  });
565
597
  try {
566
- if (!redwoodOptions.graphql) {
598
+ if (!cedarOptions.graphql) {
567
599
  const [graphqlFunctionPath] = await fg2("dist/functions/graphql.{ts,js}", {
568
600
  cwd: getPaths3().api.base,
569
601
  absolute: true
@@ -573,9 +605,9 @@ async function redwoodFastifyGraphQLServer(fastify2, options) {
573
605
  if (!__cedar_graphqlOptions) {
574
606
  return;
575
607
  }
576
- redwoodOptions.graphql = __cedar_graphqlOptions;
608
+ cedarOptions.graphql = __cedar_graphqlOptions;
577
609
  }
578
- const graphqlOptions = redwoodOptions.graphql;
610
+ const graphqlOptions = cedarOptions.graphql;
579
611
  if (graphqlOptions?.realtime?.subscriptions) {
580
612
  method.push("PUT");
581
613
  }
@@ -584,7 +616,7 @@ async function redwoodFastifyGraphQLServer(fastify2, options) {
584
616
  const routePaths = ["", "/health", "/readiness", "/stream"];
585
617
  for (const routePath of routePaths) {
586
618
  fastify2.route({
587
- url: `${redwoodOptions.apiRootPath}${graphqlEndpoint}${routePath}`,
619
+ url: `${cedarOptions.apiRootPath}${graphqlEndpoint}${routePath}`,
588
620
  method,
589
621
  handler: async (req, reply) => {
590
622
  const request = createFetchRequest(req, reply);
@@ -618,11 +650,13 @@ async function redwoodFastifyGraphQLServer(fastify2, options) {
618
650
  done();
619
651
  });
620
652
  } catch (e) {
621
- console.log(e);
653
+ const message = e instanceof Error ? e.message : String(e);
654
+ fastify2.log.error(e, `Failed to set up the GraphQL server: ${message}`);
655
+ throw e;
622
656
  }
623
657
  }
624
- function trimSlashes(path5) {
625
- return path5.replace(/^\/|\/$/g, "");
658
+ function trimSlashes(path6) {
659
+ return path6.replace(/^\/|\/$/g, "");
626
660
  }
627
661
  function createFetchRequest(req, reply) {
628
662
  const controller = new AbortController();
@@ -702,7 +736,7 @@ async function createServer(options = {}) {
702
736
  getAsyncStoreInstance4().run(/* @__PURE__ */ new Map(), done);
703
737
  });
704
738
  await server.register(cedarFastifyAPI, {
705
- redwood: {
739
+ cedar: {
706
740
  apiRootPath,
707
741
  fastGlobOptions: {
708
742
  ignore: ["**/dist/functions/graphql.js"]
@@ -716,10 +750,10 @@ async function createServer(options = {}) {
716
750
  absolute: true
717
751
  });
718
752
  if (graphqlFunctionPath) {
719
- const { redwoodFastifyGraphQLServer: redwoodFastifyGraphQLServer2 } = await Promise.resolve().then(() => (init_graphql(), graphql_exports));
753
+ const { cedarFastifyGraphQLServer: cedarFastifyGraphQLServer2 } = await Promise.resolve().then(() => (init_graphql(), graphql_exports));
720
754
  const { __cedar_graphqlOptions } = await import(pathToFileURL4(graphqlFunctionPath).href);
721
- await server.register(redwoodFastifyGraphQLServer2, {
722
- redwood: {
755
+ await server.register(cedarFastifyGraphQLServer2, {
756
+ cedar: {
723
757
  apiRootPath,
724
758
  graphql: __cedar_graphqlOptions
725
759
  }
@@ -762,10 +796,51 @@ var init_createServer = __esm({
762
796
  }
763
797
  });
764
798
 
799
+ // src/serverFile.ts
800
+ import { spawn } from "node:child_process";
801
+ import fs3 from "node:fs";
802
+ import path4 from "node:path";
803
+ import { getPaths as getPaths5 } from "@cedarjs/project-config";
804
+ function apiDistServerFilePath() {
805
+ return path4.join(getPaths5().api.dist, "server.js");
806
+ }
807
+ function apiDistServerFileExists() {
808
+ return fs3.existsSync(apiDistServerFilePath());
809
+ }
810
+ async function runApiDistServerFile(options = {}) {
811
+ const args = ["--apiRootPath", options.apiRootPath ?? "/"];
812
+ if (options.port !== void 0) {
813
+ args.push("--apiPort", String(options.port));
814
+ }
815
+ await new Promise((resolve, reject) => {
816
+ const child = spawn(process.execPath, [apiDistServerFilePath(), ...args], {
817
+ cwd: getPaths5().api.dist,
818
+ stdio: "inherit"
819
+ });
820
+ child.on("error", reject);
821
+ child.on("exit", (code, signal) => {
822
+ if (signal || code === 0) {
823
+ resolve();
824
+ return;
825
+ }
826
+ reject(new Error(`api/dist/server.js exited with code ${code}`));
827
+ });
828
+ });
829
+ }
830
+ var init_serverFile = __esm({
831
+ "src/serverFile.ts"() {
832
+ "use strict";
833
+ }
834
+ });
835
+
765
836
  // src/apiCLIConfigHandler.ts
766
837
  import ansis3 from "ansis";
767
838
  import { coerceRootPath as coerceRootPath4 } from "@cedarjs/fastify-web";
768
839
  async function handler(options = {}) {
840
+ if (apiDistServerFileExists()) {
841
+ await runApiDistServerFile(options);
842
+ return;
843
+ }
769
844
  const timeStart = Date.now();
770
845
  console.log(ansis3.dim.italic("Starting API Server..."));
771
846
  options.apiRootPath = coerceRootPath4(options.apiRootPath ?? "/");
@@ -796,6 +871,7 @@ var init_apiCLIConfigHandler = __esm({
796
871
  "src/apiCLIConfigHandler.ts"() {
797
872
  "use strict";
798
873
  init_createServer();
874
+ init_serverFile();
799
875
  }
800
876
  });
801
877
 
@@ -803,10 +879,15 @@ var init_apiCLIConfigHandler = __esm({
803
879
  import ansis4 from "ansis";
804
880
  import { redwoodFastifyWeb, coerceRootPath as coerceRootPath5 } from "@cedarjs/fastify-web";
805
881
  async function handler2(options) {
882
+ if (apiDistServerFileExists()) {
883
+ throw new Error(
884
+ "api/dist/server.js was found, but a custom server file is not supported when serving both sides from one process (`cedarjs-server` / `cedar serve`). It is a Fastify concept. Anything registered there (Realtime, custom plugins, custom middleware) would silently be skipped if this continued.\n\nRun the api and web sides as separate processes instead, so the api side goes through `cedarjs-server api`, which does run your server file:\n\n cedarjs-server api\n cedarjs-server web"
885
+ );
886
+ }
806
887
  const timeStart = Date.now();
807
888
  console.log(ansis4.dim.italic("Starting API and Web Servers..."));
808
- options.webHost ??= getWebHost();
809
- options.webPort ??= getWebPort();
889
+ options.webHost ??= getWebHost({ isPublicSide: true });
890
+ options.webPort ??= getWebPort({ isPublicSide: true });
810
891
  options.apiHost ??= getAPIHost();
811
892
  options.apiPort ??= getAPIPort();
812
893
  options.apiRootPath = coerceRootPath5(options.apiRootPath ?? "/");
@@ -873,15 +954,16 @@ var init_bothCLIConfigHandler = __esm({
873
954
  init_cliHelpers();
874
955
  init_createServer();
875
956
  init_fastify();
957
+ init_serverFile();
876
958
  }
877
959
  });
878
960
 
879
961
  // src/bin.ts
880
- import path4 from "path";
962
+ import path5 from "path";
881
963
  import { config as config2 } from "dotenv-defaults";
882
964
  import { hideBin } from "yargs/helpers";
883
965
  import yargs from "yargs/yargs";
884
- import { getPaths as getPaths5 } from "@cedarjs/project-config";
966
+ import { getPaths as getPaths6 } from "@cedarjs/project-config";
885
967
  import {
886
968
  description as webDescription,
887
969
  builder as webBuilder,
@@ -898,7 +980,7 @@ function builder(yargs2) {
898
980
  alias: "p"
899
981
  },
900
982
  host: {
901
- description: "The host to listen at. Note that you most likely want this to be '0.0.0.0' in production",
983
+ description: "The host to listen at",
902
984
  type: "string"
903
985
  },
904
986
  apiRootPath: {
@@ -929,7 +1011,7 @@ function builder2(yargs2) {
929
1011
  alias: ["web-port"]
930
1012
  },
931
1013
  webHost: {
932
- description: "The host for the web server to listen on. Note that you most likely want this to be '0.0.0.0' in production",
1014
+ description: "The host for the web server to listen on",
933
1015
  type: "string",
934
1016
  alias: ["web-host"]
935
1017
  },
@@ -939,7 +1021,7 @@ function builder2(yargs2) {
939
1021
  alias: ["api-port"]
940
1022
  },
941
1023
  apiHost: {
942
- description: "The host for the api server to listen on. Note that you most likely want this to be '0.0.0.0' in production",
1024
+ description: "The host for the api server to listen on",
943
1025
  type: "string",
944
1026
  alias: ["api-host"]
945
1027
  },
@@ -956,8 +1038,8 @@ function builder2(yargs2) {
956
1038
  init_bothCLIConfigHandler();
957
1039
  if (!process.env.CEDAR_ENV_FILES_LOADED) {
958
1040
  config2({
959
- path: path4.join(getPaths5().base, ".env"),
960
- defaults: path4.join(getPaths5().base, ".env.defaults"),
1041
+ path: path5.join(getPaths6().base, ".env"),
1042
+ defaults: path5.join(getPaths6().base, ".env.defaults"),
961
1043
  multiline: true
962
1044
  });
963
1045
  process.env.CEDAR_ENV_FILES_LOADED = "true";
@@ -1 +1 @@
1
- {"version":3,"file":"bothCLIConfig.d.ts","sourceRoot":"","sources":["../src/bothCLIConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAEjC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,eAAO,MAAM,WAAW,qDAAqD,CAAA;AAE7E,wBAAgB,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,iBAAiB,CAAC,QA+BrD;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,iBAAiB,iBAGvD"}
1
+ {"version":3,"file":"bothCLIConfig.d.ts","sourceRoot":"","sources":["../src/bothCLIConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAEjC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,eAAO,MAAM,WAAW,qDAAqD,CAAA;AAE7E,wBAAgB,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,iBAAiB,CAAC,QA6BrD;AAED,wBAAsB,OAAO,CAAC,OAAO,EAAE,iBAAiB,iBAGvD"}
@@ -7,7 +7,7 @@ function builder(yargs) {
7
7
  alias: ["web-port"]
8
8
  },
9
9
  webHost: {
10
- description: "The host for the web server to listen on. Note that you most likely want this to be '0.0.0.0' in production",
10
+ description: "The host for the web server to listen on",
11
11
  type: "string",
12
12
  alias: ["web-host"]
13
13
  },
@@ -17,7 +17,7 @@ function builder(yargs) {
17
17
  alias: ["api-port"]
18
18
  },
19
19
  apiHost: {
20
- description: "The host for the api server to listen on. Note that you most likely want this to be '0.0.0.0' in production",
20
+ description: "The host for the api server to listen on",
21
21
  type: "string",
22
22
  alias: ["api-host"]
23
23
  },
@@ -1 +1 @@
1
- {"version":3,"file":"bothCLIConfigHandler.d.ts","sourceRoot":"","sources":["../src/bothCLIConfigHandler.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,wBAAsB,OAAO,CAAC,OAAO,EAAE,iBAAiB,iBAmEvD"}
1
+ {"version":3,"file":"bothCLIConfigHandler.d.ts","sourceRoot":"","sources":["../src/bothCLIConfigHandler.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAEnD,wBAAsB,OAAO,CAAC,OAAO,EAAE,iBAAiB,iBA0FvD"}
@@ -3,11 +3,17 @@ import { redwoodFastifyWeb, coerceRootPath } from "@cedarjs/fastify-web";
3
3
  import { getWebHost, getWebPort, getAPIHost, getAPIPort } from "./cliHelpers.js";
4
4
  import { createServer as createApiServer } from "./createServer.js";
5
5
  import { createFastifyInstance } from "./fastify.js";
6
+ import { apiDistServerFileExists } from "./serverFile.js";
6
7
  async function handler(options) {
8
+ if (apiDistServerFileExists()) {
9
+ throw new Error(
10
+ "api/dist/server.js was found, but a custom server file is not supported when serving both sides from one process (`cedarjs-server` / `cedar serve`). It is a Fastify concept. Anything registered there (Realtime, custom plugins, custom middleware) would silently be skipped if this continued.\n\nRun the api and web sides as separate processes instead, so the api side goes through `cedarjs-server api`, which does run your server file:\n\n cedarjs-server api\n cedarjs-server web"
11
+ );
12
+ }
7
13
  const timeStart = Date.now();
8
14
  console.log(ansis.dim.italic("Starting API and Web Servers..."));
9
- options.webHost ??= getWebHost();
10
- options.webPort ??= getWebPort();
15
+ options.webHost ??= getWebHost({ isPublicSide: true });
16
+ options.webPort ??= getWebPort({ isPublicSide: true });
11
17
  options.apiHost ??= getAPIHost();
12
18
  options.apiPort ??= getAPIPort();
13
19
  options.apiRootPath = coerceRootPath(options.apiRootPath ?? "/");
@@ -1,6 +1,23 @@
1
- export declare function getAPIHost(): string;
2
- export declare function getAPIPort(): number;
1
+ interface SideOptions {
2
+ /**
3
+ * Whether this side receives the deployment's public traffic.
4
+ *
5
+ * Container hosts (Railway, Render, Fly.io, Cloud Run, Heroku) tell an app
6
+ * which host and port to bind with the `HOST` and `PORT` env vars. Only the
7
+ * side serving public traffic falls back to them — when the api and web
8
+ * servers run in the same deployment they would otherwise both bind to
9
+ * `PORT` and collide.
10
+ *
11
+ * The web side is the public one whenever both sides are served together,
12
+ * because it proxies api requests. The api side is only public when it is
13
+ * served on its own.
14
+ */
15
+ isPublicSide?: boolean;
16
+ }
17
+ export declare function getAPIHost({ isPublicSide }?: SideOptions): string;
18
+ export declare function getAPIPort({ isPublicSide }?: SideOptions): number;
3
19
  export declare function getAPIRootPath(): string;
4
- export declare function getWebHost(): string;
5
- export declare function getWebPort(): number;
20
+ export declare function getWebHost({ isPublicSide }?: SideOptions): string;
21
+ export declare function getWebPort({ isPublicSide }?: SideOptions): number;
22
+ export {};
6
23
  //# sourceMappingURL=cliHelpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cliHelpers.d.ts","sourceRoot":"","sources":["../src/cliHelpers.ts"],"names":[],"mappings":"AAEA,wBAAgB,UAAU,WAKzB;AAED,wBAAgB,UAAU,WAIzB;AAED,wBAAgB,cAAc,WAE7B;AAED,wBAAgB,UAAU,WAKzB;AAED,wBAAgB,UAAU,WAIzB"}
1
+ {"version":3,"file":"cliHelpers.d.ts","sourceRoot":"","sources":["../src/cliHelpers.ts"],"names":[],"mappings":"AAEA,UAAU,WAAW;IACnB;;;;;;;;;;;;OAYG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,wBAAgB,UAAU,CAAC,EAAE,YAAoB,EAAE,GAAE,WAAgB,UAepE;AAED,wBAAgB,UAAU,CAAC,EAAE,YAAoB,EAAE,GAAE,WAAgB,UAcpE;AAED,wBAAgB,cAAc,WAE7B;AAED,wBAAgB,UAAU,CAAC,EAAE,YAAoB,EAAE,GAAE,WAAgB,UAepE;AAED,wBAAgB,UAAU,CAAC,EAAE,YAAoB,EAAE,GAAE,WAAgB,UAcpE"}
@@ -1,24 +1,52 @@
1
- import { getConfig } from "@cedarjs/project-config";
2
- function getAPIHost() {
3
- let host = process.env.REDWOOD_API_HOST;
1
+ import { getConfig, parsePort, readEnvVar } from "@cedarjs/project-config";
2
+ function getAPIHost({ isPublicSide = false } = {}) {
3
+ let host = readEnvVar("CEDAR_API_HOST", {
4
+ deprecatedAlias: "REDWOOD_API_HOST"
5
+ });
6
+ if (isPublicSide) {
7
+ host ??= process.env.HOST;
8
+ }
4
9
  host ??= getConfig().api.host;
5
- host ??= process.env.NODE_ENV === "production" ? "0.0.0.0" : "::";
10
+ host ??= "::";
6
11
  return host;
7
12
  }
8
- function getAPIPort() {
9
- return process.env.REDWOOD_API_PORT ? parseInt(process.env.REDWOOD_API_PORT) : getConfig().api.port;
13
+ function getAPIPort({ isPublicSide = false } = {}) {
14
+ const apiPort = readEnvVar("CEDAR_API_PORT", {
15
+ deprecatedAlias: "REDWOOD_API_PORT"
16
+ });
17
+ if (apiPort) {
18
+ return parsePort(apiPort, "CEDAR_API_PORT");
19
+ }
20
+ if (isPublicSide && process.env.PORT) {
21
+ return parsePort(process.env.PORT, "PORT");
22
+ }
23
+ return getConfig().api.port;
10
24
  }
11
25
  function getAPIRootPath() {
12
26
  return process.env.CEDAR_API_ROOT_PATH ?? "/";
13
27
  }
14
- function getWebHost() {
15
- let host = process.env.REDWOOD_WEB_HOST;
28
+ function getWebHost({ isPublicSide = false } = {}) {
29
+ let host = readEnvVar("CEDAR_WEB_HOST", {
30
+ deprecatedAlias: "REDWOOD_WEB_HOST"
31
+ });
32
+ if (isPublicSide) {
33
+ host ??= process.env.HOST;
34
+ }
16
35
  host ??= getConfig().web.host;
17
- host ??= process.env.NODE_ENV === "production" ? "0.0.0.0" : "::";
36
+ host ??= "::";
18
37
  return host;
19
38
  }
20
- function getWebPort() {
21
- return process.env.REDWOOD_WEB_PORT ? parseInt(process.env.REDWOOD_WEB_PORT) : getConfig().web.port;
39
+ function getWebPort({ isPublicSide = false } = {}) {
40
+ const webPort = readEnvVar("CEDAR_WEB_PORT", {
41
+ deprecatedAlias: "REDWOOD_WEB_PORT"
42
+ });
43
+ if (webPort) {
44
+ return parsePort(webPort, "CEDAR_WEB_PORT");
45
+ }
46
+ if (isPublicSide && process.env.PORT) {
47
+ return parsePort(process.env.PORT, "PORT");
48
+ }
49
+ return getConfig().web.port;
22
50
  }
23
51
  export {
24
52
  getAPIHost,
@@ -1 +1 @@
1
- {"version":3,"file":"createServer.d.ts","sourceRoot":"","sources":["../src/createServer.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,mBAAmB,EACnB,MAAM,EAEP,MAAM,0BAA0B,CAAA;AAsBjC;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,YAAY,CAAC,OAAO,GAAE,mBAAwB,mBAoHnE"}
1
+ {"version":3,"file":"createServer.d.ts","sourceRoot":"","sources":["../src/createServer.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EACV,mBAAmB,EACnB,MAAM,EAEP,MAAM,0BAA0B,CAAA;AAsBjC;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,YAAY,CAAC,OAAO,GAAE,mBAAwB,mBAqHnE"}
@@ -62,7 +62,7 @@ async function createServer(options = {}) {
62
62
  getAsyncStoreInstance().run(/* @__PURE__ */ new Map(), done);
63
63
  });
64
64
  await server.register(cedarFastifyAPI, {
65
- redwood: {
65
+ cedar: {
66
66
  apiRootPath,
67
67
  fastGlobOptions: {
68
68
  ignore: ["**/dist/functions/graphql.js"]
@@ -76,10 +76,10 @@ async function createServer(options = {}) {
76
76
  absolute: true
77
77
  });
78
78
  if (graphqlFunctionPath) {
79
- const { redwoodFastifyGraphQLServer } = await import("./plugins/graphql.js");
79
+ const { cedarFastifyGraphQLServer } = await import("./plugins/graphql.js");
80
80
  const { __cedar_graphqlOptions } = await import(pathToFileURL(graphqlFunctionPath).href);
81
- await server.register(redwoodFastifyGraphQLServer, {
82
- redwood: {
81
+ await server.register(cedarFastifyGraphQLServer, {
82
+ cedar: {
83
83
  apiRootPath,
84
84
  graphql: __cedar_graphqlOptions
85
85
  }
@@ -1 +1 @@
1
- {"version":3,"file":"createServerHelpers.d.ts","sourceRoot":"","sources":["../src/createServerHelpers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EACpB,eAAe,EAChB,MAAM,SAAS,CAAA;AAMhB,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,oBAAoB,EAAE,MAAM,GAAG,MAAM,CAAC,CAAA;AAEtE,MAAM,WAAW,MAAO,SAAQ,eAAe;IAC7C,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CACnD;AAED,MAAM,WAAW,mBAAmB;IAClC,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAA;IAGpB,iCAAiC;IACjC,MAAM,CAAC,EACH,oBAAoB,CAAC,QAAQ,CAAC,GAC9B,oBAAoB,CAAC,gBAAgB,CAAC,CAAA;IAE1C;;;OAGG;IACH,oBAAoB,CAAC,EAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAA;IAE3D;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAEzC,sEAAsE;IACtE,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE7D,uDAAuD;IACvD,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,KAAK,0BAA0B,GAAG,QAAQ,CACxC,IAAI,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG;IAClD,oBAAoB,EAAE,oBAAoB,CAAA;CAC3C,CACF,CAAA;AAID,eAAO,MAAM,6BAA6B,EAAE,MAAM,0BAiB9C,CAAA;AAgBJ,wBAAgB,cAAc,CAC5B,OAAO,GAAE,mBAAwB,EACjC,IAAI,CAAC,EAAE,MAAM,EAAE;0BAdS,oBAAoB;GA4F7C"}
1
+ {"version":3,"file":"createServerHelpers.d.ts","sourceRoot":"","sources":["../src/createServerHelpers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EACpB,eAAe,EAChB,MAAM,SAAS,CAAA;AAMhB,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,oBAAoB,EAAE,MAAM,GAAG,MAAM,CAAC,CAAA;AAEtE,MAAM,WAAW,MAAO,SAAQ,eAAe;IAC7C,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;CACnD;AAED,MAAM,WAAW,mBAAmB;IAClC,iDAAiD;IACjD,WAAW,CAAC,EAAE,MAAM,CAAA;IAGpB,iCAAiC;IACjC,MAAM,CAAC,EACH,oBAAoB,CAAC,QAAQ,CAAC,GAC9B,oBAAoB,CAAC,gBAAgB,CAAC,CAAA;IAE1C;;;OAGG;IACH,oBAAoB,CAAC,EAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAA;IAE3D;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IAEzC,sEAAsE;IACtE,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE7D,uDAAuD;IACvD,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,CAAA;IAEhB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,KAAK,0BAA0B,GAAG,QAAQ,CACxC,IAAI,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,GAAG;IAClD,oBAAoB,EAAE,oBAAoB,CAAA;CAC3C,CACF,CAAA;AAID,eAAO,MAAM,6BAA6B,EAAE,MAAM,0BAqB9C,CAAA;AAgBJ,wBAAgB,cAAc,CAC5B,OAAO,GAAE,mBAAwB,EACjC,IAAI,CAAC,EAAE,MAAM,EAAE;0BAdS,oBAAoB;GA4F7C"}
@@ -15,8 +15,12 @@ const getDefaultCreateServerOptions = () => ({
15
15
  configureApiServer: () => {
16
16
  },
17
17
  parseArgs: true,
18
- apiHost: getAPIHost(),
19
- apiPort: getAPIPort()
18
+ // `createServer()`'s only callers are `cedarjs-server api` and custom
19
+ // `api/src/server.ts` files — both only ever run with the api side
20
+ // serving public traffic on its own, so they get to use the host's
21
+ // `HOST`/`PORT` env vars.
22
+ apiHost: getAPIHost({ isPublicSide: true }),
23
+ apiPort: getAPIPort({ isPublicSide: true })
20
24
  });
21
25
  function isCustomLoggerInstance(logger) {
22
26
  return !!logger && typeof logger === "object" && "info" in logger;
@@ -2,7 +2,7 @@ import type { Options as FastGlobOptions } from 'fast-glob';
2
2
  import type { FastifyInstance } from 'fastify';
3
3
  import type { Server } from '../createServerHelpers.js';
4
4
  export interface CedarFastifyAPIOptions {
5
- redwood: {
5
+ cedar: {
6
6
  apiRootPath?: string;
7
7
  fastGlobOptions?: FastGlobOptions;
8
8
  discoverFunctionsGlob?: string | string[];
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/plugins/api.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,WAAW,CAAA;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAO9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAKvD,MAAM,WAAW,sBAAsB;IAErC,OAAO,EAAE;QACP,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,eAAe,CAAC,EAAE,eAAe,CAAA;QACjC,qBAAqB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;QACzC,cAAc,CAAC,EAAE,OAAO,CAAA;QACxB,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;KAI3D,CAAA;CACF;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,sBAAsB,iBA4C7B"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/plugins/api.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,WAAW,CAAA;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAO9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAA;AAKvD,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE;QACL,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,eAAe,CAAC,EAAE,eAAe,CAAA;QACjC,qBAAqB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;QACzC,cAAc,CAAC,EAAE,OAAO,CAAA;QACxB,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;KAI3D,CAAA;CACF;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,sBAAsB,iBA4C7B"}
@@ -5,7 +5,7 @@ import { coerceRootPath } from "@cedarjs/fastify-web/dist/helpers.js";
5
5
  import { loadFastifyConfig } from "../fastify.js";
6
6
  import { lambdaRequestHandler, loadFunctionsFromDist } from "./lambdaLoader.js";
7
7
  async function cedarFastifyAPI(fastify, opts) {
8
- const cedarOptions = opts.redwood ?? {};
8
+ const cedarOptions = opts.cedar ?? {};
9
9
  cedarOptions.apiRootPath ??= "/";
10
10
  cedarOptions.apiRootPath = coerceRootPath(cedarOptions.apiRootPath);
11
11
  cedarOptions.fastGlobOptions ??= {};
@@ -1,10 +1,10 @@
1
1
  import type { FastifyInstance } from 'fastify';
2
2
  import type { GraphQLYogaOptions } from '@cedarjs/graphql-server';
3
- export interface RedwoodFastifyGraphQLOptions {
4
- redwood: {
3
+ export interface CedarFastifyGraphQLOptions {
4
+ cedar: {
5
5
  apiRootPath?: string;
6
6
  graphql?: GraphQLYogaOptions;
7
7
  };
8
8
  }
9
- export declare function redwoodFastifyGraphQLServer(fastify: FastifyInstance, options: RedwoodFastifyGraphQLOptions): Promise<void>;
9
+ export declare function cedarFastifyGraphQLServer(fastify: FastifyInstance, options: CedarFastifyGraphQLOptions): Promise<void>;
10
10
  //# sourceMappingURL=graphql.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"graphql.d.ts","sourceRoot":"","sources":["../../src/plugins/graphql.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,eAAe,EAIhB,MAAM,SAAS,CAAA;AAOhB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAKjE,MAAM,WAAW,4BAA4B;IAC3C,OAAO,EAAE;QACP,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,OAAO,CAAC,EAAE,kBAAkB,CAAA;KAC7B,CAAA;CACF;AAED,wBAAsB,2BAA2B,CAC/C,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,4BAA4B,iBAuHtC"}
1
+ {"version":3,"file":"graphql.d.ts","sourceRoot":"","sources":["../../src/plugins/graphql.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,eAAe,EAIhB,MAAM,SAAS,CAAA;AAOhB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAKjE,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE;QACL,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,OAAO,CAAC,EAAE,kBAAkB,CAAA;KAC7B,CAAA;CACF;AAED,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,0BAA0B,iBA+HpC"}