@hubspot/ui-extensions-dev-server 1.1.8 → 2.0.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 (184) hide show
  1. package/dist/lib/DevModeParentInterface.js +5 -6
  2. package/dist/lib/DevModeUnifiedInterface.js +2 -2
  3. package/dist/lib/DevServerState.d.ts +14 -4
  4. package/dist/lib/DevServerState.js +34 -1
  5. package/dist/lib/__tests__/DevModeParentInterface.spec.js +42 -1
  6. package/dist/lib/__tests__/DevModeUnifiedInterface.spec.js +34 -0
  7. package/dist/lib/__tests__/DevServerState.spec.js +180 -0
  8. package/dist/lib/__tests__/{app-functions/errorReporter.spec.js → errorReporter.spec.js} +5 -5
  9. package/dist/lib/__tests__/extensionsService.spec.js +57 -9
  10. package/dist/lib/__tests__/factories.d.ts +1 -1
  11. package/dist/lib/__tests__/factories.js +1 -1
  12. package/dist/lib/__tests__/fixtures/extensionConfig.js +3 -0
  13. package/dist/lib/__tests__/plugins/devBuildPlugin.spec.js +1 -1
  14. package/dist/lib/__tests__/{app-functions/services → proxy}/AppProxyService.spec.js +73 -3
  15. package/dist/lib/__tests__/{app-functions → proxy}/signing.spec.js +1 -1
  16. package/dist/lib/__tests__/server.spec.js +14 -11
  17. package/dist/lib/__tests__/serverless/config.spec.js +61 -0
  18. package/dist/lib/__tests__/{app-functions → serverless}/context.spec.js +2 -2
  19. package/dist/lib/__tests__/serverless/executor_unsupported.spec.js +37 -0
  20. package/dist/lib/__tests__/{app-functions/executor_v20232.spec.js → serverless/executor_v20251.spec.js} +6 -13
  21. package/dist/lib/__tests__/{app-functions/executor_v20231.spec.js → serverless/executor_v202603.spec.js} +26 -11
  22. package/dist/lib/__tests__/{app-functions → serverless}/fixtures/constants.d.ts +4 -3
  23. package/dist/lib/__tests__/{app-functions → serverless}/fixtures/constants.js +9 -3
  24. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-async-fails.cjs +5 -0
  25. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-async-fails.d.cts +1 -0
  26. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-async-succeeds.cjs +5 -0
  27. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-async-succeeds.d.cts +3 -0
  28. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-does-not-export-main.cjs +4 -0
  29. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-does-not-export-main.d.cts +1 -0
  30. package/dist/lib/__tests__/{app-functions/fixtures/v2023.1/app.functions → serverless/fixtures/v2026.03/functions}/func-echos-input.cjs +3 -3
  31. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-echos-input.d.cts +5 -0
  32. package/dist/lib/__tests__/{app-functions/fixtures/v2023.1/app.functions → serverless/fixtures/v2026.03/functions}/func-logs.cjs +2 -2
  33. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-logs.d.cts +3 -0
  34. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-returns-function.cjs +4 -0
  35. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-returns-function.d.cts +1 -0
  36. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-returns-implicitly.cjs +7 -0
  37. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-returns-implicitly.d.cts +1 -0
  38. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-returns-promise-rejected.cjs +4 -0
  39. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-returns-promise-rejected.d.cts +1 -0
  40. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-returns-promise-resolved.cjs +4 -0
  41. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-returns-promise-resolved.d.cts +3 -0
  42. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-returns-text.cjs +4 -0
  43. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-returns-text.d.cts +1 -0
  44. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-returns-undefined.cjs +4 -0
  45. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-returns-undefined.d.cts +1 -0
  46. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-times-out.cjs +12 -0
  47. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-times-out.d.cts +1 -0
  48. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-undeclared.cjs +4 -0
  49. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-undeclared.d.cts +1 -0
  50. package/dist/lib/__tests__/{app-functions/fixtures/v2023.1/app.functions → serverless/fixtures/v2026.03/functions}/func-uses-secret.cjs +3 -3
  51. package/dist/lib/__tests__/serverless/fixtures/v2026.03/functions/func-uses-secret.d.cts +4 -0
  52. package/dist/lib/__tests__/{app-functions → serverless}/secrets.spec.js +4 -4
  53. package/dist/lib/__tests__/{app-functions → serverless}/services/PrivateAppUserTokenManager.spec.js +4 -4
  54. package/dist/lib/__tests__/serverless/services/services_v20251.spec.d.ts +1 -0
  55. package/dist/lib/__tests__/{app-functions/services/services_v20232.spec.js → serverless/services/services_v20251.spec.js} +9 -63
  56. package/dist/lib/__tests__/serverless/services/services_v202603.spec.d.ts +1 -0
  57. package/dist/lib/__tests__/{app-functions/services/services_v20231.spec.js → serverless/services/services_v202603.spec.js} +18 -91
  58. package/dist/lib/__tests__/serverless/setup.d.ts +1 -0
  59. package/dist/lib/__tests__/utils.spec.js +26 -1
  60. package/dist/lib/constants.d.ts +2 -2
  61. package/dist/lib/constants.js +2 -2
  62. package/dist/lib/{app-functions/errorReporter.js → errorReporter.js} +2 -2
  63. package/dist/lib/extensionsService.js +6 -0
  64. package/dist/lib/{app-functions/services → proxy}/AppProxyService.d.ts +1 -1
  65. package/dist/lib/{app-functions/services → proxy}/AppProxyService.js +15 -4
  66. package/dist/lib/proxy/constants.d.ts +13 -0
  67. package/dist/lib/{app-functions → proxy}/constants.js +0 -18
  68. package/dist/lib/proxy/types.d.ts +44 -0
  69. package/dist/lib/proxy/types.js +1 -0
  70. package/dist/lib/server.js +2 -1
  71. package/dist/lib/serverless/config.js +100 -0
  72. package/dist/lib/serverless/constants.d.ts +7 -0
  73. package/dist/lib/serverless/constants.js +12 -0
  74. package/dist/lib/{app-functions → serverless}/errors.d.ts +1 -0
  75. package/dist/lib/{app-functions → serverless}/errors.js +6 -0
  76. package/dist/lib/{app-functions → serverless}/executor.js +19 -13
  77. package/dist/lib/serverless/secrets.d.ts +5 -0
  78. package/dist/lib/{app-functions → serverless}/services/AppFunctionExecutionService.js +1 -1
  79. package/dist/lib/{app-functions → serverless}/services/PrivateAppUserTokenManager.js +1 -1
  80. package/dist/lib/{app-functions → serverless}/types.d.ts +1 -44
  81. package/dist/lib/types.d.ts +12 -3
  82. package/dist/lib/types.js +7 -2
  83. package/dist/lib/utils.d.ts +2 -1
  84. package/dist/lib/utils.js +3 -0
  85. package/package.json +8 -5
  86. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-async-fails.cjs +0 -8
  87. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-async-fails.d.cts +0 -1
  88. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-async-succeeds.cjs +0 -8
  89. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-async-succeeds.d.cts +0 -1
  90. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-callback-on-promise-rejected.cjs +0 -8
  91. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-callback-on-promise-resolved.cjs +0 -8
  92. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-callback-on-promise-resolved.d.cts +0 -1
  93. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-does-not-export-main.cjs +0 -4
  94. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-does-not-export-main.d.cts +0 -1
  95. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-echos-input.d.cts +0 -1
  96. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-logs.d.cts +0 -1
  97. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-returns-function.cjs +0 -4
  98. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-returns-function.d.cts +0 -1
  99. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-returns-promise-rejected.cjs +0 -7
  100. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-returns-promise-rejected.d.cts +0 -1
  101. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-returns-promise-resolved.cjs +0 -7
  102. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-returns-promise-resolved.d.cts +0 -1
  103. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-returns-text.d.cts +0 -1
  104. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-returns-undefined.cjs +0 -4
  105. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-returns-undefined.d.cts +0 -1
  106. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-times-out.cjs +0 -10
  107. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-times-out.d.cts +0 -1
  108. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-undeclared.cjs +0 -4
  109. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-undeclared.d.cts +0 -1
  110. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-uses-secret.d.cts +0 -1
  111. package/dist/lib/app-functions/config.js +0 -48
  112. package/dist/lib/app-functions/constants.d.ts +0 -26
  113. package/dist/lib/app-functions/index.d.ts +0 -4
  114. package/dist/lib/app-functions/index.js +0 -4
  115. package/dist/lib/app-functions/secrets.d.ts +0 -5
  116. package/dist/lib/app-functions/services/index.d.ts +0 -3
  117. package/dist/lib/app-functions/services/index.js +0 -3
  118. /package/dist/lib/__tests__/{app-functions/context.spec.d.ts → DevServerState.spec.d.ts} +0 -0
  119. /package/dist/lib/__tests__/{app-functions/errorReporter.spec.d.ts → errorReporter.spec.d.ts} +0 -0
  120. /package/dist/lib/__tests__/{app-functions/services → proxy}/AppProxyService.spec.d.ts +0 -0
  121. /package/dist/lib/__tests__/{app-functions → proxy}/signing.spec.d.ts +0 -0
  122. /package/dist/lib/__tests__/{app-functions/executor_v20231.spec.d.ts → serverless/config.spec.d.ts} +0 -0
  123. /package/dist/lib/__tests__/{app-functions/executor_v20232.spec.d.ts → serverless/context.spec.d.ts} +0 -0
  124. /package/dist/lib/__tests__/{app-functions/secrets.spec.d.ts → serverless/executor_unsupported.spec.d.ts} +0 -0
  125. /package/dist/lib/__tests__/{app-functions/services/PrivateAppUserTokenManager.spec.d.ts → serverless/executor_v20251.spec.d.ts} +0 -0
  126. /package/dist/lib/__tests__/{app-functions/services/services_v20231.spec.d.ts → serverless/executor_v202603.spec.d.ts} +0 -0
  127. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-async-fails.cjs +0 -0
  128. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-async-fails.d.cts +0 -0
  129. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-async-succeeds.cjs +0 -0
  130. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-async-succeeds.d.cts +0 -0
  131. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-calls-callback.cjs +0 -0
  132. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-calls-callback.d.cts +0 -0
  133. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-does-not-export-main.cjs +0 -0
  134. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-does-not-export-main.d.cts +0 -0
  135. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-echos-input.cjs +0 -0
  136. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-echos-input.d.cts +0 -0
  137. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-logs.cjs +0 -0
  138. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-logs.d.cts +0 -0
  139. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-returns-function.cjs +0 -0
  140. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-returns-function.d.cts +0 -0
  141. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-returns-implicitly.cjs +0 -0
  142. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-returns-implicitly.d.cts +0 -0
  143. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-returns-promise-rejected.cjs +0 -0
  144. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-returns-promise-rejected.d.cts +0 -0
  145. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-returns-promise-resolved.cjs +0 -0
  146. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-returns-promise-resolved.d.cts +0 -0
  147. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-returns-text.cjs +0 -0
  148. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-returns-text.d.cts +0 -0
  149. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-returns-undefined.cjs +0 -0
  150. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-returns-undefined.d.cts +0 -0
  151. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.1 → serverless/fixtures/v2025.1}/app.functions/func-throws-error.cjs +0 -0
  152. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.1 → serverless/fixtures/v2025.1}/app.functions/func-throws-error.d.cts +0 -0
  153. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-times-out.cjs +0 -0
  154. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-times-out.d.cts +0 -0
  155. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-undeclared.cjs +0 -0
  156. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-undeclared.d.cts +0 -0
  157. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-uses-secret.cjs +0 -0
  158. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2 → serverless/fixtures/v2025.1}/app.functions/func-uses-secret.d.cts +0 -0
  159. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.1/app.functions/func-returns-text.cjs → serverless/fixtures/v2026.03/functions/func-calls-callback.cjs} +0 -0
  160. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.1/app.functions/func-callback-on-promise-rejected.d.cts → serverless/fixtures/v2026.03/functions/func-calls-callback.d.cts} +0 -0
  161. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2/app.functions → serverless/fixtures/v2026.03/functions}/func-throws-error.cjs +0 -0
  162. /package/dist/lib/__tests__/{app-functions/fixtures/v2023.2/app.functions → serverless/fixtures/v2026.03/functions}/func-throws-error.d.cts +0 -0
  163. /package/dist/lib/__tests__/{app-functions/services/services_v20232.spec.d.ts → serverless/secrets.spec.d.ts} +0 -0
  164. /package/dist/lib/__tests__/{app-functions/setup.d.ts → serverless/services/PrivateAppUserTokenManager.spec.d.ts} +0 -0
  165. /package/dist/lib/__tests__/{app-functions → serverless}/setup.js +0 -0
  166. /package/dist/lib/{app-functions/errorReporter.d.ts → errorReporter.d.ts} +0 -0
  167. /package/dist/lib/{app-functions → proxy}/signing.d.ts +0 -0
  168. /package/dist/lib/{app-functions → proxy}/signing.js +0 -0
  169. /package/dist/lib/{app-functions → serverless}/api/privateAppUserToken.d.ts +0 -0
  170. /package/dist/lib/{app-functions → serverless}/api/privateAppUserToken.js +0 -0
  171. /package/dist/lib/{app-functions → serverless}/config.d.ts +0 -0
  172. /package/dist/lib/{app-functions → serverless}/context.d.ts +0 -0
  173. /package/dist/lib/{app-functions → serverless}/context.js +0 -0
  174. /package/dist/lib/{app-functions → serverless}/executor.d.ts +0 -0
  175. /package/dist/lib/{app-functions → serverless}/secrets.js +0 -0
  176. /package/dist/lib/{app-functions → serverless}/services/AppFunctionExecutionService.d.ts +0 -0
  177. /package/dist/lib/{app-functions → serverless}/services/PrivateAppUserTokenManager.d.ts +0 -0
  178. /package/dist/lib/{app-functions → serverless}/services/constants.d.ts +0 -0
  179. /package/dist/lib/{app-functions → serverless}/services/constants.js +0 -0
  180. /package/dist/lib/{app-functions → serverless}/services/messages.d.ts +0 -0
  181. /package/dist/lib/{app-functions → serverless}/services/messages.js +0 -0
  182. /package/dist/lib/{app-functions → serverless}/types.js +0 -0
  183. /package/dist/lib/{app-functions → serverless}/utils.d.ts +0 -0
  184. /package/dist/lib/{app-functions → serverless}/utils.js +0 -0
