openings 0.1.8 → 0.1.9
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/.codex-plugin/plugin.json +1 -1
- package/package.json +1 -1
- package/src/locations.ts +17 -3
- package/src/providers.ts +10 -2
- package/src/version.ts +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openings",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Find evidence-grounded jobs, including relevant roles you may not have searched for, without accounts or API keys.",
|
|
5
5
|
"author": { "name": "Openings contributors" },
|
|
6
6
|
"license": "MIT",
|
package/package.json
CHANGED
package/src/locations.ts
CHANGED
|
@@ -101,12 +101,26 @@ function detectRegions(location: string, description: string): string[] {
|
|
|
101
101
|
return [...new Set([...fromLocation, ...fromDescription])];
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
/** US state and district postal codes. Many collide with ISO country codes (IN, CA, DE, CO, GA, ID, IL, LA, MA, MD, MO, MT, NE, PA, SC, SD, TN, VA). */
|
|
105
|
+
const US_STATE_CODES = new Set(["AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "FL", "GA", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA", "RI", "SC", "SD", "TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI", "WY", "DC"]);
|
|
106
|
+
const US_CITY_STATE = /,\s*([A-Z]{2})(?=\s*(?:$|,|\d{5}|\(|\/|-))/g;
|
|
107
|
+
|
|
104
108
|
function detectCountries(location: string): string[] {
|
|
105
|
-
const
|
|
109
|
+
const byName: string[] = [];
|
|
110
|
+
const byCode: string[] = [];
|
|
106
111
|
for (const rule of countryRules()) {
|
|
107
|
-
if (rule.location.test(location)
|
|
112
|
+
if (rule.location.test(location)) byName.push(rule.code);
|
|
113
|
+
else if (rule.codeLocation.test(location)) byCode.push(rule.code);
|
|
108
114
|
}
|
|
109
|
-
|
|
115
|
+
// "Indianapolis, IN" is Indiana, not India: a bare code in the US "City, ST" position is a state unless a country name
|
|
116
|
+
// or a known Indian place says otherwise.
|
|
117
|
+
// Case matters: "Berlin, de" is a lowercase country code, "Gary, IN" is a state.
|
|
118
|
+
const stateCodes = [...location.matchAll(US_CITY_STATE)].map((match) => match[1]!).filter((code) => US_STATE_CODES.has(code));
|
|
119
|
+
if (stateCodes.length && byName.length === 0 && !INDIA_PATTERN.test(location)) {
|
|
120
|
+
return [...new Set(["US", ...byCode.filter((code) => !US_STATE_CODES.has(code))])];
|
|
121
|
+
}
|
|
122
|
+
if (byName.includes("US")) return [...new Set([...byName, ...byCode.filter((code) => !US_STATE_CODES.has(code))])];
|
|
123
|
+
return [...new Set([...byName, ...byCode])];
|
|
110
124
|
}
|
|
111
125
|
|
|
112
126
|
function detectEligibleCountries(description: string): string[] {
|
package/src/providers.ts
CHANGED
|
@@ -65,7 +65,7 @@ const smartrecruiters: ProviderSpec = {
|
|
|
65
65
|
normalize(company, job) {
|
|
66
66
|
const loc = isRecord(job.location) ? job.location : {};
|
|
67
67
|
const country = str(loc.country);
|
|
68
|
-
const location = str(loc.fullLocation) || [str(loc.city), str(loc.region), country
|
|
68
|
+
const location = str(loc.fullLocation) || [str(loc.city), str(loc.region), countryLabel(country)].filter(Boolean).join(", ") || "Unspecified";
|
|
69
69
|
const remote = loc.remote === true;
|
|
70
70
|
return classifyJob({
|
|
71
71
|
id: `smartrecruiters:${company.slug}:${str(job.id)}`, company: company.name, title: str(job.name), location,
|
|
@@ -168,7 +168,7 @@ const freshteam: ProviderSpec = {
|
|
|
168
168
|
payloadVersion: () => "freshteam-widget:v1",
|
|
169
169
|
normalize(company, job) {
|
|
170
170
|
const branch = isRecord(job.branch) ? job.branch : {};
|
|
171
|
-
const location = [str(branch.city), str(branch.state), str(branch.country_code)
|
|
171
|
+
const location = [str(branch.city), str(branch.state), countryLabel(str(branch.country_code))].filter(Boolean).join(", ") || (job.remote === true ? "Remote" : "Unspecified");
|
|
172
172
|
const remote = job.remote === true;
|
|
173
173
|
return classifyJob({
|
|
174
174
|
id: `freshteam:${company.slug}:${str(job.unique_id) || str(job.id)}`, company: company.name, title: str(job.title), location,
|
|
@@ -196,6 +196,14 @@ export function resolveProviderSource(value: string): { ats: Ats; token: string;
|
|
|
196
196
|
return null;
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
+
const regionNames = new Intl.DisplayNames(["en"], { type: "region" });
|
|
200
|
+
/** ISO code to English name (US -> United States); anything that is not a two-letter code passes through. */
|
|
201
|
+
export function countryLabel(value: string): string {
|
|
202
|
+
const code = value.trim().toUpperCase();
|
|
203
|
+
if (!/^[A-Z]{2}$/.test(code)) return value.trim();
|
|
204
|
+
try { const name = regionNames.of(code); return name && name !== code ? name : value.trim(); } catch { return value.trim(); }
|
|
205
|
+
}
|
|
206
|
+
|
|
199
207
|
function validToken(value: string | undefined): string | null {
|
|
200
208
|
return value && /^[A-Za-z0-9][A-Za-z0-9._-]*$/.test(value) ? value : null;
|
|
201
209
|
}
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = "0.1.
|
|
1
|
+
export const VERSION = "0.1.9";
|