@mapomodule/core 2.0.0-beta.1 → 2.0.0-beta.10

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 (76) hide show
  1. package/README.md +31 -21
  2. package/dist/index.d.mts +14 -1
  3. package/dist/index.d.ts +6 -1
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.mjs +4 -21
  6. package/dist/module.d.mts +11 -2
  7. package/dist/module.d.ts +10 -2
  8. package/dist/module.d.ts.map +1 -0
  9. package/dist/module.json +1 -1
  10. package/dist/module.mjs +73 -15
  11. package/dist/runtime/__tests__/plugins/00.fetch.real.spec.d.ts +2 -0
  12. package/dist/runtime/__tests__/plugins/00.fetch.real.spec.d.ts.map +1 -0
  13. package/dist/runtime/__tests__/plugins/00.fetch.spec.d.ts +2 -0
  14. package/dist/runtime/__tests__/plugins/00.fetch.spec.d.ts.map +1 -0
  15. package/dist/runtime/__tests__/plugins/01.init.server.spec.d.ts +2 -0
  16. package/dist/runtime/__tests__/plugins/01.init.server.spec.d.ts.map +1 -0
  17. package/dist/runtime/__tests__/utils/fetchError.spec.d.ts +2 -0
  18. package/dist/runtime/__tests__/utils/fetchError.spec.d.ts.map +1 -0
  19. package/dist/runtime/api/crud.d.ts +23 -0
  20. package/dist/runtime/api/crud.d.ts.map +1 -0
  21. package/dist/runtime/api/crud.js +80 -0
  22. package/dist/runtime/api/multipart.d.ts +15 -0
  23. package/dist/runtime/api/multipart.d.ts.map +1 -0
  24. package/dist/runtime/api/multipart.js +31 -0
  25. package/dist/runtime/auth/useCanAccessRoute.d.ts +12 -0
  26. package/dist/runtime/auth/useCanAccessRoute.d.ts.map +1 -0
  27. package/dist/runtime/auth/useCanAccessRoute.js +28 -0
  28. package/dist/runtime/auth/useMapoAuth.d.ts +28 -0
  29. package/dist/runtime/auth/useMapoAuth.d.ts.map +1 -0
  30. package/dist/runtime/auth/useMapoAuth.js +38 -0
  31. package/dist/runtime/composables/useMapo.d.ts +48 -0
  32. package/dist/runtime/composables/useMapo.d.ts.map +1 -0
  33. package/dist/runtime/composables/useMapo.js +15 -0
  34. package/dist/runtime/middleware/auth.d.ts +10 -0
  35. package/dist/runtime/middleware/auth.d.ts.map +1 -0
  36. package/dist/runtime/middleware/auth.js +15 -0
  37. package/dist/runtime/middleware/permissions.d.ts +20 -0
  38. package/dist/runtime/middleware/permissions.d.ts.map +1 -0
  39. package/dist/runtime/middleware/permissions.js +27 -0
  40. package/dist/runtime/middleware/roles.d.ts +12 -0
  41. package/dist/runtime/middleware/roles.d.ts.map +1 -0
  42. package/dist/runtime/middleware/roles.js +13 -0
  43. package/dist/runtime/page-meta.nuxt.d.ts +23 -0
  44. package/dist/runtime/plugins/00.fetch.d.ts +21 -0
  45. package/dist/runtime/plugins/00.fetch.d.ts.map +1 -0
  46. package/dist/runtime/plugins/00.fetch.js +61 -0
  47. package/dist/runtime/plugins/01.init.server.d.ts +15 -0
  48. package/dist/runtime/plugins/01.init.server.d.ts.map +1 -0
  49. package/dist/runtime/plugins/01.init.server.js +35 -0
  50. package/dist/runtime/types.d.ts +75 -0
  51. package/dist/runtime/types.d.ts.map +1 -0
  52. package/dist/runtime/types.js +10 -0
  53. package/dist/runtime/types.nuxt.d.ts +18 -0
  54. package/dist/runtime/utils/fetchError.d.ts +29 -0
  55. package/dist/runtime/utils/fetchError.d.ts.map +1 -0
  56. package/dist/runtime/utils/fetchError.js +12 -0
  57. package/dist/runtime/utils/useMapoFetch.d.ts +30 -0
  58. package/dist/runtime/utils/useMapoFetch.d.ts.map +1 -0
  59. package/dist/runtime/utils/useMapoFetch.js +8 -0
  60. package/dist/types.d.mts +10 -10
  61. package/dist/types.d.ts +13 -0
  62. package/dist/types.d.ts.map +1 -0
  63. package/package.json +8 -8
  64. package/src/index.ts +5 -0
  65. package/src/module.ts +13 -1
  66. package/src/runtime/__tests__/plugins/00.fetch.real.spec.ts +124 -0
  67. package/src/runtime/__tests__/plugins/00.fetch.spec.ts +3 -1
  68. package/src/runtime/__tests__/plugins/01.init.server.spec.ts +94 -0
  69. package/src/runtime/__tests__/utils/fetchError.spec.ts +97 -0
  70. package/src/runtime/api/crud.ts +8 -0
  71. package/src/runtime/plugins/00.fetch.ts +13 -6
  72. package/src/runtime/plugins/01.init.server.ts +10 -6
  73. package/src/runtime/types.ts +14 -0
  74. package/src/runtime/utils/fetchError.ts +50 -0
  75. package/dist/index.d.cts +0 -1
  76. package/dist/module.d.cts +0 -2