@@ -1,10 +1,13 @@
1
1
  import { describe, it, expect, vi, afterEach, beforeEach } from 'vitest';
2
- import { extractErrorData, mapToLocalUrl, AppProxyService, } from "../../../app-functions/services/AppProxyService.js";
3
- import { axiosErrorMappings, defaultServerError, validationError, } from "../../../app-functions/constants.js";
2
+ vi.mock('../../errorReporter.ts', () => ({
3
+ reportError: vi.fn(),
4
+ }));
5
+ import { extractErrorData, mapToLocalUrl, AppProxyService, } from "../../proxy/AppProxyService.js";
6
+ import { axiosErrorMappings, defaultServerError, validationError, } from "../../proxy/constants.js";
4
7
  import axios, { AxiosError, HttpStatusCode } from 'axios';
5
8
  import httpMocks from 'node-mocks-http';
6
9
  import { EventEmitter } from 'node:events';
7
- import * as signing from "../../../app-functions/signing.js";
10
+ import * as signing from "../../proxy/signing.js";
8
11
  const callAppProxy = async ({ requestUri, method, requestTimeoutMillis, requestBody, requestHeaders, accountId, localDevUrlMapping = {}, logger, }) => {
9
12
  const request = httpMocks.createRequest({
10
13
  method: 'POST',
@@ -79,6 +82,20 @@ describe('AppProxyService', () => {
79
82
  [validUrl]: newValidUrl,
80
83
  }, validUrlWithBasePath, [], logger)).toBe(`${newValidUrl}${basePath}`);
81
84
  });
