@atmaticai/agent-tools-core 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +742 -0
- package/dist/archive/index.d.mts +1 -0
- package/dist/archive/index.d.ts +1 -0
- package/dist/archive/index.js +90 -0
- package/dist/archive/index.js.map +1 -0
- package/dist/archive/index.mjs +80 -0
- package/dist/archive/index.mjs.map +1 -0
- package/dist/color/index.d.mts +1 -0
- package/dist/color/index.d.ts +1 -0
- package/dist/color/index.js +347 -0
- package/dist/color/index.js.map +1 -0
- package/dist/color/index.mjs +336 -0
- package/dist/color/index.mjs.map +1 -0
- package/dist/crypto/index.d.mts +1 -0
- package/dist/crypto/index.d.ts +1 -0
- package/dist/crypto/index.js +116 -0
- package/dist/crypto/index.js.map +1 -0
- package/dist/crypto/index.mjs +108 -0
- package/dist/crypto/index.mjs.map +1 -0
- package/dist/csv/index.d.mts +1 -0
- package/dist/csv/index.d.ts +1 -0
- package/dist/csv/index.js +371 -0
- package/dist/csv/index.js.map +1 -0
- package/dist/csv/index.mjs +348 -0
- package/dist/csv/index.mjs.map +1 -0
- package/dist/datetime/index.d.mts +1 -0
- package/dist/datetime/index.d.ts +1 -0
- package/dist/datetime/index.js +234 -0
- package/dist/datetime/index.js.map +1 -0
- package/dist/datetime/index.mjs +224 -0
- package/dist/datetime/index.mjs.map +1 -0
- package/dist/diff/index.d.mts +2 -0
- package/dist/diff/index.d.ts +2 -0
- package/dist/diff/index.js +84 -0
- package/dist/diff/index.js.map +1 -0
- package/dist/diff/index.mjs +78 -0
- package/dist/diff/index.mjs.map +1 -0
- package/dist/excel/index.d.mts +1 -0
- package/dist/excel/index.d.ts +1 -0
- package/dist/excel/index.js +163 -0
- package/dist/excel/index.js.map +1 -0
- package/dist/excel/index.mjs +153 -0
- package/dist/excel/index.mjs.map +1 -0
- package/dist/image/index.d.mts +1 -0
- package/dist/image/index.d.ts +1 -0
- package/dist/image/index.js +123 -0
- package/dist/image/index.js.map +1 -0
- package/dist/image/index.mjs +107 -0
- package/dist/image/index.mjs.map +1 -0
- package/dist/index--vbnYfdE.d.mts +142 -0
- package/dist/index--vbnYfdE.d.ts +142 -0
- package/dist/index-7FZQloN-.d.mts +62 -0
- package/dist/index-7FZQloN-.d.ts +62 -0
- package/dist/index-7XgaTVH5.d.mts +93 -0
- package/dist/index-7XgaTVH5.d.ts +93 -0
- package/dist/index-7bvFmh45.d.mts +87 -0
- package/dist/index-7bvFmh45.d.ts +87 -0
- package/dist/index-BDZcIVCU.d.mts +53 -0
- package/dist/index-BDZcIVCU.d.ts +53 -0
- package/dist/index-BN00EnUU.d.mts +55 -0
- package/dist/index-BN00EnUU.d.ts +55 -0
- package/dist/index-CQ1EukC4.d.mts +59 -0
- package/dist/index-CQ1EukC4.d.ts +59 -0
- package/dist/index-CgRVnFOt.d.mts +91 -0
- package/dist/index-CgRVnFOt.d.ts +91 -0
- package/dist/index-DjBDZzuj.d.mts +54 -0
- package/dist/index-DjBDZzuj.d.ts +54 -0
- package/dist/index-FFrvmr-n.d.mts +50 -0
- package/dist/index-FFrvmr-n.d.ts +50 -0
- package/dist/index-QWC8yIgW.d.mts +106 -0
- package/dist/index-QWC8yIgW.d.ts +106 -0
- package/dist/index-RVqNunxE.d.mts +193 -0
- package/dist/index-RVqNunxE.d.ts +193 -0
- package/dist/index-fJD8SORm.d.mts +61 -0
- package/dist/index-fJD8SORm.d.ts +61 -0
- package/dist/index-pPy_XDQU.d.mts +56 -0
- package/dist/index-pPy_XDQU.d.ts +56 -0
- package/dist/index-rwh9hdD9.d.mts +68 -0
- package/dist/index-rwh9hdD9.d.ts +68 -0
- package/dist/index-uXdkAfea.d.mts +93 -0
- package/dist/index-uXdkAfea.d.ts +93 -0
- package/dist/index.d.mts +17 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +3744 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3694 -0
- package/dist/index.mjs.map +1 -0
- package/dist/json/index.d.mts +1 -0
- package/dist/json/index.d.ts +1 -0
- package/dist/json/index.js +599 -0
- package/dist/json/index.js.map +1 -0
- package/dist/json/index.mjs +552 -0
- package/dist/json/index.mjs.map +1 -0
- package/dist/markdown/index.d.mts +1 -0
- package/dist/markdown/index.d.ts +1 -0
- package/dist/markdown/index.js +151 -0
- package/dist/markdown/index.js.map +1 -0
- package/dist/markdown/index.mjs +139 -0
- package/dist/markdown/index.mjs.map +1 -0
- package/dist/math/index.d.mts +1 -0
- package/dist/math/index.d.ts +1 -0
- package/dist/math/index.js +247 -0
- package/dist/math/index.js.map +1 -0
- package/dist/math/index.mjs +240 -0
- package/dist/math/index.mjs.map +1 -0
- package/dist/pdf/index.d.mts +1 -0
- package/dist/pdf/index.d.ts +1 -0
- package/dist/pdf/index.js +546 -0
- package/dist/pdf/index.js.map +1 -0
- package/dist/pdf/index.mjs +518 -0
- package/dist/pdf/index.mjs.map +1 -0
- package/dist/regex/index.d.mts +1 -0
- package/dist/regex/index.d.ts +1 -0
- package/dist/regex/index.js +93 -0
- package/dist/regex/index.js.map +1 -0
- package/dist/regex/index.mjs +88 -0
- package/dist/regex/index.mjs.map +1 -0
- package/dist/settings/index.d.mts +41 -0
- package/dist/settings/index.d.ts +41 -0
- package/dist/settings/index.js +146 -0
- package/dist/settings/index.js.map +1 -0
- package/dist/settings/index.mjs +139 -0
- package/dist/settings/index.mjs.map +1 -0
- package/dist/sql/index.d.mts +1 -0
- package/dist/sql/index.d.ts +1 -0
- package/dist/sql/index.js +146 -0
- package/dist/sql/index.js.map +1 -0
- package/dist/sql/index.mjs +139 -0
- package/dist/sql/index.mjs.map +1 -0
- package/dist/text/index.d.mts +1 -0
- package/dist/text/index.d.ts +1 -0
- package/dist/text/index.js +250 -0
- package/dist/text/index.js.map +1 -0
- package/dist/text/index.mjs +242 -0
- package/dist/text/index.mjs.map +1 -0
- package/dist/xml/index.d.mts +1 -0
- package/dist/xml/index.d.ts +1 -0
- package/dist/xml/index.js +188 -0
- package/dist/xml/index.js.map +1 -0
- package/dist/xml/index.mjs +180 -0
- package/dist/xml/index.mjs.map +1 -0
- package/package.json +150 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var sqlFormatter = require('sql-formatter');
|
|
4
|
+
var nodeSqlParser = require('node-sql-parser');
|
|
5
|
+
|
|
6
|
+
// src/sql/format.ts
|
|
7
|
+
var dialectMap = {
|
|
8
|
+
mysql: "mysql",
|
|
9
|
+
postgresql: "postgresql",
|
|
10
|
+
sqlite: "sqlite",
|
|
11
|
+
transactsql: "transactsql",
|
|
12
|
+
bigquery: "bigquery"
|
|
13
|
+
};
|
|
14
|
+
function format(input, options = {}) {
|
|
15
|
+
const language = dialectMap[options.dialect ?? "postgresql"] ?? "postgresql";
|
|
16
|
+
return sqlFormatter.format(input, {
|
|
17
|
+
language,
|
|
18
|
+
tabWidth: options.indent ?? 2,
|
|
19
|
+
useTabs: false,
|
|
20
|
+
keywordCase: options.uppercase !== false ? "upper" : "preserve",
|
|
21
|
+
linesBetweenQueries: options.linesBetweenQueries ?? 2
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function minify(input) {
|
|
25
|
+
return input.replace(/--.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/\s+/g, " ").replace(/\s*([,;()=<>+\-*/])\s*/g, "$1").trim();
|
|
26
|
+
}
|
|
27
|
+
var parserDialectMap = {
|
|
28
|
+
mysql: "MySQL",
|
|
29
|
+
postgresql: "PostgresQL",
|
|
30
|
+
sqlite: "SQLite",
|
|
31
|
+
transactsql: "TransactSQL",
|
|
32
|
+
bigquery: "BigQuery"
|
|
33
|
+
};
|
|
34
|
+
function parse(input, dialect = "postgresql") {
|
|
35
|
+
const parser = new nodeSqlParser.Parser();
|
|
36
|
+
const dbType = parserDialectMap[dialect] ?? "PostgresQL";
|
|
37
|
+
const ast = parser.astify(input, { database: dbType });
|
|
38
|
+
const stmts = Array.isArray(ast) ? ast : [ast];
|
|
39
|
+
const tables = /* @__PURE__ */ new Set();
|
|
40
|
+
const columns = /* @__PURE__ */ new Set();
|
|
41
|
+
for (const stmt of stmts) {
|
|
42
|
+
extractTablesAndColumns(stmt, tables, columns);
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
type: stmts[0]?.type ?? "unknown",
|
|
46
|
+
tables: Array.from(tables),
|
|
47
|
+
columns: Array.from(columns),
|
|
48
|
+
ast
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function validate(input, dialect = "postgresql") {
|
|
52
|
+
const parser = new nodeSqlParser.Parser();
|
|
53
|
+
const dbType = parserDialectMap[dialect] ?? "PostgresQL";
|
|
54
|
+
try {
|
|
55
|
+
const ast = parser.astify(input, { database: dbType });
|
|
56
|
+
return { valid: true, ast };
|
|
57
|
+
} catch (e) {
|
|
58
|
+
return {
|
|
59
|
+
valid: false,
|
|
60
|
+
error: e.message
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function getStats(input, dialect = "postgresql") {
|
|
65
|
+
const parser = new nodeSqlParser.Parser();
|
|
66
|
+
const dbType = parserDialectMap[dialect] ?? "PostgresQL";
|
|
67
|
+
const ast = parser.astify(input, { database: dbType });
|
|
68
|
+
const stmts = Array.isArray(ast) ? ast : [ast];
|
|
69
|
+
const queryTypes = {};
|
|
70
|
+
const tables = /* @__PURE__ */ new Set();
|
|
71
|
+
let joins = 0;
|
|
72
|
+
for (const stmt of stmts) {
|
|
73
|
+
const type = (stmt.type ?? "unknown").toLowerCase();
|
|
74
|
+
queryTypes[type] = (queryTypes[type] || 0) + 1;
|
|
75
|
+
extractTablesAndColumns(stmt, tables, /* @__PURE__ */ new Set());
|
|
76
|
+
const stmtStr = JSON.stringify(stmt);
|
|
77
|
+
const joinMatches = stmtStr.match(/"join"/gi);
|
|
78
|
+
if (joinMatches) joins += joinMatches.length;
|
|
79
|
+
}
|
|
80
|
+
const subqueryRegex = /\bSELECT\b/gi;
|
|
81
|
+
const selectMatches = input.match(subqueryRegex);
|
|
82
|
+
const subqueries = Math.max(0, (selectMatches?.length ?? 0) - stmts.filter((s) => s.type === "select").length);
|
|
83
|
+
return {
|
|
84
|
+
queryCount: stmts.length,
|
|
85
|
+
queryTypes,
|
|
86
|
+
tables: Array.from(tables),
|
|
87
|
+
joins,
|
|
88
|
+
subqueries
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function extractTablesAndColumns(node, tables, columns) {
|
|
92
|
+
if (!node || typeof node !== "object") return;
|
|
93
|
+
const obj = node;
|
|
94
|
+
if (obj.table && typeof obj.table === "string") {
|
|
95
|
+
tables.add(obj.table);
|
|
96
|
+
}
|
|
97
|
+
if (obj.from && Array.isArray(obj.from)) {
|
|
98
|
+
for (const item of obj.from) {
|
|
99
|
+
if (item && typeof item === "object" && "table" in item) {
|
|
100
|
+
tables.add(String(item.table));
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
if (obj.columns && Array.isArray(obj.columns)) {
|
|
105
|
+
for (const col of obj.columns) {
|
|
106
|
+
if (col && typeof col === "object" && "expr" in col) {
|
|
107
|
+
const expr = col.expr;
|
|
108
|
+
if (expr.type === "column_ref" && typeof expr.column === "string") {
|
|
109
|
+
columns.add(expr.column);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
for (const value of Object.values(obj)) {
|
|
115
|
+
if (Array.isArray(value)) {
|
|
116
|
+
for (const item of value) {
|
|
117
|
+
extractTablesAndColumns(item, tables, columns);
|
|
118
|
+
}
|
|
119
|
+
} else if (typeof value === "object" && value !== null) {
|
|
120
|
+
extractTablesAndColumns(value, tables, columns);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
var parserDialectMap2 = {
|
|
125
|
+
mysql: "MySQL",
|
|
126
|
+
postgresql: "PostgresQL",
|
|
127
|
+
sqlite: "SQLite",
|
|
128
|
+
transactsql: "TransactSQL",
|
|
129
|
+
bigquery: "BigQuery"
|
|
130
|
+
};
|
|
131
|
+
function convert(input, options) {
|
|
132
|
+
const fromDialect = parserDialectMap2[options.from ?? "postgresql"] ?? "PostgresQL";
|
|
133
|
+
const toDialect = parserDialectMap2[options.to] ?? "PostgresQL";
|
|
134
|
+
const parser = new nodeSqlParser.Parser();
|
|
135
|
+
const ast = parser.astify(input, { database: fromDialect });
|
|
136
|
+
return parser.sqlify(ast, { database: toDialect });
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
exports.convert = convert;
|
|
140
|
+
exports.format = format;
|
|
141
|
+
exports.getStats = getStats;
|
|
142
|
+
exports.minify = minify;
|
|
143
|
+
exports.parse = parse;
|
|
144
|
+
exports.validate = validate;
|
|
145
|
+
//# sourceMappingURL=index.js.map
|
|
146
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/sql/format.ts","../../src/sql/parse.ts","../../src/sql/convert.ts"],"names":["sqlFormat","Parser","parserDialectMap"],"mappings":";;;;;;AAGA,IAAM,UAAA,GAAqC;AAAA,EACzC,KAAA,EAAO,OAAA;AAAA,EACP,UAAA,EAAY,YAAA;AAAA,EACZ,MAAA,EAAQ,QAAA;AAAA,EACR,WAAA,EAAa,aAAA;AAAA,EACb,QAAA,EAAU;AACZ,CAAA;AAEO,SAAS,MAAA,CAAO,KAAA,EAAe,OAAA,GAA4B,EAAC,EAAW;AAC5E,EAAA,MAAM,QAAA,GAAW,UAAA,CAAW,OAAA,CAAQ,OAAA,IAAW,YAAY,CAAA,IAAK,YAAA;AAEhE,EAAA,OAAOA,oBAAU,KAAA,EAAO;AAAA,IACtB,QAAA;AAAA,IACA,QAAA,EAAU,QAAQ,MAAA,IAAU,CAAA;AAAA,IAC5B,OAAA,EAAS,KAAA;AAAA,IACT,WAAA,EAAa,OAAA,CAAQ,SAAA,KAAc,KAAA,GAAQ,OAAA,GAAU,UAAA;AAAA,IACrD,mBAAA,EAAqB,QAAQ,mBAAA,IAAuB;AAAA,GACrD,CAAA;AACH;AAEO,SAAS,OAAO,KAAA,EAAuB;AAC5C,EAAA,OAAO,MACJ,OAAA,CAAQ,SAAA,EAAW,EAAE,CAAA,CACrB,QAAQ,mBAAA,EAAqB,EAAE,CAAA,CAC/B,OAAA,CAAQ,QAAQ,GAAG,CAAA,CACnB,QAAQ,yBAAA,EAA2B,IAAI,EACvC,IAAA,EAAK;AACV;AC3BA,IAAM,gBAAA,GAA+C;AAAA,EACnD,KAAA,EAAO,OAAA;AAAA,EACP,UAAA,EAAY,YAAA;AAAA,EACZ,MAAA,EAAQ,QAAA;AAAA,EACR,WAAA,EAAa,aAAA;AAAA,EACb,QAAA,EAAU;AACZ,CAAA;AAEO,SAAS,KAAA,CACd,KAAA,EACA,OAAA,GAAsB,YAAA,EACN;AAChB,EAAA,MAAM,MAAA,GAAS,IAAIC,oBAAA,EAAO;AAC1B,EAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,OAAO,CAAA,IAAK,YAAA;AAC5C,EAAA,MAAM,MAAM,MAAA,CAAO,MAAA,CAAO,OAAO,EAAE,QAAA,EAAU,QAAQ,CAAA;AAErD,EAAA,MAAM,QAAQ,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,GAAI,GAAA,GAAM,CAAC,GAAG,CAAA;AAC7C,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAY;AAC/B,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAY;AAEhC,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,uBAAA,CAAwB,IAAA,EAAM,QAAQ,OAAO,CAAA;AAAA,EAC/C;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,KAAA,CAAM,CAAC,CAAA,EAAG,IAAA,IAAQ,SAAA;AAAA,IACxB,MAAA,EAAQ,KAAA,CAAM,IAAA,CAAK,MAAM,CAAA;AAAA,IACzB,OAAA,EAAS,KAAA,CAAM,IAAA,CAAK,OAAO,CAAA;AAAA,IAC3B;AAAA,GACF;AACF;AAEO,SAAS,QAAA,CACd,KAAA,EACA,OAAA,GAAsB,YAAA,EACD;AACrB,EAAA,MAAM,MAAA,GAAS,IAAIA,oBAAA,EAAO;AAC1B,EAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,OAAO,CAAA,IAAK,YAAA;AAE5C,EAAA,IAAI;AACF,IAAA,MAAM,MAAM,MAAA,CAAO,MAAA,CAAO,OAAO,EAAE,QAAA,EAAU,QAAQ,CAAA;AACrD,IAAA,OAAO,EAAE,KAAA,EAAO,IAAA,EAAM,GAAA,EAAI;AAAA,EAC5B,SAAS,CAAA,EAAG;AACV,IAAA,OAAO;AAAA,MACL,KAAA,EAAO,KAAA;AAAA,MACP,OAAQ,CAAA,CAAY;AAAA,KACtB;AAAA,EACF;AACF;AAEO,SAAS,QAAA,CACd,KAAA,EACA,OAAA,GAAsB,YAAA,EACZ;AACV,EAAA,MAAM,MAAA,GAAS,IAAIA,oBAAA,EAAO;AAC1B,EAAA,MAAM,MAAA,GAAS,gBAAA,CAAiB,OAAO,CAAA,IAAK,YAAA;AAE5C,EAAA,MAAM,MAAM,MAAA,CAAO,MAAA,CAAO,OAAO,EAAE,QAAA,EAAU,QAAQ,CAAA;AACrD,EAAA,MAAM,QAAQ,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,GAAI,GAAA,GAAM,CAAC,GAAG,CAAA;AAE7C,EAAA,MAAM,aAAqC,EAAC;AAC5C,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAY;AAC/B,EAAA,IAAI,KAAA,GAAQ,CAAA;AAEZ,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,MAAM,IAAA,GAAA,CAAQ,IAAA,CAAK,IAAA,IAAQ,SAAA,EAAW,WAAA,EAAY;AAClD,IAAA,UAAA,CAAW,IAAI,CAAA,GAAA,CAAK,UAAA,CAAW,IAAI,KAAK,CAAA,IAAK,CAAA;AAC7C,IAAA,uBAAA,CAAwB,IAAA,EAAM,MAAA,kBAAQ,IAAI,GAAA,EAAK,CAAA;AAE/C,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA;AACnC,IAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,KAAA,CAAM,UAAU,CAAA;AAC5C,IAAA,IAAI,WAAA,WAAsB,WAAA,CAAY,MAAA;AAAA,EACxC;AAEA,EAAA,MAAM,aAAA,GAAgB,cAAA;AACtB,EAAA,MAAM,aAAA,GAAgB,KAAA,CAAM,KAAA,CAAM,aAAa,CAAA;AAC/C,EAAA,MAAM,UAAA,GAAa,IAAA,CAAK,GAAA,CAAI,CAAA,EAAA,CAAI,eAAe,MAAA,IAAU,CAAA,IAAK,KAAA,CAAM,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,QAAQ,EAAE,MAAM,CAAA;AAE7G,EAAA,OAAO;AAAA,IACL,YAAY,KAAA,CAAM,MAAA;AAAA,IAClB,UAAA;AAAA,IACA,MAAA,EAAQ,KAAA,CAAM,IAAA,CAAK,MAAM,CAAA;AAAA,IACzB,KAAA;AAAA,IACA;AAAA,GACF;AACF;AAEA,SAAS,uBAAA,CACP,IAAA,EACA,MAAA,EACA,OAAA,EACM;AACN,EAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,EAAU;AAEvC,EAAA,MAAM,GAAA,GAAM,IAAA;AAEZ,EAAA,IAAI,GAAA,CAAI,KAAA,IAAS,OAAO,GAAA,CAAI,UAAU,QAAA,EAAU;AAC9C,IAAA,MAAA,CAAO,GAAA,CAAI,IAAI,KAAK,CAAA;AAAA,EACtB;AAEA,EAAA,IAAI,IAAI,IAAA,IAAQ,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,IAAI,CAAA,EAAG;AACvC,IAAA,KAAA,MAAW,IAAA,IAAQ,IAAI,IAAA,EAAM;AAC3B,MAAA,IAAI,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,IAAY,WAAW,IAAA,EAAM;AACvD,QAAA,MAAA,CAAO,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,KAAK,CAAC,CAAA;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAEA,EAAA,IAAI,IAAI,OAAA,IAAW,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,OAAO,CAAA,EAAG;AAC7C,IAAA,KAAA,MAAW,GAAA,IAAO,IAAI,OAAA,EAAS;AAC7B,MAAA,IAAI,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAA,IAAY,UAAU,GAAA,EAAK;AACnD,QAAA,MAAM,OAAO,GAAA,CAAI,IAAA;AACjB,QAAA,IAAI,KAAK,IAAA,KAAS,YAAA,IAAgB,OAAO,IAAA,CAAK,WAAW,QAAA,EAAU;AACjE,UAAA,OAAA,CAAQ,GAAA,CAAI,KAAK,MAAM,CAAA;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,KAAA,MAAW,KAAA,IAAS,MAAA,CAAO,MAAA,CAAO,GAAG,CAAA,EAAG;AACtC,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,MAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,QAAA,uBAAA,CAAwB,IAAA,EAAM,QAAQ,OAAO,CAAA;AAAA,MAC/C;AAAA,IACF,CAAA,MAAA,IAAW,OAAO,KAAA,KAAU,QAAA,IAAY,UAAU,IAAA,EAAM;AACtD,MAAA,uBAAA,CAAwB,KAAA,EAAO,QAAQ,OAAO,CAAA;AAAA,IAChD;AAAA,EACF;AACF;AChIA,IAAMC,iBAAAA,GAA+C;AAAA,EACnD,KAAA,EAAO,OAAA;AAAA,EACP,UAAA,EAAY,YAAA;AAAA,EACZ,MAAA,EAAQ,QAAA;AAAA,EACR,WAAA,EAAa,aAAA;AAAA,EACb,QAAA,EAAU;AACZ,CAAA;AAEO,SAAS,OAAA,CACd,OACA,OAAA,EACQ;AACR,EAAA,MAAM,WAAA,GAAcA,iBAAAA,CAAiB,OAAA,CAAQ,IAAA,IAAQ,YAAY,CAAA,IAAK,YAAA;AACtE,EAAA,MAAM,SAAA,GAAYA,iBAAAA,CAAiB,OAAA,CAAQ,EAAE,CAAA,IAAK,YAAA;AAElD,EAAA,MAAM,MAAA,GAAS,IAAID,oBAAAA,EAAO;AAC1B,EAAA,MAAM,MAAM,MAAA,CAAO,MAAA,CAAO,OAAO,EAAE,QAAA,EAAU,aAAa,CAAA;AAC1D,EAAA,OAAO,OAAO,MAAA,CAAO,GAAA,EAAK,EAAE,QAAA,EAAU,WAAW,CAAA;AACnD","file":"index.js","sourcesContent":["import { format as sqlFormat } from 'sql-formatter';\nimport type { SqlFormatOptions } from './types';\n\nconst dialectMap: Record<string, string> = {\n mysql: 'mysql',\n postgresql: 'postgresql',\n sqlite: 'sqlite',\n transactsql: 'transactsql',\n bigquery: 'bigquery',\n};\n\nexport function format(input: string, options: SqlFormatOptions = {}): string {\n const language = dialectMap[options.dialect ?? 'postgresql'] ?? 'postgresql';\n\n return sqlFormat(input, {\n language: language as 'mysql' | 'postgresql' | 'sqlite' | 'transactsql' | 'bigquery',\n tabWidth: options.indent ?? 2,\n useTabs: false,\n keywordCase: options.uppercase !== false ? 'upper' : 'preserve',\n linesBetweenQueries: options.linesBetweenQueries ?? 2,\n });\n}\n\nexport function minify(input: string): string {\n return input\n .replace(/--.*$/gm, '')\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n .replace(/\\s+/g, ' ')\n .replace(/\\s*([,;()=<>+\\-*/])\\s*/g, '$1')\n .trim();\n}\n","import { Parser } from 'node-sql-parser';\nimport type { SqlDialect, SqlParseResult, SqlValidationResult, SqlStats } from './types';\n\nconst parserDialectMap: Record<SqlDialect, string> = {\n mysql: 'MySQL',\n postgresql: 'PostgresQL',\n sqlite: 'SQLite',\n transactsql: 'TransactSQL',\n bigquery: 'BigQuery',\n};\n\nexport function parse(\n input: string,\n dialect: SqlDialect = 'postgresql'\n): SqlParseResult {\n const parser = new Parser();\n const dbType = parserDialectMap[dialect] ?? 'PostgresQL';\n const ast = parser.astify(input, { database: dbType });\n\n const stmts = Array.isArray(ast) ? ast : [ast];\n const tables = new Set<string>();\n const columns = new Set<string>();\n\n for (const stmt of stmts) {\n extractTablesAndColumns(stmt, tables, columns);\n }\n\n return {\n type: stmts[0]?.type ?? 'unknown',\n tables: Array.from(tables),\n columns: Array.from(columns),\n ast,\n };\n}\n\nexport function validate(\n input: string,\n dialect: SqlDialect = 'postgresql'\n): SqlValidationResult {\n const parser = new Parser();\n const dbType = parserDialectMap[dialect] ?? 'PostgresQL';\n\n try {\n const ast = parser.astify(input, { database: dbType });\n return { valid: true, ast };\n } catch (e) {\n return {\n valid: false,\n error: (e as Error).message,\n };\n }\n}\n\nexport function getStats(\n input: string,\n dialect: SqlDialect = 'postgresql'\n): SqlStats {\n const parser = new Parser();\n const dbType = parserDialectMap[dialect] ?? 'PostgresQL';\n\n const ast = parser.astify(input, { database: dbType });\n const stmts = Array.isArray(ast) ? ast : [ast];\n\n const queryTypes: Record<string, number> = {};\n const tables = new Set<string>();\n let joins = 0;\n\n for (const stmt of stmts) {\n const type = (stmt.type ?? 'unknown').toLowerCase();\n queryTypes[type] = (queryTypes[type] || 0) + 1;\n extractTablesAndColumns(stmt, tables, new Set());\n\n const stmtStr = JSON.stringify(stmt);\n const joinMatches = stmtStr.match(/\"join\"/gi);\n if (joinMatches) joins += joinMatches.length;\n }\n\n const subqueryRegex = /\\bSELECT\\b/gi;\n const selectMatches = input.match(subqueryRegex);\n const subqueries = Math.max(0, (selectMatches?.length ?? 0) - stmts.filter((s) => s.type === 'select').length);\n\n return {\n queryCount: stmts.length,\n queryTypes,\n tables: Array.from(tables),\n joins,\n subqueries,\n };\n}\n\nfunction extractTablesAndColumns(\n node: unknown,\n tables: Set<string>,\n columns: Set<string>\n): void {\n if (!node || typeof node !== 'object') return;\n\n const obj = node as Record<string, unknown>;\n\n if (obj.table && typeof obj.table === 'string') {\n tables.add(obj.table);\n }\n\n if (obj.from && Array.isArray(obj.from)) {\n for (const item of obj.from) {\n if (item && typeof item === 'object' && 'table' in item) {\n tables.add(String(item.table));\n }\n }\n }\n\n if (obj.columns && Array.isArray(obj.columns)) {\n for (const col of obj.columns) {\n if (col && typeof col === 'object' && 'expr' in col) {\n const expr = col.expr as Record<string, unknown>;\n if (expr.type === 'column_ref' && typeof expr.column === 'string') {\n columns.add(expr.column);\n }\n }\n }\n }\n\n for (const value of Object.values(obj)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n extractTablesAndColumns(item, tables, columns);\n }\n } else if (typeof value === 'object' && value !== null) {\n extractTablesAndColumns(value, tables, columns);\n }\n }\n}\n","import { Parser } from 'node-sql-parser';\nimport type { SqlConvertOptions, SqlDialect } from './types';\n\nconst parserDialectMap: Record<SqlDialect, string> = {\n mysql: 'MySQL',\n postgresql: 'PostgresQL',\n sqlite: 'SQLite',\n transactsql: 'TransactSQL',\n bigquery: 'BigQuery',\n};\n\nexport function convert(\n input: string,\n options: SqlConvertOptions\n): string {\n const fromDialect = parserDialectMap[options.from ?? 'postgresql'] ?? 'PostgresQL';\n const toDialect = parserDialectMap[options.to] ?? 'PostgresQL';\n\n const parser = new Parser();\n const ast = parser.astify(input, { database: fromDialect });\n return parser.sqlify(ast, { database: toDialect });\n}\n"]}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { format as format$1 } from 'sql-formatter';
|
|
2
|
+
import { Parser } from 'node-sql-parser';
|
|
3
|
+
|
|
4
|
+
// src/sql/format.ts
|
|
5
|
+
var dialectMap = {
|
|
6
|
+
mysql: "mysql",
|
|
7
|
+
postgresql: "postgresql",
|
|
8
|
+
sqlite: "sqlite",
|
|
9
|
+
transactsql: "transactsql",
|
|
10
|
+
bigquery: "bigquery"
|
|
11
|
+
};
|
|
12
|
+
function format(input, options = {}) {
|
|
13
|
+
const language = dialectMap[options.dialect ?? "postgresql"] ?? "postgresql";
|
|
14
|
+
return format$1(input, {
|
|
15
|
+
language,
|
|
16
|
+
tabWidth: options.indent ?? 2,
|
|
17
|
+
useTabs: false,
|
|
18
|
+
keywordCase: options.uppercase !== false ? "upper" : "preserve",
|
|
19
|
+
linesBetweenQueries: options.linesBetweenQueries ?? 2
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function minify(input) {
|
|
23
|
+
return input.replace(/--.*$/gm, "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/\s+/g, " ").replace(/\s*([,;()=<>+\-*/])\s*/g, "$1").trim();
|
|
24
|
+
}
|
|
25
|
+
var parserDialectMap = {
|
|
26
|
+
mysql: "MySQL",
|
|
27
|
+
postgresql: "PostgresQL",
|
|
28
|
+
sqlite: "SQLite",
|
|
29
|
+
transactsql: "TransactSQL",
|
|
30
|
+
bigquery: "BigQuery"
|
|
31
|
+
};
|
|
32
|
+
function parse(input, dialect = "postgresql") {
|
|
33
|
+
const parser = new Parser();
|
|
34
|
+
const dbType = parserDialectMap[dialect] ?? "PostgresQL";
|
|
35
|
+
const ast = parser.astify(input, { database: dbType });
|
|
36
|
+
const stmts = Array.isArray(ast) ? ast : [ast];
|
|
37
|
+
const tables = /* @__PURE__ */ new Set();
|
|
38
|
+
const columns = /* @__PURE__ */ new Set();
|
|
39
|
+
for (const stmt of stmts) {
|
|
40
|
+
extractTablesAndColumns(stmt, tables, columns);
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
type: stmts[0]?.type ?? "unknown",
|
|
44
|
+
tables: Array.from(tables),
|
|
45
|
+
columns: Array.from(columns),
|
|
46
|
+
ast
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function validate(input, dialect = "postgresql") {
|
|
50
|
+
const parser = new Parser();
|
|
51
|
+
const dbType = parserDialectMap[dialect] ?? "PostgresQL";
|
|
52
|
+
try {
|
|
53
|
+
const ast = parser.astify(input, { database: dbType });
|
|
54
|
+
return { valid: true, ast };
|
|
55
|
+
} catch (e) {
|
|
56
|
+
return {
|
|
57
|
+
valid: false,
|
|
58
|
+
error: e.message
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function getStats(input, dialect = "postgresql") {
|
|
63
|
+
const parser = new Parser();
|
|
64
|
+
const dbType = parserDialectMap[dialect] ?? "PostgresQL";
|
|
65
|
+
const ast = parser.astify(input, { database: dbType });
|
|
66
|
+
const stmts = Array.isArray(ast) ? ast : [ast];
|
|
67
|
+
const queryTypes = {};
|
|
68
|
+
const tables = /* @__PURE__ */ new Set();
|
|
69
|
+
let joins = 0;
|
|
70
|
+
for (const stmt of stmts) {
|
|
71
|
+
const type = (stmt.type ?? "unknown").toLowerCase();
|
|
72
|
+
queryTypes[type] = (queryTypes[type] || 0) + 1;
|
|
73
|
+
extractTablesAndColumns(stmt, tables, /* @__PURE__ */ new Set());
|
|
74
|
+
const stmtStr = JSON.stringify(stmt);
|
|
75
|
+
const joinMatches = stmtStr.match(/"join"/gi);
|
|
76
|
+
if (joinMatches) joins += joinMatches.length;
|
|
77
|
+
}
|
|
78
|
+
const subqueryRegex = /\bSELECT\b/gi;
|
|
79
|
+
const selectMatches = input.match(subqueryRegex);
|
|
80
|
+
const subqueries = Math.max(0, (selectMatches?.length ?? 0) - stmts.filter((s) => s.type === "select").length);
|
|
81
|
+
return {
|
|
82
|
+
queryCount: stmts.length,
|
|
83
|
+
queryTypes,
|
|
84
|
+
tables: Array.from(tables),
|
|
85
|
+
joins,
|
|
86
|
+
subqueries
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function extractTablesAndColumns(node, tables, columns) {
|
|
90
|
+
if (!node || typeof node !== "object") return;
|
|
91
|
+
const obj = node;
|
|
92
|
+
if (obj.table && typeof obj.table === "string") {
|
|
93
|
+
tables.add(obj.table);
|
|
94
|
+
}
|
|
95
|
+
if (obj.from && Array.isArray(obj.from)) {
|
|
96
|
+
for (const item of obj.from) {
|
|
97
|
+
if (item && typeof item === "object" && "table" in item) {
|
|
98
|
+
tables.add(String(item.table));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (obj.columns && Array.isArray(obj.columns)) {
|
|
103
|
+
for (const col of obj.columns) {
|
|
104
|
+
if (col && typeof col === "object" && "expr" in col) {
|
|
105
|
+
const expr = col.expr;
|
|
106
|
+
if (expr.type === "column_ref" && typeof expr.column === "string") {
|
|
107
|
+
columns.add(expr.column);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
for (const value of Object.values(obj)) {
|
|
113
|
+
if (Array.isArray(value)) {
|
|
114
|
+
for (const item of value) {
|
|
115
|
+
extractTablesAndColumns(item, tables, columns);
|
|
116
|
+
}
|
|
117
|
+
} else if (typeof value === "object" && value !== null) {
|
|
118
|
+
extractTablesAndColumns(value, tables, columns);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
var parserDialectMap2 = {
|
|
123
|
+
mysql: "MySQL",
|
|
124
|
+
postgresql: "PostgresQL",
|
|
125
|
+
sqlite: "SQLite",
|
|
126
|
+
transactsql: "TransactSQL",
|
|
127
|
+
bigquery: "BigQuery"
|
|
128
|
+
};
|
|
129
|
+
function convert(input, options) {
|
|
130
|
+
const fromDialect = parserDialectMap2[options.from ?? "postgresql"] ?? "PostgresQL";
|
|
131
|
+
const toDialect = parserDialectMap2[options.to] ?? "PostgresQL";
|
|
132
|
+
const parser = new Parser();
|
|
133
|
+
const ast = parser.astify(input, { database: fromDialect });
|
|
134
|
+
return parser.sqlify(ast, { database: toDialect });
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export { convert, format, getStats, minify, parse, validate };
|
|
138
|
+
//# sourceMappingURL=index.mjs.map
|
|
139
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/sql/format.ts","../../src/sql/parse.ts","../../src/sql/convert.ts"],"names":["sqlFormat","parserDialectMap","Parser"],"mappings":"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","file":"index.mjs","sourcesContent":["import { format as sqlFormat } from 'sql-formatter';\nimport type { SqlFormatOptions } from './types';\n\nconst dialectMap: Record<string, string> = {\n mysql: 'mysql',\n postgresql: 'postgresql',\n sqlite: 'sqlite',\n transactsql: 'transactsql',\n bigquery: 'bigquery',\n};\n\nexport function format(input: string, options: SqlFormatOptions = {}): string {\n const language = dialectMap[options.dialect ?? 'postgresql'] ?? 'postgresql';\n\n return sqlFormat(input, {\n language: language as 'mysql' | 'postgresql' | 'sqlite' | 'transactsql' | 'bigquery',\n tabWidth: options.indent ?? 2,\n useTabs: false,\n keywordCase: options.uppercase !== false ? 'upper' : 'preserve',\n linesBetweenQueries: options.linesBetweenQueries ?? 2,\n });\n}\n\nexport function minify(input: string): string {\n return input\n .replace(/--.*$/gm, '')\n .replace(/\\/\\*[\\s\\S]*?\\*\\//g, '')\n .replace(/\\s+/g, ' ')\n .replace(/\\s*([,;()=<>+\\-*/])\\s*/g, '$1')\n .trim();\n}\n","import { Parser } from 'node-sql-parser';\nimport type { SqlDialect, SqlParseResult, SqlValidationResult, SqlStats } from './types';\n\nconst parserDialectMap: Record<SqlDialect, string> = {\n mysql: 'MySQL',\n postgresql: 'PostgresQL',\n sqlite: 'SQLite',\n transactsql: 'TransactSQL',\n bigquery: 'BigQuery',\n};\n\nexport function parse(\n input: string,\n dialect: SqlDialect = 'postgresql'\n): SqlParseResult {\n const parser = new Parser();\n const dbType = parserDialectMap[dialect] ?? 'PostgresQL';\n const ast = parser.astify(input, { database: dbType });\n\n const stmts = Array.isArray(ast) ? ast : [ast];\n const tables = new Set<string>();\n const columns = new Set<string>();\n\n for (const stmt of stmts) {\n extractTablesAndColumns(stmt, tables, columns);\n }\n\n return {\n type: stmts[0]?.type ?? 'unknown',\n tables: Array.from(tables),\n columns: Array.from(columns),\n ast,\n };\n}\n\nexport function validate(\n input: string,\n dialect: SqlDialect = 'postgresql'\n): SqlValidationResult {\n const parser = new Parser();\n const dbType = parserDialectMap[dialect] ?? 'PostgresQL';\n\n try {\n const ast = parser.astify(input, { database: dbType });\n return { valid: true, ast };\n } catch (e) {\n return {\n valid: false,\n error: (e as Error).message,\n };\n }\n}\n\nexport function getStats(\n input: string,\n dialect: SqlDialect = 'postgresql'\n): SqlStats {\n const parser = new Parser();\n const dbType = parserDialectMap[dialect] ?? 'PostgresQL';\n\n const ast = parser.astify(input, { database: dbType });\n const stmts = Array.isArray(ast) ? ast : [ast];\n\n const queryTypes: Record<string, number> = {};\n const tables = new Set<string>();\n let joins = 0;\n\n for (const stmt of stmts) {\n const type = (stmt.type ?? 'unknown').toLowerCase();\n queryTypes[type] = (queryTypes[type] || 0) + 1;\n extractTablesAndColumns(stmt, tables, new Set());\n\n const stmtStr = JSON.stringify(stmt);\n const joinMatches = stmtStr.match(/\"join\"/gi);\n if (joinMatches) joins += joinMatches.length;\n }\n\n const subqueryRegex = /\\bSELECT\\b/gi;\n const selectMatches = input.match(subqueryRegex);\n const subqueries = Math.max(0, (selectMatches?.length ?? 0) - stmts.filter((s) => s.type === 'select').length);\n\n return {\n queryCount: stmts.length,\n queryTypes,\n tables: Array.from(tables),\n joins,\n subqueries,\n };\n}\n\nfunction extractTablesAndColumns(\n node: unknown,\n tables: Set<string>,\n columns: Set<string>\n): void {\n if (!node || typeof node !== 'object') return;\n\n const obj = node as Record<string, unknown>;\n\n if (obj.table && typeof obj.table === 'string') {\n tables.add(obj.table);\n }\n\n if (obj.from && Array.isArray(obj.from)) {\n for (const item of obj.from) {\n if (item && typeof item === 'object' && 'table' in item) {\n tables.add(String(item.table));\n }\n }\n }\n\n if (obj.columns && Array.isArray(obj.columns)) {\n for (const col of obj.columns) {\n if (col && typeof col === 'object' && 'expr' in col) {\n const expr = col.expr as Record<string, unknown>;\n if (expr.type === 'column_ref' && typeof expr.column === 'string') {\n columns.add(expr.column);\n }\n }\n }\n }\n\n for (const value of Object.values(obj)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n extractTablesAndColumns(item, tables, columns);\n }\n } else if (typeof value === 'object' && value !== null) {\n extractTablesAndColumns(value, tables, columns);\n }\n }\n}\n","import { Parser } from 'node-sql-parser';\nimport type { SqlConvertOptions, SqlDialect } from './types';\n\nconst parserDialectMap: Record<SqlDialect, string> = {\n mysql: 'MySQL',\n postgresql: 'PostgresQL',\n sqlite: 'SQLite',\n transactsql: 'TransactSQL',\n bigquery: 'BigQuery',\n};\n\nexport function convert(\n input: string,\n options: SqlConvertOptions\n): string {\n const fromDialect = parserDialectMap[options.from ?? 'postgresql'] ?? 'PostgresQL';\n const toDialect = parserDialectMap[options.to] ?? 'PostgresQL';\n\n const parser = new Parser();\n const ast = parser.astify(input, { database: fromDialect });\n return parser.sqlify(ast, { database: toDialect });\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { C as CaseType, S as SimilarityResult, T as TemplateResult, a as TextStats, b as TruncateOptions, c as convertCase, g as generateLorem, d as getTextStats, e as interpolate, s as similarity, f as slugify, t as truncate } from '../index-DjBDZzuj.mjs';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { C as CaseType, S as SimilarityResult, T as TemplateResult, a as TextStats, b as TruncateOptions, c as convertCase, g as generateLorem, d as getTextStats, e as interpolate, s as similarity, f as slugify, t as truncate } from '../index-DjBDZzuj.js';
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/text/case.ts
|
|
4
|
+
function splitWords(input) {
|
|
5
|
+
return input.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2").replace(/[-_]/g, " ").split(/\s+/).filter((word) => word.length > 0);
|
|
6
|
+
}
|
|
7
|
+
function capitalize(word) {
|
|
8
|
+
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
|
|
9
|
+
}
|
|
10
|
+
function convertCase(input, to) {
|
|
11
|
+
const words = splitWords(input);
|
|
12
|
+
if (words.length === 0) {
|
|
13
|
+
return "";
|
|
14
|
+
}
|
|
15
|
+
switch (to) {
|
|
16
|
+
case "camel":
|
|
17
|
+
return words.map((word, index) => index === 0 ? word.toLowerCase() : capitalize(word)).join("");
|
|
18
|
+
case "pascal":
|
|
19
|
+
return words.map((word) => capitalize(word)).join("");
|
|
20
|
+
case "snake":
|
|
21
|
+
return words.map((word) => word.toLowerCase()).join("_");
|
|
22
|
+
case "kebab":
|
|
23
|
+
return words.map((word) => word.toLowerCase()).join("-");
|
|
24
|
+
case "constant":
|
|
25
|
+
return words.map((word) => word.toUpperCase()).join("_");
|
|
26
|
+
case "title":
|
|
27
|
+
return words.map((word) => capitalize(word)).join(" ");
|
|
28
|
+
case "sentence":
|
|
29
|
+
return words.map((word, index) => index === 0 ? capitalize(word) : word.toLowerCase()).join(" ");
|
|
30
|
+
case "upper":
|
|
31
|
+
return words.map((word) => word.toUpperCase()).join(" ");
|
|
32
|
+
case "lower":
|
|
33
|
+
return words.map((word) => word.toLowerCase()).join(" ");
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// src/text/slug.ts
|
|
38
|
+
function slugify(input, separator = "-") {
|
|
39
|
+
return input.toLowerCase().replace(/[^a-z0-9]+/g, separator).replace(new RegExp(`${escapeRegExp(separator)}+`, "g"), separator).replace(new RegExp(`^${escapeRegExp(separator)}|${escapeRegExp(separator)}$`, "g"), "");
|
|
40
|
+
}
|
|
41
|
+
function escapeRegExp(str) {
|
|
42
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// src/text/stats.ts
|
|
46
|
+
function getTextStats(input) {
|
|
47
|
+
const characters = input.length;
|
|
48
|
+
const words = input.split(/\s+/).filter((word) => word.length > 0);
|
|
49
|
+
const sentences = input.split(/[.!?](?:\s|$)/).filter((sentence) => sentence.trim().length > 0);
|
|
50
|
+
const paragraphs = input.split(/\n\n+/).filter((paragraph) => paragraph.trim().length > 0);
|
|
51
|
+
const lines = input.split(/\n/);
|
|
52
|
+
const readingTimeMs = words.length / 200 * 60 * 1e3;
|
|
53
|
+
return {
|
|
54
|
+
characters,
|
|
55
|
+
words: words.length,
|
|
56
|
+
sentences: sentences.length,
|
|
57
|
+
paragraphs: paragraphs.length,
|
|
58
|
+
lines: lines.length,
|
|
59
|
+
readingTimeMs
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// src/text/truncate.ts
|
|
64
|
+
function truncate(input, options) {
|
|
65
|
+
const { length, boundary = "word", suffix = "..." } = options;
|
|
66
|
+
if (input.length <= length) {
|
|
67
|
+
return input;
|
|
68
|
+
}
|
|
69
|
+
const maxContentLength = length - suffix.length;
|
|
70
|
+
if (maxContentLength <= 0) {
|
|
71
|
+
return suffix.slice(0, length);
|
|
72
|
+
}
|
|
73
|
+
if (boundary === "character") {
|
|
74
|
+
return input.slice(0, maxContentLength) + suffix;
|
|
75
|
+
}
|
|
76
|
+
const truncated = input.slice(0, maxContentLength);
|
|
77
|
+
const lastSpaceIndex = truncated.lastIndexOf(" ");
|
|
78
|
+
if (lastSpaceIndex === -1) {
|
|
79
|
+
return truncated + suffix;
|
|
80
|
+
}
|
|
81
|
+
return input.slice(0, lastSpaceIndex) + suffix;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// src/text/lorem.ts
|
|
85
|
+
var LOREM_WORDS = [
|
|
86
|
+
"lorem",
|
|
87
|
+
"ipsum",
|
|
88
|
+
"dolor",
|
|
89
|
+
"sit",
|
|
90
|
+
"amet",
|
|
91
|
+
"consectetur",
|
|
92
|
+
"adipiscing",
|
|
93
|
+
"elit",
|
|
94
|
+
"sed",
|
|
95
|
+
"do",
|
|
96
|
+
"eiusmod",
|
|
97
|
+
"tempor",
|
|
98
|
+
"incididunt",
|
|
99
|
+
"ut",
|
|
100
|
+
"labore",
|
|
101
|
+
"et",
|
|
102
|
+
"dolore",
|
|
103
|
+
"magna",
|
|
104
|
+
"aliqua",
|
|
105
|
+
"enim",
|
|
106
|
+
"ad",
|
|
107
|
+
"minim",
|
|
108
|
+
"veniam",
|
|
109
|
+
"quis",
|
|
110
|
+
"nostrud",
|
|
111
|
+
"exercitation",
|
|
112
|
+
"ullamco",
|
|
113
|
+
"laboris",
|
|
114
|
+
"nisi",
|
|
115
|
+
"aliquip",
|
|
116
|
+
"ex",
|
|
117
|
+
"ea",
|
|
118
|
+
"commodo",
|
|
119
|
+
"consequat",
|
|
120
|
+
"duis",
|
|
121
|
+
"aute",
|
|
122
|
+
"irure",
|
|
123
|
+
"in",
|
|
124
|
+
"reprehenderit",
|
|
125
|
+
"voluptate",
|
|
126
|
+
"velit",
|
|
127
|
+
"esse",
|
|
128
|
+
"cillum",
|
|
129
|
+
"fugiat",
|
|
130
|
+
"nulla",
|
|
131
|
+
"pariatur",
|
|
132
|
+
"excepteur",
|
|
133
|
+
"sint",
|
|
134
|
+
"occaecat",
|
|
135
|
+
"cupidatat"
|
|
136
|
+
];
|
|
137
|
+
function getWord(index) {
|
|
138
|
+
return LOREM_WORDS[index % LOREM_WORDS.length];
|
|
139
|
+
}
|
|
140
|
+
function generateSentence(wordOffset) {
|
|
141
|
+
const wordCount = 8 + wordOffset % 8;
|
|
142
|
+
const words = [];
|
|
143
|
+
for (let i = 0; i < wordCount; i++) {
|
|
144
|
+
words.push(getWord(wordOffset + i));
|
|
145
|
+
}
|
|
146
|
+
words[0] = words[0].charAt(0).toUpperCase() + words[0].slice(1);
|
|
147
|
+
return {
|
|
148
|
+
sentence: words.join(" ") + ".",
|
|
149
|
+
nextOffset: wordOffset + wordCount
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function generateLorem(count, unit = "words") {
|
|
153
|
+
if (count <= 0) {
|
|
154
|
+
return "";
|
|
155
|
+
}
|
|
156
|
+
if (unit === "words") {
|
|
157
|
+
const words = [];
|
|
158
|
+
for (let i = 0; i < count; i++) {
|
|
159
|
+
words.push(getWord(i));
|
|
160
|
+
}
|
|
161
|
+
return words.join(" ");
|
|
162
|
+
}
|
|
163
|
+
if (unit === "sentences") {
|
|
164
|
+
const sentences = [];
|
|
165
|
+
let offset2 = 0;
|
|
166
|
+
for (let i = 0; i < count; i++) {
|
|
167
|
+
const { sentence, nextOffset } = generateSentence(offset2);
|
|
168
|
+
sentences.push(sentence);
|
|
169
|
+
offset2 = nextOffset;
|
|
170
|
+
}
|
|
171
|
+
return sentences.join(" ");
|
|
172
|
+
}
|
|
173
|
+
const paragraphs = [];
|
|
174
|
+
let offset = 0;
|
|
175
|
+
for (let i = 0; i < count; i++) {
|
|
176
|
+
const sentenceCount = 3 + i % 4;
|
|
177
|
+
const sentences = [];
|
|
178
|
+
for (let j = 0; j < sentenceCount; j++) {
|
|
179
|
+
const { sentence, nextOffset } = generateSentence(offset);
|
|
180
|
+
sentences.push(sentence);
|
|
181
|
+
offset = nextOffset;
|
|
182
|
+
}
|
|
183
|
+
paragraphs.push(sentences.join(" "));
|
|
184
|
+
}
|
|
185
|
+
return paragraphs.join("\n\n");
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// src/text/similarity.ts
|
|
189
|
+
function similarity(a, b) {
|
|
190
|
+
if (a === b) {
|
|
191
|
+
return { distance: 0, similarity: 1 };
|
|
192
|
+
}
|
|
193
|
+
if (a.length === 0) {
|
|
194
|
+
return { distance: b.length, similarity: 0 };
|
|
195
|
+
}
|
|
196
|
+
if (b.length === 0) {
|
|
197
|
+
return { distance: a.length, similarity: 0 };
|
|
198
|
+
}
|
|
199
|
+
const m = a.length;
|
|
200
|
+
const n = b.length;
|
|
201
|
+
const dp = [];
|
|
202
|
+
for (let i = 0; i <= m; i++) {
|
|
203
|
+
dp[i] = new Array(n + 1);
|
|
204
|
+
dp[i][0] = i;
|
|
205
|
+
}
|
|
206
|
+
for (let j = 0; j <= n; j++) {
|
|
207
|
+
dp[0][j] = j;
|
|
208
|
+
}
|
|
209
|
+
for (let i = 1; i <= m; i++) {
|
|
210
|
+
for (let j = 1; j <= n; j++) {
|
|
211
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
212
|
+
dp[i][j] = Math.min(
|
|
213
|
+
dp[i - 1][j] + 1,
|
|
214
|
+
// deletion
|
|
215
|
+
dp[i][j - 1] + 1,
|
|
216
|
+
// insertion
|
|
217
|
+
dp[i - 1][j - 1] + cost
|
|
218
|
+
// substitution
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const distance = dp[m][n];
|
|
223
|
+
const maxLength = Math.max(m, n);
|
|
224
|
+
const sim = 1 - distance / maxLength;
|
|
225
|
+
return { distance, similarity: sim };
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// src/text/template.ts
|
|
229
|
+
function interpolate(template, variables) {
|
|
230
|
+
const missingKeys = [];
|
|
231
|
+
const result = template.replace(/\{\{\s*(\w+)\s*\}\}/g, (match, key) => {
|
|
232
|
+
if (key in variables) {
|
|
233
|
+
return variables[key];
|
|
234
|
+
}
|
|
235
|
+
missingKeys.push(key);
|
|
236
|
+
return match;
|
|
237
|
+
});
|
|
238
|
+
const uniqueMissingKeys = [...new Set(missingKeys)];
|
|
239
|
+
return { result, missingKeys: uniqueMissingKeys };
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
exports.convertCase = convertCase;
|
|
243
|
+
exports.generateLorem = generateLorem;
|
|
244
|
+
exports.getTextStats = getTextStats;
|
|
245
|
+
exports.interpolate = interpolate;
|
|
246
|
+
exports.similarity = similarity;
|
|
247
|
+
exports.slugify = slugify;
|
|
248
|
+
exports.truncate = truncate;
|
|
249
|
+
//# sourceMappingURL=index.js.map
|
|
250
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/text/case.ts","../../src/text/slug.ts","../../src/text/stats.ts","../../src/text/truncate.ts","../../src/text/lorem.ts","../../src/text/similarity.ts","../../src/text/template.ts"],"names":["offset"],"mappings":"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","file":"index.js","sourcesContent":["import type { CaseType } from './types';\n\nfunction splitWords(input: string): string[] {\n // Split by camelCase boundaries, spaces, hyphens, underscores\n return input\n // Insert separator before uppercase letters that follow lowercase letters (camelCase boundary)\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n // Insert separator before uppercase letters followed by lowercase (e.g. \"HTMLParser\" -> \"HTML Parser\")\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')\n // Replace hyphens and underscores with spaces\n .replace(/[-_]/g, ' ')\n // Split on whitespace\n .split(/\\s+/)\n // Filter out empty strings\n .filter((word) => word.length > 0);\n}\n\nfunction capitalize(word: string): string {\n return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();\n}\n\nexport function convertCase(input: string, to: CaseType): string {\n const words = splitWords(input);\n\n if (words.length === 0) {\n return '';\n }\n\n switch (to) {\n case 'camel':\n return words\n .map((word, index) => (index === 0 ? word.toLowerCase() : capitalize(word)))\n .join('');\n\n case 'pascal':\n return words.map((word) => capitalize(word)).join('');\n\n case 'snake':\n return words.map((word) => word.toLowerCase()).join('_');\n\n case 'kebab':\n return words.map((word) => word.toLowerCase()).join('-');\n\n case 'constant':\n return words.map((word) => word.toUpperCase()).join('_');\n\n case 'title':\n return words.map((word) => capitalize(word)).join(' ');\n\n case 'sentence':\n return words\n .map((word, index) => (index === 0 ? capitalize(word) : word.toLowerCase()))\n .join(' ');\n\n case 'upper':\n return words.map((word) => word.toUpperCase()).join(' ');\n\n case 'lower':\n return words.map((word) => word.toLowerCase()).join(' ');\n }\n}\n","export function slugify(input: string, separator: string = '-'): string {\n return input\n // Convert to lowercase\n .toLowerCase()\n // Replace non-alphanumeric chars with separator\n .replace(/[^a-z0-9]+/g, separator)\n // Collapse multiple separators\n .replace(new RegExp(`${escapeRegExp(separator)}+`, 'g'), separator)\n // Trim separators from ends\n .replace(new RegExp(`^${escapeRegExp(separator)}|${escapeRegExp(separator)}$`, 'g'), '');\n}\n\nfunction escapeRegExp(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n","import type { TextStats } from './types';\n\nexport function getTextStats(input: string): TextStats {\n const characters = input.length;\n\n const words = input\n .split(/\\s+/)\n .filter((word) => word.length > 0);\n\n const sentences = input\n .split(/[.!?](?:\\s|$)/)\n .filter((sentence) => sentence.trim().length > 0);\n\n const paragraphs = input\n .split(/\\n\\n+/)\n .filter((paragraph) => paragraph.trim().length > 0);\n\n const lines = input.split(/\\n/);\n\n // 200 words per minute average reading speed\n const readingTimeMs = (words.length / 200) * 60 * 1000;\n\n return {\n characters,\n words: words.length,\n sentences: sentences.length,\n paragraphs: paragraphs.length,\n lines: lines.length,\n readingTimeMs,\n };\n}\n","import type { TruncateOptions } from './types';\n\nexport function truncate(input: string, options: TruncateOptions): string {\n const { length, boundary = 'word', suffix = '...' } = options;\n\n if (input.length <= length) {\n return input;\n }\n\n const maxContentLength = length - suffix.length;\n\n if (maxContentLength <= 0) {\n return suffix.slice(0, length);\n }\n\n if (boundary === 'character') {\n return input.slice(0, maxContentLength) + suffix;\n }\n\n // Word boundary: find last space before maxContentLength\n const truncated = input.slice(0, maxContentLength);\n const lastSpaceIndex = truncated.lastIndexOf(' ');\n\n if (lastSpaceIndex === -1) {\n // No space found, fall back to character boundary\n return truncated + suffix;\n }\n\n return input.slice(0, lastSpaceIndex) + suffix;\n}\n","const LOREM_WORDS = [\n 'lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 'adipiscing', 'elit',\n 'sed', 'do', 'eiusmod', 'tempor', 'incididunt', 'ut', 'labore', 'et', 'dolore',\n 'magna', 'aliqua', 'enim', 'ad', 'minim', 'veniam', 'quis', 'nostrud',\n 'exercitation', 'ullamco', 'laboris', 'nisi', 'aliquip', 'ex', 'ea', 'commodo',\n 'consequat', 'duis', 'aute', 'irure', 'in', 'reprehenderit', 'voluptate',\n 'velit', 'esse', 'cillum', 'fugiat', 'nulla', 'pariatur', 'excepteur', 'sint',\n 'occaecat', 'cupidatat',\n];\n\nfunction getWord(index: number): string {\n return LOREM_WORDS[index % LOREM_WORDS.length];\n}\n\nfunction generateSentence(wordOffset: number): { sentence: string; nextOffset: number } {\n // Generate a sentence with 8-15 words\n const wordCount = 8 + (wordOffset % 8); // Deterministic 8-15 range\n const words: string[] = [];\n\n for (let i = 0; i < wordCount; i++) {\n words.push(getWord(wordOffset + i));\n }\n\n // Capitalize first word\n words[0] = words[0].charAt(0).toUpperCase() + words[0].slice(1);\n\n return {\n sentence: words.join(' ') + '.',\n nextOffset: wordOffset + wordCount,\n };\n}\n\nexport function generateLorem(\n count: number,\n unit: 'words' | 'sentences' | 'paragraphs' = 'words',\n): string {\n if (count <= 0) {\n return '';\n }\n\n if (unit === 'words') {\n const words: string[] = [];\n for (let i = 0; i < count; i++) {\n words.push(getWord(i));\n }\n return words.join(' ');\n }\n\n if (unit === 'sentences') {\n const sentences: string[] = [];\n let offset = 0;\n for (let i = 0; i < count; i++) {\n const { sentence, nextOffset } = generateSentence(offset);\n sentences.push(sentence);\n offset = nextOffset;\n }\n return sentences.join(' ');\n }\n\n // paragraphs\n const paragraphs: string[] = [];\n let offset = 0;\n\n for (let i = 0; i < count; i++) {\n const sentenceCount = 3 + (i % 4); // Deterministic 3-6 range\n const sentences: string[] = [];\n\n for (let j = 0; j < sentenceCount; j++) {\n const { sentence, nextOffset } = generateSentence(offset);\n sentences.push(sentence);\n offset = nextOffset;\n }\n\n paragraphs.push(sentences.join(' '));\n }\n\n return paragraphs.join('\\n\\n');\n}\n","import type { SimilarityResult } from './types';\n\nexport function similarity(a: string, b: string): SimilarityResult {\n // Handle edge cases\n if (a === b) {\n return { distance: 0, similarity: 1.0 };\n }\n\n if (a.length === 0) {\n return { distance: b.length, similarity: 0 };\n }\n\n if (b.length === 0) {\n return { distance: a.length, similarity: 0 };\n }\n\n // Wagner-Fischer algorithm for Levenshtein distance\n const m = a.length;\n const n = b.length;\n\n // Create a 2D matrix (m+1) x (n+1)\n const dp: number[][] = [];\n\n for (let i = 0; i <= m; i++) {\n dp[i] = new Array(n + 1);\n dp[i][0] = i;\n }\n\n for (let j = 0; j <= n; j++) {\n dp[0][j] = j;\n }\n\n for (let i = 1; i <= m; i++) {\n for (let j = 1; j <= n; j++) {\n const cost = a[i - 1] === b[j - 1] ? 0 : 1;\n dp[i][j] = Math.min(\n dp[i - 1][j] + 1, // deletion\n dp[i][j - 1] + 1, // insertion\n dp[i - 1][j - 1] + cost, // substitution\n );\n }\n }\n\n const distance = dp[m][n];\n const maxLength = Math.max(m, n);\n const sim = 1 - distance / maxLength;\n\n return { distance, similarity: sim };\n}\n","import type { TemplateResult } from './types';\n\nexport function interpolate(\n template: string,\n variables: Record<string, string>,\n): TemplateResult {\n const missingKeys: string[] = [];\n\n const result = template.replace(/\\{\\{\\s*(\\w+)\\s*\\}\\}/g, (match, key: string) => {\n if (key in variables) {\n return variables[key];\n }\n missingKeys.push(key);\n return match;\n });\n\n // Deduplicate missing keys while preserving order\n const uniqueMissingKeys = [...new Set(missingKeys)];\n\n return { result, missingKeys: uniqueMissingKeys };\n}\n"]}
|