package/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # @mapomodule/core
2
2
 
3
- The service layer of Mapo. Provides the typed CRUD factory, auth composable, route middleware, the `$mapoFetch` interceptor, and the boot plugins that wire everything together.
3
+ The service layer of Mapo: an auth-aware `$fetch`, a typed CRUD repository for Django REST Framework endpoints, the auth composable, the `auth`, `permissions` and `roles` route middleware, and a server-side plugin that loads the session before any page renders.
4
4
 
5
5
  ## Installation
6
6
 
7
- In a Nuxt 4 app — typically you don't install this directly; install the meta-package [`mapomodule`](../../mapomodule/) which registers `core` together with `@mapomodule/store`. If you really want it standalone:
7
+ Apps get it through the meta-package [`mapomodule`](https://www.npmjs.com/package/mapomodule) and set its options at the top level of the `mapo` key. On its own:
8
8
 
9
9
  ```bash
10
- pnpm add @mapomodule/core
10
+ pnpm add @mapomodule/core@next
11
11
  ```
12
12
 
13
13
  ```ts
@@ -16,31 +16,41 @@ export default defineNuxtConfig({
16
16
  modules: ["@mapomodule/core"],
17
17
  mapoCore: {
18
18
  authLoginUrl: "/api/auth/login",
19
- userInfoApi: "/api/profiles/me/",
20
- logoutUrl: "/api/auth/logout",
21
- loginUrl: "/login",
22
19
  },
23
20
  });
24
21
  ```
25
22
 
26
- When installed via `mapomodule`, configure under the `mapo` key instead.
23
+ It installs `@mapomodule/store` when the app does not register it. Mapo v2 is published on the `next` dist-tag while it is in beta.
27
24
 
28
- ## What you get (auto-imported)
25
+ ## Options
29
26
 
30
- | API | Purpose |
31
- | ----------------- | --------------------------------------------------------------------------- |
32
- | `useCrud<T>(url)` | Typed CRUD repository: `list`, `get`, `create`, `update`, `patch`, `delete` |
33
- | `useMapoAuth()` | `login`, `logout`, `fetchUser` — drives the auth store |
34
- | `useMapoFetch()` | Pre-configured `$fetch` with 401/403 interceptors |
35
- | `useMapo()` | Facade exposing the above as a single object |
36
- | `auth` middleware | Route middleware: redirects unauthenticated users to `loginUrl` |
27
+ | Option | Default | Description |
28
+ | -------------- | --------------------- | ------------------------------------------------------------------------- |
29
+ | `authLoginUrl` | `"/api/auth/login"` | Endpoint called by `useMapoAuth().login()` |
30
+ | `userInfoApi` | `"/api/profiles/me/"` | Endpoint that returns the logged-in user, called server-side on page load |
31
+ | `logoutUrl` | `"/api/auth/logout"` | Endpoint called by `useMapoAuth().logout()` |
32
+ | `loginUrl` | `"/login"` | Route that the `auth` middleware and a 401 response redirect to |
37
33
 
38
- ## Dev workflow
34
+ ## What you get
39
35
 
40
- ```bash
41
- pnpm dev:core # from monorepo root — watch mode
42
- ```
36
+ Composables are auto-imported and the middleware is registered by name.
37
+
38
+ | API | Purpose |
39
+ | ------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
40
+ | `useCrud<T>(endpoint)` | Repository over a DRF endpoint: `list`, `detail`, `create`, `update`, `partialUpdate`, `delete`, `options`, `updateOrCreate`, `updateOrder` |
41
+ | `useMapoAuth()` | `login`, `logout` and `fetchUser`, kept in sync with `useAuthStore` |
42
+ | `useMapoFetch()` | `{ fetch, loading }`: the `$mapoFetch` instance and a flag that is `true` while any request is in flight |
43
+ | `useMapo()` | One object exposing `$api`, `$auth`, `$snack` and `$confirm` |
44
+ | `useCanAccessRoute(meta)` | Whether the current user passes a route's `auth`, `roles` and `permissions` checks |
45
+ | `$mapoFetch` | The `$fetch` instance behind all of the above: a 401 (except on logout) resets the session and redirects to `loginUrl`; a 403 shows a snackbar |
46
+ | `auth`, `permissions`, `roles` | Route middleware driven by `definePageMeta` (`permissions: { model }` or a list of codenames, `roles`) |
47
+
48
+ Types such as `CrudRepository` and `PaginatedResponse` come from `mapomodule/types`.
43
49
 
44
- ## Configuration
50
+ ## Documentation
45
51
 
46
- All endpoints fall back to the `MAPO_DEFAULTS` constant exported from this package. See [docs/modules/core](../../../docs/modules/core.md) for the full reference.
52
+ - [@mapomodule/core](https://lotrekagency.github.io/mapo-new/modules/core)
53
+ - [Auth & permissions](https://lotrekagency.github.io/mapo-new/howto/auth-permissions)
54
+ - [Custom backend integration](https://lotrekagency.github.io/mapo-new/howto/backend-integration)
55
+ - [Architecture & Integration Flows](https://lotrekagency.github.io/mapo-new/guide/architecture-flows)
56
+ - [Composable & Function API Reference](https://lotrekagency.github.io/mapo-new/modules/api)
package/dist/index.d.mts CHANGED
@@ -1 +1,14 @@
1
- export * from "/home/runner/work/mapo-new/mapo-new/packages/@mapomodule/core/src/index.js";
1
+ export { ApiResponse, AuthToken, CoreCookieEnum, Credentials, CrudConfig, CrudOptions, CrudRepository, ListParams, MultipartPolicy, MultipartPolicyEnum, PaginatedResponse } from '../dist/runtime/types.js';
2
+ export { MapoApiLayer, MapoFacade } from '../dist/runtime/composables/useMapo.js';
3
+ export { RoutePermissions, useCanAccessRoute } from '../dist/runtime/auth/useCanAccessRoute.js';
4
+ export { useMapoFetch } from '../dist/runtime/utils/useMapoFetch.js';
5
+ export { getErrorData, getErrorDetail, getErrorStatus } from '../dist/runtime/utils/fetchError.js';
6
+
7
+ interface MapoOptions {
8
+ authLoginUrl?: string;
9
+ userInfoApi?: string;
10
+ logoutUrl?: string;
11
+ loginUrl?: string;
12
+ }
13
+
14
+ export type { MapoOptions };
package/dist/index.d.ts CHANGED
@@ -1 +1,6 @@
1
- export * from "/home/runner/work/mapo-new/mapo-new/packages/@mapomodule/core/src/index.js";
1
+ export type * from "./module";
2
+ export { MultipartPolicyEnum, CoreCookieEnum } from "./runtime/types";
3
+ export { useCanAccessRoute } from "./runtime/auth/useCanAccessRoute";
4
+ export { useMapoFetch } from "./runtime/utils/useMapoFetch";
5
+ export { getErrorData, getErrorStatus, getErrorDetail, } from "./runtime/utils/fetchError";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,UAAU,CAAC;AAC9B,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EACL,YAAY,EACZ,cAAc,EACd,cAAc,GACf,MAAM,4BAA4B,CAAC"}
package/dist/index.mjs CHANGED
@@ -1,21 +1,4 @@
1
- import { createJiti } from "file:///home/runner/work/mapo-new/mapo-new/node_modules/.pnpm/jiti@2.6.1/node_modules/jiti/lib/jiti.mjs";
2
-
3
- const jiti = createJiti(import.meta.url, {
4
- "interopDefault": true,
5
- "alias": {
6
- "@mapomodule/core": "/home/runner/work/mapo-new/mapo-new/packages/@mapomodule/core"
7
- },
8
- "transformOptions": {
9
- "babel": {
10
- "plugins": []
11
- }
12
- }
13
- })
14
-
15
- /** @type {import("/home/runner/work/mapo-new/mapo-new/packages/@mapomodule/core/src/index.js")} */
16
- const _module = await jiti.import("/home/runner/work/mapo-new/mapo-new/packages/@mapomodule/core/src/index.ts");
17
-
18
- export const MultipartPolicyEnum = _module.MultipartPolicyEnum;
19
- export const CoreCookieEnum = _module.CoreCookieEnum;
20
- export const useCanAccessRoute = _module.useCanAccessRoute;
21
- export const useMapoFetch = _module.useMapoFetch;
1
+ export { CoreCookieEnum, MultipartPolicyEnum } from '../dist/runtime/types.js';
2
+ export { useCanAccessRoute } from '../dist/runtime/auth/useCanAccessRoute.js';
3
+ export { useMapoFetch } from '../dist/runtime/utils/useMapoFetch.js';
4
+ export { getErrorData, getErrorDetail, getErrorStatus } from '../dist/runtime/utils/fetchError.js';
package/dist/module.d.mts CHANGED
@@ -1,2 +1,11 @@
1
- export * from "/home/runner/work/mapo-new/mapo-new/packages/@mapomodule/core/src/module.js";
2
- export { default } from "/home/runner/work/mapo-new/mapo-new/packages/@mapomodule/core/src/module.js";
1
+ import { NuxtModule } from '@nuxt/schema';
2
+ import { MapoOptions } from './index.mjs';
3
+ export { ApiResponse, AuthToken, CoreCookieEnum, Credentials, CrudConfig, CrudOptions, CrudRepository, ListParams, MultipartPolicy, MultipartPolicyEnum, PaginatedResponse } from '../dist/runtime/types.js';
4
+ export { MapoApiLayer, MapoFacade } from '../dist/runtime/composables/useMapo.js';
5
+ export { RoutePermissions } from '../dist/runtime/auth/useCanAccessRoute.js';
6
+ import '../dist/runtime/utils/useMapoFetch.js';
7
+ import '../dist/runtime/utils/fetchError.js';
8
+
9
+ declare const _default: NuxtModule<MapoOptions, MapoOptions, false>;
10
+
11
+ export { MapoOptions, _default as default };
package/dist/module.d.ts CHANGED
@@ -1,2 +1,10 @@
1
- export * from "/home/runner/work/mapo-new/mapo-new/packages/@mapomodule/core/src/module.js";
2
- export { default } from "/home/runner/work/mapo-new/mapo-new/packages/@mapomodule/core/src/module.js";
1
+ import type { NuxtModule } from "@nuxt/schema";
2
+ import type { MapoOptions } from "./types";
3
+ export type { MapoOptions } from "./types";
4
+ export type { ListParams, PaginatedResponse, ApiResponse, CrudConfig, CrudOptions, CrudRepository, MultipartPolicy, Credentials, AuthToken, } from "./runtime/types";
5
+ export { MultipartPolicyEnum, CoreCookieEnum } from "./runtime/types";
6
+ export type { MapoFacade, MapoApiLayer } from "./runtime/composables/useMapo";
7
+ export type { RoutePermissions } from "./runtime/auth/useCanAccessRoute";
8
+ declare const _default: NuxtModule<MapoOptions, MapoOptions, false>;
9
+ export default _default;
10
+ //# sourceMappingURL=module.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3C,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,YAAY,EACV,UAAU,EACV,iBAAiB,EACjB,WAAW,EACX,UAAU,EACV,WAAW,EACX,cAAc,EACd,eAAe,EACf,WAAW,EACX,SAAS,GACV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC9E,YAAY,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;;AAEzE,wBAkFqC"}
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mapomodule/core",
3
3
  "configKey": "mapoCore",
4
- "version": "2.0.0-beta.1",
4
+ "version": "2.0.0-beta.10",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "unknown"
package/dist/module.mjs CHANGED
@@ -1,20 +1,78 @@
1
- import { createJiti } from "file:///home/runner/work/mapo-new/mapo-new/node_modules/.pnpm/jiti@2.6.1/node_modules/jiti/lib/jiti.mjs";
1
+ import { readFileSync } from 'node:fs';
2
+ import { defineNuxtModule, createResolver, addTypeTemplate, hasNuxtModule, installModule, addPlugin, addImports, addRouteMiddleware } from '@nuxt/kit';
3
+ export { CoreCookieEnum, MultipartPolicyEnum } from '../dist/runtime/types.js';
2
4
 
3
- const jiti = createJiti(import.meta.url, {
4
- "interopDefault": true,
5
- "alias": {
6
- "@mapomodule/core": "/home/runner/work/mapo-new/mapo-new/packages/@mapomodule/core"
5
+ const MAPO_DEFAULTS = {
6
+ authLoginUrl: "/api/auth/login",
7
+ userInfoApi: "/api/profiles/me/",
8
+ logoutUrl: "/api/auth/logout",
9
+ loginUrl: "/login"
10
+ };
11
+
12
+ const module$1 = defineNuxtModule({
13
+ meta: {
14
+ name: "@mapomodule/core",
15
+ configKey: "mapoCore"
7
16
  },
8
- "transformOptions": {
9
- "babel": {
10
- "plugins": []
17
+ defaults: MAPO_DEFAULTS,
18
+ async setup(options, nuxt) {
19
+ const resolver = createResolver(import.meta.url);
20
+ nuxt.options.build.transpile.push(resolver.resolve("./runtime"));
21
+ nuxt.options.imports.transform ??= {};
22
+ (nuxt.options.imports.transform.include ??= []).push(
23
+ /@mapomodule[\\/]core[\\/]/
24
+ );
25
+ addTypeTemplate({
26
+ filename: "types/mapo-core-page-meta.d.ts",
27
+ getContents: () => readFileSync(
28
+ resolver.resolve("./runtime/page-meta.nuxt.d.ts"),
29
+ "utf-8"
30
+ )
31
+ });
32
+ if (!hasNuxtModule("@mapomodule/store")) {
33
+ await installModule(await resolver.resolvePath("@mapomodule/store"));
11
34
  }
35
+ nuxt.options.runtimeConfig.public.mapoCore = {
36
+ ...MAPO_DEFAULTS,
37
+ ...options
38
+ };
39
+ addPlugin({ src: resolver.resolve("./runtime/plugins/00.fetch") });
40
+ addPlugin({
41
+ src: resolver.resolve("./runtime/plugins/01.init.server"),
42
+ mode: "server"
43
+ });
44
+ addImports([
45
+ { name: "useCrud", from: resolver.resolve("./runtime/api/crud") },
46
+ {
47
+ name: "useMapoAuth",
48
+ from: resolver.resolve("./runtime/auth/useMapoAuth")
49
+ },
50
+ {
51
+ name: "useMapo",
52
+ from: resolver.resolve("./runtime/composables/useMapo")
53
+ },
54
+ {
55
+ name: "useCanAccessRoute",
56
+ from: resolver.resolve("./runtime/auth/useCanAccessRoute")
57
+ },
58
+ {
59
+ name: "useMapoFetch",
60
+ from: resolver.resolve("./runtime/utils/useMapoFetch")
61
+ }
62
+ ]);
63
+ addRouteMiddleware({
64
+ name: "auth",
65
+ path: resolver.resolve("./runtime/middleware/auth")
66
+ });
67
+ addRouteMiddleware({
68
+ name: "permissions",
69
+ path: resolver.resolve("./runtime/middleware/permissions")
70
+ });
71
+ addRouteMiddleware({
72
+ name: "roles",
73
+ path: resolver.resolve("./runtime/middleware/roles")
74
+ });
12
75
  }
13
- })
14
-
15
- /** @type {import("/home/runner/work/mapo-new/mapo-new/packages/@mapomodule/core/src/module.js")} */
16
- const _module = await jiti.import("/home/runner/work/mapo-new/mapo-new/packages/@mapomodule/core/src/module.ts");
76
+ });
17
77
 
18
- export default _module?.default ?? _module;
19
- export const MultipartPolicyEnum = _module.MultipartPolicyEnum;
20
- export const CoreCookieEnum = _module.CoreCookieEnum;
78
+ export { module$1 as default };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=00.fetch.real.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"00.fetch.real.spec.d.ts","sourceRoot":"","sources":["../../../../src/runtime/__tests__/plugins/00.fetch.real.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=00.fetch.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"00.fetch.spec.d.ts","sourceRoot":"","sources":["../../../../src/runtime/__tests__/plugins/00.fetch.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=01.init.server.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"01.init.server.spec.d.ts","sourceRoot":"","sources":["../../../../src/runtime/__tests__/plugins/01.init.server.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=fetchError.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetchError.spec.d.ts","sourceRoot":"","sources":["../../../../src/runtime/__tests__/utils/fetchError.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,23 @@
1
+ import type { CrudConfig, CrudRepository } from "../types";
2
+ /**
3
+ * Creates a typed CRUD repository bound to a resource endpoint.
4
+ *
5
+ * The returned repository exposes common operations (`list`, `detail`, `create`,
6
+ * `update`, `partialUpdate`, `delete`) plus utility actions (`updateOrCreate`,
7
+ * `updateOrder`). Requests are executed through the shared Mapo fetch client.
8
+ *
9
+ * Configuration precedence:
10
+ * - `higherConf` defines repository-level default request options.
11
+ * - Per-call config arguments override repository-level defaults.
12
+ *
13
+ * Multipart handling:
14
+ * - Write methods pass payloads through `applyMultipartPolicy`, using
15
+ * `MultipartPolicyEnum.Auto` unless overridden in `CrudOptions`.
16
+ *
17
+ * @typeParam T Entity type handled by the repository.
18
+ * @param endpoint Resource endpoint (normalized to a trailing-slash base path).
19
+ * @param higherConf Optional repository-level fetch configuration defaults.
20
+ * @returns A typed `CrudRepository<T>` for the specified endpoint.
21
+ */
22
+ export declare function useCrud<T>(endpoint: string, higherConf?: CrudConfig): CrudRepository<T>;
23
+ //# sourceMappingURL=crud.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crud.d.ts","sourceRoot":"","sources":["../../../src/runtime/api/crud.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAGV,UAAU,EAEV,cAAc,EACf,MAAM,UAAU,CAAC;AAElB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,OAAO,CAAC,CAAC,EACvB,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,UAAU,GACtB,cAAc,CAAC,CAAC,CAAC,CAsGnB"}
@@ -0,0 +1,80 @@
1
+ import { normalizeEndpoint } from "@mapomodule/utils";
2
+ import { applyMultipartPolicy } from "./multipart.js";
3
+ import { useMapoFetch } from "../utils/useMapoFetch.js";
4
+ import { MultipartPolicyEnum } from "../types.js";
5
+ export function useCrud(endpoint, higherConf) {
6
+ const base = normalizeEndpoint(endpoint);
7
+ function merged(local) {
8
+ return { ...higherConf, ...local };
9
+ }
10
+ function fetch(path, options) {
11
+ return useMapoFetch().fetch(path, options);
12
+ }
13
+ return {
14
+ list(params, config) {
15
+ return fetch(base, {
16
+ method: "GET",
17
+ params,
18
+ ...merged(config)
19
+ });
20
+ },
21
+ detail(id, config) {
22
+ return fetch(`${base}${id}/`, { method: "GET", ...merged(config) });
23
+ },
24
+ create(data, config, opts = {}) {
25
+ const body = applyMultipartPolicy(
26
+ data,
27
+ opts.multipart ?? MultipartPolicyEnum.Auto
28
+ );
29
+ return fetch(base, { method: "POST", body, ...merged(config) });
30
+ },
31
+ update(id, data, config, opts = {}) {
32
+ const body = applyMultipartPolicy(
33
+ data,
34
+ opts.multipart ?? MultipartPolicyEnum.Auto
35
+ );
36
+ return fetch(`${base}${id}/`, {
37
+ method: "PUT",
38
+ body,
39
+ ...merged(config)
40
+ });
41
+ },
42
+ partialUpdate(id, diff, config, opts = {}) {
43
+ const body = applyMultipartPolicy(
44
+ diff,
45
+ opts.multipart ?? MultipartPolicyEnum.Auto
46
+ );
47
+ return fetch(`${base}${id}/`, {
48
+ method: "PATCH",
49
+ body,
50
+ ...merged(config)
51
+ });
52
+ },
53
+ delete(id, config) {
54
+ return fetch(`${base}${id}/`, {
55
+ method: "DELETE",
56
+ ...merged(config)
57
+ });
58
+ },
59
+ options(config) {
60
+ return fetch(base, {
61
+ method: "OPTIONS",
62
+ ...merged(config)
63
+ });
64
+ },
65
+ updateOrCreate(data, config, opts) {
66
+ if (data.id) {
67
+ const { id, ...rest } = data;
68
+ return this.update(id, rest, config, opts);
69
+ }
70
+ return this.create(data, config, opts);
71
+ },
72
+ updateOrder(startId, endId, config) {
73
+ return fetch(`${base}update_order/`, {
74
+ method: "POST",
75
+ body: { startId, endId },
76
+ ...merged(config)
77
+ });
78
+ }
79
+ };
80
+ }
@@ -0,0 +1,15 @@
1
+ import type { MultipartPolicy } from "../types";
2
+ /**
3
+ * Applies the configured multipart policy to a request payload.
4
+ *
5
+ * Policy behavior:
6
+ * - `Disable`: always return the original object payload.
7
+ * - `Force`: always return a `FormData` payload.
8
+ * - `Auto`: return `FormData` only when at least one `File`/`Blob` is present.
9
+ *
10
+ * @param payload Request payload object.
11
+ * @param policy Multipart transformation policy.
12
+ * @returns Either the original payload or a `FormData` instance.
13
+ */
14
+ export declare function applyMultipartPolicy(payload: Record<string, unknown>, policy: MultipartPolicy): FormData | Record<string, unknown>;
15
+ //# sourceMappingURL=multipart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multipart.d.ts","sourceRoot":"","sources":["../../../src/runtime/api/multipart.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAyDhD;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,MAAM,EAAE,eAAe,GACtB,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKpC"}
@@ -0,0 +1,31 @@
1
+ import { MultipartPolicyEnum } from "../types.js";
2
+ function collectFiles(obj, path = "") {
3
+ if (obj instanceof File || obj instanceof Blob) {
4
+ return [{ path, file: obj }];
5
+ }
6
+ if (Array.isArray(obj)) {
7
+ return obj.flatMap(
8
+ (item, i) => collectFiles(item, path ? `${path}.${i}` : String(i))
9
+ );
10
+ }
11
+ if (obj !== null && typeof obj === "object") {
12
+ return Object.entries(obj).flatMap(
13
+ ([key, val]) => collectFiles(val, path ? `${path}.${key}` : key)
14
+ );
15
+ }
16
+ return [];
17
+ }
18
+ function toFormData(obj) {
19
+ const files = collectFiles(obj);
20
+ const fd = new FormData();
21
+ fd.append("data", JSON.stringify(obj));
22
+ for (const { path, file } of files) {
23
+ fd.append(path, file);
24
+ }
25
+ return fd;
26
+ }
27
+ export function applyMultipartPolicy(payload, policy) {
28
+ if (policy === MultipartPolicyEnum.Disable) return payload;
29
+ if (policy === MultipartPolicyEnum.Force) return toFormData(payload);
30
+ return collectFiles(payload).length > 0 ? toFormData(payload) : payload;
31
+ }
@@ -0,0 +1,12 @@
1
+ import type { RouteMeta } from "vue-router";
2
+ /** Two-format permission spec: Django model shorthand or explicit codename list. */
3
+ export type RoutePermissions = {
4
+ model: string;
5
+ } | string[];
6
+ /**
7
+ * Returns whether the current user can access a route based on its meta.
8
+ * Mirrors the logic of the `auth`, `permissions`, and `roles` middlewares
9
+ * so the sidebar and any UI that gates visibility stays in sync with navigation guards.
10
+ */
11
+ export declare function useCanAccessRoute(meta: RouteMeta): boolean;
12
+ //# sourceMappingURL=useCanAccessRoute.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCanAccessRoute.d.ts","sourceRoot":"","sources":["../../../src/runtime/auth/useCanAccessRoute.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,oFAAoF;AACpF,MAAM,MAAM,gBAAgB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,EAAE,CAAC;AAE5D;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAoC1D"}
@@ -0,0 +1,28 @@
1
+ import { useAuthStore } from "@mapomodule/store/runtime/stores/auth";
2
+ export function useCanAccessRoute(meta) {
3
+ const auth = useAuthStore();
4
+ const raw = meta.middleware;
5
+ const middleware = Array.isArray(raw) ? raw : raw ? [raw] : [];
6
+ if (middleware.includes("auth") && !auth.isAuthenticated) return false;
7
+ if (middleware.includes("roles")) {
8
+ const required = meta.roles;
9
+ if (required?.length && !auth.info?.is_superuser) {
10
+ const userGroups = auth.info?.groups ?? [];
11
+ if (!required.some((r) => userGroups.includes(r))) return false;
12
+ }
13
+ }
14
+ if (middleware.includes("permissions")) {
15
+ const perms = meta.permissions;
16
+ if (perms && !auth.info?.is_superuser) {
17
+ if (Array.isArray(perms)) {
18
+ if (!perms.every((p) => auth.rawPermissions.includes(p))) return false;
19
+ } else {
20
+ const hasView = auth.rawPermissions.some(
21
+ (p) => p === `view_${perms.model}` || p.endsWith(`_${perms.model}`) && p.startsWith("view")
22
+ );
23
+ if (!hasView) return false;
24
+ }
25
+ }
26
+ }
27
+ return true;
28
+ }
@@ -0,0 +1,28 @@
1
+ import type { Credentials } from "../types";
2
+ /**
3
+ * Optional endpoint overrides for auth operations.
4
+ */
5
+ type AuthOverrides = {
6
+ /** Login endpoint used to create the server session. */
7
+ authLoginUrl?: string;
8
+ /** Endpoint used to fetch the current authenticated user profile. */
9
+ userInfoApi?: string;
10
+ /** Logout endpoint used to invalidate the server session. */
11
+ logoutUrl?: string;
12
+ };
13
+ /**
14
+ * Provides authentication helpers built on top of the shared Mapo fetch client.
15
+ *
16
+ * Endpoints are resolved from runtime config and can be selectively overridden
17
+ * through `options`.
18
+ *
19
+ * @param options Optional endpoint overrides for login, logout, and user fetch.
20
+ * @returns Auth helpers: `login`, `logout`, and `fetchUser`.
21
+ */
22
+ export declare function useMapoAuth(options?: AuthOverrides): {
23
+ login: (credentials: Credentials) => Promise<void>;
24
+ logout: () => Promise<void>;
25
+ fetchUser: () => Promise<void>;
26
+ };
27
+ export {};
28
+ //# sourceMappingURL=useMapoAuth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMapoAuth.d.ts","sourceRoot":"","sources":["../../../src/runtime/auth/useMapoAuth.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAyB,MAAM,UAAU,CAAC;AAEnE;;GAEG;AACH,KAAK,aAAa,GAAG;IACnB,wDAAwD;IACxD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,aAAa;yBA8Bf,WAAW,KAAG,OAAO,CAAC,IAAI,CAAC;kBAepC,OAAO,CAAC,IAAI,CAAC;qBA9BV,OAAO,CAAC,IAAI,CAAC;EAiD1C"}
@@ -0,0 +1,38 @@
1
+ import { useNuxtApp, navigateTo, useCookie, useRuntimeConfig } from "nuxt/app";
2
+ import { useAuthStore } from "@mapomodule/store/runtime/stores/auth";
3
+ import { CoreCookieEnum } from "../types.js";
4
+ export function useMapoAuth(options) {
5
+ const rc = useRuntimeConfig().public.mapoCore;
6
+ const authLoginUrl = options?.authLoginUrl ?? rc.authLoginUrl;
7
+ const userInfoApi = options?.userInfoApi ?? rc.userInfoApi;
8
+ const logoutUrl = options?.logoutUrl ?? rc.logoutUrl;
9
+ const loginUrl = rc.loginUrl;
10
+ const { $mapoFetch } = useNuxtApp();
11
+ const authStore = useAuthStore();
12
+ async function fetchUser() {
13
+ const user = await $mapoFetch(userInfoApi, { method: "GET" });
14
+ authStore.setUser(user);
15
+ }
16
+ async function login(credentials) {
17
+ await $mapoFetch(authLoginUrl, { method: "POST", body: credentials });
18
+ await fetchUser();
19
+ }
20
+ async function logout() {
21
+ try {
22
+ await $mapoFetch(logoutUrl, { method: "GET" });
23
+ } finally {
24
+ useCookie(CoreCookieEnum.Session).value = null;
25
+ authStore.reset();
26
+ if (typeof localStorage !== "undefined") {
27
+ const toRemove = [];
28
+ for (let i = 0; i < localStorage.length; i++) {
29
+ const k = localStorage.key(i);
30
+ if (k?.startsWith("mapo:draft:")) toRemove.push(k);
31
+ }
32
+ toRemove.forEach((k) => localStorage.removeItem(k));
33
+ }
34
+ await navigateTo(loginUrl);
35
+ }
36
+ }
37
+ return { login, logout, fetchUser };
38
+ }
@@ -0,0 +1,48 @@
1
+ import { useSnackStore } from "@mapomodule/store/runtime/stores/snack";
2
+ import { useConfirmStore } from "@mapomodule/store/runtime/stores/confirm";
3
+ import { useMapoAuth } from "../auth/useMapoAuth";
4
+ import type { MapoOptions } from "../../types";
5
+ import type { CrudRepository } from "../types";
6
+ /**
7
+ * API layer exposed by {@link useMapo}.
8
+ */
9
+ export interface MapoApiLayer {
10
+ /**
11
+ * Creates a CRUD repository bound to the provided endpoint.
12
+ *
13
+ * @param endpoint API endpoint for the resource collection.
14
+ * @returns A typed repository with list/detail/create/update/delete helpers.
15
+ */
16
+ crud<T>(endpoint: string): CrudRepository<T>;
17
+ }
18
+ /**
19
+ * High-level facade that groups the most common Mapo runtime capabilities.
20
+ *
21
+ * This keeps feature access ergonomic in components by exposing API, auth,
22
+ * feedback stores, and resolved options from a single composable call.
23
+ */
24
+ export interface MapoFacade {
25
+ /** Resource-oriented API helpers. */
26
+ $api: MapoApiLayer;
27
+ /** Authentication helpers (`login`, `logout`, `fetchUser`). */
28
+ $auth: ReturnType<typeof useMapoAuth>;
29
+ /** Global snackbar store for user feedback messages. */
30
+ $snack: ReturnType<typeof useSnackStore>;
31
+ /** Global confirm dialog store for destructive/critical actions. */
32
+ $confirm: ReturnType<typeof useConfirmStore>;
33
+ /** Effective options passed to the facade factory. */
34
+ $options: MapoOptions;
35
+ }
36
+ /**
37
+ * Creates the Mapo facade used across admin pages and composables.
38
+ *
39
+ * The facade is a convenience aggregator over lower-level composables/stores:
40
+ * - `$api.crud<T>(endpoint)` delegates to `useCrud<T>(endpoint)`.
41
+ * - `$auth` delegates to `useMapoAuth(options)` (same overrides).
42
+ * - `$snack` and `$confirm` expose the shared UI feedback stores.
43
+ *
44
+ * @param options Optional runtime overrides forwarded to the auth layer.
45
+ * @returns A `MapoFacade` with grouped API/auth/feedback capabilities.
46
+ */
47
+ export declare function useMapo(options?: MapoOptions): MapoFacade;
48
+ //# sourceMappingURL=useMapo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMapo.d.ts","sourceRoot":"","sources":["../../../src/runtime/composables/useMapo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAElD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;;OAKG;IACH,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;CAC9C;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,qCAAqC;IACrC,IAAI,EAAE,YAAY,CAAC;IACnB,+DAA+D;IAC/D,KAAK,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;IACtC,wDAAwD;IACxD,MAAM,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;IACzC,oEAAoE;IACpE,QAAQ,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;IAC7C,sDAAsD;IACtD,QAAQ,EAAE,WAAW,CAAC;CACvB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,OAAO,CAAC,OAAO,GAAE,WAAgB,GAAG,UAAU,CAU7D"}