@hubspot/ui-extensions-dev-server 1.1.6 → 1.1.8

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 (131) hide show
  1. package/dist/lib/DevServerState.d.ts +1 -1
  2. package/dist/lib/ExtensionsWebSocket.js +26 -2
  3. package/dist/lib/__tests__/ExtensionsWebSocket.spec.js +42 -8
  4. package/dist/lib/__tests__/app-functions/context.spec.d.ts +1 -0
  5. package/dist/lib/__tests__/app-functions/context.spec.js +101 -0
  6. package/dist/lib/__tests__/app-functions/errorReporter.spec.d.ts +1 -0
  7. package/dist/lib/__tests__/app-functions/errorReporter.spec.js +102 -0
  8. package/dist/lib/__tests__/app-functions/executor_v20231.spec.d.ts +1 -0
  9. package/dist/lib/__tests__/app-functions/executor_v20231.spec.js +168 -0
  10. package/dist/lib/__tests__/app-functions/executor_v20232.spec.d.ts +1 -0
  11. package/dist/lib/__tests__/app-functions/executor_v20232.spec.js +190 -0
  12. package/dist/lib/__tests__/app-functions/fixtures/constants.d.ts +18 -0
  13. package/dist/lib/__tests__/app-functions/fixtures/constants.js +139 -0
  14. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-async-fails.cjs +8 -0
  15. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-async-fails.d.cts +1 -0
  16. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-async-succeeds.cjs +8 -0
  17. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-async-succeeds.d.cts +1 -0
  18. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-callback-on-promise-rejected.cjs +8 -0
  19. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-callback-on-promise-rejected.d.cts +1 -0
  20. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-callback-on-promise-resolved.cjs +8 -0
  21. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-callback-on-promise-resolved.d.cts +1 -0
  22. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-does-not-export-main.cjs +4 -0
  23. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-does-not-export-main.d.cts +1 -0
  24. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-echos-input.cjs +8 -0
  25. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-echos-input.d.cts +1 -0
  26. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-logs.cjs +10 -0
  27. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-logs.d.cts +1 -0
  28. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-returns-function.cjs +4 -0
  29. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-returns-function.d.cts +1 -0
  30. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-returns-promise-rejected.cjs +7 -0
  31. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-returns-promise-rejected.d.cts +1 -0
  32. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-returns-promise-resolved.cjs +7 -0
  33. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-returns-promise-resolved.d.cts +1 -0
  34. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-returns-text.cjs +4 -0
  35. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-returns-text.d.cts +1 -0
  36. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-returns-undefined.cjs +4 -0
  37. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-returns-undefined.d.cts +1 -0
  38. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-throws-error.cjs +4 -0
  39. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-throws-error.d.cts +1 -0
  40. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-times-out.cjs +10 -0
  41. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-times-out.d.cts +1 -0
  42. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-undeclared.cjs +4 -0
  43. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-undeclared.d.cts +1 -0
  44. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-uses-secret.cjs +14 -0
  45. package/dist/lib/__tests__/app-functions/fixtures/v2023.1/app.functions/func-uses-secret.d.cts +1 -0
  46. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-async-fails.cjs +5 -0
  47. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-async-fails.d.cts +1 -0
  48. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-async-succeeds.cjs +5 -0
  49. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-async-succeeds.d.cts +3 -0
  50. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-calls-callback.cjs +4 -0
  51. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-calls-callback.d.cts +1 -0
  52. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-does-not-export-main.cjs +4 -0
  53. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-does-not-export-main.d.cts +1 -0
  54. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-echos-input.cjs +8 -0
  55. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-echos-input.d.cts +5 -0
  56. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-logs.cjs +10 -0
  57. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-logs.d.cts +3 -0
  58. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-returns-function.cjs +4 -0
  59. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-returns-function.d.cts +1 -0
  60. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-returns-implicitly.cjs +7 -0
  61. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-returns-implicitly.d.cts +1 -0
  62. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-returns-promise-rejected.cjs +4 -0
  63. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-returns-promise-rejected.d.cts +1 -0
  64. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-returns-promise-resolved.cjs +4 -0
  65. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-returns-promise-resolved.d.cts +3 -0
  66. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-returns-text.cjs +4 -0
  67. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-returns-text.d.cts +1 -0
  68. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-returns-undefined.cjs +4 -0
  69. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-returns-undefined.d.cts +1 -0
  70. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-throws-error.cjs +4 -0
  71. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-throws-error.d.cts +1 -0
  72. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-times-out.cjs +12 -0
  73. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-times-out.d.cts +1 -0
  74. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-undeclared.cjs +4 -0
  75. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-undeclared.d.cts +1 -0
  76. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-uses-secret.cjs +14 -0
  77. package/dist/lib/__tests__/app-functions/fixtures/v2023.2/app.functions/func-uses-secret.d.cts +4 -0
  78. package/dist/lib/__tests__/app-functions/secrets.spec.d.ts +1 -0
  79. package/dist/lib/__tests__/app-functions/secrets.spec.js +278 -0
  80. package/dist/lib/__tests__/app-functions/services/AppProxyService.spec.d.ts +1 -0
  81. package/dist/lib/__tests__/app-functions/services/AppProxyService.spec.js +667 -0
  82. package/dist/lib/__tests__/app-functions/services/PrivateAppUserTokenManager.spec.d.ts +1 -0
  83. package/dist/lib/__tests__/app-functions/services/PrivateAppUserTokenManager.spec.js +243 -0
  84. package/dist/lib/__tests__/app-functions/services/services_v20231.spec.d.ts +1 -0
  85. package/dist/lib/__tests__/app-functions/services/services_v20231.spec.js +319 -0
  86. package/dist/lib/__tests__/app-functions/services/services_v20232.spec.d.ts +1 -0
  87. package/dist/lib/__tests__/app-functions/services/services_v20232.spec.js +302 -0
  88. package/dist/lib/__tests__/app-functions/setup.d.ts +1 -0
  89. package/dist/lib/__tests__/app-functions/setup.js +7 -0
  90. package/dist/lib/__tests__/app-functions/signing.spec.d.ts +1 -0
  91. package/dist/lib/__tests__/app-functions/signing.spec.js +460 -0
  92. package/dist/lib/__tests__/server.spec.js +24 -2
  93. package/dist/lib/app-functions/api/privateAppUserToken.d.ts +16 -0
  94. package/dist/lib/app-functions/api/privateAppUserToken.js +28 -0
  95. package/dist/lib/app-functions/config.d.ts +4 -0
  96. package/dist/lib/app-functions/config.js +48 -0
  97. package/dist/lib/app-functions/constants.d.ts +26 -0
  98. package/dist/lib/app-functions/constants.js +63 -0
  99. package/dist/lib/app-functions/context.d.ts +3 -0
  100. package/dist/lib/app-functions/context.js +65 -0
  101. package/dist/lib/app-functions/errorReporter.d.ts +22 -0
  102. package/dist/lib/app-functions/errorReporter.js +42 -0
  103. package/dist/lib/app-functions/errors.d.ts +44 -0
  104. package/dist/lib/app-functions/errors.js +82 -0
  105. package/dist/lib/app-functions/executor.d.ts +3 -0
  106. package/dist/lib/app-functions/executor.js +131 -0
  107. package/dist/lib/app-functions/index.d.ts +4 -0
  108. package/dist/lib/app-functions/index.js +4 -0
  109. package/dist/lib/app-functions/secrets.d.ts +5 -0
  110. package/dist/lib/app-functions/secrets.js +56 -0
  111. package/dist/lib/app-functions/services/AppFunctionExecutionService.d.ts +2 -0
  112. package/dist/lib/app-functions/services/AppFunctionExecutionService.js +55 -0
  113. package/dist/lib/app-functions/services/AppProxyService.d.ts +5 -0
  114. package/dist/lib/app-functions/services/AppProxyService.js +196 -0
  115. package/dist/lib/app-functions/services/PrivateAppUserTokenManager.d.ts +22 -0
  116. package/dist/lib/app-functions/services/PrivateAppUserTokenManager.js +185 -0
  117. package/dist/lib/app-functions/services/constants.d.ts +4 -0
  118. package/dist/lib/app-functions/services/constants.js +4 -0
  119. package/dist/lib/app-functions/services/index.d.ts +3 -0
  120. package/dist/lib/app-functions/services/index.js +3 -0
  121. package/dist/lib/app-functions/services/messages.d.ts +14 -0
  122. package/dist/lib/app-functions/services/messages.js +36 -0
  123. package/dist/lib/app-functions/signing.d.ts +29 -0
  124. package/dist/lib/app-functions/signing.js +51 -0
  125. package/dist/lib/app-functions/types.d.ts +172 -0
  126. package/dist/lib/app-functions/types.js +6 -0
  127. package/dist/lib/app-functions/utils.d.ts +15 -0
  128. package/dist/lib/app-functions/utils.js +28 -0
  129. package/dist/lib/server.js +15 -4
  130. package/dist/lib/types.d.ts +1 -1
  131. package/package.json +11 -7
