@cedarjs/api-server 9.0.0-canary.1784 → 9.0.0-canary.3124

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 (127) 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 +316 -98
  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 +22 -4
  12. package/dist/cliHelpers.d.ts.map +1 -1
  13. package/dist/cliHelpers.js +43 -11
  14. package/dist/createServer.d.ts +19 -3
  15. package/dist/createServer.d.ts.map +1 -1
  16. package/dist/createServer.js +18 -11
  17. package/dist/createServerHelpers.d.ts +15 -2
  18. package/dist/createServerHelpers.d.ts.map +1 -1
  19. package/dist/createServerHelpers.js +14 -4
  20. package/dist/fastify.d.ts.map +1 -1
  21. package/dist/fastify.js +5 -0
  22. package/dist/logFormatter/formatters.d.ts +1 -1
  23. package/dist/logFormatter/formatters.d.ts.map +1 -1
  24. package/dist/logFormatter/index.d.ts.map +1 -1
  25. package/dist/plugins/api.d.ts +4 -5
  26. package/dist/plugins/api.d.ts.map +1 -1
  27. package/dist/plugins/api.js +15 -15
  28. package/dist/plugins/graphql.d.ts +20 -3
  29. package/dist/plugins/graphql.d.ts.map +1 -1
  30. package/dist/plugins/graphql.js +69 -28
  31. package/dist/plugins/lambdaLoader.d.ts +16 -6
  32. package/dist/plugins/lambdaLoader.d.ts.map +1 -1
  33. package/dist/plugins/lambdaLoader.js +73 -10
  34. package/dist/requestHandlers/awsLambdaFastify.d.ts.map +1 -1
  35. package/dist/requestHandlers/awsLambdaFastify.js +16 -4
  36. package/dist/serverFile.d.ts +23 -0
  37. package/dist/serverFile.d.ts.map +1 -0
  38. package/dist/serverFile.js +35 -0
  39. package/dist/types.d.ts +4 -4
  40. package/dist/types.d.ts.map +1 -1
  41. package/dist/utils.d.ts +0 -3
  42. package/dist/utils.d.ts.map +1 -1
  43. package/dist/utils.js +0 -20
  44. package/package.json +56 -72
  45. package/LICENSE +0 -21
  46. package/dist/buildManager.d.ts +0 -15
  47. package/dist/buildManager.d.ts.map +0 -1
  48. package/dist/buildManager.js +0 -50
  49. package/dist/cjs/apiCLIConfig.d.ts +0 -6
  50. package/dist/cjs/apiCLIConfig.d.ts.map +0 -1
  51. package/dist/cjs/apiCLIConfig.js +0 -71
  52. package/dist/cjs/apiCLIConfigHandler.d.ts +0 -3
  53. package/dist/cjs/apiCLIConfigHandler.d.ts.map +0 -1
  54. package/dist/cjs/apiCLIConfigHandler.js +0 -67
  55. package/dist/cjs/bin.d.ts +0 -2
  56. package/dist/cjs/bin.d.ts.map +0 -1
  57. package/dist/cjs/bin.js +0 -896
  58. package/dist/cjs/bothCLIConfig.d.ts +0 -6
  59. package/dist/cjs/bothCLIConfig.d.ts.map +0 -1
  60. package/dist/cjs/bothCLIConfig.js +0 -76
  61. package/dist/cjs/bothCLIConfigHandler.d.ts +0 -3
  62. package/dist/cjs/bothCLIConfigHandler.d.ts.map +0 -1
  63. package/dist/cjs/bothCLIConfigHandler.js +0 -107
  64. package/dist/cjs/buildManager.d.ts +0 -15
  65. package/dist/cjs/buildManager.d.ts.map +0 -1
  66. package/dist/cjs/buildManager.js +0 -74
  67. package/dist/cjs/cliHelpers.d.ts +0 -5
  68. package/dist/cjs/cliHelpers.d.ts.map +0 -1
  69. package/dist/cjs/cliHelpers.js +0 -52
  70. package/dist/cjs/createServer.d.ts +0 -30
  71. package/dist/cjs/createServer.d.ts.map +0 -1
  72. package/dist/cjs/createServer.js +0 -144
  73. package/dist/cjs/createServerHelpers.d.ts +0 -38
  74. package/dist/cjs/createServerHelpers.d.ts.map +0 -1
  75. package/dist/cjs/createServerHelpers.js +0 -112
  76. package/dist/cjs/fastify.d.ts +0 -13
  77. package/dist/cjs/fastify.d.ts.map +0 -1
  78. package/dist/cjs/fastify.js +0 -91
  79. package/dist/cjs/logFormatter/ambient.d.js +0 -1
  80. package/dist/cjs/logFormatter/bin.d.ts +0 -2
  81. package/dist/cjs/logFormatter/bin.d.ts.map +0 -1
  82. package/dist/cjs/logFormatter/bin.js +0 -369
  83. package/dist/cjs/logFormatter/formatters.d.ts +0 -30
  84. package/dist/cjs/logFormatter/formatters.d.ts.map +0 -1
  85. package/dist/cjs/logFormatter/formatters.js +0 -275
  86. package/dist/cjs/logFormatter/index.d.ts +0 -2
  87. package/dist/cjs/logFormatter/index.d.ts.map +0 -1
  88. package/dist/cjs/logFormatter/index.js +0 -184
  89. package/dist/cjs/package.json +0 -1
  90. package/dist/cjs/plugins/api.d.ts +0 -14
  91. package/dist/cjs/plugins/api.d.ts.map +0 -1
  92. package/dist/cjs/plugins/api.js +0 -78
  93. package/dist/cjs/plugins/graphql.d.ts +0 -10
  94. package/dist/cjs/plugins/graphql.d.ts.map +0 -1
  95. package/dist/cjs/plugins/graphql.js +0 -109
  96. package/dist/cjs/plugins/lambdaLoader.d.ts +0 -24
  97. package/dist/cjs/plugins/lambdaLoader.d.ts.map +0 -1
  98. package/dist/cjs/plugins/lambdaLoader.js +0 -134
  99. package/dist/cjs/requestHandlers/awsLambdaFastify.d.ts +0 -5
  100. package/dist/cjs/requestHandlers/awsLambdaFastify.d.ts.map +0 -1
  101. package/dist/cjs/requestHandlers/awsLambdaFastify.js +0 -103
  102. package/dist/cjs/requestHandlers/utils.d.ts +0 -26
  103. package/dist/cjs/requestHandlers/utils.d.ts.map +0 -1
  104. package/dist/cjs/requestHandlers/utils.js +0 -55
  105. package/dist/cjs/serverManager.d.ts +0 -8
  106. package/dist/cjs/serverManager.d.ts.map +0 -1
  107. package/dist/cjs/serverManager.js +0 -137
  108. package/dist/cjs/types.d.ts +0 -19
  109. package/dist/cjs/types.d.ts.map +0 -1
  110. package/dist/cjs/utils.d.ts +0 -6
  111. package/dist/cjs/utils.d.ts.map +0 -1
  112. package/dist/cjs/utils.js +0 -58
  113. package/dist/cjs/watch.d.ts +0 -10
  114. package/dist/cjs/watch.d.ts.map +0 -1
  115. package/dist/cjs/watch.js +0 -394
  116. package/dist/cjs/watchPaths.d.ts +0 -3
  117. package/dist/cjs/watchPaths.d.ts.map +0 -1
  118. package/dist/cjs/watchPaths.js +0 -140
  119. package/dist/serverManager.d.ts +0 -8
  120. package/dist/serverManager.d.ts.map +0 -1
  121. package/dist/serverManager.js +0 -102
  122. package/dist/watch.d.ts +0 -10
  123. package/dist/watch.d.ts.map +0 -1
  124. package/dist/watch.js +0 -370
  125. package/dist/watchPaths.d.ts +0 -3
  126. package/dist/watchPaths.d.ts.map +0 -1
  127. package/dist/watchPaths.js +0 -109
