@elevasis/core 0.23.0 → 0.24.1

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 (243) hide show
  1. package/dist/index.d.ts +4343 -2690
  2. package/dist/index.js +1101 -156
  3. package/dist/knowledge/index.d.ts +574 -210
  4. package/dist/knowledge/index.js +104 -1
  5. package/dist/organization-model/index.d.ts +4343 -2690
  6. package/dist/organization-model/index.js +1101 -156
  7. package/dist/test-utils/index.d.ts +483 -109
  8. package/dist/test-utils/index.js +904 -144
  9. package/package.json +3 -3
  10. package/src/README.md +14 -14
  11. package/src/__tests__/publish.test.ts +24 -24
  12. package/src/__tests__/template-core-compatibility.test.ts +9 -12
  13. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +2137 -2093
  14. package/src/_gen/__tests__/scaffold-contracts.test.ts +30 -30
  15. package/src/auth/multi-tenancy/credentials/__tests__/encryption.test.ts +217 -217
  16. package/src/auth/multi-tenancy/credentials/server/encryption.ts +69 -69
  17. package/src/auth/multi-tenancy/credentials/server/kek-loader.ts +37 -37
  18. package/src/auth/multi-tenancy/index.ts +26 -26
  19. package/src/auth/multi-tenancy/invitations/api-schemas.ts +104 -104
  20. package/src/auth/multi-tenancy/memberships/api-schemas.ts +143 -143
  21. package/src/auth/multi-tenancy/memberships/index.ts +26 -26
  22. package/src/auth/multi-tenancy/memberships/membership.ts +130 -130
  23. package/src/auth/multi-tenancy/organizations/__tests__/api-schemas.test.ts +194 -194
  24. package/src/auth/multi-tenancy/organizations/api-schemas.ts +136 -136
  25. package/src/auth/multi-tenancy/permissions.test.ts +42 -42
  26. package/src/auth/multi-tenancy/permissions.ts +123 -123
  27. package/src/auth/multi-tenancy/role-management/api-schemas.ts +78 -78
  28. package/src/auth/multi-tenancy/role-management/index.ts +16 -16
  29. package/src/auth/multi-tenancy/theme-presets.ts +45 -45
  30. package/src/auth/multi-tenancy/types.ts +57 -57
  31. package/src/auth/multi-tenancy/users/api-schemas.ts +165 -165
  32. package/src/business/README.md +2 -2
  33. package/src/business/acquisition/activity-events.test.ts +250 -250
  34. package/src/business/acquisition/activity-events.ts +93 -93
  35. package/src/business/acquisition/api-schemas.test.ts +1883 -1843
  36. package/src/business/acquisition/api-schemas.ts +1492 -1497
  37. package/src/business/acquisition/build-templates.test.ts +240 -240
  38. package/src/business/acquisition/build-templates.ts +98 -98
  39. package/src/business/acquisition/crm-next-action.test.ts +262 -262
  40. package/src/business/acquisition/crm-next-action.ts +220 -220
  41. package/src/business/acquisition/crm-priority.test.ts +216 -216
  42. package/src/business/acquisition/crm-priority.ts +349 -349
  43. package/src/business/acquisition/crm-state-actions.test.ts +153 -153
  44. package/src/business/acquisition/deal-ownership.test.ts +351 -351
  45. package/src/business/acquisition/deal-ownership.ts +120 -120
  46. package/src/business/acquisition/derive-actions.test.ts +129 -104
  47. package/src/business/acquisition/derive-actions.ts +74 -84
  48. package/src/business/acquisition/index.ts +171 -170
  49. package/src/business/acquisition/ontology-validation.ts +309 -0
  50. package/src/business/acquisition/stateful.ts +30 -30
  51. package/src/business/acquisition/types.ts +396 -396
  52. package/src/business/clients/api-schemas.test.ts +115 -115
  53. package/src/business/clients/api-schemas.ts +158 -158
  54. package/src/business/clients/index.ts +1 -1
  55. package/src/business/crm/api-schemas.ts +40 -40
  56. package/src/business/crm/index.ts +1 -1
  57. package/src/business/deals/api-schemas.ts +87 -87
  58. package/src/business/deals/index.ts +1 -1
  59. package/src/business/index.ts +5 -5
  60. package/src/business/projects/types.ts +144 -144
  61. package/src/commands/queue/types/task.ts +15 -15
  62. package/src/execution/core/runner-types.ts +61 -61
  63. package/src/execution/core/sse-executions.ts +7 -7
  64. package/src/execution/engine/__tests__/fixtures/test-agents.ts +10 -10
  65. package/src/execution/engine/agent/core/__tests__/agent.test.ts +16 -16
  66. package/src/execution/engine/agent/core/__tests__/error-passthrough.test.ts +4 -4
  67. package/src/execution/engine/agent/core/types.ts +25 -25
  68. package/src/execution/engine/agent/index.ts +6 -6
  69. package/src/execution/engine/agent/reasoning/__tests__/request-builder.test.ts +24 -24
  70. package/src/execution/engine/index.ts +443 -443
  71. package/src/execution/engine/tools/integration/server/adapters/apify/__tests__/apify-run-actor.integration.test.ts +298 -298
  72. package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.test.ts +55 -55
  73. package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.ts +107 -107
  74. package/src/execution/engine/tools/integration/server/adapters/apollo/apollo-adapter.test.ts +48 -48
  75. package/src/execution/engine/tools/integration/server/adapters/apollo/apollo-adapter.ts +99 -99
  76. package/src/execution/engine/tools/integration/server/adapters/apollo/index.ts +1 -1
  77. package/src/execution/engine/tools/integration/server/adapters/attio/__tests__/attio-crud.integration.test.ts +363 -363
  78. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/get-record/index.test.ts +162 -162
  79. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-records/index.test.ts +316 -316
  80. package/src/execution/engine/tools/integration/server/adapters/clickup/clickup-adapter.test.ts +18 -18
  81. package/src/execution/engine/tools/integration/server/adapters/clickup/clickup-adapter.ts +194 -194
  82. package/src/execution/engine/tools/integration/server/adapters/clickup/index.ts +7 -7
  83. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-adapter.ts +204 -204
  84. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-tools.ts +105 -105
  85. package/src/execution/engine/tools/integration/server/adapters/google-calendar/google-calendar-adapter.ts +428 -428
  86. package/src/execution/engine/tools/integration/server/adapters/google-calendar/index.ts +2 -2
  87. package/src/execution/engine/tools/integration/server/adapters/google-sheets/__tests__/google-sheets.integration.test.ts +261 -261
  88. package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-tools.ts +1474 -1474
  89. package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-tools.ts +103 -103
  90. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.test.ts +88 -88
  91. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.ts +141 -141
  92. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/utils/types.ts +76 -76
  93. package/src/execution/engine/tools/integration/server/adapters/signature-api/signature-api-tools.ts +182 -182
  94. package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-tools.ts +310 -310
  95. package/src/execution/engine/tools/integration/service.test.ts +239 -239
  96. package/src/execution/engine/tools/integration/service.ts +172 -172
  97. package/src/execution/engine/tools/integration/tool.ts +255 -255
  98. package/src/execution/engine/tools/lead-service-types.ts +1005 -1005
  99. package/src/execution/engine/tools/messages.ts +43 -43
  100. package/src/execution/engine/tools/platform/acquisition/company-tools.ts +7 -7
  101. package/src/execution/engine/tools/platform/acquisition/contact-tools.ts +6 -6
  102. package/src/execution/engine/tools/platform/acquisition/list-tools.ts +6 -6
  103. package/src/execution/engine/tools/platform/acquisition/types.ts +280 -280
  104. package/src/execution/engine/tools/platform/email/types.ts +97 -97
  105. package/src/execution/engine/tools/registry.ts +704 -704
  106. package/src/execution/engine/tools/tool-maps.ts +831 -831
  107. package/src/execution/engine/tools/types.ts +234 -234
  108. package/src/execution/engine/workflow/types.ts +195 -197
  109. package/src/execution/external/__tests__/api-schemas.test.ts +127 -127
  110. package/src/execution/external/api-schemas.ts +40 -40
  111. package/src/execution/external/index.ts +1 -1
  112. package/src/index.ts +18 -18
  113. package/src/integrations/credentials/__tests__/api-schemas.test.ts +420 -420
  114. package/src/integrations/credentials/api-schemas.ts +146 -146
  115. package/src/integrations/credentials/schemas.ts +200 -200
  116. package/src/integrations/oauth/__tests__/provider-registry.test.ts +7 -7
  117. package/src/integrations/oauth/provider-registry.ts +74 -74
  118. package/src/integrations/oauth/server/credentials.ts +43 -43
  119. package/src/integrations/webhook-endpoints/__tests__/api-schemas.test.ts +327 -327
  120. package/src/integrations/webhook-endpoints/api-schemas.ts +103 -103
  121. package/src/integrations/webhook-endpoints/types.ts +58 -58
  122. package/src/knowledge/README.md +32 -32
  123. package/src/knowledge/__tests__/queries.test.ts +626 -535
  124. package/src/knowledge/format.ts +99 -99
  125. package/src/knowledge/index.ts +5 -5
  126. package/src/knowledge/published.ts +5 -5
  127. package/src/knowledge/queries.ts +269 -218
  128. package/src/operations/activities/api-schemas.ts +80 -80
  129. package/src/operations/activities/types.ts +64 -64
  130. package/src/organization-model/README.md +149 -149
  131. package/src/organization-model/__tests__/content-kinds-registry.test.ts +210 -210
  132. package/src/organization-model/__tests__/defaults.test.ts +168 -168
  133. package/src/organization-model/__tests__/domains/actions.test.ts +78 -56
  134. package/src/organization-model/__tests__/domains/customers.test.ts +299 -299
  135. package/src/organization-model/__tests__/domains/entities.test.ts +56 -56
  136. package/src/organization-model/__tests__/domains/goals.test.ts +493 -493
  137. package/src/organization-model/__tests__/domains/identity.test.ts +280 -280
  138. package/src/organization-model/__tests__/domains/navigation.test.ts +268 -268
  139. package/src/organization-model/__tests__/domains/offerings.test.ts +414 -414
  140. package/src/organization-model/__tests__/domains/policies.test.ts +323 -323
  141. package/src/organization-model/__tests__/domains/resource-mappings.test.ts +293 -293
  142. package/src/organization-model/__tests__/domains/resources.test.ts +387 -277
  143. package/src/organization-model/__tests__/domains/roles.test.ts +463 -463
  144. package/src/organization-model/__tests__/domains/statuses.test.ts +246 -246
  145. package/src/organization-model/__tests__/domains/systems.test.ts +209 -209
  146. package/src/organization-model/__tests__/domains/topology.test.ts +188 -0
  147. package/src/organization-model/__tests__/flatten-additive-merge.test.ts +362 -361
  148. package/src/organization-model/__tests__/foundation.test.ts +77 -77
  149. package/src/organization-model/__tests__/get-resources-for-system.test.ts +144 -144
  150. package/src/organization-model/__tests__/graph.test.ts +1312 -862
  151. package/src/organization-model/__tests__/icons.test.ts +10 -1
  152. package/src/organization-model/__tests__/knowledge.test.ts +251 -15
  153. package/src/organization-model/__tests__/lookup-helpers.test.ts +438 -438
  154. package/src/organization-model/__tests__/migration-helpers.test.ts +591 -591
  155. package/src/organization-model/__tests__/prospecting-ssot.test.ts +103 -103
  156. package/src/organization-model/__tests__/recursive-system-schema.test.ts +535 -506
  157. package/src/organization-model/__tests__/resolve.test.ts +274 -164
  158. package/src/organization-model/__tests__/schema.test.ts +844 -301
  159. package/src/organization-model/__tests__/surface-projection.test.ts +284 -284
  160. package/src/organization-model/catalogs/lead-gen.ts +144 -144
  161. package/src/organization-model/content-kinds/config.ts +36 -36
  162. package/src/organization-model/content-kinds/index.ts +76 -72
  163. package/src/organization-model/content-kinds/pipeline.ts +68 -68
  164. package/src/organization-model/content-kinds/registry.ts +44 -44
  165. package/src/organization-model/content-kinds/status.ts +71 -71
  166. package/src/organization-model/content-kinds/template.ts +83 -83
  167. package/src/organization-model/content-kinds/types.ts +117 -117
  168. package/src/organization-model/contracts.ts +27 -27
  169. package/src/organization-model/defaults.ts +42 -50
  170. package/src/organization-model/domains/actions.ts +333 -239
  171. package/src/organization-model/domains/customers.ts +78 -78
  172. package/src/organization-model/domains/entities.ts +144 -144
  173. package/src/organization-model/domains/goals.ts +83 -83
  174. package/src/organization-model/domains/knowledge.ts +117 -101
  175. package/src/organization-model/domains/navigation.ts +139 -139
  176. package/src/organization-model/domains/offerings.ts +71 -71
  177. package/src/organization-model/domains/policies.ts +102 -102
  178. package/src/organization-model/domains/projects.ts +14 -14
  179. package/src/organization-model/domains/prospecting.ts +395 -395
  180. package/src/organization-model/domains/resources.ts +202 -124
  181. package/src/organization-model/domains/roles.ts +96 -96
  182. package/src/organization-model/domains/sales.test.ts +218 -218
  183. package/src/organization-model/domains/sales.ts +380 -380
  184. package/src/organization-model/domains/shared.ts +63 -63
  185. package/src/organization-model/domains/statuses.ts +339 -339
  186. package/src/organization-model/domains/systems.ts +217 -172
  187. package/src/organization-model/domains/topology.ts +261 -0
  188. package/src/organization-model/foundation.ts +75 -75
  189. package/src/organization-model/graph/build.ts +1043 -867
  190. package/src/organization-model/graph/index.ts +4 -4
  191. package/src/organization-model/graph/link.ts +10 -10
  192. package/src/organization-model/graph/schema.ts +75 -68
  193. package/src/organization-model/graph/types.ts +71 -64
  194. package/src/organization-model/helpers.ts +289 -241
  195. package/src/organization-model/icons.ts +78 -66
  196. package/src/organization-model/index.ts +128 -125
  197. package/src/organization-model/migration-helpers.ts +247 -244
  198. package/src/organization-model/ontology.ts +658 -0
  199. package/src/organization-model/organization-graph.mdx +110 -90
  200. package/src/organization-model/organization-model.mdx +225 -213
  201. package/src/organization-model/published.ts +299 -222
  202. package/src/organization-model/resolve.ts +146 -91
  203. package/src/organization-model/schema.ts +818 -659
  204. package/src/organization-model/surface-projection.ts +212 -212
  205. package/src/organization-model/types.ts +179 -155
  206. package/src/platform/api/types.ts +38 -38
  207. package/src/platform/constants/versions.ts +3 -3
  208. package/src/platform/index.ts +23 -23
  209. package/src/platform/registry/__tests__/command-view.test.ts +10 -10
  210. package/src/platform/registry/__tests__/resource-link.test.ts +35 -35
  211. package/src/platform/registry/__tests__/resource-registry.integration.test.ts +20 -20
  212. package/src/platform/registry/__tests__/resource-registry.nested-systems.test.ts +245 -245
  213. package/src/platform/registry/__tests__/resource-registry.test.ts +2053 -2053
  214. package/src/platform/registry/__tests__/validation.test.ts +1444 -1259
  215. package/src/platform/registry/command-view.ts +10 -10
  216. package/src/platform/registry/index.ts +103 -103
  217. package/src/platform/registry/resource-link.ts +32 -32
  218. package/src/platform/registry/resource-registry.ts +886 -886
  219. package/src/platform/registry/serialization.ts +295 -295
  220. package/src/platform/registry/serialized-types.ts +166 -166
  221. package/src/platform/registry/stats-types.ts +68 -68
  222. package/src/platform/registry/types.ts +425 -425
  223. package/src/platform/registry/validation.ts +876 -684
  224. package/src/platform/utils/__tests__/validation.test.ts +1084 -1084
  225. package/src/platform/utils/validation.ts +425 -425
  226. package/src/projects/api-schemas.test.ts +39 -39
  227. package/src/projects/api-schemas.ts +291 -291
  228. package/src/reference/_generated/contracts.md +2136 -2093
  229. package/src/reference/glossary.md +76 -76
  230. package/src/scaffold-registry/__tests__/index.test.ts +206 -206
  231. package/src/scaffold-registry/__tests__/schema.test.ts +166 -166
  232. package/src/scaffold-registry/index.ts +392 -392
  233. package/src/scaffold-registry/schema.ts +243 -243
  234. package/src/server.ts +289 -289
  235. package/src/supabase/database.types.ts +3 -0
  236. package/src/test-utils/README.md +37 -37
  237. package/src/test-utils/entities.ts +108 -108
  238. package/src/test-utils/fixtures/memberships.ts +82 -82
  239. package/src/test-utils/index.ts +12 -12
  240. package/src/test-utils/organization-model.ts +65 -65
  241. package/src/test-utils/published.ts +6 -6
  242. package/src/test-utils/rls/RLSTestContext.ts +588 -588
  243. package/src/test-utils/test-utils.test.ts +44 -44
