@spotlightjs/spotlight 4.8.0 → 4.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/_commonjsHelpers.js +3 -4
- package/dist/_virtual/additionalItems.js +2 -2
- package/dist/_virtual/additionalProperties.js +2 -2
- package/dist/_virtual/ajv.js +2 -2
- package/dist/_virtual/allOf.js +2 -2
- package/dist/_virtual/anyOf.js +2 -2
- package/dist/_virtual/applicability.js +2 -2
- package/dist/_virtual/boolSchema.js +2 -2
- package/dist/_virtual/code.js +2 -2
- package/dist/_virtual/code2.js +2 -2
- package/dist/_virtual/const.js +2 -2
- package/dist/_virtual/contains.js +2 -2
- package/dist/_virtual/core.js +2 -2
- package/dist/_virtual/dataType.js +2 -2
- package/dist/_virtual/defaults.js +2 -2
- package/dist/_virtual/dependencies.js +2 -2
- package/dist/_virtual/draft7.js +2 -2
- package/dist/_virtual/enum.js +2 -2
- package/dist/_virtual/equal.js +2 -2
- package/dist/_virtual/errors.js +2 -2
- package/dist/_virtual/format.js +2 -2
- package/dist/_virtual/formats.js +2 -2
- package/dist/_virtual/id.js +2 -2
- package/dist/_virtual/if.js +2 -2
- package/dist/_virtual/index.js +2 -2
- package/dist/_virtual/index10.js +2 -2
- package/dist/_virtual/index11.js +2 -2
- package/dist/_virtual/index2.js +2 -2
- package/dist/_virtual/index3.js +2 -2
- package/dist/_virtual/index4.js +2 -2
- package/dist/_virtual/index5.js +2 -2
- package/dist/_virtual/index6.js +2 -2
- package/dist/_virtual/index7.js +2 -2
- package/dist/_virtual/index8.js +2 -2
- package/dist/_virtual/index9.js +2 -2
- package/dist/_virtual/items.js +2 -2
- package/dist/_virtual/items2020.js +2 -2
- package/dist/_virtual/keyword.js +2 -2
- package/dist/_virtual/limit.js +2 -2
- package/dist/_virtual/limitItems.js +2 -2
- package/dist/_virtual/limitLength.js +2 -2
- package/dist/_virtual/limitNumber.js +2 -2
- package/dist/_virtual/limitProperties.js +2 -2
- package/dist/_virtual/metadata.js +2 -2
- package/dist/_virtual/multipleOf.js +2 -2
- package/dist/_virtual/names.js +2 -2
- package/dist/_virtual/not.js +2 -2
- package/dist/_virtual/oneOf.js +2 -2
- package/dist/_virtual/pattern.js +2 -2
- package/dist/_virtual/patternProperties.js +2 -2
- package/dist/_virtual/prefixItems.js +2 -2
- package/dist/_virtual/properties.js +2 -2
- package/dist/_virtual/propertyNames.js +2 -2
- package/dist/_virtual/ref.js +2 -2
- package/dist/_virtual/ref_error.js +2 -2
- package/dist/_virtual/required.js +2 -2
- package/dist/_virtual/resolve.js +2 -2
- package/dist/_virtual/rules.js +2 -2
- package/dist/_virtual/scope.js +2 -2
- package/dist/_virtual/subschema.js +2 -2
- package/dist/_virtual/thenElse.js +2 -2
- package/dist/_virtual/types.js +2 -2
- package/dist/_virtual/ucs2length.js +2 -2
- package/dist/_virtual/uniqueItems.js +2 -2
- package/dist/_virtual/uri.js +2 -2
- package/dist/_virtual/util.js +2 -2
- package/dist/_virtual/validation_error.js +2 -2
- package/dist/instrument.js +7 -4
- package/dist/node_modules/.pnpm/{@modelcontextprotocol_sdk@1.24.3_zod@4.1.13 → @modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13}/node_modules/@modelcontextprotocol/sdk/dist/esm/client/index.js +109 -40
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/client/index.js.map +1 -0
- package/dist/node_modules/.pnpm/{@modelcontextprotocol_sdk@1.24.3_zod@4.1.13 → @modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13}/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/client.js +4 -5
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/client.js.map +1 -0
- package/dist/node_modules/.pnpm/{@modelcontextprotocol_sdk@1.24.3_zod@4.1.13 → @modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13}/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js +6 -8
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js.map +1 -0
- package/dist/node_modules/.pnpm/{@modelcontextprotocol_sdk@1.24.3_zod@4.1.13 → @modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13}/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js +2 -2
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js.map +1 -0
- package/dist/node_modules/.pnpm/{@modelcontextprotocol_sdk@1.24.3_zod@4.1.13 → @modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13}/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/mcp-server.js +2 -2
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/mcp-server.js.map +1 -0
- package/dist/node_modules/.pnpm/{@modelcontextprotocol_sdk@1.24.3_zod@4.1.13 → @modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13}/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js +2 -2
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js.map +1 -0
- package/dist/node_modules/.pnpm/{@modelcontextprotocol_sdk@1.24.3_zod@4.1.13 → @modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13}/node_modules/@modelcontextprotocol/sdk/dist/esm/server/completable.js +4 -4
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/server/completable.js.map +1 -0
- package/dist/node_modules/.pnpm/{@modelcontextprotocol_sdk@1.24.3_zod@4.1.13 → @modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13}/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js +23 -36
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js.map +1 -0
- package/dist/node_modules/.pnpm/{@modelcontextprotocol_sdk@1.24.3_zod@4.1.13 → @modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13}/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js +25 -12
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js.map +1 -0
- package/dist/node_modules/.pnpm/{@modelcontextprotocol_sdk@1.24.3_zod@4.1.13 → @modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13}/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js +7 -10
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js.map +1 -0
- package/dist/node_modules/.pnpm/{@modelcontextprotocol_sdk@1.24.3_zod@4.1.13 → @modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13}/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js +11 -21
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js.map +1 -0
- package/dist/node_modules/.pnpm/{@modelcontextprotocol_sdk@1.24.3_zod@4.1.13 → @modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13}/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js +10 -11
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js.map +1 -0
- package/dist/node_modules/.pnpm/{@modelcontextprotocol_sdk@1.24.3_zod@4.1.13 → @modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13}/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js +75 -91
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js.map +1 -0
- package/dist/node_modules/.pnpm/{@modelcontextprotocol_sdk@1.24.3_zod@4.1.13 → @modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13}/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js +2 -2
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js.map +1 -0
- package/dist/node_modules/.pnpm/{@modelcontextprotocol_sdk@1.24.3_zod@4.1.13 → @modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13}/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/toolNameValidation.js +2 -2
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/toolNameValidation.js.map +1 -0
- package/dist/node_modules/.pnpm/{@modelcontextprotocol_sdk@1.24.3_zod@4.1.13 → @modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13}/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js +171 -113
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js.map +1 -0
- package/dist/node_modules/.pnpm/{@modelcontextprotocol_sdk@1.24.3_zod@4.1.13 → @modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13}/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js +7 -8
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.25.2_hono@4.10.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js.map +1 -0
- package/dist/node_modules/.pnpm/ajv-formats@3.0.1_ajv@8.17.1/node_modules/ajv-formats/dist/formats.js +10 -11
- package/dist/node_modules/.pnpm/ajv-formats@3.0.1_ajv@8.17.1/node_modules/ajv-formats/dist/formats.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv-formats@3.0.1_ajv@8.17.1/node_modules/ajv-formats/dist/index.js +8 -8
- package/dist/node_modules/.pnpm/ajv-formats@3.0.1_ajv@8.17.1/node_modules/ajv-formats/dist/index.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv-formats@3.0.1_ajv@8.17.1/node_modules/ajv-formats/dist/limit.js +9 -10
- package/dist/node_modules/.pnpm/ajv-formats@3.0.1_ajv@8.17.1/node_modules/ajv-formats/dist/limit.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/ajv.js +25 -23
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/ajv.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/codegen/code.js +23 -24
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/codegen/code.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/codegen/index.js +26 -27
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/codegen/index.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/codegen/scope.js +12 -13
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/codegen/scope.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/errors.js +14 -15
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/errors.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/index.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/index.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/names.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/names.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/ref_error.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/ref_error.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/resolve.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/resolve.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/rules.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/rules.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/util.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/util.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/validate/applicability.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/validate/applicability.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/validate/boolSchema.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/validate/boolSchema.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/validate/dataType.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/validate/dataType.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/validate/defaults.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/validate/defaults.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/validate/index.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/validate/index.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/validate/keyword.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/validate/keyword.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/validate/subschema.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/compile/validate/subschema.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/core.js +14 -15
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/core.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/refs/data.json.js +2 -2
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/refs/json-schema-draft-07.json.js +2 -2
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/runtime/equal.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/runtime/equal.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/runtime/ucs2length.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/runtime/ucs2length.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/runtime/uri.js +4 -5
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/runtime/uri.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/runtime/validation_error.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/runtime/validation_error.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/additionalItems.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/additionalItems.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/allOf.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/allOf.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/anyOf.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/anyOf.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/contains.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/contains.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/dependencies.js +11 -12
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/dependencies.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/if.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/if.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/index.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/index.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/items.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/items.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/items2020.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/items2020.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/not.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/not.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/oneOf.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/oneOf.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/prefixItems.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/prefixItems.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/properties.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/properties.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/propertyNames.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/propertyNames.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/thenElse.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/applicator/thenElse.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/code.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/code.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/core/id.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/core/id.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/core/index.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/core/index.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/core/ref.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/core/ref.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/discriminator/index.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/discriminator/index.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/discriminator/types.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/discriminator/types.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/draft7.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/draft7.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/format/format.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/format/format.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/format/index.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/format/index.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/metadata.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/metadata.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/const.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/const.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/enum.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/enum.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/index.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/index.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/limitItems.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/limitItems.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/limitLength.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/limitLength.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/limitNumber.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/limitNumber.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/limitProperties.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/limitProperties.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/multipleOf.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/multipleOf.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/pattern.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/pattern.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/required.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/required.js.map +1 -1
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/uniqueItems.js +3 -4
- package/dist/node_modules/.pnpm/ajv@8.17.1/node_modules/ajv/dist/vocabularies/validation/uniqueItems.js.map +1 -1
- package/dist/node_modules/.pnpm/fast-deep-equal@3.1.3/node_modules/fast-deep-equal/index.js +3 -4
- package/dist/node_modules/.pnpm/fast-deep-equal@3.1.3/node_modules/fast-deep-equal/index.js.map +1 -1
- package/dist/node_modules/.pnpm/{fast-uri@3.0.2 → fast-uri@3.1.0}/node_modules/fast-uri/index.js +57 -60
- package/dist/node_modules/.pnpm/fast-uri@3.1.0/node_modules/fast-uri/index.js.map +1 -0
- package/dist/node_modules/.pnpm/fast-uri@3.1.0/node_modules/fast-uri/lib/schemes.js +197 -0
- package/dist/node_modules/.pnpm/fast-uri@3.1.0/node_modules/fast-uri/lib/schemes.js.map +1 -0
- package/dist/node_modules/.pnpm/fast-uri@3.1.0/node_modules/fast-uri/lib/utils.js +261 -0
- package/dist/node_modules/.pnpm/fast-uri@3.1.0/node_modules/fast-uri/lib/utils.js.map +1 -0
- package/dist/node_modules/.pnpm/hono@4.10.3/node_modules/hono/dist/helper/streaming/sse.js +2 -2
- package/dist/node_modules/.pnpm/hono@4.10.3/node_modules/hono/dist/middleware/cors/index.js +2 -2
- package/dist/node_modules/.pnpm/hono@4.10.3/node_modules/hono/dist/middleware/cors/index.js.map +1 -1
- package/dist/node_modules/.pnpm/hono@4.10.3/node_modules/hono/dist/utils/html.js +2 -2
- package/dist/node_modules/.pnpm/hono@4.10.3/node_modules/hono/dist/utils/html.js.map +1 -1
- package/dist/node_modules/.pnpm/hono@4.10.3/node_modules/hono/dist/utils/stream.js +2 -2
- package/dist/node_modules/.pnpm/hono@4.10.3/node_modules/hono/dist/utils/stream.js.map +1 -1
- package/dist/node_modules/.pnpm/json-schema-traverse@1.0.0/node_modules/json-schema-traverse/index.js +3 -4
- package/dist/node_modules/.pnpm/json-schema-traverse@1.0.0/node_modules/json-schema-traverse/index.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/Options.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/Options.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/Refs.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/Refs.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/errorMessages.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/errorMessages.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/getRelativePath.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/getRelativePath.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parseDef.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parseDef.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/any.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/any.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/array.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/array.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/bigint.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/bigint.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/boolean.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/boolean.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/branded.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/branded.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/catch.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/catch.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/date.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/date.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/default.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/default.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/effects.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/effects.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/enum.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/enum.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/intersection.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/intersection.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/literal.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/literal.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/map.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/map.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/nativeEnum.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/nativeEnum.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/never.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/never.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/null.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/null.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/nullable.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/nullable.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/number.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/number.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/object.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/object.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/optional.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/optional.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/pipeline.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/pipeline.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/promise.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/promise.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/readonly.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/readonly.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/record.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/record.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/set.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/set.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/string.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/string.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/tuple.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/tuple.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/undefined.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/undefined.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/union.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/union.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/unknown.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/parsers/unknown.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/selectParser.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/selectParser.js.map +1 -1
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/zodToJsonSchema.js +2 -2
- package/dist/node_modules/.pnpm/{zod-to-json-schema@3.25.0_zod@4.1.13 → zod-to-json-schema@3.25.1_zod@4.1.13}/node_modules/zod-to-json-schema/dist/esm/zodToJsonSchema.js.map +1 -1
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v3/ZodError.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v3/errors.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v3/helpers/errorUtil.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v3/helpers/parseUtil.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v3/helpers/util.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v3/locales/en.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v3/types.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/classic/errors.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/classic/iso.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/classic/parse.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/classic/schemas.js +4 -4
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/classic/schemas.js.map +1 -1
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/api.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/checks.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/core.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/core.js.map +1 -1
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/doc.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/errors.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/parse.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/regexes.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/registries.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/schemas.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/to-json-schema.js +3 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/to-json-schema.js.map +1 -1
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/util.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/util.js.map +1 -1
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/versions.js +2 -2
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/core/versions.js.map +1 -1
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/mini/schemas.js +4 -4
- package/dist/node_modules/.pnpm/zod@4.1.13/node_modules/zod/v4/mini/schemas.js.map +1 -1
- package/dist/run.js +5 -6
- package/dist/sentry-config.js +5 -5
- package/dist/server/cli/help.d.ts +2 -1
- package/dist/server/cli/help.js +43 -21
- package/dist/server/cli/mcp.d.ts +8 -2
- package/dist/server/cli/mcp.js +31 -8
- package/dist/server/cli/run.d.ts +8 -2
- package/dist/server/cli/run.js +36 -9
- package/dist/server/cli/server.d.ts +8 -2
- package/dist/server/cli/server.js +50 -18
- package/dist/server/cli/tail.d.ts +8 -2
- package/dist/server/cli/tail.js +42 -8
- package/dist/server/cli.d.ts +3 -2
- package/dist/server/cli.js +20 -19
- package/dist/server/constants.js +3 -4
- package/dist/server/formatters/human/errors.js +3 -4
- package/dist/server/formatters/human/index.js +3 -4
- package/dist/server/formatters/human/logs.js +3 -4
- package/dist/server/formatters/human/traces.js +3 -4
- package/dist/server/formatters/human/utils.d.ts +8 -4
- package/dist/server/formatters/human/utils.js +29 -17
- package/dist/server/formatters/index.js +4 -5
- package/dist/server/formatters/json/errors.js +3 -4
- package/dist/server/formatters/json/index.js +3 -4
- package/dist/server/formatters/json/logs.js +3 -4
- package/dist/server/formatters/json/traces.js +3 -4
- package/dist/server/formatters/logfmt/errors.js +3 -4
- package/dist/server/formatters/logfmt/index.js +3 -4
- package/dist/server/formatters/logfmt/logs.js +3 -4
- package/dist/server/formatters/logfmt/traces.js +3 -4
- package/dist/server/formatters/md/errors.js +7 -4
- package/dist/server/formatters/md/event.js +3 -4
- package/dist/server/formatters/md/index.js +3 -4
- package/dist/server/formatters/md/logs.js +7 -4
- package/dist/server/formatters/md/traces.js +3 -4
- package/dist/server/formatters/schema.d.ts +382 -382
- package/dist/server/formatters/shared/data-builders.js +3 -4
- package/dist/server/formatters/types.js +3 -4
- package/dist/server/formatters/utils.js +3 -4
- package/dist/server/handlers/fileToServe.js +3 -4
- package/dist/server/logger.js +3 -4
- package/dist/server/main.d.ts +3 -0
- package/dist/server/main.js +21 -10
- package/dist/server/mcp/constants.js +3 -4
- package/dist/server/mcp/mcp.js +6 -6
- package/dist/server/messageBuffer.js +9 -4
- package/dist/server/parser/helpers.js +3 -4
- package/dist/server/parser/processEnvelope.d.ts +10 -3
- package/dist/server/parser/processEnvelope.js +10 -4
- package/dist/server/parser/types.d.ts +47 -1
- package/dist/server/routes/clear.js +4 -4
- package/dist/server/routes/contextlines/index.js +3 -4
- package/dist/server/routes/contextlines/utils.js +3 -4
- package/dist/server/routes/health.js +3 -4
- package/dist/server/routes/index.js +3 -4
- package/dist/server/routes/mcp.js +3 -4
- package/dist/server/routes/open.js +3 -4
- package/dist/server/routes/stream/debugLogging.js +4 -4
- package/dist/server/routes/stream/index.js +4 -4
- package/dist/server/routes/stream/streaming.js +3 -4
- package/dist/server/routes/stream/userAgent.js +3 -4
- package/dist/server/sdk.d.ts +1 -1
- package/dist/server/sdk.js +5 -6
- package/dist/server/types/cli.d.ts +11 -0
- package/dist/server/utils/cors.js +3 -4
- package/dist/server/utils/docker-compose-parser.js +3 -4
- package/dist/server/utils/docker-compose.js +3 -4
- package/dist/server/utils/eventContainer.d.ts +2 -1
- package/dist/server/utils/eventContainer.js +4 -4
- package/dist/server/utils/extras.js +3 -4
- package/dist/server/utils/getBuffer.js +3 -4
- package/dist/shared/constants.js +3 -4
- package/dist/ui/assets/index.js +67 -63
- package/dist/ui/assets/index2.js +1 -1
- package/dist/ui/assets/instrumentation.js +18 -19
- package/dist/ui/assets/main.css +1 -1
- package/dist/ui/assets/main.js +1 -1
- package/dist/ui/assets/serverTimingMeta.js +16 -15
- package/dist/ui/index.html +0 -28
- package/dist/ui/manifest.json +3 -7
- package/package.json +9 -9
- package/dist/_virtual/_commonjsHelpers.js.map +0 -1
- package/dist/_virtual/_sentry-release-injection-file.js +0 -11
- package/dist/_virtual/_sentry-release-injection-file.js.map +0 -1
- package/dist/_virtual/additionalItems.js.map +0 -1
- package/dist/_virtual/additionalProperties.js.map +0 -1
- package/dist/_virtual/ajv.js.map +0 -1
- package/dist/_virtual/allOf.js.map +0 -1
- package/dist/_virtual/anyOf.js.map +0 -1
- package/dist/_virtual/applicability.js.map +0 -1
- package/dist/_virtual/boolSchema.js.map +0 -1
- package/dist/_virtual/code.js.map +0 -1
- package/dist/_virtual/code2.js.map +0 -1
- package/dist/_virtual/const.js.map +0 -1
- package/dist/_virtual/contains.js.map +0 -1
- package/dist/_virtual/core.js.map +0 -1
- package/dist/_virtual/dataType.js.map +0 -1
- package/dist/_virtual/defaults.js.map +0 -1
- package/dist/_virtual/dependencies.js.map +0 -1
- package/dist/_virtual/draft7.js.map +0 -1
- package/dist/_virtual/enum.js.map +0 -1
- package/dist/_virtual/equal.js.map +0 -1
- package/dist/_virtual/errors.js.map +0 -1
- package/dist/_virtual/format.js.map +0 -1
- package/dist/_virtual/formats.js.map +0 -1
- package/dist/_virtual/id.js.map +0 -1
- package/dist/_virtual/if.js.map +0 -1
- package/dist/_virtual/index.js.map +0 -1
- package/dist/_virtual/index10.js.map +0 -1
- package/dist/_virtual/index11.js.map +0 -1
- package/dist/_virtual/index2.js.map +0 -1
- package/dist/_virtual/index3.js.map +0 -1
- package/dist/_virtual/index4.js.map +0 -1
- package/dist/_virtual/index5.js.map +0 -1
- package/dist/_virtual/index6.js.map +0 -1
- package/dist/_virtual/index7.js.map +0 -1
- package/dist/_virtual/index8.js.map +0 -1
- package/dist/_virtual/index9.js.map +0 -1
- package/dist/_virtual/items.js.map +0 -1
- package/dist/_virtual/items2020.js.map +0 -1
- package/dist/_virtual/keyword.js.map +0 -1
- package/dist/_virtual/limit.js.map +0 -1
- package/dist/_virtual/limitItems.js.map +0 -1
- package/dist/_virtual/limitLength.js.map +0 -1
- package/dist/_virtual/limitNumber.js.map +0 -1
- package/dist/_virtual/limitProperties.js.map +0 -1
- package/dist/_virtual/metadata.js.map +0 -1
- package/dist/_virtual/multipleOf.js.map +0 -1
- package/dist/_virtual/names.js.map +0 -1
- package/dist/_virtual/not.js.map +0 -1
- package/dist/_virtual/oneOf.js.map +0 -1
- package/dist/_virtual/pattern.js.map +0 -1
- package/dist/_virtual/patternProperties.js.map +0 -1
- package/dist/_virtual/prefixItems.js.map +0 -1
- package/dist/_virtual/properties.js.map +0 -1
- package/dist/_virtual/propertyNames.js.map +0 -1
- package/dist/_virtual/ref.js.map +0 -1
- package/dist/_virtual/ref_error.js.map +0 -1
- package/dist/_virtual/required.js.map +0 -1
- package/dist/_virtual/resolve.js.map +0 -1
- package/dist/_virtual/rules.js.map +0 -1
- package/dist/_virtual/scope.js.map +0 -1
- package/dist/_virtual/subschema.js.map +0 -1
- package/dist/_virtual/thenElse.js.map +0 -1
- package/dist/_virtual/types.js.map +0 -1
- package/dist/_virtual/ucs2length.js.map +0 -1
- package/dist/_virtual/uniqueItems.js.map +0 -1
- package/dist/_virtual/uri.js.map +0 -1
- package/dist/_virtual/util.js.map +0 -1
- package/dist/_virtual/validation_error.js.map +0 -1
- package/dist/instrument.js.map +0 -1
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.24.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/client/index.js.map +0 -1
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.24.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/client.js.map +0 -1
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.24.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js.map +0 -1
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.24.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js.map +0 -1
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.24.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/mcp-server.js.map +0 -1
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.24.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js.map +0 -1
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.24.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/server/completable.js.map +0 -1
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.24.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js.map +0 -1
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.24.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js.map +0 -1
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.24.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js.map +0 -1
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.24.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js.map +0 -1
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.24.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js.map +0 -1
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.24.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js.map +0 -1
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.24.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js.map +0 -1
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.24.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/toolNameValidation.js.map +0 -1
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.24.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js.map +0 -1
- package/dist/node_modules/.pnpm/@modelcontextprotocol_sdk@1.24.3_zod@4.1.13/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js.map +0 -1
- package/dist/node_modules/.pnpm/fast-uri@3.0.2/node_modules/fast-uri/index.js.map +0 -1
- package/dist/node_modules/.pnpm/fast-uri@3.0.2/node_modules/fast-uri/lib/schemes.js +0 -152
- package/dist/node_modules/.pnpm/fast-uri@3.0.2/node_modules/fast-uri/lib/schemes.js.map +0 -1
- package/dist/node_modules/.pnpm/fast-uri@3.0.2/node_modules/fast-uri/lib/scopedChars.js +0 -40
- package/dist/node_modules/.pnpm/fast-uri@3.0.2/node_modules/fast-uri/lib/scopedChars.js.map +0 -1
- package/dist/node_modules/.pnpm/fast-uri@3.0.2/node_modules/fast-uri/lib/utils.js +0 -236
- package/dist/node_modules/.pnpm/fast-uri@3.0.2/node_modules/fast-uri/lib/utils.js.map +0 -1
- package/dist/run.js.map +0 -1
- package/dist/sentry-config.js.map +0 -1
- package/dist/server/cli/help.js.map +0 -1
- package/dist/server/cli/mcp.js.map +0 -1
- package/dist/server/cli/run.js.map +0 -1
- package/dist/server/cli/server.js.map +0 -1
- package/dist/server/cli/tail.js.map +0 -1
- package/dist/server/cli.js.map +0 -1
- package/dist/server/constants.js.map +0 -1
- package/dist/server/formatters/human/errors.js.map +0 -1
- package/dist/server/formatters/human/index.js.map +0 -1
- package/dist/server/formatters/human/logs.js.map +0 -1
- package/dist/server/formatters/human/traces.js.map +0 -1
- package/dist/server/formatters/human/utils.js.map +0 -1
- package/dist/server/formatters/index.js.map +0 -1
- package/dist/server/formatters/json/errors.js.map +0 -1
- package/dist/server/formatters/json/index.js.map +0 -1
- package/dist/server/formatters/json/logs.js.map +0 -1
- package/dist/server/formatters/json/traces.js.map +0 -1
- package/dist/server/formatters/logfmt/errors.js.map +0 -1
- package/dist/server/formatters/logfmt/index.js.map +0 -1
- package/dist/server/formatters/logfmt/logs.js.map +0 -1
- package/dist/server/formatters/logfmt/traces.js.map +0 -1
- package/dist/server/formatters/md/errors.js.map +0 -1
- package/dist/server/formatters/md/event.js.map +0 -1
- package/dist/server/formatters/md/index.js.map +0 -1
- package/dist/server/formatters/md/logs.js.map +0 -1
- package/dist/server/formatters/md/traces.js.map +0 -1
- package/dist/server/formatters/shared/data-builders.js.map +0 -1
- package/dist/server/formatters/types.js.map +0 -1
- package/dist/server/formatters/utils.js.map +0 -1
- package/dist/server/handlers/fileToServe.js.map +0 -1
- package/dist/server/logger.js.map +0 -1
- package/dist/server/main.js.map +0 -1
- package/dist/server/mcp/constants.js.map +0 -1
- package/dist/server/mcp/mcp.js.map +0 -1
- package/dist/server/messageBuffer.js.map +0 -1
- package/dist/server/parser/helpers.js.map +0 -1
- package/dist/server/parser/processEnvelope.js.map +0 -1
- package/dist/server/routes/clear.js.map +0 -1
- package/dist/server/routes/contextlines/index.js.map +0 -1
- package/dist/server/routes/contextlines/utils.js.map +0 -1
- package/dist/server/routes/health.js.map +0 -1
- package/dist/server/routes/index.js.map +0 -1
- package/dist/server/routes/mcp.js.map +0 -1
- package/dist/server/routes/open.js.map +0 -1
- package/dist/server/routes/stream/debugLogging.js.map +0 -1
- package/dist/server/routes/stream/index.js.map +0 -1
- package/dist/server/routes/stream/streaming.js.map +0 -1
- package/dist/server/routes/stream/userAgent.js.map +0 -1
- package/dist/server/sdk.js.map +0 -1
- package/dist/server/utils/cors.js.map +0 -1
- package/dist/server/utils/docker-compose-parser.js.map +0 -1
- package/dist/server/utils/docker-compose.js.map +0 -1
- package/dist/server/utils/eventContainer.js.map +0 -1
- package/dist/server/utils/extras.js.map +0 -1
- package/dist/server/utils/getBuffer.js.map +0 -1
- package/dist/shared/constants.js.map +0 -1
- package/dist/ui/assets/andromeeda.js.map +0 -1
- package/dist/ui/assets/angular-html.js.map +0 -1
- package/dist/ui/assets/angular-ts.js.map +0 -1
- package/dist/ui/assets/astro.js.map +0 -1
- package/dist/ui/assets/aurora-x.js.map +0 -1
- package/dist/ui/assets/ayu-dark.js.map +0 -1
- package/dist/ui/assets/blade.js.map +0 -1
- package/dist/ui/assets/c.js.map +0 -1
- package/dist/ui/assets/catppuccin-frappe.js.map +0 -1
- package/dist/ui/assets/catppuccin-latte.js.map +0 -1
- package/dist/ui/assets/catppuccin-macchiato.js.map +0 -1
- package/dist/ui/assets/catppuccin-mocha.js.map +0 -1
- package/dist/ui/assets/coffee.js.map +0 -1
- package/dist/ui/assets/cpp.js.map +0 -1
- package/dist/ui/assets/css.js.map +0 -1
- package/dist/ui/assets/dark-plus.js.map +0 -1
- package/dist/ui/assets/dracula-soft.js.map +0 -1
- package/dist/ui/assets/dracula.js.map +0 -1
- package/dist/ui/assets/everforest-dark.js.map +0 -1
- package/dist/ui/assets/everforest-light.js.map +0 -1
- package/dist/ui/assets/github-dark-default.js.map +0 -1
- package/dist/ui/assets/github-dark-dimmed.js.map +0 -1
- package/dist/ui/assets/github-dark-high-contrast.js.map +0 -1
- package/dist/ui/assets/github-dark.js.map +0 -1
- package/dist/ui/assets/github-light-default.js.map +0 -1
- package/dist/ui/assets/github-light-high-contrast.js.map +0 -1
- package/dist/ui/assets/github-light.js.map +0 -1
- package/dist/ui/assets/glsl.js.map +0 -1
- package/dist/ui/assets/graphql.js.map +0 -1
- package/dist/ui/assets/gruvbox-dark-hard.js.map +0 -1
- package/dist/ui/assets/gruvbox-dark-medium.js.map +0 -1
- package/dist/ui/assets/gruvbox-dark-soft.js.map +0 -1
- package/dist/ui/assets/gruvbox-light-hard.js.map +0 -1
- package/dist/ui/assets/gruvbox-light-medium.js.map +0 -1
- package/dist/ui/assets/gruvbox-light-soft.js.map +0 -1
- package/dist/ui/assets/haml.js.map +0 -1
- package/dist/ui/assets/handlebars.js.map +0 -1
- package/dist/ui/assets/houston.js.map +0 -1
- package/dist/ui/assets/html-derivative.js.map +0 -1
- package/dist/ui/assets/html.js.map +0 -1
- package/dist/ui/assets/http.js.map +0 -1
- package/dist/ui/assets/imba.js.map +0 -1
- package/dist/ui/assets/index.js.map +0 -1
- package/dist/ui/assets/index2.js.map +0 -1
- package/dist/ui/assets/instrumentation.js.map +0 -1
- package/dist/ui/assets/java.js.map +0 -1
- package/dist/ui/assets/javascript.js.map +0 -1
- package/dist/ui/assets/jinja.js.map +0 -1
- package/dist/ui/assets/jison.js.map +0 -1
- package/dist/ui/assets/json.js.map +0 -1
- package/dist/ui/assets/json5.js.map +0 -1
- package/dist/ui/assets/jsonc.js.map +0 -1
- package/dist/ui/assets/jsonl.js.map +0 -1
- package/dist/ui/assets/jsx.js.map +0 -1
- package/dist/ui/assets/julia.js.map +0 -1
- package/dist/ui/assets/kanagawa-dragon.js.map +0 -1
- package/dist/ui/assets/kanagawa-lotus.js.map +0 -1
- package/dist/ui/assets/kanagawa-wave.js.map +0 -1
- package/dist/ui/assets/laserwave.js.map +0 -1
- package/dist/ui/assets/less.js.map +0 -1
- package/dist/ui/assets/light-plus.js.map +0 -1
- package/dist/ui/assets/main.js.map +0 -1
- package/dist/ui/assets/markdown.js.map +0 -1
- package/dist/ui/assets/marko.js.map +0 -1
- package/dist/ui/assets/material-theme-darker.js.map +0 -1
- package/dist/ui/assets/material-theme-lighter.js.map +0 -1
- package/dist/ui/assets/material-theme-ocean.js.map +0 -1
- package/dist/ui/assets/material-theme-palenight.js.map +0 -1
- package/dist/ui/assets/material-theme.js.map +0 -1
- package/dist/ui/assets/mdc.js.map +0 -1
- package/dist/ui/assets/mdx.js.map +0 -1
- package/dist/ui/assets/min-dark.js.map +0 -1
- package/dist/ui/assets/min-light.js.map +0 -1
- package/dist/ui/assets/monokai.js.map +0 -1
- package/dist/ui/assets/night-owl.js.map +0 -1
- package/dist/ui/assets/nord.js.map +0 -1
- package/dist/ui/assets/one-dark-pro.js.map +0 -1
- package/dist/ui/assets/one-light.js.map +0 -1
- package/dist/ui/assets/php.js.map +0 -1
- package/dist/ui/assets/plastic.js.map +0 -1
- package/dist/ui/assets/poimandres.js.map +0 -1
- package/dist/ui/assets/postcss.js.map +0 -1
- package/dist/ui/assets/pug.js.map +0 -1
- package/dist/ui/assets/python.js.map +0 -1
- package/dist/ui/assets/r.js.map +0 -1
- package/dist/ui/assets/red.js.map +0 -1
- package/dist/ui/assets/regexp.js.map +0 -1
- package/dist/ui/assets/rose-pine-dawn.js.map +0 -1
- package/dist/ui/assets/rose-pine-moon.js.map +0 -1
- package/dist/ui/assets/rose-pine.js.map +0 -1
- package/dist/ui/assets/sass.js.map +0 -1
- package/dist/ui/assets/scss.js.map +0 -1
- package/dist/ui/assets/serverTimingMeta.js.map +0 -1
- package/dist/ui/assets/shellscript.js.map +0 -1
- package/dist/ui/assets/slack-dark.js.map +0 -1
- package/dist/ui/assets/slack-ochin.js.map +0 -1
- package/dist/ui/assets/snazzy-light.js.map +0 -1
- package/dist/ui/assets/solarized-dark.js.map +0 -1
- package/dist/ui/assets/solarized-light.js.map +0 -1
- package/dist/ui/assets/sql.js.map +0 -1
- package/dist/ui/assets/stylus.js.map +0 -1
- package/dist/ui/assets/svelte.js.map +0 -1
- package/dist/ui/assets/synthwave-84.js.map +0 -1
- package/dist/ui/assets/tokyo-night.js.map +0 -1
- package/dist/ui/assets/ts-tags.js.map +0 -1
- package/dist/ui/assets/tsx.js.map +0 -1
- package/dist/ui/assets/typescript.js.map +0 -1
- package/dist/ui/assets/vesper.js.map +0 -1
- package/dist/ui/assets/vitesse-black.js.map +0 -1
- package/dist/ui/assets/vitesse-dark.js.map +0 -1
- package/dist/ui/assets/vitesse-light.js.map +0 -1
- package/dist/ui/assets/vue-html.js.map +0 -1
- package/dist/ui/assets/vue-vine.js.map +0 -1
- package/dist/ui/assets/vue.js.map +0 -1
- package/dist/ui/assets/wasm.js.map +0 -1
- package/dist/ui/assets/wasm2.js.map +0 -1
- package/dist/ui/assets/wgsl.js.map +0 -1
- package/dist/ui/assets/wit.js.map +0 -1
- package/dist/ui/assets/xml.js.map +0 -1
- package/dist/ui/assets/yaml.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"logs.js","sources":["../../../../src/server/formatters/md/logs.ts"],"sourcesContent":["import type { Envelope, EnvelopeItem, SerializedLog } from \"@sentry/core\";\nimport { type SentryEvent, type SentryLogEvent, isLogEvent } from \"../../parser/index.ts\";\nimport type { EventContainer } from \"../../utils/index.ts\";\nimport { formatTimestamp } from \"../utils.ts\";\n\nexport function formatLogEnvelope(container: EventContainer) {\n const parsedEnvelope = container.getParsedEnvelope();\n\n const {\n envelope: [envelopeHeader, items],\n } = parsedEnvelope;\n\n const formatted: string[] = [];\n for (const item of items) {\n const [{ type }, payload] = item;\n\n if (type === \"log\" && isLogEvent(payload as SentryEvent)) {\n formatted.push(...formatLog(payload, envelopeHeader));\n }\n }\n\n return formatted;\n}\n\n/**\n * Format a single log entry to markdown string\n */\nfunction formatSingleLog(event: SerializedLog): string {\n let attr = \"\";\n for (const [key, property] of Object.entries(event.attributes ?? {})) {\n if (key.startsWith(\"sentry.\")) {\n continue;\n }\n\n attr += `${key}: ${property.value} (${property.type})\\n`;\n }\n\n return `${formatTimestamp(event.timestamp)} ${event.level} ${event.body}\nAttributes:\n${attr}`;\n}\n\n/**\n * Format a log event to markdown string\n */\nexport function formatLog(payload: EnvelopeItem[1], _envelopeHeader: Envelope[0]): string[] {\n const event = payload as SentryLogEvent;\n return event.items.map(formatSingleLog);\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AAKO,SAAS,kBAAkB,WAA2B;AAC3D,QAAM,iBAAiB,UAAU,kBAAA;AAEjC,QAAM;AAAA,IACJ,UAAU,CAAC,gBAAgB,KAAK;AAAA,EAAA,IAC9B;AAEJ,QAAM,YAAsB,CAAA;AAC5B,aAAW,QAAQ,OAAO;AACxB,UAAM,CAAC,EAAE,QAAQ,OAAO,IAAI;AAE5B,QAAI,SAAS,SAAS,WAAW,OAAsB,GAAG;AACxD,gBAAU,KAAK,GAAG,UAAU,OAAuB,CAAC;AAAA,IACtD;AAAA,EACF;AAEA,SAAO;AACT;AAKA,SAAS,gBAAgB,OAA8B;AACrD,MAAI,OAAO;AACX,aAAW,CAAC,KAAK,QAAQ,KAAK,OAAO,QAAQ,MAAM,cAAc,CAAA,CAAE,GAAG;AACpE,QAAI,IAAI,WAAW,SAAS,GAAG;AAC7B;AAAA,IACF;AAEA,YAAQ,GAAG,GAAG,KAAK,SAAS,KAAK,KAAK,SAAS,IAAI;AAAA;AAAA,EACrD;AAEA,SAAO,GAAG,gBAAgB,MAAM,SAAS,CAAC,IAAI,MAAM,KAAK,IAAI,MAAM,IAAI;AAAA;AAAA,EAEvE,IAAI;AACN;AAKO,SAAS,UAAU,SAA0B,iBAAwC;AAC1F,QAAM,QAAQ;AACd,SAAO,MAAM,MAAM,IAAI,eAAe;AACxC;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"traces.js","sources":["../../../../src/server/formatters/md/traces.ts"],"sourcesContent":["import type { Envelope, EnvelopeItem } from \"@sentry/core\";\nimport { captureException } from \"@sentry/node\";\nimport { type SentryTransactionEvent, processEnvelope } from \"../../parser/index.ts\";\nimport type { EventContainer } from \"../../utils/index.ts\";\nimport { formatTimestamp, getDuration } from \"../utils.ts\";\n\nexport interface TraceContext {\n trace_id: string;\n span_id: string;\n parent_span_id?: string;\n}\n\nexport interface SpanData {\n span_id: string;\n parent_span_id?: string;\n trace_id: string;\n op?: string;\n description?: string;\n start_timestamp?: number;\n timestamp?: number;\n duration?: number;\n status?: string;\n data?: Record<string, unknown>;\n}\n\nexport interface TraceEvent {\n event_id: string;\n type: string;\n timestamp?: number;\n start_timestamp?: number;\n transaction?: string;\n trace_context?: TraceContext;\n spans?: SpanData[];\n level?: string;\n platform?: string;\n message?: string;\n exception?: {\n values?: Array<{\n type?: string;\n value?: string;\n }>;\n };\n}\n\nexport interface TraceSummary {\n trace_id: string;\n root_transaction?: string;\n start_timestamp?: number;\n duration?: number;\n span_count: number;\n error_count: number;\n events: TraceEvent[];\n}\n\n/**\n * Extract trace events from envelopes and group by trace ID\n */\nexport function extractTracesFromEnvelopes(containers: EventContainer[]): Map<string, TraceSummary> {\n const traces = new Map<string, TraceSummary>();\n\n for (const container of containers) {\n try {\n const events = extractTraceEventsFromContainer(container);\n\n for (const event of events) {\n if (!event.trace_context?.trace_id) continue;\n\n const traceId = event.trace_context.trace_id;\n\n if (!traces.has(traceId)) {\n traces.set(traceId, {\n trace_id: traceId,\n span_count: 0,\n error_count: 0,\n events: [],\n });\n }\n\n const trace = traces.get(traceId)!;\n trace.events.push(event);\n\n // Update trace statistics\n if (event.type === \"error\") {\n trace.error_count++;\n }\n\n if (event.spans) {\n trace.span_count += event.spans.length;\n }\n\n // Set root transaction and timing info\n if (event.transaction && !trace.root_transaction) {\n trace.root_transaction = event.transaction;\n }\n\n // Use start_timestamp if available (for transactions), otherwise fall back to timestamp\n const eventStartTime = event.start_timestamp || event.timestamp;\n if (eventStartTime) {\n if (!trace.start_timestamp || eventStartTime < trace.start_timestamp) {\n trace.start_timestamp = eventStartTime;\n }\n }\n }\n } catch (err) {\n captureException(err, { extra: { context: \"Error extracting trace events\" } });\n }\n }\n\n // Calculate durations and finalize traces\n for (const trace of traces.values()) {\n calculateTraceDuration(trace);\n }\n\n return traces;\n}\n\n/**\n * Extract trace-related events from a single envelope container\n */\nfunction extractTraceEventsFromContainer(container: EventContainer): TraceEvent[] {\n const events: TraceEvent[] = [];\n\n try {\n const parsed = processEnvelope({\n contentType: container.getContentType(),\n data: container.getData(),\n });\n\n const [, items] = parsed!.envelope;\n\n for (const item of items) {\n const [{ type }, payload] = item;\n\n if (type === \"event\" && payload && typeof payload === \"object\") {\n const event = payload as any;\n\n // Only include events that have trace context\n if (event.contexts?.trace?.trace_id) {\n // Determine event type - error events have exception or level === \"error\"\n let eventType = \"unknown\";\n if (event.exception || event.level === \"error\") {\n eventType = \"error\";\n } else if (event.type) {\n eventType = event.type;\n }\n\n events.push({\n event_id: event.event_id || \"\",\n type: eventType,\n timestamp: event.timestamp,\n start_timestamp: event.start_timestamp,\n transaction: event.transaction,\n trace_context: event.contexts.trace,\n spans: event.spans,\n level: event.level,\n platform: event.platform,\n message: event.message,\n exception: event.exception,\n });\n }\n }\n\n // Handle transaction items\n if (type === \"transaction\" && payload && typeof payload === \"object\") {\n const transaction = payload as any;\n\n if (transaction.contexts?.trace?.trace_id) {\n events.push(convertPayloadToTraceEvent(transaction));\n }\n }\n }\n } catch (err) {\n captureException(err, { extra: { context: \"Error parsing envelope for traces\" } });\n }\n\n return events;\n}\n\n/**\n * Calculate trace duration from start to latest event\n */\nfunction calculateTraceDuration(trace: TraceSummary): void {\n if (!trace.start_timestamp) return;\n\n let latestTimestamp = trace.start_timestamp;\n\n for (const event of trace.events) {\n if (event.timestamp && event.timestamp > latestTimestamp) {\n latestTimestamp = event.timestamp;\n }\n\n // Also check span end times\n if (event.spans) {\n for (const span of event.spans) {\n if (span.timestamp && span.timestamp > latestTimestamp) {\n latestTimestamp = span.timestamp;\n }\n }\n }\n }\n\n trace.duration = getDuration(latestTimestamp, trace.start_timestamp);\n}\n\n/**\n * Build a hierarchical span tree from trace events\n */\nexport interface SpanNode {\n span_id: string;\n parent_span_id?: string;\n op?: string;\n description?: string;\n duration?: number;\n status?: string;\n is_transaction?: boolean;\n children: SpanNode[];\n level: number;\n event_id?: string;\n}\n\nexport function buildSpanTree(trace: TraceSummary): SpanNode[] {\n const allSpans: SpanNode[] = [];\n const spanMap = new Map<string, SpanNode>();\n\n // Collect all spans from all events in the trace\n for (const event of trace.events) {\n // Add the transaction/event itself as a span node\n if (event.trace_context) {\n const eventSpan: SpanNode = {\n span_id: event.trace_context.span_id,\n parent_span_id: event.trace_context.parent_span_id,\n op: event.type === \"transaction\" ? \"transaction\" : event.type,\n description: event.transaction || event.message || \"unnamed\",\n is_transaction: event.type === \"transaction\" || !!event.transaction,\n children: [],\n level: 0,\n event_id: event.event_id,\n duration: getDuration(event.timestamp, event.start_timestamp),\n };\n\n allSpans.push(eventSpan);\n spanMap.set(eventSpan.span_id, eventSpan);\n }\n\n // Add individual spans from the event - but only if they're not duplicates\n if (event.spans && Array.isArray(event.spans)) {\n for (const span of event.spans) {\n // Skip if we already have this span\n if (spanMap.has(span.span_id)) continue;\n\n const spanNode: SpanNode = {\n span_id: span.span_id,\n parent_span_id: span.parent_span_id || event.trace_context?.span_id, // Default to event's span as parent\n op: span.op,\n description: span.description || \"unnamed\",\n duration: span.duration !== undefined ? span.duration : getDuration(span.timestamp, span.start_timestamp),\n status: span.status,\n children: [],\n level: 0,\n };\n\n allSpans.push(spanNode);\n spanMap.set(spanNode.span_id, spanNode);\n }\n }\n }\n\n // Build parent-child relationships\n const rootSpans: SpanNode[] = [];\n const orphanedByParentId = new Map<string, SpanNode[]>();\n\n // First pass: identify roots and orphans\n for (const span of allSpans) {\n if (!span.parent_span_id) {\n // No parent ID - it's a root\n rootSpans.push(span);\n } else if (spanMap.has(span.parent_span_id)) {\n // Parent exists - attach as child\n const parent = spanMap.get(span.parent_span_id)!;\n parent.children.push(span);\n span.level = parent.level + 1;\n } else {\n // Parent doesn't exist - it's an orphan\n // Group orphans by their missing parent ID\n if (!orphanedByParentId.has(span.parent_span_id)) {\n orphanedByParentId.set(span.parent_span_id, []);\n }\n orphanedByParentId.get(span.parent_span_id)!.push(span);\n }\n }\n\n // Helper function to recursively update levels\n function updateLevels(node: SpanNode, newLevel: number) {\n node.level = newLevel;\n for (const child of node.children) {\n updateLevels(child, newLevel + 1);\n }\n }\n\n // Create orphan parent spans for grouped orphans (like the UI does)\n for (const [parentId, orphans] of orphanedByParentId) {\n const orphanParent: SpanNode = {\n span_id: parentId,\n op: \"orphan\",\n description: \"missing or unknown parent span\",\n children: orphans,\n level: 0,\n is_transaction: false,\n };\n\n // Try to find a root to attach this orphan parent to\n const parentRoot = rootSpans.length === 1 ? rootSpans[0] : null;\n if (parentRoot) {\n parentRoot.children.push(orphanParent);\n // Update levels recursively relative to parent\n updateLevels(orphanParent, parentRoot.level + 1);\n } else {\n // No single root - add as a root itself\n rootSpans.push(orphanParent);\n // Update levels recursively for all children\n updateLevels(orphanParent, 0);\n }\n }\n\n // Sort children by start timestamp (like the UI) or duration\n for (const span of allSpans) {\n span.children.sort((a, b) => {\n // Sort by duration if available, otherwise by description\n if (a.duration !== undefined && b.duration !== undefined) {\n return b.duration - a.duration;\n }\n return 0;\n });\n }\n\n // If we have multiple roots, create a synthetic trace root\n if (rootSpans.length > 1) {\n const syntheticRoot: SpanNode = {\n span_id: trace.trace_id.substring(0, 16),\n description: `Trace ${trace.trace_id.substring(0, 8)}`,\n op: \"trace\",\n is_transaction: false,\n children: rootSpans.sort((a, b) => (b.duration || 0) - (a.duration || 0)),\n level: 0,\n duration: trace.duration,\n };\n // Update all root spans to be level 1 under synthetic root\n for (const root of rootSpans) {\n updateLevels(root, 1);\n }\n return [syntheticRoot];\n }\n\n return rootSpans;\n}\n\n/**\n * Format a transaction payload for CLI output\n */\nexport function formatTransactionEvent(event: SentryTransactionEvent): string[] {\n const traceEvent = convertPayloadToTraceEvent(event);\n return processTraceEvent(traceEvent);\n}\n\n/**\n * Format a trace/transaction event to markdown string\n */\nexport function formatTrace(payload: EnvelopeItem[1], _envelopeHeader: Envelope[0]): string[] {\n const event = payload as SentryTransactionEvent;\n return formatTransactionEvent(event);\n}\n\n/**\n * Convert a transaction payload to TraceEvent\n */\nfunction convertPayloadToTraceEvent(payload: any): TraceEvent {\n return {\n event_id: payload.event_id || \"\",\n type: \"transaction\",\n timestamp: payload.timestamp,\n start_timestamp: payload.start_timestamp,\n transaction: payload.transaction,\n trace_context: payload.contexts.trace,\n spans: payload.spans,\n level: payload.level,\n platform: payload.platform,\n };\n}\n\n/**\n * Process a single trace event for CLI output\n */\nexport function processTraceEvent(event: TraceEvent): string[] {\n if (!event.trace_context?.trace_id) {\n return [\"No trace context available\"];\n }\n\n const trace: TraceSummary = {\n trace_id: event.trace_context.trace_id,\n root_transaction: event.transaction,\n start_timestamp: event.start_timestamp || event.timestamp,\n span_count: event.spans?.length || 0,\n error_count: 0,\n events: [event],\n };\n\n calculateTraceDuration(trace);\n\n const spanTree = buildSpanTree(trace);\n const lines = renderSpanTree(spanTree);\n\n return lines;\n}\n\n/**\n * Format trace summary for display\n */\nexport function formatTraceSummary(trace: TraceSummary): string {\n const duration = trace.duration ? `${Math.round(trace.duration)}ms` : \"unknown\";\n const transaction = trace.root_transaction || \"unnamed\";\n const timestamp = formatTimestamp(trace.start_timestamp);\n\n return `**${trace.trace_id.substring(0, 8)}** | ${transaction} | ${duration} | ${trace.span_count} spans | ${trace.error_count} errors | ${timestamp}`;\n}\n\n/**\n * Render span tree as hierarchical text\n */\nexport function renderSpanTree(spans: SpanNode[]): string[] {\n const lines: string[] = [];\n\n function formatSpanDisplayName(span: SpanNode): string {\n // For transaction spans, use the transaction name\n if (span.is_transaction) {\n return span.description || \"unnamed transaction\";\n }\n\n // For regular spans, use description or fallback to operation\n return span.description || span.op || \"unnamed\";\n }\n\n function renderSpan(span: SpanNode, prefix = \"\", isLast = true): void {\n const shortId = span.span_id.substring(0, 8);\n const connector = prefix === \"\" ? \"\" : isLast ? \"└─ \" : \"├─ \";\n const displayName = formatSpanDisplayName(span);\n\n // Format similar to sentry-mcp\n if (span.is_transaction) {\n // For transactions, show without operation since it's redundant\n const duration = span.duration ? `${Math.round(span.duration)}ms` : \"unknown\";\n lines.push(`${prefix}${connector}${displayName} [${shortId} · ${duration}]`);\n } else {\n const duration = span.duration ? `${Math.round(span.duration)}ms` : \"unknown\";\n\n // Don't show 'default' or 'unknown' operations as they're not meaningful\n const opDisplay =\n span.op && span.op !== \"default\" && span.op !== \"unknown\" && span.op !== \"transaction\" ? ` · ${span.op}` : \"\";\n lines.push(`${prefix}${connector}${displayName} [${shortId}${opDisplay} · ${duration}]`);\n }\n\n // Render all children with proper tree indentation\n for (let i = 0; i < span.children.length; i++) {\n const child = span.children[i];\n const isLastChild = i === span.children.length - 1;\n const childPrefix = prefix + (isLast ? \" \" : \"│ \");\n renderSpan(child, childPrefix, isLastChild);\n }\n }\n\n // Render all root spans\n for (let i = 0; i < spans.length; i++) {\n const span = spans[i];\n const isLastRoot = i === spans.length - 1;\n renderSpan(span, \"\", isLastRoot);\n }\n\n return lines;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"data-builders.js","sources":["../../../../src/server/formatters/shared/data-builders.ts"],"sourcesContent":["import { formatTimestamp, getDuration, mapFields, mapSdkFields, mapTags } from \"../utils.ts\";\n\n/**\n * Build error event data object.\n * Used by both logfmt and json formatters.\n */\nexport function buildErrorData(event: any): Record<string, any> {\n const data: Record<string, any> = {\n timestamp: formatTimestamp(event.timestamp),\n type: \"error\",\n level: event.level || \"error\",\n event_id: event.event_id,\n };\n\n const message = event.message || event.logentry?.message;\n if (message) {\n data.message = message;\n }\n\n const exc = event.exception?.values?.[0];\n if (exc) {\n mapFields(exc, data, {\n exception_type: \"type\",\n exception_value: \"value\",\n });\n\n const frames = exc.stacktrace?.frames;\n if (frames?.length) {\n const frame = frames.find((f: any) => f.in_app) || frames[frames.length - 1];\n mapFields(frame, data, {\n filename: \"filename\",\n lineno: \"lineno\",\n colno: \"colno\",\n function: \"function\",\n });\n }\n }\n\n const trace = event.contexts?.trace;\n if (trace?.trace_id) {\n mapFields(trace, data, {\n trace_id: \"trace_id\",\n span_id: \"span_id\",\n });\n }\n\n mapFields(event, data, {\n environment: \"environment\",\n release: \"release\",\n dist: \"dist\",\n platform: \"platform\",\n transaction: \"transaction\",\n logger: \"logger\",\n server_name: \"server_name\",\n user_id: \"user.id\",\n user_email: \"user.email\",\n user_username: \"user.username\",\n request_url: \"request.url\",\n request_method: \"request.method\",\n });\n\n mapSdkFields(event, data);\n\n if (event.breadcrumbs?.length) data.breadcrumb_length = event.breadcrumbs.length;\n if (event.spans?.length) data.span_length = event.spans.length;\n mapTags(event, data);\n\n return data;\n}\n\n/**\n * Build log event data object.\n * Used by both logfmt and json formatters.\n */\nexport function buildLogData(log: any): Record<string, any> {\n const data: Record<string, any> = {\n timestamp: formatTimestamp(log.timestamp),\n type: \"log\",\n level: log.level,\n };\n\n mapFields(log, data, {\n message: \"body\",\n trace_id: \"trace_id\",\n severity_number: \"severity_number\",\n });\n\n if (log.attributes) {\n for (const [key, attr] of Object.entries(log.attributes)) {\n data[key] = (attr as any).value;\n }\n }\n\n return data;\n}\n\n/**\n * Build trace/transaction event data object.\n * Used by both logfmt and json formatters.\n */\nexport function buildTraceData(event: any): Record<string, any> {\n const data: Record<string, any> = {\n timestamp: formatTimestamp(event.timestamp),\n type: \"trace\",\n event_id: event.event_id,\n };\n\n const trace = event.contexts?.trace;\n if (trace?.trace_id) {\n mapFields(trace, data, {\n trace_id: \"trace_id\",\n span_id: \"span_id\",\n parent_span_id: \"parent_span_id\",\n op: \"op\",\n status: \"status\",\n description: \"description\",\n });\n }\n\n const duration = getDuration(event.timestamp, event.start_timestamp);\n if (duration !== undefined) {\n data.duration_ms = duration;\n }\n\n if (event.spans?.length) data.span_count = event.spans.length;\n\n mapFields(event, data, {\n transaction: \"transaction\",\n environment: \"environment\",\n release: \"release\",\n platform: \"platform\",\n server_name: \"server_name\",\n });\n\n mapSdkFields(event, data);\n\n if (event.measurements) {\n for (const [key, measurement] of Object.entries(event.measurements)) {\n if ((measurement as any)?.value !== undefined) {\n data[`measurement.${key}`] = (measurement as any).value;\n }\n }\n }\n\n mapTags(event, data);\n\n return data;\n}\n"],"names":[],"mappings":";;;;;;;;;;AAMO,SAAS,eAAe,OAAiC;AAC9D,QAAM,OAA4B;AAAA,IAChC,WAAW,gBAAgB,MAAM,SAAS;AAAA,IAC1C,MAAM;AAAA,IACN,OAAO,MAAM,SAAS;AAAA,IACtB,UAAU,MAAM;AAAA,EAAA;AAGlB,QAAM,UAAU,MAAM,WAAW,MAAM,UAAU;AACjD,MAAI,SAAS;AACX,SAAK,UAAU;AAAA,EACjB;AAEA,QAAM,MAAM,MAAM,WAAW,SAAS,CAAC;AACvC,MAAI,KAAK;AACP,cAAU,KAAK,MAAM;AAAA,MACnB,gBAAgB;AAAA,MAChB,iBAAiB;AAAA,IAAA,CAClB;AAED,UAAM,SAAS,IAAI,YAAY;AAC/B,QAAI,QAAQ,QAAQ;AAClB,YAAM,QAAQ,OAAO,KAAK,CAAC,MAAW,EAAE,MAAM,KAAK,OAAO,OAAO,SAAS,CAAC;AAC3E,gBAAU,OAAO,MAAM;AAAA,QACrB,UAAU;AAAA,QACV,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,UAAU;AAAA,MAAA,CACX;AAAA,IACH;AAAA,EACF;AAEA,QAAM,QAAQ,MAAM,UAAU;AAC9B,MAAI,OAAO,UAAU;AACnB,cAAU,OAAO,MAAM;AAAA,MACrB,UAAU;AAAA,MACV,SAAS;AAAA,IAAA,CACV;AAAA,EACH;AAEA,YAAU,OAAO,MAAM;AAAA,IACrB,aAAa;AAAA,IACb,SAAS;AAAA,IACT,MAAM;AAAA,IACN,UAAU;AAAA,IACV,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,eAAe;AAAA,IACf,aAAa;AAAA,IACb,gBAAgB;AAAA,EAAA,CACjB;AAED,eAAa,OAAO,IAAI;AAExB,MAAI,MAAM,aAAa,OAAQ,MAAK,oBAAoB,MAAM,YAAY;AAC1E,MAAI,MAAM,OAAO,OAAQ,MAAK,cAAc,MAAM,MAAM;AACxD,UAAQ,OAAO,IAAI;AAEnB,SAAO;AACT;AAMO,SAAS,aAAa,KAA+B;AAC1D,QAAM,OAA4B;AAAA,IAChC,WAAW,gBAAgB,IAAI,SAAS;AAAA,IACxC,MAAM;AAAA,IACN,OAAO,IAAI;AAAA,EAAA;AAGb,YAAU,KAAK,MAAM;AAAA,IACnB,SAAS;AAAA,IACT,UAAU;AAAA,IACV,iBAAiB;AAAA,EAAA,CAClB;AAED,MAAI,IAAI,YAAY;AAClB,eAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,IAAI,UAAU,GAAG;AACxD,WAAK,GAAG,IAAK,KAAa;AAAA,IAC5B;AAAA,EACF;AAEA,SAAO;AACT;AAMO,SAAS,eAAe,OAAiC;AAC9D,QAAM,OAA4B;AAAA,IAChC,WAAW,gBAAgB,MAAM,SAAS;AAAA,IAC1C,MAAM;AAAA,IACN,UAAU,MAAM;AAAA,EAAA;AAGlB,QAAM,QAAQ,MAAM,UAAU;AAC9B,MAAI,OAAO,UAAU;AACnB,cAAU,OAAO,MAAM;AAAA,MACrB,UAAU;AAAA,MACV,SAAS;AAAA,MACT,gBAAgB;AAAA,MAChB,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,aAAa;AAAA,IAAA,CACd;AAAA,EACH;AAEA,QAAM,WAAW,YAAY,MAAM,WAAW,MAAM,eAAe;AACnE,MAAI,aAAa,QAAW;AAC1B,SAAK,cAAc;AAAA,EACrB;AAEA,MAAI,MAAM,OAAO,OAAQ,MAAK,aAAa,MAAM,MAAM;AAEvD,YAAU,OAAO,MAAM;AAAA,IACrB,aAAa;AAAA,IACb,aAAa;AAAA,IACb,SAAS;AAAA,IACT,UAAU;AAAA,IACV,aAAa;AAAA,EAAA,CACd;AAED,eAAa,OAAO,IAAI;AAExB,MAAI,MAAM,cAAc;AACtB,eAAW,CAAC,KAAK,WAAW,KAAK,OAAO,QAAQ,MAAM,YAAY,GAAG;AACnE,UAAK,aAAqB,UAAU,QAAW;AAC7C,aAAK,eAAe,GAAG,EAAE,IAAK,YAAoB;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AAEA,UAAQ,OAAO,IAAI;AAEnB,SAAO;AACT;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sources":["../../../src/server/formatters/types.ts"],"sourcesContent":["import type { Envelope } from \"@sentry/core\";\nimport type { SentryErrorEvent, SentryEvent, SentryLogEvent, SentryTransactionEvent } from \"../parser/types.ts\";\n\n/**\n * Strongly-typed formatter functions (no type guards needed in implementation)\n */\nexport type ErrorFormatterFn = (event: SentryErrorEvent, envelopeHeader: Envelope[0]) => string[];\nexport type LogFormatterFn = (event: SentryLogEvent, envelopeHeader: Envelope[0]) => string[];\nexport type TraceFormatterFn = (event: SentryTransactionEvent, envelopeHeader: Envelope[0]) => string[];\n\n/**\n * Registry entry that bundles the formatter with its type guard\n */\nexport type FormatterEntry<T extends SentryEvent> = {\n typeGuard: (event: SentryEvent) => event is T;\n format: (event: T, envelopeHeader: Envelope[0]) => string[];\n};\n\n/**\n * The formatter registry structure - this IS the formatters object\n */\nexport type FormatterRegistry = {\n event: FormatterEntry<SentryErrorEvent>;\n log: FormatterEntry<SentryLogEvent>;\n transaction: FormatterEntry<SentryTransactionEvent>;\n};\n\n/**\n * Available formatter types.\n * Add new formatters here as they are implemented.\n */\nexport type FormatterType = \"md\" | \"logfmt\" | \"json\" | \"human\";\n\n/**\n * Runtime array of valid formatter types for validation.\n * Keep in sync with FormatterType.\n */\nexport const AVAILABLE_FORMATTERS: readonly FormatterType[] = [\"md\", \"logfmt\", \"json\", \"human\"] as const;\n"],"names":[],"mappings":";;;;;;;;;AAqCO,MAAM,uBAAiD,CAAC,MAAM,UAAU,QAAQ,OAAO;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sources":["../../../src/server/formatters/utils.ts"],"sourcesContent":["/**\n * Format a Sentry timestamp (in seconds) to ISO string.\n * Sentry timestamps are Unix timestamps in seconds, so we multiply by 1000 to convert to milliseconds.\n * Falls back to epoch (1970-01-01T00:00:00.000Z) if timestamp is missing/invalid.\n */\nexport function formatTimestamp(timestamp?: number): string {\n const date = timestamp ? new Date(timestamp * 1000) : new Date(0);\n return date.toISOString();\n}\n\n/**\n * Get the duration in milliseconds between two Sentry timestamps.\n * Accepts timestamps in seconds (as numbers or strings).\n * Returns undefined if either timestamp is missing or invalid.\n */\n\nexport function getDuration(endTimestamp?: number | string, startTimestamp?: number | string): number | undefined {\n const end = typeof endTimestamp === \"string\" ? Number.parseFloat(endTimestamp) : endTimestamp;\n const start = typeof startTimestamp === \"string\" ? Number.parseFloat(startTimestamp) : startTimestamp;\n\n if (typeof end === \"number\" && typeof start === \"number\" && !Number.isNaN(end) && !Number.isNaN(start)) {\n return Math.round((end - start) * 1000);\n }\n\n return undefined;\n}\n\n/**\n * Map simple fields from source to data object.\n * Only sets fields if the source value is truthy.\n */\nexport function mapFields(source: any, data: Record<string, any>, fieldMappings: Record<string, string>): void {\n for (const [outputKey, sourcePath] of Object.entries(fieldMappings)) {\n const value = getNestedValue(source, sourcePath);\n if (value !== undefined && value !== null) {\n data[outputKey] = value;\n }\n }\n}\n\n/**\n * Map SDK name and version fields\n */\nexport function mapSdkFields(source: any, data: Record<string, any>): void {\n if (source.sdk?.name) {\n data.sdk = source.sdk.name;\n if (source.sdk.version) {\n data.sdk_version = source.sdk.version;\n }\n }\n}\n\n/**\n * Map tags directly to data object\n */\nexport function mapTags(source: any, data: Record<string, any>): void {\n if (source.tags) {\n for (const [key, value] of Object.entries(source.tags)) {\n data[key] = value;\n }\n }\n}\n\n/**\n * Get nested value from object using dot notation path\n */\nfunction getNestedValue(obj: any, path: string): any {\n return path.split(\".\").reduce((current, key) => current?.[key], obj);\n}\n"],"names":[],"mappings":";;;;;;;;;AAKO,SAAS,gBAAgB,WAA4B;AAC1D,QAAM,OAAO,YAAY,IAAI,KAAK,YAAY,GAAI,IAAI,oBAAI,KAAK,CAAC;AAChE,SAAO,KAAK,YAAA;AACd;AAQO,SAAS,YAAY,cAAgC,gBAAsD;AAChH,QAAM,MAAM,OAAO,iBAAiB,WAAW,OAAO,WAAW,YAAY,IAAI;AACjF,QAAM,QAAQ,OAAO,mBAAmB,WAAW,OAAO,WAAW,cAAc,IAAI;AAEvF,MAAI,OAAO,QAAQ,YAAY,OAAO,UAAU,YAAY,CAAC,OAAO,MAAM,GAAG,KAAK,CAAC,OAAO,MAAM,KAAK,GAAG;AACtG,WAAO,KAAK,OAAO,MAAM,SAAS,GAAI;AAAA,EACxC;AAEA,SAAO;AACT;AAMO,SAAS,UAAU,QAAa,MAA2B,eAA6C;AAC7G,aAAW,CAAC,WAAW,UAAU,KAAK,OAAO,QAAQ,aAAa,GAAG;AACnE,UAAM,QAAQ,eAAe,QAAQ,UAAU;AAC/C,QAAI,UAAU,UAAa,UAAU,MAAM;AACzC,WAAK,SAAS,IAAI;AAAA,IACpB;AAAA,EACF;AACF;AAKO,SAAS,aAAa,QAAa,MAAiC;AACzE,MAAI,OAAO,KAAK,MAAM;AACpB,SAAK,MAAM,OAAO,IAAI;AACtB,QAAI,OAAO,IAAI,SAAS;AACtB,WAAK,cAAc,OAAO,IAAI;AAAA,IAChC;AAAA,EACF;AACF;AAKO,SAAS,QAAQ,QAAa,MAAiC;AACpE,MAAI,OAAO,MAAM;AACf,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,IAAI,GAAG;AACtD,WAAK,GAAG,IAAI;AAAA,IACd;AAAA,EACF;AACF;AAKA,SAAS,eAAe,KAAU,MAAmB;AACnD,SAAO,KAAK,MAAM,GAAG,EAAE,OAAO,CAAC,SAAS,QAAQ,UAAU,GAAG,GAAG,GAAG;AACrE;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fileToServe.js","sources":["../../../src/server/handlers/fileToServe.ts"],"sourcesContent":["import { extname } from \"node:path\";\nimport type { Handler } from \"hono\";\n\nconst extensionsToContentType: Record<string, string | undefined> = {\n \".js\": \"text/javascript\",\n \".css\": \"text/css\",\n \".json\": \"application/json\",\n};\n\nexport function serveFilesHandler(filesToServe: Record<string, Buffer>): Handler {\n return ctx => {\n let filePath = `${ctx.req.path || ctx.req.url}`;\n\n // The `/telemetry` route is handled by the React app with the location\n // router. This is kind of a hack to avoid a 404 when the user refreshes\n // the page or directly navigates to `/telemetry`. Should probably find\n // a better way to share routes from the UI to the server later on.\n if (filePath === \"/\" || filePath.startsWith(\"/telemetry\")) {\n filePath = \"/index.html\";\n }\n\n filePath = filePath.slice(1);\n\n const extName = extname(filePath);\n const contentType = extensionsToContentType[extName] ?? \"text/html\";\n\n if (!Object.hasOwn(filesToServe, filePath) || !filesToServe[filePath]) {\n return ctx.notFound();\n }\n\n // Enable profiling in browser\n ctx.header(\"Document-Policy\", \"js-profiling\");\n ctx.header(\"Content-Type\", contentType);\n\n return ctx.body(new Uint8Array(filesToServe[filePath]));\n };\n}\n"],"names":[],"mappings":";;;;;;;;;;AAGA,MAAM,0BAA8D;AAAA,EAClE,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,SAAS;AACX;AAEO,SAAS,kBAAkB,cAA+C;AAC/E,SAAO,CAAA,QAAO;AACZ,QAAI,WAAW,GAAG,IAAI,IAAI,QAAQ,IAAI,IAAI,GAAG;AAM7C,QAAI,aAAa,OAAO,SAAS,WAAW,YAAY,GAAG;AACzD,iBAAW;AAAA,IACb;AAEA,eAAW,SAAS,MAAM,CAAC;AAE3B,UAAM,UAAU,QAAQ,QAAQ;AAChC,UAAM,cAAc,wBAAwB,OAAO,KAAK;AAExD,QAAI,CAAC,OAAO,OAAO,cAAc,QAAQ,KAAK,CAAC,aAAa,QAAQ,GAAG;AACrE,aAAO,IAAI,SAAA;AAAA,IACb;AAGA,QAAI,OAAO,mBAAmB,cAAc;AAC5C,QAAI,OAAO,gBAAgB,WAAW;AAEtC,WAAO,IAAI,KAAK,IAAI,WAAW,aAAa,QAAQ,CAAC,CAAC;AAAA,EACxD;AACF;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sources":["../../src/server/logger.ts"],"sourcesContent":["import type { SidecarLogger } from \"./types/index.ts\";\n\nconst SPOTLIGHT_PREFIX = \"🔎 [Spotlight]\";\n\nconst defaultLogger: SidecarLogger = {\n info: message => console.error(SPOTLIGHT_PREFIX, message),\n warn: message => console.error(SPOTLIGHT_PREFIX, message),\n error: message => console.error(SPOTLIGHT_PREFIX, message),\n debug: message => debugEnabled && console.error(SPOTLIGHT_PREFIX, message),\n};\n\nlet injectedLogger: SidecarLogger | undefined = undefined;\nlet debugEnabled = false;\n\nexport function activateLogger(logger: SidecarLogger): void {\n injectedLogger = logger;\n}\n\nexport function enableDebugLogging(debug: boolean): void {\n debugEnabled = debug;\n}\n\nexport function isDebugEnabled(): boolean {\n return debugEnabled;\n}\n\nexport const logger: SidecarLogger = {\n info: message => (injectedLogger || defaultLogger).info(message),\n warn: message => (injectedLogger || defaultLogger).warn(message),\n error: message => (injectedLogger || defaultLogger).error(message),\n debug: message => (injectedLogger || defaultLogger).debug(message),\n};\n"],"names":["logger"],"mappings":";;;;;;;;;AAEA,MAAM,mBAAmB;AAEzB,MAAM,gBAA+B;AAAA,EACnC,MAAM,CAAA,YAAW,QAAQ,MAAM,kBAAkB,OAAO;AAAA,EACxD,MAAM,CAAA,YAAW,QAAQ,MAAM,kBAAkB,OAAO;AAAA,EACxD,OAAO,CAAA,YAAW,QAAQ,MAAM,kBAAkB,OAAO;AAAA,EACzD,OAAO,CAAA,YAAW,gBAAgB,QAAQ,MAAM,kBAAkB,OAAO;AAC3E;AAEA,IAAI,iBAA4C;AAChD,IAAI,eAAe;AAEZ,SAAS,eAAeA,SAA6B;AAC1D,mBAAiBA;AACnB;AAEO,SAAS,mBAAmB,OAAsB;AACvD,iBAAe;AACjB;AAEO,SAAS,iBAA0B;AACxC,SAAO;AACT;AAEO,MAAM,SAAwB;AAAA,EACnC,MAAM,CAAA,aAAY,kBAAkB,eAAe,KAAK,OAAO;AAAA,EAC/D,MAAM,CAAA,aAAY,kBAAkB,eAAe,KAAK,OAAO;AAAA,EAC/D,OAAO,CAAA,aAAY,kBAAkB,eAAe,MAAM,OAAO;AAAA,EACjE,OAAO,CAAA,aAAY,kBAAkB,eAAe,MAAM,OAAO;AACnE;"}
|
package/dist/server/main.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"main.js","sources":["../../src/server/main.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport type { Server } from \"node:http\";\nimport type { AddressInfo } from \"node:net\";\nimport { join } from \"node:path\";\nimport { serve } from \"@hono/node-server\";\nimport { addEventProcessor, captureException, getTraceData, startSpan } from \"@sentry/node\";\nimport { Hono } from \"hono\";\nimport { cors } from \"hono/cors\";\nimport { DEFAULT_PORT, SERVER_IDENTIFIER } from \"./constants.ts\";\nimport { serveFilesHandler } from \"./handlers/index.ts\";\nimport { activateLogger, logger } from \"./logger.ts\";\nimport routes from \"./routes/index.ts\";\nimport type { HonoEnv, SideCarOptions, StartServerOptions } from \"./types/index.ts\";\nimport {\n getBuffer,\n isAllowedOrigin,\n isSidecarRunning,\n isValidPort,\n logSpotlightUrl,\n normalizeAllowedOrigins,\n} from \"./utils/index.ts\";\n\nlet portInUseRetryTimeout: NodeJS.Timeout | null = null;\n\nconst MAX_RETRIES = 3;\nexport async function startServer(options: StartServerOptions): Promise<Server> {\n const { port, basePath } = options;\n let filesToServe = options.filesToServe;\n if (!filesToServe && basePath) {\n try {\n filesToServe = {\n \"index.html\": readFileSync(join(basePath, \"index.html\")),\n \"assets/main.js\": readFileSync(join(basePath, \"assets/main.js\")),\n };\n } catch {\n // pass -- no UI\n }\n }\n\n const app = new Hono<HonoEnv>().use(\n cors({\n origin: async origin => ((await isAllowedOrigin(origin, options.normalizedAllowedOrigins)) ? origin : null),\n }),\n );\n\n app\n .use(async (ctx, next) => {\n ctx.header(\"X-Powered-By\", SERVER_IDENTIFIER);\n\n ctx.set(\"basePath\", options.basePath);\n ctx.set(\"incomingPayload\", options.incomingPayload);\n\n const host = ctx.req.header(\"Host\") || \"localhost\";\n const path = ctx.req.path;\n await startSpan(\n {\n name: `HTTP ${ctx.req.method} ${path}`,\n op: `sidecar.http.${ctx.req.method?.toLowerCase()}`,\n forceTransaction: true,\n attributes: {\n \"http.request.method\": ctx.req.method,\n \"http.request.url\": ctx.req.url,\n \"http.request.query\": ctx.req.query().toString(),\n \"server.address\": host,\n \"server.port\": ctx.env.incoming.socket.localPort,\n },\n },\n async span => {\n const traceData = getTraceData();\n ctx.header(\n \"server-timing\",\n [\n `sentryTrace;desc=\"${traceData[\"sentry-trace\"]}\"`,\n `baggage;desc=\"${traceData.baggage}\"`,\n `sentrySpotlightPort;desc=${ctx.env.incoming.socket.localPort}`,\n ].join(\", \"),\n );\n\n if (path === \"/mcp\" || path === \"/health\") {\n await next();\n } else {\n await startSpan({ name: \"enableCORS\", op: \"sidecar.http.middleware.cors\" }, () => next());\n }\n\n span.setAttribute(\"http.response.status_code\", ctx.res.status);\n },\n );\n })\n .route(\"/\", routes);\n\n if (filesToServe) {\n app.get(\"/*\", serveFilesHandler(filesToServe));\n }\n\n let resolve: (value: Server) => void;\n let reject!: (err: Error) => void;\n const promise = new Promise<Server>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n const server = serve(\n {\n fetch: app.fetch,\n port,\n },\n () => {\n const realPort = (server.address() as AddressInfo).port;\n logger.info(`Spotlight listening on ${realPort}`);\n if (basePath) {\n logSpotlightUrl(realPort);\n }\n resolve(server as Server);\n },\n );\n server.addListener(\"error\", handleServerError);\n\n let retries = 0;\n function handleServerError(err: { code?: string }): void {\n if (\"code\" in err && err.code === \"EADDRINUSE\") {\n logger.info(`Port ${options.port} in use, retrying...`);\n server.close();\n\n retries++;\n if (retries > MAX_RETRIES) {\n reject(err as Error);\n return;\n }\n\n if (portInUseRetryTimeout) {\n clearTimeout(portInUseRetryTimeout);\n }\n portInUseRetryTimeout = setTimeout(() => {\n server.listen(options.port);\n }, 5000);\n portInUseRetryTimeout.unref();\n } else {\n captureException(err);\n reject(err as Error);\n }\n }\n\n return promise;\n}\n\nexport async function setupSpotlight(\n {\n port,\n logger: customLogger,\n basePath,\n filesToServe,\n incomingPayload,\n isStandalone,\n allowedOrigins,\n }: SideCarOptions = {\n port: DEFAULT_PORT,\n },\n): Promise<Server | undefined> {\n if (!isStandalone) {\n addEventProcessor(event => (event.spans?.some(span => span.op?.startsWith(\"sidecar.\")) ? null : event));\n }\n\n if (customLogger) {\n activateLogger(customLogger);\n }\n\n if (port && !isValidPort(port)) {\n throw new Error(`Invalid port number: ${port}. Must be between 1 and 65535, or 0 for automatic assignment.`);\n }\n\n if (port > 0 && (await isSidecarRunning(port))) {\n logger.info(`Spotlight is already running on port ${port}`);\n const hasSpotlightUI = (filesToServe && \"index.html\" in filesToServe) || (!filesToServe && basePath);\n if (hasSpotlightUI) {\n logSpotlightUrl(port);\n }\n return;\n }\n const serverInstance = await startServer({\n port,\n basePath,\n filesToServe,\n incomingPayload,\n normalizedAllowedOrigins: allowedOrigins ? normalizeAllowedOrigins(allowedOrigins) : undefined,\n });\n setShutdownHandlers(serverInstance);\n return serverInstance;\n}\n\nexport function clearBuffer(): void {\n getBuffer().reset();\n}\n\nexport function setShutdownHandlers(server: Server): void {\n let forceShutdown = false;\n const shutdown = () => {\n if (forceShutdown) {\n logger.info(\"Bye.\");\n process.exit(0);\n }\n\n forceShutdown = true;\n logger.info(\"Shutting down server gracefully...\");\n server.close();\n server.closeAllConnections();\n server.unref();\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n}\n"],"names":["routes"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sources":["../../../src/server/mcp/constants.ts"],"sourcesContent":["import type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\n\nexport const NO_ERRORS_CONTENT: CallToolResult = {\n content: [\n {\n type: \"text\",\n text: `**No errors detected in Spotlight**\n\n**This means:**\n- Application is currently running without runtime failures\n- No crashes, exceptions, or critical issues in the recent timeframe\n- System appears stable at the moment\n\n**Next debugging steps:**\n\n1. **If user reports a specific issue:**\n - Ask them to reproduce the problem (click the button, submit the form, navigate to the page)\n - Run this tool again immediately after they reproduce it\n - Errors will appear in real-time as they happen\n\n2. **If investigating existing code:**\n - Check application logs separately\n - Look for TODO comments, error handling gaps, or potential edge cases in the code\n - Consider testing error scenarios (invalid inputs, network failures, etc.)\n\n3. **Proactive error detection:**\n - Have user interact with recently changed features\n - Test API endpoints or database operations that might be fragile\n - Check pages/features mentioned in recent commits\n\n** Pro tip:** Absence of errors doesn't mean absence of bugs - it just means no runtime failures occurred recently. The issue might be logical errors, UI problems, or dormant bugs waiting for specific conditions.`,\n },\n ],\n};\n\nexport const NO_LOGS_CONTENT: CallToolResult = {\n content: [\n {\n type: \"text\",\n text: `**No logs detected in Spotlight**\n\n**This means:**\n- Application hasn't generated any log messages in the recent timeframe\n- No debug, info, warning, or trace messages were captured\n- Application might be idle or not actively processing requests\n\n**Next debugging steps:**\n\n1. **If investigating application behavior:**\n - Have user interact with the application (navigate pages, submit forms, trigger features)\n - Run this tool again after user activity to capture runtime logs\n - Logs appear in real-time as your application executes\n\n2. **If checking for specific functionality:**\n - Trigger the feature or workflow you're investigating\n - Look for custom logging statements in your code\n - Consider adding more logging to critical paths if needed\n\n3. **If monitoring general health:**\n - Check that logging is properly configured in your application\n - Verify that Spotlight is correctly capturing your log output\n - Test with known log-generating actions (API calls, database operations)\n\n4. **Expand search timeframe:**\n - Use a longer duration (300+ seconds) to capture older log entries\n - Consider that some operations might generate logs less frequently\n\n**Log Levels to expect:**\n- **INFO**: General application flow and significant events\n- **WARN**: Potential issues or important notices\n- **DEBUG**: Detailed execution information\n- **ERROR**: Failures (also check search_errors tool)\n\n**Pro tip:** Absence of logs doesn't mean your application isn't working - it might just be running quietly. Many applications only log during significant events, errors, or when explicitly configured for verbose logging.`,\n },\n ],\n};\n"],"names":[],"mappings":";;;;;;;;;AAEO,MAAM,oBAAoC;AAAA,EAC/C,SAAS;AAAA,IACP;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA;AAAA,EAyBR;AAEJ;AAEO,MAAM,kBAAkC;AAAA,EAC7C,SAAS;AAAA,IACP;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAA;AAAA,EAmCR;AAEJ;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.js","sources":["../../../src/server/mcp/mcp.ts"],"sourcesContent":["import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { TextContent } from \"@modelcontextprotocol/sdk/types.js\";\nimport { captureException, wrapMcpServerWithSentry } from \"@sentry/node\";\nimport { z } from \"zod/v3\";\nimport { formatErrorEnvelope } from \"../formatters/md/errors.ts\";\nimport { formatLogEnvelope } from \"../formatters/md/logs.ts\";\nimport {\n buildSpanTree,\n extractTracesFromEnvelopes,\n formatTraceSummary,\n renderSpanTree,\n} from \"../formatters/md/traces.ts\";\nimport { getBuffer } from \"../utils/index.ts\";\nimport { NO_ERRORS_CONTENT, NO_LOGS_CONTENT } from \"./constants.ts\";\n\nconst inputSchema = {\n filters: z.union([\n z.object({\n timeWindow: z\n .number()\n .describe(\n \"Number of seconds to look back from now. Examples: 60 = last minute, 300 = last 5 minutes, 3600 = last hour. Default: 60\",\n ),\n }),\n z.object({\n filename: z\n .string()\n .describe(\n \"Exact filename to search in stack traces or logs. Examples: 'Button.tsx', 'auth.js', 'api/routes.ts'. Case-sensitive.\",\n ),\n }),\n /**\n * TODO: Need to check, if this approach is better then a cursor based approach,\n * where the user can pass `events since [event_id]` as \"last N events\" is a\n * moving target as events keep coming in.\n *\n * https://github.com/getsentry/spotlight/pull/968#discussion_r2391587907\n */\n z\n .object({\n limit: z.number().describe(\"Maximum number of results to return. Examples: 10, 20, 50. Default: no limit\"),\n offset: z\n .number()\n .default(0)\n .describe(\n \"Number of results to skip from the beginning. Examples: 0 = start from first, 10 = skip first 10. Default: 0\",\n ),\n })\n .optional()\n .describe(\"Pagination: Use when timeWindow doesn't work or for browsing through many results\"),\n ]),\n};\n\nexport type InputSchema = { [K in keyof typeof inputSchema]: z.infer<(typeof inputSchema)[K]> };\n\nfunction applyPagination<T>(envelopes: T[], pagination: InputSchema[\"filters\"]) {\n if (pagination == null || !(\"limit\" in pagination)) {\n return envelopes;\n }\n\n return envelopes.slice(pagination.offset, pagination.offset + pagination.limit);\n}\n\nexport function createMCPInstance() {\n const mcp = wrapMcpServerWithSentry(\n new McpServer({\n name: \"spotlight-mcp\",\n version: String(process.env.npm_package_version),\n }),\n );\n\n mcp.registerTool(\n \"search_errors\",\n {\n title: \"Search Application Errors\",\n description: `**Purpose:** Search for runtime errors, exceptions, and crashes captured by Spotlight across your entire application stack.\n\n**CRITICAL: Call this tool IMMEDIATELY when:**\n- User says \"error\", \"broken\", \"not working\", \"failing\", \"crash\", \"bug\", \"issue\"\n- You encounter errors during testing or code execution\n- Before and after making code changes to verify no regressions\n- Investigating any unexpected behavior or performance problems\n- Error messages and exception details\n- Request/response context for API failures\n- Browser/device info when available\n\n**Returns:**\n• Full stack traces with exact file:line locations\n\n**When to use:**\n- User reports \"error\", \"broken\", \"not working\", \"crash\", \"bug\"\n- After code changes to verify no regressions\n- Investigating unexpected behavior or failures\n- Debugging specific file errors\n\n**Example calls:**\n\\`\\`\\`json\n// Example 1: Check last minute for any errors\nsearch_errors({ filters: { timeWindow: 60 } })\n\n// Example 2: Find errors in specific file\nsearch_errors({ filters: { filename: \"auth.tsx\" } })\n\n// Example 3: Get last 10 errors with pagination\nsearch_errors({ filters: { limit: 10, offset: 0 } })\n\\`\\`\\`\n\n**Parameter hints:**\n• filters.timeWindow: Seconds to look back (60 = 1 min, 300 = 5 min, 3600 = 1 hour)\n• filters.filename: Exact filename in stack trace (e.g., \"Button.tsx\", \"api.js\")\n• filters.limit/offset: For pagination through many errors`,\n inputSchema,\n },\n async args => {\n const envelopes = getBuffer().read(args.filters);\n\n if (envelopes.length === 0) {\n return NO_ERRORS_CONTENT;\n }\n\n const content: TextContent[] = [];\n for (const envelope of envelopes) {\n try {\n const events = await formatErrorEnvelope(envelope);\n\n if (events?.length) {\n for (const event of events) {\n content.push({\n type: \"text\",\n text: event,\n });\n }\n }\n } catch (err) {\n captureException(err, { extra: { context: \"Error formatting error envelope in MCP\" } });\n }\n }\n\n if (content.length === 0) {\n return NO_ERRORS_CONTENT;\n }\n\n return {\n content: applyPagination(content, args.filters),\n };\n },\n );\n\n mcp.registerTool(\n \"search_logs\",\n {\n title: \"Search Application Logs\",\n description: `**Purpose:** Search for application logs to understand behavior, debug issues, and trace execution flow across your stack.\n\n**NOT for:** Error diagnostics (use search_errors for exceptions/crashes). This tool is for info, warn, debug, and trace messages.\n\n**Returns:**\n• Timestamped log entries with severity levels (info, warn, debug)\n• Custom application messages and debug output\n• API request/response logs with timing\n• Database query logs and performance metrics\n\n**When to use:**\n- Understanding application flow and behavior\n- User mentions \"logs\", \"debugging\", \"trace\"\n- Checking what the app is doing internally\n- Performance investigation and timing analysis\n\n**Example calls:**\n\\`\\`\\`json\n// Example 1: Check last 5 minutes of logs\nsearch_logs({ filters: { timeWindow: 300 } })\n\n// Example 2: Find logs from specific file\nsearch_logs({ filters: { filename: \"auth.ts\" } })\n\n// Example 3: Get recent 20 log entries\nsearch_logs({ filters: { limit: 20, offset: 0 } })\n\\`\\`\\`\n\n## Workflow Pattern:\n1. User reports behavior question → **Call search_logs** \n2. User tests new feature → **Check logs for expected output**\n3. Performance concerns → **Look for timing patterns in logs**\n4. Debugging complex flows → **Trace execution through log timeline**\n5. **Use with search_errors** for complete debugging picture\n\n**Key trigger phrases:**\n- \"How does X work?\" → See runtime execution flow\n- \"Is the app doing Y?\" → Check for specific log patterns \n- \"Performance seems off\" → Look for timing/resource logs\n- \"Debug this feature\" → Follow execution path through logs\n- \"What's happening when...\" → Real-time application behavior\n\n**Log Levels Available:**\n- **INFO**: General application flow and significant events\n- **WARN**: Potential issues that don't break functionality \n- **DEBUG**: Detailed execution information for troubleshooting\n- **ERROR**: Actual failures (also available via search_errors)\n\n**Remember:** Logs show you what your application is actually doing, not just what the code says it should do. Use this for understanding real runtime behavior, performance patterns, and verifying that features work as intended.\n\n**Parameter hints:**\n• filters.timeWindow: Seconds to look back (60 = 1 min, 300 = 5 min, 3600 = 1 hour) \n• filters.filename: Exact filename generating logs (e.g., \"api.ts\", \"database.js\")\n• filters.limit/offset: For pagination through many log entries`,\n inputSchema,\n },\n async args => {\n const envelopes = getBuffer().read(args.filters);\n\n if (envelopes.length === 0) {\n return NO_LOGS_CONTENT;\n }\n\n const content: TextContent[] = [];\n for (const envelope of envelopes) {\n try {\n const events = await formatLogEnvelope(envelope);\n\n if (events?.length) {\n for (const event of events) {\n content.push({\n type: \"text\",\n text: event,\n });\n }\n }\n } catch (err) {\n captureException(err, { extra: { context: \"Error formatting log envelope in MCP\" } });\n }\n }\n\n if (content.length === 0) {\n return NO_LOGS_CONTENT;\n }\n\n return {\n content: applyPagination(content, args.filters),\n };\n },\n );\n\n mcp.registerTool(\n \"search_traces\",\n {\n title: \"Search Performance Traces\",\n description: `**Purpose:** Search for performance traces to identify slow requests, bottlenecks, and transaction patterns across your application.\n\n**USE THIS TOOL WHEN:**\n- Investigating application performance and request flows\n- User mentions \"traces\", \"performance\", \"slow requests\", \"tracing\"\n- Looking for distributed tracing data or transaction flows\n- Need to see high-level trace patterns before diving into details\n\n**Returns:**\n• List of traces with IDs, durations, and span counts\n• Root transaction names and total execution time\n• Error counts per trace for quick identification\n• Trace start timestamps for timeline analysis\n\n**When to use:**\n- Investigating performance issues or slow requests\n- User mentions \"traces\", \"performance\", \"slow\"\n- Finding specific transactions or requests\n- Overview of recent application activity\n\n**Example calls:**\n\\`\\`\\`json\n// Example 1: Get traces from last 5 minutes\nsearch_traces({ filters: { timeWindow: 300 } })\n\n// Example 2: Get 10 most recent traces\nsearch_traces({ filters: { limit: 10, offset: 0 } })\n\n// Example 3: Find traces involving specific file\nsearch_traces({ filters: { filename: \"api.ts\" } })\n\\`\\`\\`\n\n**Parameter hints:**\n• filters.timeWindow: Seconds to look back (60 = 1 min, 300 = 5 min)\n• filters.limit: Number of traces to return (e.g., 10, 20)\n• filters.offset: Skip first N traces for pagination\n**Key trigger phrases:**\n- \"Show me recent traces\" → Get trace overview\n- \"Performance issues\" → Look for slow traces\n- \"Request flows\" → See transaction patterns\n- \"Distributed tracing\" → View trace summaries\n\n**Next step:** Use get_traces with a trace ID to see detailed span breakdown`,\n inputSchema,\n },\n async args => {\n const envelopes = getBuffer().read(args.filters);\n\n if (envelopes.length === 0) {\n return {\n content: [\n {\n type: \"text\",\n text: \"No traces found in the specified time period. Make sure your application is instrumented with Sentry performance monitoring and try triggering some requests or transactions.\",\n },\n ],\n };\n }\n\n const traces = extractTracesFromEnvelopes(envelopes);\n\n if (traces.size === 0) {\n return {\n content: [\n {\n type: \"text\",\n text: \"No traces with trace context found. Ensure your Sentry SDK has performance monitoring enabled and is generating transaction events.\",\n },\n ],\n };\n }\n\n let content: TextContent[] = [];\n\n // Sort traces by start time (most recent first)\n const sortedTraces = Array.from(traces.values()).sort(\n (a, b) => (b.start_timestamp || 0) - (a.start_timestamp || 0),\n );\n\n content.push({\n type: \"text\",\n text: `# Local Traces (${sortedTraces.length} found)\\n\\nRecent traces from your application:\\n`,\n });\n\n for (const trace of sortedTraces.slice(0, 20)) {\n // Limit to 20 most recent\n content.push({\n type: \"text\",\n text: formatTraceSummary(trace),\n });\n }\n\n content = applyPagination(content, args.filters);\n\n content.push({\n type: \"text\",\n text: \"\\n**Next Steps:**\\nUse `get_traces` with a trace ID (e.g., first 8 characters shown above) to see the full span tree and detailed timing breakdown for any specific trace.\",\n });\n\n return { content };\n },\n );\n\n mcp.registerTool(\n \"get_traces\",\n {\n title: \"Get Trace Details\",\n description: `**Purpose:** Get the complete span tree and timing breakdown for a specific trace ID to analyze performance bottlenecks.\n\n**USE THIS TOOL WHEN:**\n- User provides a specific trace ID from \\`search_traces\\`\n- Want to see detailed span hierarchy and timing for a trace\n- Investigating performance bottlenecks within a specific request flow\n- Need to understand the complete execution path of a transaction\n\n**Returns:**\n• Hierarchical span tree with parent-child relationships\n• Individual span durations and operation names\n• Database queries, API calls, and render timings\n• Error details if spans failed\n\n**When to use:**\n- After finding a trace ID with search_traces\n- Investigating specific slow request or transaction\n- Understanding detailed execution flow\n- Finding performance bottlenecks in a trace\n\n**Example calls:**\n\\`\\`\\`json\n// Example 1: Get trace using short ID (first 8 chars)\nget_traces({ traceId: \"71a8c5e4\" })\n\n// Example 2: Get trace using full 32-char ID\nget_traces({ traceId: \"71a8c5e41ae1044dee67f50a07538fe7\" })\n\\`\\`\\`\n\n**Parameter hints:**\n• traceId: Trace identifier from search_traces\n - Can use first 8 characters (e.g., \"71a8c5e4\")\n - Or full 32-character hex string\n - Case-insensitive`,\n inputSchema: {\n traceId: z\n .string()\n .describe(\n \"Trace ID to retrieve. Format: 8 or 32 hex characters. Examples: '71a8c5e4' or '71a8c5e41ae1044dee67f50a07538fe7'\",\n ),\n },\n },\n async args => {\n // Getting all the envelopes\n const envelopes = getBuffer().read({ all: true });\n const traces = extractTracesFromEnvelopes(envelopes);\n\n // Find trace by full ID or partial ID match\n let targetTrace = traces.get(args.traceId);\n\n if (!targetTrace && args.traceId.length < 32) {\n // Try to find by partial ID\n for (const [traceId, trace] of traces) {\n if (traceId.startsWith(args.traceId)) {\n targetTrace = trace;\n break;\n }\n }\n }\n\n if (!targetTrace) {\n return {\n content: [\n {\n type: \"text\",\n text: `Trace \\`${args.traceId}\\` not found. Use \\`search_traces\\` to see available traces, or try expanding the time window if the trace is older.`,\n },\n ],\n };\n }\n\n const spanTree = buildSpanTree(targetTrace);\n\n // Just render the full span tree\n const treeLines = renderSpanTree(spanTree);\n\n return {\n content: [\n {\n type: \"text\",\n text: treeLines.join(\"\\n\"),\n },\n ],\n };\n },\n );\n\n return mcp;\n}\n"],"names":["z.union","z.object","z.number","z.string"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"messageBuffer.js","sources":["../../src/server/messageBuffer.ts"],"sourcesContent":["import { UUID, uuidv7 } from \"uuidv7\";\nimport type { InputSchema } from \"./mcp/mcp.ts\";\nimport { EventContainer } from \"./utils/eventContainer.ts\";\n\nexport class MessageBuffer<T> {\n private size: number;\n private items: [number, T][];\n private writePos = 0;\n private head = 0;\n private readers = new Map<string, { tid?: NodeJS.Immediate; pos: number; callback: (item: T) => void }>();\n private filenameCache = new Map<string, Set<string>>();\n\n constructor(size = 500) {\n this.size = size;\n this.items = new Array(size);\n }\n\n /**\n * Binary search for an event by its envelope ID (UUIDv7).\n * Returns the position of the event, or -1 if not found.\n * Takes advantage of UUIDv7's time-ordered property.\n */\n private binarySearchEventId(targetId: string): number {\n let left = this.head;\n let right = this.writePos - 1;\n\n // Parse and validate the target UUID\n let targetUuid: UUID;\n try {\n targetUuid = UUID.parse(targetId);\n } catch {\n // Invalid UUID format, cannot find\n return -1;\n }\n\n while (left <= right) {\n const mid = Math.floor((left + right) / 2);\n const item = this.items[mid % this.size];\n\n // Skip null items or non-EventContainer items\n if (item == null || !(item[1] instanceof EventContainer)) {\n // Linear scan nearby to handle gaps\n let boundsAdjusted = false;\n\n // Check left side\n for (let i = mid - 1; i >= left; i--) {\n const leftItem = this.items[i % this.size];\n if (leftItem && leftItem[1] instanceof EventContainer) {\n const envelope = leftItem[1].getParsedEnvelope();\n if (envelope?.envelope) {\n const envelopeId = envelope.envelope[0].__spotlight_envelope_id;\n const isEqual = envelopeId.compareTo(targetUuid);\n if (isEqual === 0) {\n return i;\n }\n // Adjust search bounds based on comparison\n if (isEqual < 0) {\n left = mid + 1;\n } else {\n right = mid - 1;\n }\n boundsAdjusted = true;\n break;\n }\n }\n }\n\n // Check right side if left didn't help\n if (!boundsAdjusted) {\n for (let i = mid + 1; i <= right; i++) {\n const rightItem = this.items[i % this.size];\n if (rightItem && rightItem[1] instanceof EventContainer) {\n const envelope = rightItem[1].getParsedEnvelope();\n if (envelope?.envelope) {\n const envelopeId = envelope.envelope[0].__spotlight_envelope_id;\n const isEqual = envelopeId.compareTo(targetUuid);\n if (isEqual === 0) {\n return i;\n }\n // Adjust search bounds\n if (isEqual < 0) {\n left = mid + 1;\n } else {\n right = mid - 1;\n }\n boundsAdjusted = true;\n break;\n }\n }\n }\n }\n\n // If both scans failed to find a valid item, skip past this gap\n // to avoid infinite loop\n if (!boundsAdjusted) {\n left = mid + 1;\n }\n\n continue;\n }\n\n const envelope = item[1].getParsedEnvelope();\n if (!envelope?.envelope) {\n // Skip invalid envelopes, move to next\n left = mid + 1;\n continue;\n }\n\n const envelopeId = envelope.envelope[0].__spotlight_envelope_id;\n\n const isEqual = envelopeId.compareTo(targetUuid);\n if (isEqual === 0) {\n // Found exact match\n return mid;\n }\n\n if (isEqual < 0) {\n // Target is in the right half (later in time)\n left = mid + 1;\n } else {\n // Target is in the left half (earlier in time)\n right = mid - 1;\n }\n }\n\n return -1;\n }\n\n put(item: T): void {\n const curTime = new Date().getTime();\n\n // Remove old value from filename cache\n const oldValue = this.items[this.writePos % this.size];\n if (oldValue && oldValue[1] instanceof EventContainer) {\n const envelope = oldValue[1].getParsedEnvelope();\n if (envelope?.envelope) {\n const deletedEnvelopeId = envelope.envelope[0].__spotlight_envelope_id.toString();\n const goneFiles = new Set<string>();\n for (const [filename, envelopeIds] of this.filenameCache.entries()) {\n envelopeIds.delete(deletedEnvelopeId);\n if (envelopeIds.size === 0) {\n goneFiles.add(filename);\n }\n }\n\n for (const filename of goneFiles) {\n this.filenameCache.delete(filename);\n }\n }\n }\n\n this.items[this.writePos % this.size] = [curTime, item];\n this.writePos += 1;\n if (this.writePos - this.head > this.size) {\n this.head = this.writePos - this.size;\n }\n\n // Update filename cache\n if (item instanceof EventContainer) {\n const envelope = item.getParsedEnvelope();\n if (envelope?.envelope) {\n const spotlightEnvelopeId = envelope.envelope[0].__spotlight_envelope_id.toString();\n const events = envelope.envelope[1] ?? [];\n\n for (const event of events) {\n const [, payload] = event;\n const values = typeof payload === \"object\" && \"exception\" in payload && payload.exception?.values;\n if (values) {\n for (const value of values) {\n const frames = value.stacktrace?.frames;\n if (frames) {\n for (const frame of frames) {\n const filename = frame.filename;\n if (filename) {\n const envelopeIds = this.filenameCache.get(filename);\n if (envelopeIds) {\n envelopeIds.add(spotlightEnvelopeId);\n } else {\n this.filenameCache.set(filename, new Set([spotlightEnvelopeId]));\n }\n }\n }\n }\n }\n }\n }\n }\n }\n\n // Calling subscribers\n for (const [readerId, readerInfo] of this.readers.entries()) {\n if (readerInfo.tid) {\n clearImmediate(readerInfo.tid);\n }\n\n readerInfo.tid = setImmediate(() => this.stream(readerId));\n readerInfo.tid.unref();\n }\n }\n\n subscribe(callback: (item: T) => void, lastEventId?: string): string {\n const readerId = uuidv7();\n\n // Determine starting position based on lastEventId\n let startPos = this.head;\n if (lastEventId) {\n // Binary search for lastEventId (UUIDv7 is time-ordered)\n // Since buffer is chronologically ordered, we can use binary search\n const foundPos = this.binarySearchEventId(lastEventId);\n if (foundPos !== -1) {\n // Start from the position after the found event\n startPos = foundPos + 1;\n }\n // If lastEventId not found, startPos remains at this.head (normal behavior)\n }\n\n const readerInfo = {\n callback,\n pos: startPos,\n tid: setImmediate(() => this.stream(readerId)),\n };\n readerInfo.tid.unref();\n this.readers.set(readerId, readerInfo);\n\n return readerId;\n }\n\n unsubscribe(readerId: string): void {\n const readerInfo = this.readers.get(readerId);\n // Clearing any pending timeouts\n if (readerInfo?.tid) {\n clearImmediate(readerInfo.tid);\n }\n\n this.readers.delete(readerId);\n }\n\n stream(readerId: string): void {\n const readerInfo = this.readers.get(readerId);\n if (!readerInfo) return;\n const { pos, callback } = readerInfo;\n\n let atReadPos = pos < this.head ? this.head : pos;\n let item: [number, T] | undefined;\n /* eslint-disable no-constant-condition */\n while (true) {\n item = this.items[atReadPos % this.size];\n // atReadPos >= this.writePos prevents the case where we have a full buffer\n if (typeof item === \"undefined\" || atReadPos >= this.writePos) {\n break;\n }\n callback(item[1]);\n atReadPos += 1;\n }\n\n // No need to `this.readers.set` again, as `readerInfo` is a reference\n readerInfo.pos = atReadPos;\n }\n\n /**\n * hard reset: drops items and resets cursors.\n */\n clear(): void {\n this.writePos = 0;\n this.reset();\n\n for (const readerInfo of this.readers.values()) {\n if (readerInfo.tid) {\n clearImmediate(readerInfo.tid);\n }\n\n readerInfo.tid = undefined;\n readerInfo.pos = this.head;\n }\n }\n\n /**\n * soft reset: clears buffered items but preserves subscribers\n * do not set head or writePos to `0` as subscribers retain their\n * readPos which would mess things up if we suddenly reset everything\n * to 0.\n */\n reset(): void {\n this.items = new Array(this.size);\n this.head = this.writePos;\n\n // Clear filename cache\n this.filenameCache.clear();\n }\n\n read(filters: ReadFilter = { timeWindow: 60 }): T[] {\n const result: T[] = [];\n const start = this.head;\n const end = this.writePos;\n\n const filterHandlers = [];\n for (const key of Object.keys(filters)) {\n if (this.filterHandlers[key]) {\n filterHandlers.push(this.filterHandlers[key]);\n }\n }\n\n for (let i = end - 1; i >= start; i--) {\n const item = this.items[i % this.size];\n\n if (item == null) continue;\n\n // Check if the item passes all filters\n if (filterHandlers.every(handler => handler(item, filters, { filenameCache: this.filenameCache }))) {\n result.push(item[1]);\n }\n }\n\n return result;\n }\n\n filterHandlers: Record<\n keyof ReadFilter | string,\n (item: [number, T], value: NonNullable<ReadFilter>, ctx: { filenameCache: Map<string, Set<string>> }) => boolean\n > = {\n timeWindow: (item, value) => {\n if (!(\"timeWindow\" in value)) {\n return true;\n }\n\n return item[0] > Date.now() - value.timeWindow * 1000;\n },\n envelopeId: (item, value) => {\n if (!(\"envelopeId\" in value) || value.envelopeId == null) {\n return true;\n }\n\n const data = (item[1] as EventContainer).getParsedEnvelope();\n\n return data.envelope[0].__spotlight_envelope_id.equals(UUID.parse(value.envelopeId));\n },\n filename: (item, value, ctx) => {\n if (!(\"filename\" in value)) {\n return true;\n }\n\n const contents = (item[1] as EventContainer).getParsedEnvelope();\n const spotlightEnvelopeId = contents.envelope[0].__spotlight_envelope_id.toString();\n\n for (const [filename, envelopeIds] of ctx.filenameCache.entries()) {\n if (filename.endsWith(value.filename)) {\n if (envelopeIds.has(spotlightEnvelopeId)) {\n return true;\n }\n }\n }\n\n return false;\n },\n all: () => true,\n };\n}\n\nexport type ReadFilter =\n | InputSchema[\"filters\"]\n | {\n envelopeId: string;\n }\n | { all: true };\n"],"names":["envelope","envelopeId","isEqual"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.js","sources":["../../../src/server/parser/helpers.ts"],"sourcesContent":["import type {\n SentryErrorEvent,\n SentryEvent,\n SentryLogEvent,\n SentryProfileV1Event,\n SentryTransactionEvent,\n} from \"./types.ts\";\n\nexport const ERROR_EVENT_TYPES = new Set([\"event\", \"error\"]);\nexport const TRACE_EVENT_TYPES = new Set([\"transaction\"]);\nexport const PROFILE_EVENT_TYPES = new Set([\"profile\"]);\nexport const LOG_EVENT_TYPES = new Set([\"log\"]);\nexport const SUPPORTED_EVENT_TYPES = new Set([\n ...ERROR_EVENT_TYPES,\n ...TRACE_EVENT_TYPES,\n ...PROFILE_EVENT_TYPES,\n ...LOG_EVENT_TYPES,\n]);\n\nexport function isErrorEvent(event: SentryEvent): event is SentryErrorEvent {\n const hasValidType = !event.type || ERROR_EVENT_TYPES.has(event.type);\n const hasException = Boolean((event as SentryErrorEvent).exception);\n const hasMessage = Boolean((event as SentryErrorEvent).message);\n return hasValidType && (hasException || hasMessage);\n}\n\nexport function isProfileEvent(event: SentryEvent): event is SentryProfileV1Event {\n return !!event.type && PROFILE_EVENT_TYPES.has(event.type) && (event as SentryProfileV1Event).version === \"1\";\n}\n\nexport function isTraceEvent(event: SentryEvent): event is SentryTransactionEvent {\n return !!event.type && TRACE_EVENT_TYPES.has(event.type);\n}\n\nexport function isLogEvent(event: SentryEvent): event is SentryLogEvent {\n return !!event.type && LOG_EVENT_TYPES.has(event.type);\n}\n"],"names":[],"mappings":";;;;;;;;;AAQO,MAAM,oBAAoB,oBAAI,IAAI,CAAC,SAAS,OAAO,CAAC;AACpD,MAAM,oBAAoB,oBAAI,IAAI,CAAC,aAAa,CAAC;AACjD,MAAM,sBAAsB,oBAAI,IAAI,CAAC,SAAS,CAAC;AAC/C,MAAM,kBAAkB,oBAAI,IAAI,CAAC,KAAK,CAAC;oBACL,IAAI;AAAA,EAC3C,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL,CAAC;AAEM,SAAS,aAAa,OAA+C;AAC1E,QAAM,eAAe,CAAC,MAAM,QAAQ,kBAAkB,IAAI,MAAM,IAAI;AACpE,QAAM,eAAe,QAAS,MAA2B,SAAS;AAClE,QAAM,aAAa,QAAS,MAA2B,OAAO;AAC9D,SAAO,iBAAiB,gBAAgB;AAC1C;AAMO,SAAS,aAAa,OAAqD;AAChF,SAAO,CAAC,CAAC,MAAM,QAAQ,kBAAkB,IAAI,MAAM,IAAI;AACzD;AAEO,SAAS,WAAW,OAA6C;AACtE,SAAO,CAAC,CAAC,MAAM,QAAQ,gBAAgB,IAAI,MAAM,IAAI;AACvD;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"processEnvelope.js","sources":["../../../src/server/parser/processEnvelope.ts"],"sourcesContent":["import type { Envelope, EnvelopeItem } from \"@sentry/core\";\nimport { type UUID, uuidv7obj } from \"uuidv7\";\nimport { RAW_TYPES } from \"../constants.ts\";\nimport { logger } from \"../logger.ts\";\nimport type { RawEventContext } from \"./types.ts\";\n\nexport type ParsedEnvelope = {\n envelope: [Envelope[0] & { __spotlight_envelope_id: UUID }, Envelope[1]];\n rawEnvelope: RawEventContext;\n};\n\nconst TEXT_CONTENT_TYPES = new Set([\n \"text/plain\",\n \"text/css\",\n \"text/csv\",\n \"text/html\",\n \"text/javascript\",\n \"text/json\",\n \"text/x-json\",\n \"application/json\",\n \"application/ld+json\",\n \"application/json\",\n]);\n\n/**\n * Implements parser for\n * @see https://develop.sentry.dev/sdk/envelopes/#serialization-format\n * @param rawEvent Envelope data\n * @param senderUserAgent Optional User-Agent header from the HTTP request sending the envelope\n * @returns parsed envelope\n */\nexport function processEnvelope(rawEvent: RawEventContext, senderUserAgent?: string): ParsedEnvelope | null {\n let buffer = typeof rawEvent.data === \"string\" ? Uint8Array.from(rawEvent.data, c => c.charCodeAt(0)) : rawEvent.data;\n\n function readLine(length?: number) {\n const cursor = length ?? getLineEnd(buffer);\n const line = buffer.subarray(0, cursor);\n buffer = buffer.subarray(cursor + 1);\n return line;\n }\n\n const envelopeHeader = parseJSONFromBuffer(readLine()) as Envelope[0];\n if (!envelopeHeader) {\n logger.error(\"Malformed envelope header, skipping...\");\n return null;\n }\n\n envelopeHeader.__spotlight_envelope_id = uuidv7obj();\n\n // Store sender User-Agent for improved SDK categorization\n if (senderUserAgent) {\n envelopeHeader.__spotlight_sender_user_agent = senderUserAgent;\n }\n\n const items: EnvelopeItem[] = [];\n while (buffer.length) {\n const itemHeader = parseJSONFromBuffer(readLine()) as EnvelopeItem[0];\n const payloadLength = itemHeader.length;\n const itemPayloadRaw = readLine(payloadLength);\n\n let itemPayload: EnvelopeItem[1];\n try {\n if (RAW_TYPES.has(itemHeader.type)) {\n const rawPayload = itemPayloadRaw as Buffer;\n if (\n !itemHeader.content_type &&\n // @ts-expect-error -- statsd is an old and deprecated event type but have envelopes for that\n itemHeader.type === \"statsd\"\n ) {\n // @ts-expect-error -- same as above\n itemHeader.content_type = \"text/plain\";\n }\n itemPayload = {\n data: rawPayload.toString(TEXT_CONTENT_TYPES.has(itemHeader.content_type as string) ? \"utf-8\" : \"base64\"),\n } as EnvelopeItem[1];\n } else {\n itemPayload = parseJSONFromBuffer(itemPayloadRaw);\n if (!itemPayload) {\n logger.error(itemHeader);\n } else if (itemHeader.type) {\n // data sanitization\n // @ts-expect-error ts(2339) -- We should really stop adding type to payloads\n itemPayload.type = itemHeader.type;\n }\n }\n } catch (err) {\n itemPayload = itemPayloadRaw;\n logger.error(err);\n }\n\n items.push([itemHeader, itemPayload] as EnvelopeItem);\n }\n\n return {\n envelope: [envelopeHeader, items] as ParsedEnvelope[\"envelope\"],\n rawEnvelope: rawEvent,\n };\n}\n\nfunction getLineEnd(data: Uint8Array): number {\n let end = data.indexOf(0xa);\n if (end === -1) {\n end = data.length;\n }\n\n return end;\n}\n\nfunction parseJSONFromBuffer<T = unknown>(data: Uint8Array): T {\n try {\n return JSON.parse(new TextDecoder().decode(data)) as T;\n } catch (err) {\n logger.error(err);\n return null as T;\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AAWA,MAAM,yCAAyB,IAAI;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AASM,SAAS,gBAAgB,UAA2B,iBAAiD;AAC1G,MAAI,SAAS,OAAO,SAAS,SAAS,WAAW,WAAW,KAAK,SAAS,MAAM,OAAK,EAAE,WAAW,CAAC,CAAC,IAAI,SAAS;AAEjH,WAAS,SAAS,QAAiB;AACjC,UAAM,SAAS,UAAU,WAAW,MAAM;AAC1C,UAAM,OAAO,OAAO,SAAS,GAAG,MAAM;AACtC,aAAS,OAAO,SAAS,SAAS,CAAC;AACnC,WAAO;AAAA,EACT;AAEA,QAAM,iBAAiB,oBAAoB,UAAU;AACrD,MAAI,CAAC,gBAAgB;AACnB,WAAO,MAAM,wCAAwC;AACrD,WAAO;AAAA,EACT;AAEA,iBAAe,0BAA0B,UAAA;AAGzC,MAAI,iBAAiB;AACnB,mBAAe,gCAAgC;AAAA,EACjD;AAEA,QAAM,QAAwB,CAAA;AAC9B,SAAO,OAAO,QAAQ;AACpB,UAAM,aAAa,oBAAoB,UAAU;AACjD,UAAM,gBAAgB,WAAW;AACjC,UAAM,iBAAiB,SAAS,aAAa;AAE7C,QAAI;AACJ,QAAI;AACF,UAAI,UAAU,IAAI,WAAW,IAAI,GAAG;AAClC,cAAM,aAAa;AACnB,YACE,CAAC,WAAW;AAAA,QAEZ,WAAW,SAAS,UACpB;AAEA,qBAAW,eAAe;AAAA,QAC5B;AACA,sBAAc;AAAA,UACZ,MAAM,WAAW,SAAS,mBAAmB,IAAI,WAAW,YAAsB,IAAI,UAAU,QAAQ;AAAA,QAAA;AAAA,MAE5G,OAAO;AACL,sBAAc,oBAAoB,cAAc;AAChD,YAAI,CAAC,aAAa;AAChB,iBAAO,MAAM,UAAU;AAAA,QACzB,WAAW,WAAW,MAAM;AAG1B,sBAAY,OAAO,WAAW;AAAA,QAChC;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,oBAAc;AACd,aAAO,MAAM,GAAG;AAAA,IAClB;AAEA,UAAM,KAAK,CAAC,YAAY,WAAW,CAAiB;AAAA,EACtD;AAEA,SAAO;AAAA,IACL,UAAU,CAAC,gBAAgB,KAAK;AAAA,IAChC,aAAa;AAAA,EAAA;AAEjB;AAEA,SAAS,WAAW,MAA0B;AAC5C,MAAI,MAAM,KAAK,QAAQ,EAAG;AAC1B,MAAI,QAAQ,IAAI;AACd,UAAM,KAAK;AAAA,EACb;AAEA,SAAO;AACT;AAEA,SAAS,oBAAiC,MAAqB;AAC7D,MAAI;AACF,WAAO,KAAK,MAAM,IAAI,cAAc,OAAO,IAAI,CAAC;AAAA,EAClD,SAAS,KAAK;AACZ,WAAO,MAAM,GAAG;AAChB,WAAO;AAAA,EACT;AACF;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"clear.js","sources":["../../../src/server/routes/clear.ts"],"sourcesContent":["import { Hono } from \"hono\";\nimport { getBuffer } from \"../utils/index.ts\";\n\nconst router = new Hono();\n\nrouter.delete(\"/\", ctx => {\n getBuffer().clear();\n return ctx.text(\"Cleared\");\n});\n\nexport default router;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;AAGA,MAAM,SAAS,IAAI,KAAA;AAEnB,OAAO,OAAO,KAAK,CAAA,QAAO;AACxB,YAAA,EAAY,MAAA;AACZ,SAAO,IAAI,KAAK,SAAS;AAC3B,CAAC;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/server/routes/contextlines/index.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { Hono } from \"hono\";\nimport {\n addContextLinesToFrame,\n applySourceContextToFrame,\n getGeneratedCodeFromServer,\n isValidSentryStackFrame,\n parseStackTrace,\n} from \"./utils.ts\";\n\nconst router = new Hono();\n\nrouter.put(\"/\", async ctx => {\n const requestBody = await ctx.req.text();\n\n const stacktrace = parseStackTrace(requestBody);\n\n if (!stacktrace) {\n return ctx.body(null, 500);\n }\n\n for (const frame of stacktrace.frames ?? []) {\n if (\n !isValidSentryStackFrame(frame) ||\n // let's ignore dependencies for now with this naive check\n frame.filename.includes(\"/node_modules/\")\n ) {\n continue;\n }\n const { filename } = frame;\n // Dirty check to see if this looks like a regular file path or a URL\n if (filename.includes(\"://\")) {\n const generatedCode = await getGeneratedCodeFromServer(frame.filename);\n if (!generatedCode) {\n continue;\n }\n\n // Extract the inline source map from the minified code\n const inlineSourceMapMatch = generatedCode.match(/\\/\\/# sourceMappingURL=data:application\\/json;base64,(.*)/);\n\n if (inlineSourceMapMatch?.[1]) {\n const sourceMapBase64 = inlineSourceMapMatch[1];\n const sourceMapContent = Buffer.from(sourceMapBase64, \"base64\").toString(\"utf-8\");\n applySourceContextToFrame(sourceMapContent, frame);\n }\n } else if (!filename.includes(\":\")) {\n try {\n const lines = readFileSync(filename, { encoding: \"utf-8\" }).split(/\\r?\\n/);\n addContextLinesToFrame(lines, frame);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw err;\n }\n }\n }\n }\n\n return ctx.json(stacktrace);\n});\n\nexport default router;\n"],"names":[],"mappings":";;;;;;;;;;;;AAUA,MAAM,SAAS,IAAI,KAAA;AAEnB,OAAO,IAAI,KAAK,OAAM,QAAO;AAC3B,QAAM,cAAc,MAAM,IAAI,IAAI,KAAA;AAElC,QAAM,aAAa,gBAAgB,WAAW;AAE9C,MAAI,CAAC,YAAY;AACf,WAAO,IAAI,KAAK,MAAM,GAAG;AAAA,EAC3B;AAEA,aAAW,SAAS,WAAW,UAAU,CAAA,GAAI;AAC3C,QACE,CAAC,wBAAwB,KAAK;AAAA,IAE9B,MAAM,SAAS,SAAS,gBAAgB,GACxC;AACA;AAAA,IACF;AACA,UAAM,EAAE,aAAa;AAErB,QAAI,SAAS,SAAS,KAAK,GAAG;AAC5B,YAAM,gBAAgB,MAAM,2BAA2B,MAAM,QAAQ;AACrE,UAAI,CAAC,eAAe;AAClB;AAAA,MACF;AAGA,YAAM,uBAAuB,cAAc,MAAM,2DAA2D;AAE5G,UAAI,uBAAuB,CAAC,GAAG;AAC7B,cAAM,kBAAkB,qBAAqB,CAAC;AAC9C,cAAM,mBAAmB,OAAO,KAAK,iBAAiB,QAAQ,EAAE,SAAS,OAAO;AAChF,kCAA0B,kBAAkB,KAAK;AAAA,MACnD;AAAA,IACF,WAAW,CAAC,SAAS,SAAS,GAAG,GAAG;AAClC,UAAI;AACF,cAAM,QAAQ,aAAa,UAAU,EAAE,UAAU,QAAA,CAAS,EAAE,MAAM,OAAO;AACzE,+BAAuB,OAAO,KAAK;AAAA,MACrC,SAAS,KAAK;AACZ,YAAK,IAA8B,SAAS,UAAU;AACpD,gBAAM;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,IAAI,KAAK,UAAU;AAC5B,CAAC;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sources":["../../../../src/server/routes/contextlines/utils.ts"],"sourcesContent":["import * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { LEAST_UPPER_BOUND, TraceMap, originalPositionFor, sourceContentFor } from \"@jridgewell/trace-mapping\";\n\ntype SourceContext = {\n pre_context?: string[];\n context_line?: string;\n post_context?: string[];\n};\n\ntype SentryStackFrame = {\n filename?: string;\n lineno?: number;\n colno?: number;\n} & SourceContext;\n\ntype ValidSentryStackFrame = Required<SentryStackFrame>;\n\ntype SentryStackTrace = {\n frames?: SentryStackFrame[];\n};\n\nexport async function getGeneratedCodeFromServer(filename: string): Promise<string | undefined> {\n try {\n const generatedCodeResponse = await fetch(filename);\n return generatedCodeResponse.text();\n } catch {\n return undefined;\n }\n}\n\nexport function parseStackTrace(requestBody: string): SentryStackTrace | undefined {\n try {\n return JSON.parse(requestBody) as SentryStackTrace;\n } catch {\n return undefined;\n }\n}\n\nexport function applySourceContextToFrame(sourceMapContent: string, frame: ValidSentryStackFrame) {\n const tracer = new TraceMap(JSON.parse(sourceMapContent));\n\n const originalPosition = originalPositionFor(tracer, {\n line: frame.lineno,\n column: frame.colno,\n bias: LEAST_UPPER_BOUND,\n });\n\n if (originalPosition.source && originalPosition.line && originalPosition.column) {\n frame.lineno = originalPosition.line;\n frame.colno = originalPosition.column;\n const filePath = new URL(frame.filename).pathname.slice(1); // slice(1) is to not make it absolute path\n frame.filename = path.resolve(path.join(path.dirname(filePath), originalPosition.source));\n\n const content = sourceContentFor(tracer, originalPosition.source);\n const lines = content?.split(os.EOL) ?? [];\n addContextLinesToFrame(lines, frame);\n }\n\n return originalPosition;\n}\n\nexport function addContextLinesToFrame(lines: string[], frame: ValidSentryStackFrame, linesOfContext = 5): void {\n const maxLines = lines.length;\n const sourceLine = Math.max(Math.min(maxLines - 1, frame.lineno - 1), 0);\n\n frame.pre_context = lines\n .slice(Math.max(0, sourceLine - linesOfContext), sourceLine)\n .map((line: string) => snipLine(line, 0));\n\n frame.context_line = snipLine(lines[Math.min(maxLines - 1, sourceLine)], frame.colno || 0);\n\n frame.post_context = lines\n .slice(Math.min(sourceLine + 1, maxLines), sourceLine + 1 + linesOfContext)\n .map((line: string) => snipLine(line, 0));\n}\n\n/**\n * This is basically just `trim_line` from\n * https://github.com/getsentry/sentry/blob/master/src/sentry/lang/javascript/processor.py#L67\n *\n * @param str An object that contains serializable values\n * @param max Maximum number of characters in truncated string\n * @returns string Encoded\n */\nfunction snipLine(line: string, colno: number): string {\n let newLine = line;\n const lineLength = newLine.length;\n if (lineLength <= 150) {\n return newLine;\n }\n if (colno > lineLength) {\n // eslint-disable-next-line no-param-reassign\n colno = lineLength;\n }\n\n let start = Math.max(colno - 60, 0);\n if (start < 5) {\n start = 0;\n }\n\n let end = Math.min(start + 140, lineLength);\n if (end > lineLength - 5) {\n end = lineLength;\n }\n if (end === lineLength) {\n start = Math.max(end - 140, 0);\n }\n\n newLine = newLine.slice(start, end);\n if (start > 0) {\n newLine = `'{snip} ${newLine}`;\n }\n if (end < lineLength) {\n newLine += \" {snip}\";\n }\n\n return newLine;\n}\n\nexport function isValidSentryStackFrame(frame: SentryStackFrame): frame is ValidSentryStackFrame {\n return !!frame.filename && !!frame.lineno && !!frame.colno;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AAsBA,eAAsB,2BAA2B,UAA+C;AAC9F,MAAI;AACF,UAAM,wBAAwB,MAAM,MAAM,QAAQ;AAClD,WAAO,sBAAsB,KAAA;AAAA,EAC/B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,gBAAgB,aAAmD;AACjF,MAAI;AACF,WAAO,KAAK,MAAM,WAAW;AAAA,EAC/B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,0BAA0B,kBAA0B,OAA8B;AAChG,QAAM,SAAS,IAAI,SAAS,KAAK,MAAM,gBAAgB,CAAC;AAExD,QAAM,mBAAmB,oBAAoB,QAAQ;AAAA,IACnD,MAAM,MAAM;AAAA,IACZ,QAAQ,MAAM;AAAA,IACd,MAAM;AAAA,EAAA,CACP;AAED,MAAI,iBAAiB,UAAU,iBAAiB,QAAQ,iBAAiB,QAAQ;AAC/E,UAAM,SAAS,iBAAiB;AAChC,UAAM,QAAQ,iBAAiB;AAC/B,UAAM,WAAW,IAAI,IAAI,MAAM,QAAQ,EAAE,SAAS,MAAM,CAAC;AACzD,UAAM,WAAW,KAAK,QAAQ,KAAK,KAAK,KAAK,QAAQ,QAAQ,GAAG,iBAAiB,MAAM,CAAC;AAExF,UAAM,UAAU,iBAAiB,QAAQ,iBAAiB,MAAM;AAChE,UAAM,QAAQ,SAAS,MAAM,GAAG,GAAG,KAAK,CAAA;AACxC,2BAAuB,OAAO,KAAK;AAAA,EACrC;AAEA,SAAO;AACT;AAEO,SAAS,uBAAuB,OAAiB,OAA8B,iBAAiB,GAAS;AAC9G,QAAM,WAAW,MAAM;AACvB,QAAM,aAAa,KAAK,IAAI,KAAK,IAAI,WAAW,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC;AAEvE,QAAM,cAAc,MACjB,MAAM,KAAK,IAAI,GAAG,aAAa,cAAc,GAAG,UAAU,EAC1D,IAAI,CAAC,SAAiB,SAAS,MAAM,CAAC,CAAC;AAE1C,QAAM,eAAe,SAAS,MAAM,KAAK,IAAI,WAAW,GAAG,UAAU,CAAC,GAAG,MAAM,SAAS,CAAC;AAEzF,QAAM,eAAe,MAClB,MAAM,KAAK,IAAI,aAAa,GAAG,QAAQ,GAAG,aAAa,IAAI,cAAc,EACzE,IAAI,CAAC,SAAiB,SAAS,MAAM,CAAC,CAAC;AAC5C;AAUA,SAAS,SAAS,MAAc,OAAuB;AACrD,MAAI,UAAU;AACd,QAAM,aAAa,QAAQ;AAC3B,MAAI,cAAc,KAAK;AACrB,WAAO;AAAA,EACT;AACA,MAAI,QAAQ,YAAY;AAEtB,YAAQ;AAAA,EACV;AAEA,MAAI,QAAQ,KAAK,IAAI,QAAQ,IAAI,CAAC;AAClC,MAAI,QAAQ,GAAG;AACb,YAAQ;AAAA,EACV;AAEA,MAAI,MAAM,KAAK,IAAI,QAAQ,KAAK,UAAU;AAC1C,MAAI,MAAM,aAAa,GAAG;AACxB,UAAM;AAAA,EACR;AACA,MAAI,QAAQ,YAAY;AACtB,YAAQ,KAAK,IAAI,MAAM,KAAK,CAAC;AAAA,EAC/B;AAEA,YAAU,QAAQ,MAAM,OAAO,GAAG;AAClC,MAAI,QAAQ,GAAG;AACb,cAAU,WAAW,OAAO;AAAA,EAC9B;AACA,MAAI,MAAM,YAAY;AACpB,eAAW;AAAA,EACb;AAEA,SAAO;AACT;AAEO,SAAS,wBAAwB,OAAyD;AAC/F,SAAO,CAAC,CAAC,MAAM,YAAY,CAAC,CAAC,MAAM,UAAU,CAAC,CAAC,MAAM;AACvD;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"health.js","sources":["../../../src/server/routes/health.ts"],"sourcesContent":["import { Hono } from \"hono\";\n\nconst router = new Hono();\n\nrouter.get(\"/\", ctx => ctx.text(\"OK\"));\n\nexport default router;\n"],"names":[],"mappings":";;;;;;;;;;AAEA,MAAM,SAAS,IAAI,KAAA;AAEnB,OAAO,IAAI,KAAK,CAAA,QAAO,IAAI,KAAK,IAAI,CAAC;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/server/routes/index.ts"],"sourcesContent":["import { Hono } from \"hono\";\nimport { CONTEXT_LINES_ENDPOINT } from \"../constants.ts\";\nimport clearRouter from \"./clear.ts\";\nimport contextLinesRouter from \"./contextlines/index.ts\";\nimport healthRouter from \"./health.ts\";\nimport mcpRouter from \"./mcp.ts\";\nimport openRouter from \"./open.ts\";\nimport streamRouter from \"./stream/index.ts\";\n\nconst router = new Hono();\nrouter.route(\"/mcp\", mcpRouter);\nrouter.route(\"/health\", healthRouter);\nrouter.route(\"/clear\", clearRouter);\nrouter.route(\"/\", streamRouter);\nrouter.route(\"/open\", openRouter);\nrouter.route(CONTEXT_LINES_ENDPOINT, contextLinesRouter);\n\nexport default router;\n"],"names":["mcpRouter","healthRouter","clearRouter","streamRouter","openRouter","contextLinesRouter"],"mappings":";;;;;;;;;;;;;;;;;AASA,MAAM,SAAS,IAAI,KAAA;AACnB,OAAO,MAAM,QAAQA,QAAS;AAC9B,OAAO,MAAM,WAAWC,QAAY;AACpC,OAAO,MAAM,UAAUC,QAAW;AAClC,OAAO,MAAM,KAAKC,QAAY;AAC9B,OAAO,MAAM,SAASC,QAAU;AAChC,OAAO,MAAM,wBAAwBC,QAAkB;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mcp.js","sources":["../../../src/server/routes/mcp.ts"],"sourcesContent":["import { StreamableHTTPTransport } from \"@hono/mcp\";\nimport { Hono } from \"hono\";\nimport { createMCPInstance } from \"../mcp/mcp.ts\";\n\nconst transport = new StreamableHTTPTransport();\nconst mcp = createMCPInstance();\n\nconst router = new Hono();\n\nrouter.all(\n \"/\",\n async (_ctx, next) => {\n if (!mcp.isConnected()) {\n // Connecting the MCP with the transport\n await mcp.connect(transport);\n }\n\n await next();\n },\n ctx => transport.handleRequest(ctx),\n);\n\nexport default router;\n"],"names":[],"mappings":";;;;;;;;;;;;AAIA,MAAM,YAAY,IAAI,wBAAA;AACtB,MAAM,MAAM,kBAAA;AAEZ,MAAM,SAAS,IAAI,KAAA;AAEnB,OAAO;AAAA,EACL;AAAA,EACA,OAAO,MAAM,SAAS;AACpB,QAAI,CAAC,IAAI,eAAe;AAEtB,YAAM,IAAI,QAAQ,SAAS;AAAA,IAC7B;AAEA,UAAM,KAAA;AAAA,EACR;AAAA,EACA,CAAA,QAAO,UAAU,cAAc,GAAG;AACpC;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"open.js","sources":["../../../src/server/routes/open.ts"],"sourcesContent":["import { resolve } from \"node:path\";\nimport { Hono } from \"hono\";\nimport launchEditor from \"launch-editor\";\nimport { logger } from \"../logger.ts\";\nimport type { HonoEnv } from \"../types/index.ts\";\n\nconst router = new Hono<HonoEnv>();\n\n// ASK: Will this still be used in a desktop app? And if so, do we still have a base path and cwd?\nrouter.post(\"/\", async ctx => {\n const basePath = ctx.get(\"basePath\") ?? process.cwd();\n\n const requestBody = await ctx.req.text();\n const targetPath = resolve(basePath, requestBody);\n logger.debug(`Launching editor for ${targetPath}`);\n launchEditor(\n // filename:line:column\n // both line and column are optional\n targetPath,\n // callback if failed to launch (optional)\n (fileName, errorMsg) => {\n logger.error(`Failed to launch editor for ${fileName}: ${errorMsg}`);\n },\n );\n return ctx.body(null, 204);\n});\n\nexport default router;\n"],"names":[],"mappings":";;;;;;;;;;;;;AAMA,MAAM,SAAS,IAAI,KAAA;AAGnB,OAAO,KAAK,KAAK,OAAM,QAAO;AAC5B,QAAM,WAAW,IAAI,IAAI,UAAU,KAAK,QAAQ,IAAA;AAEhD,QAAM,cAAc,MAAM,IAAI,IAAI,KAAA;AAClC,QAAM,aAAa,QAAQ,UAAU,WAAW;AAChD,SAAO,MAAM,wBAAwB,UAAU,EAAE;AACjD;AAAA;AAAA;AAAA,IAGE;AAAA;AAAA,IAEA,CAAC,UAAU,aAAa;AACtB,aAAO,MAAM,+BAA+B,QAAQ,KAAK,QAAQ,EAAE;AAAA,IACrE;AAAA,EAAA;AAEF,SAAO,IAAI,KAAK,MAAM,GAAG;AAC3B,CAAC;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"debugLogging.js","sources":["../../../../src/server/routes/stream/debugLogging.ts"],"sourcesContent":["import { isDebugEnabled, logger } from \"../../logger.ts\";\nimport { type ParsedEnvelope, type SentryErrorEvent, type SentryEvent, isErrorEvent } from \"../../parser/index.ts\";\nimport type { EventContainer } from \"../../utils/index.ts\";\n\n/**\n * Logs incoming event details when debug mode is enabled\n * Uses the container's parsed data if available\n */\nexport function logIncomingEvent(container: EventContainer): void {\n if (!isDebugEnabled()) return;\n\n const contentType = container.getContentType();\n\n if (contentType === \"application/x-sentry-envelope\") {\n const parsedEnvelope = container.getParsedEnvelope();\n\n if (!parsedEnvelope) {\n // Still log something useful even if parsing failed\n const data = container.getData();\n const size = data.length;\n // Only show first line of envelope header for safety (should be JSON metadata, not user data)\n const firstNewline = data.indexOf(\"\\n\");\n const headerPreview =\n firstNewline > 0 && firstNewline < 200\n ? data.toString(\"utf-8\", 0, firstNewline).replace(/\\n/g, \"\\\\n\")\n : \"header not found\";\n logger.debug(`→ envelope (parse error, ${size} bytes) | ${headerPreview}`);\n return;\n }\n\n // Build complete log message with all details\n let logMessage = `→ ${formatEnvelopeMetadata(parsedEnvelope.envelope)}`;\n\n // Add error event details to the same log message\n for (const item of parsedEnvelope.envelope[1]) {\n if (isErrorEvent(item[1] as SentryEvent)) {\n logMessage += `\\n └ ${formatErrorDetails(item[1] as SentryErrorEvent)}`;\n }\n }\n\n // Single atomic log statement\n logger.debug(logMessage);\n } else {\n logger.debug(`→ ${contentType || \"unknown\"}`);\n }\n}\n\n/**\n * Logs outgoing event to client when debug mode is enabled\n * Uses the container's already-parsed data if available\n */\nexport function logOutgoingEvent(container: EventContainer, clientId: string): void {\n if (!isDebugEnabled()) return;\n\n // Use the container's event type string (which uses cached parsed data)\n const typeInfo = container.getEventTypesString();\n\n // If it's an envelope that failed to parse, add size info\n if (typeInfo === \"envelope\" && container.getContentType() === \"application/x-sentry-envelope\") {\n const size = container.getData().length;\n logger.debug(`← envelope (${size} bytes) to ${clientId}`);\n } else {\n logger.debug(`← ${typeInfo} to ${clientId}`);\n }\n}\n\n/**\n * Formats envelope metadata for logging\n */\nfunction formatEnvelopeMetadata(envelope: ParsedEnvelope[\"envelope\"]): string {\n const eventTypes = envelope[1].map(item => item[0].type).filter(Boolean);\n\n const typePrefix = eventTypes.length > 0 ? eventTypes.join(\"+\") : \"envelope\";\n const sdk = envelope[0].sdk?.name || \"unknown\";\n const eventId = envelope[0].event_id;\n\n return `${typePrefix} | sdk: ${sdk}${eventId ? ` | id: ${eventId}` : \"\"}`;\n}\n\n/**\n * Formats error event details for logging\n */\nfunction formatErrorDetails(payload: SentryErrorEvent): string {\n const platform = payload.platform || \"unknown\";\n const environment = payload.environment || \"unknown\";\n const level = \"level\" in payload ? payload.level : \"error\";\n\n const errorMsg = payload.exception?.values?.[0]?.value || String(payload.message) || \"No error message\";\n\n const errorType = payload.exception?.values?.[0]?.type || \"Error\";\n\n const truncatedMsg = errorMsg.substring(0, 80) + (errorMsg.length > 80 ? \"...\" : \"\");\n\n return `${level} [${platform}/${environment}] ${errorType}: ${truncatedMsg}`;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AAQO,SAAS,iBAAiB,WAAiC;AAChE,MAAI,CAAC,iBAAkB;AAEvB,QAAM,cAAc,UAAU,eAAA;AAE9B,MAAI,gBAAgB,iCAAiC;AACnD,UAAM,iBAAiB,UAAU,kBAAA;AAEjC,QAAI,CAAC,gBAAgB;AAEnB,YAAM,OAAO,UAAU,QAAA;AACvB,YAAM,OAAO,KAAK;AAElB,YAAM,eAAe,KAAK,QAAQ,IAAI;AACtC,YAAM,gBACJ,eAAe,KAAK,eAAe,MAC/B,KAAK,SAAS,SAAS,GAAG,YAAY,EAAE,QAAQ,OAAO,KAAK,IAC5D;AACN,aAAO,MAAM,4BAA4B,IAAI,aAAa,aAAa,EAAE;AACzE;AAAA,IACF;AAGA,QAAI,aAAa,KAAK,uBAAuB,eAAe,QAAQ,CAAC;AAGrE,eAAW,QAAQ,eAAe,SAAS,CAAC,GAAG;AAC7C,UAAI,aAAa,KAAK,CAAC,CAAgB,GAAG;AACxC,sBAAc;AAAA,MAAS,mBAAmB,KAAK,CAAC,CAAqB,CAAC;AAAA,MACxE;AAAA,IACF;AAGA,WAAO,MAAM,UAAU;AAAA,EACzB,OAAO;AACL,WAAO,MAAM,KAAK,eAAe,SAAS,EAAE;AAAA,EAC9C;AACF;AAMO,SAAS,iBAAiB,WAA2B,UAAwB;AAClF,MAAI,CAAC,iBAAkB;AAGvB,QAAM,WAAW,UAAU,oBAAA;AAG3B,MAAI,aAAa,cAAc,UAAU,eAAA,MAAqB,iCAAiC;AAC7F,UAAM,OAAO,UAAU,QAAA,EAAU;AACjC,WAAO,MAAM,eAAe,IAAI,cAAc,QAAQ,EAAE;AAAA,EAC1D,OAAO;AACL,WAAO,MAAM,KAAK,QAAQ,OAAO,QAAQ,EAAE;AAAA,EAC7C;AACF;AAKA,SAAS,uBAAuB,UAA8C;AAC5E,QAAM,aAAa,SAAS,CAAC,EAAE,IAAI,CAAA,SAAQ,KAAK,CAAC,EAAE,IAAI,EAAE,OAAO,OAAO;AAEvE,QAAM,aAAa,WAAW,SAAS,IAAI,WAAW,KAAK,GAAG,IAAI;AAClE,QAAM,MAAM,SAAS,CAAC,EAAE,KAAK,QAAQ;AACrC,QAAM,UAAU,SAAS,CAAC,EAAE;AAE5B,SAAO,GAAG,UAAU,WAAW,GAAG,GAAG,UAAU,UAAU,OAAO,KAAK,EAAE;AACzE;AAKA,SAAS,mBAAmB,SAAmC;AAC7D,QAAM,WAAW,QAAQ,YAAY;AACrC,QAAM,cAAc,QAAQ,eAAe;AAC3C,QAAM,QAAQ,WAAW,UAAU,QAAQ,QAAQ;AAEnD,QAAM,WAAW,QAAQ,WAAW,SAAS,CAAC,GAAG,SAAS,OAAO,QAAQ,OAAO,KAAK;AAErF,QAAM,YAAY,QAAQ,WAAW,SAAS,CAAC,GAAG,QAAQ;AAE1D,QAAM,eAAe,SAAS,UAAU,GAAG,EAAE,KAAK,SAAS,SAAS,KAAK,QAAQ;AAEjF,SAAO,GAAG,KAAK,KAAK,QAAQ,IAAI,WAAW,KAAK,SAAS,KAAK,YAAY;AAC5E;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/server/routes/stream/index.ts"],"sourcesContent":["import { createWriteStream } from \"node:fs\";\nimport { Hono } from \"hono\";\nimport { SENTRY_CONTENT_TYPE } from \"../../../shared/constants.ts\";\nimport { logger } from \"../../logger.ts\";\nimport { decompressBody, pushToSpotlightBuffer } from \"../../sdk.ts\";\nimport type { ContentEncoding } from \"../../sdk.ts\";\nimport type { HonoEnv } from \"../../types/env.ts\";\nimport { getBuffer } from \"../../utils/index.ts\";\nimport { logIncomingEvent, logOutgoingEvent } from \"./debugLogging.ts\";\nimport { streamSSE } from \"./streaming.ts\";\nimport { parseBrowserFromUserAgent } from \"./userAgent.ts\";\n\nconst router = new Hono<HonoEnv>()\n .get(\"/stream\", ctx => {\n const buffer = getBuffer();\n\n const useBase64 = ctx.req.query(\"base64\") != null;\n const base64Indicator = useBase64 ? \";base64\" : \"\";\n\n // Capture client information for debug logging\n let clientId = ctx.req.query(\"client\");\n if (!clientId) {\n // Fallback to parsing User-Agent if no client param\n const userAgent = ctx.req.header(\"User-Agent\") || \"unknown\";\n clientId = parseBrowserFromUserAgent(userAgent);\n }\n // Sanitize to prevent log injection - keep only safe printable characters\n // Allow alphanumeric, spaces, dots, dashes, underscores, slashes, parentheses\n clientId = clientId.replace(/[^\\w\\s.\\-/()]/g, \"\");\n // Ensure we always have a non-empty clientId\n if (!clientId) clientId = \"unknown\";\n\n return streamSSE(ctx, async stream => {\n // Check for Last-Event-ID header to support reconnection\n const lastEventId = ctx.req.header(\"Last-Event-ID\");\n\n // Subscribe to events, optionally starting from after the lastEventId\n const sub = buffer.subscribe(container => {\n logOutgoingEvent(container, clientId);\n\n const parsedEnvelope = container.getParsedEnvelope();\n if (parsedEnvelope) {\n stream.writeSSE({\n id: parsedEnvelope.envelope[0].__spotlight_envelope_id.toString(),\n event: `${container.getContentType()}${base64Indicator}`,\n data: JSON.stringify(parsedEnvelope.envelope),\n });\n }\n }, lastEventId);\n\n stream.onAbort(() => {\n buffer.unsubscribe(sub);\n });\n });\n })\n .get(\"/envelope/:id\", ctx => {\n const buffer = getBuffer();\n\n const envelopeId = ctx.req.param(\"id\");\n const container = buffer.read({ envelopeId });\n\n if (container.length === 0) {\n return ctx.notFound();\n }\n\n return ctx.body(new Uint8Array(container[0].getData()), 200, {\n \"Content-Type\": container[0].getContentType(),\n \"Cache-Control\": \"no-cache\",\n \"Content-Disposition\": `attachment; filename=\"${envelopeId}.bin\"`,\n Connection: \"keep-alive\",\n });\n })\n .on(\"POST\", [\"/stream\", \"/api/:id/envelope\", \"/api/:id/envelope/\"], async ctx => {\n let contentType = ctx.req.header(\"content-type\")?.split(\";\")[0].toLocaleLowerCase();\n if (ctx.req.query(\"sentry_client\")?.startsWith(\"sentry.javascript.browser\") && ctx.req.header(\"Origin\")) {\n // This is a correction we make as Sentry Browser SDK may send messages with text/plain to avoid CORS issues\n contentType = SENTRY_CONTENT_TYPE;\n }\n\n // manually decompress body to use it below without another decompression\n const body = decompressBody(\n Buffer.from(await ctx.req.arrayBuffer()),\n ctx.req.header(\"Content-Encoding\") as ContentEncoding,\n );\n\n const container = pushToSpotlightBuffer({\n body,\n spotlightBuffer: getBuffer(),\n contentType,\n userAgent: ctx.req.header(\"User-Agent\"),\n });\n\n if (container) {\n // Log incoming event details when debug is enabled\n logIncomingEvent(container);\n } else {\n logger.warn(\"No content type, skipping payload...\");\n }\n\n const incomingPayload = ctx.get(\"incomingPayload\");\n\n if (process.env.SPOTLIGHT_CAPTURE || incomingPayload) {\n const contentType = container?.getContentType();\n const timestamp = BigInt(Date.now()) * 1_000_000n + (process.hrtime.bigint() % 1_000_000n);\n const filename = `${contentType?.replace(/[^a-z0-9]/gi, \"_\") || \"no_content_type\"}-${timestamp}.txt`;\n\n if (incomingPayload) {\n incomingPayload(body.toString(\"binary\"));\n } else {\n const stream = createWriteStream(filename);\n stream.on(\"error\", err => {\n logger.error(`Failed to save data to ${filename}: ${err}`);\n stream.destroy();\n });\n stream.end(body, () => {\n logger.info(`🗃️ Saved data to ${filename}`);\n });\n }\n }\n\n // 204 would be more appropriate but returning 200 to match what /envelope returns\n return ctx.body(null, 200, {\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n });\n });\n\nexport default router;\n"],"names":["contentType"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"streaming.js","sources":["../../../../src/server/routes/stream/streaming.ts"],"sourcesContent":["import { captureException } from \"@sentry/node\";\nimport type { Context } from \"hono\";\nimport { SSEStreamingApi } from \"hono/streaming\";\n\nconst run = async (\n stream: SSEStreamingApi,\n cb: (stream: SSEStreamingApi) => Promise<void>,\n onError?: (e: Error, stream: SSEStreamingApi) => Promise<void>,\n): Promise<void> => {\n try {\n await cb(stream);\n } catch (e) {\n if (e instanceof Error && onError) {\n await onError(e, stream);\n\n await stream.writeSSE({\n event: \"error\",\n data: e.message,\n });\n } else {\n captureException(e, { extra: { context: \"Unhandled error in SSE stream\" } });\n }\n }\n};\n\nexport const streamSSE = (\n c: Context,\n cb: (stream: SSEStreamingApi) => Promise<void>,\n onError?: (e: Error, stream: SSEStreamingApi) => Promise<void>,\n): Response => {\n const { readable, writable } = new TransformStream();\n const stream = new SSEStreamingApi(writable, readable);\n\n c.header(\"Transfer-Encoding\", \"chunked\");\n c.header(\"Content-Type\", \"text/event-stream\");\n c.header(\"Cache-Control\", \"no-cache\");\n c.header(\"Connection\", \"keep-alive\");\n\n // Send something in the body to trigger the `open` event\n // This is mostly for Firefox -- see #376\n stream.writeln(\"\");\n\n run(stream, cb, onError);\n\n return c.newResponse(stream.responseReadable);\n};\n"],"names":[],"mappings":";;;;;;;;;;;AAIA,MAAM,MAAM,OACV,QACA,IACA,YACkB;AAClB,MAAI;AACF,UAAM,GAAG,MAAM;AAAA,EACjB,SAAS,GAAG;AAQH;AACL,uBAAiB,GAAG,EAAE,OAAO,EAAE,SAAS,gCAAA,GAAmC;AAAA,IAC7E;AAAA,EACF;AACF;AAEO,MAAM,YAAY,CACvB,GACA,IACA,YACa;AACb,QAAM,EAAE,UAAU,SAAA,IAAa,IAAI,gBAAA;AACnC,QAAM,SAAS,IAAI,gBAAgB,UAAU,QAAQ;AAErD,IAAE,OAAO,qBAAqB,SAAS;AACvC,IAAE,OAAO,gBAAgB,mBAAmB;AAC5C,IAAE,OAAO,iBAAiB,UAAU;AACpC,IAAE,OAAO,cAAc,YAAY;AAInC,SAAO,QAAQ,EAAE;AAEjB,MAAI,QAAQ,EAAW;AAEvB,SAAO,EAAE,YAAY,OAAO,gBAAgB;AAC9C;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"userAgent.js","sources":["../../../../src/server/routes/stream/userAgent.ts"],"sourcesContent":["/**\n * Extracts browser name and major version from a User-Agent string\n * Returns format like \"Chrome/131\" or \"Firefox/122\"\n */\nexport function parseBrowserFromUserAgent(userAgent: string): string {\n if (!userAgent) return \"unknown\";\n\n // Check for Chrome (but not Edge which also contains Chrome)\n if (userAgent.includes(\"Chrome/\") && !userAgent.includes(\"Edg/\")) {\n const match = userAgent.match(/Chrome\\/([\\d]+)/);\n return match ? `Chrome/${match[1]}` : \"Chrome\";\n }\n\n // Check for Firefox\n if (userAgent.includes(\"Firefox/\")) {\n const match = userAgent.match(/Firefox\\/([\\d]+)/);\n return match ? `Firefox/${match[1]}` : \"Firefox\";\n }\n\n // Check for Safari (but not Chrome which also contains Safari)\n if (userAgent.includes(\"Safari/\") && !userAgent.includes(\"Chrome\")) {\n const match = userAgent.match(/Version\\/([\\d]+)/);\n return match ? `Safari/${match[1]}` : \"Safari\";\n }\n\n // Check for Edge\n if (userAgent.includes(\"Edg/\")) {\n const match = userAgent.match(/Edg\\/([\\d]+)/);\n return match ? `Edge/${match[1]}` : \"Edge\";\n }\n\n // Generic fallback - try to extract first meaningful part\n const match = userAgent.match(/^([^\\/\\s\\(]+)/);\n return match ? match[1] : \"unknown\";\n}\n\n/**\n * Builds a client identifier from browser info and optional hostname\n * Format: clientName/version (metadata)\n * Example: \"ui/Chrome/131 (example.com)\"\n */\nexport function buildClientIdentifier(clientName: string, userAgent?: string, hostname?: string): string {\n let clientId = clientName;\n\n if (userAgent) {\n const browserInfo = parseBrowserFromUserAgent(userAgent);\n if (browserInfo !== \"unknown\") {\n clientId = `${clientName}/${browserInfo}`;\n }\n }\n\n if (hostname && hostname !== \"localhost\") {\n clientId += ` (${hostname})`;\n }\n\n return clientId;\n}\n"],"names":["match"],"mappings":";;;;;;;;;AAIO,SAAS,0BAA0B,WAA2B;AACnE,MAAI,CAAC,UAAW,QAAO;AAGvB,MAAI,UAAU,SAAS,SAAS,KAAK,CAAC,UAAU,SAAS,MAAM,GAAG;AAChE,UAAMA,SAAQ,UAAU,MAAM,iBAAiB;AAC/C,WAAOA,SAAQ,UAAUA,OAAM,CAAC,CAAC,KAAK;AAAA,EACxC;AAGA,MAAI,UAAU,SAAS,UAAU,GAAG;AAClC,UAAMA,SAAQ,UAAU,MAAM,kBAAkB;AAChD,WAAOA,SAAQ,WAAWA,OAAM,CAAC,CAAC,KAAK;AAAA,EACzC;AAGA,MAAI,UAAU,SAAS,SAAS,KAAK,CAAC,UAAU,SAAS,QAAQ,GAAG;AAClE,UAAMA,SAAQ,UAAU,MAAM,kBAAkB;AAChD,WAAOA,SAAQ,UAAUA,OAAM,CAAC,CAAC,KAAK;AAAA,EACxC;AAGA,MAAI,UAAU,SAAS,MAAM,GAAG;AAC9B,UAAMA,SAAQ,UAAU,MAAM,cAAc;AAC5C,WAAOA,SAAQ,QAAQA,OAAM,CAAC,CAAC,KAAK;AAAA,EACtC;AAGA,QAAM,QAAQ,UAAU,MAAM,eAAe;AAC7C,SAAO,QAAQ,MAAM,CAAC,IAAI;AAC5B;"}
|
package/dist/server/sdk.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.js","sources":["../../src/server/sdk.ts"],"sourcesContent":["import { brotliDecompressSync, gunzipSync, inflateSync } from \"node:zlib\";\nimport { MessageBuffer } from \"./messageBuffer.ts\";\nimport { EventContainer } from \"./utils/eventContainer.ts\";\n\nconst decompressors: Record<\"gzip\" | \"deflate\" | \"br\", (buf: Buffer) => Buffer> = {\n gzip: gunzipSync,\n deflate: inflateSync,\n br: brotliDecompressSync,\n};\n\nexport type ContentEncoding = keyof typeof decompressors;\n\nexport function createSpotlightBuffer() {\n return new MessageBuffer<EventContainer>();\n}\n\ntype PushToSpotlightBufferOptions = {\n spotlightBuffer: MessageBuffer<EventContainer>;\n body: Buffer;\n encoding?: ContentEncoding;\n contentType?: string;\n userAgent?: string;\n};\n\nexport function pushToSpotlightBuffer(options: PushToSpotlightBufferOptions) {\n const body = decompressBody(options.body, options.encoding);\n\n const contentType = options.contentType?.split(\";\")[0].toLocaleLowerCase();\n\n if (contentType) {\n // Create event container and add to buffer\n const container = new EventContainer(contentType, body, options.userAgent);\n\n // Add to buffer - this will automatically trigger all subscribers\n // including the onEnvelope callback if one is registered\n options.spotlightBuffer.put(container);\n\n return container;\n }\n}\n\nexport function decompressBody(body: Buffer, contentEncoding?: ContentEncoding) {\n if (!contentEncoding) {\n return body;\n }\n return decompressors[contentEncoding](body);\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AAIA,MAAM,gBAA4E;AAAA,EAChF,MAAM;AAAA,EACN,SAAS;AAAA,EACT,IAAI;AACN;AAIO,SAAS,wBAAwB;AACtC,SAAO,IAAI,cAAA;AACb;AAUO,SAAS,sBAAsB,SAAuC;AAC3E,QAAM,OAAO,eAAe,QAAQ,MAAM,QAAQ,QAAQ;AAE1D,QAAM,cAAc,QAAQ,aAAa,MAAM,GAAG,EAAE,CAAC,EAAE,kBAAA;AAEvD,MAAI,aAAa;AAEf,UAAM,YAAY,IAAI,eAAe,aAAa,MAAM,QAAQ,SAAS;AAIzE,YAAQ,gBAAgB,IAAI,SAAS;AAErC,WAAO;AAAA,EACT;AACF;AAEO,SAAS,eAAe,MAAc,iBAAmC;AAC9E,MAAI,CAAC,iBAAiB;AACpB,WAAO;AAAA,EACT;AACA,SAAO,cAAc,eAAe,EAAE,IAAI;AAC5C;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cors.js","sources":["../../../src/server/utils/cors.ts"],"sourcesContent":["import dns from \"node:dns/promises\";\nimport net from \"node:net\";\nimport os from \"node:os\";\n\n/**\n * DNS Resolution Cache Entry\n */\ninterface CacheEntry {\n isLocal: boolean;\n expiresAt: number;\n}\n\n/**\n * DNS Resolution Result with optional TTL\n */\ninterface DnsResult {\n address: string;\n ttl?: number;\n}\n\n/**\n * Cache for DNS resolution results.\n * Key: lowercase hostname\n * Value: { isLocal, expiresAt }\n */\nconst dnsCache = new Map<string, CacheEntry>();\n\n/**\n * In-flight DNS resolutions for request coalescing.\n * Prevents duplicate DNS lookups when multiple requests come in\n * for the same hostname before the first one completes.\n */\nconst pendingResolutions = new Map<string, Promise<boolean>>();\n\n/**\n * TTL Constants (in milliseconds)\n *\n * DNS Rebinding Attack Protection:\n * ================================\n * A DNS rebinding attack works by:\n * 1. Attacker controls evil.com with a short TTL\n * 2. User visits evil.com, which initially resolves to attacker's server\n * 3. Attacker's page loads malicious JavaScript\n * 4. Attacker rebinds evil.com to 127.0.0.1\n * 5. JavaScript makes requests to evil.com (now 127.0.0.1), bypassing same-origin policy\n *\n * Our mitigation: Reject DNS records with TTL < 1 hour.\n * This means an attacker would need to set a TTL >= 1 hour, making their\n * site inaccessible for that duration after rebinding. This makes the attack\n * impractical for real-world exploitation.\n */\nconst MIN_TTL_SECONDS = 60 * 60; // 1 hour - reject DNS records with lower TTL\nconst DEFAULT_TTL_MS = 60 * 60 * 1000; // 1 hour - used when DNS doesn't provide TTL (e.g., /etc/hosts)\nconst FAILURE_TTL_MS = 5 * 60 * 1000; // 5 minutes - cache failed lookups to avoid hammering DNS\n\n/**\n * DNS resolution notes:\n * We use both resolve4/6 AND lookup because:\n * - dns.resolve4/6: Queries DNS servers directly, can return TTL\n * - dns.lookup: Uses OS resolver (getaddrinfo), checks /etc/hosts first, then DNS\n *\n * A hostname in /etc/hosts won't be found by resolve4/6, hence we need both.\n * We can only trust lookup results when DNS (resolve4/6) fails - that means\n * the result came from /etc/hosts rather than DNS.\n */\n\n/**\n * Cache for machine's own IP addresses.\n * Refreshed periodically as network interfaces can change.\n */\nlet machineIPsCache: Set<string> | null = null;\nlet machineIPsCacheTime = 0;\nconst MACHINE_IPS_CACHE_TTL_MS = 60 * 1000; // 1 minute - refresh periodically for network changes\n\n/**\n * Get all IP addresses assigned to this machine's network interfaces.\n * This includes:\n * - Loopback (127.0.0.1, ::1)\n * - Local/private IPs (192.168.x.x, 10.x.x.x, etc.)\n * - VPN IPs (e.g., Tailscale 100.x.x.x, Zerotier IPs)\n *\n * Results are cached for 1 minute to handle network changes while\n * avoiding repeated system calls.\n */\nfunction getMachineIPs(): Set<string> {\n const now = Date.now();\n if (machineIPsCache && now - machineIPsCacheTime < MACHINE_IPS_CACHE_TTL_MS) {\n return machineIPsCache;\n }\n\n const ips = new Set<string>();\n const interfaces = os.networkInterfaces();\n\n for (const name in interfaces) {\n const addresses = interfaces[name];\n if (addresses) {\n for (const addr of addresses) {\n ips.add(addr.address);\n }\n }\n }\n\n machineIPsCache = ips;\n machineIPsCacheTime = now;\n return ips;\n}\n\n/**\n * Check if a string is an IP address (IPv4 or IPv6).\n */\nfunction isIPAddress(hostname: string): boolean {\n // Handle bracketed IPv6 (e.g., [::1])\n const cleanHostname = hostname.startsWith(\"[\") && hostname.endsWith(\"]\") ? hostname.slice(1, -1) : hostname;\n return net.isIP(cleanHostname) !== 0;\n}\n\n/**\n * Check if an IP address belongs to this machine.\n * See getMachineIPs() for details on what IPs are considered local.\n */\nfunction isLocalMachineIP(ip: string): boolean {\n // Handle bracketed IPv6\n const cleanIP = ip.startsWith(\"[\") && ip.endsWith(\"]\") ? ip.slice(1, -1) : ip;\n const machineIPs = getMachineIPs();\n return machineIPs.has(cleanIP);\n}\n\n/**\n * Resolution result with source information for trust decisions.\n */\ninterface ResolutionResult {\n /** Addresses from dns.resolve4/6() with TTL */\n dnsAddresses: DnsResult[];\n /** Addresses from dns.lookup() when DNS failed - these are from /etc/hosts */\n hostsFileAddresses: string[];\n /** Minimum TTL from DNS results (seconds) */\n minTtl?: number;\n}\n\n/**\n * Resolve a hostname to IP addresses using both DNS and OS resolver.\n *\n * Why both dns.resolve() and dns.lookup()?\n * - dns.resolve4/6: Direct DNS query, returns TTL when available\n * - dns.lookup: Uses OS resolver (getaddrinfo), which reads /etc/hosts\n *\n * A hostname in /etc/hosts won't be found by resolve4/6, hence we need both.\n *\n * Trust model:\n * - If dns.resolve() succeeds → result is from DNS, needs TTL validation\n * - If dns.resolve() fails but dns.lookup() succeeds → result is from /etc/hosts, trusted\n *\n * We can only trust lookup results when DNS failed, because lookup also queries\n * DNS servers (via the OS resolver) if the hostname isn't in /etc/hosts.\n */\nasync function resolveHostname(hostname: string): Promise<ResolutionResult> {\n const dnsAddresses: DnsResult[] = [];\n const hostsFileAddresses: string[] = [];\n let minTtl: number | undefined;\n\n // Run all resolution methods in parallel for efficiency\n const [resolve4Result, resolve6Result, lookupResult] = await Promise.allSettled([\n dns.resolve4(hostname, { ttl: true }),\n dns.resolve6(hostname, { ttl: true }),\n dns.lookup(hostname, { all: true }),\n ]);\n\n const dnsSucceeded = resolve4Result.status === \"fulfilled\" || resolve6Result.status === \"fulfilled\";\n\n // Process IPv4 DNS results (with TTL)\n if (resolve4Result.status === \"fulfilled\") {\n for (const record of resolve4Result.value) {\n dnsAddresses.push({ address: record.address, ttl: record.ttl });\n if (record.ttl !== undefined) {\n minTtl = minTtl === undefined ? record.ttl : Math.min(minTtl, record.ttl);\n }\n }\n }\n\n // Process IPv6 DNS results (with TTL)\n if (resolve6Result.status === \"fulfilled\") {\n for (const record of resolve6Result.value) {\n dnsAddresses.push({ address: record.address, ttl: record.ttl });\n if (record.ttl !== undefined) {\n minTtl = minTtl === undefined ? record.ttl : Math.min(minTtl, record.ttl);\n }\n }\n }\n\n // Process OS resolver results - ONLY trusted if DNS failed\n // If DNS succeeded, lookup would return the same DNS result (not trusted separately)\n // If DNS failed but lookup succeeded, it must be from /etc/hosts (trusted)\n if (!dnsSucceeded && lookupResult.status === \"fulfilled\") {\n const lookupAddresses = Array.isArray(lookupResult.value) ? lookupResult.value : [lookupResult.value];\n for (const record of lookupAddresses) {\n hostsFileAddresses.push(record.address);\n }\n }\n\n return { dnsAddresses, hostsFileAddresses, minTtl };\n}\n\n/**\n * Perform the actual DNS resolution and cache the result.\n * This is separated from isHostnameLocal to enable request coalescing.\n */\nasync function resolveAndCacheHostname(hostname: string): Promise<boolean> {\n try {\n const { dnsAddresses, hostsFileAddresses, minTtl } = await resolveHostname(hostname);\n\n // First check /etc/hosts addresses (trusted - DNS failed, so these must be from hosts file)\n // These are under local control and don't need TTL validation\n const hostsLocal = hostsFileAddresses.some(addr => isLocalMachineIP(addr));\n if (hostsLocal) {\n // /etc/hosts entry resolves to local - cache and allow\n dnsCache.set(hostname, {\n isLocal: true,\n expiresAt: Date.now() + DEFAULT_TTL_MS,\n });\n return true;\n }\n\n // Check DNS addresses (need TTL validation for rebinding protection)\n const dnsLocal = dnsAddresses.some(result => isLocalMachineIP(result.address));\n\n if (dnsLocal) {\n // DNS rebinding protection: reject records with TTL < 1 hour\n if (minTtl !== undefined && minTtl < MIN_TTL_SECONDS) {\n // Low TTL is suspicious - reject and cache as non-local\n dnsCache.set(hostname, {\n isLocal: false,\n expiresAt: Date.now() + FAILURE_TTL_MS,\n });\n return false;\n }\n\n // DNS resolves to local with safe TTL\n const cacheTtl = minTtl !== undefined ? minTtl * 1000 : DEFAULT_TTL_MS;\n dnsCache.set(hostname, {\n isLocal: true,\n expiresAt: Date.now() + cacheTtl,\n });\n return true;\n }\n\n // Not a local address - cache the negative result\n const cacheTtl = minTtl !== undefined ? minTtl * 1000 : DEFAULT_TTL_MS;\n dnsCache.set(hostname, {\n isLocal: false,\n expiresAt: Date.now() + cacheTtl,\n });\n return false;\n } catch {\n // DNS resolution failed - cache the failure briefly\n dnsCache.set(hostname, {\n isLocal: false,\n expiresAt: Date.now() + FAILURE_TTL_MS,\n });\n return false;\n }\n}\n\n/**\n * Check if a hostname resolves to this machine, with DNS rebinding protection.\n *\n * Returns true if the hostname resolves to a local IP AND has a safe TTL.\n * DNS records with TTL < 1 hour are rejected to prevent rebinding attacks.\n * Results are cached to avoid repeated DNS lookups.\n *\n * Uses request coalescing: if multiple requests come in for the same hostname\n * before the first resolution completes, they all share the same promise.\n */\nasync function isHostnameLocal(hostname: string): Promise<boolean> {\n // Check cache first\n const cached = dnsCache.get(hostname);\n if (cached && cached.expiresAt > Date.now()) {\n return cached.isLocal;\n }\n\n // Check if there's already an in-flight resolution for this hostname\n const pending = pendingResolutions.get(hostname);\n if (pending) {\n return pending;\n }\n\n // Start a new resolution and track it\n const resolution = resolveAndCacheHostname(hostname);\n pendingResolutions.set(hostname, resolution);\n\n try {\n return await resolution;\n } finally {\n pendingResolutions.delete(hostname);\n }\n}\n\n/**\n * Check if an origin is from spotlightjs.com (HTTPS only, default port).\n */\nfunction isSpotlightOrigin(url: URL, hostname: string): boolean {\n if (hostname === \"spotlightjs.com\" || hostname.endsWith(\".spotlightjs.com\")) {\n return url.protocol === \"https:\" && (url.port === \"\" || url.port === \"443\");\n }\n return false;\n}\n\n/**\n * Pre-normalized allowed origins for efficient matching.\n * Call normalizeAllowedOrigins() once at server startup to create this structure.\n */\nexport interface NormalizedAllowedOrigins {\n /** Full origins (lowercased, trailing slash removed) for exact matching */\n fullOrigins: Set<string>;\n /** Plain domains (lowercased) for permissive matching */\n domains: Set<string>;\n}\n\n/**\n * Normalize and classify allowed origins for efficient matching.\n * Call this once at server startup, then pass the result to isAllowedOrigin().\n *\n * @param allowedOrigins - Raw list of allowed origins/domains from config\n * @returns Pre-normalized structure for O(1) lookups\n */\nexport function normalizeAllowedOrigins(allowedOrigins: string[]): NormalizedAllowedOrigins {\n const fullOrigins = new Set<string>();\n const domains = new Set<string>();\n\n for (const entry of allowedOrigins) {\n const normalized = entry.toLowerCase();\n if (normalized.includes(\"://\")) {\n // Full origin - normalize by removing trailing slash\n fullOrigins.add(normalized.replace(/\\/$/, \"\"));\n } else {\n // Plain domain\n domains.add(normalized);\n }\n }\n\n return { fullOrigins, domains };\n}\n\n/**\n * Check if an origin matches an entry in the pre-normalized allowed origins.\n *\n * Supports two formats:\n * - Full origins (e.g., \"https://ngrok.io:443\") - exact match required\n * - Plain domains (e.g., \"myapp.local\") - matches any protocol/port\n *\n * @param origin - The origin to check (e.g., \"https://myapp.local:3000\")\n * @param hostname - The lowercase hostname from the origin URL\n * @param normalized - Pre-normalized allowed origins\n */\nfunction isCustomAllowedOrigin(origin: string, hostname: string, normalized: NormalizedAllowedOrigins): boolean {\n // Check plain domain match first (more common case)\n if (normalized.domains.has(hostname)) {\n return true;\n }\n\n // Check full origin match\n const normalizedOrigin = origin.toLowerCase().replace(/\\/$/, \"\");\n return normalized.fullOrigins.has(normalizedOrigin);\n}\n\n/**\n * Clear the DNS cache, pending resolutions, and machine IPs cache. Useful for testing.\n */\nexport function clearDnsCache(): void {\n dnsCache.clear();\n pendingResolutions.clear();\n machineIPsCache = null;\n machineIPsCacheTime = 0;\n}\n\n/**\n * Get the current DNS cache size. Useful for testing.\n */\nexport function getDnsCacheSize(): number {\n return dnsCache.size;\n}\n\n/**\n * Validates if an origin should be allowed to access the Sidecar.\n *\n * Allowed origins:\n * - localhost (RFC 6761 reserved name, always trusted)\n * - Any origin whose hostname resolves to this machine's IPs (with TTL >= 1h)\n * - https://spotlightjs.com and subdomains (HTTPS only, default port)\n * - Custom origins/domains from the normalizedAllowedOrigins list\n *\n * For DNS rebinding protection details, see the TTL Constants section above.\n *\n * @param origin - The origin to validate\n * @param normalizedAllowedOrigins - Optional pre-normalized allowed origins (from normalizeAllowedOrigins())\n * @returns Promise<boolean> - true if the origin is allowed, false otherwise\n */\nexport async function isAllowedOrigin(\n origin: string,\n normalizedAllowedOrigins?: NormalizedAllowedOrigins,\n): Promise<boolean> {\n if (!origin) {\n return false;\n }\n\n try {\n const url = new URL(origin);\n const hostname = url.hostname.toLowerCase();\n\n // Fast path: localhost is always allowed (RFC 6761 reserved name)\n // This is safe because \"localhost\" is guaranteed to resolve to loopback\n // and cannot be registered as a public domain name.\n if (hostname === \"localhost\") {\n return true;\n }\n\n // Fast path: spotlightjs.com domains (no DNS lookup needed)\n if (isSpotlightOrigin(url, hostname)) {\n return true;\n }\n\n // Fast path: Check custom allowed origins (no DNS lookup needed)\n if (normalizedAllowedOrigins && isCustomAllowedOrigin(origin, hostname, normalizedAllowedOrigins)) {\n return true;\n }\n\n // Fast path: If hostname is already an IP address, check directly\n if (isIPAddress(hostname)) {\n return isLocalMachineIP(hostname);\n }\n\n // Resolve hostname and check if it's local (with caching and TTL validation)\n return isHostnameLocal(hostname);\n } catch {\n // Invalid URL\n return false;\n }\n}\n"],"names":["os","cacheTtl"],"mappings":";;;;;;;;;;;;AAyBA,MAAM,+BAAe,IAAA;AAOrB,MAAM,yCAAyB,IAAA;AAmB/B,MAAM,kBAAkB,KAAK;AAC7B,MAAM,iBAAiB,KAAK,KAAK;AACjC,MAAM,iBAAiB,IAAI,KAAK;AAiBhC,IAAI,kBAAsC;AAC1C,IAAI,sBAAsB;AAC1B,MAAM,2BAA2B,KAAK;AAYtC,SAAS,gBAA6B;AACpC,QAAM,MAAM,KAAK,IAAA;AACjB,MAAI,mBAAmB,MAAM,sBAAsB,0BAA0B;AAC3E,WAAO;AAAA,EACT;AAEA,QAAM,0BAAU,IAAA;AAChB,QAAM,aAAaA,YAAG,kBAAA;AAEtB,aAAW,QAAQ,YAAY;AAC7B,UAAM,YAAY,WAAW,IAAI;AACjC,QAAI,WAAW;AACb,iBAAW,QAAQ,WAAW;AAC5B,YAAI,IAAI,KAAK,OAAO;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AAEA,oBAAkB;AAClB,wBAAsB;AACtB,SAAO;AACT;AAKA,SAAS,YAAY,UAA2B;AAE9C,QAAM,gBAAgB,SAAS,WAAW,GAAG,KAAK,SAAS,SAAS,GAAG,IAAI,SAAS,MAAM,GAAG,EAAE,IAAI;AACnG,SAAO,IAAI,KAAK,aAAa,MAAM;AACrC;AAMA,SAAS,iBAAiB,IAAqB;AAE7C,QAAM,UAAU,GAAG,WAAW,GAAG,KAAK,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,GAAG,EAAE,IAAI;AAC3E,QAAM,aAAa,cAAA;AACnB,SAAO,WAAW,IAAI,OAAO;AAC/B;AA8BA,eAAe,gBAAgB,UAA6C;AAC1E,QAAM,eAA4B,CAAA;AAClC,QAAM,qBAA+B,CAAA;AACrC,MAAI;AAGJ,QAAM,CAAC,gBAAgB,gBAAgB,YAAY,IAAI,MAAM,QAAQ,WAAW;AAAA,IAC9E,IAAI,SAAS,UAAU,EAAE,KAAK,MAAM;AAAA,IACpC,IAAI,SAAS,UAAU,EAAE,KAAK,MAAM;AAAA,IACpC,IAAI,OAAO,UAAU,EAAE,KAAK,MAAM;AAAA,EAAA,CACnC;AAED,QAAM,eAAe,eAAe,WAAW,eAAe,eAAe,WAAW;AAGxF,MAAI,eAAe,WAAW,aAAa;AACzC,eAAW,UAAU,eAAe,OAAO;AACzC,mBAAa,KAAK,EAAE,SAAS,OAAO,SAAS,KAAK,OAAO,KAAK;AAC9D,UAAI,OAAO,QAAQ,QAAW;AAC5B,iBAAS,WAAW,SAAY,OAAO,MAAM,KAAK,IAAI,QAAQ,OAAO,GAAG;AAAA,MAC1E;AAAA,IACF;AAAA,EACF;AAGA,MAAI,eAAe,WAAW,aAAa;AACzC,eAAW,UAAU,eAAe,OAAO;AACzC,mBAAa,KAAK,EAAE,SAAS,OAAO,SAAS,KAAK,OAAO,KAAK;AAC9D,UAAI,OAAO,QAAQ,QAAW;AAC5B,iBAAS,WAAW,SAAY,OAAO,MAAM,KAAK,IAAI,QAAQ,OAAO,GAAG;AAAA,MAC1E;AAAA,IACF;AAAA,EACF;AAKA,MAAI,CAAC,gBAAgB,aAAa,WAAW,aAAa;AACxD,UAAM,kBAAkB,MAAM,QAAQ,aAAa,KAAK,IAAI,aAAa,QAAQ,CAAC,aAAa,KAAK;AACpG,eAAW,UAAU,iBAAiB;AACpC,yBAAmB,KAAK,OAAO,OAAO;AAAA,IACxC;AAAA,EACF;AAEA,SAAO,EAAE,cAAc,oBAAoB,OAAA;AAC7C;AAMA,eAAe,wBAAwB,UAAoC;AACzE,MAAI;AACF,UAAM,EAAE,cAAc,oBAAoB,WAAW,MAAM,gBAAgB,QAAQ;AAInF,UAAM,aAAa,mBAAmB,KAAK,CAAA,SAAQ,iBAAiB,IAAI,CAAC;AACzE,QAAI,YAAY;AAEd,eAAS,IAAI,UAAU;AAAA,QACrB,SAAS;AAAA,QACT,WAAW,KAAK,QAAQ;AAAA,MAAA,CACzB;AACD,aAAO;AAAA,IACT;AAGA,UAAM,WAAW,aAAa,KAAK,YAAU,iBAAiB,OAAO,OAAO,CAAC;AAE7E,QAAI,UAAU;AAEZ,UAAI,WAAW,UAAa,SAAS,iBAAiB;AAEpD,iBAAS,IAAI,UAAU;AAAA,UACrB,SAAS;AAAA,UACT,WAAW,KAAK,QAAQ;AAAA,QAAA,CACzB;AACD,eAAO;AAAA,MACT;AAGA,YAAMC,YAAW,WAAW,SAAY,SAAS,MAAO;AACxD,eAAS,IAAI,UAAU;AAAA,QACrB,SAAS;AAAA,QACT,WAAW,KAAK,QAAQA;AAAAA,MAAA,CACzB;AACD,aAAO;AAAA,IACT;AAGA,UAAM,WAAW,WAAW,SAAY,SAAS,MAAO;AACxD,aAAS,IAAI,UAAU;AAAA,MACrB,SAAS;AAAA,MACT,WAAW,KAAK,QAAQ;AAAA,IAAA,CACzB;AACD,WAAO;AAAA,EACT,QAAQ;AAEN,aAAS,IAAI,UAAU;AAAA,MACrB,SAAS;AAAA,MACT,WAAW,KAAK,QAAQ;AAAA,IAAA,CACzB;AACD,WAAO;AAAA,EACT;AACF;AAYA,eAAe,gBAAgB,UAAoC;AAEjE,QAAM,SAAS,SAAS,IAAI,QAAQ;AACpC,MAAI,UAAU,OAAO,YAAY,KAAK,OAAO;AAC3C,WAAO,OAAO;AAAA,EAChB;AAGA,QAAM,UAAU,mBAAmB,IAAI,QAAQ;AAC/C,MAAI,SAAS;AACX,WAAO;AAAA,EACT;AAGA,QAAM,aAAa,wBAAwB,QAAQ;AACnD,qBAAmB,IAAI,UAAU,UAAU;AAE3C,MAAI;AACF,WAAO,MAAM;AAAA,EACf,UAAA;AACE,uBAAmB,OAAO,QAAQ;AAAA,EACpC;AACF;AAKA,SAAS,kBAAkB,KAAU,UAA2B;AAC9D,MAAI,aAAa,qBAAqB,SAAS,SAAS,kBAAkB,GAAG;AAC3E,WAAO,IAAI,aAAa,aAAa,IAAI,SAAS,MAAM,IAAI,SAAS;AAAA,EACvE;AACA,SAAO;AACT;AAoBO,SAAS,wBAAwB,gBAAoD;AAC1F,QAAM,kCAAkB,IAAA;AACxB,QAAM,8BAAc,IAAA;AAEpB,aAAW,SAAS,gBAAgB;AAClC,UAAM,aAAa,MAAM,YAAA;AACzB,QAAI,WAAW,SAAS,KAAK,GAAG;AAE9B,kBAAY,IAAI,WAAW,QAAQ,OAAO,EAAE,CAAC;AAAA,IAC/C,OAAO;AAEL,cAAQ,IAAI,UAAU;AAAA,IACxB;AAAA,EACF;AAEA,SAAO,EAAE,aAAa,QAAA;AACxB;AAaA,SAAS,sBAAsB,QAAgB,UAAkB,YAA+C;AAE9G,MAAI,WAAW,QAAQ,IAAI,QAAQ,GAAG;AACpC,WAAO;AAAA,EACT;AAGA,QAAM,mBAAmB,OAAO,YAAA,EAAc,QAAQ,OAAO,EAAE;AAC/D,SAAO,WAAW,YAAY,IAAI,gBAAgB;AACpD;AAkCA,eAAsB,gBACpB,QACA,0BACkB;AAClB,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,MAAM;AAC1B,UAAM,WAAW,IAAI,SAAS,YAAA;AAK9B,QAAI,aAAa,aAAa;AAC5B,aAAO;AAAA,IACT;AAGA,QAAI,kBAAkB,KAAK,QAAQ,GAAG;AACpC,aAAO;AAAA,IACT;AAGA,QAAI,4BAA4B,sBAAsB,QAAQ,UAAU,wBAAwB,GAAG;AACjG,aAAO;AAAA,IACT;AAGA,QAAI,YAAY,QAAQ,GAAG;AACzB,aAAO,iBAAiB,QAAQ;AAAA,IAClC;AAGA,WAAO,gBAAgB,QAAQ;AAAA,EACjC,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"docker-compose-parser.js","sources":["../../../src/server/utils/docker-compose-parser.ts"],"sourcesContent":["import { constants, accessSync, readFileSync } from \"node:fs\";\nimport { delimiter } from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport { logger } from \"../logger.ts\";\n\nconst COMPOSE_FILE_BASE_NAMES = [\"docker-compose\", \"compose\"] as const;\nconst COMPOSE_FILE_EXTENSIONS = [\".yml\", \".yaml\"] as const;\n\n/**\n * Get compose files from COMPOSE_FILE environment variable\n * Returns an array of file paths if the variable is set, null otherwise\n */\nexport function getComposeFilesFromEnv(): string[] | null {\n const composeFileEnv = process.env.COMPOSE_FILE;\n if (!composeFileEnv) {\n return null;\n }\n\n // Split by platform-specific path delimiter (: on Unix, ; on Windows)\n const files = composeFileEnv\n .split(delimiter)\n .map(f => f.trim())\n .filter(Boolean);\n\n return files.length > 0 ? files : null;\n}\n\n/**\n * Find the compose file in the current directory by trying all combinations\n * of base names and extensions.\n */\nexport function findComposeFile(): string | null {\n for (const baseName of COMPOSE_FILE_BASE_NAMES) {\n for (const ext of COMPOSE_FILE_EXTENSIONS) {\n const fileName = `${baseName}${ext}`;\n try {\n accessSync(fileName, constants.R_OK);\n return fileName;\n } catch {\n // File doesn't exist or isn't readable, continue searching\n }\n }\n }\n return null;\n}\n\n/**\n * Find the override file for a given compose file.\n * Docker Compose looks for an override file with the same base name and extension.\n * For example: docker-compose.yml -> docker-compose.override.yml\n */\nexport function findOverrideFile(composeFile: string): string | null {\n // Extract extension from the original file to maintain consistency\n const ext = composeFile.endsWith(\".yaml\") ? \".yaml\" : \".yml\";\n const baseName = composeFile.replace(/\\.(yaml|yml)$/, \"\");\n const overrideFile = `${baseName}.override${ext}`;\n\n try {\n accessSync(overrideFile, constants.R_OK);\n return overrideFile;\n } catch {\n // File doesn't exist or isn't readable\n return null;\n }\n}\n\n/**\n * Parse compose file and extract service names\n */\nexport function getDockerComposeServices(filePath: string): string[] {\n try {\n const content = readFileSync(filePath, \"utf-8\");\n const parsed = parseYaml(content);\n\n if (!parsed || typeof parsed !== \"object\" || !(\"services\" in parsed)) {\n logger.error(`Invalid compose file: ${filePath} - missing 'services' key`);\n return [];\n }\n\n const services = parsed.services as Record<string, unknown>;\n return Object.keys(services);\n } catch (error) {\n logger.error(`Failed to parse compose file: ${filePath}`);\n logger.error(error);\n return [];\n }\n}\n"],"names":["parseYaml"],"mappings":";;;;;;;;;;;;;AAKA,MAAM,0BAA0B,CAAC,kBAAkB,SAAS;AAC5D,MAAM,0BAA0B,CAAC,QAAQ,OAAO;AAMzC,SAAS,yBAA0C;AACxD,QAAM,iBAAiB,QAAQ,IAAI;AACnC,MAAI,CAAC,gBAAgB;AACnB,WAAO;AAAA,EACT;AAGA,QAAM,QAAQ,eACX,MAAM,SAAS,EACf,IAAI,CAAA,MAAK,EAAE,KAAA,CAAM,EACjB,OAAO,OAAO;AAEjB,SAAO,MAAM,SAAS,IAAI,QAAQ;AACpC;AAMO,SAAS,kBAAiC;AAC/C,aAAW,YAAY,yBAAyB;AAC9C,eAAW,OAAO,yBAAyB;AACzC,YAAM,WAAW,GAAG,QAAQ,GAAG,GAAG;AAClC,UAAI;AACF,mBAAW,UAAU,UAAU,IAAI;AACnC,eAAO;AAAA,MACT,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,iBAAiB,aAAoC;AAEnE,QAAM,MAAM,YAAY,SAAS,OAAO,IAAI,UAAU;AACtD,QAAM,WAAW,YAAY,QAAQ,iBAAiB,EAAE;AACxD,QAAM,eAAe,GAAG,QAAQ,YAAY,GAAG;AAE/C,MAAI;AACF,eAAW,cAAc,UAAU,IAAI;AACvC,WAAO;AAAA,EACT,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;AAKO,SAAS,yBAAyB,UAA4B;AACnE,MAAI;AACF,UAAM,UAAU,aAAa,UAAU,OAAO;AAC9C,UAAM,SAASA,MAAU,OAAO;AAEhC,QAAI,CAAC,UAAU,OAAO,WAAW,YAAY,EAAE,cAAc,SAAS;AACpE,aAAO,MAAM,yBAAyB,QAAQ,2BAA2B;AACzE,aAAO,CAAA;AAAA,IACT;AAEA,UAAM,WAAW,OAAO;AACxB,WAAO,OAAO,KAAK,QAAQ;AAAA,EAC7B,SAAS,OAAO;AACd,WAAO,MAAM,iCAAiC,QAAQ,EAAE;AACxD,WAAO,MAAM,KAAK;AAClB,WAAO,CAAA;AAAA,EACT;AACF;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"docker-compose.js","sources":["../../../src/server/utils/docker-compose.ts"],"sourcesContent":["import { execSync } from \"node:child_process\";\nimport semver from \"semver\";\nimport { stringify as stringifyYaml } from \"yaml\";\nimport { logger } from \"../logger.ts\";\nimport {\n findComposeFile,\n findOverrideFile,\n getComposeFilesFromEnv,\n getDockerComposeServices,\n} from \"./docker-compose-parser.ts\";\n\n// minimum version of Docker required to use host.docker.internal on linux\n/// https://docs.docker.com/engine/release-notes/20.10/#bug-fixes-and-enhancements-1\nexport const DOCKER_MIN_VERSION = \"20.10.0\";\nexport const DOCKER_HOST_INTERNAL = \"host.docker.internal\";\nexport const DOCKER_HOST_GATEWAY = \"host-gateway\";\n\ninterface DockerComposeConfig {\n composeFiles: string[]; // Array of compose files\n command: string[];\n serviceNames: string[];\n subcommandArgs: string[]; // Subcommand and its arguments (e.g., up -d --build, logs -f, exec web bash)\n}\n\n/**\n * Execute a command and return the output, or null if it fails\n */\nfunction tryExec(command: string): string | null {\n try {\n return execSync(command, { encoding: \"utf-8\", stdio: [\"pipe\", \"pipe\", \"pipe\"] }).trim();\n } catch {\n return null;\n }\n}\n\n/**\n * Detect if Docker is installed and check its version\n */\nexport function detectDocker(): { version: string; valid: boolean } | null {\n const version = tryExec(\"docker --version\");\n if (!version) {\n return null;\n }\n\n const match = version.match(/Docker version ([\\d.]+)/);\n if (!match) {\n return null;\n }\n\n const versionNumber = match[1];\n const valid = semver.gte(versionNumber, DOCKER_MIN_VERSION);\n\n return { version: versionNumber, valid };\n}\n\n/**\n * Validate Docker is installed and meets minimum version requirement.\n * Logs appropriate messages on failure.\n */\nfunction validateDocker(): boolean {\n const docker = detectDocker();\n if (!docker) {\n logger.debug(\"Docker is not installed or not in PATH\");\n return false;\n }\n\n if (!docker.valid) {\n logger.error(`Docker version ${docker.version} does not meet the minimum required version ${DOCKER_MIN_VERSION}`);\n return false;\n }\n\n logger.debug(`Detected Docker version ${docker.version}`);\n return true;\n}\n\n/**\n * Detect which compose command to use and its version\n * Follows the logic from sentry/self-hosted\n */\nfunction detectComposeCommand(): { command: string[]; version: string } | null {\n const composePluginVersion = tryExec(\"docker compose version --short\");\n const composeStandaloneVersion = tryExec(\"docker-compose version --short\");\n\n if (!composePluginVersion && !composeStandaloneVersion) {\n return null;\n }\n\n if (!composePluginVersion) {\n return { command: [\"docker-compose\"], version: composeStandaloneVersion! };\n }\n\n if (!composeStandaloneVersion) {\n return { command: [\"docker\", \"compose\"], version: composePluginVersion! };\n }\n\n // Use standalone if it's newer, otherwise prefer plugin\n const pluginVer = composePluginVersion.replace(/^v/, \"\");\n const standaloneVer = composeStandaloneVersion.replace(/^v/, \"\");\n\n if (semver.gt(standaloneVer, pluginVer)) {\n return { command: [\"docker-compose\"], version: composeStandaloneVersion };\n }\n\n return { command: [\"docker\", \"compose\"], version: composePluginVersion };\n}\n\n/**\n * Generate the override YAML for injecting Spotlight environment variables\n */\nfunction generateSpotlightOverrideYaml(serviceNames: string[]): string {\n const services: Record<string, { environment: string[]; extra_hosts: string[] }> = {};\n // Pass environment variables without values to inherit from parent process (run.ts)\n // so the values set in run.ts are propagated correctly\n for (const serviceName of serviceNames) {\n services[serviceName] = {\n environment: [\"SENTRY_SPOTLIGHT\", \"NEXT_PUBLIC_SENTRY_SPOTLIGHT\", \"SENTRY_TRACES_SAMPLE_RATE\"],\n extra_hosts: [`${DOCKER_HOST_INTERNAL}:${DOCKER_HOST_GATEWAY}`],\n };\n }\n\n return stringifyYaml({ services });\n}\n\n/**\n * Resolve compose files to use, with the following priority:\n * 1. User-specified files (from -f flags)\n * 2. COMPOSE_FILE environment variable\n * 3. Auto-detect compose file + override file\n */\nfunction resolveComposeFiles(userSpecifiedFiles?: string[]): string[] | null {\n if (userSpecifiedFiles && userSpecifiedFiles.length > 0) {\n logger.debug(`Using user-specified compose files: ${userSpecifiedFiles.join(\", \")}`);\n return userSpecifiedFiles;\n }\n\n const fromEnv = getComposeFilesFromEnv();\n if (fromEnv) {\n logger.debug(`Using COMPOSE_FILE environment variable: ${fromEnv.join(\", \")}`);\n return fromEnv;\n }\n\n const composeFile = findComposeFile();\n if (!composeFile) {\n logger.debug(\"No compose file found\");\n return null;\n }\n\n logger.debug(`Found compose file: ${composeFile}`);\n const files = [composeFile];\n\n const overrideFile = findOverrideFile(composeFile);\n if (overrideFile) {\n logger.debug(`Found override file: ${overrideFile}`);\n files.push(overrideFile);\n }\n\n return files;\n}\n\n/**\n * Collect and deduplicate service names from compose files\n */\nfunction collectServices(composeFiles: string[]): string[] {\n const serviceSet = new Set<string>();\n for (const file of composeFiles) {\n for (const service of getDockerComposeServices(file)) {\n serviceSet.add(service);\n }\n }\n return Array.from(serviceSet);\n}\n\nconst FILE_FLAGS = [\"-f\", \"--file\"];\n\n// Global flags that take a value (we need to skip over their values when finding the subcommand)\nconst FLAGS_WITH_VALUES = [\"-f\", \"--file\", \"-p\", \"--project-name\", \"--project-directory\", \"--env-file\", \"--profile\"];\n\n/**\n * Extract -f/--file flags from global options (before the subcommand).\n * Once we hit the first non-flag argument (the subcommand), everything passes through.\n * This prevents confusing `logs -f` (follow) with `-f file.yml` (compose file).\n */\nfunction parseComposeFlags(args: string[]): { files: string[]; remainingArgs: string[] } {\n const files: string[] = [];\n const remainingArgs: string[] = [];\n let parsingGlobalFlags = true;\n\n for (let i = 0; i < args.length; i++) {\n const arg = args[i];\n\n if (parsingGlobalFlags) {\n // Extract -f/--file flags\n if (FILE_FLAGS.includes(arg) && args[i + 1]) {\n files.push(args[++i]);\n continue;\n }\n\n const matchedFileFlag = FILE_FLAGS.find(flag => arg.startsWith(`${flag}=`));\n if (matchedFileFlag) {\n files.push(arg.slice(matchedFileFlag.length + 1));\n continue;\n }\n\n // Skip other global flags that take values (e.g., -p myproject)\n if (FLAGS_WITH_VALUES.includes(arg) && args[i + 1]) {\n remainingArgs.push(arg, args[++i]);\n continue;\n }\n\n const matchedValueFlag = FLAGS_WITH_VALUES.find(flag => arg.startsWith(`${flag}=`));\n if (matchedValueFlag) {\n remainingArgs.push(arg);\n continue;\n }\n\n // First non-flag argument is the subcommand - stop parsing global flags\n if (!arg.startsWith(\"-\")) {\n parsingGlobalFlags = false;\n }\n }\n\n remainingArgs.push(arg);\n }\n\n return { files, remainingArgs };\n}\n\n/**\n * Build the Docker Compose command with Spotlight environment injection\n */\nexport function buildDockerComposeCommand(config: DockerComposeConfig): {\n cmdArgs: string[];\n stdin: string;\n} {\n const cmdArgs = [...config.command];\n\n // Add -f for each compose file\n for (const file of config.composeFiles) {\n cmdArgs.push(\"-f\", file);\n }\n\n // Add our Spotlight override last\n cmdArgs.push(\"-f\", \"-\");\n\n // Add the subcommand and its arguments (e.g., up -d --build, logs -f)\n if (config.subcommandArgs && config.subcommandArgs.length > 0) {\n cmdArgs.push(...config.subcommandArgs);\n }\n\n const stdin = generateSpotlightOverrideYaml(config.serviceNames);\n\n return { cmdArgs, stdin };\n}\n\n/**\n * Prepare Docker Compose run by configuring environment and building command\n *\n * This helper sets up the SENTRY_SPOTLIGHT URL to use host.docker.internal\n * (so containers can reach the host machine), builds the compose command,\n * and removes COMPOSE_FILE from env to avoid conflicts with explicit -f flags.\n */\nexport function prepareDockerComposeRun(\n config: DockerComposeConfig,\n serverPort: number,\n env: Record<string, string | undefined>,\n): { cmdArgs: string[]; stdin: string } {\n env.SENTRY_SPOTLIGHT = `http://${DOCKER_HOST_INTERNAL}:${serverPort}/stream`;\n const command = buildDockerComposeCommand(config);\n // biome-ignore lint/performance/noDelete: need to remove env var entirely\n delete env.COMPOSE_FILE;\n return command;\n}\n\n/**\n * Detect and configure Docker Compose\n *\n * This function orchestrates the detection of Docker, Docker Compose,\n * compose files, and services to build a complete configuration.\n */\nexport function detectDockerCompose(): DockerComposeConfig | null {\n if (!validateDocker()) {\n return null;\n }\n\n const compose = detectComposeCommand();\n if (!compose) {\n logger.debug(\"Docker Compose is not installed or not in PATH\");\n return null;\n }\n\n logger.debug(`Detected Docker Compose version ${compose.version} (${compose.command.join(\" \")})`);\n\n const composeFiles = resolveComposeFiles();\n if (!composeFiles) {\n return null;\n }\n\n const serviceNames = collectServices(composeFiles);\n if (serviceNames.length === 0) {\n logger.debug(\"No services found in compose file(s)\");\n return null;\n }\n\n logger.debug(`Found ${serviceNames.length} service(s): ${serviceNames.join(\", \")}`);\n\n return {\n composeFiles,\n command: compose.command,\n serviceNames,\n subcommandArgs: [\"up\"], // Default to 'up' when auto-detecting\n };\n}\n\n/**\n * Parse an explicit Docker Compose command from cmdArgs\n *\n * This handles cases where the user runs:\n * - `spotlight run docker compose up -d`\n * - `spotlight run docker-compose logs -f`\n * - `spotlight run docker compose -f custom.yml exec web bash`\n *\n * Returns a DockerComposeConfig if the command is a docker compose command,\n * null otherwise.\n */\nexport function parseExplicitDockerCompose(cmdArgs: string[]): DockerComposeConfig | null {\n if (cmdArgs.length < 2) {\n return null;\n }\n\n let command: string[];\n let argsStartIndex: number;\n\n if (cmdArgs[0] === \"docker-compose\") {\n command = [\"docker-compose\"];\n argsStartIndex = 1;\n } else if (cmdArgs[0] === \"docker\" && cmdArgs[1] === \"compose\") {\n command = [\"docker\", \"compose\"];\n argsStartIndex = 2;\n } else {\n return null;\n }\n\n // Validate Docker version (required for host.docker.internal on Linux)\n if (!validateDocker()) {\n return null;\n }\n\n const argsAfterCommand = cmdArgs.slice(argsStartIndex);\n const { files: userFiles, remainingArgs: subcommandArgs } = parseComposeFlags(argsAfterCommand);\n\n if (subcommandArgs.length === 0) {\n logger.debug(\"No subcommand provided for docker compose\");\n return null;\n }\n\n const composeFiles = resolveComposeFiles(userFiles.length > 0 ? userFiles : undefined);\n if (!composeFiles) {\n return null;\n }\n\n const serviceNames = collectServices(composeFiles);\n if (serviceNames.length === 0) {\n logger.debug(\"No services found in compose file(s)\");\n return null;\n }\n\n logger.debug(`Found ${serviceNames.length} service(s): ${serviceNames.join(\", \")}`);\n\n return {\n composeFiles,\n command,\n serviceNames,\n subcommandArgs,\n };\n}\n"],"names":["stringifyYaml"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"eventContainer.js","sources":["../../../src/server/utils/eventContainer.ts"],"sourcesContent":["import { type ParsedEnvelope, processEnvelope } from \"../parser/index.ts\";\n\n/**\n * Container for events that flow through the sidecar\n * Provides lazy parsing only when needed (in debug mode)\n */\nexport class EventContainer {\n private contentType: string;\n private data: Buffer;\n private senderUserAgent?: string;\n private parsedEnvelope: ParsedEnvelope | null = null;\n private isParsed = false;\n\n constructor(contentType: string, data: Buffer, senderUserAgent?: string) {\n this.contentType = contentType;\n this.data = data;\n this.senderUserAgent = senderUserAgent;\n }\n\n /**\n * Get the content type of the event\n */\n getContentType(): string {\n return this.contentType;\n }\n\n /**\n * Get the raw data buffer\n */\n getData(): Buffer {\n return this.data;\n }\n\n /**\n * Get parsed envelope data (lazy parsing)\n */\n getParsedEnvelope(): ParsedEnvelope {\n // Parse once and cache the result\n if (!this.isParsed) {\n this.parsedEnvelope = processEnvelope(\n {\n contentType: this.contentType,\n data: this.data,\n },\n this.senderUserAgent,\n );\n this.isParsed = true;\n }\n\n return this.parsedEnvelope!;\n }\n\n /**\n * Get a summary of the event types in this container\n * Returns null if not a parseable envelope\n */\n getEventTypes(): string[] | null {\n const envelope = this.getParsedEnvelope();\n if (!envelope) return null;\n\n const eventTypes: string[] = [];\n for (const item of envelope.envelope[1]) {\n if (item[0].type) {\n eventTypes.push(item[0].type);\n }\n }\n\n return eventTypes;\n }\n\n /**\n * Get a formatted string of event types for logging\n */\n getEventTypesString(): string {\n const types = this.getEventTypes();\n if (!types || types.length === 0) {\n return this.contentType === \"application/x-sentry-envelope\" ? \"envelope\" : this.contentType;\n }\n return types.join(\"+\");\n }\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAMO,MAAM,eAAe;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAwC;AAAA,EACxC,WAAW;AAAA,EAEnB,YAAY,aAAqB,MAAc,iBAA0B;AACvE,SAAK,cAAc;AACnB,SAAK,OAAO;AACZ,SAAK,kBAAkB;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,iBAAyB;AACvB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,UAAkB;AAChB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoC;AAElC,QAAI,CAAC,KAAK,UAAU;AAClB,WAAK,iBAAiB;AAAA,QACpB;AAAA,UACE,aAAa,KAAK;AAAA,UAClB,MAAM,KAAK;AAAA,QAAA;AAAA,QAEb,KAAK;AAAA,MAAA;AAEP,WAAK,WAAW;AAAA,IAClB;AAEA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAiC;AAC/B,UAAM,WAAW,KAAK,kBAAA;AACtB,QAAI,CAAC,SAAU,QAAO;AAEtB,UAAM,aAAuB,CAAA;AAC7B,eAAW,QAAQ,SAAS,SAAS,CAAC,GAAG;AACvC,UAAI,KAAK,CAAC,EAAE,MAAM;AAChB,mBAAW,KAAK,KAAK,CAAC,EAAE,IAAI;AAAA,MAC9B;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,sBAA8B;AAC5B,UAAM,QAAQ,KAAK,cAAA;AACnB,QAAI,CAAC,SAAS,MAAM,WAAW,GAAG;AAChC,aAAO,KAAK,gBAAgB,kCAAkC,aAAa,KAAK;AAAA,IAClF;AACA,WAAO,MAAM,KAAK,GAAG;AAAA,EACvB;AACF;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"extras.js","sources":["../../../src/server/utils/extras.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport { get } from \"node:http\";\nimport { startSpan } from \"@sentry/node\";\nimport { SERVER_IDENTIFIER } from \"../constants.ts\";\nimport { logger } from \"../logger.ts\";\n\nexport const withTracing =\n (fn: CallableFunction, spanArgs = {}) =>\n (...args: unknown[]) =>\n startSpan({ name: fn.name, ...spanArgs }, () => fn(...args));\n\nexport const getSpotlightURL = (port: number, host = \"localhost\") => `http://${host}:${port}/stream`;\n\nexport function getSpotlightWebUrl(port: number): string {\n return `http://localhost:${port}`;\n}\n\nexport function logSpotlightUrl(port: number): void {\n logger.info(`Open ${getSpotlightWebUrl(port)} to see the Spotlight UI`);\n}\n\nexport function openInBrowser(port: number): void {\n const url = getSpotlightWebUrl(port);\n const platform = process.platform;\n\n let cmd: string;\n let args: string[];\n\n if (platform === \"darwin\") {\n cmd = \"open\";\n args = [url];\n } else if (platform === \"win32\") {\n cmd = \"cmd\";\n args = [\"/c\", \"start\", \"\", url];\n } else {\n cmd = \"xdg-open\";\n args = [url];\n }\n\n const child = spawn(cmd, args, { detached: true, stdio: \"ignore\" });\n // Handle spawn errors gracefully (e.g., command not found in minimal environments)\n child.on(\"error\", err => {\n logger.debug(`Failed to open browser: ${err.message}`);\n });\n child.unref();\n}\n\nexport const isValidPort = withTracing(\n (value: string | number) => {\n if (typeof value === \"string\") {\n const portNumber = Number(value);\n return /^\\d+$/.test(value) && portNumber > 0 && portNumber <= 65535;\n }\n return value > 0 && value <= 65535;\n },\n { name: \"isValidPort\", op: \"sidecar.server.portCheck\" },\n);\n\nexport const isSidecarRunning = withTracing(\n (port: string | number | undefined) =>\n new Promise(_resolve => {\n logger.debug(`Checking if we are already running on port ${port}`);\n const options = {\n hostname: \"localhost\",\n port: port,\n path: \"/health\",\n method: \"GET\",\n // This is only the socket timeout so set up\n // a connection timeout below manually\n timeout: 1000,\n headers: { Connection: \"close\" },\n };\n\n let timeoutId: NodeJS.Timeout | null = null;\n const healthReq = get(options, res => {\n const serverIdentifier = res.headers[\"x-powered-by\"];\n resolve(serverIdentifier === SERVER_IDENTIFIER);\n });\n const destroyHealthReq = () => !healthReq.destroyed && healthReq.destroy(new Error(\"Request timed out.\"));\n function resolve(value: boolean) {\n process.off(\"SIGINT\", destroyHealthReq);\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n _resolve(value);\n }\n process.on(\"SIGINT\", destroyHealthReq);\n timeoutId = setTimeout(destroyHealthReq, 2000);\n timeoutId.unref();\n healthReq.on(\"error\", () => {\n resolve(false);\n });\n healthReq.end();\n }),\n { name: \"isSidecarRunning\", op: \"sidecar.server.collideCheck\" },\n);\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAMO,MAAM,cACX,CAAC,IAAsB,WAAW,CAAA,MAClC,IAAI,SACF,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAA,GAAY,MAAM,GAAG,GAAG,IAAI,CAAC;AAExD,MAAM,kBAAkB,CAAC,MAAc,OAAO,gBAAgB,UAAU,IAAI,IAAI,IAAI;AAEpF,SAAS,mBAAmB,MAAsB;AACvD,SAAO,oBAAoB,IAAI;AACjC;AAEO,SAAS,gBAAgB,MAAoB;AAClD,SAAO,KAAK,QAAQ,mBAAmB,IAAI,CAAC,0BAA0B;AACxE;AAEO,SAAS,cAAc,MAAoB;AAChD,QAAM,MAAM,mBAAmB,IAAI;AACnC,QAAM,WAAW,QAAQ;AAEzB,MAAI;AACJ,MAAI;AAEJ,MAAI,aAAa,UAAU;AACzB,UAAM;AACN,WAAO,CAAC,GAAG;AAAA,EACb,WAAW,aAAa,SAAS;AAC/B,UAAM;AACN,WAAO,CAAC,MAAM,SAAS,IAAI,GAAG;AAAA,EAChC,OAAO;AACL,UAAM;AACN,WAAO,CAAC,GAAG;AAAA,EACb;AAEA,QAAM,QAAQ,MAAM,KAAK,MAAM,EAAE,UAAU,MAAM,OAAO,UAAU;AAElE,QAAM,GAAG,SAAS,CAAA,QAAO;AACvB,WAAO,MAAM,2BAA2B,IAAI,OAAO,EAAE;AAAA,EACvD,CAAC;AACD,QAAM,MAAA;AACR;AAEO,MAAM,cAAc;AAAA,EACzB,CAAC,UAA2B;AAC1B,QAAI,OAAO,UAAU,UAAU;AAC7B,YAAM,aAAa,OAAO,KAAK;AAC/B,aAAO,QAAQ,KAAK,KAAK,KAAK,aAAa,KAAK,cAAc;AAAA,IAChE;AACA,WAAO,QAAQ,KAAK,SAAS;AAAA,EAC/B;AAAA,EACA,EAAE,MAAM,eAAe,IAAI,2BAAA;AAC7B;AAEO,MAAM,mBAAmB;AAAA,EAC9B,CAAC,SACC,IAAI,QAAQ,CAAA,aAAY;AACtB,WAAO,MAAM,8CAA8C,IAAI,EAAE;AACjE,UAAM,UAAU;AAAA,MACd,UAAU;AAAA,MACV;AAAA,MACA,MAAM;AAAA,MACN,QAAQ;AAAA;AAAA;AAAA,MAGR,SAAS;AAAA,MACT,SAAS,EAAE,YAAY,QAAA;AAAA,IAAQ;AAGjC,QAAI,YAAmC;AACvC,UAAM,YAAY,IAAI,SAAS,CAAA,QAAO;AACpC,YAAM,mBAAmB,IAAI,QAAQ,cAAc;AACnD,cAAQ,qBAAqB,iBAAiB;AAAA,IAChD,CAAC;AACD,UAAM,mBAAmB,MAAM,CAAC,UAAU,aAAa,UAAU,QAAQ,IAAI,MAAM,oBAAoB,CAAC;AACxG,aAAS,QAAQ,OAAgB;AAC/B,cAAQ,IAAI,UAAU,gBAAgB;AACtC,UAAI,WAAW;AACb,qBAAa,SAAS;AAAA,MACxB;AACA,eAAS,KAAK;AAAA,IAChB;AACA,YAAQ,GAAG,UAAU,gBAAgB;AACrC,gBAAY,WAAW,kBAAkB,GAAI;AAC7C,cAAU,MAAA;AACV,cAAU,GAAG,SAAS,MAAM;AAC1B,cAAQ,KAAK;AAAA,IACf,CAAC;AACD,cAAU,IAAA;AAAA,EACZ,CAAC;AAAA,EACH,EAAE,MAAM,oBAAoB,IAAI,8BAAA;AAClC;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getBuffer.js","sources":["../../../src/server/utils/getBuffer.ts"],"sourcesContent":["import { createSpotlightBuffer } from \"../sdk.ts\";\n\nconst GLOBAL_BUFFER = createSpotlightBuffer();\n\nexport function getBuffer() {\n return GLOBAL_BUFFER;\n}\n"],"names":[],"mappings":";;;;;;;;;;AAEA,MAAM,gBAAgB,sBAAA;AAEf,SAAS,YAAY;AAC1B,SAAO;AACT;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sources":["../../src/shared/constants.ts"],"sourcesContent":["// Shared constants used by both UI and server\nexport const CONTEXT_LINES_ENDPOINT = \"/contextlines\";\nexport const RAW_TYPES = new Set([\"attachment\", \"replay_video\", \"statsd\"]);\nexport const SENTRY_CONTENT_TYPE = \"application/x-sentry-envelope\";\n"],"names":[],"mappings":";;;;;;;;;AACO,MAAM,yBAAyB;AAC/B,MAAM,YAAY,oBAAI,IAAI,CAAC,cAAc,gBAAgB,QAAQ,CAAC;AAClE,MAAM,sBAAsB;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"andromeeda.js","sources":["../../../../../node_modules/.pnpm/@shikijs+themes@3.13.0/node_modules/@shikijs/themes/dist/andromeeda.mjs"],"sourcesContent":["/* Theme: andromeeda */\nexport default Object.freeze(JSON.parse(\"{\\\"colors\\\":{\\\"activityBar.background\\\":\\\"#23262E\\\",\\\"activityBar.dropBackground\\\":\\\"#3a404e\\\",\\\"activityBar.foreground\\\":\\\"#BAAFC0\\\",\\\"activityBarBadge.background\\\":\\\"#00b0ff\\\",\\\"activityBarBadge.foreground\\\":\\\"#20232B\\\",\\\"badge.background\\\":\\\"#00b0ff\\\",\\\"badge.foreground\\\":\\\"#20232B\\\",\\\"button.background\\\":\\\"#00e8c5cc\\\",\\\"button.hoverBackground\\\":\\\"#07d4b6cc\\\",\\\"debugExceptionWidget.background\\\":\\\"#FF9F2E60\\\",\\\"debugExceptionWidget.border\\\":\\\"#FF9F2E60\\\",\\\"debugToolBar.background\\\":\\\"#20232A\\\",\\\"diffEditor.insertedTextBackground\\\":\\\"#29BF1220\\\",\\\"diffEditor.removedTextBackground\\\":\\\"#F21B3F20\\\",\\\"dropdown.background\\\":\\\"#2b303b\\\",\\\"dropdown.border\\\":\\\"#363c49\\\",\\\"editor.background\\\":\\\"#23262E\\\",\\\"editor.findMatchBackground\\\":\\\"#f39d1256\\\",\\\"editor.findMatchBorder\\\":\\\"#f39d12b6\\\",\\\"editor.findMatchHighlightBackground\\\":\\\"#59b8b377\\\",\\\"editor.foreground\\\":\\\"#D5CED9\\\",\\\"editor.hoverHighlightBackground\\\":\\\"#373941\\\",\\\"editor.lineHighlightBackground\\\":\\\"#2e323d\\\",\\\"editor.lineHighlightBorder\\\":\\\"#2e323d\\\",\\\"editor.rangeHighlightBackground\\\":\\\"#372F3C\\\",\\\"editor.selectionBackground\\\":\\\"#3D4352\\\",\\\"editor.selectionHighlightBackground\\\":\\\"#4F435580\\\",\\\"editor.wordHighlightBackground\\\":\\\"#4F4355\\\",\\\"editor.wordHighlightStrongBackground\\\":\\\"#db45a280\\\",\\\"editorBracketMatch.background\\\":\\\"#746f77\\\",\\\"editorBracketMatch.border\\\":\\\"#746f77\\\",\\\"editorCodeLens.foreground\\\":\\\"#746f77\\\",\\\"editorCursor.foreground\\\":\\\"#FFF\\\",\\\"editorError.foreground\\\":\\\"#FC644D\\\",\\\"editorGroup.background\\\":\\\"#23262E\\\",\\\"editorGroup.dropBackground\\\":\\\"#495061d7\\\",\\\"editorGroupHeader.tabsBackground\\\":\\\"#23262E\\\",\\\"editorGutter.addedBackground\\\":\\\"#9BC53DBB\\\",\\\"editorGutter.deletedBackground\\\":\\\"#FC644DBB\\\",\\\"editorGutter.modifiedBackground\\\":\\\"#5BC0EBBB\\\",\\\"editorHoverWidget.background\\\":\\\"#373941\\\",\\\"editorHoverWidget.border\\\":\\\"#00e8c5cc\\\",\\\"editorIndentGuide.activeBackground\\\":\\\"#585C66\\\",\\\"editorIndentGuide.background\\\":\\\"#333844\\\",\\\"editorLineNumber.foreground\\\":\\\"#746f77\\\",\\\"editorLink.activeForeground\\\":\\\"#3B79C7\\\",\\\"editorOverviewRuler.border\\\":\\\"#1B1D23\\\",\\\"editorRuler.foreground\\\":\\\"#4F4355\\\",\\\"editorSuggestWidget.background\\\":\\\"#20232A\\\",\\\"editorSuggestWidget.border\\\":\\\"#372F3C\\\",\\\"editorSuggestWidget.selectedBackground\\\":\\\"#373941\\\",\\\"editorWarning.foreground\\\":\\\"#FF9F2E\\\",\\\"editorWhitespace.foreground\\\":\\\"#333844\\\",\\\"editorWidget.background\\\":\\\"#20232A\\\",\\\"errorForeground\\\":\\\"#FC644D\\\",\\\"extensionButton.prominentBackground\\\":\\\"#07d4b6cc\\\",\\\"extensionButton.prominentHoverBackground\\\":\\\"#07d4b5b0\\\",\\\"focusBorder\\\":\\\"#746f77\\\",\\\"foreground\\\":\\\"#D5CED9\\\",\\\"gitDecoration.ignoredResourceForeground\\\":\\\"#555555\\\",\\\"input.background\\\":\\\"#2b303b\\\",\\\"input.placeholderForeground\\\":\\\"#746f77\\\",\\\"inputOption.activeBorder\\\":\\\"#C668BA\\\",\\\"inputValidation.errorBackground\\\":\\\"#D65343\\\",\\\"inputValidation.errorBorder\\\":\\\"#D65343\\\",\\\"inputValidation.infoBackground\\\":\\\"#3A6395\\\",\\\"inputValidation.infoBorder\\\":\\\"#3A6395\\\",\\\"inputValidation.warningBackground\\\":\\\"#DE9237\\\",\\\"inputValidation.warningBorder\\\":\\\"#DE9237\\\",\\\"list.activeSelectionBackground\\\":\\\"#23262E\\\",\\\"list.activeSelectionForeground\\\":\\\"#00e8c6\\\",\\\"list.dropBackground\\\":\\\"#3a404e\\\",\\\"list.focusBackground\\\":\\\"#282b35\\\",\\\"list.focusForeground\\\":\\\"#eee\\\",\\\"list.hoverBackground\\\":\\\"#23262E\\\",\\\"list.hoverForeground\\\":\\\"#eee\\\",\\\"list.inactiveSelectionBackground\\\":\\\"#23262E\\\",\\\"list.inactiveSelectionForeground\\\":\\\"#00e8c6\\\",\\\"merge.currentContentBackground\\\":\\\"#F9267240\\\",\\\"merge.currentHeaderBackground\\\":\\\"#F92672\\\",\\\"merge.incomingContentBackground\\\":\\\"#3B79C740\\\",\\\"merge.incomingHeaderBackground\\\":\\\"#3B79C7BB\\\",\\\"minimapSlider.activeBackground\\\":\\\"#60698060\\\",\\\"minimapSlider.background\\\":\\\"#58607460\\\",\\\"minimapSlider.hoverBackground\\\":\\\"#60698060\\\",\\\"notification.background\\\":\\\"#2d313b\\\",\\\"notification.buttonBackground\\\":\\\"#00e8c5cc\\\",\\\"notification.buttonHoverBackground\\\":\\\"#07d4b5b0\\\",\\\"notification.errorBackground\\\":\\\"#FC644D\\\",\\\"notification.infoBackground\\\":\\\"#00b0ff\\\",\\\"notification.warningBackground\\\":\\\"#FF9F2E\\\",\\\"panel.background\\\":\\\"#23262E\\\",\\\"panel.border\\\":\\\"#1B1D23\\\",\\\"panelTitle.activeBorder\\\":\\\"#23262E\\\",\\\"panelTitle.inactiveForeground\\\":\\\"#746f77\\\",\\\"peekView.border\\\":\\\"#23262E\\\",\\\"peekViewEditor.background\\\":\\\"#1A1C22\\\",\\\"peekViewEditor.matchHighlightBackground\\\":\\\"#FF9F2E60\\\",\\\"peekViewResult.background\\\":\\\"#1A1C22\\\",\\\"peekViewResult.matchHighlightBackground\\\":\\\"#FF9F2E60\\\",\\\"peekViewResult.selectionBackground\\\":\\\"#23262E\\\",\\\"peekViewTitle.background\\\":\\\"#1A1C22\\\",\\\"peekViewTitleDescription.foreground\\\":\\\"#746f77\\\",\\\"pickerGroup.border\\\":\\\"#4F4355\\\",\\\"pickerGroup.foreground\\\":\\\"#746f77\\\",\\\"progressBar.background\\\":\\\"#C668BA\\\",\\\"scrollbar.shadow\\\":\\\"#23262E\\\",\\\"scrollbarSlider.activeBackground\\\":\\\"#3A3F4CCC\\\",\\\"scrollbarSlider.background\\\":\\\"#3A3F4C77\\\",\\\"scrollbarSlider.hoverBackground\\\":\\\"#3A3F4CAA\\\",\\\"selection.background\\\":\\\"#746f77\\\",\\\"sideBar.background\\\":\\\"#23262E\\\",\\\"sideBar.foreground\\\":\\\"#999999\\\",\\\"sideBarSectionHeader.background\\\":\\\"#23262E\\\",\\\"sideBarTitle.foreground\\\":\\\"#00e8c6\\\",\\\"statusBar.background\\\":\\\"#23262E\\\",\\\"statusBar.debuggingBackground\\\":\\\"#FC644D\\\",\\\"statusBar.noFolderBackground\\\":\\\"#23262E\\\",\\\"statusBarItem.activeBackground\\\":\\\"#00e8c5cc\\\",\\\"statusBarItem.hoverBackground\\\":\\\"#07d4b5b0\\\",\\\"statusBarItem.prominentBackground\\\":\\\"#07d4b5b0\\\",\\\"statusBarItem.prominentHoverBackground\\\":\\\"#00e8c5cc\\\",\\\"tab.activeBackground\\\":\\\"#23262e\\\",\\\"tab.activeBorder\\\":\\\"#00e8c6\\\",\\\"tab.activeForeground\\\":\\\"#00e8c6\\\",\\\"tab.inactiveBackground\\\":\\\"#23262E\\\",\\\"tab.inactiveForeground\\\":\\\"#746f77\\\",\\\"terminal.ansiBlue\\\":\\\"#7cb7ff\\\",\\\"terminal.ansiBrightBlue\\\":\\\"#7cb7ff\\\",\\\"terminal.ansiBrightCyan\\\":\\\"#00e8c6\\\",\\\"terminal.ansiBrightGreen\\\":\\\"#96E072\\\",\\\"terminal.ansiBrightMagenta\\\":\\\"#ff00aa\\\",\\\"terminal.ansiBrightRed\\\":\\\"#ee5d43\\\",\\\"terminal.ansiBrightYellow\\\":\\\"#FFE66D\\\",\\\"terminal.ansiCyan\\\":\\\"#00e8c6\\\",\\\"terminal.ansiGreen\\\":\\\"#96E072\\\",\\\"terminal.ansiMagenta\\\":\\\"#ff00aa\\\",\\\"terminal.ansiRed\\\":\\\"#ee5d43\\\",\\\"terminal.ansiYellow\\\":\\\"#FFE66D\\\",\\\"terminalCursor.background\\\":\\\"#23262E\\\",\\\"terminalCursor.foreground\\\":\\\"#FFE66D\\\",\\\"titleBar.activeBackground\\\":\\\"#23262E\\\",\\\"walkThrough.embeddedEditorBackground\\\":\\\"#23262E\\\",\\\"widget.shadow\\\":\\\"#14151A\\\"},\\\"displayName\\\":\\\"Andromeeda\\\",\\\"name\\\":\\\"andromeeda\\\",\\\"semanticTokenColors\\\":{\\\"property.declaration:javascript\\\":\\\"#D5CED9\\\",\\\"variable.defaultLibrary:javascript\\\":\\\"#f39c12\\\"},\\\"tokenColors\\\":[{\\\"settings\\\":{\\\"background\\\":\\\"#23262E\\\",\\\"foreground\\\":\\\"#D5CED9\\\"}},{\\\"scope\\\":[\\\"comment\\\",\\\"markup.quote.markdown\\\",\\\"meta.diff\\\",\\\"meta.diff.header\\\"],\\\"settings\\\":{\\\"foreground\\\":\\\"#A0A1A7cc\\\"}},{\\\"scope\\\":[\\\"meta.template.expression.js\\\",\\\"constant.name.attribute.tag.jade\\\",\\\"punctuation.definition.metadata.markdown\\\",\\\"punctuation.definition.string.end.markdown\\\",\\\"punctuation.definition.string.begin.markdown\\\"],\\\"settings\\\":{\\\"foreground\\\":\\\"#D5CED9\\\"}},{\\\"scope\\\":[\\\"variable\\\",\\\"support.variable\\\",\\\"entity.name.tag.yaml\\\",\\\"constant.character.entity.html\\\",\\\"source.css entity.name.tag.reference\\\",\\\"beginning.punctuation.definition.list.markdown\\\",\\\"source.css entity.other.attribute-name.parent-selector\\\",\\\"meta.structure.dictionary.json support.type.property-name\\\"],\\\"settings\\\":{\\\"foreground\\\":\\\"#00e8c6\\\"}},{\\\"scope\\\":[\\\"markup.bold\\\",\\\"constant.numeric\\\",\\\"meta.group.regexp\\\",\\\"constant.other.php\\\",\\\"support.constant.ext.php\\\",\\\"constant.other.class.php\\\",\\\"support.constant.core.php\\\",\\\"fenced_code.block.language\\\",\\\"constant.other.caps.python\\\",\\\"entity.other.attribute-name\\\",\\\"support.type.exception.python\\\",\\\"source.css keyword.other.unit\\\",\\\"variable.other.object.property.js.jsx\\\",\\\"variable.other.object.js\\\"],\\\"settings\\\":{\\\"foreground\\\":\\\"#f39c12\\\"}},{\\\"scope\\\":[\\\"markup.list\\\",\\\"text.xml string\\\",\\\"entity.name.type\\\",\\\"support.function\\\",\\\"entity.other.attribute-name\\\",\\\"meta.at-rule.extend\\\",\\\"entity.name.function\\\",\\\"entity.other.inherited-class\\\",\\\"entity.other.keyframe-offset.css\\\",\\\"text.html.markdown string.quoted\\\",\\\"meta.function-call.generic.python\\\",\\\"meta.at-rule.extend support.constant\\\",\\\"entity.other.attribute-name.class.jade\\\",\\\"source.css entity.other.attribute-name\\\",\\\"text.xml punctuation.definition.string\\\"],\\\"settings\\\":{\\\"foreground\\\":\\\"#FFE66D\\\"}},{\\\"scope\\\":[\\\"markup.heading\\\",\\\"variable.language.this.js\\\",\\\"variable.language.special.self.python\\\"],\\\"settings\\\":{\\\"foreground\\\":\\\"#ff00aa\\\"}},{\\\"scope\\\":[\\\"punctuation.definition.interpolation\\\",\\\"punctuation.section.embedded.end.php\\\",\\\"punctuation.section.embedded.end.ruby\\\",\\\"punctuation.section.embedded.begin.php\\\",\\\"punctuation.section.embedded.begin.ruby\\\",\\\"punctuation.definition.template-expression\\\",\\\"entity.name.tag\\\"],\\\"settings\\\":{\\\"foreground\\\":\\\"#f92672\\\"}},{\\\"scope\\\":[\\\"storage\\\",\\\"keyword\\\",\\\"meta.link\\\",\\\"meta.image\\\",\\\"markup.italic\\\",\\\"source.js support.type\\\"],\\\"settings\\\":{\\\"foreground\\\":\\\"#c74ded\\\"}},{\\\"scope\\\":[\\\"string.regexp\\\",\\\"markup.changed\\\"],\\\"settings\\\":{\\\"foreground\\\":\\\"#7cb7ff\\\"}},{\\\"scope\\\":[\\\"constant\\\",\\\"support.class\\\",\\\"keyword.operator\\\",\\\"support.constant\\\",\\\"text.html.markdown string\\\",\\\"source.css support.function\\\",\\\"source.php support.function\\\",\\\"support.function.magic.python\\\",\\\"entity.other.attribute-name.id\\\",\\\"markup.deleted\\\"],\\\"settings\\\":{\\\"foreground\\\":\\\"#ee5d43\\\"}},{\\\"scope\\\":[\\\"string\\\",\\\"text.html.php string\\\",\\\"markup.inline.raw\\\",\\\"markup.inserted\\\",\\\"punctuation.definition.string\\\",\\\"punctuation.definition.markdown\\\",\\\"text.html meta.embedded source.js string\\\",\\\"text.html.php punctuation.definition.string\\\",\\\"text.html meta.embedded source.js punctuation.definition.string\\\",\\\"text.html punctuation.definition.string\\\",\\\"text.html string\\\"],\\\"settings\\\":{\\\"foreground\\\":\\\"#96E072\\\"}},{\\\"scope\\\":[\\\"entity.other.inherited-class\\\"],\\\"settings\\\":{\\\"fontStyle\\\":\\\"underline\\\"}}],\\\"type\\\":\\\"dark\\\"}\"))\n"],"names":["andromeeda"],"mappings":"0VACA,MAAAA,EAAe,OAAO,OAAO,KAAK,MAAM,stRAAskT,CAAC","x_google_ignoreList":[0]}
|