@nhealth/nutils 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.
Files changed (36) hide show
  1. package/README.md +503 -0
  2. package/dist/module.cjs +43 -0
  3. package/dist/module.d.cts +13 -0
  4. package/dist/module.d.mts +13 -0
  5. package/dist/module.d.ts +13 -0
  6. package/dist/module.json +12 -0
  7. package/dist/module.mjs +40 -0
  8. package/dist/runtime/app/assets/styles.css +1 -0
  9. package/dist/runtime/app/components/ComponentRouter.d.vue.ts +50 -0
  10. package/dist/runtime/app/components/ComponentRouter.vue +26 -0
  11. package/dist/runtime/app/components/ComponentRouter.vue.d.ts +50 -0
  12. package/dist/runtime/app/components/ComponentShell.d.vue.ts +28 -0
  13. package/dist/runtime/app/components/ComponentShell.vue +95 -0
  14. package/dist/runtime/app/components/ComponentShell.vue.d.ts +28 -0
  15. package/dist/runtime/app/components/ConfirmModal.d.vue.ts +3 -0
  16. package/dist/runtime/app/components/ConfirmModal.vue +163 -0
  17. package/dist/runtime/app/components/ConfirmModal.vue.d.ts +3 -0
  18. package/dist/runtime/app/components/LiveIndicator.d.vue.ts +9 -0
  19. package/dist/runtime/app/components/LiveIndicator.vue +43 -0
  20. package/dist/runtime/app/components/LiveIndicator.vue.d.ts +9 -0
  21. package/dist/runtime/app/components/StatCard.d.vue.ts +15 -0
  22. package/dist/runtime/app/components/StatCard.vue +99 -0
  23. package/dist/runtime/app/components/StatCard.vue.d.ts +15 -0
  24. package/dist/runtime/app/components/StatCounter.d.vue.ts +11 -0
  25. package/dist/runtime/app/components/StatCounter.vue +29 -0
  26. package/dist/runtime/app/components/StatCounter.vue.d.ts +11 -0
  27. package/dist/runtime/app/composables/useComponentRouter.d.ts +50 -0
  28. package/dist/runtime/app/composables/useComponentRouter.js +265 -0
  29. package/dist/runtime/app/composables/useConfirmModal.d.ts +50 -0
  30. package/dist/runtime/app/composables/useConfirmModal.js +107 -0
  31. package/dist/runtime/app/composables/useConfirmModalState.d.ts +12 -0
  32. package/dist/runtime/app/composables/useConfirmModalState.js +12 -0
  33. package/dist/runtime/shared/formatters.d.ts +22 -0
  34. package/dist/runtime/shared/formatters.js +15 -0
  35. package/dist/types.d.mts +3 -0
  36. package/package.json +63 -0
