directus-template-cli 0.6.0-beta.2 → 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/README.md +0 -14
- 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 +166 -174
- package/dist/commands/base.d.ts +15 -0
- package/dist/commands/base.js +45 -0
- package/dist/commands/extract.d.ts +16 -9
- package/dist/commands/extract.js +81 -100
- package/dist/commands/init.d.ts +42 -0
- package/dist/commands/init.js +241 -0
- 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 +18 -0
- package/dist/lib/constants.js +25 -6
- 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.d.ts +1 -1
- package/dist/lib/extract/extract-content.js +17 -26
- 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 +12 -16
- 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.d.ts +1 -6
- package/dist/lib/extract/index.js +47 -58
- package/dist/lib/init/config.d.ts +3 -0
- package/dist/lib/init/config.js +12 -0
- package/dist/lib/init/index.d.ts +10 -0
- package/dist/lib/init/index.js +192 -0
- package/dist/lib/init/types.d.ts +30 -0
- package/dist/lib/init/types.js +1 -0
- 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.d.ts +2 -0
- package/dist/lib/load/load-collections.js +29 -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.d.ts +2 -0
- package/dist/lib/utils/ensure-dir.js +11 -0
- 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 -36
- 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 +19 -0
- package/dist/lib/utils/parse-github-url.js +89 -0
- 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.d.ts +7 -0
- package/dist/lib/utils/wait.js +9 -0
- package/dist/lib/utils/write-to-file.js +8 -11
- package/dist/services/docker.d.ts +23 -0
- package/dist/services/docker.js +187 -0
- package/dist/services/github.d.ts +18 -0
- package/dist/services/github.js +88 -0
- package/dist/services/posthog.d.ts +37 -0
- package/dist/services/posthog.js +104 -0
- package/oclif.manifest.json +102 -23
- package/package.json +46 -29
- package/bin/dev +0 -17
- package/bin/run +0 -5
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import logUpdate from 'log-update';
|
|
3
|
+
import { DIRECTUS_PINK } from '../constants.js';
|
|
4
|
+
export const RANDOM_SAYINGS = [
|
|
5
|
+
'One does not simply write backends...',
|
|
6
|
+
'I don\'t always test my code, but when I do, I use production.',
|
|
7
|
+
'A wild Directus appears!',
|
|
8
|
+
'Error 418: I\'m a teapot. Just kidding, I\'m Directus and I\'ve got your backend covered.',
|
|
9
|
+
'I\'ll fix it later. Narrator: They didn\'t fix it later.',
|
|
10
|
+
];
|
|
11
|
+
export async function animatedBunny(customMessage) {
|
|
12
|
+
const saying = customMessage || RANDOM_SAYINGS[Math.floor(Math.random() * RANDOM_SAYINGS.length)];
|
|
13
|
+
let typedSaying = '';
|
|
14
|
+
let blinkState = true;
|
|
15
|
+
let charIndex = 0;
|
|
16
|
+
let isCleanedUp = false;
|
|
17
|
+
const cleanup = () => {
|
|
18
|
+
if (isCleanedUp)
|
|
19
|
+
return;
|
|
20
|
+
isCleanedUp = true;
|
|
21
|
+
clearInterval(animation);
|
|
22
|
+
clearInterval(typing);
|
|
23
|
+
logUpdate.done();
|
|
24
|
+
};
|
|
25
|
+
// Ensure cleanup on process exit
|
|
26
|
+
process.on('exit', cleanup);
|
|
27
|
+
process.on('SIGINT', () => {
|
|
28
|
+
cleanup();
|
|
29
|
+
process.exit(0);
|
|
30
|
+
});
|
|
31
|
+
const updateFrame = () => {
|
|
32
|
+
if (isCleanedUp)
|
|
33
|
+
return;
|
|
34
|
+
const eyes = blinkState ? '- -' : 'Õ Õ';
|
|
35
|
+
const frame = `(\\ /)\n \\\\_//\n ( ${eyes}) ${chalk.dim('')}${chalk.hex(DIRECTUS_PINK).visible(`"${typedSaying}"`)}\nC(")(")`;
|
|
36
|
+
logUpdate(frame);
|
|
37
|
+
};
|
|
38
|
+
const animation = setInterval(() => {
|
|
39
|
+
blinkState = !blinkState;
|
|
40
|
+
updateFrame();
|
|
41
|
+
}, 500);
|
|
42
|
+
const typing = setInterval(() => {
|
|
43
|
+
if (charIndex < saying.length) {
|
|
44
|
+
typedSaying += saying[charIndex];
|
|
45
|
+
charIndex++;
|
|
46
|
+
updateFrame();
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
clearInterval(typing);
|
|
50
|
+
}
|
|
51
|
+
}, 25);
|
|
52
|
+
try {
|
|
53
|
+
// Run the animation for the duration of typing plus 1 second
|
|
54
|
+
await new Promise(resolve => setTimeout(resolve, saying.length * 25 + 1000));
|
|
55
|
+
}
|
|
56
|
+
finally {
|
|
57
|
+
cleanup();
|
|
58
|
+
// Remove the event listeners
|
|
59
|
+
process.removeListener('exit', cleanup);
|
|
60
|
+
process.removeListener('SIGINT', cleanup);
|
|
61
|
+
}
|
|
62
|
+
}
|
package/dist/lib/utils/auth.d.ts
CHANGED
|
@@ -16,13 +16,15 @@ export declare function getDirectusUrl(): Promise<string>;
|
|
|
16
16
|
*/
|
|
17
17
|
export declare function getDirectusToken(directusUrl: string): Promise<string>;
|
|
18
18
|
/**
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
* Initialize the Directus API with the provided flags and log in the user
|
|
20
|
+
* @param flags - The validated ApplyFlags
|
|
21
|
+
* @returns {Promise<void>} - Returns nothing
|
|
22
|
+
*/
|
|
22
23
|
export declare function initializeDirectusApi(flags: AuthFlags): Promise<void>;
|
|
23
24
|
/**
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
* Validate the authentication flags
|
|
26
|
+
* @param flags - The AuthFlags
|
|
27
|
+
* @returns {void} - Errors if the flags are invalid
|
|
28
|
+
*/
|
|
27
29
|
export declare function validateAuthFlags(flags: AuthFlags): void;
|
|
28
30
|
export {};
|
package/dist/lib/utils/auth.js
CHANGED
|
@@ -1,42 +1,52 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const sdk_2 = require("../sdk");
|
|
8
|
-
const catch_error_1 = tslib_1.__importDefault(require("./catch-error"));
|
|
9
|
-
const validate_url_1 = tslib_1.__importDefault(require("./validate-url"));
|
|
1
|
+
import { readMe } from '@directus/sdk';
|
|
2
|
+
import { text, log, isCancel } from '@clack/prompts';
|
|
3
|
+
import { ux } from '@oclif/core';
|
|
4
|
+
import { api } from '../sdk.js';
|
|
5
|
+
import catchError from './catch-error.js';
|
|
6
|
+
import validateUrl from './validate-url.js';
|
|
10
7
|
/**
|
|
11
8
|
* Get the Directus URL from the user
|
|
12
9
|
* @returns The Directus URL
|
|
13
10
|
*/
|
|
14
|
-
async function getDirectusUrl() {
|
|
15
|
-
const directusUrl = await
|
|
11
|
+
export async function getDirectusUrl() {
|
|
12
|
+
const directusUrl = await text({
|
|
13
|
+
placeholder: 'http://localhost:8055',
|
|
14
|
+
message: 'What is your Directus URL?',
|
|
15
|
+
});
|
|
16
|
+
if (isCancel(directusUrl)) {
|
|
17
|
+
log.info('Exiting...');
|
|
18
|
+
ux.exit(0);
|
|
19
|
+
}
|
|
16
20
|
// Validate URL
|
|
17
|
-
if (!(
|
|
18
|
-
|
|
21
|
+
if (!validateUrl(directusUrl)) {
|
|
22
|
+
ux.warn('Invalid URL');
|
|
19
23
|
return getDirectusUrl();
|
|
20
24
|
}
|
|
21
|
-
|
|
25
|
+
api.initialize(directusUrl);
|
|
22
26
|
return directusUrl;
|
|
23
27
|
}
|
|
24
|
-
exports.getDirectusUrl = getDirectusUrl;
|
|
25
28
|
/**
|
|
26
29
|
* Get the Directus token from the user
|
|
27
30
|
* @param directusUrl - The Directus URL
|
|
28
31
|
* @returns The Directus token
|
|
29
32
|
*/
|
|
30
|
-
async function getDirectusToken(directusUrl) {
|
|
31
|
-
const directusToken = await
|
|
33
|
+
export async function getDirectusToken(directusUrl) {
|
|
34
|
+
const directusToken = await text({
|
|
35
|
+
placeholder: 'admin-token-here',
|
|
36
|
+
message: 'What is your Directus Admin Token?',
|
|
37
|
+
});
|
|
38
|
+
if (isCancel(directusToken)) {
|
|
39
|
+
log.info('Exiting...');
|
|
40
|
+
ux.exit(0);
|
|
41
|
+
}
|
|
32
42
|
// Validate token by fetching the user
|
|
33
43
|
try {
|
|
34
|
-
await
|
|
35
|
-
const response = await
|
|
44
|
+
await api.loginWithToken(directusToken);
|
|
45
|
+
const response = await api.client.request(readMe());
|
|
36
46
|
return directusToken;
|
|
37
47
|
}
|
|
38
48
|
catch (error) {
|
|
39
|
-
(
|
|
49
|
+
catchError(error, {
|
|
40
50
|
context: {
|
|
41
51
|
directusUrl,
|
|
42
52
|
message: 'Invalid token. Please try again.',
|
|
@@ -46,40 +56,39 @@ async function getDirectusToken(directusUrl) {
|
|
|
46
56
|
return getDirectusToken(directusUrl);
|
|
47
57
|
}
|
|
48
58
|
}
|
|
49
|
-
exports.getDirectusToken = getDirectusToken;
|
|
50
59
|
/**
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
60
|
+
* Initialize the Directus API with the provided flags and log in the user
|
|
61
|
+
* @param flags - The validated ApplyFlags
|
|
62
|
+
* @returns {Promise<void>} - Returns nothing
|
|
63
|
+
*/
|
|
64
|
+
export async function initializeDirectusApi(flags) {
|
|
65
|
+
api.initialize(flags.directusUrl);
|
|
56
66
|
try {
|
|
57
67
|
if (flags.directusToken) {
|
|
58
|
-
await
|
|
68
|
+
await api.loginWithToken(flags.directusToken);
|
|
59
69
|
}
|
|
60
70
|
else if (flags.userEmail && flags.userPassword) {
|
|
61
|
-
await
|
|
71
|
+
await api.login(flags.userEmail, flags.userPassword);
|
|
62
72
|
}
|
|
63
|
-
const response = await
|
|
64
|
-
|
|
73
|
+
const response = await api.client.request(readMe());
|
|
74
|
+
ux.stdout(`-- Logged in as ${response.first_name} ${response.last_name}`);
|
|
65
75
|
}
|
|
66
76
|
catch {
|
|
67
|
-
(
|
|
77
|
+
catchError('-- Unable to authenticate with the provided credentials. Please check your credentials.', {
|
|
68
78
|
fatal: true,
|
|
69
79
|
});
|
|
70
80
|
}
|
|
71
81
|
}
|
|
72
|
-
exports.initializeDirectusApi = initializeDirectusApi;
|
|
73
82
|
/**
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
83
|
+
* Validate the authentication flags
|
|
84
|
+
* @param flags - The AuthFlags
|
|
85
|
+
* @returns {void} - Errors if the flags are invalid
|
|
86
|
+
*/
|
|
87
|
+
export function validateAuthFlags(flags) {
|
|
78
88
|
if (!flags.directusUrl) {
|
|
79
|
-
|
|
89
|
+
ux.error('Directus URL is required.');
|
|
80
90
|
}
|
|
81
91
|
if (!flags.directusToken && (!flags.userEmail || !flags.userPassword)) {
|
|
82
|
-
|
|
92
|
+
ux.error('Either Directus token or email and password are required.');
|
|
83
93
|
}
|
|
84
94
|
}
|
|
85
|
-
exports.validateAuthFlags = validateAuthFlags;
|
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const sdk_1 = require("../sdk");
|
|
5
|
-
const logger_1 = require("../utils/logger");
|
|
1
|
+
import { ux } from '@oclif/core';
|
|
2
|
+
import { DirectusError } from '../sdk.js';
|
|
3
|
+
import { logger } from '../utils/logger.js';
|
|
6
4
|
/**
|
|
7
5
|
* Handles errors by formatting them and optionally logging to console and file.
|
|
8
6
|
* @param error - The error to be handled.
|
|
9
7
|
* @param options - Configuration options for error handling.
|
|
10
8
|
* @returns void
|
|
11
9
|
*/
|
|
12
|
-
function catchError(error, options = {}) {
|
|
10
|
+
export default function catchError(error, options = {}) {
|
|
13
11
|
const { context = {}, fatal = false, logToFile = true } = options;
|
|
14
12
|
let errorMessage;
|
|
15
|
-
if (error instanceof
|
|
13
|
+
if (error instanceof DirectusError) {
|
|
16
14
|
errorMessage = error.message;
|
|
17
15
|
}
|
|
18
16
|
else if (error instanceof Error) {
|
|
@@ -29,13 +27,12 @@ function catchError(error, options = {}) {
|
|
|
29
27
|
// Log the error message to the console with the appropriate color
|
|
30
28
|
if (fatal) {
|
|
31
29
|
// ux.error exits the process with a non-zero code
|
|
32
|
-
|
|
30
|
+
ux.error(formattedMessage);
|
|
33
31
|
}
|
|
34
32
|
else {
|
|
35
|
-
|
|
33
|
+
ux.warn(formattedMessage);
|
|
36
34
|
}
|
|
37
35
|
if (logToFile) {
|
|
38
|
-
|
|
36
|
+
logger.log('error', errorMessage, context);
|
|
39
37
|
}
|
|
40
38
|
}
|
|
41
|
-
exports.default = catchError;
|
|
@@ -1,12 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
|
-
const read_file_1 = tslib_1.__importDefault(require("../utils/read-file"));
|
|
5
|
-
async function checkTemplate(dir) {
|
|
1
|
+
import readFile from '../utils/read-file.js';
|
|
2
|
+
export default async function checkTemplate(dir) {
|
|
6
3
|
// Check for the collections,fields, and relations files
|
|
7
4
|
try {
|
|
8
|
-
const collections = (
|
|
9
|
-
const fields = (
|
|
5
|
+
const collections = readFile('collections', dir);
|
|
6
|
+
const fields = readFile('fields', dir);
|
|
10
7
|
const isCollectionsOk = collections.length > 0 && fields.length > 0;
|
|
11
8
|
return isCollectionsOk;
|
|
12
9
|
}
|
|
@@ -14,4 +11,3 @@ async function checkTemplate(dir) {
|
|
|
14
11
|
console.error(error);
|
|
15
12
|
}
|
|
16
13
|
}
|
|
17
|
-
exports.default = checkTemplate;
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.chunkArray = void 0;
|
|
4
|
-
function chunkArray(array, size) {
|
|
1
|
+
export function chunkArray(array, size) {
|
|
5
2
|
return Array.from({ length: Math.ceil(array.length / size) }, (_, index) => array.slice(index * size, (index + 1) * size));
|
|
6
3
|
}
|
|
7
|
-
exports.chunkArray = chunkArray;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { existsSync, mkdirSync } from 'node:fs';
|
|
2
|
+
export function ensureDir(dir) {
|
|
3
|
+
if (!existsSync(dir)) {
|
|
4
|
+
mkdirSync(dir, { recursive: true });
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export function ensureDirSync(dir) {
|
|
8
|
+
if (!existsSync(dir)) {
|
|
9
|
+
mkdirSync(dir, { recursive: true });
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
1
|
// Utility function to remove relationship data (arrays of integers or UUIDs) from system collection data. Used for when custom fields are added to system collections. The relational data should be populated when the actual data is loaded.
|
|
4
|
-
function filterFields(dataArray, systemFields) {
|
|
2
|
+
export default function filterFields(dataArray, systemFields) {
|
|
5
3
|
return dataArray.map(item => {
|
|
6
4
|
for (const key of Object.keys(item)) {
|
|
7
5
|
if (!systemFields.includes(key)) {
|
|
@@ -19,4 +17,3 @@ function filterFields(dataArray, systemFields) {
|
|
|
19
17
|
return item;
|
|
20
18
|
});
|
|
21
19
|
}
|
|
22
|
-
exports.default = filterFields;
|
|
@@ -1,16 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const read_file_1 = tslib_1.__importDefault(require("./read-file"));
|
|
7
|
-
async function getRoleIds(dir) {
|
|
8
|
-
var _a;
|
|
9
|
-
const roles = (0, read_file_1.default)('roles', dir);
|
|
1
|
+
import { readMe } from '@directus/sdk';
|
|
2
|
+
import { api } from '../sdk.js';
|
|
3
|
+
import readFile from './read-file.js';
|
|
4
|
+
export default async function getRoleIds(dir) {
|
|
5
|
+
const roles = readFile('roles', dir);
|
|
10
6
|
// Legacy admin role may be undefined if the admin role was renamed in the source Directus project.
|
|
11
|
-
const legacyAdminRoleId =
|
|
12
|
-
const currentUser = await
|
|
7
|
+
const legacyAdminRoleId = roles.find(role => role.name === 'Administrator')?.id;
|
|
8
|
+
const currentUser = await api.client.request(readMe());
|
|
13
9
|
const newAdminRoleId = currentUser.role;
|
|
14
10
|
return { email: currentUser.email, legacyAdminRoleId, newAdminRoleId };
|
|
15
11
|
}
|
|
16
|
-
exports.default = getRoleIds;
|
|
@@ -1,48 +1,47 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
import { downloadTemplate } from 'giget';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import path, { dirname } from 'pathe';
|
|
5
|
+
import { COMMUNITY_TEMPLATE_REPO } from '../constants.js';
|
|
6
|
+
import resolvePathAndCheckExistence from './path.js';
|
|
7
|
+
import { readAllTemplates, readTemplate } from './read-templates.js';
|
|
8
|
+
import { transformGitHubUrl } from './transform-github-url.js';
|
|
9
|
+
// Create __dirname equivalent for ESM
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = dirname(__filename);
|
|
12
|
+
export async function getCommunityTemplates() {
|
|
13
|
+
const downloadDir = resolvePathAndCheckExistence(path.join(__dirname, '..', 'downloads', 'official'), false);
|
|
13
14
|
if (!downloadDir) {
|
|
14
|
-
throw new Error(`Invalid download directory: ${
|
|
15
|
+
throw new Error(`Invalid download directory: ${path.join(__dirname, '..', 'downloads', 'official')}`);
|
|
15
16
|
}
|
|
16
17
|
try {
|
|
17
|
-
const { dir } = await (
|
|
18
|
+
const { dir } = await downloadTemplate(COMMUNITY_TEMPLATE_REPO.string, {
|
|
18
19
|
dir: downloadDir,
|
|
19
20
|
force: true,
|
|
20
21
|
});
|
|
21
|
-
return await
|
|
22
|
+
return await readAllTemplates(dir);
|
|
22
23
|
}
|
|
23
24
|
catch (error) {
|
|
24
25
|
throw new Error(`Failed to download community templates: ${error}`);
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const resolvedDir = (0, path_1.default)(localTemplateDir);
|
|
28
|
+
export async function getLocalTemplate(localTemplateDir) {
|
|
29
|
+
const resolvedDir = resolvePathAndCheckExistence(localTemplateDir);
|
|
30
30
|
if (!resolvedDir) {
|
|
31
31
|
throw new Error('Directory does not exist.');
|
|
32
32
|
}
|
|
33
|
-
return
|
|
33
|
+
return readTemplate(resolvedDir);
|
|
34
34
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const resolvedDir = (0, path_1.default)(localTemplateDir);
|
|
35
|
+
export async function getInteractiveLocalTemplate(localTemplateDir) {
|
|
36
|
+
const resolvedDir = resolvePathAndCheckExistence(localTemplateDir);
|
|
38
37
|
if (!resolvedDir) {
|
|
39
38
|
throw new Error('Directory does not exist.');
|
|
40
39
|
}
|
|
41
|
-
const directTemplate = await
|
|
40
|
+
const directTemplate = await readTemplate(resolvedDir);
|
|
42
41
|
if (directTemplate) {
|
|
43
42
|
return [directTemplate];
|
|
44
43
|
}
|
|
45
|
-
const templates = await
|
|
44
|
+
const templates = await readAllTemplates(resolvedDir);
|
|
46
45
|
if (templates.length === 0) {
|
|
47
46
|
// If no templates found, search nested directories
|
|
48
47
|
const nestedTemplates = await findNestedTemplates(resolvedDir, 2);
|
|
@@ -53,16 +52,15 @@ async function getInteractiveLocalTemplate(localTemplateDir) {
|
|
|
53
52
|
}
|
|
54
53
|
return templates;
|
|
55
54
|
}
|
|
56
|
-
exports.getInteractiveLocalTemplate = getInteractiveLocalTemplate;
|
|
57
55
|
async function findNestedTemplates(dir, depth) {
|
|
58
56
|
if (depth === 0)
|
|
59
57
|
return [];
|
|
60
58
|
const templates = [];
|
|
61
|
-
const entries = await
|
|
59
|
+
const entries = await fs.promises.readdir(dir, { withFileTypes: true });
|
|
62
60
|
for (const entry of entries) {
|
|
63
61
|
if (entry.isDirectory()) {
|
|
64
|
-
const fullPath =
|
|
65
|
-
const dirTemplates = await
|
|
62
|
+
const fullPath = path.join(dir, entry.name);
|
|
63
|
+
const dirTemplates = await readAllTemplates(fullPath);
|
|
66
64
|
templates.push(...dirTemplates);
|
|
67
65
|
if (dirTemplates.length === 0 && depth > 1) {
|
|
68
66
|
// If no templates found and we can go deeper, search subdirectories
|
|
@@ -73,26 +71,25 @@ async function findNestedTemplates(dir, depth) {
|
|
|
73
71
|
}
|
|
74
72
|
return templates;
|
|
75
73
|
}
|
|
76
|
-
async function getGithubTemplate(ghTemplateUrl) {
|
|
74
|
+
export async function getGithubTemplate(ghTemplateUrl) {
|
|
77
75
|
try {
|
|
78
|
-
const ghString = await
|
|
79
|
-
const downloadDir = (
|
|
76
|
+
const ghString = await transformGitHubUrl(ghTemplateUrl);
|
|
77
|
+
const downloadDir = resolvePathAndCheckExistence(path.join(__dirname, '..', 'downloads', 'github'), false);
|
|
80
78
|
if (!downloadDir) {
|
|
81
|
-
throw new Error(`Invalid download directory: ${
|
|
79
|
+
throw new Error(`Invalid download directory: ${path.join(__dirname, '..', 'downloads', 'github')}`);
|
|
82
80
|
}
|
|
83
|
-
const { dir } = await
|
|
81
|
+
const { dir } = await downloadTemplate(ghString, {
|
|
84
82
|
dir: downloadDir,
|
|
85
83
|
force: true,
|
|
86
84
|
forceClean: true,
|
|
87
85
|
});
|
|
88
|
-
const resolvedDir = (
|
|
86
|
+
const resolvedDir = resolvePathAndCheckExistence(dir);
|
|
89
87
|
if (!resolvedDir) {
|
|
90
88
|
throw new Error(`Downloaded template directory does not exist: ${dir}`);
|
|
91
89
|
}
|
|
92
|
-
return
|
|
90
|
+
return readTemplate(resolvedDir);
|
|
93
91
|
}
|
|
94
92
|
catch (error) {
|
|
95
93
|
throw new Error(`Failed to download GitHub template: ${error}`);
|
|
96
94
|
}
|
|
97
95
|
}
|
|
98
|
-
exports.getGithubTemplate = getGithubTemplate;
|
package/dist/lib/utils/logger.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.logger = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
|
|
6
|
-
const node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'pathe';
|
|
7
3
|
class Logger {
|
|
4
|
+
static instance;
|
|
5
|
+
logFilePath;
|
|
8
6
|
constructor() {
|
|
9
7
|
this.initializeLogFile();
|
|
10
8
|
}
|
|
@@ -21,13 +19,13 @@ class Logger {
|
|
|
21
19
|
this.writeToFile(logEntry);
|
|
22
20
|
}
|
|
23
21
|
initializeLogFile() {
|
|
24
|
-
// @ts-ignore
|
|
22
|
+
// @ts-ignore - ignore
|
|
25
23
|
const timestamp = new Date().toISOString().replaceAll(/[.:]/g, '-');
|
|
26
|
-
const logDir =
|
|
27
|
-
if (!
|
|
28
|
-
|
|
24
|
+
const logDir = path.join(process.cwd(), '.directus-template-cli', 'logs');
|
|
25
|
+
if (!fs.existsSync(logDir)) {
|
|
26
|
+
fs.mkdirSync(logDir, { recursive: true });
|
|
29
27
|
}
|
|
30
|
-
this.logFilePath =
|
|
28
|
+
this.logFilePath = path.join(logDir, `run-${timestamp}.log`);
|
|
31
29
|
// Write initial timestamp to the log file
|
|
32
30
|
this.writeToFile(`Log started at ${timestamp}\n`);
|
|
33
31
|
}
|
|
@@ -45,11 +43,11 @@ class Logger {
|
|
|
45
43
|
}
|
|
46
44
|
writeToFile(message) {
|
|
47
45
|
try {
|
|
48
|
-
|
|
46
|
+
fs.appendFileSync(this.logFilePath, message);
|
|
49
47
|
}
|
|
50
48
|
catch (error) {
|
|
51
49
|
console.error('Error writing to log file:', error);
|
|
52
50
|
}
|
|
53
51
|
}
|
|
54
52
|
}
|
|
55
|
-
|
|
53
|
+
export const logger = Logger.getInstance();
|
|
@@ -1,19 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const node_child_process_1 = require("node:child_process");
|
|
4
|
-
function openUrl(url) {
|
|
1
|
+
import { exec } from 'node:child_process';
|
|
2
|
+
export default function openUrl(url) {
|
|
5
3
|
switch (process.platform) {
|
|
6
4
|
case 'darwin': {
|
|
7
|
-
|
|
5
|
+
exec(`open ${url}`);
|
|
8
6
|
break;
|
|
9
7
|
}
|
|
10
8
|
case 'win32': {
|
|
11
|
-
|
|
9
|
+
exec(`start ${url}`);
|
|
12
10
|
break;
|
|
13
11
|
}
|
|
14
12
|
default: {
|
|
15
|
-
|
|
13
|
+
exec(`xdg-open ${url}`);
|
|
16
14
|
}
|
|
17
15
|
}
|
|
18
16
|
}
|
|
19
|
-
exports.default = openUrl;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
interface GitHubUrlParts {
|
|
2
|
+
owner: string;
|
|
3
|
+
path?: string;
|
|
4
|
+
ref?: string;
|
|
5
|
+
repo: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Parse a GitHub URL or path into its components
|
|
9
|
+
* @param url The URL or path to parse
|
|
10
|
+
* @returns The parsed components
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseGitHubUrl(url: string): GitHubUrlParts;
|
|
13
|
+
/**
|
|
14
|
+
* Creates a giget-compatible string from GitHub URL parts
|
|
15
|
+
* @param parts The parsed GitHub URL parts
|
|
16
|
+
* @returns A string in the format 'gh:owner/repo#ref[/path]'
|
|
17
|
+
*/
|
|
18
|
+
export declare function createGigetString(parts: GitHubUrlParts): string;
|
|
19
|
+
export {};
|