@elevasis/core 0.12.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +9 -2
- package/dist/organization-model/index.d.ts +1 -1
- package/dist/organization-model/index.js +9 -2
- package/dist/test-utils/index.d.ts +480 -389
- package/dist/test-utils/index.js +28 -2
- package/package.json +1 -1
- package/src/_gen/__tests__/__snapshots__/contracts.md.snap +2324 -0
- package/src/auth/multi-tenancy/credentials/__tests__/encryption.test.ts +217 -216
- package/src/auth/multi-tenancy/credentials/server/encryption.ts +5 -19
- package/src/auth/multi-tenancy/credentials/server/kek-loader.ts +3 -13
- package/src/auth/multi-tenancy/permissions.ts +12 -5
- package/src/business/acquisition/activity-events.test.ts +250 -0
- package/src/business/acquisition/activity-events.ts +84 -0
- package/src/business/acquisition/api-schemas.test.ts +1180 -0
- package/src/business/acquisition/api-schemas.ts +456 -235
- package/src/business/acquisition/crm-state-actions.test.ts +160 -0
- package/src/business/acquisition/derive-actions.test.ts +518 -0
- package/src/business/acquisition/derive-actions.ts +103 -0
- package/src/business/acquisition/index.ts +51 -11
- package/src/business/acquisition/stateful.ts +30 -0
- package/src/business/acquisition/types.ts +44 -77
- package/src/execution/engine/index.ts +4 -1
- package/src/execution/engine/tools/integration/server/adapters/apify/__tests__/apify-run-actor.integration.test.ts +1 -2
- package/src/execution/engine/tools/integration/server/adapters/attio/__tests__/attio-crud.integration.test.ts +363 -361
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/get-record/index.test.ts +162 -186
- package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-records/index.test.ts +316 -338
- package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-adapter.ts +204 -210
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.test.ts +88 -0
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.ts +141 -134
- package/src/execution/engine/tools/integration/server/adapters/resend/fetch/utils/types.ts +76 -75
- package/src/execution/engine/tools/integration/service.test.ts +34 -9
- package/src/execution/engine/tools/integration/service.ts +6 -3
- package/src/execution/engine/tools/lead-service-types.ts +90 -30
- package/src/execution/engine/tools/platform/acquisition/types.ts +266 -260
- package/src/execution/engine/tools/registry.ts +5 -4
- package/src/execution/engine/tools/tool-maps.ts +43 -21
- package/src/execution/engine/workflow/types.ts +11 -0
- package/src/organization-model/contracts.ts +4 -4
- package/src/organization-model/domains/navigation.ts +62 -62
- package/src/organization-model/domains/sales.ts +272 -0
- package/src/organization-model/organization-graph.mdx +2 -2
- package/src/organization-model/published.ts +21 -21
- package/src/organization-model/resolve.ts +21 -8
- package/src/platform/constants/versions.ts +1 -1
- package/src/reference/_generated/contracts.md +2324 -0
- package/src/scaffold-registry/index.ts +10 -9
- package/src/scaffold-registry/schema.ts +68 -62
- package/src/supabase/database.types.ts +2958 -2884
- package/src/test-utils/rls/RLSTestContext.ts +585 -553
package/src/execution/engine/tools/integration/server/adapters/attio/fetch/get-record/index.test.ts
CHANGED
|
@@ -1,186 +1,162 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for Attio getRecord fetch implementation
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
expect(result).toEqual({
|
|
46
|
-
id: 'record-789',
|
|
47
|
-
values: mockResponse.data.values,
|
|
48
|
-
createdAt: '2024-01-01T12:00:00Z',
|
|
49
|
-
webUrl: 'https://app.attio.com/workspace/record-789'
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
expect(mockFetch).toHaveBeenCalledWith(
|
|
53
|
-
'https://api.attio.com/v2/objects/people/records/record-789',
|
|
54
|
-
expect.objectContaining({
|
|
55
|
-
method: 'GET',
|
|
56
|
-
headers: {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
})
|
|
61
|
-
)
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
it('should throw credentials_invalid when API key is missing', async () => {
|
|
65
|
-
await expect(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
domains: [{ domain: 'acme.com' }]
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
mockFetch.mockResolvedValue({
|
|
169
|
-
ok: true,
|
|
170
|
-
json: async () => mockResponse
|
|
171
|
-
})
|
|
172
|
-
|
|
173
|
-
const result = await getRecord(
|
|
174
|
-
{ apiKey: 'test-key' },
|
|
175
|
-
{ object: 'companies', recordId: 'company-789' }
|
|
176
|
-
)
|
|
177
|
-
|
|
178
|
-
expect(result.id).toBe('company-789')
|
|
179
|
-
expect(result.values.name).toBe('Acme Corp')
|
|
180
|
-
|
|
181
|
-
expect(mockFetch).toHaveBeenCalledWith(
|
|
182
|
-
'https://api.attio.com/v2/objects/companies/records/company-789',
|
|
183
|
-
expect.anything()
|
|
184
|
-
)
|
|
185
|
-
})
|
|
186
|
-
})
|
|
1
|
+
/**
|
|
2
|
+
* Tests for Attio getRecord fetch implementation
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe as _describe, it, expect, vi, beforeEach } from 'vitest'
|
|
6
|
+
|
|
7
|
+
// Attio integration not in use; suite skipped per project decision (2026-04-29).
|
|
8
|
+
const describe = _describe.skip
|
|
9
|
+
import { getRecord } from './index.js'
|
|
10
|
+
import { ToolingError } from '../../../../../../types.js'
|
|
11
|
+
|
|
12
|
+
// Mock fetch globally
|
|
13
|
+
const mockFetch = vi.fn()
|
|
14
|
+
global.fetch = mockFetch as typeof fetch
|
|
15
|
+
|
|
16
|
+
describe('getRecord', () => {
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
vi.clearAllMocks()
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('should fetch a record successfully', async () => {
|
|
22
|
+
const mockResponse = {
|
|
23
|
+
data: {
|
|
24
|
+
id: {
|
|
25
|
+
workspace_id: 'workspace-123',
|
|
26
|
+
object_id: 'object-456',
|
|
27
|
+
record_id: 'record-789'
|
|
28
|
+
},
|
|
29
|
+
created_at: '2024-01-01T12:00:00Z',
|
|
30
|
+
web_url: 'https://app.attio.com/workspace/record-789',
|
|
31
|
+
values: {
|
|
32
|
+
name: [{ first_name: 'John', last_name: 'Doe' }],
|
|
33
|
+
email: [{ email_address: 'john@example.com' }]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
mockFetch.mockResolvedValue({
|
|
39
|
+
ok: true,
|
|
40
|
+
json: async () => mockResponse
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
const result = await getRecord({ apiKey: 'test-key' }, { object: 'people', recordId: 'record-789' })
|
|
44
|
+
|
|
45
|
+
expect(result).toEqual({
|
|
46
|
+
id: 'record-789',
|
|
47
|
+
values: mockResponse.data.values,
|
|
48
|
+
createdAt: '2024-01-01T12:00:00Z',
|
|
49
|
+
webUrl: 'https://app.attio.com/workspace/record-789'
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
expect(mockFetch).toHaveBeenCalledWith(
|
|
53
|
+
'https://api.attio.com/v2/objects/people/records/record-789',
|
|
54
|
+
expect.objectContaining({
|
|
55
|
+
method: 'GET',
|
|
56
|
+
headers: {
|
|
57
|
+
Authorization: 'Bearer test-key',
|
|
58
|
+
Accept: 'application/json'
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
)
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
it('should throw credentials_invalid when API key is missing', async () => {
|
|
65
|
+
await expect(getRecord({ apiKey: '' }, { object: 'people', recordId: 'record-123' })).rejects.toThrow(ToolingError)
|
|
66
|
+
|
|
67
|
+
await expect(getRecord({ apiKey: '' }, { object: 'people', recordId: 'record-123' })).rejects.toThrow(
|
|
68
|
+
'Missing Attio API key'
|
|
69
|
+
)
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it('should throw validation_error when parameters are missing', async () => {
|
|
73
|
+
await expect(getRecord({ apiKey: 'test-key' }, { object: '', recordId: 'record-123' })).rejects.toThrow(
|
|
74
|
+
ToolingError
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
await expect(getRecord({ apiKey: 'test-key' }, { object: 'people', recordId: '' })).rejects.toThrow(
|
|
78
|
+
'Missing required parameters'
|
|
79
|
+
)
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it('should handle 404 not found errors', async () => {
|
|
83
|
+
mockFetch.mockResolvedValue({
|
|
84
|
+
ok: false,
|
|
85
|
+
status: 404,
|
|
86
|
+
statusText: 'Not Found',
|
|
87
|
+
text: async () =>
|
|
88
|
+
JSON.stringify({
|
|
89
|
+
status_code: 404,
|
|
90
|
+
type: 'invalid_request_error',
|
|
91
|
+
code: 'not_found',
|
|
92
|
+
message: 'Record not found'
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
await expect(getRecord({ apiKey: 'test-key' }, { object: 'people', recordId: 'nonexistent' })).rejects.toThrow(
|
|
97
|
+
ToolingError
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
await getRecord({ apiKey: 'test-key' }, { object: 'people', recordId: 'nonexistent' })
|
|
102
|
+
} catch (error) {
|
|
103
|
+
expect((error as ToolingError).errorType).toBe('validation_error')
|
|
104
|
+
expect((error as ToolingError).message).toContain('Record not found')
|
|
105
|
+
}
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
it('should handle 401 authentication errors', async () => {
|
|
109
|
+
mockFetch.mockResolvedValue({
|
|
110
|
+
ok: false,
|
|
111
|
+
status: 401,
|
|
112
|
+
statusText: 'Unauthorized',
|
|
113
|
+
text: async () =>
|
|
114
|
+
JSON.stringify({
|
|
115
|
+
status_code: 401,
|
|
116
|
+
type: 'authentication_error',
|
|
117
|
+
code: 'unauthorized',
|
|
118
|
+
message: 'Invalid API key'
|
|
119
|
+
})
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
await getRecord({ apiKey: 'invalid-key' }, { object: 'people', recordId: 'record-123' })
|
|
124
|
+
} catch (error) {
|
|
125
|
+
expect((error as ToolingError).errorType).toBe('credentials_invalid')
|
|
126
|
+
expect((error as ToolingError).message).toContain('Invalid API key')
|
|
127
|
+
}
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
it('should work with different object types', async () => {
|
|
131
|
+
const mockResponse = {
|
|
132
|
+
data: {
|
|
133
|
+
id: {
|
|
134
|
+
workspace_id: 'workspace-123',
|
|
135
|
+
object_id: 'object-456',
|
|
136
|
+
record_id: 'company-789'
|
|
137
|
+
},
|
|
138
|
+
created_at: '2024-01-01T12:00:00Z',
|
|
139
|
+
web_url: 'https://app.attio.com/workspace/company-789',
|
|
140
|
+
values: {
|
|
141
|
+
name: 'Acme Corp',
|
|
142
|
+
domains: [{ domain: 'acme.com' }]
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
mockFetch.mockResolvedValue({
|
|
148
|
+
ok: true,
|
|
149
|
+
json: async () => mockResponse
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
const result = await getRecord({ apiKey: 'test-key' }, { object: 'companies', recordId: 'company-789' })
|
|
153
|
+
|
|
154
|
+
expect(result.id).toBe('company-789')
|
|
155
|
+
expect(result.values.name).toBe('Acme Corp')
|
|
156
|
+
|
|
157
|
+
expect(mockFetch).toHaveBeenCalledWith(
|
|
158
|
+
'https://api.attio.com/v2/objects/companies/records/company-789',
|
|
159
|
+
expect.anything()
|
|
160
|
+
)
|
|
161
|
+
})
|
|
162
|
+
})
|