@gzl10/ts-helpers 4.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +320 -0
- package/README.md +233 -0
- package/USAGE-GUIDE.md +800 -0
- package/dist/browser/async.js +15 -0
- package/dist/browser/async.js.map +1 -0
- package/dist/browser/chunk-4O7ZPIJN.js +383 -0
- package/dist/browser/chunk-4O7ZPIJN.js.map +1 -0
- package/dist/browser/chunk-75XNTC34.js +60 -0
- package/dist/browser/chunk-75XNTC34.js.map +1 -0
- package/dist/browser/chunk-C3D7YZVE.js +299 -0
- package/dist/browser/chunk-C3D7YZVE.js.map +1 -0
- package/dist/browser/chunk-CZL6C2EI.js +452 -0
- package/dist/browser/chunk-CZL6C2EI.js.map +1 -0
- package/dist/browser/chunk-D4FZFIVA.js +240 -0
- package/dist/browser/chunk-D4FZFIVA.js.map +1 -0
- package/dist/browser/chunk-IL7NG7IC.js +72 -0
- package/dist/browser/chunk-IL7NG7IC.js.map +1 -0
- package/dist/browser/chunk-NSBPE2FW.js +17 -0
- package/dist/browser/chunk-NSBPE2FW.js.map +1 -0
- package/dist/browser/chunk-SLQVNPTH.js +27 -0
- package/dist/browser/chunk-SLQVNPTH.js.map +1 -0
- package/dist/browser/chunk-WG7ILCUB.js +195 -0
- package/dist/browser/chunk-WG7ILCUB.js.map +1 -0
- package/dist/browser/chunk-WJA4JDMZ.js +278 -0
- package/dist/browser/chunk-WJA4JDMZ.js.map +1 -0
- package/dist/browser/chunk-ZFVYLUTT.js +65 -0
- package/dist/browser/chunk-ZFVYLUTT.js.map +1 -0
- package/dist/browser/chunk-ZYTSVMTI.js +263 -0
- package/dist/browser/chunk-ZYTSVMTI.js.map +1 -0
- package/dist/browser/dates.js +78 -0
- package/dist/browser/dates.js.map +1 -0
- package/dist/browser/environment-detection.js +21 -0
- package/dist/browser/environment-detection.js.map +1 -0
- package/dist/browser/environment.js +34 -0
- package/dist/browser/environment.js.map +1 -0
- package/dist/browser/errors.js +18 -0
- package/dist/browser/errors.js.map +1 -0
- package/dist/browser/index.js +412 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/math.js +51 -0
- package/dist/browser/math.js.map +1 -0
- package/dist/browser/number.js +10 -0
- package/dist/browser/number.js.map +1 -0
- package/dist/browser/objects.js +31 -0
- package/dist/browser/objects.js.map +1 -0
- package/dist/browser/strings.js +80 -0
- package/dist/browser/strings.js.map +1 -0
- package/dist/browser/validation-core.js +54 -0
- package/dist/browser/validation-core.js.map +1 -0
- package/dist/browser/validation-crypto.js +28 -0
- package/dist/browser/validation-crypto.js.map +1 -0
- package/dist/browser/validators.js +98 -0
- package/dist/browser/validators.js.map +1 -0
- package/dist/cjs/async.js +86 -0
- package/dist/cjs/async.js.map +1 -0
- package/dist/cjs/dates.js +285 -0
- package/dist/cjs/dates.js.map +1 -0
- package/dist/cjs/environment-detection.js +84 -0
- package/dist/cjs/environment-detection.js.map +1 -0
- package/dist/cjs/environment.js +261 -0
- package/dist/cjs/environment.js.map +1 -0
- package/dist/cjs/errors.js +80 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/index.js +2035 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/math.js +388 -0
- package/dist/cjs/math.js.map +1 -0
- package/dist/cjs/number.js +37 -0
- package/dist/cjs/number.js.map +1 -0
- package/dist/cjs/objects.js +249 -0
- package/dist/cjs/objects.js.map +1 -0
- package/dist/cjs/strings.js +253 -0
- package/dist/cjs/strings.js.map +1 -0
- package/dist/cjs/validation.js +450 -0
- package/dist/cjs/validation.js.map +1 -0
- package/dist/esm/async.js +15 -0
- package/dist/esm/async.js.map +1 -0
- package/dist/esm/chunk-4O7ZPIJN.js +383 -0
- package/dist/esm/chunk-4O7ZPIJN.js.map +1 -0
- package/dist/esm/chunk-75XNTC34.js +60 -0
- package/dist/esm/chunk-75XNTC34.js.map +1 -0
- package/dist/esm/chunk-BDOBKBKA.js +72 -0
- package/dist/esm/chunk-BDOBKBKA.js.map +1 -0
- package/dist/esm/chunk-C3D7YZVE.js +299 -0
- package/dist/esm/chunk-C3D7YZVE.js.map +1 -0
- package/dist/esm/chunk-CZL6C2EI.js +452 -0
- package/dist/esm/chunk-CZL6C2EI.js.map +1 -0
- package/dist/esm/chunk-EBLSTOEC.js +263 -0
- package/dist/esm/chunk-EBLSTOEC.js.map +1 -0
- package/dist/esm/chunk-NSBPE2FW.js +17 -0
- package/dist/esm/chunk-NSBPE2FW.js.map +1 -0
- package/dist/esm/chunk-SLQVNPTH.js +27 -0
- package/dist/esm/chunk-SLQVNPTH.js.map +1 -0
- package/dist/esm/chunk-WG7ILCUB.js +195 -0
- package/dist/esm/chunk-WG7ILCUB.js.map +1 -0
- package/dist/esm/chunk-WJA4JDMZ.js +278 -0
- package/dist/esm/chunk-WJA4JDMZ.js.map +1 -0
- package/dist/esm/chunk-ZFVYLUTT.js +65 -0
- package/dist/esm/chunk-ZFVYLUTT.js.map +1 -0
- package/dist/esm/dates.js +78 -0
- package/dist/esm/dates.js.map +1 -0
- package/dist/esm/environment-detection.js +21 -0
- package/dist/esm/environment-detection.js.map +1 -0
- package/dist/esm/environment.js +34 -0
- package/dist/esm/environment.js.map +1 -0
- package/dist/esm/errors.js +18 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/index.js +380 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/math.js +51 -0
- package/dist/esm/math.js.map +1 -0
- package/dist/esm/number.js +10 -0
- package/dist/esm/number.js.map +1 -0
- package/dist/esm/objects.js +31 -0
- package/dist/esm/objects.js.map +1 -0
- package/dist/esm/strings.js +80 -0
- package/dist/esm/strings.js.map +1 -0
- package/dist/esm/validation.js +54 -0
- package/dist/esm/validation.js.map +1 -0
- package/dist/node/async.js +93 -0
- package/dist/node/async.js.map +1 -0
- package/dist/node/csv.js +102 -0
- package/dist/node/csv.js.map +1 -0
- package/dist/node/data.js +880 -0
- package/dist/node/data.js.map +1 -0
- package/dist/node/dates.js +324 -0
- package/dist/node/dates.js.map +1 -0
- package/dist/node/environment.js +278 -0
- package/dist/node/environment.js.map +1 -0
- package/dist/node/errors.js +89 -0
- package/dist/node/errors.js.map +1 -0
- package/dist/node/index.js +3151 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/json.js +107 -0
- package/dist/node/json.js.map +1 -0
- package/dist/node/math.js +413 -0
- package/dist/node/math.js.map +1 -0
- package/dist/node/number.js +42 -0
- package/dist/node/number.js.map +1 -0
- package/dist/node/objects.js +264 -0
- package/dist/node/objects.js.map +1 -0
- package/dist/node/strings.js +293 -0
- package/dist/node/strings.js.map +1 -0
- package/dist/node/tree.js +89 -0
- package/dist/node/tree.js.map +1 -0
- package/dist/node/validation-core.js +477 -0
- package/dist/node/validation-core.js.map +1 -0
- package/dist/node/validation-crypto.js +179 -0
- package/dist/node/validation-crypto.js.map +1 -0
- package/dist/node/validation.js +677 -0
- package/dist/node/validation.js.map +1 -0
- package/dist/node/validators.js +123 -0
- package/dist/node/validators.js.map +1 -0
- package/dist/node-esm/async.js +15 -0
- package/dist/node-esm/async.js.map +1 -0
- package/dist/node-esm/chunk-3YOF7NPT.js +299 -0
- package/dist/node-esm/chunk-3YOF7NPT.js.map +1 -0
- package/dist/node-esm/chunk-64TBXJQS.js +263 -0
- package/dist/node-esm/chunk-64TBXJQS.js.map +1 -0
- package/dist/node-esm/chunk-75XNTC34.js +60 -0
- package/dist/node-esm/chunk-75XNTC34.js.map +1 -0
- package/dist/node-esm/chunk-C4PKXIPB.js +278 -0
- package/dist/node-esm/chunk-C4PKXIPB.js.map +1 -0
- package/dist/node-esm/chunk-CMDFZME3.js +452 -0
- package/dist/node-esm/chunk-CMDFZME3.js.map +1 -0
- package/dist/node-esm/chunk-DZZPUYMP.js +74 -0
- package/dist/node-esm/chunk-DZZPUYMP.js.map +1 -0
- package/dist/node-esm/chunk-HTSEHRHI.js +195 -0
- package/dist/node-esm/chunk-HTSEHRHI.js.map +1 -0
- package/dist/node-esm/chunk-JCAUVOPH.js +27 -0
- package/dist/node-esm/chunk-JCAUVOPH.js.map +1 -0
- package/dist/node-esm/chunk-KBHE3K2F.js +505 -0
- package/dist/node-esm/chunk-KBHE3K2F.js.map +1 -0
- package/dist/node-esm/chunk-LYTET5NX.js +65 -0
- package/dist/node-esm/chunk-LYTET5NX.js.map +1 -0
- package/dist/node-esm/chunk-PZ5AY32C.js +10 -0
- package/dist/node-esm/chunk-PZ5AY32C.js.map +1 -0
- package/dist/node-esm/chunk-UKGXL2QO.js +383 -0
- package/dist/node-esm/chunk-UKGXL2QO.js.map +1 -0
- package/dist/node-esm/chunk-XAEYT23H.js +164 -0
- package/dist/node-esm/chunk-XAEYT23H.js.map +1 -0
- package/dist/node-esm/csv.js +63 -0
- package/dist/node-esm/csv.js.map +1 -0
- package/dist/node-esm/data.js +32 -0
- package/dist/node-esm/data.js.map +1 -0
- package/dist/node-esm/dates.js +78 -0
- package/dist/node-esm/dates.js.map +1 -0
- package/dist/node-esm/environment.js +34 -0
- package/dist/node-esm/environment.js.map +1 -0
- package/dist/node-esm/errors.js +18 -0
- package/dist/node-esm/errors.js.map +1 -0
- package/dist/node-esm/index.js +426 -0
- package/dist/node-esm/index.js.map +1 -0
- package/dist/node-esm/json.js +68 -0
- package/dist/node-esm/json.js.map +1 -0
- package/dist/node-esm/math.js +51 -0
- package/dist/node-esm/math.js.map +1 -0
- package/dist/node-esm/number.js +10 -0
- package/dist/node-esm/number.js.map +1 -0
- package/dist/node-esm/objects.js +31 -0
- package/dist/node-esm/objects.js.map +1 -0
- package/dist/node-esm/strings.js +80 -0
- package/dist/node-esm/strings.js.map +1 -0
- package/dist/node-esm/tree.js +8 -0
- package/dist/node-esm/tree.js.map +1 -0
- package/dist/node-esm/validation-core.js +54 -0
- package/dist/node-esm/validation-core.js.map +1 -0
- package/dist/node-esm/validation-crypto.js +26 -0
- package/dist/node-esm/validation-crypto.js.map +1 -0
- package/dist/node-esm/validation.js +606 -0
- package/dist/node-esm/validation.js.map +1 -0
- package/dist/node-esm/validators.js +98 -0
- package/dist/node-esm/validators.js.map +1 -0
- package/dist/types/async-C8gvbSG-.d.ts +453 -0
- package/dist/types/async.d.ts +1 -0
- package/dist/types/csv.d.ts +226 -0
- package/dist/types/data.d.ts +1561 -0
- package/dist/types/dates-hTiE0Z11.d.ts +298 -0
- package/dist/types/dates.d.ts +1 -0
- package/dist/types/environment-B8eLS7KT.d.ts +420 -0
- package/dist/types/environment-detection.d.ts +102 -0
- package/dist/types/environment.d.ts +1 -0
- package/dist/types/errors.d.ts +147 -0
- package/dist/types/index.d.ts +211 -0
- package/dist/types/json.d.ts +284 -0
- package/dist/types/math-BQ9Lwdp7.d.ts +2060 -0
- package/dist/types/math.d.ts +1 -0
- package/dist/types/number-CYnQfLWj.d.ts +44 -0
- package/dist/types/number.d.ts +1 -0
- package/dist/types/objects-BohS8GCS.d.ts +1185 -0
- package/dist/types/objects.d.ts +1 -0
- package/dist/types/strings-CiqRPYLL.d.ts +1349 -0
- package/dist/types/strings.d.ts +1 -0
- package/dist/types/tree.d.ts +284 -0
- package/dist/types/validation-core-DfHF8rCG.d.ts +238 -0
- package/dist/types/validation-crypto-browser.d.ts +56 -0
- package/dist/types/validation-crypto-node.d.ts +31 -0
- package/dist/types/validation.d.ts +1 -0
- package/dist/types/validators.d.ts +216 -0
- package/package.json +253 -0
|
@@ -0,0 +1,880 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __esm = (fn, res) => function __init() {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
};
|
|
11
|
+
var __export = (target, all) => {
|
|
12
|
+
for (var name in all)
|
|
13
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
14
|
+
};
|
|
15
|
+
var __copyProps = (to, from, except, desc) => {
|
|
16
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
17
|
+
for (let key of __getOwnPropNames(from))
|
|
18
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
19
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
20
|
+
}
|
|
21
|
+
return to;
|
|
22
|
+
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
24
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
25
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
26
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
27
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
28
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
29
|
+
mod
|
|
30
|
+
));
|
|
31
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
|
+
|
|
33
|
+
// src/environment.ts
|
|
34
|
+
function isNodeEnvironment() {
|
|
35
|
+
return typeof window === "undefined" && typeof process !== "undefined" && !!process.versions?.node;
|
|
36
|
+
}
|
|
37
|
+
function isBrowserEnvironment() {
|
|
38
|
+
const win = typeof window !== "undefined" ? window : global.window;
|
|
39
|
+
const doc = typeof document !== "undefined" ? document : global.document;
|
|
40
|
+
return typeof win !== "undefined" && win !== null && typeof doc !== "undefined" && doc !== null;
|
|
41
|
+
}
|
|
42
|
+
var isNode, isBrowser;
|
|
43
|
+
var init_environment = __esm({
|
|
44
|
+
"src/environment.ts"() {
|
|
45
|
+
"use strict";
|
|
46
|
+
isNode = isNodeEnvironment;
|
|
47
|
+
isBrowser = isBrowserEnvironment;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
// src/tree.ts
|
|
52
|
+
var tree_exports = {};
|
|
53
|
+
__export(tree_exports, {
|
|
54
|
+
renderTreeAsText: () => renderTreeAsText
|
|
55
|
+
});
|
|
56
|
+
function renderTreeAsText(data, options) {
|
|
57
|
+
if (!data || !Array.isArray(data)) {
|
|
58
|
+
return "";
|
|
59
|
+
}
|
|
60
|
+
if (data.length === 0) {
|
|
61
|
+
return "";
|
|
62
|
+
}
|
|
63
|
+
const {
|
|
64
|
+
labelField = "name",
|
|
65
|
+
verticalLine = "\u2502 ",
|
|
66
|
+
middleBranch = "\u251C\u2500\u2500 ",
|
|
67
|
+
lastBranch = "\u2514\u2500\u2500 ",
|
|
68
|
+
emptySpace = " ",
|
|
69
|
+
labelFunction
|
|
70
|
+
} = options || {};
|
|
71
|
+
const visited = /* @__PURE__ */ new WeakSet();
|
|
72
|
+
const getLabel = (node) => {
|
|
73
|
+
try {
|
|
74
|
+
if (labelFunction) return String(labelFunction(node));
|
|
75
|
+
if (node == null) return "[null]";
|
|
76
|
+
if (typeof node !== "object") return String(node);
|
|
77
|
+
return node[labelField] != null ? String(node[labelField]) : String(node);
|
|
78
|
+
} catch (_error) {
|
|
79
|
+
return "[error]";
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
const renderNode = (node, prefix = "", isLast = true, depth = 0) => {
|
|
83
|
+
if (node == null) {
|
|
84
|
+
return "";
|
|
85
|
+
}
|
|
86
|
+
if (typeof node === "object" && visited.has(node)) {
|
|
87
|
+
return `${prefix + (isLast ? lastBranch : middleBranch)}[circular reference]`;
|
|
88
|
+
}
|
|
89
|
+
if (depth > 100) {
|
|
90
|
+
return `${prefix + (isLast ? lastBranch : middleBranch)}[max depth exceeded]`;
|
|
91
|
+
}
|
|
92
|
+
if (typeof node === "object") {
|
|
93
|
+
visited.add(node);
|
|
94
|
+
}
|
|
95
|
+
const lines = [];
|
|
96
|
+
const currentPrefix = isLast ? lastBranch : middleBranch;
|
|
97
|
+
lines.push(prefix + currentPrefix + getLabel(node));
|
|
98
|
+
const children = Array.isArray(node.children) ? node.children.filter((child) => child != null) : [];
|
|
99
|
+
const nextPrefix = prefix + (isLast ? emptySpace : verticalLine);
|
|
100
|
+
children.forEach((child, index) => {
|
|
101
|
+
const isLastChild = index === children.length - 1;
|
|
102
|
+
const childOutput = renderNode(child, nextPrefix, isLastChild, depth + 1);
|
|
103
|
+
if (childOutput) {
|
|
104
|
+
lines.push(childOutput);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
return lines.join("\n");
|
|
108
|
+
};
|
|
109
|
+
const validRoots = data.filter((root) => root != null);
|
|
110
|
+
if (validRoots.length === 0) {
|
|
111
|
+
return "";
|
|
112
|
+
}
|
|
113
|
+
return validRoots.map((root, index) => renderNode(root, "", index === validRoots.length - 1)).join("\n");
|
|
114
|
+
}
|
|
115
|
+
var init_tree = __esm({
|
|
116
|
+
"src/tree.ts"() {
|
|
117
|
+
"use strict";
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
// src/validators.ts
|
|
122
|
+
var validators_exports = {};
|
|
123
|
+
__export(validators_exports, {
|
|
124
|
+
isValidFilePath: () => isValidFilePath,
|
|
125
|
+
isValidFileSize: () => isValidFileSize,
|
|
126
|
+
isValidTextContent: () => isValidTextContent
|
|
127
|
+
});
|
|
128
|
+
function isValidFilePath(filePath) {
|
|
129
|
+
if (!filePath || typeof filePath !== "string") return false;
|
|
130
|
+
if (typeof filePath === "object") return false;
|
|
131
|
+
if (filePath.length === 0 || filePath.length > 1e3) return false;
|
|
132
|
+
if (filePath.includes("../") || filePath.includes("..\\")) return false;
|
|
133
|
+
const suspiciousPatterns = ["//", "\\\\", "//\\", "\\//", "/./", "\\.\\"];
|
|
134
|
+
if (suspiciousPatterns.some((pattern) => filePath.includes(pattern))) return false;
|
|
135
|
+
const encodedPatterns = [
|
|
136
|
+
"%2e%2e%2f",
|
|
137
|
+
// ../
|
|
138
|
+
"%2e%2e/",
|
|
139
|
+
// ../
|
|
140
|
+
"%2e%2e%5c",
|
|
141
|
+
// ..\
|
|
142
|
+
"%252e"
|
|
143
|
+
// double-encoded
|
|
144
|
+
];
|
|
145
|
+
if (encodedPatterns.some((pattern) => filePath.toLowerCase().includes(pattern))) return false;
|
|
146
|
+
if (filePath.includes("\0")) return false;
|
|
147
|
+
const commandChars = [";", "&", "|", "`", "$", "(", ")", "{", "}"];
|
|
148
|
+
if (commandChars.some((char) => filePath.includes(char))) return false;
|
|
149
|
+
const sqlPatterns = ["'", '"', "--", "/*", "*/", "DROP", "DELETE", "UNION", "SELECT"];
|
|
150
|
+
const lowerPath = filePath.toLowerCase();
|
|
151
|
+
if (sqlPatterns.some(
|
|
152
|
+
(pattern) => lowerPath.includes(pattern.toLowerCase()) && (pattern === "'" || pattern === '"' || lowerPath.includes(` ${pattern.toLowerCase()}`))
|
|
153
|
+
))
|
|
154
|
+
return false;
|
|
155
|
+
const dangerousUnicode = [
|
|
156
|
+
"\u202E",
|
|
157
|
+
// Right-to-left override
|
|
158
|
+
"\u200B",
|
|
159
|
+
// Zero-width space
|
|
160
|
+
"\u200C",
|
|
161
|
+
// Zero-width non-joiner
|
|
162
|
+
"\u200D",
|
|
163
|
+
// Zero-width joiner
|
|
164
|
+
"\uFEFF"
|
|
165
|
+
// Zero-width no-break space
|
|
166
|
+
];
|
|
167
|
+
if (dangerousUnicode.some((char) => filePath.includes(char))) return false;
|
|
168
|
+
if (/^[A-Za-z]:\\.*\\\.\./.test(filePath)) return false;
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
function isValidFileSize(size, maxSize) {
|
|
172
|
+
return typeof size === "number" && size >= 0 && size <= maxSize;
|
|
173
|
+
}
|
|
174
|
+
function isValidTextContent(content, options = {}) {
|
|
175
|
+
const { maxLength = 1e6 } = options;
|
|
176
|
+
if (typeof content !== "string") return false;
|
|
177
|
+
if (content.length > maxLength) return false;
|
|
178
|
+
const lowerContent = content.toLowerCase();
|
|
179
|
+
const scriptPatterns = ["<script", "</script", "<scr<script>ipt", "<scr\0ipt"];
|
|
180
|
+
if (scriptPatterns.some((pattern) => lowerContent.includes(pattern))) return false;
|
|
181
|
+
const eventHandlers = [
|
|
182
|
+
"onerror",
|
|
183
|
+
"onload",
|
|
184
|
+
"onclick",
|
|
185
|
+
"onmouseover",
|
|
186
|
+
"onfocus",
|
|
187
|
+
"onblur",
|
|
188
|
+
"oninput"
|
|
189
|
+
];
|
|
190
|
+
if (eventHandlers.some((handler) => lowerContent.includes(handler))) return false;
|
|
191
|
+
const protocolPatterns = [
|
|
192
|
+
"javascript:",
|
|
193
|
+
"data:text/html",
|
|
194
|
+
"data:text/javascript",
|
|
195
|
+
"data:application",
|
|
196
|
+
"vbscript:",
|
|
197
|
+
"file:///",
|
|
198
|
+
"steam://",
|
|
199
|
+
"slack://"
|
|
200
|
+
];
|
|
201
|
+
if (protocolPatterns.some((pattern) => lowerContent.includes(pattern))) return false;
|
|
202
|
+
const encodedPatterns = [
|
|
203
|
+
"<script",
|
|
204
|
+
// < = <
|
|
205
|
+
"%3cscript",
|
|
206
|
+
// %3c = <
|
|
207
|
+
"\\x3cscript",
|
|
208
|
+
// \x3c = <
|
|
209
|
+
"\\u003cscript"
|
|
210
|
+
// \u003c = <
|
|
211
|
+
];
|
|
212
|
+
if (encodedPatterns.some((pattern) => lowerContent.includes(pattern))) return false;
|
|
213
|
+
if (lowerContent.includes("<svg") && lowerContent.includes("onload")) return false;
|
|
214
|
+
if (lowerContent.includes("<iframe")) return false;
|
|
215
|
+
return true;
|
|
216
|
+
}
|
|
217
|
+
var init_validators = __esm({
|
|
218
|
+
"src/validators.ts"() {
|
|
219
|
+
"use strict";
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
// src/csv.ts
|
|
224
|
+
var csv_exports = {};
|
|
225
|
+
__export(csv_exports, {
|
|
226
|
+
exportCSV: () => exportCSV,
|
|
227
|
+
importCSV: () => importCSV
|
|
228
|
+
});
|
|
229
|
+
async function exportCSV(data, filePath, options) {
|
|
230
|
+
if (data == null) {
|
|
231
|
+
throw new TypeError("Data cannot be null or undefined");
|
|
232
|
+
}
|
|
233
|
+
if (!Array.isArray(data)) {
|
|
234
|
+
throw new TypeError("Data must be an array");
|
|
235
|
+
}
|
|
236
|
+
if (data.length === 0) {
|
|
237
|
+
throw new Error("Data array cannot be empty");
|
|
238
|
+
}
|
|
239
|
+
if (!filePath || typeof filePath !== "string" || filePath.trim() === "") {
|
|
240
|
+
throw new TypeError("File path must be a non-empty string");
|
|
241
|
+
}
|
|
242
|
+
const csvText = import_papaparse.default.unparse(data, {
|
|
243
|
+
delimiter: ";",
|
|
244
|
+
header: true,
|
|
245
|
+
...options
|
|
246
|
+
});
|
|
247
|
+
if (isNode()) {
|
|
248
|
+
const fs = await import("fs/promises");
|
|
249
|
+
await fs.writeFile(filePath, `\uFEFF${csvText}`, { encoding: "utf-8" });
|
|
250
|
+
} else {
|
|
251
|
+
const blob = new Blob([`\uFEFF${csvText}`], { type: "text/csv;charset=utf-8" });
|
|
252
|
+
const url = URL.createObjectURL(blob);
|
|
253
|
+
const link = document.createElement("a");
|
|
254
|
+
link.href = url;
|
|
255
|
+
link.download = filePath.split("/").pop() || "data.csv";
|
|
256
|
+
document.body.appendChild(link);
|
|
257
|
+
link.click();
|
|
258
|
+
document.body.removeChild(link);
|
|
259
|
+
URL.revokeObjectURL(url);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
async function importCSV(filePath, options) {
|
|
263
|
+
if (!filePath || typeof filePath !== "string" || filePath.trim() === "") {
|
|
264
|
+
throw new TypeError("File path must be a non-empty string");
|
|
265
|
+
}
|
|
266
|
+
if (isNode()) {
|
|
267
|
+
const fs = await import("fs/promises");
|
|
268
|
+
const content = await fs.readFile(filePath, { encoding: "utf-8" });
|
|
269
|
+
const parseResult = import_papaparse.default.parse(content, {
|
|
270
|
+
header: true,
|
|
271
|
+
delimiter: ";",
|
|
272
|
+
skipEmptyLines: true,
|
|
273
|
+
...options
|
|
274
|
+
});
|
|
275
|
+
return parseResult.data || [];
|
|
276
|
+
} else {
|
|
277
|
+
throw new Error("CSV import not supported in browser. Use readFileAsText() with a File object.");
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
var import_papaparse;
|
|
281
|
+
var init_csv = __esm({
|
|
282
|
+
"src/csv.ts"() {
|
|
283
|
+
"use strict";
|
|
284
|
+
import_papaparse = __toESM(require("papaparse"));
|
|
285
|
+
init_environment();
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
// src/json.ts
|
|
290
|
+
var json_exports = {};
|
|
291
|
+
__export(json_exports, {
|
|
292
|
+
exportJSON: () => exportJSON,
|
|
293
|
+
importJSON: () => importJSON
|
|
294
|
+
});
|
|
295
|
+
async function exportJSON(data, filePath, options) {
|
|
296
|
+
if (data === null || data === void 0) {
|
|
297
|
+
throw new TypeError("Data cannot be null or undefined");
|
|
298
|
+
}
|
|
299
|
+
if (!filePath || typeof filePath !== "string" || filePath.trim() === "") {
|
|
300
|
+
throw new TypeError("File path must be a non-empty string");
|
|
301
|
+
}
|
|
302
|
+
const { indent = 2 } = options || {};
|
|
303
|
+
let jsonText;
|
|
304
|
+
try {
|
|
305
|
+
jsonText = JSON.stringify(data, null, indent);
|
|
306
|
+
} catch (error) {
|
|
307
|
+
if (error instanceof TypeError && error.message.includes("circular")) {
|
|
308
|
+
throw new TypeError("Cannot serialize data with circular references");
|
|
309
|
+
}
|
|
310
|
+
throw error;
|
|
311
|
+
}
|
|
312
|
+
if (isNode()) {
|
|
313
|
+
const fs = await import("fs/promises");
|
|
314
|
+
await fs.writeFile(filePath, jsonText, { encoding: "utf-8" });
|
|
315
|
+
} else {
|
|
316
|
+
const blob = new Blob([jsonText], { type: "application/json;charset=utf-8" });
|
|
317
|
+
const url = URL.createObjectURL(blob);
|
|
318
|
+
const link = document.createElement("a");
|
|
319
|
+
link.href = url;
|
|
320
|
+
link.download = filePath.split("/").pop() || "data.json";
|
|
321
|
+
document.body.appendChild(link);
|
|
322
|
+
link.click();
|
|
323
|
+
document.body.removeChild(link);
|
|
324
|
+
URL.revokeObjectURL(url);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
async function importJSON(filePath, _options) {
|
|
328
|
+
if (!filePath || typeof filePath !== "string" || filePath.trim() === "") {
|
|
329
|
+
throw new TypeError("File path must be a non-empty string");
|
|
330
|
+
}
|
|
331
|
+
if (isNode()) {
|
|
332
|
+
const fs = await import("fs/promises");
|
|
333
|
+
const content = await fs.readFile(filePath, { encoding: "utf-8" });
|
|
334
|
+
const trimmed = content.trim();
|
|
335
|
+
if (trimmed === "") {
|
|
336
|
+
throw new SyntaxError("JSON file is empty");
|
|
337
|
+
}
|
|
338
|
+
try {
|
|
339
|
+
return JSON.parse(content);
|
|
340
|
+
} catch (error) {
|
|
341
|
+
if (error instanceof SyntaxError) {
|
|
342
|
+
throw new SyntaxError(`Invalid JSON in file ${filePath}: ${error.message}`);
|
|
343
|
+
}
|
|
344
|
+
throw error;
|
|
345
|
+
}
|
|
346
|
+
} else {
|
|
347
|
+
throw new Error(
|
|
348
|
+
"JSON import not supported in browser. Use readFileAsText() with a File object."
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
var init_json = __esm({
|
|
353
|
+
"src/json.ts"() {
|
|
354
|
+
"use strict";
|
|
355
|
+
init_environment();
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
// src/data.ts
|
|
360
|
+
var data_exports = {};
|
|
361
|
+
__export(data_exports, {
|
|
362
|
+
detectFileExtension: () => detectFileExtension,
|
|
363
|
+
detectFormatFromFilename: () => detectFormatFromFilename,
|
|
364
|
+
detectUniversalFormat: () => detectUniversalFormat,
|
|
365
|
+
exportData: () => exportData,
|
|
366
|
+
exportTree: () => exportTree,
|
|
367
|
+
exportTxt: () => exportTxt,
|
|
368
|
+
importData: () => importData,
|
|
369
|
+
importTree: () => importTree,
|
|
370
|
+
importTxt: () => importTxt,
|
|
371
|
+
readFileAsText: () => readFileAsText,
|
|
372
|
+
validateCSVData: () => validateCSVData,
|
|
373
|
+
validateExportData: () => validateExportData
|
|
374
|
+
});
|
|
375
|
+
module.exports = __toCommonJS(data_exports);
|
|
376
|
+
|
|
377
|
+
// src/errors.ts
|
|
378
|
+
var TsHelpersError = class _TsHelpersError extends Error {
|
|
379
|
+
constructor(message, options = {}) {
|
|
380
|
+
super(message);
|
|
381
|
+
this.name = "TsHelpersError";
|
|
382
|
+
this.code = options.code;
|
|
383
|
+
this.data = options.data;
|
|
384
|
+
this.cause = options.cause;
|
|
385
|
+
if (Error.captureStackTrace) {
|
|
386
|
+
Error.captureStackTrace(this, _TsHelpersError);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
var DataError = class extends TsHelpersError {
|
|
391
|
+
constructor(message, code, data) {
|
|
392
|
+
super(message, { code, data });
|
|
393
|
+
this.name = "DataError";
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
function createValidationError(message, field, value) {
|
|
397
|
+
return new TsHelpersError(`Validation failed: ${message}`, {
|
|
398
|
+
code: "VALIDATION_FAILED" /* VALIDATION_FAILED */,
|
|
399
|
+
data: { field, value }
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// src/data.ts
|
|
404
|
+
init_environment();
|
|
405
|
+
var readFileAsText = async (fileOrPath, encoding = "utf8") => {
|
|
406
|
+
if (isNode() && typeof fileOrPath === "string") {
|
|
407
|
+
const fs = await import("fs/promises");
|
|
408
|
+
return fs.readFile(fileOrPath, encoding);
|
|
409
|
+
} else if (isBrowser() && fileOrPath instanceof File) {
|
|
410
|
+
return new Promise((resolve, reject) => {
|
|
411
|
+
const reader = new FileReader();
|
|
412
|
+
reader.onload = (e) => resolve(e.target?.result);
|
|
413
|
+
reader.onerror = () => reject(new Error("Error reading file"));
|
|
414
|
+
reader.readAsText(fileOrPath);
|
|
415
|
+
});
|
|
416
|
+
} else {
|
|
417
|
+
throw new DataError(
|
|
418
|
+
"Invalid parameter for current environment",
|
|
419
|
+
"ENVIRONMENT_NOT_SUPPORTED" /* ENVIRONMENT_NOT_SUPPORTED */,
|
|
420
|
+
{
|
|
421
|
+
data: {
|
|
422
|
+
isNodeEnv: isNode(),
|
|
423
|
+
isBrowserEnv: isBrowser(),
|
|
424
|
+
parameterType: typeof fileOrPath
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
);
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
function validateExportData(data) {
|
|
431
|
+
if (!Array.isArray(data)) {
|
|
432
|
+
throw createValidationError("Data must be an array", "data", typeof data);
|
|
433
|
+
}
|
|
434
|
+
if (data.length === 0) {
|
|
435
|
+
throw createValidationError("Data array cannot be empty", "data.length", data.length);
|
|
436
|
+
}
|
|
437
|
+
const firstItem = data[0];
|
|
438
|
+
const isObjectArray = typeof firstItem === "object" && firstItem !== null && !Array.isArray(firstItem);
|
|
439
|
+
const isArrayOfArrays = Array.isArray(firstItem);
|
|
440
|
+
if (!isObjectArray && !isArrayOfArrays) {
|
|
441
|
+
throw createValidationError(
|
|
442
|
+
"Data must be an array of objects or an array of arrays",
|
|
443
|
+
"data[0]",
|
|
444
|
+
typeof firstItem
|
|
445
|
+
);
|
|
446
|
+
}
|
|
447
|
+
if (isObjectArray) {
|
|
448
|
+
for (let i = 1; i < data.length; i++) {
|
|
449
|
+
const item = data[i];
|
|
450
|
+
if (typeof item !== "object" || item === null || Array.isArray(item)) {
|
|
451
|
+
throw createValidationError(
|
|
452
|
+
"All elements must be objects if first one is an object",
|
|
453
|
+
`data[${i}]`,
|
|
454
|
+
typeof item
|
|
455
|
+
);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
} else if (isArrayOfArrays) {
|
|
459
|
+
const firstRowLength = firstItem.length;
|
|
460
|
+
for (let i = 1; i < data.length; i++) {
|
|
461
|
+
if (!Array.isArray(data[i])) {
|
|
462
|
+
throw createValidationError(`Row ${i} is not an array`, `data[${i}]`, typeof data[i]);
|
|
463
|
+
}
|
|
464
|
+
if (data[i].length !== firstRowLength) {
|
|
465
|
+
throw createValidationError(
|
|
466
|
+
`Row ${i} has ${data[i].length} columns, but first has ${firstRowLength}`,
|
|
467
|
+
`data[${i}].length`,
|
|
468
|
+
{ expected: firstRowLength, actual: data[i].length }
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
return true;
|
|
474
|
+
}
|
|
475
|
+
var validateCSVData = validateExportData;
|
|
476
|
+
function detectFormatFromFilename(filename) {
|
|
477
|
+
const parts = filename.toLowerCase().split(".");
|
|
478
|
+
const extension = parts.length > 1 ? parts.pop() : void 0;
|
|
479
|
+
switch (extension) {
|
|
480
|
+
case "csv":
|
|
481
|
+
return "csv";
|
|
482
|
+
case "json":
|
|
483
|
+
return "json";
|
|
484
|
+
case "tree":
|
|
485
|
+
return "tree";
|
|
486
|
+
case "txt":
|
|
487
|
+
return "txt";
|
|
488
|
+
default:
|
|
489
|
+
if (!extension) {
|
|
490
|
+
throw new DataError(
|
|
491
|
+
"Could not detect file format. Must have a valid extension (.csv, .json, .tree, .txt)",
|
|
492
|
+
"UNSUPPORTED_FORMAT" /* UNSUPPORTED_FORMAT */,
|
|
493
|
+
{ data: { filename } }
|
|
494
|
+
);
|
|
495
|
+
}
|
|
496
|
+
throw new DataError(
|
|
497
|
+
`Unsupported file format: .${extension}. Use .csv, .json, .tree or .txt`,
|
|
498
|
+
"UNSUPPORTED_FORMAT" /* UNSUPPORTED_FORMAT */,
|
|
499
|
+
{ data: { filename, extension } }
|
|
500
|
+
);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
function detectFileExtension(filename) {
|
|
504
|
+
if (!filename || typeof filename !== "string") {
|
|
505
|
+
return null;
|
|
506
|
+
}
|
|
507
|
+
const parts = filename.trim().split(".");
|
|
508
|
+
if (parts.length < 2) {
|
|
509
|
+
return null;
|
|
510
|
+
}
|
|
511
|
+
const extension = parts.pop()?.toLowerCase();
|
|
512
|
+
return extension || null;
|
|
513
|
+
}
|
|
514
|
+
function detectUniversalFormat(filename) {
|
|
515
|
+
const extension = detectFileExtension(filename);
|
|
516
|
+
if (!extension) {
|
|
517
|
+
return {
|
|
518
|
+
extension: null,
|
|
519
|
+
category: "unknown",
|
|
520
|
+
isText: false,
|
|
521
|
+
isBinary: false,
|
|
522
|
+
mimeType: null
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
const formatInfo = {
|
|
526
|
+
// Data formats
|
|
527
|
+
json: { category: "data", isText: true, isBinary: false, mimeType: "application/json" },
|
|
528
|
+
csv: { category: "data", isText: true, isBinary: false, mimeType: "text/csv" },
|
|
529
|
+
xml: { category: "data", isText: true, isBinary: false, mimeType: "application/xml" },
|
|
530
|
+
yaml: { category: "data", isText: true, isBinary: false, mimeType: "application/yaml" },
|
|
531
|
+
yml: { category: "data", isText: true, isBinary: false, mimeType: "application/yaml" },
|
|
532
|
+
tree: { category: "data", isText: true, isBinary: false, mimeType: "text/plain" },
|
|
533
|
+
tsv: { category: "data", isText: true, isBinary: false, mimeType: "text/tab-separated-values" },
|
|
534
|
+
sql: { category: "data", isText: true, isBinary: false, mimeType: "application/sql" },
|
|
535
|
+
db: { category: "data", isText: false, isBinary: true, mimeType: "application/x-sqlite3" },
|
|
536
|
+
sqlite: { category: "data", isText: false, isBinary: true, mimeType: "application/x-sqlite3" },
|
|
537
|
+
// Text and code formats
|
|
538
|
+
txt: { category: "text", isText: true, isBinary: false, mimeType: "text/plain" },
|
|
539
|
+
md: { category: "text", isText: true, isBinary: false, mimeType: "text/markdown" },
|
|
540
|
+
rst: { category: "text", isText: true, isBinary: false, mimeType: "text/x-rst" },
|
|
541
|
+
rtf: { category: "text", isText: true, isBinary: false, mimeType: "application/rtf" },
|
|
542
|
+
log: { category: "text", isText: true, isBinary: false, mimeType: "text/plain" },
|
|
543
|
+
// Web formats
|
|
544
|
+
html: { category: "web", isText: true, isBinary: false, mimeType: "text/html" },
|
|
545
|
+
htm: { category: "web", isText: true, isBinary: false, mimeType: "text/html" },
|
|
546
|
+
css: { category: "web", isText: true, isBinary: false, mimeType: "text/css" },
|
|
547
|
+
scss: { category: "web", isText: true, isBinary: false, mimeType: "text/x-scss" },
|
|
548
|
+
sass: { category: "web", isText: true, isBinary: false, mimeType: "text/x-sass" },
|
|
549
|
+
less: { category: "web", isText: true, isBinary: false, mimeType: "text/x-less" },
|
|
550
|
+
// Programming languages
|
|
551
|
+
js: { category: "code", isText: true, isBinary: false, mimeType: "application/javascript" },
|
|
552
|
+
mjs: { category: "code", isText: true, isBinary: false, mimeType: "application/javascript" },
|
|
553
|
+
jsx: { category: "code", isText: true, isBinary: false, mimeType: "text/jsx" },
|
|
554
|
+
ts: { category: "code", isText: true, isBinary: false, mimeType: "application/typescript" },
|
|
555
|
+
tsx: { category: "code", isText: true, isBinary: false, mimeType: "text/tsx" },
|
|
556
|
+
py: { category: "code", isText: true, isBinary: false, mimeType: "text/x-python" },
|
|
557
|
+
java: { category: "code", isText: true, isBinary: false, mimeType: "text/x-java-source" },
|
|
558
|
+
php: { category: "code", isText: true, isBinary: false, mimeType: "application/x-httpd-php" },
|
|
559
|
+
rb: { category: "code", isText: true, isBinary: false, mimeType: "text/x-ruby" },
|
|
560
|
+
go: { category: "code", isText: true, isBinary: false, mimeType: "text/x-go" },
|
|
561
|
+
rs: { category: "code", isText: true, isBinary: false, mimeType: "text/x-rust" },
|
|
562
|
+
c: { category: "code", isText: true, isBinary: false, mimeType: "text/x-c" },
|
|
563
|
+
cpp: { category: "code", isText: true, isBinary: false, mimeType: "text/x-c++" },
|
|
564
|
+
cc: { category: "code", isText: true, isBinary: false, mimeType: "text/x-c++" },
|
|
565
|
+
h: { category: "code", isText: true, isBinary: false, mimeType: "text/x-c" },
|
|
566
|
+
cs: { category: "code", isText: true, isBinary: false, mimeType: "text/x-csharp" },
|
|
567
|
+
sh: { category: "code", isText: true, isBinary: false, mimeType: "application/x-sh" },
|
|
568
|
+
bash: { category: "code", isText: true, isBinary: false, mimeType: "application/x-sh" },
|
|
569
|
+
ps1: { category: "code", isText: true, isBinary: false, mimeType: "application/x-powershell" },
|
|
570
|
+
// Microsoft Office documents
|
|
571
|
+
doc: { category: "document", isText: false, isBinary: true, mimeType: "application/msword" },
|
|
572
|
+
docx: {
|
|
573
|
+
category: "document",
|
|
574
|
+
isText: false,
|
|
575
|
+
isBinary: true,
|
|
576
|
+
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
|
577
|
+
},
|
|
578
|
+
xls: {
|
|
579
|
+
category: "spreadsheet",
|
|
580
|
+
isText: false,
|
|
581
|
+
isBinary: true,
|
|
582
|
+
mimeType: "application/vnd.ms-excel"
|
|
583
|
+
},
|
|
584
|
+
xlsx: {
|
|
585
|
+
category: "spreadsheet",
|
|
586
|
+
isText: false,
|
|
587
|
+
isBinary: true,
|
|
588
|
+
mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
589
|
+
},
|
|
590
|
+
ppt: {
|
|
591
|
+
category: "presentation",
|
|
592
|
+
isText: false,
|
|
593
|
+
isBinary: true,
|
|
594
|
+
mimeType: "application/vnd.ms-powerpoint"
|
|
595
|
+
},
|
|
596
|
+
pptx: {
|
|
597
|
+
category: "presentation",
|
|
598
|
+
isText: false,
|
|
599
|
+
isBinary: true,
|
|
600
|
+
mimeType: "application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
|
601
|
+
},
|
|
602
|
+
// LibreOffice/OpenOffice
|
|
603
|
+
odt: {
|
|
604
|
+
category: "document",
|
|
605
|
+
isText: false,
|
|
606
|
+
isBinary: true,
|
|
607
|
+
mimeType: "application/vnd.oasis.opendocument.text"
|
|
608
|
+
},
|
|
609
|
+
ods: {
|
|
610
|
+
category: "spreadsheet",
|
|
611
|
+
isText: false,
|
|
612
|
+
isBinary: true,
|
|
613
|
+
mimeType: "application/vnd.oasis.opendocument.spreadsheet"
|
|
614
|
+
},
|
|
615
|
+
odp: {
|
|
616
|
+
category: "presentation",
|
|
617
|
+
isText: false,
|
|
618
|
+
isBinary: true,
|
|
619
|
+
mimeType: "application/vnd.oasis.opendocument.presentation"
|
|
620
|
+
},
|
|
621
|
+
// Other document formats
|
|
622
|
+
pdf: { category: "document", isText: false, isBinary: true, mimeType: "application/pdf" },
|
|
623
|
+
epub: { category: "document", isText: false, isBinary: true, mimeType: "application/epub+zip" },
|
|
624
|
+
mobi: {
|
|
625
|
+
category: "document",
|
|
626
|
+
isText: false,
|
|
627
|
+
isBinary: true,
|
|
628
|
+
mimeType: "application/x-mobipocket-ebook"
|
|
629
|
+
},
|
|
630
|
+
// Image formats
|
|
631
|
+
jpg: { category: "image", isText: false, isBinary: true, mimeType: "image/jpeg" },
|
|
632
|
+
jpeg: { category: "image", isText: false, isBinary: true, mimeType: "image/jpeg" },
|
|
633
|
+
png: { category: "image", isText: false, isBinary: true, mimeType: "image/png" },
|
|
634
|
+
gif: { category: "image", isText: false, isBinary: true, mimeType: "image/gif" },
|
|
635
|
+
svg: { category: "image", isText: true, isBinary: false, mimeType: "image/svg+xml" },
|
|
636
|
+
webp: { category: "image", isText: false, isBinary: true, mimeType: "image/webp" },
|
|
637
|
+
avif: { category: "image", isText: false, isBinary: true, mimeType: "image/avif" },
|
|
638
|
+
bmp: { category: "image", isText: false, isBinary: true, mimeType: "image/bmp" },
|
|
639
|
+
tiff: { category: "image", isText: false, isBinary: true, mimeType: "image/tiff" },
|
|
640
|
+
tif: { category: "image", isText: false, isBinary: true, mimeType: "image/tiff" },
|
|
641
|
+
ico: { category: "image", isText: false, isBinary: true, mimeType: "image/x-icon" },
|
|
642
|
+
psd: {
|
|
643
|
+
category: "image",
|
|
644
|
+
isText: false,
|
|
645
|
+
isBinary: true,
|
|
646
|
+
mimeType: "image/vnd.adobe.photoshop"
|
|
647
|
+
},
|
|
648
|
+
// Audio formats
|
|
649
|
+
mp3: { category: "audio", isText: false, isBinary: true, mimeType: "audio/mpeg" },
|
|
650
|
+
wav: { category: "audio", isText: false, isBinary: true, mimeType: "audio/wav" },
|
|
651
|
+
flac: { category: "audio", isText: false, isBinary: true, mimeType: "audio/flac" },
|
|
652
|
+
ogg: { category: "audio", isText: false, isBinary: true, mimeType: "audio/ogg" },
|
|
653
|
+
aac: { category: "audio", isText: false, isBinary: true, mimeType: "audio/aac" },
|
|
654
|
+
m4a: { category: "audio", isText: false, isBinary: true, mimeType: "audio/m4a" },
|
|
655
|
+
wma: { category: "audio", isText: false, isBinary: true, mimeType: "audio/x-ms-wma" },
|
|
656
|
+
// Video formats
|
|
657
|
+
mp4: { category: "video", isText: false, isBinary: true, mimeType: "video/mp4" },
|
|
658
|
+
avi: { category: "video", isText: false, isBinary: true, mimeType: "video/x-msvideo" },
|
|
659
|
+
mov: { category: "video", isText: false, isBinary: true, mimeType: "video/quicktime" },
|
|
660
|
+
wmv: { category: "video", isText: false, isBinary: true, mimeType: "video/x-ms-wmv" },
|
|
661
|
+
flv: { category: "video", isText: false, isBinary: true, mimeType: "video/x-flv" },
|
|
662
|
+
webm: { category: "video", isText: false, isBinary: true, mimeType: "video/webm" },
|
|
663
|
+
mkv: { category: "video", isText: false, isBinary: true, mimeType: "video/x-matroska" },
|
|
664
|
+
"3gp": { category: "video", isText: false, isBinary: true, mimeType: "video/3gpp" },
|
|
665
|
+
// Archive formats
|
|
666
|
+
zip: { category: "archive", isText: false, isBinary: true, mimeType: "application/zip" },
|
|
667
|
+
rar: {
|
|
668
|
+
category: "archive",
|
|
669
|
+
isText: false,
|
|
670
|
+
isBinary: true,
|
|
671
|
+
mimeType: "application/x-rar-compressed"
|
|
672
|
+
},
|
|
673
|
+
"7z": {
|
|
674
|
+
category: "archive",
|
|
675
|
+
isText: false,
|
|
676
|
+
isBinary: true,
|
|
677
|
+
mimeType: "application/x-7z-compressed"
|
|
678
|
+
},
|
|
679
|
+
tar: { category: "archive", isText: false, isBinary: true, mimeType: "application/x-tar" },
|
|
680
|
+
gz: { category: "archive", isText: false, isBinary: true, mimeType: "application/gzip" },
|
|
681
|
+
bz2: { category: "archive", isText: false, isBinary: true, mimeType: "application/x-bzip2" },
|
|
682
|
+
xz: { category: "archive", isText: false, isBinary: true, mimeType: "application/x-xz" },
|
|
683
|
+
// Configuration files
|
|
684
|
+
ini: { category: "config", isText: true, isBinary: false, mimeType: "text/plain" },
|
|
685
|
+
cfg: { category: "config", isText: true, isBinary: false, mimeType: "text/plain" },
|
|
686
|
+
conf: { category: "config", isText: true, isBinary: false, mimeType: "text/plain" },
|
|
687
|
+
toml: { category: "config", isText: true, isBinary: false, mimeType: "application/toml" },
|
|
688
|
+
env: { category: "config", isText: true, isBinary: false, mimeType: "text/plain" },
|
|
689
|
+
// Font formats
|
|
690
|
+
ttf: { category: "font", isText: false, isBinary: true, mimeType: "font/ttf" },
|
|
691
|
+
otf: { category: "font", isText: false, isBinary: true, mimeType: "font/otf" },
|
|
692
|
+
woff: { category: "font", isText: false, isBinary: true, mimeType: "font/woff" },
|
|
693
|
+
woff2: { category: "font", isText: false, isBinary: true, mimeType: "font/woff2" },
|
|
694
|
+
eot: {
|
|
695
|
+
category: "font",
|
|
696
|
+
isText: false,
|
|
697
|
+
isBinary: true,
|
|
698
|
+
mimeType: "application/vnd.ms-fontobject"
|
|
699
|
+
}
|
|
700
|
+
};
|
|
701
|
+
const info = formatInfo[extension] || {
|
|
702
|
+
category: "unknown",
|
|
703
|
+
isText: false,
|
|
704
|
+
isBinary: false,
|
|
705
|
+
mimeType: null
|
|
706
|
+
};
|
|
707
|
+
return {
|
|
708
|
+
extension,
|
|
709
|
+
...info
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
async function exportTree(data, filePath, options) {
|
|
713
|
+
if (!Array.isArray(data)) {
|
|
714
|
+
throw createValidationError(
|
|
715
|
+
"Data for tree format must be an array of nodes",
|
|
716
|
+
"data",
|
|
717
|
+
typeof data
|
|
718
|
+
);
|
|
719
|
+
}
|
|
720
|
+
const { renderTreeAsText: renderTreeAsText2 } = await Promise.resolve().then(() => (init_tree(), tree_exports));
|
|
721
|
+
const treeText = renderTreeAsText2(data, options);
|
|
722
|
+
if (isNode()) {
|
|
723
|
+
const fs = await import("fs/promises");
|
|
724
|
+
await fs.writeFile(filePath, treeText, { encoding: "utf-8" });
|
|
725
|
+
} else {
|
|
726
|
+
const blob = new Blob([treeText], { type: "text/plain;charset=utf-8" });
|
|
727
|
+
const url = URL.createObjectURL(blob);
|
|
728
|
+
const link = document.createElement("a");
|
|
729
|
+
link.href = url;
|
|
730
|
+
link.download = filePath.split("/").pop() || "tree.tree";
|
|
731
|
+
document.body.appendChild(link);
|
|
732
|
+
link.click();
|
|
733
|
+
document.body.removeChild(link);
|
|
734
|
+
URL.revokeObjectURL(url);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
async function importTree(filePath, _options) {
|
|
738
|
+
if (isNode()) {
|
|
739
|
+
const fs = await import("fs/promises");
|
|
740
|
+
return fs.readFile(filePath, { encoding: "utf-8" });
|
|
741
|
+
} else {
|
|
742
|
+
throw new DataError(
|
|
743
|
+
".tree file import is not supported in browser. Use readFileAsText() with a File object.",
|
|
744
|
+
"ENVIRONMENT_NOT_SUPPORTED" /* ENVIRONMENT_NOT_SUPPORTED */,
|
|
745
|
+
{ data: { environment: "browser", operation: "importTree" } }
|
|
746
|
+
);
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
async function exportTxt(data, filePath, options) {
|
|
750
|
+
const { separator = "\n", stringify, indent = 2 } = options || {};
|
|
751
|
+
let textContent;
|
|
752
|
+
if (stringify) {
|
|
753
|
+
textContent = stringify(data);
|
|
754
|
+
} else if (typeof data === "string") {
|
|
755
|
+
textContent = data;
|
|
756
|
+
} else if (Array.isArray(data)) {
|
|
757
|
+
textContent = data.map((item) => typeof item === "string" ? item : JSON.stringify(item, null, indent)).join(separator);
|
|
758
|
+
} else if (typeof data === "object" && data !== null) {
|
|
759
|
+
textContent = JSON.stringify(data, null, indent);
|
|
760
|
+
} else {
|
|
761
|
+
textContent = String(data);
|
|
762
|
+
}
|
|
763
|
+
if (isNode()) {
|
|
764
|
+
const fs = await import("fs/promises");
|
|
765
|
+
await fs.writeFile(filePath, textContent, { encoding: "utf-8" });
|
|
766
|
+
} else {
|
|
767
|
+
const blob = new Blob([textContent], { type: "text/plain;charset=utf-8" });
|
|
768
|
+
const url = URL.createObjectURL(blob);
|
|
769
|
+
const link = document.createElement("a");
|
|
770
|
+
link.href = url;
|
|
771
|
+
link.download = filePath.split("/").pop() || "file.txt";
|
|
772
|
+
document.body.appendChild(link);
|
|
773
|
+
link.click();
|
|
774
|
+
document.body.removeChild(link);
|
|
775
|
+
URL.revokeObjectURL(url);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
function sanitizeTextContent(content) {
|
|
779
|
+
return content.replace(/\r\n|\r/g, "\n").replace(/[\x00-\x08\x0E-\x1F\x7F]/g, "").replace(/\n{4,}/g, "\n\n\n").replace(/[ \t]+$/gm, "");
|
|
780
|
+
}
|
|
781
|
+
async function importTxt(filePath, options = {}) {
|
|
782
|
+
const {
|
|
783
|
+
maxFileSize = 10 * 1024 * 1024,
|
|
784
|
+
// 10MB default
|
|
785
|
+
maxLength = 1e6,
|
|
786
|
+
// 1M characters default
|
|
787
|
+
validateSecurity = true,
|
|
788
|
+
sanitize = true
|
|
789
|
+
} = options;
|
|
790
|
+
if (isNode()) {
|
|
791
|
+
const fs = await import("fs/promises");
|
|
792
|
+
const path = await import("path");
|
|
793
|
+
const { isValidFilePath: isValidFilePath2, isValidFileSize: isValidFileSize2, isValidTextContent: isValidTextContent2 } = await Promise.resolve().then(() => (init_validators(), validators_exports));
|
|
794
|
+
if (!isValidFilePath2(filePath)) {
|
|
795
|
+
throw new Error("Invalid or unsafe file path");
|
|
796
|
+
}
|
|
797
|
+
const resolvedPath = path.resolve(filePath);
|
|
798
|
+
try {
|
|
799
|
+
const stats = await fs.stat(resolvedPath);
|
|
800
|
+
if (!isValidFileSize2(stats.size, maxFileSize)) {
|
|
801
|
+
throw new Error(`File too large: ${stats.size} bytes (max: ${maxFileSize})`);
|
|
802
|
+
}
|
|
803
|
+
} catch (error) {
|
|
804
|
+
if (error.code === "ENOENT") {
|
|
805
|
+
throw new Error(`File not found: ${filePath}`);
|
|
806
|
+
}
|
|
807
|
+
throw error;
|
|
808
|
+
}
|
|
809
|
+
const content = await fs.readFile(resolvedPath, { encoding: "utf-8" });
|
|
810
|
+
if (validateSecurity && !isValidTextContent2(content, { maxLength })) {
|
|
811
|
+
throw new Error("File contains potentially dangerous content or exceeds security limits");
|
|
812
|
+
}
|
|
813
|
+
return sanitize ? sanitizeTextContent(content) : content;
|
|
814
|
+
} else {
|
|
815
|
+
throw new Error(
|
|
816
|
+
".txt file import is not supported in browser. Use readFileAsText() with a File object."
|
|
817
|
+
);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
async function exportData(data, filePath, options) {
|
|
821
|
+
const format = detectFormatFromFilename(filePath);
|
|
822
|
+
if (format === "csv") {
|
|
823
|
+
validateExportData(data);
|
|
824
|
+
}
|
|
825
|
+
switch (format) {
|
|
826
|
+
case "csv": {
|
|
827
|
+
const { exportCSV: exportCSV2 } = await Promise.resolve().then(() => (init_csv(), csv_exports));
|
|
828
|
+
return exportCSV2(data, filePath, options);
|
|
829
|
+
}
|
|
830
|
+
case "json": {
|
|
831
|
+
const { exportJSON: exportJSON2 } = await Promise.resolve().then(() => (init_json(), json_exports));
|
|
832
|
+
return exportJSON2(data, filePath, options);
|
|
833
|
+
}
|
|
834
|
+
case "tree": {
|
|
835
|
+
return exportTree(data, filePath, options);
|
|
836
|
+
}
|
|
837
|
+
case "txt": {
|
|
838
|
+
return exportTxt(data, filePath, options);
|
|
839
|
+
}
|
|
840
|
+
default:
|
|
841
|
+
throw new Error(`Unsupported format: ${format}`);
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
async function importData(filePath, options) {
|
|
845
|
+
const format = detectFormatFromFilename(filePath);
|
|
846
|
+
switch (format) {
|
|
847
|
+
case "csv": {
|
|
848
|
+
const { importCSV: importCSV2 } = await Promise.resolve().then(() => (init_csv(), csv_exports));
|
|
849
|
+
return importCSV2(filePath, options);
|
|
850
|
+
}
|
|
851
|
+
case "json": {
|
|
852
|
+
const { importJSON: importJSON2 } = await Promise.resolve().then(() => (init_json(), json_exports));
|
|
853
|
+
return importJSON2(filePath, options);
|
|
854
|
+
}
|
|
855
|
+
case "tree": {
|
|
856
|
+
return importTree(filePath, options);
|
|
857
|
+
}
|
|
858
|
+
case "txt": {
|
|
859
|
+
return importTxt(filePath, options);
|
|
860
|
+
}
|
|
861
|
+
default:
|
|
862
|
+
throw new Error(`Unsupported format: ${format}`);
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
866
|
+
0 && (module.exports = {
|
|
867
|
+
detectFileExtension,
|
|
868
|
+
detectFormatFromFilename,
|
|
869
|
+
detectUniversalFormat,
|
|
870
|
+
exportData,
|
|
871
|
+
exportTree,
|
|
872
|
+
exportTxt,
|
|
873
|
+
importData,
|
|
874
|
+
importTree,
|
|
875
|
+
importTxt,
|
|
876
|
+
readFileAsText,
|
|
877
|
+
validateCSVData,
|
|
878
|
+
validateExportData
|
|
879
|
+
});
|
|
880
|
+
//# sourceMappingURL=data.js.map
|