@devappsnpm/vue-kit 0.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.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +82 -0
  3. package/bin/devapps-vue.js +3 -0
  4. package/dist/index.cjs +556 -0
  5. package/dist/index.cjs.map +1 -0
  6. package/dist/index.js +510 -0
  7. package/dist/index.js.map +1 -0
  8. package/dist/ui.cjs +515 -0
  9. package/dist/ui.cjs.map +1 -0
  10. package/dist/ui.js +485 -0
  11. package/dist/ui.js.map +1 -0
  12. package/package.json +57 -0
  13. package/stubs/components/component.vue.stub +17 -0
  14. package/stubs/module/basic/component.vue.stub +9 -0
  15. package/stubs/module/basic/index.ts.stub +1 -0
  16. package/stubs/module/crud/modal/components/DeleteModal.vue.stub +35 -0
  17. package/stubs/module/crud/modal/components/FormModal.vue.stub +88 -0
  18. package/stubs/module/crud/modal/components/List.vue.stub +60 -0
  19. package/stubs/module/crud/modal/index.ts.stub +4 -0
  20. package/stubs/module/crud/modal/router.ts.stub +11 -0
  21. package/stubs/module/crud/modal/services/service.ts.stub +9 -0
  22. package/stubs/module/crud/modal/stores/store.ts.stub +9 -0
  23. package/stubs/module/crud/modal/types/types.ts.stub +16 -0
  24. package/stubs/module/crud/modal/views/View.vue.stub +83 -0
  25. package/stubs/module/crud/page/components/DeleteModal.vue.stub +35 -0
  26. package/stubs/module/crud/page/components/Form.vue.stub +62 -0
  27. package/stubs/module/crud/page/components/List.vue.stub +42 -0
  28. package/stubs/module/crud/page/index.ts.stub +4 -0
  29. package/stubs/module/crud/page/pages/CreatePage.vue.stub +27 -0
  30. package/stubs/module/crud/page/pages/EditPage.vue.stub +34 -0
  31. package/stubs/module/crud/page/pages/ListPage.vue.stub +59 -0
  32. package/stubs/module/crud/page/pages/ShowPage.vue.stub +28 -0
  33. package/stubs/module/crud/page/router.ts.stub +26 -0
  34. package/stubs/module/crud/page/services/service.ts.stub +9 -0
  35. package/stubs/module/crud/page/stores/store.ts.stub +9 -0
  36. package/stubs/module/crud/page/types/types.ts.stub +16 -0
  37. package/stubs/module/dashboard/Dashboard.vue.stub +24 -0
  38. package/stubs/module/dashboard/index.ts.stub +1 -0
  39. package/stubs/module/dashboard/router.ts.stub +11 -0
  40. package/stubs/module/resource/List.vue.stub +19 -0
  41. package/stubs/module/resource/index.ts.stub +3 -0
  42. package/stubs/module/resource/service.ts.stub +9 -0
  43. package/stubs/module/resource/store.ts.stub +9 -0
  44. package/stubs/module/resource/types.ts.stub +10 -0
  45. package/stubs/pages/page.vue.stub +14 -0
  46. package/stubs/services/service.ts.stub +13 -0
  47. package/stubs/stores/store.ts.stub +19 -0
  48. package/stubs/types/types.ts.stub +6 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/core/http/HttpClient.ts","../src/core/http/auth/JwtAuthDriver.ts","../src/core/http/auth/CookieAuthDriver.ts","../src/core/http/auth/LocalStorageTokenStorage.ts","../src/core/http/auth/SessionStorageTokenStorage.ts","../src/core/http/HttpError.ts","../src/core/http/interceptors/response.interceptor.ts","../src/config/createVueKit.ts","../src/core/services/BaseService.ts","../src/core/services/CrudService.ts","../src/core/stores/CrudStore.ts","../src/core/pagination/Pagination.ts","../src/core/forms/Form.ts"],"sourcesContent":["export { createVueKit } from \"./config/createVueKit\";\nexport type { VueKit } from \"./config/createVueKit\";\nexport type { VueKitConfig } from \"./config/VueKitConfig\";\n\nexport { HttpClient } from \"./core/http/HttpClient\";\nexport type { HttpClientConfig } from \"./core/http/HttpClientConfig\";\nexport { HttpError } from \"./core/http/HttpError\";\n\nexport { LocalStorageTokenStorage } from \"./core/http/auth/LocalStorageTokenStorage\";\nexport { SessionStorageTokenStorage } from \"./core/http/auth/SessionStorageTokenStorage\";\nexport type { TokenStorage } from \"./core/http/auth/TokenStorage\";\n\nexport { BaseService } from \"./core/services/BaseService\";\nexport { CrudService } from \"./core/services/CrudService\";\n\nexport { defineCrudStore } from \"./core/stores/CrudStore\";\nexport type { CrudState } from \"./core/stores/BaseStore\";\n\nexport { Form } from \"./core/forms/Form\";\nexport { Pagination } from \"./core/pagination/Pagination\";\n\nexport type {\n ApiResource,\n ApiCollection,\n ApiPaginatedCollection,\n ApiParams,\n ApiErrorResponse,\n} from \"./contracts/api\";\n\nexport type {\n PaginationMeta,\n PaginationLinks,\n PaginationParams,\n} from \"./contracts/pagination\";\n\nexport type {\n AuthConfig,\n AuthDriver,\n TokenStorageConfig,\n CsrfConfig,\n} from \"./contracts/auth\";\n\nexport type { HttpHandlers } from \"./contracts/http\";\n","import axios, { type AxiosInstance } from \"axios\";\n\nimport type { HttpClientConfig } from \"./HttpClientConfig\";\n\nimport { JwtAuthDriver } from \"./auth/JwtAuthDriver\";\n\nimport { CookieAuthDriver } from \"./auth/CookieAuthDriver\";\n\nimport type { AuthDriver } from \"./auth/AuthDriver\";\n\nimport type { TokenStorage } from \"./auth/TokenStorage\";\n\nimport type { TokenStorageConfig } from \"../../contracts/auth\";\n\nimport { LocalStorageTokenStorage } from \"./auth/LocalStorageTokenStorage\";\n\nimport { SessionStorageTokenStorage } from \"./auth/SessionStorageTokenStorage\";\n\nimport { registerResponseInterceptor } from \"./interceptors/response.interceptor\";\n\nexport class HttpClient {\n private readonly client: AxiosInstance;\n\n private readonly authDriver: AuthDriver | undefined;\n\n constructor(config: HttpClientConfig) {\n this.client = axios.create({\n baseURL: config.baseURL,\n timeout: config.timeout ?? 30000,\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n },\n });\n\n this.authDriver = this.createAuthDriver(config);\n\n this.authDriver?.configure(this.client);\n\n registerResponseInterceptor(this.client, config.handlers);\n }\n\n private createAuthDriver(config: HttpClientConfig): AuthDriver | undefined {\n const auth = config.auth;\n\n if (!auth || auth.driver === \"none\") {\n return undefined;\n }\n\n if (auth.driver === \"cookie\") {\n return new CookieAuthDriver(auth.csrf);\n }\n\n if (auth.driver === \"jwt\") {\n return new JwtAuthDriver(this.resolveTokenStorage(auth.tokenStorage));\n }\n\n return undefined;\n }\n\n private resolveTokenStorage(\n tokenStorage: TokenStorageConfig | TokenStorage | undefined,\n ): TokenStorage {\n if (tokenStorage && \"get\" in tokenStorage && \"set\" in tokenStorage) {\n return tokenStorage;\n }\n\n const key = tokenStorage?.key ?? \"auth_token\";\n\n if (tokenStorage?.type === \"sessionStorage\") {\n return new SessionStorageTokenStorage(key);\n }\n\n return new LocalStorageTokenStorage(key);\n }\n\n /** Clears whatever authentication state the configured driver holds (token, csrf, etc). */\n clearAuth(): void {\n this.authDriver?.clear();\n }\n\n instance(): AxiosInstance {\n return this.client;\n }\n}\n","import type { AxiosInstance } from \"axios\";\nimport type { AuthDriver } from \"./AuthDriver\";\nimport type { TokenStorage } from \"./TokenStorage\";\n\nexport class JwtAuthDriver implements AuthDriver {\n constructor(private readonly storage: TokenStorage) {}\n\n configure(client: AxiosInstance): void {\n client.interceptors.request.use((config) => {\n const token = this.storage.get();\n\n if (token) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n\n return config;\n });\n }\n\n clear(): void {\n this.storage.remove();\n }\n}\n","import type { AxiosInstance } from \"axios\";\nimport type { AuthDriver } from \"./AuthDriver\";\nimport type { CsrfConfig } from \"../../../contracts/auth\";\n\nconst MUTATING_METHODS = new Set([\"post\", \"put\", \"patch\", \"delete\"]);\n\nexport class CookieAuthDriver implements AuthDriver {\n private csrfInitialization: Promise<void> | null = null;\n\n constructor(private readonly csrf?: CsrfConfig) {}\n\n configure(client: AxiosInstance): void {\n client.defaults.withCredentials = true;\n client.defaults.withXSRFToken = true;\n client.defaults.headers.common[\"X-Requested-With\"] = \"XMLHttpRequest\";\n\n if (this.csrf?.enabled) {\n client.interceptors.request.use(async (config) => {\n const method = config.method?.toLowerCase();\n\n if (method && MUTATING_METHODS.has(method)) {\n await this.ensureCsrfCookie(client);\n }\n\n return config;\n });\n }\n }\n\n clear(): void {\n this.csrfInitialization = null;\n }\n\n private ensureCsrfCookie(client: AxiosInstance): Promise<void> {\n if (!this.csrfInitialization) {\n const endpoint = this.csrf?.endpoint ?? \"/sanctum/csrf-cookie\";\n this.csrfInitialization = client.get(endpoint).then(() => undefined);\n }\n\n return this.csrfInitialization;\n }\n}\n","import type { TokenStorage } from \"./TokenStorage\";\n\nexport class LocalStorageTokenStorage implements TokenStorage {\n constructor(private readonly key: string) {}\n\n get(): string | null {\n if (typeof localStorage === \"undefined\") return null;\n return localStorage.getItem(this.key);\n }\n\n set(token: string): void {\n if (typeof localStorage === \"undefined\") return;\n localStorage.setItem(this.key, token);\n }\n\n remove(): void {\n if (typeof localStorage === \"undefined\") return;\n localStorage.removeItem(this.key);\n }\n}\n","import type { TokenStorage } from \"./TokenStorage\";\n\nexport class SessionStorageTokenStorage implements TokenStorage {\n constructor(private readonly key: string) {}\n\n get(): string | null {\n if (typeof sessionStorage === \"undefined\") return null;\n return sessionStorage.getItem(this.key);\n }\n\n set(token: string): void {\n if (typeof sessionStorage === \"undefined\") return;\n sessionStorage.setItem(this.key, token);\n }\n\n remove(): void {\n if (typeof sessionStorage === \"undefined\") return;\n sessionStorage.removeItem(this.key);\n }\n}\n","import type { AxiosError } from \"axios\";\nimport type { ApiErrorResponse } from \"../../contracts/api\";\n\nexport class HttpError extends Error {\n readonly status: number | null;\n readonly errors: Record<string, string[]> | undefined;\n readonly response: unknown;\n\n constructor(\n message: string,\n status: number | null,\n errors?: Record<string, string[]>,\n response?: unknown,\n ) {\n super(message);\n this.name = \"HttpError\";\n this.status = status;\n this.errors = errors;\n this.response = response;\n }\n\n static fromAxiosError(error: AxiosError<ApiErrorResponse>): HttpError {\n const status = error.response?.status ?? null;\n const data = error.response?.data;\n\n const message =\n (typeof data === \"object\" && data && \"message\" in data\n ? data.message\n : undefined) ?? error.message ?? \"Unexpected HTTP error.\";\n\n const errors =\n typeof data === \"object\" && data && \"errors\" in data\n ? data.errors\n : undefined;\n\n return new HttpError(message, status, errors, error.response);\n }\n}\n","import type { AxiosError, AxiosInstance } from \"axios\";\nimport type { HttpHandlers } from \"../../../contracts/http\";\nimport type { ApiErrorResponse } from \"../../../contracts/api\";\nimport { HttpError } from \"../HttpError\";\n\nexport function registerResponseInterceptor(\n client: AxiosInstance,\n handlers?: HttpHandlers,\n): void {\n client.interceptors.response.use(\n (response) => response,\n (error: AxiosError<ApiErrorResponse>) => {\n const httpError = HttpError.fromAxiosError(error);\n\n if (httpError.status === 401) {\n handlers?.onUnauthorized?.();\n }\n\n return Promise.reject(httpError);\n },\n );\n}\n","import { HttpClient } from \"../core/http/HttpClient\";\nimport type { HttpClientConfig } from \"../core/http/HttpClientConfig\";\nimport type { VueKitConfig } from \"./VueKitConfig\";\n\nexport interface VueKit {\n http: HttpClient;\n config: VueKitConfig;\n}\n\nexport function createVueKit(config: VueKitConfig): VueKit {\n const httpConfig: HttpClientConfig = { baseURL: config.api.baseURL };\n\n if (config.api.timeout !== undefined) httpConfig.timeout = config.api.timeout;\n if (config.api.auth !== undefined) httpConfig.auth = config.api.auth;\n if (config.api.handlers !== undefined) httpConfig.handlers = config.api.handlers;\n\n const http = new HttpClient(httpConfig);\n\n return { http, config };\n}\n","import type { AxiosResponse } from \"axios\";\nimport type { HttpClient } from \"../http/HttpClient\";\nimport type { ApiParams } from \"../../contracts/api\";\n\n/**\n * Base class for all application services.\n * Services that extend BaseService never import Axios directly.\n */\nexport class BaseService {\n constructor(protected readonly http: HttpClient) {}\n\n protected get<T>(\n url: string,\n params?: ApiParams,\n ): Promise<AxiosResponse<T>> {\n return this.http.instance().get<T>(url, { params });\n }\n\n protected post<T>(\n url: string,\n data?: unknown,\n params?: ApiParams,\n ): Promise<AxiosResponse<T>> {\n return this.http.instance().post<T>(url, data, { params });\n }\n\n protected put<T>(\n url: string,\n data?: unknown,\n params?: ApiParams,\n ): Promise<AxiosResponse<T>> {\n return this.http.instance().put<T>(url, data, { params });\n }\n\n protected patch<T>(\n url: string,\n data?: unknown,\n params?: ApiParams,\n ): Promise<AxiosResponse<T>> {\n return this.http.instance().patch<T>(url, data, { params });\n }\n\n protected delete<T>(\n url: string,\n params?: ApiParams,\n ): Promise<AxiosResponse<T>> {\n return this.http.instance().delete<T>(url, { params });\n }\n}\n","import type { HttpClient } from \"../http/HttpClient\";\nimport type {\n ApiResource,\n ApiPaginatedCollection,\n ApiParams,\n} from \"../../contracts/api\";\nimport type { PaginationParams } from \"../../contracts/pagination\";\nimport { BaseService } from \"./BaseService\";\n\n/**\n * Generic CRUD service for resources exposed by a Laravel REST API.\n *\n * @example\n * class CustomerService extends CrudService<Customer> {\n * constructor(http: HttpClient) {\n * super(http, '/customers')\n * }\n * }\n */\nexport class CrudService<T> extends BaseService {\n constructor(\n http: HttpClient,\n protected readonly resourcePath: string,\n ) {\n super(http);\n }\n\n /** GET /resource — paginated list */\n async index(\n params?: PaginationParams & ApiParams,\n ): Promise<ApiPaginatedCollection<T>> {\n const response = await this.get<ApiPaginatedCollection<T>>(\n this.resourcePath,\n params,\n );\n return response.data;\n }\n\n /** GET /resource/:id */\n async show(id: string | number, params?: ApiParams): Promise<ApiResource<T>> {\n const response = await this.get<ApiResource<T>>(\n `${this.resourcePath}/${id}`,\n params,\n );\n return response.data;\n }\n\n /** POST /resource */\n async store(data: unknown): Promise<ApiResource<T>> {\n const response = await this.post<ApiResource<T>>(this.resourcePath, data);\n return response.data;\n }\n\n /** PUT /resource/:id */\n async update(id: string | number, data: unknown): Promise<ApiResource<T>> {\n const response = await this.put<ApiResource<T>>(\n `${this.resourcePath}/${id}`,\n data,\n );\n return response.data;\n }\n\n /** DELETE /resource/:id */\n async destroy(id: string | number): Promise<void> {\n await this.delete(`${this.resourcePath}/${id}`);\n }\n}\n","import { defineStore } from \"pinia\";\nimport { ref } from \"vue\";\nimport type { CrudService } from \"../services/CrudService\";\nimport type { ApiParams } from \"../../contracts/api\";\nimport type { PaginationParams } from \"../../contracts/pagination\";\nimport { Pagination } from \"../pagination/Pagination\";\nimport { HttpError } from \"../http/HttpError\";\n\n/**\n * Factory that creates a fully-typed Pinia Composition-API store for CRUD operations.\n *\n * @example\n * export const useCustomerStore = defineCrudStore('customer', () => customerService)\n */\nexport function defineCrudStore<T extends { uuid: string }>(\n id: string,\n serviceFactory: () => CrudService<T>,\n) {\n return defineStore(id, () => {\n const service = serviceFactory();\n\n const items = ref<T[]>([]) as import(\"vue\").Ref<T[]>;\n const item = ref<T | null>(null) as import(\"vue\").Ref<T | null>;\n const loading = ref(false);\n const saving = ref(false);\n const deleting = ref(false);\n const error = ref<string | null>(null);\n const pagination = ref<Pagination | null>(null);\n\n function setError(err: unknown): void {\n if (err instanceof HttpError) {\n error.value = err.message;\n } else if (err instanceof Error) {\n error.value = err.message;\n } else {\n error.value = \"An unexpected error occurred.\";\n }\n }\n\n async function fetchAll(\n params?: PaginationParams & ApiParams,\n ): Promise<void> {\n loading.value = true;\n error.value = null;\n\n try {\n const result = await service.index(params);\n items.value = result.data;\n pagination.value = new Pagination(result.meta, result.links);\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n loading.value = false;\n }\n }\n\n async function fetchOne(id: string | number): Promise<void> {\n loading.value = true;\n error.value = null;\n\n try {\n const result = await service.show(id);\n item.value = result.data;\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n loading.value = false;\n }\n }\n\n async function create(data: unknown): Promise<T> {\n saving.value = true;\n error.value = null;\n\n try {\n const result = await service.store(data);\n return result.data;\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n saving.value = false;\n }\n }\n\n async function update(id: string | number, data: unknown): Promise<T> {\n saving.value = true;\n error.value = null;\n\n try {\n const result = await service.update(id, data);\n return result.data;\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n saving.value = false;\n }\n }\n\n async function remove(id: string | number): Promise<void> {\n deleting.value = true;\n error.value = null;\n\n try {\n await service.destroy(id);\n items.value = items.value.filter((i) => i.uuid !== id);\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n deleting.value = false;\n }\n }\n\n function $reset(): void {\n items.value = [];\n item.value = null;\n loading.value = false;\n saving.value = false;\n deleting.value = false;\n error.value = null;\n pagination.value = null;\n }\n\n return {\n items,\n item,\n loading,\n saving,\n deleting,\n error,\n pagination,\n fetchAll,\n fetchOne,\n create,\n update,\n remove,\n $reset,\n };\n });\n}\n","import type { PaginationMeta, PaginationLinks } from \"../../contracts/pagination\";\n\n/**\n * Immutable value-object that wraps Laravel pagination meta + links\n * and exposes derived helpers.\n */\nexport class Pagination {\n readonly meta: PaginationMeta;\n readonly links: PaginationLinks;\n\n constructor(meta: PaginationMeta, links: PaginationLinks) {\n this.meta = meta;\n this.links = links;\n }\n\n get currentPage(): number {\n return this.meta.current_page;\n }\n\n get lastPage(): number {\n return this.meta.last_page;\n }\n\n get perPage(): number {\n return this.meta.per_page;\n }\n\n get total(): number {\n return this.meta.total;\n }\n\n get from(): number | null {\n return this.meta.from;\n }\n\n get to(): number | null {\n return this.meta.to;\n }\n\n get isFirstPage(): boolean {\n return this.meta.current_page === 1;\n }\n\n get isLastPage(): boolean {\n return this.meta.current_page === this.meta.last_page;\n }\n\n get hasPrevPage(): boolean {\n return this.links.prev !== null;\n }\n\n get hasNextPage(): boolean {\n return this.links.next !== null;\n }\n\n /** Total number of pages. */\n get pageCount(): number {\n return this.meta.last_page;\n }\n\n /** Array of page numbers for rendering a paginator UI. */\n pages(): number[] {\n return Array.from({ length: this.meta.last_page }, (_, i) => i + 1);\n }\n\n /** Build the next page params or null if on last page. */\n nextPageParams(): { page: number } | null {\n if (this.isLastPage) return null;\n return { page: this.meta.current_page + 1 };\n }\n\n /** Build the prev page params or null if on first page. */\n prevPageParams(): { page: number } | null {\n if (this.isFirstPage) return null;\n return { page: this.meta.current_page - 1 };\n }\n}\n","import { HttpError } from \"../http/HttpError\";\n\ntype FormErrors<T extends object> = Partial<Record<keyof T, string>>;\n\ntype SubmitCallback<T extends object> = (data: T) => Promise<unknown>;\n\n/**\n * Generic form abstraction with error handling compatible with Laravel 422 responses.\n *\n * @example\n * const form = new Form({ name: '', email: '' })\n * await form.submit(() => service.store(form.data))\n * if (form.errors.name) { ... }\n */\nexport class Form<T extends object> {\n data: T;\n errors: FormErrors<T> = {};\n processing = false;\n success = false;\n\n private readonly _initial: T;\n\n constructor(initialData: T) {\n this._initial = { ...initialData };\n this.data = { ...initialData };\n }\n\n async submit(callback: SubmitCallback<T>): Promise<void> {\n this.processing = true;\n this.success = false;\n this.clearErrors();\n\n try {\n await callback(this.data);\n this.success = true;\n } catch (error) {\n if (error instanceof HttpError && error.status === 422 && error.errors) {\n this.setErrors(error.errors as Record<keyof T, string[]>);\n } else {\n throw error;\n }\n } finally {\n this.processing = false;\n }\n }\n\n reset(): void {\n this.data = { ...this._initial };\n this.clearErrors();\n this.success = false;\n this.processing = false;\n }\n\n resetField(field: keyof T): void {\n (this.data as Record<keyof T, unknown>)[field] = (\n this._initial as Record<keyof T, unknown>\n )[field];\n this.clearError(field);\n }\n\n clearErrors(): void {\n this.errors = {};\n }\n\n clearError(field: keyof T): void {\n const updated = { ...this.errors };\n delete updated[field];\n this.errors = updated;\n }\n\n /**\n * Accepts Laravel-style error bags: `{ field: ['msg1', 'msg2'] }`.\n * Only the first message per field is stored.\n */\n setErrors(errors: Record<string, string[]>): void {\n const mapped: FormErrors<T> = {};\n\n for (const [field, messages] of Object.entries(errors)) {\n const key = field as keyof T;\n const first = messages[0];\n if (first !== undefined) {\n mapped[key] = first;\n }\n }\n\n this.errors = mapped;\n }\n\n /** True when the form has any validation error. */\n get hasErrors(): boolean {\n return Object.keys(this.errors).length > 0;\n }\n}\n"],"mappings":"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","names":["axios","id"]}
