@oxygen-agent/cli 1.987.20 → 1.1003.12
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/README.md +1 -1
- package/dist/admin-primary-providers-render.d.ts +0 -2
- package/dist/admin-primary-providers-render.js +1 -1
- package/dist/browser-login.js +1 -4
- package/dist/command-manifest.d.ts +3 -2
- package/dist/command-manifest.js +10 -0
- package/dist/credentials.d.ts +1 -1
- package/dist/functions-commands.js +6 -2
- package/dist/help.d.ts +8 -0
- package/dist/help.js +46 -0
- package/dist/index.js +1569 -123
- package/dist/knowledge-mirror.d.ts +2 -2
- package/dist/runtime.d.ts +0 -15
- package/dist/runtime.js +1 -1
- package/dist/session.d.ts +4 -3
- package/dist/skills.d.ts +8 -7
- package/dist/skills.js +24 -10
- package/dist/transcript.d.ts +2 -1
- package/dist/util.d.ts +1 -1
- package/dist/util.js +1 -3
- package/node_modules/@oxygen/formula/dist/coerce.d.ts +10 -0
- package/node_modules/@oxygen/formula/dist/coerce.js +10 -0
- package/node_modules/@oxygen/formula/dist/formula-functions.js +65 -0
- package/node_modules/@oxygen/formula/dist/hash.d.ts +19 -0
- package/node_modules/@oxygen/formula/dist/hash.js +199 -0
- package/node_modules/@oxygen/formula/dist/value-cleaners.d.ts +6 -1
- package/node_modules/@oxygen/formula/dist/value-cleaners.js +10 -26
- package/node_modules/@oxygen/shared/dist/array-utils.d.ts +5 -0
- package/node_modules/@oxygen/shared/dist/array-utils.js +11 -0
- package/node_modules/@oxygen/shared/dist/billing.d.ts +78 -22
- package/node_modules/@oxygen/shared/dist/billing.js +150 -40
- package/node_modules/@oxygen/shared/dist/capability-discovery.d.ts +17 -0
- package/node_modules/@oxygen/shared/dist/capability-discovery.js +89 -16
- package/node_modules/@oxygen/shared/dist/column-autofill.d.ts +52 -0
- package/node_modules/@oxygen/shared/dist/column-autofill.js +80 -0
- package/node_modules/@oxygen/shared/dist/column-output-fields.js +2 -6
- package/node_modules/@oxygen/shared/dist/company-enrichment-fields.d.ts +108 -0
- package/node_modules/@oxygen/shared/dist/company-enrichment-fields.js +545 -0
- package/node_modules/@oxygen/shared/dist/copilot-skills.generated.d.ts +2 -2
- package/node_modules/@oxygen/shared/dist/copilot-skills.generated.js +2 -2
- package/node_modules/@oxygen/shared/dist/deploy-env.d.ts +74 -0
- package/node_modules/@oxygen/shared/dist/deploy-env.js +82 -0
- package/node_modules/@oxygen/shared/dist/dnc-rules.d.ts +130 -0
- package/node_modules/@oxygen/shared/dist/dnc-rules.js +221 -0
- package/node_modules/@oxygen/shared/dist/enrichment-intents.d.ts +103 -0
- package/node_modules/@oxygen/shared/dist/enrichment-intents.js +819 -0
- package/node_modules/@oxygen/shared/dist/error-message.d.ts +1 -0
- package/node_modules/@oxygen/shared/dist/error-message.js +3 -0
- package/node_modules/@oxygen/shared/dist/error-redaction.js +1 -3
- package/node_modules/@oxygen/shared/dist/external-write-policy.d.ts +33 -0
- package/node_modules/@oxygen/shared/dist/external-write-policy.js +68 -0
- package/node_modules/@oxygen/shared/dist/format-percent.d.ts +8 -0
- package/node_modules/@oxygen/shared/dist/format-percent.js +13 -0
- package/node_modules/@oxygen/shared/dist/freemail-domains.d.ts +81 -0
- package/node_modules/@oxygen/shared/dist/freemail-domains.js +157 -0
- package/node_modules/@oxygen/shared/dist/future-signup-lifecycle-projection.d.ts +1 -0
- package/node_modules/@oxygen/shared/dist/future-signup-lifecycle-projection.js +1 -1
- package/node_modules/@oxygen/shared/dist/index.d.ts +13 -0
- package/node_modules/@oxygen/shared/dist/index.js +13 -0
- package/node_modules/@oxygen/shared/dist/json-path.js +1 -3
- package/node_modules/@oxygen/shared/dist/knowledge-bases.js +1 -3
- package/node_modules/@oxygen/shared/dist/knowledge-bootstrap.d.ts +2 -2
- package/node_modules/@oxygen/shared/dist/knowledge-bootstrap.js +2 -2
- package/node_modules/@oxygen/shared/dist/langfuse.js +9 -0
- package/node_modules/@oxygen/shared/dist/linkedin-countries.d.ts +32 -0
- package/node_modules/@oxygen/shared/dist/linkedin-countries.js +359 -0
- package/node_modules/@oxygen/shared/dist/log-sink-selector.d.ts +39 -0
- package/node_modules/@oxygen/shared/dist/log-sink-selector.js +56 -0
- package/node_modules/@oxygen/shared/dist/log.d.ts +1 -0
- package/node_modules/@oxygen/shared/dist/log.js +6 -1
- package/node_modules/@oxygen/shared/dist/object-storage.d.ts +17 -0
- package/node_modules/@oxygen/shared/dist/object-storage.js +21 -0
- package/node_modules/@oxygen/shared/dist/otlp-log-sink.d.ts +54 -0
- package/node_modules/@oxygen/shared/dist/otlp-log-sink.js +213 -0
- package/node_modules/@oxygen/shared/dist/plan-capabilities.js +1 -0
- package/node_modules/@oxygen/shared/dist/plan-limits.d.ts +23 -22
- package/node_modules/@oxygen/shared/dist/plan-limits.js +45 -18
- package/node_modules/@oxygen/shared/dist/pricing-sheet.d.ts +48 -41
- package/node_modules/@oxygen/shared/dist/pricing-sheet.js +36 -25
- package/node_modules/@oxygen/shared/dist/pricing-snapshot.generated.d.ts +22 -22
- package/node_modules/@oxygen/shared/dist/pricing-snapshot.generated.js +40 -34
- package/node_modules/@oxygen/shared/dist/product-analytics-environment.js +9 -0
- package/node_modules/@oxygen/shared/dist/product-analytics-events.d.ts +15 -0
- package/node_modules/@oxygen/shared/dist/product-analytics-events.js +15 -0
- package/node_modules/@oxygen/shared/dist/rate-window.d.ts +5 -0
- package/node_modules/@oxygen/shared/dist/rate-window.js +8 -0
- package/node_modules/@oxygen/shared/dist/research-output-contract.js +1 -3
- package/node_modules/@oxygen/shared/dist/search-vocab.js +4 -5
- package/node_modules/@oxygen/shared/dist/select-options.js +6 -1
- package/node_modules/@oxygen/shared/dist/sequence-failures.js +1 -5
- package/node_modules/@oxygen/shared/dist/sequences.d.ts +23 -0
- package/node_modules/@oxygen/shared/dist/sequences.js +110 -4
- package/node_modules/@oxygen/shared/dist/spend-safety.d.ts +22 -10
- package/node_modules/@oxygen/shared/dist/spend-safety.js +15 -21
- package/node_modules/@oxygen/shared/dist/sql-rows.d.ts +1 -0
- package/node_modules/@oxygen/shared/dist/sql-rows.js +3 -0
- package/node_modules/@oxygen/shared/dist/telemetry.js +9 -1
- package/node_modules/@oxygen/shared/dist/type-guards.d.ts +22 -0
- package/node_modules/@oxygen/shared/dist/type-guards.js +35 -0
- package/node_modules/@oxygen/shared/dist/value-readers.d.ts +21 -0
- package/node_modules/@oxygen/shared/dist/value-readers.js +59 -0
- package/node_modules/@oxygen/shared/dist/version.js +1 -1
- package/node_modules/@oxygen/shared/package.json +50 -0
- package/node_modules/@oxygen/workflows/dist/graph/expression.js +2 -5
- package/node_modules/@oxygen/workflows/dist/graph/params.js +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The country vocabulary behind the CRM's "Primary Location — Country" column.
|
|
3
|
+
*
|
|
4
|
+
* WHY A CHECKED-IN TABLE AND NOT `Intl.DisplayNames` AT RUNTIME: these strings
|
|
5
|
+
* are persisted. They become `definition.options[].value` on the column and the
|
|
6
|
+
* literal text stored in every cell, so deriving them from ICU would let a Node
|
|
7
|
+
* upgrade silently rename an option and orphan every row that already carried
|
|
8
|
+
* the old spelling. The table was GENERATED from CLDR English region names once
|
|
9
|
+
* (the 249 officially assigned ISO 3166-1 alpha-2 codes, plus XK/Kosovo, which
|
|
10
|
+
* LinkedIn lists and ISO does not), then frozen here with the overrides below.
|
|
11
|
+
*
|
|
12
|
+
* NAMING: LinkedIn spells a handful differently from CLDR's English short name
|
|
13
|
+
* — those are the entries carrying a trailing comment. Everything else is the
|
|
14
|
+
* CLDR name verbatim, which is what LinkedIn uses. This is a faithful
|
|
15
|
+
* reproduction of LinkedIn's vocabulary, not a scrape of its dropdown: the
|
|
16
|
+
* RESOLVER below is what makes that safe, because it accepts the alpha-2 code,
|
|
17
|
+
* any spelling in this table, and the aliases in COUNTRY_ALIASES. A scrape that
|
|
18
|
+
* returns "US", "United States", "USA" or "Congo - Kinshasa" all land on the
|
|
19
|
+
* one canonical option rather than on an empty cell.
|
|
20
|
+
*/
|
|
21
|
+
/** Canonical LinkedIn country name for each ISO 3166-1 alpha-2 code, A→Z by name. */
|
|
22
|
+
export const LINKEDIN_COUNTRIES = [
|
|
23
|
+
["AF", "Afghanistan"],
|
|
24
|
+
["AX", "Åland Islands"],
|
|
25
|
+
["AL", "Albania"],
|
|
26
|
+
["DZ", "Algeria"],
|
|
27
|
+
["AS", "American Samoa"],
|
|
28
|
+
["AD", "Andorra"],
|
|
29
|
+
["AO", "Angola"],
|
|
30
|
+
["AI", "Anguilla"],
|
|
31
|
+
["AQ", "Antarctica"],
|
|
32
|
+
["AG", "Antigua & Barbuda"],
|
|
33
|
+
["AR", "Argentina"],
|
|
34
|
+
["AM", "Armenia"],
|
|
35
|
+
["AW", "Aruba"],
|
|
36
|
+
["AU", "Australia"],
|
|
37
|
+
["AT", "Austria"],
|
|
38
|
+
["AZ", "Azerbaijan"],
|
|
39
|
+
["BS", "Bahamas"],
|
|
40
|
+
["BH", "Bahrain"],
|
|
41
|
+
["BD", "Bangladesh"],
|
|
42
|
+
["BB", "Barbados"],
|
|
43
|
+
["BY", "Belarus"],
|
|
44
|
+
["BE", "Belgium"],
|
|
45
|
+
["BZ", "Belize"],
|
|
46
|
+
["BJ", "Benin"],
|
|
47
|
+
["BM", "Bermuda"],
|
|
48
|
+
["BT", "Bhutan"],
|
|
49
|
+
["BO", "Bolivia"],
|
|
50
|
+
["BA", "Bosnia & Herzegovina"],
|
|
51
|
+
["BW", "Botswana"],
|
|
52
|
+
["BV", "Bouvet Island"],
|
|
53
|
+
["BR", "Brazil"],
|
|
54
|
+
["IO", "British Indian Ocean Territory"],
|
|
55
|
+
["VG", "British Virgin Islands"],
|
|
56
|
+
["BN", "Brunei"],
|
|
57
|
+
["BG", "Bulgaria"],
|
|
58
|
+
["BF", "Burkina Faso"],
|
|
59
|
+
["BI", "Burundi"],
|
|
60
|
+
["KH", "Cambodia"],
|
|
61
|
+
["CM", "Cameroon"],
|
|
62
|
+
["CA", "Canada"],
|
|
63
|
+
["CV", "Cape Verde"],
|
|
64
|
+
["BQ", "Caribbean Netherlands"],
|
|
65
|
+
["KY", "Cayman Islands"],
|
|
66
|
+
["CF", "Central African Republic"],
|
|
67
|
+
["TD", "Chad"],
|
|
68
|
+
["CL", "Chile"],
|
|
69
|
+
["CN", "China"],
|
|
70
|
+
["CX", "Christmas Island"],
|
|
71
|
+
["CC", "Cocos (Keeling) Islands"],
|
|
72
|
+
["CO", "Colombia"],
|
|
73
|
+
["KM", "Comoros"],
|
|
74
|
+
["CD", "Congo (DRC)"],
|
|
75
|
+
["CG", "Congo (Republic)"],
|
|
76
|
+
["CK", "Cook Islands"],
|
|
77
|
+
["CR", "Costa Rica"],
|
|
78
|
+
["CI", "Côte d'Ivoire"],
|
|
79
|
+
["HR", "Croatia"],
|
|
80
|
+
["CU", "Cuba"],
|
|
81
|
+
["CW", "Curaçao"],
|
|
82
|
+
["CY", "Cyprus"],
|
|
83
|
+
["CZ", "Czechia"],
|
|
84
|
+
["DK", "Denmark"],
|
|
85
|
+
["DJ", "Djibouti"],
|
|
86
|
+
["DM", "Dominica"],
|
|
87
|
+
["DO", "Dominican Republic"],
|
|
88
|
+
["EC", "Ecuador"],
|
|
89
|
+
["EG", "Egypt"],
|
|
90
|
+
["SV", "El Salvador"],
|
|
91
|
+
["GQ", "Equatorial Guinea"],
|
|
92
|
+
["ER", "Eritrea"],
|
|
93
|
+
["EE", "Estonia"],
|
|
94
|
+
["SZ", "Eswatini"],
|
|
95
|
+
["ET", "Ethiopia"],
|
|
96
|
+
["FK", "Falkland Islands"],
|
|
97
|
+
["FO", "Faroe Islands"],
|
|
98
|
+
["FJ", "Fiji"],
|
|
99
|
+
["FI", "Finland"],
|
|
100
|
+
["FR", "France"],
|
|
101
|
+
["GF", "French Guiana"],
|
|
102
|
+
["PF", "French Polynesia"],
|
|
103
|
+
["TF", "French Southern Territories"],
|
|
104
|
+
["GA", "Gabon"],
|
|
105
|
+
["GM", "Gambia"],
|
|
106
|
+
["GE", "Georgia"],
|
|
107
|
+
["DE", "Germany"],
|
|
108
|
+
["GH", "Ghana"],
|
|
109
|
+
["GI", "Gibraltar"],
|
|
110
|
+
["GR", "Greece"],
|
|
111
|
+
["GL", "Greenland"],
|
|
112
|
+
["GD", "Grenada"],
|
|
113
|
+
["GP", "Guadeloupe"],
|
|
114
|
+
["GU", "Guam"],
|
|
115
|
+
["GT", "Guatemala"],
|
|
116
|
+
["GG", "Guernsey"],
|
|
117
|
+
["GN", "Guinea"],
|
|
118
|
+
["GW", "Guinea-Bissau"],
|
|
119
|
+
["GY", "Guyana"],
|
|
120
|
+
["HT", "Haiti"],
|
|
121
|
+
["HM", "Heard & McDonald Islands"],
|
|
122
|
+
["HN", "Honduras"],
|
|
123
|
+
["HK", "Hong Kong SAR"],
|
|
124
|
+
["HU", "Hungary"],
|
|
125
|
+
["IS", "Iceland"],
|
|
126
|
+
["IN", "India"],
|
|
127
|
+
["ID", "Indonesia"],
|
|
128
|
+
["IR", "Iran"],
|
|
129
|
+
["IQ", "Iraq"],
|
|
130
|
+
["IE", "Ireland"],
|
|
131
|
+
["IM", "Isle of Man"],
|
|
132
|
+
["IL", "Israel"],
|
|
133
|
+
["IT", "Italy"],
|
|
134
|
+
["JM", "Jamaica"],
|
|
135
|
+
["JP", "Japan"],
|
|
136
|
+
["JE", "Jersey"],
|
|
137
|
+
["JO", "Jordan"],
|
|
138
|
+
["KZ", "Kazakhstan"],
|
|
139
|
+
["KE", "Kenya"],
|
|
140
|
+
["KI", "Kiribati"],
|
|
141
|
+
["XK", "Kosovo"],
|
|
142
|
+
["KW", "Kuwait"],
|
|
143
|
+
["KG", "Kyrgyzstan"],
|
|
144
|
+
["LA", "Laos"],
|
|
145
|
+
["LV", "Latvia"],
|
|
146
|
+
["LB", "Lebanon"],
|
|
147
|
+
["LS", "Lesotho"],
|
|
148
|
+
["LR", "Liberia"],
|
|
149
|
+
["LY", "Libya"],
|
|
150
|
+
["LI", "Liechtenstein"],
|
|
151
|
+
["LT", "Lithuania"],
|
|
152
|
+
["LU", "Luxembourg"],
|
|
153
|
+
["MO", "Macao SAR"],
|
|
154
|
+
["MG", "Madagascar"],
|
|
155
|
+
["MW", "Malawi"],
|
|
156
|
+
["MY", "Malaysia"],
|
|
157
|
+
["MV", "Maldives"],
|
|
158
|
+
["ML", "Mali"],
|
|
159
|
+
["MT", "Malta"],
|
|
160
|
+
["MH", "Marshall Islands"],
|
|
161
|
+
["MQ", "Martinique"],
|
|
162
|
+
["MR", "Mauritania"],
|
|
163
|
+
["MU", "Mauritius"],
|
|
164
|
+
["YT", "Mayotte"],
|
|
165
|
+
["MX", "Mexico"],
|
|
166
|
+
["FM", "Micronesia"],
|
|
167
|
+
["MD", "Moldova"],
|
|
168
|
+
["MC", "Monaco"],
|
|
169
|
+
["MN", "Mongolia"],
|
|
170
|
+
["ME", "Montenegro"],
|
|
171
|
+
["MS", "Montserrat"],
|
|
172
|
+
["MA", "Morocco"],
|
|
173
|
+
["MZ", "Mozambique"],
|
|
174
|
+
["MM", "Myanmar"],
|
|
175
|
+
["NA", "Namibia"],
|
|
176
|
+
["NR", "Nauru"],
|
|
177
|
+
["NP", "Nepal"],
|
|
178
|
+
["NL", "Netherlands"],
|
|
179
|
+
["NC", "New Caledonia"],
|
|
180
|
+
["NZ", "New Zealand"],
|
|
181
|
+
["NI", "Nicaragua"],
|
|
182
|
+
["NE", "Niger"],
|
|
183
|
+
["NG", "Nigeria"],
|
|
184
|
+
["NU", "Niue"],
|
|
185
|
+
["NF", "Norfolk Island"],
|
|
186
|
+
["KP", "North Korea"],
|
|
187
|
+
["MK", "North Macedonia"],
|
|
188
|
+
["MP", "Northern Mariana Islands"],
|
|
189
|
+
["NO", "Norway"],
|
|
190
|
+
["OM", "Oman"],
|
|
191
|
+
["PK", "Pakistan"],
|
|
192
|
+
["PW", "Palau"],
|
|
193
|
+
["PS", "Palestinian Territories"],
|
|
194
|
+
["PA", "Panama"],
|
|
195
|
+
["PG", "Papua New Guinea"],
|
|
196
|
+
["PY", "Paraguay"],
|
|
197
|
+
["PE", "Peru"],
|
|
198
|
+
["PH", "Philippines"],
|
|
199
|
+
["PN", "Pitcairn Islands"],
|
|
200
|
+
["PL", "Poland"],
|
|
201
|
+
["PT", "Portugal"],
|
|
202
|
+
["PR", "Puerto Rico"],
|
|
203
|
+
["QA", "Qatar"],
|
|
204
|
+
["RE", "Réunion"],
|
|
205
|
+
["RO", "Romania"],
|
|
206
|
+
["RU", "Russia"],
|
|
207
|
+
["RW", "Rwanda"],
|
|
208
|
+
["WS", "Samoa"],
|
|
209
|
+
["SM", "San Marino"],
|
|
210
|
+
["ST", "São Tomé & Príncipe"],
|
|
211
|
+
["SA", "Saudi Arabia"],
|
|
212
|
+
["SN", "Senegal"],
|
|
213
|
+
["RS", "Serbia"],
|
|
214
|
+
["SC", "Seychelles"],
|
|
215
|
+
["SL", "Sierra Leone"],
|
|
216
|
+
["SG", "Singapore"],
|
|
217
|
+
["SX", "Sint Maarten"],
|
|
218
|
+
["SK", "Slovakia"],
|
|
219
|
+
["SI", "Slovenia"],
|
|
220
|
+
["SB", "Solomon Islands"],
|
|
221
|
+
["SO", "Somalia"],
|
|
222
|
+
["ZA", "South Africa"],
|
|
223
|
+
["GS", "South Georgia & South Sandwich Islands"],
|
|
224
|
+
["KR", "South Korea"],
|
|
225
|
+
["SS", "South Sudan"],
|
|
226
|
+
["ES", "Spain"],
|
|
227
|
+
["LK", "Sri Lanka"],
|
|
228
|
+
["BL", "St. Barthélemy"],
|
|
229
|
+
["SH", "St. Helena"],
|
|
230
|
+
["KN", "St. Kitts & Nevis"],
|
|
231
|
+
["LC", "St. Lucia"],
|
|
232
|
+
["MF", "St. Martin"],
|
|
233
|
+
["PM", "St. Pierre & Miquelon"],
|
|
234
|
+
["VC", "St. Vincent & Grenadines"],
|
|
235
|
+
["SD", "Sudan"],
|
|
236
|
+
["SR", "Suriname"],
|
|
237
|
+
["SJ", "Svalbard & Jan Mayen"],
|
|
238
|
+
["SE", "Sweden"],
|
|
239
|
+
["CH", "Switzerland"],
|
|
240
|
+
["SY", "Syria"],
|
|
241
|
+
["TW", "Taiwan"],
|
|
242
|
+
["TJ", "Tajikistan"],
|
|
243
|
+
["TZ", "Tanzania"],
|
|
244
|
+
["TH", "Thailand"],
|
|
245
|
+
["TL", "Timor-Leste"],
|
|
246
|
+
["TG", "Togo"],
|
|
247
|
+
["TK", "Tokelau"],
|
|
248
|
+
["TO", "Tonga"],
|
|
249
|
+
["TT", "Trinidad & Tobago"],
|
|
250
|
+
["TN", "Tunisia"],
|
|
251
|
+
["TR", "Türkiye"],
|
|
252
|
+
["TM", "Turkmenistan"],
|
|
253
|
+
["TC", "Turks & Caicos Islands"],
|
|
254
|
+
["TV", "Tuvalu"],
|
|
255
|
+
["UM", "U.S. Outlying Islands"],
|
|
256
|
+
["VI", "U.S. Virgin Islands"],
|
|
257
|
+
["UG", "Uganda"],
|
|
258
|
+
["UA", "Ukraine"],
|
|
259
|
+
["AE", "United Arab Emirates"],
|
|
260
|
+
["GB", "United Kingdom"],
|
|
261
|
+
["US", "United States"],
|
|
262
|
+
["UY", "Uruguay"],
|
|
263
|
+
["UZ", "Uzbekistan"],
|
|
264
|
+
["VU", "Vanuatu"],
|
|
265
|
+
["VA", "Vatican City"],
|
|
266
|
+
["VE", "Venezuela"],
|
|
267
|
+
["VN", "Vietnam"],
|
|
268
|
+
["WF", "Wallis & Futuna"],
|
|
269
|
+
["EH", "Western Sahara"],
|
|
270
|
+
["YE", "Yemen"],
|
|
271
|
+
["ZM", "Zambia"],
|
|
272
|
+
["ZW", "Zimbabwe"],
|
|
273
|
+
];
|
|
274
|
+
/**
|
|
275
|
+
* Spellings a provider may return that are not the canonical name. Lowercased
|
|
276
|
+
* keys; the resolver lowercases its input before the lookup. Kept deliberately
|
|
277
|
+
* short — it covers the CLDR spellings this table overrides (so a payload
|
|
278
|
+
* carrying the un-overridden name still resolves), the common colloquial forms,
|
|
279
|
+
* and the alpha-3 codes, because Up2Data's `hq.country` is not contractually
|
|
280
|
+
* alpha-2 and has been observed carrying a display name.
|
|
281
|
+
*/
|
|
282
|
+
const COUNTRY_ALIASES = {
|
|
283
|
+
// CLDR spellings this table overrides.
|
|
284
|
+
"hong kong sar china": "HK",
|
|
285
|
+
"macao sar china": "MO",
|
|
286
|
+
"macau sar china": "MO",
|
|
287
|
+
"myanmar (burma)": "MM",
|
|
288
|
+
"congo - kinshasa": "CD",
|
|
289
|
+
"congo - brazzaville": "CG",
|
|
290
|
+
"côte d’ivoire": "CI",
|
|
291
|
+
"st. helena": "SH",
|
|
292
|
+
// Colloquial and legacy forms.
|
|
293
|
+
usa: "US",
|
|
294
|
+
"u.s.": "US",
|
|
295
|
+
"u.s.a.": "US",
|
|
296
|
+
"united states of america": "US",
|
|
297
|
+
uk: "GB",
|
|
298
|
+
"u.k.": "GB",
|
|
299
|
+
"great britain": "GB",
|
|
300
|
+
england: "GB",
|
|
301
|
+
scotland: "GB",
|
|
302
|
+
wales: "GB",
|
|
303
|
+
"northern ireland": "GB",
|
|
304
|
+
"czech republic": "CZ",
|
|
305
|
+
turkey: "TR",
|
|
306
|
+
"ivory coast": "CI",
|
|
307
|
+
burma: "MM",
|
|
308
|
+
swaziland: "SZ",
|
|
309
|
+
macedonia: "MK",
|
|
310
|
+
holland: "NL",
|
|
311
|
+
"the netherlands": "NL",
|
|
312
|
+
"south korea": "KR",
|
|
313
|
+
"korea, republic of": "KR",
|
|
314
|
+
"republic of korea": "KR",
|
|
315
|
+
"north korea": "KP",
|
|
316
|
+
"russian federation": "RU",
|
|
317
|
+
vatican: "VA",
|
|
318
|
+
"holy see": "VA",
|
|
319
|
+
palestine: "PS",
|
|
320
|
+
laos: "LA",
|
|
321
|
+
"cape verde": "CV",
|
|
322
|
+
"east timor": "TL",
|
|
323
|
+
uae: "AE",
|
|
324
|
+
"democratic republic of the congo": "CD",
|
|
325
|
+
"republic of the congo": "CG",
|
|
326
|
+
"hong kong": "HK",
|
|
327
|
+
macao: "MO",
|
|
328
|
+
macau: "MO",
|
|
329
|
+
};
|
|
330
|
+
const BY_CODE = new Map(LINKEDIN_COUNTRIES.map(([code, name]) => [code, name]));
|
|
331
|
+
const BY_LOWER_NAME = new Map(LINKEDIN_COUNTRIES.map(([code, name]) => [name.toLowerCase(), code]));
|
|
332
|
+
/**
|
|
333
|
+
* Resolve a provider value — an alpha-2 code, a canonical name, or a known
|
|
334
|
+
* alias — to its canonical LinkedIn country name.
|
|
335
|
+
*
|
|
336
|
+
* Returns null for anything unrecognized, which is deliberate: the column is a
|
|
337
|
+
* select, so writing a value that is not one of its options would produce a
|
|
338
|
+
* cell no filter can match and no dropdown can show. An empty cell is the
|
|
339
|
+
* honest outcome, and the raw payload is still on the record.
|
|
340
|
+
*/
|
|
341
|
+
export function resolveLinkedInCountry(value) {
|
|
342
|
+
if (typeof value !== "string")
|
|
343
|
+
return null;
|
|
344
|
+
const trimmed = value.trim();
|
|
345
|
+
if (!trimmed)
|
|
346
|
+
return null;
|
|
347
|
+
const upper = trimmed.toUpperCase();
|
|
348
|
+
if (upper.length === 2) {
|
|
349
|
+
const direct = BY_CODE.get(upper);
|
|
350
|
+
if (direct)
|
|
351
|
+
return direct;
|
|
352
|
+
}
|
|
353
|
+
const lower = trimmed.toLowerCase();
|
|
354
|
+
const byName = BY_LOWER_NAME.get(lower);
|
|
355
|
+
if (byName)
|
|
356
|
+
return BY_CODE.get(byName) ?? null;
|
|
357
|
+
const aliased = COUNTRY_ALIASES[lower];
|
|
358
|
+
return aliased ? BY_CODE.get(aliased) ?? null : null;
|
|
359
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { LogSink } from "./log.js";
|
|
2
|
+
/**
|
|
3
|
+
* Which transport(s) `log()` records leave the process on.
|
|
4
|
+
*
|
|
5
|
+
* Portability selector (`.agents/skills/oxygen-platform-portability/SKILL.md`):
|
|
6
|
+
* one concern, one variable, and **unset means managed**. An environment that
|
|
7
|
+
* sets nothing keeps today's behaviour exactly — the Axiom shipper alone, with
|
|
8
|
+
* the same handle and the same drain — so this can land on `dev` and flow to
|
|
9
|
+
* managed production with no flag day. Self-hosted opts in with `otlp` (an
|
|
10
|
+
* OTLP/HTTP collector instead of Axiom) or `both` (during a cutover window,
|
|
11
|
+
* when the two stores must be comparable before Axiom is switched off).
|
|
12
|
+
*
|
|
13
|
+
* An unrecognised value resolves to `axiom` rather than throwing: a typo in a
|
|
14
|
+
* telemetry variable must not decide whether a process boots.
|
|
15
|
+
*/
|
|
16
|
+
export type LogSinkSelector = "axiom" | "otlp" | "both";
|
|
17
|
+
export declare function resolveLogSinkSelector(env?: NodeJS.ProcessEnv): LogSinkSelector;
|
|
18
|
+
export declare function logSinkSelectorIncludesAxiom(selector: LogSinkSelector): boolean;
|
|
19
|
+
export declare function logSinkSelectorIncludesOtlp(selector: LogSinkSelector): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Failed sink invocations swallowed by a composed sink since process start.
|
|
22
|
+
*
|
|
23
|
+
* A composed sink cannot report its own failure through `log()` — it IS what
|
|
24
|
+
* `log()` calls, so logging from it would recurse. The count is the honest
|
|
25
|
+
* alternative to silence: readable from a diagnostic surface without the
|
|
26
|
+
* failing transport ever getting a second chance to throw.
|
|
27
|
+
*/
|
|
28
|
+
export declare function composedLogSinkFailureCount(): number;
|
|
29
|
+
/**
|
|
30
|
+
* Fans one record out to several transports.
|
|
31
|
+
*
|
|
32
|
+
* Every sink is called, in order, and each is wrapped: `both` exists precisely
|
|
33
|
+
* for the window where one of the two stores is not trusted yet, so a throwing
|
|
34
|
+
* Axiom sink must not stop the OTLP one from receiving the record (or the
|
|
35
|
+
* reverse). Nulls are dropped, so a caller can pass an adapter that declined to
|
|
36
|
+
* start without branching; all-null composes to `null`, which `setLogSink`
|
|
37
|
+
* reads as "no sink" and which keeps `log()` on its plain stdout path.
|
|
38
|
+
*/
|
|
39
|
+
export declare function composeLogSinks(...sinks: Array<LogSink | null | undefined>): LogSink | null;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export function resolveLogSinkSelector(env = process.env) {
|
|
2
|
+
const configured = env.OXYGEN_LOG_SINK?.trim().toLowerCase();
|
|
3
|
+
if (configured === "otlp")
|
|
4
|
+
return "otlp";
|
|
5
|
+
if (configured === "both")
|
|
6
|
+
return "both";
|
|
7
|
+
return "axiom";
|
|
8
|
+
}
|
|
9
|
+
export function logSinkSelectorIncludesAxiom(selector) {
|
|
10
|
+
return selector === "axiom" || selector === "both";
|
|
11
|
+
}
|
|
12
|
+
export function logSinkSelectorIncludesOtlp(selector) {
|
|
13
|
+
return selector === "otlp" || selector === "both";
|
|
14
|
+
}
|
|
15
|
+
let composedSinkFailures = 0;
|
|
16
|
+
/**
|
|
17
|
+
* Failed sink invocations swallowed by a composed sink since process start.
|
|
18
|
+
*
|
|
19
|
+
* A composed sink cannot report its own failure through `log()` — it IS what
|
|
20
|
+
* `log()` calls, so logging from it would recurse. The count is the honest
|
|
21
|
+
* alternative to silence: readable from a diagnostic surface without the
|
|
22
|
+
* failing transport ever getting a second chance to throw.
|
|
23
|
+
*/
|
|
24
|
+
export function composedLogSinkFailureCount() {
|
|
25
|
+
return composedSinkFailures;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Fans one record out to several transports.
|
|
29
|
+
*
|
|
30
|
+
* Every sink is called, in order, and each is wrapped: `both` exists precisely
|
|
31
|
+
* for the window where one of the two stores is not trusted yet, so a throwing
|
|
32
|
+
* Axiom sink must not stop the OTLP one from receiving the record (or the
|
|
33
|
+
* reverse). Nulls are dropped, so a caller can pass an adapter that declined to
|
|
34
|
+
* start without branching; all-null composes to `null`, which `setLogSink`
|
|
35
|
+
* reads as "no sink" and which keeps `log()` on its plain stdout path.
|
|
36
|
+
*/
|
|
37
|
+
export function composeLogSinks(...sinks) {
|
|
38
|
+
const active = sinks.filter((sink) => typeof sink === "function");
|
|
39
|
+
if (active.length === 0)
|
|
40
|
+
return null;
|
|
41
|
+
const only = active[0];
|
|
42
|
+
if (active.length === 1 && only)
|
|
43
|
+
return only;
|
|
44
|
+
return (record) => {
|
|
45
|
+
for (const sink of active) {
|
|
46
|
+
try {
|
|
47
|
+
sink(record);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// Telemetry must never break the code it observes, and this is the one
|
|
51
|
+
// place that cannot say so out loud (see composedLogSinkFailureCount).
|
|
52
|
+
composedSinkFailures += 1;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
@@ -19,6 +19,7 @@ export declare function enterLogContext(ctx: LogContext): void;
|
|
|
19
19
|
export declare function logLevelForHttpStatus(status: number): LogLevel;
|
|
20
20
|
export type LogSink = (record: Record<string, unknown>) => void;
|
|
21
21
|
export declare function setLogSink(sink: LogSink | null): void;
|
|
22
|
+
export declare function getLogSink(): LogSink | null;
|
|
22
23
|
export declare function log(level: LogLevel, msg: string, fields?: Record<string, unknown>): void;
|
|
23
24
|
export declare function errorId(err: unknown): string;
|
|
24
25
|
export declare function errorFields(err: unknown): Record<string, unknown>;
|
|
@@ -118,7 +118,12 @@ const LOG_SINK_SLOT = Symbol.for("oxygen.log.sink");
|
|
|
118
118
|
export function setLogSink(sink) {
|
|
119
119
|
globalThis[LOG_SINK_SLOT] = sink;
|
|
120
120
|
}
|
|
121
|
-
|
|
121
|
+
// Exported so a second transport can COMPOSE with the sink already registered
|
|
122
|
+
// rather than replacing it: under `OXYGEN_LOG_SINK=both` the OTLP adapter starts
|
|
123
|
+
// after the Axiom shipper has claimed the slot, and reading the slot back is what
|
|
124
|
+
// lets it fan out to both (`log-sink-selector.ts`). Reading through this function,
|
|
125
|
+
// not the raw Symbol, keeps the slot's location owned by exactly one module.
|
|
126
|
+
export function getLogSink() {
|
|
122
127
|
return globalThis[LOG_SINK_SLOT] ?? null;
|
|
123
128
|
}
|
|
124
129
|
const LEVEL_RANK = { debug: 10, info: 20, warn: 30, error: 40 };
|
|
@@ -5,6 +5,23 @@ export declare function resolveObjectStorageClient(): {
|
|
|
5
5
|
client: S3Client;
|
|
6
6
|
bucket: string;
|
|
7
7
|
};
|
|
8
|
+
/**
|
|
9
|
+
* The same endpoint and credentials, aimed at a DIFFERENT bucket.
|
|
10
|
+
*
|
|
11
|
+
* Every namespace above shares one private bucket because they share one access
|
|
12
|
+
* story: org-scoped keys, no anonymous reads. Public blobs (agency-directory
|
|
13
|
+
* logos; Payload media reaches the same bucket through its own plugin) are the
|
|
14
|
+
* opposite — their bytes are fetched by browsers with no credential at all — so
|
|
15
|
+
* on a self-hosted deploy they belong in a bucket whose read policy is public,
|
|
16
|
+
* never in the one holding customer lead lists.
|
|
17
|
+
* Same S3 account, different bucket: hence the client is reused and only the
|
|
18
|
+
* bucket is overridden. Empty is refused rather than silently falling back to
|
|
19
|
+
* the import bucket, which is exactly the mix-up this split exists to prevent.
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveObjectStorageClientForBucket(bucket: string): {
|
|
22
|
+
client: S3Client;
|
|
23
|
+
bucket: string;
|
|
24
|
+
};
|
|
8
25
|
export declare function buildImportObjectKey(input: {
|
|
9
26
|
organizationId: string;
|
|
10
27
|
fileName?: string | null;
|
|
@@ -82,6 +82,27 @@ export function resolveObjectStorageClient() {
|
|
|
82
82
|
const { client, config } = resolveClient();
|
|
83
83
|
return { client, bucket: config.bucket };
|
|
84
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* The same endpoint and credentials, aimed at a DIFFERENT bucket.
|
|
87
|
+
*
|
|
88
|
+
* Every namespace above shares one private bucket because they share one access
|
|
89
|
+
* story: org-scoped keys, no anonymous reads. Public blobs (agency-directory
|
|
90
|
+
* logos; Payload media reaches the same bucket through its own plugin) are the
|
|
91
|
+
* opposite — their bytes are fetched by browsers with no credential at all — so
|
|
92
|
+
* on a self-hosted deploy they belong in a bucket whose read policy is public,
|
|
93
|
+
* never in the one holding customer lead lists.
|
|
94
|
+
* Same S3 account, different bucket: hence the client is reused and only the
|
|
95
|
+
* bucket is overridden. Empty is refused rather than silently falling back to
|
|
96
|
+
* the import bucket, which is exactly the mix-up this split exists to prevent.
|
|
97
|
+
*/
|
|
98
|
+
export function resolveObjectStorageClientForBucket(bucket) {
|
|
99
|
+
const target = bucket.trim();
|
|
100
|
+
if (!target) {
|
|
101
|
+
throw new OxygenError("object_storage_bucket_missing", "No object-storage bucket was resolved for this operation.", { exitCode: 1 });
|
|
102
|
+
}
|
|
103
|
+
const { client } = resolveClient();
|
|
104
|
+
return { client, bucket: target };
|
|
105
|
+
}
|
|
85
106
|
export function buildImportObjectKey(input) {
|
|
86
107
|
const safeName = sanitizeFileName(input.fileName) || "import";
|
|
87
108
|
return `imports/${input.organizationId}/${randomUUID()}/${safeName}`;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { LogSink } from "./log.js";
|
|
2
|
+
/**
|
|
3
|
+
* Ships `log()` records to an OTLP/HTTP logs receiver (the self-hosted SigNoz
|
|
4
|
+
* collector) instead of — or alongside — Axiom.
|
|
5
|
+
*
|
|
6
|
+
* WHY HAND-ROLLED. This is a few dozen lines of JSON against a stable, versioned
|
|
7
|
+
* wire format. `@opentelemetry/exporter-logs-otlp-http` would pull the OTel logs
|
|
8
|
+
* SDK, a LoggerProvider, a BatchLogRecordProcessor and their transitive protobuf
|
|
9
|
+
* machinery into a package that every workspace imports — including edge-safe
|
|
10
|
+
* ones — to serialize a shape this module states in full below. The exporter
|
|
11
|
+
* also owns its own batching, so the drop-oldest/never-block/never-throw
|
|
12
|
+
* contract the two existing shippers hold would become the SDK's opinion rather
|
|
13
|
+
* than ours. OTLP/JSON is chosen over protobuf for the same reason: no codegen,
|
|
14
|
+
* no dependency, and a body an operator can read with `curl` when a collector
|
|
15
|
+
* silently rejects a batch.
|
|
16
|
+
*
|
|
17
|
+
* DELIVERY IS BEST-EFFORT BY CONSTRUCTION, exactly like
|
|
18
|
+
* `apps/worker/src/log-shipper.ts`: the sink only enqueues (it is called from
|
|
19
|
+
* inside `log()`, so it must never await, throw, or block), the queue drops the
|
|
20
|
+
* OLDEST record on overflow because the newest lines describe the incident being
|
|
21
|
+
* debugged, and a collector outage is a dropped batch rather than a process
|
|
22
|
+
* failure. Failures are written to stderr directly and at most once per flush
|
|
23
|
+
* window — reporting them through `log()` would feed this sink its own error
|
|
24
|
+
* line and recurse.
|
|
25
|
+
*/
|
|
26
|
+
export type OtlpLogSinkOptions = {
|
|
27
|
+
/** Full receiver URL, e.g. `http://collector.internal:4318/v1/logs`. */
|
|
28
|
+
endpoint: string;
|
|
29
|
+
/** Extra request headers (collector auth); see `parseOtlpHeaders`. */
|
|
30
|
+
headers?: Record<string, string> | undefined;
|
|
31
|
+
/** `service.name` resource attribute. */
|
|
32
|
+
serviceName: string;
|
|
33
|
+
/** Resource attributes merged after the defaults, so a caller can override them. */
|
|
34
|
+
resource?: Record<string, string | null | undefined> | undefined;
|
|
35
|
+
batchSize?: number | undefined;
|
|
36
|
+
/** `0` disables the interval timer, for runtimes that flush off a request lifecycle. */
|
|
37
|
+
flushIntervalMs?: number | undefined;
|
|
38
|
+
maxQueue?: number | undefined;
|
|
39
|
+
fetch?: typeof globalThis.fetch | undefined;
|
|
40
|
+
};
|
|
41
|
+
export type OtlpLogSinkHandle = {
|
|
42
|
+
sink: LogSink;
|
|
43
|
+
flush: () => Promise<void>;
|
|
44
|
+
stop: () => Promise<void>;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* `k=v,k=v` — the same shape as `OTEL_EXPORTER_OTLP_HEADERS`, so an operator who
|
|
48
|
+
* knows the OTel variable can set ours without learning a second syntax. A pair
|
|
49
|
+
* with no `=`, or an empty key, is skipped rather than throwing: this is parsed
|
|
50
|
+
* at process start, and a malformed telemetry header must not stop a boot. The
|
|
51
|
+
* value keeps every `=` after the first (tokens contain them).
|
|
52
|
+
*/
|
|
53
|
+
export declare function parseOtlpHeaders(raw: string | null | undefined): Record<string, string>;
|
|
54
|
+
export declare function createOtlpLogSink(options: OtlpLogSinkOptions): OtlpLogSinkHandle;
|