directus-template-cli 0.7.0-beta.1 → 0.7.0-beta.2
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/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +41 -55
- package/dist/lib/init/index.d.ts +6 -1
- package/dist/lib/init/index.js +31 -12
- package/dist/lib/utils/animated-bunny.d.ts +2 -0
- package/dist/lib/utils/animated-bunny.js +71 -0
- package/dist/services/docker.js +9 -6
- package/oclif.manifest.json +1 -1
- package/package.json +5 -1
package/dist/commands/init.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ export default class InitCommand extends Command {
|
|
|
24
24
|
/**
|
|
25
25
|
* Interactive mode: prompts the user for each piece of info, with added template checks.
|
|
26
26
|
* @param flags - The flags passed to the command.
|
|
27
|
+
* @param args - The arguments passed to the command.
|
|
27
28
|
* @returns void
|
|
28
29
|
*/
|
|
29
30
|
private runInteractive;
|
package/dist/commands/init.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
+
const prompts_1 = require("@clack/prompts");
|
|
4
5
|
const core_1 = require("@oclif/core");
|
|
5
|
-
const
|
|
6
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
6
7
|
const node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
8
|
+
const constants_1 = require("../lib/constants");
|
|
7
9
|
const init_1 = require("../lib/init");
|
|
10
|
+
const animated_bunny_1 = require("../lib/utils/animated-bunny");
|
|
8
11
|
const github_1 = require("../services/github");
|
|
9
12
|
class InitCommand extends core_1.Command {
|
|
10
13
|
constructor() {
|
|
@@ -18,37 +21,44 @@ class InitCommand extends core_1.Command {
|
|
|
18
21
|
async run() {
|
|
19
22
|
const { args, flags } = await this.parse(InitCommand);
|
|
20
23
|
const typedFlags = flags;
|
|
24
|
+
const typedArgs = args;
|
|
21
25
|
// Set the target directory and create it if it doesn't exist
|
|
22
26
|
this.targetDir = node_path_1.default.resolve(args.directory);
|
|
23
27
|
// if (!fs.existsSync(this.targetDir)) {
|
|
24
28
|
// fs.mkdirSync(this.targetDir, {recursive: true})
|
|
25
29
|
// }
|
|
26
|
-
await (typedFlags.programmatic ? this.runProgrammatic(typedFlags) : this.runInteractive(typedFlags));
|
|
30
|
+
await (typedFlags.programmatic ? this.runProgrammatic(typedFlags) : this.runInteractive(typedFlags, typedArgs));
|
|
27
31
|
}
|
|
28
32
|
/**
|
|
29
33
|
* Interactive mode: prompts the user for each piece of info, with added template checks.
|
|
30
34
|
* @param flags - The flags passed to the command.
|
|
35
|
+
* @param args - The arguments passed to the command.
|
|
31
36
|
* @returns void
|
|
32
37
|
*/
|
|
33
|
-
async runInteractive(flags) {
|
|
34
|
-
|
|
38
|
+
async runInteractive(flags, args) {
|
|
39
|
+
await (0, animated_bunny_1.animatedBunny)('Let\'s create a new Directus project!');
|
|
40
|
+
(0, prompts_1.intro)(`${chalk_1.default.bgHex(constants_1.DIRECTUS_PURPLE).white.bold('Directus Template CLI 🐰')} - Create Project`);
|
|
35
41
|
// Create GitHub service
|
|
36
42
|
const github = (0, github_1.createGitHub)();
|
|
43
|
+
// If no dir is provided, ask for it
|
|
44
|
+
if (!args.directory || args.directory === '.') {
|
|
45
|
+
this.targetDir = await (0, prompts_1.text)({
|
|
46
|
+
message: 'Enter the directory to create the project in:',
|
|
47
|
+
placeholder: './my-directus-project',
|
|
48
|
+
}).then(ans => ans);
|
|
49
|
+
}
|
|
37
50
|
// 1. Fetch available templates
|
|
38
51
|
const availableTemplates = await github.getTemplates();
|
|
39
52
|
// 2. Prompt for template if not provided
|
|
40
53
|
let { template } = flags;
|
|
41
54
|
if (!template) {
|
|
42
|
-
template = await
|
|
43
|
-
|
|
44
|
-
{
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
},
|
|
50
|
-
])
|
|
51
|
-
.then(ans => ans.template);
|
|
55
|
+
template = await (0, prompts_1.select)({
|
|
56
|
+
message: 'Which Directus backend template would you like to use?',
|
|
57
|
+
options: availableTemplates.map(template => ({
|
|
58
|
+
label: template,
|
|
59
|
+
value: template,
|
|
60
|
+
})),
|
|
61
|
+
}).then(ans => ans);
|
|
52
62
|
}
|
|
53
63
|
// 3. Validate that the template exists, fetch subdirectories
|
|
54
64
|
let directories = await github.getTemplateDirectories(template);
|
|
@@ -66,55 +76,30 @@ class InitCommand extends core_1.Command {
|
|
|
66
76
|
// 4. If user hasn't specified a valid flags.frontend, ask from the list
|
|
67
77
|
let chosenFrontend = flags.frontend;
|
|
68
78
|
if (!chosenFrontend || !potentialFrontends.includes(chosenFrontend)) {
|
|
69
|
-
chosenFrontend = await
|
|
70
|
-
|
|
71
|
-
{
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
},
|
|
77
|
-
])
|
|
78
|
-
.then(ans => ans.chosenFrontend);
|
|
79
|
+
chosenFrontend = await (0, prompts_1.select)({
|
|
80
|
+
message: 'Which frontend framework do you want to use?',
|
|
81
|
+
options: potentialFrontends.map(frontend => ({
|
|
82
|
+
label: frontend,
|
|
83
|
+
value: frontend,
|
|
84
|
+
})),
|
|
85
|
+
}).then(ans => ans);
|
|
79
86
|
}
|
|
80
87
|
flags.frontend = chosenFrontend;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
// },
|
|
90
|
-
// ])
|
|
91
|
-
// if (installDocker) {
|
|
92
|
-
// ux.log('Please follow Docker\'s official instructions to install Docker, then re-run the init command.')
|
|
93
|
-
// this.exit(0)
|
|
94
|
-
// }
|
|
95
|
-
// }
|
|
96
|
-
const { installDeps } = await inquirer_1.default.prompt([
|
|
97
|
-
{
|
|
98
|
-
default: true,
|
|
99
|
-
message: 'Would you like to install project dependencies automatically?',
|
|
100
|
-
name: 'installDeps',
|
|
101
|
-
type: 'confirm',
|
|
102
|
-
},
|
|
103
|
-
]);
|
|
104
|
-
const { initGit } = await inquirer_1.default.prompt([
|
|
105
|
-
{
|
|
106
|
-
default: true,
|
|
107
|
-
message: 'Initialize a new Git repository?',
|
|
108
|
-
name: 'initGit',
|
|
109
|
-
type: 'confirm',
|
|
110
|
-
},
|
|
111
|
-
]);
|
|
88
|
+
const installDeps = await (0, prompts_1.confirm)({
|
|
89
|
+
initialValue: true,
|
|
90
|
+
message: 'Would you like to install project dependencies automatically?',
|
|
91
|
+
}).then(ans => ans);
|
|
92
|
+
const initGit = await (0, prompts_1.confirm)({
|
|
93
|
+
initialValue: true,
|
|
94
|
+
message: 'Initialize a new Git repository?',
|
|
95
|
+
}).then(ans => ans);
|
|
112
96
|
await (0, init_1.init)(this.targetDir, {
|
|
113
97
|
frontend: chosenFrontend,
|
|
114
98
|
gitInit: initGit,
|
|
115
99
|
installDeps,
|
|
116
100
|
template,
|
|
117
101
|
});
|
|
102
|
+
core_1.ux.exit(0);
|
|
118
103
|
}
|
|
119
104
|
/**
|
|
120
105
|
* Programmatic mode: relies on flags only, with checks for template existence and valid frontend.
|
|
@@ -144,6 +129,7 @@ class InitCommand extends core_1.Command {
|
|
|
144
129
|
installDeps: true,
|
|
145
130
|
template,
|
|
146
131
|
});
|
|
132
|
+
core_1.ux.exit(0);
|
|
147
133
|
}
|
|
148
134
|
}
|
|
149
135
|
InitCommand.args = {
|
package/dist/lib/init/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type DownloadTemplateResult } from 'giget';
|
|
1
2
|
interface InitFlags {
|
|
2
3
|
frontend?: string;
|
|
3
4
|
gitInit?: boolean;
|
|
@@ -5,5 +6,9 @@ interface InitFlags {
|
|
|
5
6
|
overrideDir?: boolean;
|
|
6
7
|
template?: string;
|
|
7
8
|
}
|
|
8
|
-
export declare function init(dir: string, flags: InitFlags): Promise<
|
|
9
|
+
export declare function init(dir: string, flags: InitFlags): Promise<{
|
|
10
|
+
directusDir: string;
|
|
11
|
+
frontendDir: string;
|
|
12
|
+
template: DownloadTemplateResult;
|
|
13
|
+
}>;
|
|
9
14
|
export {};
|
package/dist/lib/init/index.js
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.init = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
+
const prompts_1 = require("@clack/prompts");
|
|
5
6
|
const core_1 = require("@oclif/core");
|
|
7
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
6
8
|
const giget_1 = require("giget");
|
|
7
9
|
const glob_1 = require("glob");
|
|
8
10
|
const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
|
|
@@ -74,7 +76,9 @@ async function init(dir, flags) {
|
|
|
74
76
|
const healthCheckUrl = `${config_1.DIRECTUS_CONFIG.url}:${config_1.DIRECTUS_CONFIG.port}${config_1.DOCKER_CONFIG.healthCheckEndpoint}`;
|
|
75
77
|
await dockerService.waitForHealthy(healthCheckUrl);
|
|
76
78
|
const templatePath = node_path_1.default.join(directusDir, 'template');
|
|
77
|
-
|
|
79
|
+
// const s = spinner()
|
|
80
|
+
// s.start(`Attempting to apply template from: ${templatePath}`)
|
|
81
|
+
// ux.log(`Attempting to apply template from: ${templatePath}`)
|
|
78
82
|
await apply_1.default.run([
|
|
79
83
|
'--directusUrl=http://localhost:8055',
|
|
80
84
|
'-p',
|
|
@@ -82,6 +86,7 @@ async function init(dir, flags) {
|
|
|
82
86
|
'--userPassword=d1r3ctu5',
|
|
83
87
|
'--templateLocation=' + templatePath,
|
|
84
88
|
]);
|
|
89
|
+
// s.stop('Template applied!')
|
|
85
90
|
}
|
|
86
91
|
catch (error) {
|
|
87
92
|
core_1.ux.error('Failed to start Directus containers or apply template');
|
|
@@ -90,32 +95,41 @@ async function init(dir, flags) {
|
|
|
90
95
|
}
|
|
91
96
|
// Install dependencies for frontend if it exists
|
|
92
97
|
if (flags.installDeps && node_fs_1.default.existsSync(frontendDir)) {
|
|
93
|
-
|
|
98
|
+
const s = (0, prompts_1.spinner)();
|
|
99
|
+
s.start('Installing dependencies');
|
|
100
|
+
// ux.action.start('Installing dependencies')
|
|
94
101
|
try {
|
|
95
102
|
const packageManager = await (0, nypm_1.detectPackageManager)(frontendDir);
|
|
96
103
|
await (0, nypm_1.installDependencies)({
|
|
97
104
|
cwd: frontendDir,
|
|
98
105
|
packageManager,
|
|
106
|
+
silent: true,
|
|
99
107
|
});
|
|
100
108
|
}
|
|
101
109
|
catch (error) {
|
|
102
110
|
core_1.ux.warn('Failed to install dependencies');
|
|
103
111
|
throw error;
|
|
104
112
|
}
|
|
105
|
-
|
|
113
|
+
// ux.action.stop()
|
|
114
|
+
s.stop('Dependencies installed!');
|
|
106
115
|
}
|
|
107
116
|
// Initialize Git repo
|
|
108
117
|
if (flags.gitInit) {
|
|
109
|
-
|
|
118
|
+
const s = (0, prompts_1.spinner)();
|
|
119
|
+
s.start('Initializing git repository');
|
|
120
|
+
// ux.action.start('Initializing git repository')
|
|
110
121
|
await initGit(dir);
|
|
111
|
-
|
|
122
|
+
// ux.action.stop()
|
|
123
|
+
s.stop('Git repository initialized!');
|
|
112
124
|
}
|
|
113
125
|
// Finishing up
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
126
|
+
const relativeDir = node_path_1.default.relative(process.cwd(), dir);
|
|
127
|
+
const nextSteps = `- Directus is running on http://localhost:8055 \n- Navigate to your project directory using ${chalk_1.default.cyan(`cd ${relativeDir}`)} and start developing! \n- Review the \`./README.md\` file for next steps.`;
|
|
128
|
+
(0, prompts_1.note)(nextSteps, 'Next Steps');
|
|
129
|
+
// ux.log('You\'ll find the following directories in your project:')
|
|
130
|
+
// ux.log('• directus')
|
|
131
|
+
// ux.log(`• ${flags.frontend}`)
|
|
132
|
+
(0, prompts_1.outro)(`Problems? Join the community on Discord at ${chalk_1.default.underline(chalk_1.default.cyan('https://directus.chat'))}`);
|
|
119
133
|
}
|
|
120
134
|
catch (error) {
|
|
121
135
|
(0, catch_error_1.default)(error, {
|
|
@@ -124,6 +138,11 @@ async function init(dir, flags) {
|
|
|
124
138
|
logToFile: true,
|
|
125
139
|
});
|
|
126
140
|
}
|
|
141
|
+
return {
|
|
142
|
+
directusDir,
|
|
143
|
+
frontendDir,
|
|
144
|
+
template,
|
|
145
|
+
};
|
|
127
146
|
}
|
|
128
147
|
exports.init = init;
|
|
129
148
|
/**
|
|
@@ -133,10 +152,10 @@ exports.init = init;
|
|
|
133
152
|
*/
|
|
134
153
|
async function initGit(targetDir) {
|
|
135
154
|
try {
|
|
136
|
-
|
|
155
|
+
// ux.action.start('Initializing git repository')
|
|
137
156
|
const { execa } = await Promise.resolve().then(() => tslib_1.__importStar(require('execa')));
|
|
138
157
|
await execa('git', ['init'], { cwd: targetDir });
|
|
139
|
-
|
|
158
|
+
// ux.action.stop()
|
|
140
159
|
}
|
|
141
160
|
catch (error) {
|
|
142
161
|
(0, catch_error_1.default)(error, {
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.animatedBunny = exports.RANDOM_SAYINGS = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
6
|
+
const log_update_1 = tslib_1.__importDefault(require("log-update"));
|
|
7
|
+
const constants_1 = require("../constants");
|
|
8
|
+
exports.RANDOM_SAYINGS = [
|
|
9
|
+
'One does not simply write backends...',
|
|
10
|
+
'I don\'t always test my code, but when I do, I use production.',
|
|
11
|
+
'A wild Directus appears!',
|
|
12
|
+
'Error 418: I\'m a teapot. Just kidding, I\'m Directus and I\'ve got your backend covered.',
|
|
13
|
+
'I\'ll fix it later. Narrator: They didn\'t fix it later.',
|
|
14
|
+
];
|
|
15
|
+
async function animatedBunny(customMessage) {
|
|
16
|
+
const saying = customMessage || exports.RANDOM_SAYINGS[Math.floor(Math.random() * exports.RANDOM_SAYINGS.length)];
|
|
17
|
+
let typedSaying = '';
|
|
18
|
+
let blinkState = true;
|
|
19
|
+
let charIndex = 0;
|
|
20
|
+
let isCleanedUp = false;
|
|
21
|
+
const cleanup = () => {
|
|
22
|
+
if (isCleanedUp)
|
|
23
|
+
return;
|
|
24
|
+
isCleanedUp = true;
|
|
25
|
+
clearInterval(animation);
|
|
26
|
+
clearInterval(typing);
|
|
27
|
+
log_update_1.default.done();
|
|
28
|
+
};
|
|
29
|
+
// Ensure cleanup on process exit
|
|
30
|
+
process.on('exit', cleanup);
|
|
31
|
+
process.on('SIGINT', () => {
|
|
32
|
+
cleanup();
|
|
33
|
+
process.exit(0);
|
|
34
|
+
});
|
|
35
|
+
const updateFrame = () => {
|
|
36
|
+
if (isCleanedUp)
|
|
37
|
+
return;
|
|
38
|
+
const eyes = blinkState ? '• •' : '- -';
|
|
39
|
+
const frame = `
|
|
40
|
+
(\\(\\
|
|
41
|
+
( ${eyes}) ${chalk_1.default.dim('.')}${chalk_1.default.hex(constants_1.DIRECTUS_PINK).visible(`"${typedSaying}"`)}
|
|
42
|
+
o_(")(")
|
|
43
|
+
`;
|
|
44
|
+
(0, log_update_1.default)(frame);
|
|
45
|
+
};
|
|
46
|
+
const animation = setInterval(() => {
|
|
47
|
+
blinkState = !blinkState;
|
|
48
|
+
updateFrame();
|
|
49
|
+
}, 500);
|
|
50
|
+
const typing = setInterval(() => {
|
|
51
|
+
if (charIndex < saying.length) {
|
|
52
|
+
typedSaying += saying[charIndex];
|
|
53
|
+
charIndex++;
|
|
54
|
+
updateFrame();
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
clearInterval(typing);
|
|
58
|
+
}
|
|
59
|
+
}, 10);
|
|
60
|
+
try {
|
|
61
|
+
// Run the animation for the duration of typing plus 1 second
|
|
62
|
+
await new Promise(resolve => setTimeout(resolve, saying.length * 10 + 1000));
|
|
63
|
+
}
|
|
64
|
+
finally {
|
|
65
|
+
cleanup();
|
|
66
|
+
// Remove the event listeners
|
|
67
|
+
process.removeListener('exit', cleanup);
|
|
68
|
+
process.removeListener('SIGINT', cleanup);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
exports.animatedBunny = animatedBunny;
|
package/dist/services/docker.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createDocker = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const
|
|
5
|
+
const prompts_1 = require("@clack/prompts");
|
|
6
6
|
const execa_1 = require("execa");
|
|
7
7
|
const catch_error_1 = tslib_1.__importDefault(require("../lib/utils/catch-error"));
|
|
8
8
|
const wait_1 = require("../lib/utils/wait");
|
|
@@ -43,12 +43,14 @@ async function checkDocker() {
|
|
|
43
43
|
*/
|
|
44
44
|
function startContainers(cwd) {
|
|
45
45
|
try {
|
|
46
|
-
|
|
46
|
+
// ux.action.start('Starting Docker containers')
|
|
47
|
+
const s = (0, prompts_1.spinner)();
|
|
48
|
+
s.start('Starting Docker containers');
|
|
47
49
|
return (0, execa_1.execa)('docker-compose', ['up', '-d'], {
|
|
48
50
|
cwd,
|
|
49
51
|
// stdio: 'inherit',
|
|
50
52
|
}).then(() => {
|
|
51
|
-
|
|
53
|
+
s.stop('Docker containers running!');
|
|
52
54
|
});
|
|
53
55
|
}
|
|
54
56
|
catch (error) {
|
|
@@ -88,7 +90,8 @@ function stopContainers(cwd) {
|
|
|
88
90
|
*/
|
|
89
91
|
function createWaitForHealthy(config) {
|
|
90
92
|
async function waitForHealthy(healthCheckUrl) {
|
|
91
|
-
|
|
93
|
+
const s = (0, prompts_1.spinner)();
|
|
94
|
+
s.start('Waiting for Directus to be ready.');
|
|
92
95
|
try {
|
|
93
96
|
await (0, wait_1.waitFor)(async () => {
|
|
94
97
|
try {
|
|
@@ -103,11 +106,11 @@ function createWaitForHealthy(config) {
|
|
|
103
106
|
interval: config.interval,
|
|
104
107
|
maxAttempts: config.maxAttempts,
|
|
105
108
|
});
|
|
106
|
-
|
|
109
|
+
s.stop('Directus is ready!');
|
|
107
110
|
return true;
|
|
108
111
|
}
|
|
109
112
|
catch (error) {
|
|
110
|
-
|
|
113
|
+
s.stop('');
|
|
111
114
|
(0, catch_error_1.default)(error, {
|
|
112
115
|
context: { function: 'waitForHealthy', url: healthCheckUrl },
|
|
113
116
|
fatal: true,
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "directus-template-cli",
|
|
3
|
-
"version": "0.7.0-beta.
|
|
3
|
+
"version": "0.7.0-beta.2",
|
|
4
4
|
"description": "CLI Utility for applying templates to a Directus instance.",
|
|
5
5
|
"author": "bryantgillespie @bryantgillespie",
|
|
6
6
|
"bin": {
|
|
@@ -17,12 +17,14 @@
|
|
|
17
17
|
"/oclif.manifest.json"
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
|
+
"@clack/prompts": "^0.10.0",
|
|
20
21
|
"@directus/sdk": "^17.0.1",
|
|
21
22
|
"@oclif/core": "^3.18.1",
|
|
22
23
|
"@oclif/plugin-help": "^6.0.12",
|
|
23
24
|
"@oclif/plugin-plugins": "^4.1.22",
|
|
24
25
|
"@octokit/rest": "^21.1.1",
|
|
25
26
|
"bottleneck": "^2.19.5",
|
|
27
|
+
"chalk": "^5.4.1",
|
|
26
28
|
"defu": "^6.1.4",
|
|
27
29
|
"dotenv": "^16.4.1",
|
|
28
30
|
"execa": "^9.5.2",
|
|
@@ -30,7 +32,9 @@
|
|
|
30
32
|
"giget": "^1.2.1",
|
|
31
33
|
"glob": "^11.0.1",
|
|
32
34
|
"inquirer": "^8.2.5",
|
|
35
|
+
"log-update": "^6.1.0",
|
|
33
36
|
"nypm": "^0.5.2",
|
|
37
|
+
"picocolors": "^1.1.1",
|
|
34
38
|
"pkg-types": "^1.3.1",
|
|
35
39
|
"slugify": "^1.6.6"
|
|
36
40
|
},
|