wwv-plugin-opencorporates 1.0.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/README.md +106 -0
- package/dist/index.esm.js +122 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# wwv-plugin-opencorporates
|
|
2
|
+
|
|
3
|
+
> **WorldWideView Plugin** β OpenCorporates Business Intelligence Layer
|
|
4
|
+
|
|
5
|
+
Search for companies using the [OpenCorporates API](https://opencorporates.com) and plot them on the WorldWideView 3D globe with full ownership, officer, and financial status data.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What it does
|
|
10
|
+
|
|
11
|
+
- Searches OpenCorporates for any company name you specify
|
|
12
|
+
- Geocodes each company's registered address via OpenStreetMap Nominatim
|
|
13
|
+
- Plots them as colored pins on the globe:
|
|
14
|
+
- π’ **Green** = Active company
|
|
15
|
+
- π΄ **Red** = Dissolved / struck off / liquidated
|
|
16
|
+
- π‘ **Yellow** = Unknown status
|
|
17
|
+
- Click any pin to see: company number, jurisdiction, type, incorporation date, officers, registry URL
|
|
18
|
+
- Refreshes every 10 minutes
|
|
19
|
+
- Filter by jurisdiction (e.g. `us_de` for Delaware, `gb` for UK, `eg` for Egypt)
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Use Cases
|
|
24
|
+
|
|
25
|
+
- Track shell company networks by jurisdiction
|
|
26
|
+
- Map corporate ownership structures geographically
|
|
27
|
+
- Research where companies in a financial crime investigation are registered
|
|
28
|
+
- Compare corporate density across jurisdictions
|
|
29
|
+
- Follow the money β see where holding companies cluster
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
### Option 1: Via WorldWideView Marketplace (once published)
|
|
36
|
+
|
|
37
|
+
1. Open WorldWideView β click **Submit a Plugin**
|
|
38
|
+
2. Enter: `wwv-plugin-opencorporates`
|
|
39
|
+
3. Click **Submit Plugin**
|
|
40
|
+
|
|
41
|
+
### Option 2: Manual / Local Dev
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# 1. Clone / download this plugin
|
|
45
|
+
git clone https://your-repo/wwv-plugin-opencorporates
|
|
46
|
+
cd wwv-plugin-opencorporates
|
|
47
|
+
|
|
48
|
+
# 2. Install dependencies
|
|
49
|
+
npm install
|
|
50
|
+
|
|
51
|
+
# 3. Build
|
|
52
|
+
npm run build
|
|
53
|
+
|
|
54
|
+
# 4. Publish to npm (required for marketplace submission)
|
|
55
|
+
npm login
|
|
56
|
+
npm publish --access public
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Configuration
|
|
62
|
+
|
|
63
|
+
After installing in WorldWideView, open the plugin settings panel and fill in:
|
|
64
|
+
|
|
65
|
+
| Field | Description | Example |
|
|
66
|
+
|---|---|---|
|
|
67
|
+
| **API Key** | Your OpenCorporates API key | `abc123xyz` |
|
|
68
|
+
| **Company Search Query** | What to search for | `Goldman Sachs` |
|
|
69
|
+
| **Jurisdiction Filter** | Limit by country/state (optional) | `us_de` or `gb` |
|
|
70
|
+
| **Max Results** | How many companies to plot (1-100) | `50` |
|
|
71
|
+
|
|
72
|
+
### Get a free OpenCorporates API key:
|
|
73
|
+
π https://opencorporates.com/api_accounts/new
|
|
74
|
+
|
|
75
|
+
### Jurisdiction codes:
|
|
76
|
+
- `us_de` β Delaware USA
|
|
77
|
+
- `us_ny` β New York USA
|
|
78
|
+
- `gb` β United Kingdom
|
|
79
|
+
- `eg` β Egypt
|
|
80
|
+
- `ae` β UAE
|
|
81
|
+
- `ky` β Cayman Islands
|
|
82
|
+
- Leave blank for global search
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## How it works
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
User sets search query
|
|
90
|
+
β
|
|
91
|
+
OpenCorporates API β returns company list
|
|
92
|
+
β
|
|
93
|
+
Each company's address β Nominatim geocoder β lat/lon
|
|
94
|
+
β
|
|
95
|
+
Globe entity emitted with color based on company status
|
|
96
|
+
β
|
|
97
|
+
WorldWideView plots pin on 3D globe
|
|
98
|
+
β
|
|
99
|
+
Click pin β popup shows full company data
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## License
|
|
105
|
+
|
|
106
|
+
MIT β build on it, modify it, do whatever.
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
const d = /* @__PURE__ */ new Map();
|
|
2
|
+
async function h(t) {
|
|
3
|
+
if (d.has(t)) return d.get(t);
|
|
4
|
+
try {
|
|
5
|
+
const e = encodeURIComponent(t), n = await (await fetch(`https://nominatim.openstreetmap.org/search?q=${e}&format=json&limit=1`, {
|
|
6
|
+
headers: { "User-Agent": "wwv-plugin-opencorporates/1.0" }
|
|
7
|
+
})).json();
|
|
8
|
+
if (n && n[0]) {
|
|
9
|
+
const s = { lat: parseFloat(n[0].lat), lon: parseFloat(n[0].lon) };
|
|
10
|
+
return d.set(t, s), s;
|
|
11
|
+
}
|
|
12
|
+
} catch {
|
|
13
|
+
}
|
|
14
|
+
return d.set(t, null), null;
|
|
15
|
+
}
|
|
16
|
+
const _ = "https://api.opencorporates.com/v0.4";
|
|
17
|
+
async function w(t, e, r, n) {
|
|
18
|
+
var l;
|
|
19
|
+
const s = new URLSearchParams({
|
|
20
|
+
q: t,
|
|
21
|
+
api_token: e,
|
|
22
|
+
per_page: String(Math.min(n, 100)),
|
|
23
|
+
fields: "name,company_number,jurisdiction_code,incorporation_date,dissolution_date,company_type,registry_url,registered_address,current_status"
|
|
24
|
+
});
|
|
25
|
+
r && s.set("jurisdiction_code", r);
|
|
26
|
+
const u = `${_}/companies/search?${s}`, a = await fetch(u);
|
|
27
|
+
if (!a.ok) throw new Error(`OpenCorporates API error: ${a.status} ${a.statusText}`);
|
|
28
|
+
const c = await a.json();
|
|
29
|
+
return ((l = c == null ? void 0 : c.results) == null ? void 0 : l.companies) ?? [];
|
|
30
|
+
}
|
|
31
|
+
function C(t) {
|
|
32
|
+
if (!t) return "#FFD700";
|
|
33
|
+
const e = t.toLowerCase();
|
|
34
|
+
return e.includes("active") || e.includes("live") ? "#00FF88" : e.includes("dissolv") || e.includes("struck") || e.includes("liquidat") ? "#FF4444" : "#FFD700";
|
|
35
|
+
}
|
|
36
|
+
async function $(t) {
|
|
37
|
+
var a, c, l, m;
|
|
38
|
+
const e = t.company, r = [
|
|
39
|
+
(a = e.registered_address) == null ? void 0 : a.street_address,
|
|
40
|
+
(c = e.registered_address) == null ? void 0 : c.locality,
|
|
41
|
+
(l = e.registered_address) == null ? void 0 : l.country
|
|
42
|
+
].filter(Boolean);
|
|
43
|
+
if (r.length === 0) return null;
|
|
44
|
+
const n = r.join(", "), s = await h(n);
|
|
45
|
+
if (!s) return null;
|
|
46
|
+
const u = () => (Math.random() - 0.5) * 0.01;
|
|
47
|
+
return {
|
|
48
|
+
id: `oc-${e.jurisdiction_code}-${e.company_number}`,
|
|
49
|
+
lat: s.lat + u(),
|
|
50
|
+
lon: s.lon + u(),
|
|
51
|
+
label: e.name,
|
|
52
|
+
color: C(e.current_status),
|
|
53
|
+
size: 10,
|
|
54
|
+
data: {
|
|
55
|
+
"Company Number": e.company_number,
|
|
56
|
+
Jurisdiction: ((m = e.jurisdiction_code) == null ? void 0 : m.toUpperCase()) ?? "β",
|
|
57
|
+
Type: e.company_type ?? "β",
|
|
58
|
+
Status: e.current_status ?? "β",
|
|
59
|
+
Incorporated: e.incorporation_date ?? "β",
|
|
60
|
+
Dissolved: e.dissolution_date ?? "β",
|
|
61
|
+
Address: n,
|
|
62
|
+
Registry: e.registry_url ?? "β",
|
|
63
|
+
Officers: (e.officers ?? []).map((y) => `${y.name} (${y.position})`).join(", ") || "β",
|
|
64
|
+
_source: "OpenCorporates"
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
let o, i, p = null, g = !1;
|
|
69
|
+
async function f() {
|
|
70
|
+
if (!g) {
|
|
71
|
+
if (!i.apiKey) {
|
|
72
|
+
o.showNotification("OpenCorporates: Please set your API key in plugin settings.", "error");
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (!i.searchQuery) {
|
|
76
|
+
o.showNotification("OpenCorporates: Enter a company name in plugin settings to search.", "info");
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
g = !0, o.log(`[OpenCorporates] Searching: "${i.searchQuery}" (jurisdiction: ${i.jurisdiction || "global"})`), o.showNotification(`Searching OpenCorporates for "${i.searchQuery}"β¦`, "info");
|
|
80
|
+
try {
|
|
81
|
+
const t = await w(
|
|
82
|
+
i.searchQuery,
|
|
83
|
+
i.apiKey,
|
|
84
|
+
i.jurisdiction,
|
|
85
|
+
i.maxResults ?? 50
|
|
86
|
+
);
|
|
87
|
+
o.log(`[OpenCorporates] Found ${t.length} companies, geocodingβ¦`);
|
|
88
|
+
const e = [];
|
|
89
|
+
for (let r = 0; r < t.length; r++) {
|
|
90
|
+
const n = await $(t[r]);
|
|
91
|
+
n && e.push(n), r % 5 === 4 && await new Promise((s) => setTimeout(s, 1200));
|
|
92
|
+
}
|
|
93
|
+
o.emit("entities:replace", {
|
|
94
|
+
pluginId: "wwv-plugin-opencorporates",
|
|
95
|
+
entities: e
|
|
96
|
+
}), o.showNotification(
|
|
97
|
+
`OpenCorporates: Plotted ${e.length} companies on the globe.`,
|
|
98
|
+
"success"
|
|
99
|
+
), o.log(`[OpenCorporates] Done. ${e.length} entities emitted.`);
|
|
100
|
+
} catch (t) {
|
|
101
|
+
const e = t instanceof Error ? t.message : String(t);
|
|
102
|
+
o.log(`[OpenCorporates] Error: ${e}`), o.showNotification(`OpenCorporates error: ${e}`, "error");
|
|
103
|
+
} finally {
|
|
104
|
+
g = !1;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const O = {
|
|
109
|
+
id: "wwv-plugin-opencorporates",
|
|
110
|
+
async initialize(t, e) {
|
|
111
|
+
o = t, i = e, o.log("[OpenCorporates] Plugin initialized."), o.onConfigChange((r) => {
|
|
112
|
+
i = r, p && clearInterval(p), setTimeout(() => f(), 1500);
|
|
113
|
+
}), await f(), p = setInterval(() => f(), 10 * 60 * 1e3);
|
|
114
|
+
},
|
|
115
|
+
destroy() {
|
|
116
|
+
p && clearInterval(p), o == null || o.log("[OpenCorporates] Plugin destroyed.");
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
export {
|
|
120
|
+
O as default
|
|
121
|
+
};
|
|
122
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/index.ts"],"sourcesContent":["/**\n * wwv-plugin-opencorporates\n * WorldWideView plugin β OpenCorporates Business Intelligence Layer\n *\n * Queries the OpenCorporates API for companies matching a search term,\n * geocodes their registered addresses, and emits them as globe entities\n * with rich financial/ownership popups.\n */\n\n// βββ Types (mirrors @worldwideview/wwv-plugin-sdk interfaces) ββββββββββββββββ\n\ninterface PluginContext {\n emit: (event: string, payload: unknown) => void;\n onConfigChange: (cb: (cfg: PluginConfig) => void) => void;\n log: (msg: string) => void;\n showNotification: (msg: string, type?: \"info\" | \"error\" | \"success\") => void;\n}\n\ninterface PluginConfig {\n apiKey: string;\n searchQuery: string;\n jurisdiction: string;\n maxResults: number;\n}\n\ninterface GlobeEntity {\n id: string;\n lat: number;\n lon: number;\n label: string;\n color: string; // hex\n size: number; // pixels\n data: Record<string, unknown>;\n}\n\ninterface OcCompany {\n company: {\n name: string;\n company_number: string;\n jurisdiction_code: string;\n incorporation_date: string;\n dissolution_date: string | null;\n company_type: string;\n registry_url: string;\n registered_address: {\n street_address?: string;\n locality?: string;\n country?: string;\n } | null;\n officers?: Array<{ name: string; position: string }>;\n number_of_employees?: number;\n current_status: string;\n };\n}\n\n// βββ Geocoding cache (simple in-memory) ββββββββββββββββββββββββββββββββββββββ\n\nconst geocodeCache = new Map<string, { lat: number; lon: number } | null>();\n\nasync function geocodeAddress(address: string): Promise<{ lat: number; lon: number } | null> {\n if (geocodeCache.has(address)) return geocodeCache.get(address)!;\n try {\n const q = encodeURIComponent(address);\n const res = await fetch(`https://nominatim.openstreetmap.org/search?q=${q}&format=json&limit=1`, {\n headers: { \"User-Agent\": \"wwv-plugin-opencorporates/1.0\" }\n });\n const data = await res.json();\n if (data && data[0]) {\n const result = { lat: parseFloat(data[0].lat), lon: parseFloat(data[0].lon) };\n geocodeCache.set(address, result);\n return result;\n }\n } catch (_) {/* silently fail */}\n geocodeCache.set(address, null);\n return null;\n}\n\n// βββ OpenCorporates API helpers βββββββββββββββββββββββββββββββββββββββββββββββ\n\nconst OC_BASE = \"https://api.opencorporates.com/v0.4\";\n\nasync function searchCompanies(\n query: string,\n apiKey: string,\n jurisdiction: string,\n perPage: number\n): Promise<OcCompany[]> {\n const params = new URLSearchParams({\n q: query,\n api_token: apiKey,\n per_page: String(Math.min(perPage, 100)),\n fields: \"name,company_number,jurisdiction_code,incorporation_date,dissolution_date,company_type,registry_url,registered_address,current_status\"\n });\n if (jurisdiction) params.set(\"jurisdiction_code\", jurisdiction);\n\n const url = `${OC_BASE}/companies/search?${params}`;\n const res = await fetch(url);\n if (!res.ok) throw new Error(`OpenCorporates API error: ${res.status} ${res.statusText}`);\n const json = await res.json();\n return json?.results?.companies ?? [];\n}\n\n// βββ Color logic (active=green, dissolved=red, unknown=yellow) ββββββββββββββββ\n\nfunction statusColor(status: string | null): string {\n if (!status) return \"#FFD700\";\n const s = status.toLowerCase();\n if (s.includes(\"active\") || s.includes(\"live\")) return \"#00FF88\";\n if (s.includes(\"dissolv\") || s.includes(\"struck\") || s.includes(\"liquidat\")) return \"#FF4444\";\n return \"#FFD700\";\n}\n\n// βββ Build globe entity from OC company ββββββββββββββββββββββββββββββββββββββ\n\nasync function companyToEntity(raw: OcCompany): Promise<GlobeEntity | null> {\n const c = raw.company;\n\n // Build address string for geocoding\n const addrParts = [\n c.registered_address?.street_address,\n c.registered_address?.locality,\n c.registered_address?.country\n ].filter(Boolean);\n\n if (addrParts.length === 0) return null;\n const addressStr = addrParts.join(\", \");\n\n const coords = await geocodeAddress(addressStr);\n if (!coords) return null;\n\n // Add slight jitter so overlapping pins don't stack exactly\n const jitter = () => (Math.random() - 0.5) * 0.01;\n\n return {\n id: `oc-${c.jurisdiction_code}-${c.company_number}`,\n lat: coords.lat + jitter(),\n lon: coords.lon + jitter(),\n label: c.name,\n color: statusColor(c.current_status),\n size: 10,\n data: {\n \"Company Number\": c.company_number,\n \"Jurisdiction\": c.jurisdiction_code?.toUpperCase() ?? \"β\",\n \"Type\": c.company_type ?? \"β\",\n \"Status\": c.current_status ?? \"β\",\n \"Incorporated\": c.incorporation_date ?? \"β\",\n \"Dissolved\": c.dissolution_date ?? \"β\",\n \"Address\": addressStr,\n \"Registry\": c.registry_url ?? \"β\",\n \"Officers\": (c.officers ?? []).map((o) => `${o.name} (${o.position})`).join(\", \") || \"β\",\n \"_source\": \"OpenCorporates\"\n }\n };\n}\n\n// βββ Plugin lifecycle βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nlet _ctx: PluginContext;\nlet _cfg: PluginConfig;\nlet _pollTimer: ReturnType<typeof setInterval> | null = null;\nlet _running = false;\n\nasync function runScan() {\n if (_running) return;\n if (!_cfg.apiKey) {\n _ctx.showNotification(\"OpenCorporates: Please set your API key in plugin settings.\", \"error\");\n return;\n }\n if (!_cfg.searchQuery) {\n _ctx.showNotification(\"OpenCorporates: Enter a company name in plugin settings to search.\", \"info\");\n return;\n }\n\n _running = true;\n _ctx.log(`[OpenCorporates] Searching: \"${_cfg.searchQuery}\" (jurisdiction: ${_cfg.jurisdiction || \"global\"})`);\n _ctx.showNotification(`Searching OpenCorporates for \"${_cfg.searchQuery}\"β¦`, \"info\");\n\n try {\n const companies = await searchCompanies(\n _cfg.searchQuery,\n _cfg.apiKey,\n _cfg.jurisdiction,\n _cfg.maxResults ?? 50\n );\n\n _ctx.log(`[OpenCorporates] Found ${companies.length} companies, geocodingβ¦`);\n\n const entities: GlobeEntity[] = [];\n\n // Process in batches to avoid hammering Nominatim\n for (let i = 0; i < companies.length; i++) {\n const entity = await companyToEntity(companies[i]);\n if (entity) entities.push(entity);\n // Nominatim rate limit: 1 req/sec\n if (i % 5 === 4) await new Promise((r) => setTimeout(r, 1200));\n }\n\n _ctx.emit(\"entities:replace\", {\n pluginId: \"wwv-plugin-opencorporates\",\n entities\n });\n\n _ctx.showNotification(\n `OpenCorporates: Plotted ${entities.length} companies on the globe.`,\n \"success\"\n );\n _ctx.log(`[OpenCorporates] Done. ${entities.length} entities emitted.`);\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n _ctx.log(`[OpenCorporates] Error: ${msg}`);\n _ctx.showNotification(`OpenCorporates error: ${msg}`, \"error\");\n } finally {\n _running = false;\n }\n}\n\n// βββ Exported plugin object (WorldWideView plugin contract) ββββββββββββββββββ\n\nexport default {\n id: \"wwv-plugin-opencorporates\",\n\n async initialize(context: PluginContext, config: PluginConfig) {\n _ctx = context;\n _cfg = config;\n\n _ctx.log(\"[OpenCorporates] Plugin initialized.\");\n\n // React to config changes (user types new search query / API key)\n _ctx.onConfigChange((newCfg: PluginConfig) => {\n _cfg = newCfg;\n // Debounce: clear old timer, rescan after 1.5s\n if (_pollTimer) clearInterval(_pollTimer);\n setTimeout(() => runScan(), 1500);\n });\n\n // Initial scan\n await runScan();\n\n // Refresh every 10 minutes (company data doesn't change fast)\n _pollTimer = setInterval(() => runScan(), 10 * 60 * 1000);\n },\n\n destroy() {\n if (_pollTimer) clearInterval(_pollTimer);\n _ctx?.log(\"[OpenCorporates] Plugin destroyed.\");\n }\n};\n"],"names":["geocodeCache","geocodeAddress","address","q","data","result","OC_BASE","searchCompanies","query","apiKey","jurisdiction","perPage","_a","params","url","res","json","statusColor","status","s","companyToEntity","raw","_b","_c","_d","c","addrParts","addressStr","coords","jitter","o","_ctx","_cfg","_pollTimer","_running","runScan","companies","entities","i","entity","r","err","msg","index","context","config","newCfg"],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const d=new Map;async function h(t){if(d.has(t))return d.get(t);try{const e=encodeURIComponent(t),n=await(await fetch(`https://nominatim.openstreetmap.org/search?q=${e}&format=json&limit=1`,{headers:{"User-Agent":"wwv-plugin-opencorporates/1.0"}})).json();if(n&&n[0]){const s={lat:parseFloat(n[0].lat),lon:parseFloat(n[0].lon)};return d.set(t,s),s}}catch{}return d.set(t,null),null}const _="https://api.opencorporates.com/v0.4";async function w(t,e,r,n){var l;const s=new URLSearchParams({q:t,api_token:e,per_page:String(Math.min(n,100)),fields:"name,company_number,jurisdiction_code,incorporation_date,dissolution_date,company_type,registry_url,registered_address,current_status"});r&&s.set("jurisdiction_code",r);const u=`${_}/companies/search?${s}`,a=await fetch(u);if(!a.ok)throw new Error(`OpenCorporates API error: ${a.status} ${a.statusText}`);const c=await a.json();return((l=c==null?void 0:c.results)==null?void 0:l.companies)??[]}function C(t){if(!t)return"#FFD700";const e=t.toLowerCase();return e.includes("active")||e.includes("live")?"#00FF88":e.includes("dissolv")||e.includes("struck")||e.includes("liquidat")?"#FF4444":"#FFD700"}async function $(t){var a,c,l,m;const e=t.company,r=[(a=e.registered_address)==null?void 0:a.street_address,(c=e.registered_address)==null?void 0:c.locality,(l=e.registered_address)==null?void 0:l.country].filter(Boolean);if(r.length===0)return null;const n=r.join(", "),s=await h(n);if(!s)return null;const u=()=>(Math.random()-.5)*.01;return{id:`oc-${e.jurisdiction_code}-${e.company_number}`,lat:s.lat+u(),lon:s.lon+u(),label:e.name,color:C(e.current_status),size:10,data:{"Company Number":e.company_number,Jurisdiction:((m=e.jurisdiction_code)==null?void 0:m.toUpperCase())??"β",Type:e.company_type??"β",Status:e.current_status??"β",Incorporated:e.incorporation_date??"β",Dissolved:e.dissolution_date??"β",Address:n,Registry:e.registry_url??"β",Officers:(e.officers??[]).map(y=>`${y.name} (${y.position})`).join(", ")||"β",_source:"OpenCorporates"}}}let o,i,p=null,g=!1;async function f(){if(!g){if(!i.apiKey){o.showNotification("OpenCorporates: Please set your API key in plugin settings.","error");return}if(!i.searchQuery){o.showNotification("OpenCorporates: Enter a company name in plugin settings to search.","info");return}g=!0,o.log(`[OpenCorporates] Searching: "${i.searchQuery}" (jurisdiction: ${i.jurisdiction||"global"})`),o.showNotification(`Searching OpenCorporates for "${i.searchQuery}"β¦`,"info");try{const t=await w(i.searchQuery,i.apiKey,i.jurisdiction,i.maxResults??50);o.log(`[OpenCorporates] Found ${t.length} companies, geocodingβ¦`);const e=[];for(let r=0;r<t.length;r++){const n=await $(t[r]);n&&e.push(n),r%5===4&&await new Promise(s=>setTimeout(s,1200))}o.emit("entities:replace",{pluginId:"wwv-plugin-opencorporates",entities:e}),o.showNotification(`OpenCorporates: Plotted ${e.length} companies on the globe.`,"success"),o.log(`[OpenCorporates] Done. ${e.length} entities emitted.`)}catch(t){const e=t instanceof Error?t.message:String(t);o.log(`[OpenCorporates] Error: ${e}`),o.showNotification(`OpenCorporates error: ${e}`,"error")}finally{g=!1}}}const O={id:"wwv-plugin-opencorporates",async initialize(t,e){o=t,i=e,o.log("[OpenCorporates] Plugin initialized."),o.onConfigChange(r=>{i=r,p&&clearInterval(p),setTimeout(()=>f(),1500)}),await f(),p=setInterval(()=>f(),10*60*1e3)},destroy(){p&&clearInterval(p),o==null||o.log("[OpenCorporates] Plugin destroyed.")}};module.exports=O;
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["/**\n * wwv-plugin-opencorporates\n * WorldWideView plugin β OpenCorporates Business Intelligence Layer\n *\n * Queries the OpenCorporates API for companies matching a search term,\n * geocodes their registered addresses, and emits them as globe entities\n * with rich financial/ownership popups.\n */\n\n// βββ Types (mirrors @worldwideview/wwv-plugin-sdk interfaces) ββββββββββββββββ\n\ninterface PluginContext {\n emit: (event: string, payload: unknown) => void;\n onConfigChange: (cb: (cfg: PluginConfig) => void) => void;\n log: (msg: string) => void;\n showNotification: (msg: string, type?: \"info\" | \"error\" | \"success\") => void;\n}\n\ninterface PluginConfig {\n apiKey: string;\n searchQuery: string;\n jurisdiction: string;\n maxResults: number;\n}\n\ninterface GlobeEntity {\n id: string;\n lat: number;\n lon: number;\n label: string;\n color: string; // hex\n size: number; // pixels\n data: Record<string, unknown>;\n}\n\ninterface OcCompany {\n company: {\n name: string;\n company_number: string;\n jurisdiction_code: string;\n incorporation_date: string;\n dissolution_date: string | null;\n company_type: string;\n registry_url: string;\n registered_address: {\n street_address?: string;\n locality?: string;\n country?: string;\n } | null;\n officers?: Array<{ name: string; position: string }>;\n number_of_employees?: number;\n current_status: string;\n };\n}\n\n// βββ Geocoding cache (simple in-memory) ββββββββββββββββββββββββββββββββββββββ\n\nconst geocodeCache = new Map<string, { lat: number; lon: number } | null>();\n\nasync function geocodeAddress(address: string): Promise<{ lat: number; lon: number } | null> {\n if (geocodeCache.has(address)) return geocodeCache.get(address)!;\n try {\n const q = encodeURIComponent(address);\n const res = await fetch(`https://nominatim.openstreetmap.org/search?q=${q}&format=json&limit=1`, {\n headers: { \"User-Agent\": \"wwv-plugin-opencorporates/1.0\" }\n });\n const data = await res.json();\n if (data && data[0]) {\n const result = { lat: parseFloat(data[0].lat), lon: parseFloat(data[0].lon) };\n geocodeCache.set(address, result);\n return result;\n }\n } catch (_) {/* silently fail */}\n geocodeCache.set(address, null);\n return null;\n}\n\n// βββ OpenCorporates API helpers βββββββββββββββββββββββββββββββββββββββββββββββ\n\nconst OC_BASE = \"https://api.opencorporates.com/v0.4\";\n\nasync function searchCompanies(\n query: string,\n apiKey: string,\n jurisdiction: string,\n perPage: number\n): Promise<OcCompany[]> {\n const params = new URLSearchParams({\n q: query,\n api_token: apiKey,\n per_page: String(Math.min(perPage, 100)),\n fields: \"name,company_number,jurisdiction_code,incorporation_date,dissolution_date,company_type,registry_url,registered_address,current_status\"\n });\n if (jurisdiction) params.set(\"jurisdiction_code\", jurisdiction);\n\n const url = `${OC_BASE}/companies/search?${params}`;\n const res = await fetch(url);\n if (!res.ok) throw new Error(`OpenCorporates API error: ${res.status} ${res.statusText}`);\n const json = await res.json();\n return json?.results?.companies ?? [];\n}\n\n// βββ Color logic (active=green, dissolved=red, unknown=yellow) ββββββββββββββββ\n\nfunction statusColor(status: string | null): string {\n if (!status) return \"#FFD700\";\n const s = status.toLowerCase();\n if (s.includes(\"active\") || s.includes(\"live\")) return \"#00FF88\";\n if (s.includes(\"dissolv\") || s.includes(\"struck\") || s.includes(\"liquidat\")) return \"#FF4444\";\n return \"#FFD700\";\n}\n\n// βββ Build globe entity from OC company ββββββββββββββββββββββββββββββββββββββ\n\nasync function companyToEntity(raw: OcCompany): Promise<GlobeEntity | null> {\n const c = raw.company;\n\n // Build address string for geocoding\n const addrParts = [\n c.registered_address?.street_address,\n c.registered_address?.locality,\n c.registered_address?.country\n ].filter(Boolean);\n\n if (addrParts.length === 0) return null;\n const addressStr = addrParts.join(\", \");\n\n const coords = await geocodeAddress(addressStr);\n if (!coords) return null;\n\n // Add slight jitter so overlapping pins don't stack exactly\n const jitter = () => (Math.random() - 0.5) * 0.01;\n\n return {\n id: `oc-${c.jurisdiction_code}-${c.company_number}`,\n lat: coords.lat + jitter(),\n lon: coords.lon + jitter(),\n label: c.name,\n color: statusColor(c.current_status),\n size: 10,\n data: {\n \"Company Number\": c.company_number,\n \"Jurisdiction\": c.jurisdiction_code?.toUpperCase() ?? \"β\",\n \"Type\": c.company_type ?? \"β\",\n \"Status\": c.current_status ?? \"β\",\n \"Incorporated\": c.incorporation_date ?? \"β\",\n \"Dissolved\": c.dissolution_date ?? \"β\",\n \"Address\": addressStr,\n \"Registry\": c.registry_url ?? \"β\",\n \"Officers\": (c.officers ?? []).map((o) => `${o.name} (${o.position})`).join(\", \") || \"β\",\n \"_source\": \"OpenCorporates\"\n }\n };\n}\n\n// βββ Plugin lifecycle βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ\n\nlet _ctx: PluginContext;\nlet _cfg: PluginConfig;\nlet _pollTimer: ReturnType<typeof setInterval> | null = null;\nlet _running = false;\n\nasync function runScan() {\n if (_running) return;\n if (!_cfg.apiKey) {\n _ctx.showNotification(\"OpenCorporates: Please set your API key in plugin settings.\", \"error\");\n return;\n }\n if (!_cfg.searchQuery) {\n _ctx.showNotification(\"OpenCorporates: Enter a company name in plugin settings to search.\", \"info\");\n return;\n }\n\n _running = true;\n _ctx.log(`[OpenCorporates] Searching: \"${_cfg.searchQuery}\" (jurisdiction: ${_cfg.jurisdiction || \"global\"})`);\n _ctx.showNotification(`Searching OpenCorporates for \"${_cfg.searchQuery}\"β¦`, \"info\");\n\n try {\n const companies = await searchCompanies(\n _cfg.searchQuery,\n _cfg.apiKey,\n _cfg.jurisdiction,\n _cfg.maxResults ?? 50\n );\n\n _ctx.log(`[OpenCorporates] Found ${companies.length} companies, geocodingβ¦`);\n\n const entities: GlobeEntity[] = [];\n\n // Process in batches to avoid hammering Nominatim\n for (let i = 0; i < companies.length; i++) {\n const entity = await companyToEntity(companies[i]);\n if (entity) entities.push(entity);\n // Nominatim rate limit: 1 req/sec\n if (i % 5 === 4) await new Promise((r) => setTimeout(r, 1200));\n }\n\n _ctx.emit(\"entities:replace\", {\n pluginId: \"wwv-plugin-opencorporates\",\n entities\n });\n\n _ctx.showNotification(\n `OpenCorporates: Plotted ${entities.length} companies on the globe.`,\n \"success\"\n );\n _ctx.log(`[OpenCorporates] Done. ${entities.length} entities emitted.`);\n } catch (err: unknown) {\n const msg = err instanceof Error ? err.message : String(err);\n _ctx.log(`[OpenCorporates] Error: ${msg}`);\n _ctx.showNotification(`OpenCorporates error: ${msg}`, \"error\");\n } finally {\n _running = false;\n }\n}\n\n// βββ Exported plugin object (WorldWideView plugin contract) ββββββββββββββββββ\n\nexport default {\n id: \"wwv-plugin-opencorporates\",\n\n async initialize(context: PluginContext, config: PluginConfig) {\n _ctx = context;\n _cfg = config;\n\n _ctx.log(\"[OpenCorporates] Plugin initialized.\");\n\n // React to config changes (user types new search query / API key)\n _ctx.onConfigChange((newCfg: PluginConfig) => {\n _cfg = newCfg;\n // Debounce: clear old timer, rescan after 1.5s\n if (_pollTimer) clearInterval(_pollTimer);\n setTimeout(() => runScan(), 1500);\n });\n\n // Initial scan\n await runScan();\n\n // Refresh every 10 minutes (company data doesn't change fast)\n _pollTimer = setInterval(() => runScan(), 10 * 60 * 1000);\n },\n\n destroy() {\n if (_pollTimer) clearInterval(_pollTimer);\n _ctx?.log(\"[OpenCorporates] Plugin destroyed.\");\n }\n};\n"],"names":["geocodeCache","geocodeAddress","address","q","data","result","OC_BASE","searchCompanies","query","apiKey","jurisdiction","perPage","params","url","res","json","_a","statusColor","status","s","companyToEntity","raw","c","addrParts","_b","_c","addressStr","coords","jitter","_d","o","_ctx","_cfg","_pollTimer","_running","runScan","companies","entities","i","entity","r","err","msg","index","context","config","newCfg"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wwv-plugin-opencorporates",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "WorldWideView plugin β OpenCorporates business intelligence layer. Plots companies on the globe with financial & ownership data.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.esm.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": ["dist"],
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "vite build",
|
|
11
|
+
"dev": "vite build --watch"
|
|
12
|
+
},
|
|
13
|
+
"worldwideview": {
|
|
14
|
+
"id": "wwv-plugin-opencorporates",
|
|
15
|
+
"name": "OpenCorporates Intelligence",
|
|
16
|
+
"description": "Search and visualize companies worldwide using the OpenCorporates API. Plots HQ locations on the globe with ownership, officers, filing history and financial flags.",
|
|
17
|
+
"version": "1.0.0",
|
|
18
|
+
"author": "malek",
|
|
19
|
+
"category": "FINANCIAL",
|
|
20
|
+
"tags": ["finance", "corporate", "osint", "business", "shell-companies"],
|
|
21
|
+
"icon": "π’",
|
|
22
|
+
"pluginType": "ActiveProxied",
|
|
23
|
+
"configSchema": {
|
|
24
|
+
"apiKey": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"label": "OpenCorporates API Key",
|
|
27
|
+
"description": "Get a free key at opencorporates.com/api_accounts/new",
|
|
28
|
+
"required": true,
|
|
29
|
+
"secret": true
|
|
30
|
+
},
|
|
31
|
+
"searchQuery": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"label": "Company Search Query",
|
|
34
|
+
"description": "Company name to search and plot",
|
|
35
|
+
"required": false,
|
|
36
|
+
"default": ""
|
|
37
|
+
},
|
|
38
|
+
"jurisdiction": {
|
|
39
|
+
"type": "string",
|
|
40
|
+
"label": "Jurisdiction Filter",
|
|
41
|
+
"description": "e.g. us_de, gb, eg β leave blank for global",
|
|
42
|
+
"required": false,
|
|
43
|
+
"default": ""
|
|
44
|
+
},
|
|
45
|
+
"maxResults": {
|
|
46
|
+
"type": "number",
|
|
47
|
+
"label": "Max Results",
|
|
48
|
+
"description": "Max companies to plot (1-100)",
|
|
49
|
+
"required": false,
|
|
50
|
+
"default": 50
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"devDependencies": {
|
|
55
|
+
"vite": "^5.0.0",
|
|
56
|
+
"typescript": "^5.0.0"
|
|
57
|
+
}
|
|
58
|
+
}
|