@segment/analytics-browser-actions-facebook-conversions-api-web 1.9.0 → 1.9.1-staging-c01044061.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/cjs/functions.js +5 -2
- package/dist/cjs/functions.js.map +1 -1
- package/dist/cjs/index.js +4 -4
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/send/depends-on.js +35 -3
- package/dist/cjs/send/depends-on.js.map +1 -1
- package/dist/cjs/send/fields.js +4 -4
- package/dist/cjs/send/fields.js.map +1 -1
- package/dist/cjs/send/functions.js +9 -7
- package/dist/cjs/send/functions.js.map +1 -1
- package/dist/cjs/types.js.map +1 -1
- package/dist/esm/functions.js +5 -2
- package/dist/esm/functions.js.map +1 -1
- package/dist/esm/index.js +4 -4
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/send/depends-on.js +35 -3
- package/dist/esm/send/depends-on.js.map +1 -1
- package/dist/esm/send/fields.js +4 -4
- package/dist/esm/send/fields.js.map +1 -1
- package/dist/esm/send/functions.js +9 -7
- package/dist/esm/send/functions.js.map +1 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/constants.ts +1 -1
- package/src/functions.ts +59 -66
- package/src/index.ts +22 -27
- package/src/send/depends-on.ts +62 -30
- package/src/send/fields.ts +299 -291
- package/src/send/functions.ts +151 -179
- package/src/send/index.ts +2 -2
- package/src/types.ts +21 -21
package/src/send/functions.ts
CHANGED
|
@@ -2,212 +2,184 @@ import { FBEvent, UserData, EventOptions, FBClient, FBStandardEventType, FBNonSt
|
|
|
2
2
|
import { Payload } from './generated-types'
|
|
3
3
|
import { Settings } from '../generated-types'
|
|
4
4
|
import { UniversalStorage, Analytics } from '@segment/analytics-next'
|
|
5
|
-
import {US_STATE_CODES, COUNTRY_CODES, MAX_INIT_COUNT, INIT_COUNT_KEY, USER_DATA_KEY } from '../constants'
|
|
5
|
+
import { US_STATE_CODES, COUNTRY_CODES, MAX_INIT_COUNT, INIT_COUNT_KEY, USER_DATA_KEY } from '../constants'
|
|
6
6
|
import { storageFallback, setStorageInitCount } from '../functions'
|
|
7
7
|
import { getNotVisibleForEvent } from './depends-on'
|
|
8
8
|
|
|
9
9
|
export function send(client: FBClient, payload: Payload, settings: Settings, analytics: Analytics) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
event_config: {
|
|
13
|
-
custom_event_name,
|
|
14
|
-
event_name
|
|
15
|
-
} = {}
|
|
16
|
-
} = payload
|
|
10
|
+
const { pixelId } = settings
|
|
11
|
+
const { event_config: { custom_event_name, event_name } = {} } = payload
|
|
17
12
|
|
|
18
|
-
|
|
13
|
+
const isCustom = event_name === 'CustomEvent' ? true : false
|
|
19
14
|
|
|
20
|
-
|
|
15
|
+
const errorMessage = validate(payload)
|
|
21
16
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
{ ...fbEvent },
|
|
39
|
-
options
|
|
40
|
-
)
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
client(
|
|
44
|
-
'trackSingle',
|
|
45
|
-
pixelId,
|
|
46
|
-
event_name as FBStandardEventType,
|
|
47
|
-
{ ...fbEvent },
|
|
48
|
-
options
|
|
49
|
-
)
|
|
50
|
-
}
|
|
17
|
+
if (errorMessage) {
|
|
18
|
+
console.warn(`${errorMessage}`)
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const fbEvent = formatFBEvent(payload)
|
|
23
|
+
|
|
24
|
+
maybeSendUserData(client, payload, settings, analytics)
|
|
25
|
+
|
|
26
|
+
const options = formatOptions(payload)
|
|
27
|
+
|
|
28
|
+
if (isCustom) {
|
|
29
|
+
client('trackSingleCustom', pixelId, custom_event_name as string, { ...fbEvent }, options)
|
|
30
|
+
} else {
|
|
31
|
+
client('trackSingle', pixelId, event_name as FBStandardEventType, { ...fbEvent }, options)
|
|
32
|
+
}
|
|
51
33
|
}
|
|
52
34
|
|
|
53
35
|
function validate(payload: Payload): string | undefined {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
36
|
+
const {
|
|
37
|
+
event_config: { event_name },
|
|
38
|
+
content_ids,
|
|
39
|
+
contents
|
|
40
|
+
} = payload
|
|
41
|
+
|
|
42
|
+
if (['AddToCart', 'Purchase', 'ViewContent'].includes(event_name)) {
|
|
43
|
+
if (
|
|
44
|
+
(!content_ids || (Array.isArray(content_ids) && content_ids.length === 0)) &&
|
|
45
|
+
(!contents || (Array.isArray(contents) && contents.length === 0))
|
|
46
|
+
) {
|
|
47
|
+
return `At least one of content_ids or contents is required for the ${event_name} event.`
|
|
64
48
|
}
|
|
49
|
+
}
|
|
65
50
|
|
|
66
|
-
|
|
51
|
+
return undefined
|
|
67
52
|
}
|
|
68
53
|
|
|
69
54
|
function formatFBEvent(payload: Payload): FBEvent {
|
|
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
|
-
return Object.keys(fbEvent).length > 0 ? fbEvent : {}
|
|
55
|
+
const {
|
|
56
|
+
content_category,
|
|
57
|
+
content_ids,
|
|
58
|
+
content_name,
|
|
59
|
+
content_type,
|
|
60
|
+
contents,
|
|
61
|
+
currency,
|
|
62
|
+
delivery_category,
|
|
63
|
+
num_items,
|
|
64
|
+
value,
|
|
65
|
+
predicted_ltv,
|
|
66
|
+
net_revenue,
|
|
67
|
+
custom_data,
|
|
68
|
+
event_config: { event_name, show_fields } = {}
|
|
69
|
+
} = payload
|
|
70
|
+
|
|
71
|
+
const fbEvent: FBEvent = {
|
|
72
|
+
...(content_category ? { content_category } : {}),
|
|
73
|
+
...(content_ids && Array.isArray(content_ids) && content_ids.length > 0 ? { content_ids } : {}),
|
|
74
|
+
...(content_name ? { content_name } : {}),
|
|
75
|
+
...(content_type ? { content_type } : {}),
|
|
76
|
+
...(contents && Array.isArray(contents) && contents.length > 0 ? { contents } : {}),
|
|
77
|
+
...(currency ? { currency } : {}),
|
|
78
|
+
...(delivery_category ? { delivery_category } : {}),
|
|
79
|
+
...(typeof num_items === 'number' ? { num_items } : {}),
|
|
80
|
+
...(typeof value === 'number' ? { value } : {}),
|
|
81
|
+
...(typeof predicted_ltv === 'number' ? { predicted_ltv } : {}),
|
|
82
|
+
...(typeof net_revenue === 'number' ? { net_revenue } : {}),
|
|
83
|
+
...(custom_data && Object.entries(custom_data).length > 0 ? { custom_data } : {})
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (show_fields === false) {
|
|
87
|
+
// If show_fields is false we delete values for fields which are hidden in the UI.
|
|
88
|
+
const fieldsToDelete = getNotVisibleForEvent(event_name as FBStandardEventType | FBNonStandardEventType)
|
|
89
|
+
fieldsToDelete.forEach((field) => {
|
|
90
|
+
if (field in fbEvent) {
|
|
91
|
+
delete fbEvent[field as keyof typeof fbEvent]
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return Object.keys(fbEvent).length > 0 ? fbEvent : {}
|
|
115
97
|
}
|
|
116
98
|
|
|
117
99
|
function formatOptions(payload: Payload): EventOptions | undefined {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
100
|
+
const { eventID, eventSourceUrl } = payload
|
|
101
|
+
const options: EventOptions = {
|
|
102
|
+
...(eventID ? { eventID } : {}),
|
|
103
|
+
...(eventSourceUrl ? { eventSourceUrl } : {})
|
|
104
|
+
}
|
|
105
|
+
return Object.values(options).some(Boolean) ? options : undefined
|
|
124
106
|
}
|
|
125
107
|
|
|
126
108
|
function maybeSendUserData(client: FBClient, payload: Payload, settings: Settings, analytics: Analytics) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
setStorageInitCount(analytics, initCount + 1)
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
storage.set(USER_DATA_KEY, JSON.stringify(userDataFormatted))
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
function formatUserData(userData: Payload['userData']): UserData | undefined {
|
|
148
|
-
if(!userData){
|
|
149
|
-
return undefined
|
|
109
|
+
const { pixelId } = settings
|
|
110
|
+
const { userData } = payload
|
|
111
|
+
const userDataFormatted = formatUserData(userData)
|
|
112
|
+
|
|
113
|
+
if (userDataFormatted) {
|
|
114
|
+
const storage = (analytics.storage as UniversalStorage<Record<string, string>>) ?? storageFallback
|
|
115
|
+
const initCountFromStorage: string | null = storage.get(INIT_COUNT_KEY)
|
|
116
|
+
const initCount: number | undefined =
|
|
117
|
+
initCountFromStorage && !isNaN(Number(initCountFromStorage)) ? parseInt(initCountFromStorage, 10) : undefined
|
|
118
|
+
|
|
119
|
+
if (typeof initCount === 'number' && initCount < MAX_INIT_COUNT) {
|
|
120
|
+
client('init', pixelId, userDataFormatted)
|
|
121
|
+
setStorageInitCount(analytics, initCount + 1)
|
|
150
122
|
}
|
|
151
123
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
ph,
|
|
156
|
-
fn,
|
|
157
|
-
ln,
|
|
158
|
-
ge,
|
|
159
|
-
db,
|
|
160
|
-
ct,
|
|
161
|
-
st,
|
|
162
|
-
zp,
|
|
163
|
-
country
|
|
164
|
-
} = userData
|
|
165
|
-
|
|
166
|
-
const dbFormatted = formatDate(db)
|
|
167
|
-
const stFormatted = fromMap(US_STATE_CODES, st)
|
|
168
|
-
const countryFormatted = fromMap(COUNTRY_CODES, country)
|
|
169
|
-
|
|
170
|
-
const ud: UserData = {
|
|
171
|
-
...(typeof em === 'string' ? {em: em.toLowerCase().trim()} : {}), // lowercase and trim whitespace
|
|
172
|
-
...(typeof ph === 'string' ? {ph: ph.replace(/\D/g, '')} : {}), // remove non-numeric characters
|
|
173
|
-
...(typeof fn === 'string' ? {fn: fn.toLowerCase().trim()} : {}), // lowercase and trim whitespace
|
|
174
|
-
...(typeof ln === 'string' ? {ln: ln.toLowerCase().trim()} : {}), // lowercase and trim whitespace
|
|
175
|
-
...(typeof ge === 'string' && ['m', 'f'].includes(ge) ? { ge: ge as 'm' | 'f' } : {}),
|
|
176
|
-
...(typeof dbFormatted === 'string' ? {db: dbFormatted} : {}), // format date to YYYYMMDD
|
|
177
|
-
...(typeof ct === 'string' ? {ct: ct.toLowerCase().replace(/\s+/g, '')} : {}), // lowercase and replace any whitespace
|
|
178
|
-
...(typeof stFormatted === 'string' ? {st: stFormatted} : {}), // lowercase 2 character state code
|
|
179
|
-
...(typeof zp === 'string' ? {zp: zp.trim()} : {}),
|
|
180
|
-
...(typeof countryFormatted === 'string' ? {country: countryFormatted} : {}), // lowercase 2 character country code
|
|
181
|
-
...(typeof external_id === 'string' ? {external_id: external_id.trim()} : {}) // trim whitespace
|
|
182
|
-
}
|
|
124
|
+
storage.set(USER_DATA_KEY, JSON.stringify(userDataFormatted))
|
|
125
|
+
}
|
|
126
|
+
}
|
|
183
127
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
128
|
+
function formatUserData(userData: Payload['userData']): UserData | undefined {
|
|
129
|
+
if (!userData) {
|
|
130
|
+
return undefined
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const { external_id, em, ph, fn, ln, ge, db, ct, st, zp, country } = userData
|
|
134
|
+
|
|
135
|
+
const dbFormatted = formatDate(db)
|
|
136
|
+
const stFormatted = fromMap(US_STATE_CODES, st)
|
|
137
|
+
const countryFormatted = fromMap(COUNTRY_CODES, country)
|
|
138
|
+
|
|
139
|
+
const ud: UserData = {
|
|
140
|
+
...(typeof em === 'string' ? { em: em.toLowerCase().trim() } : {}), // lowercase and trim whitespace
|
|
141
|
+
...(typeof ph === 'string' ? { ph: ph.replace(/\D/g, '') } : {}), // remove non-numeric characters
|
|
142
|
+
...(typeof fn === 'string' ? { fn: fn.toLowerCase().trim() } : {}), // lowercase and trim whitespace
|
|
143
|
+
...(typeof ln === 'string' ? { ln: ln.toLowerCase().trim() } : {}), // lowercase and trim whitespace
|
|
144
|
+
...(typeof ge === 'string' && ['m', 'f'].includes(ge) ? { ge: ge as 'm' | 'f' } : {}),
|
|
145
|
+
...(typeof dbFormatted === 'string' ? { db: dbFormatted } : {}), // format date to YYYYMMDD
|
|
146
|
+
...(typeof ct === 'string' ? { ct: ct.toLowerCase().replace(/\s+/g, '') } : {}), // lowercase and replace any whitespace
|
|
147
|
+
...(typeof stFormatted === 'string' ? { st: stFormatted } : {}), // lowercase 2 character state code
|
|
148
|
+
...(typeof zp === 'string' ? { zp: zp.trim() } : {}),
|
|
149
|
+
...(typeof countryFormatted === 'string' ? { country: countryFormatted } : {}), // lowercase 2 character country code
|
|
150
|
+
...(typeof external_id === 'string' ? { external_id: external_id.trim() } : {}) // trim whitespace
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (Object.keys(ud).length === 0) {
|
|
154
|
+
return undefined
|
|
155
|
+
}
|
|
156
|
+
return ud
|
|
188
157
|
}
|
|
189
158
|
|
|
190
159
|
function formatDate(isoDate?: string): string | undefined {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
160
|
+
if (!isoDate || typeof isoDate !== 'string') {
|
|
161
|
+
return undefined
|
|
162
|
+
}
|
|
163
|
+
const date = new Date(isoDate)
|
|
164
|
+
if (isNaN(date.getTime())) {
|
|
165
|
+
return undefined
|
|
166
|
+
}
|
|
167
|
+
const year = date.getUTCFullYear()
|
|
168
|
+
const month = (date.getUTCMonth() + 1).toString().padStart(2, '0')
|
|
169
|
+
const day = date.getUTCDate().toString().padStart(2, '0')
|
|
170
|
+
return `${year}${month}${day}`
|
|
202
171
|
}
|
|
203
172
|
|
|
204
173
|
function fromMap(map: Map<string, string>, value?: string): string | undefined {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
174
|
+
const cleaned = value
|
|
175
|
+
?.toLowerCase()
|
|
176
|
+
.replace(/[^a-z]/g, '')
|
|
177
|
+
.trim()
|
|
178
|
+
if (!cleaned) {
|
|
179
|
+
return undefined
|
|
180
|
+
}
|
|
181
|
+
if (cleaned.length === 2 && Array.from(map.values()).includes(cleaned)) {
|
|
182
|
+
return cleaned
|
|
183
|
+
}
|
|
184
|
+
return map.get(cleaned) || undefined
|
|
185
|
+
}
|
package/src/send/index.ts
CHANGED
|
@@ -12,8 +12,8 @@ const action: BrowserActionDefinition<Settings, FBClient, Payload> = {
|
|
|
12
12
|
platform: 'web',
|
|
13
13
|
fields: AllFields,
|
|
14
14
|
perform: (client, { payload, settings, analytics }) => {
|
|
15
|
-
return send(client, payload, settings, analytics)
|
|
15
|
+
return send(client, payload, settings, analytics)
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
export default action
|
|
19
|
+
export default action
|
package/src/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export interface WindowWithOptionalFbq extends Omit<Window, 'fbq' | '_fbq'> {
|
|
2
|
-
fbq?: FBClient
|
|
3
|
-
_fbq?: FBClient
|
|
2
|
+
fbq?: FBClient
|
|
3
|
+
_fbq?: FBClient
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
export type FBStandardEventType =
|
|
@@ -29,8 +29,8 @@ export type InitOptions = {
|
|
|
29
29
|
agent?: string
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
export type EventOptions = {
|
|
33
|
-
eventID?: string
|
|
32
|
+
export type EventOptions = {
|
|
33
|
+
eventID?: string
|
|
34
34
|
eventSourceUrl?: string
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -63,7 +63,7 @@ export type FBEvent = {
|
|
|
63
63
|
currency?: string
|
|
64
64
|
delivery_category?: string
|
|
65
65
|
num_items?: number
|
|
66
|
-
value?: number
|
|
66
|
+
value?: number
|
|
67
67
|
custom_data?: {
|
|
68
68
|
[k: string]: unknown
|
|
69
69
|
}
|
|
@@ -78,26 +78,26 @@ export type FBClient = {
|
|
|
78
78
|
callMethod?: (...args: unknown[]) => void
|
|
79
79
|
(command: 'set', key: string, value: boolean, pixelId: string): void
|
|
80
80
|
(command: 'dataProcessingOptions', options: string[], country?: number, state?: number): void
|
|
81
|
-
(command: 'init', pixelId: string, userData?: UserData, options?: InitOptions
|
|
81
|
+
(command: 'init', pixelId: string, userData?: UserData, options?: InitOptions): void
|
|
82
82
|
(command: 'trackSingle', pixelId: string, event: FBStandardEventType, params?: FBEvent, options?: EventOptions): void
|
|
83
83
|
(command: 'trackSingleCustom', pixelId: string, event: string, params?: FBEvent, options?: EventOptions): void
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
export const LDU = {
|
|
87
|
-
Disabled: {key: 'Disabled', state: undefined, country: undefined},
|
|
88
|
-
GeolocationLogic: {key: 'GeolocationLogic', state: 0, country: 0},
|
|
89
|
-
California: {key: 'California', state: 1000, country: 1},
|
|
90
|
-
Colorado: {key: 'Colorado', state: 1001, country: 1},
|
|
91
|
-
Connecticut: {key: 'Connecticut', state: 1002, country: 1},
|
|
92
|
-
Florida: {key: 'Florida', state: 1003, country: 1},
|
|
93
|
-
Oregon: {key: 'Oregon', state: 1004, country: 1},
|
|
94
|
-
Texas: {key: 'Texas', state: 1005, country: 1},
|
|
95
|
-
Montana: {key: 'Montana', state: 1006, country: 1},
|
|
96
|
-
Delaware: {key: 'Delaware', state: 1007, country: 1},
|
|
97
|
-
Nebraska: {key: 'Nebraska', state: 1008, country: 1},
|
|
98
|
-
NewHampshire: {key: 'NewHampshire', state: 1009, country: 1},
|
|
99
|
-
NewJersey: {key: 'NewJersey', state: 1010, country: 1},
|
|
100
|
-
Minnesota: {key: 'Minnesota', state: 1011, country: 1}
|
|
87
|
+
Disabled: { key: 'Disabled', state: undefined, country: undefined },
|
|
88
|
+
GeolocationLogic: { key: 'GeolocationLogic', state: 0, country: 0 },
|
|
89
|
+
California: { key: 'California', state: 1000, country: 1 },
|
|
90
|
+
Colorado: { key: 'Colorado', state: 1001, country: 1 },
|
|
91
|
+
Connecticut: { key: 'Connecticut', state: 1002, country: 1 },
|
|
92
|
+
Florida: { key: 'Florida', state: 1003, country: 1 },
|
|
93
|
+
Oregon: { key: 'Oregon', state: 1004, country: 1 },
|
|
94
|
+
Texas: { key: 'Texas', state: 1005, country: 1 },
|
|
95
|
+
Montana: { key: 'Montana', state: 1006, country: 1 },
|
|
96
|
+
Delaware: { key: 'Delaware', state: 1007, country: 1 },
|
|
97
|
+
Nebraska: { key: 'Nebraska', state: 1008, country: 1 },
|
|
98
|
+
NewHampshire: { key: 'NewHampshire', state: 1009, country: 1 },
|
|
99
|
+
NewJersey: { key: 'NewJersey', state: 1010, country: 1 },
|
|
100
|
+
Minnesota: { key: 'Minnesota', state: 1011, country: 1 }
|
|
101
101
|
} as const
|
|
102
102
|
|
|
103
|
-
export type LDU = typeof LDU[keyof typeof LDU]
|
|
103
|
+
export type LDU = typeof LDU[keyof typeof LDU]
|