@q32/signal-scanner 0.1.0 → 0.1.1

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.
Files changed (75) hide show
  1. package/dist/dynamic.d.ts +43 -0
  2. package/dist/dynamic.d.ts.map +1 -0
  3. package/{src/dynamic.ts → dist/dynamic.js} +133 -156
  4. package/dist/dynamic.js.map +1 -0
  5. package/dist/feeds.d.ts +66 -0
  6. package/dist/feeds.d.ts.map +1 -0
  7. package/dist/feeds.js +259 -0
  8. package/dist/feeds.js.map +1 -0
  9. package/dist/index.d.ts +110 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +1251 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/intel.d.ts +72 -0
  14. package/dist/intel.d.ts.map +1 -0
  15. package/dist/intel.js +480 -0
  16. package/dist/intel.js.map +1 -0
  17. package/dist/node-tls.d.ts +8 -0
  18. package/dist/node-tls.d.ts.map +1 -0
  19. package/dist/node-tls.js +48 -0
  20. package/dist/node-tls.js.map +1 -0
  21. package/dist/render.d.ts +26 -0
  22. package/dist/render.d.ts.map +1 -0
  23. package/dist/render.js +248 -0
  24. package/dist/render.js.map +1 -0
  25. package/dist/rules/packs/binary.d.ts +4 -0
  26. package/dist/rules/packs/binary.d.ts.map +1 -0
  27. package/dist/rules/packs/binary.js +101 -0
  28. package/dist/rules/packs/binary.js.map +1 -0
  29. package/dist/rules/packs/css.d.ts +3 -0
  30. package/dist/rules/packs/css.d.ts.map +1 -0
  31. package/dist/rules/packs/css.js +43 -0
  32. package/dist/rules/packs/css.js.map +1 -0
  33. package/dist/rules/packs/decoders.d.ts +3 -0
  34. package/dist/rules/packs/decoders.d.ts.map +1 -0
  35. package/dist/rules/packs/decoders.js +46 -0
  36. package/dist/rules/packs/decoders.js.map +1 -0
  37. package/dist/rules/packs/html.d.ts +4 -0
  38. package/dist/rules/packs/html.d.ts.map +1 -0
  39. package/dist/rules/packs/html.js +227 -0
  40. package/dist/rules/packs/html.js.map +1 -0
  41. package/dist/rules/packs/index.d.ts +24 -0
  42. package/dist/rules/packs/index.d.ts.map +1 -0
  43. package/dist/rules/packs/index.js +75 -0
  44. package/dist/rules/packs/index.js.map +1 -0
  45. package/dist/rules/packs/script-risk.d.ts +4 -0
  46. package/dist/rules/packs/script-risk.d.ts.map +1 -0
  47. package/dist/rules/packs/script-risk.js +231 -0
  48. package/dist/rules/packs/script-risk.js.map +1 -0
  49. package/dist/rules/packs/source-code.d.ts +3 -0
  50. package/dist/rules/packs/source-code.d.ts.map +1 -0
  51. package/dist/rules/packs/source-code.js +179 -0
  52. package/dist/rules/packs/source-code.js.map +1 -0
  53. package/dist/rules/packs/urls.d.ts +3 -0
  54. package/dist/rules/packs/urls.d.ts.map +1 -0
  55. package/dist/rules/packs/urls.js +123 -0
  56. package/dist/rules/packs/urls.js.map +1 -0
  57. package/dist/rules/types.d.ts +34 -0
  58. package/dist/rules/types.d.ts.map +1 -0
  59. package/dist/rules/types.js +2 -0
  60. package/dist/rules/types.js.map +1 -0
  61. package/package.json +18 -14
  62. package/src/feeds.ts +0 -334
  63. package/src/index.ts +0 -1366
  64. package/src/intel.ts +0 -561
  65. package/src/node-tls.ts +0 -55
  66. package/src/render.ts +0 -233
  67. package/src/rules/packs/binary.ts +0 -103
  68. package/src/rules/packs/css.ts +0 -44
  69. package/src/rules/packs/decoders.ts +0 -47
  70. package/src/rules/packs/html.ts +0 -255
  71. package/src/rules/packs/index.ts +0 -76
  72. package/src/rules/packs/script-risk.ts +0 -236
  73. package/src/rules/packs/source-code.ts +0 -180
  74. package/src/rules/packs/urls.ts +0 -138
  75. package/src/rules/types.ts +0 -56
