@cedarjs/internal 5.0.2-rc.5 → 6.0.0-canary.2619

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 (33) hide show
  1. package/dist/build/api-graphql-transforms.d.ts +34 -0
  2. package/dist/build/api-graphql-transforms.d.ts.map +1 -0
  3. package/dist/build/api-graphql-transforms.js +119 -0
  4. package/dist/build/api.d.ts.map +1 -1
  5. package/dist/build/api.js +41 -18
  6. package/dist/build/esbuild-plugin-api-graphql.d.ts +6 -0
  7. package/dist/build/esbuild-plugin-api-graphql.d.ts.map +1 -0
  8. package/dist/build/esbuild-plugin-api-graphql.js +47 -0
  9. package/dist/build/esbuild-plugin-cedar-otel-wrapping.d.ts +13 -0
  10. package/dist/build/esbuild-plugin-cedar-otel-wrapping.d.ts.map +1 -0
  11. package/dist/build/esbuild-plugin-cedar-otel-wrapping.js +180 -0
  12. package/dist/build/esbuild-plugin-handler-als-wrapping.d.ts +4 -0
  13. package/dist/build/esbuild-plugin-handler-als-wrapping.d.ts.map +1 -0
  14. package/dist/build/{esbuild-plugin-cedar-context-wrapping.js → esbuild-plugin-handler-als-wrapping.js} +12 -12
  15. package/dist/cjs/build/api-graphql-transforms.d.ts +34 -0
  16. package/dist/cjs/build/api-graphql-transforms.d.ts.map +1 -0
  17. package/dist/cjs/build/api-graphql-transforms.js +150 -0
  18. package/dist/cjs/build/api.d.ts.map +1 -1
  19. package/dist/cjs/build/api.js +38 -18
  20. package/dist/cjs/build/esbuild-plugin-api-graphql.d.ts +6 -0
  21. package/dist/cjs/build/esbuild-plugin-api-graphql.d.ts.map +1 -0
  22. package/dist/cjs/build/esbuild-plugin-api-graphql.js +75 -0
  23. package/dist/cjs/build/esbuild-plugin-cedar-otel-wrapping.d.ts +13 -0
  24. package/dist/cjs/build/esbuild-plugin-cedar-otel-wrapping.d.ts.map +1 -0
  25. package/dist/cjs/build/esbuild-plugin-cedar-otel-wrapping.js +214 -0
  26. package/dist/cjs/build/esbuild-plugin-handler-als-wrapping.d.ts +4 -0
  27. package/dist/cjs/build/esbuild-plugin-handler-als-wrapping.d.ts.map +1 -0
  28. package/dist/cjs/build/{esbuild-plugin-cedar-context-wrapping.js → esbuild-plugin-handler-als-wrapping.js} +16 -16
  29. package/package.json +21 -9
  30. package/dist/build/esbuild-plugin-cedar-context-wrapping.d.ts +0 -4
  31. package/dist/build/esbuild-plugin-cedar-context-wrapping.d.ts.map +0 -1
  32. package/dist/cjs/build/esbuild-plugin-cedar-context-wrapping.d.ts +0 -4
  33. package/dist/cjs/build/esbuild-plugin-cedar-context-wrapping.d.ts.map +0 -1
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Extracts the options argument from createGraphQLHandler calls and stores
3
+ * them in an exported variable. Returns the transformed code, or null if no
4
+ * transformation was needed.
5
+ *
6
+ * Transforms:
7
+ * export const handler = createGraphQLHandler({ options })
8
+ * into:
9
+ * export const __cedar_graphqlOptions = { options }
10
+ * export const handler = createGraphQLHandler(__cedar_graphqlOptions)
11
+ */
12
+ export declare function applyGraphqlOptionsExtract(code: string): string | null;
13
+ /**
14
+ * Injects the auto-generated gqlorm backend into graphql.ts at build time.
15
+ *
16
+ * When `experimental.gqlorm.enabled = true` and `.cedar/gqlorm/backend.ts`
17
+ * exists, this function:
18
+ *
19
+ * 1. Adds imports at the top of graphql.ts:
20
+ * import * as __gqlorm_sdl__ from '../../../.cedar/gqlorm/backend'
21
+ * import { db as __gqlorm_db__ } from 'src/lib/db'
22
+ *
23
+ * 2. Inserts a statement immediately before the `createGraphQLHandler` call:
24
+ * Object.assign(sdls, {
25
+ * __gqlorm__: {
26
+ * schema: __gqlorm_sdl__.schema,
27
+ * resolvers: __gqlorm_sdl__.createGqlormResolvers(__gqlorm_db__),
28
+ * },
29
+ * })
30
+ *
31
+ * Returns the transformed code, or null if no transformation was needed.
32
+ */
33
+ export declare function applyGqlormInject(code: string, id: string, dbExt?: '.ts' | '.js'): string | null;
34
+ //# sourceMappingURL=api-graphql-transforms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-graphql-transforms.d.ts","sourceRoot":"","sources":["../../src/build/api-graphql-transforms.ts"],"names":[],"mappings":"AAYA;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA6FtE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,KAAK,GAAE,KAAK,GAAG,KAAa,GAC3B,MAAM,GAAG,IAAI,CAmFf"}
@@ -0,0 +1,119 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { parseSync, Visitor } from "oxc-parser";
4
+ import {
5
+ getConfig,
6
+ getPaths,
7
+ importStatementPath
8
+ } from "@cedarjs/project-config";
9
+ function applyGraphqlOptionsExtract(code) {
10
+ if (code.includes("__cedar_graphqlOptions")) {
11
+ return null;
12
+ }
13
+ const { program } = parseSync("graphql.ts", code, {
14
+ // lang is only a parse hint; 'ts' also parses JS (the graphql handler can
15
+ // be graphql.js in JS projects), so this is safe for both file types.
16
+ lang: "ts",
17
+ sourceType: "module"
18
+ });
19
+ const importNames = /* @__PURE__ */ new Set();
20
+ for (const node of program.body) {
21
+ if (node.type === "ImportDeclaration") {
22
+ if (node.source.value !== "@cedarjs/graphql-server") {
23
+ continue;
24
+ }
25
+ for (const specifier of node.specifiers) {
26
+ if (specifier.type === "ImportSpecifier" && specifier.imported.type === "Identifier" && specifier.imported.name === "createGraphQLHandler") {
27
+ importNames.add(specifier.local.name);
28
+ }
29
+ }
30
+ }
31
+ }
32
+ if (importNames.size === 0) {
33
+ return null;
34
+ }
35
+ const callExpressionPaths = [];
36
+ new Visitor({
37
+ CallExpression(node) {
38
+ if (node.callee.type === "Identifier" && importNames.has(node.callee.name)) {
39
+ callExpressionPaths.push(node);
40
+ }
41
+ }
42
+ }).visit(program);
43
+ if (callExpressionPaths.length > 1) {
44
+ return null;
45
+ }
46
+ const callExpression = callExpressionPaths[0];
47
+ if (!callExpression) {
48
+ return null;
49
+ }
50
+ const options = callExpression.arguments[0];
51
+ if (!options) {
52
+ return null;
53
+ }
54
+ if (options.type !== "Identifier" && options.type !== "ObjectExpression" && options.type !== "CallExpression" && options.type !== "ConditionalExpression") {
55
+ return null;
56
+ }
57
+ const optionsStart = options.start;
58
+ const optionsEnd = options.end;
59
+ const lineStart = code.lastIndexOf("\n", callExpression.start) + 1;
60
+ const indentMatch = /^[ \t]*/.exec(code.slice(lineStart));
61
+ const indent = indentMatch ? indentMatch[0] : "";
62
+ const optionsConst = `${indent}export const __cedar_graphqlOptions = ${code.slice(
63
+ optionsStart,
64
+ optionsEnd
65
+ )}
66
+ `;
67
+ const before = code.slice(0, lineStart);
68
+ const between = code.slice(lineStart, optionsStart);
69
+ const after = code.slice(optionsEnd);
70
+ return before + optionsConst + between + "__cedar_graphqlOptions" + after;
71
+ }
72
+ function applyGqlormInject(code, id, dbExt = ".ts") {
73
+ if (code.includes("__gqlorm_sdl__")) {
74
+ return null;
75
+ }
76
+ if (!code.includes("createGraphQLHandler")) {
77
+ return null;
78
+ }
79
+ if (!getConfig().experimental?.gqlorm?.enabled) {
80
+ return null;
81
+ }
82
+ const backendPathWithoutExt = path.join(
83
+ getPaths().generated.base,
84
+ "gqlorm",
85
+ "backend"
86
+ );
87
+ if (!fs.existsSync(backendPathWithoutExt + ".ts")) {
88
+ return null;
89
+ }
90
+ const handlerPattern = /^export\s+const\s+(\w+)\s*=\s*createGraphQLHandler\s*\(/m;
91
+ const handlerMatch = handlerPattern.exec(code);
92
+ if (!handlerMatch) {
93
+ return null;
94
+ }
95
+ const handlerLineStart = code.lastIndexOf("\n", handlerMatch.index) + 1;
96
+ const relPath = importStatementPath(
97
+ path.relative(path.dirname(id), backendPathWithoutExt)
98
+ ) + ".ts";
99
+ const dbSrcPath = path.join(getPaths().api.src, "lib", "db");
100
+ const relDbPath = importStatementPath(path.relative(path.dirname(id), dbSrcPath)) + dbExt;
101
+ const importDb = `import { db as __gqlorm_db__ } from '${relDbPath}'`;
102
+ const importSdl = `import * as __gqlorm_sdl__ from '${relPath}'`;
103
+ const importsToAdd = `${importDb}
104
+ ${importSdl}
105
+ `;
106
+ const sdlsMutation = `Object.assign(sdls, {
107
+ __gqlorm__: {
108
+ schema: __gqlorm_sdl__.schema,
109
+ resolvers: __gqlorm_sdl__.createGqlormResolvers(__gqlorm_db__),
110
+ },
111
+ })
112
+ `;
113
+ const transformed = importsToAdd + code.slice(0, handlerLineStart) + sdlsMutation + code.slice(handlerLineStart);
114
+ return transformed;
115
+ }
116
+ export {
117
+ applyGqlormInject,
118
+ applyGraphqlOptionsExtract
119
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/build/api.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAgB,YAAY,EAAe,MAAM,SAAS,CAAA;AAiBtE,eAAO,MAAM,QAAQ,4DAIpB,CAAA;AAED,eAAO,MAAM,UAAU,4DAStB,CAAA;AAED,eAAO,MAAM,aAAa,qBAGzB,CAAA;AA8FD,eAAO,MAAM,gBAAgB,iHAqD5B,CAAA;AAcD,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAoDf"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/build/api.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAgB,YAAY,EAAe,MAAM,SAAS,CAAA;AAuBtE,eAAO,MAAM,QAAQ,4DAIpB,CAAA;AAED,eAAO,MAAM,UAAU,4DAStB,CAAA;AAED,eAAO,MAAM,aAAa,qBAGzB,CAAA;AAuID,eAAO,MAAM,gBAAgB,iHAqD5B,CAAA;AAcD,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAoDf"}
package/dist/build/api.js CHANGED
@@ -8,7 +8,13 @@ import {
8
8
  } from "@cedarjs/babel-config";
9
9
  import { getConfig, getPaths, projectSideIsEsm } from "@cedarjs/project-config";
10
10
  import { findApiFiles } from "../files.js";
11
- import { applyContextWrapping } from "./esbuild-plugin-cedar-context-wrapping.js";
11
+ import {
12
+ applyGqlormInject,
13
+ applyGraphqlOptionsExtract
14
+ } from "./api-graphql-transforms.js";
15
+ import { cedarApiGraphqlPlugin } from "./esbuild-plugin-api-graphql.js";
16
+ import { applyOtelWrapping } from "./esbuild-plugin-cedar-otel-wrapping.js";
17
+ import { applyHandlerAlsWrapping } from "./esbuild-plugin-handler-als-wrapping.js";
12
18
  let BUILD_CTX = null;
13
19
  const buildApi = async () => {
14
20
  BUILD_CTX?.dispose();
@@ -32,24 +38,29 @@ const cleanApiBuild = async () => {
32
38
  const runCedarBabelTransformsPlugin = {
33
39
  name: "cedar-esbuild-babel-transform",
34
40
  setup(build2) {
35
- const cedarConfig = getConfig();
36
41
  build2.onLoad({ filter: /\.(js|ts|tsx|jsx)$/ }, async (args) => {
37
42
  const fileContents = await fs.promises.readFile(args.path, "utf-8");
38
43
  const transformedCode = await transformWithBabel(
39
44
  fileContents,
40
45
  args.path,
41
46
  getApiSideBabelPlugins({
42
- openTelemetry: cedarConfig.experimental.opentelemetry.enabled && cedarConfig.experimental.opentelemetry.wrapApi,
43
47
  projectIsEsm: projectSideIsEsm("api")
44
48
  })
45
49
  );
46
50
  if (transformedCode?.code) {
47
- const functionsDir = normalizePath(
48
- path.join(getPaths().api.src, "functions")
49
- );
50
- const code = normalizePath(args.path).startsWith(functionsDir + "/") ? applyContextWrapping(transformedCode.code, {
51
- projectIsEsm: projectSideIsEsm("api")
52
- }) ?? transformedCode.code : transformedCode.code;
51
+ let code = transformedCode.code;
52
+ const normalizedPath = normalizePath(args.path);
53
+ const cedarPaths = getPaths();
54
+ const isEsm = projectSideIsEsm("api");
55
+ const functionsDir = normalizePath(cedarPaths.api.functions);
56
+ if (normalizedPath.startsWith(functionsDir + "/")) {
57
+ code = applyHandlerAlsWrapping(code, {
58
+ projectIsEsm: isEsm
59
+ }) ?? code;
60
+ }
61
+ if (normalizedPath.startsWith(normalizePath(cedarPaths.api.src) + "/")) {
62
+ code = applyOtelWrapping(code, args.path, cedarPaths.api.src) ?? code;
63
+ }
53
64
  return {
54
65
  contents: code,
55
66
  loader: "js"
@@ -76,22 +87,31 @@ function createCedarViteApiPlugin() {
76
87
  if (!normalizePath(id).startsWith(normalizePath(cedarPaths.api.base))) {
77
88
  return null;
78
89
  }
90
+ let sourceCode = code;
91
+ const normalizedId = normalizePath(id);
92
+ if (normalizedId.endsWith("/graphql.ts") || normalizedId.endsWith("/graphql.js")) {
93
+ sourceCode = applyGraphqlOptionsExtract(sourceCode) ?? sourceCode;
94
+ sourceCode = applyGqlormInject(sourceCode, id) ?? sourceCode;
95
+ }
79
96
  const transformedCode = await transformWithBabel(
80
- code,
97
+ sourceCode,
81
98
  id,
82
99
  getApiSideBabelPlugins({
83
- openTelemetry: cedarConfig.experimental.opentelemetry.enabled && cedarConfig.experimental.opentelemetry.wrapApi,
84
100
  projectIsEsm: isEsm
85
101
  }),
86
102
  true
87
103
  );
88
104
  if (transformedCode?.code) {
89
- const functionsDir = normalizePath(
90
- path.join(cedarPaths.api.src, "functions")
91
- );
92
- const code2 = normalizePath(id).startsWith(functionsDir + "/") ? applyContextWrapping(transformedCode.code, {
93
- projectIsEsm: isEsm
94
- }) ?? transformedCode.code : transformedCode.code;
105
+ let code2 = transformedCode.code;
106
+ if (cedarConfig.experimental?.opentelemetry?.enabled && cedarConfig.experimental?.opentelemetry?.wrapApi) {
107
+ code2 = applyOtelWrapping(code2, id, cedarPaths.api.src) ?? code2;
108
+ }
109
+ const functionsDir = normalizePath(cedarPaths.api.functions);
110
+ if (normalizedId.startsWith(functionsDir + "/")) {
111
+ code2 = applyHandlerAlsWrapping(code2, {
112
+ projectIsEsm: isEsm
113
+ }) ?? code2;
114
+ }
95
115
  return {
96
116
  code: code2,
97
117
  map: transformedCode.map ?? null
@@ -199,7 +219,10 @@ function getEsbuildOptions(files) {
199
219
  format,
200
220
  allowOverwrite: true,
201
221
  bundle: false,
202
- plugins: [runCedarBabelTransformsPlugin],
222
+ // Registration order matters: cedarApiGraphqlPlugin (narrow filter) must
223
+ // come first so it claims graphql.ts before runCedarBabelTransformsPlugin
224
+ // (broad filter) can. See the NOTE on cedarApiGraphqlPlugin.
225
+ plugins: [cedarApiGraphqlPlugin, runCedarBabelTransformsPlugin],
203
226
  outdir: cedarPaths.api.dist,
204
227
  // setting this to 'true' will generate an external sourcemap x.js.map
205
228
  // AND set the sourceMappingURL comment
@@ -0,0 +1,6 @@
1
+ import type { PluginBuild } from 'esbuild';
2
+ export declare const cedarApiGraphqlPlugin: {
3
+ name: string;
4
+ setup(build: PluginBuild): void;
5
+ };
6
+ //# sourceMappingURL=esbuild-plugin-api-graphql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"esbuild-plugin-api-graphql.d.ts","sourceRoot":"","sources":["../../src/build/esbuild-plugin-api-graphql.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAe1C,eAAO,MAAM,qBAAqB;;iBAEnB,WAAW;CA0DzB,CAAA"}
@@ -0,0 +1,47 @@
1
+ import fs from "node:fs";
2
+ import {
3
+ getApiSideBabelPlugins,
4
+ transformWithBabel
5
+ } from "@cedarjs/babel-config";
6
+ import { getConfig, getPaths, projectSideIsEsm } from "@cedarjs/project-config";
7
+ import {
8
+ applyGqlormInject,
9
+ applyGraphqlOptionsExtract
10
+ } from "./api-graphql-transforms.js";
11
+ import { applyOtelWrapping } from "./esbuild-plugin-cedar-otel-wrapping.js";
12
+ import { applyHandlerAlsWrapping } from "./esbuild-plugin-handler-als-wrapping.js";
13
+ const cedarApiGraphqlPlugin = {
14
+ name: "cedar-api-graphql",
15
+ setup(build) {
16
+ build.onLoad({ filter: /[/\\]graphql\.(ts|js)$/ }, async (args) => {
17
+ const cedarConfig = getConfig();
18
+ let fileContents = await fs.promises.readFile(args.path, "utf-8");
19
+ fileContents = applyGraphqlOptionsExtract(fileContents) ?? fileContents;
20
+ fileContents = applyGqlormInject(fileContents, args.path, ".js") ?? fileContents;
21
+ const transformedCode = await transformWithBabel(
22
+ fileContents,
23
+ args.path,
24
+ getApiSideBabelPlugins({
25
+ projectIsEsm: projectSideIsEsm("api")
26
+ })
27
+ );
28
+ if (!transformedCode?.code) {
29
+ throw new Error(`Could not transform file: ${args.path}`);
30
+ }
31
+ let code = transformedCode.code;
32
+ if (cedarConfig.experimental?.opentelemetry?.enabled && cedarConfig.experimental?.opentelemetry?.wrapApi) {
33
+ code = applyOtelWrapping(code, args.path, getPaths().api.src) ?? code;
34
+ }
35
+ code = applyHandlerAlsWrapping(code, {
36
+ projectIsEsm: projectSideIsEsm("api")
37
+ }) ?? code;
38
+ return {
39
+ contents: code,
40
+ loader: "js"
41
+ };
42
+ });
43
+ }
44
+ };
45
+ export {
46
+ cedarApiGraphqlPlugin
47
+ };
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Standalone esbuild equivalent of the Vite cedarOtelWrappingPlugin. Applied
3
+ * inline in the esbuild API build and the standalone-Vite API build so neither
4
+ * path depends on a Babel OTel plugin.
5
+ *
6
+ * For each `export const fn = (async?) (...) => {...}` in an API file, this
7
+ * wraps it with an OpenTelemetry span.
8
+ *
9
+ * Keep this in sync with
10
+ * packages/vite/src/plugins/vite-plugin-cedar-otel-wrapping.ts.
11
+ */
12
+ export declare function applyOtelWrapping(code: string, filename: string, apiSrc: string): string | null;
13
+ //# sourceMappingURL=esbuild-plugin-cedar-otel-wrapping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"esbuild-plugin-cedar-otel-wrapping.d.ts","sourceRoot":"","sources":["../../src/build/esbuild-plugin-cedar-otel-wrapping.ts"],"names":[],"mappings":"AASA;;;;;;;;;;GAUG;AAEH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,IAAI,CAmFf"}
@@ -0,0 +1,180 @@
1
+ import path from "node:path";
2
+ import { parseSync } from "oxc-parser";
3
+ function applyOtelWrapping(code, filename, apiSrc) {
4
+ const relative = path.relative(apiSrc, filename);
5
+ const apiFolder = relative.split(path.sep)[0] ?? "?";
6
+ const parseResult = parseSync(filename, code, { sourceType: "module" });
7
+ const replacements = [];
8
+ for (const node of parseResult.program.body) {
9
+ if (node.type !== "ExportNamedDeclaration") {
10
+ continue;
11
+ }
12
+ const decl = node.declaration;
13
+ if (decl?.type !== "VariableDeclaration") {
14
+ continue;
15
+ }
16
+ const declarator = decl.declarations[0];
17
+ if (!declarator) {
18
+ continue;
19
+ }
20
+ const fn = declarator.init;
21
+ if (fn?.type !== "ArrowFunctionExpression") {
22
+ continue;
23
+ }
24
+ if (declarator.id.type !== "Identifier") {
25
+ continue;
26
+ }
27
+ const fnName = declarator.id.name;
28
+ const innerArgs = buildInnerArgs(fn.params);
29
+ if (innerArgs === null) {
30
+ continue;
31
+ }
32
+ const fnHeader = code.slice(fn.start, fn.body.start);
33
+ const originalFnSrc = code.slice(fn.start, fn.end);
34
+ const isAsync = fn.async;
35
+ const awaitKw = isAsync ? "await " : "";
36
+ const asyncKw = isAsync ? "async " : "";
37
+ replacements.push({
38
+ start: node.start,
39
+ end: node.end,
40
+ src: buildWrappedExport(
41
+ fnName,
42
+ fnHeader,
43
+ originalFnSrc,
44
+ innerArgs,
45
+ awaitKw,
46
+ asyncKw,
47
+ apiFolder,
48
+ filename
49
+ )
50
+ });
51
+ }
52
+ if (replacements.length === 0) {
53
+ return null;
54
+ }
55
+ let output = code;
56
+ for (let i = replacements.length - 1; i >= 0; i--) {
57
+ const r = replacements[i];
58
+ output = output.slice(0, r.start) + r.src + output.slice(r.end);
59
+ }
60
+ return `import { trace as OTEL_TRACE } from '@opentelemetry/api'
61
+ ` + output;
62
+ }
63
+ function buildInnerArgs(params) {
64
+ const args = [];
65
+ for (const param of params) {
66
+ if (param.type === "RestElement" || param.type === "ArrayPattern" || param.type === "TSParameterProperty") {
67
+ return null;
68
+ }
69
+ if (param.type === "Identifier") {
70
+ args.push(param.name);
71
+ continue;
72
+ }
73
+ if (param.type === "ObjectPattern") {
74
+ for (const prop of param.properties) {
75
+ if (prop.type === "RestElement") {
76
+ return null;
77
+ }
78
+ if (prop.key.type !== "Identifier") {
79
+ return null;
80
+ }
81
+ const value = prop.value;
82
+ if (value.type !== "Identifier" && value.type !== "AssignmentPattern" && value.type !== "ObjectPattern") {
83
+ return null;
84
+ }
85
+ if (value.type === "AssignmentPattern") {
86
+ if (value.left.type !== "Identifier" && value.left.type !== "ObjectPattern") {
87
+ return null;
88
+ }
89
+ }
90
+ }
91
+ const obj = buildObjectCallArg(param);
92
+ if (obj === null) {
93
+ return null;
94
+ }
95
+ args.push(obj);
96
+ continue;
97
+ }
98
+ if (param.type === "AssignmentPattern") {
99
+ const ap = param;
100
+ if (ap.left.type === "Identifier") {
101
+ args.push(ap.left.name);
102
+ } else if (ap.left.type === "ObjectPattern") {
103
+ const obj = buildObjectCallArg(ap.left);
104
+ if (obj === null) {
105
+ return null;
106
+ }
107
+ args.push(obj);
108
+ } else {
109
+ return null;
110
+ }
111
+ continue;
112
+ }
113
+ return null;
114
+ }
115
+ return args.join(", ");
116
+ }
117
+ function buildObjectCallArg(pattern) {
118
+ const keys = [];
119
+ for (const prop of pattern.properties) {
120
+ if (prop.type === "RestElement") {
121
+ return null;
122
+ }
123
+ if (prop.key.type !== "Identifier") {
124
+ return null;
125
+ }
126
+ const keyName = prop.key.name;
127
+ let valueName = null;
128
+ if (prop.value.type === "Identifier") {
129
+ valueName = prop.value.name;
130
+ } else if (prop.value.type === "AssignmentPattern") {
131
+ if (prop.value.left.type === "Identifier") {
132
+ valueName = prop.value.left.name;
133
+ } else {
134
+ return null;
135
+ }
136
+ } else {
137
+ return null;
138
+ }
139
+ if (valueName !== keyName) {
140
+ keys.push(`${keyName}: ${valueName}`);
141
+ } else {
142
+ keys.push(keyName);
143
+ }
144
+ }
145
+ return `{ ${keys.join(", ")} }`;
146
+ }
147
+ function buildWrappedExport(fnName, fnHeader, originalFnSrc, innerArgs, awaitKw, asyncKw, apiFolder, filename) {
148
+ const privateName = `__${fnName}`;
149
+ const spanName = `redwoodjs:api:${apiFolder}:${fnName}`;
150
+ return `export const ${fnName} = ${fnHeader}{
151
+ const ${privateName} = ${originalFnSrc}
152
+ const OTEL_TRACER = OTEL_TRACE.getTracer('redwoodjs')
153
+ const OTEL_RESULT = ${awaitKw}OTEL_TRACER.startActiveSpan(
154
+ '${spanName}',
155
+ ${asyncKw}(span) => {
156
+ span.setAttribute('code.function', '${fnName}')
157
+ span.setAttribute('code.filepath', ${JSON.stringify(filename)})
158
+ try {
159
+ const OTEL_INNER_RESULT = ${awaitKw}${privateName}(${innerArgs})
160
+ span.end()
161
+ return OTEL_INNER_RESULT
162
+ } catch (error) {
163
+ span.recordException(error)
164
+ span.setStatus({
165
+ code: 2,
166
+ message:
167
+ error?.message?.split('\\n')[0] ??
168
+ error?.toString()?.split('\\n')[0],
169
+ })
170
+ span.end()
171
+ throw error
172
+ }
173
+ }
174
+ )
175
+ return OTEL_RESULT
176
+ }`;
177
+ }
178
+ export {
179
+ applyOtelWrapping
180
+ };
@@ -0,0 +1,4 @@
1
+ export declare function applyHandlerAlsWrapping(code: string, { projectIsEsm }?: {
2
+ projectIsEsm?: boolean;
3
+ }): string | null;
4
+ //# sourceMappingURL=esbuild-plugin-handler-als-wrapping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"esbuild-plugin-handler-als-wrapping.d.ts","sourceRoot":"","sources":["../../src/build/esbuild-plugin-handler-als-wrapping.ts"],"names":[],"mappings":"AAOA,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,EAAE,YAAoB,EAAE,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAO,GACxD,MAAM,GAAG,IAAI,CA0Cf"}
@@ -1,4 +1,4 @@
1
- function applyContextWrapping(code, { projectIsEsm = false } = {}) {
1
+ function applyHandlerAlsWrapping(code, { projectIsEsm = false } = {}) {
2
2
  const handlerRe = /^export\s+(?:const|let|var)\s+handler(?:[^=]|=>)*?=(?![>=])/m;
3
3
  const handlerMatch = handlerRe.exec(code);
4
4
  if (!handlerMatch) {
@@ -7,29 +7,29 @@ function applyContextWrapping(code, { projectIsEsm = false } = {}) {
7
7
  const afterEquals = code.slice(handlerMatch.index + handlerMatch[0].length).trimStart();
8
8
  const isAsync = /^async(?:\s*[\(\*]|\s+function)/.test(afterEquals);
9
9
  const storePath = projectIsEsm ? "@cedarjs/context/dist/store.js" : "@cedarjs/context/dist/store";
10
- const importStatement = `import { getAsyncStoreInstance as __rw_getAsyncStoreInstance } from '${storePath}'
10
+ const importStatement = `import { getAsyncStoreInstance as __cedar_getAsyncStoreInstance } from '${storePath}'
11
11
  `;
12
12
  const handlerStart = handlerMatch.index;
13
13
  const before = code.slice(0, handlerStart);
14
14
  const after = code.slice(handlerStart);
15
- const renamed = after.replace(handlerRe, "const __rw_handler =");
15
+ const renamed = after.replace(handlerRe, "const __cedar_handler =");
16
16
  const wrappedHandler = `
17
- export const handler = ${isAsync ? "async " : ""}(__rw_event, __rw__context) => {
17
+ export const handler = ${isAsync ? "async " : ""}(__cedar_event, __cedar_context) => {
18
18
  // The store will be undefined if no context isolation has been performed yet
19
- const __rw_contextStore = __rw_getAsyncStoreInstance().getStore()
20
- if (__rw_contextStore === undefined) {
21
- return __rw_getAsyncStoreInstance().run(
19
+ const __cedar_contextStore = __cedar_getAsyncStoreInstance().getStore()
20
+ if (__cedar_contextStore === undefined) {
21
+ return __cedar_getAsyncStoreInstance().run(
22
22
  new Map(),
23
- __rw_handler,
24
- __rw_event,
25
- __rw__context
23
+ __cedar_handler,
24
+ __cedar_event,
25
+ __cedar_context
26
26
  )
27
27
  }
28
- return __rw_handler(__rw_event, __rw__context)
28
+ return __cedar_handler(__cedar_event, __cedar_context)
29
29
  }
30
30
  `;
31
31
  return before + importStatement + renamed + wrappedHandler;
32
32
  }
33
33
  export {
34
- applyContextWrapping
34
+ applyHandlerAlsWrapping
35
35
  };
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Extracts the options argument from createGraphQLHandler calls and stores
3
+ * them in an exported variable. Returns the transformed code, or null if no
4
+ * transformation was needed.
5
+ *
6
+ * Transforms:
7
+ * export const handler = createGraphQLHandler({ options })
8
+ * into:
9
+ * export const __cedar_graphqlOptions = { options }
10
+ * export const handler = createGraphQLHandler(__cedar_graphqlOptions)
11
+ */
12
+ export declare function applyGraphqlOptionsExtract(code: string): string | null;
13
+ /**
14
+ * Injects the auto-generated gqlorm backend into graphql.ts at build time.
15
+ *
16
+ * When `experimental.gqlorm.enabled = true` and `.cedar/gqlorm/backend.ts`
17
+ * exists, this function:
18
+ *
19
+ * 1. Adds imports at the top of graphql.ts:
20
+ * import * as __gqlorm_sdl__ from '../../../.cedar/gqlorm/backend'
21
+ * import { db as __gqlorm_db__ } from 'src/lib/db'
22
+ *
23
+ * 2. Inserts a statement immediately before the `createGraphQLHandler` call:
24
+ * Object.assign(sdls, {
25
+ * __gqlorm__: {
26
+ * schema: __gqlorm_sdl__.schema,
27
+ * resolvers: __gqlorm_sdl__.createGqlormResolvers(__gqlorm_db__),
28
+ * },
29
+ * })
30
+ *
31
+ * Returns the transformed code, or null if no transformation was needed.
32
+ */
33
+ export declare function applyGqlormInject(code: string, id: string, dbExt?: '.ts' | '.js'): string | null;
34
+ //# sourceMappingURL=api-graphql-transforms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-graphql-transforms.d.ts","sourceRoot":"","sources":["../../../src/build/api-graphql-transforms.ts"],"names":[],"mappings":"AAYA;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA6FtE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,KAAK,GAAE,KAAK,GAAG,KAAa,GAC3B,MAAM,GAAG,IAAI,CAmFf"}