@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,1561 @@
1
+ /**
2
+ * Data manipulation utilities for multiple formats with automatic detection
3
+ * Consolidated from data/index module
4
+ */
5
+ /**
6
+ * Type for data - array of objects or array of arrays (for CSV, etc.)
7
+ */
8
+ type ExportData = Record<string, any>[] | string[][];
9
+ /**
10
+ * Type for imported data - can include string for .tree files
11
+ */
12
+ type ImportData = ExportData | string | any;
13
+ /**
14
+ * Type for CSV data (backward compatibility)
15
+ */
16
+ type CSVData = ExportData;
17
+ /**
18
+ * Supported format types
19
+ */
20
+ type ExportFormat = 'csv' | 'json' | 'tree' | 'txt';
21
+ /**
22
+ * Universal file format detection - detects any file extension
23
+ */
24
+ type FileFormat = string;
25
+ /**
26
+ * Reads a file as text in any environment (Node.js or Browser)
27
+ *
28
+ * Universal file reading utility that adapts to the runtime environment.
29
+ * In Node.js, reads from filesystem. In Browser, reads from File object.
30
+ *
31
+ * Environment behavior:
32
+ * - **Node.js**: Pass file path as string, reads from filesystem
33
+ * - **Browser**: Pass File object (from input[type="file"]), reads with FileReader API
34
+ *
35
+ * @param fileOrPath - File path string (Node.js) or File object (Browser)
36
+ * @param encoding - Text encoding for Node.js filesystem read (default: 'utf8')
37
+ * @returns Promise<string> File contents as text
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * // Node.js - Read from filesystem
42
+ * const config = await readFileAsText('./config.json')
43
+ * const data = JSON.parse(config)
44
+ *
45
+ * // Browser - Read from File input
46
+ * // HTML: <input type="file" id="fileInput">
47
+ * const input = document.getElementById('fileInput') as HTMLInputElement
48
+ * input.addEventListener('change', async (e) => {
49
+ * const file = e.target.files[0]
50
+ * const content = await readFileAsText(file)
51
+ * console.log('File content:', content)
52
+ * })
53
+ * ```
54
+ *
55
+ * @example
56
+ * ```typescript
57
+ * // Real-world: Load and parse CSV from user upload (Browser)
58
+ * async function handleCSVUpload(file: File) {
59
+ * const csvText = await readFileAsText(file)
60
+ * const rows = csvText.split('\n').map(row => row.split(';'))
61
+ * console.log(`Loaded ${rows.length} rows`)
62
+ * return rows
63
+ * }
64
+ * ```
65
+ *
66
+ * @throws {DataError} If called with invalid parameter for current environment
67
+ * @see {@link importData} for format-aware file importing
68
+ */
69
+ declare const readFileAsText: (fileOrPath: string | File, encoding?: BufferEncoding) => Promise<string>;
70
+ /**
71
+ * Validates that data is exportable (array of objects or array of arrays)
72
+ *
73
+ * Ensures data structure is compatible with export formats (CSV, JSON).
74
+ * Validates consistency: all elements must be same type, arrays must have equal length.
75
+ *
76
+ * Validation rules:
77
+ * - Must be non-empty array
78
+ * - If first element is object → all must be objects (no arrays/primitives)
79
+ * - If first element is array → all must be arrays with equal length
80
+ * - Null/undefined not allowed
81
+ *
82
+ * @param data - Data to validate for export
83
+ * @returns `true` if data is valid (type guard for ExportData)
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * // Valid: Array of objects (typical use case)
88
+ * const users = [
89
+ * { id: 1, name: 'Alice', role: 'Admin' },
90
+ * { id: 2, name: 'Bob', role: 'User' }
91
+ * ]
92
+ * validateExportData(users) // ✅ true
93
+ * await exportData(users, 'users.csv')
94
+ * ```
95
+ *
96
+ * @example
97
+ * ```typescript
98
+ * // Valid: Array of arrays (matrix/tabular data)
99
+ * const matrix = [
100
+ * ['Name', 'Age', 'City'],
101
+ * ['Alice', 25, 'Madrid'],
102
+ * ['Bob', 30, 'Barcelona']
103
+ * ]
104
+ * validateExportData(matrix) // ✅ true
105
+ * await exportData(matrix, 'data.csv')
106
+ * ```
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * // Invalid: Mixed types - throws ValidationError
111
+ * const mixed = [
112
+ * { id: 1, name: 'Alice' },
113
+ * ['Bob', 30] // ❌ Array mixed with object
114
+ * ]
115
+ * try {
116
+ * validateExportData(mixed)
117
+ * } catch (error) {
118
+ * console.error(error.message)
119
+ * // 'All elements must be objects if first one is an object'
120
+ * }
121
+ * ```
122
+ *
123
+ * @example
124
+ * ```typescript
125
+ * // Invalid: Inconsistent array lengths - throws ValidationError
126
+ * const uneven = [
127
+ * ['Alice', 25, 'Madrid'],
128
+ * ['Bob', 30] // ❌ Missing city
129
+ * ]
130
+ * try {
131
+ * validateExportData(uneven)
132
+ * } catch (error) {
133
+ * console.error(error.message)
134
+ * // 'Row 1 has 2 columns, but first has 3'
135
+ * }
136
+ * ```
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * // Real-world: Pre-export validation with error handling
141
+ * async function safeExportUsers(users: any[], filename: string) {
142
+ * try {
143
+ * // Validate before export
144
+ * validateExportData(users)
145
+ * await exportData(users, filename)
146
+ * console.log(`✅ Exported ${users.length} users to ${filename}`)
147
+ * } catch (error) {
148
+ * console.error('Export failed:', error.message)
149
+ * // Log validation errors for debugging
150
+ * if (error.code === 'VALIDATION_ERROR') {
151
+ * console.error('Invalid data structure:', error.details)
152
+ * }
153
+ * }
154
+ * }
155
+ * ```
156
+ *
157
+ * @throws {ValidationError} If data is not an array
158
+ * @throws {ValidationError} If array is empty
159
+ * @throws {ValidationError} If elements have inconsistent types
160
+ * @throws {ValidationError} If array rows have different lengths
161
+ *
162
+ * @see {@link exportData} for universal export using validated data
163
+ * @see {@link ExportData} for type definition
164
+ */
165
+ declare function validateExportData(data: any): data is ExportData;
166
+ /**
167
+ * Alias for validateExportData for CSV backward compatibility
168
+ */
169
+ declare const validateCSVData: typeof validateExportData;
170
+ /**
171
+ * Detects file format based on filename extension
172
+ *
173
+ * Analyzes filename to determine export format for automatic format selection.
174
+ * Supports CSV, JSON, Tree, and TXT formats. Case-insensitive.
175
+ *
176
+ * @param filename - Filename with extension
177
+ * @returns Detected format ('csv' | 'json' | 'tree' | 'txt')
178
+ *
179
+ * @example
180
+ * ```typescript
181
+ * // CSV detection
182
+ * detectFormatFromFilename('users.csv') // 'csv'
183
+ * detectFormatFromFilename('DATA.CSV') // 'csv' (case-insensitive)
184
+ * ```
185
+ *
186
+ * @example
187
+ * ```typescript
188
+ * // JSON detection
189
+ * detectFormatFromFilename('config.json') // 'json'
190
+ * detectFormatFromFilename('data.JSON') // 'json'
191
+ * ```
192
+ *
193
+ * @example
194
+ * ```typescript
195
+ * // Tree structure detection
196
+ * detectFormatFromFilename('structure.tree') // 'tree'
197
+ * ```
198
+ *
199
+ * @example
200
+ * ```typescript
201
+ * // Plain text detection
202
+ * detectFormatFromFilename('notes.txt') // 'txt'
203
+ * detectFormatFromFilename('log.TXT') // 'txt'
204
+ * ```
205
+ *
206
+ * @example
207
+ * ```typescript
208
+ * // Real-world: Dynamic export routing
209
+ * async function smartExport(data: any[], filename: string) {
210
+ * const format = detectFormatFromFilename(filename)
211
+ * console.log(`Exporting as ${format.toUpperCase()}...`)
212
+ *
213
+ * await exportData(data, filename)
214
+ * console.log(`✅ Export completed: ${filename}`)
215
+ * }
216
+ *
217
+ * smartExport(users, 'users.csv') // Exports as CSV
218
+ * smartExport(config, 'config.json') // Exports as JSON
219
+ * ```
220
+ *
221
+ * @throws {DataError} If filename has no extension
222
+ * @throws {DataError} If extension is not supported (.csv, .json, .tree, .txt)
223
+ *
224
+ * @see {@link detectFileExtension} for universal extension detection (any file type)
225
+ * @see {@link detectUniversalFormat} for detailed format metadata
226
+ * @see {@link exportData} for universal export using detected format
227
+ *
228
+ * @deprecated Use detectFileExtension for universal detection, or use exportData directly (auto-detects)
229
+ */
230
+ declare function detectFormatFromFilename(filename: string): ExportFormat;
231
+ /**
232
+ * Universal file extension detector - detects any file extension
233
+ *
234
+ * Extracts file extension from filename (without dot) for any file type.
235
+ * Returns last extension for compound extensions (e.g., '.tar.gz' → 'gz').
236
+ * Case-insensitive, trims whitespace, returns null if no extension found.
237
+ *
238
+ * @param filename - Filename with extension
239
+ * @returns File extension (lowercase, without dot) or `null` if no extension
240
+ *
241
+ * @example
242
+ * ```typescript
243
+ * // Common file types
244
+ * detectFileExtension('document.pdf') // 'pdf'
245
+ * detectFileExtension('image.jpg') // 'jpg'
246
+ * detectFileExtension('data.json') // 'json'
247
+ * detectFileExtension('styles.css') // 'css'
248
+ * ```
249
+ *
250
+ * @example
251
+ * ```typescript
252
+ * // Compound extensions (returns last extension)
253
+ * detectFileExtension('archive.tar.gz') // 'gz'
254
+ * detectFileExtension('backup.sql.bz2') // 'bz2'
255
+ * detectFileExtension('file.test.ts') // 'ts'
256
+ * ```
257
+ *
258
+ * @example
259
+ * ```typescript
260
+ * // Edge cases
261
+ * detectFileExtension('noextension') // null
262
+ * detectFileExtension('.hidden') // 'hidden' (Unix hidden files)
263
+ * detectFileExtension('file.') // '' (empty string)
264
+ * detectFileExtension(' file.txt ') // 'txt' (trims whitespace)
265
+ * detectFileExtension('FILE.PDF') // 'pdf' (case-insensitive)
266
+ * ```
267
+ *
268
+ * @example
269
+ * ```typescript
270
+ * // Real-world: Conditional file processing
271
+ * async function processUploadedFile(filename: string, data: any) {
272
+ * const ext = detectFileExtension(filename)
273
+ *
274
+ * switch (ext) {
275
+ * case 'csv':
276
+ * return await importCSV(filename)
277
+ * case 'json':
278
+ * return await importJSON(filename)
279
+ * case 'pdf':
280
+ * return await extractPdfText(filename)
281
+ * case null:
282
+ * throw new Error('File must have an extension')
283
+ * default:
284
+ * throw new Error(`Unsupported file type: .${ext}`)
285
+ * }
286
+ * }
287
+ * ```
288
+ *
289
+ * @example
290
+ * ```typescript
291
+ * // Real-world: File type validation
292
+ * function validateUpload(file: File) {
293
+ * const ext = detectFileExtension(file.name)
294
+ * const allowedExtensions = ['jpg', 'jpeg', 'png', 'gif']
295
+ *
296
+ * if (!ext) {
297
+ * return { valid: false, error: 'File must have an extension' }
298
+ * }
299
+ *
300
+ * if (!allowedExtensions.includes(ext)) {
301
+ * return {
302
+ * valid: false,
303
+ * error: `Invalid file type .${ext}. Allowed: ${allowedExtensions.join(', ')}`
304
+ * }
305
+ * }
306
+ *
307
+ * return { valid: true }
308
+ * }
309
+ * ```
310
+ *
311
+ * @see {@link detectUniversalFormat} for detailed format metadata (category, MIME type)
312
+ * @see {@link detectFormatFromFilename} for export format detection (csv/json/tree/txt only)
313
+ */
314
+ declare function detectFileExtension(filename: string): FileFormat | null;
315
+ /**
316
+ * Universal filename format detection with comprehensive extension support
317
+ *
318
+ * Analyzes filename extension and returns detailed format metadata including:
319
+ * category, MIME type, text/binary classification. Supports 80+ file formats
320
+ * across data, code, documents, images, audio, video, archives, and fonts.
321
+ *
322
+ * @param filename - Filename with extension
323
+ * @returns Object with extension, category, isText, isBinary, mimeType properties
324
+ *
325
+ * @example
326
+ * ```typescript
327
+ * // Data formats
328
+ * detectUniversalFormat('config.json')
329
+ * // { extension: 'json', category: 'data', isText: true, isBinary: false, mimeType: 'application/json' }
330
+ *
331
+ * detectUniversalFormat('users.csv')
332
+ * // { extension: 'csv', category: 'data', isText: true, isBinary: false, mimeType: 'text/csv' }
333
+ * ```
334
+ *
335
+ * @example
336
+ * ```typescript
337
+ * // Programming languages
338
+ * detectUniversalFormat('app.ts')
339
+ * // { extension: 'ts', category: 'code', isText: true, isBinary: false, mimeType: 'application/typescript' }
340
+ *
341
+ * detectUniversalFormat('main.py')
342
+ * // { extension: 'py', category: 'code', isText: true, isBinary: false, mimeType: 'text/x-python' }
343
+ * ```
344
+ *
345
+ * @example
346
+ * ```typescript
347
+ * // Documents
348
+ * detectUniversalFormat('report.pdf')
349
+ * // { extension: 'pdf', category: 'document', isText: false, isBinary: true, mimeType: 'application/pdf' }
350
+ *
351
+ * detectUniversalFormat('doc.docx')
352
+ * // { extension: 'docx', category: 'document', isText: false, isBinary: true, mimeType: '...' }
353
+ * ```
354
+ *
355
+ * @example
356
+ * ```typescript
357
+ * // Images
358
+ * detectUniversalFormat('photo.jpg')
359
+ * // { extension: 'jpg', category: 'image', isText: false, isBinary: true, mimeType: 'image/jpeg' }
360
+ *
361
+ * detectUniversalFormat('icon.svg')
362
+ * // { extension: 'svg', category: 'image', isText: true, isBinary: false, mimeType: 'image/svg+xml' }
363
+ * ```
364
+ *
365
+ * @example
366
+ * ```typescript
367
+ * // Archives
368
+ * detectUniversalFormat('backup.zip')
369
+ * // { extension: 'zip', category: 'archive', isText: false, isBinary: true, mimeType: 'application/zip' }
370
+ * ```
371
+ *
372
+ * @example
373
+ * ```typescript
374
+ * // Real-world: Smart file processing routing
375
+ * async function processFile(filename: string, content: any) {
376
+ * const format = detectUniversalFormat(filename)
377
+ *
378
+ * console.log(`Processing ${format.extension} file (${format.category})`)
379
+ *
380
+ * if (format.isText) {
381
+ * // Can read as text
382
+ * const text = await readFileAsText(filename)
383
+ * return parseTextFormat(text, format.extension)
384
+ * } else if (format.isBinary) {
385
+ * // Needs binary processing
386
+ * return processBinaryFile(filename, format.mimeType)
387
+ * }
388
+ * }
389
+ * ```
390
+ *
391
+ * @example
392
+ * ```typescript
393
+ * // Real-world: Content-Type header generation
394
+ * function getResponseHeaders(filename: string) {
395
+ * const format = detectUniversalFormat(filename)
396
+ *
397
+ * return {
398
+ * 'Content-Type': format.mimeType || 'application/octet-stream',
399
+ * 'Content-Disposition': `attachment; filename="${filename}"`,
400
+ * 'X-File-Category': format.category
401
+ * }
402
+ * }
403
+ * ```
404
+ *
405
+ * @see {@link detectFileExtension} for simple extension extraction
406
+ * @see {@link detectFormatFromFilename} for export format detection
407
+ */
408
+ declare function detectUniversalFormat(filename: string): {
409
+ extension: null;
410
+ category: string;
411
+ isText: boolean;
412
+ isBinary: boolean;
413
+ mimeType: null;
414
+ } | {
415
+ category: "data";
416
+ isText: true;
417
+ isBinary: false;
418
+ mimeType: "application/json";
419
+ extension: string;
420
+ } | {
421
+ category: "data";
422
+ isText: true;
423
+ isBinary: false;
424
+ mimeType: "text/csv";
425
+ extension: string;
426
+ } | {
427
+ category: "data";
428
+ isText: true;
429
+ isBinary: false;
430
+ mimeType: "application/xml";
431
+ extension: string;
432
+ } | {
433
+ category: "data";
434
+ isText: true;
435
+ isBinary: false;
436
+ mimeType: "application/yaml";
437
+ extension: string;
438
+ } | {
439
+ category: "data";
440
+ isText: true;
441
+ isBinary: false;
442
+ mimeType: "text/plain";
443
+ extension: string;
444
+ } | {
445
+ category: "data";
446
+ isText: true;
447
+ isBinary: false;
448
+ mimeType: "text/tab-separated-values";
449
+ extension: string;
450
+ } | {
451
+ category: "data";
452
+ isText: true;
453
+ isBinary: false;
454
+ mimeType: "application/sql";
455
+ extension: string;
456
+ } | {
457
+ category: "data";
458
+ isText: false;
459
+ isBinary: true;
460
+ mimeType: "application/x-sqlite3";
461
+ extension: string;
462
+ } | {
463
+ category: "text";
464
+ isText: true;
465
+ isBinary: false;
466
+ mimeType: "text/plain";
467
+ extension: string;
468
+ } | {
469
+ category: "text";
470
+ isText: true;
471
+ isBinary: false;
472
+ mimeType: "text/markdown";
473
+ extension: string;
474
+ } | {
475
+ category: "text";
476
+ isText: true;
477
+ isBinary: false;
478
+ mimeType: "text/x-rst";
479
+ extension: string;
480
+ } | {
481
+ category: "text";
482
+ isText: true;
483
+ isBinary: false;
484
+ mimeType: "application/rtf";
485
+ extension: string;
486
+ } | {
487
+ category: "web";
488
+ isText: true;
489
+ isBinary: false;
490
+ mimeType: "text/html";
491
+ extension: string;
492
+ } | {
493
+ category: "web";
494
+ isText: true;
495
+ isBinary: false;
496
+ mimeType: "text/css";
497
+ extension: string;
498
+ } | {
499
+ category: "web";
500
+ isText: true;
501
+ isBinary: false;
502
+ mimeType: "text/x-scss";
503
+ extension: string;
504
+ } | {
505
+ category: "web";
506
+ isText: true;
507
+ isBinary: false;
508
+ mimeType: "text/x-sass";
509
+ extension: string;
510
+ } | {
511
+ category: "web";
512
+ isText: true;
513
+ isBinary: false;
514
+ mimeType: "text/x-less";
515
+ extension: string;
516
+ } | {
517
+ category: "code";
518
+ isText: true;
519
+ isBinary: false;
520
+ mimeType: "application/javascript";
521
+ extension: string;
522
+ } | {
523
+ category: "code";
524
+ isText: true;
525
+ isBinary: false;
526
+ mimeType: "text/jsx";
527
+ extension: string;
528
+ } | {
529
+ category: "code";
530
+ isText: true;
531
+ isBinary: false;
532
+ mimeType: "application/typescript";
533
+ extension: string;
534
+ } | {
535
+ category: "code";
536
+ isText: true;
537
+ isBinary: false;
538
+ mimeType: "text/tsx";
539
+ extension: string;
540
+ } | {
541
+ category: "code";
542
+ isText: true;
543
+ isBinary: false;
544
+ mimeType: "text/x-python";
545
+ extension: string;
546
+ } | {
547
+ category: "code";
548
+ isText: true;
549
+ isBinary: false;
550
+ mimeType: "text/x-java-source";
551
+ extension: string;
552
+ } | {
553
+ category: "code";
554
+ isText: true;
555
+ isBinary: false;
556
+ mimeType: "application/x-httpd-php";
557
+ extension: string;
558
+ } | {
559
+ category: "code";
560
+ isText: true;
561
+ isBinary: false;
562
+ mimeType: "text/x-ruby";
563
+ extension: string;
564
+ } | {
565
+ category: "code";
566
+ isText: true;
567
+ isBinary: false;
568
+ mimeType: "text/x-go";
569
+ extension: string;
570
+ } | {
571
+ category: "code";
572
+ isText: true;
573
+ isBinary: false;
574
+ mimeType: "text/x-rust";
575
+ extension: string;
576
+ } | {
577
+ category: "code";
578
+ isText: true;
579
+ isBinary: false;
580
+ mimeType: "text/x-c";
581
+ extension: string;
582
+ } | {
583
+ category: "code";
584
+ isText: true;
585
+ isBinary: false;
586
+ mimeType: "text/x-c++";
587
+ extension: string;
588
+ } | {
589
+ category: "code";
590
+ isText: true;
591
+ isBinary: false;
592
+ mimeType: "text/x-csharp";
593
+ extension: string;
594
+ } | {
595
+ category: "code";
596
+ isText: true;
597
+ isBinary: false;
598
+ mimeType: "application/x-sh";
599
+ extension: string;
600
+ } | {
601
+ category: "code";
602
+ isText: true;
603
+ isBinary: false;
604
+ mimeType: "application/x-powershell";
605
+ extension: string;
606
+ } | {
607
+ category: "document";
608
+ isText: false;
609
+ isBinary: true;
610
+ mimeType: "application/msword";
611
+ extension: string;
612
+ } | {
613
+ category: "document";
614
+ isText: false;
615
+ isBinary: true;
616
+ mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
617
+ extension: string;
618
+ } | {
619
+ category: "spreadsheet";
620
+ isText: false;
621
+ isBinary: true;
622
+ mimeType: "application/vnd.ms-excel";
623
+ extension: string;
624
+ } | {
625
+ category: "spreadsheet";
626
+ isText: false;
627
+ isBinary: true;
628
+ mimeType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
629
+ extension: string;
630
+ } | {
631
+ category: "presentation";
632
+ isText: false;
633
+ isBinary: true;
634
+ mimeType: "application/vnd.ms-powerpoint";
635
+ extension: string;
636
+ } | {
637
+ category: "presentation";
638
+ isText: false;
639
+ isBinary: true;
640
+ mimeType: "application/vnd.openxmlformats-officedocument.presentationml.presentation";
641
+ extension: string;
642
+ } | {
643
+ category: "document";
644
+ isText: false;
645
+ isBinary: true;
646
+ mimeType: "application/vnd.oasis.opendocument.text";
647
+ extension: string;
648
+ } | {
649
+ category: "spreadsheet";
650
+ isText: false;
651
+ isBinary: true;
652
+ mimeType: "application/vnd.oasis.opendocument.spreadsheet";
653
+ extension: string;
654
+ } | {
655
+ category: "presentation";
656
+ isText: false;
657
+ isBinary: true;
658
+ mimeType: "application/vnd.oasis.opendocument.presentation";
659
+ extension: string;
660
+ } | {
661
+ category: "document";
662
+ isText: false;
663
+ isBinary: true;
664
+ mimeType: "application/pdf";
665
+ extension: string;
666
+ } | {
667
+ category: "document";
668
+ isText: false;
669
+ isBinary: true;
670
+ mimeType: "application/epub+zip";
671
+ extension: string;
672
+ } | {
673
+ category: "document";
674
+ isText: false;
675
+ isBinary: true;
676
+ mimeType: "application/x-mobipocket-ebook";
677
+ extension: string;
678
+ } | {
679
+ category: "image";
680
+ isText: false;
681
+ isBinary: true;
682
+ mimeType: "image/jpeg";
683
+ extension: string;
684
+ } | {
685
+ category: "image";
686
+ isText: false;
687
+ isBinary: true;
688
+ mimeType: "image/png";
689
+ extension: string;
690
+ } | {
691
+ category: "image";
692
+ isText: false;
693
+ isBinary: true;
694
+ mimeType: "image/gif";
695
+ extension: string;
696
+ } | {
697
+ category: "image";
698
+ isText: true;
699
+ isBinary: false;
700
+ mimeType: "image/svg+xml";
701
+ extension: string;
702
+ } | {
703
+ category: "image";
704
+ isText: false;
705
+ isBinary: true;
706
+ mimeType: "image/webp";
707
+ extension: string;
708
+ } | {
709
+ category: "image";
710
+ isText: false;
711
+ isBinary: true;
712
+ mimeType: "image/avif";
713
+ extension: string;
714
+ } | {
715
+ category: "image";
716
+ isText: false;
717
+ isBinary: true;
718
+ mimeType: "image/bmp";
719
+ extension: string;
720
+ } | {
721
+ category: "image";
722
+ isText: false;
723
+ isBinary: true;
724
+ mimeType: "image/tiff";
725
+ extension: string;
726
+ } | {
727
+ category: "image";
728
+ isText: false;
729
+ isBinary: true;
730
+ mimeType: "image/x-icon";
731
+ extension: string;
732
+ } | {
733
+ category: "image";
734
+ isText: false;
735
+ isBinary: true;
736
+ mimeType: "image/vnd.adobe.photoshop";
737
+ extension: string;
738
+ } | {
739
+ category: "audio";
740
+ isText: false;
741
+ isBinary: true;
742
+ mimeType: "audio/mpeg";
743
+ extension: string;
744
+ } | {
745
+ category: "audio";
746
+ isText: false;
747
+ isBinary: true;
748
+ mimeType: "audio/wav";
749
+ extension: string;
750
+ } | {
751
+ category: "audio";
752
+ isText: false;
753
+ isBinary: true;
754
+ mimeType: "audio/flac";
755
+ extension: string;
756
+ } | {
757
+ category: "audio";
758
+ isText: false;
759
+ isBinary: true;
760
+ mimeType: "audio/ogg";
761
+ extension: string;
762
+ } | {
763
+ category: "audio";
764
+ isText: false;
765
+ isBinary: true;
766
+ mimeType: "audio/aac";
767
+ extension: string;
768
+ } | {
769
+ category: "audio";
770
+ isText: false;
771
+ isBinary: true;
772
+ mimeType: "audio/m4a";
773
+ extension: string;
774
+ } | {
775
+ category: "audio";
776
+ isText: false;
777
+ isBinary: true;
778
+ mimeType: "audio/x-ms-wma";
779
+ extension: string;
780
+ } | {
781
+ category: "video";
782
+ isText: false;
783
+ isBinary: true;
784
+ mimeType: "video/mp4";
785
+ extension: string;
786
+ } | {
787
+ category: "video";
788
+ isText: false;
789
+ isBinary: true;
790
+ mimeType: "video/x-msvideo";
791
+ extension: string;
792
+ } | {
793
+ category: "video";
794
+ isText: false;
795
+ isBinary: true;
796
+ mimeType: "video/quicktime";
797
+ extension: string;
798
+ } | {
799
+ category: "video";
800
+ isText: false;
801
+ isBinary: true;
802
+ mimeType: "video/x-ms-wmv";
803
+ extension: string;
804
+ } | {
805
+ category: "video";
806
+ isText: false;
807
+ isBinary: true;
808
+ mimeType: "video/x-flv";
809
+ extension: string;
810
+ } | {
811
+ category: "video";
812
+ isText: false;
813
+ isBinary: true;
814
+ mimeType: "video/webm";
815
+ extension: string;
816
+ } | {
817
+ category: "video";
818
+ isText: false;
819
+ isBinary: true;
820
+ mimeType: "video/x-matroska";
821
+ extension: string;
822
+ } | {
823
+ category: "video";
824
+ isText: false;
825
+ isBinary: true;
826
+ mimeType: "video/3gpp";
827
+ extension: string;
828
+ } | {
829
+ category: "archive";
830
+ isText: false;
831
+ isBinary: true;
832
+ mimeType: "application/zip";
833
+ extension: string;
834
+ } | {
835
+ category: "archive";
836
+ isText: false;
837
+ isBinary: true;
838
+ mimeType: "application/x-rar-compressed";
839
+ extension: string;
840
+ } | {
841
+ category: "archive";
842
+ isText: false;
843
+ isBinary: true;
844
+ mimeType: "application/x-7z-compressed";
845
+ extension: string;
846
+ } | {
847
+ category: "archive";
848
+ isText: false;
849
+ isBinary: true;
850
+ mimeType: "application/x-tar";
851
+ extension: string;
852
+ } | {
853
+ category: "archive";
854
+ isText: false;
855
+ isBinary: true;
856
+ mimeType: "application/gzip";
857
+ extension: string;
858
+ } | {
859
+ category: "archive";
860
+ isText: false;
861
+ isBinary: true;
862
+ mimeType: "application/x-bzip2";
863
+ extension: string;
864
+ } | {
865
+ category: "archive";
866
+ isText: false;
867
+ isBinary: true;
868
+ mimeType: "application/x-xz";
869
+ extension: string;
870
+ } | {
871
+ category: "config";
872
+ isText: true;
873
+ isBinary: false;
874
+ mimeType: "text/plain";
875
+ extension: string;
876
+ } | {
877
+ category: "config";
878
+ isText: true;
879
+ isBinary: false;
880
+ mimeType: "application/toml";
881
+ extension: string;
882
+ } | {
883
+ category: "font";
884
+ isText: false;
885
+ isBinary: true;
886
+ mimeType: "font/ttf";
887
+ extension: string;
888
+ } | {
889
+ category: "font";
890
+ isText: false;
891
+ isBinary: true;
892
+ mimeType: "font/otf";
893
+ extension: string;
894
+ } | {
895
+ category: "font";
896
+ isText: false;
897
+ isBinary: true;
898
+ mimeType: "font/woff";
899
+ extension: string;
900
+ } | {
901
+ category: "font";
902
+ isText: false;
903
+ isBinary: true;
904
+ mimeType: "font/woff2";
905
+ extension: string;
906
+ } | {
907
+ category: "font";
908
+ isText: false;
909
+ isBinary: true;
910
+ mimeType: "application/vnd.ms-fontobject";
911
+ extension: string;
912
+ };
913
+ interface TreeExportOptions {
914
+ /** Property to display as node name (default: 'name') */
915
+ labelField?: string;
916
+ /** Characters for vertical line (default: '│ ') */
917
+ verticalLine?: string;
918
+ /** Characters for middle branch (default: '├── ') */
919
+ middleBranch?: string;
920
+ /** Characters for last branch (default: '└── ') */
921
+ lastBranch?: string;
922
+ /** Spacing for nodes without vertical line (default: ' ') */
923
+ emptySpace?: string;
924
+ /** Custom function to get node label */
925
+ labelFunction?: (node: any) => string;
926
+ }
927
+ /**
928
+ * Exports a tree structure as a text file with visual format
929
+ *
930
+ * Converts hierarchical data (nodes with `children` arrays) into ASCII/Unicode tree
931
+ * visualization and saves as .tree file. Supports Node.js (filesystem) and Browser (download).
932
+ *
933
+ * @param data - Array of root nodes (each with optional `children` property)
934
+ * @param filePath - Output file path (Node.js) or filename (Browser)
935
+ * @param options - Tree rendering options (labelField, box-drawing characters, labelFunction)
936
+ *
937
+ * @example
938
+ * ```typescript
939
+ * // Basic tree export - File structure
940
+ * const fileTree = [
941
+ * {
942
+ * name: 'src',
943
+ * children: [
944
+ * { name: 'index.ts' },
945
+ * { name: 'utils.ts' },
946
+ * {
947
+ * name: 'components',
948
+ * children: [
949
+ * { name: 'Button.tsx' },
950
+ * { name: 'Input.tsx' }
951
+ * ]
952
+ * }
953
+ * ]
954
+ * }
955
+ * ]
956
+ *
957
+ * await exportTree(fileTree, 'structure.tree')
958
+ * // Creates file:
959
+ * // └── src
960
+ * // ├── index.ts
961
+ * // ├── utils.ts
962
+ * // └── components
963
+ * // ├── Button.tsx
964
+ * // └── Input.tsx
965
+ * ```
966
+ *
967
+ * @example
968
+ * ```typescript
969
+ * // Custom label field - Organization chart
970
+ * const orgChart = [
971
+ * {
972
+ * title: 'CEO',
973
+ * children: [
974
+ * {
975
+ * title: 'CTO',
976
+ * children: [
977
+ * { title: 'Dev Lead' },
978
+ * { title: 'QA Lead' }
979
+ * ]
980
+ * },
981
+ * { title: 'CFO' }
982
+ * ]
983
+ * }
984
+ * ]
985
+ *
986
+ * await exportTree(orgChart, 'org-chart.tree', { labelField: 'title' })
987
+ * ```
988
+ *
989
+ * @example
990
+ * ```typescript
991
+ * // ASCII characters - Better terminal compatibility
992
+ * await exportTree(data, 'structure.tree', {
993
+ * verticalLine: '| ',
994
+ * middleBranch: '+-- ',
995
+ * lastBranch: '`-- ',
996
+ * emptySpace: ' '
997
+ * })
998
+ * ```
999
+ *
1000
+ * @example
1001
+ * ```typescript
1002
+ * // Custom label function - Rich formatting
1003
+ * const tasks = [
1004
+ * {
1005
+ * name: 'Backend',
1006
+ * status: 'in-progress',
1007
+ * assignee: 'Alice',
1008
+ * children: [
1009
+ * { name: 'API', status: 'done', assignee: 'Bob' },
1010
+ * { name: 'Database', status: 'pending', assignee: 'Charlie' }
1011
+ * ]
1012
+ * }
1013
+ * ]
1014
+ *
1015
+ * await exportTree(tasks, 'tasks.tree', {
1016
+ * labelFunction: (node) => `[${node.status}] ${node.name} (@${node.assignee})`
1017
+ * })
1018
+ * // Output:
1019
+ * // └── [in-progress] Backend (@Alice)
1020
+ * // ├── [done] API (@Bob)
1021
+ * // └── [pending] Database (@Charlie)
1022
+ * ```
1023
+ *
1024
+ * @throws {ValidationError} If data is not an array of nodes
1025
+ *
1026
+ * @see {@link importTree} for importing .tree files as text
1027
+ * @see {@link renderTreeAsText} for tree rendering without file export
1028
+ * @see {@link TreeExportOptions} for configuration options
1029
+ */
1030
+ declare function exportTree(data: any[], filePath: string, options?: TreeExportOptions): Promise<void>;
1031
+ /**
1032
+ * Imports a .tree file as plain text (Node.js only)
1033
+ *
1034
+ * Reads tree structure visualization files created with exportTree() as plain text.
1035
+ * Returns the ASCII/Unicode tree diagram as string. Only supported in Node.js environment.
1036
+ *
1037
+ * @param filePath - Path to .tree file (Node.js only)
1038
+ * @param _options - Reserved for future use
1039
+ * @returns Promise<string> Tree structure as text
1040
+ *
1041
+ * @example
1042
+ * ```typescript
1043
+ * // Import tree structure
1044
+ * const treeText = await importTree('./structure.tree')
1045
+ * console.log(treeText)
1046
+ * // Output:
1047
+ * // └── src
1048
+ * // ├── index.ts
1049
+ * // ├── utils.ts
1050
+ * // └── components
1051
+ * // ├── Button.tsx
1052
+ * // └── Input.tsx
1053
+ * ```
1054
+ *
1055
+ * @example
1056
+ * ```typescript
1057
+ * // Real-world: Display tree structure in terminal
1058
+ * async function showProjectStructure(filePath: string) {
1059
+ * try {
1060
+ * const structure = await importTree(filePath)
1061
+ * console.log('📁 Project Structure:')
1062
+ * console.log(structure)
1063
+ * } catch (error) {
1064
+ * console.error('Failed to load structure:', error.message)
1065
+ * }
1066
+ * }
1067
+ * ```
1068
+ *
1069
+ * @throws {DataError} If called in Browser environment (use readFileAsText with File object instead)
1070
+ *
1071
+ * @see {@link exportTree} for creating .tree files
1072
+ * @see {@link readFileAsText} for browser-compatible file reading
1073
+ */
1074
+ declare function importTree(filePath: string, _options?: any): Promise<string>;
1075
+ interface TxtExportOptions {
1076
+ /** Separator between array elements (default: '\n') */
1077
+ separator?: string;
1078
+ /** Custom function to convert objects to string */
1079
+ stringify?: (obj: any) => string;
1080
+ /** Indentation for JSON objects (default: 2) */
1081
+ indent?: number;
1082
+ }
1083
+ /**
1084
+ * Exports any type of data as plain text file
1085
+ *
1086
+ * Universal text file exporter supporting strings, arrays, objects, and primitives.
1087
+ * Automatically formats data based on type. Supports Node.js (filesystem) and Browser (download).
1088
+ *
1089
+ * Features:
1090
+ * - **Strings**: Direct output
1091
+ * - **Arrays**: One element per line (or custom separator)
1092
+ * - **Objects**: Formatted JSON with indentation
1093
+ * - **Primitives**: String conversion
1094
+ * - **Custom stringify**: Optional transform function
1095
+ *
1096
+ * @param data - Data to export (string, array, object, or primitive)
1097
+ * @param filePath - Output file path (Node.js) or filename (Browser)
1098
+ * @param options - Export options (separator, stringify function, indent)
1099
+ *
1100
+ * @example
1101
+ * ```typescript
1102
+ * // Export string - Direct output
1103
+ * await exportTxt('Hello, World!', 'message.txt')
1104
+ * // Creates: Hello, World!
1105
+ * ```
1106
+ *
1107
+ * @example
1108
+ * ```typescript
1109
+ * // Export array - One per line
1110
+ * const logs = [
1111
+ * '[INFO] Server started',
1112
+ * '[WARN] High memory usage',
1113
+ * '[ERROR] Connection failed'
1114
+ * ]
1115
+ * await exportTxt(logs, 'server.log')
1116
+ * // Creates:
1117
+ * // [INFO] Server started
1118
+ * // [WARN] High memory usage
1119
+ * // [ERROR] Connection failed
1120
+ * ```
1121
+ *
1122
+ * @example
1123
+ * ```typescript
1124
+ * // Export object - Formatted JSON
1125
+ * const config = {
1126
+ * server: { host: 'localhost', port: 3000 },
1127
+ * database: { url: 'mongodb://localhost' }
1128
+ * }
1129
+ * await exportTxt(config, 'config.txt', { indent: 2 })
1130
+ * // Creates formatted JSON
1131
+ * ```
1132
+ *
1133
+ * @example
1134
+ * ```typescript
1135
+ * // Custom separator - Comma-separated list
1136
+ * const tags = ['typescript', 'nodejs', 'express', 'mongodb']
1137
+ * await exportTxt(tags, 'tags.txt', { separator: ', ' })
1138
+ * // Creates: typescript, nodejs, express, mongodb
1139
+ * ```
1140
+ *
1141
+ * @example
1142
+ * ```typescript
1143
+ * // Custom stringify function - Markdown list
1144
+ * const tasks = [
1145
+ * { id: 1, title: 'Setup project', done: true },
1146
+ * { id: 2, title: 'Write tests', done: false }
1147
+ * ]
1148
+ * await exportTxt(tasks, 'tasks.txt', {
1149
+ * stringify: (tasks) =>
1150
+ * tasks.map(t => `- [${t.done ? 'x' : ' '}] ${t.title}`).join('\n')
1151
+ * })
1152
+ * // Creates:
1153
+ * // - [x] Setup project
1154
+ * // - [ ] Write tests
1155
+ * ```
1156
+ *
1157
+ * @example
1158
+ * ```typescript
1159
+ * // Real-world: Export error log with timestamps
1160
+ * async function exportErrorLog(errors: Error[]) {
1161
+ * const timestamp = new Date().toISOString()
1162
+ * const filename = `errors-${timestamp}.txt`
1163
+ *
1164
+ * await exportTxt(errors, filename, {
1165
+ * stringify: (errors) =>
1166
+ * errors.map(e => `[${new Date().toISOString()}] ${e.message}\n${e.stack}`).join('\n\n')
1167
+ * })
1168
+ *
1169
+ * console.log(`✅ Exported ${errors.length} errors to ${filename}`)
1170
+ * }
1171
+ * ```
1172
+ *
1173
+ * @see {@link importTxt} for importing text files with security validations
1174
+ * @see {@link TxtExportOptions} for configuration options
1175
+ */
1176
+ declare function exportTxt(data: any, filePath: string, options?: TxtExportOptions): Promise<void>;
1177
+ interface TxtImportOptions {
1178
+ /** Maximum file size in bytes (default: 10MB) */
1179
+ maxFileSize?: number;
1180
+ /** Maximum content length in characters (default: 1M characters) */
1181
+ maxLength?: number;
1182
+ /** Whether to validate content for security (default: true) */
1183
+ validateSecurity?: boolean;
1184
+ /** Whether to sanitize content (default: true) */
1185
+ sanitize?: boolean;
1186
+ }
1187
+ /**
1188
+ * Imports a .txt file as plain text with security validations (Node.js only)
1189
+ *
1190
+ * Reads text files with comprehensive security checks: file size limits, content length validation,
1191
+ * path traversal prevention, and dangerous character sanitization. Only supported in Node.js.
1192
+ *
1193
+ * Security features:
1194
+ * - **File size limit**: Default 10MB (configurable)
1195
+ * - **Content length limit**: Default 1M characters (configurable)
1196
+ * - **Path validation**: Prevents directory traversal attacks
1197
+ * - **Content sanitization**: Removes dangerous control characters
1198
+ * - **Line break normalization**: Standardizes to \n
1199
+ *
1200
+ * @param filePath - Path to .txt file (Node.js only)
1201
+ * @param options - Security and sanitization options
1202
+ *
1203
+ * @example
1204
+ * ```typescript
1205
+ * // Basic import - Default security settings
1206
+ * const content = await importTxt('./notes.txt')
1207
+ * console.log(content)
1208
+ * ```
1209
+ *
1210
+ * @example
1211
+ * ```typescript
1212
+ * // Custom size limits - Large file support
1213
+ * const largeFile = await importTxt('./large-log.txt', {
1214
+ * maxFileSize: 50 * 1024 * 1024, // 50MB
1215
+ * maxLength: 10_000_000 // 10M characters
1216
+ * })
1217
+ * ```
1218
+ *
1219
+ * @example
1220
+ * ```typescript
1221
+ * // Disable sanitization - Raw content
1222
+ * const rawContent = await importTxt('./data.txt', {
1223
+ * sanitize: false,
1224
+ * validateSecurity: false
1225
+ * })
1226
+ * ```
1227
+ *
1228
+ * @example
1229
+ * ```typescript
1230
+ * // Real-world: Safe log file reader with error handling
1231
+ * async function readServerLog(logPath: string) {
1232
+ * try {
1233
+ * const log = await importTxt(logPath, {
1234
+ * maxFileSize: 100 * 1024 * 1024, // 100MB logs
1235
+ * maxLength: 50_000_000, // 50M chars
1236
+ * sanitize: true,
1237
+ * validateSecurity: true
1238
+ * })
1239
+ *
1240
+ * const lines = log.split('\n')
1241
+ * const errors = lines.filter(line => line.includes('[ERROR]'))
1242
+ *
1243
+ * console.log(`📊 Log stats:`)
1244
+ * console.log(` Total lines: ${lines.length}`)
1245
+ * console.log(` Errors: ${errors.length}`)
1246
+ *
1247
+ * return { lines, errors }
1248
+ * } catch (error) {
1249
+ * if (error.message.includes('too large')) {
1250
+ * console.error('Log file exceeds size limit')
1251
+ * } else if (error.message.includes('not found')) {
1252
+ * console.error('Log file does not exist')
1253
+ * } else {
1254
+ * console.error('Failed to read log:', error.message)
1255
+ * }
1256
+ * throw error
1257
+ * }
1258
+ * }
1259
+ * ```
1260
+ *
1261
+ * @example
1262
+ * ```typescript
1263
+ * // Real-world: Secure user file upload processing
1264
+ * async function processUserUpload(uploadedFilePath: string) {
1265
+ * // Enforce strict limits for user-uploaded files
1266
+ * const content = await importTxt(uploadedFilePath, {
1267
+ * maxFileSize: 5 * 1024 * 1024, // 5MB max
1268
+ * maxLength: 1_000_000, // 1M chars max
1269
+ * validateSecurity: true, // Check for dangerous content
1270
+ * sanitize: true // Remove control chars
1271
+ * })
1272
+ *
1273
+ * // Process sanitized content safely
1274
+ * return analyzeText(content)
1275
+ * }
1276
+ * ```
1277
+ *
1278
+ * @throws {Error} If file exceeds maxFileSize
1279
+ * @throws {Error} If content exceeds maxLength
1280
+ * @throws {Error} If file path is invalid or unsafe
1281
+ * @throws {Error} If file not found
1282
+ * @throws {Error} If called in Browser environment
1283
+ *
1284
+ * @see {@link exportTxt} for creating text files
1285
+ * @see {@link TxtImportOptions} for configuration options
1286
+ * @see {@link readFileAsText} for browser-compatible file reading
1287
+ */
1288
+ declare function importTxt(filePath: string, options?: TxtImportOptions): Promise<string>;
1289
+ /**
1290
+ * Exports data in specified format based on file extension (Universal dispatcher)
1291
+ *
1292
+ * Universal export function that automatically detects format from filename extension
1293
+ * and delegates to specialized exporters (CSV, JSON, Tree, TXT). Simplifies data export
1294
+ * with a single unified API for all formats.
1295
+ *
1296
+ * Automatic format detection:
1297
+ * - **.csv** → exportCSV (PapaParse, UTF-8 BOM, semicolon delimiter)
1298
+ * - **.json** → exportJSON (pretty-printed JSON)
1299
+ * - **.tree** → exportTree (ASCII/Unicode tree visualization)
1300
+ * - **.txt** → exportTxt (plain text with auto-formatting)
1301
+ *
1302
+ * Environment support:
1303
+ * - **Node.js**: Writes to filesystem
1304
+ * - **Browser**: Triggers download
1305
+ *
1306
+ * @param data - Data to export (structure depends on format)
1307
+ * @param filePath - Output file path with extension (determines format)
1308
+ * @param options - Format-specific options (passed to specialized exporter)
1309
+ *
1310
+ * @example
1311
+ * ```typescript
1312
+ * // CSV export - Array of objects
1313
+ * const users = [
1314
+ * { id: 1, name: 'Alice', email: 'alice@example.com' },
1315
+ * { id: 2, name: 'Bob', email: 'bob@example.com' }
1316
+ * ]
1317
+ * await exportData(users, 'users.csv')
1318
+ * // Auto-detects CSV format, exports with semicolon delimiter
1319
+ * ```
1320
+ *
1321
+ * @example
1322
+ * ```typescript
1323
+ * // JSON export - Any data structure
1324
+ * const config = {
1325
+ * server: { host: 'localhost', port: 3000 },
1326
+ * database: { url: 'mongodb://localhost' },
1327
+ * features: { auth: true, cache: false }
1328
+ * }
1329
+ * await exportData(config, 'config.json', { indent: 2 })
1330
+ * // Auto-detects JSON format, pretty-prints with 2-space indent
1331
+ * ```
1332
+ *
1333
+ * @example
1334
+ * ```typescript
1335
+ * // Tree export - Hierarchical structure
1336
+ * const fileTree = [
1337
+ * {
1338
+ * name: 'src',
1339
+ * children: [
1340
+ * { name: 'index.ts' },
1341
+ * { name: 'utils.ts' },
1342
+ * {
1343
+ * name: 'components',
1344
+ * children: [
1345
+ * { name: 'Button.tsx' },
1346
+ * { name: 'Input.tsx' }
1347
+ * ]
1348
+ * }
1349
+ * ]
1350
+ * }
1351
+ * ]
1352
+ * await exportData(fileTree, 'structure.tree')
1353
+ * // Auto-detects tree format, renders as ASCII tree
1354
+ * ```
1355
+ *
1356
+ * @example
1357
+ * ```typescript
1358
+ * // Text export - Logs/strings
1359
+ * const logs = [
1360
+ * '[2024-01-15 10:30:00] Server started',
1361
+ * '[2024-01-15 10:30:15] Connected to database',
1362
+ * '[2024-01-15 10:31:00] Ready to accept connections'
1363
+ * ]
1364
+ * await exportData(logs, 'server.log')
1365
+ * // Auto-detects txt format, one line per array element
1366
+ * ```
1367
+ *
1368
+ * @example
1369
+ * ```typescript
1370
+ * // Real-world: Multi-format export function
1371
+ * async function exportReport(data: any[], format: 'csv' | 'json' | 'txt') {
1372
+ * const timestamp = new Date().toISOString().split('T')[0]
1373
+ * const filename = `report-${timestamp}.${format}`
1374
+ *
1375
+ * try {
1376
+ * await exportData(data, filename)
1377
+ * console.log(`✅ Report exported: ${filename}`)
1378
+ * return { success: true, filename }
1379
+ * } catch (error) {
1380
+ * console.error(`❌ Export failed:`, error.message)
1381
+ * return { success: false, error: error.message }
1382
+ * }
1383
+ * }
1384
+ *
1385
+ * // Usage
1386
+ * exportReport(users, 'csv') // users-2024-01-15.csv
1387
+ * exportReport(stats, 'json') // report-2024-01-15.json
1388
+ * exportReport(logs, 'txt') // report-2024-01-15.txt
1389
+ * ```
1390
+ *
1391
+ * @example
1392
+ * ```typescript
1393
+ * // Real-world: User-selected format export
1394
+ * async function exportWithUserChoice(data: any[], filename: string) {
1395
+ * // User provides filename with desired extension
1396
+ * // exportData automatically routes to correct exporter
1397
+ *
1398
+ * await exportData(data, filename)
1399
+ *
1400
+ * const format = detectFormatFromFilename(filename)
1401
+ * console.log(`Exported as ${format.toUpperCase()}`)
1402
+ * }
1403
+ *
1404
+ * // Works with any supported extension
1405
+ * exportWithUserChoice(data, 'data.csv')
1406
+ * exportWithUserChoice(data, 'data.json')
1407
+ * exportWithUserChoice(data, 'data.txt')
1408
+ * ```
1409
+ *
1410
+ * @throws {DataError} If file extension is not supported
1411
+ * @throws {ValidationError} If data structure is invalid for format (e.g., CSV requires array)
1412
+ *
1413
+ * @see {@link importData} for universal import
1414
+ * @see {@link exportCSV} for CSV-specific export
1415
+ * @see {@link exportJSON} for JSON-specific export
1416
+ * @see {@link exportTree} for tree-specific export
1417
+ * @see {@link exportTxt} for text-specific export
1418
+ */
1419
+ declare function exportData(data: any, filePath: string, options?: any): Promise<void>;
1420
+ /**
1421
+ * Imports data from specified file based on extension (Universal dispatcher)
1422
+ *
1423
+ * Universal import function that automatically detects format from filename extension
1424
+ * and delegates to specialized importers (CSV, JSON, Tree, TXT). Simplifies data import
1425
+ * with a single unified API for all formats. Node.js only.
1426
+ *
1427
+ * Automatic format detection:
1428
+ * - **.csv** → importCSV (PapaParse with header detection)
1429
+ * - **.json** → importJSON (native JSON.parse)
1430
+ * - **.tree** → importTree (plain text tree visualization)
1431
+ * - **.txt** → importTxt (plain text with security validations)
1432
+ *
1433
+ * @param filePath - Input file path with extension (determines format)
1434
+ * @param options - Format-specific options (passed to specialized importer)
1435
+ * @returns Promise<ImportData> Imported data (type depends on format)
1436
+ *
1437
+ * @example
1438
+ * ```typescript
1439
+ * // CSV import - Returns array of objects
1440
+ * const users = await importData('./users.csv')
1441
+ * // [
1442
+ * // { id: '1', name: 'Alice', email: 'alice@example.com' },
1443
+ * // { id: '2', name: 'Bob', email: 'bob@example.com' }
1444
+ * // ]
1445
+ * ```
1446
+ *
1447
+ * @example
1448
+ * ```typescript
1449
+ * // JSON import - Returns original data structure
1450
+ * const config = await importData('./config.json')
1451
+ * console.log(config.server.host) // 'localhost'
1452
+ * console.log(config.server.port) // 3000
1453
+ * ```
1454
+ *
1455
+ * @example
1456
+ * ```typescript
1457
+ * // Tree import - Returns plain text visualization
1458
+ * const treeText = await importData('./structure.tree')
1459
+ * console.log(treeText)
1460
+ * // └── src
1461
+ * // ├── index.ts
1462
+ * // ├── utils.ts
1463
+ * // └── components
1464
+ * ```
1465
+ *
1466
+ * @example
1467
+ * ```typescript
1468
+ * // Text import - Returns file content as string
1469
+ * const log = await importData('./server.log')
1470
+ * const lines = log.split('\n')
1471
+ * const errors = lines.filter(line => line.includes('[ERROR]'))
1472
+ * console.log(`Found ${errors.length} errors`)
1473
+ * ```
1474
+ *
1475
+ * @example
1476
+ * ```typescript
1477
+ * // Real-world: Dynamic file processor
1478
+ * async function processFile(filePath: string) {
1479
+ * const ext = detectFileExtension(filePath)
1480
+ * console.log(`Processing ${ext} file...`)
1481
+ *
1482
+ * const data = await importData(filePath)
1483
+ *
1484
+ * switch (ext) {
1485
+ * case 'csv':
1486
+ * return processCSVData(data as any[])
1487
+ * case 'json':
1488
+ * return processJSONData(data)
1489
+ * case 'txt':
1490
+ * return processTextData(data as string)
1491
+ * default:
1492
+ * throw new Error(`Unsupported format: ${ext}`)
1493
+ * }
1494
+ * }
1495
+ * ```
1496
+ *
1497
+ * @example
1498
+ * ```typescript
1499
+ * // Real-world: Batch file import with error handling
1500
+ * async function importAllFiles(directory: string) {
1501
+ * const files = await fs.readdir(directory)
1502
+ * const results = []
1503
+ *
1504
+ * for (const file of files) {
1505
+ * const filePath = path.join(directory, file)
1506
+ * const ext = detectFileExtension(file)
1507
+ *
1508
+ * // Skip unsupported formats
1509
+ * if (!['csv', 'json', 'txt', 'tree'].includes(ext || '')) {
1510
+ * console.log(`⏭️ Skipping unsupported file: ${file}`)
1511
+ * continue
1512
+ * }
1513
+ *
1514
+ * try {
1515
+ * const data = await importData(filePath)
1516
+ * results.push({ file, data, success: true })
1517
+ * console.log(`✅ Imported: ${file}`)
1518
+ * } catch (error) {
1519
+ * results.push({ file, error: error.message, success: false })
1520
+ * console.error(`❌ Failed: ${file} - ${error.message}`)
1521
+ * }
1522
+ * }
1523
+ *
1524
+ * return results
1525
+ * }
1526
+ * ```
1527
+ *
1528
+ * @example
1529
+ * ```typescript
1530
+ * // Real-world: Import with custom options per format
1531
+ * async function smartImport(filePath: string) {
1532
+ * const format = detectFormatFromFilename(filePath)
1533
+ *
1534
+ * let options: any = {}
1535
+ *
1536
+ * if (format === 'csv') {
1537
+ * options = { delimiter: ';', header: true }
1538
+ * } else if (format === 'json') {
1539
+ * options = { reviver: (key, value) => key === 'date' ? new Date(value) : value }
1540
+ * } else if (format === 'txt') {
1541
+ * options = { maxFileSize: 50 * 1024 * 1024, sanitize: true }
1542
+ * }
1543
+ *
1544
+ * return await importData(filePath, options)
1545
+ * }
1546
+ * ```
1547
+ *
1548
+ * @throws {DataError} If file extension is not supported
1549
+ * @throws {Error} If file not found or cannot be read
1550
+ * @throws {Error} If file format is invalid
1551
+ * @throws {DataError} If called in Browser environment (use readFileAsText with File object instead)
1552
+ *
1553
+ * @see {@link exportData} for universal export
1554
+ * @see {@link importCSV} for CSV-specific import
1555
+ * @see {@link importJSON} for JSON-specific import
1556
+ * @see {@link importTree} for tree-specific import
1557
+ * @see {@link importTxt} for text-specific import
1558
+ */
1559
+ declare function importData(filePath: string, options?: any): Promise<ImportData>;
1560
+
1561
+ export { type CSVData, type ExportData, type ExportFormat, type FileFormat, type ImportData, type TreeExportOptions, type TxtExportOptions, type TxtImportOptions, detectFileExtension, detectFormatFromFilename, detectUniversalFormat, exportData, exportTree, exportTxt, importData, importTree, importTxt, readFileAsText, validateCSVData, validateExportData };