@@ -0,0 +1,179 @@
1
+ export const sourceCodeRules = [
2
+ {
3
+ id: "hardcoded_secret_candidate",
4
+ pack: "source-code",
5
+ severity: "high",
6
+ confidence: "medium",
7
+ title: "Hardcoded secret candidate",
8
+ description: "Source text matched a risky secret-like token pattern.",
9
+ locationType: "source",
10
+ pattern: /(?:AKIA[0-9A-Z]{16}|xox[baprs]-[a-zA-Z0-9-]{20,}|ghp_[a-zA-Z0-9]{20,})/,
11
+ score: { base: 62, tags: ["source"] }
12
+ },
13
+ {
14
+ id: "webhook_url_candidate",
15
+ pack: "source-code",
16
+ severity: "medium",
17
+ confidence: "medium",
18
+ title: "Webhook URL candidate",
19
+ description: "Source text contains a webhook URL candidate.",
20
+ locationType: "source",
21
+ pattern: /https:\/\/(?:hooks\.slack\.com\/services\/|discord(?:app)?\.com\/api\/webhooks\/|api\.telegram\.org\/bot)[A-Za-z0-9/_:.-]+/,
22
+ score: { base: 35, tags: ["source", "url"] }
23
+ },
24
+ {
25
+ id: "dangerous_child_process",
26
+ pack: "source-code",
27
+ severity: "high",
28
+ confidence: "medium",
29
+ title: "Dangerous child process use",
30
+ description: "Source text references command execution through child_process.",
31
+ locationType: "source",
32
+ pattern: /\bchild_process\.(?:exec|execSync|spawn|spawnSync|execFile|execFileSync)\b|require\s*\(\s*['"]child_process['"]\s*\)\s*\.\s*(?:exec|execSync|spawn|spawnSync|execFile|execFileSync)\b|import\s*\{[^}]*\b(?:exec|execSync|spawn|spawnSync|execFile|execFileSync)\b[^}]*\}\s*from\s*['"]node:child_process['"]/,
33
+ score: { base: 50, tags: ["source"] }
34
+ },
35
+ {
36
+ id: "shell_execution_import",
37
+ pack: "source-code",
38
+ severity: "medium",
39
+ confidence: "medium",
40
+ title: "Shell execution import",
41
+ description: "Source text imports Node child_process command execution APIs.",
42
+ locationType: "source",
43
+ pattern: /\b(?:import|require)\b[^;\n]{0,120}\bchild_process\b/,
44
+ score: { base: 24, tags: ["source"] }
45
+ },
46
+ {
47
+ id: "curl_pipe_shell",
48
+ pack: "source-code",
49
+ severity: "high",
50
+ confidence: "medium",
51
+ title: "curl pipe shell",
52
+ description: "Source text pipes a downloaded script into a shell.",
53
+ locationType: "source",
54
+ pattern: /\bcurl\b[^|]{0,120}\|\s*(?:sh|bash)/,
55
+ score: { base: 70, tags: ["source", "url"] }
56
+ },
57
+ {
58
+ id: "postinstall_script",
59
+ pack: "source-code",
60
+ severity: "medium",
61
+ confidence: "medium",
62
+ title: "Postinstall script",
63
+ description: "Package metadata defines a postinstall script.",
64
+ locationType: "source",
65
+ pattern: /"postinstall"\s*:/,
66
+ score: { base: 20, tags: ["source"] }
67
+ },
68
+ {
69
+ id: "preinstall_script",
70
+ pack: "source-code",
71
+ severity: "medium",
72
+ confidence: "medium",
73
+ title: "Preinstall script",
74
+ description: "Package metadata defines a preinstall script.",
75
+ locationType: "source",
76
+ pattern: /"preinstall"\s*:/,
77
+ score: { base: 20, tags: ["source"] }
78
+ },
79
+ {
80
+ id: "install_script_network_fetch",
81
+ pack: "source-code",
82
+ severity: "high",
83
+ confidence: "medium",
84
+ title: "Install script performs network fetch",
85
+ description: "Install lifecycle script appears to fetch network content.",
86
+ locationType: "source",
87
+ pattern: /"(?:preinstall|install|postinstall)"\s*:\s*"[^"]*(?:curl|wget|fetch|https?:\/\/)/,
88
+ score: { base: 66, tags: ["source", "url"] }
89
+ },
90
+ {
91
+ id: "non_literal_require",
92
+ pack: "source-code",
93
+ severity: "medium",
94
+ confidence: "medium",
95
+ title: "Non-literal require candidate",
96
+ description: "Source text calls require() with an expression instead of a string literal.",
97
+ locationType: "source",
98
+ pattern: /\brequire\s*\(\s*(?!['"`])/,
99
+ score: { base: 18, tags: ["source"] }
100
+ },
101
+ {
102
+ id: "non_literal_regexp",
103
+ pack: "source-code",
104
+ severity: "medium",
105
+ confidence: "medium",
106
+ title: "Non-literal RegExp candidate",
107
+ description: "Source text constructs a RegExp from a non-literal expression.",
108
+ locationType: "source",
109
+ pattern: /\bnew\s+RegExp\s*\(\s*(?!['"`])|\bRegExp\s*\(\s*(?!['"`])/,
110
+ score: { base: 16, tags: ["source"] }
111
+ },
112
+ {
113
+ id: "new_buffer_constructor",
114
+ pack: "source-code",
115
+ severity: "medium",
116
+ confidence: "medium",
117
+ title: "New Buffer constructor",
118
+ description: "Source text uses the legacy Buffer constructor.",
119
+ locationType: "source",
120
+ pattern: /\bnew\s+Buffer\s*\(/,
121
+ score: { base: 12, tags: ["source"] }
122
+ },
123
+ {
124
+ id: "weak_crypto_hash",
125
+ pack: "source-code",
126
+ severity: "medium",
127
+ confidence: "medium",
128
+ title: "Weak crypto hash",
129
+ description: "Source text references weak hash algorithms.",
130
+ locationType: "source",
131
+ pattern: /\bcreateHash\s*\(\s*['"](?:md5|sha1)['"]\s*\)/,
132
+ score: { base: 16, tags: ["source"] }
133
+ },
134
+ {
135
+ id: "pseudo_random_bytes",
136
+ pack: "source-code",
137
+ severity: "medium",
138
+ confidence: "medium",
139
+ title: "Pseudo-random bytes",
140
+ description: "Source text references crypto.pseudoRandomBytes().",
141
+ locationType: "source",
142
+ pattern: /\bpseudoRandomBytes\s*\(/,
143
+ score: { base: 16, tags: ["source"] }
144
+ },
145
+ {
146
+ id: "template_escape_disabled",
147
+ pack: "source-code",
148
+ severity: "medium",
149
+ confidence: "medium",
150
+ title: "Template escaping disabled",
151
+ description: "Source text appears to disable template escaping.",
152
+ locationType: "source",
153
+ pattern: /\bescapeMarkup\s*=\s*false\b/,
154
+ score: { base: 22, tags: ["source"] }
155
+ },
156
+ {
157
+ id: "sensitive_file_read",
158
+ pack: "source-code",
159
+ severity: "high",
160
+ confidence: "medium",
161
+ title: "Sensitive file read candidate",
162
+ description: "Source text references filesystem reads of sensitive paths or environment files.",
163
+ locationType: "source",
164
+ pattern: /\b(?:readFileSync|readFile)\s*\([^)]*(?:\/etc\/passwd|\.env|id_rsa|credentials)/,
165
+ score: { base: 48, tags: ["source"] }
166
+ },
167
+ {
168
+ id: "private_key_material",
169
+ pack: "source-code",
170
+ severity: "critical",
171
+ confidence: "high",
172
+ title: "Private key material",
173
+ description: "Source text contains a private key header.",
174
+ locationType: "source",
175
+ pattern: /-----BEGIN (?:RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----/,
176
+ score: { base: 95, tags: ["source"] }
177
+ }
178
+ ];
179
+ //# sourceMappingURL=source-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-code.js","sourceRoot":"","sources":["../../../src/rules/packs/source-code.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { RuleDefinition } from "../types.js";
2
+ export declare const urlRules: Record<"punycode_login_url" | "redirect_to_url_shortener" | "final_url_offsite_redirect" | "private_ip_url" | "ip_literal_url" | "suspicious_tld_url" | "download_like_external_url" | "malware_download_like_url" | "shared_hosting_subdomain_url" | "brand_impersonation_url" | "credential_path_on_suspicious_host" | "generated_landing_url", RuleDefinition>;
3
+ //# sourceMappingURL=urls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"urls.d.ts","sourceRoot":"","sources":["../../../src/rules/packs/urls.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,eAAO,MAAM,QAAQ,EAAE,MAAM,CACzB,oBAAoB,GACpB,2BAA2B,GAC3B,4BAA4B,GAC5B,gBAAgB,GAChB,gBAAgB,GAChB,oBAAoB,GACpB,4BAA4B,GAC5B,2BAA2B,GAC3B,8BAA8B,GAC9B,yBAAyB,GACzB,oCAAoC,GACpC,uBAAuB,EACzB,cAAc,CA0Hf,CAAC"}
@@ -0,0 +1,123 @@
1
+ export const urlRules = {
2
+ punycode_login_url: {
3
+ id: "punycode_login_url",
4
+ pack: "phishing",
5
+ severity: "high",
6
+ confidence: "high",
7
+ title: "Punycode login URL",
8
+ description: "A login-like URL uses punycode.",
9
+ locationType: "url",
10
+ score: { base: 70, tags: ["phishing", "url"] }
11
+ },
12
+ redirect_to_url_shortener: {
13
+ id: "redirect_to_url_shortener",
14
+ pack: "redirects",
15
+ severity: "medium",
16
+ confidence: "medium",
17
+ title: "URL shortener destination",
18
+ description: "The scanned URL is, or redirects through, a known URL shortener (a common cloaking step).",
19
+ locationType: "url",
20
+ score: { base: 20, tags: ["redirect", "url"] }
21
+ },
22
+ final_url_offsite_redirect: {
23
+ id: "final_url_offsite_redirect",
24
+ pack: "redirects",
25
+ severity: "medium",
26
+ confidence: "high",
27
+ title: "Final URL redirects off-site",
28
+ description: "The fetched URL resolves to a different registrable domain than the submitted URL.",
29
+ locationType: "url",
30
+ score: { base: 25, tags: ["redirect", "url"] }
31
+ },
32
+ private_ip_url: {
33
+ id: "private_ip_url",
34
+ pack: "url-risk",
35
+ severity: "medium",
36
+ confidence: "high",
37
+ title: "Private or local network URL",
38
+ description: "Content references a localhost or private-network URL.",
39
+ locationType: "url",
40
+ score: { base: 25, tags: ["url"] }
41
+ },
42
+ ip_literal_url: {
43
+ id: "ip_literal_url",
44
+ pack: "url-risk",
45
+ severity: "medium",
46
+ confidence: "medium",
47
+ title: "IP literal URL",
48
+ description: "Content references a URL by IP address instead of a hostname.",
49
+ locationType: "url",
50
+ score: { base: 22, tags: ["url"] }
51
+ },
52
+ suspicious_tld_url: {
53
+ id: "suspicious_tld_url",
54
+ pack: "url-risk",
55
+ severity: "low",
56
+ confidence: "medium",
57
+ title: "Suspicious TLD URL",
58
+ description: "Content references a URL with a TLD commonly seen in abuse investigations.",
59
+ locationType: "url",
60
+ score: { base: 8, tags: ["url"] }
61
+ },
62
+ download_like_external_url: {
63
+ id: "download_like_external_url",
64
+ pack: "url-risk",
65
+ severity: "medium",
66
+ confidence: "medium",
67
+ title: "Download-like external URL",
68
+ description: "Content references an off-site URL with download or payload path terms.",
69
+ locationType: "url",
70
+ score: { base: 18, tags: ["url"], repeatMultiplier: 0.25, maxRepeats: 3 }
71
+ },
72
+ malware_download_like_url: {
73
+ id: "malware_download_like_url",
74
+ pack: "url-risk",
75
+ severity: "high",
76
+ confidence: "medium",
77
+ title: "Malware-download-like URL path",
78
+ description: "URL path resembles common malware download naming for scripts, botnet payloads, or architecture-specific binaries.",
79
+ locationType: "url",
80
+ score: { base: 55, tags: ["binary", "url"] }
81
+ },
82
+ shared_hosting_subdomain_url: {
83
+ id: "shared_hosting_subdomain_url",
84
+ pack: "url-risk",
85
+ severity: "low",
86
+ confidence: "medium",
87
+ title: "Shared-hosting subdomain",
88
+ description: "The target URL is hosted on a shared/free-hosting subdomain rather than an independently controlled registrable domain.",
89
+ locationType: "url",
90
+ score: { base: 6, tags: ["hosting", "url"] }
91
+ },
92
+ brand_impersonation_url: {
93
+ id: "brand_impersonation_url",
94
+ pack: "phishing",
95
+ severity: "high",
96
+ confidence: "high",
97
+ title: "Brand name in host of an unrelated domain",
98
+ description: "A well-known brand appears in the hostname while the registrable domain does not belong to that brand — a hallmark of credential-phishing lookalike hosts.",
99
+ locationType: "url",
100
+ score: { base: 68, tags: ["phishing", "url"] }
101
+ },
102
+ credential_path_on_suspicious_host: {
103
+ id: "credential_path_on_suspicious_host",
104
+ pack: "phishing",
105
+ severity: "high",
106
+ confidence: "high",
107
+ title: "Login/account path on a suspicious host",
108
+ description: "A login, sign-in, account, or verification path is served from a free-hosting subdomain, generated host label, suspicious TLD, punycode, IP literal, or URL shortener — where legitimate brands do not host credentials.",
109
+ locationType: "url",
110
+ score: { base: 66, tags: ["credential", "phishing", "url"] }
111
+ },
112
+ generated_landing_url: {
113
+ id: "generated_landing_url",
114
+ pack: "url-risk",
115
+ severity: "high",
116
+ confidence: "medium",
117
+ title: "Generated suspicious landing URL",
118
+ description: "URL has generated-looking host/path structure commonly seen in injected landing pages and fake-update campaigns.",
119
+ locationType: "url",
120
+ score: { base: 78, tags: ["phishing", "url"] }
121
+ }
122
+ };
123
+ //# sourceMappingURL=urls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"urls.js","sourceRoot":"","sources":["../../../src/rules/packs/urls.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ export type Severity = "info" | "low" | "medium" | "high" | "critical";
2
+ export type Confidence = "low" | "medium" | "high";
3
+ export type FindingLocationType = "url" | "html" | "javascript" | "css" | "source" | "binary" | "decoded_artifact" | "aggregate";
4
+ export type ScoreTag = "binary" | "credential" | "decoded" | "dependency" | "exfiltration" | "hosting" | "obfuscation" | "payment" | "phishing" | "redirect" | "seo" | "script" | "source" | "technology" | "url" | "wallet";
5
+ export interface RuleScoreModel {
6
+ base: number;
7
+ tags: ScoreTag[];
8
+ repeatMultiplier?: number;
9
+ maxRepeats?: number;
10
+ maxGroup?: string;
11
+ }
12
+ export interface PatternRule {
13
+ id: string;
14
+ pack: string;
15
+ severity: Severity;
16
+ confidence: Confidence;
17
+ title: string;
18
+ description: string;
19
+ locationType: FindingLocationType;
20
+ pattern: RegExp;
21
+ counter?: string;
22
+ score: RuleScoreModel;
23
+ }
24
+ export interface RuleDefinition {
25
+ id: string;
26
+ pack: string;
27
+ severity: Severity;
28
+ confidence: Confidence;
29
+ title: string;
30
+ description: string;
31
+ locationType: FindingLocationType;
32
+ score: RuleScoreModel;
33
+ }
34
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/rules/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;AACvE,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AACnD,MAAM,MAAM,mBAAmB,GAAG,KAAK,GAAG,MAAM,GAAG,YAAY,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,kBAAkB,GAAG,WAAW,CAAC;AACjI,MAAM,MAAM,QAAQ,GAChB,QAAQ,GACR,YAAY,GACZ,SAAS,GACT,YAAY,GACZ,cAAc,GACd,SAAS,GACT,aAAa,GACb,SAAS,GACT,UAAU,GACV,UAAU,GACV,KAAK,GACL,QAAQ,GACR,QAAQ,GACR,YAAY,GACZ,KAAK,GACL,QAAQ,CAAC;AAEb,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IAKpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,mBAAmB,CAAC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,cAAc,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,mBAAmB,CAAC;IAClC,KAAK,EAAE,cAAc,CAAC;CACvB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/rules/types.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@q32/signal-scanner",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "description": "Static web signal scanner with bounded streaming analyzers, URL extraction, rule packs, scoring, and normalized reports.",
6
6
  "license": "MIT",
@@ -10,10 +10,12 @@
10
10
  },
11
11
  "files": [
12
12
  "README.md",
13
- "src/",
13
+ "dist/",
14
14
  "scripts/"
15
15
  ],
16
16
  "scripts": {
17
+ "build": "tsc -p tsconfig.json",
18
+ "prepack": "npm run build",
17
19
  "test": "bun test",
18
20
  "coverage": "bun test --coverage --coverage-reporter=lcov --coverage-dir=coverage && bun scripts/check-coverage.ts coverage/lcov.info 80",
19
21
  "coverage:report": "bun test --coverage",
@@ -22,28 +24,28 @@
22
24
  },
23
25
  "exports": {
24
26
  ".": {
25
- "types": "./src/index.ts",
26
- "default": "./src/index.ts"
27
+ "types": "./dist/index.d.ts",
28
+ "default": "./dist/index.js"
27
29
  },
28
30
  "./node-tls": {
29
- "types": "./src/node-tls.ts",
30
- "default": "./src/node-tls.ts"
31
+ "types": "./dist/node-tls.d.ts",
32
+ "default": "./dist/node-tls.js"
31
33
  },
32
34
  "./intel": {
33
- "types": "./src/intel.ts",
34
- "default": "./src/intel.ts"
35
+ "types": "./dist/intel.d.ts",
36
+ "default": "./dist/intel.js"
35
37
  },
36
38
  "./feeds": {
37
- "types": "./src/feeds.ts",
38
- "default": "./src/feeds.ts"
39
+ "types": "./dist/feeds.d.ts",
40
+ "default": "./dist/feeds.js"
39
41
  },
40
42
  "./dynamic": {
41
- "types": "./src/dynamic.ts",
42
- "default": "./src/dynamic.ts"
43
+ "types": "./dist/dynamic.d.ts",
44
+ "default": "./dist/dynamic.js"
43
45
  },
44
46
  "./render": {
45
- "types": "./src/render.ts",
46
- "default": "./src/render.ts"
47
+ "types": "./dist/render.d.ts",
48
+ "default": "./dist/render.js"
47
49
  }
48
50
  },
49
51
  "sideEffects": false,
@@ -57,6 +59,8 @@
57
59
  "esbuild": "^0.28.0",
58
60
  "fast-text-encoding": "^1.0.6",
59
61
  "isolated-vm": "^6.1.2",
62
+ "typescript": "^5.9.3",
63
+ "@types/node": "^24.0.0",
60
64
  "whatwg-url-without-unicode": "^8.0.0-3"
61
65
  }
62
66
  }