@webiny/api-core 6.4.12-beta.4 → 6.5.0-beta.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.
Files changed (143) hide show
  1. package/ApiCoreFeature.js +0 -2
  2. package/ApiCoreFeature.js.map +1 -1
  3. package/createApiCore.d.ts +1 -1
  4. package/createApiCore.js +9 -7
  5. package/createApiCore.js.map +1 -1
  6. package/exports/api/security/api-key.d.ts +1 -0
  7. package/exports/api/security/api-key.js +1 -0
  8. package/exports/api.d.ts +2 -1
  9. package/exports/api.js +1 -1
  10. package/features/ai/Ai.d.ts +3 -1
  11. package/features/ai/Ai.js +38 -3
  12. package/features/ai/Ai.js.map +1 -1
  13. package/features/ai/AiModelRegistry.js +3 -1
  14. package/features/ai/AiModelRegistry.js.map +1 -1
  15. package/features/ai/AnthropicSdkFactory.js +24 -4
  16. package/features/ai/AnthropicSdkFactory.js.map +1 -1
  17. package/features/ai/DEVELOPERS.md +126 -0
  18. package/features/ai/GoogleSdkFactory.d.ts +10 -0
  19. package/features/ai/GoogleSdkFactory.js +65 -0
  20. package/features/ai/GoogleSdkFactory.js.map +1 -0
  21. package/features/ai/OpenAiSdkFactory.js +67 -11
  22. package/features/ai/OpenAiSdkFactory.js.map +1 -1
  23. package/features/ai/TextExtractor/DefaultTextExtractor.d.ts +9 -0
  24. package/features/ai/TextExtractor/DefaultTextExtractor.js +28 -0
  25. package/features/ai/TextExtractor/DefaultTextExtractor.js.map +1 -0
  26. package/features/ai/TextExtractor/abstractions.d.ts +12 -0
  27. package/features/ai/TextExtractor/abstractions.js +5 -0
  28. package/features/ai/TextExtractor/abstractions.js.map +1 -0
  29. package/features/ai/TextExtractor/index.d.ts +3 -0
  30. package/features/ai/TextExtractor/index.js +2 -0
  31. package/features/ai/TextExtractor/parsers/docxParser.d.ts +1 -0
  32. package/features/ai/TextExtractor/parsers/docxParser.js +111 -0
  33. package/features/ai/TextExtractor/parsers/docxParser.js.map +1 -0
  34. package/features/ai/abstractions.d.ts +4 -0
  35. package/features/ai/abstractions.js.map +1 -1
  36. package/features/ai/events.d.ts +59 -0
  37. package/features/ai/events.js +41 -0
  38. package/features/ai/events.js.map +1 -0
  39. package/features/ai/feature.js +9 -1
  40. package/features/ai/feature.js.map +1 -1
  41. package/features/ai/index.d.ts +7 -1
  42. package/features/ai/index.js +3 -0
  43. package/features/ai/toolPipeline/AiOutputToolRegistry.d.ts +11 -0
  44. package/features/ai/toolPipeline/AiOutputToolRegistry.js +31 -0
  45. package/features/ai/toolPipeline/AiOutputToolRegistry.js.map +1 -0
  46. package/features/ai/toolPipeline/AiToolPipelineRunner.d.ts +10 -0
  47. package/features/ai/toolPipeline/AiToolPipelineRunner.js +36 -0
  48. package/features/ai/toolPipeline/AiToolPipelineRunner.js.map +1 -0
  49. package/features/ai/toolPipeline/abstractions.d.ts +23 -0
  50. package/features/ai/toolPipeline/abstractions.js +7 -0
  51. package/features/ai/toolPipeline/abstractions.js.map +1 -0
  52. package/features/ai/toolPipeline/index.d.ts +2 -0
  53. package/features/ai/toolPipeline/index.js +1 -0
  54. package/features/security/apiKeys/GetApiKey/GetApiKeyUseCase.d.ts +1 -1
  55. package/features/security/apiKeys/GetApiKey/GetApiKeyUseCase.js.map +1 -1
  56. package/features/security/apiKeys/GetApiKeyBySlug/GetApiKeyBySlugUseCase.d.ts +1 -3
  57. package/features/security/apiKeys/GetApiKeyBySlug/GetApiKeyBySlugUseCase.js.map +1 -1
  58. package/features/security/apiKeys/GetApiKeyBySlug/abstractions.d.ts +1 -1
  59. package/features/security/apiKeys/GetApiKeyBySlug/abstractions.js.map +1 -1
  60. package/features/security/apiKeys/GetApiKeyByToken/GetApiKeyByTokenUseCase.d.ts +1 -3
  61. package/features/security/apiKeys/GetApiKeyByToken/GetApiKeyByTokenUseCase.js.map +1 -1
  62. package/features/security/apiKeys/GetApiKeyByToken/abstractions.d.ts +1 -1
  63. package/features/security/apiKeys/GetApiKeyByToken/abstractions.js.map +1 -1
  64. package/features/security/apiKeys/feature.js +7 -2
  65. package/features/security/apiKeys/feature.js.map +1 -1
  66. package/features/security/apiKeys/shared/ApiKeyProvider.d.ts +3 -5
  67. package/features/security/apiKeys/shared/ApiKeyProvider.js +6 -21
  68. package/features/security/apiKeys/shared/ApiKeyProvider.js.map +1 -1
  69. package/features/security/apiKeys/shared/ApiKeysRepository.d.ts +1 -0
  70. package/features/security/apiKeys/shared/ApiKeysRepository.js +19 -4
  71. package/features/security/apiKeys/shared/ApiKeysRepository.js.map +1 -1
  72. package/features/security/apiKeys/shared/generateToken.d.ts +1 -1
  73. package/features/security/apiKeys/shared/generateToken.js.map +1 -1
  74. package/features/security/apiKeys/shared/types.d.ts +1 -1
  75. package/features/security/authorization/GroupsTeamsAuthorizer/GetPermissionsFromIdentity.d.ts +1 -1
  76. package/features/security/utils/getPermissionsFromRoles.d.ts +1 -1
  77. package/features/serviceDiscovery/ServiceDiscovery.d.ts +17 -0
  78. package/features/serviceDiscovery/ServiceDiscovery.js +22 -0
  79. package/features/serviceDiscovery/ServiceDiscovery.js.map +1 -0
  80. package/features/serviceDiscovery/__tests__/ServiceDiscovery.test.js +111 -0
  81. package/features/serviceDiscovery/__tests__/ServiceDiscovery.test.js.map +1 -0
  82. package/features/serviceDiscovery/index.d.ts +3 -0
  83. package/features/serviceDiscovery/index.js +1 -0
  84. package/features/tenancy/CreateTenant/CreateTenantUseCase.d.ts +1 -1
  85. package/features/tenancy/InstallTenant/InstallTenantUseCase.d.ts +1 -1
  86. package/features/tenancy/UpdateTenant/UpdateTenantUseCase.d.ts +2 -2
  87. package/features/users/CreateUser/decorators/CreateUserWithWcpIncrement.d.ts +1 -1
  88. package/features/users/shared/loaders.js.map +1 -1
  89. package/features/wcp/WcpContext/WcpContext.d.ts +9 -0
  90. package/features/wcp/WcpContext/WcpContext.js +27 -0
  91. package/features/wcp/WcpContext/WcpContext.js.map +1 -1
  92. package/features/wcp/WcpContext/decorators/WcpContextWithFeatureFlagsDecorator.d.ts +31 -5
  93. package/features/wcp/WcpContext/decorators/WcpContextWithFeatureFlagsDecorator.js +48 -2
  94. package/features/wcp/WcpContext/decorators/WcpContextWithFeatureFlagsDecorator.js.map +1 -1
  95. package/legacy/security/plugins/apiKeyAuthentication.d.ts +1 -1
  96. package/legacy/security/plugins/apiKeyAuthorization.d.ts +1 -1
  97. package/legacy/security/plugins/authenticateUsingCookie.d.ts +1 -1
  98. package/legacy/security/plugins/authenticateUsingHttpHeader.d.ts +1 -1
  99. package/legacy/security/plugins/secureHeaders.js +0 -1
  100. package/legacy/security/plugins/secureHeaders.js.map +1 -1
  101. package/legacy/wcp/LegacyWcpContext.d.ts +9 -0
  102. package/legacy/wcp/LegacyWcpContext.js +27 -0
  103. package/legacy/wcp/LegacyWcpContext.js.map +1 -1
  104. package/package.json +24 -25
  105. package/types/security.d.ts +1 -1
  106. package/features/debugger/Debugger.d.ts +0 -23
  107. package/features/debugger/Debugger.js +0 -134
  108. package/features/debugger/Debugger.js.map +0 -1
  109. package/features/debugger/GraphQLDebuggerTransport.d.ts +0 -26
  110. package/features/debugger/GraphQLDebuggerTransport.js +0 -45
  111. package/features/debugger/GraphQLDebuggerTransport.js.map +0 -1
  112. package/features/debugger/__tests__/matchNamespace.test.js +0 -67
  113. package/features/debugger/__tests__/matchNamespace.test.js.map +0 -1
  114. package/features/debugger/__tests__/serialize.test.d.ts +0 -1
  115. package/features/debugger/__tests__/serialize.test.js +0 -220
  116. package/features/debugger/__tests__/serialize.test.js.map +0 -1
  117. package/features/debugger/abstractions.d.ts +0 -100
  118. package/features/debugger/abstractions.js +0 -6
  119. package/features/debugger/abstractions.js.map +0 -1
  120. package/features/debugger/feature.d.ts +0 -5
  121. package/features/debugger/feature.js +0 -15
  122. package/features/debugger/feature.js.map +0 -1
  123. package/features/debugger/index.d.ts +0 -7
  124. package/features/debugger/index.js +0 -7
  125. package/features/debugger/limits.d.ts +0 -18
  126. package/features/debugger/limits.js +0 -11
  127. package/features/debugger/limits.js.map +0 -1
  128. package/features/debugger/matchNamespace.d.ts +0 -21
  129. package/features/debugger/matchNamespace.js +0 -48
  130. package/features/debugger/matchNamespace.js.map +0 -1
  131. package/features/debugger/permissions.d.ts +0 -33
  132. package/features/debugger/permissions.js +0 -12
  133. package/features/debugger/permissions.js.map +0 -1
  134. package/features/debugger/permissionsSchema.d.ts +0 -17
  135. package/features/debugger/permissionsSchema.js +0 -18
  136. package/features/debugger/permissionsSchema.js.map +0 -1
  137. package/features/debugger/plugins.d.ts +0 -4
  138. package/features/debugger/plugins.js +0 -82
  139. package/features/debugger/plugins.js.map +0 -1
  140. package/features/debugger/serialize.d.ts +0 -11
  141. package/features/debugger/serialize.js +0 -121
  142. package/features/debugger/serialize.js.map +0 -1
  143. /package/features/{debugger/__tests__/matchNamespace.test.d.ts → serviceDiscovery/__tests__/ServiceDiscovery.test.d.ts} +0 -0
