@zuplo/cli 7.4.4 → 7.4.5

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 (61) hide show
  1. package/dist/common/settings.d.ts +1 -0
  2. package/dist/common/settings.d.ts.map +1 -1
  3. package/dist/common/settings.js +3 -0
  4. package/dist/common/settings.js.map +1 -1
  5. package/dist/deploy/classify-build-probe.d.ts +14 -0
  6. package/dist/deploy/classify-build-probe.d.ts.map +1 -0
  7. package/dist/deploy/classify-build-probe.js +35 -0
  8. package/dist/deploy/classify-build-probe.js.map +1 -0
  9. package/dist/deploy/classify-build-probe.test.d.ts +2 -0
  10. package/dist/deploy/classify-build-probe.test.d.ts.map +1 -0
  11. package/dist/deploy/classify-build-probe.test.js +51 -0
  12. package/dist/deploy/classify-build-probe.test.js.map +1 -0
  13. package/dist/deploy/handler.js +20 -5
  14. package/dist/deploy/handler.js.map +1 -1
  15. package/dist/deploy/poll-deployment.d.ts +8 -4
  16. package/dist/deploy/poll-deployment.d.ts.map +1 -1
  17. package/dist/deploy/poll-deployment.js +32 -4
  18. package/dist/deploy/poll-deployment.js.map +1 -1
  19. package/dist/deploy/poll-deployment.test.d.ts +2 -0
  20. package/dist/deploy/poll-deployment.test.d.ts.map +1 -0
  21. package/dist/deploy/poll-deployment.test.js +158 -0
  22. package/dist/deploy/poll-deployment.test.js.map +1 -0
  23. package/dist/tsconfig.tsbuildinfo +1 -1
  24. package/node_modules/@posthog/core/dist/logs/index.js +1 -1
  25. package/node_modules/@posthog/core/dist/logs/index.mjs +1 -1
  26. package/node_modules/@posthog/core/dist/logs/logs-utils.d.ts +4 -13
  27. package/node_modules/@posthog/core/dist/logs/logs-utils.d.ts.map +1 -1
  28. package/node_modules/@posthog/core/dist/logs/logs-utils.js +160 -26
  29. package/node_modules/@posthog/core/dist/logs/logs-utils.mjs +160 -26
  30. package/node_modules/@posthog/core/dist/metrics/index.js +1 -1
  31. package/node_modules/@posthog/core/dist/metrics/index.mjs +1 -1
  32. package/node_modules/@posthog/core/dist/posthog-core.d.ts.map +1 -1
  33. package/node_modules/@posthog/core/dist/posthog-core.js +12 -7
  34. package/node_modules/@posthog/core/dist/posthog-core.mjs +12 -7
  35. package/node_modules/@posthog/core/dist/utils/index.d.ts +1 -1
  36. package/node_modules/@posthog/core/dist/utils/index.d.ts.map +1 -1
  37. package/node_modules/@posthog/core/dist/utils/index.js +14 -24
  38. package/node_modules/@posthog/core/dist/utils/index.mjs +2 -2
  39. package/node_modules/@posthog/core/dist/utils/json-utils.d.ts +15 -0
  40. package/node_modules/@posthog/core/dist/utils/json-utils.d.ts.map +1 -1
  41. package/node_modules/@posthog/core/dist/utils/json-utils.js +24 -0
  42. package/node_modules/@posthog/core/dist/utils/json-utils.mjs +1 -1
  43. package/node_modules/@posthog/core/package.json +2 -2
  44. package/node_modules/@posthog/core/src/logs/index.ts +1 -1
  45. package/node_modules/@posthog/core/src/logs/logs-utils.spec.ts +314 -9
  46. package/node_modules/@posthog/core/src/logs/logs-utils.ts +215 -27
  47. package/node_modules/@posthog/core/src/metrics/index.spec.ts +15 -1
  48. package/node_modules/@posthog/core/src/metrics/index.ts +1 -1
  49. package/node_modules/@posthog/core/src/posthog-core.ts +19 -12
  50. package/node_modules/@posthog/core/src/utils/index.ts +3 -1
  51. package/node_modules/@posthog/core/src/utils/json-utils.ts +15 -8
  52. package/node_modules/@posthog/types/dist/capture-log.d.ts +10 -1
  53. package/node_modules/@posthog/types/dist/capture-log.d.ts.map +1 -1
  54. package/node_modules/@posthog/types/package.json +1 -1
  55. package/node_modules/@posthog/types/src/capture-log.ts +8 -1
  56. package/node_modules/@zuplo/core/package.json +1 -1
  57. package/node_modules/@zuplo/graphql/package.json +1 -1
  58. package/node_modules/@zuplo/openapi-tools/package.json +1 -1
  59. package/node_modules/@zuplo/otel/package.json +1 -1
  60. package/node_modules/@zuplo/runtime/package.json +1 -1
  61. package/package.json +11 -11
