abckit 0.0.28 → 0.0.30

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 CHANGED
@@ -4,124 +4,81 @@
4
4
  [![npm downloads][npm-downloads-src]][npm-downloads-href]
5
5
  [![License][license-src]][license-href]
6
6
 
7
- A batteries-included Nuxt 4 module that gives you everything you need to build modern web apps beautiful UI components, authentication, storage, and more.
7
+ Nuxt 4 module — UI components, auth, storage, GraphQL.
8
8
 
9
- ## Features
10
-
11
- - **50+ UI Components** — shadcn/ui style components built on [Reka UI](https://reka-ui.com)
12
- - **Authentication** — [Better Auth](https://better-auth.com) integration with session management
13
- - **Storage** — S3/R2, Redis/Dragonfly, and local disk drivers
14
- - **GraphQL API** — [GraphQL Yoga](https://the-guild.dev/graphql/yoga-server) via nitro-graphql
15
- - **Dark Mode** — Built-in color mode support
16
- - **Forms** — Validation with VeeValidate + Zod
17
- - **Data Fetching** — Pinia Colada with global error handling
18
- - **Icons** — 100k+ icons via Nuxt Icon
19
-
20
- ## Quick Start
9
+ ## Install
21
10
 
22
11
  ```bash
23
- # Install
24
12
  pnpm add abckit
13
+ ```
25
14
 
26
- # Add to nuxt.config.ts
15
+ ```typescript
16
+ // nuxt.config.ts
27
17
  export default defineNuxtConfig({
28
- modules: ['abckit']
18
+ modules: ['abckit'],
29
19
  })
30
20
  ```
31
21
 
32
- Import components from `abckit/shadcn/*`:
33
-
34
- ```vue
35
- <script setup lang="ts">
36
- import { Button } from 'abckit/shadcn/button'
37
- import { Card, CardHeader, CardTitle } from 'abckit/shadcn/card'
38
- </script>
39
-
40
- <template>
41
- <Button variant="outline">Click me</Button>
42
- <Card>
43
- <CardHeader>
44
- <CardTitle>Hello</CardTitle>
45
- </CardHeader>
46
- </Card>
47
- </template>
48
- ```
49
-
50
- ## Components
51
-
52
- Accordion, Alert, AlertDialog, AspectRatio, AutoForm, Avatar, Badge, Breadcrumb, Button, ButtonGroup, Calendar, Card, Carousel, Chart, Checkbox, Collapsible, Combobox, Command, ContextMenu, CountrySelect, CurrencySelect, Dialog, Drawer, DropdownMenu, Empty, Field, File, Form, HoverCard, Input, InputGroup, InputOTP, Item, Kbd, Label, LanguageSelect, Menubar, NativeSelect, NavigationMenu, NumberField, Pagination, PinInput, Popover, Progress, RadioGroup, RangeCalendar, Resizable, ScrollArea, Select, Separator, Sheet, Sidebar, Skeleton, Slider, Spinner, Stepper, Storage, Switch, Table, Tabs, TagsInput, Textarea, TimezoneSelect, Toggle, ToggleGroup, Tooltip
53
-
54
- ## Composables
55
-
56
- ```ts
57
- // Authentication
58
- const { user, isAuthenticated, login, logout } = useAuth()
59
-
60
- // Image CDN URLs with presets
61
- const { getImageUrl } = useImageUrl()
62
- const url = getImageUrl('products/photo.jpg', 'lg') // 1000x1000
63
-
64
- // Auto breadcrumbs from routes
65
- const items = useBreadcrumbItems()
22
+ ## Modules
23
+
24
+ ```typescript
25
+ abckit: {
26
+ modules: {
27
+ // Default: true
28
+ tailwindcss: true,
29
+ notivue: true,
30
+ icon: true,
31
+ colada: true,
32
+ colorMode: true,
33
+ vueuse: true,
34
+ pinia: true,
35
+ veeValidate: true,
36
+ graphql: true,
37
+ persistedState: true,
38
+ ionic: true,
39
+ scripts: true,
40
+
41
+ // Default: false
42
+ sentry: false,
43
+
44
+ // all: true // Enable all
45
+ },
46
+ auth: {
47
+ baseURL: 'https://api.example.com',
48
+ basePath: '/api/auth',
49
+ capacitor: false,
50
+ },
51
+ }
66
52
  ```
67
53
 
68
- ## Configuration
54
+ ## Usage
69
55
 
70
- ```ts
71
- // nuxt.config.ts
72
- export default defineNuxtConfig({
73
- extends: ['abckit'],
74
- runtimeConfig: {
75
- // Redis/Dragonfly
76
- dragonfly: {
77
- host: 'localhost',
78
- port: 6379
79
- },
80
- // S3/R2 Storage
81
- s3: {
82
- accessKeyId: '',
83
- secretAccessKey: '',
84
- endpoint: '',
85
- bucket: ''
86
- },
87
- // Enable storage drivers
88
- storage: {
89
- redis: true,
90
- s3: true,
91
- disk: false
92
- }
93
- }
94
- })
56
+ ```typescript
57
+ import { Button } from 'abckit/shadcn/button'
58
+ import { useAuth } from 'abckit/composables/useAuth'
59
+ import { cn } from 'abckit/utils'
95
60
  ```
96
61
 
97
- ## Theming
62
+ ## Runtime Config
98
63
 
99
- Override the default theme by creating `app/assets/css/tailwind.css`:
100
-
101
- ```css
102
- @import "tailwindcss";
103
- @import "tw-animate-css";
104
-
105
- :root {
106
- --primary: oklch(0.6 0.2 250);
107
- --radius: 0.5rem;
64
+ ```typescript
65
+ runtimeConfig: {
66
+ dragonfly: { host: 'localhost', port: 6379 },
67
+ s3: { accessKeyId: '', secretAccessKey: '', endpoint: '', bucket: '' },
68
+ storage: { redis: true, s3: true, disk: false },
108
69
  }
109
70
  ```
110
71
 
111
- ## Contributing
72
+ ## Development
112
73
 
113
- Contributions, issues, and feature requests are welcome! Feel free to open an issue or submit a pull request.
74
+ ```bash
75
+ pnpm install && pnpm dev:prepare && pnpm dev
76
+ ```
114
77
 
115
78
  ## License
116
79
 
117
80
  MIT
118
81
 
119
- ---
120
-
121
- <p align="center">
122
- <img src=".github/assets/footer.svg" width="100%" alt="abckit footer" />
123
- </p>
124
-
125
82
  <!-- Badges -->
126
83
  [npm-version-src]: https://img.shields.io/npm/v/abckit?style=flat&colorA=080f12&colorB=1fa669
127
84
  [npm-version-href]: https://npmjs.com/package/abckit
package/dist/module.d.mts CHANGED
@@ -46,20 +46,104 @@ interface AuthClientOptions {
46
46
  */
47
47
  capacitor?: boolean;
48
48
  }
49
- interface ModuleOptions {
49
+ interface ModulesConfig {
50
50
  /**
51
- * Enable Sentry user tracking in useAuth composable
51
+ * Enable all modules by default
52
+ * Individual module settings override this
52
53
  * @default false
53
54
  */
55
+ all?: boolean;
56
+ /**
57
+ * Enable Tailwind CSS
58
+ * @default true
59
+ */
60
+ tailwindcss?: boolean;
61
+ /**
62
+ * Enable Notivue toast notifications
63
+ * @default true
64
+ */
65
+ notivue?: boolean;
66
+ /**
67
+ * Enable Nuxt Icon
68
+ * @default true
69
+ */
70
+ icon?: boolean;
71
+ /**
72
+ * Enable Pinia Colada for data fetching
73
+ * @default true
74
+ */
75
+ colada?: boolean;
76
+ /**
77
+ * Enable Color Mode (dark/light)
78
+ * @default true
79
+ */
80
+ colorMode?: boolean;
81
+ /**
82
+ * Enable VueUse composables
83
+ * @default true
84
+ */
85
+ vueuse?: boolean;
86
+ /**
87
+ * Enable Pinia state management
88
+ * @default true
89
+ */
90
+ pinia?: boolean;
91
+ /**
92
+ * Enable VeeValidate form validation
93
+ * @default true
94
+ */
95
+ veeValidate?: boolean;
96
+ /**
97
+ * Enable GraphQL API with nitro-graphql
98
+ * @default true
99
+ */
100
+ graphql?: boolean;
101
+ /**
102
+ * Enable Pinia persisted state plugin
103
+ * @default true
104
+ */
105
+ persistedState?: boolean;
106
+ /**
107
+ * Enable Ionic Vue integration
108
+ * @default true
109
+ */
110
+ ionic?: boolean;
111
+ /**
112
+ * Enable Nuxt Scripts
113
+ * @default true
114
+ */
115
+ scripts?: boolean;
116
+ /**
117
+ * Enable Sentry error tracking
118
+ * @default false (or true if all: true)
119
+ */
54
120
  sentry?: boolean;
121
+ }
122
+ interface ModuleOptions {
123
+ /**
124
+ * Module toggles - enable/disable individual features
125
+ * Use `all: true` to enable all modules, then disable specific ones
126
+ * @example
127
+ * modules: { all: true, graphql: false } // Enable all except graphql
128
+ * modules: { sentry: true } // Only enable sentry
129
+ */
130
+ modules?: ModulesConfig;
55
131
  /**
56
132
  * Better Auth client configuration
57
133
  */
58
134
  auth?: AuthClientOptions;
59
135
  /**
60
- Set to true when installed via npm package, dont used project.
136
+ * Set to true when installed via npm package, dont used project.
61
137
  */
62
138
  npm?: boolean;
139
+ /**
140
+ * @deprecated Use `modules.sentry` instead
141
+ */
142
+ sentry?: boolean;
143
+ /**
144
+ * @deprecated Use `modules.graphql` instead
145
+ */
146
+ graphql?: boolean;
63
147
  }
64
148
  declare module '@nuxt/schema' {
65
149
  interface AppConfig extends BreadcrumbsConfig, SetupConfig {
@@ -113,7 +197,8 @@ declare module '@nuxt/schema' {
113
197
  };
114
198
  }
115
199
  }
200
+
116
201
  declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
117
202
 
118
203
  export { _default as default };
119
- export type { AuthClientOptions, BreadcrumbsConfig, ModuleOptions, SetupConfig };
204
+ export type { AuthClientOptions, BreadcrumbsConfig, ModuleOptions, ModulesConfig, SetupConfig };
package/dist/module.mjs CHANGED
@@ -1,145 +1,137 @@
1
- import { join } from 'node:path';
2
- import { defineNuxtModule, createResolver, addTypeTemplate, addServerScanDir, addRouteMiddleware } from '@nuxt/kit';
1
+ import { addTypeTemplate, addServerScanDir, addRouteMiddleware, defineNuxtModule, createResolver } from '@nuxt/kit';
3
2
  import { defu } from 'defu';
3
+ import { join } from 'node:path';
4
4
  import { networkInterfaces } from 'node:os';
5
5
 
6
- const isMobileBuild = process.env.MOBILE_BUILD === "true" || process.env.NUXT_PUBLIC_MOBILE_DEV === "true";
7
- const isMobileDev = process.env.MOBILE_DEV === "true" || process.env.NUXT_PUBLIC_MOBILE_DEV === "true";
8
- function getLocalIP() {
9
- const nets = networkInterfaces();
10
- for (const name of Object.keys(nets)) {
11
- for (const net of nets[name] || []) {
12
- if (net.family === "IPv4" && !net.internal) {
13
- return net.address;
14
- }
15
- }
6
+ const CORE_MODULES = ["tailwindcss", "notivue", "icon", "colada", "colorMode", "vueuse", "pinia", "veeValidate", "graphql", "persistedState", "ionic", "scripts"];
7
+ function resolveModule(modules, key) {
8
+ if (modules?.[key] !== void 0) {
9
+ return modules[key];
16
10
  }
17
- return "localhost";
11
+ if (modules?.all !== void 0) {
12
+ return modules.all;
13
+ }
14
+ return CORE_MODULES.includes(key);
18
15
  }
19
- const localIP = isMobileDev ? getLocalIP() : null;
20
- const mobileBaseURL = isMobileDev ? `http://${localIP}:3000` : "https://e.sayfa.app";
21
-
22
- const module$1 = defineNuxtModule({
23
- meta: {
24
- name: "abckit",
25
- configKey: "abckit",
26
- version: "0.0.1"
27
- },
28
- defaults: {
29
- sentry: false,
30
- auth: {
31
- baseURL: isMobileBuild ? mobileBaseURL : void 0,
32
- basePath: "/api/auth",
33
- capacitor: isMobileBuild
34
- },
35
- npm: false
36
- },
37
- moduleDependencies: (nuxt) => ({
38
- "@nuxtjs/tailwindcss": {},
39
- "notivue/nuxt": {},
40
- "@nuxt/icon": {},
41
- "@pinia/colada-nuxt": {},
42
- "@nuxtjs/color-mode": {},
43
- "@vueuse/nuxt": {},
44
- "@pinia/nuxt": {},
45
- "@vee-validate/nuxt": {},
46
- "nitro-graphql/nuxt": {},
47
- "pinia-plugin-persistedstate/nuxt": {},
48
- "@nuxtjs/ionic": {},
49
- "@nuxt/scripts": {},
50
- "@sentry/nuxt/module": {
51
- optional: nuxt.options.dev
16
+ function createModuleChecker(opts) {
17
+ const m = opts?.modules;
18
+ return (key, deprecatedKey) => {
19
+ if (deprecatedKey && opts?.[deprecatedKey] !== void 0) {
20
+ return opts[deprecatedKey] === true;
52
21
  }
53
- }),
54
- async setup(options, nuxt) {
55
- const { resolve } = createResolver(import.meta.url);
56
- nuxt.options.abckit = defu(nuxt.options.abckit, options);
57
- nuxt.options.devtools = defu(nuxt.options.devtools, {
58
- enabled: false
59
- });
60
- nuxt.options.runtimeConfig.public.abckit = {
61
- sentry: nuxt.options.runtimeConfig.public.abckit?.sentry ?? options.sentry ?? false,
62
- auth: {
63
- baseURL: isMobileBuild ? mobileBaseURL : nuxt.options.runtimeConfig.public.abckit?.auth?.baseURL ?? options.auth?.baseURL,
64
- basePath: nuxt.options.runtimeConfig.public.abckit?.auth?.basePath ?? options.auth?.basePath,
65
- capacitor: isMobileBuild
66
- }
67
- };
68
- nuxt.options.runtimeConfig.dragonfly = defu(nuxt.options.runtimeConfig.dragonfly, {
69
- host: "dragonfly",
70
- port: Number.parseInt("6379", 10),
71
- password: "",
72
- url: ""
73
- });
74
- nuxt.options.runtimeConfig.s3 = defu(nuxt.options.runtimeConfig.s3, {
75
- accessKeyId: "",
76
- secretAccessKey: "",
77
- endpoint: "",
78
- bucket: "",
79
- region: "auto",
80
- publicUrl: ""
81
- });
82
- nuxt.options.runtimeConfig.polar = defu(nuxt.options.runtimeConfig.polar, {
83
- accessToken: "",
84
- checkoutSuccessUrl: "/checkout/success",
85
- server: "sandbox",
86
- webhookSecret: ""
87
- });
88
- nuxt.options.runtimeConfig.imgproxy = defu(nuxt.options.runtimeConfig.imgproxy, {
89
- storageUrl: "",
90
- cdnDomains: []
91
- });
92
- nuxt.options.runtimeConfig.storage = defu(nuxt.options.runtimeConfig.storage, {
93
- redis: false,
94
- s3: false,
95
- disk: false
96
- });
97
- nuxt.options.runtimeConfig.public = defu(nuxt.options.runtimeConfig.public, {
98
- siteUrl: isMobileBuild ? mobileBaseURL : "http://localhost:3000",
99
- isMobile: isMobileBuild,
100
- debug: nuxt.options.dev,
101
- imgproxy: {
102
- storageUrl: "",
103
- cdnDomains: []
104
- }
105
- });
106
- const siteUrl = nuxt.options.runtimeConfig.public.siteUrl;
107
- const appName = nuxt.options.app.head?.title || "abckit";
108
- nuxt.options.app.head = defu(nuxt.options.app.head, {
109
- meta: [
110
- { charset: "utf-8" },
111
- { name: "viewport", content: "viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" },
112
- { name: "author", content: appName },
113
- { name: "robots", content: "index, follow" },
114
- // Open Graph
115
- { property: "og:type", content: "website" },
116
- { property: "og:site_name", content: appName },
117
- { property: "og:image", content: `${siteUrl}/og-image.png` },
118
- { property: "og:url", content: siteUrl },
119
- // Twitter
120
- { name: "twitter:card", content: "summary_large_image" },
121
- { name: "twitter:image", content: `${siteUrl}/og-image.png` },
122
- // Apple
123
- { name: "apple-mobile-web-app-title", content: appName }
124
- ],
125
- link: [
126
- { rel: "icon", type: "image/png", href: "/favicon-96x96.png", sizes: "96x96" },
127
- { rel: "icon", type: "image/svg+xml", href: "/favicon.svg" },
128
- { rel: "shortcut icon", href: "/favicon.ico" },
129
- { rel: "apple-touch-icon", sizes: "180x180", href: "/apple-touch-icon.png" },
130
- // Manifest only for web, not needed in native apps
131
- ...isMobileBuild ? [] : [{ rel: "manifest", href: "/site.webmanifest" }]
132
- ]
133
- });
134
- addTypeTemplate({
135
- filename: "types/nuxt-shared-h3.d.ts",
136
- getContents: () => `
22
+ return resolveModule(m, key);
23
+ };
24
+ }
25
+ function getModuleDependencies(nuxt) {
26
+ const opts = nuxt.options.abckit;
27
+ const isEnabled = createModuleChecker(opts);
28
+ return {
29
+ "@nuxtjs/tailwindcss": { optional: !isEnabled("tailwindcss") },
30
+ "notivue/nuxt": { optional: !isEnabled("notivue") },
31
+ "@nuxt/icon": { optional: !isEnabled("icon") },
32
+ "@pinia/colada-nuxt": { optional: !isEnabled("colada") },
33
+ "@nuxtjs/color-mode": { optional: !isEnabled("colorMode") },
34
+ "@vueuse/nuxt": { optional: !isEnabled("vueuse") },
35
+ "@pinia/nuxt": { optional: !isEnabled("pinia") },
36
+ "@vee-validate/nuxt": { optional: !isEnabled("veeValidate") },
37
+ "nitro-graphql/nuxt": { optional: !isEnabled("graphql", "graphql") },
38
+ "pinia-plugin-persistedstate/nuxt": { optional: !isEnabled("persistedState") },
39
+ "@nuxtjs/ionic": { optional: !isEnabled("ionic") },
40
+ "@nuxt/scripts": { optional: !isEnabled("scripts") },
41
+ "@sentry/nuxt/module": { optional: nuxt.options.dev || !isEnabled("sentry", "sentry") }
42
+ };
43
+ }
44
+
45
+ const VITE_EXCLUDE_PACKAGES = [
46
+ "abckit",
47
+ "shadcn-nuxt",
48
+ "@vue/devtools-core",
49
+ "@vue/devtools-kit",
50
+ "notivue",
51
+ "zod",
52
+ "date-fns",
53
+ "date-fns/locale",
54
+ "class-variance-authority",
55
+ "reka-ui",
56
+ "clsx",
57
+ "tailwind-merge",
58
+ "@sindresorhus/slugify",
59
+ "better-auth",
60
+ "leaflet",
61
+ "@capgo/capacitor-social-login",
62
+ "ionicons/icons",
63
+ "@ionic/vue",
64
+ "@capacitor/core",
65
+ "@capacitor/status-bar",
66
+ "@capacitor/splash-screen",
67
+ "@capacitor/preferences",
68
+ "@capacitor/geolocation",
69
+ "@capacitor/network",
70
+ "@capacitor/push-notifications",
71
+ "@capacitor/device",
72
+ "capacitor-native-settings",
73
+ "@capacitor/haptics",
74
+ "@unovis/vue"
75
+ ];
76
+ const DRAGONFLY_DEFAULTS = {
77
+ host: "dragonfly",
78
+ port: 6379,
79
+ password: "",
80
+ url: ""
81
+ };
82
+ const S3_DEFAULTS = {
83
+ accessKeyId: "",
84
+ secretAccessKey: "",
85
+ endpoint: "",
86
+ bucket: "",
87
+ region: "auto",
88
+ publicUrl: ""
89
+ };
90
+ const POLAR_DEFAULTS = {
91
+ accessToken: "",
92
+ checkoutSuccessUrl: "/checkout/success",
93
+ server: "sandbox",
94
+ webhookSecret: ""
95
+ };
96
+ const IMGPROXY_DEFAULTS = {
97
+ storageUrl: "",
98
+ cdnDomains: []
99
+ };
100
+ const STORAGE_DEFAULTS = {
101
+ redis: false,
102
+ s3: false,
103
+ disk: false
104
+ };
105
+ const APP_HEAD_LINKS = [
106
+ { rel: "icon", type: "image/png", href: "/favicon-96x96.png", sizes: "96x96" },
107
+ { rel: "icon", type: "image/svg+xml", href: "/favicon.svg" },
108
+ { rel: "shortcut icon", href: "/favicon.ico" },
109
+ { rel: "apple-touch-icon", sizes: "180x180", href: "/apple-touch-icon.png" }
110
+ ];
111
+ const ALIAS_PATHS = {
112
+ "abckit/runtime": "./runtime",
113
+ "abckit/server/utils": "./runtime/server/utils",
114
+ "abckit/components": "./runtime/components",
115
+ "abckit/shadcn": "./runtime/components/ui",
116
+ "abckit/composables": "./runtime/composables",
117
+ "abckit/middleware": "./runtime/middleware",
118
+ "abckit/plugins": "./runtime/plugins",
119
+ "abckit/graphql": "./runtime/graphql",
120
+ "abckit/stores": "./runtime/stores",
121
+ "abckit/utils": "./runtime/utils",
122
+ "abckit/types/client": "./runtime/types/nitro-graphql-client",
123
+ "abckit/shared": "./runtime/shared"
124
+ };
125
+ const NPM_TS_PATHS = {
126
+ "abckit/components": ["./node_modules/abckit/runtime/components/ui"],
127
+ "abckit/composables": ["./node_modules/abckit/runtime/composables"],
128
+ "abckit/utils": ["./node_modules/abckit/runtime/utils"],
129
+ "abckit/shadcn": ["./node_modules/abckit/runtime/components/ui"],
130
+ "abckit/lib": ["./node_modules/abckit/runtime/utils"]
131
+ };
132
+ const H3_TYPE_TEMPLATE = `
137
133
  declare module 'h3' {
138
134
  interface H3EventContext {
139
- /**
140
- * Better Auth session
141
- * Check auth?.user in protected routes
142
- */
143
135
  auth: {
144
136
  user: {
145
137
  id: string
@@ -162,193 +154,237 @@ declare module 'h3' {
162
154
  userAgent?: string
163
155
  }
164
156
  }
165
-
166
- /**
167
- * Authorization error (set by auth middleware, thrown by API routes)
168
- */
169
157
  authError?: {
170
158
  statusCode: number
171
159
  statusMessage: string
172
160
  }
173
-
174
- /**
175
- * Premium subscription status
176
- *
177
- * @example
178
- * if (!event.context.isPremium) {
179
- * throw createError({ statusCode: 403, message: 'Premium subscription required' })
180
- * }
181
- */
182
161
  isPremium: boolean
183
-
184
- /**
185
- * Full subscription data (if available)
186
- */
187
162
  subscription: any | null
188
163
  }
189
164
  }
190
165
 
191
166
  export {}
192
- `
193
- }, { nitro: true });
194
- nuxt.hook("app:resolve", (app) => {
195
- app.errorComponent = resolve("./runtime/error.vue");
196
- });
197
- nuxt.options.css = nuxt.options.css || [];
198
- const { existsSync } = await import('node:fs');
199
- const appTailwindPath = join(nuxt.options.rootDir, "app/assets/css/tailwind.css");
200
- if (existsSync(appTailwindPath)) {
201
- nuxt.options.css.push(appTailwindPath);
202
- } else {
203
- nuxt.options.css.push(resolve("./runtime/assets/css/tailwind.css"));
167
+ `;
168
+ const GRAPHQL_SCALARS = {
169
+ Timestamp: "string",
170
+ File: "File",
171
+ Decimal: "string"
172
+ };
173
+
174
+ const isMobileBuild = process.env.MOBILE_BUILD === "true" || process.env.NUXT_PUBLIC_MOBILE_DEV === "true";
175
+ const isMobileDev = process.env.MOBILE_DEV === "true" || process.env.NUXT_PUBLIC_MOBILE_DEV === "true";
176
+ function getLocalIP() {
177
+ const nets = networkInterfaces();
178
+ for (const name of Object.keys(nets)) {
179
+ for (const net of nets[name] || []) {
180
+ if (net.family === "IPv4" && !net.internal) {
181
+ return net.address;
182
+ }
204
183
  }
205
- nuxt.options.css.push(
206
- "notivue/notification.css",
207
- "notivue/animations.css"
208
- );
184
+ }
185
+ return "localhost";
186
+ }
187
+ const localIP = isMobileDev ? getLocalIP() : null;
188
+ const mobileBaseURL = isMobileDev ? `http://${localIP}:3000` : "https://e.sayfa.app";
189
+
190
+ function setupRuntimeConfig(nuxt, options, isSentryEnabled) {
191
+ nuxt.options.runtimeConfig.public.abckit = {
192
+ sentry: isSentryEnabled,
193
+ auth: {
194
+ baseURL: isMobileBuild ? mobileBaseURL : nuxt.options.runtimeConfig.public.abckit?.auth?.baseURL ?? options.auth?.baseURL,
195
+ basePath: nuxt.options.runtimeConfig.public.abckit?.auth?.basePath ?? options.auth?.basePath,
196
+ capacitor: isMobileBuild
197
+ }
198
+ };
199
+ nuxt.options.runtimeConfig.dragonfly = defu(nuxt.options.runtimeConfig.dragonfly, DRAGONFLY_DEFAULTS);
200
+ nuxt.options.runtimeConfig.s3 = defu(nuxt.options.runtimeConfig.s3, S3_DEFAULTS);
201
+ nuxt.options.runtimeConfig.polar = defu(nuxt.options.runtimeConfig.polar, POLAR_DEFAULTS);
202
+ nuxt.options.runtimeConfig.imgproxy = defu(nuxt.options.runtimeConfig.imgproxy, IMGPROXY_DEFAULTS);
203
+ nuxt.options.runtimeConfig.storage = defu(nuxt.options.runtimeConfig.storage, STORAGE_DEFAULTS);
204
+ nuxt.options.runtimeConfig.public = defu(nuxt.options.runtimeConfig.public, {
205
+ siteUrl: isMobileBuild ? mobileBaseURL : "http://localhost:3000",
206
+ isMobile: isMobileBuild,
207
+ debug: nuxt.options.dev,
208
+ imgproxy: IMGPROXY_DEFAULTS
209
+ });
210
+ }
211
+ function setupAppHead(nuxt) {
212
+ const siteUrl = nuxt.options.runtimeConfig.public.siteUrl;
213
+ const appName = nuxt.options.app.head?.title || "abckit";
214
+ nuxt.options.app.head = defu(nuxt.options.app.head, {
215
+ meta: [
216
+ { charset: "utf-8" },
217
+ { name: "viewport", content: "viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" },
218
+ { name: "author", content: appName },
219
+ { name: "robots", content: "index, follow" },
220
+ { property: "og:type", content: "website" },
221
+ { property: "og:site_name", content: appName },
222
+ { property: "og:image", content: `${siteUrl}/og-image.png` },
223
+ { property: "og:url", content: siteUrl },
224
+ { name: "twitter:card", content: "summary_large_image" },
225
+ { name: "twitter:image", content: `${siteUrl}/og-image.png` },
226
+ { name: "apple-mobile-web-app-title", content: appName }
227
+ ],
228
+ link: [
229
+ ...APP_HEAD_LINKS,
230
+ ...isMobileBuild ? [] : [{ rel: "manifest", href: "/site.webmanifest" }]
231
+ ]
232
+ });
233
+ }
234
+ async function setupCSS(nuxt, resolve) {
235
+ nuxt.options.css = nuxt.options.css || [];
236
+ const { existsSync } = await import('node:fs');
237
+ const appTailwindPath = join(nuxt.options.rootDir, "app/assets/css/tailwind.css");
238
+ if (existsSync(appTailwindPath)) {
239
+ nuxt.options.css.push(appTailwindPath);
240
+ } else {
241
+ nuxt.options.css.push(resolve("./runtime/assets/css/tailwind.css"));
242
+ }
243
+ nuxt.options.css.push("notivue/notification.css", "notivue/animations.css");
244
+ }
245
+ function setupNitro(nuxt, resolve, isGraphqlEnabled) {
246
+ nuxt.options.nitro.experimental = defu(nuxt.options.nitro.experimental, {
247
+ tasks: true,
248
+ asyncContext: true
249
+ });
250
+ nuxt.options.nitro.esbuild = defu(nuxt.options.nitro.esbuild, {
251
+ options: { target: "esnext" }
252
+ });
253
+ if (isGraphqlEnabled) {
209
254
  nuxt.options.nitro.modules = nuxt.options.nitro.modules || [];
210
255
  nuxt.options.nitro.modules.push("nitro-graphql");
211
- nuxt.options.nitro.experimental = defu(nuxt.options.nitro.experimental, {
212
- tasks: true,
213
- asyncContext: true
214
- });
215
- nuxt.options.nitro.esbuild = defu(nuxt.options.nitro.esbuild, {
216
- options: {
217
- target: "esnext"
218
- }
219
- });
220
256
  nuxt.options.nitro.graphql = defu(nuxt.options.nitro.graphql, {
221
257
  framework: "graphql-yoga",
222
258
  codegen: {
223
- server: {
224
- scalars: {
225
- Timestamp: "string",
226
- File: "File",
227
- Decimal: "string"
228
- }
229
- },
230
- client: {
231
- scalars: {
232
- Timestamp: "string",
233
- File: "File",
234
- Decimal: "string"
235
- }
236
- }
259
+ server: { scalars: GRAPHQL_SCALARS },
260
+ client: { scalars: GRAPHQL_SCALARS }
237
261
  },
238
262
  scaffold: false
239
263
  });
240
- nuxt.options.ionic = defu(nuxt.options.ionic, {
241
- integrations: {
242
- icons: false
243
- },
244
- css: {
245
- basic: false,
246
- // Tailwind ile çakışan normalize/typography kapalı
247
- core: true,
248
- // IonPage, IonHeader stilleri açık
249
- utilities: false
250
- // ion-padding vs. kapalı
264
+ }
265
+ nuxt.options.ionic = defu(nuxt.options.ionic, {
266
+ integrations: { icons: false },
267
+ css: { basic: false, core: true, utilities: false }
268
+ });
269
+ nuxt.options.nitro.publicAssets = nuxt.options.nitro.publicAssets || [];
270
+ nuxt.options.nitro.publicAssets.push({
271
+ dir: resolve("./runtime/public"),
272
+ baseURL: "/",
273
+ maxAge: 0
274
+ });
275
+ }
276
+ function setupVite(nuxt) {
277
+ nuxt.options.vite.define = defu(nuxt.options.vite.define, {
278
+ "import.meta.env.VITE_MOBILE_BUILD": JSON.stringify(isMobileBuild ? "true" : "false")
279
+ });
280
+ nuxt.options.vite.optimizeDeps = nuxt.options.vite.optimizeDeps || {};
281
+ nuxt.options.vite.optimizeDeps.exclude = nuxt.options.vite.optimizeDeps.exclude || [];
282
+ const excludeSet = new Set(nuxt.options.vite.optimizeDeps.exclude);
283
+ VITE_EXCLUDE_PACKAGES.forEach((pkg) => excludeSet.add(pkg));
284
+ nuxt.options.vite.optimizeDeps.exclude = Array.from(excludeSet);
285
+ if (nuxt.options.dev) {
286
+ nuxt.options.vite.server = nuxt.options.vite.server || {};
287
+ nuxt.options.vite.server.allowedHosts = true;
288
+ }
289
+ }
290
+ function setupAliases(nuxt, resolve) {
291
+ for (const [alias, path] of Object.entries(ALIAS_PATHS)) {
292
+ nuxt.options.alias[alias] = resolve(path);
293
+ }
294
+ }
295
+ function setupTypeScript(nuxt) {
296
+ nuxt.options.typescript = defu(nuxt.options.typescript, {
297
+ tsConfig: {
298
+ compilerOptions: {
299
+ allowArbitraryExtensions: true,
300
+ types: ["@pinia/colada-plugin-auto-refetch"]
251
301
  }
252
- });
253
- nuxt.options.nitro.publicAssets = nuxt.options.nitro.publicAssets || [];
254
- nuxt.options.nitro.publicAssets.push({
255
- dir: resolve("./runtime/public"),
256
- baseURL: "/",
257
- maxAge: 0
258
- });
259
- nuxt.hook("tailwindcss:sources:extend", (sources) => {
260
- sources.push({
261
- source: `${resolve("./runtime/components")}`,
262
- type: "path"
263
- });
264
- });
265
- if (nuxt.options.dev) {
266
- nuxt.options.vite.server = nuxt.options.vite.server || {};
267
- nuxt.options.vite.server.allowedHosts = true;
268
302
  }
269
- nuxt.options.alias["abckit/runtime"] = resolve("./runtime");
270
- nuxt.options.alias["abckit/server/utils"] = resolve("./runtime/server/utils");
271
- nuxt.options.alias["abckit/components"] = resolve("./runtime/components");
272
- nuxt.options.alias["abckit/shadcn"] = resolve("./runtime/components/ui");
273
- nuxt.options.alias["abckit/composables"] = resolve("./runtime/composables");
274
- nuxt.options.alias["abckit/middleware"] = resolve("./runtime/middleware");
275
- nuxt.options.alias["abckit/plugins"] = resolve("./runtime/plugins");
276
- nuxt.options.alias["abckit/graphql"] = resolve("./runtime/graphql");
277
- nuxt.options.alias["abckit/stores"] = resolve("./runtime/stores");
278
- nuxt.options.alias["abckit/utils"] = resolve("./runtime/utils");
279
- nuxt.options.alias["abckit/types/client"] = resolve("./runtime/types/nitro-graphql-client");
280
- nuxt.options.alias["abckit/shared"] = resolve("./runtime/shared");
281
- nuxt.options.vite.define = defu(nuxt.options.vite.define, {
282
- "import.meta.env.VITE_MOBILE_BUILD": JSON.stringify(isMobileBuild ? "true" : "false")
283
- });
284
- nuxt.options.vite.optimizeDeps = nuxt.options.vite.optimizeDeps || {};
285
- nuxt.options.vite.optimizeDeps.exclude = nuxt.options.vite.optimizeDeps.exclude || [];
286
- const excludeSet = new Set(nuxt.options.vite.optimizeDeps.exclude);
287
- excludeSet.add("abckit");
288
- excludeSet.add("shadcn-nuxt");
289
- excludeSet.add("@vue/devtools-core");
290
- excludeSet.add("@vue/devtools-kit");
291
- excludeSet.add("notivue");
292
- excludeSet.add("zod");
293
- excludeSet.add("date-fns");
294
- excludeSet.add("date-fns/locale");
295
- excludeSet.add("class-variance-authority");
296
- excludeSet.add("reka-ui");
297
- excludeSet.add("clsx");
298
- excludeSet.add("tailwind-merge");
299
- excludeSet.add("@sindresorhus/slugify");
300
- excludeSet.add("better-auth");
301
- excludeSet.add("leaflet");
302
- excludeSet.add("@capgo/capacitor-social-login");
303
- excludeSet.add("ionicons/icons");
304
- excludeSet.add("@ionic/vue");
305
- excludeSet.add("@capacitor/core");
306
- excludeSet.add("@capacitor/status-bar");
307
- excludeSet.add("@capacitor/splash-screen");
308
- excludeSet.add("@capacitor/preferences");
309
- excludeSet.add("@capacitor/geolocation");
310
- excludeSet.add("@capacitor/network");
311
- excludeSet.add("@capacitor/push-notifications");
312
- excludeSet.add("@capacitor/device");
313
- excludeSet.add("capacitor-native-settings");
314
- excludeSet.add("@capacitor/haptics");
315
- excludeSet.add("@unovis/vue");
316
- nuxt.options.vite.optimizeDeps.exclude = Array.from(excludeSet);
317
- nuxt.options.typescript = defu(nuxt.options.typescript, {
318
- tsConfig: {
319
- compilerOptions: {
320
- allowArbitraryExtensions: true,
321
- types: ["@pinia/colada-plugin-auto-refetch"]
322
- }
323
- }
324
- });
325
- nuxt.options.colorMode = defu(nuxt.options.colorMode, {
326
- classSuffix: "",
327
- fallback: "light",
328
- storageKey: "color-mode",
329
- preference: "light"
330
- });
331
- addServerScanDir(resolve("./runtime/server"));
332
- addRouteMiddleware({
333
- name: "auth",
334
- path: resolve("./runtime/middleware/auth")
335
- });
336
- nuxt.options.routeRules = nuxt.options.routeRules || {};
337
- nuxt.options.routeRules["/**"] = defu(nuxt.options.routeRules["/**"] || {}, {
338
- ssr: false
339
- });
340
- nuxt.options.routeRules["/"] = defu(nuxt.options.routeRules["/"] || {}, {
341
- ssr: true
303
+ });
304
+ if (nuxt.options.abckit?.npm) {
305
+ nuxt.options.typescript.tsConfig.compilerOptions ??= {};
306
+ nuxt.options.typescript.tsConfig.compilerOptions.paths ??= {};
307
+ Object.assign(nuxt.options.typescript.tsConfig.compilerOptions.paths, NPM_TS_PATHS);
308
+ }
309
+ }
310
+ function setupColorMode(nuxt) {
311
+ nuxt.options.colorMode = defu(nuxt.options.colorMode, {
312
+ classSuffix: "",
313
+ fallback: "light",
314
+ storageKey: "color-mode",
315
+ preference: "light"
316
+ });
317
+ }
318
+ function setupRouting(nuxt, resolve) {
319
+ addServerScanDir(resolve("./runtime/server"));
320
+ addRouteMiddleware({
321
+ name: "auth",
322
+ path: resolve("./runtime/middleware/auth")
323
+ });
324
+ nuxt.options.routeRules = nuxt.options.routeRules || {};
325
+ nuxt.options.routeRules["/**"] = defu(nuxt.options.routeRules["/**"] || {}, { ssr: false });
326
+ nuxt.options.routeRules["/"] = defu(nuxt.options.routeRules["/"] || {}, { ssr: true });
327
+ }
328
+ function setupTypes() {
329
+ addTypeTemplate({
330
+ filename: "types/nuxt-shared-h3.d.ts",
331
+ getContents: () => H3_TYPE_TEMPLATE
332
+ }, { nitro: true });
333
+ }
334
+ function setupHooks(nuxt, resolve) {
335
+ nuxt.hook("app:resolve", (app) => {
336
+ app.errorComponent = resolve("./runtime/error.vue");
337
+ });
338
+ nuxt.hook("tailwindcss:sources:extend", (sources) => {
339
+ sources.push({
340
+ source: `${resolve("./runtime/components")}`,
341
+ type: "path"
342
342
  });
343
- if (nuxt.options.abckit.npm) {
344
- nuxt.options.typescript.tsConfig.compilerOptions ??= {};
345
- nuxt.options.typescript.tsConfig.compilerOptions.paths ??= {};
346
- nuxt.options.typescript.tsConfig.compilerOptions.paths["abckit/components"] = ["./node_modules/abckit/runtime/components/ui"];
347
- nuxt.options.typescript.tsConfig.compilerOptions.paths["abckit/composables"] = ["./node_modules/abckit/runtime/composables"];
348
- nuxt.options.typescript.tsConfig.compilerOptions.paths["abckit/utils"] = ["./node_modules/abckit/runtime/utils"];
349
- nuxt.options.typescript.tsConfig.compilerOptions.paths["abckit/shadcn"] = ["./node_modules/abckit/runtime/components/ui"];
350
- nuxt.options.typescript.tsConfig.compilerOptions.paths["abckit/lib"] = ["./node_modules/abckit/runtime/utils"];
351
- }
343
+ });
344
+ }
345
+ function setupDevtools(nuxt) {
346
+ nuxt.options.devtools = defu(nuxt.options.devtools, {
347
+ enabled: false
348
+ });
349
+ }
350
+
351
+ const module$1 = defineNuxtModule({
352
+ meta: {
353
+ name: "abckit",
354
+ configKey: "abckit",
355
+ version: "0.0.1"
356
+ },
357
+ defaults: {
358
+ modules: {
359
+ all: false,
360
+ sentry: false
361
+ },
362
+ auth: {
363
+ baseURL: isMobileBuild ? mobileBaseURL : void 0,
364
+ basePath: "/api/auth",
365
+ capacitor: isMobileBuild
366
+ },
367
+ npm: false
368
+ },
369
+ moduleDependencies: getModuleDependencies,
370
+ async setup(options, nuxt) {
371
+ const { resolve } = createResolver(import.meta.url);
372
+ nuxt.options.abckit = defu(nuxt.options.abckit, options);
373
+ const isEnabled = createModuleChecker(nuxt.options.abckit);
374
+ const isSentryEnabled = isEnabled("sentry", "sentry");
375
+ const isGraphqlEnabled = isEnabled("graphql", "graphql");
376
+ setupDevtools(nuxt);
377
+ setupRuntimeConfig(nuxt, options, isSentryEnabled);
378
+ setupAppHead(nuxt);
379
+ setupTypes();
380
+ setupHooks(nuxt, resolve);
381
+ await setupCSS(nuxt, resolve);
382
+ setupNitro(nuxt, resolve, isGraphqlEnabled);
383
+ setupVite(nuxt);
384
+ setupAliases(nuxt, resolve);
385
+ setupTypeScript(nuxt);
386
+ setupColorMode(nuxt);
387
+ setupRouting(nuxt, resolve);
352
388
  }
353
389
  });
354
390
 
@@ -9,19 +9,19 @@ type __VLS_Slots = {} & {
9
9
  };
10
10
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
11
11
  "update:modelValue": (value: import("reka-ui").AcceptableValue) => any;
12
- entryFocus: (event: CustomEvent<any>) => any;
13
12
  highlight: (payload: {
14
13
  ref: HTMLElement;
15
14
  value: import("reka-ui").AcceptableValue;
16
15
  } | undefined) => any;
16
+ entryFocus: (event: CustomEvent<any>) => any;
17
17
  leave: (event: Event) => any;
18
18
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
19
19
  "onUpdate:modelValue"?: ((value: import("reka-ui").AcceptableValue) => any) | undefined;
20
- onEntryFocus?: ((event: CustomEvent<any>) => any) | undefined;
21
20
  onHighlight?: ((payload: {
22
21
  ref: HTMLElement;
23
22
  value: import("reka-ui").AcceptableValue;
24
23
  } | undefined) => any) | undefined;
24
+ onEntryFocus?: ((event: CustomEvent<any>) => any) | undefined;
25
25
  onLeave?: ((event: Event) => any) | undefined;
26
26
  }>, {
27
27
  modelValue: import("reka-ui").AcceptableValue | import("reka-ui").AcceptableValue[];
@@ -9,19 +9,19 @@ type __VLS_Slots = {} & {
9
9
  };
10
10
  declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
11
11
  "update:modelValue": (value: import("reka-ui").AcceptableValue) => any;
12
- entryFocus: (event: CustomEvent<any>) => any;
13
12
  highlight: (payload: {
14
13
  ref: HTMLElement;
15
14
  value: import("reka-ui").AcceptableValue;
16
15
  } | undefined) => any;
16
+ entryFocus: (event: CustomEvent<any>) => any;
17
17
  leave: (event: Event) => any;
18
18
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
19
19
  "onUpdate:modelValue"?: ((value: import("reka-ui").AcceptableValue) => any) | undefined;
20
- onEntryFocus?: ((event: CustomEvent<any>) => any) | undefined;
21
20
  onHighlight?: ((payload: {
22
21
  ref: HTMLElement;
23
22
  value: import("reka-ui").AcceptableValue;
24
23
  } | undefined) => any) | undefined;
24
+ onEntryFocus?: ((event: CustomEvent<any>) => any) | undefined;
25
25
  onLeave?: ((event: Event) => any) | undefined;
26
26
  }>, {
27
27
  modelValue: import("reka-ui").AcceptableValue | import("reka-ui").AcceptableValue[];
package/dist/types.d.mts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { default } from './module.mjs'
2
2
 
3
- export { type AuthClientOptions, type BreadcrumbsConfig, type ModuleOptions, type SetupConfig } from './module.mjs'
3
+ export { type AuthClientOptions, type BreadcrumbsConfig, type ModuleOptions, type ModulesConfig, type SetupConfig } from './module.mjs'
package/package.json CHANGED
@@ -1,7 +1,31 @@
1
1
  {
2
2
  "name": "abckit",
3
3
  "type": "module",
4
- "version": "0.0.28",
4
+ "version": "0.0.30",
5
+ "description": "Nuxt 4 module — UI components, auth, storage, GraphQL",
6
+ "author": "productdevbook",
7
+ "license": "MIT",
8
+ "homepage": "https://github.com/productdevbook/abckit",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/productdevbook/abckit.git"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/productdevbook/abckit/issues"
15
+ },
16
+ "keywords": [
17
+ "nuxt",
18
+ "nuxt-module",
19
+ "vue",
20
+ "shadcn",
21
+ "ui-components",
22
+ "auth",
23
+ "graphql",
24
+ "tailwindcss",
25
+ "pinia",
26
+ "better-auth",
27
+ "reka-ui"
28
+ ],
5
29
  "private": false,
6
30
  "sideEffects": false,
7
31
  "workspaces": ["playground/*"],