nuxt-directus-sdk 5.0.2 → 6.0.0-beta.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 +64 -30
- package/dist/cli/index.mjs +139 -19
- package/dist/module.d.mts +35 -0
- package/dist/module.d.ts +35 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +41 -34
- package/dist/rules/index.mjs +2 -2
- package/dist/runtime/components/directus-visual-editor.d.vue.ts +2 -2
- package/dist/runtime/components/directus-visual-editor.vue.d.ts +2 -2
- package/dist/runtime/middleware/auth.d.ts +1 -1
- package/dist/runtime/middleware/guest.d.ts +1 -1
- package/dist/runtime/plugin.d.ts +1 -1
- package/dist/runtime/plugins/visual-editor.client.d.ts +2 -2
- package/dist/runtime/server/services/directus.d.ts +1 -1
- package/dist/runtime/server/services/directus.js +1 -1
- package/dist/runtime/types/extensions/index.d.ts +15 -0
- package/dist/runtime/types/extensions/index.js +15 -0
- package/dist/runtime/types/extensions/seo-plugin.d.ts +2 -0
- package/dist/runtime/types/extensions/seo-plugin.js +24 -0
- package/dist/runtime/types/generate.d.ts +77 -4
- package/dist/runtime/types/generate.js +524 -37
- package/dist/runtime/types/index.d.ts +1 -1
- package/dist/runtime/types/index.js +1 -1
- package/dist/shared/{nuxt-directus-sdk.VgzMwq7f.mjs → nuxt-directus-sdk.1qEbZAZ_.mjs} +1 -1
- package/package.json +44 -27
- package/dist/runtime/components/directus-add-button.d.vue.ts +0 -22
- package/dist/runtime/components/directus-add-button.vue +0 -64
- package/dist/runtime/components/directus-add-button.vue.d.ts +0 -22
- package/dist/runtime/components/directus-edit-button.d.vue.ts +0 -25
- package/dist/runtime/components/directus-edit-button.vue +0 -64
- package/dist/runtime/components/directus-edit-button.vue.d.ts +0 -25
package/README.md
CHANGED
|
@@ -2,22 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
[![npm version][npm-version-src]][npm-version-href]
|
|
4
4
|
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
5
|
+
[![CI][ci-src]][ci-href]
|
|
6
|
+
[![Install size][install-size-src]][install-size-href]
|
|
5
7
|
[![License][license-src]][license-href]
|
|
6
8
|
[![Nuxt][nuxt-src]][nuxt-href]
|
|
7
9
|
|
|
8
|
-
> A Nuxt
|
|
10
|
+
> A Nuxt module for Directus with built-in authentication, realtime, file management, type generation, and visual editor support.
|
|
9
11
|
|
|
10
|
-
- [✨ Release Notes](/
|
|
12
|
+
- [✨ Release Notes](https://github.com/rolleyio/nuxt-directus-sdk/releases)
|
|
11
13
|
- [📚 Documentation](https://nuxt-directus-sdk.rolley.io)
|
|
12
14
|
|
|
13
15
|
## Features
|
|
14
16
|
|
|
15
17
|
- 🔒 **Session-based authentication** with cross-domain support
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
18
|
+
- ⚡ **Realtime** via typed WebSocket subscriptions
|
|
19
|
+
- 📁 **File management** with `@nuxt/image` integration
|
|
20
|
+
- ✏️ **Visual editor** support for `@directus/visual-editing`
|
|
21
|
+
- 🧩 **Auto-generated types** from your Directus schema, plus a standalone CLI
|
|
22
|
+
- 📐 **Rules DSL** for defining and syncing permissions in code
|
|
23
|
+
- 🗂️ Directus admin panel embedded in Nuxt Devtools
|
|
24
|
+
|
|
25
|
+
## Requirements
|
|
26
|
+
|
|
27
|
+
- **Nuxt 4.0+**
|
|
28
|
+
- **Directus v11.16.0+** (required by the bundled `@directus/visual-editing` v2 and `@directus/sdk` v21)
|
|
21
29
|
|
|
22
30
|
## Quick Setup
|
|
23
31
|
|
|
@@ -39,19 +47,12 @@ bun install --save-dev nuxt-directus-sdk
|
|
|
39
47
|
|
|
40
48
|
2. Add `nuxt-directus-sdk` to the `modules` section of `nuxt.config.ts`
|
|
41
49
|
|
|
42
|
-
```
|
|
50
|
+
```ts
|
|
43
51
|
export default defineNuxtConfig({
|
|
44
|
-
modules: [
|
|
45
|
-
'nuxt-directus-sdk'
|
|
46
|
-
],
|
|
52
|
+
modules: ['nuxt-directus-sdk'],
|
|
47
53
|
directus: {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
autoRefresh: true,
|
|
51
|
-
credentials: 'include', // Required for cross-domain
|
|
52
|
-
realtimeAuthMode: 'public',
|
|
53
|
-
}
|
|
54
|
-
}
|
|
54
|
+
url: process.env.DIRECTUS_URL,
|
|
55
|
+
},
|
|
55
56
|
})
|
|
56
57
|
```
|
|
57
58
|
|
|
@@ -59,41 +60,68 @@ export default defineNuxtConfig({
|
|
|
59
60
|
|
|
60
61
|
```dotenv
|
|
61
62
|
DIRECTUS_URL=https://your-directus-url.com
|
|
62
|
-
DIRECTUS_ADMIN_TOKEN=your_admin_token # Optional: for type generation
|
|
63
|
+
DIRECTUS_ADMIN_TOKEN=your_admin_token # Optional: required for type generation
|
|
63
64
|
```
|
|
64
65
|
|
|
65
|
-
4. **Configure your Directus backend** for cross-domain authentication (see [Authentication Guide](https://nuxt-directus-sdk.rolley.io/guide/authentication.html))
|
|
66
|
+
4. **Configure your Directus backend** for cross-domain authentication (see the [Authentication Guide](https://nuxt-directus-sdk.rolley.io/guide/authentication.html))
|
|
66
67
|
|
|
67
68
|
That's it! You can now use Directus within your Nuxt app ✨
|
|
68
69
|
|
|
69
|
-
For cross-domain setups (e.g
|
|
70
|
+
For cross-domain setups (e.g. `app.example.com` and `api.example.com`), see the [Authentication Guide](https://nuxt-directus-sdk.rolley.io/guide/authentication.html).
|
|
71
|
+
|
|
72
|
+
## CLI
|
|
73
|
+
|
|
74
|
+
The module ships with a CLI for type generation and permissions/rules sync that doesn't require a running Nuxt instance. Useful in CI, pre-commit hooks, or quick regeneration during development.
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Generate TypeScript types from a Directus schema
|
|
78
|
+
npx nuxt-directus-sdk generate-types --prefix App -o types/directus.d.ts
|
|
79
|
+
|
|
80
|
+
# Pull permissions/rules to a JSON file
|
|
81
|
+
npx nuxt-directus-sdk rules:pull -o rules.json
|
|
82
|
+
|
|
83
|
+
# See all commands
|
|
84
|
+
npx nuxt-directus-sdk --help
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
See the [CLI documentation](https://nuxt-directus-sdk.rolley.io/api/configuration/module#types) for flags and examples.
|
|
70
88
|
|
|
71
89
|
## Development
|
|
72
90
|
|
|
91
|
+
> [!IMPORTANT] The playground uses the [directus-template-cli](https://github.com/directus-labs/directus-template-cli?tab=readme-ov-file#applying-a-template) `cms` template.
|
|
92
|
+
> Apply the template with `npx directus-template-cli@latest apply` and follow the interactive prompts.
|
|
93
|
+
|
|
73
94
|
```bash
|
|
74
95
|
# Install dependencies
|
|
75
|
-
|
|
96
|
+
pnpm install
|
|
97
|
+
|
|
98
|
+
# Add DIRECTUS_ADMIN_TOKEN to playground .env (don't forget to update your token)
|
|
99
|
+
cp ./playground/.env.example ./playground/.env
|
|
76
100
|
|
|
77
101
|
# Generate type stubs
|
|
78
|
-
|
|
102
|
+
pnpm run dev:prepare
|
|
79
103
|
|
|
80
104
|
# Develop with the playground
|
|
81
|
-
|
|
105
|
+
pnpm run dev
|
|
82
106
|
|
|
83
107
|
# Build the playground
|
|
84
|
-
|
|
108
|
+
pnpm run dev:build
|
|
85
109
|
|
|
86
110
|
# Run ESLint
|
|
87
|
-
|
|
111
|
+
pnpm run lint
|
|
88
112
|
|
|
89
113
|
# Run Vitest
|
|
90
|
-
|
|
91
|
-
|
|
114
|
+
pnpm run test
|
|
115
|
+
pnpm run test:watch
|
|
92
116
|
|
|
93
|
-
# Release new version
|
|
94
|
-
|
|
117
|
+
# Release new version (see RELEASING.md)
|
|
118
|
+
pnpm run release
|
|
95
119
|
```
|
|
96
120
|
|
|
121
|
+
## Contributing
|
|
122
|
+
|
|
123
|
+
Contributions are welcome. Please target the `next` branch for new features and fixes; `main` is reserved for stable releases and hotfixes. See [RELEASING.md](./RELEASING.md) for the release process.
|
|
124
|
+
|
|
97
125
|
<!-- Badges -->
|
|
98
126
|
[npm-version-src]: https://img.shields.io/npm/v/nuxt-directus-sdk/latest.svg?style=flat&colorA=18181B&colorB=28CF8D
|
|
99
127
|
[npm-version-href]: https://npmjs.com/package/nuxt-directus-sdk
|
|
@@ -101,6 +129,12 @@ bun run release
|
|
|
101
129
|
[npm-downloads-src]: https://img.shields.io/npm/dm/nuxt-directus-sdk.svg?style=flat&colorA=18181B&colorB=28CF8D
|
|
102
130
|
[npm-downloads-href]: https://npmjs.com/package/nuxt-directus-sdk
|
|
103
131
|
|
|
132
|
+
[ci-src]: https://github.com/rolleyio/nuxt-directus-sdk/actions/workflows/ci.yml/badge.svg?branch=main
|
|
133
|
+
[ci-href]: https://github.com/rolleyio/nuxt-directus-sdk/actions/workflows/ci.yml
|
|
134
|
+
|
|
135
|
+
[install-size-src]: https://packagephobia.com/badge?p=nuxt-directus-sdk
|
|
136
|
+
[install-size-href]: https://packagephobia.com/result?p=nuxt-directus-sdk
|
|
137
|
+
|
|
104
138
|
[license-src]: https://img.shields.io/npm/l/nuxt-directus-sdk.svg?style=flat&colorA=18181B&colorB=28CF8D
|
|
105
139
|
[license-href]: https://npmjs.com/package/nuxt-directus-sdk
|
|
106
140
|
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
|
-
import { resolve } from 'node:path';
|
|
2
|
+
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { resolve, dirname } from 'node:path';
|
|
4
4
|
import { parseArgs } from 'node:util';
|
|
5
5
|
import { createDirectus, staticToken, rest } from '@directus/sdk';
|
|
6
|
-
import {
|
|
6
|
+
import { d as diffRemoteRules, e as formatDiff, c as compareRulesPayloads, f as fetchRemoteRules, k as loadRulesFromPayload, o as pushRules, g as formatPushResult, b as fetchRemoteRulesAsJson } from '../shared/nuxt-directus-sdk.1qEbZAZ_.mjs';
|
|
7
|
+
import { generateTypesFromDirectus } from '../../dist/runtime/types/generate.js';
|
|
8
|
+
|
|
9
|
+
function parseCsv(raw) {
|
|
10
|
+
if (!raw)
|
|
11
|
+
return [];
|
|
12
|
+
return raw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
13
|
+
}
|
|
14
|
+
function resolveNegatableBoolean(positive, negative, fallback) {
|
|
15
|
+
if (negative)
|
|
16
|
+
return false;
|
|
17
|
+
if (positive !== void 0)
|
|
18
|
+
return positive;
|
|
19
|
+
return fallback;
|
|
20
|
+
}
|
|
7
21
|
|
|
8
22
|
function loadEnv() {
|
|
9
23
|
const envPath = resolve(process.cwd(), ".env");
|
|
@@ -28,12 +42,14 @@ function getConnectionConfig(urlFlag, tokenFlag, label) {
|
|
|
28
42
|
const token = tokenFlag ?? process.env.DIRECTUS_ADMIN_TOKEN;
|
|
29
43
|
if (!url) {
|
|
30
44
|
console.error(`Error: ${label} URL is required`);
|
|
31
|
-
|
|
45
|
+
const flagHint = label === "Source" ? "--url (or --source-url)" : `--${label.toLowerCase()}-url`;
|
|
46
|
+
console.error(`Provide ${flagHint} or set DIRECTUS_URL in your .env file`);
|
|
32
47
|
process.exit(1);
|
|
33
48
|
}
|
|
34
49
|
if (!token) {
|
|
35
50
|
console.error(`Error: ${label} token is required`);
|
|
36
|
-
|
|
51
|
+
const flagHint = label === "Source" ? "--token (or --source-token)" : `--${label.toLowerCase()}-token`;
|
|
52
|
+
console.error(`Provide ${flagHint} or set DIRECTUS_ADMIN_TOKEN in your .env file`);
|
|
37
53
|
process.exit(1);
|
|
38
54
|
}
|
|
39
55
|
return { url, token };
|
|
@@ -43,7 +59,7 @@ function createClient(url, token) {
|
|
|
43
59
|
}
|
|
44
60
|
function printHelp() {
|
|
45
61
|
console.log(`
|
|
46
|
-
|
|
62
|
+
nuxt-directus-sdk CLI
|
|
47
63
|
|
|
48
64
|
Usage:
|
|
49
65
|
npx nuxt-directus-sdk <command> [options]
|
|
@@ -54,24 +70,40 @@ Commands:
|
|
|
54
70
|
rules:diff <file> Compare local JSON file with remote Directus
|
|
55
71
|
rules:diff-files <a> <b> Compare two local JSON files
|
|
56
72
|
rules:diff-remote Compare two remote Directus instances
|
|
73
|
+
generate-types Generate TypeScript types from a Directus schema
|
|
57
74
|
|
|
58
75
|
Options:
|
|
59
76
|
-h, --help Show this help message
|
|
60
|
-
-o, --output <file> Output file path (default: rules.json)
|
|
77
|
+
-o, --output <file> Output file path (default: stdout for generate-types, rules.json for rules:pull)
|
|
61
78
|
--compact Output compact JSON (no pretty-print)
|
|
62
79
|
--dry-run Show what would be changed without making changes (rules:push)
|
|
63
80
|
--add-only Only add new items, don't modify or delete existing (rules:push)
|
|
64
81
|
--skip-deletes Skip deleting items that exist remotely but not locally (rules:push)
|
|
82
|
+
--prefix <prefix> Prefix for custom collection type names (generate-types)
|
|
83
|
+
--include <names> Comma-separated collection names to include (generate-types).
|
|
84
|
+
When set, only these collections (plus any they reference
|
|
85
|
+
via --expand-references, default on) are emitted.
|
|
86
|
+
Takes precedence over --exclude if both are set.
|
|
87
|
+
--no-expand-references When --include is set, do NOT follow references to other
|
|
88
|
+
collections. Strict include mode \u2014 references to collections
|
|
89
|
+
not in the list collapse to \`string\`. (generate-types)
|
|
90
|
+
--exclude <names> Comma-separated collection names to exclude (generate-types).
|
|
91
|
+
References to excluded types are rewritten to \`string\`.
|
|
92
|
+
--verbose Show per-target warnings listing every field whose reference
|
|
93
|
+
was collapsed to \`string\` (generate-types).
|
|
94
|
+
--no-declare-global Emit types without the \`declare global\` wrapper (generate-types)
|
|
65
95
|
|
|
66
96
|
Connection options (override DIRECTUS_URL / DIRECTUS_ADMIN_TOKEN):
|
|
97
|
+
--url <url> Directus URL (alias of --source-url)
|
|
98
|
+
--token <token> Admin token (alias of --source-token)
|
|
67
99
|
--source-url <url> Source Directus URL
|
|
68
100
|
--source-token <token> Source admin token
|
|
69
101
|
--target-url <url> Target Directus URL (for rules:diff-remote)
|
|
70
102
|
--target-token <token> Target admin token (for rules:diff-remote)
|
|
71
103
|
|
|
72
104
|
Environment Variables:
|
|
73
|
-
DIRECTUS_URL Default Directus URL (used if --source-url not provided)
|
|
74
|
-
DIRECTUS_ADMIN_TOKEN Default admin token (used if --source-token not provided)
|
|
105
|
+
DIRECTUS_URL Default Directus URL (used if --url / --source-url not provided)
|
|
106
|
+
DIRECTUS_ADMIN_TOKEN Default admin token (used if --token / --source-token not provided)
|
|
75
107
|
|
|
76
108
|
Examples:
|
|
77
109
|
# Pull rules from Directus (uses env vars)
|
|
@@ -99,6 +131,27 @@ Examples:
|
|
|
99
131
|
npx nuxt-directus-sdk rules:diff-remote \\
|
|
100
132
|
--source-url https://staging.example.com --source-token staging-token \\
|
|
101
133
|
--target-url https://production.example.com --target-token production-token
|
|
134
|
+
|
|
135
|
+
# Generate TypeScript types, pipe to a file
|
|
136
|
+
npx nuxt-directus-sdk generate-types > types/directus.d.ts
|
|
137
|
+
|
|
138
|
+
# Generate types with a prefix, write directly to a file
|
|
139
|
+
npx nuxt-directus-sdk generate-types --prefix App -o types/directus.d.ts
|
|
140
|
+
|
|
141
|
+
# Generate types from a specific instance
|
|
142
|
+
npx nuxt-directus-sdk generate-types --url https://my-directus.com --token my-token
|
|
143
|
+
|
|
144
|
+
# Exclude specific collections \u2014 references to them become \`string\`
|
|
145
|
+
npx nuxt-directus-sdk generate-types --exclude directus_activity,directus_revisions
|
|
146
|
+
|
|
147
|
+
# Include only specific collections (referenced collections auto-included)
|
|
148
|
+
npx nuxt-directus-sdk generate-types --include posts
|
|
149
|
+
|
|
150
|
+
# Strict include \u2014 only the listed collections, references collapse to \`string\`
|
|
151
|
+
npx nuxt-directus-sdk generate-types --include posts --no-expand-references
|
|
152
|
+
|
|
153
|
+
# Verbose \u2014 show every field whose reference was collapsed, grouped by target
|
|
154
|
+
npx nuxt-directus-sdk generate-types --exclude directus_users --verbose
|
|
102
155
|
`);
|
|
103
156
|
}
|
|
104
157
|
function loadJsonFile(filePath) {
|
|
@@ -191,17 +244,67 @@ async function commandPush(localFile, connection, options) {
|
|
|
191
244
|
process.exit(1);
|
|
192
245
|
}
|
|
193
246
|
}
|
|
247
|
+
async function commandGenerateTypes(connection, options) {
|
|
248
|
+
console.error(`Generating types from ${connection.url}...`);
|
|
249
|
+
if (options.include.length > 0) {
|
|
250
|
+
console.error(`Including collections: ${options.include.join(", ")}`);
|
|
251
|
+
}
|
|
252
|
+
if (options.exclude.length > 0) {
|
|
253
|
+
console.error(`Excluding collections: ${options.exclude.join(", ")}`);
|
|
254
|
+
}
|
|
255
|
+
const { typeString, logs } = await generateTypesFromDirectus(
|
|
256
|
+
connection.url,
|
|
257
|
+
connection.token,
|
|
258
|
+
options.prefix,
|
|
259
|
+
{
|
|
260
|
+
include: options.include,
|
|
261
|
+
exclude: options.exclude,
|
|
262
|
+
expandReferences: options.expandReferences,
|
|
263
|
+
verbose: options.verbose
|
|
264
|
+
}
|
|
265
|
+
);
|
|
266
|
+
for (const line of logs) {
|
|
267
|
+
console.error(line);
|
|
268
|
+
}
|
|
269
|
+
if (!typeString) {
|
|
270
|
+
console.error("Error: Type generation returned empty output.");
|
|
271
|
+
process.exit(1);
|
|
272
|
+
}
|
|
273
|
+
const output = options.declareGlobal ? typeString : typeString.replace(/^declare global \{\n\n/, "").replace(/\n\}\n\nexport \{\};?\n?$/, "\n");
|
|
274
|
+
if (options.output) {
|
|
275
|
+
const outputPath = resolve(process.cwd(), options.output);
|
|
276
|
+
mkdirSync(dirname(outputPath), { recursive: true });
|
|
277
|
+
writeFileSync(outputPath, output, "utf-8");
|
|
278
|
+
console.error(`Types written to ${outputPath}`);
|
|
279
|
+
} else {
|
|
280
|
+
process.stdout.write(output);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
194
283
|
async function main() {
|
|
195
284
|
loadEnv();
|
|
196
285
|
const { values, positionals } = parseArgs({
|
|
197
286
|
allowPositionals: true,
|
|
198
287
|
options: {
|
|
199
288
|
"help": { type: "boolean", short: "h" },
|
|
200
|
-
|
|
289
|
+
// `output` has no default here — each command applies its own fallback
|
|
290
|
+
// (rules:pull defaults to rules.json, generate-types defaults to stdout).
|
|
291
|
+
"output": { type: "string", short: "o" },
|
|
201
292
|
"compact": { type: "boolean", default: false },
|
|
202
293
|
"dry-run": { type: "boolean", default: false },
|
|
203
294
|
"add-only": { type: "boolean", default: false },
|
|
204
295
|
"skip-deletes": { type: "boolean", default: false },
|
|
296
|
+
"prefix": { type: "string", default: "" },
|
|
297
|
+
"include": { type: "string" },
|
|
298
|
+
"exclude": { type: "string" },
|
|
299
|
+
// Node's parseArgs doesn't support `--no-X` syntax natively, so we
|
|
300
|
+
// register both forms. Negation wins if both are passed.
|
|
301
|
+
"expand-references": { type: "boolean", default: true },
|
|
302
|
+
"no-expand-references": { type: "boolean" },
|
|
303
|
+
"verbose": { type: "boolean", default: false },
|
|
304
|
+
"declare-global": { type: "boolean", default: true },
|
|
305
|
+
"no-declare-global": { type: "boolean" },
|
|
306
|
+
"url": { type: "string" },
|
|
307
|
+
"token": { type: "string" },
|
|
205
308
|
"source-url": { type: "string" },
|
|
206
309
|
"source-token": { type: "string" },
|
|
207
310
|
"target-url": { type: "string" },
|
|
@@ -217,12 +320,12 @@ async function main() {
|
|
|
217
320
|
switch (command) {
|
|
218
321
|
case "rules:pull": {
|
|
219
322
|
const connection = getConnectionConfig(
|
|
220
|
-
values["source-url"],
|
|
221
|
-
values["source-token"],
|
|
323
|
+
values["source-url"] ?? values.url,
|
|
324
|
+
values["source-token"] ?? values.token,
|
|
222
325
|
"Source"
|
|
223
326
|
);
|
|
224
327
|
await commandPull({
|
|
225
|
-
output: values.output,
|
|
328
|
+
output: values.output ?? "rules.json",
|
|
226
329
|
compact: values.compact
|
|
227
330
|
}, connection);
|
|
228
331
|
break;
|
|
@@ -234,8 +337,8 @@ async function main() {
|
|
|
234
337
|
process.exit(1);
|
|
235
338
|
}
|
|
236
339
|
const connection = getConnectionConfig(
|
|
237
|
-
values["source-url"],
|
|
238
|
-
values["source-token"],
|
|
340
|
+
values["source-url"] ?? values.url,
|
|
341
|
+
values["source-token"] ?? values.token,
|
|
239
342
|
"Source"
|
|
240
343
|
);
|
|
241
344
|
await commandPush(positionals[1], connection, {
|
|
@@ -252,8 +355,8 @@ async function main() {
|
|
|
252
355
|
process.exit(1);
|
|
253
356
|
}
|
|
254
357
|
const connection = getConnectionConfig(
|
|
255
|
-
values["source-url"],
|
|
256
|
-
values["source-token"],
|
|
358
|
+
values["source-url"] ?? values.url,
|
|
359
|
+
values["source-token"] ?? values.token,
|
|
257
360
|
"Source"
|
|
258
361
|
);
|
|
259
362
|
await commandDiff(positionals[1], connection);
|
|
@@ -269,8 +372,8 @@ async function main() {
|
|
|
269
372
|
break;
|
|
270
373
|
case "rules:diff-remote": {
|
|
271
374
|
const source = getConnectionConfig(
|
|
272
|
-
values["source-url"],
|
|
273
|
-
values["source-token"],
|
|
375
|
+
values["source-url"] ?? values.url,
|
|
376
|
+
values["source-token"] ?? values.token,
|
|
274
377
|
"Source"
|
|
275
378
|
);
|
|
276
379
|
const target = getConnectionConfig(
|
|
@@ -281,6 +384,23 @@ async function main() {
|
|
|
281
384
|
await commandDiffRemote(source, target);
|
|
282
385
|
break;
|
|
283
386
|
}
|
|
387
|
+
case "generate-types": {
|
|
388
|
+
const connection = getConnectionConfig(
|
|
389
|
+
values.url ?? values["source-url"],
|
|
390
|
+
values.token ?? values["source-token"],
|
|
391
|
+
"Source"
|
|
392
|
+
);
|
|
393
|
+
await commandGenerateTypes(connection, {
|
|
394
|
+
prefix: values.prefix ?? "",
|
|
395
|
+
output: values.output,
|
|
396
|
+
declareGlobal: resolveNegatableBoolean(values["declare-global"], values["no-declare-global"], true),
|
|
397
|
+
include: parseCsv(values.include),
|
|
398
|
+
exclude: parseCsv(values.exclude),
|
|
399
|
+
expandReferences: resolveNegatableBoolean(values["expand-references"], values["no-expand-references"], true),
|
|
400
|
+
verbose: values.verbose
|
|
401
|
+
});
|
|
402
|
+
break;
|
|
403
|
+
}
|
|
284
404
|
default:
|
|
285
405
|
console.error(`Unknown command: ${command}`);
|
|
286
406
|
printHelp();
|
package/dist/module.d.mts
CHANGED
|
@@ -153,6 +153,41 @@ interface ModuleOptions {
|
|
|
153
153
|
* @default ''
|
|
154
154
|
*/
|
|
155
155
|
prefix?: string;
|
|
156
|
+
/**
|
|
157
|
+
* Collection names to include in the generated types. When non-empty,
|
|
158
|
+
* only these collections (plus any they reference — see
|
|
159
|
+
* `expandReferences`) are emitted. References to collections not in
|
|
160
|
+
* the resolved set collapse to `string` (M2O) or `string[]` (O2M).
|
|
161
|
+
*
|
|
162
|
+
* Takes precedence over `exclude` if both are set.
|
|
163
|
+
* @type string[]
|
|
164
|
+
* @default []
|
|
165
|
+
*/
|
|
166
|
+
include?: string[];
|
|
167
|
+
/**
|
|
168
|
+
* When `include` is set, also pull in any collections referenced by
|
|
169
|
+
* the included collections (transitively). Follows M2O, O2M, and M2A.
|
|
170
|
+
* No-op when `include` is empty.
|
|
171
|
+
* @type boolean
|
|
172
|
+
* @default true
|
|
173
|
+
*/
|
|
174
|
+
expandReferences?: boolean;
|
|
175
|
+
/**
|
|
176
|
+
* Collection names to exclude from generated types.
|
|
177
|
+
* References to excluded collections are rewritten to `string` (M2O) or
|
|
178
|
+
* `string[]` (O2M) so the generated types stay resolvable.
|
|
179
|
+
* @type string[]
|
|
180
|
+
* @default []
|
|
181
|
+
*/
|
|
182
|
+
exclude?: string[];
|
|
183
|
+
/**
|
|
184
|
+
* When true, emit per-target warnings listing every field whose
|
|
185
|
+
* reference was collapsed to `string`/`string[]`. Field lists are
|
|
186
|
+
* capped at 5 per collection.
|
|
187
|
+
* @type boolean
|
|
188
|
+
* @default false
|
|
189
|
+
*/
|
|
190
|
+
verbose?: boolean;
|
|
156
191
|
};
|
|
157
192
|
}
|
|
158
193
|
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
package/dist/module.d.ts
CHANGED
|
@@ -153,6 +153,41 @@ interface ModuleOptions {
|
|
|
153
153
|
* @default ''
|
|
154
154
|
*/
|
|
155
155
|
prefix?: string;
|
|
156
|
+
/**
|
|
157
|
+
* Collection names to include in the generated types. When non-empty,
|
|
158
|
+
* only these collections (plus any they reference — see
|
|
159
|
+
* `expandReferences`) are emitted. References to collections not in
|
|
160
|
+
* the resolved set collapse to `string` (M2O) or `string[]` (O2M).
|
|
161
|
+
*
|
|
162
|
+
* Takes precedence over `exclude` if both are set.
|
|
163
|
+
* @type string[]
|
|
164
|
+
* @default []
|
|
165
|
+
*/
|
|
166
|
+
include?: string[];
|
|
167
|
+
/**
|
|
168
|
+
* When `include` is set, also pull in any collections referenced by
|
|
169
|
+
* the included collections (transitively). Follows M2O, O2M, and M2A.
|
|
170
|
+
* No-op when `include` is empty.
|
|
171
|
+
* @type boolean
|
|
172
|
+
* @default true
|
|
173
|
+
*/
|
|
174
|
+
expandReferences?: boolean;
|
|
175
|
+
/**
|
|
176
|
+
* Collection names to exclude from generated types.
|
|
177
|
+
* References to excluded collections are rewritten to `string` (M2O) or
|
|
178
|
+
* `string[]` (O2M) so the generated types stay resolvable.
|
|
179
|
+
* @type string[]
|
|
180
|
+
* @default []
|
|
181
|
+
*/
|
|
182
|
+
exclude?: string[];
|
|
183
|
+
/**
|
|
184
|
+
* When true, emit per-target warnings listing every field whose
|
|
185
|
+
* reference was collapsed to `string`/`string[]`. Field lists are
|
|
186
|
+
* capped at 5 per collection.
|
|
187
|
+
* @type boolean
|
|
188
|
+
* @default false
|
|
189
|
+
*/
|
|
190
|
+
verbose?: boolean;
|
|
156
191
|
};
|
|
157
192
|
}
|
|
158
193
|
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { useLogger, defineNuxtModule, createResolver, addServerHandler, hasNuxtModule, tryResolveModule, addPlugin, addRouteMiddleware, addImportsDir,
|
|
1
|
+
import { useLogger, defineNuxtModule, createResolver, addServerHandler, hasNuxtModule, tryResolveModule, addPlugin, addComponentsDir, addRouteMiddleware, addImportsDir, addImportsSources, addTypeTemplate, installModule } from '@nuxt/kit';
|
|
2
2
|
import { colors } from 'consola/utils';
|
|
3
3
|
import { defu } from 'defu';
|
|
4
4
|
import { joinURL } from 'ufo';
|
|
5
|
-
import {
|
|
5
|
+
import { generateTypesFromDirectus } from '../dist/runtime/types/index.js';
|
|
6
6
|
import { useUrl } from '../dist/runtime/utils/index.js';
|
|
7
7
|
|
|
8
8
|
const name = "nuxt-directus-sdk";
|
|
9
|
-
const version = "
|
|
9
|
+
const version = "6.0.0-beta.1";
|
|
10
10
|
|
|
11
11
|
const configKey = "directus";
|
|
12
12
|
const logger = useLogger("nuxt-directus-sdk");
|
|
@@ -59,17 +59,17 @@ const module$1 = defineNuxtModule({
|
|
|
59
59
|
nuxtApp.options[key] = defu(nuxtApp.options[key], moduleOptions);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
+
const loggerMessage = [];
|
|
62
63
|
const devProxyConfig = typeof options.devProxy === "boolean" ? { enabled: options.devProxy } : { ...options.devProxy };
|
|
63
64
|
const directusUrl = serverUrl || clientUrl;
|
|
64
65
|
const devProxyEnabled = devProxyConfig.enabled ?? nuxtApp.options.dev;
|
|
65
66
|
const devProxyPath = devProxyConfig.path ?? "/directus";
|
|
66
67
|
const wsProxyPath = devProxyConfig.wsPath ?? `${devProxyPath}-ws`;
|
|
67
68
|
const wsTarget = joinURL(directusUrl, "websocket");
|
|
68
|
-
const loggerMessage = [];
|
|
69
69
|
if (devProxyEnabled && nuxtApp.options.dev) {
|
|
70
|
-
loggerMessage.push(`\u{1F310} Development
|
|
71
|
-
loggerMessage.push(`URL${colors.dim(` ${devProxyPath}`)} proxies ${colors.underline(colors.green(`${directusUrl}`))}`);
|
|
72
|
-
loggerMessage.push(`WS URL${colors.dim(` ${wsProxyPath}`)} proxies ${colors.underline(colors.green(`${wsTarget}`))}
|
|
70
|
+
loggerMessage.push(`\u{1F310} Development Proxy Mode Enabled:`);
|
|
71
|
+
loggerMessage.push(` - URL${colors.dim(` ${devProxyPath}`)} proxies ${colors.underline(colors.green(`${directusUrl}`))}`);
|
|
72
|
+
loggerMessage.push(` - WS URL${colors.dim(` ${wsProxyPath}`)} proxies ${colors.underline(colors.green(`${wsTarget}`))}`, "");
|
|
73
73
|
nuxtApp.options.nitro = nuxtApp.options.nitro || {};
|
|
74
74
|
nuxtApp.options.nitro.devProxy = nuxtApp.options.nitro.devProxy || {};
|
|
75
75
|
nuxtApp.options.nitro.devProxy[wsProxyPath] = {
|
|
@@ -128,7 +128,7 @@ const module$1 = defineNuxtModule({
|
|
|
128
128
|
wsPath: wsProxyPath
|
|
129
129
|
};
|
|
130
130
|
} else if (!nuxtApp.options.dev) {
|
|
131
|
-
loggerMessage.push(`\u{1F310} Production
|
|
131
|
+
loggerMessage.push(`\u{1F310} Production Mode:`, ` - SDK connects directly to ${colors.dim(`${directusUrl}`)}`, "");
|
|
132
132
|
options.devProxy = false;
|
|
133
133
|
}
|
|
134
134
|
options.directusUrl = clientUrl;
|
|
@@ -153,11 +153,22 @@ const module$1 = defineNuxtModule({
|
|
|
153
153
|
modifiers
|
|
154
154
|
}
|
|
155
155
|
});
|
|
156
|
+
loggerMessage.push("\u{1F4F7} Nuxt/Image default provider is set to Directus", "");
|
|
156
157
|
}
|
|
157
158
|
addPlugin(resolver.resolve("./runtime/plugin"));
|
|
158
159
|
const hasVisualEditing = options.visualEditor && await tryResolveModule("@directus/visual-editing", new URL(import.meta.url));
|
|
159
160
|
if (hasVisualEditing) {
|
|
160
161
|
addPlugin(resolver.resolve("./runtime/plugins/visual-editor.client"));
|
|
162
|
+
addComponentsDir({
|
|
163
|
+
path: resolver.resolve("./runtime/components"),
|
|
164
|
+
pathPrefix: false,
|
|
165
|
+
prefix: "",
|
|
166
|
+
global: true
|
|
167
|
+
});
|
|
168
|
+
loggerMessage.push("\u{1F4DD} Visual Editor Components Added", "");
|
|
169
|
+
}
|
|
170
|
+
if (options.auth?.enableGlobalAuthMiddleware) {
|
|
171
|
+
loggerMessage.push("\u{1F512} Auth middleware installed globally.", "");
|
|
161
172
|
}
|
|
162
173
|
addRouteMiddleware({
|
|
163
174
|
name: "auth",
|
|
@@ -169,14 +180,6 @@ const module$1 = defineNuxtModule({
|
|
|
169
180
|
path: resolver.resolve("./runtime/middleware/guest")
|
|
170
181
|
});
|
|
171
182
|
addImportsDir(resolver.resolve("./runtime/composables"));
|
|
172
|
-
if (hasVisualEditing) {
|
|
173
|
-
addComponentsDir({
|
|
174
|
-
path: resolver.resolve("./runtime/components"),
|
|
175
|
-
pathPrefix: false,
|
|
176
|
-
prefix: "",
|
|
177
|
-
global: true
|
|
178
|
-
});
|
|
179
|
-
}
|
|
180
183
|
const directusSdkImports = {
|
|
181
184
|
from: "@directus/sdk",
|
|
182
185
|
imports: [
|
|
@@ -245,15 +248,14 @@ const module$1 = defineNuxtModule({
|
|
|
245
248
|
imports: [
|
|
246
249
|
"getDirectusSessionToken",
|
|
247
250
|
"useAdminDirectus",
|
|
248
|
-
"
|
|
251
|
+
"useSessionDirectus",
|
|
249
252
|
"useDirectusUrl",
|
|
250
253
|
"useTokenDirectus"
|
|
251
254
|
]
|
|
252
255
|
});
|
|
253
256
|
});
|
|
254
|
-
loggerMessage.push(``);
|
|
255
257
|
if (options.devtools) {
|
|
256
|
-
loggerMessage.push(
|
|
258
|
+
loggerMessage.push(`\u{1F4E6} Directus added to Nuxt DevTools`, "");
|
|
257
259
|
nuxtApp.hook("devtools:customTabs", (iframeTabs) => {
|
|
258
260
|
iframeTabs.push({
|
|
259
261
|
name: "directus",
|
|
@@ -265,33 +267,38 @@ const module$1 = defineNuxtModule({
|
|
|
265
267
|
}
|
|
266
268
|
});
|
|
267
269
|
});
|
|
268
|
-
} else {
|
|
269
|
-
loggerMessage.push(`${colors.dim(` Directus Admin was not added to Nuxt DevTools`)}`);
|
|
270
270
|
}
|
|
271
271
|
const typesEnabled = typeof options.types === "boolean" && options.types || options.types && options.types.enabled === true;
|
|
272
272
|
const typesPrefix = typeof options.types === "object" ? options.types.prefix ?? "" : "";
|
|
273
|
+
const typesInclude = typeof options.types === "object" ? options.types.include ?? [] : [];
|
|
274
|
+
const typesExpandReferences = typeof options.types === "object" ? options.types.expandReferences ?? true : true;
|
|
275
|
+
const typesExclude = typeof options.types === "object" ? options.types.exclude ?? [] : [];
|
|
276
|
+
const typesVerbose = typeof options.types === "object" ? options.types.verbose ?? false : false;
|
|
273
277
|
if (typesEnabled) {
|
|
278
|
+
loggerMessage.push("\u{1F4CB} Directus Type Generator Enabled");
|
|
274
279
|
if (!options.adminToken) {
|
|
275
|
-
loggerMessage.push(
|
|
280
|
+
loggerMessage.push(` ${colors.bgRedBright(`${colors.red("\u2691 ERROR:")} Unable to generate Types`)}`, ` Fix: Set adminToken in config or DIRECTUS_ADMIN_TOKEN in .env`);
|
|
276
281
|
} else {
|
|
277
282
|
try {
|
|
278
|
-
|
|
283
|
+
const { typeString, logs } = await generateTypesFromDirectus(directusUrl, options.adminToken, typesPrefix, {
|
|
284
|
+
include: typesInclude,
|
|
285
|
+
expandReferences: typesExpandReferences,
|
|
286
|
+
exclude: typesExclude,
|
|
287
|
+
verbose: typesVerbose
|
|
288
|
+
});
|
|
289
|
+
loggerMessage.push(...logs);
|
|
279
290
|
addTypeTemplate({
|
|
280
291
|
filename: `types/${configKey}.d.ts`,
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
cachedTypes = await generateTypes({
|
|
284
|
-
url: directusUrl,
|
|
285
|
-
token: options.adminToken,
|
|
286
|
-
prefix: typesPrefix
|
|
287
|
-
});
|
|
288
|
-
}
|
|
289
|
-
return cachedTypes;
|
|
292
|
+
getContents() {
|
|
293
|
+
return typeString;
|
|
290
294
|
}
|
|
291
295
|
}, { nitro: true, nuxt: true });
|
|
292
|
-
|
|
296
|
+
if (logs.some((log) => log.toLowerCase().includes("error"))) {
|
|
297
|
+
throw new Error(` ${colors.bgRedBright(`${colors.red("\u2691 ERROR:")} TypeGenerator returned an error`)}`);
|
|
298
|
+
}
|
|
299
|
+
loggerMessage.push(` - Directus Types saved successfully to ${colors.dim(`#build/types/${configKey}.d.ts`)}`);
|
|
293
300
|
} catch (error) {
|
|
294
|
-
|
|
301
|
+
loggerMessage.push(`${error instanceof Error ? error.message : String(error)}`, ` - Fallback DirectusSchema is being used ${colors.dim("(not recommended)")}`);
|
|
295
302
|
}
|
|
296
303
|
}
|
|
297
304
|
}
|