85
+ it('should preserve the local mapping sub-path when merging URLs', () => {
86
+ const newValidUrl = 'https://localhost:3000/api/v1';
87
+ const requestPath = '/some/endpoint';
88
+ expect(mapToLocalUrl({
89
+ [validUrl]: newValidUrl,
90
+ }, `${validUrl}${requestPath}`, [], logger)).toBe(`${newValidUrl}${requestPath}`);
91
+ });
92
+ it('should preserve the local mapping sub-path with trailing slash when merging URLs', () => {
93
+ const newValidUrl = 'https://localhost:3000/api/v1/';
94
+ const requestPath = '/some/endpoint';
95
+ expect(mapToLocalUrl({
96
+ [validUrl]: newValidUrl,
97
+ }, `${validUrl}${requestPath}`, [], logger)).toBe(`https://localhost:3000/api/v1${requestPath}`);
98
+ });
82
99
  it('should honor urls with ports', () => {
83
100
  const newValidUrl = 'https://localhost:5173';
84
101
  expect(mapToLocalUrl({
@@ -343,6 +360,8 @@ describe('AppProxyService', () => {
343
360
  requestUri: [requestUri],
344
361
  }),
345
362
  }));
363
+ expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining(`returned HTTP ${statusCode}`));
364
+ expect(logger.info).toHaveBeenCalledWith(expect.stringContaining('Request failed'));
346
365
  });