@@ -0,0 +1,190 @@
1
+ import { describe, it, expect, vi, afterEach, beforeEach } from 'vitest';
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`, () => {
12
+ let actual;
13
+ const initialEnvJson = JSON.stringify(process.env);
14
+ const setActual = (value) => {
15
+ actual = value;
16
+ };
17
+ beforeEach(() => {
18
+ setActual(undefined);
19
+ // mock `apiClient.crm.objects.basicApi.getById` to return propertiesToSend for the CRM object
20
+ vi.spyOn(Client.prototype, 'crm', 'get').mockReturnValue({
21
+ objects: {
22
+ basicApi: {
23
+ getById: () =>
24
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
25
+ // @ts-ignore
26
+ Promise.resolve({
27
+ properties: { firstname: 'First', lastname: 'Last' },
28
+ }),
29
+ },
30
+ },
31
+ });
32
+ });
33
+ afterEach(() => {
34
+ vi.resetAllMocks();
35
+ // restore process.env
36
+ process.env = JSON.parse(initialEnvJson);
37
+ });
38
+ it('executes a function', async () => {
39
+ await executeFunction(TEST_CONFIG, 'returns-text', {}, setActual);
40
+ expect(actual).toEqual('result');
41
+ });
42
+ describe('handles inputs', () => {
43
+ it('none', async () => {
44
+ await executeFunction(TEST_CONFIG, 'echos-input', {}, setActual);
45
+ expect(actual).toEqual({
46
+ propertiesToSend: {},
47
+ parameters: undefined,
48
+ payload: undefined,
49
+ });
50
+ });
51
+ it('object query', async () => {
52
+ const inputs = {
53
+ objectQuery: {
54
+ objectId: 51,
55
+ objectTypeId: '0-1',
56
+ objectPropertyNames: ['firstname', 'lastname'],
57
+ },
58
+ };
59
+ await executeFunction(TEST_CONFIG, 'echos-input', inputs, setActual);
60
+ expect(actual).toEqual({
61
+ propertiesToSend: { firstname: 'First', lastname: 'Last' },
62
+ parameters: undefined,
63
+ payload: undefined,
64
+ });
65
+ });
66
+ it('parameters', async () => {
67
+ const inputs = { parameters: { firstname: 'Wilbert' } };
68
+ await executeFunction(TEST_CONFIG, 'echos-input', inputs, setActual);
69
+ expect(actual).toEqual({
70
+ propertiesToSend: {},
71
+ parameters: { firstname: 'Wilbert' },
72
+ payload: undefined,
73
+ });
74
+ });
75
+ it('object query and parameters', async () => {
76
+ const inputs = {
77
+ objectQuery: {
78
+ objectId: 51,
79
+ objectTypeId: '0-1',
80
+ objectPropertyNames: ['lastname'],
81
+ },
82
+ parameters: 'Salutations!',
83
+ };
84
+ await executeFunction(TEST_CONFIG, 'echos-input', inputs, setActual);
85
+ expect(actual).toEqual({
86
+ propertiesToSend: { lastname: 'Last' },
87
+ parameters: 'Salutations!',
88
+ payload: undefined,
89
+ });
90
+ });
91
+ });
92
+ describe('handles secrets', () => {
93
+ it('supplies secrets including the private app access token', async () => {
94
+ const setProperTokenInSecretsSpy = vi.spyOn(SecretsModule, 'setProperTokenInSecrets');
95
+ const loadSecretsSpy = vi.spyOn(SecretsModule, 'loadSecrets');
96
+ await executeFunction(TEST_CONFIG, 'uses-secret', {}, setActual);
97
+ expect(actual).toEqual({
98
+ contextSecrets: 'Listen up: ',
99
+ processEnvs: 'Listen up: Good dog!',
100
+ });
101
+ expect(setProperTokenInSecretsSpy).toHaveBeenCalledTimes(1);
102
+ expect(loadSecretsSpy).toHaveBeenCalledTimes(1);
103
+ setProperTokenInSecretsSpy.mockRestore();
104
+ loadSecretsSpy.mockRestore();
105
+ });
106
+ it('works with other inputs', async () => {
107
+ const setProperTokenInSecretsSpy = vi.spyOn(SecretsModule, 'setProperTokenInSecrets');
108
+ const loadSecretsSpy = vi.spyOn(SecretsModule, 'loadSecrets');
109
+ const inputs = { parameters: { PHRASE: 'Bella, ' } };
110
+ await executeFunction(TEST_CONFIG, 'uses-secret', inputs, setActual);
111
+ expect(actual).toEqual({
112
+ contextSecrets: 'Listen up: Bella, ',
113
+ processEnvs: 'Listen up: Bella, Good dog!',
114
+ });
115
+ setProperTokenInSecretsSpy.mockRestore();
116
+ loadSecretsSpy.mockRestore();
117
+ });
118
+ });
119
+ it('throws an error if the function is not declared', async () => {
120
+ try {
121
+ await executeFunction(TEST_CONFIG, 'func-undeclared', {}, NOOP_CALLBACK);
122
+ }
123
+ catch (err) {
124
+ expect(err).toBeInstanceOf(ExecutionError);
125
+ expect(err.reason).toBe(Reason.FunctionNotFound);
126
+ }
127
+ });
128
+ it('throws an error if the function does not exist', async () => {
129
+ try {
130
+ await executeFunction(TEST_CONFIG, 'does-not-exist', {}, NOOP_CALLBACK);
131
+ }
132
+ catch (err) {
133
+ expect(err).toBeInstanceOf(ExecutionError);
134
+ expect(err.reason).toBe(Reason.FunctionNotFound);
135
+ }
136
+ });
137
+ it('throws an error if the function does not export main', async () => {
138
+ try {
139
+ await executeFunction(TEST_CONFIG, 'does-not-export-main', {}, NOOP_CALLBACK);
140
+ }
141
+ catch (err) {
142
+ expect(err).toBeInstanceOf(ExecutionError);
143
+ expect(err.reason).toBe(Reason.InvalidFunction);
144
+ }
145
+ });
146
+ it('throws an error if the function returns invalid json', async () => {
147
+ try {
148
+ await executeFunction(TEST_CONFIG, 'returns-function', {}, NOOP_CALLBACK);
149
+ }
150
+ catch (err) {
151
+ expect(err).toBeInstanceOf(ExecutionError);
152
+ expect(err.reason).toBe(Reason.InvalidResponse);
153
+ }
154
+ });
155
+ it('maps response undefined to null', async () => {
156
+ await executeFunction(TEST_CONFIG, 'returns-undefined', {}, setActual);
157
+ expect(actual).toBe(null);
158
+ });
159
+ it('throws an error if the function times out', async () => {
160
+ try {
161
+ await executeFunction(TEST_CONFIG, 'times-out', { parameters: { delayMs: 400 } }, NOOP_CALLBACK);
162
+ }
163
+ catch (err) {
164
+ expect(err).toBeInstanceOf(ExecutionError);
165
+ expect(err.reason).toBe(Reason.Timeout);
166
+ }
167
+ });
168
+ it('throws an error if the function throws an error', async () => {
169
+ try {
170
+ await executeFunction(TEST_CONFIG, 'throws-error', {}, NOOP_CALLBACK);
171
+ }
172
+ catch (err) {
173
+ expect(err).toBeInstanceOf(ExecutionError);
174
+ expect(err.reason).toBe(Reason.UncaughtError);
175
+ expect(err.cause).toBeInstanceOf(Error);
176
+ expect(err.cause).toHaveProperty('message', 'Oops');
177
+ }
178
+ });
179
+ it('throws an error if the function calls callback (only 2023.2)', async () => {
180
+ try {
181
+ await executeFunction(TEST_CONFIG, 'calls-callback', {}, NOOP_CALLBACK);
182
+ }
183
+ catch (err) {
184
+ expect(err).toBeInstanceOf(ExecutionError);
185
+ expect(err.reason).toBe(Reason.UncaughtError);
186
+ expect(err.cause).toBeInstanceOf(Error);
187
+ expect(err.cause).toHaveProperty('message', 'callback is not a function');
188
+ }
189
+ });
190
+ });
@@ -0,0 +1,18 @@
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;
4
+ export declare const NOOP_CALLBACK: () => void;
5
+ 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
+ export declare const SAMPLE_SERVERLESS_JSON: {
7
+ runtime: string;
8
+ version: string;
9
+ appFunctions: {
10
+ 'sample-function': {
11
+ file: string;
12
+ secrets: never[];
13
+ };
14
+ };
15
+ };
16
+ export declare const SAMPLE_BAD_REQUEST_API_ERROR: ApiException;
17
+ export declare const SAMPLE_UNAUTHORIZED_API_ERROR: ApiException;
18
+ export declare const SAMPLE_NOT_FOUND_API_ERROR: ApiException;
@@ -0,0 +1,139 @@
1
+ import { vi } from 'vitest';
2
+ import { PLATFORM_VERSION } from "../../../app-functions/constants.js";
3
+ import path from 'node:path';
4
+ function buildTestConfig(platformVersion) {
5
+ return {
6
+ accountId: 12345,
7
+ app: { path: path.join(import.meta.dirname, `v${platformVersion}`) },
8
+ functionTimeoutMs: 250,
9
+ hubspotApiOrigin: 'https://api.hubapi.com',
10
+ hubspotWebsiteOrigin: 'https://app.hubspot.com',
11
+ logger: {
12
+ debug: vi.fn(),
13
+ info: vi.fn(),
14
+ warn: vi.fn(),
15
+ error: vi.fn(),
16
+ },
17
+ platformVersion,
18
+ };
19
+ }
20
+ export const TEST_CONFIG_V20231 = buildTestConfig(PLATFORM_VERSION.V20231);
21
+ export const TEST_CONFIG_V20232 = buildTestConfig(PLATFORM_VERSION.V20232);
22
+ export const NOOP_CALLBACK = () => { };
23
+ export const SAMPLE_FUNCTION_JS = `exports.main = (context = {}, sendResponse) => {
24
+ sendResponse({
25
+ propertiesToSend: context.propertiesToSend,
26
+ parameters: context.parameters,
27
+ payload: context.event && context.event.payload,
28
+ secrets: context.secrets,
29
+ });
30
+ };
31
+ `;
32
+ export const SAMPLE_SERVERLESS_JSON = {
33
+ runtime: 'nodejs18.x',
34
+ version: '1.0',
35
+ appFunctions: {
36
+ 'sample-function': {
37
+ file: 'sample-function.cjs',
38
+ secrets: [],
39
+ },
40
+ },
41
+ };
42
+ export const SAMPLE_BAD_REQUEST_API_ERROR = JSON.parse(`
43
+ {
44
+ "code": 400,
45
+ "body": {
46
+ "status": "error",
47
+ "message": "Unable to infer object type from: 0-3-bad",
48
+ "correlationId": "e476081a-cbb6-476b-a415-2b3f09418052"
49
+ },
50
+ "headers": {
51
+ "access-control-allow-credentials": "false",
52
+ "content-length": "127",
53
+ "content-type": "application/json;charset=utf-8",
54
+ "date": "Thu, 26 Oct 2023 17:57:54 GMT",
55
+ "server": "envoy",
56
+ "vary": "origin",
57
+ "x-content-type-options": "nosniff",
58
+ "x-envoy-upstream-service-time": "20",
59
+ "x-evy-trace-listener": "listener_https",
60
+ "x-evy-trace-route-configuration": "listener_https/api.hubapi.com",
61
+ "x-evy-trace-route-service-name": "envoyset-translator",
62
+ "x-evy-trace-served-by-pod": "iad02/hubapi-td/envoy-proxy-5b5c96c966-2nv8j",
63
+ "x-evy-trace-virtual-host": "api.hubapi.com",
64
+ "x-hubspot-correlation-id": "e476081a-cbb6-476b-a415-2b3f09418052",
65
+ "x-hubspot-ratelimit-daily": "500000",
66
+ "x-hubspot-ratelimit-daily-remaining": "499998",
67
+ "x-hubspot-ratelimit-interval-milliseconds": "10000",
68
+ "x-hubspot-ratelimit-max": "150",
69
+ "x-hubspot-ratelimit-remaining": "149",
70
+ "x-hubspot-ratelimit-secondly": "15",
71
+ "x-hubspot-ratelimit-secondly-remaining": "14",
72
+ "x-request-id": "e476081a-cbb6-476b-a415-2b3f09418052",
73
+ "x-trace": "2B1DA0E7D887CD2016B490150CA3B689D71E3DF22E000000000000000000"
74
+ }
75
+ }
76
+ `);
77
+ export const SAMPLE_UNAUTHORIZED_API_ERROR = JSON.parse(`
78
+ {
79
+ "code": 401,
80
+ "body": {
81
+ "status": "error",
82
+ "message": "Authentication credentials not found. This API supports OAuth 2.0 authentication and you can find more details at https://developers.hubspot.com/docs/methods/auth/oauth-overview",
83
+ "correlationId": "a0994adf-8b3a-4ee5-a67d-2bfcc2fdca16",
84
+ "category": "INVALID_AUTHENTICATION"
85
+ },
86
+ "headers": {
87
+ "access-control-allow-credentials": "false",
88
+ "content-length": "299",
89
+ "content-type": "application/json;charset=utf-8",
90
+ "date": "Thu, 26 Oct 2023 17:36:27 GMT",
91
+ "server": "envoy",
92
+ "vary": "origin",
93
+ "x-content-type-options": "nosniff",
94
+ "x-envoy-upstream-service-time": "56",
95
+ "x-evy-trace-listener": "listener_https",
96
+ "x-evy-trace-route-configuration": "listener_https/api.hubapi.com",
97
+ "x-evy-trace-route-service-name": "envoyset-translator",
98
+ "x-evy-trace-served-by-pod": "iad02/hubapi-td/envoy-proxy-5b5c96c966-f2ktm",
99
+ "x-evy-trace-virtual-host": "api.hubapi.com",
100
+ "x-hubspot-auth-failure": "401 Unauthorized",
101
+ "x-hubspot-correlation-id": "a0994adf-8b3a-4ee5-a67d-2bfcc2fdca16",
102
+ "x-request-id": "a0994adf-8b3a-4ee5-a67d-2bfcc2fdca16",
103
+ "x-trace": "2BC42BB07C7ECADFCC04750F115A9B56890AA2F99F000000000000000000"
104
+ }
105
+ }
106
+ `);
107
+ export const SAMPLE_NOT_FOUND_API_ERROR = JSON.parse(`
108
+ {
109
+ "code": 404,
110
+ "body": "...Some HTML was found here...",
111
+ "headers": {
112
+ "access-control-allow-credentials": "false",
113
+ "cache-control": "must-revalidate,no-cache,no-store",
114
+ "content-length": "197",
115
+ "content-type": "text/html;charset=iso-8859-1",
116
+ "date": "Thu, 26 Oct 2023 18:09:08 GMT",
117
+ "server": "envoy",
118
+ "vary": "origin",
119
+ "x-content-type-options": "nosniff",
120
+ "x-envoy-upstream-service-time": "78",
121
+ "x-evy-trace-listener": "listener_https",
122
+ "x-evy-trace-route-configuration": "listener_https/api.hubapi.com",
123
+ "x-evy-trace-route-service-name": "envoyset-translator",
124
+ "x-evy-trace-served-by-pod": "iad02/hubapi-td/envoy-proxy-5b5c96c966-2w6d7",
125
+ "x-evy-trace-virtual-host": "api.hubapi.com",
126
+ "x-hubspot-correlation-id": "ebbe430d-abc6-46c2-abcd-79a38c3b716c",
127
+ "x-hubspot-notfound": "true",
128
+ "x-hubspot-ratelimit-daily": "500000",
129
+ "x-hubspot-ratelimit-daily-remaining": "499997",
130
+ "x-hubspot-ratelimit-interval-milliseconds": "10000",
131
+ "x-hubspot-ratelimit-max": "150",
132
+ "x-hubspot-ratelimit-remaining": "149",
133
+ "x-hubspot-ratelimit-secondly": "15",
134
+ "x-hubspot-ratelimit-secondly-remaining": "14",
135
+ "x-request-id": "ebbe430d-abc6-46c2-abcd-79a38c3b716c",
136
+ "x-trace": "2BAD33940117002410F300AF284601FA13FCCA6958000000000000000000"
137
+ }
138
+ }
139
+ `);
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ exports.main = async (__context = {}, callback) => {
3
+ // Asynchronous app functions are technically not supported.
4
+ // If a function makes an async call, it must invoke callback to return the result.
5
+ // Any error thrown in the async function will be caught by the Lambda handler.
6
+ const { data } = await Promise.reject(new Error('fail'));
7
+ callback(data);
8
+ };
@@ -0,0 +1 @@
1
+ export function main(__context: {} | undefined, callback: any): Promise<void>;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ exports.main = async (__context = {}, callback) => {
3
+ // Asynchronous app functions are technically not supported.
4
+ // If a function makes an async call, it must invoke callback to return the result.
5
+ // Any error thrown in the async function will be caught by the Lambda handler.
6
+ const { data } = await Promise.resolve({ data: { result: 'simulated' } });
7
+ callback(data);
8
+ };
@@ -0,0 +1 @@
1
+ export function main(__context: {} | undefined, callback: any): Promise<void>;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ exports.main = (__context = {}, callback) => {
3
+ // Floating promises are not recommended. Callback and error from the promise may not work as expected.
4
+ // The purpose of this test case is to validate/document the behavior.
5
+ Promise.reject(new Error('fail'))
6
+ .then((res) => callback(res.data))
7
+ .catch((err) => callback({ error: `${err}` }));
8
+ };
@@ -0,0 +1 @@
1
+ export function main(__context: {} | undefined, callback: any): void;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ exports.main = (__context = {}, callback) => {
3
+ // Floating promises are not recommended. Callback and error from the promise may not work as expected.
4
+ // The purpose of this test case is to validate/document the behavior.
5
+ Promise.resolve({ data: { result: 'simulated' } })
6
+ .then((res) => callback(res.data))
7
+ .catch((err) => callback({ error: `${err}` }));
8
+ };
@@ -0,0 +1 @@
1
+ export function main(__context: {} | undefined, callback: any): void;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ exports.notMain = (__context = {}, callback) => {
3
+ callback('result');
4
+ };
@@ -0,0 +1 @@
1
+ export function notMain(__context: {} | undefined, callback: any): void;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ exports.main = (context = {}, callback) => {
3
+ callback({
4
+ propertiesToSend: context.propertiesToSend,
5
+ parameters: context.parameters,
6
+ payload: context.event && context.event.payload,
7
+ });
8
+ };
@@ -0,0 +1 @@
1
+ export function main(context: {} | undefined, callback: any): void;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ exports.main = (__context = {}, callback) => {
3
+ console.log('log line');
4
+ console.debug('debug line');
5
+ console.info('info line');
6
+ console.warn('warn line');
7
+ console.error('error line');
8
+ console.info('print data:', [1, 2]);
9
+ callback({ status: 'success' });
10
+ };
@@ -0,0 +1 @@
1
+ export function main(__context: {} | undefined, callback: any): void;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ exports.main = (__context = {}, callback) => {
3
+ callback(() => { });
4
+ };
@@ -0,0 +1 @@
1
+ export function main(__context: {} | undefined, callback: any): void;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ exports.main = (__context = {}, callback) => {
3
+ // Asynchronous app functions are technically not supported.
4
+ // If a function makes an async call, it must invoke callback to return the result.
5
+ // Any error thrown in the promise will be caught by the Lambda handler.
6
+ return Promise.reject(new Error('fail')).then((res) => callback(res.data));
7
+ };
@@ -0,0 +1 @@
1
+ export function main(__context: {} | undefined, callback: any): Promise<any>;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ exports.main = (__context = {}, callback) => {
3
+ // Asynchronous app functions are technically not supported.
4
+ // If a function makes an async call, it must invoke callback to return the result.
5
+ // Any error thrown in the promise will be caught by the Lambda handler.
6
+ return Promise.resolve({ data: { result: 'simulated' } }).then((res) => callback(res.data));
7
+ };
@@ -0,0 +1 @@
1
+ export function main(__context: {} | undefined, callback: any): Promise<any>;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ exports.main = (__context = {}, callback) => {
3
+ callback('result');
4
+ };
@@ -0,0 +1 @@
1
+ export function main(__context: {} | undefined, callback: any): void;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ exports.main = (__context = {}, callback) => {
3
+ callback(undefined);
4
+ };
@@ -0,0 +1 @@
1
+ export function main(__context: {} | undefined, callback: any): void;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ exports.main = () => {
3
+ throw new Error('Oops');
4
+ };
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ exports.main = (context = {}, callback) => {
3
+ const parameters = context.parameters || {};
4
+ const delayMs = parameters.delayMs || 60_000;
5
+ const startedAt = Date.now();
6
+ setTimeout(() => callback({
7
+ status: 'success',
8
+ elapsedMs: Date.now() - startedAt,
9
+ }), delayMs);
10
+ };
@@ -0,0 +1 @@
1
+ export function main(context: {} | undefined, callback: any): void;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ exports.main = (__context = {}, callback) => {
3
+ callback('This function is not declared in serverless.json');
4
+ };
@@ -0,0 +1 @@
1
+ export function main(__context: {} | undefined, callback: any): void;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ exports.main = (context = {}, callback) => {
3
+ const parameters = context.parameters || {};
4
+ const paramPhrase = parameters['PHRASE'] || '';
5
+ const secrets = context.secrets || {};
6
+ const secretToken = secrets['PRIVATE_APP_ACCESS_TOKEN'] || '';
7
+ const secretPhrase = secrets['PHRASE'] || '';
8
+ const envToken = process.env['PRIVATE_APP_ACCESS_TOKEN'] || '';
9
+ const envPhrase = process.env['PHRASE'] || '';
10
+ callback({
11
+ contextSecrets: `${secretToken}${paramPhrase}${secretPhrase}`,
12
+ processEnvs: `${envToken}${paramPhrase}${envPhrase}`,
13
+ });
14
+ };
@@ -0,0 +1 @@
1
+ export function main(context: {} | undefined, callback: any): void;
@@ -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.main = (__context = {}, callback) => {
3
+ callback('result');
4
+ };
@@ -0,0 +1 @@
1
+ export function main(__context: {} | undefined, callback: any): void;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ exports.notMain = (__context = {}) => {
3
+ return 'result';
4
+ };
@@ -0,0 +1 @@
1
+ export function notMain(__context?: {}): string;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ exports.main = (context = {}) => {
3
+ return {
4
+ propertiesToSend: context.propertiesToSend,
5
+ parameters: context.parameters,
6
+ payload: context.event && context.event.payload,
7
+ };
8
+ };
@@ -0,0 +1,5 @@
1
+ export function main(context?: {}): {
2
+ propertiesToSend: any;
3
+ parameters: any;
4
+ payload: any;
5
+ };
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ exports.main = (__context = {}) => {
3
+ console.log('log line');
4
+ console.debug('debug line');
5
+ console.info('info line');
6
+ console.warn('warn line');
7
+ console.error('error line');
8
+ console.info('print data:', [1, 2]);
9
+ return { status: 'success' };
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
+ };