@@ -1,298 +1,298 @@
1
- import { describe, it, expect, beforeAll, vi } from 'vitest'
2
- import { ApifyAdapter } from '../apify-adapter'
3
- import type { ExecutionContext } from '../../../../../../base/types'
4
- import { createClient } from '@supabase/supabase-js'
5
- import type { Database } from '../../../../../../../../supabase/database.types'
6
- import { decryptCredentialValue } from '../../../../../../../../auth/multi-tenancy/credentials/server/service'
7
- import { loadCredentialKEKs } from '../../../../../../../../auth/multi-tenancy/credentials/server/kek-loader'
8
- import type { RunActorResult } from '../fetch/run-actor'
9
-
10
- /**
11
- * Apify Actor Integration Test Suite
12
- *
13
- * Tests the complete runActor flow:
14
- * 1. Start actor with input
15
- * 2. Poll for completion
16
- * 3. Fetch dataset results
17
- * 4. Handle various actor statuses
18
- *
19
- * Prerequisites:
20
- * - Supabase database with credentials table
21
- * - Credential 'elevasis-apify' with valid Apify API token
22
- * - Organization ID: f9aa5a56-8c13-4cd1-9161-8827ae7b452b
23
- * - SUPABASE_URL and SUPABASE_SERVICE_KEY env vars set
24
- * - Apify account accessible with provided credentials
25
- *
26
- * Run: pnpm test apify-run-actor.integration.test.ts
27
- */
28
-
29
- const SKIP_TESTS = !process.env.SUPABASE_URL || !process.env.SUPABASE_SERVICE_KEY
30
-
31
- describe.skipIf(SKIP_TESTS)('Apify Run Actor Integration Tests', () => {
32
- const adapter = new ApifyAdapter()
33
- const organizationId = 'f9aa5a56-8c13-4cd1-9161-8827ae7b452b'
34
- const credentialName = 'elevasis-apify'
35
-
36
- const context: ExecutionContext = {
37
- organizationId,
38
- executionId: 'apify-integration-test',
39
- resourceId: 'apify-test-agent',
40
- resourceType: 'agent',
41
- logger: { info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn(), child: vi.fn().mockReturnThis() }
42
- }
43
-
44
- let supabase: ReturnType<typeof createClient<Database>>
45
- let credentials: Record<string, unknown>
46
-
47
- beforeAll(async () => {
48
- console.log('\n=== Apify Actor Integration Test Suite ===')
49
- console.log(`Organization: ${organizationId}`)
50
- console.log(`Credential: ${credentialName}\n`)
51
-
52
- // Initialize Supabase
53
- supabase = createClient<Database>(process.env.SUPABASE_URL!, process.env.SUPABASE_SERVICE_KEY!)
54
-
55
- // Load Vault KEK so platform-v1 ciphertext (post-Wave-B4 re-encrypted rows)
56
- // decrypts. Without this, the env-fallback would register the legacy key
57
- // under platform-v1 and AES-GCM auth-tag verification would fail.
58
- await loadCredentialKEKs()
59
-
60
- // Fetch credential from database
61
- const { data: credRow, error } = await supabase
62
- .from('credentials')
63
- .select('encrypted_value')
64
- .eq('organization_id', organizationId)
65
- .eq('name', credentialName)
66
- .single()
67
-
68
- if (error || !credRow) {
69
- throw new Error(`Credential '${credentialName}' not found for org ${organizationId}. Error: ${error?.message}`)
70
- }
71
-
72
- // Decrypt credentials
73
- credentials = decryptCredentialValue(credRow.encrypted_value)
74
-
75
- console.log('✓ Credentials loaded and decrypted')
76
- console.log('Credential fields:', Object.keys(credentials))
77
- console.log(
78
- 'Credential values (masked):',
79
- Object.keys(credentials).reduce(
80
- (acc, key) => {
81
- acc[key] = typeof credentials[key] === 'string' ? credentials[key].substring(0, 10) + '...' : credentials[key]
82
- return acc
83
- },
84
- {} as Record<string, unknown>
85
- )
86
- )
87
- const tokenPresent = !!(credentials.apiToken || credentials.apiKey || credentials.api_token || credentials.token)
88
- console.log(`✓ API Token present: ${tokenPresent}`)
89
-
90
- // Validate credentials
91
- const isValid = adapter.validateCredentials(credentials)
92
- if (!isValid) {
93
- throw new Error('Credential validation failed')
94
- }
95
- console.log('✓ Credentials validated')
96
- console.log('\n✓ Ready to run tests')
97
- })
98
-
99
- it('should run a simple actor and return results', { timeout: 60000 }, async () => {
100
- console.log('\n[Test] Run simple hello-world actor')
101
-
102
- // Using apify/hello-world - a simple actor that runs quickly
103
- const result = (await adapter.call(
104
- 'runActor',
105
- {
106
- actorId: 'apify/hello-world',
107
- input: {
108
- message: 'Integration test from Elevasis'
109
- },
110
- timeoutSecs: 60,
111
- pollIntervalSecs: 5
112
- },
113
- credentials,
114
- context
115
- )) as RunActorResult
116
-
117
- console.log(`✓ Actor completed with status: ${result.status}`)
118
- console.log(`✓ Run ID: ${result.runId}`)
119
- console.log(`✓ Dataset ID: ${result.datasetId}`)
120
- console.log(`✓ Items returned: ${result.totalCount}`)
121
- console.log(`✓ Execution time: ${result.executionTimeMs}ms`)
122
-
123
- expect(result).toBeDefined()
124
- expect(result.status).toBe('SUCCEEDED')
125
- expect(result.runId).toBeDefined()
126
- expect(result.datasetId).toBeDefined()
127
- expect(result.items).toBeInstanceOf(Array)
128
- expect(result.totalCount).toBeGreaterThanOrEqual(0)
129
- expect(result.executionTimeMs).toBeGreaterThan(0)
130
- })
131
-
132
- it('should handle actor with custom input', { timeout: 60000 }, async () => {
133
- console.log('\n[Test] Run actor with custom input')
134
-
135
- const result = (await adapter.call(
136
- 'runActor',
137
- {
138
- actorId: 'apify/hello-world',
139
- input: {
140
- message: 'Custom test message',
141
- outputDatasetItems: 5
142
- },
143
- timeoutSecs: 60,
144
- pollIntervalSecs: 5
145
- },
146
- credentials,
147
- context
148
- )) as RunActorResult
149
-
150
- console.log(`✓ Actor completed: ${result.status}`)
151
- console.log(`✓ Items in dataset: ${result.totalCount}`)
152
-
153
- expect(result).toBeDefined()
154
- expect(result.status).toBe('SUCCEEDED')
155
- expect(result.items).toBeInstanceOf(Array)
156
- })
157
-
158
- it('should handle maxItems parameter', { timeout: 60000 }, async () => {
159
- console.log('\n[Test] Run actor with maxItems limit')
160
-
161
- const maxItems = 3
162
-
163
- const result = (await adapter.call(
164
- 'runActor',
165
- {
166
- actorId: 'apify/hello-world',
167
- input: {
168
- outputDatasetItems: 10
169
- },
170
- maxItems: maxItems,
171
- timeoutSecs: 60,
172
- pollIntervalSecs: 5
173
- },
174
- credentials,
175
- context
176
- )) as RunActorResult
177
-
178
- console.log(`✓ Actor completed: ${result.status}`)
179
- console.log(`✓ Items returned (limited): ${result.totalCount}`)
180
-
181
- expect(result).toBeDefined()
182
- expect(result.status).toBe('SUCCEEDED')
183
- expect(result.items).toBeInstanceOf(Array)
184
- expect(result.items.length).toBeLessThanOrEqual(maxItems)
185
- })
186
-
187
- it('should handle timeout gracefully', { timeout: 15000 }, async () => {
188
- console.log('\n[Test] Handle actor timeout')
189
-
190
- // Use very short timeout to trigger TIMED_OUT status
191
- const result = (await adapter.call(
192
- 'runActor',
193
- {
194
- actorId: 'apify/hello-world',
195
- input: {},
196
- timeoutSecs: 1, // Very short timeout
197
- pollIntervalSecs: 1
198
- },
199
- credentials,
200
- context
201
- )) as RunActorResult
202
-
203
- console.log(`✓ Actor status: ${result.status}`)
204
- console.log(`✓ Timeout handled gracefully`)
205
-
206
- expect(result).toBeDefined()
207
- // Actor might succeed, timeout, or fail depending on external state
208
- expect(['SUCCEEDED', 'TIMED_OUT', 'FAILED']).toContain(result.status)
209
-
210
- if (result.status === 'TIMED_OUT') {
211
- expect(result.items).toEqual([])
212
- expect(result.totalCount).toBe(0)
213
- console.log('✓ TIMED_OUT status returns empty items as expected')
214
- }
215
- })
216
-
217
- it('should handle invalid actor ID gracefully', async () => {
218
- console.log('\n[Test] Handle invalid actor ID')
219
-
220
- await expect(
221
- adapter.call(
222
- 'runActor',
223
- {
224
- actorId: 'invalid/nonexistent-actor-xyz-123',
225
- input: {},
226
- timeoutSecs: 30,
227
- pollIntervalSecs: 5
228
- },
229
- credentials,
230
- context
231
- )
232
- ).rejects.toThrow()
233
-
234
- console.log('✓ Invalid actor ID rejected as expected')
235
- })
236
-
237
- it('should handle missing actorId parameter', async () => {
238
- console.log('\n[Test] Handle missing actorId')
239
-
240
- await expect(
241
- adapter.call(
242
- 'runActor',
243
- {
244
- // Missing actorId
245
- input: {},
246
- timeoutSecs: 30
247
- },
248
- credentials,
249
- context
250
- )
251
- ).rejects.toThrow('Missing required parameter: actorId')
252
-
253
- console.log('✓ Missing actorId parameter rejected as expected')
254
- })
255
-
256
- it('should handle invalid credentials gracefully', async () => {
257
- console.log('\n[Test] Handle invalid credentials')
258
-
259
- const invalidCreds = { apiToken: 'invalid-token-12345' }
260
-
261
- await expect(
262
- adapter.call(
263
- 'runActor',
264
- {
265
- actorId: 'apify/hello-world',
266
- input: {},
267
- timeoutSecs: 30
268
- },
269
- invalidCreds,
270
- context
271
- )
272
- ).rejects.toThrow()
273
-
274
- console.log('✓ Invalid credentials rejected as expected')
275
- })
276
-
277
- it('should validate credentials correctly', () => {
278
- console.log('\n[Test] Validate credentials')
279
-
280
- // Valid credentials
281
- const validCreds = { apiToken: 'test-token' }
282
- expect(adapter.validateCredentials(validCreds)).toBe(true)
283
-
284
- // Invalid credentials (missing apiToken)
285
- const invalidCreds1 = {}
286
- expect(adapter.validateCredentials(invalidCreds1)).toBe(false)
287
-
288
- // Invalid credentials (empty apiToken)
289
- const invalidCreds2 = { apiToken: '' }
290
- expect(adapter.validateCredentials(invalidCreds2)).toBe(false)
291
-
292
- // Invalid credentials (wrong type)
293
- const invalidCreds3 = { apiToken: 123 }
294
- expect(adapter.validateCredentials(invalidCreds3)).toBe(false)
295
-
296
- console.log('✓ Credential validation working correctly')
297
- })
298
- })
1
+ import { describe, it, expect, beforeAll, vi } from 'vitest'
2
+ import { ApifyAdapter } from '../apify-adapter'
3
+ import type { ExecutionContext } from '../../../../../../base/types'
4
+ import { createClient } from '@supabase/supabase-js'
5
+ import type { Database } from '../../../../../../../../supabase/database.types'
6
+ import { decryptCredentialValue } from '../../../../../../../../auth/multi-tenancy/credentials/server/service'
7
+ import { loadCredentialKEKs } from '../../../../../../../../auth/multi-tenancy/credentials/server/kek-loader'
8
+ import type { RunActorResult } from '../fetch/run-actor'
9
+
10
+ /**
11
+ * Apify Actor Integration Test Suite
12
+ *
13
+ * Tests the complete runActor flow:
14
+ * 1. Start actor with input
15
+ * 2. Poll for completion
16
+ * 3. Fetch dataset results
17
+ * 4. Handle various actor statuses
18
+ *
19
+ * Prerequisites:
20
+ * - Supabase database with credentials table
21
+ * - Credential 'elevasis-apify' with valid Apify API token
22
+ * - Organization ID: f9aa5a56-8c13-4cd1-9161-8827ae7b452b
23
+ * - SUPABASE_URL and SUPABASE_SERVICE_KEY env vars set
24
+ * - Apify account accessible with provided credentials
25
+ *
26
+ * Run: pnpm test apify-run-actor.integration.test.ts
27
+ */
28
+
29
+ const SKIP_TESTS = !process.env.SUPABASE_URL || !process.env.SUPABASE_SERVICE_KEY
30
+
31
+ describe.skipIf(SKIP_TESTS)('Apify Run Actor Integration Tests', () => {
32
+ const adapter = new ApifyAdapter()
33
+ const organizationId = 'f9aa5a56-8c13-4cd1-9161-8827ae7b452b'
34
+ const credentialName = 'elevasis-apify'
35
+
36
+ const context: ExecutionContext = {
37
+ organizationId,
38
+ executionId: 'apify-integration-test',
39
+ resourceId: 'apify-test-agent',
40
+ resourceType: 'agent',
41
+ logger: { info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn(), child: vi.fn().mockReturnThis() }
42
+ }
43
+
44
+ let supabase: ReturnType<typeof createClient<Database>>
45
+ let credentials: Record<string, unknown>
46
+
47
+ beforeAll(async () => {
48
+ console.log('\n=== Apify Actor Integration Test Suite ===')
49
+ console.log(`Organization: ${organizationId}`)
50
+ console.log(`Credential: ${credentialName}\n`)
51
+
52
+ // Initialize Supabase
53
+ supabase = createClient<Database>(process.env.SUPABASE_URL!, process.env.SUPABASE_SERVICE_KEY!)
54
+
55
+ // Load Vault KEK so platform-v1 ciphertext (post-Wave-B4 re-encrypted rows)
56
+ // decrypts. Without this, the env-fallback would register the legacy key
57
+ // under platform-v1 and AES-GCM auth-tag verification would fail.
58
+ await loadCredentialKEKs()
59
+
60
+ // Fetch credential from database
61
+ const { data: credRow, error } = await supabase
62
+ .from('credentials')
63
+ .select('encrypted_value')
64
+ .eq('organization_id', organizationId)
65
+ .eq('name', credentialName)
66
+ .single()
67
+
68
+ if (error || !credRow) {
69
+ throw new Error(`Credential '${credentialName}' not found for org ${organizationId}. Error: ${error?.message}`)
70
+ }
71
+
72
+ // Decrypt credentials
73
+ credentials = decryptCredentialValue(credRow.encrypted_value)
74
+
75
+ console.log('✓ Credentials loaded and decrypted')
76
+ console.log('Credential fields:', Object.keys(credentials))
77
+ console.log(
78
+ 'Credential values (masked):',
79
+ Object.keys(credentials).reduce(
80
+ (acc, key) => {
81
+ acc[key] = typeof credentials[key] === 'string' ? credentials[key].substring(0, 10) + '...' : credentials[key]
82
+ return acc
83
+ },
84
+ {} as Record<string, unknown>
85
+ )
86
+ )
87
+ const tokenPresent = !!(credentials.apiToken || credentials.apiKey || credentials.api_token || credentials.token)
88
+ console.log(`✓ API Token present: ${tokenPresent}`)
89
+
90
+ // Validate credentials
91
+ const isValid = adapter.validateCredentials(credentials)
92
+ if (!isValid) {
93
+ throw new Error('Credential validation failed')
94
+ }
95
+ console.log('✓ Credentials validated')
96
+ console.log('\n✓ Ready to run tests')
97
+ })
98
+
99
+ it('should run a simple actor and return results', { timeout: 60000 }, async () => {
100
+ console.log('\n[Test] Run simple hello-world actor')
101
+
102
+ // Using apify/hello-world - a simple actor that runs quickly
103
+ const result = (await adapter.call(
104
+ 'runActor',
105
+ {
106
+ actorId: 'apify/hello-world',
107
+ input: {
108
+ message: 'Integration test from Elevasis'
109
+ },
110
+ timeoutSecs: 60,
111
+ pollIntervalSecs: 5
112
+ },
113
+ credentials,
114
+ context
115
+ )) as RunActorResult
116
+
117
+ console.log(`✓ Actor completed with status: ${result.status}`)
118
+ console.log(`✓ Run ID: ${result.runId}`)
119
+ console.log(`✓ Dataset ID: ${result.datasetId}`)
120
+ console.log(`✓ Items returned: ${result.totalCount}`)
121
+ console.log(`✓ Execution time: ${result.executionTimeMs}ms`)
122
+
123
+ expect(result).toBeDefined()
124
+ expect(result.status).toBe('SUCCEEDED')
125
+ expect(result.runId).toBeDefined()
126
+ expect(result.datasetId).toBeDefined()
127
+ expect(result.items).toBeInstanceOf(Array)
128
+ expect(result.totalCount).toBeGreaterThanOrEqual(0)
129
+ expect(result.executionTimeMs).toBeGreaterThan(0)
130
+ })
131
+
132
+ it('should handle actor with custom input', { timeout: 60000 }, async () => {
133
+ console.log('\n[Test] Run actor with custom input')
134
+
135
+ const result = (await adapter.call(
136
+ 'runActor',
137
+ {
138
+ actorId: 'apify/hello-world',
139
+ input: {
140
+ message: 'Custom test message',
141
+ outputDatasetItems: 5
142
+ },
143
+ timeoutSecs: 60,
144
+ pollIntervalSecs: 5
145
+ },
146
+ credentials,
147
+ context
148
+ )) as RunActorResult
149
+
150
+ console.log(`✓ Actor completed: ${result.status}`)
151
+ console.log(`✓ Items in dataset: ${result.totalCount}`)
152
+
153
+ expect(result).toBeDefined()
154
+ expect(result.status).toBe('SUCCEEDED')
155
+ expect(result.items).toBeInstanceOf(Array)
156
+ })
157
+
158
+ it('should handle maxItems parameter', { timeout: 60000 }, async () => {
159
+ console.log('\n[Test] Run actor with maxItems limit')
160
+
161
+ const maxItems = 3
162
+
163
+ const result = (await adapter.call(
164
+ 'runActor',
165
+ {
166
+ actorId: 'apify/hello-world',
167
+ input: {
168
+ outputDatasetItems: 10
169
+ },
170
+ maxItems: maxItems,
171
+ timeoutSecs: 60,
172
+ pollIntervalSecs: 5
173
+ },
174
+ credentials,
175
+ context
176
+ )) as RunActorResult
177
+
178
+ console.log(`✓ Actor completed: ${result.status}`)
179
+ console.log(`✓ Items returned (limited): ${result.totalCount}`)
180
+
181
+ expect(result).toBeDefined()
182
+ expect(result.status).toBe('SUCCEEDED')
183
+ expect(result.items).toBeInstanceOf(Array)
184
+ expect(result.items.length).toBeLessThanOrEqual(maxItems)
185
+ })
186
+
187
+ it('should handle timeout gracefully', { timeout: 15000 }, async () => {
188
+ console.log('\n[Test] Handle actor timeout')
189
+
190
+ // Use very short timeout to trigger TIMED_OUT status
191
+ const result = (await adapter.call(
192
+ 'runActor',
193
+ {
194
+ actorId: 'apify/hello-world',
195
+ input: {},
196
+ timeoutSecs: 1, // Very short timeout
197
+ pollIntervalSecs: 1
198
+ },
199
+ credentials,
200
+ context
201
+ )) as RunActorResult
202
+
203
+ console.log(`✓ Actor status: ${result.status}`)
204
+ console.log(`✓ Timeout handled gracefully`)
205
+
206
+ expect(result).toBeDefined()
207
+ // Actor might succeed, timeout, or fail depending on external state
208
+ expect(['SUCCEEDED', 'TIMED_OUT', 'FAILED']).toContain(result.status)
209
+
210
+ if (result.status === 'TIMED_OUT') {
211
+ expect(result.items).toEqual([])
212
+ expect(result.totalCount).toBe(0)
213
+ console.log('✓ TIMED_OUT status returns empty items as expected')
214
+ }
215
+ })
216
+
217
+ it('should handle invalid actor ID gracefully', async () => {
218
+ console.log('\n[Test] Handle invalid actor ID')
219
+
220
+ await expect(
221
+ adapter.call(
222
+ 'runActor',
223
+ {
224
+ actorId: 'invalid/nonexistent-actor-xyz-123',
225
+ input: {},
226
+ timeoutSecs: 30,
227
+ pollIntervalSecs: 5
228
+ },
229
+ credentials,
230
+ context
231
+ )
232
+ ).rejects.toThrow()
233
+
234
+ console.log('✓ Invalid actor ID rejected as expected')
235
+ })
236
+
237
+ it('should handle missing actorId parameter', async () => {
238
+ console.log('\n[Test] Handle missing actorId')
239
+
240
+ await expect(
241
+ adapter.call(
242
+ 'runActor',
243
+ {
244
+ // Missing actorId
245
+ input: {},
246
+ timeoutSecs: 30
247
+ },
248
+ credentials,
249
+ context
250
+ )
251
+ ).rejects.toThrow('Missing required parameter: actorId')
252
+
253
+ console.log('✓ Missing actorId parameter rejected as expected')
254
+ })
255
+
256
+ it('should handle invalid credentials gracefully', async () => {
257
+ console.log('\n[Test] Handle invalid credentials')
258
+
259
+ const invalidCreds = { apiToken: 'invalid-token-12345' }
260
+
261
+ await expect(
262
+ adapter.call(
263
+ 'runActor',
264
+ {
265
+ actorId: 'apify/hello-world',
266
+ input: {},
267
+ timeoutSecs: 30
268
+ },
269
+ invalidCreds,
270
+ context
271
+ )
272
+ ).rejects.toThrow()
273
+
274
+ console.log('✓ Invalid credentials rejected as expected')
275
+ })
276
+
277
+ it('should validate credentials correctly', () => {
278
+ console.log('\n[Test] Validate credentials')
279
+
280
+ // Valid credentials
281
+ const validCreds = { apiToken: 'test-token' }
282
+ expect(adapter.validateCredentials(validCreds)).toBe(true)
283
+
284
+ // Invalid credentials (missing apiToken)
285
+ const invalidCreds1 = {}
286
+ expect(adapter.validateCredentials(invalidCreds1)).toBe(false)
287
+
288
+ // Invalid credentials (empty apiToken)
289
+ const invalidCreds2 = { apiToken: '' }
290
+ expect(adapter.validateCredentials(invalidCreds2)).toBe(false)
291
+
292
+ // Invalid credentials (wrong type)
293
+ const invalidCreds3 = { apiToken: 123 }
294
+ expect(adapter.validateCredentials(invalidCreds3)).toBe(false)
295
+
296
+ console.log('✓ Credential validation working correctly')
297
+ })
298
+ })