hunter-mate 0.1.24 → 0.1.25
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/assets/extension/build-info.json +1 -1
- package/dist/assets/extension/manifest.json +3 -3
- package/dist/assets/server/chunks/{chunk-SAJB6JRK.mjs → chunk-VL7WHUEV.mjs} +556 -8
- package/dist/assets/server/chunks/{script-rule-ZJN6CEYX.mjs → script-rule-4RZQ2PQE.mjs} +1 -2
- package/dist/assets/server/main.mjs +153 -88
- package/dist/index.js +159 -20
- package/dist/web/dist/404.html +1 -1
- package/dist/web/dist/admin/data.html +1 -1
- package/dist/web/dist/admin/data.txt +1 -1
- package/dist/web/dist/auth/verify.html +1 -1
- package/dist/web/dist/auth/verify.txt +1 -1
- package/dist/web/dist/companies.html +1 -1
- package/dist/web/dist/companies.txt +1 -1
- package/dist/web/dist/company/admin.html +1 -1
- package/dist/web/dist/company/admin.txt +1 -1
- package/dist/web/dist/entity.html +1 -1
- package/dist/web/dist/entity.txt +1 -1
- package/dist/web/dist/index.html +1 -1
- package/dist/web/dist/index.txt +1 -1
- package/dist/web/dist/jobs.html +1 -1
- package/dist/web/dist/jobs.txt +1 -1
- package/dist/web/dist/logs.html +1 -1
- package/dist/web/dist/logs.txt +1 -1
- package/dist/web/dist/matching/jobs/placeholder/talents.html +1 -1
- package/dist/web/dist/matching/jobs/placeholder/talents.txt +1 -1
- package/dist/web/dist/matching/portraits/placeholder/jobs.html +1 -1
- package/dist/web/dist/matching/portraits/placeholder/jobs.txt +1 -1
- package/dist/web/dist/parselog.html +1 -1
- package/dist/web/dist/parselog.txt +1 -1
- package/dist/web/dist/recordings.html +1 -1
- package/dist/web/dist/recordings.txt +1 -1
- package/dist/web/dist/resource-usage.html +1 -1
- package/dist/web/dist/resource-usage.txt +1 -1
- package/dist/web/dist/shared/placeholder.html +1 -1
- package/dist/web/dist/shared/placeholder.txt +1 -1
- package/dist/web/dist/snapshots/placeholder/agent-prompt.html +1 -1
- package/dist/web/dist/snapshots/placeholder/agent-prompt.txt +1 -1
- package/dist/web/dist/talents.html +1 -1
- package/dist/web/dist/talents.txt +1 -1
- package/dist/web/dist/team/insights.html +1 -1
- package/dist/web/dist/team/insights.txt +1 -1
- package/package.json +1 -1
- package/dist/assets/server/chunks/chunk-BLXHCSZD.mjs +0 -565
- package/dist/assets/server/chunks/esm-4U746B76.mjs +0 -29
- /package/dist/assets/extension/background/{service-worker.20261017012007.js → service-worker.20261017183328.js} +0 -0
- /package/dist/web/dist/_next/static/{hBLezfvVOMiGqm4V9F15i → 5MA8faUttk6FzlxGWnOlM}/_buildManifest.js +0 -0
- /package/dist/web/dist/_next/static/{hBLezfvVOMiGqm4V9F15i → 5MA8faUttk6FzlxGWnOlM}/_ssgManifest.js +0 -0
|
@@ -21,11 +21,9 @@ import {
|
|
|
21
21
|
trace
|
|
22
22
|
} from "./chunks/chunk-U7FVFSKP.mjs";
|
|
23
23
|
import {
|
|
24
|
-
applyScriptRule
|
|
25
|
-
} from "./chunks/chunk-BLXHCSZD.mjs";
|
|
26
|
-
import {
|
|
24
|
+
applyScriptRule,
|
|
27
25
|
load
|
|
28
|
-
} from "./chunks/chunk-
|
|
26
|
+
} from "./chunks/chunk-VL7WHUEV.mjs";
|
|
29
27
|
import {
|
|
30
28
|
__commonJS,
|
|
31
29
|
__esm,
|
|
@@ -179242,7 +179240,7 @@ var require_src4 = __commonJS({
|
|
|
179242
179240
|
return new createAgent.Agent(callback, opts);
|
|
179243
179241
|
}
|
|
179244
179242
|
(function(createAgent2) {
|
|
179245
|
-
class
|
|
179243
|
+
class Agent4 extends events_1.EventEmitter {
|
|
179246
179244
|
constructor(callback, _opts) {
|
|
179247
179245
|
super();
|
|
179248
179246
|
let opts = _opts;
|
|
@@ -179394,7 +179392,7 @@ var require_src4 = __commonJS({
|
|
|
179394
179392
|
debug3("Destroying agent %o", this.constructor.name);
|
|
179395
179393
|
}
|
|
179396
179394
|
}
|
|
179397
|
-
createAgent2.Agent =
|
|
179395
|
+
createAgent2.Agent = Agent4;
|
|
179398
179396
|
createAgent2.prototype = createAgent2.Agent.prototype;
|
|
179399
179397
|
})(createAgent || (createAgent = {}));
|
|
179400
179398
|
module2.exports = createAgent;
|
|
@@ -217671,7 +217669,6 @@ __decorate7([
|
|
|
217671
217669
|
__metadata6("design:type", Number)
|
|
217672
217670
|
], RecordingEvent.prototype, "id", void 0);
|
|
217673
217671
|
__decorate7([
|
|
217674
|
-
Index(),
|
|
217675
217672
|
Column({ type: "varchar", length: 64 }),
|
|
217676
217673
|
__metadata6("design:type", String)
|
|
217677
217674
|
], RecordingEvent.prototype, "sessionId", void 0);
|
|
@@ -217696,7 +217693,8 @@ __decorate7([
|
|
|
217696
217693
|
__metadata6("design:type", Date)
|
|
217697
217694
|
], RecordingEvent.prototype, "createdAt", void 0);
|
|
217698
217695
|
RecordingEvent = __decorate7([
|
|
217699
|
-
Entity("recording_events")
|
|
217696
|
+
Entity("recording_events"),
|
|
217697
|
+
Index("IDX_recording_events_session_lookup", ["sessionId", "createdAt", "sourceUrl", "tabId"])
|
|
217700
217698
|
], RecordingEvent);
|
|
217701
217699
|
|
|
217702
217700
|
// dist/.server-tsc/jobcase/jobcase.entity.js
|
|
@@ -222321,7 +222319,7 @@ var AuthService = AuthService_1 = class AuthService2 {
|
|
|
222321
222319
|
const decodedEmail = decoded?.data?.email ?? email ?? "";
|
|
222322
222320
|
const existing = await this.saasTokenRepo.findOne({ where: { hmUserId } });
|
|
222323
222321
|
if (existing) {
|
|
222324
|
-
await this.saasTokenRepo.update({ id: existing.id }, { token, email: decodedEmail });
|
|
222322
|
+
await this.saasTokenRepo.update({ id: existing.id }, { token, email: decodedEmail, savedAt: /* @__PURE__ */ new Date() });
|
|
222325
222323
|
} else {
|
|
222326
222324
|
await this.saasTokenRepo.save({ hmUserId, email: decodedEmail, token });
|
|
222327
222325
|
}
|
|
@@ -222815,11 +222813,13 @@ var DatasyncService = class DatasyncService2 {
|
|
|
222815
222813
|
changeLog;
|
|
222816
222814
|
tenant;
|
|
222817
222815
|
logger = new import_common18.Logger(DatasyncService_1.name);
|
|
222818
|
-
static SYNC_VIEW_TTL_MS =
|
|
222816
|
+
static SYNC_VIEW_TTL_MS = 6e4;
|
|
222819
222817
|
static SYNC_VIEW_STALE_GRACE_MS = 6e5;
|
|
222818
|
+
static SYNC_VIEW_ERROR_CACHE_MS = 6e4;
|
|
222820
222819
|
timer;
|
|
222821
222820
|
syncViewCache = null;
|
|
222822
222821
|
syncViewRefresh = null;
|
|
222822
|
+
syncViewError = null;
|
|
222823
222823
|
pushing = false;
|
|
222824
222824
|
pulling = false;
|
|
222825
222825
|
authFailed = false;
|
|
@@ -223016,9 +223016,22 @@ var DatasyncService = class DatasyncService2 {
|
|
|
223016
223016
|
return { ...base, loggedIn: true, ...cached2.view, activeTenantId: await this.getActiveTenantId() };
|
|
223017
223017
|
}
|
|
223018
223018
|
}
|
|
223019
|
+
const lastErr = this.syncViewError;
|
|
223020
|
+
if (lastErr && lastErr.uid === uid && Date.now() - lastErr.at < DatasyncService_1.SYNC_VIEW_ERROR_CACHE_MS) {
|
|
223021
|
+
return { ...base, loggedIn: true, remoteError: lastErr.message };
|
|
223022
|
+
}
|
|
223019
223023
|
try {
|
|
223024
|
+
if (this.syncViewRefresh) {
|
|
223025
|
+
await this.syncViewRefresh;
|
|
223026
|
+
const refreshed = this.syncViewCache;
|
|
223027
|
+
if (refreshed && refreshed.uid === uid) {
|
|
223028
|
+
return { ...base, loggedIn: true, ...refreshed.view, activeTenantId: await this.getActiveTenantId() };
|
|
223029
|
+
}
|
|
223030
|
+
throw new Error("sync view refresh failed");
|
|
223031
|
+
}
|
|
223020
223032
|
const view = await this.fetchSyncView(uid, token.token);
|
|
223021
223033
|
this.syncViewCache = { uid, at: Date.now(), view };
|
|
223034
|
+
this.syncViewError = null;
|
|
223022
223035
|
return {
|
|
223023
223036
|
...base,
|
|
223024
223037
|
loggedIn: true,
|
|
@@ -223026,12 +223039,14 @@ var DatasyncService = class DatasyncService2 {
|
|
|
223026
223039
|
activeTenantId: await this.getActiveTenantId()
|
|
223027
223040
|
};
|
|
223028
223041
|
} catch (err) {
|
|
223042
|
+
this.syncViewError = { uid, message: err.message ?? String(err), at: Date.now() };
|
|
223029
223043
|
return { ...base, loggedIn: true, remoteError: err.message ?? String(err) };
|
|
223030
223044
|
}
|
|
223031
223045
|
}
|
|
223032
223046
|
async fetchSyncView(uid, jwt5) {
|
|
223033
223047
|
const res = await fetch(`${this.saasBaseUrl}/hunter-mate/sync/state?heads=0`, {
|
|
223034
|
-
headers: { Authorization: `HMJWT ${jwt5}` }
|
|
223048
|
+
headers: { Authorization: `HMJWT ${jwt5}` },
|
|
223049
|
+
signal: AbortSignal.timeout(1e4)
|
|
223035
223050
|
});
|
|
223036
223051
|
if (!res.ok)
|
|
223037
223052
|
throw new Error(`HTTP ${res.status}`);
|
|
@@ -223077,6 +223092,7 @@ var DatasyncService = class DatasyncService2 {
|
|
|
223077
223092
|
"Content-Type": "application/json",
|
|
223078
223093
|
Authorization: `HMJWT ${token.token}`
|
|
223079
223094
|
},
|
|
223095
|
+
signal: AbortSignal.timeout(3e4),
|
|
223080
223096
|
...body !== void 0 ? { body: JSON.stringify(body) } : {}
|
|
223081
223097
|
});
|
|
223082
223098
|
const text = await res.text();
|
|
@@ -223343,19 +223359,23 @@ var DatasyncService = class DatasyncService2 {
|
|
|
223343
223359
|
await this.reconcileMembership(token.token);
|
|
223344
223360
|
await this.syncTenantMembers(token.token);
|
|
223345
223361
|
const myId = this.hmUserIdOf(token.token);
|
|
223346
|
-
|
|
223347
|
-
|
|
223348
|
-
|
|
223349
|
-
|
|
223350
|
-
|
|
223351
|
-
const
|
|
223352
|
-
|
|
223353
|
-
|
|
223354
|
-
|
|
223355
|
-
|
|
223356
|
-
|
|
223362
|
+
const targets = SYNC_REGISTRY.filter((c) => c.direction === "both");
|
|
223363
|
+
const CONCURRENCY = 4;
|
|
223364
|
+
let next = 0;
|
|
223365
|
+
await Promise.all(Array.from({ length: Math.min(CONCURRENCY, targets.length) }, async () => {
|
|
223366
|
+
while (next < targets.length) {
|
|
223367
|
+
const cfg = targets[next++];
|
|
223368
|
+
const table = this.tableOf(cfg);
|
|
223369
|
+
try {
|
|
223370
|
+
const r = await this.pullEntity(cfg, token.token, myId);
|
|
223371
|
+
result[table] = `${r.applied}u/${r.conflicts}c/${r.deleted}d/${r.pooled}p`;
|
|
223372
|
+
} catch (err) {
|
|
223373
|
+
const msg = err.message ?? String(err);
|
|
223374
|
+
this.logger.warn(`pull entity ${table} failed: ${msg}`);
|
|
223375
|
+
result[table] = `ERR: ${msg}`;
|
|
223376
|
+
}
|
|
223357
223377
|
}
|
|
223358
|
-
}
|
|
223378
|
+
}));
|
|
223359
223379
|
return result;
|
|
223360
223380
|
} finally {
|
|
223361
223381
|
this.pulling = false;
|
|
@@ -223363,8 +223383,9 @@ var DatasyncService = class DatasyncService2 {
|
|
|
223363
223383
|
}
|
|
223364
223384
|
async reconcileMembership(jwt5) {
|
|
223365
223385
|
try {
|
|
223366
|
-
const res = await fetch(`${this.saasBaseUrl}/hunter-mate/sync/state`, {
|
|
223367
|
-
headers: { Authorization: `HMJWT ${jwt5}` }
|
|
223386
|
+
const res = await fetch(`${this.saasBaseUrl}/hunter-mate/sync/state?heads=0`, {
|
|
223387
|
+
headers: { Authorization: `HMJWT ${jwt5}` },
|
|
223388
|
+
signal: AbortSignal.timeout(3e4)
|
|
223368
223389
|
});
|
|
223369
223390
|
if (res.status === 401) {
|
|
223370
223391
|
this.authFailed = true;
|
|
@@ -224528,6 +224549,7 @@ SearchlogController = __decorate73([
|
|
|
224528
224549
|
var import_common31 = __toESM(require_common(), 1);
|
|
224529
224550
|
var import_axios4 = __toESM(require_axios2(), 1);
|
|
224530
224551
|
var import_typeorm69 = __toESM(require_typeorm2(), 1);
|
|
224552
|
+
import { Agent } from "https";
|
|
224531
224553
|
|
|
224532
224554
|
// dist/.server-tsc/auth/auth.controller.js
|
|
224533
224555
|
var import_common26 = __toESM(require_common(), 1);
|
|
@@ -224881,7 +224903,15 @@ var AuthModule = class AuthModule2 {
|
|
|
224881
224903
|
};
|
|
224882
224904
|
AuthModule = __decorate79([
|
|
224883
224905
|
(0, import_common31.Module)({
|
|
224884
|
-
imports: [
|
|
224906
|
+
imports: [
|
|
224907
|
+
import_axios4.HttpModule.register({
|
|
224908
|
+
proxy: false,
|
|
224909
|
+
timeout: 15e3,
|
|
224910
|
+
httpsAgent: new Agent({ keepAlive: true, maxSockets: 8 })
|
|
224911
|
+
}),
|
|
224912
|
+
import_typeorm69.TypeOrmModule.forFeature([SaasToken]),
|
|
224913
|
+
OpLogModule
|
|
224914
|
+
],
|
|
224885
224915
|
providers: [AuthService, OptionalAuthMiddleware],
|
|
224886
224916
|
controllers: [AuthController],
|
|
224887
224917
|
exports: [AuthService]
|
|
@@ -245985,7 +246015,7 @@ import * as tls from "node:tls";
|
|
|
245985
246015
|
import * as http3 from "node:http";
|
|
245986
246016
|
var _a;
|
|
245987
246017
|
var INTERNAL = /* @__PURE__ */ Symbol("AgentBaseInternalState");
|
|
245988
|
-
var
|
|
246018
|
+
var Agent3 = class extends (_a = http3.Agent, _a) {
|
|
245989
246019
|
constructor(opts) {
|
|
245990
246020
|
super(opts);
|
|
245991
246021
|
this[INTERNAL] = {};
|
|
@@ -246132,7 +246162,7 @@ function parseProxyResponse(socket) {
|
|
|
246132
246162
|
function debugLog2(...args) {
|
|
246133
246163
|
debug.log("[https-proxy-agent]", ...args);
|
|
246134
246164
|
}
|
|
246135
|
-
var HttpsProxyAgent = class extends
|
|
246165
|
+
var HttpsProxyAgent = class extends Agent3 {
|
|
246136
246166
|
constructor(proxy, opts) {
|
|
246137
246167
|
super(opts);
|
|
246138
246168
|
this.options = {};
|
|
@@ -265089,7 +265119,11 @@ var __param25 = function(paramIndex, decorator) {
|
|
|
265089
265119
|
decorator(target, key, paramIndex);
|
|
265090
265120
|
};
|
|
265091
265121
|
};
|
|
265122
|
+
var RecordingService_1;
|
|
265092
265123
|
var RecordingService = class RecordingService2 {
|
|
265124
|
+
static {
|
|
265125
|
+
RecordingService_1 = this;
|
|
265126
|
+
}
|
|
265093
265127
|
eventRepo;
|
|
265094
265128
|
snapshotService;
|
|
265095
265129
|
eventBus;
|
|
@@ -265171,8 +265205,10 @@ var RecordingService = class RecordingService2 {
|
|
|
265171
265205
|
}
|
|
265172
265206
|
return { sessionId, eventsDeleted, snapshotsDeleted };
|
|
265173
265207
|
}
|
|
265208
|
+
static DEFAULT_WINDOW_MS = 90 * 24 * 60 * 60 * 1e3;
|
|
265174
265209
|
async listRecordings(limit = 100, options = {}) {
|
|
265175
|
-
const { q,
|
|
265210
|
+
const { q, to } = options;
|
|
265211
|
+
const from = options.from ?? (!to ? new Date(Date.now() - RecordingService_1.DEFAULT_WINDOW_MS) : void 0);
|
|
265176
265212
|
const qb = this.eventRepo.createQueryBuilder("e").select("e.sessionId", "sessionId").addSelect("COUNT(*)", "eventCount").addSelect("MIN(e.createdAt)", "startedAt").addSelect("MAX(e.createdAt)", "lastEventAt").addSelect("MAX(e.sourceUrl)", "sourceUrl").addSelect("MAX(e.tabId)", "tabId").groupBy("e.sessionId");
|
|
265177
265213
|
if (from)
|
|
265178
265214
|
qb.andWhere("e.createdAt >= :from", { from });
|
|
@@ -265197,7 +265233,7 @@ var RecordingService = class RecordingService2 {
|
|
|
265197
265233
|
};
|
|
265198
265234
|
}
|
|
265199
265235
|
};
|
|
265200
|
-
RecordingService = __decorate94([
|
|
265236
|
+
RecordingService = RecordingService_1 = __decorate94([
|
|
265201
265237
|
(0, import_common51.Injectable)(),
|
|
265202
265238
|
__param25(0, (0, import_typeorm79.InjectRepository)(RecordingEvent)),
|
|
265203
265239
|
__metadata80("design:paramtypes", [
|
|
@@ -265855,7 +265891,7 @@ async function pool(items, limit, fn) {
|
|
|
265855
265891
|
});
|
|
265856
265892
|
await Promise.all(workers);
|
|
265857
265893
|
}
|
|
265858
|
-
async function
|
|
265894
|
+
async function sizeOfDir(dir) {
|
|
265859
265895
|
let total = 0;
|
|
265860
265896
|
let entries;
|
|
265861
265897
|
try {
|
|
@@ -265867,7 +265903,7 @@ async function folderSize(dir) {
|
|
|
265867
265903
|
const full = path6.join(dir, ent.name);
|
|
265868
265904
|
try {
|
|
265869
265905
|
if (ent.isDirectory()) {
|
|
265870
|
-
const sub = await
|
|
265906
|
+
const sub = await sizeOfDir(full);
|
|
265871
265907
|
total += sub;
|
|
265872
265908
|
} else if (ent.isFile()) {
|
|
265873
265909
|
const st = await fsp.stat(full);
|
|
@@ -265878,19 +265914,19 @@ async function folderSize(dir) {
|
|
|
265878
265914
|
});
|
|
265879
265915
|
return total;
|
|
265880
265916
|
}
|
|
265881
|
-
async function
|
|
265917
|
+
async function sizeWithBreakdown(dir, limit = TOP_ENTRIES_LIMIT) {
|
|
265882
265918
|
let entries;
|
|
265883
265919
|
try {
|
|
265884
265920
|
entries = await fsp.readdir(dir, { withFileTypes: true });
|
|
265885
265921
|
} catch {
|
|
265886
|
-
return [];
|
|
265922
|
+
return { totalBytes: 0, topEntries: [] };
|
|
265887
265923
|
}
|
|
265888
265924
|
const sized = [];
|
|
265889
265925
|
await pool(entries, WALK_CONCURRENCY, async (ent) => {
|
|
265890
265926
|
const full = path6.join(dir, ent.name);
|
|
265891
265927
|
try {
|
|
265892
265928
|
if (ent.isDirectory()) {
|
|
265893
|
-
const sub = await
|
|
265929
|
+
const sub = await sizeOfDir(full);
|
|
265894
265930
|
sized.push({ name: ent.name + "/", bytes: sub });
|
|
265895
265931
|
} else if (ent.isFile()) {
|
|
265896
265932
|
const st = await fsp.stat(full);
|
|
@@ -265899,13 +265935,14 @@ async function topLevelBreakdown(dir, limit = TOP_ENTRIES_LIMIT) {
|
|
|
265899
265935
|
} catch {
|
|
265900
265936
|
}
|
|
265901
265937
|
});
|
|
265938
|
+
const totalBytes = sized.reduce((acc, e) => acc + e.bytes, 0);
|
|
265902
265939
|
sized.sort((a, b2) => b2.bytes - a.bytes);
|
|
265903
265940
|
if (sized.length <= limit)
|
|
265904
|
-
return sized;
|
|
265941
|
+
return { totalBytes, topEntries: sized };
|
|
265905
265942
|
const head = sized.slice(0, limit);
|
|
265906
265943
|
const restBytes = sized.slice(limit).reduce((acc, e) => acc + e.bytes, 0);
|
|
265907
265944
|
head.push({ name: `others(${sized.length - limit})`, bytes: restBytes });
|
|
265908
|
-
return head;
|
|
265945
|
+
return { totalBytes, topEntries: head };
|
|
265909
265946
|
}
|
|
265910
265947
|
function findInstallRoot(startDir, maxUp = 6) {
|
|
265911
265948
|
let dir = startDir;
|
|
@@ -265972,27 +266009,26 @@ var ResourceCollector = ResourceCollector_1 = class ResourceCollector2 {
|
|
|
265972
266009
|
}
|
|
265973
266010
|
async collectPaths(specs = this.resolvePathSpecs()) {
|
|
265974
266011
|
const out = [];
|
|
265975
|
-
|
|
266012
|
+
let slot = 0;
|
|
266013
|
+
await pool(specs, WALK_CONCURRENCY, async (spec) => {
|
|
266014
|
+
const idx = slot++;
|
|
265976
266015
|
try {
|
|
265977
266016
|
if (!fs7.existsSync(spec.path)) {
|
|
265978
|
-
out
|
|
265979
|
-
|
|
266017
|
+
out[idx] = { key: spec.key, path: spec.path, exists: false, totalBytes: 0, topEntries: [], group: spec.group };
|
|
266018
|
+
return;
|
|
265980
266019
|
}
|
|
265981
266020
|
const st = await fsp.stat(spec.path);
|
|
265982
266021
|
if (st.isFile()) {
|
|
265983
|
-
out
|
|
265984
|
-
|
|
266022
|
+
out[idx] = { key: spec.key, path: spec.path, exists: true, totalBytes: st.size, topEntries: [], group: spec.group };
|
|
266023
|
+
return;
|
|
265985
266024
|
}
|
|
265986
|
-
const
|
|
265987
|
-
|
|
265988
|
-
topLevelBreakdown(spec.path)
|
|
265989
|
-
]);
|
|
265990
|
-
out.push({ key: spec.key, path: spec.path, exists: true, totalBytes, topEntries, group: spec.group });
|
|
266025
|
+
const { totalBytes, topEntries } = await sizeWithBreakdown(spec.path);
|
|
266026
|
+
out[idx] = { key: spec.key, path: spec.path, exists: true, totalBytes, topEntries, group: spec.group };
|
|
265991
266027
|
} catch (err) {
|
|
265992
266028
|
this.logger.warn(`\u91C7\u96C6\u8DEF\u5F84\u5360\u7528\u5931\u8D25 ${spec.path}: ${err.message}`);
|
|
265993
|
-
out
|
|
266029
|
+
out[idx] = { key: spec.key, path: spec.path, exists: false, totalBytes: 0, topEntries: [], group: spec.group };
|
|
265994
266030
|
}
|
|
265995
|
-
}
|
|
266031
|
+
});
|
|
265996
266032
|
return out;
|
|
265997
266033
|
}
|
|
265998
266034
|
async collectProcesses() {
|
|
@@ -291376,6 +291412,9 @@ ExtractionRuleService = __decorate101([
|
|
|
291376
291412
|
], ExtractionRuleService);
|
|
291377
291413
|
|
|
291378
291414
|
// dist/.server-tsc/extraction/structured-data.js
|
|
291415
|
+
function toCheerio(html) {
|
|
291416
|
+
return typeof html === "string" ? load(html) : html;
|
|
291417
|
+
}
|
|
291379
291418
|
function pageClassFromJsonLdTypes(types2) {
|
|
291380
291419
|
const t = new Set(types2.map((x) => x.toLowerCase()));
|
|
291381
291420
|
if (t.has("person"))
|
|
@@ -291411,7 +291450,7 @@ function flattenEntity(entity, prefix = "", out = {}) {
|
|
|
291411
291450
|
return out;
|
|
291412
291451
|
}
|
|
291413
291452
|
function extractJsonLd(html) {
|
|
291414
|
-
const $ =
|
|
291453
|
+
const $ = toCheerio(html);
|
|
291415
291454
|
const entities = [];
|
|
291416
291455
|
$('script[type="application/ld+json"]').each((_i, el) => {
|
|
291417
291456
|
try {
|
|
@@ -291441,7 +291480,7 @@ function extractJsonLd(html) {
|
|
|
291441
291480
|
return { types: types2, data };
|
|
291442
291481
|
}
|
|
291443
291482
|
function extractOpenGraph(html) {
|
|
291444
|
-
const $ =
|
|
291483
|
+
const $ = toCheerio(html);
|
|
291445
291484
|
const out = {};
|
|
291446
291485
|
$('meta[property^="og:"], meta[name^="og:"]').each((_i, el) => {
|
|
291447
291486
|
const key = $(el).attr("property") || $(el).attr("name") || "";
|
|
@@ -291546,7 +291585,7 @@ function applySelectorRule(payload, html) {
|
|
|
291546
291585
|
if (payload?.fields || payload?.lists || payload?.entityList) {
|
|
291547
291586
|
return applyScriptRule(html, payload);
|
|
291548
291587
|
}
|
|
291549
|
-
const $ = load(html);
|
|
291588
|
+
const $ = typeof html === "string" ? load(html) : html;
|
|
291550
291589
|
const result = {};
|
|
291551
291590
|
const mapping = payload.mapping || {};
|
|
291552
291591
|
for (const [field, selector] of Object.entries(mapping)) {
|
|
@@ -291628,13 +291667,14 @@ var ExtractionService = class ExtractionService2 {
|
|
|
291628
291667
|
applyRulesToHtml(sourceUrl, html, rules) {
|
|
291629
291668
|
const matched = rules.filter((r) => r.enabled && matchRule(r, sourceUrl)).sort((a, b2) => b2.priority - a.priority);
|
|
291630
291669
|
const extracted = {};
|
|
291670
|
+
const $ = load(html);
|
|
291631
291671
|
for (const rule of matched) {
|
|
291632
291672
|
if (rule.ruleType === "selector")
|
|
291633
|
-
Object.assign(extracted, applySelectorRule(rule.rulePayload,
|
|
291673
|
+
Object.assign(extracted, applySelectorRule(rule.rulePayload, $));
|
|
291634
291674
|
else if (rule.ruleType === "regex")
|
|
291635
291675
|
Object.assign(extracted, applyRegexRule(rule.rulePayload, html));
|
|
291636
291676
|
else if (rule.ruleType === "script")
|
|
291637
|
-
Object.assign(extracted, applyScriptRule(
|
|
291677
|
+
Object.assign(extracted, applyScriptRule($, rule.rulePayload));
|
|
291638
291678
|
}
|
|
291639
291679
|
this.applyProfileUrlFallback(extracted, sourceUrl, matched);
|
|
291640
291680
|
return {
|
|
@@ -291712,8 +291752,9 @@ var ExtractionService = class ExtractionService2 {
|
|
|
291712
291752
|
});
|
|
291713
291753
|
return { ...result, status: "no-snapshot", message: "Missing sourceUrl or rrweb full snapshot." };
|
|
291714
291754
|
}
|
|
291715
|
-
const
|
|
291716
|
-
const
|
|
291755
|
+
const $ = load(html);
|
|
291756
|
+
const jsonld = extractJsonLd($);
|
|
291757
|
+
const og = extractOpenGraph($);
|
|
291717
291758
|
const rules = await this.ruleService.findEnabled();
|
|
291718
291759
|
const adapterRules = (await this.adapterRuleRepo.find({ where: { enabled: true } })).map((r) => ({
|
|
291719
291760
|
ruleId: r.externalId || `${r.platform}/${r.hostPattern}`,
|
|
@@ -291730,11 +291771,11 @@ var ExtractionService = class ExtractionService2 {
|
|
|
291730
291771
|
const ruleExtracted = {};
|
|
291731
291772
|
for (const rule of matched) {
|
|
291732
291773
|
if (rule.ruleType === "selector")
|
|
291733
|
-
Object.assign(ruleExtracted, applySelectorRule(rule.rulePayload,
|
|
291774
|
+
Object.assign(ruleExtracted, applySelectorRule(rule.rulePayload, $));
|
|
291734
291775
|
else if (rule.ruleType === "regex")
|
|
291735
291776
|
Object.assign(ruleExtracted, applyRegexRule(rule.rulePayload, html));
|
|
291736
291777
|
else if (rule.ruleType === "script")
|
|
291737
|
-
Object.assign(ruleExtracted, applyScriptRule(
|
|
291778
|
+
Object.assign(ruleExtracted, applyScriptRule($, rule.rulePayload));
|
|
291738
291779
|
}
|
|
291739
291780
|
const merged = { ...og, ...jsonld?.data || {}, ...ruleExtracted };
|
|
291740
291781
|
for (const [k2, v] of Object.entries({ ...jsonld?.data || {}, ...og || {} })) {
|
|
@@ -292086,8 +292127,9 @@ var ExtractionService = class ExtractionService2 {
|
|
|
292086
292127
|
return { sessionId, error: "missing snapshot or sourceUrl" };
|
|
292087
292128
|
}
|
|
292088
292129
|
const parsed = new URL(sourceUrl);
|
|
292089
|
-
const
|
|
292090
|
-
const
|
|
292130
|
+
const $ = load(html);
|
|
292131
|
+
const jsonld = extractJsonLd($);
|
|
292132
|
+
const og = extractOpenGraph($);
|
|
292091
292133
|
const pageClass = jsonld ? pageClassFromJsonLdTypes(jsonld.types) : null;
|
|
292092
292134
|
const draft = {
|
|
292093
292135
|
ruleId: `${etldPlus1(parsed.hostname).replace(/\./g, "-")}-${pageClass || "page"}-auto`,
|
|
@@ -294489,6 +294531,8 @@ var AdapterService = class AdapterService2 {
|
|
|
294489
294531
|
const sourceUrl = snapshot.sourceUrl || "";
|
|
294490
294532
|
const html = snapshot.html;
|
|
294491
294533
|
const matched = sourceUrl ? await this.findRulesForUrl(sourceUrl) : [];
|
|
294534
|
+
let cached$ = null;
|
|
294535
|
+
const $ = () => cached$ ??= load(html);
|
|
294492
294536
|
const ruleExtracted = {};
|
|
294493
294537
|
const isEmptyVal = (v) => v == null || v === "" || Array.isArray(v) && v.length === 0;
|
|
294494
294538
|
const mergeRuleOutput = (out) => {
|
|
@@ -294502,15 +294546,13 @@ var AdapterService = class AdapterService2 {
|
|
|
294502
294546
|
if (rule.ruleType === "selector") {
|
|
294503
294547
|
const payload = rule.rulePayload;
|
|
294504
294548
|
if (payload?.fields || payload?.lists) {
|
|
294505
|
-
const { applyScriptRule: applyScriptRule2 } = await import("./chunks/script-rule-
|
|
294506
|
-
mergeRuleOutput(applyScriptRule2(
|
|
294549
|
+
const { applyScriptRule: applyScriptRule2 } = await import("./chunks/script-rule-4RZQ2PQE.mjs");
|
|
294550
|
+
mergeRuleOutput(applyScriptRule2($(), payload));
|
|
294507
294551
|
} else {
|
|
294508
|
-
const { load: load2 } = await import("./chunks/esm-4U746B76.mjs");
|
|
294509
|
-
const $ = load2(html);
|
|
294510
294552
|
const mapping = payload.mapping || {};
|
|
294511
294553
|
const out = {};
|
|
294512
294554
|
for (const [field, selector] of Object.entries(mapping)) {
|
|
294513
|
-
const el = $(selector).first();
|
|
294555
|
+
const el = $()(selector).first();
|
|
294514
294556
|
out[field] = el.text().trim() || el.attr("content") || el.attr("value") || null;
|
|
294515
294557
|
}
|
|
294516
294558
|
mergeRuleOutput(out);
|
|
@@ -294524,13 +294566,13 @@ var AdapterService = class AdapterService2 {
|
|
|
294524
294566
|
}
|
|
294525
294567
|
mergeRuleOutput(out);
|
|
294526
294568
|
} else if (rule.ruleType === "script") {
|
|
294527
|
-
const { applyScriptRule: applyScriptRule2 } = await import("./chunks/script-rule-
|
|
294528
|
-
mergeRuleOutput(applyScriptRule2(
|
|
294569
|
+
const { applyScriptRule: applyScriptRule2 } = await import("./chunks/script-rule-4RZQ2PQE.mjs");
|
|
294570
|
+
mergeRuleOutput(applyScriptRule2($(), rule.rulePayload));
|
|
294529
294571
|
} else if (rule.ruleType === "jsonld") {
|
|
294530
294572
|
}
|
|
294531
294573
|
}
|
|
294532
|
-
const jsonld = extractJsonLd(
|
|
294533
|
-
const og = extractOpenGraph(
|
|
294574
|
+
const jsonld = extractJsonLd($());
|
|
294575
|
+
const og = extractOpenGraph($());
|
|
294534
294576
|
const merged = { ...og, ...jsonld?.data || {}, ...ruleExtracted };
|
|
294535
294577
|
for (const [k2, v] of Object.entries({ ...jsonld?.data || {}, ...og || {} })) {
|
|
294536
294578
|
if (ruleExtracted[k2] == null && v != null)
|
|
@@ -305346,6 +305388,11 @@ var CustomerService = class CustomerService2 {
|
|
|
305346
305388
|
datasync;
|
|
305347
305389
|
tenant;
|
|
305348
305390
|
logger = new import_common136.Logger(CustomerService_1.name);
|
|
305391
|
+
static COLLECT_TTL_MS = 6e4;
|
|
305392
|
+
collectCache = null;
|
|
305393
|
+
invalidateCollectCache() {
|
|
305394
|
+
this.collectCache = null;
|
|
305395
|
+
}
|
|
305349
305396
|
constructor(repo, jobCaseRepo, remarkRepo, companyProfileRepo, talentProfileRepo, jobPostingRepo, parseLogRepo, datasync, tenant) {
|
|
305350
305397
|
this.repo = repo;
|
|
305351
305398
|
this.jobCaseRepo = jobCaseRepo;
|
|
@@ -305358,7 +305405,9 @@ var CustomerService = class CustomerService2 {
|
|
|
305358
305405
|
this.tenant = tenant;
|
|
305359
305406
|
}
|
|
305360
305407
|
async batchDelete(ids) {
|
|
305361
|
-
|
|
305408
|
+
const result = await this.datasync.deleteWithTombstones(this.repo, "customers", ids);
|
|
305409
|
+
this.invalidateCollectCache();
|
|
305410
|
+
return result;
|
|
305362
305411
|
}
|
|
305363
305412
|
async onModuleInit() {
|
|
305364
305413
|
await this.repo.query("UPDATE customers SET isCustomer = 1 WHERE isCustomer IS NULL");
|
|
@@ -305439,6 +305488,7 @@ var CustomerService = class CustomerService2 {
|
|
|
305439
305488
|
if (changed) {
|
|
305440
305489
|
customer.aliases = [...aliases];
|
|
305441
305490
|
await this.repo.save(customer);
|
|
305491
|
+
this.invalidateCollectCache();
|
|
305442
305492
|
}
|
|
305443
305493
|
return { customer, created: false, merged: true };
|
|
305444
305494
|
};
|
|
@@ -305472,6 +305522,7 @@ var CustomerService = class CustomerService2 {
|
|
|
305472
305522
|
});
|
|
305473
305523
|
try {
|
|
305474
305524
|
const saved = await this.repo.save(entity);
|
|
305525
|
+
this.invalidateCollectCache();
|
|
305475
305526
|
return { customer: saved, created: true, merged: false };
|
|
305476
305527
|
} catch (err) {
|
|
305477
305528
|
if (String(err?.code).startsWith("SQLITE_CONSTRAINT")) {
|
|
@@ -305521,7 +305572,9 @@ var CustomerService = class CustomerService2 {
|
|
|
305521
305572
|
}
|
|
305522
305573
|
customer.profile = next;
|
|
305523
305574
|
}
|
|
305524
|
-
|
|
305575
|
+
const saved = await this.repo.save(customer);
|
|
305576
|
+
this.invalidateCollectCache();
|
|
305577
|
+
return saved;
|
|
305525
305578
|
}
|
|
305526
305579
|
async duplicates(id) {
|
|
305527
305580
|
const customer = await this.findOne(id);
|
|
@@ -305595,6 +305648,7 @@ var CustomerService = class CustomerService2 {
|
|
|
305595
305648
|
if ((keep.isCustomer ?? 0) !== 1 && (remove.isCustomer ?? 0) === 1)
|
|
305596
305649
|
keep.isCustomer = 1;
|
|
305597
305650
|
await this.repo.save(keep);
|
|
305651
|
+
this.invalidateCollectCache();
|
|
305598
305652
|
await this.jobCaseRepo.update({ customerId: removeId }, { customerId: keepId });
|
|
305599
305653
|
await this.remarkRepo.update({ targetType: "customer", targetId: String(removeId) }, { targetId: String(keepId) });
|
|
305600
305654
|
await this.datasync.deleteWithTombstones(this.repo, "customers", [removeId]);
|
|
@@ -305618,7 +305672,15 @@ var CustomerService = class CustomerService2 {
|
|
|
305618
305672
|
});
|
|
305619
305673
|
return [...new Set(parts)];
|
|
305620
305674
|
}
|
|
305621
|
-
async collectCompanies() {
|
|
305675
|
+
async collectCompanies(force = false) {
|
|
305676
|
+
if (!force && this.collectCache && Date.now() - this.collectCache.at < CustomerService_1.COLLECT_TTL_MS) {
|
|
305677
|
+
return this.collectCache.result;
|
|
305678
|
+
}
|
|
305679
|
+
const result = await this.runCollectCompanies();
|
|
305680
|
+
this.collectCache = { at: Date.now(), result };
|
|
305681
|
+
return result;
|
|
305682
|
+
}
|
|
305683
|
+
async runCollectCompanies() {
|
|
305622
305684
|
const talents = await this.talentProfileRepo.find();
|
|
305623
305685
|
const talentNames = new Set(talents.map((t) => (t.name ?? "").trim().toLowerCase()).filter(Boolean));
|
|
305624
305686
|
const existing = await this.repo.find();
|
|
@@ -305656,7 +305718,7 @@ var CustomerService = class CustomerService2 {
|
|
|
305656
305718
|
}
|
|
305657
305719
|
}
|
|
305658
305720
|
const profileKeys = /* @__PURE__ */ new Set();
|
|
305659
|
-
for (const p of
|
|
305721
|
+
for (const p of profiles) {
|
|
305660
305722
|
const k2 = normalizeCustomerName(p.name ?? "");
|
|
305661
305723
|
if (k2)
|
|
305662
305724
|
profileKeys.add(k2);
|
|
@@ -305671,7 +305733,9 @@ var CustomerService = class CustomerService2 {
|
|
|
305671
305733
|
}
|
|
305672
305734
|
}
|
|
305673
305735
|
const caseCustomerIds = new Set((await this.jobCaseRepo.find({ select: ["customerId"] })).map((jc) => jc.customerId).filter((id) => id != null));
|
|
305674
|
-
for (const c of await this.repo.find(
|
|
305736
|
+
for (const c of await this.repo.find({
|
|
305737
|
+
select: ["id", "canonicalName", "dedupKey", "aliases", "isCustomer", "ownerId"]
|
|
305738
|
+
})) {
|
|
305675
305739
|
if (!(c.canonicalName ?? "").trim()) {
|
|
305676
305740
|
if (caseCustomerIds.has(c.id))
|
|
305677
305741
|
continue;
|
|
@@ -305707,13 +305771,13 @@ var CustomerService = class CustomerService2 {
|
|
|
305707
305771
|
qb.select([...CustomerService_1.LIST_COLS]);
|
|
305708
305772
|
const matched = await qb.getMany();
|
|
305709
305773
|
const profileKeys = /* @__PURE__ */ new Set();
|
|
305710
|
-
for (const p of await this.companyProfileRepo.find()) {
|
|
305774
|
+
for (const p of await this.companyProfileRepo.find({ select: ["name"] })) {
|
|
305711
305775
|
const k2 = normalizeCustomerName(p.name ?? "");
|
|
305712
305776
|
if (k2)
|
|
305713
305777
|
profileKeys.add(k2);
|
|
305714
305778
|
}
|
|
305715
305779
|
const resumeKeys = /* @__PURE__ */ new Set();
|
|
305716
|
-
for (const t of await this.talentProfileRepo.find()) {
|
|
305780
|
+
for (const t of await this.talentProfileRepo.find({ select: ["extracted"] })) {
|
|
305717
305781
|
const ex = t.extracted ?? {};
|
|
305718
305782
|
for (const cand of this.parseResumeCompanies(String(ex.currentCompany ?? ex.company ?? ""))) {
|
|
305719
305783
|
const k2 = normalizeCustomerName(cand);
|
|
@@ -305724,15 +305788,15 @@ var CustomerService = class CustomerService2 {
|
|
|
305724
305788
|
const caseCount = /* @__PURE__ */ new Map();
|
|
305725
305789
|
const activeCount = /* @__PURE__ */ new Map();
|
|
305726
305790
|
const hmhLocal = /* @__PURE__ */ new Set();
|
|
305727
|
-
|
|
305728
|
-
|
|
305729
|
-
|
|
305730
|
-
caseCount.set(
|
|
305731
|
-
|
|
305732
|
-
|
|
305733
|
-
|
|
305734
|
-
if ((
|
|
305735
|
-
hmhLocal.add(
|
|
305791
|
+
const caseRows = await this.jobCaseRepo.createQueryBuilder("jc").select("jc.customerId", "customerId").addSelect("COUNT(*)", "cnt").addSelect("SUM(CASE WHEN jc.status = 'active' THEN 1 ELSE 0 END)", "activeCnt").addSelect("MAX(CASE WHEN jc.folderPath LIKE '%/local/clients/%' THEN 1 ELSE 0 END)", "hmhFlag").where("jc.customerId IS NOT NULL").groupBy("jc.customerId").getRawMany();
|
|
305792
|
+
for (const r of caseRows) {
|
|
305793
|
+
const id = Number(r.customerId);
|
|
305794
|
+
caseCount.set(id, Number(r.cnt));
|
|
305795
|
+
const active = Number(r.activeCnt ?? 0);
|
|
305796
|
+
if (active)
|
|
305797
|
+
activeCount.set(id, active);
|
|
305798
|
+
if (Number(r.hmhFlag ?? 0))
|
|
305799
|
+
hmhLocal.add(id);
|
|
305736
305800
|
}
|
|
305737
305801
|
const decorated = matched.map((c) => {
|
|
305738
305802
|
const keys = [c.dedupKey, ...(c.aliases ?? []).map((a) => normalizeCustomerName(a))];
|
|
@@ -305878,7 +305942,7 @@ var CustomerController = class CustomerController2 {
|
|
|
305878
305942
|
});
|
|
305879
305943
|
}
|
|
305880
305944
|
collect() {
|
|
305881
|
-
return this.service.collectCompanies();
|
|
305945
|
+
return this.service.collectCompanies(true);
|
|
305882
305946
|
}
|
|
305883
305947
|
batchDelete(body) {
|
|
305884
305948
|
const ids = this.parseBatchIds(body);
|
|
@@ -306701,8 +306765,9 @@ var ResourceUsageController = class ResourceUsageController2 {
|
|
|
306701
306765
|
}
|
|
306702
306766
|
async collectNow() {
|
|
306703
306767
|
const snapshot = await this.service.collectNow();
|
|
306704
|
-
|
|
306705
|
-
|
|
306768
|
+
this.service.reportUnreported().catch(() => {
|
|
306769
|
+
});
|
|
306770
|
+
return { ok: true, snapshot };
|
|
306706
306771
|
}
|
|
306707
306772
|
pending() {
|
|
306708
306773
|
return this.service.pendingCount().then((count2) => ({ count: count2 }));
|