hunter-mate 0.1.3 → 0.1.4
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/LICENSE +21 -0
- package/dist/assets/extension/background/service-worker.js +113 -24
- package/dist/assets/extension/content/index.js +239 -134
- package/dist/assets/extension/manifest.json +2 -4
- package/dist/assets/extension/sidepanel/index.js +76 -2
- package/dist/assets/server/app.module.js +4 -2
- package/dist/assets/server/app.module.js.map +1 -1
- package/dist/assets/server/build-info.json +1 -1
- package/dist/assets/server/db/sqlite.module.js +4 -0
- package/dist/assets/server/db/sqlite.module.js.map +1 -1
- package/dist/assets/server/devops/devops-sink-init.d.ts +14 -1
- package/dist/assets/server/devops/devops-sink-init.js +8 -3
- package/dist/assets/server/devops/devops-sink-init.js.map +1 -1
- package/dist/assets/server/doctor/doctor.controller.d.ts +13 -0
- package/dist/assets/server/doctor/doctor.controller.js +62 -0
- package/dist/assets/server/doctor/doctor.controller.js.map +1 -0
- package/dist/assets/server/doctor/doctor.module.d.ts +2 -0
- package/dist/assets/server/doctor/doctor.module.js +27 -0
- package/dist/assets/server/doctor/doctor.module.js.map +1 -0
- package/dist/assets/server/doctor/doctor.service.d.ts +15 -0
- package/dist/assets/server/doctor/doctor.service.js +209 -0
- package/dist/assets/server/doctor/doctor.service.js.map +1 -0
- package/dist/assets/server/doctor/doctor.types.d.ts +46 -0
- package/dist/assets/server/doctor/doctor.types.js +3 -0
- package/dist/assets/server/doctor/doctor.types.js.map +1 -0
- package/dist/assets/server/extraction/adapter.service.d.ts +18 -4
- package/dist/assets/server/extraction/adapter.service.js +129 -15
- package/dist/assets/server/extraction/adapter.service.js.map +1 -1
- package/dist/assets/server/extraction/anomaly-report.service.d.ts +12 -0
- package/dist/assets/server/extraction/anomaly-report.service.js +81 -0
- package/dist/assets/server/extraction/anomaly-report.service.js.map +1 -0
- package/dist/assets/server/extraction/entities/adapter-rule.entity.d.ts +13 -0
- package/dist/assets/server/extraction/entities/adapter-rule.entity.js +71 -0
- package/dist/assets/server/extraction/entities/adapter-rule.entity.js.map +1 -0
- package/dist/assets/server/extraction/entities/parse-log.entity.d.ts +4 -1
- package/dist/assets/server/extraction/entities/parse-log.entity.js +15 -0
- package/dist/assets/server/extraction/entities/parse-log.entity.js.map +1 -1
- package/dist/assets/server/extraction/extraction-entity.controller.d.ts +40 -2
- package/dist/assets/server/extraction/extraction-entity.controller.js +196 -13
- package/dist/assets/server/extraction/extraction-entity.controller.js.map +1 -1
- package/dist/assets/server/extraction/extraction-rule.service.js +16 -8
- package/dist/assets/server/extraction/extraction-rule.service.js.map +1 -1
- package/dist/assets/server/extraction/extraction.module.js +12 -2
- package/dist/assets/server/extraction/extraction.module.js.map +1 -1
- package/dist/assets/server/extraction/extraction.service.d.ts +17 -1
- package/dist/assets/server/extraction/extraction.service.js +125 -42
- package/dist/assets/server/extraction/extraction.service.js.map +1 -1
- package/dist/assets/server/extraction/linkedin-extractor.d.ts +1 -0
- package/dist/assets/server/extraction/linkedin-extractor.js +244 -0
- package/dist/assets/server/extraction/linkedin-extractor.js.map +1 -0
- package/dist/assets/server/extraction/rrweb-snapshot.utils.d.ts +15 -0
- package/dist/assets/server/extraction/rrweb-snapshot.utils.js +48 -0
- package/dist/assets/server/extraction/rrweb-snapshot.utils.js.map +1 -0
- package/dist/assets/server/extraction/rrweb-snapshot.utils.spec.d.ts +1 -0
- package/dist/assets/server/extraction/rrweb-snapshot.utils.spec.js +60 -0
- package/dist/assets/server/extraction/rrweb-snapshot.utils.spec.js.map +1 -0
- package/dist/assets/server/extraction/script-rule.d.ts +1 -0
- package/dist/assets/server/extraction/script-rule.js +4 -0
- package/dist/assets/server/extraction/script-rule.js.map +1 -1
- package/dist/assets/server/extraction/snapshot-analysis.service.d.ts +23 -0
- package/dist/assets/server/extraction/snapshot-analysis.service.js +147 -0
- package/dist/assets/server/extraction/snapshot-analysis.service.js.map +1 -0
- package/dist/assets/server/recording/entities/recording-snapshot.entity.d.ts +16 -0
- package/dist/assets/server/recording/entities/recording-snapshot.entity.js +91 -0
- package/dist/assets/server/recording/entities/recording-snapshot.entity.js.map +1 -0
- package/dist/assets/server/recording/recording-event-bus.service.d.ts +4 -0
- package/dist/assets/server/recording/recording-event-bus.service.js +25 -0
- package/dist/assets/server/recording/recording-event-bus.service.js.map +1 -0
- package/dist/assets/server/recording/recording-snapshot.service.d.ts +13 -0
- package/dist/assets/server/recording/recording-snapshot.service.js +81 -0
- package/dist/assets/server/recording/recording-snapshot.service.js.map +1 -0
- package/dist/assets/server/recording/recording-snapshot.service.spec.d.ts +1 -0
- package/dist/assets/server/recording/recording-snapshot.service.spec.js +65 -0
- package/dist/assets/server/recording/recording-snapshot.service.spec.js.map +1 -0
- package/dist/assets/server/recording/recording.controller.d.ts +3 -1
- package/dist/assets/server/recording/recording.controller.js +7 -3
- package/dist/assets/server/recording/recording.controller.js.map +1 -1
- package/dist/assets/server/recording/recording.module.js +11 -4
- package/dist/assets/server/recording/recording.module.js.map +1 -1
- package/dist/assets/server/recording/recording.service.d.ts +5 -21
- package/dist/assets/server/recording/recording.service.js +22 -9
- package/dist/assets/server/recording/recording.service.js.map +1 -1
- package/dist/assets/server/site/entities/site-registry.entity.d.ts +2 -0
- package/dist/assets/server/site/entities/site-registry.entity.js +10 -0
- package/dist/assets/server/site/entities/site-registry.entity.js.map +1 -1
- package/dist/assets/server/site/site.controller.d.ts +2 -0
- package/dist/assets/server/site/site.controller.js +1 -1
- package/dist/assets/server/site/site.controller.js.map +1 -1
- package/dist/assets/server/site/site.service.d.ts +2 -1
- package/dist/assets/server/site/site.service.js +10 -3
- package/dist/assets/server/site/site.service.js.map +1 -1
- package/dist/auto-doctor.d.ts +8 -0
- package/dist/auto-doctor.js +34 -0
- package/dist/commands/doctor.d.ts +38 -0
- package/dist/commands/doctor.js +162 -7
- package/dist/commands/extension.js +2 -2
- package/dist/commands/extras.d.ts +1 -1
- package/dist/commands/extras.js +4 -3
- package/dist/commands/install.js +11 -8
- package/dist/index.js +7 -0
- package/package.json +3 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 HiredChina
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -2546,7 +2546,10 @@ var PATH_CLASS_HINTS = [
|
|
|
2546
2546
|
{ re: /\/(company|companies|employer)\b/i, cls: "company" },
|
|
2547
2547
|
{ re: /\/(search|talent|people|directory)\b/i, cls: "list" }
|
|
2548
2548
|
];
|
|
2549
|
-
var
|
|
2549
|
+
var sitePolicyMap = /* @__PURE__ */ new Map();
|
|
2550
|
+
function getSitePolicy(hostname) {
|
|
2551
|
+
return sitePolicyMap.get(etldPlusOne(hostname)) ?? { record: false, parse: false };
|
|
2552
|
+
}
|
|
2550
2553
|
async function syncSites() {
|
|
2551
2554
|
let entries = [];
|
|
2552
2555
|
try {
|
|
@@ -2558,10 +2561,19 @@ async function syncSites() {
|
|
|
2558
2561
|
} catch {
|
|
2559
2562
|
return [];
|
|
2560
2563
|
}
|
|
2561
|
-
const next =
|
|
2562
|
-
const
|
|
2563
|
-
|
|
2564
|
-
|
|
2564
|
+
const next = /* @__PURE__ */ new Map();
|
|
2565
|
+
for (const e of entries) {
|
|
2566
|
+
if (!e.enabled) continue;
|
|
2567
|
+
next.set(e.domain, {
|
|
2568
|
+
record: true,
|
|
2569
|
+
parse: true,
|
|
2570
|
+
adapterPlatform: e.adapterPlatform || e.platform
|
|
2571
|
+
});
|
|
2572
|
+
}
|
|
2573
|
+
sitePolicyMap.clear();
|
|
2574
|
+
for (const [k, v] of next) sitePolicyMap.set(k, v);
|
|
2575
|
+
const domains = [...sitePolicyMap.keys()];
|
|
2576
|
+
await registerDynamicScripts(domains);
|
|
2565
2577
|
return entries;
|
|
2566
2578
|
}
|
|
2567
2579
|
async function registerDynamicScripts(domains) {
|
|
@@ -2582,11 +2594,6 @@ async function registerDynamicScripts(domains) {
|
|
|
2582
2594
|
]);
|
|
2583
2595
|
console.log(`[HunterMate] dynamic content scripts registered for ${domains.length} domains`);
|
|
2584
2596
|
}
|
|
2585
|
-
function symmetricDiffers(a, b) {
|
|
2586
|
-
if (a.size !== b.size) return true;
|
|
2587
|
-
for (const v of a) if (!b.has(v)) return true;
|
|
2588
|
-
return false;
|
|
2589
|
-
}
|
|
2590
2597
|
function isProductionDomain(hostname) {
|
|
2591
2598
|
const h = hostname.toLowerCase().trim();
|
|
2592
2599
|
if (!h) return false;
|
|
@@ -2621,7 +2628,7 @@ function maybeDiscover(url, title) {
|
|
|
2621
2628
|
}
|
|
2622
2629
|
if (!isProductionDomain(hostname)) return;
|
|
2623
2630
|
const domain = etldPlusOne(hostname);
|
|
2624
|
-
if (discovered.has(domain) ||
|
|
2631
|
+
if (discovered.has(domain) || sitePolicyMap.has(domain)) return;
|
|
2625
2632
|
const haystack = `${title} ${url}`.toLowerCase();
|
|
2626
2633
|
const hit = RECRUITING_HINTS.find((k) => haystack.includes(k));
|
|
2627
2634
|
if (!hit) return;
|
|
@@ -2965,14 +2972,12 @@ async function createBackgroundLogForwarder(options) {
|
|
|
2965
2972
|
var state = {
|
|
2966
2973
|
serverConnected: false,
|
|
2967
2974
|
wsConnected: false,
|
|
2968
|
-
recordingSessionId: null,
|
|
2969
|
-
eventCount: 0,
|
|
2970
2975
|
ruleVersion: null,
|
|
2971
|
-
classification: null,
|
|
2972
2976
|
sidePanel: "pending",
|
|
2973
2977
|
serverVersion: null,
|
|
2974
2978
|
serverBuildTime: null
|
|
2975
2979
|
};
|
|
2980
|
+
var tabStates = /* @__PURE__ */ new Map();
|
|
2976
2981
|
var backgroundLogger = createExtensionLogger({ context: "background", sessionId: () => `bg-${Date.now()}` });
|
|
2977
2982
|
backgroundLogger.patchConsole();
|
|
2978
2983
|
var logForwarder = null;
|
|
@@ -3073,8 +3078,32 @@ async function checkRuleVersion() {
|
|
|
3073
3078
|
} catch {
|
|
3074
3079
|
}
|
|
3075
3080
|
}
|
|
3081
|
+
async function buildStatusForActiveTab() {
|
|
3082
|
+
try {
|
|
3083
|
+
const tabs = await chrome.tabs.query({ active: true, currentWindow: true });
|
|
3084
|
+
const tab = tabs[0];
|
|
3085
|
+
const tabId = tab?.id;
|
|
3086
|
+
if (tabId == null) {
|
|
3087
|
+
return { ...state, tabId: -1, url: "", recordingSessionId: null, eventCount: 0, classification: null };
|
|
3088
|
+
}
|
|
3089
|
+
const ts = tabStates.get(tabId);
|
|
3090
|
+
if (ts) return { ...state, ...ts };
|
|
3091
|
+
return {
|
|
3092
|
+
...state,
|
|
3093
|
+
tabId,
|
|
3094
|
+
url: tab.url || "",
|
|
3095
|
+
recordingSessionId: null,
|
|
3096
|
+
eventCount: 0,
|
|
3097
|
+
classification: null
|
|
3098
|
+
};
|
|
3099
|
+
} catch {
|
|
3100
|
+
return { ...state, tabId: -1, url: "", recordingSessionId: null, eventCount: 0, classification: null };
|
|
3101
|
+
}
|
|
3102
|
+
}
|
|
3076
3103
|
function broadcastState() {
|
|
3077
|
-
|
|
3104
|
+
buildStatusForActiveTab().then((payload) => {
|
|
3105
|
+
chrome.runtime.sendMessage({ type: "status", payload }).catch(() => {
|
|
3106
|
+
});
|
|
3078
3107
|
});
|
|
3079
3108
|
}
|
|
3080
3109
|
function connect() {
|
|
@@ -3128,6 +3157,7 @@ function connect() {
|
|
|
3128
3157
|
status: "ok",
|
|
3129
3158
|
result: {
|
|
3130
3159
|
...state,
|
|
3160
|
+
tabStatesCount: tabStates.size,
|
|
3131
3161
|
extBasePath: chrome.runtime.getURL(""),
|
|
3132
3162
|
manifestPermissions: manifest.permissions,
|
|
3133
3163
|
hasSidePanelInManifest: manifest.permissions?.includes("sidePanel"),
|
|
@@ -3215,35 +3245,74 @@ if (typeof chrome !== "undefined" && chrome.sidePanel?.setPanelBehavior) {
|
|
|
3215
3245
|
} else {
|
|
3216
3246
|
state.sidePanel = "error: chrome.sidePanel API not available";
|
|
3217
3247
|
}
|
|
3248
|
+
chrome.tabs.onActivated.addListener(() => {
|
|
3249
|
+
broadcastState();
|
|
3250
|
+
});
|
|
3251
|
+
chrome.tabs.onUpdated.addListener((_tabId, changeInfo, tab) => {
|
|
3252
|
+
if (!tab.url) return;
|
|
3253
|
+
const ts = tabStates.get(_tabId);
|
|
3254
|
+
if (ts) {
|
|
3255
|
+
ts.url = tab.url;
|
|
3256
|
+
}
|
|
3257
|
+
if (changeInfo.url) {
|
|
3258
|
+
broadcastState();
|
|
3259
|
+
}
|
|
3260
|
+
});
|
|
3218
3261
|
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
3219
3262
|
if (message.type === "get-status") {
|
|
3220
|
-
|
|
3263
|
+
buildStatusForActiveTab().then((payload) => {
|
|
3264
|
+
sendResponse(payload);
|
|
3265
|
+
});
|
|
3266
|
+
return true;
|
|
3267
|
+
}
|
|
3268
|
+
if (message.type === "query-site-policy") {
|
|
3269
|
+
const url = message.payload?.url;
|
|
3270
|
+
let policy = { record: false, parse: false };
|
|
3271
|
+
try {
|
|
3272
|
+
if (url) {
|
|
3273
|
+
const hostname = new URL(url).hostname;
|
|
3274
|
+
policy = getSitePolicy(hostname);
|
|
3275
|
+
}
|
|
3276
|
+
} catch {
|
|
3277
|
+
}
|
|
3278
|
+
sendResponse(policy);
|
|
3221
3279
|
return true;
|
|
3222
3280
|
}
|
|
3223
3281
|
if (message.type === "recording-started" && message.payload?.sessionId) {
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3282
|
+
const tabId = sender.tab?.id ?? -1;
|
|
3283
|
+
const classification = message.payload.classification ?? null;
|
|
3284
|
+
tabStates.set(tabId, {
|
|
3285
|
+
tabId,
|
|
3286
|
+
url: sender.tab?.url || "",
|
|
3287
|
+
recordingSessionId: message.payload.sessionId,
|
|
3288
|
+
eventCount: 0,
|
|
3289
|
+
classification
|
|
3290
|
+
});
|
|
3227
3291
|
broadcastState();
|
|
3228
3292
|
sendResponse({ ok: true });
|
|
3229
3293
|
return true;
|
|
3230
3294
|
}
|
|
3231
3295
|
if (message.type === "recording-stopped") {
|
|
3232
|
-
|
|
3233
|
-
|
|
3296
|
+
const tabId = sender.tab?.id ?? -1;
|
|
3297
|
+
const existing = tabStates.get(tabId);
|
|
3298
|
+
if (existing) {
|
|
3299
|
+
tabStates.set(tabId, { ...existing, recordingSessionId: null, eventCount: 0 });
|
|
3300
|
+
}
|
|
3234
3301
|
broadcastState();
|
|
3235
3302
|
sendResponse({ ok: true });
|
|
3236
3303
|
return true;
|
|
3237
3304
|
}
|
|
3238
3305
|
if (message.type === "recording-event") {
|
|
3239
|
-
const
|
|
3306
|
+
const tabId = sender.tab?.id ?? -1;
|
|
3307
|
+
const payload = { ...message.payload, tabId };
|
|
3240
3308
|
if (socket?.readyState === WebSocket.OPEN) {
|
|
3241
3309
|
socket.send(JSON.stringify(payload));
|
|
3242
3310
|
} else {
|
|
3243
3311
|
enqueueRecordingEvent(payload);
|
|
3244
3312
|
}
|
|
3245
|
-
|
|
3246
|
-
|
|
3313
|
+
const ts = tabStates.get(tabId);
|
|
3314
|
+
if (ts && message.payload?.sessionId === ts.recordingSessionId) {
|
|
3315
|
+
ts.eventCount++;
|
|
3247
3316
|
}
|
|
3248
3317
|
} else if (message.type === "hm:logs" && Array.isArray(message.logs)) {
|
|
3249
3318
|
logForwarder?.onLogsMessage(message.logs);
|
|
@@ -3251,3 +3320,23 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
3251
3320
|
sendResponse({ ok: true });
|
|
3252
3321
|
return true;
|
|
3253
3322
|
});
|
|
3323
|
+
chrome.tabs.query({}, (tabs) => {
|
|
3324
|
+
for (const tab of tabs) {
|
|
3325
|
+
const tabId = tab.id;
|
|
3326
|
+
if (tabId == null || !tab.url) continue;
|
|
3327
|
+
const policy = getSitePolicy(new URL(tab.url).hostname);
|
|
3328
|
+
if (policy.record) {
|
|
3329
|
+
tabStates.set(tabId, {
|
|
3330
|
+
tabId,
|
|
3331
|
+
url: tab.url,
|
|
3332
|
+
recordingSessionId: null,
|
|
3333
|
+
eventCount: 0,
|
|
3334
|
+
classification: null
|
|
3335
|
+
});
|
|
3336
|
+
}
|
|
3337
|
+
}
|
|
3338
|
+
broadcastState();
|
|
3339
|
+
});
|
|
3340
|
+
chrome.tabs.onRemoved.addListener((tabId) => {
|
|
3341
|
+
tabStates.delete(tabId);
|
|
3342
|
+
});
|