package/dist/index.js ADDED
@@ -0,0 +1,510 @@
1
+ // src/core/http/HttpClient.ts
2
+ import axios from "axios";
3
+
4
+ // src/core/http/auth/JwtAuthDriver.ts
5
+ var JwtAuthDriver = class {
6
+ constructor(storage) {
7
+ this.storage = storage;
8
+ }
9
+ storage;
10
+ configure(client) {
11
+ client.interceptors.request.use((config) => {
12
+ const token = this.storage.get();
13
+ if (token) {
14
+ config.headers.Authorization = `Bearer ${token}`;
15
+ }
16
+ return config;
17
+ });
18
+ }
19
+ clear() {
20
+ this.storage.remove();
21
+ }
22
+ };
23
+
24
+ // src/core/http/auth/CookieAuthDriver.ts
25
+ var MUTATING_METHODS = /* @__PURE__ */ new Set(["post", "put", "patch", "delete"]);
26
+ var CookieAuthDriver = class {
27
+ constructor(csrf) {
28
+ this.csrf = csrf;
29
+ }
30
+ csrf;
31
+ csrfInitialization = null;
32
+ configure(client) {
33
+ client.defaults.withCredentials = true;
34
+ client.defaults.withXSRFToken = true;
35
+ client.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
36
+ if (this.csrf?.enabled) {
37
+ client.interceptors.request.use(async (config) => {
38
+ const method = config.method?.toLowerCase();
39
+ if (method && MUTATING_METHODS.has(method)) {
40
+ await this.ensureCsrfCookie(client);
41
+ }
42
+ return config;
43
+ });
44
+ }
45
+ }
46
+ clear() {
47
+ this.csrfInitialization = null;
48
+ }
49
+ ensureCsrfCookie(client) {
50
+ if (!this.csrfInitialization) {
51
+ const endpoint = this.csrf?.endpoint ?? "/sanctum/csrf-cookie";
52
+ this.csrfInitialization = client.get(endpoint).then(() => void 0);
53
+ }
54
+ return this.csrfInitialization;
55
+ }
56
+ };
57
+
58
+ // src/core/http/auth/LocalStorageTokenStorage.ts
59
+ var LocalStorageTokenStorage = class {
60
+ constructor(key) {
61
+ this.key = key;
62
+ }
63
+ key;
64
+ get() {
65
+ if (typeof localStorage === "undefined") return null;
66
+ return localStorage.getItem(this.key);
67
+ }
68
+ set(token) {
69
+ if (typeof localStorage === "undefined") return;
70
+ localStorage.setItem(this.key, token);
71
+ }
72
+ remove() {
73
+ if (typeof localStorage === "undefined") return;
74
+ localStorage.removeItem(this.key);
75
+ }
76
+ };
77
+
78
+ // src/core/http/auth/SessionStorageTokenStorage.ts
79
+ var SessionStorageTokenStorage = class {
80
+ constructor(key) {
81
+ this.key = key;
82
+ }
83
+ key;
84
+ get() {
85
+ if (typeof sessionStorage === "undefined") return null;
86
+ return sessionStorage.getItem(this.key);
87
+ }
88
+ set(token) {
89
+ if (typeof sessionStorage === "undefined") return;
90
+ sessionStorage.setItem(this.key, token);
91
+ }
92
+ remove() {
93
+ if (typeof sessionStorage === "undefined") return;
94
+ sessionStorage.removeItem(this.key);
95
+ }
96
+ };
97
+
98
+ // src/core/http/HttpError.ts
99
+ var HttpError = class _HttpError extends Error {
100
+ status;
101
+ errors;
102
+ response;
103
+ constructor(message, status, errors, response) {
104
+ super(message);
105
+ this.name = "HttpError";
106
+ this.status = status;
107
+ this.errors = errors;
108
+ this.response = response;
109
+ }
110
+ static fromAxiosError(error) {
111
+ const status = error.response?.status ?? null;
112
+ const data = error.response?.data;
113
+ const message = (typeof data === "object" && data && "message" in data ? data.message : void 0) ?? error.message ?? "Unexpected HTTP error.";
114
+ const errors = typeof data === "object" && data && "errors" in data ? data.errors : void 0;
115
+ return new _HttpError(message, status, errors, error.response);
116
+ }
117
+ };
118
+
119
+ // src/core/http/interceptors/response.interceptor.ts
120
+ function registerResponseInterceptor(client, handlers) {
121
+ client.interceptors.response.use(
122
+ (response) => response,
123
+ (error) => {
124
+ const httpError = HttpError.fromAxiosError(error);
125
+ if (httpError.status === 401) {
126
+ handlers?.onUnauthorized?.();
127
+ }
128
+ return Promise.reject(httpError);
129
+ }
130
+ );
131
+ }
132
+
133
+ // src/core/http/HttpClient.ts
134
+ var HttpClient = class {
135
+ client;
136
+ authDriver;
137
+ constructor(config) {
138
+ this.client = axios.create({
139
+ baseURL: config.baseURL,
140
+ timeout: config.timeout ?? 3e4,
141
+ headers: {
142
+ Accept: "application/json",
143
+ "Content-Type": "application/json"
144
+ }
145
+ });
146
+ this.authDriver = this.createAuthDriver(config);
147
+ this.authDriver?.configure(this.client);
148
+ registerResponseInterceptor(this.client, config.handlers);
149
+ }
150
+ createAuthDriver(config) {
151
+ const auth = config.auth;
152
+ if (!auth || auth.driver === "none") {
153
+ return void 0;
154
+ }
155
+ if (auth.driver === "cookie") {
156
+ return new CookieAuthDriver(auth.csrf);
157
+ }
158
+ if (auth.driver === "jwt") {
159
+ return new JwtAuthDriver(this.resolveTokenStorage(auth.tokenStorage));
160
+ }
161
+ return void 0;
162
+ }
163
+ resolveTokenStorage(tokenStorage) {
164
+ if (tokenStorage && "get" in tokenStorage && "set" in tokenStorage) {
165
+ return tokenStorage;
166
+ }
167
+ const key = tokenStorage?.key ?? "auth_token";
168
+ if (tokenStorage?.type === "sessionStorage") {
169
+ return new SessionStorageTokenStorage(key);
170
+ }
171
+ return new LocalStorageTokenStorage(key);
172
+ }
173
+ /** Clears whatever authentication state the configured driver holds (token, csrf, etc). */
174
+ clearAuth() {
175
+ this.authDriver?.clear();
176
+ }
177
+ instance() {
178
+ return this.client;
179
+ }
180
+ };
181
+
182
+ // src/config/createVueKit.ts
183
+ function createVueKit(config) {
184
+ const httpConfig = { baseURL: config.api.baseURL };
185
+ if (config.api.timeout !== void 0) httpConfig.timeout = config.api.timeout;
186
+ if (config.api.auth !== void 0) httpConfig.auth = config.api.auth;
187
+ if (config.api.handlers !== void 0) httpConfig.handlers = config.api.handlers;
188
+ const http = new HttpClient(httpConfig);
189
+ return { http, config };
190
+ }
191
+
192
+ // src/core/services/BaseService.ts
193
+ var BaseService = class {
194
+ constructor(http) {
195
+ this.http = http;
196
+ }
197
+ http;
198
+ get(url, params) {
199
+ return this.http.instance().get(url, { params });
200
+ }
201
+ post(url, data, params) {
202
+ return this.http.instance().post(url, data, { params });
203
+ }
204
+ put(url, data, params) {
205
+ return this.http.instance().put(url, data, { params });
206
+ }
207
+ patch(url, data, params) {
208
+ return this.http.instance().patch(url, data, { params });
209
+ }
210
+ delete(url, params) {
211
+ return this.http.instance().delete(url, { params });
212
+ }
213
+ };
214
+
215
+ // src/core/services/CrudService.ts
216
+ var CrudService = class extends BaseService {
217
+ constructor(http, resourcePath) {
218
+ super(http);
219
+ this.resourcePath = resourcePath;
220
+ }
221
+ resourcePath;
222
+ /** GET /resource — paginated list */
223
+ async index(params) {
224
+ const response = await this.get(
225
+ this.resourcePath,
226
+ params
227
+ );
228
+ return response.data;
229
+ }
230
+ /** GET /resource/:id */
231
+ async show(id, params) {
232
+ const response = await this.get(
233
+ `${this.resourcePath}/${id}`,
234
+ params
235
+ );
236
+ return response.data;
237
+ }
238
+ /** POST /resource */
239
+ async store(data) {
240
+ const response = await this.post(this.resourcePath, data);
241
+ return response.data;
242
+ }
243
+ /** PUT /resource/:id */
244
+ async update(id, data) {
245
+ const response = await this.put(
246
+ `${this.resourcePath}/${id}`,
247
+ data
248
+ );
249
+ return response.data;
250
+ }
251
+ /** DELETE /resource/:id */
252
+ async destroy(id) {
253
+ await this.delete(`${this.resourcePath}/${id}`);
254
+ }
255
+ };
256
+
257
+ // src/core/stores/CrudStore.ts
258
+ import { defineStore } from "pinia";
259
+ import { ref } from "vue";
260
+
261
+ // src/core/pagination/Pagination.ts
262
+ var Pagination = class {
263
+ meta;
264
+ links;
265
+ constructor(meta, links) {
266
+ this.meta = meta;
267
+ this.links = links;
268
+ }
269
+ get currentPage() {
270
+ return this.meta.current_page;
271
+ }
272
+ get lastPage() {
273
+ return this.meta.last_page;
274
+ }
275
+ get perPage() {
276
+ return this.meta.per_page;
277
+ }
278
+ get total() {
279
+ return this.meta.total;
280
+ }
281
+ get from() {
282
+ return this.meta.from;
283
+ }
284
+ get to() {
285
+ return this.meta.to;
286
+ }
287
+ get isFirstPage() {
288
+ return this.meta.current_page === 1;
289
+ }
290
+ get isLastPage() {
291
+ return this.meta.current_page === this.meta.last_page;
292
+ }
293
+ get hasPrevPage() {
294
+ return this.links.prev !== null;
295
+ }
296
+ get hasNextPage() {
297
+ return this.links.next !== null;
298
+ }
299
+ /** Total number of pages. */
300
+ get pageCount() {
301
+ return this.meta.last_page;
302
+ }
303
+ /** Array of page numbers for rendering a paginator UI. */
304
+ pages() {
305
+ return Array.from({ length: this.meta.last_page }, (_, i) => i + 1);
306
+ }
307
+ /** Build the next page params or null if on last page. */
308
+ nextPageParams() {
309
+ if (this.isLastPage) return null;
310
+ return { page: this.meta.current_page + 1 };
311
+ }
312
+ /** Build the prev page params or null if on first page. */
313
+ prevPageParams() {
314
+ if (this.isFirstPage) return null;
315
+ return { page: this.meta.current_page - 1 };
316
+ }
317
+ };
318
+
319
+ // src/core/stores/CrudStore.ts
320
+ function defineCrudStore(id, serviceFactory) {
321
+ return defineStore(id, () => {
322
+ const service = serviceFactory();
323
+ const items = ref([]);
324
+ const item = ref(null);
325
+ const loading = ref(false);
326
+ const saving = ref(false);
327
+ const deleting = ref(false);
328
+ const error = ref(null);
329
+ const pagination = ref(null);
330
+ function setError(err) {
331
+ if (err instanceof HttpError) {
332
+ error.value = err.message;
333
+ } else if (err instanceof Error) {
334
+ error.value = err.message;
335
+ } else {
336
+ error.value = "An unexpected error occurred.";
337
+ }
338
+ }
339
+ async function fetchAll(params) {
340
+ loading.value = true;
341
+ error.value = null;
342
+ try {
343
+ const result = await service.index(params);
344
+ items.value = result.data;
345
+ pagination.value = new Pagination(result.meta, result.links);
346
+ } catch (err) {
347
+ setError(err);
348
+ throw err;
349
+ } finally {
350
+ loading.value = false;
351
+ }
352
+ }
353
+ async function fetchOne(id2) {
354
+ loading.value = true;
355
+ error.value = null;
356
+ try {
357
+ const result = await service.show(id2);
358
+ item.value = result.data;
359
+ } catch (err) {
360
+ setError(err);
361
+ throw err;
362
+ } finally {
363
+ loading.value = false;
364
+ }
365
+ }
366
+ async function create(data) {
367
+ saving.value = true;
368
+ error.value = null;
369
+ try {
370
+ const result = await service.store(data);
371
+ return result.data;
372
+ } catch (err) {
373
+ setError(err);
374
+ throw err;
375
+ } finally {
376
+ saving.value = false;
377
+ }
378
+ }
379
+ async function update(id2, data) {
380
+ saving.value = true;
381
+ error.value = null;
382
+ try {
383
+ const result = await service.update(id2, data);
384
+ return result.data;
385
+ } catch (err) {
386
+ setError(err);
387
+ throw err;
388
+ } finally {
389
+ saving.value = false;
390
+ }
391
+ }
392
+ async function remove(id2) {
393
+ deleting.value = true;
394
+ error.value = null;
395
+ try {
396
+ await service.destroy(id2);
397
+ items.value = items.value.filter((i) => i.uuid !== id2);
398
+ } catch (err) {
399
+ setError(err);
400
+ throw err;
401
+ } finally {
402
+ deleting.value = false;
403
+ }
404
+ }
405
+ function $reset() {
406
+ items.value = [];
407
+ item.value = null;
408
+ loading.value = false;
409
+ saving.value = false;
410
+ deleting.value = false;
411
+ error.value = null;
412
+ pagination.value = null;
413
+ }
414
+ return {
415
+ items,
416
+ item,
417
+ loading,
418
+ saving,
419
+ deleting,
420
+ error,
421
+ pagination,
422
+ fetchAll,
423
+ fetchOne,
424
+ create,
425
+ update,
426
+ remove,
427
+ $reset
428
+ };
429
+ });
430
+ }
431
+
432
+ // src/core/forms/Form.ts
433
+ var Form = class {
434
+ data;
435
+ errors = {};
436
+ processing = false;
437
+ success = false;
438
+ _initial;
439
+ constructor(initialData) {
440
+ this._initial = { ...initialData };
441
+ this.data = { ...initialData };
442
+ }
443
+ async submit(callback) {
444
+ this.processing = true;
445
+ this.success = false;
446
+ this.clearErrors();
447
+ try {
448
+ await callback(this.data);
449
+ this.success = true;
450
+ } catch (error) {
451
+ if (error instanceof HttpError && error.status === 422 && error.errors) {
452
+ this.setErrors(error.errors);
453
+ } else {
454
+ throw error;
455
+ }
456
+ } finally {
457
+ this.processing = false;
458
+ }
459
+ }
460
+ reset() {
461
+ this.data = { ...this._initial };
462
+ this.clearErrors();
463
+ this.success = false;
464
+ this.processing = false;
465
+ }
466
+ resetField(field) {
467
+ this.data[field] = this._initial[field];
468
+ this.clearError(field);
469
+ }
470
+ clearErrors() {
471
+ this.errors = {};
472
+ }
473
+ clearError(field) {
474
+ const updated = { ...this.errors };
475
+ delete updated[field];
476
+ this.errors = updated;
477
+ }
478
+ /**
479
+ * Accepts Laravel-style error bags: `{ field: ['msg1', 'msg2'] }`.
480
+ * Only the first message per field is stored.
481
+ */
482
+ setErrors(errors) {
483
+ const mapped = {};
484
+ for (const [field, messages] of Object.entries(errors)) {
485
+ const key = field;
486
+ const first = messages[0];
487
+ if (first !== void 0) {
488
+ mapped[key] = first;
489
+ }
490
+ }
491
+ this.errors = mapped;
492
+ }
493
+ /** True when the form has any validation error. */
494
+ get hasErrors() {
495
+ return Object.keys(this.errors).length > 0;
496
+ }
497
+ };
498
+ export {
499
+ BaseService,
500
+ CrudService,
501
+ Form,
502
+ HttpClient,
503
+ HttpError,
504
+ LocalStorageTokenStorage,
505
+ Pagination,
506
+ SessionStorageTokenStorage,
507
+ createVueKit,
508
+ defineCrudStore
509
+ };
510
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/http/HttpClient.ts","../src/core/http/auth/JwtAuthDriver.ts","../src/core/http/auth/CookieAuthDriver.ts","../src/core/http/auth/LocalStorageTokenStorage.ts","../src/core/http/auth/SessionStorageTokenStorage.ts","../src/core/http/HttpError.ts","../src/core/http/interceptors/response.interceptor.ts","../src/config/createVueKit.ts","../src/core/services/BaseService.ts","../src/core/services/CrudService.ts","../src/core/stores/CrudStore.ts","../src/core/pagination/Pagination.ts","../src/core/forms/Form.ts"],"sourcesContent":["import axios, { type AxiosInstance } from \"axios\";\n\nimport type { HttpClientConfig } from \"./HttpClientConfig\";\n\nimport { JwtAuthDriver } from \"./auth/JwtAuthDriver\";\n\nimport { CookieAuthDriver } from \"./auth/CookieAuthDriver\";\n\nimport type { AuthDriver } from \"./auth/AuthDriver\";\n\nimport type { TokenStorage } from \"./auth/TokenStorage\";\n\nimport type { TokenStorageConfig } from \"../../contracts/auth\";\n\nimport { LocalStorageTokenStorage } from \"./auth/LocalStorageTokenStorage\";\n\nimport { SessionStorageTokenStorage } from \"./auth/SessionStorageTokenStorage\";\n\nimport { registerResponseInterceptor } from \"./interceptors/response.interceptor\";\n\nexport class HttpClient {\n private readonly client: AxiosInstance;\n\n private readonly authDriver: AuthDriver | undefined;\n\n constructor(config: HttpClientConfig) {\n this.client = axios.create({\n baseURL: config.baseURL,\n timeout: config.timeout ?? 30000,\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n },\n });\n\n this.authDriver = this.createAuthDriver(config);\n\n this.authDriver?.configure(this.client);\n\n registerResponseInterceptor(this.client, config.handlers);\n }\n\n private createAuthDriver(config: HttpClientConfig): AuthDriver | undefined {\n const auth = config.auth;\n\n if (!auth || auth.driver === \"none\") {\n return undefined;\n }\n\n if (auth.driver === \"cookie\") {\n return new CookieAuthDriver(auth.csrf);\n }\n\n if (auth.driver === \"jwt\") {\n return new JwtAuthDriver(this.resolveTokenStorage(auth.tokenStorage));\n }\n\n return undefined;\n }\n\n private resolveTokenStorage(\n tokenStorage: TokenStorageConfig | TokenStorage | undefined,\n ): TokenStorage {\n if (tokenStorage && \"get\" in tokenStorage && \"set\" in tokenStorage) {\n return tokenStorage;\n }\n\n const key = tokenStorage?.key ?? \"auth_token\";\n\n if (tokenStorage?.type === \"sessionStorage\") {\n return new SessionStorageTokenStorage(key);\n }\n\n return new LocalStorageTokenStorage(key);\n }\n\n /** Clears whatever authentication state the configured driver holds (token, csrf, etc). */\n clearAuth(): void {\n this.authDriver?.clear();\n }\n\n instance(): AxiosInstance {\n return this.client;\n }\n}\n","import type { AxiosInstance } from \"axios\";\nimport type { AuthDriver } from \"./AuthDriver\";\nimport type { TokenStorage } from \"./TokenStorage\";\n\nexport class JwtAuthDriver implements AuthDriver {\n constructor(private readonly storage: TokenStorage) {}\n\n configure(client: AxiosInstance): void {\n client.interceptors.request.use((config) => {\n const token = this.storage.get();\n\n if (token) {\n config.headers.Authorization = `Bearer ${token}`;\n }\n\n return config;\n });\n }\n\n clear(): void {\n this.storage.remove();\n }\n}\n","import type { AxiosInstance } from \"axios\";\nimport type { AuthDriver } from \"./AuthDriver\";\nimport type { CsrfConfig } from \"../../../contracts/auth\";\n\nconst MUTATING_METHODS = new Set([\"post\", \"put\", \"patch\", \"delete\"]);\n\nexport class CookieAuthDriver implements AuthDriver {\n private csrfInitialization: Promise<void> | null = null;\n\n constructor(private readonly csrf?: CsrfConfig) {}\n\n configure(client: AxiosInstance): void {\n client.defaults.withCredentials = true;\n client.defaults.withXSRFToken = true;\n client.defaults.headers.common[\"X-Requested-With\"] = \"XMLHttpRequest\";\n\n if (this.csrf?.enabled) {\n client.interceptors.request.use(async (config) => {\n const method = config.method?.toLowerCase();\n\n if (method && MUTATING_METHODS.has(method)) {\n await this.ensureCsrfCookie(client);\n }\n\n return config;\n });\n }\n }\n\n clear(): void {\n this.csrfInitialization = null;\n }\n\n private ensureCsrfCookie(client: AxiosInstance): Promise<void> {\n if (!this.csrfInitialization) {\n const endpoint = this.csrf?.endpoint ?? \"/sanctum/csrf-cookie\";\n this.csrfInitialization = client.get(endpoint).then(() => undefined);\n }\n\n return this.csrfInitialization;\n }\n}\n","import type { TokenStorage } from \"./TokenStorage\";\n\nexport class LocalStorageTokenStorage implements TokenStorage {\n constructor(private readonly key: string) {}\n\n get(): string | null {\n if (typeof localStorage === \"undefined\") return null;\n return localStorage.getItem(this.key);\n }\n\n set(token: string): void {\n if (typeof localStorage === \"undefined\") return;\n localStorage.setItem(this.key, token);\n }\n\n remove(): void {\n if (typeof localStorage === \"undefined\") return;\n localStorage.removeItem(this.key);\n }\n}\n","import type { TokenStorage } from \"./TokenStorage\";\n\nexport class SessionStorageTokenStorage implements TokenStorage {\n constructor(private readonly key: string) {}\n\n get(): string | null {\n if (typeof sessionStorage === \"undefined\") return null;\n return sessionStorage.getItem(this.key);\n }\n\n set(token: string): void {\n if (typeof sessionStorage === \"undefined\") return;\n sessionStorage.setItem(this.key, token);\n }\n\n remove(): void {\n if (typeof sessionStorage === \"undefined\") return;\n sessionStorage.removeItem(this.key);\n }\n}\n","import type { AxiosError } from \"axios\";\nimport type { ApiErrorResponse } from \"../../contracts/api\";\n\nexport class HttpError extends Error {\n readonly status: number | null;\n readonly errors: Record<string, string[]> | undefined;\n readonly response: unknown;\n\n constructor(\n message: string,\n status: number | null,\n errors?: Record<string, string[]>,\n response?: unknown,\n ) {\n super(message);\n this.name = \"HttpError\";\n this.status = status;\n this.errors = errors;\n this.response = response;\n }\n\n static fromAxiosError(error: AxiosError<ApiErrorResponse>): HttpError {\n const status = error.response?.status ?? null;\n const data = error.response?.data;\n\n const message =\n (typeof data === \"object\" && data && \"message\" in data\n ? data.message\n : undefined) ?? error.message ?? \"Unexpected HTTP error.\";\n\n const errors =\n typeof data === \"object\" && data && \"errors\" in data\n ? data.errors\n : undefined;\n\n return new HttpError(message, status, errors, error.response);\n }\n}\n","import type { AxiosError, AxiosInstance } from \"axios\";\nimport type { HttpHandlers } from \"../../../contracts/http\";\nimport type { ApiErrorResponse } from \"../../../contracts/api\";\nimport { HttpError } from \"../HttpError\";\n\nexport function registerResponseInterceptor(\n client: AxiosInstance,\n handlers?: HttpHandlers,\n): void {\n client.interceptors.response.use(\n (response) => response,\n (error: AxiosError<ApiErrorResponse>) => {\n const httpError = HttpError.fromAxiosError(error);\n\n if (httpError.status === 401) {\n handlers?.onUnauthorized?.();\n }\n\n return Promise.reject(httpError);\n },\n );\n}\n","import { HttpClient } from \"../core/http/HttpClient\";\nimport type { HttpClientConfig } from \"../core/http/HttpClientConfig\";\nimport type { VueKitConfig } from \"./VueKitConfig\";\n\nexport interface VueKit {\n http: HttpClient;\n config: VueKitConfig;\n}\n\nexport function createVueKit(config: VueKitConfig): VueKit {\n const httpConfig: HttpClientConfig = { baseURL: config.api.baseURL };\n\n if (config.api.timeout !== undefined) httpConfig.timeout = config.api.timeout;\n if (config.api.auth !== undefined) httpConfig.auth = config.api.auth;\n if (config.api.handlers !== undefined) httpConfig.handlers = config.api.handlers;\n\n const http = new HttpClient(httpConfig);\n\n return { http, config };\n}\n","import type { AxiosResponse } from \"axios\";\nimport type { HttpClient } from \"../http/HttpClient\";\nimport type { ApiParams } from \"../../contracts/api\";\n\n/**\n * Base class for all application services.\n * Services that extend BaseService never import Axios directly.\n */\nexport class BaseService {\n constructor(protected readonly http: HttpClient) {}\n\n protected get<T>(\n url: string,\n params?: ApiParams,\n ): Promise<AxiosResponse<T>> {\n return this.http.instance().get<T>(url, { params });\n }\n\n protected post<T>(\n url: string,\n data?: unknown,\n params?: ApiParams,\n ): Promise<AxiosResponse<T>> {\n return this.http.instance().post<T>(url, data, { params });\n }\n\n protected put<T>(\n url: string,\n data?: unknown,\n params?: ApiParams,\n ): Promise<AxiosResponse<T>> {\n return this.http.instance().put<T>(url, data, { params });\n }\n\n protected patch<T>(\n url: string,\n data?: unknown,\n params?: ApiParams,\n ): Promise<AxiosResponse<T>> {\n return this.http.instance().patch<T>(url, data, { params });\n }\n\n protected delete<T>(\n url: string,\n params?: ApiParams,\n ): Promise<AxiosResponse<T>> {\n return this.http.instance().delete<T>(url, { params });\n }\n}\n","import type { HttpClient } from \"../http/HttpClient\";\nimport type {\n ApiResource,\n ApiPaginatedCollection,\n ApiParams,\n} from \"../../contracts/api\";\nimport type { PaginationParams } from \"../../contracts/pagination\";\nimport { BaseService } from \"./BaseService\";\n\n/**\n * Generic CRUD service for resources exposed by a Laravel REST API.\n *\n * @example\n * class CustomerService extends CrudService<Customer> {\n * constructor(http: HttpClient) {\n * super(http, '/customers')\n * }\n * }\n */\nexport class CrudService<T> extends BaseService {\n constructor(\n http: HttpClient,\n protected readonly resourcePath: string,\n ) {\n super(http);\n }\n\n /** GET /resource — paginated list */\n async index(\n params?: PaginationParams & ApiParams,\n ): Promise<ApiPaginatedCollection<T>> {\n const response = await this.get<ApiPaginatedCollection<T>>(\n this.resourcePath,\n params,\n );\n return response.data;\n }\n\n /** GET /resource/:id */\n async show(id: string | number, params?: ApiParams): Promise<ApiResource<T>> {\n const response = await this.get<ApiResource<T>>(\n `${this.resourcePath}/${id}`,\n params,\n );\n return response.data;\n }\n\n /** POST /resource */\n async store(data: unknown): Promise<ApiResource<T>> {\n const response = await this.post<ApiResource<T>>(this.resourcePath, data);\n return response.data;\n }\n\n /** PUT /resource/:id */\n async update(id: string | number, data: unknown): Promise<ApiResource<T>> {\n const response = await this.put<ApiResource<T>>(\n `${this.resourcePath}/${id}`,\n data,\n );\n return response.data;\n }\n\n /** DELETE /resource/:id */\n async destroy(id: string | number): Promise<void> {\n await this.delete(`${this.resourcePath}/${id}`);\n }\n}\n","import { defineStore } from \"pinia\";\nimport { ref } from \"vue\";\nimport type { CrudService } from \"../services/CrudService\";\nimport type { ApiParams } from \"../../contracts/api\";\nimport type { PaginationParams } from \"../../contracts/pagination\";\nimport { Pagination } from \"../pagination/Pagination\";\nimport { HttpError } from \"../http/HttpError\";\n\n/**\n * Factory that creates a fully-typed Pinia Composition-API store for CRUD operations.\n *\n * @example\n * export const useCustomerStore = defineCrudStore('customer', () => customerService)\n */\nexport function defineCrudStore<T extends { uuid: string }>(\n id: string,\n serviceFactory: () => CrudService<T>,\n) {\n return defineStore(id, () => {\n const service = serviceFactory();\n\n const items = ref<T[]>([]) as import(\"vue\").Ref<T[]>;\n const item = ref<T | null>(null) as import(\"vue\").Ref<T | null>;\n const loading = ref(false);\n const saving = ref(false);\n const deleting = ref(false);\n const error = ref<string | null>(null);\n const pagination = ref<Pagination | null>(null);\n\n function setError(err: unknown): void {\n if (err instanceof HttpError) {\n error.value = err.message;\n } else if (err instanceof Error) {\n error.value = err.message;\n } else {\n error.value = \"An unexpected error occurred.\";\n }\n }\n\n async function fetchAll(\n params?: PaginationParams & ApiParams,\n ): Promise<void> {\n loading.value = true;\n error.value = null;\n\n try {\n const result = await service.index(params);\n items.value = result.data;\n pagination.value = new Pagination(result.meta, result.links);\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n loading.value = false;\n }\n }\n\n async function fetchOne(id: string | number): Promise<void> {\n loading.value = true;\n error.value = null;\n\n try {\n const result = await service.show(id);\n item.value = result.data;\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n loading.value = false;\n }\n }\n\n async function create(data: unknown): Promise<T> {\n saving.value = true;\n error.value = null;\n\n try {\n const result = await service.store(data);\n return result.data;\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n saving.value = false;\n }\n }\n\n async function update(id: string | number, data: unknown): Promise<T> {\n saving.value = true;\n error.value = null;\n\n try {\n const result = await service.update(id, data);\n return result.data;\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n saving.value = false;\n }\n }\n\n async function remove(id: string | number): Promise<void> {\n deleting.value = true;\n error.value = null;\n\n try {\n await service.destroy(id);\n items.value = items.value.filter((i) => i.uuid !== id);\n } catch (err) {\n setError(err);\n throw err;\n } finally {\n deleting.value = false;\n }\n }\n\n function $reset(): void {\n items.value = [];\n item.value = null;\n loading.value = false;\n saving.value = false;\n deleting.value = false;\n error.value = null;\n pagination.value = null;\n }\n\n return {\n items,\n item,\n loading,\n saving,\n deleting,\n error,\n pagination,\n fetchAll,\n fetchOne,\n create,\n update,\n remove,\n $reset,\n };\n });\n}\n","import type { PaginationMeta, PaginationLinks } from \"../../contracts/pagination\";\n\n/**\n * Immutable value-object that wraps Laravel pagination meta + links\n * and exposes derived helpers.\n */\nexport class Pagination {\n readonly meta: PaginationMeta;\n readonly links: PaginationLinks;\n\n constructor(meta: PaginationMeta, links: PaginationLinks) {\n this.meta = meta;\n this.links = links;\n }\n\n get currentPage(): number {\n return this.meta.current_page;\n }\n\n get lastPage(): number {\n return this.meta.last_page;\n }\n\n get perPage(): number {\n return this.meta.per_page;\n }\n\n get total(): number {\n return this.meta.total;\n }\n\n get from(): number | null {\n return this.meta.from;\n }\n\n get to(): number | null {\n return this.meta.to;\n }\n\n get isFirstPage(): boolean {\n return this.meta.current_page === 1;\n }\n\n get isLastPage(): boolean {\n return this.meta.current_page === this.meta.last_page;\n }\n\n get hasPrevPage(): boolean {\n return this.links.prev !== null;\n }\n\n get hasNextPage(): boolean {\n return this.links.next !== null;\n }\n\n /** Total number of pages. */\n get pageCount(): number {\n return this.meta.last_page;\n }\n\n /** Array of page numbers for rendering a paginator UI. */\n pages(): number[] {\n return Array.from({ length: this.meta.last_page }, (_, i) => i + 1);\n }\n\n /** Build the next page params or null if on last page. */\n nextPageParams(): { page: number } | null {\n if (this.isLastPage) return null;\n return { page: this.meta.current_page + 1 };\n }\n\n /** Build the prev page params or null if on first page. */\n prevPageParams(): { page: number } | null {\n if (this.isFirstPage) return null;\n return { page: this.meta.current_page - 1 };\n }\n}\n","import { HttpError } from \"../http/HttpError\";\n\ntype FormErrors<T extends object> = Partial<Record<keyof T, string>>;\n\ntype SubmitCallback<T extends object> = (data: T) => Promise<unknown>;\n\n/**\n * Generic form abstraction with error handling compatible with Laravel 422 responses.\n *\n * @example\n * const form = new Form({ name: '', email: '' })\n * await form.submit(() => service.store(form.data))\n * if (form.errors.name) { ... }\n */\nexport class Form<T extends object> {\n data: T;\n errors: FormErrors<T> = {};\n processing = false;\n success = false;\n\n private readonly _initial: T;\n\n constructor(initialData: T) {\n this._initial = { ...initialData };\n this.data = { ...initialData };\n }\n\n async submit(callback: SubmitCallback<T>): Promise<void> {\n this.processing = true;\n this.success = false;\n this.clearErrors();\n\n try {\n await callback(this.data);\n this.success = true;\n } catch (error) {\n if (error instanceof HttpError && error.status === 422 && error.errors) {\n this.setErrors(error.errors as Record<keyof T, string[]>);\n } else {\n throw error;\n }\n } finally {\n this.processing = false;\n }\n }\n\n reset(): void {\n this.data = { ...this._initial };\n this.clearErrors();\n this.success = false;\n this.processing = false;\n }\n\n resetField(field: keyof T): void {\n (this.data as Record<keyof T, unknown>)[field] = (\n this._initial as Record<keyof T, unknown>\n )[field];\n this.clearError(field);\n }\n\n clearErrors(): void {\n this.errors = {};\n }\n\n clearError(field: keyof T): void {\n const updated = { ...this.errors };\n delete updated[field];\n this.errors = updated;\n }\n\n /**\n * Accepts Laravel-style error bags: `{ field: ['msg1', 'msg2'] }`.\n * Only the first message per field is stored.\n */\n setErrors(errors: Record<string, string[]>): void {\n const mapped: FormErrors<T> = {};\n\n for (const [field, messages] of Object.entries(errors)) {\n const key = field as keyof T;\n const first = messages[0];\n if (first !== undefined) {\n mapped[key] = first;\n }\n }\n\n this.errors = mapped;\n }\n\n /** True when the form has any validation error. */\n get hasErrors(): boolean {\n return Object.keys(this.errors).length > 0;\n }\n}\n"],"mappings":"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","names":["id"]}