nuxt-directus-sdk 3.1.0 → 4.0.1
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 +18 -5
- package/dist/module.d.mts +48 -49
- package/dist/module.json +12 -0
- package/dist/module.mjs +105 -27
- package/dist/runtime/components/directus-visual-editor.d.vue.ts +21 -0
- package/dist/runtime/components/directus-visual-editor.vue +37 -33
- package/dist/runtime/components/directus-visual-editor.vue.d.ts +21 -0
- package/dist/runtime/composables/auth.d.ts +2 -8
- package/dist/runtime/composables/auth.js +15 -24
- package/dist/runtime/composables/directus.d.ts +1 -1
- package/dist/runtime/composables/directus.js +39 -25
- package/dist/runtime/composables/files.d.ts +2 -3
- package/dist/runtime/composables/files.js +0 -6
- package/dist/runtime/composables/storage.d.ts +6 -0
- package/dist/runtime/composables/storage.js +11 -0
- package/dist/runtime/middleware/guest.d.ts +2 -0
- package/dist/runtime/middleware/guest.js +3 -0
- package/dist/runtime/plugin.js +7 -36
- package/dist/runtime/server/routes/directus.d.ts +2 -0
- package/dist/runtime/server/routes/directus.js +10 -0
- package/dist/runtime/server/services/directus.d.ts +3 -3
- package/dist/runtime/server/services/directus.js +6 -6
- package/dist/runtime/server/services/index.d.ts +1 -1
- package/dist/runtime/server/services/index.js +1 -1
- package/dist/runtime/types/generate.d.ts +4 -0
- package/dist/runtime/types/generate.js +125 -43
- package/dist/runtime/types/index.d.ts +1 -0
- package/dist/runtime/types/index.js +1 -0
- package/dist/runtime/types/types.d.ts +1 -0
- package/dist/types.d.mts +3 -0
- package/package.json +22 -16
- package/dist/module.cjs +0 -5
- package/dist/module.d.ts +0 -140
- package/dist/runtime/composables/tokens.d.ts +0 -9
- package/dist/runtime/composables/tokens.js +0 -55
package/README.md
CHANGED
|
@@ -5,13 +5,14 @@
|
|
|
5
5
|
[![License][license-src]][license-href]
|
|
6
6
|
[![Nuxt][nuxt-src]][nuxt-href]
|
|
7
7
|
|
|
8
|
-
> A Nuxt
|
|
8
|
+
> A Nuxt 4 Directus module that uses the Directus SDK to enhance your Nuxt application
|
|
9
9
|
|
|
10
10
|
- [✨ Release Notes](/CHANGELOG.md)
|
|
11
|
-
- [
|
|
11
|
+
- [📚 Documentation](https://nuxt-directus-sdk.rolley.io)
|
|
12
12
|
|
|
13
13
|
## Features
|
|
14
14
|
|
|
15
|
+
- 🔒 **Session-based authentication** with cross-domain support
|
|
15
16
|
- ⛰ Authentication out of the box
|
|
16
17
|
- 🚠 Type generation based on Directus collections
|
|
17
18
|
- 🔥 Typesafe Client Websockets enabled
|
|
@@ -44,17 +45,29 @@ export default defineNuxtConfig({
|
|
|
44
45
|
'nuxt-directus-sdk'
|
|
45
46
|
],
|
|
46
47
|
directus: {
|
|
47
|
-
|
|
48
|
+
// Optional: customize authentication (defaults shown)
|
|
49
|
+
auth: {
|
|
50
|
+
autoRefresh: true,
|
|
51
|
+
credentials: 'include', // Required for cross-domain
|
|
52
|
+
realtimeAuthMode: 'public',
|
|
53
|
+
}
|
|
48
54
|
}
|
|
49
55
|
})
|
|
50
56
|
```
|
|
51
57
|
|
|
52
|
-
3.
|
|
58
|
+
3. Create a `.env` file:
|
|
53
59
|
|
|
54
|
-
|
|
60
|
+
```env
|
|
61
|
+
DIRECTUS_URL=https://your-directus-url.com
|
|
62
|
+
DIRECTUS_ADMIN_TOKEN=your_admin_token # Optional: for type generation
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
4. **Configure your Directus backend** for cross-domain authentication (see [Authentication Guide](https://nuxt-directus-sdk.rolley.io/guide/authentication))
|
|
55
66
|
|
|
56
67
|
That's it! You can now use Directus within your Nuxt app ✨
|
|
57
68
|
|
|
69
|
+
For cross-domain setups (e.g., `app.example.com` ↔ `api.example.com`), see the [Authentication Guide](https://nuxt-directus-sdk.rolley.io/guide/authentication).
|
|
70
|
+
|
|
58
71
|
## Development
|
|
59
72
|
|
|
60
73
|
```bash
|
package/dist/module.d.mts
CHANGED
|
@@ -8,6 +8,25 @@ interface ModuleOptions {
|
|
|
8
8
|
* @type string
|
|
9
9
|
*/
|
|
10
10
|
url: string;
|
|
11
|
+
/**
|
|
12
|
+
* Development proxy configuration
|
|
13
|
+
* When enabled, creates a proxy at /directus that forwards to your Directus URL
|
|
14
|
+
* This solves CORS and cookie issues in development
|
|
15
|
+
* @default { enabled: true, path: '/directus' } in dev mode
|
|
16
|
+
* @type boolean | { enabled?: boolean, path?: string }
|
|
17
|
+
*/
|
|
18
|
+
devProxy?: boolean | {
|
|
19
|
+
/**
|
|
20
|
+
* Enable the development proxy
|
|
21
|
+
* @default true in dev mode, false in production
|
|
22
|
+
*/
|
|
23
|
+
enabled?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Proxy path (where the proxy will be mounted)
|
|
26
|
+
* @default '/directus'
|
|
27
|
+
*/
|
|
28
|
+
path?: string;
|
|
29
|
+
};
|
|
11
30
|
/**
|
|
12
31
|
* Admin Auth Token used for generating types and server functions
|
|
13
32
|
* @default process.env.DIRECTUS_ADMIN_TOKEN
|
|
@@ -43,56 +62,31 @@ interface ModuleOptions {
|
|
|
43
62
|
* @type boolean
|
|
44
63
|
*/
|
|
45
64
|
enableGlobalAuthMiddleware?: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* Auto refresh tokens
|
|
67
|
+
* @default true
|
|
68
|
+
* @type boolean
|
|
69
|
+
*/
|
|
70
|
+
autoRefresh?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Credentials mode for cross-domain requests
|
|
73
|
+
* Set to 'include' when your frontend and backend are on different domains
|
|
74
|
+
* @default 'include'
|
|
75
|
+
* @type RequestCredentials
|
|
76
|
+
*/
|
|
77
|
+
credentials?: RequestCredentials;
|
|
78
|
+
/**
|
|
79
|
+
* Realtime/WebSocket authentication mode
|
|
80
|
+
* @default 'handshake'
|
|
81
|
+
* @type 'public' | 'handshake' | 'strict'
|
|
82
|
+
*/
|
|
83
|
+
realtimeAuthMode?: 'public' | 'handshake' | 'strict';
|
|
46
84
|
/**
|
|
47
85
|
* ReadMe fields to fetch
|
|
48
86
|
* @default []
|
|
49
|
-
* @type Query<
|
|
87
|
+
* @type Query<DirectusSchema, DirectusSchema['directus_users']>['fields']
|
|
50
88
|
*/
|
|
51
|
-
readMeFields?: Query<
|
|
52
|
-
cookies?: {
|
|
53
|
-
/**
|
|
54
|
-
* Session token cookie name
|
|
55
|
-
* @default 'directus_access_token'
|
|
56
|
-
*/
|
|
57
|
-
accessToken?: string;
|
|
58
|
-
/**
|
|
59
|
-
* Refresh token cookie name
|
|
60
|
-
* @default 'directus_refresh_token'
|
|
61
|
-
*/
|
|
62
|
-
refreshToken?: string;
|
|
63
|
-
/**
|
|
64
|
-
* Logged in token cookie name
|
|
65
|
-
* @default 'directus_logged_in'
|
|
66
|
-
*/
|
|
67
|
-
loggedInToken?: string;
|
|
68
|
-
/**
|
|
69
|
-
* Session token cookie max age
|
|
70
|
-
* @default 900
|
|
71
|
-
*/
|
|
72
|
-
maxAge?: number;
|
|
73
|
-
/**
|
|
74
|
-
* Refresh token cookie max age
|
|
75
|
-
* @default 604800
|
|
76
|
-
*/
|
|
77
|
-
maxAgeRefreshToken?: number;
|
|
78
|
-
/**
|
|
79
|
-
* SameSite cookie attribute
|
|
80
|
-
* @default 'lax'
|
|
81
|
-
*/
|
|
82
|
-
sameSite?: 'lax' | 'strict' | 'none';
|
|
83
|
-
/**
|
|
84
|
-
* Secure cookie attribute
|
|
85
|
-
* @default false
|
|
86
|
-
* @type boolean
|
|
87
|
-
*/
|
|
88
|
-
secure?: boolean;
|
|
89
|
-
/**
|
|
90
|
-
* Domain cookie attribute
|
|
91
|
-
* @default undefined
|
|
92
|
-
* @type string | undefined
|
|
93
|
-
*/
|
|
94
|
-
domain?: string | undefined;
|
|
95
|
-
};
|
|
89
|
+
readMeFields?: Query<DirectusSchema, DirectusSchema['directus_users']>['fields'];
|
|
96
90
|
redirect?: {
|
|
97
91
|
/**
|
|
98
92
|
* Redirect to home page after login
|
|
@@ -128,13 +122,18 @@ interface ModuleOptions {
|
|
|
128
122
|
}
|
|
129
123
|
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
130
124
|
|
|
125
|
+
interface NuxtDirectusModuleOptions extends ModuleOptions {
|
|
126
|
+
directusUrl: string;
|
|
127
|
+
wsProxyUrl?: string;
|
|
128
|
+
}
|
|
131
129
|
declare module '@nuxt/schema' {
|
|
132
130
|
interface ConfigSchema {
|
|
133
|
-
directus?:
|
|
131
|
+
directus?: NuxtDirectusModuleOptions;
|
|
134
132
|
publicRuntimeConfig?: {
|
|
135
|
-
directus?: Omit<
|
|
133
|
+
directus?: Omit<NuxtDirectusModuleOptions, 'adminToken'>;
|
|
136
134
|
};
|
|
137
135
|
}
|
|
138
136
|
}
|
|
139
137
|
|
|
140
|
-
export {
|
|
138
|
+
export { _default as default };
|
|
139
|
+
export type { ModuleOptions };
|
package/dist/module.json
ADDED
package/dist/module.mjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { useLogger, defineNuxtModule, createResolver, installModule, addPlugin, addRouteMiddleware, addImportsDir, addComponentsDir, addImportsSources, addTypeTemplate } from '@nuxt/kit';
|
|
1
|
+
import { useLogger, defineNuxtModule, createResolver, addServerHandler, installModule, addPlugin, addRouteMiddleware, addImportsDir, addComponentsDir, addImportsSources, addTypeTemplate } from '@nuxt/kit';
|
|
2
2
|
import { defu } from 'defu';
|
|
3
|
+
import { joinURL } from 'ufo';
|
|
3
4
|
import { generateTypes } from '../dist/runtime/types/index.js';
|
|
4
5
|
import { useUrl } from '../dist/runtime/utils/index.js';
|
|
5
6
|
|
|
6
7
|
const name = "nuxt-directus-sdk";
|
|
7
|
-
const version = "
|
|
8
|
+
const version = "4.0.1";
|
|
8
9
|
|
|
9
10
|
const configKey = "directus";
|
|
10
11
|
const logger = useLogger("nuxt-directus-sdk");
|
|
@@ -14,12 +15,13 @@ const module = defineNuxtModule({
|
|
|
14
15
|
version,
|
|
15
16
|
configKey,
|
|
16
17
|
compatibility: {
|
|
17
|
-
nuxt: "^
|
|
18
|
-
bridge: false
|
|
18
|
+
nuxt: "^4.0.0"
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
21
|
defaults: {
|
|
22
22
|
url: import.meta.env.DIRECTUS_URL ?? "",
|
|
23
|
+
devProxy: void 0,
|
|
24
|
+
// Will be set based on dev mode in setup
|
|
23
25
|
adminToken: import.meta.env.DIRECTUS_ADMIN_TOKEN ?? "",
|
|
24
26
|
devtools: true,
|
|
25
27
|
visualEditor: true,
|
|
@@ -30,18 +32,10 @@ const module = defineNuxtModule({
|
|
|
30
32
|
auth: {
|
|
31
33
|
enabled: true,
|
|
32
34
|
enableGlobalAuthMiddleware: false,
|
|
35
|
+
autoRefresh: true,
|
|
36
|
+
credentials: "include",
|
|
37
|
+
realtimeAuthMode: "public",
|
|
33
38
|
readMeFields: [],
|
|
34
|
-
cookies: {
|
|
35
|
-
accessToken: "directus_access_token",
|
|
36
|
-
refreshToken: "directus_refresh_token",
|
|
37
|
-
loggedInToken: "directus_logged_in",
|
|
38
|
-
maxAge: 900,
|
|
39
|
-
maxAgeRefreshToken: 604800,
|
|
40
|
-
// Nuxt Cookies Docs @ https://nuxt.com/docs/api/composables/use-cookie
|
|
41
|
-
sameSite: "lax",
|
|
42
|
-
secure: false,
|
|
43
|
-
domain: void 0
|
|
44
|
-
},
|
|
45
39
|
redirect: {
|
|
46
40
|
home: "/",
|
|
47
41
|
login: "/account/login",
|
|
@@ -54,11 +48,88 @@ const module = defineNuxtModule({
|
|
|
54
48
|
logger.error("nuxt-directus-sdk requires a url to your Directus instance, set it in the config options or .env file as DIRECTUS_URL");
|
|
55
49
|
return;
|
|
56
50
|
}
|
|
51
|
+
const resolver = createResolver(import.meta.url);
|
|
52
|
+
const devProxyConfig = typeof options.devProxy === "boolean" ? { enabled: options.devProxy } : { ...options.devProxy };
|
|
53
|
+
const devProxyEnabled = devProxyConfig.enabled ?? nuxtApp.options.dev;
|
|
54
|
+
const devProxyPath = devProxyConfig.path ?? "/directus";
|
|
55
|
+
const directusUrl = options.url;
|
|
56
|
+
if (devProxyEnabled && nuxtApp.options.dev) {
|
|
57
|
+
const devPort = nuxtApp.options.devServer?.port ?? 3e3;
|
|
58
|
+
const devHost = nuxtApp.options.devServer?.host ?? "localhost";
|
|
59
|
+
const baseUrl = `http://${devHost}:${devPort}`;
|
|
60
|
+
const proxyUrl = `${baseUrl}${devProxyPath}/`;
|
|
61
|
+
const wsProxyPath = `${devProxyPath}-ws`;
|
|
62
|
+
const wsTarget = joinURL(directusUrl, "websocket");
|
|
63
|
+
logger.info(`\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501`);
|
|
64
|
+
logger.info(`\u{1F504} Directus Development Proxy Enabled`);
|
|
65
|
+
logger.info(` Proxy path: ${devProxyPath}`);
|
|
66
|
+
logger.info(` Forwarding to: ${directusUrl}`);
|
|
67
|
+
logger.info(` Local URL: ${proxyUrl}`);
|
|
68
|
+
logger.info(` WebSocket proxy path: ${wsProxyPath}`);
|
|
69
|
+
logger.info(` WebSocket target: ${wsTarget}`);
|
|
70
|
+
logger.info(`\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501`);
|
|
71
|
+
nuxtApp.options.nitro = nuxtApp.options.nitro || {};
|
|
72
|
+
nuxtApp.options.nitro.devProxy = nuxtApp.options.nitro.devProxy || {};
|
|
73
|
+
nuxtApp.options.nitro.devProxy[wsProxyPath] = {
|
|
74
|
+
target: directusUrl,
|
|
75
|
+
changeOrigin: true,
|
|
76
|
+
ws: true
|
|
77
|
+
};
|
|
78
|
+
const httpProxy = await import('http-proxy');
|
|
79
|
+
const proxy = httpProxy.default.createProxyServer({
|
|
80
|
+
target: directusUrl,
|
|
81
|
+
changeOrigin: true,
|
|
82
|
+
ws: true,
|
|
83
|
+
secure: false
|
|
84
|
+
// Allow self-signed certificates
|
|
85
|
+
});
|
|
86
|
+
proxy.on("error", (err, _req, socket) => {
|
|
87
|
+
logger.error(`WebSocket proxy error:`, err.message);
|
|
88
|
+
if (socket && !socket.destroyed) {
|
|
89
|
+
socket.end();
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
proxy.on("proxyReqWs", (proxyReq, req, _socket) => {
|
|
93
|
+
proxyReq.path = "/websocket";
|
|
94
|
+
if (req.headers.cookie) {
|
|
95
|
+
proxyReq.setHeader("cookie", req.headers.cookie);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
nuxtApp.hook("ready", () => {
|
|
99
|
+
const originalUpgrade = nuxtApp.server?.upgrade;
|
|
100
|
+
if (nuxtApp.server) {
|
|
101
|
+
nuxtApp.server.upgrade = (req, socket, head) => {
|
|
102
|
+
if (req.url?.startsWith(wsProxyPath)) {
|
|
103
|
+
try {
|
|
104
|
+
proxy.ws(req, socket, head);
|
|
105
|
+
} catch (err) {
|
|
106
|
+
logger.error("WebSocket proxy error:", err.message);
|
|
107
|
+
if (!socket.destroyed) {
|
|
108
|
+
socket.destroy();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
} else if (originalUpgrade) {
|
|
112
|
+
return originalUpgrade(req, socket, head);
|
|
113
|
+
} else if (!socket.destroyed) {
|
|
114
|
+
socket.destroy();
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
addServerHandler({
|
|
120
|
+
route: `${devProxyPath}/**`,
|
|
121
|
+
handler: resolver.resolve("./runtime/server/routes/directus")
|
|
122
|
+
});
|
|
123
|
+
options.url = proxyUrl;
|
|
124
|
+
options.wsProxyUrl = joinURL(baseUrl, wsProxyPath);
|
|
125
|
+
} else if (!nuxtApp.options.dev) {
|
|
126
|
+
logger.info(`\u{1F310} Production mode: Connecting directly to ${directusUrl}`);
|
|
127
|
+
}
|
|
128
|
+
options.directusUrl = directusUrl;
|
|
57
129
|
nuxtApp.options.runtimeConfig[configKey] = options;
|
|
58
130
|
nuxtApp.options.runtimeConfig.public = nuxtApp.options.runtimeConfig.public || {};
|
|
59
131
|
nuxtApp.options.runtimeConfig.public[configKey] = defu(nuxtApp.options.runtimeConfig.public[configKey], options);
|
|
60
132
|
delete nuxtApp.options.runtimeConfig.public[configKey].adminToken;
|
|
61
|
-
const resolver = createResolver(import.meta.url);
|
|
62
133
|
await installModule("@nuxt/image", {
|
|
63
134
|
directus: {
|
|
64
135
|
baseURL: useUrl(options.url, "assets")
|
|
@@ -70,6 +141,10 @@ const module = defineNuxtModule({
|
|
|
70
141
|
path: resolver.resolve("./runtime/middleware/auth"),
|
|
71
142
|
global: options.auth?.enableGlobalAuthMiddleware
|
|
72
143
|
});
|
|
144
|
+
addRouteMiddleware({
|
|
145
|
+
name: "guest",
|
|
146
|
+
path: resolver.resolve("./runtime/middleware/guest")
|
|
147
|
+
});
|
|
73
148
|
addImportsDir(resolver.resolve("./runtime/composables"));
|
|
74
149
|
addComponentsDir({
|
|
75
150
|
path: resolver.resolve("./runtime/components"),
|
|
@@ -143,16 +218,16 @@ const module = defineNuxtModule({
|
|
|
143
218
|
nitroConfig.imports.presets.push({
|
|
144
219
|
from: resolver.resolve("./runtime/server/services"),
|
|
145
220
|
imports: [
|
|
146
|
-
"
|
|
147
|
-
"useUserDirectus",
|
|
221
|
+
"getDirectusSessionToken",
|
|
148
222
|
"useAdminDirectus",
|
|
223
|
+
"useServerDirectus",
|
|
149
224
|
"useDirectusUrl",
|
|
150
|
-
"
|
|
225
|
+
"useTokenDirectus"
|
|
151
226
|
]
|
|
152
227
|
});
|
|
153
228
|
});
|
|
154
229
|
if (options.devtools) {
|
|
155
|
-
const adminUrl = useUrl(
|
|
230
|
+
const adminUrl = useUrl(directusUrl, "admin");
|
|
156
231
|
logger.info(`Directus Admin URL: ${adminUrl}`);
|
|
157
232
|
nuxtApp.hook("devtools:customTabs", (iframeTabs) => {
|
|
158
233
|
iframeTabs.push({
|
|
@@ -172,16 +247,19 @@ const module = defineNuxtModule({
|
|
|
172
247
|
if (!options.adminToken) {
|
|
173
248
|
logger.warn("Directus types generation is disabled, set the admin token in the config or .env file as DIRECTUS_ADMIN_TOKEN");
|
|
174
249
|
} else {
|
|
175
|
-
logger.info("Generating Directus types");
|
|
176
250
|
try {
|
|
251
|
+
let cachedTypes = null;
|
|
177
252
|
const typesPath = addTypeTemplate({
|
|
178
253
|
filename: `types/${configKey}.d.ts`,
|
|
179
|
-
getContents() {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
254
|
+
async getContents() {
|
|
255
|
+
if (!cachedTypes) {
|
|
256
|
+
cachedTypes = await generateTypes({
|
|
257
|
+
url: useUrl(directusUrl),
|
|
258
|
+
token: options.adminToken,
|
|
259
|
+
prefix: options.types?.prefix ?? ""
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
return cachedTypes;
|
|
185
263
|
}
|
|
186
264
|
}, { nitro: true, nuxt: true }).dst;
|
|
187
265
|
nuxtApp.hook("prepare:types", (options2) => {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { PrimaryKey } from '@directus/types';
|
|
2
|
+
declare const _default: <T extends keyof DirectusSchema>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
3
|
+
props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, never> & {
|
|
4
|
+
collection: T;
|
|
5
|
+
item: PrimaryKey;
|
|
6
|
+
fields?: (string | number | symbol) | (string | number | symbol)[];
|
|
7
|
+
mode?: "drawer" | "modal" | "popover";
|
|
8
|
+
} & {}> & import("vue").PublicProps;
|
|
9
|
+
expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
|
|
10
|
+
attrs: any;
|
|
11
|
+
slots: {
|
|
12
|
+
default?: (props: {}) => any;
|
|
13
|
+
};
|
|
14
|
+
emit: {};
|
|
15
|
+
}>) => import("vue").VNode & {
|
|
16
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
17
|
+
};
|
|
18
|
+
export default _default;
|
|
19
|
+
type __VLS_PrettifyLocal<T> = {
|
|
20
|
+
[K in keyof T as K]: T[K];
|
|
21
|
+
} & {};
|
|
@@ -1,47 +1,51 @@
|
|
|
1
|
-
<script setup
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
type
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
mode?: 'drawer' | 'modal' | 'popover'
|
|
16
|
-
}>()
|
|
17
|
-
|
|
18
|
-
const directusPreview = useDirectusPreview()
|
|
19
|
-
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, onBeforeUnmount, onMounted, ref, useRuntimeConfig } from "#imports";
|
|
3
|
+
import { apply, setAttr } from "@directus/visual-editing";
|
|
4
|
+
import { useDirectusPreview } from "../composables/directus";
|
|
5
|
+
import { Slot } from "../utils";
|
|
6
|
+
const props = defineProps({
|
|
7
|
+
collection: { type: null, required: true },
|
|
8
|
+
item: { type: [String, Number], required: true },
|
|
9
|
+
fields: { type: null, required: false },
|
|
10
|
+
mode: { type: String, required: false }
|
|
11
|
+
});
|
|
12
|
+
const config = useRuntimeConfig();
|
|
13
|
+
const directusPreview = useDirectusPreview();
|
|
14
|
+
const editorElement = ref(null);
|
|
20
15
|
const directusAttr = computed(() => {
|
|
21
|
-
const data
|
|
22
|
-
|
|
16
|
+
const data = {};
|
|
23
17
|
Object.entries(props).forEach(([key, value]) => {
|
|
24
|
-
if (value !==
|
|
25
|
-
data[key] = value
|
|
18
|
+
if (value !== void 0) {
|
|
19
|
+
data[key] = value;
|
|
26
20
|
}
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
})
|
|
31
|
-
|
|
21
|
+
});
|
|
22
|
+
return setAttr(data);
|
|
23
|
+
});
|
|
32
24
|
const attributes = computed(() => {
|
|
33
25
|
if (!directusPreview.value) {
|
|
34
|
-
return null
|
|
26
|
+
return null;
|
|
35
27
|
}
|
|
36
|
-
|
|
37
28
|
return {
|
|
38
|
-
|
|
29
|
+
"data-directus": directusAttr.value
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
onMounted(async () => {
|
|
33
|
+
if (!config.public.directus.visualEditor || !editorElement.value || import.meta.server) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const applied = await apply({ directusUrl: config.public.directus.url });
|
|
37
|
+
if (!applied) {
|
|
38
|
+
return;
|
|
39
39
|
}
|
|
40
|
-
|
|
40
|
+
applied.enable();
|
|
41
|
+
onBeforeUnmount(() => {
|
|
42
|
+
applied.remove();
|
|
43
|
+
});
|
|
44
|
+
});
|
|
41
45
|
</script>
|
|
42
46
|
|
|
43
47
|
<template>
|
|
44
|
-
<Slot v-bind="attributes">
|
|
48
|
+
<Slot ref="editorElement" v-bind="attributes">
|
|
45
49
|
<slot />
|
|
46
50
|
</Slot>
|
|
47
51
|
</template>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { PrimaryKey } from '@directus/types';
|
|
2
|
+
declare const _default: <T extends keyof DirectusSchema>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
|
|
3
|
+
props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, never> & {
|
|
4
|
+
collection: T;
|
|
5
|
+
item: PrimaryKey;
|
|
6
|
+
fields?: (string | number | symbol) | (string | number | symbol)[];
|
|
7
|
+
mode?: "drawer" | "modal" | "popover";
|
|
8
|
+
} & {}> & import("vue").PublicProps;
|
|
9
|
+
expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
|
|
10
|
+
attrs: any;
|
|
11
|
+
slots: {
|
|
12
|
+
default?: (props: {}) => any;
|
|
13
|
+
};
|
|
14
|
+
emit: {};
|
|
15
|
+
}>) => import("vue").VNode & {
|
|
16
|
+
__ctx?: Awaited<typeof __VLS_setup>;
|
|
17
|
+
};
|
|
18
|
+
export default _default;
|
|
19
|
+
type __VLS_PrettifyLocal<T> = {
|
|
20
|
+
[K in keyof T as K]: T[K];
|
|
21
|
+
} & {};
|
|
@@ -8,20 +8,14 @@ export interface DirectusAuth {
|
|
|
8
8
|
updateMe: (data: Partial<DirectusUsers>) => Promise<DirectusUsers | null>;
|
|
9
9
|
login: (email: string, password: string, options?: LoginOptions & {
|
|
10
10
|
redirect?: boolean | RouteLocationRaw;
|
|
11
|
-
}) => Promise<
|
|
12
|
-
user: DirectusUsers | null;
|
|
13
|
-
accessToken: string;
|
|
14
|
-
refreshToken: string | null;
|
|
15
|
-
expires: number | null;
|
|
16
|
-
expiresAt: number | null;
|
|
17
|
-
}>;
|
|
11
|
+
}) => Promise<DirectusUsers | null>;
|
|
18
12
|
loginWithProvider: (provider: string, redirectOnLogin?: string) => Promise<void>;
|
|
19
13
|
logout: (redirect?: boolean | RouteLocationRaw) => Promise<void>;
|
|
20
14
|
createUser: (data: Partial<DirectusUsers>) => Promise<DirectusUsers>;
|
|
21
15
|
register: (data: Partial<DirectusUsers>) => Promise<DirectusUsers>;
|
|
22
16
|
inviteUser: (email: string, role: string, inviteUrl?: string | undefined) => Promise<void>;
|
|
23
17
|
acceptUserInvite: (token: string, password: string) => Promise<void>;
|
|
24
|
-
passwordRequest: (email: string, resetUrl?: string |
|
|
18
|
+
passwordRequest: (email: string, resetUrl?: string | undefined) => Promise<void>;
|
|
25
19
|
passwordReset: (token: string, password: string) => Promise<void>;
|
|
26
20
|
}
|
|
27
21
|
export declare function useDirectusUser(): Ref<DirectusUsers | null>;
|
|
@@ -1,29 +1,33 @@
|
|
|
1
1
|
import { navigateTo, useNuxtApp, useRouter, useRuntimeConfig } from "#app";
|
|
2
2
|
import { computed, useState } from "#imports";
|
|
3
3
|
import { acceptUserInvite as directusAcceptUserInvite, createUser as directusCreateUser, inviteUser as directusInviteUser, passwordRequest as directusPasswordRequest, passwordReset as directusPasswordReset, readMe as directusReadMe, updateMe as directusUpdateMe } from "@directus/sdk";
|
|
4
|
-
import { useDirectus } from "./directus.js";
|
|
5
|
-
import { useDirectusTokens } from "./tokens.js";
|
|
4
|
+
import { useDirectus, useDirectusUrl } from "./directus.js";
|
|
6
5
|
export function useDirectusUser() {
|
|
7
6
|
return useState("directus.user", () => null);
|
|
8
7
|
}
|
|
8
|
+
function useDirectusUserLoading() {
|
|
9
|
+
return useState("directus.user.loading", () => false);
|
|
10
|
+
}
|
|
9
11
|
export function useDirectusAuth() {
|
|
10
12
|
const config = useRuntimeConfig();
|
|
11
13
|
const router = useRouter();
|
|
12
14
|
const directus = useDirectus();
|
|
13
|
-
const tokens = useDirectusTokens();
|
|
14
15
|
const user = useDirectusUser();
|
|
16
|
+
const loading = useDirectusUserLoading();
|
|
15
17
|
const nuxtApp = useNuxtApp();
|
|
16
18
|
const loggedIn = computed(() => user.value !== null);
|
|
17
19
|
async function readMe() {
|
|
20
|
+
if (loading.value) {
|
|
21
|
+
return user.value;
|
|
22
|
+
}
|
|
23
|
+
loading.value = true;
|
|
18
24
|
try {
|
|
19
|
-
if (!tokens.accessToken.value) {
|
|
20
|
-
if (!tokens.refreshToken.value)
|
|
21
|
-
throw new Error("No refresh token");
|
|
22
|
-
await directus.refresh();
|
|
23
|
-
}
|
|
24
25
|
user.value = await directus.request(directusReadMe({ fields: config.public.directus.auth?.readMeFields ?? ["*"] }));
|
|
25
|
-
} catch {
|
|
26
|
+
} catch (error) {
|
|
27
|
+
console.error("[Auth] Failed to fetch user:", error);
|
|
26
28
|
user.value = null;
|
|
29
|
+
} finally {
|
|
30
|
+
loading.value = false;
|
|
27
31
|
}
|
|
28
32
|
await nuxtApp.callHook("directus:loggedIn", user.value);
|
|
29
33
|
return user.value;
|
|
@@ -36,9 +40,7 @@ export function useDirectusAuth() {
|
|
|
36
40
|
return user.value;
|
|
37
41
|
}
|
|
38
42
|
async function login(email, password, options) {
|
|
39
|
-
|
|
40
|
-
if (!response.access_token)
|
|
41
|
-
throw new Error("Login failed, please check your credentials.");
|
|
43
|
+
await directus.login({ email, password }, { ...options, mode: "session" });
|
|
42
44
|
await readMe();
|
|
43
45
|
const redirect = options?.redirect ?? true;
|
|
44
46
|
if (redirect !== false) {
|
|
@@ -51,16 +53,9 @@ export function useDirectusAuth() {
|
|
|
51
53
|
navigateTo(config.public.directus.auth?.redirect?.home ?? "/");
|
|
52
54
|
}
|
|
53
55
|
}
|
|
54
|
-
return
|
|
55
|
-
user: user.value,
|
|
56
|
-
accessToken: response.access_token,
|
|
57
|
-
refreshToken: response.refresh_token,
|
|
58
|
-
expires: response.expires,
|
|
59
|
-
expiresAt: response.expires_at
|
|
60
|
-
};
|
|
56
|
+
return user.value;
|
|
61
57
|
}
|
|
62
58
|
async function loginWithProvider(provider, redirectOnLogin) {
|
|
63
|
-
await logout();
|
|
64
59
|
const redirect = `${window.location.origin}${redirectOnLogin ?? router.currentRoute.value.fullPath}`;
|
|
65
60
|
await navigateTo(useDirectusUrl(`/auth/login/${provider}?redirect=${encodeURIComponent(redirect)}`), { external: true });
|
|
66
61
|
}
|
|
@@ -87,10 +82,6 @@ export function useDirectusAuth() {
|
|
|
87
82
|
await directus.logout();
|
|
88
83
|
} finally {
|
|
89
84
|
user.value = null;
|
|
90
|
-
tokens.refreshToken.value = null;
|
|
91
|
-
tokens.accessToken.value = null;
|
|
92
|
-
tokens.expires.value = null;
|
|
93
|
-
tokens.expiresAt.value = null;
|
|
94
85
|
}
|
|
95
86
|
if (redirect) {
|
|
96
87
|
const defaultRedirect = config.public.directus.auth?.redirect?.logout ?? config.public.directus.auth?.redirect?.home ?? "/";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Ref } from '#imports';
|
|
2
2
|
export declare function useDirectusPreview(): Ref<boolean>;
|
|
3
3
|
export declare function useDirectusUrl(path?: string): string;
|
|
4
|
-
export declare function useDirectus(
|
|
4
|
+
export declare function useDirectus(): import("@directus/sdk").DirectusClient<DirectusSchema> & import("@directus/sdk").AuthenticationClient<DirectusSchema> & import("@directus/sdk").RestClient<DirectusSchema> & import("@directus/sdk").WebSocketClient<DirectusSchema>;
|