@@ -0,0 +1,158 @@
1
+ import { afterEach, beforeEach, describe, it } from "node:test";
2
+ import { assert } from "chai";
3
+ import { getGlobalDispatcher, MockAgent, setGlobalDispatcher, } from "undici";
4
+ import { pollDeployment } from "./poll-deployment.js";
5
+ const DEV_API_ORIGIN = "https://developer.test";
6
+ const DEPLOYMENT_ORIGIN = "https://my-api.zuplo.app";
7
+ const PRIVATE_DEPLOYMENT_ORIGIN = "https://gateway.example.com";
8
+ const STATUS_PATH = "/v1/accounts/test-account/projects/test-project/deployment-status/deployment-123";
9
+ const BUILD_PATH = "/__zuplo/build";
10
+ const BUILD_ID = "build-new";
11
+ const LOG_URL = "https://portal.zuplo.com/builds/build-new";
12
+ const INIT_ERROR_DETAIL = "Value of 'allowedOrigins' on custom cors policies is invalid.";
13
+ const FALLBACK_INIT_ERROR_DETAIL = "The gateway failed to initialize after deployment. Check the deployment logs for details.";
14
+ const ENVIRONMENT_VARIABLES = [
15
+ "ZUPLO_DEVELOPER_API_ENDPOINT",
16
+ "MAX_POLL_RETRIES",
17
+ "POLL_INTERVAL",
18
+ "DEPLOY_INIT_ERROR_FAIL_FAST",
19
+ ];
20
+ const argv = { authToken: "tok" };
21
+ function statusBody(overrides = {}) {
22
+ return {
23
+ status: "SUCCESS",
24
+ url: DEPLOYMENT_ORIGIN,
25
+ logUrl: LOG_URL,
26
+ buildId: BUILD_ID,
27
+ ...overrides,
28
+ };
29
+ }
30
+ function initErrorBody(overrides = {}) {
31
+ return {
32
+ status: 500,
33
+ title: "Gateway Initialization Error",
34
+ type: "https://httpproblems.com/http-status/500",
35
+ detail: INIT_ERROR_DETAIL,
36
+ trace: { timestamp: 0, buildId: BUILD_ID },
37
+ ...overrides,
38
+ };
39
+ }
40
+ describe("pollDeployment", () => {
41
+ let mockAgent;
42
+ let previousDispatcher;
43
+ let devApiPool;
44
+ let deploymentPool;
45
+ let previousEnvironment;
46
+ let spinner;
47
+ beforeEach(() => {
48
+ previousEnvironment = Object.fromEntries(ENVIRONMENT_VARIABLES.map((name) => [name, process.env[name]]));
49
+ process.env.ZUPLO_DEVELOPER_API_ENDPOINT = DEV_API_ORIGIN;
50
+ process.env.MAX_POLL_RETRIES = "3";
51
+ process.env.POLL_INTERVAL = "1";
52
+ delete process.env.DEPLOY_INIT_ERROR_FAIL_FAST;
53
+ previousDispatcher = getGlobalDispatcher();
54
+ mockAgent = new MockAgent();
55
+ mockAgent.disableNetConnect();
56
+ setGlobalDispatcher(mockAgent);
57
+ devApiPool = mockAgent.get(DEV_API_ORIGIN);
58
+ deploymentPool = mockAgent.get(DEPLOYMENT_ORIGIN);
59
+ spinner = { suffixText: "" };
60
+ });
61
+ afterEach(async () => {
62
+ await mockAgent.close();
63
+ setGlobalDispatcher(previousDispatcher);
64
+ for (const name of ENVIRONMENT_VARIABLES) {
65
+ const value = previousEnvironment[name];
66
+ if (value === undefined) {
67
+ delete process.env[name];
68
+ }
69
+ else {
70
+ process.env[name] = value;
71
+ }
72
+ }
73
+ });
74
+ function interceptStatus(body, times = 1) {
75
+ devApiPool
76
+ .intercept({ path: STATUS_PATH, method: "GET" })
77
+ .reply(200, body)
78
+ .times(times);
79
+ }
80
+ function interceptProbe(status, body, times = 1) {
81
+ deploymentPool
82
+ .intercept({ path: BUILD_PATH, method: "GET" })
83
+ .reply(status, body)
84
+ .times(times);
85
+ }
86
+ function poll() {
87
+ return pollDeployment(argv, "deployment-123", "test-account", "test-project", spinner);
88
+ }
89
+ it("fails fast after two consecutive matching initialization errors", async () => {
90
+ interceptStatus(statusBody(), 2);
91
+ interceptProbe(500, initErrorBody(), 2);
92
+ const result = await poll();
93
+ assert.deepEqual(result, {
94
+ logUrl: LOG_URL,
95
+ initError: { detail: INIT_ERROR_DETAIL },
96
+ });
97
+ assert.strictEqual(mockAgent.pendingInterceptors().length, 0);
98
+ });
99
+ it("succeeds when one matching initialization error is followed by a live probe", async () => {
100
+ interceptStatus(statusBody(), 2);
101
+ interceptProbe(500, initErrorBody());
102
+ interceptProbe(200, { buildId: BUILD_ID });
103
+ assert.deepEqual(await poll(), {
104
+ url: DEPLOYMENT_ORIGIN,
105
+ logUrl: LOG_URL,
106
+ });
107
+ assert.strictEqual(mockAgent.pendingInterceptors().length, 0);
108
+ });
109
+ it("polls to exhaustion when the initialization error is for another build", async () => {
110
+ interceptStatus(statusBody(), 3);
111
+ interceptProbe(500, initErrorBody({ trace: { timestamp: 0, buildId: "build-old" } }), 3);
112
+ assert.deepEqual(await poll(), { logUrl: LOG_URL });
113
+ });
114
+ it("does not fail fast when the status response omits buildId", async () => {
115
+ interceptStatus(statusBody({ buildId: undefined }), 3);
116
+ interceptProbe(500, initErrorBody(), 3);
117
+ assert.deepEqual(await poll(), { logUrl: LOG_URL });
118
+ });
119
+ it("keeps polling after a non-JSON 5xx probe response", async () => {
120
+ interceptStatus(statusBody(), 3);
121
+ interceptProbe(500, "<html>unavailable</html>", 3);
122
+ assert.deepEqual(await poll(), { logUrl: LOG_URL });
123
+ });
124
+ it("uses the fallback detail when a matching initialization error omits detail", async () => {
125
+ interceptStatus(statusBody(), 2);
126
+ interceptProbe(500, initErrorBody({ detail: undefined }), 2);
127
+ assert.deepEqual(await poll(), {
128
+ logUrl: LOG_URL,
129
+ initError: { detail: FALLBACK_INIT_ERROR_DETAIL },
130
+ });
131
+ });
132
+ it("returns the latest build log URL when in-progress polling is exhausted", async () => {
133
+ interceptStatus(statusBody({ status: "IN_PROGRESS", url: undefined }), 3);
134
+ assert.deepEqual(await poll(), { logUrl: LOG_URL });
135
+ });
136
+ it("returns the deployment URL after a successful build probe", async () => {
137
+ interceptStatus(statusBody());
138
+ interceptProbe(200, { buildId: BUILD_ID });
139
+ assert.deepEqual(await poll(), {
140
+ url: DEPLOYMENT_ORIGIN,
141
+ logUrl: LOG_URL,
142
+ });
143
+ });
144
+ it("returns a non-Zuplo deployment URL without probing it", async () => {
145
+ interceptStatus(statusBody({ url: PRIVATE_DEPLOYMENT_ORIGIN }));
146
+ assert.deepEqual(await poll(), {
147
+ url: PRIVATE_DEPLOYMENT_ORIGIN,
148
+ logUrl: LOG_URL,
149
+ });
150
+ });
151
+ it("keeps polling matching initialization errors when fail-fast is disabled", async () => {
152
+ process.env.DEPLOY_INIT_ERROR_FAIL_FAST = "false";
153
+ interceptStatus(statusBody(), 3);
154
+ interceptProbe(500, initErrorBody(), 3);
155
+ assert.deepEqual(await poll(), { logUrl: LOG_URL });
156
+ });
157
+ });
158
+ //# sourceMappingURL=poll-deployment.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poll-deployment.test.js","sourceRoot":"","sources":["../../src/deploy/poll-deployment.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { afterEach, beforeEach, describe, it } from \"node:test\";\nimport { assert } from \"chai\";\nimport type { Ora } from \"ora\";\nimport {\n type Dispatcher,\n getGlobalDispatcher,\n MockAgent,\n type MockPool,\n setGlobalDispatcher,\n} from \"undici\";\nimport type { Arguments } from \"./handler.js\";\nimport { pollDeployment } from \"./poll-deployment.js\";\n\nconst DEV_API_ORIGIN = \"https://developer.test\";\nconst DEPLOYMENT_ORIGIN = \"https://my-api.zuplo.app\";\nconst PRIVATE_DEPLOYMENT_ORIGIN = \"https://gateway.example.com\";\nconst STATUS_PATH =\n \"/v1/accounts/test-account/projects/test-project/deployment-status/deployment-123\";\nconst BUILD_PATH = \"/__zuplo/build\";\nconst BUILD_ID = \"build-new\";\nconst LOG_URL = \"https://portal.zuplo.com/builds/build-new\";\nconst INIT_ERROR_DETAIL =\n \"Value of 'allowedOrigins' on custom cors policies is invalid.\";\nconst FALLBACK_INIT_ERROR_DETAIL =\n \"The gateway failed to initialize after deployment. Check the deployment logs for details.\";\nconst ENVIRONMENT_VARIABLES = [\n \"ZUPLO_DEVELOPER_API_ENDPOINT\",\n \"MAX_POLL_RETRIES\",\n \"POLL_INTERVAL\",\n \"DEPLOY_INIT_ERROR_FAIL_FAST\",\n] as const;\n\nconst argv = { authToken: \"tok\" } as Arguments;\n\nfunction statusBody(overrides: Record<string, unknown> = {}) {\n return {\n status: \"SUCCESS\",\n url: DEPLOYMENT_ORIGIN,\n logUrl: LOG_URL,\n buildId: BUILD_ID,\n ...overrides,\n };\n}\n\nfunction initErrorBody(overrides: Record<string, unknown> = {}) {\n return {\n status: 500,\n title: \"Gateway Initialization Error\",\n type: \"https://httpproblems.com/http-status/500\",\n detail: INIT_ERROR_DETAIL,\n trace: { timestamp: 0, buildId: BUILD_ID },\n ...overrides,\n };\n}\n\ndescribe(\"pollDeployment\", () => {\n let mockAgent: MockAgent;\n let previousDispatcher: Dispatcher;\n let devApiPool: MockPool;\n let deploymentPool: MockPool;\n let previousEnvironment: Record<string, string | undefined>;\n let spinner: Ora;\n\n beforeEach(() => {\n previousEnvironment = Object.fromEntries(\n ENVIRONMENT_VARIABLES.map((name) => [name, process.env[name]])\n );\n process.env.ZUPLO_DEVELOPER_API_ENDPOINT = DEV_API_ORIGIN;\n process.env.MAX_POLL_RETRIES = \"3\";\n process.env.POLL_INTERVAL = \"1\";\n delete process.env.DEPLOY_INIT_ERROR_FAIL_FAST;\n\n previousDispatcher = getGlobalDispatcher();\n mockAgent = new MockAgent();\n mockAgent.disableNetConnect();\n setGlobalDispatcher(mockAgent);\n devApiPool = mockAgent.get(DEV_API_ORIGIN);\n deploymentPool = mockAgent.get(DEPLOYMENT_ORIGIN);\n spinner = { suffixText: \"\" } as unknown as Ora;\n });\n\n afterEach(async () => {\n await mockAgent.close();\n setGlobalDispatcher(previousDispatcher);\n\n for (const name of ENVIRONMENT_VARIABLES) {\n const value = previousEnvironment[name];\n if (value === undefined) {\n delete process.env[name];\n } else {\n process.env[name] = value;\n }\n }\n });\n\n function interceptStatus(body: Record<string, unknown>, times = 1) {\n devApiPool\n .intercept({ path: STATUS_PATH, method: \"GET\" })\n .reply(200, body)\n .times(times);\n }\n\n function interceptProbe(\n status: number,\n body: Record<string, unknown> | string,\n times = 1\n ) {\n deploymentPool\n .intercept({ path: BUILD_PATH, method: \"GET\" })\n .reply(status, body)\n .times(times);\n }\n\n function poll() {\n return pollDeployment(\n argv,\n \"deployment-123\",\n \"test-account\",\n \"test-project\",\n spinner\n );\n }\n\n it(\"fails fast after two consecutive matching initialization errors\", async () => {\n interceptStatus(statusBody(), 2);\n interceptProbe(500, initErrorBody(), 2);\n\n const result = await poll();\n\n assert.deepEqual(result, {\n logUrl: LOG_URL,\n initError: { detail: INIT_ERROR_DETAIL },\n });\n assert.strictEqual(mockAgent.pendingInterceptors().length, 0);\n });\n\n it(\"succeeds when one matching initialization error is followed by a live probe\", async () => {\n interceptStatus(statusBody(), 2);\n interceptProbe(500, initErrorBody());\n interceptProbe(200, { buildId: BUILD_ID });\n\n assert.deepEqual(await poll(), {\n url: DEPLOYMENT_ORIGIN,\n logUrl: LOG_URL,\n });\n assert.strictEqual(mockAgent.pendingInterceptors().length, 0);\n });\n\n it(\"polls to exhaustion when the initialization error is for another build\", async () => {\n interceptStatus(statusBody(), 3);\n interceptProbe(\n 500,\n initErrorBody({ trace: { timestamp: 0, buildId: \"build-old\" } }),\n 3\n );\n\n assert.deepEqual(await poll(), { logUrl: LOG_URL });\n });\n\n it(\"does not fail fast when the status response omits buildId\", async () => {\n interceptStatus(statusBody({ buildId: undefined }), 3);\n interceptProbe(500, initErrorBody(), 3);\n\n assert.deepEqual(await poll(), { logUrl: LOG_URL });\n });\n\n it(\"keeps polling after a non-JSON 5xx probe response\", async () => {\n interceptStatus(statusBody(), 3);\n interceptProbe(500, \"<html>unavailable</html>\", 3);\n\n assert.deepEqual(await poll(), { logUrl: LOG_URL });\n });\n\n it(\"uses the fallback detail when a matching initialization error omits detail\", async () => {\n interceptStatus(statusBody(), 2);\n interceptProbe(500, initErrorBody({ detail: undefined }), 2);\n\n assert.deepEqual(await poll(), {\n logUrl: LOG_URL,\n initError: { detail: FALLBACK_INIT_ERROR_DETAIL },\n });\n });\n\n it(\"returns the latest build log URL when in-progress polling is exhausted\", async () => {\n interceptStatus(statusBody({ status: \"IN_PROGRESS\", url: undefined }), 3);\n\n assert.deepEqual(await poll(), { logUrl: LOG_URL });\n });\n\n it(\"returns the deployment URL after a successful build probe\", async () => {\n interceptStatus(statusBody());\n interceptProbe(200, { buildId: BUILD_ID });\n\n assert.deepEqual(await poll(), {\n url: DEPLOYMENT_ORIGIN,\n logUrl: LOG_URL,\n });\n });\n\n it(\"returns a non-Zuplo deployment URL without probing it\", async () => {\n interceptStatus(statusBody({ url: PRIVATE_DEPLOYMENT_ORIGIN }));\n\n assert.deepEqual(await poll(), {\n url: PRIVATE_DEPLOYMENT_ORIGIN,\n logUrl: LOG_URL,\n });\n });\n\n it(\"keeps polling matching initialization errors when fail-fast is disabled\", async () => {\n process.env.DEPLOY_INIT_ERROR_FAIL_FAST = \"false\";\n interceptStatus(statusBody(), 3);\n interceptProbe(500, initErrorBody(), 3);\n\n assert.deepEqual(await poll(), { logUrl: LOG_URL });\n });\n});\n"]}
@@ -1 +1 @@
1
- {"root":["../src/cli.ts","../src/internal.ts","../src/types.d.ts","../src/__tests__/archive-utils.test.ts","../src/__tests__/import-openapi.test.ts","../src/__tests__/outdated.test.ts","../src/__tests__/populate.test.ts","../src/__tests__/tsconfig-upgrader.test.ts","../src/__tests__/integration/confirm-linked-config.integration.test.ts","../src/__tests__/integration/confirm-production-deploy.integration.test.ts","../src/__tests__/integration/custom-domain.integration.test.ts","../src/__tests__/integration/delete.integration.test.ts","../src/__tests__/integration/deploy.integration.test.ts","../src/__tests__/integration/get-project-param.integration.test.ts","../src/__tests__/integration/info.integration.test.ts","../src/__tests__/integration/jest-mocks-setup.ts","../src/__tests__/integration/jest-setup.ts","../src/__tests__/integration/link.integration.test.ts","../src/__tests__/integration/linked-config-cascade.integration.test.ts","../src/__tests__/integration/list.integration.test.ts","../src/__tests__/integration/test-utils.ts","../src/__tests__/integration/tunnel.integration.test.ts","../src/__tests__/integration/variable.integration.test.ts","../src/__tests__/integration/whoami.integration.test.ts","../src/bucket/models.ts","../src/bucket/list/handler.ts","../src/build/handler.ts","../src/ca-certificate/models.ts","../src/ca-certificate/validation.test.ts","../src/ca-certificate/validation.ts","../src/ca-certificate/create/handler.ts","../src/ca-certificate/delete/handler.ts","../src/ca-certificate/describe/handler.ts","../src/ca-certificate/list/handler.ts","../src/ca-certificate/update/handler.ts","../src/cmds/build.ts","../src/cmds/compile.ts","../src/cmds/delete.ts","../src/cmds/deploy.ts","../src/cmds/dev.ts","../src/cmds/docs.ts","../src/cmds/editor.ts","../src/cmds/info.ts","../src/cmds/init.ts","../src/cmds/link.ts","../src/cmds/lint.ts","../src/cmds/list.ts","../src/cmds/login.ts","../src/cmds/logout.ts","../src/cmds/test.ts","../src/cmds/whoami.ts","../src/cmds/bucket/index.ts","../src/cmds/bucket/list.ts","../src/cmds/ca-certificate/create.ts","../src/cmds/ca-certificate/delete.ts","../src/cmds/ca-certificate/describe.ts","../src/cmds/ca-certificate/index.ts","../src/cmds/ca-certificate/list.ts","../src/cmds/ca-certificate/update.ts","../src/cmds/custom-domain/create.ts","../src/cmds/custom-domain/delete.ts","../src/cmds/custom-domain/index.ts","../src/cmds/custom-domain/list.ts","../src/cmds/custom-domain/update.ts","../src/cmds/mtls-certificates/create.ts","../src/cmds/mtls-certificates/delete.ts","../src/cmds/mtls-certificates/describe.ts","../src/cmds/mtls-certificates/disable.ts","../src/cmds/mtls-certificates/index.ts","../src/cmds/mtls-certificates/list.ts","../src/cmds/mtls-certificates/update.ts","../src/cmds/open-api/convert.ts","../src/cmds/open-api/index.ts","../src/cmds/open-api/merge.ts","../src/cmds/open-api/overlay.ts","../src/cmds/project/create.ts","../src/cmds/project/index.ts","../src/cmds/project/info.ts","../src/cmds/project/list.ts","../src/cmds/proxies/create.ts","../src/cmds/proxies/delete.ts","../src/cmds/proxies/describe.ts","../src/cmds/proxies/index.ts","../src/cmds/proxies/update.ts","../src/cmds/source/import-openapi.ts","../src/cmds/source/index.ts","../src/cmds/source/migrate.ts","../src/cmds/source/upgrade.ts","../src/cmds/tunnel/create.ts","../src/cmds/tunnel/delete.ts","../src/cmds/tunnel/describe.ts","../src/cmds/tunnel/index.ts","../src/cmds/tunnel/list.ts","../src/cmds/tunnel/rotate-token.ts","../src/cmds/tunnel/services/describe.ts","../src/cmds/tunnel/services/index.ts","../src/cmds/tunnel/services/update.ts","../src/cmds/variable/create.ts","../src/cmds/variable/index.ts","../src/cmds/variable/update.ts","../src/common/alias.ts","../src/common/args.ts","../src/common/cli-dispatcher.test.ts","../src/common/cli-dispatcher.ts","../src/common/constants.ts","../src/common/handler.ts","../src/common/logger.ts","../src/common/models.ts","../src/common/outdated.ts","../src/common/output.ts","../src/common/populate.ts","../src/common/read-linked-config.test.ts","../src/common/read-linked-config.ts","../src/common/runner.ts","../src/common/settings.ts","../src/common/terminal.test.ts","../src/common/terminal.ts","../src/common/worker-output.ts","../src/common/analytics/cli-invocation.test.ts","../src/common/analytics/cli-invocation.ts","../src/common/analytics/lib.ts","../src/common/analytics/package-manager.test.ts","../src/common/analytics/package-manager.ts","../src/common/api/client.ts","../src/common/api/lib.ts","../src/common/machine-id/lib.ts","../src/common/middleware/authentication.ts","../src/common/middleware/check-pnpm-lifecycle.test.ts","../src/common/middleware/check-pnpm-lifecycle.ts","../src/common/middleware/confirm-linked-config.ts","../src/common/middleware/confirm-production-deploy.ts","../src/common/middleware/get-account-param.ts","../src/common/middleware/get-environment-param.test.ts","../src/common/middleware/get-environment-param.ts","../src/common/middleware/get-project-param.ts","../src/common/middleware/logging.ts","../src/common/middleware/user-configuration.ts","../src/common/middleware/user-identification.ts","../src/common/middleware/validate-fleet.ts","../src/common/upgraders/lib.ts","../src/common/upgraders/package-json-upgrader.ts","../src/common/upgraders/tsconfig-upgrader.ts","../src/common/upgraders/vscode-settings-json-upgrader.ts","../src/common/utils/box.ts","../src/common/utils/branch.ts","../src/common/utils/build-environment-prompt-choices.test.ts","../src/common/utils/build-environment-prompt-choices.ts","../src/common/utils/format-environment-type.test.ts","../src/common/utils/format-environment-type.ts","../src/common/utils/pnpm-lifecycle.test.ts","../src/common/utils/pnpm-lifecycle.ts","../src/common/utils/ports.ts","../src/common/utils/prefixed-output.ts","../src/common/utils/pretty-print-environment-prompt.test.ts","../src/common/utils/pretty-print-environment-prompt.ts","../src/common/utils/sort-environments-for-prompt.test.ts","../src/common/utils/sort-environments-for-prompt.ts","../src/common/utils/stringify-config.test.ts","../src/common/utils/stringify-config.ts","../src/common/utils/types.ts","../src/common/utils/urls.ts","../src/common/validators/argument-validators.spec.ts","../src/common/validators/argument-validators.ts","../src/common/validators/file-system-validator.ts","../src/common/validators/lib.ts","../src/common/validators/project-name-validator.ts","../src/common/xdg/lib.ts","../src/compile/handler.ts","../src/custom-domain/models.ts","../src/custom-domain/create/handler.ts","../src/custom-domain/delete/handler.ts","../src/custom-domain/list/handler.ts","../src/custom-domain/update/handler.ts","../src/delete/handler.ts","../src/delete/poll-deployment.ts","../src/deploy/archive.local-registry.test.ts","../src/deploy/archive.test.ts","../src/deploy/archive.ts","../src/deploy/environments.ts","../src/deploy/file-upload.ts","../src/deploy/handler.ts","../src/deploy/poll-deployment.ts","../src/dev/handler.ts","../src/dev/zuplo-local-gitignore.test.ts","../src/dev/zuplo-local-gitignore.ts","../src/docs/handler.ts","../src/editor/handler.ts","../src/editor/e2e/editor.spec.ts","../src/init/handler.ts","../src/link/handler.ts","../src/link/project-type.test.ts","../src/link/project-type.ts","../src/lint/handler.ts","../src/lint/resolve-binary.test.ts","../src/lint/resolve-binary.ts","../src/list/handler.ts","../src/login/login.ts","../src/login/logout.ts","../src/login/tokens.ts","../src/mtls-certificates/models.ts","../src/mtls-certificates/create/handler.ts","../src/mtls-certificates/delete/handler.ts","../src/mtls-certificates/describe/handler.ts","../src/mtls-certificates/disable/handler.ts","../src/mtls-certificates/list/handler.ts","../src/mtls-certificates/update/handler.ts","../src/open-api/convert/handler.spec.ts","../src/open-api/convert/handler.ts","../src/open-api/merge/handler.spec.ts","../src/open-api/merge/handler.ts","../src/open-api/overlay/handler.spec.ts","../src/open-api/overlay/handler.ts","../src/project/create/handler.ts","../src/project/info/handler.ts","../src/project/list/handler.ts","../src/proxies/models.ts","../src/proxies/create/handler.ts","../src/proxies/delete/handler.ts","../src/proxies/describe/handler.ts","../src/proxies/update/handler.ts","../src/source/migrate/dev-portal/handler.ts","../src/source/migrate/dev-portal/types.ts","../src/source/update/handler.ts","../src/test/esbuild-config.ts","../src/test/handler.ts","../src/test/invoke-test.test.ts","../src/test/invoke-test.ts","../src/test/test-files.test.ts","../src/test/test-files.ts","../src/test/esbuild-plugins/node-test-prep-plugin.ts","../src/tunnel/models.ts","../src/tunnel/create/handler.ts","../src/tunnel/delete/handler.ts","../src/tunnel/delete/poll-teardown-operation.ts","../src/tunnel/describe/handler.ts","../src/tunnel/list/handler.ts","../src/tunnel/rotate-token/handler.ts","../src/tunnel/services/describe/handler.ts","../src/tunnel/services/update/handler.ts","../src/tunnel/services/update/poll-provisioning-operations.ts","../src/variable/models.ts","../src/variable/create/handler.ts","../src/variable/update/handler.ts","../src/whoami/handler.ts"],"version":"5.8.3"}
1
+ {"root":["../src/cli.ts","../src/internal.ts","../src/types.d.ts","../src/__tests__/archive-utils.test.ts","../src/__tests__/import-openapi.test.ts","../src/__tests__/outdated.test.ts","../src/__tests__/populate.test.ts","../src/__tests__/tsconfig-upgrader.test.ts","../src/__tests__/integration/confirm-linked-config.integration.test.ts","../src/__tests__/integration/confirm-production-deploy.integration.test.ts","../src/__tests__/integration/custom-domain.integration.test.ts","../src/__tests__/integration/delete.integration.test.ts","../src/__tests__/integration/deploy.integration.test.ts","../src/__tests__/integration/get-project-param.integration.test.ts","../src/__tests__/integration/info.integration.test.ts","../src/__tests__/integration/jest-mocks-setup.ts","../src/__tests__/integration/jest-setup.ts","../src/__tests__/integration/link.integration.test.ts","../src/__tests__/integration/linked-config-cascade.integration.test.ts","../src/__tests__/integration/list.integration.test.ts","../src/__tests__/integration/test-utils.ts","../src/__tests__/integration/tunnel.integration.test.ts","../src/__tests__/integration/variable.integration.test.ts","../src/__tests__/integration/whoami.integration.test.ts","../src/bucket/models.ts","../src/bucket/list/handler.ts","../src/build/handler.ts","../src/ca-certificate/models.ts","../src/ca-certificate/validation.test.ts","../src/ca-certificate/validation.ts","../src/ca-certificate/create/handler.ts","../src/ca-certificate/delete/handler.ts","../src/ca-certificate/describe/handler.ts","../src/ca-certificate/list/handler.ts","../src/ca-certificate/update/handler.ts","../src/cmds/build.ts","../src/cmds/compile.ts","../src/cmds/delete.ts","../src/cmds/deploy.ts","../src/cmds/dev.ts","../src/cmds/docs.ts","../src/cmds/editor.ts","../src/cmds/info.ts","../src/cmds/init.ts","../src/cmds/link.ts","../src/cmds/lint.ts","../src/cmds/list.ts","../src/cmds/login.ts","../src/cmds/logout.ts","../src/cmds/test.ts","../src/cmds/whoami.ts","../src/cmds/bucket/index.ts","../src/cmds/bucket/list.ts","../src/cmds/ca-certificate/create.ts","../src/cmds/ca-certificate/delete.ts","../src/cmds/ca-certificate/describe.ts","../src/cmds/ca-certificate/index.ts","../src/cmds/ca-certificate/list.ts","../src/cmds/ca-certificate/update.ts","../src/cmds/custom-domain/create.ts","../src/cmds/custom-domain/delete.ts","../src/cmds/custom-domain/index.ts","../src/cmds/custom-domain/list.ts","../src/cmds/custom-domain/update.ts","../src/cmds/mtls-certificates/create.ts","../src/cmds/mtls-certificates/delete.ts","../src/cmds/mtls-certificates/describe.ts","../src/cmds/mtls-certificates/disable.ts","../src/cmds/mtls-certificates/index.ts","../src/cmds/mtls-certificates/list.ts","../src/cmds/mtls-certificates/update.ts","../src/cmds/open-api/convert.ts","../src/cmds/open-api/index.ts","../src/cmds/open-api/merge.ts","../src/cmds/open-api/overlay.ts","../src/cmds/project/create.ts","../src/cmds/project/index.ts","../src/cmds/project/info.ts","../src/cmds/project/list.ts","../src/cmds/proxies/create.ts","../src/cmds/proxies/delete.ts","../src/cmds/proxies/describe.ts","../src/cmds/proxies/index.ts","../src/cmds/proxies/update.ts","../src/cmds/source/import-openapi.ts","../src/cmds/source/index.ts","../src/cmds/source/migrate.ts","../src/cmds/source/upgrade.ts","../src/cmds/tunnel/create.ts","../src/cmds/tunnel/delete.ts","../src/cmds/tunnel/describe.ts","../src/cmds/tunnel/index.ts","../src/cmds/tunnel/list.ts","../src/cmds/tunnel/rotate-token.ts","../src/cmds/tunnel/services/describe.ts","../src/cmds/tunnel/services/index.ts","../src/cmds/tunnel/services/update.ts","../src/cmds/variable/create.ts","../src/cmds/variable/index.ts","../src/cmds/variable/update.ts","../src/common/alias.ts","../src/common/args.ts","../src/common/cli-dispatcher.test.ts","../src/common/cli-dispatcher.ts","../src/common/constants.ts","../src/common/handler.ts","../src/common/logger.ts","../src/common/models.ts","../src/common/outdated.ts","../src/common/output.ts","../src/common/populate.ts","../src/common/read-linked-config.test.ts","../src/common/read-linked-config.ts","../src/common/runner.ts","../src/common/settings.ts","../src/common/terminal.test.ts","../src/common/terminal.ts","../src/common/worker-output.ts","../src/common/analytics/cli-invocation.test.ts","../src/common/analytics/cli-invocation.ts","../src/common/analytics/lib.ts","../src/common/analytics/package-manager.test.ts","../src/common/analytics/package-manager.ts","../src/common/api/client.ts","../src/common/api/lib.ts","../src/common/machine-id/lib.ts","../src/common/middleware/authentication.ts","../src/common/middleware/check-pnpm-lifecycle.test.ts","../src/common/middleware/check-pnpm-lifecycle.ts","../src/common/middleware/confirm-linked-config.ts","../src/common/middleware/confirm-production-deploy.ts","../src/common/middleware/get-account-param.ts","../src/common/middleware/get-environment-param.test.ts","../src/common/middleware/get-environment-param.ts","../src/common/middleware/get-project-param.ts","../src/common/middleware/logging.ts","../src/common/middleware/user-configuration.ts","../src/common/middleware/user-identification.ts","../src/common/middleware/validate-fleet.ts","../src/common/upgraders/lib.ts","../src/common/upgraders/package-json-upgrader.ts","../src/common/upgraders/tsconfig-upgrader.ts","../src/common/upgraders/vscode-settings-json-upgrader.ts","../src/common/utils/box.ts","../src/common/utils/branch.ts","../src/common/utils/build-environment-prompt-choices.test.ts","../src/common/utils/build-environment-prompt-choices.ts","../src/common/utils/format-environment-type.test.ts","../src/common/utils/format-environment-type.ts","../src/common/utils/pnpm-lifecycle.test.ts","../src/common/utils/pnpm-lifecycle.ts","../src/common/utils/ports.ts","../src/common/utils/prefixed-output.ts","../src/common/utils/pretty-print-environment-prompt.test.ts","../src/common/utils/pretty-print-environment-prompt.ts","../src/common/utils/sort-environments-for-prompt.test.ts","../src/common/utils/sort-environments-for-prompt.ts","../src/common/utils/stringify-config.test.ts","../src/common/utils/stringify-config.ts","../src/common/utils/types.ts","../src/common/utils/urls.ts","../src/common/validators/argument-validators.spec.ts","../src/common/validators/argument-validators.ts","../src/common/validators/file-system-validator.ts","../src/common/validators/lib.ts","../src/common/validators/project-name-validator.ts","../src/common/xdg/lib.ts","../src/compile/handler.ts","../src/custom-domain/models.ts","../src/custom-domain/create/handler.ts","../src/custom-domain/delete/handler.ts","../src/custom-domain/list/handler.ts","../src/custom-domain/update/handler.ts","../src/delete/handler.ts","../src/delete/poll-deployment.ts","../src/deploy/archive.local-registry.test.ts","../src/deploy/archive.test.ts","../src/deploy/archive.ts","../src/deploy/classify-build-probe.test.ts","../src/deploy/classify-build-probe.ts","../src/deploy/environments.ts","../src/deploy/file-upload.ts","../src/deploy/handler.ts","../src/deploy/poll-deployment.test.ts","../src/deploy/poll-deployment.ts","../src/dev/handler.ts","../src/dev/zuplo-local-gitignore.test.ts","../src/dev/zuplo-local-gitignore.ts","../src/docs/handler.ts","../src/editor/handler.ts","../src/editor/e2e/editor.spec.ts","../src/init/handler.ts","../src/link/handler.ts","../src/link/project-type.test.ts","../src/link/project-type.ts","../src/lint/handler.ts","../src/lint/resolve-binary.test.ts","../src/lint/resolve-binary.ts","../src/list/handler.ts","../src/login/login.ts","../src/login/logout.ts","../src/login/tokens.ts","../src/mtls-certificates/models.ts","../src/mtls-certificates/create/handler.ts","../src/mtls-certificates/delete/handler.ts","../src/mtls-certificates/describe/handler.ts","../src/mtls-certificates/disable/handler.ts","../src/mtls-certificates/list/handler.ts","../src/mtls-certificates/update/handler.ts","../src/open-api/convert/handler.spec.ts","../src/open-api/convert/handler.ts","../src/open-api/merge/handler.spec.ts","../src/open-api/merge/handler.ts","../src/open-api/overlay/handler.spec.ts","../src/open-api/overlay/handler.ts","../src/project/create/handler.ts","../src/project/info/handler.ts","../src/project/list/handler.ts","../src/proxies/models.ts","../src/proxies/create/handler.ts","../src/proxies/delete/handler.ts","../src/proxies/describe/handler.ts","../src/proxies/update/handler.ts","../src/source/migrate/dev-portal/handler.ts","../src/source/migrate/dev-portal/types.ts","../src/source/update/handler.ts","../src/test/esbuild-config.ts","../src/test/handler.ts","../src/test/invoke-test.test.ts","../src/test/invoke-test.ts","../src/test/test-files.test.ts","../src/test/test-files.ts","../src/test/esbuild-plugins/node-test-prep-plugin.ts","../src/tunnel/models.ts","../src/tunnel/create/handler.ts","../src/tunnel/delete/handler.ts","../src/tunnel/delete/poll-teardown-operation.ts","../src/tunnel/describe/handler.ts","../src/tunnel/list/handler.ts","../src/tunnel/rotate-token/handler.ts","../src/tunnel/services/describe/handler.ts","../src/tunnel/services/update/handler.ts","../src/tunnel/services/update/poll-provisioning-operations.ts","../src/variable/models.ts","../src/variable/create/handler.ts","../src/variable/update/handler.ts","../src/whoami/handler.ts"],"version":"5.8.3"}
@@ -74,7 +74,7 @@ class PostHogLogs {
74
74
  if (null === filtered) return;
75
75
  if (!filtered.body) return void this._logger.info("Log was rejected in beforeSend function");
76
76
  if (!this._checkRateLimit()) return;
77
- const record = (0, external_logs_utils_js_namespaceObject.buildOtlpLogRecord)(filtered, this._getContext());
77
+ const record = (0, external_logs_utils_js_namespaceObject.buildOtlpLogRecord)(filtered, this._getContext(), this._logger);
78
78
  const entry = {
79
79
  record
80
80
  };
@@ -46,7 +46,7 @@ class PostHogLogs {
46
46
  if (null === filtered) return;
47
47
  if (!filtered.body) return void this._logger.info("Log was rejected in beforeSend function");
48
48
  if (!this._checkRateLimit()) return;
49
- const record = buildOtlpLogRecord(filtered, this._getContext());
49
+ const record = buildOtlpLogRecord(filtered, this._getContext(), this._logger);
50
50
  const entry = {
51
51
  record
52
52
  };
@@ -1,20 +1,11 @@
1
1
  import type { CaptureLogOptions, LogAttributeValue, LogSeverityLevel, OtlpAnyValue, OtlpKeyValue, OtlpLogRecord, OtlpLogsPayload, OtlpSeverityText } from '@posthog/types';
2
+ import type { Logger } from '../types';
2
3
  import type { LogSdkContext, ResolvedPostHogLogsConfig } from './types';
3
4
  export declare function getOtlpSeverityText(level: LogSeverityLevel): OtlpSeverityText;
4
5
  export declare function getOtlpSeverityNumber(level: LogSeverityLevel): number;
5
- export declare function toOtlpAnyValue(value: LogAttributeValue): OtlpAnyValue;
6
- export declare function toOtlpKeyValueList(attrs: Record<string, LogAttributeValue>): OtlpKeyValue[];
7
- /**
8
- * Builds a single OTLP log record.
9
- *
10
- * Auto-attribute population is shape-driven: any field present on `sdkContext`
11
- * is emitted as the corresponding attribute. Each SDK populates only the
12
- * fields that apply to it (browser fills `currentUrl`; mobile fills
13
- * `screenName` / `appState`), so a missing field never adds a stray attribute.
14
- *
15
- * User-provided `options.attributes` always wins on conflicts.
16
- */
17
- export declare function buildOtlpLogRecord(options: CaptureLogOptions, sdkContext: LogSdkContext): OtlpLogRecord;
6
+ export declare function toOtlpAnyValue(value: LogAttributeValue, logger?: Logger): OtlpAnyValue;
7
+ export declare function toOtlpKeyValueList(attrs: Record<string, LogAttributeValue>, logger?: Logger): OtlpKeyValue[];
8
+ export declare function buildOtlpLogRecord(options: CaptureLogOptions, sdkContext: LogSdkContext, logger?: Logger): OtlpLogRecord;
18
9
  /**
19
10
  * OTLP resource attributes for every batch, shared by the core flush path and
20
11
  * SDK-specific paths that bypass it (e.g. the browser's synchronous sendBeacon
@@ -1 +1 @@
1
- {"version":3,"file":"logs-utils.d.ts","sourceRoot":"","sources":["../../src/logs/logs-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,eAAe,EAEf,gBAAgB,EACjB,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAA;AAkBvE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,gBAAgB,CAE7E;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAErE;AAMD,wBAAgB,cAAc,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CAiCrE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,YAAY,EAAE,CAU3F;AAiBD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,aAAa,GAAG,aAAa,CA4DvG;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,yBAAyB,EACjC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CASnC;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,aAAa,EAAE,EAC3B,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,EACrD,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,eAAe,CAcjB"}
1
+ {"version":3,"file":"logs-utils.d.ts","sourceRoot":"","sources":["../../src/logs/logs-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,eAAe,EAEf,gBAAgB,EACjB,MAAM,gBAAgB,CAAA;AACvB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAA;AA4BvE,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,gBAAgB,CAE7E;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAErE;AAqBD,wBAAgB,cAAc,CAAC,KAAK,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY,CAQtF;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAM5G;AAmMD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,iBAAiB,EAC1B,UAAU,EAAE,aAAa,EACzB,MAAM,CAAC,EAAE,MAAM,GACd,aAAa,CA+Ef;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,yBAAyB,EACjC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CASnC;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,aAAa,EAAE,EAC3B,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,EACrD,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,eAAe,CAcjB"}
@@ -33,6 +33,7 @@ __webpack_require__.d(__webpack_exports__, {
33
33
  toOtlpAnyValue: ()=>toOtlpAnyValue
34
34
  });
35
35
  const index_js_namespaceObject = require("../utils/index.js");
36
+ const json_utils_js_namespaceObject = require("../utils/json-utils.js");
36
37
  const OTLP_SEVERITY_MAP = {
37
38
  trace: {
38
39
  text: 'TRACE',
@@ -66,7 +67,35 @@ function getOtlpSeverityText(level) {
66
67
  function getOtlpSeverityNumber(level) {
67
68
  return (OTLP_SEVERITY_MAP[level] || DEFAULT_OTLP_SEVERITY).number;
68
69
  }
69
- function toOtlpAnyValue(value) {
70
+ const INT64_RANGE_LIMIT = 9223372036854775808;
71
+ const propertyIsEnumerable = Object.prototype.propertyIsEnumerable;
72
+ function newState() {
73
+ return {
74
+ ancestors: new WeakSet(),
75
+ remainingNodes: json_utils_js_namespaceObject.MAX_JSON_SAFE_VALUE_NODES
76
+ };
77
+ }
78
+ function toOtlpAnyValue(value, logger) {
79
+ try {
80
+ return encodeAnyValue(value, logger, newState(), 0);
81
+ } catch {
82
+ return {
83
+ stringValue: json_utils_js_namespaceObject.UNSERIALIZABLE_VALUE
84
+ };
85
+ }
86
+ }
87
+ function toOtlpKeyValueList(attrs, logger) {
88
+ try {
89
+ return encodeKeyValueList(attrs, logger, newState(), 0);
90
+ } catch {
91
+ return [];
92
+ }
93
+ }
94
+ function encodeAnyValue(value, logger, state, depth) {
95
+ if (state.remainingNodes <= 0) return {
96
+ stringValue: json_utils_js_namespaceObject.TRUNCATED_VALUE
97
+ };
98
+ state.remainingNodes--;
70
99
  if ((0, index_js_namespaceObject.isBoolean)(value)) return {
71
100
  boolValue: value
72
101
  };
@@ -74,46 +103,129 @@ function toOtlpAnyValue(value) {
74
103
  if (!Number.isFinite(value)) return {
75
104
  stringValue: String(value)
76
105
  };
77
- if (Number.isInteger(value)) return {
78
- intValue: value
79
- };
106
+ if (Number.isInteger(value)) {
107
+ if (Number.isSafeInteger(value)) return {
108
+ intValue: String(value)
109
+ };
110
+ if ('undefined' == typeof BigInt) return {
111
+ stringValue: String(value)
112
+ };
113
+ const decimal = BigInt(value).toString();
114
+ if (value >= INT64_RANGE_LIMIT || value < -INT64_RANGE_LIMIT) {
115
+ logger?.debug(`Attribute ${decimal} is outside the int64 range; encoding it as a string`);
116
+ return {
117
+ stringValue: decimal
118
+ };
119
+ }
120
+ return {
121
+ intValue: decimal
122
+ };
123
+ }
80
124
  return {
81
125
  doubleValue: value
82
126
  };
83
127
  }
84
128
  if ('string' == typeof value) return {
85
- stringValue: value
129
+ stringValue: (0, json_utils_js_namespaceObject.sanitizeString)(value)
86
130
  };
87
- if ((0, index_js_namespaceObject.isArray)(value)) return {
88
- arrayValue: {
89
- values: value.map((v)=>toOtlpAnyValue(v))
90
- }
131
+ if ('function' == typeof value) return {
132
+ stringValue: json_utils_js_namespaceObject.FUNCTION_VALUE
91
133
  };
92
- try {
93
- return {
94
- stringValue: JSON.stringify(value)
134
+ if ('symbol' == typeof value) return {
135
+ stringValue: String(value)
136
+ };
137
+ if ('object' == typeof value && null !== value) {
138
+ if (state.ancestors.has(value)) return {
139
+ stringValue: json_utils_js_namespaceObject.CIRCULAR_VALUE
95
140
  };
96
- } catch {
97
- return {
98
- stringValue: String(value)
141
+ if (depth >= json_utils_js_namespaceObject.MAX_JSON_SAFE_VALUE_DEPTH) return {
142
+ stringValue: json_utils_js_namespaceObject.TRUNCATED_VALUE
99
143
  };
144
+ if (value instanceof Date) {
145
+ const time = value.getTime();
146
+ const iso = Number.isFinite(time) ? value.toISOString() : String(value);
147
+ return {
148
+ stringValue: 'string' == typeof iso ? (0, json_utils_js_namespaceObject.sanitizeString)(iso) : String(iso)
149
+ };
150
+ }
151
+ state.ancestors.add(value);
152
+ try {
153
+ try {
154
+ const toJSON = value.toJSON;
155
+ if ('function' == typeof toJSON) return encodeAnyValue(toJSON.call(value), logger, state, depth + 1);
156
+ } catch {}
157
+ if ((0, index_js_namespaceObject.isArray)(value)) return {
158
+ arrayValue: {
159
+ values: encodeArrayValues(value, logger, state, depth + 1)
160
+ }
161
+ };
162
+ return {
163
+ kvlistValue: {
164
+ values: encodeKeyValueList(value, logger, state, depth + 1)
165
+ }
166
+ };
167
+ } finally{
168
+ state.ancestors.delete(value);
169
+ }
100
170
  }
171
+ return {
172
+ stringValue: (0, json_utils_js_namespaceObject.sanitizeString)(String(value))
173
+ };
101
174
  }
102
- function toOtlpKeyValueList(attrs) {
175
+ function encodeArrayValues(values, logger, state, depth) {
103
176
  const result = [];
104
- for(const key in attrs){
105
- const value = attrs[key];
106
- if (!((0, index_js_namespaceObject.isNull)(value) || (0, index_js_namespaceObject.isUndefined)(value))) result.push({
107
- key,
108
- value: toOtlpAnyValue(value)
177
+ const itemCount = Math.min(values.length, json_utils_js_namespaceObject.MAX_JSON_SAFE_VALUE_ITEMS);
178
+ let index = 0;
179
+ for(; index < itemCount && state.remainingNodes > 0; index++)try {
180
+ const element = index in values ? values[index] : void 0;
181
+ if ((0, index_js_namespaceObject.isNullish)(element)) continue;
182
+ result.push(encodeAnyValue(element, logger, state, depth));
183
+ } catch {
184
+ result.push({
185
+ stringValue: json_utils_js_namespaceObject.UNSERIALIZABLE_VALUE
109
186
  });
110
187
  }
188
+ if (values.length > index) result.push({
189
+ stringValue: json_utils_js_namespaceObject.TRUNCATED_VALUE
190
+ });
191
+ return result;
192
+ }
193
+ function encodeKeyValueList(attrs, logger, state, depth) {
194
+ const result = [];
195
+ for(const key in attrs)if (propertyIsEnumerable.call(attrs, key)) {
196
+ if (result.length >= json_utils_js_namespaceObject.MAX_JSON_SAFE_VALUE_ITEMS || state.remainingNodes <= 0) {
197
+ logger?.debug('Attributes truncated: the value exceeds the OTLP encoder budget');
198
+ break;
199
+ }
200
+ try {
201
+ const value = attrs[key];
202
+ if ((0, index_js_namespaceObject.isNull)(value) || (0, index_js_namespaceObject.isUndefined)(value)) continue;
203
+ result.push({
204
+ key: (0, json_utils_js_namespaceObject.sanitizeString)(key),
205
+ value: encodeAnyValue(value, logger, state, depth)
206
+ });
207
+ } catch {
208
+ result.push({
209
+ key: (0, json_utils_js_namespaceObject.sanitizeString)(key),
210
+ value: {
211
+ stringValue: json_utils_js_namespaceObject.UNSERIALIZABLE_VALUE
212
+ }
213
+ });
214
+ }
215
+ }
111
216
  return result;
112
217
  }
113
218
  function timestampToUnixNano() {
114
219
  return String(Date.now()) + '000000';
115
220
  }
116
- function buildOtlpLogRecord(options, sdkContext) {
221
+ function encodeBody(body) {
222
+ try {
223
+ return (0, json_utils_js_namespaceObject.sanitizeString)(String(body));
224
+ } catch {
225
+ return json_utils_js_namespaceObject.UNSERIALIZABLE_VALUE;
226
+ }
227
+ }
228
+ function buildOtlpLogRecord(options, sdkContext, logger) {
117
229
  const level = options.level || 'info';
118
230
  const { text: severityText, number: severityNumber } = OTLP_SEVERITY_MAP[level] || DEFAULT_OTLP_SEVERITY;
119
231
  const now = timestampToUnixNano();
@@ -128,18 +240,40 @@ function buildOtlpLogRecord(options, sdkContext) {
128
240
  if (sdkContext.appState) autoAttributes['app.state'] = sdkContext.appState;
129
241
  if (sdkContext.activeFeatureFlags && sdkContext.activeFeatureFlags.length > 0) autoAttributes.feature_flags = sdkContext.activeFeatureFlags;
130
242
  const mergedAttributes = {
131
- ...autoAttributes,
132
- ...options.attributes || {}
243
+ ...autoAttributes
133
244
  };
245
+ const userAttributes = options.attributes;
246
+ if (userAttributes) {
247
+ let keys = [];
248
+ try {
249
+ keys = Object.keys(userAttributes);
250
+ } catch {
251
+ keys = [];
252
+ }
253
+ for (const key of keys){
254
+ let value;
255
+ try {
256
+ value = userAttributes[key];
257
+ } catch {
258
+ value = json_utils_js_namespaceObject.UNSERIALIZABLE_VALUE;
259
+ }
260
+ Object.defineProperty(mergedAttributes, key, {
261
+ value,
262
+ enumerable: true,
263
+ writable: true,
264
+ configurable: true
265
+ });
266
+ }
267
+ }
134
268
  const record = {
135
269
  timeUnixNano: now,
136
270
  observedTimeUnixNano: now,
137
271
  severityNumber,
138
272
  severityText,
139
273
  body: {
140
- stringValue: options.body
274
+ stringValue: encodeBody(options.body)
141
275
  },
142
- attributes: toOtlpKeyValueList(mergedAttributes)
276
+ attributes: toOtlpKeyValueList(mergedAttributes, logger)
143
277
  };
144
278
  if (options.trace_id) record.traceId = options.trace_id;
145
279
  if (options.span_id) record.spanId = options.span_id;