@@ -0,0 +1,50 @@
1
+ import { type Component } from '#imports';
2
+ import type { ShallowRef } from 'vue';
3
+ import { createHooks } from 'hookable';
4
+ type AsyncComponentLoader = () => Promise<Component | {
5
+ default: Component;
6
+ }>;
7
+ export type ComponentRouteRecord = {
8
+ path: string;
9
+ component: Component | AsyncComponentLoader;
10
+ name?: string;
11
+ };
12
+ export type ComponentRouterMode = 'query' | 'hash' | 'memory';
13
+ export interface UseComponentRouterOptions {
14
+ routes: ComponentRouteRecord[] | Record<string, Component | AsyncComponentLoader>;
15
+ base?: string;
16
+ mode?: ComponentRouterMode;
17
+ initial?: string;
18
+ provideKey?: string;
19
+ debug?: boolean;
20
+ }
21
+ type RouterHooks = {
22
+ navigated: (data: {
23
+ path: string;
24
+ params: Record<string, string>;
25
+ }) => void;
26
+ };
27
+ type RouterContext = {
28
+ route: ShallowRef<{
29
+ path: string;
30
+ params: Record<string, string>;
31
+ query: Record<string, string | string[]>;
32
+ }>;
33
+ push: (path: string) => Promise<void>;
34
+ replace: (path: string) => Promise<void>;
35
+ makePath: (patternOrPath: string, params?: Record<string, string | number | boolean>) => string;
36
+ makeHref: (patternOrPath: string, params?: Record<string, string | number | boolean>) => string;
37
+ pushTo: (patternOrPath: string, params?: Record<string, string | number | boolean>) => Promise<void>;
38
+ replaceTo: (patternOrPath: string, params?: Record<string, string | number | boolean>) => Promise<void>;
39
+ hooks: ReturnType<typeof createHooks<RouterHooks>>;
40
+ };
41
+ export declare function useComponentRouter(): RouterContext & {
42
+ component?: Component;
43
+ };
44
+ export declare function useComponentRouter(opts: UseComponentRouterOptions): RouterContext & {
45
+ component: Component;
46
+ };
47
+ export default useComponentRouter;
48
+ export declare function createComponentRoutes(glob: Record<string, AsyncComponentLoader>, options?: {
49
+ base?: string;
50
+ }): ComponentRouteRecord[];
@@ -0,0 +1,265 @@
1
+ import {
2
+ computed,
3
+ inject,
4
+ provide,
5
+ shallowRef,
6
+ useRoute,
7
+ useRouter,
8
+ watch,
9
+ defineAsyncComponent
10
+ } from "#imports";
11
+ import { createHooks } from "hookable";
12
+ export function useComponentRouter(opts) {
13
+ const CTX_KEY = "component-router";
14
+ if (!opts || !("routes" in opts) || !opts.routes) {
15
+ const key = (opts && "provideKey" in opts ? opts.provideKey : void 0) ?? CTX_KEY;
16
+ const ctx = inject(key, null);
17
+ if (!ctx) {
18
+ console.warn(
19
+ "[useComponentRouter] No parent router context found. Ensure a parent uses useComponentRouter with routes or wrap children in <component-router>."
20
+ );
21
+ const emptyRoute = shallowRef({ path: "", params: {}, query: {} });
22
+ const warnNav = async (_p) => console.warn(
23
+ "[useComponentRouter] push/replace called without a parent router context."
24
+ );
25
+ const noopMake = (p, _params) => p;
26
+ const noopHref = (p, _params) => p;
27
+ const emptyHooks = createHooks();
28
+ return {
29
+ route: emptyRoute,
30
+ push: warnNav,
31
+ replace: warnNav,
32
+ makePath: noopMake,
33
+ makeHref: noopHref,
34
+ pushTo: async (p, _params) => warnNav(p),
35
+ replaceTo: async (p, _params) => warnNav(p),
36
+ hooks: emptyHooks,
37
+ component: void 0
38
+ };
39
+ }
40
+ return ctx;
41
+ }
42
+ const props = {
43
+ routes: Array.isArray(opts.routes) ? opts.routes : Object.entries(opts.routes || {}).map(([path, component2]) => ({
44
+ path,
45
+ component: component2
46
+ })),
47
+ base: opts.base ?? "fp",
48
+ mode: opts.mode ?? "query",
49
+ initial: opts.initial,
50
+ provideKey: opts.provideKey ?? CTX_KEY,
51
+ debug: opts.debug === true
52
+ };
53
+ const nuxtRoute = useRoute();
54
+ const nuxtRouter = useRouter();
55
+ const component = shallowRef(null);
56
+ const route = shallowRef({
57
+ path: "",
58
+ params: {},
59
+ query: {}
60
+ });
61
+ const hooks = createHooks();
62
+ const dbg = (...args) => {
63
+ if (props.debug) console.info("[component-router]", ...args);
64
+ };
65
+ function isAsyncComponentLoader(comp) {
66
+ return typeof comp === "function" && !("__vccOpts" in comp) && !("_asyncResolved" in comp);
67
+ }
68
+ function normalizeComponent(comp) {
69
+ if (isAsyncComponentLoader(comp)) {
70
+ return defineAsyncComponent(() => {
71
+ const result = comp();
72
+ return Promise.resolve(result).then((m) => {
73
+ if (typeof m === "object" && m !== null && "default" in m) {
74
+ return m.default;
75
+ }
76
+ return m;
77
+ });
78
+ });
79
+ }
80
+ return comp;
81
+ }
82
+ function esc(text) {
83
+ return text.replace(/([.+*?=^!${}()[\]|\\])/g, "\\$1");
84
+ }
85
+ function compilePattern(path) {
86
+ const keys = [];
87
+ const dyn = /\/:([^/]+)/g;
88
+ let last = 0;
89
+ let pattern = "";
90
+ let m;
91
+ while (m = dyn.exec(path)) {
92
+ pattern += esc(path.slice(last, m.index));
93
+ keys.push(m[1]);
94
+ pattern += "/([^/]+)";
95
+ last = m.index + m[0].length;
96
+ }
97
+ pattern += esc(path.slice(last));
98
+ const regex = new RegExp("^" + pattern + "$");
99
+ dbg("compiled", { path, pattern, regex, keys });
100
+ return { regex, keys };
101
+ }
102
+ const records = computed(
103
+ () => props.routes.map((r) => {
104
+ const { regex, keys } = compilePattern(r.path);
105
+ return { ...r, regex, keys };
106
+ })
107
+ );
108
+ function matchPath(path) {
109
+ dbg("matchPath", path);
110
+ for (const r of records.value) {
111
+ const m = r.regex.exec(path);
112
+ dbg(" try", r.path, r.regex, !!m);
113
+ if (m) {
114
+ const params = {};
115
+ r.keys.forEach(
116
+ (k, i) => params[k] = decodeURIComponent(m[i + 1] || "")
117
+ );
118
+ return { record: r, params };
119
+ }
120
+ }
121
+ return null;
122
+ }
123
+ function setCurrent(path) {
124
+ dbg("setCurrent", path);
125
+ const m = matchPath(path) || matchPath(props.routes[0]?.path || "/");
126
+ if (!m) return;
127
+ const rawComponent = m.record.component;
128
+ component.value = normalizeComponent(rawComponent);
129
+ const [pathOnly, queryString] = path.split("?");
130
+ const queryParams = {};
131
+ if (queryString) {
132
+ const params = new URLSearchParams(queryString);
133
+ params.forEach((value, key) => {
134
+ queryParams[key] = value;
135
+ });
136
+ }
137
+ route.value = {
138
+ path: pathOnly || path,
139
+ params: m.params,
140
+ query: queryParams
141
+ // Only use query params from the current path, not from nuxtRoute
142
+ };
143
+ dbg("current", route.value);
144
+ dbg("calling navigated hook with", { path: pathOnly || path, params: m.params });
145
+ hooks.callHook("navigated", { path: pathOnly || path, params: m.params });
146
+ }
147
+ function readFromHost() {
148
+ if (props.mode === "query") {
149
+ const p = nuxtRoute.query[props.base];
150
+ dbg("readFromHost(query)", p);
151
+ return typeof p === "string" ? p : null;
152
+ }
153
+ if (props.mode === "hash") {
154
+ const h = (typeof window !== "undefined" ? window.location.hash : "") || "";
155
+ const key = `#${props.base}=`;
156
+ const idx = h.indexOf(key);
157
+ dbg("readFromHost(hash)", h);
158
+ return idx >= 0 ? h.slice(idx + key.length) : null;
159
+ }
160
+ return null;
161
+ }
162
+ async function writeToHost(path, replace2 = false) {
163
+ dbg("writeToHost", path, { replace: replace2, mode: props.mode });
164
+ const prevPath = route.value.path;
165
+ dbg("current path before write:", prevPath, "new path:", path);
166
+ if (props.mode === "query") {
167
+ const [pathOnly, queryString] = path.split("?");
168
+ const pathQuery = {};
169
+ if (queryString) {
170
+ const params = new URLSearchParams(queryString);
171
+ params.forEach((value, key) => {
172
+ pathQuery[key] = value;
173
+ });
174
+ }
175
+ const nextQuery = { [props.base]: pathOnly, ...pathQuery };
176
+ if (nuxtRoute.query[props.base] === pathOnly && !queryString) {
177
+ setCurrent(path);
178
+ return;
179
+ }
180
+ await (replace2 ? nuxtRouter.replace({ query: nextQuery }) : nuxtRouter.push({ query: nextQuery }));
181
+ return;
182
+ }
183
+ if (props.mode === "hash" && typeof window !== "undefined") {
184
+ const key = `#${props.base}=`;
185
+ const nextHash = key + path;
186
+ if (window.location.hash !== nextHash) {
187
+ if (replace2) {
188
+ const url = window.location.href.replace(/#.*/, "") + nextHash;
189
+ window.history.replaceState(null, "", url);
190
+ } else {
191
+ window.location.hash = nextHash;
192
+ }
193
+ }
194
+ setCurrent(path);
195
+ return;
196
+ }
197
+ setCurrent(path);
198
+ }
199
+ async function push(path) {
200
+ await writeToHost(path, false);
201
+ }
202
+ async function replace(path) {
203
+ await writeToHost(path, true);
204
+ }
205
+ function makePath(patternOrPath, params) {
206
+ const hasDyn = /:[^/]+/.test(patternOrPath);
207
+ if (!hasDyn) return patternOrPath;
208
+ const replaced = patternOrPath.replace(/:([^/]+)/g, (_m, key) => {
209
+ const v = params?.[key];
210
+ return encodeURIComponent(v == null ? "" : String(v));
211
+ });
212
+ return replaced.replace(/\/{2,}/g, "/");
213
+ }
214
+ function makeHref(patternOrPath, params) {
215
+ const path = makePath(patternOrPath, params);
216
+ if (props.mode === "query") return `?${props.base}=${path}`;
217
+ if (props.mode === "hash") return `#${props.base}=${path}`;
218
+ return path;
219
+ }
220
+ async function pushTo(patternOrPath, params) {
221
+ const path = makePath(patternOrPath, params);
222
+ await push(path);
223
+ }
224
+ async function replaceTo(patternOrPath, params) {
225
+ const path = makePath(patternOrPath, params);
226
+ await replace(path);
227
+ }
228
+ const exposed = { push, replace, route, makePath, makeHref, pushTo, replaceTo, hooks };
229
+ provide(props.provideKey, exposed);
230
+ const initialPath = readFromHost() || props.initial || props.routes[0]?.path || "/";
231
+ dbg("init", { initialPath });
232
+ writeToHost(initialPath, true);
233
+ watch(
234
+ () => ({
235
+ q: nuxtRoute.query[props.base],
236
+ h: typeof window !== "undefined" ? window.location.hash : ""
237
+ }),
238
+ () => {
239
+ const path = readFromHost();
240
+ dbg("watch change detected ->", path);
241
+ if (path) setCurrent(path);
242
+ }
243
+ );
244
+ return { component, route, push, replace, makePath, makeHref, pushTo, replaceTo, hooks };
245
+ }
246
+ export default useComponentRouter;
247
+ export function createComponentRoutes(glob, options) {
248
+ const base = options?.base || "";
249
+ const toPath = (key) => {
250
+ let p = key.replace(/^\.\//, "/").replace(/\.(vue|tsx?|jsx?)$/, "");
251
+ p = p.replace(/\/index$/, "");
252
+ p = p.replace(/\[(.+?)\]/g, ":$1");
253
+ if (!p.startsWith("/")) p = "/" + p;
254
+ if (base) {
255
+ const b = base.startsWith("/") ? base : "/" + base;
256
+ p = (b + (p === "/" ? "" : p)).replace(/\/+/, "/");
257
+ }
258
+ return p || "/";
259
+ };
260
+ return Object.entries(glob).map(([key, loader]) => ({
261
+ path: toPath(key),
262
+ component: loader
263
+ // Pass loader directly, normalizeComponent handles it
264
+ }));
265
+ }
@@ -0,0 +1,50 @@
1
+ export type ConfirmModalResult<T = unknown> = {
2
+ confirmed: boolean;
3
+ value?: T;
4
+ };
5
+ export type ConfirmModalOptions<T = unknown> = {
6
+ title?: string;
7
+ text?: string;
8
+ description?: string;
9
+ items?: string[];
10
+ warning?: string;
11
+ icon?: string;
12
+ confirmLabel?: string;
13
+ cancelLabel?: string;
14
+ confirmColor?: 'primary' | 'neutral' | 'error' | 'success' | 'warning';
15
+ cancelColor?: 'neutral' | 'primary' | 'error' | 'success' | 'warning';
16
+ confirmVariant?: 'solid' | 'subtle' | 'ghost' | 'outline' | 'soft' | 'link';
17
+ cancelVariant?: 'solid' | 'subtle' | 'ghost' | 'outline' | 'soft' | 'link';
18
+ iconColor?: 'primary' | 'error' | 'warning' | 'success' | 'info';
19
+ dangerous?: boolean;
20
+ size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl';
21
+ autofocus?: 'confirm' | 'cancel' | 'none';
22
+ closeOnConfirm?: boolean;
23
+ closeOnCancel?: boolean;
24
+ requireInputEquals?: string;
25
+ inputPlaceholder?: string;
26
+ inputLabel?: string;
27
+ inputHint?: string;
28
+ requireCheckbox?: boolean;
29
+ checkboxLabel?: string;
30
+ payload?: T;
31
+ onConfirm?: (ctx: {
32
+ payload?: T;
33
+ }) => void | Promise<void>;
34
+ onCancel?: (ctx: {
35
+ payload?: T;
36
+ }) => void | Promise<void>;
37
+ };
38
+ export type InternalRequest<T = unknown> = {
39
+ id: number;
40
+ options: ConfirmModalOptions<T>;
41
+ resolve: (v: ConfirmModalResult<T>) => void;
42
+ reject: (e?: unknown) => void;
43
+ };
44
+ export declare function useConfirmModal<T = unknown>(defaults?: ConfirmModalOptions<T>): (overrides?: ConfirmModalOptions<T>) => Promise<ConfirmModalResult<T>>;
45
+ export declare function useConfirmModalActions(): {
46
+ onConfirm: () => Promise<void>;
47
+ onCancel: () => Promise<void>;
48
+ onClosedExternally: () => void;
49
+ };
50
+ export default useConfirmModal;
@@ -0,0 +1,107 @@
1
+ import { useConfirmModalState } from "./useConfirmModalState.js";
2
+ let autoId = 0;
3
+ function enqueue(req) {
4
+ const state = useConfirmModalState();
5
+ const id = ++autoId;
6
+ const full = { id, ...req };
7
+ state.value.queue.push(full);
8
+ if (!state.value.current) {
9
+ showNext();
10
+ }
11
+ }
12
+ function showNext() {
13
+ const state = useConfirmModalState();
14
+ const next = state.value.queue[0] || null;
15
+ state.value.current = next;
16
+ state.value.confirmInput = "";
17
+ state.value.confirmChecked = false;
18
+ state.value.loading = false;
19
+ state.value.open = !!next;
20
+ state.value.renderOptions = next?.options ?? state.value.renderOptions;
21
+ }
22
+ function finishCurrent(result) {
23
+ const state = useConfirmModalState();
24
+ const cur = state.value.current;
25
+ if (!cur) return;
26
+ try {
27
+ cur.resolve(result);
28
+ } catch {
29
+ }
30
+ state.value.queue.shift();
31
+ state.value.current = null;
32
+ state.value.open = false;
33
+ state.value.loading = false;
34
+ if (state.value.queue.length > 0) {
35
+ queueMicrotask(showNext);
36
+ }
37
+ }
38
+ export function useConfirmModal(defaults) {
39
+ const mergedDefaults = {
40
+ title: "Confirm",
41
+ confirmLabel: "Confirm",
42
+ cancelLabel: "Cancel",
43
+ confirmColor: "primary",
44
+ cancelColor: "neutral",
45
+ confirmVariant: "solid",
46
+ cancelVariant: "subtle",
47
+ autofocus: "confirm",
48
+ closeOnConfirm: true,
49
+ closeOnCancel: true,
50
+ ...defaults || {}
51
+ };
52
+ return function confirm(overrides = {}) {
53
+ const options = {
54
+ ...mergedDefaults,
55
+ ...overrides || {}
56
+ };
57
+ return new Promise((resolve, reject) => {
58
+ enqueue({ options, resolve, reject });
59
+ });
60
+ };
61
+ }
62
+ export function useConfirmModalActions() {
63
+ const state = useConfirmModalState();
64
+ async function onConfirm() {
65
+ const cur = state.value.current;
66
+ if (!cur) return;
67
+ const { requireInputEquals, requireCheckbox } = cur.options;
68
+ if (requireInputEquals && state.value.confirmInput !== requireInputEquals) {
69
+ return;
70
+ }
71
+ if (requireCheckbox && !state.value.confirmChecked) {
72
+ return;
73
+ }
74
+ state.value.loading = true;
75
+ try {
76
+ const res = await cur.options.onConfirm?.({
77
+ payload: cur.options.payload
78
+ });
79
+ const result = { confirmed: true, value: res };
80
+ if (cur.options.closeOnConfirm !== false) {
81
+ finishCurrent(result);
82
+ } else {
83
+ state.value.loading = false;
84
+ }
85
+ } catch {
86
+ state.value.loading = false;
87
+ }
88
+ }
89
+ async function onCancel() {
90
+ const cur = state.value.current;
91
+ if (!cur) return;
92
+ try {
93
+ await cur.options.onCancel?.({ payload: cur.options.payload });
94
+ } finally {
95
+ if (cur.options.closeOnCancel !== false) {
96
+ finishCurrent({ confirmed: false });
97
+ }
98
+ }
99
+ }
100
+ function onClosedExternally() {
101
+ const cur = state.value.current;
102
+ if (!cur) return;
103
+ finishCurrent({ confirmed: false });
104
+ }
105
+ return { onConfirm, onCancel, onClosedExternally };
106
+ }
107
+ export default useConfirmModal;
@@ -0,0 +1,12 @@
1
+ import type { InternalRequest, ConfirmModalOptions } from './useConfirmModal.js';
2
+ type ConfirmModalState = {
3
+ open: boolean;
4
+ loading: boolean;
5
+ queue: InternalRequest<unknown>[];
6
+ current: InternalRequest | null;
7
+ confirmInput: string;
8
+ confirmChecked: boolean;
9
+ renderOptions: ConfirmModalOptions<unknown> | null;
10
+ };
11
+ export declare function useConfirmModalState(): Ref<ConfirmModalState>;
12
+ export default useConfirmModalState;
@@ -0,0 +1,12 @@
1
+ export function useConfirmModalState() {
2
+ return useState("confirmModal", () => ({
3
+ open: false,
4
+ loading: false,
5
+ queue: [],
6
+ current: null,
7
+ confirmInput: "",
8
+ confirmChecked: false,
9
+ renderOptions: null
10
+ }));
11
+ }
12
+ export default useConfirmModalState;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Format a date to a readable string
3
+ * @param date - Date object or timestamp
4
+ * @param locale - Locale string (default: 'en-US')
5
+ * @returns Formatted date string
6
+ */
7
+ export declare const formatDate: (date: Date | number, locale?: string) => string;
8
+ /**
9
+ * Format a number with thousand separators
10
+ * @param num - Number to format
11
+ * @param locale - Locale string (default: 'en-US')
12
+ * @returns Formatted number string
13
+ */
14
+ export declare const formatNumber: (num: number, locale?: string) => string;
15
+ /**
16
+ * Truncate a string to a specified length
17
+ * @param str - String to truncate
18
+ * @param maxLength - Maximum length (default: 50)
19
+ * @param suffix - Suffix to add when truncated (default: '...')
20
+ * @returns Truncated string
21
+ */
22
+ export declare const truncate: (str: string, maxLength?: number, suffix?: string) => string;
@@ -0,0 +1,15 @@
1
+ export const formatDate = (date, locale = "en-US") => {
2
+ const dateObj = typeof date === "number" ? new Date(date) : date;
3
+ return dateObj.toLocaleDateString(locale, {
4
+ year: "numeric",
5
+ month: "long",
6
+ day: "numeric"
7
+ });
8
+ };
9
+ export const formatNumber = (num, locale = "en-US") => {
10
+ return num.toLocaleString(locale);
11
+ };
12
+ export const truncate = (str, maxLength = 50, suffix = "...") => {
13
+ if (str.length <= maxLength) return str;
14
+ return str.substring(0, maxLength - suffix.length) + suffix;
15
+ };
@@ -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,63 @@
1
+ {
2
+ "name": "@nhealth/nutils",
3
+ "version": "0.0.2",
4
+ "description": "Shared Nuxt.js v4 module with components, composables, and utilities",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": {
8
+ "types": "./dist/types.d.mts",
9
+ "import": "./dist/module.mjs",
10
+ "require": "./dist/module.cjs",
11
+ "style": "./dist/runtime/app/assets/styles.css"
12
+ }
13
+ },
14
+ "main": "./dist/module.cjs",
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "prepack": "nuxt-module-build build",
20
+ "dev": "nuxi dev playground",
21
+ "build": "yarn dev:prepare && nuxt-module-build build",
22
+ "dev:build": "nuxi build playground",
23
+ "dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
24
+ "release": "bumpp --recursive && npm publish",
25
+ "bumpp": "bumpp --recursive",
26
+ "lint": "eslint .",
27
+ "test": "vitest run",
28
+ "test:watch": "vitest watch",
29
+ "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit"
30
+ },
31
+ "dependencies": {
32
+ "@nuxt/kit": "^4.2.2"
33
+ },
34
+ "devDependencies": {
35
+ "@nuxt/devtools": "^3.1.1",
36
+ "@nuxt/eslint-config": "^1.12.1",
37
+ "@nuxt/module-builder": "^1.0.2",
38
+ "@nuxt/schema": "^4.2.2",
39
+ "@nuxt/test-utils": "^3.23.0",
40
+ "@nuxt/ui": "^4.3.0",
41
+ "changelogen": "^0.6.2",
42
+ "eslint": "^9.39.2",
43
+ "nuxt": "^4.2.2",
44
+ "typescript": "^5.9.3",
45
+ "vitest": "^4.0.16",
46
+ "vue-tsc": "^3.2.2",
47
+ "bumpp": "10.3.2"
48
+ },
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "git+https://github.com/nhealthorg/nutils.git"
52
+ },
53
+ "keywords": [
54
+ "nuxt",
55
+ "nuxt-module",
56
+ "nuxt4",
57
+ "components",
58
+ "composables",
59
+ "utilities"
60
+ ],
61
+ "author": "nhealth.org",
62
+ "license": "MIT"
63
+ }