@gzl10/ts-helpers 4.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +320 -0
- package/README.md +233 -0
- package/USAGE-GUIDE.md +800 -0
- package/dist/browser/async.js +15 -0
- package/dist/browser/async.js.map +1 -0
- package/dist/browser/chunk-4O7ZPIJN.js +383 -0
- package/dist/browser/chunk-4O7ZPIJN.js.map +1 -0
- package/dist/browser/chunk-75XNTC34.js +60 -0
- package/dist/browser/chunk-75XNTC34.js.map +1 -0
- package/dist/browser/chunk-C3D7YZVE.js +299 -0
- package/dist/browser/chunk-C3D7YZVE.js.map +1 -0
- package/dist/browser/chunk-CZL6C2EI.js +452 -0
- package/dist/browser/chunk-CZL6C2EI.js.map +1 -0
- package/dist/browser/chunk-D4FZFIVA.js +240 -0
- package/dist/browser/chunk-D4FZFIVA.js.map +1 -0
- package/dist/browser/chunk-IL7NG7IC.js +72 -0
- package/dist/browser/chunk-IL7NG7IC.js.map +1 -0
- package/dist/browser/chunk-NSBPE2FW.js +17 -0
- package/dist/browser/chunk-NSBPE2FW.js.map +1 -0
- package/dist/browser/chunk-SLQVNPTH.js +27 -0
- package/dist/browser/chunk-SLQVNPTH.js.map +1 -0
- package/dist/browser/chunk-WG7ILCUB.js +195 -0
- package/dist/browser/chunk-WG7ILCUB.js.map +1 -0
- package/dist/browser/chunk-WJA4JDMZ.js +278 -0
- package/dist/browser/chunk-WJA4JDMZ.js.map +1 -0
- package/dist/browser/chunk-ZFVYLUTT.js +65 -0
- package/dist/browser/chunk-ZFVYLUTT.js.map +1 -0
- package/dist/browser/chunk-ZYTSVMTI.js +263 -0
- package/dist/browser/chunk-ZYTSVMTI.js.map +1 -0
- package/dist/browser/dates.js +78 -0
- package/dist/browser/dates.js.map +1 -0
- package/dist/browser/environment-detection.js +21 -0
- package/dist/browser/environment-detection.js.map +1 -0
- package/dist/browser/environment.js +34 -0
- package/dist/browser/environment.js.map +1 -0
- package/dist/browser/errors.js +18 -0
- package/dist/browser/errors.js.map +1 -0
- package/dist/browser/index.js +412 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/math.js +51 -0
- package/dist/browser/math.js.map +1 -0
- package/dist/browser/number.js +10 -0
- package/dist/browser/number.js.map +1 -0
- package/dist/browser/objects.js +31 -0
- package/dist/browser/objects.js.map +1 -0
- package/dist/browser/strings.js +80 -0
- package/dist/browser/strings.js.map +1 -0
- package/dist/browser/validation-core.js +54 -0
- package/dist/browser/validation-core.js.map +1 -0
- package/dist/browser/validation-crypto.js +28 -0
- package/dist/browser/validation-crypto.js.map +1 -0
- package/dist/browser/validators.js +98 -0
- package/dist/browser/validators.js.map +1 -0
- package/dist/cjs/async.js +86 -0
- package/dist/cjs/async.js.map +1 -0
- package/dist/cjs/dates.js +285 -0
- package/dist/cjs/dates.js.map +1 -0
- package/dist/cjs/environment-detection.js +84 -0
- package/dist/cjs/environment-detection.js.map +1 -0
- package/dist/cjs/environment.js +261 -0
- package/dist/cjs/environment.js.map +1 -0
- package/dist/cjs/errors.js +80 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/index.js +2035 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/math.js +388 -0
- package/dist/cjs/math.js.map +1 -0
- package/dist/cjs/number.js +37 -0
- package/dist/cjs/number.js.map +1 -0
- package/dist/cjs/objects.js +249 -0
- package/dist/cjs/objects.js.map +1 -0
- package/dist/cjs/strings.js +253 -0
- package/dist/cjs/strings.js.map +1 -0
- package/dist/cjs/validation.js +450 -0
- package/dist/cjs/validation.js.map +1 -0
- package/dist/esm/async.js +15 -0
- package/dist/esm/async.js.map +1 -0
- package/dist/esm/chunk-4O7ZPIJN.js +383 -0
- package/dist/esm/chunk-4O7ZPIJN.js.map +1 -0
- package/dist/esm/chunk-75XNTC34.js +60 -0
- package/dist/esm/chunk-75XNTC34.js.map +1 -0
- package/dist/esm/chunk-BDOBKBKA.js +72 -0
- package/dist/esm/chunk-BDOBKBKA.js.map +1 -0
- package/dist/esm/chunk-C3D7YZVE.js +299 -0
- package/dist/esm/chunk-C3D7YZVE.js.map +1 -0
- package/dist/esm/chunk-CZL6C2EI.js +452 -0
- package/dist/esm/chunk-CZL6C2EI.js.map +1 -0
- package/dist/esm/chunk-EBLSTOEC.js +263 -0
- package/dist/esm/chunk-EBLSTOEC.js.map +1 -0
- package/dist/esm/chunk-NSBPE2FW.js +17 -0
- package/dist/esm/chunk-NSBPE2FW.js.map +1 -0
- package/dist/esm/chunk-SLQVNPTH.js +27 -0
- package/dist/esm/chunk-SLQVNPTH.js.map +1 -0
- package/dist/esm/chunk-WG7ILCUB.js +195 -0
- package/dist/esm/chunk-WG7ILCUB.js.map +1 -0
- package/dist/esm/chunk-WJA4JDMZ.js +278 -0
- package/dist/esm/chunk-WJA4JDMZ.js.map +1 -0
- package/dist/esm/chunk-ZFVYLUTT.js +65 -0
- package/dist/esm/chunk-ZFVYLUTT.js.map +1 -0
- package/dist/esm/dates.js +78 -0
- package/dist/esm/dates.js.map +1 -0
- package/dist/esm/environment-detection.js +21 -0
- package/dist/esm/environment-detection.js.map +1 -0
- package/dist/esm/environment.js +34 -0
- package/dist/esm/environment.js.map +1 -0
- package/dist/esm/errors.js +18 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/index.js +380 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/math.js +51 -0
- package/dist/esm/math.js.map +1 -0
- package/dist/esm/number.js +10 -0
- package/dist/esm/number.js.map +1 -0
- package/dist/esm/objects.js +31 -0
- package/dist/esm/objects.js.map +1 -0
- package/dist/esm/strings.js +80 -0
- package/dist/esm/strings.js.map +1 -0
- package/dist/esm/validation.js +54 -0
- package/dist/esm/validation.js.map +1 -0
- package/dist/node/async.js +93 -0
- package/dist/node/async.js.map +1 -0
- package/dist/node/csv.js +102 -0
- package/dist/node/csv.js.map +1 -0
- package/dist/node/data.js +880 -0
- package/dist/node/data.js.map +1 -0
- package/dist/node/dates.js +324 -0
- package/dist/node/dates.js.map +1 -0
- package/dist/node/environment.js +278 -0
- package/dist/node/environment.js.map +1 -0
- package/dist/node/errors.js +89 -0
- package/dist/node/errors.js.map +1 -0
- package/dist/node/index.js +3151 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/json.js +107 -0
- package/dist/node/json.js.map +1 -0
- package/dist/node/math.js +413 -0
- package/dist/node/math.js.map +1 -0
- package/dist/node/number.js +42 -0
- package/dist/node/number.js.map +1 -0
- package/dist/node/objects.js +264 -0
- package/dist/node/objects.js.map +1 -0
- package/dist/node/strings.js +293 -0
- package/dist/node/strings.js.map +1 -0
- package/dist/node/tree.js +89 -0
- package/dist/node/tree.js.map +1 -0
- package/dist/node/validation-core.js +477 -0
- package/dist/node/validation-core.js.map +1 -0
- package/dist/node/validation-crypto.js +179 -0
- package/dist/node/validation-crypto.js.map +1 -0
- package/dist/node/validation.js +677 -0
- package/dist/node/validation.js.map +1 -0
- package/dist/node/validators.js +123 -0
- package/dist/node/validators.js.map +1 -0
- package/dist/node-esm/async.js +15 -0
- package/dist/node-esm/async.js.map +1 -0
- package/dist/node-esm/chunk-3YOF7NPT.js +299 -0
- package/dist/node-esm/chunk-3YOF7NPT.js.map +1 -0
- package/dist/node-esm/chunk-64TBXJQS.js +263 -0
- package/dist/node-esm/chunk-64TBXJQS.js.map +1 -0
- package/dist/node-esm/chunk-75XNTC34.js +60 -0
- package/dist/node-esm/chunk-75XNTC34.js.map +1 -0
- package/dist/node-esm/chunk-C4PKXIPB.js +278 -0
- package/dist/node-esm/chunk-C4PKXIPB.js.map +1 -0
- package/dist/node-esm/chunk-CMDFZME3.js +452 -0
- package/dist/node-esm/chunk-CMDFZME3.js.map +1 -0
- package/dist/node-esm/chunk-DZZPUYMP.js +74 -0
- package/dist/node-esm/chunk-DZZPUYMP.js.map +1 -0
- package/dist/node-esm/chunk-HTSEHRHI.js +195 -0
- package/dist/node-esm/chunk-HTSEHRHI.js.map +1 -0
- package/dist/node-esm/chunk-JCAUVOPH.js +27 -0
- package/dist/node-esm/chunk-JCAUVOPH.js.map +1 -0
- package/dist/node-esm/chunk-KBHE3K2F.js +505 -0
- package/dist/node-esm/chunk-KBHE3K2F.js.map +1 -0
- package/dist/node-esm/chunk-LYTET5NX.js +65 -0
- package/dist/node-esm/chunk-LYTET5NX.js.map +1 -0
- package/dist/node-esm/chunk-PZ5AY32C.js +10 -0
- package/dist/node-esm/chunk-PZ5AY32C.js.map +1 -0
- package/dist/node-esm/chunk-UKGXL2QO.js +383 -0
- package/dist/node-esm/chunk-UKGXL2QO.js.map +1 -0
- package/dist/node-esm/chunk-XAEYT23H.js +164 -0
- package/dist/node-esm/chunk-XAEYT23H.js.map +1 -0
- package/dist/node-esm/csv.js +63 -0
- package/dist/node-esm/csv.js.map +1 -0
- package/dist/node-esm/data.js +32 -0
- package/dist/node-esm/data.js.map +1 -0
- package/dist/node-esm/dates.js +78 -0
- package/dist/node-esm/dates.js.map +1 -0
- package/dist/node-esm/environment.js +34 -0
- package/dist/node-esm/environment.js.map +1 -0
- package/dist/node-esm/errors.js +18 -0
- package/dist/node-esm/errors.js.map +1 -0
- package/dist/node-esm/index.js +426 -0
- package/dist/node-esm/index.js.map +1 -0
- package/dist/node-esm/json.js +68 -0
- package/dist/node-esm/json.js.map +1 -0
- package/dist/node-esm/math.js +51 -0
- package/dist/node-esm/math.js.map +1 -0
- package/dist/node-esm/number.js +10 -0
- package/dist/node-esm/number.js.map +1 -0
- package/dist/node-esm/objects.js +31 -0
- package/dist/node-esm/objects.js.map +1 -0
- package/dist/node-esm/strings.js +80 -0
- package/dist/node-esm/strings.js.map +1 -0
- package/dist/node-esm/tree.js +8 -0
- package/dist/node-esm/tree.js.map +1 -0
- package/dist/node-esm/validation-core.js +54 -0
- package/dist/node-esm/validation-core.js.map +1 -0
- package/dist/node-esm/validation-crypto.js +26 -0
- package/dist/node-esm/validation-crypto.js.map +1 -0
- package/dist/node-esm/validation.js +606 -0
- package/dist/node-esm/validation.js.map +1 -0
- package/dist/node-esm/validators.js +98 -0
- package/dist/node-esm/validators.js.map +1 -0
- package/dist/types/async-C8gvbSG-.d.ts +453 -0
- package/dist/types/async.d.ts +1 -0
- package/dist/types/csv.d.ts +226 -0
- package/dist/types/data.d.ts +1561 -0
- package/dist/types/dates-hTiE0Z11.d.ts +298 -0
- package/dist/types/dates.d.ts +1 -0
- package/dist/types/environment-B8eLS7KT.d.ts +420 -0
- package/dist/types/environment-detection.d.ts +102 -0
- package/dist/types/environment.d.ts +1 -0
- package/dist/types/errors.d.ts +147 -0
- package/dist/types/index.d.ts +211 -0
- package/dist/types/json.d.ts +284 -0
- package/dist/types/math-BQ9Lwdp7.d.ts +2060 -0
- package/dist/types/math.d.ts +1 -0
- package/dist/types/number-CYnQfLWj.d.ts +44 -0
- package/dist/types/number.d.ts +1 -0
- package/dist/types/objects-BohS8GCS.d.ts +1185 -0
- package/dist/types/objects.d.ts +1 -0
- package/dist/types/strings-CiqRPYLL.d.ts +1349 -0
- package/dist/types/strings.d.ts +1 -0
- package/dist/types/tree.d.ts +284 -0
- package/dist/types/validation-core-DfHF8rCG.d.ts +238 -0
- package/dist/types/validation-crypto-browser.d.ts +56 -0
- package/dist/types/validation-crypto-node.d.ts +31 -0
- package/dist/types/validation.d.ts +1 -0
- package/dist/types/validators.d.ts +216 -0
- package/package.json +253 -0
|
@@ -0,0 +1,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 };
|