@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 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
+ - [✨ &nbsp;Release Notes](/CHANGELOG.md)
20
+ <!-- - [🏀 Online playground](https://stackblitz.com/github/your-org/my-module?file=playground%2Fapp.vue) -->
21
+ <!-- - [📖 &nbsp;Documentation](https://example.com) -->
22
+
23
+ ## Features
24
+
25
+ <!-- Highlight some of the features your module provide here -->
26
+ - ⛰ &nbsp;Foo
27
+ - 🚠 &nbsp;Bar
28
+ - 🌲 &nbsp;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
@@ -0,0 +1,8 @@
1
+ import * as _nuxt_schema from '@nuxt/schema';
2
+
3
+ interface ModuleOptions {
4
+ }
5
+ declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
6
+
7
+ export { _default as default };
8
+ export type { ModuleOptions };
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "@type32/nuxt-cs-utils",
3
+ "configKey": "csUtils",
4
+ "version": "1.1.0",
5
+ "builder": {
6
+ "@nuxt/module-builder": "1.0.2",
7
+ "unbuild": "unknown"
8
+ }
9
+ }
@@ -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
+ }
@@ -0,0 +1,3 @@
1
+ export { default } from './module.mjs'
2
+
3
+ export { type ModuleOptions } from './module.mjs'
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
+ }