@sqlrooms/utils 0.0.1-alpha.0 → 0.0.2
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/dist/filepaths.d.ts +74 -0
- package/dist/filepaths.d.ts.map +1 -0
- package/dist/filepaths.js +156 -0
- package/dist/filepaths.test.d.ts +2 -0
- package/dist/filepaths.test.d.ts.map +1 -0
- package/dist/filepaths.test.js +42 -0
- package/dist/format.d.ts +21 -0
- package/dist/format.d.ts.map +1 -1
- package/dist/format.js +21 -0
- package/dist/helpers.d.ts +58 -3
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +57 -24
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/random.d.ts +13 -0
- package/dist/random.d.ts.map +1 -0
- package/dist/random.js +29 -0
- package/dist/str.d.ts +16 -10
- package/dist/str.d.ts.map +1 -1
- package/dist/str.js +16 -93
- package/dist/xhr.d.ts +33 -1
- package/dist/xhr.d.ts.map +1 -1
- package/dist/xhr.js +29 -0
- package/package.json +9 -8
- package/CHANGELOG.md +0 -10
- package/jest.config.ms +0 -8
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Splits a file path into its directory, name, and extension components.
|
|
3
|
+
* @param filePath - The full file path to split
|
|
4
|
+
* @returns An object containing the directory path, file name (without extension), and extension
|
|
5
|
+
* @example
|
|
6
|
+
* splitFilePath("path/to/file.txt") // returns { dir: "path/to", name: "file", ext: "txt" }
|
|
7
|
+
*/
|
|
8
|
+
export declare function splitFilePath(filePath: string): {
|
|
9
|
+
dir: string;
|
|
10
|
+
name: string;
|
|
11
|
+
ext: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Converts a filename into a valid and unique column or table name for database use.
|
|
15
|
+
* - Removes file extension
|
|
16
|
+
* - Replaces invalid characters with underscores
|
|
17
|
+
* - Ensures the name starts with a letter or underscore
|
|
18
|
+
* - Truncates to max length of 63 characters
|
|
19
|
+
* - Ensures uniqueness among existing names
|
|
20
|
+
*
|
|
21
|
+
* @param filename - The original filename to convert
|
|
22
|
+
* @param existingTables - Optional array of existing table names to ensure uniqueness
|
|
23
|
+
* @returns A valid and unique table/column name
|
|
24
|
+
* @example
|
|
25
|
+
* convertToUniqueColumnOrTableName("my-file.csv") // returns "my_file"
|
|
26
|
+
* convertToUniqueColumnOrTableName("123data.csv") // returns "_123data"
|
|
27
|
+
*/
|
|
28
|
+
export declare function convertToUniqueColumnOrTableName(filename: string, existingTables?: string[]): string;
|
|
29
|
+
/**
|
|
30
|
+
* Generates a unique name by appending a numeric suffix if the name already exists.
|
|
31
|
+
* @param name - The base name to make unique
|
|
32
|
+
* @param usedNames - Optional array of existing names to check against
|
|
33
|
+
* @returns A unique name, potentially with a numeric suffix
|
|
34
|
+
* @example
|
|
35
|
+
* generateUniqueName("table", ["table"]) // returns "table_1"
|
|
36
|
+
* generateUniqueName("table_1", ["table_1"]) // returns "table_2"
|
|
37
|
+
*/
|
|
38
|
+
export declare function generateUniqueName(name: string, usedNames?: string[]): string;
|
|
39
|
+
/**
|
|
40
|
+
* Generates a unique file path by appending a numeric suffix if the path already exists.
|
|
41
|
+
* @param filePath - The original file path
|
|
42
|
+
* @param existingPaths - Array of existing file paths to check against
|
|
43
|
+
* @returns A unique file path
|
|
44
|
+
* @example
|
|
45
|
+
* generateUniquePath("file.txt", ["file.txt"]) // returns "file_1.txt"
|
|
46
|
+
*/
|
|
47
|
+
export declare function generateUniquePath(filePath: string, existingPaths: string[]): string;
|
|
48
|
+
/**
|
|
49
|
+
* Converts a string into a valid and unique S3 object name.
|
|
50
|
+
* - Replaces special characters with underscores
|
|
51
|
+
* - Ensures name is within S3's length limits
|
|
52
|
+
* - Ensures uniqueness among existing objects
|
|
53
|
+
*
|
|
54
|
+
* @param str - The string to convert into an S3 object name
|
|
55
|
+
* @param existingObjects - Optional array of existing S3 object names to ensure uniqueness
|
|
56
|
+
* @returns A valid and unique S3 object name
|
|
57
|
+
* @example
|
|
58
|
+
* convertToUniqueS3ObjectName("my file.txt") // returns "my_file.txt"
|
|
59
|
+
*/
|
|
60
|
+
export declare function convertToUniqueS3ObjectName(str: string, existingObjects?: string[]): string;
|
|
61
|
+
/**
|
|
62
|
+
* Converts a string into a valid and unique S3 folder path.
|
|
63
|
+
* - Ensures the path ends with a forward slash
|
|
64
|
+
* - Replaces special characters with underscores
|
|
65
|
+
* - Ensures uniqueness among existing paths
|
|
66
|
+
*
|
|
67
|
+
* @param str - The string to convert into an S3 folder path
|
|
68
|
+
* @param existingObjects - Optional array of existing S3 paths to ensure uniqueness
|
|
69
|
+
* @returns A valid and unique S3 folder path ending with a forward slash
|
|
70
|
+
* @example
|
|
71
|
+
* convertToUniqueS3FolderPath("my folder") // returns "my_folder/"
|
|
72
|
+
*/
|
|
73
|
+
export declare function convertToUniqueS3FolderPath(str: string, existingObjects?: string[]): string;
|
|
74
|
+
//# sourceMappingURL=filepaths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filepaths.d.ts","sourceRoot":"","sources":["../src/filepaths.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb,CAYA;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,MAAM,EAChB,cAAc,CAAC,EAAE,MAAM,EAAE,GACxB,MAAM,CAoBR;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,UAsBpE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EAAE,GACtB,MAAM,CAqBR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,MAAM,EACX,eAAe,CAAC,EAAE,MAAM,EAAE,GACzB,MAAM,CAeR;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,MAAM,EACX,eAAe,CAAC,EAAE,MAAM,EAAE,GACzB,MAAM,CAaR"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Splits a file path into its directory, name, and extension components.
|
|
3
|
+
* @param filePath - The full file path to split
|
|
4
|
+
* @returns An object containing the directory path, file name (without extension), and extension
|
|
5
|
+
* @example
|
|
6
|
+
* splitFilePath("path/to/file.txt") // returns { dir: "path/to", name: "file", ext: "txt" }
|
|
7
|
+
*/
|
|
8
|
+
export function splitFilePath(filePath) {
|
|
9
|
+
const pathParts = filePath.split('/');
|
|
10
|
+
const file = pathParts.pop() || '';
|
|
11
|
+
const dotIndex = file.lastIndexOf('.');
|
|
12
|
+
if (dotIndex === -1 || dotIndex === 0)
|
|
13
|
+
return { dir: pathParts.join('/'), name: file, ext: '' };
|
|
14
|
+
const name = file.substring(0, dotIndex);
|
|
15
|
+
const ext = file.substring(dotIndex + 1);
|
|
16
|
+
return { dir: pathParts.join('/'), name, ext };
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Converts a filename into a valid and unique column or table name for database use.
|
|
20
|
+
* - Removes file extension
|
|
21
|
+
* - Replaces invalid characters with underscores
|
|
22
|
+
* - Ensures the name starts with a letter or underscore
|
|
23
|
+
* - Truncates to max length of 63 characters
|
|
24
|
+
* - Ensures uniqueness among existing names
|
|
25
|
+
*
|
|
26
|
+
* @param filename - The original filename to convert
|
|
27
|
+
* @param existingTables - Optional array of existing table names to ensure uniqueness
|
|
28
|
+
* @returns A valid and unique table/column name
|
|
29
|
+
* @example
|
|
30
|
+
* convertToUniqueColumnOrTableName("my-file.csv") // returns "my_file"
|
|
31
|
+
* convertToUniqueColumnOrTableName("123data.csv") // returns "_123data"
|
|
32
|
+
*/
|
|
33
|
+
export function convertToUniqueColumnOrTableName(filename, existingTables) {
|
|
34
|
+
// Remove file extension
|
|
35
|
+
const base = filename.replace(/\.[^/.]+$/, '');
|
|
36
|
+
// Replace any invalid character with underscore, and convert to lowercase
|
|
37
|
+
let tableName = base.replace(/[^a-z0-9_]/gi, '_');
|
|
38
|
+
// If the first character is a number, prepend an underscore
|
|
39
|
+
if (/^\d/.test(tableName)) {
|
|
40
|
+
tableName = '_' + tableName;
|
|
41
|
+
}
|
|
42
|
+
// Truncate to the max length 63
|
|
43
|
+
if (tableName.length > 63) {
|
|
44
|
+
tableName = tableName.substring(0, 63);
|
|
45
|
+
}
|
|
46
|
+
tableName = generateUniqueName(tableName, existingTables);
|
|
47
|
+
return tableName;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Generates a unique name by appending a numeric suffix if the name already exists.
|
|
51
|
+
* @param name - The base name to make unique
|
|
52
|
+
* @param usedNames - Optional array of existing names to check against
|
|
53
|
+
* @returns A unique name, potentially with a numeric suffix
|
|
54
|
+
* @example
|
|
55
|
+
* generateUniqueName("table", ["table"]) // returns "table_1"
|
|
56
|
+
* generateUniqueName("table_1", ["table_1"]) // returns "table_2"
|
|
57
|
+
*/
|
|
58
|
+
export function generateUniqueName(name, usedNames) {
|
|
59
|
+
const usedNamesLower = usedNames?.map((n) => n.toLowerCase());
|
|
60
|
+
// If tableName exists in the list
|
|
61
|
+
if (usedNamesLower?.includes(name.toLowerCase())) {
|
|
62
|
+
let baseName = name;
|
|
63
|
+
let i = 0;
|
|
64
|
+
// If tableName ends with `_${i}` pattern, update the baseTableName and i
|
|
65
|
+
const matched = name.match(/^(.+)_(\d+)$/);
|
|
66
|
+
if (matched) {
|
|
67
|
+
baseName = matched[1];
|
|
68
|
+
i = Number(matched[2]);
|
|
69
|
+
}
|
|
70
|
+
do {
|
|
71
|
+
i++;
|
|
72
|
+
name = `${baseName}_${i}`;
|
|
73
|
+
} while (usedNamesLower.includes(name.toLowerCase()));
|
|
74
|
+
}
|
|
75
|
+
return name;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Generates a unique file path by appending a numeric suffix if the path already exists.
|
|
79
|
+
* @param filePath - The original file path
|
|
80
|
+
* @param existingPaths - Array of existing file paths to check against
|
|
81
|
+
* @returns A unique file path
|
|
82
|
+
* @example
|
|
83
|
+
* generateUniquePath("file.txt", ["file.txt"]) // returns "file_1.txt"
|
|
84
|
+
*/
|
|
85
|
+
export function generateUniquePath(filePath, existingPaths) {
|
|
86
|
+
let nextPath = filePath;
|
|
87
|
+
if (existingPaths?.includes(filePath)) {
|
|
88
|
+
const { dir, name, ext } = splitFilePath(filePath);
|
|
89
|
+
let i = 0;
|
|
90
|
+
let baseName = name;
|
|
91
|
+
const matched = name.match(/^(.+)_(\d+)$/);
|
|
92
|
+
if (matched) {
|
|
93
|
+
baseName = matched[1];
|
|
94
|
+
i = Number(matched[2]);
|
|
95
|
+
}
|
|
96
|
+
do {
|
|
97
|
+
i++;
|
|
98
|
+
const fname = `${baseName}_${i}${ext ? `.${ext}` : ''}`;
|
|
99
|
+
nextPath = `${dir}${dir ? '/' : ''}${fname}`;
|
|
100
|
+
} while (existingPaths.includes(nextPath));
|
|
101
|
+
}
|
|
102
|
+
return nextPath;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Converts a string into a valid and unique S3 object name.
|
|
106
|
+
* - Replaces special characters with underscores
|
|
107
|
+
* - Ensures name is within S3's length limits
|
|
108
|
+
* - Ensures uniqueness among existing objects
|
|
109
|
+
*
|
|
110
|
+
* @param str - The string to convert into an S3 object name
|
|
111
|
+
* @param existingObjects - Optional array of existing S3 object names to ensure uniqueness
|
|
112
|
+
* @returns A valid and unique S3 object name
|
|
113
|
+
* @example
|
|
114
|
+
* convertToUniqueS3ObjectName("my file.txt") // returns "my_file.txt"
|
|
115
|
+
*/
|
|
116
|
+
export function convertToUniqueS3ObjectName(str, existingObjects) {
|
|
117
|
+
let rv = str
|
|
118
|
+
.trim() // Remove leading and trailing white spaces
|
|
119
|
+
.replace(/[^\w\s-\.]/g, '_') // Replace special characters with underscores
|
|
120
|
+
.replace(/\s+/g, '_') // Replace consecutive spaces with a single underscore
|
|
121
|
+
// .replace(/_+/g, '_') // Remove consecutive underscores
|
|
122
|
+
// .replace(/^_/, '') // Remove leading underscores
|
|
123
|
+
// .replace(/_$/, '') // Remove trailing underscores
|
|
124
|
+
.slice(0, 255); // Truncate the string if it exceeds 255 characters
|
|
125
|
+
if (existingObjects?.length) {
|
|
126
|
+
rv = generateUniquePath(rv, existingObjects);
|
|
127
|
+
}
|
|
128
|
+
return rv;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Converts a string into a valid and unique S3 folder path.
|
|
132
|
+
* - Ensures the path ends with a forward slash
|
|
133
|
+
* - Replaces special characters with underscores
|
|
134
|
+
* - Ensures uniqueness among existing paths
|
|
135
|
+
*
|
|
136
|
+
* @param str - The string to convert into an S3 folder path
|
|
137
|
+
* @param existingObjects - Optional array of existing S3 paths to ensure uniqueness
|
|
138
|
+
* @returns A valid and unique S3 folder path ending with a forward slash
|
|
139
|
+
* @example
|
|
140
|
+
* convertToUniqueS3FolderPath("my folder") // returns "my_folder/"
|
|
141
|
+
*/
|
|
142
|
+
export function convertToUniqueS3FolderPath(str, existingObjects) {
|
|
143
|
+
let next = convertToUniqueS3ObjectName(str, existingObjects);
|
|
144
|
+
if (!next.endsWith('/'))
|
|
145
|
+
next += '/'; // Add trailing slash if not present
|
|
146
|
+
return next;
|
|
147
|
+
// return (
|
|
148
|
+
// str
|
|
149
|
+
// .trim() // Remove leading and trailing white spaces
|
|
150
|
+
// .replace(/\/+/g, '/') // Replace consecutive slashes with a single slash
|
|
151
|
+
// .replace(/[^\w\s-\/]/g, '_') // Replace special characters with underscores
|
|
152
|
+
// .replace(/\s+/g, '_') // Replace consecutive spaces with a single underscore
|
|
153
|
+
// .replace(/^\//, '') + // Remove leading slash
|
|
154
|
+
// (str.endsWith('/') ? '' : '/')
|
|
155
|
+
// );
|
|
156
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filepaths.test.d.ts","sourceRoot":"","sources":["../src/filepaths.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { generateUniqueName, generateUniquePath, convertToUniqueS3ObjectName, } from './filepaths';
|
|
2
|
+
test('generateUniqueName generates unique table names', () => {
|
|
3
|
+
expect(generateUniqueName('foo', [])).toBe('foo');
|
|
4
|
+
expect(generateUniqueName('foo', ['345'])).toBe('foo');
|
|
5
|
+
expect(generateUniqueName('foo', ['foo_1'])).toBe('foo');
|
|
6
|
+
expect(generateUniqueName('foo', ['foo', 'foo_1'])).toBe('foo_2');
|
|
7
|
+
expect(generateUniqueName('foo_1', ['foo_1'])).toBe('foo_2');
|
|
8
|
+
expect(generateUniqueName('foo_2', ['foo_2'])).toBe('foo_3');
|
|
9
|
+
expect(generateUniqueName('foo', ['foo', 'foo_1', 'foo_2'])).toBe('foo_3');
|
|
10
|
+
expect(generateUniqueName('')).toBe('');
|
|
11
|
+
expect(generateUniqueName('', [''])).toBe('_1');
|
|
12
|
+
expect(generateUniqueName('_', ['_'])).toBe('__1');
|
|
13
|
+
});
|
|
14
|
+
test('generateUniquePath generates unique paths', () => {
|
|
15
|
+
expect(generateUniquePath('/foo/bar.csv', [])).toBe('/foo/bar.csv');
|
|
16
|
+
expect(generateUniquePath('/foo/bar.csv', ['345'])).toBe('/foo/bar.csv');
|
|
17
|
+
expect(generateUniquePath('/foo/bar.csv', ['/foo/bar.csv'])).toBe('/foo/bar_1.csv');
|
|
18
|
+
expect(generateUniquePath('/foo/bar.csv', ['/foo/bar_1.csv'])).toBe('/foo/bar.csv');
|
|
19
|
+
expect(generateUniquePath('/foo/bar.csv', ['/foo/bar.csv', '/foo/bar_1.csv'])).toBe('/foo/bar_2.csv');
|
|
20
|
+
expect(generateUniquePath('/foo/bar.csv', [
|
|
21
|
+
'/foo/bar.csv',
|
|
22
|
+
'/foo/bar_1.csv',
|
|
23
|
+
'/foo/bar_2.csv',
|
|
24
|
+
])).toBe('/foo/bar_3.csv');
|
|
25
|
+
expect(generateUniquePath('/foo/bar_1.csv', ['/foo/bar_1.csv'])).toBe('/foo/bar_2.csv');
|
|
26
|
+
expect(generateUniquePath('/foo/bar_2.csv', ['/foo/bar_2.csv'])).toBe('/foo/bar_3.csv');
|
|
27
|
+
expect(generateUniquePath('/foo', [])).toBe('/foo');
|
|
28
|
+
expect(generateUniquePath('/foo/bar', [])).toBe('/foo/bar');
|
|
29
|
+
expect(generateUniquePath('/foo/bar', ['/foo/bar'])).toBe('/foo/bar_1');
|
|
30
|
+
expect(generateUniquePath('/', [])).toBe('/');
|
|
31
|
+
expect(generateUniquePath('', [])).toBe('');
|
|
32
|
+
expect(generateUniquePath('', [''])).toBe('_1');
|
|
33
|
+
expect(generateUniquePath('_', ['_'])).toBe('__1');
|
|
34
|
+
});
|
|
35
|
+
test('convertToUniqueS3ObjectName works correctly', () => {
|
|
36
|
+
expect(convertToUniqueS3ObjectName('/flows.csv', [])).toBe('_flows.csv');
|
|
37
|
+
expect(convertToUniqueS3ObjectName('&flows.csv', [])).toBe('_flows.csv');
|
|
38
|
+
expect(convertToUniqueS3ObjectName('@flows.csv', [])).toBe('_flows.csv');
|
|
39
|
+
expect(convertToUniqueS3ObjectName('/flows.csv', [])).toBe('_flows.csv');
|
|
40
|
+
expect(convertToUniqueS3ObjectName('flows.csv', ['flows.csv'])).toBe('flows_1.csv');
|
|
41
|
+
expect(convertToUniqueS3ObjectName('flows.csv', ['flows.csv', 'flows_1.csv'])).toBe('flows_2.csv');
|
|
42
|
+
});
|
package/dist/format.d.ts
CHANGED
|
@@ -1,11 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formats a number as a string with thousands separators and no decimal places.
|
|
3
|
+
* Example: 1234567 -> "1,234,567"
|
|
4
|
+
*/
|
|
1
5
|
export declare const formatCount: (n: number | {
|
|
2
6
|
valueOf(): number;
|
|
3
7
|
}) => string;
|
|
8
|
+
/**
|
|
9
|
+
* Formats a number as a string with 4 significant digits and SI prefix.
|
|
10
|
+
* Example: 1234567 -> "1.235M"
|
|
11
|
+
*/
|
|
4
12
|
export declare const formatCount4: (n: number | {
|
|
5
13
|
valueOf(): number;
|
|
6
14
|
}) => string;
|
|
15
|
+
/**
|
|
16
|
+
* Formats a number as a string with thousands separators and SI prefix.
|
|
17
|
+
* Example: 1234567 -> "1M"
|
|
18
|
+
*/
|
|
7
19
|
export declare const formatCountShort: (n: number | {
|
|
8
20
|
valueOf(): number;
|
|
9
21
|
}) => string;
|
|
22
|
+
/**
|
|
23
|
+
* Shortens a string to a specified maximum length by truncating and adding an ellipsis.
|
|
24
|
+
* @param str - The string to shorten
|
|
25
|
+
* @param maxLength - Maximum length of the resulting string (including ellipsis). Defaults to 10.
|
|
26
|
+
* @returns The shortened string with ellipsis if truncated, or the original string if shorter than maxLength
|
|
27
|
+
* @example
|
|
28
|
+
* shorten("Hello World", 8) // Returns "Hello..."
|
|
29
|
+
* shorten("Hi", 8) // Returns "Hi"
|
|
30
|
+
*/
|
|
10
31
|
export declare function shorten(str: string, maxLength?: number): string;
|
|
11
32
|
//# sourceMappingURL=format.d.ts.map
|
package/dist/format.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW;;YAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,WAAW;;YAA0B,CAAC;AAEnD;;;GAGG;AACH,eAAO,MAAM,YAAY;;YAA0B,CAAC;AAEpD;;;GAGG;AACH,eAAO,MAAM,gBAAgB;;YAA0B,CAAC;AAExD;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,SAAK,GAAG,MAAM,CAK3D"}
|
package/dist/format.js
CHANGED
|
@@ -1,7 +1,28 @@
|
|
|
1
1
|
import * as d3Format from 'd3-format';
|
|
2
|
+
/**
|
|
3
|
+
* Formats a number as a string with thousands separators and no decimal places.
|
|
4
|
+
* Example: 1234567 -> "1,234,567"
|
|
5
|
+
*/
|
|
2
6
|
export const formatCount = d3Format.format(',.0f');
|
|
7
|
+
/**
|
|
8
|
+
* Formats a number as a string with 4 significant digits and SI prefix.
|
|
9
|
+
* Example: 1234567 -> "1.235M"
|
|
10
|
+
*/
|
|
3
11
|
export const formatCount4 = d3Format.format('.4~s');
|
|
12
|
+
/**
|
|
13
|
+
* Formats a number as a string with thousands separators and SI prefix.
|
|
14
|
+
* Example: 1234567 -> "1M"
|
|
15
|
+
*/
|
|
4
16
|
export const formatCountShort = d3Format.format(',.0s');
|
|
17
|
+
/**
|
|
18
|
+
* Shortens a string to a specified maximum length by truncating and adding an ellipsis.
|
|
19
|
+
* @param str - The string to shorten
|
|
20
|
+
* @param maxLength - Maximum length of the resulting string (including ellipsis). Defaults to 10.
|
|
21
|
+
* @returns The shortened string with ellipsis if truncated, or the original string if shorter than maxLength
|
|
22
|
+
* @example
|
|
23
|
+
* shorten("Hello World", 8) // Returns "Hello..."
|
|
24
|
+
* shorten("Hi", 8) // Returns "Hi"
|
|
25
|
+
*/
|
|
5
26
|
export function shorten(str, maxLength = 10) {
|
|
6
27
|
if (str.length <= maxLength) {
|
|
7
28
|
return str;
|
package/dist/helpers.d.ts
CHANGED
|
@@ -1,11 +1,66 @@
|
|
|
1
1
|
import { ConfigType } from 'dayjs';
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Number formatter instance configured for US locale with no minimum fraction digits
|
|
4
|
+
*/
|
|
4
5
|
export declare const NUMBER_FORMAT: Intl.NumberFormat;
|
|
6
|
+
/**
|
|
7
|
+
* Formats a number using US locale formatting
|
|
8
|
+
* @param n - Number to format
|
|
9
|
+
* @returns Formatted number string
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* formatNumber(1234567.89); // "1,234,568"
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
5
15
|
export declare const formatNumber: (n: number) => string;
|
|
16
|
+
/**
|
|
17
|
+
* Formats a date into a human-readable datetime string
|
|
18
|
+
* @param d - Date to format (can be Date object, timestamp number, or bigint)
|
|
19
|
+
* @returns Formatted string in "Day YYYY-MM-DD HH:MM AM/PM" format
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* formatDateTime(new Date()); // e.g., "Wed 2024-03-13 02:30 PM"
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
6
25
|
export declare const formatDateTime: (d: Date | number | bigint) => string;
|
|
26
|
+
/**
|
|
27
|
+
* Formats a date into YYYY-MM-DD format
|
|
28
|
+
* @param d - Date to format (can be Date object, timestamp number, or bigint)
|
|
29
|
+
* @returns Formatted date string
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* formatDate(new Date()); // e.g., "2024-03-13"
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
7
35
|
export declare const formatDate: (d: Date | number | bigint) => string;
|
|
36
|
+
/**
|
|
37
|
+
* Formats a date into time of day (HH:MM AM/PM)
|
|
38
|
+
* @param d - Date to format (can be Date object, timestamp number, or bigint)
|
|
39
|
+
* @returns Formatted time string
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* formatTimeOfDay(new Date()); // e.g., "02:30 PM"
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
8
45
|
export declare const formatTimeOfDay: (d: Date | number | bigint) => string;
|
|
46
|
+
/**
|
|
47
|
+
* Formats a date relative to the current time (e.g., "2 hours ago", "in 3 days")
|
|
48
|
+
* @param d - Date to format (accepts any dayjs ConfigType)
|
|
49
|
+
* @returns Human-readable relative time string
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* formatTimeRelative(new Date(Date.now() - 3600000)); // "1 hour ago"
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
9
55
|
export declare const formatTimeRelative: (d: ConfigType) => string;
|
|
10
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Extracts and formats an error message for display, removing common prefixes and truncating at first newline
|
|
58
|
+
* @param e - Error object or any other value that can be converted to string
|
|
59
|
+
* @returns Cleaned up error message string
|
|
60
|
+
* @example
|
|
61
|
+
* ```ts
|
|
62
|
+
* getErrorMessageForDisplay(new Error("Query failed: Error: Invalid syntax\nMore details...")); // "Invalid syntax"
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export declare const getErrorMessageForDisplay: (e: unknown) => string;
|
|
11
66
|
//# sourceMappingURL=helpers.d.ts.map
|
package/dist/helpers.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAEA,OAAc,EAAC,UAAU,EAAC,MAAM,OAAO,CAAC;AAKxC;;GAEG;AACH,eAAO,MAAM,aAAa,mBAExB,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,MAAO,MAAM,WAA4B,CAAC;AAMnE;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,MAAO,IAAI,GAAG,MAAM,GAAG,MAAM,WAGvD,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU,MAAO,IAAI,GAAG,MAAM,GAAG,MAAM,WAGnD,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,MAAO,IAAI,GAAG,MAAM,GAAG,MAAM,WAGxD,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,MAAO,UAAU,WAE/C,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,MAAO,OAAO,WAKnD,CAAC"}
|
package/dist/helpers.js
CHANGED
|
@@ -1,53 +1,86 @@
|
|
|
1
1
|
import { timeFormat } from 'd3-time-format';
|
|
2
|
-
import { alea } from 'seedrandom';
|
|
3
2
|
import dayjs from 'dayjs';
|
|
4
3
|
import relativeTime from 'dayjs/plugin/relativeTime';
|
|
5
4
|
dayjs.extend(relativeTime);
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
export function genRandomStr(length, seed) {
|
|
12
|
-
const rnd = seed ? alea(seed) : Math.random;
|
|
13
|
-
return Array.from((function* () {
|
|
14
|
-
for (let i = 0; i < length; i++) {
|
|
15
|
-
const v = Math.floor(rnd() * (26 * 2 + 10));
|
|
16
|
-
if (v < 26) {
|
|
17
|
-
yield String.fromCharCode(v + 65); // 'A' - 'Z'
|
|
18
|
-
}
|
|
19
|
-
else if (v < 52) {
|
|
20
|
-
yield String.fromCharCode(v + 71); // 'a' - 'z'
|
|
21
|
-
}
|
|
22
|
-
else {
|
|
23
|
-
yield String.fromCharCode(v + 48); // '0' - '9'
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
})()).join('');
|
|
27
|
-
}
|
|
5
|
+
/**
|
|
6
|
+
* Number formatter instance configured for US locale with no minimum fraction digits
|
|
7
|
+
*/
|
|
28
8
|
export const NUMBER_FORMAT = new Intl.NumberFormat('en-US', {
|
|
29
9
|
minimumFractionDigits: 0,
|
|
30
10
|
});
|
|
11
|
+
/**
|
|
12
|
+
* Formats a number using US locale formatting
|
|
13
|
+
* @param n - Number to format
|
|
14
|
+
* @returns Formatted number string
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* formatNumber(1234567.89); // "1,234,568"
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
31
20
|
export const formatNumber = (n) => NUMBER_FORMAT.format(n);
|
|
32
21
|
const TIME_OF_DAY_FORMAT = timeFormat('%I:%M %p');
|
|
33
22
|
const DATE_TIME_FORMAT = timeFormat('%a %Y-%m-%d %I:%M %p');
|
|
34
23
|
const DATE_FORMAT = timeFormat('%Y-%m-%d');
|
|
24
|
+
/**
|
|
25
|
+
* Formats a date into a human-readable datetime string
|
|
26
|
+
* @param d - Date to format (can be Date object, timestamp number, or bigint)
|
|
27
|
+
* @returns Formatted string in "Day YYYY-MM-DD HH:MM AM/PM" format
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* formatDateTime(new Date()); // e.g., "Wed 2024-03-13 02:30 PM"
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
35
33
|
export const formatDateTime = (d) => {
|
|
36
34
|
const date = d instanceof Date ? d : new Date(Number(d));
|
|
37
|
-
// return date.toISOString();
|
|
38
35
|
return DATE_TIME_FORMAT(date);
|
|
39
36
|
};
|
|
37
|
+
/**
|
|
38
|
+
* Formats a date into YYYY-MM-DD format
|
|
39
|
+
* @param d - Date to format (can be Date object, timestamp number, or bigint)
|
|
40
|
+
* @returns Formatted date string
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* formatDate(new Date()); // e.g., "2024-03-13"
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
40
46
|
export const formatDate = (d) => {
|
|
41
47
|
const date = d instanceof Date ? d : new Date(Number(d));
|
|
42
48
|
return DATE_FORMAT(date);
|
|
43
49
|
};
|
|
50
|
+
/**
|
|
51
|
+
* Formats a date into time of day (HH:MM AM/PM)
|
|
52
|
+
* @param d - Date to format (can be Date object, timestamp number, or bigint)
|
|
53
|
+
* @returns Formatted time string
|
|
54
|
+
* @example
|
|
55
|
+
* ```ts
|
|
56
|
+
* formatTimeOfDay(new Date()); // e.g., "02:30 PM"
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
44
59
|
export const formatTimeOfDay = (d) => {
|
|
45
60
|
const date = d instanceof Date ? d : new Date(Number(d));
|
|
46
61
|
return TIME_OF_DAY_FORMAT(date);
|
|
47
62
|
};
|
|
63
|
+
/**
|
|
64
|
+
* Formats a date relative to the current time (e.g., "2 hours ago", "in 3 days")
|
|
65
|
+
* @param d - Date to format (accepts any dayjs ConfigType)
|
|
66
|
+
* @returns Human-readable relative time string
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* formatTimeRelative(new Date(Date.now() - 3600000)); // "1 hour ago"
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
48
72
|
export const formatTimeRelative = (d) => {
|
|
49
73
|
return dayjs().to(d);
|
|
50
74
|
};
|
|
75
|
+
/**
|
|
76
|
+
* Extracts and formats an error message for display, removing common prefixes and truncating at first newline
|
|
77
|
+
* @param e - Error object or any other value that can be converted to string
|
|
78
|
+
* @returns Cleaned up error message string
|
|
79
|
+
* @example
|
|
80
|
+
* ```ts
|
|
81
|
+
* getErrorMessageForDisplay(new Error("Query failed: Error: Invalid syntax\nMore details...")); // "Invalid syntax"
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
51
84
|
export const getErrorMessageForDisplay = (e) => {
|
|
52
85
|
let msg = e instanceof Error ? e.message : String(e);
|
|
53
86
|
msg = msg.replace(/Query failed: Error: /, '');
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,OAAO,CAAC;AACtB,cAAc,OAAO,CAAC;AACtB,cAAc,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/random.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates a random string of specified length with optional seed
|
|
3
|
+
* @param length - The length of the random string to generate
|
|
4
|
+
* @param seed - Optional seed string for reproducible random generation
|
|
5
|
+
* @returns Random string containing uppercase letters, lowercase letters, and numbers
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* const random = genRandomStr(10); // e.g., "aB3kF9mN2x"
|
|
9
|
+
* const seeded = genRandomStr(10, "myseed"); // Will always generate the same string for "myseed"
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export declare function genRandomStr(length: number, seed?: string): string;
|
|
13
|
+
//# sourceMappingURL=random.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"random.d.ts","sourceRoot":"","sources":["../src/random.ts"],"names":[],"mappings":"AACA;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,UAgBzD"}
|
package/dist/random.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { alea } from 'seedrandom';
|
|
2
|
+
/**
|
|
3
|
+
* Generates a random string of specified length with optional seed
|
|
4
|
+
* @param length - The length of the random string to generate
|
|
5
|
+
* @param seed - Optional seed string for reproducible random generation
|
|
6
|
+
* @returns Random string containing uppercase letters, lowercase letters, and numbers
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const random = genRandomStr(10); // e.g., "aB3kF9mN2x"
|
|
10
|
+
* const seeded = genRandomStr(10, "myseed"); // Will always generate the same string for "myseed"
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export function genRandomStr(length, seed) {
|
|
14
|
+
const rnd = seed ? alea(seed) : Math.random;
|
|
15
|
+
return Array.from((function* () {
|
|
16
|
+
for (let i = 0; i < length; i++) {
|
|
17
|
+
const v = Math.floor(rnd() * (26 * 2 + 10));
|
|
18
|
+
if (v < 26) {
|
|
19
|
+
yield String.fromCharCode(v + 65); // 'A' - 'Z'
|
|
20
|
+
}
|
|
21
|
+
else if (v < 52) {
|
|
22
|
+
yield String.fromCharCode(v + 71); // 'a' - 'z'
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
yield String.fromCharCode(v + 48); // '0' - '9'
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
})()).join('');
|
|
29
|
+
}
|
package/dist/str.d.ts
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formats a number of bytes into a human-readable string with appropriate size units.
|
|
3
|
+
* @param bytes - The number of bytes to format
|
|
4
|
+
* @returns A string representation of the bytes with appropriate unit (Bytes, KB, MB, etc.)
|
|
5
|
+
* @example
|
|
6
|
+
* formatBytes(1024) // returns "1 KB"
|
|
7
|
+
* formatBytes(1234567) // returns "1.18 MB"
|
|
8
|
+
*/
|
|
1
9
|
export declare function formatBytes(bytes: number): string;
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export declare function convertToUniqueS3ObjectName(str: string, existingObjects?: string[]): string;
|
|
11
|
-
export declare function convertToUniqueS3FolderPath(str: string, existingObjects?: string[]): string;
|
|
10
|
+
/**
|
|
11
|
+
* Converts a camelCase string into a Title Case string.
|
|
12
|
+
* @param camelCase - The camelCase string to convert
|
|
13
|
+
* @returns A Title Case string with spaces between words
|
|
14
|
+
* @example
|
|
15
|
+
* camelCaseToTitle("myVariableName") // returns "My Variable Name"
|
|
16
|
+
* camelCaseToTitle("URL") // returns "URL"
|
|
17
|
+
*/
|
|
12
18
|
export declare function camelCaseToTitle(camelCase: string): string;
|
|
13
19
|
//# sourceMappingURL=str.d.ts.map
|
package/dist/str.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"str.d.ts","sourceRoot":"","sources":["../src/str.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAgBjD;AAED
|
|
1
|
+
{"version":3,"file":"str.d.ts","sourceRoot":"","sources":["../src/str.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAgBjD;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAgB1D"}
|
package/dist/str.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formats a number of bytes into a human-readable string with appropriate size units.
|
|
3
|
+
* @param bytes - The number of bytes to format
|
|
4
|
+
* @returns A string representation of the bytes with appropriate unit (Bytes, KB, MB, etc.)
|
|
5
|
+
* @example
|
|
6
|
+
* formatBytes(1024) // returns "1 KB"
|
|
7
|
+
* formatBytes(1234567) // returns "1.18 MB"
|
|
8
|
+
*/
|
|
1
9
|
export function formatBytes(bytes) {
|
|
2
10
|
if (bytes === 0)
|
|
3
11
|
return '0 Bytes';
|
|
@@ -12,99 +20,14 @@ export function formatBytes(bytes) {
|
|
|
12
20
|
: Math.floor(sizeValue);
|
|
13
21
|
return sizeValue + ' ' + sizes[i];
|
|
14
22
|
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
return { dir: pathParts.join('/'), name, ext };
|
|
24
|
-
}
|
|
25
|
-
export function convertToUniqueColumnOrTableName(filename, existingTables) {
|
|
26
|
-
// Remove file extension
|
|
27
|
-
const base = filename.replace(/\.[^/.]+$/, '');
|
|
28
|
-
// Replace any invalid character with underscore, and convert to lowercase
|
|
29
|
-
let tableName = base.replace(/[^a-z0-9_]/gi, '_');
|
|
30
|
-
// If the first character is a number, prepend an underscore
|
|
31
|
-
if (/^\d/.test(tableName)) {
|
|
32
|
-
tableName = '_' + tableName;
|
|
33
|
-
}
|
|
34
|
-
// Truncate to the max length 63
|
|
35
|
-
if (tableName.length > 63) {
|
|
36
|
-
tableName = tableName.substring(0, 63);
|
|
37
|
-
}
|
|
38
|
-
tableName = generateUniqueName(tableName, existingTables);
|
|
39
|
-
return tableName;
|
|
40
|
-
}
|
|
41
|
-
export function generateUniqueName(name, usedNames) {
|
|
42
|
-
const usedNamesLower = usedNames?.map((n) => n.toLowerCase());
|
|
43
|
-
// If tableName exists in the list
|
|
44
|
-
if (usedNamesLower?.includes(name.toLowerCase())) {
|
|
45
|
-
let baseName = name;
|
|
46
|
-
let i = 0;
|
|
47
|
-
// If tableName ends with `_${i}` pattern, update the baseTableName and i
|
|
48
|
-
const matched = name.match(/^(.+)_(\d+)$/);
|
|
49
|
-
if (matched) {
|
|
50
|
-
baseName = matched[1];
|
|
51
|
-
i = Number(matched[2]);
|
|
52
|
-
}
|
|
53
|
-
do {
|
|
54
|
-
i++;
|
|
55
|
-
name = `${baseName}_${i}`;
|
|
56
|
-
} while (usedNamesLower.includes(name.toLowerCase()));
|
|
57
|
-
}
|
|
58
|
-
return name;
|
|
59
|
-
}
|
|
60
|
-
export function generateUniquePath(filePath, existingPaths) {
|
|
61
|
-
let nextPath = filePath;
|
|
62
|
-
if (existingPaths?.includes(filePath)) {
|
|
63
|
-
const { dir, name, ext } = splitFilePath(filePath);
|
|
64
|
-
let i = 0;
|
|
65
|
-
let baseName = name;
|
|
66
|
-
const matched = name.match(/^(.+)_(\d+)$/);
|
|
67
|
-
if (matched) {
|
|
68
|
-
baseName = matched[1];
|
|
69
|
-
i = Number(matched[2]);
|
|
70
|
-
}
|
|
71
|
-
do {
|
|
72
|
-
i++;
|
|
73
|
-
const fname = `${baseName}_${i}${ext ? `.${ext}` : ''}`;
|
|
74
|
-
nextPath = `${dir}${dir ? '/' : ''}${fname}`;
|
|
75
|
-
} while (existingPaths.includes(nextPath));
|
|
76
|
-
}
|
|
77
|
-
return nextPath;
|
|
78
|
-
}
|
|
79
|
-
export function convertToUniqueS3ObjectName(str, existingObjects) {
|
|
80
|
-
let rv = str
|
|
81
|
-
.trim() // Remove leading and trailing white spaces
|
|
82
|
-
.replace(/[^\w\s-\.]/g, '_') // Replace special characters with underscores
|
|
83
|
-
.replace(/\s+/g, '_') // Replace consecutive spaces with a single underscore
|
|
84
|
-
// .replace(/_+/g, '_') // Remove consecutive underscores
|
|
85
|
-
// .replace(/^_/, '') // Remove leading underscores
|
|
86
|
-
// .replace(/_$/, '') // Remove trailing underscores
|
|
87
|
-
.slice(0, 255); // Truncate the string if it exceeds 255 characters
|
|
88
|
-
if (existingObjects?.length) {
|
|
89
|
-
rv = generateUniquePath(rv, existingObjects);
|
|
90
|
-
}
|
|
91
|
-
return rv;
|
|
92
|
-
}
|
|
93
|
-
export function convertToUniqueS3FolderPath(str, existingObjects) {
|
|
94
|
-
let next = convertToUniqueS3ObjectName(str, existingObjects);
|
|
95
|
-
if (!next.endsWith('/'))
|
|
96
|
-
next += '/'; // Add trailing slash if not present
|
|
97
|
-
return next;
|
|
98
|
-
// return (
|
|
99
|
-
// str
|
|
100
|
-
// .trim() // Remove leading and trailing white spaces
|
|
101
|
-
// .replace(/\/+/g, '/') // Replace consecutive slashes with a single slash
|
|
102
|
-
// .replace(/[^\w\s-\/]/g, '_') // Replace special characters with underscores
|
|
103
|
-
// .replace(/\s+/g, '_') // Replace consecutive spaces with a single underscore
|
|
104
|
-
// .replace(/^\//, '') + // Remove leading slash
|
|
105
|
-
// (str.endsWith('/') ? '' : '/')
|
|
106
|
-
// );
|
|
107
|
-
}
|
|
23
|
+
/**
|
|
24
|
+
* Converts a camelCase string into a Title Case string.
|
|
25
|
+
* @param camelCase - The camelCase string to convert
|
|
26
|
+
* @returns A Title Case string with spaces between words
|
|
27
|
+
* @example
|
|
28
|
+
* camelCaseToTitle("myVariableName") // returns "My Variable Name"
|
|
29
|
+
* camelCaseToTitle("URL") // returns "URL"
|
|
30
|
+
*/
|
|
108
31
|
export function camelCaseToTitle(camelCase) {
|
|
109
32
|
// Split the string into words on the camelCase boundaries
|
|
110
33
|
const words = camelCase.match(/^[a-z]+|[A-Z][a-z]*/g);
|
package/dist/xhr.d.ts
CHANGED
|
@@ -1,17 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Posts data to a specified URL endpoint using fetch API
|
|
3
|
+
* @param {Object} params - The parameters for the POST request
|
|
4
|
+
* @param {string} params.url - The URL to send the POST request to
|
|
5
|
+
* @param {Record<string, unknown>} [params.data] - Optional data to be sent in the request body
|
|
6
|
+
* @returns {Promise<any>} The parsed JSON response from the server
|
|
7
|
+
* @throws {Error} If the response is not ok, throws an error with the status message or error details
|
|
8
|
+
*/
|
|
1
9
|
export declare const postData: ({ url, data, }: {
|
|
2
10
|
url: string;
|
|
3
|
-
data?: Record<string,
|
|
11
|
+
data?: Record<string, unknown>;
|
|
4
12
|
}) => Promise<any>;
|
|
13
|
+
/**
|
|
14
|
+
* Represents progress information for file operations
|
|
15
|
+
*/
|
|
5
16
|
export type ProgressInfo = {
|
|
6
17
|
loaded: number;
|
|
7
18
|
total: number;
|
|
8
19
|
ratio: number;
|
|
9
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* Downloads a file from a specified URL using XMLHttpRequest
|
|
23
|
+
* @param {string} url - The URL to download the file from
|
|
24
|
+
* @param {Object} [opts] - Optional configuration for the download
|
|
25
|
+
* @param {string} [opts.method='GET'] - The HTTP method to use
|
|
26
|
+
* @param {Record<string, string>} [opts.headers] - Additional headers to include in the request
|
|
27
|
+
* @param {(info: ProgressInfo) => void} [opts.onProgress] - Callback function to track download progress
|
|
28
|
+
* @returns {Promise<Uint8Array>} The downloaded file as a Uint8Array
|
|
29
|
+
* @throws {Object} Throws an object containing status and error message if download fails
|
|
30
|
+
*/
|
|
10
31
|
export declare function downloadFile(url: string, opts?: {
|
|
11
32
|
method?: string;
|
|
12
33
|
headers?: Record<string, string>;
|
|
13
34
|
onProgress?: (info: ProgressInfo) => void;
|
|
14
35
|
}): Promise<Uint8Array>;
|
|
36
|
+
/**
|
|
37
|
+
* Uploads a file to a specified URL using XMLHttpRequest
|
|
38
|
+
* @param {string} url - The URL to upload the file to
|
|
39
|
+
* @param {File | Blob | FormData} content - The content to upload
|
|
40
|
+
* @param {Object} [opts] - Optional configuration for the upload
|
|
41
|
+
* @param {string} [opts.method='POST'] - The HTTP method to use
|
|
42
|
+
* @param {Record<string, string>} [opts.headers] - Additional headers to include in the request
|
|
43
|
+
* @param {(info: ProgressInfo) => void} [opts.onProgress] - Callback function to track upload progress
|
|
44
|
+
* @returns {Promise<Response>} The server response
|
|
45
|
+
* @throws {Object} Throws an object containing status and error message if upload fails
|
|
46
|
+
*/
|
|
15
47
|
export declare function uploadFile(url: string, content: File | Blob | FormData, opts?: {
|
|
16
48
|
method?: string;
|
|
17
49
|
headers?: Record<string, string>;
|
package/dist/xhr.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xhr.d.ts","sourceRoot":"","sources":["../src/xhr.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,mBAGlB;IACD,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"xhr.d.ts","sourceRoot":"","sources":["../src/xhr.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ,mBAGlB;IACD,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC,iBAoBA,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAC,CAAC;AAK1E;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IACJ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;CACtC,GACL,OAAO,CAAC,UAAU,CAAC,CAsCrB;AAID;;;;;;;;;;GAUG;AACH,wBAAsB,UAAU,CAC9B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,IAAI,GAAG,IAAI,GAAG,QAAQ,EAC/B,IAAI,GAAE;IACJ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;CACtC,GACL,OAAO,CAAC,QAAQ,CAAC,CAiCnB"}
|
package/dist/xhr.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Posts data to a specified URL endpoint using fetch API
|
|
3
|
+
* @param {Object} params - The parameters for the POST request
|
|
4
|
+
* @param {string} params.url - The URL to send the POST request to
|
|
5
|
+
* @param {Record<string, unknown>} [params.data] - Optional data to be sent in the request body
|
|
6
|
+
* @returns {Promise<any>} The parsed JSON response from the server
|
|
7
|
+
* @throws {Error} If the response is not ok, throws an error with the status message or error details
|
|
8
|
+
*/
|
|
1
9
|
export const postData = async ({ url, data, }) => {
|
|
2
10
|
const res = await fetch(url, {
|
|
3
11
|
method: 'POST',
|
|
@@ -21,6 +29,16 @@ export const postData = async ({ url, data, }) => {
|
|
|
21
29
|
};
|
|
22
30
|
// TODO: use range requests to download in chunks
|
|
23
31
|
// https://github.com/duckdb/duckdb-wasm/blob/d9ea9c919b6301e7c6dc8a9b3fd527e86f69a38e/packages/duckdb-wasm/src/bindings/runtime_browser.ts#L307
|
|
32
|
+
/**
|
|
33
|
+
* Downloads a file from a specified URL using XMLHttpRequest
|
|
34
|
+
* @param {string} url - The URL to download the file from
|
|
35
|
+
* @param {Object} [opts] - Optional configuration for the download
|
|
36
|
+
* @param {string} [opts.method='GET'] - The HTTP method to use
|
|
37
|
+
* @param {Record<string, string>} [opts.headers] - Additional headers to include in the request
|
|
38
|
+
* @param {(info: ProgressInfo) => void} [opts.onProgress] - Callback function to track download progress
|
|
39
|
+
* @returns {Promise<Uint8Array>} The downloaded file as a Uint8Array
|
|
40
|
+
* @throws {Object} Throws an object containing status and error message if download fails
|
|
41
|
+
*/
|
|
24
42
|
export async function downloadFile(url, opts = {}) {
|
|
25
43
|
const { method = 'GET', headers = {}, onProgress } = opts;
|
|
26
44
|
return await new Promise((resolve, reject) => {
|
|
@@ -57,6 +75,17 @@ export async function downloadFile(url, opts = {}) {
|
|
|
57
75
|
});
|
|
58
76
|
}
|
|
59
77
|
// TODO: upload in chunks https://www.html5rocks.com/en/tutorials/file/xhr2/
|
|
78
|
+
/**
|
|
79
|
+
* Uploads a file to a specified URL using XMLHttpRequest
|
|
80
|
+
* @param {string} url - The URL to upload the file to
|
|
81
|
+
* @param {File | Blob | FormData} content - The content to upload
|
|
82
|
+
* @param {Object} [opts] - Optional configuration for the upload
|
|
83
|
+
* @param {string} [opts.method='POST'] - The HTTP method to use
|
|
84
|
+
* @param {Record<string, string>} [opts.headers] - Additional headers to include in the request
|
|
85
|
+
* @param {(info: ProgressInfo) => void} [opts.onProgress] - Callback function to track upload progress
|
|
86
|
+
* @returns {Promise<Response>} The server response
|
|
87
|
+
* @throws {Object} Throws an object containing status and error message if upload fails
|
|
88
|
+
*/
|
|
60
89
|
export async function uploadFile(url, content, opts = {}) {
|
|
61
90
|
const { method = 'POST', headers = {}, onProgress } = opts;
|
|
62
91
|
return await new Promise((resolve, reject) => {
|
package/package.json
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sqlrooms/utils",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
|
-
"types": "
|
|
5
|
+
"types": "dist/index.d.ts",
|
|
6
6
|
"module": "dist/index.js",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"private": false,
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
9
12
|
"publishConfig": {
|
|
10
13
|
"access": "public"
|
|
11
14
|
},
|
|
@@ -14,23 +17,21 @@
|
|
|
14
17
|
"build": "tsc",
|
|
15
18
|
"_test": "jest",
|
|
16
19
|
"_test:watch": "jest --watch",
|
|
17
|
-
"lint": "eslint ."
|
|
20
|
+
"lint": "eslint .",
|
|
21
|
+
"typedoc": "typedoc"
|
|
18
22
|
},
|
|
19
23
|
"dependencies": {
|
|
20
24
|
"d3-color": "^3.1.0",
|
|
21
25
|
"d3-format": "^3.1.0",
|
|
22
26
|
"d3-time-format": "^4.1.0",
|
|
27
|
+
"dayjs": "^1.11.13",
|
|
23
28
|
"seedrandom": "^3.0.5"
|
|
24
29
|
},
|
|
25
|
-
"peerDependencies": {
|
|
26
|
-
"dayjs": "*",
|
|
27
|
-
"zod": "*"
|
|
28
|
-
},
|
|
29
30
|
"devDependencies": {
|
|
30
31
|
"@types/d3-color": "^3.1.3",
|
|
31
32
|
"@types/d3-format": "^3.0.4",
|
|
32
33
|
"@types/d3-time-format": "^4.0.3",
|
|
33
34
|
"@types/seedrandom": "^3.0.8"
|
|
34
35
|
},
|
|
35
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "32da0b35fe906bdcef42274624d069cc49425a74"
|
|
36
37
|
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# Change Log
|
|
2
|
-
|
|
3
|
-
All notable changes to this project will be documented in this file.
|
|
4
|
-
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
|
-
|
|
6
|
-
## 0.0.1-alpha.0 (2025-01-30)
|
|
7
|
-
|
|
8
|
-
**Note:** Version bump only for package @sqlrooms/utils
|
|
9
|
-
|
|
10
|
-
**Note:** Version bump only for package @sqlrooms/utils
|
package/jest.config.ms
DELETED