Skip to content

Commit eb4c130

Browse files
authored
Merge branch 'segmentio:main' into main
2 parents 80aeefb + b93a98c commit eb4c130

14 files changed

Lines changed: 245 additions & 101 deletions

File tree

packages/destination-actions/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@segment/action-destinations",
33
"description": "Destination Actions engine and definitions.",
4-
"version": "3.489.0",
4+
"version": "3.490.0",
55
"repository": {
66
"type": "git",
77
"url": "https://github.com/segmentio/action-destinations",

packages/destination-actions/src/destinations/amplitude-cohorts/__tests__/index.test.ts

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const settings = {
88
api_key: 'test_api_key',
99
secret_key: 'test_secret_key',
1010
app_id: 'test_app_id',
11-
owner_email: '[email protected]',
11+
default_owner_email: '[email protected]',
1212
endpoint: 'north_america'
1313
}
1414

@@ -17,7 +17,7 @@ describe('Amplitude Cohorts', () => {
1717
it('should validate authentication inputs', async () => {
1818
nock('https://amplitude.com')
1919
.get('/api/2/usersearch')
20-
.query({ user: settings.owner_email })
20+
.query({ user: settings.default_owner_email })
2121
.reply(200, {})
2222

2323
await expect(testDestination.testAuthentication(settings)).resolves.not.toThrowError()
@@ -86,11 +86,9 @@ describe('Amplitude Cohorts', () => {
8686
it('should successfully retrieve an existing audience', async () => {
8787
const externalId = 'cohort_789'
8888

89-
nock('https://amplitude.com')
90-
.get(`/api/5/cohorts/request/${externalId}`)
91-
.reply(200, {
92-
cohortId: externalId
93-
})
89+
nock('https://amplitude.com').get(`/api/5/cohorts/request/${externalId}`).reply(200, {
90+
cohortId: externalId
91+
})
9492

9593
const result = await testDestination.getAudience({
9694
settings,
@@ -103,11 +101,9 @@ describe('Amplitude Cohorts', () => {
103101
it('should throw error if cohort not found', async () => {
104102
const externalId = 'nonexistent_cohort'
105103

106-
nock('https://amplitude.com')
107-
.get(`/api/5/cohorts/request/${externalId}`)
108-
.reply(200, {
109-
cohortId: 'different_id'
110-
})
104+
nock('https://amplitude.com').get(`/api/5/cohorts/request/${externalId}`).reply(200, {
105+
cohortId: 'different_id'
106+
})
111107

112108
await expect(
113109
testDestination.getAudience({

packages/destination-actions/src/destinations/amplitude-cohorts/functions.ts

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,25 @@ export function getEndpointByRegion(endpoint: keyof typeof endpoints, region?: s
88
return endpoints[endpoint][region as Region] ?? endpoints[endpoint]['north_america']
99
}
1010

11-
export async function createAudience(request: RequestClient, settings: Settings, name: string, id_type: IDType, owner_email?: string): Promise<string> {
12-
const {
13-
endpoint,
14-
app_id,
15-
owner_email: default_owner_email
16-
} = settings
11+
export async function createAudience(
12+
request: RequestClient,
13+
settings: Settings,
14+
name: string,
15+
id_type: IDType,
16+
owner_email?: string
17+
): Promise<string> {
18+
const { endpoint, app_id, default_owner_email } = settings
1719

1820
if (!name) {
1921
throw new IntegrationError('Missing audience name value', 'MISSING_REQUIRED_FIELD', 400)
2022
}
21-
22-
if(!id_type){
23+
24+
if (!id_type) {
2325
throw new IntegrationError('Missing id_type value', 'MISSING_REQUIRED_FIELD', 400)
2426
}
2527

2628
const url = getEndpointByRegion('cohorts_upload', endpoint)
27-
29+
2830
const json: CreateAudienceJSON = {
2931
name,
3032
app_id,
@@ -42,25 +44,31 @@ export async function createAudience(request: RequestClient, settings: Settings,
4244
const id = response?.data?.cohortId
4345

4446
if (!id) {
45-
throw new IntegrationError('Invalid response from Amplitude Cohorts API when attempting to create new Cohort: Missing cohortId', 'INVALID_RESPONSE', 500)
47+
throw new IntegrationError(
48+
'Invalid response from Amplitude Cohorts API when attempting to create new Cohort: Missing cohortId',
49+
'INVALID_RESPONSE',
50+
500
51+
)
4652
}
4753
return id
4854
}
4955

5056
export async function getAudience(request: RequestClient, settings: Settings, externalId: string): Promise<void> {
51-
const {
52-
endpoint
53-
} = settings
57+
const { endpoint } = settings
5458

5559
const url = `${getEndpointByRegion('cohorts_get_one', endpoint)}/${externalId}`
5660
const response = await request<CreateAudienceResponse>(url)
5761
const id = response?.data?.cohortId
58-
59-
if(!id) {
60-
throw new IntegrationError('Invalid response from Amplitude Cohorts API when attempting to get Cohort: Missing cohortId', 'INVALID_RESPONSE', 500)
62+
63+
if (!id) {
64+
throw new IntegrationError(
65+
'Invalid response from Amplitude Cohorts API when attempting to get Cohort: Missing cohortId',
66+
'INVALID_RESPONSE',
67+
500
68+
)
6169
}
6270

63-
if(id !== externalId) {
71+
if (id !== externalId) {
6472
throw new IntegrationError(`Cohort with id ${externalId} not found`, 'COHORT_NOT_FOUND', 404)
6573
}
66-
}
74+
}

packages/destination-actions/src/destinations/amplitude-cohorts/generated-types.ts

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/destination-actions/src/destinations/amplitude-cohorts/index.ts

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,22 @@ const destination: AudienceDestinationDefinition<Settings, AudienceSettings> = {
2121
},
2222
secret_key: {
2323
label: 'Secret Key',
24-
description: 'Amplitude project secret key. You can find this key in the "General" tab of your Amplitude project.',
24+
description:
25+
'Amplitude project secret key. You can find this key in the "General" tab of your Amplitude project.',
2526
type: 'password',
2627
required: true
2728
},
2829
app_id: {
2930
label: 'Amplitude App ID',
30-
description: 'The Amplitude App ID for the cohort you want to sync to. You can find this in the "General" tab of your Amplitude project.',
31+
description:
32+
'The Amplitude App ID for the cohort you want to sync to. You can find this in the "General" tab of your Amplitude project.',
3133
type: 'string',
3234
required: true
3335
},
34-
owner_email: {
36+
default_owner_email: {
3537
label: 'Cohort Owner Email',
36-
description: 'The email of the user who will own the cohorts in Amplitude. This can be overriden per Audience, but if left blank, all cohorts will be owned by this user.',
38+
description:
39+
'The email of the user who will own the cohorts in Amplitude. This can be overriden per Audience, but if left blank, all cohorts will be owned by this user.',
3740
type: 'string',
3841
required: true
3942
},
@@ -57,27 +60,25 @@ const destination: AudienceDestinationDefinition<Settings, AudienceSettings> = {
5760
}
5861
},
5962
testAuthentication: (request, { settings }) => {
60-
const {
61-
endpoint,
62-
owner_email
63-
} = settings
63+
const { endpoint, default_owner_email } = settings
6464
const baseUrl = getEndpointByRegion('usersearch', endpoint)
65-
return request(`${baseUrl}?user=${owner_email}`)
65+
return request(`${baseUrl}?user=${default_owner_email}`)
6666
}
6767
},
6868
extendRequest({ settings }) {
6969
const { api_key, secret_key } = settings
7070
return {
71-
headers: {
71+
headers: {
7272
'Content-Type': 'application/json',
73-
Authorization: `Basic ${Buffer.from(`${api_key}:${secret_key}`).toString('base64')}`
73+
Authorization: `Basic ${Buffer.from(`${api_key}:${secret_key}`).toString('base64')}`
7474
}
7575
}
7676
},
7777
audienceFields: {
7878
owner_email: {
7979
label: 'Cohort Owner Email',
80-
description: 'The email of the user who will own the cohort in Amplitude. Overrides the default Cohort Owner Email value from Settings.',
80+
description:
81+
'The email of the user who will own the cohort in Amplitude. Overrides the default Cohort Owner Email value from Settings.',
8182
type: 'string',
8283
format: 'email',
8384
required: false
@@ -94,14 +95,15 @@ const destination: AudienceDestinationDefinition<Settings, AudienceSettings> = {
9495
},
9596
{
9697
label: 'Amplitude ID',
97-
value: ID_TYPES.BY_AMP_ID
98+
value: ID_TYPES.BY_AMP_ID
9899
}
99100
],
100101
default: ID_TYPES.BY_USER_ID
101102
},
102103
audience_name: {
103104
label: 'Cohort Name',
104-
description: 'The name of the cohort in Amplitude. This will override the default cohort name which is the snake_case version of the Segment Audience name.',
105+
description:
106+
'The name of the cohort in Amplitude. This will override the default cohort name which is the snake_case version of the Segment Audience name.',
105107
type: 'string',
106108
required: false
107109
}
@@ -112,14 +114,10 @@ const destination: AudienceDestinationDefinition<Settings, AudienceSettings> = {
112114
full_audience_sync: false
113115
},
114116
async createAudience(request, createAudienceInput) {
115-
const {
116-
audienceName,
117-
settings,
118-
audienceSettings: {
119-
owner_email,
120-
audience_name,
121-
id_type
122-
} = {}
117+
const {
118+
audienceName,
119+
settings,
120+
audienceSettings: { owner_email, audience_name, id_type } = {}
123121
} = createAudienceInput
124122

125123
const name = typeof audience_name === 'string' && audience_name.length > 0 ? audience_name : audienceName
@@ -128,13 +126,10 @@ const destination: AudienceDestinationDefinition<Settings, AudienceSettings> = {
128126
return { externalId }
129127
},
130128
async getAudience(request, createAudienceInput) {
131-
const {
132-
externalId,
133-
settings
134-
} = createAudienceInput
129+
const { externalId, settings } = createAudienceInput
135130

136131
await getAudience(request, settings, externalId)
137-
132+
138133
return { externalId }
139134
}
140135
},

packages/destination-actions/src/destinations/customerio/__tests__/utils.test.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { resolveIdentifiers, isIsoDate } from '../utils'
1+
import { convertValidTimestamp, resolveIdentifiers, isIsoDate } from '../utils'
22

33
describe('isIsoDate', () => {
44
it('should return true for valid ISO date with fractional seconds from 1-9 digits', () => {
@@ -79,3 +79,9 @@ describe('resolveIdentifiers', () => {
7979
expect(resolveIdentifiers({})).toBeUndefined()
8080
})
8181
})
82+
83+
describe('convertValidTimestamp', () => {
84+
it('should leave decimal unix timestamps unchanged', () => {
85+
expect(convertValidTimestamp('1712345678.123')).toBe('1712345678.123')
86+
})
87+
})

packages/destination-actions/src/destinations/customerio/utils.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,11 @@ export enum AccountRegion {
3939

4040
export const convertValidTimestamp = <Value = unknown>(value: Value): Value | number => {
4141
// Timestamps may be on a `string` field, so check if the string is only
42-
// numbers. If it is, ignore it since it's probably already a unix timestamp.
42+
// digits (optionally with a fractional part). If it is, ignore it since
43+
// it's probably already a unix timestamp (integer or decimal).
4344
// DayJS doesn't parse unix timestamps correctly outside of the `.unix()`
4445
// initializer.
45-
if (typeof value !== 'string' || /^\d+$/.test(value)) {
46+
if (typeof value !== 'string' || /^\d+(\.\d+)?$/.test(value)) {
4647
return value
4748
}
4849

0 commit comments

Comments
 (0)