347
366
  it('returns success responses with error info in the body if the proxy returns 4xx, mimicking the backend proxy behavior', async () => {
348
367
  const responseBody = { message: 'this is 404z' };
@@ -380,6 +399,7 @@ describe('AppProxyService', () => {
380
399
  requestUri: [requestUri],
381
400
  }),
382
401
  }));
402
+ expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining(`returned HTTP ${statusCode}`));
383
403
  });
384
404
  it('returns success responses with error info in the body if the proxy returns 5xx, mimicking the backend proxy behavior', async () => {
385
405
  const responseBody = { message: 'there is 500' };
@@ -417,6 +437,56 @@ describe('AppProxyService', () => {
417
437
  requestUri: [requestUri],
418
438
  }),
419
439
  }));
440
+ expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining(`returned HTTP ${statusCode}`));
441
+ });
442
+ it('should log an error when the proxy cannot reach the backend (e.g. ECONNREFUSED)', async () => {
443
+ const method = 'GET';
444
+ const requestUri = 'http://localhost:9999';
445
+ const accountId = 123456;
446
+ const requestTimeoutMillis = 1000;
447
+ // @ts-expect-error Typescript doesn't know this is a spy
448
+ axios.request.mockImplementationOnce(() => Promise.reject(new AxiosError('connect ECONNREFUSED 127.0.0.1:9999', AxiosError.ERR_NETWORK)));
449
+ await callAppProxy({
450
+ requestUri,
451
+ method,
452
+ requestTimeoutMillis,
453
+ accountId,
454
+ logger,
455
+ });
456
+ expect(logger.error).toHaveBeenCalledWith(expect.stringContaining('connect ECONNREFUSED'));
457
+ expect(logger.info).toHaveBeenCalledWith(expect.stringContaining('Request failed'));
458
+ });
459
+ it('should log an error when TLS verification fails', async () => {
460
+ const method = 'GET';
461
+ const requestUri = 'https://localhost:1235';
462
+ const accountId = 123456;
463
+ const requestTimeoutMillis = 1000;
464
+ // @ts-expect-error Typescript doesn't know this is a spy
465
+ axios.request.mockImplementationOnce(() => Promise.reject(new AxiosError('unable to verify the first certificate', AxiosError.ERR_NETWORK)));
466
+ await callAppProxy({
467
+ requestUri,
468
+ method,
469
+ requestTimeoutMillis,
470
+ accountId,
471
+ logger,
472
+ });
473
+ expect(logger.error).toHaveBeenCalledWith(expect.stringContaining('unable to verify the first certificate'));
474
+ });
475
+ it('should log an error for non-Axios errors', async () => {
476
+ const method = 'GET';
477
+ const requestUri = 'http://localhost:1234';
478
+ const accountId = 123456;
479
+ const requestTimeoutMillis = 1000;
480
+ // @ts-expect-error Typescript doesn't know this is a spy
481
+ axios.request.mockImplementationOnce(() => Promise.reject(new TypeError('Cannot read properties of undefined')));
482
+ await callAppProxy({
483
+ requestUri,
484
+ method,
485
+ requestTimeoutMillis,
486
+ accountId,
487
+ logger,
488
+ });
489
+ expect(logger.error).toHaveBeenCalledWith(expect.stringContaining('Cannot read properties of undefined'));
420
490
  });
