@utilix-tech/sdk 0.17.0 → 0.19.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/CHANGELOG.md +6 -0
- package/README.md +13 -4
- package/dist/{ai_agent-CcpkV2DR.d.cts → ai_agent-B-c59NXD.d.cts} +23 -2
- package/dist/{ai_agent-CcpkV2DR.d.ts → ai_agent-B-c59NXD.d.ts} +23 -2
- package/dist/{chunk-M35VJETW.js → chunk-265NPGKH.js} +32 -2
- package/dist/{chunk-L53LAVAD.js → chunk-LXKIPPDG.js} +266 -1
- package/dist/{chunk-M4MMO6C6.js → chunk-U34B5XPK.js} +41 -1
- package/dist/{code-Cn9uOIAh.d.cts → code-DaRvff2v.d.cts} +33 -2
- package/dist/{code-Cn9uOIAh.d.ts → code-DaRvff2v.d.ts} +33 -2
- package/dist/index.cjs +336 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/tools/ai_agent.cjs +30 -0
- package/dist/tools/ai_agent.d.cts +1 -1
- package/dist/tools/ai_agent.d.ts +1 -1
- package/dist/tools/ai_agent.js +1 -1
- package/dist/tools/code.cjs +265 -0
- package/dist/tools/code.d.cts +1 -1
- package/dist/tools/code.d.ts +1 -1
- package/dist/tools/code.js +1 -1
- package/dist/tools/units.cjs +40 -0
- package/dist/tools/units.d.cts +1 -1
- package/dist/tools/units.d.ts +1 -1
- package/dist/tools/units.js +1 -1
- package/dist/{units-CkV4kAIs.d.cts → units-BFTQwpBu.d.cts} +30 -2
- package/dist/{units-CkV4kAIs.d.ts → units-BFTQwpBu.d.ts} +30 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
Full release notes for all Utilix surfaces (browser tools, REST API, SDKs, MCP server) live at [utilix.tech/changelog](https://utilix.tech/changelog). This file tracks just this package.
|
|
4
4
|
|
|
5
|
+
## 0.19.0
|
|
6
|
+
- Add `detectRedos` (regex-redos-detector): statically flag catastrophic-backtracking risk (nested quantifiers, overlapping alternation, adjacent overlapping quantifiers).
|
|
7
|
+
|
|
8
|
+
## 0.18.0
|
|
9
|
+
- Added Present Value / Future Value Calculator (`calculateTimeValue`) and Vector Similarity Calculator (`vectorSimilarity`).
|
|
10
|
+
|
|
5
11
|
## 0.17.0
|
|
6
12
|
- Added User-Agent Parser (`parseUserAgent`) and GitHub URL Parser (`parseGithubUrl`).
|
|
7
13
|
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @utilix-tech/sdk
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**553 developer utility functions for Node.js: runs locally, no API key required.**
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@utilix-tech/sdk)
|
|
6
6
|
[](https://www.npmjs.com/package/@utilix-tech/sdk)
|
|
@@ -247,7 +247,7 @@ getNextRuns("*/5 * * * *", 5); // next 5 run timestamps
|
|
|
247
247
|
### `/units`: Conversions
|
|
248
248
|
|
|
249
249
|
```ts
|
|
250
|
-
import { convertBytes, pxToAll, convert, formatValue, validateCardNumber, validateIban, calculateLoan, validateBarcode, calculateTax, calculateCompoundInterest, validateIsbn, calculateTipSplit, calculateSimpleInterest } from "@utilix-tech/sdk/units";
|
|
250
|
+
import { convertBytes, pxToAll, convert, formatValue, validateCardNumber, validateIban, calculateLoan, validateBarcode, calculateTax, calculateCompoundInterest, validateIsbn, calculateTipSplit, calculateSimpleInterest, calculateTimeValue } from "@utilix-tech/sdk/units";
|
|
251
251
|
|
|
252
252
|
// File sizes
|
|
253
253
|
convertBytes(1073741824, "GB"); // 1
|
|
@@ -301,6 +301,10 @@ calculateTipSplit(84.5, 18, 2);
|
|
|
301
301
|
// Simple (non-compounding) interest: principal x rate x time
|
|
302
302
|
calculateSimpleInterest(1000, 5, 2);
|
|
303
303
|
// { interest: 100, totalPayoff: 1100, ... }
|
|
304
|
+
|
|
305
|
+
// Present / future value (time value of money), either direction
|
|
306
|
+
calculateTimeValue(1000, 5, 10, "future");
|
|
307
|
+
// { presentValue: 1000, futureValue: 1628.89, growthFactor: 1.628895, ... }
|
|
304
308
|
```
|
|
305
309
|
|
|
306
310
|
---
|
|
@@ -385,7 +389,8 @@ generateCspHeader({ "default-src": ["'self'"], "script-src": ["'self'", "cdn.exa
|
|
|
385
389
|
|
|
386
390
|
```ts
|
|
387
391
|
import { formatSql, minifySql, testRegex, formatHtml, formatGql,
|
|
388
|
-
detectDialect, splitStatements, lookupMime, parseGithubUrl
|
|
392
|
+
detectDialect, splitStatements, lookupMime, parseGithubUrl,
|
|
393
|
+
detectRedos } from "@utilix-tech/sdk/code";
|
|
389
394
|
|
|
390
395
|
// SQL
|
|
391
396
|
formatSql("SELECT id,name FROM users WHERE active=1 ORDER BY name");
|
|
@@ -417,6 +422,10 @@ lookupMime("image/jpeg"); // { kind: "mime", matches: [{ extension: "jpg", ...
|
|
|
417
422
|
// GitHub URL parsing
|
|
418
423
|
parseGithubUrl("https://github.com/facebook/react/pull/1234");
|
|
419
424
|
// { owner: "facebook", repo: "react", type: "pull", number: 1234 }
|
|
425
|
+
|
|
426
|
+
// Regex ReDoS (catastrophic-backtracking) detection
|
|
427
|
+
detectRedos("(a+)+");
|
|
428
|
+
// { risk: "high", safe: false, findings: [{ type: "nested-quantifier", ... }] }
|
|
420
429
|
```
|
|
421
430
|
|
|
422
431
|
---
|
|
@@ -552,7 +561,7 @@ readIcoInfo(new Uint8Array(icoBytes));
|
|
|
552
561
|
| `@utilix-tech/sdk/color` | Hex/RGB/HSL/HSV/CMYK convert, palette generation, contrast check |
|
|
553
562
|
| `@utilix-tech/sdk/css` | CSS gradient, box-shadow, border-radius, keyframe animation generators |
|
|
554
563
|
| `@utilix-tech/sdk/misc` | SVG optimize/sanitize, file size format, Unicode inspector |
|
|
555
|
-
| `@utilix-tech/sdk/ai_agent` | Token estimate/trim, chunk text, extract URLs/JSON/keywords, sanitize HTML, flatten/merge JSON, dedupe lines, validate schema, PII/secret/injection detect |
|
|
564
|
+
| `@utilix-tech/sdk/ai_agent` | Token estimate/trim, chunk text, extract URLs/JSON/keywords, sanitize HTML, flatten/merge JSON, dedupe lines, validate schema, PII/secret/injection detect, vector similarity |
|
|
556
565
|
| `@utilix-tech/sdk/media` | Image format & dimension reading from raw bytes (PNG, JPEG, GIF, WebP, BMP); PDF metadata reading; WAV audio info; ID3 tags; ICO favicon inspection |
|
|
557
566
|
|
|
558
567
|
---
|
|
@@ -314,6 +314,25 @@ interface SummaryResult {
|
|
|
314
314
|
sentencesTotal: number;
|
|
315
315
|
}
|
|
316
316
|
declare function summarizeForLlm(text: string, maxTokens?: number, strategy?: 'extractive' | 'first' | 'last'): SummaryResult;
|
|
317
|
+
interface VectorSimilarityResult {
|
|
318
|
+
dimensions: number;
|
|
319
|
+
dotProduct: number;
|
|
320
|
+
cosineSimilarity: number;
|
|
321
|
+
euclideanDistance: number;
|
|
322
|
+
manhattanDistance: number;
|
|
323
|
+
magnitudeA: number;
|
|
324
|
+
magnitudeB: number;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Compute cosine similarity, dot product, Euclidean distance, and Manhattan
|
|
328
|
+
* distance between two equal-length numeric vectors. Useful for debugging a
|
|
329
|
+
* RAG pipeline that already has embedding vectors from an external model.
|
|
330
|
+
* Cosine similarity is undefined when either vector is all zeros; this
|
|
331
|
+
* returns 0 in that case.
|
|
332
|
+
*/
|
|
333
|
+
declare function vectorSimilarity(a: number[], b: number[]): VectorSimilarityResult | {
|
|
334
|
+
error: string;
|
|
335
|
+
};
|
|
317
336
|
|
|
318
337
|
type ai_agent_ChunkStrategy = ChunkStrategy;
|
|
319
338
|
type ai_agent_CompressHtmlResult = CompressHtmlResult;
|
|
@@ -358,6 +377,7 @@ type ai_agent_TrimStrategy = TrimStrategy;
|
|
|
358
377
|
type ai_agent_UrlMatch = UrlMatch;
|
|
359
378
|
type ai_agent_ValidationError = ValidationError;
|
|
360
379
|
type ai_agent_ValidationResult = ValidationResult;
|
|
380
|
+
type ai_agent_VectorSimilarityResult = VectorSimilarityResult;
|
|
361
381
|
declare const ai_agent_chunkText: typeof chunkText;
|
|
362
382
|
declare const ai_agent_compressHtml: typeof compressHtml;
|
|
363
383
|
declare const ai_agent_compressJson: typeof compressJson;
|
|
@@ -386,8 +406,9 @@ declare const ai_agent_summarizeForLlm: typeof summarizeForLlm;
|
|
|
386
406
|
declare const ai_agent_trimToTokens: typeof trimToTokens;
|
|
387
407
|
declare const ai_agent_unflattenJson: typeof unflattenJson;
|
|
388
408
|
declare const ai_agent_validateJsonSchema: typeof validateJsonSchema;
|
|
409
|
+
declare const ai_agent_vectorSimilarity: typeof vectorSimilarity;
|
|
389
410
|
declare namespace ai_agent {
|
|
390
|
-
export { type ai_agent_ChunkStrategy as ChunkStrategy, type ai_agent_CompressHtmlResult as CompressHtmlResult, type ai_agent_CompressJsonResult as CompressJsonResult, type ai_agent_CompressMarkdownResult as CompressMarkdownResult, type ai_agent_CostEstimate as CostEstimate, type ai_agent_DedupeResult as DedupeResult, type ai_agent_DedupeStrategy as DedupeStrategy, type ai_agent_DiffEntry2 as DiffEntry2, type ai_agent_DiffOp2 as DiffOp2, type ai_agent_DiffResult2 as DiffResult2, type ai_agent_Entity2 as Entity2, type ai_agent_EntityType2 as EntityType2, type ai_agent_ExtractJsonResult as ExtractJsonResult, type ai_agent_ExtractKeywordsResult as ExtractKeywordsResult, type ai_agent_ExtractUrlsResult as ExtractUrlsResult, type ai_agent_InjectionDetectResult as InjectionDetectResult, type ai_agent_InjectionFinding as InjectionFinding, type ai_agent_JsonBlock as JsonBlock, type ai_agent_JsonRepairResult as JsonRepairResult, type ai_agent_Keyword as Keyword, ai_agent_MODEL_PRICING as MODEL_PRICING, type ai_agent_MergeResult as MergeResult, type ai_agent_MergeStrategy as MergeStrategy, type ai_agent_ModelPricing as ModelPricing, type ai_agent_PiiDetectResult as PiiDetectResult, type ai_agent_PiiFinding as PiiFinding, type ai_agent_PiiType as PiiType, type ai_agent_RankedChunk as RankedChunk, type ai_agent_RelevanceResult as RelevanceResult, type ai_agent_SanitizeResult as SanitizeResult, type ai_agent_SecretDetectResult as SecretDetectResult, type ai_agent_SecretFinding as SecretFinding, type ai_agent_SecretType as SecretType, type ai_agent_SummaryResult as SummaryResult, type ai_agent_TableResult2 as TableResult2, type ai_agent_TextChunk as TextChunk, type ai_agent_TokenEstimate as TokenEstimate, type ai_agent_TokenEstimateResult as TokenEstimateResult, type ai_agent_TrimResult as TrimResult, type ai_agent_TrimStrategy as TrimStrategy, type ai_agent_UrlMatch as UrlMatch, type ai_agent_ValidationError as ValidationError, type ai_agent_ValidationResult as ValidationResult, ai_agent_chunkText as chunkText, ai_agent_compressHtml as compressHtml, ai_agent_compressJson as compressJson, ai_agent_compressMarkdown as compressMarkdown, ai_agent_deduplicateLines as deduplicateLines, ai_agent_detectPii as detectPii, ai_agent_detectPromptInjection as detectPromptInjection, ai_agent_detectSecrets as detectSecrets, ai_agent_diffJson as diffJson, ai_agent_estimateCost as estimateCost, ai_agent_estimateTokens as estimateTokens, ai_agent_expandQuery as expandQuery, ai_agent_extractEntities as extractEntities, ai_agent_extractJson as extractJson, ai_agent_extractKeywords as extractKeywords, ai_agent_extractTables as extractTables, ai_agent_extractUrls as extractUrls, ai_agent_flattenJson as flattenJson, ai_agent_mergeJson as mergeJson, ai_agent_redactPii as redactPii, ai_agent_repairJson as repairJson, ai_agent_rerankChunks as rerankChunks, ai_agent_sanitizeHtml as sanitizeHtml, ai_agent_scoreRelevance as scoreRelevance, ai_agent_summarizeForLlm as summarizeForLlm, ai_agent_trimToTokens as trimToTokens, ai_agent_unflattenJson as unflattenJson, ai_agent_validateJsonSchema as validateJsonSchema };
|
|
411
|
+
export { type ai_agent_ChunkStrategy as ChunkStrategy, type ai_agent_CompressHtmlResult as CompressHtmlResult, type ai_agent_CompressJsonResult as CompressJsonResult, type ai_agent_CompressMarkdownResult as CompressMarkdownResult, type ai_agent_CostEstimate as CostEstimate, type ai_agent_DedupeResult as DedupeResult, type ai_agent_DedupeStrategy as DedupeStrategy, type ai_agent_DiffEntry2 as DiffEntry2, type ai_agent_DiffOp2 as DiffOp2, type ai_agent_DiffResult2 as DiffResult2, type ai_agent_Entity2 as Entity2, type ai_agent_EntityType2 as EntityType2, type ai_agent_ExtractJsonResult as ExtractJsonResult, type ai_agent_ExtractKeywordsResult as ExtractKeywordsResult, type ai_agent_ExtractUrlsResult as ExtractUrlsResult, type ai_agent_InjectionDetectResult as InjectionDetectResult, type ai_agent_InjectionFinding as InjectionFinding, type ai_agent_JsonBlock as JsonBlock, type ai_agent_JsonRepairResult as JsonRepairResult, type ai_agent_Keyword as Keyword, ai_agent_MODEL_PRICING as MODEL_PRICING, type ai_agent_MergeResult as MergeResult, type ai_agent_MergeStrategy as MergeStrategy, type ai_agent_ModelPricing as ModelPricing, type ai_agent_PiiDetectResult as PiiDetectResult, type ai_agent_PiiFinding as PiiFinding, type ai_agent_PiiType as PiiType, type ai_agent_RankedChunk as RankedChunk, type ai_agent_RelevanceResult as RelevanceResult, type ai_agent_SanitizeResult as SanitizeResult, type ai_agent_SecretDetectResult as SecretDetectResult, type ai_agent_SecretFinding as SecretFinding, type ai_agent_SecretType as SecretType, type ai_agent_SummaryResult as SummaryResult, type ai_agent_TableResult2 as TableResult2, type ai_agent_TextChunk as TextChunk, type ai_agent_TokenEstimate as TokenEstimate, type ai_agent_TokenEstimateResult as TokenEstimateResult, type ai_agent_TrimResult as TrimResult, type ai_agent_TrimStrategy as TrimStrategy, type ai_agent_UrlMatch as UrlMatch, type ai_agent_ValidationError as ValidationError, type ai_agent_ValidationResult as ValidationResult, type ai_agent_VectorSimilarityResult as VectorSimilarityResult, ai_agent_chunkText as chunkText, ai_agent_compressHtml as compressHtml, ai_agent_compressJson as compressJson, ai_agent_compressMarkdown as compressMarkdown, ai_agent_deduplicateLines as deduplicateLines, ai_agent_detectPii as detectPii, ai_agent_detectPromptInjection as detectPromptInjection, ai_agent_detectSecrets as detectSecrets, ai_agent_diffJson as diffJson, ai_agent_estimateCost as estimateCost, ai_agent_estimateTokens as estimateTokens, ai_agent_expandQuery as expandQuery, ai_agent_extractEntities as extractEntities, ai_agent_extractJson as extractJson, ai_agent_extractKeywords as extractKeywords, ai_agent_extractTables as extractTables, ai_agent_extractUrls as extractUrls, ai_agent_flattenJson as flattenJson, ai_agent_mergeJson as mergeJson, ai_agent_redactPii as redactPii, ai_agent_repairJson as repairJson, ai_agent_rerankChunks as rerankChunks, ai_agent_sanitizeHtml as sanitizeHtml, ai_agent_scoreRelevance as scoreRelevance, ai_agent_summarizeForLlm as summarizeForLlm, ai_agent_trimToTokens as trimToTokens, ai_agent_unflattenJson as unflattenJson, ai_agent_validateJsonSchema as validateJsonSchema, ai_agent_vectorSimilarity as vectorSimilarity };
|
|
391
412
|
}
|
|
392
413
|
|
|
393
|
-
export {
|
|
414
|
+
export { diffJson as $, type TokenEstimate as A, type TokenEstimateResult as B, type ChunkStrategy as C, type DedupeResult as D, type Entity2 as E, type TrimResult as F, type TrimStrategy as G, type ValidationResult as H, type InjectionDetectResult as I, type JsonBlock as J, type Keyword as K, type VectorSimilarityResult as L, MODEL_PRICING as M, chunkText as N, compressHtml as O, type PiiDetectResult as P, compressJson as Q, type RankedChunk as R, type SanitizeResult as S, type TableResult2 as T, type UrlMatch as U, type ValidationError as V, compressMarkdown as W, deduplicateLines as X, detectPii as Y, detectPromptInjection as Z, detectSecrets as _, ai_agent as a, estimateCost as a0, estimateTokens as a1, expandQuery as a2, extractEntities as a3, extractJson as a4, extractKeywords as a5, extractTables as a6, extractUrls as a7, flattenJson as a8, mergeJson as a9, redactPii as aa, repairJson as ab, rerankChunks as ac, sanitizeHtml as ad, scoreRelevance as ae, summarizeForLlm as af, trimToTokens as ag, unflattenJson as ah, validateJsonSchema as ai, vectorSimilarity as aj, type CompressHtmlResult as b, type CompressJsonResult as c, type CompressMarkdownResult as d, type CostEstimate as e, type DedupeStrategy as f, type DiffEntry2 as g, type DiffOp2 as h, type DiffResult2 as i, type EntityType2 as j, type ExtractJsonResult as k, type ExtractKeywordsResult as l, type ExtractUrlsResult as m, type InjectionFinding as n, type JsonRepairResult as o, type MergeResult as p, type MergeStrategy as q, type ModelPricing as r, type PiiFinding as s, type PiiType as t, type RelevanceResult as u, type SecretDetectResult as v, type SecretFinding as w, type SecretType as x, type SummaryResult as y, type TextChunk as z };
|
|
@@ -314,6 +314,25 @@ interface SummaryResult {
|
|
|
314
314
|
sentencesTotal: number;
|
|
315
315
|
}
|
|
316
316
|
declare function summarizeForLlm(text: string, maxTokens?: number, strategy?: 'extractive' | 'first' | 'last'): SummaryResult;
|
|
317
|
+
interface VectorSimilarityResult {
|
|
318
|
+
dimensions: number;
|
|
319
|
+
dotProduct: number;
|
|
320
|
+
cosineSimilarity: number;
|
|
321
|
+
euclideanDistance: number;
|
|
322
|
+
manhattanDistance: number;
|
|
323
|
+
magnitudeA: number;
|
|
324
|
+
magnitudeB: number;
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Compute cosine similarity, dot product, Euclidean distance, and Manhattan
|
|
328
|
+
* distance between two equal-length numeric vectors. Useful for debugging a
|
|
329
|
+
* RAG pipeline that already has embedding vectors from an external model.
|
|
330
|
+
* Cosine similarity is undefined when either vector is all zeros; this
|
|
331
|
+
* returns 0 in that case.
|
|
332
|
+
*/
|
|
333
|
+
declare function vectorSimilarity(a: number[], b: number[]): VectorSimilarityResult | {
|
|
334
|
+
error: string;
|
|
335
|
+
};
|
|
317
336
|
|
|
318
337
|
type ai_agent_ChunkStrategy = ChunkStrategy;
|
|
319
338
|
type ai_agent_CompressHtmlResult = CompressHtmlResult;
|
|
@@ -358,6 +377,7 @@ type ai_agent_TrimStrategy = TrimStrategy;
|
|
|
358
377
|
type ai_agent_UrlMatch = UrlMatch;
|
|
359
378
|
type ai_agent_ValidationError = ValidationError;
|
|
360
379
|
type ai_agent_ValidationResult = ValidationResult;
|
|
380
|
+
type ai_agent_VectorSimilarityResult = VectorSimilarityResult;
|
|
361
381
|
declare const ai_agent_chunkText: typeof chunkText;
|
|
362
382
|
declare const ai_agent_compressHtml: typeof compressHtml;
|
|
363
383
|
declare const ai_agent_compressJson: typeof compressJson;
|
|
@@ -386,8 +406,9 @@ declare const ai_agent_summarizeForLlm: typeof summarizeForLlm;
|
|
|
386
406
|
declare const ai_agent_trimToTokens: typeof trimToTokens;
|
|
387
407
|
declare const ai_agent_unflattenJson: typeof unflattenJson;
|
|
388
408
|
declare const ai_agent_validateJsonSchema: typeof validateJsonSchema;
|
|
409
|
+
declare const ai_agent_vectorSimilarity: typeof vectorSimilarity;
|
|
389
410
|
declare namespace ai_agent {
|
|
390
|
-
export { type ai_agent_ChunkStrategy as ChunkStrategy, type ai_agent_CompressHtmlResult as CompressHtmlResult, type ai_agent_CompressJsonResult as CompressJsonResult, type ai_agent_CompressMarkdownResult as CompressMarkdownResult, type ai_agent_CostEstimate as CostEstimate, type ai_agent_DedupeResult as DedupeResult, type ai_agent_DedupeStrategy as DedupeStrategy, type ai_agent_DiffEntry2 as DiffEntry2, type ai_agent_DiffOp2 as DiffOp2, type ai_agent_DiffResult2 as DiffResult2, type ai_agent_Entity2 as Entity2, type ai_agent_EntityType2 as EntityType2, type ai_agent_ExtractJsonResult as ExtractJsonResult, type ai_agent_ExtractKeywordsResult as ExtractKeywordsResult, type ai_agent_ExtractUrlsResult as ExtractUrlsResult, type ai_agent_InjectionDetectResult as InjectionDetectResult, type ai_agent_InjectionFinding as InjectionFinding, type ai_agent_JsonBlock as JsonBlock, type ai_agent_JsonRepairResult as JsonRepairResult, type ai_agent_Keyword as Keyword, ai_agent_MODEL_PRICING as MODEL_PRICING, type ai_agent_MergeResult as MergeResult, type ai_agent_MergeStrategy as MergeStrategy, type ai_agent_ModelPricing as ModelPricing, type ai_agent_PiiDetectResult as PiiDetectResult, type ai_agent_PiiFinding as PiiFinding, type ai_agent_PiiType as PiiType, type ai_agent_RankedChunk as RankedChunk, type ai_agent_RelevanceResult as RelevanceResult, type ai_agent_SanitizeResult as SanitizeResult, type ai_agent_SecretDetectResult as SecretDetectResult, type ai_agent_SecretFinding as SecretFinding, type ai_agent_SecretType as SecretType, type ai_agent_SummaryResult as SummaryResult, type ai_agent_TableResult2 as TableResult2, type ai_agent_TextChunk as TextChunk, type ai_agent_TokenEstimate as TokenEstimate, type ai_agent_TokenEstimateResult as TokenEstimateResult, type ai_agent_TrimResult as TrimResult, type ai_agent_TrimStrategy as TrimStrategy, type ai_agent_UrlMatch as UrlMatch, type ai_agent_ValidationError as ValidationError, type ai_agent_ValidationResult as ValidationResult, ai_agent_chunkText as chunkText, ai_agent_compressHtml as compressHtml, ai_agent_compressJson as compressJson, ai_agent_compressMarkdown as compressMarkdown, ai_agent_deduplicateLines as deduplicateLines, ai_agent_detectPii as detectPii, ai_agent_detectPromptInjection as detectPromptInjection, ai_agent_detectSecrets as detectSecrets, ai_agent_diffJson as diffJson, ai_agent_estimateCost as estimateCost, ai_agent_estimateTokens as estimateTokens, ai_agent_expandQuery as expandQuery, ai_agent_extractEntities as extractEntities, ai_agent_extractJson as extractJson, ai_agent_extractKeywords as extractKeywords, ai_agent_extractTables as extractTables, ai_agent_extractUrls as extractUrls, ai_agent_flattenJson as flattenJson, ai_agent_mergeJson as mergeJson, ai_agent_redactPii as redactPii, ai_agent_repairJson as repairJson, ai_agent_rerankChunks as rerankChunks, ai_agent_sanitizeHtml as sanitizeHtml, ai_agent_scoreRelevance as scoreRelevance, ai_agent_summarizeForLlm as summarizeForLlm, ai_agent_trimToTokens as trimToTokens, ai_agent_unflattenJson as unflattenJson, ai_agent_validateJsonSchema as validateJsonSchema };
|
|
411
|
+
export { type ai_agent_ChunkStrategy as ChunkStrategy, type ai_agent_CompressHtmlResult as CompressHtmlResult, type ai_agent_CompressJsonResult as CompressJsonResult, type ai_agent_CompressMarkdownResult as CompressMarkdownResult, type ai_agent_CostEstimate as CostEstimate, type ai_agent_DedupeResult as DedupeResult, type ai_agent_DedupeStrategy as DedupeStrategy, type ai_agent_DiffEntry2 as DiffEntry2, type ai_agent_DiffOp2 as DiffOp2, type ai_agent_DiffResult2 as DiffResult2, type ai_agent_Entity2 as Entity2, type ai_agent_EntityType2 as EntityType2, type ai_agent_ExtractJsonResult as ExtractJsonResult, type ai_agent_ExtractKeywordsResult as ExtractKeywordsResult, type ai_agent_ExtractUrlsResult as ExtractUrlsResult, type ai_agent_InjectionDetectResult as InjectionDetectResult, type ai_agent_InjectionFinding as InjectionFinding, type ai_agent_JsonBlock as JsonBlock, type ai_agent_JsonRepairResult as JsonRepairResult, type ai_agent_Keyword as Keyword, ai_agent_MODEL_PRICING as MODEL_PRICING, type ai_agent_MergeResult as MergeResult, type ai_agent_MergeStrategy as MergeStrategy, type ai_agent_ModelPricing as ModelPricing, type ai_agent_PiiDetectResult as PiiDetectResult, type ai_agent_PiiFinding as PiiFinding, type ai_agent_PiiType as PiiType, type ai_agent_RankedChunk as RankedChunk, type ai_agent_RelevanceResult as RelevanceResult, type ai_agent_SanitizeResult as SanitizeResult, type ai_agent_SecretDetectResult as SecretDetectResult, type ai_agent_SecretFinding as SecretFinding, type ai_agent_SecretType as SecretType, type ai_agent_SummaryResult as SummaryResult, type ai_agent_TableResult2 as TableResult2, type ai_agent_TextChunk as TextChunk, type ai_agent_TokenEstimate as TokenEstimate, type ai_agent_TokenEstimateResult as TokenEstimateResult, type ai_agent_TrimResult as TrimResult, type ai_agent_TrimStrategy as TrimStrategy, type ai_agent_UrlMatch as UrlMatch, type ai_agent_ValidationError as ValidationError, type ai_agent_ValidationResult as ValidationResult, type ai_agent_VectorSimilarityResult as VectorSimilarityResult, ai_agent_chunkText as chunkText, ai_agent_compressHtml as compressHtml, ai_agent_compressJson as compressJson, ai_agent_compressMarkdown as compressMarkdown, ai_agent_deduplicateLines as deduplicateLines, ai_agent_detectPii as detectPii, ai_agent_detectPromptInjection as detectPromptInjection, ai_agent_detectSecrets as detectSecrets, ai_agent_diffJson as diffJson, ai_agent_estimateCost as estimateCost, ai_agent_estimateTokens as estimateTokens, ai_agent_expandQuery as expandQuery, ai_agent_extractEntities as extractEntities, ai_agent_extractJson as extractJson, ai_agent_extractKeywords as extractKeywords, ai_agent_extractTables as extractTables, ai_agent_extractUrls as extractUrls, ai_agent_flattenJson as flattenJson, ai_agent_mergeJson as mergeJson, ai_agent_redactPii as redactPii, ai_agent_repairJson as repairJson, ai_agent_rerankChunks as rerankChunks, ai_agent_sanitizeHtml as sanitizeHtml, ai_agent_scoreRelevance as scoreRelevance, ai_agent_summarizeForLlm as summarizeForLlm, ai_agent_trimToTokens as trimToTokens, ai_agent_unflattenJson as unflattenJson, ai_agent_validateJsonSchema as validateJsonSchema, ai_agent_vectorSimilarity as vectorSimilarity };
|
|
391
412
|
}
|
|
392
413
|
|
|
393
|
-
export {
|
|
414
|
+
export { diffJson as $, type TokenEstimate as A, type TokenEstimateResult as B, type ChunkStrategy as C, type DedupeResult as D, type Entity2 as E, type TrimResult as F, type TrimStrategy as G, type ValidationResult as H, type InjectionDetectResult as I, type JsonBlock as J, type Keyword as K, type VectorSimilarityResult as L, MODEL_PRICING as M, chunkText as N, compressHtml as O, type PiiDetectResult as P, compressJson as Q, type RankedChunk as R, type SanitizeResult as S, type TableResult2 as T, type UrlMatch as U, type ValidationError as V, compressMarkdown as W, deduplicateLines as X, detectPii as Y, detectPromptInjection as Z, detectSecrets as _, ai_agent as a, estimateCost as a0, estimateTokens as a1, expandQuery as a2, extractEntities as a3, extractJson as a4, extractKeywords as a5, extractTables as a6, extractUrls as a7, flattenJson as a8, mergeJson as a9, redactPii as aa, repairJson as ab, rerankChunks as ac, sanitizeHtml as ad, scoreRelevance as ae, summarizeForLlm as af, trimToTokens as ag, unflattenJson as ah, validateJsonSchema as ai, vectorSimilarity as aj, type CompressHtmlResult as b, type CompressJsonResult as c, type CompressMarkdownResult as d, type CostEstimate as e, type DedupeStrategy as f, type DiffEntry2 as g, type DiffOp2 as h, type DiffResult2 as i, type EntityType2 as j, type ExtractJsonResult as k, type ExtractKeywordsResult as l, type ExtractUrlsResult as m, type InjectionFinding as n, type JsonRepairResult as o, type MergeResult as p, type MergeStrategy as q, type ModelPricing as r, type PiiFinding as s, type PiiType as t, type RelevanceResult as u, type SecretDetectResult as v, type SecretFinding as w, type SecretType as x, type SummaryResult as y, type TextChunk as z };
|
|
@@ -31,7 +31,8 @@ __export(ai_agent_exports, {
|
|
|
31
31
|
summarizeForLlm: () => summarizeForLlm,
|
|
32
32
|
trimToTokens: () => trimToTokens,
|
|
33
33
|
unflattenJson: () => unflattenJson,
|
|
34
|
-
validateJsonSchema: () => validateJsonSchema
|
|
34
|
+
validateJsonSchema: () => validateJsonSchema,
|
|
35
|
+
vectorSimilarity: () => vectorSimilarity
|
|
35
36
|
});
|
|
36
37
|
var MODEL_PRICING = [
|
|
37
38
|
{ model: "gpt-4o", label: "GPT-4o", inputPer1M: 5, outputPer1M: 15 },
|
|
@@ -949,5 +950,34 @@ function summarizeForLlm(text, maxTokens = 200, strategy = "extractive") {
|
|
|
949
950
|
const st = tok(summary);
|
|
950
951
|
return { summary, originalTokens: ot, summaryTokens: st, compressionRatio: Math.round(st / Math.max(1, ot) * 100) / 100, sentencesKept: picked.length, sentencesTotal: sents.length };
|
|
951
952
|
}
|
|
953
|
+
function vectorSimilarity(a, b) {
|
|
954
|
+
if (!Array.isArray(a) || !Array.isArray(b)) return { error: "Both inputs must be arrays of numbers" };
|
|
955
|
+
if (a.length === 0 || b.length === 0) return { error: "Vectors must not be empty" };
|
|
956
|
+
if (a.length !== b.length) return { error: `Vectors must have the same length (got ${a.length} and ${b.length})` };
|
|
957
|
+
if (!a.every((n) => typeof n === "number" && Number.isFinite(n)) || !b.every((n) => typeof n === "number" && Number.isFinite(n))) {
|
|
958
|
+
return { error: "Vectors must contain only finite numbers" };
|
|
959
|
+
}
|
|
960
|
+
const round6 = (n) => Math.round(n * 1e6) / 1e6;
|
|
961
|
+
let dot = 0, sa = 0, sb = 0, sqDist = 0, absDist = 0;
|
|
962
|
+
for (let i = 0; i < a.length; i++) {
|
|
963
|
+
dot += a[i] * b[i];
|
|
964
|
+
sa += a[i] * a[i];
|
|
965
|
+
sb += b[i] * b[i];
|
|
966
|
+
const d = a[i] - b[i];
|
|
967
|
+
sqDist += d * d;
|
|
968
|
+
absDist += Math.abs(d);
|
|
969
|
+
}
|
|
970
|
+
const magA = Math.sqrt(sa), magB = Math.sqrt(sb);
|
|
971
|
+
const cosine = magA === 0 || magB === 0 ? 0 : dot / (magA * magB);
|
|
972
|
+
return {
|
|
973
|
+
dimensions: a.length,
|
|
974
|
+
dotProduct: round6(dot),
|
|
975
|
+
cosineSimilarity: round6(cosine),
|
|
976
|
+
euclideanDistance: round6(Math.sqrt(sqDist)),
|
|
977
|
+
manhattanDistance: round6(absDist),
|
|
978
|
+
magnitudeA: round6(magA),
|
|
979
|
+
magnitudeB: round6(magB)
|
|
980
|
+
};
|
|
981
|
+
}
|
|
952
982
|
|
|
953
|
-
export { MODEL_PRICING, ai_agent_exports, chunkText, compressHtml, compressJson, compressMarkdown, deduplicateLines, detectPii, detectPromptInjection, detectSecrets, diffJson, estimateCost, estimateTokens, expandQuery, extractEntities, extractJson, extractKeywords, extractTables, extractUrls, flattenJson, mergeJson, redactPii, repairJson, rerankChunks, sanitizeHtml, scoreRelevance, summarizeForLlm, trimToTokens, unflattenJson, validateJsonSchema };
|
|
983
|
+
export { MODEL_PRICING, ai_agent_exports, chunkText, compressHtml, compressJson, compressMarkdown, deduplicateLines, detectPii, detectPromptInjection, detectSecrets, diffJson, estimateCost, estimateTokens, expandQuery, extractEntities, extractJson, extractKeywords, extractTables, extractUrls, flattenJson, mergeJson, redactPii, repairJson, rerankChunks, sanitizeHtml, scoreRelevance, summarizeForLlm, trimToTokens, unflattenJson, validateJsonSchema, vectorSimilarity };
|
|
@@ -18,6 +18,7 @@ __export(code_exports, {
|
|
|
18
18
|
countRules: () => countRules,
|
|
19
19
|
detectDialect: () => detectDialect,
|
|
20
20
|
detectOperationType: () => detectOperationType,
|
|
21
|
+
detectRedos: () => detectRedos,
|
|
21
22
|
envToExport: () => envToExport,
|
|
22
23
|
envToJson: () => envToJson,
|
|
23
24
|
formatCss: () => formatCss,
|
|
@@ -2475,5 +2476,269 @@ function parseGithubUrl(input) {
|
|
|
2475
2476
|
}
|
|
2476
2477
|
return { error: `Unsupported GitHub URL path: /${rest.join("/")}` };
|
|
2477
2478
|
}
|
|
2479
|
+
var _REDOS_UNBOUNDED = /* @__PURE__ */ new Set(["*", "+"]);
|
|
2480
|
+
function _redosParseQuant(src, i) {
|
|
2481
|
+
const ch = src[i];
|
|
2482
|
+
if (ch === "*" || ch === "+" || ch === "?") {
|
|
2483
|
+
let end = i + 1;
|
|
2484
|
+
if (src[end] === "?" || src[end] === "+") end++;
|
|
2485
|
+
return { unbounded: _REDOS_UNBOUNDED.has(ch), raw: src.slice(i, end), end };
|
|
2486
|
+
}
|
|
2487
|
+
if (ch === "{") {
|
|
2488
|
+
const close = src.indexOf("}", i);
|
|
2489
|
+
if (close === -1) return null;
|
|
2490
|
+
const inner = src.slice(i + 1, close);
|
|
2491
|
+
if (!/^\d+(,\d*)?$/.test(inner)) return null;
|
|
2492
|
+
let end = close + 1;
|
|
2493
|
+
if (src[end] === "?" || src[end] === "+") end++;
|
|
2494
|
+
const unbounded = /^\d+,$/.test(inner);
|
|
2495
|
+
return { unbounded, raw: src.slice(i, end), end };
|
|
2496
|
+
}
|
|
2497
|
+
return null;
|
|
2498
|
+
}
|
|
2499
|
+
function _redosParseAlternation(src, start, endExclusive) {
|
|
2500
|
+
const alternatives = [];
|
|
2501
|
+
let current = [];
|
|
2502
|
+
let i = start;
|
|
2503
|
+
while (i < endExclusive) {
|
|
2504
|
+
const ch = src[i];
|
|
2505
|
+
if (ch === "|") {
|
|
2506
|
+
alternatives.push(current);
|
|
2507
|
+
current = [];
|
|
2508
|
+
i++;
|
|
2509
|
+
continue;
|
|
2510
|
+
}
|
|
2511
|
+
let node;
|
|
2512
|
+
if (ch === "\\") {
|
|
2513
|
+
const atomEnd = i + 2 <= endExclusive ? i + 2 : i + 1;
|
|
2514
|
+
node = { kind: "char", start: i, end: atomEnd, quant: null, quantEnd: atomEnd, raw: src.slice(i, atomEnd) };
|
|
2515
|
+
i = atomEnd;
|
|
2516
|
+
} else if (ch === "[") {
|
|
2517
|
+
let j = i + 1;
|
|
2518
|
+
if (src[j] === "^") j++;
|
|
2519
|
+
if (src[j] === "]") j++;
|
|
2520
|
+
while (j < endExclusive && src[j] !== "]") {
|
|
2521
|
+
j += src[j] === "\\" ? 2 : 1;
|
|
2522
|
+
}
|
|
2523
|
+
const classEnd = j < endExclusive ? j + 1 : endExclusive;
|
|
2524
|
+
node = { kind: "class", start: i, end: classEnd, quant: null, quantEnd: classEnd, raw: src.slice(i, classEnd) };
|
|
2525
|
+
i = classEnd;
|
|
2526
|
+
} else if (ch === "(") {
|
|
2527
|
+
let depth = 1;
|
|
2528
|
+
let j = i + 1;
|
|
2529
|
+
while (j < endExclusive && depth > 0) {
|
|
2530
|
+
const cj = src[j];
|
|
2531
|
+
if (cj === "\\") {
|
|
2532
|
+
j += 2;
|
|
2533
|
+
continue;
|
|
2534
|
+
}
|
|
2535
|
+
if (cj === "[") {
|
|
2536
|
+
j++;
|
|
2537
|
+
if (src[j] === "^") j++;
|
|
2538
|
+
if (src[j] === "]") j++;
|
|
2539
|
+
while (j < endExclusive && src[j] !== "]") {
|
|
2540
|
+
j += src[j] === "\\" ? 2 : 1;
|
|
2541
|
+
}
|
|
2542
|
+
j++;
|
|
2543
|
+
continue;
|
|
2544
|
+
}
|
|
2545
|
+
if (cj === "(") depth++;
|
|
2546
|
+
else if (cj === ")") depth--;
|
|
2547
|
+
j++;
|
|
2548
|
+
}
|
|
2549
|
+
const closeIdx = depth === 0 ? j - 1 : endExclusive;
|
|
2550
|
+
let contentStart = i + 1;
|
|
2551
|
+
let lookaround = false;
|
|
2552
|
+
if (src[i + 1] === "?") {
|
|
2553
|
+
const after = src[i + 2];
|
|
2554
|
+
if (after === ":") contentStart = i + 3;
|
|
2555
|
+
else if (after === "=" || after === "!") {
|
|
2556
|
+
contentStart = i + 3;
|
|
2557
|
+
lookaround = true;
|
|
2558
|
+
} else if (after === "<") {
|
|
2559
|
+
const a3 = src[i + 3];
|
|
2560
|
+
if (a3 === "=" || a3 === "!") {
|
|
2561
|
+
contentStart = i + 4;
|
|
2562
|
+
lookaround = true;
|
|
2563
|
+
} else {
|
|
2564
|
+
const gt = src.indexOf(">", i + 2);
|
|
2565
|
+
contentStart = gt !== -1 && gt < closeIdx ? gt + 1 : i + 3;
|
|
2566
|
+
}
|
|
2567
|
+
}
|
|
2568
|
+
}
|
|
2569
|
+
node = {
|
|
2570
|
+
kind: "group",
|
|
2571
|
+
start: i,
|
|
2572
|
+
end: closeIdx + 1,
|
|
2573
|
+
quant: null,
|
|
2574
|
+
quantEnd: closeIdx + 1,
|
|
2575
|
+
raw: src.slice(i, closeIdx + 1),
|
|
2576
|
+
alternatives: _redosParseAlternation(src, contentStart, closeIdx),
|
|
2577
|
+
lookaround
|
|
2578
|
+
};
|
|
2579
|
+
i = closeIdx + 1;
|
|
2580
|
+
} else if (ch === ".") {
|
|
2581
|
+
node = { kind: "dot", start: i, end: i + 1, quant: null, quantEnd: i + 1, raw: "." };
|
|
2582
|
+
i++;
|
|
2583
|
+
} else if (ch === "^" || ch === "$") {
|
|
2584
|
+
node = { kind: "anchor", start: i, end: i + 1, quant: null, quantEnd: i + 1, raw: ch };
|
|
2585
|
+
i++;
|
|
2586
|
+
} else {
|
|
2587
|
+
node = { kind: "char", start: i, end: i + 1, quant: null, quantEnd: i + 1, raw: ch };
|
|
2588
|
+
i++;
|
|
2589
|
+
}
|
|
2590
|
+
if (node.kind !== "anchor") {
|
|
2591
|
+
const q = _redosParseQuant(src, i);
|
|
2592
|
+
if (q) {
|
|
2593
|
+
node.quant = q;
|
|
2594
|
+
node.quantEnd = q.end;
|
|
2595
|
+
i = q.end;
|
|
2596
|
+
}
|
|
2597
|
+
}
|
|
2598
|
+
current.push(node);
|
|
2599
|
+
}
|
|
2600
|
+
alternatives.push(current);
|
|
2601
|
+
return alternatives;
|
|
2602
|
+
}
|
|
2603
|
+
var _REDOS_ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_ .,-@/:;#%&=";
|
|
2604
|
+
function _redosFirstMatcher(node) {
|
|
2605
|
+
if (node.kind === "dot") return (c) => c !== "\n";
|
|
2606
|
+
if (node.kind === "char") {
|
|
2607
|
+
if (node.raw.startsWith("\\")) {
|
|
2608
|
+
const body = node.raw.slice(1);
|
|
2609
|
+
if (/^[dDwWsS]$/.test(body)) {
|
|
2610
|
+
try {
|
|
2611
|
+
const re = new RegExp("\\" + body);
|
|
2612
|
+
return (c) => re.test(c);
|
|
2613
|
+
} catch {
|
|
2614
|
+
return null;
|
|
2615
|
+
}
|
|
2616
|
+
}
|
|
2617
|
+
const literal = { n: "\n", t: " ", r: "\r", f: "\f", v: "\v" }[body] ?? body;
|
|
2618
|
+
return (c) => c === literal;
|
|
2619
|
+
}
|
|
2620
|
+
const lit = node.raw;
|
|
2621
|
+
return (c) => c === lit;
|
|
2622
|
+
}
|
|
2623
|
+
if (node.kind === "class") {
|
|
2624
|
+
try {
|
|
2625
|
+
const re = new RegExp(node.raw);
|
|
2626
|
+
return (c) => re.test(c);
|
|
2627
|
+
} catch {
|
|
2628
|
+
return null;
|
|
2629
|
+
}
|
|
2630
|
+
}
|
|
2631
|
+
if (node.kind === "group") {
|
|
2632
|
+
const first = node.alternatives?.[0]?.[0];
|
|
2633
|
+
return first ? _redosFirstMatcher(first) : null;
|
|
2634
|
+
}
|
|
2635
|
+
return null;
|
|
2636
|
+
}
|
|
2637
|
+
function _redosOverlaps(a, b) {
|
|
2638
|
+
const fa = _redosFirstMatcher(a);
|
|
2639
|
+
const fb = _redosFirstMatcher(b);
|
|
2640
|
+
if (!fa || !fb) return false;
|
|
2641
|
+
for (const c of _REDOS_ALPHABET) {
|
|
2642
|
+
if (fa(c) && fb(c)) return true;
|
|
2643
|
+
}
|
|
2644
|
+
return false;
|
|
2645
|
+
}
|
|
2646
|
+
function _redosAnalyzeGroup(node, findings) {
|
|
2647
|
+
const alts = node.alternatives ?? [];
|
|
2648
|
+
const outerUnbounded = node.quant?.unbounded === true && !node.lookaround;
|
|
2649
|
+
if (outerUnbounded) {
|
|
2650
|
+
for (const alt of alts) {
|
|
2651
|
+
const meaningful = alt.filter((n) => n.kind !== "anchor");
|
|
2652
|
+
if (meaningful.length === 1 && meaningful[0].quant?.unbounded) {
|
|
2653
|
+
findings.push({
|
|
2654
|
+
type: "nested-quantifier",
|
|
2655
|
+
severity: "high",
|
|
2656
|
+
message: "Nested unbounded quantifiers: a repeated group whose body is itself unbounded-repeated can match the same input in exponentially many ways, causing catastrophic backtracking.",
|
|
2657
|
+
snippet: node.raw + (node.quant?.raw ?? ""),
|
|
2658
|
+
index: node.start
|
|
2659
|
+
});
|
|
2660
|
+
break;
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
if (alts.length > 1) {
|
|
2664
|
+
const firsts = alts.map((alt) => alt.find((n) => n.kind !== "anchor")).filter((n) => !!n);
|
|
2665
|
+
let flagged = false;
|
|
2666
|
+
for (let x = 0; x < firsts.length && !flagged; x++) {
|
|
2667
|
+
for (let y = x + 1; y < firsts.length; y++) {
|
|
2668
|
+
if (_redosOverlaps(firsts[x], firsts[y])) {
|
|
2669
|
+
findings.push({
|
|
2670
|
+
type: "overlapping-alternation",
|
|
2671
|
+
severity: "medium",
|
|
2672
|
+
message: "Overlapping alternation under a repetition: two branches can match the same starting input, so the engine has multiple ways to split each repeat and may backtrack heavily.",
|
|
2673
|
+
snippet: node.raw + (node.quant?.raw ?? ""),
|
|
2674
|
+
index: node.start
|
|
2675
|
+
});
|
|
2676
|
+
flagged = true;
|
|
2677
|
+
break;
|
|
2678
|
+
}
|
|
2679
|
+
}
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2682
|
+
}
|
|
2683
|
+
for (const alt of alts) {
|
|
2684
|
+
_redosAnalyzeSequence(alt, findings);
|
|
2685
|
+
}
|
|
2686
|
+
}
|
|
2687
|
+
function _redosAnalyzeSequence(seq, findings) {
|
|
2688
|
+
for (let k = 0; k + 1 < seq.length; k++) {
|
|
2689
|
+
const a = seq[k];
|
|
2690
|
+
const b = seq[k + 1];
|
|
2691
|
+
if (a.quant?.unbounded && b.quant?.unbounded && _redosOverlaps(a, b)) {
|
|
2692
|
+
findings.push({
|
|
2693
|
+
type: "adjacent-quantifier",
|
|
2694
|
+
severity: "medium",
|
|
2695
|
+
message: "Adjacent unbounded quantifiers over overlapping characters: the engine can distribute the same input between them in many ways, causing quadratic backtracking.",
|
|
2696
|
+
snippet: seq[k].raw + (a.quant?.raw ?? "") + seq[k + 1].raw + (b.quant?.raw ?? ""),
|
|
2697
|
+
index: a.start
|
|
2698
|
+
});
|
|
2699
|
+
}
|
|
2700
|
+
}
|
|
2701
|
+
for (const node of seq) {
|
|
2702
|
+
if (node.kind === "group") _redosAnalyzeGroup(node, findings);
|
|
2703
|
+
}
|
|
2704
|
+
}
|
|
2705
|
+
function detectRedos(pattern) {
|
|
2706
|
+
if (typeof pattern !== "string" || pattern === "") {
|
|
2707
|
+
return { error: "Empty pattern" };
|
|
2708
|
+
}
|
|
2709
|
+
if (pattern.length > 5e3) {
|
|
2710
|
+
return { error: "Pattern too long (max 5,000 chars)" };
|
|
2711
|
+
}
|
|
2712
|
+
let valid = true;
|
|
2713
|
+
let compileError;
|
|
2714
|
+
try {
|
|
2715
|
+
new RegExp(pattern);
|
|
2716
|
+
} catch (e) {
|
|
2717
|
+
valid = false;
|
|
2718
|
+
compileError = e instanceof Error ? e.message : String(e);
|
|
2719
|
+
}
|
|
2720
|
+
const findings = [];
|
|
2721
|
+
const alternatives = _redosParseAlternation(pattern, 0, pattern.length);
|
|
2722
|
+
for (const alt of alternatives) {
|
|
2723
|
+
_redosAnalyzeSequence(alt, findings);
|
|
2724
|
+
}
|
|
2725
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2726
|
+
const unique = findings.filter((f) => {
|
|
2727
|
+
const key = `${f.type}:${f.index}`;
|
|
2728
|
+
if (seen.has(key)) return false;
|
|
2729
|
+
seen.add(key);
|
|
2730
|
+
return true;
|
|
2731
|
+
});
|
|
2732
|
+
unique.sort((a, b) => a.index - b.index);
|
|
2733
|
+
const risk = unique.some((f) => f.severity === "high") ? "high" : unique.length > 0 ? "medium" : "none";
|
|
2734
|
+
return {
|
|
2735
|
+
pattern,
|
|
2736
|
+
valid,
|
|
2737
|
+
...compileError ? { compileError } : {},
|
|
2738
|
+
risk,
|
|
2739
|
+
safe: unique.length === 0,
|
|
2740
|
+
findings: unique
|
|
2741
|
+
};
|
|
2742
|
+
}
|
|
2478
2743
|
|
|
2479
|
-
export { ALL_FLAGS, CHEATSHEET, MIME_TABLE, OPERATIONS, SQL_DEFAULT_OPTIONS, buildDockerPull, buildDockerRun, buildGitCommand, code_exports, collapseHtmlWhitespace, collapseJsWhitespace, countProperties, countRules, detectDialect, detectOperationType, envToExport, envToJson, formatCss, formatGql, formatHtml, formatSql, getEndpointsByTag, getHtmlStats, getJsStats, getMethodColor, isValidTag, lookupMime, minifyCss, minifyGql, minifyHtml, minifyJs, minifySql, normalizeRef, parseDockerImage, parseEnv, parseGitCommand, parseGithubUrl, parseSpec, removeConsoleCalls, removeEmptyAttributes, removeHtmlComments, removeJsComments, removeRedundantAttributes, searchCheatsheet, searchEndpoints, splitStatements, testPattern, testRegex, validateEnvKey };
|
|
2744
|
+
export { ALL_FLAGS, CHEATSHEET, MIME_TABLE, OPERATIONS, SQL_DEFAULT_OPTIONS, buildDockerPull, buildDockerRun, buildGitCommand, code_exports, collapseHtmlWhitespace, collapseJsWhitespace, countProperties, countRules, detectDialect, detectOperationType, detectRedos, envToExport, envToJson, formatCss, formatGql, formatHtml, formatSql, getEndpointsByTag, getHtmlStats, getJsStats, getMethodColor, isValidTag, lookupMime, minifyCss, minifyGql, minifyHtml, minifyJs, minifySql, normalizeRef, parseDockerImage, parseEnv, parseGitCommand, parseGithubUrl, parseSpec, removeConsoleCalls, removeEmptyAttributes, removeHtmlComments, removeJsComments, removeRedundantAttributes, searchCheatsheet, searchEndpoints, splitStatements, testPattern, testRegex, validateEnvKey };
|
|
@@ -22,6 +22,7 @@ __export(units_exports, {
|
|
|
22
22
|
calculateLoan: () => calculateLoan,
|
|
23
23
|
calculateSimpleInterest: () => calculateSimpleInterest,
|
|
24
24
|
calculateTax: () => calculateTax,
|
|
25
|
+
calculateTimeValue: () => calculateTimeValue,
|
|
25
26
|
calculateTipSplit: () => calculateTipSplit,
|
|
26
27
|
compareSemver: () => compareSemver,
|
|
27
28
|
convert: () => convert,
|
|
@@ -1297,5 +1298,44 @@ function calculateSimpleInterest(principal, annualRatePercent, years) {
|
|
|
1297
1298
|
totalPayoff: round22(principal + interest)
|
|
1298
1299
|
};
|
|
1299
1300
|
}
|
|
1301
|
+
function calculateTimeValue(amount, annualRatePercent, years, direction, compoundsPerYear = 1) {
|
|
1302
|
+
if (!Number.isFinite(amount) || amount < 0) return { error: "Amount must be zero or a positive number" };
|
|
1303
|
+
if (!Number.isFinite(annualRatePercent) || annualRatePercent < 0) {
|
|
1304
|
+
return { error: "Annual interest rate must be zero or a positive number" };
|
|
1305
|
+
}
|
|
1306
|
+
if (!Number.isFinite(years) || years <= 0) return { error: "Years must be a positive number" };
|
|
1307
|
+
if (!Number.isInteger(compoundsPerYear) || compoundsPerYear <= 0) {
|
|
1308
|
+
return { error: "Compounding frequency must be a positive whole number of periods per year" };
|
|
1309
|
+
}
|
|
1310
|
+
if (direction !== "future" && direction !== "present") {
|
|
1311
|
+
return { error: 'Direction must be "future" or "present"' };
|
|
1312
|
+
}
|
|
1313
|
+
const round22 = (n) => Math.round(n * 100) / 100;
|
|
1314
|
+
const round6 = (n) => Math.round(n * 1e6) / 1e6;
|
|
1315
|
+
const ratePerPeriod = annualRatePercent / 100 / compoundsPerYear;
|
|
1316
|
+
const totalPeriods = years * compoundsPerYear;
|
|
1317
|
+
const growthFactor = Math.pow(1 + ratePerPeriod, totalPeriods);
|
|
1318
|
+
let presentValue;
|
|
1319
|
+
let futureValue;
|
|
1320
|
+
if (direction === "future") {
|
|
1321
|
+
presentValue = amount;
|
|
1322
|
+
futureValue = amount * growthFactor;
|
|
1323
|
+
} else {
|
|
1324
|
+
futureValue = amount;
|
|
1325
|
+
presentValue = amount / growthFactor;
|
|
1326
|
+
}
|
|
1327
|
+
return {
|
|
1328
|
+
direction,
|
|
1329
|
+
annualRatePercent,
|
|
1330
|
+
years,
|
|
1331
|
+
compoundsPerYear,
|
|
1332
|
+
totalPeriods,
|
|
1333
|
+
ratePerPeriodPercent: round6(ratePerPeriod * 100),
|
|
1334
|
+
growthFactor: round6(growthFactor),
|
|
1335
|
+
presentValue: round22(presentValue),
|
|
1336
|
+
futureValue: round22(futureValue),
|
|
1337
|
+
interest: round22(futureValue - presentValue)
|
|
1338
|
+
};
|
|
1339
|
+
}
|
|
1300
1340
|
|
|
1301
|
-
export { BASE_LABELS, BASE_PREFIXES, BYTE_UNITS, COMMON_CURRENCIES, COMMON_LOCALES, COMMON_PERMISSIONS, COMMON_RATIOS, COMMON_SIZES, COMMON_TAX_RATES, COMMON_TIP_PERCENTAGES, COMMON_VIEWPORTS, autoFormat, bumpVersion, calcAspectRatio, calcSubnet, calculateCompoundInterest, calculateLoan, calculateSimpleInterest, calculateTax, calculateTipSplit, compareSemver, convert, convertBytes, convertIp, coverBox, decimalToIp, decimalToIpCidr, describePermissions, fitIntoBox, formatNumber, formatValue, formatVwValue, formatWithSeparator, gcd, ipFromBinary, ipFromDecimal, ipFromHex, ipToBinary, ipToDecimal, ipToDecimalCidr, ipToHex, ipToOctal, isValid, isValidCidr, isValidIp, isValidIpv4, octalToPermissions, parseFileSize, parseInput, parseNumberString, parseSemver, permissionsToChmod, permissionsToOctal, permissionsToSymbolic, ptToPx, pxToAll, pxToViewport, remToPx, satisfiesRange, scaleByHeight, scaleByWidth, sortVersions, splitSubnet, symbolicToPermissions, units_exports, validateBarcode, validateCardNumber, validateIban, validateIsbn, viewportToPx };
|
|
1341
|
+
export { BASE_LABELS, BASE_PREFIXES, BYTE_UNITS, COMMON_CURRENCIES, COMMON_LOCALES, COMMON_PERMISSIONS, COMMON_RATIOS, COMMON_SIZES, COMMON_TAX_RATES, COMMON_TIP_PERCENTAGES, COMMON_VIEWPORTS, autoFormat, bumpVersion, calcAspectRatio, calcSubnet, calculateCompoundInterest, calculateLoan, calculateSimpleInterest, calculateTax, calculateTimeValue, calculateTipSplit, compareSemver, convert, convertBytes, convertIp, coverBox, decimalToIp, decimalToIpCidr, describePermissions, fitIntoBox, formatNumber, formatValue, formatVwValue, formatWithSeparator, gcd, ipFromBinary, ipFromDecimal, ipFromHex, ipToBinary, ipToDecimal, ipToDecimalCidr, ipToHex, ipToOctal, isValid, isValidCidr, isValidIp, isValidIpv4, octalToPermissions, parseFileSize, parseInput, parseNumberString, parseSemver, permissionsToChmod, permissionsToOctal, permissionsToSymbolic, ptToPx, pxToAll, pxToViewport, remToPx, satisfiesRange, scaleByHeight, scaleByWidth, sortVersions, splitSubnet, symbolicToPermissions, units_exports, validateBarcode, validateCardNumber, validateIban, validateIsbn, viewportToPx };
|