@type32/nuxt-cs-utils 1.1.0
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/README.md +84 -0
- package/dist/module.d.mts +8 -0
- package/dist/module.json +9 -0
- package/dist/module.mjs +16 -0
- package/dist/runtime/shared/utils/dates.d.ts +5 -0
- package/dist/runtime/shared/utils/dates.js +22 -0
- package/dist/runtime/shared/utils/parsing/paths.d.ts +22 -0
- package/dist/runtime/shared/utils/parsing/paths.js +30 -0
- package/dist/runtime/shared/utils/parsing/query.d.ts +26 -0
- package/dist/runtime/shared/utils/parsing/query.js +64 -0
- package/dist/types.d.mts +3 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Get your module up and running quickly.
|
|
3
|
+
|
|
4
|
+
Find and replace all on all files (CMD+SHIFT+F):
|
|
5
|
+
- Name: My Module
|
|
6
|
+
- Package name: my-module
|
|
7
|
+
- Description: My new Nuxt module
|
|
8
|
+
-->
|
|
9
|
+
|
|
10
|
+
# My Module
|
|
11
|
+
|
|
12
|
+
[![npm version][npm-version-src]][npm-version-href]
|
|
13
|
+
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
14
|
+
[![License][license-src]][license-href]
|
|
15
|
+
[![Nuxt][nuxt-src]][nuxt-href]
|
|
16
|
+
|
|
17
|
+
My new Nuxt module for doing amazing things.
|
|
18
|
+
|
|
19
|
+
- [✨ Release Notes](/CHANGELOG.md)
|
|
20
|
+
<!-- - [🏀 Online playground](https://stackblitz.com/github/your-org/my-module?file=playground%2Fapp.vue) -->
|
|
21
|
+
<!-- - [📖 Documentation](https://example.com) -->
|
|
22
|
+
|
|
23
|
+
## Features
|
|
24
|
+
|
|
25
|
+
<!-- Highlight some of the features your module provide here -->
|
|
26
|
+
- ⛰ Foo
|
|
27
|
+
- 🚠 Bar
|
|
28
|
+
- 🌲 Baz
|
|
29
|
+
|
|
30
|
+
## Quick Setup
|
|
31
|
+
|
|
32
|
+
Install the module to your Nuxt application with one command:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
bunx nuxt module add @type32/nuxt-cs-utils
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
That's it! You can now use My Module in your Nuxt app ✨
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
## Contribution
|
|
42
|
+
|
|
43
|
+
<details>
|
|
44
|
+
<summary>Local development</summary>
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Install dependencies
|
|
48
|
+
npm install
|
|
49
|
+
|
|
50
|
+
# Generate type stubs
|
|
51
|
+
npm run dev:prepare
|
|
52
|
+
|
|
53
|
+
# Develop with the playground
|
|
54
|
+
npm run dev
|
|
55
|
+
|
|
56
|
+
# Build the playground
|
|
57
|
+
npm run dev:build
|
|
58
|
+
|
|
59
|
+
# Run ESLint
|
|
60
|
+
npm run lint
|
|
61
|
+
|
|
62
|
+
# Run Vitest
|
|
63
|
+
npm run test
|
|
64
|
+
npm run test:watch
|
|
65
|
+
|
|
66
|
+
# Release new version
|
|
67
|
+
npm run release
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
</details>
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
<!-- Badges -->
|
|
74
|
+
[npm-version-src]: https://img.shields.io/npm/v/my-module/latest.svg?style=flat&colorA=020420&colorB=00DC82
|
|
75
|
+
[npm-version-href]: https://npmjs.com/package/my-module
|
|
76
|
+
|
|
77
|
+
[npm-downloads-src]: https://img.shields.io/npm/dm/my-module.svg?style=flat&colorA=020420&colorB=00DC82
|
|
78
|
+
[npm-downloads-href]: https://npm.chart.dev/my-module
|
|
79
|
+
|
|
80
|
+
[license-src]: https://img.shields.io/npm/l/my-module.svg?style=flat&colorA=020420&colorB=00DC82
|
|
81
|
+
[license-href]: https://npmjs.com/package/my-module
|
|
82
|
+
|
|
83
|
+
[nuxt-src]: https://img.shields.io/badge/Nuxt-020420?logo=nuxt
|
|
84
|
+
[nuxt-href]: https://nuxt.com
|
package/dist/module.json
ADDED
package/dist/module.mjs
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { defineNuxtModule, createResolver, addImportsDir } from '@nuxt/kit';
|
|
2
|
+
|
|
3
|
+
const module$1 = defineNuxtModule({
|
|
4
|
+
meta: {
|
|
5
|
+
name: "@type32/nuxt-cs-utils",
|
|
6
|
+
configKey: "csUtils"
|
|
7
|
+
},
|
|
8
|
+
// Default configuration options of the Nuxt module
|
|
9
|
+
defaults: {},
|
|
10
|
+
setup(_options, _nuxt) {
|
|
11
|
+
const resolver = createResolver(import.meta.url);
|
|
12
|
+
addImportsDir(resolver.resolve("./runtime/shared/utils"));
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export { module$1 as default };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { CalendarDate, CalendarDateTime } from "@internationalized/date";
|
|
2
|
+
export declare function convertJSDate(jsDate: Date): CalendarDate;
|
|
3
|
+
export declare function convertJSDateTime(jsDate: Date): CalendarDateTime;
|
|
4
|
+
export declare function getTodayDate(): CalendarDate;
|
|
5
|
+
export declare function wrapDate(date?: Date | null): Date;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getLocalTimeZone,
|
|
3
|
+
today,
|
|
4
|
+
fromDate,
|
|
5
|
+
toCalendarDate,
|
|
6
|
+
toCalendarDateTime
|
|
7
|
+
} from "@internationalized/date";
|
|
8
|
+
export function convertJSDate(jsDate) {
|
|
9
|
+
return toCalendarDate(fromDate(new Date(jsDate), getLocalTimeZone()));
|
|
10
|
+
}
|
|
11
|
+
export function convertJSDateTime(jsDate) {
|
|
12
|
+
return toCalendarDateTime(fromDate(new Date(jsDate), getLocalTimeZone()));
|
|
13
|
+
}
|
|
14
|
+
export function getTodayDate() {
|
|
15
|
+
return today(getLocalTimeZone());
|
|
16
|
+
}
|
|
17
|
+
export function wrapDate(date) {
|
|
18
|
+
if (!date)
|
|
19
|
+
return /* @__PURE__ */ new Date();
|
|
20
|
+
else
|
|
21
|
+
return new Date(date);
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sanitizes a string to be a valid filename. It replaces illegal characters
|
|
3
|
+
* and handles Windows-specific reserved names and edge cases. This function
|
|
4
|
+
* is designed to be safe for multilingual input.
|
|
5
|
+
*
|
|
6
|
+
* @param name The string to sanitize.
|
|
7
|
+
* @param options An optional options object.
|
|
8
|
+
* @param options.replacement The character to use for replacing illegal characters. Defaults to an empty string (removal).
|
|
9
|
+
* @returns A safe filename string.
|
|
10
|
+
*/
|
|
11
|
+
export declare function sanitizeFilename(name: string, options?: {
|
|
12
|
+
replacement?: string;
|
|
13
|
+
}): string;
|
|
14
|
+
/**
|
|
15
|
+
* Checks if a given string is a valid and safe filename across platforms.
|
|
16
|
+
* It's stricter than sanitizeFilename; it checks if the string is *already* clean.
|
|
17
|
+
*
|
|
18
|
+
* @param name The string to validate.
|
|
19
|
+
* @returns `true` if the filename is valid, `false` otherwise.
|
|
20
|
+
*/
|
|
21
|
+
export declare function isValidFilename(name: string): boolean;
|
|
22
|
+
export declare function getFileExtensionFromPath(path: string): string;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const ILEGAL_CHARACTERS_REGEX = /[<>:"/\\|?*\x00-\x1f\x7f]/g;
|
|
2
|
+
const RESERVED_FILENAMES_REGEX = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i;
|
|
3
|
+
export function sanitizeFilename(name, options) {
|
|
4
|
+
const replacement = options?.replacement ?? "";
|
|
5
|
+
let sanitized = name.replace(ILEGAL_CHARACTERS_REGEX, replacement);
|
|
6
|
+
sanitized = sanitized.trim().replace(/[. ]+$/, "");
|
|
7
|
+
const baseName = sanitized.split(".")[0];
|
|
8
|
+
if (RESERVED_FILENAMES_REGEX.test(baseName || "")) {
|
|
9
|
+
sanitized = "_" + sanitized;
|
|
10
|
+
}
|
|
11
|
+
if (sanitized === "" || /^\.+$/.test(sanitized)) {
|
|
12
|
+
return "_";
|
|
13
|
+
}
|
|
14
|
+
return sanitized;
|
|
15
|
+
}
|
|
16
|
+
export function isValidFilename(name) {
|
|
17
|
+
if (name.length === 0) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const sanitizedName = sanitizeFilename(name, { replacement: "X" });
|
|
21
|
+
if (name !== sanitizedName) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
const baseName = name.split(".")[0];
|
|
25
|
+
return !(!baseName || RESERVED_FILENAMES_REGEX.test(baseName));
|
|
26
|
+
}
|
|
27
|
+
export function getFileExtensionFromPath(path) {
|
|
28
|
+
const fn = path.split(".");
|
|
29
|
+
return fn[fn.length - 1] || "unknown";
|
|
30
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safely converts a query value to a Date object.
|
|
3
|
+
* Handles ISO strings and numeric timestamps.
|
|
4
|
+
*/
|
|
5
|
+
export declare function queryToDate(val: any): Date | undefined;
|
|
6
|
+
/**
|
|
7
|
+
* Safely converts a query value to a Boolean.
|
|
8
|
+
* Handles string 'true'/'false', '1'/'0', and H3 query arrays.
|
|
9
|
+
*/
|
|
10
|
+
export declare function queryToBoolean(val: any): boolean | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Safely converts a query value to a Number.
|
|
13
|
+
* Returns undefined if NaN or empty.
|
|
14
|
+
*/
|
|
15
|
+
export declare function queryToNumber(val: any): number | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Ensures a query value is an Array of a specific type.
|
|
18
|
+
* Useful for handling Enums like status arrays.
|
|
19
|
+
*/
|
|
20
|
+
export declare function queryToArray<T>(val: any): T[] | undefined;
|
|
21
|
+
type FieldType = 'boolean' | 'number' | 'string' | 'array' | 'date';
|
|
22
|
+
export type QueryMapConfig<T> = {
|
|
23
|
+
[K in keyof T]?: NonNullable<T[K]> extends Date ? FieldType : NonNullable<T[K]> extends any[] ? FieldType : NonNullable<T[K]> extends Record<string, any> ? QueryMapConfig<NonNullable<T[K]>> : FieldType;
|
|
24
|
+
};
|
|
25
|
+
export declare function parseQueryObject<T>(query: any, config: QueryMapConfig<T>): T;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export function queryToDate(val) {
|
|
2
|
+
if (val instanceof Date) return Number.isNaN(val.getTime()) ? void 0 : val;
|
|
3
|
+
if (Array.isArray(val)) val = val[0];
|
|
4
|
+
const str = String(val ?? "").trim();
|
|
5
|
+
if (!str || str.toLowerCase() === "undefined" || str.toLowerCase() === "null") return void 0;
|
|
6
|
+
const isNumeric = /^\d+$/.test(str);
|
|
7
|
+
const parsedDate = new Date(isNumeric ? Number(str) : str);
|
|
8
|
+
return Number.isNaN(parsedDate.getTime()) ? void 0 : parsedDate;
|
|
9
|
+
}
|
|
10
|
+
export function queryToBoolean(val) {
|
|
11
|
+
if (typeof val === "boolean") return val;
|
|
12
|
+
if (Array.isArray(val)) val = val[0];
|
|
13
|
+
const str = String(val ?? "").toLowerCase().trim();
|
|
14
|
+
if (!str || str === "undefined" || str === "null") return void 0;
|
|
15
|
+
return str === "true" || str === "1";
|
|
16
|
+
}
|
|
17
|
+
export function queryToNumber(val) {
|
|
18
|
+
if (typeof val === "number") return val;
|
|
19
|
+
if (Array.isArray(val)) val = val[0];
|
|
20
|
+
const str = String(val ?? "").trim().toLowerCase();
|
|
21
|
+
if (!str || str === "undefined" || str === "null") return void 0;
|
|
22
|
+
const num = Number(str);
|
|
23
|
+
return Number.isNaN(num) ? void 0 : num;
|
|
24
|
+
}
|
|
25
|
+
export function queryToArray(val) {
|
|
26
|
+
if (val === void 0 || val === null || val === "") return void 0;
|
|
27
|
+
const str = String(val).toLowerCase();
|
|
28
|
+
if (str === "undefined" || str === "null") return void 0;
|
|
29
|
+
if (Array.isArray(val)) return val;
|
|
30
|
+
return [val];
|
|
31
|
+
}
|
|
32
|
+
export function parseQueryObject(query, config) {
|
|
33
|
+
if (!query || typeof query !== "object" || Array.isArray(query)) {
|
|
34
|
+
return query;
|
|
35
|
+
}
|
|
36
|
+
const result = { ...query };
|
|
37
|
+
for (const [key, typeOrConfig] of Object.entries(config)) {
|
|
38
|
+
const val = query[key];
|
|
39
|
+
if (val === void 0 || val === null) continue;
|
|
40
|
+
if (typeof typeOrConfig === "object") {
|
|
41
|
+
result[key] = parseQueryObject(val, typeOrConfig);
|
|
42
|
+
} else {
|
|
43
|
+
switch (typeOrConfig) {
|
|
44
|
+
case "boolean":
|
|
45
|
+
result[key] = queryToBoolean(val);
|
|
46
|
+
break;
|
|
47
|
+
case "number":
|
|
48
|
+
result[key] = queryToNumber(val);
|
|
49
|
+
break;
|
|
50
|
+
case "array":
|
|
51
|
+
result[key] = queryToArray(val);
|
|
52
|
+
break;
|
|
53
|
+
case "date":
|
|
54
|
+
result[key] = queryToDate(val);
|
|
55
|
+
break;
|
|
56
|
+
// <-- New Date Case
|
|
57
|
+
case "string":
|
|
58
|
+
result[key] = Array.isArray(val) ? String(val[0]) : String(val);
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return result;
|
|
64
|
+
}
|
package/dist/types.d.mts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@type32/nuxt-cs-utils",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "My new Nuxt module",
|
|
5
|
+
"repository": "https://github.com/CTRL-Neo-Studios/client-server-utils",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/types.d.mts",
|
|
11
|
+
"import": "./dist/module.mjs"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"main": "./dist/module.mjs",
|
|
15
|
+
"typesVersions": {
|
|
16
|
+
"*": {
|
|
17
|
+
".": [
|
|
18
|
+
"./dist/types.d.mts"
|
|
19
|
+
]
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"workspaces": [
|
|
26
|
+
"playground"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"prepack": "nuxt-module-build build",
|
|
30
|
+
"dev": "bun run dev:prepare && nuxt dev playground",
|
|
31
|
+
"dev:build": "nuxt build playground",
|
|
32
|
+
"dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxt prepare playground",
|
|
33
|
+
"release": "bun run prepack && changelogen --release && bun publish && git push --follow-tags",
|
|
34
|
+
"test": "vitest run",
|
|
35
|
+
"test:watch": "vitest watch",
|
|
36
|
+
"test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@internationalized/date": "^3.11.0",
|
|
40
|
+
"@nuxt/kit": "^4.3.1"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@nuxt/devtools": "^3.2.1",
|
|
44
|
+
"@nuxt/module-builder": "^1.0.2",
|
|
45
|
+
"@nuxt/schema": "^4.3.1",
|
|
46
|
+
"@nuxt/test-utils": "^4.0.0",
|
|
47
|
+
"@types/node": "latest",
|
|
48
|
+
"changelogen": "^0.6.2",
|
|
49
|
+
"nuxt": "^4.3.1",
|
|
50
|
+
"typescript": "~5.9.3",
|
|
51
|
+
"vitest": "^4.0.18",
|
|
52
|
+
"vue-tsc": "^3.2.5"
|
|
53
|
+
}
|
|
54
|
+
}
|