@hkdigital/lib-sveltekit 0.1.46 → 0.1.47

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.
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Convert a path string to an array path
3
+ * - The path string will be spit at the `pathSeparator` token
4
+ * - If the supplied path is already an array, the original array will
5
+ * be returned
6
+ *
7
+ * @param {string|string[]} path
8
+ * String or array path (e.g. "some.path.to")
9
+ *
10
+ * @param {string} [pathSeparator=PATH_SEPARATOR]
11
+ * A custom path separator to use instead of the default "."
12
+ *
13
+ * @returns {string} string path (e.g. "some.path.to")
14
+ */
15
+ export function toStringPath(path: string | string[], pathSeparator?: string): string;
@@ -0,0 +1,75 @@
1
+ import { PATH_SEPARATOR } from '../object/index.js';
2
+
3
+ /**
4
+ * Convert a path string to an array path
5
+ * - The path string will be spit at the `pathSeparator` token
6
+ * - If the supplied path is already an array, the original array will
7
+ * be returned
8
+ *
9
+ * @param {string|string[]} path
10
+ * String or array path (e.g. "some.path.to")
11
+ *
12
+ * @param {string} [pathSeparator=PATH_SEPARATOR]
13
+ * A custom path separator to use instead of the default "."
14
+ *
15
+ * @returns {string} string path (e.g. "some.path.to")
16
+ */
17
+ export function toStringPath(path, pathSeparator = PATH_SEPARATOR) {
18
+ if (Array.isArray(path)) {
19
+ return path.join(pathSeparator);
20
+ } else if (typeof path === 'string') {
21
+ // path is already a string
22
+ return path;
23
+ } else {
24
+ throw new Error(
25
+ 'Missing or invalid parameter [path] (expected string or array)'
26
+ );
27
+ }
28
+ }
29
+
30
+ // -----------------------------------------------------------------------------
31
+
32
+ /**
33
+ * Make sure that the outputted path is an array path
34
+ * - The input value may be a array path
35
+ * - The input value may be a string path (no conversion needed)
36
+ *
37
+ * @param {string|string[]} path
38
+ *
39
+ * @returns {string[]} array path (list of strings)
40
+ */
41
+ // export function fromPath( path )
42
+ // {
43
+ // if( typeof path === "string" )
44
+ // {
45
+ // return path;
46
+ // }
47
+ // else {
48
+ // expect.array( path,
49
+ // "Missing or invalid parameter [path] (expected string or string[])" );
50
+
51
+ // let strPath = proc.arrayToStringPathWeakMap.get( path );
52
+
53
+ // if( strPath )
54
+ // {
55
+ // // std.debug( "Using cached value", path );
56
+ // return strPath;
57
+ // }
58
+
59
+ // // Check array path
60
+ // for( let j = 0, n = path.length; j < n; j = j + 1 )
61
+ // {
62
+ // if( typeof path[j] !== "string" )
63
+ // {
64
+ // throw new Error("Invalid array path. Expected array of strings");
65
+ // }
66
+ // }
67
+
68
+ // strPath = path.join("/");
69
+
70
+ // proc.safeArrayPathsWeakMap.set( path, true );
71
+ // proc.arrayToStringPathWeakMap.set( path, strPath );
72
+
73
+ // return strPath;
74
+ // }
75
+ // }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Remove strange characters from a string and replace whitespace by
3
+ * dashes.
4
+ *
5
+ * @returns {string} string that can be used as uri
6
+ */
7
+ export function toUriName(str: any): string;
8
+ /**
9
+ * Captizalize the first character of a string
10
+ *
11
+ * @param {string} str - Input string
12
+ *
13
+ * @returns {string} string with first letter capitalized
14
+ */
15
+ export function capitalizeFirst(str: string): string;
16
+ /**
17
+ * Converts a kebab-case string to Title Case.
18
+ *
19
+ * @param {string} kebabString - The kebab-case string to convert
20
+ * @return {string} The converted Title Case string
21
+ */
22
+ export function kebabToTitleCase(kebabString: string): string;
@@ -0,0 +1,54 @@
1
+ import * as expect from '../expect/index.js';
2
+
3
+ /**
4
+ * Remove strange characters from a string and replace whitespace by
5
+ * dashes.
6
+ *
7
+ * @returns {string} string that can be used as uri
8
+ */
9
+ export function toUriName(str) {
10
+ expect.string(str);
11
+
12
+ str = str.toLowerCase().replace(/[^a-z0-9]+/gi, '-');
13
+
14
+ // TODO: remove duplicate dashes
15
+
16
+ return str;
17
+ }
18
+
19
+ /**
20
+ * Captizalize the first character of a string
21
+ *
22
+ * @param {string} str - Input string
23
+ *
24
+ * @returns {string} string with first letter capitalized
25
+ */
26
+ export function capitalizeFirst(str) {
27
+ if (!str.length) {
28
+ return str;
29
+ }
30
+
31
+ return str.charAt(0).toUpperCase() + str.slice(1);
32
+ }
33
+
34
+ /**
35
+ * Converts a kebab-case string to Title Case.
36
+ *
37
+ * @param {string} kebabString - The kebab-case string to convert
38
+ * @return {string} The converted Title Case string
39
+ */
40
+ export function kebabToTitleCase(kebabString) {
41
+ // Check if input is a string
42
+ if (typeof kebabString !== 'string') {
43
+ throw new Error('Input must be a string');
44
+ }
45
+
46
+ // Split the string by hyphens
47
+ return kebabString
48
+ .split('-')
49
+ .map((word) => {
50
+ // Capitalize the first letter of each word
51
+ return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
52
+ })
53
+ .join(' ');
54
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Path utilities for working with file and directory paths.
3
+ * Provides functions similar to Node.js path module but for browser and SvelteKit use.
4
+ */
5
+ /**
6
+ * Extracts the filename from a path, with or without extension.
7
+ *
8
+ * @param {string} path - The path to extract the filename from
9
+ * @param {boolean} [includeExtension=true] - Whether to include the extension
10
+ * @return {string} The extracted filename
11
+ */
12
+ export function basename(path: string, includeExtension?: boolean): string;
13
+ /**
14
+ * Extracts the extension from a filename.
15
+ *
16
+ * @param {string} path - The path to extract the extension from
17
+ * @param {boolean} [includeDot=false] - Whether to include the dot in the extension
18
+ * @return {string} The extracted extension
19
+ */
20
+ export function extname(path: string, includeDot?: boolean): string;
21
+ /**
22
+ * Extracts the directory name from a path.
23
+ *
24
+ * @param {string} path - The path to extract the directory name from
25
+ * @return {string} The extracted directory name
26
+ */
27
+ export function dirname(path: string): string;
28
+ /**
29
+ * Joins path segments with the appropriate separator.
30
+ *
31
+ * @param {...string} paths - The path segments to join
32
+ * @return {string} The joined path
33
+ */
34
+ export function join(...paths: string[]): string;
35
+ /**
36
+ * Normalizes a path by resolving '..' and '.' segments.
37
+ *
38
+ * @param {string} path - The path to normalize
39
+ * @return {string} The normalized path
40
+ */
41
+ export function normalize(path: string): string;
42
+ /**
43
+ * Checks if a path is absolute.
44
+ *
45
+ * @param {string} path - The path to check
46
+ * @return {boolean} Whether the path is absolute
47
+ */
48
+ export function isAbsolute(path: string): boolean;
49
+ /**
50
+ * Returns the path segments as an array.
51
+ *
52
+ * @param {string} path - The path to split
53
+ * @return {string[]} The path segments
54
+ */
55
+ export function segments(path: string): string[];
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Path utilities for working with file and directory paths.
3
+ * Provides functions similar to Node.js path module but for browser and SvelteKit use.
4
+ */
5
+
6
+ /**
7
+ * Extracts the filename from a path, with or without extension.
8
+ *
9
+ * @param {string} path - The path to extract the filename from
10
+ * @param {boolean} [includeExtension=true] - Whether to include the extension
11
+ * @return {string} The extracted filename
12
+ */
13
+ export function basename(path, includeExtension = true) {
14
+ if (typeof path !== 'string') {
15
+ throw new Error('Path must be a string');
16
+ }
17
+
18
+ // Handle empty string
19
+ if (path === '') {
20
+ return '';
21
+ }
22
+
23
+ // Remove trailing slashes
24
+ path = path.replace(/\/+$/, '');
25
+
26
+ // Find the last occurrence of '/'
27
+ const lastSlashIndex = path.lastIndexOf('/');
28
+
29
+ // Get the full filename
30
+ const filename =
31
+ lastSlashIndex === -1 ? path : path.substring(lastSlashIndex + 1);
32
+
33
+ // Return the full filename if extension should be included
34
+ if (includeExtension) {
35
+ return filename;
36
+ }
37
+
38
+ // Otherwise, remove the extension
39
+ const lastDotIndex = filename.lastIndexOf('.');
40
+
41
+ // If no dot is found or dot is the first character (hidden file), return the filename
42
+ if (lastDotIndex <= 0) {
43
+ return filename;
44
+ }
45
+
46
+ // Return everything before the last dot
47
+ return filename.substring(0, lastDotIndex);
48
+ }
49
+
50
+ /**
51
+ * Extracts the extension from a filename.
52
+ *
53
+ * @param {string} path - The path to extract the extension from
54
+ * @param {boolean} [includeDot=false] - Whether to include the dot in the extension
55
+ * @return {string} The extracted extension
56
+ */
57
+ export function extname(path, includeDot = false) {
58
+ if (typeof path !== 'string') {
59
+ throw new Error('Path must be a string');
60
+ }
61
+
62
+ const filename = basename(path);
63
+ const lastDotIndex = filename.lastIndexOf('.');
64
+
65
+ // If no dot is found or dot is the first character (hidden file), return empty string
66
+ if (lastDotIndex <= 0) {
67
+ return '';
68
+ }
69
+
70
+ // Return the extension with or without the dot
71
+ return includeDot
72
+ ? filename.substring(lastDotIndex)
73
+ : filename.substring(lastDotIndex + 1);
74
+ }
75
+
76
+ /**
77
+ * Extracts the directory name from a path.
78
+ *
79
+ * @param {string} path - The path to extract the directory name from
80
+ * @return {string} The extracted directory name
81
+ */
82
+ export function dirname(path) {
83
+ if (typeof path !== 'string') {
84
+ throw new Error('Path must be a string');
85
+ }
86
+
87
+ // Handle empty string
88
+ if (path === '') {
89
+ return '.';
90
+ }
91
+
92
+ // Remove trailing slashes
93
+ path = path.replace(/\/+$/, '');
94
+
95
+ // Find the last occurrence of '/'
96
+ const lastSlashIndex = path.lastIndexOf('/');
97
+
98
+ // If no slash is found, return '.'
99
+ if (lastSlashIndex === -1) {
100
+ return '.';
101
+ }
102
+
103
+ // If slash is at the beginning, return '/'
104
+ if (lastSlashIndex === 0) {
105
+ return '/';
106
+ }
107
+
108
+ // Return everything before the last slash
109
+ return path.substring(0, lastSlashIndex);
110
+ }
111
+
112
+ /**
113
+ * Joins path segments with the appropriate separator.
114
+ *
115
+ * @param {...string} paths - The path segments to join
116
+ * @return {string} The joined path
117
+ */
118
+ export function join(...paths) {
119
+ if (paths.length === 0) {
120
+ return '.';
121
+ }
122
+
123
+ return paths
124
+ .filter((segment) => typeof segment === 'string' && segment !== '')
125
+ .join('/')
126
+ .replace(/\/+/g, '/'); // Replace multiple consecutive slashes with a single one
127
+ }
128
+
129
+ /**
130
+ * Normalizes a path by resolving '..' and '.' segments.
131
+ *
132
+ * @param {string} path - The path to normalize
133
+ * @return {string} The normalized path
134
+ */
135
+ export function normalize(path) {
136
+ if (typeof path !== 'string') {
137
+ throw new Error('Path must be a string');
138
+ }
139
+
140
+ // Replace backslashes with forward slashes
141
+ path = path.replace(/\\/g, '/');
142
+
143
+ // Handle empty string
144
+ if (path === '') {
145
+ return '.';
146
+ }
147
+
148
+ const isAbsolute = path.startsWith('/');
149
+ const trailingSlash = path.endsWith('/');
150
+
151
+ // Split path into segments
152
+ const segments = path.split('/').filter(Boolean);
153
+ const resultSegments = [];
154
+
155
+ for (const segment of segments) {
156
+ if (segment === '.') {
157
+ // Ignore current directory marker
158
+ continue;
159
+ } else if (segment === '..') {
160
+ // Go up one directory
161
+ if (
162
+ resultSegments.length > 0 &&
163
+ resultSegments[resultSegments.length - 1] !== '..'
164
+ ) {
165
+ resultSegments.pop();
166
+ } else if (!isAbsolute) {
167
+ resultSegments.push('..');
168
+ }
169
+ } else {
170
+ // Add segment to result
171
+ resultSegments.push(segment);
172
+ }
173
+ }
174
+
175
+ // Handle empty result
176
+ if (resultSegments.length === 0) {
177
+ return isAbsolute ? '/' : '.';
178
+ }
179
+
180
+ // Join segments
181
+ let result = resultSegments.join('/');
182
+
183
+ // Add leading slash for absolute paths
184
+ if (isAbsolute) {
185
+ result = '/' + result;
186
+ }
187
+
188
+ // Add trailing slash if original path had one
189
+ if (trailingSlash && !result.endsWith('/')) {
190
+ result += '/';
191
+ }
192
+
193
+ return result;
194
+ }
195
+
196
+ /**
197
+ * Checks if a path is absolute.
198
+ *
199
+ * @param {string} path - The path to check
200
+ * @return {boolean} Whether the path is absolute
201
+ */
202
+ export function isAbsolute(path) {
203
+ if (typeof path !== 'string') {
204
+ throw new Error('Path must be a string');
205
+ }
206
+
207
+ return path.startsWith('/');
208
+ }
209
+
210
+ /**
211
+ * Returns the path segments as an array.
212
+ *
213
+ * @param {string} path - The path to split
214
+ * @return {string[]} The path segments
215
+ */
216
+ export function segments(path) {
217
+ if (typeof path !== 'string') {
218
+ throw new Error('Path must be a string');
219
+ }
220
+
221
+ // Normalize path first
222
+ const normalizedPath = normalize(path);
223
+
224
+ // Split path into segments
225
+ return normalizedPath.split('/').filter(Boolean);
226
+ }
@@ -1,60 +1,5 @@
1
- /**
2
- * Captizalize the first character of a string
3
- *
4
- * @param {string} str - Input string
5
- *
6
- * @returns {string} string with first letter capitalized
7
- */
8
- export function capitalizeFirst(str: string): string;
9
- /**
10
- * Interpolate: substitute variables in a string
11
- *
12
- * - Uses mustache template style expression substitution:
13
- * Variables and expressions are surrounded by {{...}}
14
- *
15
- * TODO: full mustache support, see https://github.com/janl/mustache.js
16
- *
17
- * --
18
- *
19
- * @eg const template = `Hello {{name}}`;
20
- *
21
- * --
22
- *
23
- * @param {string} template - Template string to interpolate
24
- * @param {object} templateData - Template data to use for interpolation
25
- *
26
- * @returns {string} interpolated string
27
- */
28
- export function interpolate(template: string, templateData: object, expressionRegexp?: RegExp): string;
29
- /**
30
- * Remove strange characters from a string and replace whitespace by
31
- * dashes.
32
- *
33
- * @returns {string} string that can be used as uri
34
- */
35
- export function toUriName(str: any): string;
36
- /**
37
- * Convert a path string to an array path
38
- * - The path string will be spit at the `pathSeparator` token
39
- * - If the supplied path is already an array, the original array will
40
- * be returned
41
- *
42
- * @param {string|string[]} path
43
- * String or array path (e.g. "some.path.to")
44
- *
45
- * @param {string} [pathSeparator=PATH_SEPARATOR]
46
- * A custom path separator to use instead of the default "."
47
- *
48
- * @returns {string[]} array path (e.g. ["some", "path", "to"])
49
- */
50
- export function toStringPath(path: string | string[], pathSeparator?: string): string[];
51
- /**
52
- * Prefix a numeric string with 0's
53
- *
54
- * @param {string|number} input
55
- *
56
- * @returns {string}
57
- */
58
- export function padDigits(input: string | number, targetLength?: number, padString?: string): string;
59
- export const RE_JS_EXPRESSION: RegExp;
60
- export const RE_MUSTACHE: RegExp;
1
+ export * from "./array-path.js";
2
+ export * from "./convert.js";
3
+ export * from "./fs.js";
4
+ export * from "./interpolate.js";
5
+ export * from "./pad.js";
@@ -1,184 +1,5 @@
1
- /* ------------------------------------------------------------------ Imports */
2
-
3
- import * as expect from '../expect/index.js';
4
-
5
- import { objectGet, PATH_SEPARATOR } from '../object/index.js';
6
-
7
- import { toArrayPath } from '../array/index.js';
8
-
9
- /* ------------------------------------------------------------------ Exports */
10
-
11
- export const RE_JS_EXPRESSION = /\$\{([^${}]*)\}/g;
12
- export const RE_MUSTACHE = /\{\{([^{}]*)\}\}/g;
13
-
14
- // -----------------------------------------------------------------------------
15
-
16
- /**
17
- * Captizalize the first character of a string
18
- *
19
- * @param {string} str - Input string
20
- *
21
- * @returns {string} string with first letter capitalized
22
- */
23
- export function capitalizeFirst(str) {
24
- if (!str.length) {
25
- return str;
26
- }
27
-
28
- return str.charAt(0).toUpperCase() + str.slice(1);
29
- }
30
-
31
- // -----------------------------------------------------------------------------
32
-
33
- /**
34
- * Interpolate: substitute variables in a string
35
- *
36
- * - Uses mustache template style expression substitution:
37
- * Variables and expressions are surrounded by {{...}}
38
- *
39
- * TODO: full mustache support, see https://github.com/janl/mustache.js
40
- *
41
- * --
42
- *
43
- * @eg const template = `Hello {{name}}`;
44
- *
45
- * --
46
- *
47
- * @param {string} template - Template string to interpolate
48
- * @param {object} templateData - Template data to use for interpolation
49
- *
50
- * @returns {string} interpolated string
51
- */
52
- export function interpolate(template, templateData, expressionRegexp = RE_MUSTACHE) {
53
- expect.string(template, 'Missing or invalid variable [template]');
54
-
55
- expect.object(templateData, 'Missing or invalid variable [templateData]');
56
-
57
- return template.replace(
58
- expressionRegexp,
59
-
60
- (match, expression) => {
61
- const path = toArrayPath(expression);
62
-
63
- const replacement = objectGet(templateData, path, undefined);
64
-
65
- if (
66
- typeof replacement !== 'string' &&
67
- typeof replacement !== 'number' &&
68
- typeof replacement !== 'boolean'
69
- ) {
70
- throw new Error(
71
- 'Failed to interpolate template: Missing or invalid value for ' +
72
- `expression [${expression}] (expected string, number or boolean)`
73
- );
74
- }
75
-
76
- return replacement;
77
- }
78
- );
79
- }
80
-
81
- // -----------------------------------------------------------------------------
82
-
83
- /**
84
- * Remove strange characters from a string and replace whitespace by
85
- * dashes.
86
- *
87
- * @returns {string} string that can be used as uri
88
- */
89
- export function toUriName(str) {
90
- expect.string(str, 'Missing or invalid variable [str]');
91
-
92
- str = str.toLowerCase().replace(/[^a-z0-9]+/gi, '-');
93
-
94
- // TODO: remove duplicate dashes
95
-
96
- return str;
97
- }
98
-
99
- // -----------------------------------------------------------------------------
100
-
101
- /**
102
- * Convert a path string to an array path
103
- * - The path string will be spit at the `pathSeparator` token
104
- * - If the supplied path is already an array, the original array will
105
- * be returned
106
- *
107
- * @param {string|string[]} path
108
- * String or array path (e.g. "some.path.to")
109
- *
110
- * @param {string} [pathSeparator=PATH_SEPARATOR]
111
- * A custom path separator to use instead of the default "."
112
- *
113
- * @returns {string[]} array path (e.g. ["some", "path", "to"])
114
- */
115
- export function toStringPath(path, pathSeparator = PATH_SEPARATOR) {
116
- if (Array.isArray(path)) {
117
- return path.join(pathSeparator);
118
- } else if (typeof path === 'string') {
119
- // path is already a string
120
- return path;
121
- } else {
122
- throw new Error('Missing or invalid parameter [path] (expected string or array)');
123
- }
124
- }
125
-
126
- // -----------------------------------------------------------------------------
127
-
128
- /**
129
- * Prefix a numeric string with 0's
130
- *
131
- * @param {string|number} input
132
- *
133
- * @returns {string}
134
- */
135
- export function padDigits(input, targetLength = 2, padString = '0') {
136
- return ('' + input).padStart(targetLength, padString);
137
- }
138
-
139
- // -----------------------------------------------------------------------------
140
-
141
- /**
142
- * Make sure that the outputted path is an array path
143
- * - The input value may be a array path
144
- * - The input value may be a string path (no conversion needed)
145
- *
146
- * @param {string|string[]} path
147
- *
148
- * @returns {string[]} array path (list of strings)
149
- */
150
- // export function fromPath( path )
151
- // {
152
- // if( typeof path === "string" )
153
- // {
154
- // return path;
155
- // }
156
- // else {
157
- // expect.array( path,
158
- // "Missing or invalid parameter [path] (expected string or string[])" );
159
-
160
- // let strPath = proc.arrayToStringPathWeakMap.get( path );
161
-
162
- // if( strPath )
163
- // {
164
- // // std.debug( "Using cached value", path );
165
- // return strPath;
166
- // }
167
-
168
- // // Check array path
169
- // for( let j = 0, n = path.length; j < n; j = j + 1 )
170
- // {
171
- // if( typeof path[j] !== "string" )
172
- // {
173
- // throw new Error("Invalid array path. Expected array of strings");
174
- // }
175
- // }
176
-
177
- // strPath = path.join("/");
178
-
179
- // proc.safeArrayPathsWeakMap.set( path, true );
180
- // proc.arrayToStringPathWeakMap.set( path, strPath );
181
-
182
- // return strPath;
183
- // }
184
- // }
1
+ export * from './array-path.js';
2
+ export * from './convert.js';
3
+ export * from './fs.js';
4
+ export * from './interpolate.js';
5
+ export * from './pad.js';
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Interpolate: substitute variables in a string
3
+ *
4
+ * - Uses mustache template style expression substitution:
5
+ * Variables and expressions are surrounded by {{...}}
6
+ *
7
+ * TODO: full mustache support, see https://github.com/janl/mustache.js
8
+ *
9
+ * --
10
+ *
11
+ * @eg const template = `Hello {{name}}`;
12
+ *
13
+ * --
14
+ *
15
+ * @param {string} template - Template string to interpolate
16
+ * @param {object} templateData - Template data to use for interpolation
17
+ *
18
+ * @returns {string} interpolated string
19
+ */
20
+ export function interpolate(template: string, templateData: object, expressionRegexp?: RegExp): string;
21
+ export const RE_JS_EXPRESSION: RegExp;
22
+ export const RE_MUSTACHE: RegExp;
@@ -0,0 +1,61 @@
1
+ import * as expect from '../expect/index.js';
2
+
3
+ import { toArrayPath } from '../array/index.js';
4
+
5
+ import { objectGet, PATH_SEPARATOR } from '../object/index.js';
6
+
7
+ export const RE_JS_EXPRESSION = /\$\{([^${}]*)\}/g;
8
+ export const RE_MUSTACHE = /\{\{([^{}]*)\}\}/g;
9
+
10
+ /**
11
+ * Interpolate: substitute variables in a string
12
+ *
13
+ * - Uses mustache template style expression substitution:
14
+ * Variables and expressions are surrounded by {{...}}
15
+ *
16
+ * TODO: full mustache support, see https://github.com/janl/mustache.js
17
+ *
18
+ * --
19
+ *
20
+ * @eg const template = `Hello {{name}}`;
21
+ *
22
+ * --
23
+ *
24
+ * @param {string} template - Template string to interpolate
25
+ * @param {object} templateData - Template data to use for interpolation
26
+ *
27
+ * @returns {string} interpolated string
28
+ */
29
+ export function interpolate(
30
+ template,
31
+ templateData,
32
+ expressionRegexp = RE_MUSTACHE
33
+ ) {
34
+ expect.string(template);
35
+
36
+ expect.object(templateData);
37
+
38
+ return template.replace(
39
+ expressionRegexp,
40
+
41
+ (match, expression) => {
42
+ const path = toArrayPath(expression);
43
+
44
+ /** @type {string} */
45
+ const replacement = objectGet(templateData, path, undefined);
46
+
47
+ if (
48
+ typeof replacement !== 'string' &&
49
+ typeof replacement !== 'number' &&
50
+ typeof replacement !== 'boolean'
51
+ ) {
52
+ throw new Error(
53
+ 'Failed to interpolate template: Missing or invalid value for ' +
54
+ `expression [${expression}] (expected string, number or boolean)`
55
+ );
56
+ }
57
+
58
+ return replacement;
59
+ }
60
+ );
61
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Prefix a numeric string with 0's
3
+ *
4
+ * @param {string|number} input
5
+ *
6
+ * @returns {string}
7
+ */
8
+ export function padDigits(input: string | number, targetLength?: number, padString?: string): string;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Prefix a numeric string with 0's
3
+ *
4
+ * @param {string|number} input
5
+ *
6
+ * @returns {string}
7
+ */
8
+ export function padDigits(input, targetLength = 2, padString = '0') {
9
+ return ('' + input).padStart(targetLength, padString);
10
+ }
@@ -9,15 +9,20 @@ export function isValidRoutePath(path: string): boolean;
9
9
  * @param {Object} options - Scan options
10
10
  * @param {string} options.dirPath - Directory path to scan
11
11
  * @param {number} [options.maxDepth=1] - Maximum depth to scan
12
- * @param {Set<string>} [options.skipFolders=new Set(['assets'])] - Folders to skip
13
- * @returns {Promise<Array<{displayName: string, path: string}>>}
12
+ * @param {Set<string>} [options.skipFolders] - Folders to skip
13
+ *
14
+ * @param {number} [depth=0] - Do not set manually!
15
+ *
16
+ * @returns {Promise<Array<{displayName: string, path: string, depth: number}>>}
17
+ *
14
18
  * @throws {Error} If path is outside project routes directory
15
19
  */
16
20
  export function scanRouteFolders({ dirPath, maxDepth, skipFolders }: {
17
21
  dirPath: string;
18
22
  maxDepth?: number;
19
23
  skipFolders?: Set<string>;
20
- }): Promise<Array<{
24
+ }, depth?: number): Promise<Array<{
21
25
  displayName: string;
22
26
  path: string;
27
+ depth: number;
23
28
  }>>;
@@ -1,6 +1,8 @@
1
1
  import { readdir } from 'node:fs/promises';
2
2
  import { join, resolve } from 'node:path';
3
3
 
4
+ import { kebabToTitleCase, basename } from '../../string/index.js';
5
+
4
6
  /**
5
7
  * Validates if a path is within the project's src/routes directory
6
8
  * @param {string} path - Path to validate
@@ -17,20 +19,28 @@ export function isValidRoutePath(path) {
17
19
  * @param {Object} options - Scan options
18
20
  * @param {string} options.dirPath - Directory path to scan
19
21
  * @param {number} [options.maxDepth=1] - Maximum depth to scan
20
- * @param {Set<string>} [options.skipFolders=new Set(['assets'])] - Folders to skip
21
- * @returns {Promise<Array<{displayName: string, path: string}>>}
22
+ * @param {Set<string>} [options.skipFolders] - Folders to skip
23
+ *
24
+ * @param {number} [depth=0] - Do not set manually!
25
+ *
26
+ * @returns {Promise<Array<{displayName: string, path: string, depth: number}>>}
27
+ *
22
28
  * @throws {Error} If path is outside project routes directory
23
29
  */
24
- export async function scanRouteFolders({
25
- dirPath,
26
- maxDepth = 1,
27
- skipFolders = new Set(['assets'])
28
- }) {
30
+ export async function scanRouteFolders(
31
+ { dirPath, maxDepth = 1, skipFolders },
32
+ depth = 0
33
+ ) {
34
+ // console.debug({
35
+ // maxDepth,
36
+ // depth
37
+ // });
38
+
29
39
  if (!isValidRoutePath(dirPath)) {
30
40
  throw new Error('Invalid path: Must be within src/routes directory');
31
41
  }
32
42
 
33
- if (maxDepth < 1) return [];
43
+ if (depth > maxDepth) return [];
34
44
 
35
45
  try {
36
46
  const entries = await readdir(dirPath, { withFileTypes: true });
@@ -39,7 +49,7 @@ export async function scanRouteFolders({
39
49
  for (const entry of entries) {
40
50
  if (
41
51
  !entry.isDirectory() ||
42
- skipFolders.has(entry.name) ||
52
+ skipFolders?.has(entry.name) ||
43
53
  entry.name.startsWith('.')
44
54
  ) {
45
55
  continue;
@@ -54,21 +64,30 @@ export async function scanRouteFolders({
54
64
  if (hasPageFile) {
55
65
  results.push({
56
66
  displayName: entry.name,
57
- path: currentPath
67
+ path: currentPath,
68
+ depth
58
69
  });
59
70
  }
60
71
 
61
72
  if (maxDepth > 1) {
62
- const subFolders = await scanRouteFolders({
63
- dirPath: fullPath,
64
- maxDepth: maxDepth - 1,
65
- skipFolders
66
- });
73
+ const subFolders = await scanRouteFolders(
74
+ {
75
+ dirPath: fullPath,
76
+ maxDepth,
77
+ skipFolders
78
+ },
79
+ depth + 1
80
+ );
67
81
 
68
82
  for (const subFolder of subFolders) {
83
+ const path = `${currentPath}/${subFolder.path}`;
84
+
85
+ const displayName = kebabToTitleCase(basename(subFolder.path));
86
+
69
87
  results.push({
70
- displayName: `${entry.name}/${subFolder.displayName}`,
71
- path: `${currentPath}/${subFolder.path}`
88
+ displayName,
89
+ path,
90
+ depth: subFolder.depth
72
91
  });
73
92
  }
74
93
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hkdigital/lib-sveltekit",
3
- "version": "0.1.46",
3
+ "version": "0.1.47",
4
4
  "author": {
5
5
  "name": "HKdigital",
6
6
  "url": "https://hkdigital.nl"