directus-template-cli 0.7.0-beta.1 → 0.7.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.
- package/bin/dev.js +6 -0
- package/bin/run.js +5 -0
- package/dist/commands/apply.d.ts +17 -17
- package/dist/commands/apply.js +165 -173
- package/dist/commands/base.d.ts +15 -0
- package/dist/commands/base.js +45 -0
- package/dist/commands/extract.d.ts +16 -7
- package/dist/commands/extract.js +81 -73
- package/dist/commands/init.d.ts +21 -15
- package/dist/commands/init.js +204 -155
- package/dist/flags/common.d.ts +8 -7
- package/dist/flags/common.js +13 -11
- package/dist/index.js +1 -5
- package/dist/lib/constants.d.ts +7 -5
- package/dist/lib/constants.js +17 -14
- package/dist/lib/extract/extract-access.js +11 -15
- package/dist/lib/extract/extract-assets.js +20 -25
- package/dist/lib/extract/extract-collections.js +12 -16
- package/dist/lib/extract/extract-content.js +14 -19
- package/dist/lib/extract/extract-dashboards.js +22 -28
- package/dist/lib/extract/extract-extensions.js +12 -16
- package/dist/lib/extract/extract-fields.js +13 -17
- package/dist/lib/extract/extract-files.js +15 -19
- package/dist/lib/extract/extract-flows.js +22 -28
- package/dist/lib/extract/extract-folders.js +15 -19
- package/dist/lib/extract/extract-permissions.js +12 -16
- package/dist/lib/extract/extract-policies.js +12 -16
- package/dist/lib/extract/extract-presets.js +12 -16
- package/dist/lib/extract/extract-relations.js +14 -18
- package/dist/lib/extract/extract-roles.js +15 -19
- package/dist/lib/extract/extract-schema.js +17 -21
- package/dist/lib/extract/extract-settings.js +12 -16
- package/dist/lib/extract/extract-translations.js +12 -16
- package/dist/lib/extract/extract-users.js +15 -19
- package/dist/lib/extract/index.js +47 -51
- package/dist/lib/init/config.d.ts +1 -1
- package/dist/lib/init/config.js +4 -7
- package/dist/lib/init/index.d.ts +10 -9
- package/dist/lib/init/index.js +129 -85
- package/dist/lib/init/types.js +1 -2
- package/dist/lib/load/apply-flags.js +17 -23
- package/dist/lib/load/index.d.ts +1 -12
- package/dist/lib/load/index.js +40 -44
- package/dist/lib/load/load-access.js +15 -20
- package/dist/lib/load/load-collections.js +27 -32
- package/dist/lib/load/load-dashboards.js +19 -25
- package/dist/lib/load/load-data.js +43 -49
- package/dist/lib/load/load-extensions.js +30 -38
- package/dist/lib/load/load-files.js +20 -24
- package/dist/lib/load/load-flows.js +23 -29
- package/dist/lib/load/load-folders.js +16 -20
- package/dist/lib/load/load-permissions.js +13 -17
- package/dist/lib/load/load-policies.js +14 -18
- package/dist/lib/load/load-presets.js +14 -18
- package/dist/lib/load/load-relations.d.ts +2 -0
- package/dist/lib/load/load-relations.js +16 -18
- package/dist/lib/load/load-roles.js +19 -23
- package/dist/lib/load/load-settings.js +18 -21
- package/dist/lib/load/load-translations.js +14 -18
- package/dist/lib/load/load-users.js +21 -25
- package/dist/lib/load/update-required-fields.js +13 -17
- package/dist/lib/sdk.d.ts +1 -2
- package/dist/lib/sdk.js +27 -27
- package/dist/lib/types/extension.js +1 -2
- package/dist/lib/types.d.ts +18 -0
- package/dist/lib/types.js +1 -0
- package/dist/lib/utils/animated-bunny.d.ts +2 -0
- package/dist/lib/utils/animated-bunny.js +62 -0
- package/dist/lib/utils/auth.d.ts +8 -6
- package/dist/lib/utils/auth.js +48 -39
- package/dist/lib/utils/catch-error.js +8 -11
- package/dist/lib/utils/check-template.js +4 -8
- package/dist/lib/utils/chunk-array.js +1 -5
- package/dist/lib/utils/ensure-dir.js +7 -12
- package/dist/lib/utils/filter-fields.js +1 -4
- package/dist/lib/utils/get-role-ids.d.ts +1 -1
- package/dist/lib/utils/get-role-ids.js +7 -12
- package/dist/lib/utils/get-template.js +33 -37
- package/dist/lib/utils/logger.js +11 -13
- package/dist/lib/utils/open-url.js +5 -8
- package/dist/lib/utils/parse-github-url.d.ts +10 -5
- package/dist/lib/utils/parse-github-url.js +80 -45
- package/dist/lib/utils/path.js +6 -10
- package/dist/lib/utils/protected-domains.js +1 -4
- package/dist/lib/utils/read-file.js +8 -12
- package/dist/lib/utils/read-templates.js +9 -15
- package/dist/lib/utils/sanitize-flags.d.ts +3 -0
- package/dist/lib/utils/sanitize-flags.js +4 -0
- package/dist/lib/utils/system-fields.js +19 -22
- package/dist/lib/utils/template-config.d.ts +16 -0
- package/dist/lib/utils/template-config.js +34 -0
- package/dist/lib/utils/template-defaults.d.ts +1 -1
- package/dist/lib/utils/template-defaults.js +5 -14
- package/dist/lib/utils/transform-github-url.js +1 -5
- package/dist/lib/utils/validate-url.js +3 -6
- package/dist/lib/utils/wait.js +1 -5
- package/dist/lib/utils/write-to-file.js +8 -11
- package/dist/services/docker.js +82 -29
- package/dist/services/github.d.ts +1 -1
- package/dist/services/github.js +53 -22
- package/dist/services/posthog.d.ts +37 -0
- package/dist/services/posthog.js +104 -0
- package/oclif.manifest.json +32 -13
- package/package.json +41 -31
- package/bin/dev +0 -17
- package/bin/run +0 -5
package/dist/lib/init/index.js
CHANGED
|
@@ -1,131 +1,178 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
import { note, outro, spinner, log as clackLog } from '@clack/prompts';
|
|
2
|
+
import { ux } from '@oclif/core';
|
|
3
|
+
import { execa } from 'execa';
|
|
4
|
+
import { downloadTemplate } from 'giget';
|
|
5
|
+
import { glob } from 'glob';
|
|
6
|
+
import fs from 'node:fs';
|
|
7
|
+
import { detectPackageManager, installDependencies } from 'nypm';
|
|
8
|
+
import path from 'pathe';
|
|
9
|
+
import dotenv from 'dotenv';
|
|
10
|
+
import terminalLink from 'terminal-link';
|
|
11
|
+
import ApplyCommand from '../../commands/apply.js';
|
|
12
|
+
import { createDocker } from '../../services/docker.js';
|
|
13
|
+
import catchError from '../utils/catch-error.js';
|
|
14
|
+
import { createGigetString, parseGitHubUrl } from '../utils/parse-github-url.js';
|
|
15
|
+
import { readTemplateConfig } from '../utils/template-config.js';
|
|
16
|
+
import { DOCKER_CONFIG } from './config.js';
|
|
17
|
+
import { BSL_LICENSE_TEXT, pinkText } from '../constants.js';
|
|
18
|
+
export async function init({ dir, flags }) {
|
|
17
19
|
// Check target directory
|
|
18
20
|
const shouldForce = flags.overrideDir;
|
|
19
|
-
if (
|
|
21
|
+
if (fs.existsSync(dir) && !shouldForce) {
|
|
20
22
|
throw new Error('Directory already exists. Use --override-dir to override.');
|
|
21
23
|
}
|
|
22
|
-
|
|
23
|
-
const
|
|
24
|
+
// If template is a URL, we need to handle it differently
|
|
25
|
+
const isDirectUrl = flags.template?.startsWith('http');
|
|
26
|
+
const directusDir = path.join(dir, 'directus');
|
|
24
27
|
let template;
|
|
28
|
+
let packageManager = null;
|
|
25
29
|
try {
|
|
26
30
|
// Download the template from GitHub
|
|
27
|
-
const parsedUrl =
|
|
28
|
-
|
|
31
|
+
const parsedUrl = parseGitHubUrl(flags.template);
|
|
32
|
+
// If it's a direct URL, we download the entire repository
|
|
33
|
+
// Otherwise, we use the template from the starters repo
|
|
34
|
+
template = await downloadTemplate(createGigetString(parsedUrl), {
|
|
29
35
|
dir,
|
|
30
36
|
force: shouldForce,
|
|
31
37
|
});
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (!
|
|
36
|
-
|
|
38
|
+
// For direct URLs, we need to check if there's a directus directory
|
|
39
|
+
// If not, assume the entire repo is a directus template
|
|
40
|
+
if (isDirectUrl) {
|
|
41
|
+
if (!fs.existsSync(directusDir)) {
|
|
42
|
+
// Move all files to directus directory
|
|
43
|
+
fs.mkdirSync(directusDir, { recursive: true });
|
|
44
|
+
const files = fs.readdirSync(dir);
|
|
45
|
+
for (const file of files) {
|
|
46
|
+
if (file !== 'directus') {
|
|
47
|
+
fs.renameSync(path.join(dir, file), path.join(directusDir, file));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
37
50
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
51
|
+
}
|
|
52
|
+
// Read template configuration
|
|
53
|
+
const templateInfo = readTemplateConfig(dir);
|
|
54
|
+
let frontendDir;
|
|
55
|
+
// Handle frontends based on template configuration
|
|
56
|
+
if (flags.frontend && templateInfo) {
|
|
57
|
+
// Find the selected frontend in the configuration
|
|
58
|
+
const selectedFrontend = templateInfo.frontendOptions.find(f => f.id === flags.frontend);
|
|
59
|
+
if (!selectedFrontend) {
|
|
60
|
+
throw new Error(`Frontend "${flags.frontend}" not found in template configuration`);
|
|
42
61
|
}
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
for (const frontendPath of frontendPaths) {
|
|
51
|
-
const pathToRemove = node_path_1.default.join(dir, frontendPath);
|
|
52
|
-
if (node_fs_1.default.existsSync(pathToRemove)) {
|
|
53
|
-
node_fs_1.default.rmSync(pathToRemove, { recursive: true });
|
|
62
|
+
// Remove all frontend directories except the selected one
|
|
63
|
+
for (const frontend of templateInfo.frontendOptions) {
|
|
64
|
+
if (frontend.id !== flags.frontend) {
|
|
65
|
+
const pathToRemove = path.join(dir, frontend.path);
|
|
66
|
+
if (fs.existsSync(pathToRemove)) {
|
|
67
|
+
fs.rmSync(pathToRemove, { recursive: true });
|
|
68
|
+
}
|
|
54
69
|
}
|
|
55
70
|
}
|
|
71
|
+
// Move the selected frontend to the correct location if needed
|
|
72
|
+
frontendDir = path.join(dir, selectedFrontend.path);
|
|
73
|
+
if (frontendDir !== path.join(dir, flags.frontend)) {
|
|
74
|
+
fs.renameSync(frontendDir, path.join(dir, flags.frontend));
|
|
75
|
+
frontendDir = path.join(dir, flags.frontend);
|
|
76
|
+
}
|
|
56
77
|
}
|
|
78
|
+
const directusInfo = {
|
|
79
|
+
email: '',
|
|
80
|
+
password: '',
|
|
81
|
+
url: '',
|
|
82
|
+
};
|
|
57
83
|
// Find and copy all .env.example files
|
|
58
|
-
const envFiles =
|
|
84
|
+
const envFiles = glob.sync(path.join(dir, '**', '.env.example'));
|
|
85
|
+
// Process all env files first
|
|
59
86
|
for (const file of envFiles) {
|
|
60
87
|
const envFile = file.replace('.env.example', '.env');
|
|
61
|
-
|
|
88
|
+
fs.copyFileSync(file, envFile);
|
|
89
|
+
}
|
|
90
|
+
// Then read Directus-specific info only from the Directus env file
|
|
91
|
+
const directusEnvFile = path.join(directusDir, '.env');
|
|
92
|
+
if (fs.existsSync(directusEnvFile)) {
|
|
93
|
+
const parsedEnv = dotenv.parse(fs.readFileSync(directusEnvFile, 'utf8'));
|
|
94
|
+
directusInfo.email = parsedEnv.ADMIN_EMAIL;
|
|
95
|
+
directusInfo.password = parsedEnv.ADMIN_PASSWORD;
|
|
96
|
+
directusInfo.url = parsedEnv.PUBLIC_URL;
|
|
62
97
|
}
|
|
63
98
|
// Start Directus and apply template only if directus directory exists
|
|
64
|
-
if (
|
|
99
|
+
if (fs.existsSync(directusDir)) {
|
|
65
100
|
// Initialize Docker service
|
|
66
|
-
const dockerService =
|
|
101
|
+
const dockerService = createDocker(DOCKER_CONFIG);
|
|
67
102
|
// Check if Docker is installed
|
|
68
103
|
const dockerStatus = await dockerService.checkDocker();
|
|
69
104
|
if (!dockerStatus.installed || !dockerStatus.running) {
|
|
70
105
|
throw new Error(dockerStatus.message);
|
|
71
106
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
await apply_1.default.run([
|
|
79
|
-
'--directusUrl=http://localhost:8055',
|
|
80
|
-
'-p',
|
|
81
|
-
'--userEmail=admin@example.com',
|
|
82
|
-
'--userPassword=d1r3ctu5',
|
|
83
|
-
'--templateLocation=' + templatePath,
|
|
84
|
-
]);
|
|
85
|
-
}
|
|
86
|
-
catch (error) {
|
|
87
|
-
core_1.ux.error('Failed to start Directus containers or apply template');
|
|
88
|
-
throw error;
|
|
107
|
+
await dockerService.startContainers(directusDir);
|
|
108
|
+
const healthCheckUrl = `${directusInfo.url || 'http://localhost:8055'}${DOCKER_CONFIG.healthCheckEndpoint}`;
|
|
109
|
+
// Wait for healthy before proceeding
|
|
110
|
+
const isHealthy = await dockerService.waitForHealthy(healthCheckUrl);
|
|
111
|
+
if (!isHealthy) {
|
|
112
|
+
throw new Error('Directus failed to become healthy');
|
|
89
113
|
}
|
|
114
|
+
const templatePath = path.join(directusDir, 'template');
|
|
115
|
+
ux.stdout(`Attempting to apply template from: ${templatePath}`);
|
|
116
|
+
await ApplyCommand.run([
|
|
117
|
+
'--directusUrl=http://localhost:8055',
|
|
118
|
+
'-p',
|
|
119
|
+
'--userEmail=admin@example.com',
|
|
120
|
+
'--userPassword=d1r3ctu5',
|
|
121
|
+
`--templateLocation=${templatePath}`,
|
|
122
|
+
]);
|
|
90
123
|
}
|
|
91
|
-
// Install dependencies
|
|
92
|
-
if (flags.installDeps
|
|
93
|
-
|
|
124
|
+
// Install dependencies if requested
|
|
125
|
+
if (flags.installDeps) {
|
|
126
|
+
const s = spinner();
|
|
127
|
+
s.start('Installing dependencies');
|
|
94
128
|
try {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
129
|
+
if (fs.existsSync(frontendDir)) {
|
|
130
|
+
packageManager = await detectPackageManager(frontendDir);
|
|
131
|
+
await installDependencies({
|
|
132
|
+
cwd: frontendDir,
|
|
133
|
+
packageManager,
|
|
134
|
+
silent: true,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
100
137
|
}
|
|
101
138
|
catch (error) {
|
|
102
|
-
|
|
139
|
+
ux.warn('Failed to install dependencies');
|
|
103
140
|
throw error;
|
|
104
141
|
}
|
|
105
|
-
|
|
142
|
+
s.stop('Dependencies installed!');
|
|
106
143
|
}
|
|
107
144
|
// Initialize Git repo
|
|
108
145
|
if (flags.gitInit) {
|
|
109
|
-
|
|
146
|
+
const s = spinner();
|
|
147
|
+
s.start('Initializing git repository');
|
|
110
148
|
await initGit(dir);
|
|
111
|
-
|
|
149
|
+
s.stop('Git repository initialized!');
|
|
112
150
|
}
|
|
113
151
|
// Finishing up
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
152
|
+
const relativeDir = path.relative(process.cwd(), dir);
|
|
153
|
+
const directusUrl = directusInfo.url ?? 'http://localhost:8055';
|
|
154
|
+
const directusText = `- Directus is running on ${terminalLink(directusUrl, directusUrl)}. You can login with the email: ${pinkText(directusInfo.email)} and password: ${pinkText(directusInfo.password)}. \n`;
|
|
155
|
+
const frontendText = flags.frontend ? `- To start the frontend, run ${pinkText(`cd ${flags.frontend}`)} and then ${pinkText(`${packageManager?.name} run dev`)}. \n` : '';
|
|
156
|
+
const projectText = `- Navigate to your project directory using ${pinkText(`cd ${relativeDir}`)}. \n`;
|
|
157
|
+
const readmeText = '- Review the \`./README.md\` file for more information and next steps.';
|
|
158
|
+
const nextSteps = `${directusText}${projectText}${frontendText}${readmeText}`;
|
|
159
|
+
note(nextSteps, 'Next Steps');
|
|
160
|
+
clackLog.warn(BSL_LICENSE_TEXT);
|
|
161
|
+
outro(`Problems or questions? Hop into the community on Discord at ${pinkText(terminalLink('https://directus.chat', 'https://directus.chat'))}`);
|
|
119
162
|
}
|
|
120
163
|
catch (error) {
|
|
121
|
-
(
|
|
164
|
+
catchError(error, {
|
|
122
165
|
context: { dir, flags, function: 'init' },
|
|
123
166
|
fatal: true,
|
|
124
167
|
logToFile: true,
|
|
125
168
|
});
|
|
126
169
|
}
|
|
170
|
+
return {
|
|
171
|
+
directusDir,
|
|
172
|
+
frontendDir: flags.frontend ? path.join(dir, flags.frontend) : undefined,
|
|
173
|
+
template,
|
|
174
|
+
};
|
|
127
175
|
}
|
|
128
|
-
exports.init = init;
|
|
129
176
|
/**
|
|
130
177
|
* Initialize a git repository
|
|
131
178
|
* @param targetDir - The directory to initialize the git repository in
|
|
@@ -133,13 +180,10 @@ exports.init = init;
|
|
|
133
180
|
*/
|
|
134
181
|
async function initGit(targetDir) {
|
|
135
182
|
try {
|
|
136
|
-
core_1.ux.action.start('Initializing git repository');
|
|
137
|
-
const { execa } = await Promise.resolve().then(() => tslib_1.__importStar(require('execa')));
|
|
138
183
|
await execa('git', ['init'], { cwd: targetDir });
|
|
139
|
-
core_1.ux.action.stop();
|
|
140
184
|
}
|
|
141
185
|
catch (error) {
|
|
142
|
-
(
|
|
186
|
+
catchError(error, {
|
|
143
187
|
context: { function: 'initGit', targetDir },
|
|
144
188
|
fatal: false,
|
|
145
189
|
logToFile: true,
|
package/dist/lib/init/types.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const core_1 = require("@oclif/core");
|
|
6
|
-
const catch_error_1 = tslib_1.__importDefault(require("../utils/catch-error"));
|
|
7
|
-
exports.loadFlags = [
|
|
1
|
+
import { ux } from '@oclif/core';
|
|
2
|
+
import catchError from '../utils/catch-error.js';
|
|
3
|
+
export const loadFlags = [
|
|
8
4
|
'content',
|
|
9
5
|
'dashboards',
|
|
10
6
|
'extensions',
|
|
@@ -15,53 +11,51 @@ exports.loadFlags = [
|
|
|
15
11
|
'settings',
|
|
16
12
|
'users',
|
|
17
13
|
];
|
|
18
|
-
function validateProgrammaticFlags(flags) {
|
|
14
|
+
export function validateProgrammaticFlags(flags) {
|
|
19
15
|
const { directusToken, directusUrl, templateLocation, userEmail, userPassword } = flags;
|
|
20
16
|
if (!directusUrl)
|
|
21
|
-
|
|
17
|
+
ux.error('Directus URL is required for programmatic mode.');
|
|
22
18
|
if (!directusToken && (!userEmail || !userPassword))
|
|
23
|
-
|
|
19
|
+
ux.error('Either Directus token or email and password are required for programmatic mode.');
|
|
24
20
|
if (!templateLocation)
|
|
25
|
-
|
|
21
|
+
ux.error('Template location is required for programmatic mode.');
|
|
26
22
|
return flags.partial ? handlePartialFlags(flags) : setAllFlagsTrue(flags);
|
|
27
23
|
}
|
|
28
|
-
|
|
29
|
-
function validateInteractiveFlags(flags) {
|
|
24
|
+
export function validateInteractiveFlags(flags) {
|
|
30
25
|
return flags.partial ? handlePartialFlags(flags) : setAllFlagsTrue(flags);
|
|
31
26
|
}
|
|
32
|
-
exports.validateInteractiveFlags = validateInteractiveFlags;
|
|
33
27
|
function handlePartialFlags(flags) {
|
|
34
|
-
const enabledFlags =
|
|
35
|
-
const disabledFlags =
|
|
28
|
+
const enabledFlags = loadFlags.filter(flag => flags[flag] === true);
|
|
29
|
+
const disabledFlags = loadFlags.filter(flag => flags[flag] === false);
|
|
36
30
|
if (enabledFlags.length > 0) {
|
|
37
|
-
for (const flag of
|
|
31
|
+
for (const flag of loadFlags)
|
|
38
32
|
flags[flag] = enabledFlags.includes(flag);
|
|
39
33
|
}
|
|
40
34
|
else if (disabledFlags.length > 0) {
|
|
41
|
-
for (const flag of
|
|
35
|
+
for (const flag of loadFlags)
|
|
42
36
|
flags[flag] = !disabledFlags.includes(flag);
|
|
43
37
|
}
|
|
44
38
|
else {
|
|
45
39
|
setAllFlagsTrue(flags);
|
|
46
40
|
}
|
|
47
41
|
handleDependencies(flags);
|
|
48
|
-
if (!
|
|
49
|
-
(
|
|
42
|
+
if (!loadFlags.some(flag => flags[flag])) {
|
|
43
|
+
catchError(new Error('When using --partial, at least one component must be loaded.'), { fatal: true });
|
|
50
44
|
}
|
|
51
45
|
return flags;
|
|
52
46
|
}
|
|
53
47
|
function handleDependencies(flags) {
|
|
54
48
|
if (flags.content && (!flags.schema || !flags.files)) {
|
|
55
49
|
flags.schema = flags.files = true;
|
|
56
|
-
|
|
50
|
+
ux.warn('Content loading requires schema and files. Enabling schema and files flags.');
|
|
57
51
|
}
|
|
58
52
|
if (flags.users && !flags.permissions) {
|
|
59
53
|
flags.permissions = true;
|
|
60
|
-
|
|
54
|
+
ux.warn('User loading requires permissions. Enabling permissions flag.');
|
|
61
55
|
}
|
|
62
56
|
}
|
|
63
57
|
function setAllFlagsTrue(flags) {
|
|
64
|
-
for (const flag of
|
|
58
|
+
for (const flag of loadFlags)
|
|
65
59
|
flags[flag] = true;
|
|
66
60
|
return flags;
|
|
67
61
|
}
|
package/dist/lib/load/index.d.ts
CHANGED
|
@@ -1,13 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
content: boolean;
|
|
3
|
-
dashboards: boolean;
|
|
4
|
-
extensions: boolean;
|
|
5
|
-
files: boolean;
|
|
6
|
-
flows: boolean;
|
|
7
|
-
permissions: boolean;
|
|
8
|
-
schema: boolean;
|
|
9
|
-
settings: boolean;
|
|
10
|
-
users: boolean;
|
|
11
|
-
}
|
|
1
|
+
import type { ApplyFlags } from './apply-flags.js';
|
|
12
2
|
export default function apply(dir: string, flags: ApplyFlags): Promise<{}>;
|
|
13
|
-
export {};
|
package/dist/lib/load/index.js
CHANGED
|
@@ -1,68 +1,64 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
async function apply(dir, flags) {
|
|
24
|
-
const source = dir + '/src';
|
|
25
|
-
const isTemplateOk = await (0, check_template_1.default)(source);
|
|
1
|
+
import { ux } from '@oclif/core';
|
|
2
|
+
import checkTemplate from '../utils/check-template.js';
|
|
3
|
+
import loadAccess from './load-access.js';
|
|
4
|
+
import loadCollections from './load-collections.js';
|
|
5
|
+
import loadDashboards from './load-dashboards.js';
|
|
6
|
+
import loadData from './load-data.js';
|
|
7
|
+
import loadExtensions from './load-extensions.js';
|
|
8
|
+
import loadFiles from './load-files.js';
|
|
9
|
+
import loadFlows from './load-flows.js';
|
|
10
|
+
import loadFolders from './load-folders.js';
|
|
11
|
+
import loadPermissions from './load-permissions.js';
|
|
12
|
+
import loadPolicies from './load-policies.js';
|
|
13
|
+
import loadPresets from './load-presets.js';
|
|
14
|
+
import loadRelations from './load-relations.js';
|
|
15
|
+
import loadRoles from './load-roles.js';
|
|
16
|
+
import loadSettings from './load-settings.js';
|
|
17
|
+
import loadTranslations from './load-translations.js';
|
|
18
|
+
import loadUsers from './load-users.js';
|
|
19
|
+
import updateRequiredFields from './update-required-fields.js';
|
|
20
|
+
export default async function apply(dir, flags) {
|
|
21
|
+
const source = `${dir}/src`;
|
|
22
|
+
const isTemplateOk = await checkTemplate(source);
|
|
26
23
|
if (!isTemplateOk) {
|
|
27
|
-
|
|
24
|
+
ux.error('The template is missing the collections, fields, or relations files. Older templates are not supported in v0.4 of directus-template-cli. Try using v0.3 to load older templates npx directus-template-cli@0.3 apply or extract the template using latest version before applying. Exiting...');
|
|
28
25
|
}
|
|
29
26
|
if (flags.schema) {
|
|
30
|
-
await (
|
|
31
|
-
await (
|
|
27
|
+
await loadCollections(source);
|
|
28
|
+
await loadRelations(source);
|
|
32
29
|
}
|
|
33
30
|
if (flags.permissions || flags.users) {
|
|
34
|
-
await (
|
|
35
|
-
await (
|
|
36
|
-
await (
|
|
31
|
+
await loadRoles(source);
|
|
32
|
+
await loadPolicies(source);
|
|
33
|
+
await loadPermissions(source);
|
|
37
34
|
if (flags.users) {
|
|
38
|
-
await (
|
|
35
|
+
await loadUsers(source);
|
|
39
36
|
}
|
|
40
|
-
await (
|
|
37
|
+
await loadAccess(source);
|
|
41
38
|
}
|
|
42
39
|
if (flags.files) {
|
|
43
|
-
await (
|
|
44
|
-
await (
|
|
40
|
+
await loadFolders(source);
|
|
41
|
+
await loadFiles(source);
|
|
45
42
|
}
|
|
46
43
|
if (flags.content) {
|
|
47
|
-
await (
|
|
44
|
+
await loadData(source);
|
|
48
45
|
}
|
|
49
46
|
if (flags.schema) {
|
|
50
|
-
await (
|
|
47
|
+
await updateRequiredFields(source);
|
|
51
48
|
}
|
|
52
49
|
if (flags.dashboards) {
|
|
53
|
-
await (
|
|
50
|
+
await loadDashboards(source);
|
|
54
51
|
}
|
|
55
52
|
if (flags.flows) {
|
|
56
|
-
await (
|
|
53
|
+
await loadFlows(source);
|
|
57
54
|
}
|
|
58
55
|
if (flags.settings) {
|
|
59
|
-
await (
|
|
60
|
-
await (
|
|
61
|
-
await (
|
|
56
|
+
await loadSettings(source);
|
|
57
|
+
await loadTranslations(source);
|
|
58
|
+
await loadPresets(source);
|
|
62
59
|
}
|
|
63
60
|
if (flags.extensions) {
|
|
64
|
-
await (
|
|
61
|
+
await loadExtensions(source);
|
|
65
62
|
}
|
|
66
63
|
return {};
|
|
67
64
|
}
|
|
68
|
-
exports.default = apply;
|
|
@@ -1,25 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
async function loadAccess(dir) {
|
|
11
|
-
const access = (0, read_file_1.default)('access', dir);
|
|
12
|
-
core_1.ux.action.start(core_1.ux.colorize(constants_1.DIRECTUS_PINK, `Loading ${access.length} accesses`));
|
|
1
|
+
import { ux } from '@oclif/core';
|
|
2
|
+
import { DIRECTUS_PINK } from '../constants.js';
|
|
3
|
+
import { api } from '../sdk.js';
|
|
4
|
+
import catchError from '../utils/catch-error.js';
|
|
5
|
+
import getRoleIds from '../utils/get-role-ids.js';
|
|
6
|
+
import readFile from '../utils/read-file.js';
|
|
7
|
+
export default async function loadAccess(dir) {
|
|
8
|
+
const access = readFile('access', dir);
|
|
9
|
+
ux.action.start(ux.colorize(DIRECTUS_PINK, `Loading ${access.length} accesses`));
|
|
13
10
|
if (access && access.length > 0) {
|
|
14
11
|
// Fetch existing accesses
|
|
15
|
-
const existingAccesses = await
|
|
12
|
+
const existingAccesses = await api.client.request(() => ({
|
|
16
13
|
method: 'GET',
|
|
17
14
|
params: {
|
|
18
15
|
limit: -1,
|
|
19
16
|
},
|
|
20
17
|
path: '/access',
|
|
21
18
|
}));
|
|
22
|
-
const { legacyAdminRoleId, newAdminRoleId } = await (
|
|
19
|
+
const { legacyAdminRoleId, newAdminRoleId } = await getRoleIds(dir);
|
|
23
20
|
const existingAccessById = new Map(existingAccesses.map(acc => [acc.id, acc]));
|
|
24
21
|
const existingAccessByCompositeKey = new Map(existingAccesses.map(acc => [getCompositeKey(acc), acc]));
|
|
25
22
|
for await (const acc of access) {
|
|
@@ -39,7 +36,7 @@ async function loadAccess(dir) {
|
|
|
39
36
|
if (acc.role === legacyAdminRoleId) {
|
|
40
37
|
acc.role = newAdminRoleId;
|
|
41
38
|
}
|
|
42
|
-
await
|
|
39
|
+
await api.client.request(() => ({
|
|
43
40
|
body: JSON.stringify(acc),
|
|
44
41
|
method: 'POST',
|
|
45
42
|
path: '/access',
|
|
@@ -49,7 +46,7 @@ async function loadAccess(dir) {
|
|
|
49
46
|
existingAccessByCompositeKey.set(compositeKey, acc);
|
|
50
47
|
}
|
|
51
48
|
catch (error) {
|
|
52
|
-
(
|
|
49
|
+
catchError(error, {
|
|
53
50
|
context: {
|
|
54
51
|
access: acc,
|
|
55
52
|
operation: 'createAccess',
|
|
@@ -58,11 +55,9 @@ async function loadAccess(dir) {
|
|
|
58
55
|
}
|
|
59
56
|
}
|
|
60
57
|
}
|
|
61
|
-
|
|
58
|
+
ux.action.stop();
|
|
62
59
|
}
|
|
63
|
-
exports.default = loadAccess;
|
|
64
60
|
// Helper function to generate a composite key for each access
|
|
65
61
|
function getCompositeKey(acc) {
|
|
66
|
-
|
|
67
|
-
return `${(_a = acc.role) !== null && _a !== void 0 ? _a : 'null'}-${(_b = acc.user) !== null && _b !== void 0 ? _b : 'null'}-${acc.policy}`;
|
|
62
|
+
return `${acc.role ?? 'null'}-${acc.user ?? 'null'}-${acc.policy}`;
|
|
68
63
|
}
|