421
491
  describe('with local.json mapping', () => {
422
492
  const mappedUrl = 'http://localhost:1234';
@@ -1,6 +1,6 @@
1
1
  import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
2
  import { Signature } from '@hubspot/api-client';
3
- import { getSignatureHeaders, sign, formatForSigning, } from "../../app-functions/signing.js";
3
+ import { getSignatureHeaders, sign, formatForSigning, } from "../../proxy/signing.js";
4
4
  /**
5
5
  * Validate signing of requests for headers
6
6
  */
@@ -1,13 +1,16 @@
1
1
  import { afterEach, describe, it, expect, vi, beforeEach } from 'vitest';
2
- import * as devServer from "../app-functions/services/index.js";
2
+ import * as serverlessServices from "../serverless/services/AppFunctionExecutionService.js";
3
+ import * as proxyService from "../proxy/AppProxyService.js";
3
4
  import startDevServer from "../server.js";
4
5
  import { DevServerState } from "../DevServerState.js";
5
6
  import { createMockLogger, createDevServerConfig, createMockViteDevServer, } from "./factories.js";
6
7
  const useMock = vi.fn();
7
- vi.mock('../app-functions/services/index.ts', () => ({
8
- AppProxyService: vi.fn(() => vi.fn((req, res, next) => next())),
8
+ vi.mock('../serverless/services/AppFunctionExecutionService.ts', () => ({
9
9
  AppFunctionExecutionService: vi.fn(() => vi.fn((req, res, next) => next())),
10
10
  }));
11
+ vi.mock('../proxy/AppProxyService.ts', () => ({
12
+ AppProxyService: vi.fn(() => vi.fn((req, res, next) => next())),
13
+ }));
11
14
  vi.mock('express', () => {
12
15
  const expressMock = () => ({
13
16
  use: useMock,
@@ -43,8 +46,8 @@ describe('server', () => {
43
46
  describe('startDevServer', () => {
44
47
  beforeEach(() => {
45
48
  useMock.mockClear();
46
- vi.mocked(devServer.AppFunctionExecutionService).mockReturnValue(vi.fn());
47
- vi.mocked(devServer.AppProxyService).mockReturnValue(vi.fn());
49
+ vi.mocked(serverlessServices.AppFunctionExecutionService).mockReturnValue(vi.fn());
50
+ vi.mocked(proxyService.AppProxyService).mockReturnValue(vi.fn());
48
51
  vi.clearAllMocks();
49
52
  });
50
53
  it('should add the AppProxyService middleware when localDevUrlMapping is provided', async () => {
@@ -61,8 +64,8 @@ describe('server', () => {
61
64
  expect(useMock).toHaveBeenNthCalledWith(3, '/api/crm-extensibility/execution/internal/v3', expect.any(Function),
62
65
  // This is the AppProxyService middleware
63
66
  expect.any(Function));
64
- expect(devServer.AppProxyService).toHaveBeenCalledTimes(1);
65
- expect(devServer.AppProxyService).toHaveBeenCalledWith({
67
+ expect(proxyService.AppProxyService).toHaveBeenCalledTimes(1);
68
+ expect(proxyService.AppProxyService).toHaveBeenCalledWith({
66
69
  accountId: devServerConfig.accountId,
67
70
  allowedUrls: [],
68
71
  localDevUrlMapping: devServerState.localDevUrlMapping,
@@ -79,7 +82,7 @@ describe('server', () => {
79
82
  viteDevServer: createMockViteDevServer(),
80
83
  });
81
84
  expect(useMock).toHaveBeenNthCalledWith(3, '/api/crm-extensibility/execution/internal/v3', expect.any(Function));
82
- expect(devServer.AppProxyService).toHaveBeenCalledTimes(0);
85
+ expect(proxyService.AppProxyService).toHaveBeenCalledTimes(0);
83
86
  });
84
87
  it('should not add the AppProxyService middleware when localDevUrlMapping is not provided', async () => {
85
88
  const devServerState = new DevServerState({
@@ -91,7 +94,7 @@ describe('server', () => {
91
94
  viteDevServer: createMockViteDevServer(),
92
95
  });
93
96
  expect(useMock).toHaveBeenNthCalledWith(3, '/api/crm-extensibility/execution/internal/v3', expect.any(Function));
94
- expect(devServer.AppProxyService).toHaveBeenCalledTimes(0);
97
+ expect(proxyService.AppProxyService).toHaveBeenCalledTimes(0);
95
98
  });
96
99
  it('should add the AppFunctionExecutionService middleware if is a private app', async () => {
97
100
  const devServerState = new DevServerState({
@@ -104,7 +107,7 @@ describe('server', () => {
104
107
  devServerState,
105
108
  viteDevServer: createMockViteDevServer(),
106
109
  });
107
- expect(devServer.AppFunctionExecutionService).toHaveBeenCalledTimes(1);
110
+ expect(serverlessServices.AppFunctionExecutionService).toHaveBeenCalledTimes(1);
108
111
  });
109
112
  it('should not add the AppFunctionExecutionService middleware if is a public app', async () => {
110
113
  const devServerState = new DevServerState({
@@ -118,7 +121,7 @@ describe('server', () => {
118
121
  devServerState,
119
122
  viteDevServer: createMockViteDevServer(),
120
123
  });
121
- expect(devServer.AppFunctionExecutionService).not.toHaveBeenCalled();
124
+ expect(serverlessServices.AppFunctionExecutionService).not.toHaveBeenCalled();
122
125
  });
123
126
  it('should return httpServer and shutdown function', async () => {
124
127
  const devServerState = new DevServerState(devServerConfig);
@@ -0,0 +1,61 @@
1
+ import { describe, it, expect, vi, afterEach } from 'vitest';
2
+ import fs from 'node:fs';
3
+ import { loadMultiFunctionInfo } from "../../serverless/config.js";
4
+ import { TEST_CONFIG_V202603 as TEST_CONFIG } from "./fixtures/constants.js";
5
+ describe('loadMultiFunctionInfo (v2026.03)', () => {
6
+ afterEach(() => {
7
+ vi.restoreAllMocks();
8
+ });
9
+ it('loads app functions from hsmeta files', () => {
10
+ const result = loadMultiFunctionInfo(TEST_CONFIG);
11
+ expect(result.appFunctions).toHaveProperty('returns-text');
12
+ expect(result.appFunctions['returns-text']).toEqual({
13
+ file: 'func-returns-text.cjs',
14
+ secrets: [],
15
+ });
16
+ expect(Object.keys(result.appFunctions).length).toBeGreaterThan(0);
17
+ });
18
+ it('skips hsmeta files that cannot be read', () => {
19
+ const originalReadFileSync = fs.readFileSync;
20
+ vi.spyOn(fs, 'readFileSync').mockImplementation((...args) => {
21
+ const filePath = args[0];
22
+ if (typeof filePath === 'string' &&
23
+ filePath.endsWith('returns-text-hsmeta.json')) {
24
+ throw new Error('ENOENT: no such file or directory');
25
+ }
26
+ return originalReadFileSync.apply(fs, args);
27
+ });
28
+ const result = loadMultiFunctionInfo(TEST_CONFIG);
29
+ expect(result.appFunctions).not.toHaveProperty('returns-text');
30
+ expect(TEST_CONFIG.logger.warn).toHaveBeenCalledWith(expect.stringContaining('Failed to read or parse'));
31
+ expect(TEST_CONFIG.logger.warn).toHaveBeenCalledWith(expect.stringContaining('returns-text-hsmeta.json'));
32
+ });
33
+ it('skips hsmeta files with invalid JSON', () => {
34
+ const originalReadFileSync = fs.readFileSync;
35
+ vi.spyOn(fs, 'readFileSync').mockImplementation((...args) => {
36
+ const filePath = args[0];
37
+ if (typeof filePath === 'string' &&
38
+ filePath.endsWith('returns-text-hsmeta.json')) {
39
+ return 'not-valid-json';
40
+ }
41
+ return originalReadFileSync.apply(fs, args);
42
+ });
43
+ const result = loadMultiFunctionInfo(TEST_CONFIG);
44
+ expect(result.appFunctions).not.toHaveProperty('returns-text');
45
+ expect(TEST_CONFIG.logger.warn).toHaveBeenCalledWith(expect.stringContaining('Failed to read or parse'));
46
+ });
47
+ it('still loads other functions when one hsmeta file fails', () => {
48
+ const originalReadFileSync = fs.readFileSync;
49
+ vi.spyOn(fs, 'readFileSync').mockImplementation((...args) => {
50
+ const filePath = args[0];
51
+ if (typeof filePath === 'string' &&
52
+ filePath.endsWith('returns-text-hsmeta.json')) {
53
+ throw new Error('ENOENT: no such file or directory');
54
+ }
55
+ return originalReadFileSync.apply(fs, args);
56
+ });
57
+ const result = loadMultiFunctionInfo(TEST_CONFIG);
58
+ expect(result.appFunctions).not.toHaveProperty('returns-text');
59
+ expect(Object.keys(result.appFunctions).length).toBeGreaterThan(0);
60
+ });
61
+ });
@@ -1,7 +1,7 @@
1
1
  import { describe, it, expect, vi, afterEach } from 'vitest';
2
2
  import { Client } from '@hubspot/api-client';
3
- import { fetchObjectContext } from "../../app-functions/context.js";
4
- import { SAMPLE_BAD_REQUEST_API_ERROR, SAMPLE_NOT_FOUND_API_ERROR, SAMPLE_UNAUTHORIZED_API_ERROR, TEST_CONFIG_V20231 as TEST_CONFIG, } from "./fixtures/constants.js";
3
+ import { fetchObjectContext } from "../../serverless/context.js";
4
+ import { SAMPLE_BAD_REQUEST_API_ERROR, SAMPLE_NOT_FOUND_API_ERROR, SAMPLE_UNAUTHORIZED_API_ERROR, TEST_CONFIG_V20251 as TEST_CONFIG, } from "./fixtures/constants.js";
5
5
  /**
6
6
  * Validate construction of the context (first argument in an app function)
7
7
  */
@@ -0,0 +1,37 @@
1
+ import { describe, it, expect, vi, afterEach, beforeEach } from 'vitest';
2
+ import { Client } from '@hubspot/api-client';
3
+ import { executeFunction } from "../../serverless/executor.js";
4
+ import { Reason, ExecutionError } from "../../serverless/errors.js";
5
+ import { PLATFORM_VERSION } from "../../constants.js";
6
+ import { buildUnsupportedVersionConfig } from "./fixtures/constants.js";
7
+ describe('app function executor - unsupported platform versions', () => {
8
+ const initialEnvJson = JSON.stringify(process.env);
9
+ beforeEach(() => {
10
+ vi.spyOn(Client.prototype, 'crm', 'get').mockReturnValue({
11
+ objects: {
12
+ basicApi: {
13
+ getById: () =>
14
+ // @ts-ignore
15
+ Promise.resolve({
16
+ properties: { firstname: 'First', lastname: 'Last' },
17
+ }),
18
+ },
19
+ },
20
+ });
21
+ });
22
+ afterEach(() => {
23
+ vi.resetAllMocks();
24
+ process.env = JSON.parse(initialEnvJson);
25
+ });
26
+ it.each([['V20252', PLATFORM_VERSION.V20252]])('should reject with UnsupportedVersion for %s', async (_label, platformVersion) => {
27
+ const config = buildUnsupportedVersionConfig(platformVersion);
28
+ try {
29
+ await executeFunction(config, 'returns-text', {}, () => { });
30
+ expect.unreachable('should have thrown');
31
+ }
32
+ catch (err) {
33
+ expect(err).toBeInstanceOf(ExecutionError);
34
+ expect(err.reason).toBe(Reason.UnsupportedVersion);
35
+ }
36
+ });
37
+ });
@@ -1,14 +1,10 @@
1
1
  import { describe, it, expect, vi, afterEach, beforeEach } from 'vitest';
2
2
  import { Client } from '@hubspot/api-client';
3
- import { Reason, ExecutionError } from "../../app-functions/errors.js";
4
- import { executeFunction } from "../../app-functions/executor.js";
5
- import * as SecretsModule from "../../app-functions/secrets.js";
6
- import { NOOP_CALLBACK, TEST_CONFIG_V20232 as TEST_CONFIG, } from "./fixtures/constants.js";
7
- /**
8
- * Validate function execution using sample functions defined in
9
- * the app path of TEST_CONFIG, which is fixtures/app.functions/
10
- */
11
- describe(`app function executor`, () => {
3
+ import { Reason, ExecutionError } from "../../serverless/errors.js";
4
+ import { executeFunction } from "../../serverless/executor.js";
5
+ import * as SecretsModule from "../../serverless/secrets.js";
6
+ import { NOOP_CALLBACK, TEST_CONFIG_V20251 as TEST_CONFIG, } from "./fixtures/constants.js";
7
+ describe(`app function executor (v2025.1)`, () => {
12
8
  let actual;
13
9
  const initialEnvJson = JSON.stringify(process.env);
14
10
  const setActual = (value) => {
@@ -16,12 +12,10 @@ describe(`app function executor`, () => {
16
12
  };
17
13
  beforeEach(() => {
18
14
  setActual(undefined);
19
- // mock `apiClient.crm.objects.basicApi.getById` to return propertiesToSend for the CRM object
20
15
  vi.spyOn(Client.prototype, 'crm', 'get').mockReturnValue({
21
16
  objects: {
22
17
  basicApi: {
23
18
  getById: () =>
24
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
25
19
  // @ts-ignore
26
20
  Promise.resolve({
27
21
  properties: { firstname: 'First', lastname: 'Last' },
@@ -32,7 +26,6 @@ describe(`app function executor`, () => {
32
26
  });
33
27
  afterEach(() => {
34
28
  vi.resetAllMocks();
35
- // restore process.env
36
29
  process.env = JSON.parse(initialEnvJson);
37
30
  });
38
31
  it('executes a function', async () => {
@@ -176,7 +169,7 @@ describe(`app function executor`, () => {
176
169
  expect(err.cause).toHaveProperty('message', 'Oops');
177
170
  }
178
171
  });
179
- it('throws an error if the function calls callback (only 2023.2)', async () => {
172
+ it('throws an error if the function calls callback', async () => {
180
173
  try {
181
174
  await executeFunction(TEST_CONFIG, 'calls-callback', {}, NOOP_CALLBACK);
182
175
  }
@@ -1,13 +1,10 @@
1
1
  import { describe, it, expect, vi, afterEach, beforeEach } from 'vitest';
2
2
  import { Client } from '@hubspot/api-client';
3
- import { Reason, ExecutionError } from "../../app-functions/errors.js";
4
- import { executeFunction } from "../../app-functions/executor.js";
5
- import { NOOP_CALLBACK, TEST_CONFIG_V20231 as TEST_CONFIG, } from "./fixtures/constants.js";
6
- /**
7
- * Validate function execution using sample functions defined in
8
- * the app path of TEST_CONFIG, which is fixtures/app.functions/
9
- */
10
- describe('app function executor', () => {
3
+ import { Reason, ExecutionError } from "../../serverless/errors.js";
4
+ import { executeFunction } from "../../serverless/executor.js";
5
+ import * as SecretsModule from "../../serverless/secrets.js";
6
+ import { NOOP_CALLBACK, TEST_CONFIG_V202603 as TEST_CONFIG, } from "./fixtures/constants.js";
7
+ describe(`app function executor (v2026.03)`, () => {
11
8
  let actual;
12
9
  const initialEnvJson = JSON.stringify(process.env);
13
10
  const setActual = (value) => {
@@ -15,12 +12,10 @@ describe('app function executor', () => {
15
12
  };
16
13
  beforeEach(() => {
17
14
  setActual(undefined);
18
- // mock `apiClient.crm.objects.basicApi.getById` to return propertiesToSend for the CRM object
19
15
  vi.spyOn(Client.prototype, 'crm', 'get').mockReturnValue({
20
16
  objects: {
21
17
  basicApi: {
22
18
  getById: () =>
23
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
24
19
  // @ts-ignore
25
20
  Promise.resolve({
26
21
  properties: { firstname: 'First', lastname: 'Last' },
@@ -31,7 +26,6 @@ describe('app function executor', () => {
31
26
  });
32
27
  afterEach(() => {
33
28
  vi.resetAllMocks();
34
- // restore process.env
35
29
  process.env = JSON.parse(initialEnvJson);
36
30
  });
37
31
  it('executes a function', async () => {
@@ -90,19 +84,29 @@ describe('app function executor', () => {
90
84
  });
91
85
  describe('handles secrets', () => {
92
86
  it('supplies secrets including the private app access token', async () => {
87
+ const setProperTokenInSecretsSpy = vi.spyOn(SecretsModule, 'setProperTokenInSecrets');
88
+ const loadSecretsSpy = vi.spyOn(SecretsModule, 'loadSecrets');
93
89
  await executeFunction(TEST_CONFIG, 'uses-secret', {}, setActual);
94
90
  expect(actual).toEqual({
95
91
  contextSecrets: 'Listen up: ',
96
92
  processEnvs: 'Listen up: Good dog!',
97
93
  });
94
+ expect(setProperTokenInSecretsSpy).toHaveBeenCalledTimes(1);
95
+ expect(loadSecretsSpy).toHaveBeenCalledTimes(1);
96
+ setProperTokenInSecretsSpy.mockRestore();
97
+ loadSecretsSpy.mockRestore();
98
98
  });
99
99
  it('works with other inputs', async () => {
100
+ const setProperTokenInSecretsSpy = vi.spyOn(SecretsModule, 'setProperTokenInSecrets');
101
+ const loadSecretsSpy = vi.spyOn(SecretsModule, 'loadSecrets');
100
102
  const inputs = { parameters: { PHRASE: 'Bella, ' } };
101
103
  await executeFunction(TEST_CONFIG, 'uses-secret', inputs, setActual);
102
104
  expect(actual).toEqual({
103
105
  contextSecrets: 'Listen up: Bella, ',
104
106
  processEnvs: 'Listen up: Bella, Good dog!',
105
107
  });
108
+ setProperTokenInSecretsSpy.mockRestore();
109
+ loadSecretsSpy.mockRestore();
106
110
  });
107
111
  });
108
112
  it('throws an error if the function is not declared', async () => {
@@ -165,4 +169,15 @@ describe('app function executor', () => {
165
169
  expect(err.cause).toHaveProperty('message', 'Oops');
166
170
  }
167
171
  });
172
+ it('throws an error if the function calls callback', async () => {
173
+ try {
174
+ await executeFunction(TEST_CONFIG, 'calls-callback', {}, NOOP_CALLBACK);
175
+ }
176
+ catch (err) {
177
+ expect(err).toBeInstanceOf(ExecutionError);
178
+ expect(err.reason).toBe(Reason.UncaughtError);
179
+ expect(err.cause).toBeInstanceOf(Error);
180
+ expect(err.cause).toHaveProperty('message', 'callback is not a function');
181
+ }
182
+ });
168
183
  });
@@ -1,6 +1,7 @@
1
- import { ApiException, ServiceConfiguration } from '../../../app-functions/types.ts';
2
- export declare const TEST_CONFIG_V20231: ServiceConfiguration;
3
- export declare const TEST_CONFIG_V20232: ServiceConfiguration;
1
+ import { ApiException, PlatformVersion, ServiceConfiguration } from '../../../serverless/types.ts';
2
+ export declare const TEST_CONFIG_V20251: ServiceConfiguration;
3
+ export declare const TEST_CONFIG_V202603: ServiceConfiguration;
4
+ export declare function buildUnsupportedVersionConfig(platformVersion: PlatformVersion): ServiceConfiguration;
4
5
  export declare const NOOP_CALLBACK: () => void;
5
6
  export declare const SAMPLE_FUNCTION_JS = "exports.main = (context = {}, sendResponse) => {\n sendResponse({\n propertiesToSend: context.propertiesToSend,\n parameters: context.parameters,\n payload: context.event && context.event.payload,\n secrets: context.secrets,\n });\n};\n";
6
7
  export declare const SAMPLE_SERVERLESS_JSON: {
@@ -1,5 +1,5 @@
1
1
  import { vi } from 'vitest';
2
- import { PLATFORM_VERSION } from "../../../app-functions/constants.js";
2
+ import { PLATFORM_VERSION } from "../../../constants.js";
3
3
  import path from 'node:path';
4
4
  function buildTestConfig(platformVersion) {
5
5
  return {
@@ -17,8 +17,14 @@ function buildTestConfig(platformVersion) {
17
17
  platformVersion,
18
18
  };
19
19
  }
20
- export const TEST_CONFIG_V20231 = buildTestConfig(PLATFORM_VERSION.V20231);
21
- export const TEST_CONFIG_V20232 = buildTestConfig(PLATFORM_VERSION.V20232);
20
+ export const TEST_CONFIG_V20251 = buildTestConfig(PLATFORM_VERSION.V20251);
21
+ export const TEST_CONFIG_V202603 = buildTestConfig(PLATFORM_VERSION.V202603);
22
+ export function buildUnsupportedVersionConfig(platformVersion) {
23
+ return {
24
+ ...buildTestConfig(PLATFORM_VERSION.V20251),
25
+ platformVersion,
26
+ };
27
+ }
22
28
  export const NOOP_CALLBACK = () => { };
23
29
  export const SAMPLE_FUNCTION_JS = `exports.main = (context = {}, sendResponse) => {
24
30
  sendResponse({
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ exports.main = async (__context = {}) => {
3
+ const { data } = await Promise.reject(new Error('fail'));
4
+ return data;
5
+ };
@@ -0,0 +1 @@
1
+ export function main(__context?: {}): Promise<never>;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ exports.main = async (__context = {}) => {
3
+ const { data } = await Promise.resolve({ data: { result: 'simulated' } });
4
+ return data;
5
+ };
@@ -0,0 +1,3 @@
1
+ export function main(__context?: {}): Promise<{
2
+ result: string;
3
+ }>;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ exports.notMain = (__context = {}) => {
3
+ return 'result';
4
+ };
@@ -0,0 +1 @@
1
+ export function notMain(__context?: {}): string;
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
- exports.main = (context = {}, callback) => {
3
- callback({
2
+ exports.main = (context = {}) => {
3
+ return {
4
4
  propertiesToSend: context.propertiesToSend,
5
5
  parameters: context.parameters,
6
6
  payload: context.event && context.event.payload,
7
- });
7
+ };
8
8
  };
@@ -0,0 +1,5 @@
1
+ export function main(context?: {}): {
2
+ propertiesToSend: any;
3
+ parameters: any;
4
+ payload: any;
5
+ };
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
- exports.main = (__context = {}, callback) => {
2
+ exports.main = (__context = {}) => {
3
3
  console.log('log line');
4
4
  console.debug('debug line');
5
5
  console.info('info line');
6
6
  console.warn('warn line');
7
7
  console.error('error line');
8
8
  console.info('print data:', [1, 2]);
9
- callback({ status: 'success' });
9
+ return { status: 'success' };
10
10
  };
@@ -0,0 +1,3 @@
1
+ export function main(__context?: {}): {
2
+ status: string;
3
+ };
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ exports.main = (__context = {}) => {
3
+ return () => { };
4
+ };
@@ -0,0 +1 @@
1
+ export function main(__context?: {}): () => void;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ exports.main = async (__context = {}) => {
3
+ await Promise.resolve({ data: { result: 'simulated' } })
4
+ .then((res) => res.data)
5
+ .catch((err) => ({ error: `${err}` }));
6
+ // Implicitly returning 'undefined'
7
+ };
@@ -0,0 +1 @@
1
+ export function main(__context?: {}): Promise<void>;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ exports.main = (__context = {}) => {
3
+ return Promise.reject(new Error('fail')).then((res) => res.data);
4
+ };
@@ -0,0 +1 @@
1
+ export function main(__context?: {}): Promise<any>;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ exports.main = (__context = {}) => {
3
+ return Promise.resolve({ data: { result: 'simulated' } }).then((res) => res.data);
4
+ };
@@ -0,0 +1,3 @@
1
+ export function main(__context?: {}): Promise<{
2
+ result: string;
3
+ }>;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ exports.main = (__context = {}) => {
3
+ return 'result';
4
+ };
@@ -0,0 +1 @@
1
+ export function main(__context?: {}): string;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ exports.main = (__context = {}) => {
3
+ return undefined;
4
+ };
@@ -0,0 +1 @@
1
+ export function main(__context?: {}): undefined;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ exports.main = (context = {}) => {
3
+ const parameters = context.parameters || {};
4
+ const delayMs = parameters.delayMs || 60_000;
5
+ const startedAt = Date.now();
6
+ return new Promise((resolve, __reject) => {
7
+ setTimeout(() => resolve({
8
+ status: 'success',
9
+ elapsedMs: Date.now() - startedAt,
10
+ }), delayMs);
11
+ });
12
+ };
@@ -0,0 +1 @@
1
+ export function main(context?: {}): Promise<any>;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ exports.main = (__context = {}) => {
3
+ return 'This function is not declared in serverless.json';
4
+ };