@@ -1,82 +0,0 @@
1
- import { Request, RequestId, createBeforeHandlerPlugin, createHandlerResultPlugin } from "@webiny/handler";
2
- import { Debugger } from "./abstractions.js";
3
- import { IdentityContext } from "../security/IdentityContext/index.js";
4
- import { parseNamespaceHeader } from "./matchNamespace.js";
5
- import { canCaptureDebugData } from "./permissions.js";
6
- import { GRAPHQL_TARGET } from "./GraphQLDebuggerTransport.js";
7
- const DEBUG_HEADER = "x-webiny-debug";
8
- const DEBUG_PERMISSION = "dev-tools.debug";
9
- const isPlainObject = (value)=>"object" == typeof value && null !== value && !Array.isArray(value);
10
- const isGraphQLResult = (value)=>isPlainObject(value) && ("data" in value || "errors" in value);
11
- const resolveTarget = (payload)=>{
12
- const candidate = Array.isArray(payload) ? payload.at(-1) : payload;
13
- return isGraphQLResult(candidate) ? candidate : void 0;
14
- };
15
- const readOperationNames = (body)=>{
16
- const operations = Array.isArray(body) ? body : [
17
- body
18
- ];
19
- return operations.map((operation)=>isPlainObject(operation) && "string" == typeof operation.operationName ? operation.operationName : void 0).filter((name)=>Boolean(name));
20
- };
21
- const createStartPlugin = ()=>createBeforeHandlerPlugin(async (context)=>{
22
- try {
23
- const request = context.container.resolve(Request);
24
- const requested = parseNamespaceHeader(request.headers[DEBUG_HEADER]);
25
- const namespaces = requested.length > 0 ? requested : [
26
- "*"
27
- ];
28
- context.container.resolve(Debugger).start({
29
- namespaces
30
- });
31
- } catch {}
32
- });
33
- const createFlushPlugin = ()=>createHandlerResultPlugin(async (context, payload)=>{
34
- try {
35
- const debuggerService = context.container.resolve(Debugger);
36
- const identityContext = context.container.resolve(IdentityContext);
37
- const result = resolveTarget(payload);
38
- if (!result) {
39
- debuggerService.discard();
40
- return payload;
41
- }
42
- if (identityContext.getIdentity().isAnonymous()) {
43
- debuggerService.discard();
44
- return payload;
45
- }
46
- const isAuthorized = identityContext.isAuthorizationEnabled() && await canCaptureDebugData(identityContext);
47
- if (!isAuthorized) {
48
- debuggerService.discard();
49
- return payload;
50
- }
51
- let operations = [];
52
- let requestId = "";
53
- let url = "";
54
- try {
55
- const request = context.container.resolve(Request);
56
- operations = readOperationNames(request.body);
57
- requestId = context.container.resolve(RequestId).value;
58
- url = request.url || "";
59
- } catch {}
60
- const target = {
61
- type: GRAPHQL_TARGET,
62
- result,
63
- requestId,
64
- operations,
65
- url
66
- };
67
- await debuggerService.flush(target);
68
- } catch (ex) {
69
- console.error("Debugger failed to flush.", ex instanceof Error ? `${ex.name}: ${ex.message}` : "Unknown error.");
70
- try {
71
- context.container.resolve(Debugger).discard();
72
- } catch {}
73
- }
74
- return payload;
75
- });
76
- const createDebuggerPlugins = ()=>[
77
- createStartPlugin(),
78
- createFlushPlugin()
79
- ];
80
- export { DEBUG_HEADER, DEBUG_PERMISSION, createDebuggerPlugins };
81
-
82
- //# sourceMappingURL=plugins.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"features/debugger/plugins.js","sources":["../../../src/features/debugger/plugins.ts"],"sourcesContent":["import {\n createBeforeHandlerPlugin,\n createHandlerResultPlugin,\n Request,\n RequestId\n} from \"@webiny/handler\";\nimport type { PluginCollection } from \"@webiny/plugins/types.js\";\nimport type { Context } from \"@webiny/handler/types.js\";\nimport { Debugger } from \"./abstractions.js\";\nimport { IdentityContext } from \"~/features/security/IdentityContext/index.js\";\nimport { parseNamespaceHeader } from \"./matchNamespace.js\";\nimport { canCaptureDebugData } from \"./permissions.js\";\nimport { GRAPHQL_TARGET, type IGraphQLDeliveryTarget } from \"./GraphQLDebuggerTransport.js\";\n\nexport const DEBUG_HEADER = \"x-webiny-debug\";\nexport const DEBUG_PERMISSION = \"dev-tools.debug\";\n\nconst isPlainObject = (value: unknown): value is Record<string, any> => {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n};\n\n/**\n * A GraphQL result carries `data` or `errors`. Anything else - asset delivery, a plain string body -\n * is not ours to write to.\n */\nconst isGraphQLResult = (value: unknown): value is Record<string, any> => {\n return isPlainObject(value) && (\"data\" in value || \"errors\" in value);\n};\n\n/**\n * Batched requests produce an array of results. The session spans the whole HTTP request, so it is\n * attached once, to the last element - duplicating it per operation would multiply it against the\n * byte budget.\n */\nconst resolveTarget = (payload: unknown): Record<string, any> | undefined => {\n const candidate = Array.isArray(payload) ? payload.at(-1) : payload;\n return isGraphQLResult(candidate) ? candidate : undefined;\n};\n\nconst readOperationNames = (body: unknown): string[] => {\n const operations = Array.isArray(body) ? body : [body];\n return operations\n .map(operation => {\n return isPlainObject(operation) && typeof operation.operationName === \"string\"\n ? operation.operationName\n : undefined;\n })\n .filter((name): name is string => Boolean(name));\n};\n\n/**\n * Opens the capture session.\n *\n * Runs as a `BeforeHandlerPlugin`, so it is in place before the route handler and therefore before\n * any resolver. Note that `ContextPlugin`s run earlier still, so anything logged from one of those\n * is not captured.\n */\nconst createStartPlugin = () => {\n return createBeforeHandlerPlugin<Context>(async context => {\n /**\n * Must never throw: `ProcessBeforeHandlerPlugins` rethrows, which would turn a malformed\n * header into a 500 for the whole request.\n */\n try {\n const request = context.container.resolve(Request);\n\n /**\n * A session starts on every request, and the permission check at flush decides whether\n * anything is delivered or the whole thing is discarded.\n *\n * Nothing is required from the client. Asking for a request header would mean putting it\n * on the CORS allow-list, which is cached in preflight responses at CloudFront and in\n * the browser for a day - so rolling one out breaks requests intermittently until every\n * cache entry expires.\n *\n * The header is still honoured when present, so a direct API client can narrow what it\n * captures.\n */\n const requested = parseNamespaceHeader(request.headers[DEBUG_HEADER]);\n const namespaces = requested.length > 0 ? requested : [\"*\"];\n\n context.container.resolve(Debugger).start({ namespaces });\n } catch {\n // A debugger that cannot start is not a reason to fail the request.\n }\n });\n};\n\n/**\n * Performs the permission gate and hands the session to the transports.\n *\n * This runs once per HTTP response, in the `preSerialization` hook - deliberately not in\n * `graphql-after-query`, which also fires for the nested executions that CMS resolvers perform\n * internally and would attach the session to a result that is then discarded.\n */\nconst createFlushPlugin = () => {\n return createHandlerResultPlugin<Context>(async (context, payload) => {\n /**\n * The whole body is guarded: `preSerialization` rethrows whatever a `HandlerResultPlugin`\n * throws, so an error here would turn a working response into a 500 - and only for requests\n * that asked for debugging.\n */\n try {\n const debuggerService = context.container.resolve(Debugger);\n const identityContext = context.container.resolve(IdentityContext);\n\n const result = resolveTarget(payload);\n if (!result) {\n debuggerService.discard();\n return payload;\n }\n\n /**\n * Anonymous callers are rejected before permissions are resolved: `getPermission` runs\n * every registered Authorizer, some of which hit the database.\n */\n if (identityContext.getIdentity().isAnonymous()) {\n debuggerService.discard();\n return payload;\n }\n\n /**\n * `getPermission` returns a wildcard permission whenever authorization is disabled, so a\n * flush occurring inside a `withoutAuthorization` scope would pass for anyone.\n */\n const isAuthorized =\n identityContext.isAuthorizationEnabled() &&\n (await canCaptureDebugData(identityContext));\n\n if (!isAuthorized) {\n /**\n * Nothing is written. Reporting the denial would tell every unauthorized caller that\n * the feature exists, and the Admin app already knows from the identity's own\n * permissions whether capture is available to it.\n */\n debuggerService.discard();\n return payload;\n }\n\n let operations: string[] = [];\n let requestId = \"\";\n let url = \"\";\n try {\n const request = context.container.resolve(Request);\n operations = readOperationNames(request.body);\n requestId = context.container.resolve(RequestId).value;\n /**\n * Which endpoint this was. An Admin session talks to several - the main API and the\n * CMS manage, read and preview endpoints - and knowing which one produced an entry\n * is most of the context when reading a report.\n */\n url = request.url || \"\";\n } catch {\n // All three are conveniences; their absence must not stop the flush.\n }\n\n const target: IGraphQLDeliveryTarget = {\n type: GRAPHQL_TARGET,\n result,\n requestId,\n operations,\n url\n };\n\n await debuggerService.flush(target);\n } catch (ex) {\n /**\n * Only the message - never the session or the payload.\n */\n console.error(\n \"Debugger failed to flush.\",\n ex instanceof Error ? `${ex.name}: ${ex.message}` : \"Unknown error.\"\n );\n try {\n context.container.resolve(Debugger).discard();\n } catch {\n // Nothing further to do.\n }\n }\n\n /**\n * `preSerialization` ignores this return value and serializes the original payload object,\n * so every write above mutates `result` in place.\n */\n return payload;\n });\n};\n\nexport const createDebuggerPlugins = (): PluginCollection => {\n return [createStartPlugin(), createFlushPlugin()];\n};\n"],"names":["DEBUG_HEADER","DEBUG_PERMISSION","isPlainObject","value","Array","isGraphQLResult","resolveTarget","payload","candidate","undefined","readOperationNames","body","operations","operation","name","Boolean","createStartPlugin","createBeforeHandlerPlugin","context","request","Request","requested","parseNamespaceHeader","namespaces","Debugger","createFlushPlugin","createHandlerResultPlugin","debuggerService","identityContext","IdentityContext","result","isAuthorized","canCaptureDebugData","requestId","url","RequestId","target","GRAPHQL_TARGET","ex","console","Error","createDebuggerPlugins"],"mappings":";;;;;;AAcO,MAAMA,eAAe;AACrB,MAAMC,mBAAmB;AAEhC,MAAMC,gBAAgB,CAACC,QACZ,AAAiB,YAAjB,OAAOA,SAAsBA,AAAU,SAAVA,SAAkB,CAACC,MAAM,OAAO,CAACD;AAOzE,MAAME,kBAAkB,CAACF,QACdD,cAAcC,UAAW,WAAUA,SAAS,YAAYA,KAAI;AAQvE,MAAMG,gBAAgB,CAACC;IACnB,MAAMC,YAAYJ,MAAM,OAAO,CAACG,WAAWA,QAAQ,EAAE,CAAC,MAAMA;IAC5D,OAAOF,gBAAgBG,aAAaA,YAAYC;AACpD;AAEA,MAAMC,qBAAqB,CAACC;IACxB,MAAMC,aAAaR,MAAM,OAAO,CAACO,QAAQA,OAAO;QAACA;KAAK;IACtD,OAAOC,WACF,GAAG,CAACC,CAAAA,YACMX,cAAcW,cAAc,AAAmC,YAAnC,OAAOA,UAAU,aAAa,GAC3DA,UAAU,aAAa,GACvBJ,QAET,MAAM,CAAC,CAACK,OAAyBC,QAAQD;AAClD;AASA,MAAME,oBAAoB,IACfC,0BAAmC,OAAMC;QAK5C,IAAI;YACA,MAAMC,UAAUD,QAAQ,SAAS,CAAC,OAAO,CAACE;YAc1C,MAAMC,YAAYC,qBAAqBH,QAAQ,OAAO,CAACnB,aAAa;YACpE,MAAMuB,aAAaF,UAAU,MAAM,GAAG,IAAIA,YAAY;gBAAC;aAAI;YAE3DH,QAAQ,SAAS,CAAC,OAAO,CAACM,UAAU,KAAK,CAAC;gBAAED;YAAW;QAC3D,EAAE,OAAM,CAER;IACJ;AAUJ,MAAME,oBAAoB,IACfC,0BAAmC,OAAOR,SAASX;QAMtD,IAAI;YACA,MAAMoB,kBAAkBT,QAAQ,SAAS,CAAC,OAAO,CAACM;YAClD,MAAMI,kBAAkBV,QAAQ,SAAS,CAAC,OAAO,CAACW;YAElD,MAAMC,SAASxB,cAAcC;YAC7B,IAAI,CAACuB,QAAQ;gBACTH,gBAAgB,OAAO;gBACvB,OAAOpB;YACX;YAMA,IAAIqB,gBAAgB,WAAW,GAAG,WAAW,IAAI;gBAC7CD,gBAAgB,OAAO;gBACvB,OAAOpB;YACX;YAMA,MAAMwB,eACFH,gBAAgB,sBAAsB,MACrC,MAAMI,oBAAoBJ;YAE/B,IAAI,CAACG,cAAc;gBAMfJ,gBAAgB,OAAO;gBACvB,OAAOpB;YACX;YAEA,IAAIK,aAAuB,EAAE;YAC7B,IAAIqB,YAAY;YAChB,IAAIC,MAAM;YACV,IAAI;gBACA,MAAMf,UAAUD,QAAQ,SAAS,CAAC,OAAO,CAACE;gBAC1CR,aAAaF,mBAAmBS,QAAQ,IAAI;gBAC5Cc,YAAYf,QAAQ,SAAS,CAAC,OAAO,CAACiB,WAAW,KAAK;gBAMtDD,MAAMf,QAAQ,GAAG,IAAI;YACzB,EAAE,OAAM,CAER;YAEA,MAAMiB,SAAiC;gBACnC,MAAMC;gBACNP;gBACAG;gBACArB;gBACAsB;YACJ;YAEA,MAAMP,gBAAgB,KAAK,CAACS;QAChC,EAAE,OAAOE,IAAI;YAITC,QAAQ,KAAK,CACT,6BACAD,cAAcE,QAAQ,GAAGF,GAAG,IAAI,CAAC,EAAE,EAAEA,GAAG,OAAO,EAAE,GAAG;YAExD,IAAI;gBACApB,QAAQ,SAAS,CAAC,OAAO,CAACM,UAAU,OAAO;YAC/C,EAAE,OAAM,CAER;QACJ;QAMA,OAAOjB;IACX;AAGG,MAAMkC,wBAAwB,IAC1B;QAACzB;QAAqBS;KAAoB"}
@@ -1,11 +0,0 @@
1
- import type { IDebuggerLimits } from "./limits.js";
2
- export interface ISerializeResult {
3
- json: string;
4
- bytes: number;
5
- /** True if the value was replaced by the per-entry cap marker. */
6
- truncated: boolean;
7
- }
8
- /**
9
- * Serializes a captured payload to JSON, never throwing and always producing valid JSON.
10
- */
11
- export declare const serialize: (value: unknown, limits: IDebuggerLimits) => ISerializeResult;
@@ -1,121 +0,0 @@
1
- const UNDEFINED = "#[Undefined value]";
2
- const CIRCULAR = "#[Circular]";
3
- const DEPTH_LIMIT = "#[Depth limit]";
4
- const isPlainValue = (value)=>{
5
- const type = typeof value;
6
- return "string" === type || "number" === type || "boolean" === type || null === value;
7
- };
8
- const describeBinary = (value)=>{
9
- const name = value.constructor?.name || "TypedArray";
10
- return `#[${name} ${value.byteLength} bytes]`;
11
- };
12
- const walk = (value, limits, seen, depth)=>{
13
- if (void 0 === value) return UNDEFINED;
14
- if (isPlainValue(value)) {
15
- if ("string" == typeof value && value.length > limits.stringLength) {
16
- const kept = value.slice(0, limits.stringLength);
17
- return `${kept}…(${value.length - limits.stringLength} more)`;
18
- }
19
- if ("number" == typeof value && !Number.isFinite(value)) return String(value);
20
- return value;
21
- }
22
- if ("bigint" == typeof value) return `${value.toString()}n`;
23
- if ("symbol" == typeof value) return String(value);
24
- if ("function" == typeof value) return `#[Function: ${value.name || "anonymous"}]`;
25
- if (value instanceof Error) return {
26
- name: value.name,
27
- message: value.message,
28
- stack: value.stack
29
- };
30
- if (value instanceof Date) return value.toISOString();
31
- if (value instanceof RegExp) return value.toString();
32
- if (ArrayBuffer.isView(value)) return describeBinary(value);
33
- if (value instanceof ArrayBuffer) return `#[ArrayBuffer ${value.byteLength} bytes]`;
34
- if (depth >= limits.depth) return DEPTH_LIMIT;
35
- if ("object" != typeof value || null === value) return String(value);
36
- if (seen.has(value)) return CIRCULAR;
37
- seen.add(value);
38
- try {
39
- if (Array.isArray(value)) {
40
- const kept = value.slice(0, limits.arrayLength).map((item)=>walk(item, limits, seen, depth + 1));
41
- if (value.length > limits.arrayLength) kept.push(`…(${value.length - limits.arrayLength} more items)`);
42
- return kept;
43
- }
44
- if (value instanceof Map) {
45
- const entries = [];
46
- for (const [key, item] of value.entries()){
47
- if (entries.length >= limits.arrayLength) {
48
- entries.push(`…(${value.size - limits.arrayLength} more entries)`);
49
- break;
50
- }
51
- entries.push([
52
- walk(key, limits, seen, depth + 1),
53
- walk(item, limits, seen, depth + 1)
54
- ]);
55
- }
56
- return {
57
- __type: "Map",
58
- entries
59
- };
60
- }
61
- if (value instanceof Set) {
62
- const items = [];
63
- for (const item of value.values()){
64
- if (items.length >= limits.arrayLength) {
65
- items.push(`…(${value.size - limits.arrayLength} more items)`);
66
- break;
67
- }
68
- items.push(walk(item, limits, seen, depth + 1));
69
- }
70
- return {
71
- __type: "Set",
72
- items
73
- };
74
- }
75
- const result = {};
76
- for (const key of Object.keys(value)){
77
- let item;
78
- try {
79
- item = value[key];
80
- } catch (ex) {
81
- result[key] = `#[Throws: ${ex instanceof Error ? ex.message : String(ex)}]`;
82
- continue;
83
- }
84
- if (void 0 !== item) result[key] = walk(item, limits, seen, depth + 1);
85
- }
86
- return result;
87
- } finally{
88
- seen.delete(value);
89
- }
90
- };
91
- const serialize = (value, limits)=>{
92
- let json;
93
- try {
94
- const walked = walk(value, limits, new WeakSet(), 0);
95
- json = JSON.stringify(walked) ?? JSON.stringify(UNDEFINED);
96
- } catch (ex) {
97
- const message = ex instanceof Error ? ex.message : String(ex);
98
- json = JSON.stringify({
99
- __serializationFailed: true,
100
- message
101
- });
102
- }
103
- let bytes = Buffer.byteLength(json, "utf8");
104
- let truncated = false;
105
- if (bytes > limits.entryBytes) {
106
- json = JSON.stringify({
107
- truncated: true,
108
- originalBytes: bytes
109
- });
110
- bytes = Buffer.byteLength(json, "utf8");
111
- truncated = true;
112
- }
113
- return {
114
- json,
115
- bytes,
116
- truncated
117
- };
118
- };
119
- export { serialize };
120
-
121
- //# sourceMappingURL=serialize.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"features/debugger/serialize.js","sources":["../../../src/features/debugger/serialize.ts"],"sourcesContent":["import type { IDebuggerLimits } from \"./limits.js\";\n\nexport interface ISerializeResult {\n json: string;\n bytes: number;\n /** True if the value was replaced by the per-entry cap marker. */\n truncated: boolean;\n}\n\n/**\n * Markers stand in for values that cannot be represented as JSON.\n *\n * They are prefixed with `#` so a reader can tell at a glance that a value was substituted by the\n * serializer rather than being what the code actually held - the previous `[undefined]` read as an\n * array literal in documents that are full of real arrays.\n */\nconst UNDEFINED = \"#[Undefined value]\";\nconst CIRCULAR = \"#[Circular]\";\nconst DEPTH_LIMIT = \"#[Depth limit]\";\n\nconst isPlainValue = (value: unknown): boolean => {\n const type = typeof value;\n return type === \"string\" || type === \"number\" || type === \"boolean\" || value === null;\n};\n\nconst describeBinary = (value: ArrayBufferView): string => {\n const name = value.constructor?.name || \"TypedArray\";\n return `#[${name} ${value.byteLength} bytes]`;\n};\n\n/**\n * Walks a value into a JSON-safe structure, applying depth, string and array caps as it goes.\n *\n * Caps are applied during the walk rather than by slicing the finished JSON string, so the output is\n * always parseable.\n *\n * A custom `toJSON` is never invoked - own properties are enumerated instead. That means an object\n * is reported as its internals rather than its intended representation, which is what you want when\n * debugging, and it removes a whole class of failure where a third-party `toJSON` throws.\n */\nconst walk = (\n value: unknown,\n limits: IDebuggerLimits,\n seen: WeakSet<object>,\n depth: number\n): unknown => {\n if (value === undefined) {\n /**\n * Only reached for array elements and for a top-level payload. Object properties holding\n * `undefined` are dropped before they get here, matching `JSON.stringify`.\n *\n * Inside an array the element cannot be dropped without shifting every later index, and\n * `JSON.stringify` would turn it into `null` - which is a meaningful value in its own right.\n */\n return UNDEFINED;\n }\n\n if (isPlainValue(value)) {\n if (typeof value === \"string\" && value.length > limits.stringLength) {\n const kept = value.slice(0, limits.stringLength);\n return `${kept}…(${value.length - limits.stringLength} more)`;\n }\n /**\n * Infinity and NaN serialize to `null`, which silently loses the distinction. Keep them\n * readable instead.\n */\n if (typeof value === \"number\" && !Number.isFinite(value)) {\n return String(value);\n }\n return value;\n }\n\n if (typeof value === \"bigint\") {\n return `${value.toString()}n`;\n }\n\n if (typeof value === \"symbol\") {\n return String(value);\n }\n\n if (typeof value === \"function\") {\n return `#[Function: ${value.name || \"anonymous\"}]`;\n }\n\n if (value instanceof Error) {\n return {\n name: value.name,\n message: value.message,\n stack: value.stack\n };\n }\n\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n if (value instanceof RegExp) {\n return value.toString();\n }\n\n if (ArrayBuffer.isView(value)) {\n return describeBinary(value);\n }\n\n if (value instanceof ArrayBuffer) {\n return `#[ArrayBuffer ${value.byteLength} bytes]`;\n }\n\n if (depth >= limits.depth) {\n return DEPTH_LIMIT;\n }\n\n if (typeof value !== \"object\" || value === null) {\n return String(value);\n }\n\n if (seen.has(value)) {\n return CIRCULAR;\n }\n seen.add(value);\n\n try {\n if (Array.isArray(value)) {\n const kept = value.slice(0, limits.arrayLength).map(item => {\n return walk(item, limits, seen, depth + 1);\n });\n if (value.length > limits.arrayLength) {\n kept.push(`…(${value.length - limits.arrayLength} more items)`);\n }\n return kept;\n }\n\n if (value instanceof Map) {\n const entries: unknown[] = [];\n for (const [key, item] of value.entries()) {\n if (entries.length >= limits.arrayLength) {\n entries.push(`…(${value.size - limits.arrayLength} more entries)`);\n break;\n }\n entries.push([\n walk(key, limits, seen, depth + 1),\n walk(item, limits, seen, depth + 1)\n ]);\n }\n return { __type: \"Map\", entries };\n }\n\n if (value instanceof Set) {\n const items: unknown[] = [];\n for (const item of value.values()) {\n if (items.length >= limits.arrayLength) {\n items.push(`…(${value.size - limits.arrayLength} more items)`);\n break;\n }\n items.push(walk(item, limits, seen, depth + 1));\n }\n return { __type: \"Set\", items };\n }\n\n const result: Record<string, unknown> = {};\n for (const key of Object.keys(value)) {\n /**\n * A getter can throw. One bad property must not take down the whole entry, let alone the\n * request that is being observed.\n */\n let item: unknown;\n try {\n item = (value as Record<string, unknown>)[key];\n } catch (ex) {\n result[key] = `#[Throws: ${ex instanceof Error ? ex.message : String(ex)}]`;\n continue;\n }\n\n /**\n * Drop the key, as `JSON.stringify` does.\n *\n * Captured payloads are frequently copies of something that went over the wire, and the\n * wire never carried these keys - keeping them would describe a request that was never\n * made.\n */\n if (item === undefined) {\n continue;\n }\n\n result[key] = walk(item, limits, seen, depth + 1);\n }\n return result;\n } finally {\n /**\n * Only guard against cycles along the current branch. Without this, a value referenced twice\n * as siblings would report the second one as circular.\n */\n seen.delete(value);\n }\n};\n\n/**\n * Serializes a captured payload to JSON, never throwing and always producing valid JSON.\n */\nexport const serialize = (value: unknown, limits: IDebuggerLimits): ISerializeResult => {\n let json: string;\n\n try {\n const walked = walk(value, limits, new WeakSet(), 0);\n json = JSON.stringify(walked) ?? JSON.stringify(UNDEFINED);\n } catch (ex) {\n const message = ex instanceof Error ? ex.message : String(ex);\n json = JSON.stringify({ __serializationFailed: true, message });\n }\n\n let bytes = Buffer.byteLength(json, \"utf8\");\n let truncated = false;\n\n if (bytes > limits.entryBytes) {\n /**\n * Slicing the string would produce invalid JSON, so the payload is replaced wholesale.\n */\n json = JSON.stringify({ truncated: true, originalBytes: bytes });\n bytes = Buffer.byteLength(json, \"utf8\");\n truncated = true;\n }\n\n return { json, bytes, truncated };\n};\n"],"names":["UNDEFINED","CIRCULAR","DEPTH_LIMIT","isPlainValue","value","type","describeBinary","name","walk","limits","seen","depth","undefined","kept","Number","String","Error","Date","RegExp","ArrayBuffer","Array","item","Map","entries","key","Set","items","result","Object","ex","serialize","json","walked","WeakSet","JSON","message","bytes","Buffer","truncated"],"mappings":"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"}