@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.
Files changed (240) hide show
  1. package/CHANGELOG.md +320 -0
  2. package/README.md +233 -0
  3. package/USAGE-GUIDE.md +800 -0
  4. package/dist/browser/async.js +15 -0
  5. package/dist/browser/async.js.map +1 -0
  6. package/dist/browser/chunk-4O7ZPIJN.js +383 -0
  7. package/dist/browser/chunk-4O7ZPIJN.js.map +1 -0
  8. package/dist/browser/chunk-75XNTC34.js +60 -0
  9. package/dist/browser/chunk-75XNTC34.js.map +1 -0
  10. package/dist/browser/chunk-C3D7YZVE.js +299 -0
  11. package/dist/browser/chunk-C3D7YZVE.js.map +1 -0
  12. package/dist/browser/chunk-CZL6C2EI.js +452 -0
  13. package/dist/browser/chunk-CZL6C2EI.js.map +1 -0
  14. package/dist/browser/chunk-D4FZFIVA.js +240 -0
  15. package/dist/browser/chunk-D4FZFIVA.js.map +1 -0
  16. package/dist/browser/chunk-IL7NG7IC.js +72 -0
  17. package/dist/browser/chunk-IL7NG7IC.js.map +1 -0
  18. package/dist/browser/chunk-NSBPE2FW.js +17 -0
  19. package/dist/browser/chunk-NSBPE2FW.js.map +1 -0
  20. package/dist/browser/chunk-SLQVNPTH.js +27 -0
  21. package/dist/browser/chunk-SLQVNPTH.js.map +1 -0
  22. package/dist/browser/chunk-WG7ILCUB.js +195 -0
  23. package/dist/browser/chunk-WG7ILCUB.js.map +1 -0
  24. package/dist/browser/chunk-WJA4JDMZ.js +278 -0
  25. package/dist/browser/chunk-WJA4JDMZ.js.map +1 -0
  26. package/dist/browser/chunk-ZFVYLUTT.js +65 -0
  27. package/dist/browser/chunk-ZFVYLUTT.js.map +1 -0
  28. package/dist/browser/chunk-ZYTSVMTI.js +263 -0
  29. package/dist/browser/chunk-ZYTSVMTI.js.map +1 -0
  30. package/dist/browser/dates.js +78 -0
  31. package/dist/browser/dates.js.map +1 -0
  32. package/dist/browser/environment-detection.js +21 -0
  33. package/dist/browser/environment-detection.js.map +1 -0
  34. package/dist/browser/environment.js +34 -0
  35. package/dist/browser/environment.js.map +1 -0
  36. package/dist/browser/errors.js +18 -0
  37. package/dist/browser/errors.js.map +1 -0
  38. package/dist/browser/index.js +412 -0
  39. package/dist/browser/index.js.map +1 -0
  40. package/dist/browser/math.js +51 -0
  41. package/dist/browser/math.js.map +1 -0
  42. package/dist/browser/number.js +10 -0
  43. package/dist/browser/number.js.map +1 -0
  44. package/dist/browser/objects.js +31 -0
  45. package/dist/browser/objects.js.map +1 -0
  46. package/dist/browser/strings.js +80 -0
  47. package/dist/browser/strings.js.map +1 -0
  48. package/dist/browser/validation-core.js +54 -0
  49. package/dist/browser/validation-core.js.map +1 -0
  50. package/dist/browser/validation-crypto.js +28 -0
  51. package/dist/browser/validation-crypto.js.map +1 -0
  52. package/dist/browser/validators.js +98 -0
  53. package/dist/browser/validators.js.map +1 -0
  54. package/dist/cjs/async.js +86 -0
  55. package/dist/cjs/async.js.map +1 -0
  56. package/dist/cjs/dates.js +285 -0
  57. package/dist/cjs/dates.js.map +1 -0
  58. package/dist/cjs/environment-detection.js +84 -0
  59. package/dist/cjs/environment-detection.js.map +1 -0
  60. package/dist/cjs/environment.js +261 -0
  61. package/dist/cjs/environment.js.map +1 -0
  62. package/dist/cjs/errors.js +80 -0
  63. package/dist/cjs/errors.js.map +1 -0
  64. package/dist/cjs/index.js +2035 -0
  65. package/dist/cjs/index.js.map +1 -0
  66. package/dist/cjs/math.js +388 -0
  67. package/dist/cjs/math.js.map +1 -0
  68. package/dist/cjs/number.js +37 -0
  69. package/dist/cjs/number.js.map +1 -0
  70. package/dist/cjs/objects.js +249 -0
  71. package/dist/cjs/objects.js.map +1 -0
  72. package/dist/cjs/strings.js +253 -0
  73. package/dist/cjs/strings.js.map +1 -0
  74. package/dist/cjs/validation.js +450 -0
  75. package/dist/cjs/validation.js.map +1 -0
  76. package/dist/esm/async.js +15 -0
  77. package/dist/esm/async.js.map +1 -0
  78. package/dist/esm/chunk-4O7ZPIJN.js +383 -0
  79. package/dist/esm/chunk-4O7ZPIJN.js.map +1 -0
  80. package/dist/esm/chunk-75XNTC34.js +60 -0
  81. package/dist/esm/chunk-75XNTC34.js.map +1 -0
  82. package/dist/esm/chunk-BDOBKBKA.js +72 -0
  83. package/dist/esm/chunk-BDOBKBKA.js.map +1 -0
  84. package/dist/esm/chunk-C3D7YZVE.js +299 -0
  85. package/dist/esm/chunk-C3D7YZVE.js.map +1 -0
  86. package/dist/esm/chunk-CZL6C2EI.js +452 -0
  87. package/dist/esm/chunk-CZL6C2EI.js.map +1 -0
  88. package/dist/esm/chunk-EBLSTOEC.js +263 -0
  89. package/dist/esm/chunk-EBLSTOEC.js.map +1 -0
  90. package/dist/esm/chunk-NSBPE2FW.js +17 -0
  91. package/dist/esm/chunk-NSBPE2FW.js.map +1 -0
  92. package/dist/esm/chunk-SLQVNPTH.js +27 -0
  93. package/dist/esm/chunk-SLQVNPTH.js.map +1 -0
  94. package/dist/esm/chunk-WG7ILCUB.js +195 -0
  95. package/dist/esm/chunk-WG7ILCUB.js.map +1 -0
  96. package/dist/esm/chunk-WJA4JDMZ.js +278 -0
  97. package/dist/esm/chunk-WJA4JDMZ.js.map +1 -0
  98. package/dist/esm/chunk-ZFVYLUTT.js +65 -0
  99. package/dist/esm/chunk-ZFVYLUTT.js.map +1 -0
  100. package/dist/esm/dates.js +78 -0
  101. package/dist/esm/dates.js.map +1 -0
  102. package/dist/esm/environment-detection.js +21 -0
  103. package/dist/esm/environment-detection.js.map +1 -0
  104. package/dist/esm/environment.js +34 -0
  105. package/dist/esm/environment.js.map +1 -0
  106. package/dist/esm/errors.js +18 -0
  107. package/dist/esm/errors.js.map +1 -0
  108. package/dist/esm/index.js +380 -0
  109. package/dist/esm/index.js.map +1 -0
  110. package/dist/esm/math.js +51 -0
  111. package/dist/esm/math.js.map +1 -0
  112. package/dist/esm/number.js +10 -0
  113. package/dist/esm/number.js.map +1 -0
  114. package/dist/esm/objects.js +31 -0
  115. package/dist/esm/objects.js.map +1 -0
  116. package/dist/esm/strings.js +80 -0
  117. package/dist/esm/strings.js.map +1 -0
  118. package/dist/esm/validation.js +54 -0
  119. package/dist/esm/validation.js.map +1 -0
  120. package/dist/node/async.js +93 -0
  121. package/dist/node/async.js.map +1 -0
  122. package/dist/node/csv.js +102 -0
  123. package/dist/node/csv.js.map +1 -0
  124. package/dist/node/data.js +880 -0
  125. package/dist/node/data.js.map +1 -0
  126. package/dist/node/dates.js +324 -0
  127. package/dist/node/dates.js.map +1 -0
  128. package/dist/node/environment.js +278 -0
  129. package/dist/node/environment.js.map +1 -0
  130. package/dist/node/errors.js +89 -0
  131. package/dist/node/errors.js.map +1 -0
  132. package/dist/node/index.js +3151 -0
  133. package/dist/node/index.js.map +1 -0
  134. package/dist/node/json.js +107 -0
  135. package/dist/node/json.js.map +1 -0
  136. package/dist/node/math.js +413 -0
  137. package/dist/node/math.js.map +1 -0
  138. package/dist/node/number.js +42 -0
  139. package/dist/node/number.js.map +1 -0
  140. package/dist/node/objects.js +264 -0
  141. package/dist/node/objects.js.map +1 -0
  142. package/dist/node/strings.js +293 -0
  143. package/dist/node/strings.js.map +1 -0
  144. package/dist/node/tree.js +89 -0
  145. package/dist/node/tree.js.map +1 -0
  146. package/dist/node/validation-core.js +477 -0
  147. package/dist/node/validation-core.js.map +1 -0
  148. package/dist/node/validation-crypto.js +179 -0
  149. package/dist/node/validation-crypto.js.map +1 -0
  150. package/dist/node/validation.js +677 -0
  151. package/dist/node/validation.js.map +1 -0
  152. package/dist/node/validators.js +123 -0
  153. package/dist/node/validators.js.map +1 -0
  154. package/dist/node-esm/async.js +15 -0
  155. package/dist/node-esm/async.js.map +1 -0
  156. package/dist/node-esm/chunk-3YOF7NPT.js +299 -0
  157. package/dist/node-esm/chunk-3YOF7NPT.js.map +1 -0
  158. package/dist/node-esm/chunk-64TBXJQS.js +263 -0
  159. package/dist/node-esm/chunk-64TBXJQS.js.map +1 -0
  160. package/dist/node-esm/chunk-75XNTC34.js +60 -0
  161. package/dist/node-esm/chunk-75XNTC34.js.map +1 -0
  162. package/dist/node-esm/chunk-C4PKXIPB.js +278 -0
  163. package/dist/node-esm/chunk-C4PKXIPB.js.map +1 -0
  164. package/dist/node-esm/chunk-CMDFZME3.js +452 -0
  165. package/dist/node-esm/chunk-CMDFZME3.js.map +1 -0
  166. package/dist/node-esm/chunk-DZZPUYMP.js +74 -0
  167. package/dist/node-esm/chunk-DZZPUYMP.js.map +1 -0
  168. package/dist/node-esm/chunk-HTSEHRHI.js +195 -0
  169. package/dist/node-esm/chunk-HTSEHRHI.js.map +1 -0
  170. package/dist/node-esm/chunk-JCAUVOPH.js +27 -0
  171. package/dist/node-esm/chunk-JCAUVOPH.js.map +1 -0
  172. package/dist/node-esm/chunk-KBHE3K2F.js +505 -0
  173. package/dist/node-esm/chunk-KBHE3K2F.js.map +1 -0
  174. package/dist/node-esm/chunk-LYTET5NX.js +65 -0
  175. package/dist/node-esm/chunk-LYTET5NX.js.map +1 -0
  176. package/dist/node-esm/chunk-PZ5AY32C.js +10 -0
  177. package/dist/node-esm/chunk-PZ5AY32C.js.map +1 -0
  178. package/dist/node-esm/chunk-UKGXL2QO.js +383 -0
  179. package/dist/node-esm/chunk-UKGXL2QO.js.map +1 -0
  180. package/dist/node-esm/chunk-XAEYT23H.js +164 -0
  181. package/dist/node-esm/chunk-XAEYT23H.js.map +1 -0
  182. package/dist/node-esm/csv.js +63 -0
  183. package/dist/node-esm/csv.js.map +1 -0
  184. package/dist/node-esm/data.js +32 -0
  185. package/dist/node-esm/data.js.map +1 -0
  186. package/dist/node-esm/dates.js +78 -0
  187. package/dist/node-esm/dates.js.map +1 -0
  188. package/dist/node-esm/environment.js +34 -0
  189. package/dist/node-esm/environment.js.map +1 -0
  190. package/dist/node-esm/errors.js +18 -0
  191. package/dist/node-esm/errors.js.map +1 -0
  192. package/dist/node-esm/index.js +426 -0
  193. package/dist/node-esm/index.js.map +1 -0
  194. package/dist/node-esm/json.js +68 -0
  195. package/dist/node-esm/json.js.map +1 -0
  196. package/dist/node-esm/math.js +51 -0
  197. package/dist/node-esm/math.js.map +1 -0
  198. package/dist/node-esm/number.js +10 -0
  199. package/dist/node-esm/number.js.map +1 -0
  200. package/dist/node-esm/objects.js +31 -0
  201. package/dist/node-esm/objects.js.map +1 -0
  202. package/dist/node-esm/strings.js +80 -0
  203. package/dist/node-esm/strings.js.map +1 -0
  204. package/dist/node-esm/tree.js +8 -0
  205. package/dist/node-esm/tree.js.map +1 -0
  206. package/dist/node-esm/validation-core.js +54 -0
  207. package/dist/node-esm/validation-core.js.map +1 -0
  208. package/dist/node-esm/validation-crypto.js +26 -0
  209. package/dist/node-esm/validation-crypto.js.map +1 -0
  210. package/dist/node-esm/validation.js +606 -0
  211. package/dist/node-esm/validation.js.map +1 -0
  212. package/dist/node-esm/validators.js +98 -0
  213. package/dist/node-esm/validators.js.map +1 -0
  214. package/dist/types/async-C8gvbSG-.d.ts +453 -0
  215. package/dist/types/async.d.ts +1 -0
  216. package/dist/types/csv.d.ts +226 -0
  217. package/dist/types/data.d.ts +1561 -0
  218. package/dist/types/dates-hTiE0Z11.d.ts +298 -0
  219. package/dist/types/dates.d.ts +1 -0
  220. package/dist/types/environment-B8eLS7KT.d.ts +420 -0
  221. package/dist/types/environment-detection.d.ts +102 -0
  222. package/dist/types/environment.d.ts +1 -0
  223. package/dist/types/errors.d.ts +147 -0
  224. package/dist/types/index.d.ts +211 -0
  225. package/dist/types/json.d.ts +284 -0
  226. package/dist/types/math-BQ9Lwdp7.d.ts +2060 -0
  227. package/dist/types/math.d.ts +1 -0
  228. package/dist/types/number-CYnQfLWj.d.ts +44 -0
  229. package/dist/types/number.d.ts +1 -0
  230. package/dist/types/objects-BohS8GCS.d.ts +1185 -0
  231. package/dist/types/objects.d.ts +1 -0
  232. package/dist/types/strings-CiqRPYLL.d.ts +1349 -0
  233. package/dist/types/strings.d.ts +1 -0
  234. package/dist/types/tree.d.ts +284 -0
  235. package/dist/types/validation-core-DfHF8rCG.d.ts +238 -0
  236. package/dist/types/validation-crypto-browser.d.ts +56 -0
  237. package/dist/types/validation-crypto-node.d.ts +31 -0
  238. package/dist/types/validation.d.ts +1 -0
  239. package/dist/types/validators.d.ts +216 -0
  240. 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
+ "&#60;script",
204
+ // &#60; = <
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