@@ -1,3 +1,4 @@
1
+ import { pathToFileURL } from "node:url";
1
2
  import fastifyMultiPart from "@fastify/multipart";
2
3
  import fastifyUrlData from "@fastify/url-data";
3
4
  import fg from "fast-glob";
@@ -6,51 +7,60 @@ import { coerceRootPath } from "@cedarjs/fastify-web/dist/helpers.js";
6
7
  import { createGraphQLYoga } from "@cedarjs/graphql-server";
7
8
  import { getPaths } from "@cedarjs/project-config";
8
9
  import { lambdaEventForFastifyRequest } from "../requestHandlers/awsLambdaFastify.js";
9
- async function redwoodFastifyGraphQLServer(fastify, options) {
10
- const redwoodOptions = options.redwood ?? {};
11
- redwoodOptions.apiRootPath ??= "/";
12
- redwoodOptions.apiRootPath = coerceRootPath(redwoodOptions.apiRootPath);
10
+ async function cedarFastifyGraphQLServer(fastify, options) {
11
+ const cedarOptions = options.cedar ?? {};
12
+ cedarOptions.apiRootPath ??= "/";
13
+ cedarOptions.apiRootPath = coerceRootPath(cedarOptions.apiRootPath);
13
14
  fastify.register(fastifyUrlData);
14
15
  fastify.register(fastifyMultiPart);
15
16
  const method = ["GET", "POST", "OPTIONS"];
16
17
  fastify.addHook("onRequest", (_req, _reply, done) => {
17
18
  getAsyncStoreInstance().run(/* @__PURE__ */ new Map(), done);
18
19
  });
20
+ if (cedarOptions.configureServer) {
21
+ await cedarOptions.configureServer(fastify);
22
+ }
19
23
  try {
20
- if (!redwoodOptions.graphql) {
24
+ if (!cedarOptions.graphql) {
21
25
  const [graphqlFunctionPath] = await fg("dist/functions/graphql.{ts,js}", {
22
26
  cwd: getPaths().api.base,
23
27
  absolute: true
24
28
  });
25
- const filePath = `file://${graphqlFunctionPath}`;
26
- const { __rw_graphqlOptions } = await import(filePath);
27
- if (!__rw_graphqlOptions) {
29
+ const filePath = pathToFileURL(graphqlFunctionPath).href;
30
+ const { __cedar_graphqlOptions } = await import(filePath);
31
+ if (!__cedar_graphqlOptions) {
28
32
  return;
29
33
  }
30
- redwoodOptions.graphql = __rw_graphqlOptions;
34
+ cedarOptions.graphql = __cedar_graphqlOptions;
31
35
  }
32
- const graphqlOptions = redwoodOptions.graphql;
33
- if (graphqlOptions?.realtime) {
34
- const { useCedarRealtime } = await import("@cedarjs/realtime");
35
- const originalExtraPlugins = graphqlOptions.extraPlugins ?? [];
36
- originalExtraPlugins.push(useCedarRealtime(graphqlOptions.realtime));
37
- graphqlOptions.extraPlugins = originalExtraPlugins;
38
- if (graphqlOptions.realtime.subscriptions) {
39
- method.push("PUT");
40
- }
36
+ const graphqlOptions = cedarOptions.graphql;
37
+ if (graphqlOptions?.realtime?.subscriptions) {
38
+ method.push("PUT");
41
39
  }
42
- const { yoga } = createGraphQLYoga(graphqlOptions);
43
- const graphqlEndpoint = trimSlashes(yoga.graphqlEndpoint);
40
+ const graphqlServer = await createGraphQLYoga(graphqlOptions);
41
+ const graphqlEndpoint = trimSlashes(graphqlServer.yoga.graphqlEndpoint);
44
42
  const routePaths = ["", "/health", "/readiness", "/stream"];
45
43
  for (const routePath of routePaths) {
46
44
  fastify.route({
47
- url: `${redwoodOptions.apiRootPath}${graphqlEndpoint}${routePath}`,
45
+ url: `${cedarOptions.apiRootPath}${graphqlEndpoint}${routePath}`,
48
46
  method,
49
- handler: (req, reply) => yoga.handleNodeRequestAndResponse(req, reply, {
50
- req,
51
- reply,
52
- event: lambdaEventForFastifyRequest(req)
53
- })
47
+ handler: async (req, reply) => {
48
+ const request = createFetchRequest(req, reply);
49
+ const cedarContext = await graphqlServer.buildRequestContext(request);
50
+ try {
51
+ return await graphqlServer.yoga.handle(request, {
52
+ request,
53
+ cedarContext,
54
+ event: lambdaEventForFastifyRequest(req),
55
+ requestContext: void 0
56
+ });
57
+ } catch (e) {
58
+ if (isClientDisconnectError(e)) {
59
+ return new Response(null, { status: 499 });
60
+ }
61
+ throw e;
62
+ }
63
+ }
54
64
  });
55
65
  }
56
66
  fastify.addHook("onReady", (done) => {
@@ -64,12 +74,43 @@ async function redwoodFastifyGraphQLServer(fastify, options) {
64
74
  done();
65
75
  });
66
76
  } catch (e) {
67
- console.log(e);
77
+ const message = e instanceof Error ? e.message : String(e);
78
+ fastify.log.error(e, `Failed to set up the GraphQL server: ${message}`);
79
+ throw e;
68
80
  }
69
81
  }
70
82
  function trimSlashes(path) {
71
83
  return path.replace(/^\/|\/$/g, "");
72
84
  }
85
+ function isClientDisconnectError(e) {
86
+ if (!e || typeof e !== "object") {
87
+ return false;
88
+ }
89
+ if ("code" in e && e.code === "ERR_STREAM_PREMATURE_CLOSE") {
90
+ return true;
91
+ }
92
+ if (e instanceof DOMException && e.name === "AbortError") {
93
+ return true;
94
+ }
95
+ return false;
96
+ }
97
+ function createFetchRequest(req, reply) {
98
+ const controller = new AbortController();
99
+ reply.raw.on("close", () => {
100
+ if (!reply.raw.writableFinished) {
101
+ controller.abort();
102
+ }
103
+ });
104
+ const requestBody = req.method === "GET" || req.method === "HEAD" ? void 0 : typeof req.body === "string" ? req.body : req.body ? JSON.stringify(req.body) : void 0;
105
+ const href = `${req.protocol}://${req.hostname}${req.raw.url ?? "/"}`;
106
+ return new Request(href, {
107
+ method: req.method,
108
+ headers: req.headers,
109
+ body: requestBody,
110
+ signal: controller.signal
111
+ });
112
+ }
73
113
  export {
74
- redwoodFastifyGraphQLServer
114
+ cedarFastifyGraphQLServer,
115
+ isClientDisconnectError
75
116
  };
@@ -1,8 +1,16 @@
1
1
  import type { Handler } from 'aws-lambda';
2
2
  import type { Options as FastGlobOptions } from 'fast-glob';
3
3
  import type { FastifyReply, FastifyRequest, RequestGenericInterface } from 'fastify';
4
- export type Lambdas = Record<string, Handler>;
5
- export declare const LAMBDA_FUNCTIONS: Lambdas;
4
+ import type { CedarHandler, CedarRouteRecord } from '@cedarjs/api/runtime';
5
+ export declare const LAMBDA_FUNCTIONS: Map<string, Handler>;
6
+ export declare const CEDAR_HANDLERS: Map<string, CedarHandler>;
7
+ /**
8
+ * Exports a copy of the Cedar route manifest.
9
+ *
10
+ * This is intended to be used to later build WinterTC compatible `fetch`
11
+ * exports
12
+ */
13
+ export declare const getCedarRouteManifest: () => CedarRouteRecord[];
6
14
  export declare const setLambdaFunctions: (foundFunctions: string[]) => Promise<void>;
7
15
  type LoadFunctionsFromDistOptions = {
8
16
  fastGlobOptions?: FastGlobOptions;
@@ -15,10 +23,12 @@ interface LambdaHandlerRequest extends RequestGenericInterface {
15
23
  };
16
24
  }
17
25
  /**
18
- This will take a fastify request
19
- Then convert it to a lambdaEvent, and pass it to the the appropriate handler for the routeName
20
- The LAMBDA_FUNCTIONS lookup has been populated already by this point
21
- **/
26
+ * This will take a fastify request
27
+ * Then convert it to a lambdaEvent, and pass it to the the appropriate handler
28
+ * for the routeName
29
+ * The CEDAR_HANDLERS and LAMBDA_FUNCTIONS maps have been populated already by
30
+ * this point
31
+ */
22
32
  export declare const lambdaRequestHandler: (req: FastifyRequest<LambdaHandlerRequest>, reply: FastifyReply) => Promise<void>;
23
33
  export {};
24
34
  //# sourceMappingURL=lambdaLoader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"lambdaLoader.d.ts","sourceRoot":"","sources":["../../src/plugins/lambdaLoader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEzC,OAAO,KAAK,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,WAAW,CAAA;AAC3D,OAAO,KAAK,EACV,YAAY,EACZ,cAAc,EACd,uBAAuB,EACxB,MAAM,SAAS,CAAA;AAOhB,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAC7C,eAAO,MAAM,gBAAgB,EAAE,OAAY,CAAA;AAI3C,eAAO,MAAM,kBAAkB,GAAU,gBAAgB,MAAM,EAAE,kBAsDhE,CAAA;AAED,KAAK,4BAA4B,GAAG;IAClC,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,qBAAqB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAC1C,CAAA;AAGD,eAAO,MAAM,qBAAqB,GAChC,UAAS,4BAAiC,kBAe3C,CAAA;AA0BD,UAAU,oBAAqB,SAAQ,uBAAuB;IAC5D,MAAM,EAAE;QACN,SAAS,EAAE,MAAM,CAAA;KAClB,CAAA;CACF;AAED;;;;IAII;AACJ,eAAO,MAAM,oBAAoB,GAC/B,KAAK,cAAc,CAAC,oBAAoB,CAAC,EACzC,OAAO,YAAY,kBAsBpB,CAAA"}
1
+ {"version":3,"file":"lambdaLoader.d.ts","sourceRoot":"","sources":["../../src/plugins/lambdaLoader.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAEzC,OAAO,KAAK,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,WAAW,CAAA;AAC3D,OAAO,KAAK,EACV,YAAY,EACZ,cAAc,EACd,uBAAuB,EACxB,MAAM,SAAS,CAAA;AAGhB,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAEjB,MAAM,sBAAsB,CAAA;AAO7B,eAAO,MAAM,gBAAgB,sBAA6B,CAAA;AAC1D,eAAO,MAAM,cAAc,2BAAkC,CAAA;AAG7D;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,0BAAgC,CAAA;AAIlE,eAAO,MAAM,kBAAkB,GAAU,gBAAgB,MAAM,EAAE,kBAuGhE,CAAA;AAED,KAAK,4BAA4B,GAAG;IAClC,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,qBAAqB,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAC1C,CAAA;AAGD,eAAO,MAAM,qBAAqB,GAChC,UAAS,4BAAiC,kBAe3C,CAAA;AA0BD,UAAU,oBAAqB,SAAQ,uBAAuB;IAC5D,MAAM,EAAE;QACN,SAAS,EAAE,MAAM,CAAA;KAClB,CAAA;CACF;AAED;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,GAC/B,KAAK,cAAc,CAAC,oBAAoB,CAAC,EACzC,OAAO,YAAY,kBAqEpB,CAAA"}
@@ -1,17 +1,27 @@
1
- import path from "path";
1
+ import path from "node:path";
2
+ import { pathToFileURL } from "node:url";
2
3
  import ansis from "ansis";
3
4
  import fg from "fast-glob";
5
+ import { terminalLink } from "termi-link";
6
+ import { buildCedarContext, wrapLegacyHandler } from "@cedarjs/api/runtime";
4
7
  import { getPaths } from "@cedarjs/project-config";
5
8
  import { requestHandler } from "../requestHandlers/awsLambdaFastify.js";
6
9
  import { escape } from "../utils.js";
7
- const LAMBDA_FUNCTIONS = {};
10
+ const LAMBDA_FUNCTIONS = /* @__PURE__ */ new Map();
11
+ const CEDAR_HANDLERS = /* @__PURE__ */ new Map();
12
+ const cedarRouteManifest = [];
13
+ const getCedarRouteManifest = () => [...cedarRouteManifest];
8
14
  const setLambdaFunctions = async (foundFunctions) => {
9
15
  const tsImport = Date.now();
10
16
  console.log(ansis.dim.italic("Importing Server Functions... "));
17
+ cedarRouteManifest.length = 0;
18
+ LAMBDA_FUNCTIONS.clear();
19
+ CEDAR_HANDLERS.clear();
11
20
  const imports = foundFunctions.map(async (fnPath) => {
12
21
  const ts = Date.now();
13
22
  const routeName = path.basename(fnPath).replace(".js", "");
14
- const fnImport = await import(`file://${fnPath}`);
23
+ const routePath = `/${routeName}`;
24
+ const fnImport = await import(pathToFileURL(fnPath).href);
15
25
  const handler = (() => {
16
26
  if ("handler" in fnImport) {
17
27
  return fnImport.handler;
@@ -23,17 +33,40 @@ const setLambdaFunctions = async (foundFunctions) => {
23
33
  }
24
34
  return void 0;
25
35
  })();
26
- LAMBDA_FUNCTIONS[routeName] = handler;
27
- if (!handler) {
36
+ const cedarHandler = (() => {
37
+ if ("handleRequest" in fnImport && typeof fnImport.handleRequest === "function") {
38
+ return fnImport.handleRequest;
39
+ }
40
+ if ("default" in fnImport && fnImport.default && "handleRequest" in fnImport.default && typeof fnImport.default.handleRequest === "function") {
41
+ return fnImport.default.handleRequest;
42
+ }
43
+ return void 0;
44
+ })();
45
+ if (handler) {
46
+ LAMBDA_FUNCTIONS.set(routeName, handler);
47
+ }
48
+ if (cedarHandler) {
49
+ CEDAR_HANDLERS.set(routeName, cedarHandler);
50
+ } else if (handler) {
51
+ CEDAR_HANDLERS.set(routeName, wrapLegacyHandler(handler));
52
+ }
53
+ if (!handler && !cedarHandler) {
28
54
  console.warn(
29
55
  routeName,
30
56
  "at",
31
57
  fnPath,
32
- "does not have a function called handler defined."
58
+ "does not have a function called handler or handleRequest defined."
33
59
  );
34
60
  }
61
+ cedarRouteManifest.push({
62
+ id: routePath,
63
+ path: routePath,
64
+ methods: routeName === "graphql" ? ["GET", "POST", "OPTIONS"] : [],
65
+ type: routeName === "graphql" ? "graphql" : routeName === "health" ? "health" : routeName.toLowerCase().includes("auth") ? "auth" : "function",
66
+ entry: fnPath
67
+ });
35
68
  console.log(
36
- ansis.magenta("/" + routeName),
69
+ terminalLink(ansis.magenta("/" + routeName), pathToFileURL(fnPath).href),
37
70
  ansis.dim.italic(Date.now() - ts + " ms")
38
71
  );
39
72
  });
@@ -72,14 +105,43 @@ const findApiDistFunctions = (params) => {
72
105
  };
73
106
  const lambdaRequestHandler = async (req, reply) => {
74
107
  const { routeName } = req.params;
75
- if (!LAMBDA_FUNCTIONS[routeName]) {
108
+ const cedarHandlerCandidate = CEDAR_HANDLERS.get(routeName);
109
+ const cedarHandler = typeof cedarHandlerCandidate === "function" ? cedarHandlerCandidate : void 0;
110
+ if (cedarHandler) {
111
+ const requestBody = req.method === "GET" || req.method === "HEAD" ? void 0 : typeof req.rawBody === "string" ? req.rawBody : req.rawBody ? Buffer.from(req.rawBody).toString() : void 0;
112
+ const href = `${req.protocol}://${req.hostname}${req.raw.url ?? "/"}`;
113
+ const request = new Request(href, {
114
+ method: req.method,
115
+ headers: req.headers,
116
+ body: requestBody
117
+ });
118
+ const ctx = await buildCedarContext(request, {
119
+ params: {
120
+ routeName
121
+ }
122
+ });
123
+ const response = await cedarHandler(request, ctx);
124
+ reply.status(response.status);
125
+ response.headers.forEach((value, name) => {
126
+ reply.header(name, value);
127
+ });
128
+ const body = await response.arrayBuffer();
129
+ reply.send(Buffer.from(body));
130
+ return;
131
+ }
132
+ const handler = LAMBDA_FUNCTIONS.get(routeName);
133
+ if (handler) {
134
+ return requestHandler(req, reply, handler);
135
+ } else {
76
136
  const errorMessage = `Function "${routeName}" was not found.`;
77
137
  req.log.error(errorMessage);
78
138
  reply.status(404);
79
139
  if (process.env.NODE_ENV === "development") {
80
140
  const devError = {
81
141
  error: errorMessage,
82
- availableFunctions: Object.keys(LAMBDA_FUNCTIONS)
142
+ availableFunctions: [
143
+ .../* @__PURE__ */ new Set([...LAMBDA_FUNCTIONS.keys(), ...CEDAR_HANDLERS.keys()])
144
+ ]
83
145
  };
84
146
  reply.send(devError);
85
147
  } else {
@@ -87,10 +149,11 @@ const lambdaRequestHandler = async (req, reply) => {
87
149
  }
88
150
  return;
89
151
  }
90
- return requestHandler(req, reply, LAMBDA_FUNCTIONS[routeName]);
91
152
  };
92
153
  export {
154
+ CEDAR_HANDLERS,
93
155
  LAMBDA_FUNCTIONS,
156
+ getCedarRouteManifest,
94
157
  lambdaRequestHandler,
95
158
  loadFunctionsFromDist,
96
159
  setLambdaFunctions
@@ -1 +1 @@
1
- {"version":3,"file":"awsLambdaFastify.d.ts","sourceRoot":"","sources":["../../src/requestHandlers/awsLambdaFastify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,oBAAoB,EACpB,OAAO,EACR,MAAM,YAAY,CAAA;AACnB,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAK3D,eAAO,MAAM,4BAA4B,GACvC,SAAS,cAAc,KACtB,oBAcF,CAAA;AAoCD,eAAO,MAAM,cAAc,GACzB,KAAK,cAAc,EACnB,OAAO,YAAY,EACnB,SAAS,OAAO,kBAmCjB,CAAA"}
1
+ {"version":3,"file":"awsLambdaFastify.d.ts","sourceRoot":"","sources":["../../src/requestHandlers/awsLambdaFastify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,oBAAoB,EACpB,OAAO,EAGR,MAAM,YAAY,CAAA;AACnB,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAK3D,eAAO,MAAM,4BAA4B,GACvC,SAAS,cAAc,KACtB,oBA6BF,CAAA;AAoCD,eAAO,MAAM,cAAc,GACzB,KAAK,cAAc,EACnB,OAAO,YAAY,EACnB,SAAS,OAAO,kBAmCjB,CAAA"}
@@ -1,16 +1,28 @@
1
- import qs from "qs";
1
+ import { parse } from "picoquery";
2
2
  import { mergeMultiValueHeaders, parseBody } from "./utils.js";
3
3
  const lambdaEventForFastifyRequest = (request) => {
4
+ const qsParams = parse(
5
+ request.url.split(/\?(.+)/)[1],
6
+ {
7
+ nestingSyntax: "index",
8
+ arrayRepeat: true,
9
+ arrayRepeatSyntax: "bracket"
10
+ }
11
+ );
4
12
  return {
5
13
  httpMethod: request.method,
6
- headers: request.headers,
14
+ headers: {
15
+ "x-forwarded-proto": request.protocol,
16
+ ...request.headers
17
+ },
7
18
  path: request.urlData("path"),
8
- queryStringParameters: qs.parse(request.url.split(/\?(.+)/)[1]),
19
+ queryStringParameters: qsParams,
9
20
  requestContext: {
10
21
  requestId: request.id,
11
22
  identity: {
12
23
  sourceIp: request.ip
13
- }
24
+ },
25
+ domainName: request.hostname
14
26
  },
15
27
  ...parseBody(request.rawBody || "")
16
28
  // adds `body` and `isBase64Encoded`
@@ -0,0 +1,23 @@
1
+ import type { APIParsedOptions } from './types.js';
2
+ /**
3
+ * Path to a project's built custom server file, if it has one.
4
+ *
5
+ * This checks `api/dist/server.js` — the built output — not
6
+ * `api/src/server.{ts,js}`, which is what `@cedarjs/cli`'s own
7
+ * `serverFileExists()` checks. A production install typically ships only
8
+ * `api/dist`, so checking source would return false in exactly the
9
+ * situation this needs to catch.
10
+ */
11
+ export declare function apiDistServerFilePath(): string;
12
+ export declare function apiDistServerFileExists(): boolean;
13
+ /**
14
+ * Run a project's custom `api/dist/server.js` instead of the default Fastify
15
+ * server.
16
+ *
17
+ * Reimplements what `@cedarjs/cli`'s `apiServerFileHandler` does for
18
+ * `cedar serve api`, rather than importing it — `@cedarjs/cli` pulls in its
19
+ * whole build/dev toolchain, which is exactly what a production install of
20
+ * this package needs to stay clear of.
21
+ */
22
+ export declare function runApiDistServerFile(options?: APIParsedOptions): Promise<void>;
23
+ //# sourceMappingURL=serverFile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serverFile.d.ts","sourceRoot":"","sources":["../src/serverFile.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED,wBAAgB,uBAAuB,IAAI,OAAO,CAEjD;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,IAAI,CAAC,CA4Bf"}
@@ -0,0 +1,35 @@
1
+ import { spawn } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { getPaths } from "@cedarjs/project-config";
5
+ function apiDistServerFilePath() {
6
+ return path.join(getPaths().api.dist, "server.js");
7
+ }
8
+ function apiDistServerFileExists() {
9
+ return fs.existsSync(apiDistServerFilePath());
10
+ }
11
+ async function runApiDistServerFile(options = {}) {
12
+ const args = ["--apiRootPath", options.apiRootPath ?? "/"];
13
+ if (options.port !== void 0) {
14
+ args.push("--apiPort", String(options.port));
15
+ }
16
+ await new Promise((resolve, reject) => {
17
+ const child = spawn(process.execPath, [apiDistServerFilePath(), ...args], {
18
+ cwd: getPaths().api.dist,
19
+ stdio: "inherit"
20
+ });
21
+ child.on("error", reject);
22
+ child.on("exit", (code, signal) => {
23
+ if (signal || code === 0) {
24
+ resolve();
25
+ return;
26
+ }
27
+ reject(new Error(`api/dist/server.js exited with code ${code}`));
28
+ });
29
+ });
30
+ }
31
+ export {
32
+ apiDistServerFileExists,
33
+ apiDistServerFilePath,
34
+ runApiDistServerFile
35
+ };
package/dist/types.d.ts CHANGED
@@ -1,19 +1,19 @@
1
1
  import type { FastifyInstance } from 'fastify';
2
- import type { RedwoodFastifyAPIOptions } from './plugins/api.js';
2
+ import type { CedarFastifyAPIOptions } from './plugins/api.js';
3
3
  export type FastifySideConfigFnOptions = {
4
4
  side: 'api' | 'web';
5
5
  };
6
- export type FastifySideConfigFn = (fastify: FastifyInstance, options?: FastifySideConfigFnOptions & Pick<RedwoodFastifyAPIOptions['redwood'], 'apiRootPath'>) => Promise<FastifyInstance> | void;
6
+ export type FastifySideConfigFn = (fastify: FastifyInstance, options?: FastifySideConfigFnOptions & Pick<CedarFastifyAPIOptions['cedar'], 'apiRootPath'>) => Promise<FastifyInstance> | void;
7
7
  export type APIParsedOptions = {
8
8
  port?: number;
9
9
  host?: string;
10
10
  loadEnvFiles?: boolean;
11
- } & Omit<RedwoodFastifyAPIOptions['redwood'], 'fastGlobOptions'>;
11
+ } & Omit<CedarFastifyAPIOptions['cedar'], 'fastGlobOptions'>;
12
12
  export type BothParsedOptions = {
13
13
  webPort?: number;
14
14
  webHost?: string;
15
15
  apiPort?: number;
16
16
  apiHost?: string;
17
17
  apiRootPath?: string;
18
- } & Omit<RedwoodFastifyAPIOptions['redwood'], 'fastGlobOptions'>;
18
+ } & Omit<CedarFastifyAPIOptions['cedar'], 'fastGlobOptions'>;
19
19
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAE9C,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAA;AAGhE,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,KAAK,GAAG,KAAK,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,CAChC,OAAO,EAAE,eAAe,EACxB,OAAO,CAAC,EAAE,0BAA0B,GAClC,IAAI,CAAC,wBAAwB,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC,KACvD,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI,CAAA;AAEpC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,GAAG,IAAI,CAAC,wBAAwB,CAAC,SAAS,CAAC,EAAE,iBAAiB,CAAC,CAAA;AAEhE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,GAAG,IAAI,CAAC,wBAAwB,CAAC,SAAS,CAAC,EAAE,iBAAiB,CAAC,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAE9C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAA;AAG9D,MAAM,MAAM,0BAA0B,GAAG;IACvC,IAAI,EAAE,KAAK,GAAG,KAAK,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,mBAAmB,GAAG,CAChC,OAAO,EAAE,eAAe,EACxB,OAAO,CAAC,EAAE,0BAA0B,GAClC,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,KACnD,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI,CAAA;AAEpC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB,GAAG,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC,CAAA;AAE5D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB,GAAG,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,EAAE,iBAAiB,CAAC,CAAA"}
package/dist/utils.d.ts CHANGED
@@ -1,6 +1,3 @@
1
- export declare function debounce<T extends (...args: any[]) => any>(func: T, wait: number): T & {
2
- cancel: () => void;
3
- };
4
1
  /** Escapes HTML characters to prevent XSS attacks */
5
2
  export declare function escape(string: string): string;
6
3
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACxD,IAAI,EAAE,CAAC,EACP,IAAI,EAAE,MAAM,GACX,CAAC,GAAG;IAAE,MAAM,EAAE,MAAM,IAAI,CAAA;CAAE,CAsB5B;AAED,qDAAqD;AACrD,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAU7C"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAU7C"}
package/dist/utils.js CHANGED
@@ -1,22 +1,3 @@
1
- function debounce(func, wait) {
2
- let timeoutId = null;
3
- const debounced = (...args) => {
4
- if (timeoutId !== null) {
5
- clearTimeout(timeoutId);
6
- }
7
- timeoutId = setTimeout(() => {
8
- timeoutId = null;
9
- func(...args);
10
- }, wait);
11
- };
12
- debounced.cancel = () => {
13
- if (timeoutId !== null) {
14
- clearTimeout(timeoutId);
15
- timeoutId = null;
16
- }
17
- };
18
- return debounced;
19
- }
20
1
  function escape(string) {
21
2
  const htmlEscapes = {
22
3
  "&": "&amp;",
@@ -28,6 +9,5 @@ function escape(string) {
28
9
  return string.replace(/[&<>"']/g, (char) => htmlEscapes[char]);
29
10
  }
30
11
  export {
31
- debounce,
32
12
  escape
33
13
  };