create-moost 0.2.32
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 +1 -0
- package/bin.js +4 -0
- package/dist/index.cjs +343 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +341 -0
- package/package.json +41 -0
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# create-moost
|
package/bin.js
ADDED
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var moost = require('moost');
|
|
4
|
+
var eventCli = require('@moostjs/event-cli');
|
|
5
|
+
var eventCli$1 = require('@wooksjs/event-cli');
|
|
6
|
+
var fs = require('fs');
|
|
7
|
+
var prompts = require('prompts');
|
|
8
|
+
var rewrite = require('@prostojs/rewrite');
|
|
9
|
+
var path = require('path');
|
|
10
|
+
|
|
11
|
+
/******************************************************************************
|
|
12
|
+
Copyright (c) Microsoft Corporation.
|
|
13
|
+
|
|
14
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
15
|
+
purpose with or without fee is hereby granted.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
18
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
19
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
20
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
21
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
22
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
23
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
24
|
+
***************************************************************************** */
|
|
25
|
+
/* global Reflect, Promise */
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
function __decorate(decorators, target, key, desc) {
|
|
29
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
30
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
31
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
32
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function __param(paramIndex, decorator) {
|
|
36
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function __metadata(metadataKey, metadataValue) {
|
|
40
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
44
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
45
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
46
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
47
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
48
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
49
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const defaultProjectName = 'moost-app';
|
|
54
|
+
function getPrompts(inputs) {
|
|
55
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
56
|
+
const predefined = {
|
|
57
|
+
targetDir: inputs.name || '',
|
|
58
|
+
projectName: inputs.name || '',
|
|
59
|
+
packageName: inputs.name || '',
|
|
60
|
+
prettier: !!inputs.prettier,
|
|
61
|
+
eslint: !!inputs.eslint,
|
|
62
|
+
};
|
|
63
|
+
try {
|
|
64
|
+
const results = yield prompts([
|
|
65
|
+
{
|
|
66
|
+
name: 'projectName',
|
|
67
|
+
type: predefined.targetDir ? null : 'text',
|
|
68
|
+
message: 'Project name:',
|
|
69
|
+
initial: defaultProjectName,
|
|
70
|
+
onState: (state) => (predefined.targetDir =
|
|
71
|
+
String(state.value).trim() || defaultProjectName),
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: 'overwrite',
|
|
75
|
+
type: () => canSkipEmptying(predefined.targetDir) || inputs.force
|
|
76
|
+
? null
|
|
77
|
+
: 'confirm',
|
|
78
|
+
message: () => {
|
|
79
|
+
const dirForPrompt = predefined.targetDir === '.'
|
|
80
|
+
? 'Current directory'
|
|
81
|
+
: `Target directory "${predefined.targetDir}"`;
|
|
82
|
+
return `${dirForPrompt} is not empty. Remove existing files and continue?`;
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: 'overwriteChecker',
|
|
87
|
+
type: (prev, values) => {
|
|
88
|
+
if (values.overwrite === false) {
|
|
89
|
+
throw new Error('Operation cancelled');
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: 'type',
|
|
96
|
+
type: () => {
|
|
97
|
+
if (inputs.cli && !inputs.http) {
|
|
98
|
+
predefined.type = 'cli';
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
if (!inputs.cli && inputs.http) {
|
|
102
|
+
predefined.type = 'http';
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
return 'select';
|
|
106
|
+
},
|
|
107
|
+
message: 'Moost Adapter:',
|
|
108
|
+
choices: [
|
|
109
|
+
{ title: 'HTTP (Web) Application', value: 'http' },
|
|
110
|
+
{ title: 'CLI Application', value: 'cli' },
|
|
111
|
+
],
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: 'bundler',
|
|
115
|
+
type: () => {
|
|
116
|
+
if (inputs.esbuild && !inputs.rollup) {
|
|
117
|
+
predefined.bundler = 'esbuild';
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
if (!inputs.esbuild && inputs.rollup) {
|
|
121
|
+
predefined.bundler = 'rollup';
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
return 'select';
|
|
125
|
+
},
|
|
126
|
+
message: 'Bundler:',
|
|
127
|
+
choices: [
|
|
128
|
+
{ title: 'ESBuild (with nodemon for dev)', value: 'esbuild' },
|
|
129
|
+
{ title: 'Rollup', value: 'rollup' },
|
|
130
|
+
],
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: 'packageName',
|
|
134
|
+
type: () => (isValidPackageName(predefined.targetDir) ? null : 'text'),
|
|
135
|
+
message: 'Package name:',
|
|
136
|
+
initial: () => toValidPackageName(predefined.targetDir),
|
|
137
|
+
validate: (dir) => isValidPackageName(dir) || 'Invalid package.json name',
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: 'eslint',
|
|
141
|
+
type: () => (inputs.eslint ? null : 'toggle'),
|
|
142
|
+
message: 'Add ESLint for code quality?',
|
|
143
|
+
initial: false,
|
|
144
|
+
active: 'Yes',
|
|
145
|
+
inactive: 'No',
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
name: 'prettier',
|
|
149
|
+
type: (prev, values) => {
|
|
150
|
+
if (!values.eslint) {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
return 'toggle';
|
|
154
|
+
},
|
|
155
|
+
message: 'Add Prettier for code formatting?',
|
|
156
|
+
initial: false,
|
|
157
|
+
active: 'Yes',
|
|
158
|
+
inactive: 'No',
|
|
159
|
+
},
|
|
160
|
+
], {
|
|
161
|
+
onCancel: () => {
|
|
162
|
+
throw new Error('Operation cancelled');
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
return Object.assign(Object.assign(Object.assign({}, predefined), results), { packageName: (results.packageName || results.targetDir || predefined.targetDir) });
|
|
166
|
+
}
|
|
167
|
+
catch (e) {
|
|
168
|
+
console.log(e.message);
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
function canSkipEmptying(dir) {
|
|
174
|
+
if (!fs.existsSync(dir)) {
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
const files = fs.readdirSync(dir);
|
|
178
|
+
if (files.length === 0) {
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
if (files.length === 1 && files[0] === '.git') {
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
function isValidPackageName(projectName) {
|
|
187
|
+
return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(projectName);
|
|
188
|
+
}
|
|
189
|
+
function toValidPackageName(projectName) {
|
|
190
|
+
return projectName
|
|
191
|
+
.trim()
|
|
192
|
+
.toLowerCase()
|
|
193
|
+
.replace(/\s+/g, '-')
|
|
194
|
+
.replace(/^[._]/, '')
|
|
195
|
+
.replace(/[^a-z0-9-~]+/g, '-');
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const rw = new rewrite.ProstoRewrite({
|
|
199
|
+
textPattern: [
|
|
200
|
+
'*.{js,jsx,ts,tsx,txt,json,yml,yaml,md,ini}',
|
|
201
|
+
'Dockerfile',
|
|
202
|
+
'*config',
|
|
203
|
+
'.gitignore',
|
|
204
|
+
'.eslintrc.json',
|
|
205
|
+
'.prettierignore',
|
|
206
|
+
'.prettierrc',
|
|
207
|
+
],
|
|
208
|
+
});
|
|
209
|
+
const root = process.cwd();
|
|
210
|
+
const { version } = JSON.parse(fs.readFileSync(path.join(__dirname, '../package.json')).toString());
|
|
211
|
+
function scaffold(data) {
|
|
212
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
213
|
+
const projectDir = path.join(root, data.targetDir);
|
|
214
|
+
if (fs.existsSync(projectDir)) {
|
|
215
|
+
if (data.overwrite) {
|
|
216
|
+
emptyDirectorySync(projectDir);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
fs.mkdirSync(projectDir);
|
|
221
|
+
}
|
|
222
|
+
const templatePath = path.join(__dirname, '../templates', data.type);
|
|
223
|
+
const commonPath = path.join(__dirname, '../templates/common');
|
|
224
|
+
const context = Object.assign(Object.assign({}, data), { version });
|
|
225
|
+
const excludeCommon = [];
|
|
226
|
+
if (!data.eslint) {
|
|
227
|
+
excludeCommon.push('.eslintrc.json');
|
|
228
|
+
}
|
|
229
|
+
if (!data.prettier) {
|
|
230
|
+
excludeCommon.push('.prettierignore');
|
|
231
|
+
excludeCommon.push('.prettierrc');
|
|
232
|
+
}
|
|
233
|
+
if (data.bundler !== 'rollup') {
|
|
234
|
+
excludeCommon.push('rollup.config.js');
|
|
235
|
+
}
|
|
236
|
+
yield rw.rewriteDir({
|
|
237
|
+
baseDir: templatePath,
|
|
238
|
+
output: projectDir,
|
|
239
|
+
}, context);
|
|
240
|
+
yield rw.rewriteDir({
|
|
241
|
+
baseDir: commonPath,
|
|
242
|
+
output: projectDir,
|
|
243
|
+
exclude: excludeCommon,
|
|
244
|
+
}, context);
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
function emptyDirectorySync(directory) {
|
|
248
|
+
if (fs.existsSync(directory)) {
|
|
249
|
+
fs.readdirSync(directory).forEach((file) => {
|
|
250
|
+
const currentPath = path.join(directory, file);
|
|
251
|
+
if (fs.lstatSync(currentPath).isDirectory()) {
|
|
252
|
+
// Recurse if the current path is a directory
|
|
253
|
+
emptyDirectorySync(currentPath);
|
|
254
|
+
fs.rmdirSync(currentPath); // Remove the empty directory
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
// Delete file
|
|
258
|
+
fs.unlinkSync(currentPath);
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
let CliController = class CliController extends moost.Moost {
|
|
265
|
+
root() {
|
|
266
|
+
return this.execute();
|
|
267
|
+
}
|
|
268
|
+
withName(name) {
|
|
269
|
+
return this.execute(name);
|
|
270
|
+
}
|
|
271
|
+
execute(name) {
|
|
272
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
273
|
+
eventCli$1.useAutoHelp() && process.exit(0);
|
|
274
|
+
const prompts = yield getPrompts({
|
|
275
|
+
name,
|
|
276
|
+
eslint: !!eventCli$1.useCliOption('eslint'),
|
|
277
|
+
prettier: !!eventCli$1.useCliOption('prettier'),
|
|
278
|
+
http: !!eventCli$1.useCliOption('http'),
|
|
279
|
+
cli: !!eventCli$1.useCliOption('cli'),
|
|
280
|
+
force: !!eventCli$1.useCliOption('force'),
|
|
281
|
+
esbuild: !!eventCli$1.useCliOption('esbuild'),
|
|
282
|
+
rollup: !!eventCli$1.useCliOption('rollup'),
|
|
283
|
+
});
|
|
284
|
+
console.log('\nScaffolding a new project...');
|
|
285
|
+
yield scaffold(prompts);
|
|
286
|
+
const cli = prompts.type === 'cli';
|
|
287
|
+
return `
|
|
288
|
+
${'[97m' + '[1m'}Success! ${'[22m'}Your new "${prompts.projectName}" project has been created successfully. ${'[39m'}
|
|
289
|
+
|
|
290
|
+
Follow these next steps to start your development server:
|
|
291
|
+
|
|
292
|
+
1. Navigate to your new project:
|
|
293
|
+
${'[36m'}cd ${prompts.targetDir} ${'[39m'}
|
|
294
|
+
|
|
295
|
+
2. Install the dependencies:
|
|
296
|
+
${'[36m'}npm install ${'[39m'}
|
|
297
|
+
${cli ? `
|
|
298
|
+
3. Make bin.js executable:
|
|
299
|
+
${'[36m'}chmod +x ./bin.js ${'[39m'}
|
|
300
|
+
` : ''}
|
|
301
|
+
${cli ? '4' : '3'}. Start the development server:
|
|
302
|
+
${'[36m'}npm run dev${cli ? ' -- hello World' : ''}${'[39m'}
|
|
303
|
+
|
|
304
|
+
${'[32m'}You're all set! The development server will help you in building your application.
|
|
305
|
+
Enjoy coding, and build something amazing!${'[39m'}
|
|
306
|
+
`;
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
__decorate([
|
|
311
|
+
eventCli.Cli(''),
|
|
312
|
+
__metadata("design:type", Function),
|
|
313
|
+
__metadata("design:paramtypes", []),
|
|
314
|
+
__metadata("design:returntype", void 0)
|
|
315
|
+
], CliController.prototype, "root", null);
|
|
316
|
+
__decorate([
|
|
317
|
+
eventCli.Cli(':name'),
|
|
318
|
+
__param(0, moost.Param('name')),
|
|
319
|
+
__metadata("design:type", Function),
|
|
320
|
+
__metadata("design:paramtypes", [String]),
|
|
321
|
+
__metadata("design:returntype", void 0)
|
|
322
|
+
], CliController.prototype, "withName", null);
|
|
323
|
+
CliController = __decorate([
|
|
324
|
+
moost.Controller()
|
|
325
|
+
], CliController);
|
|
326
|
+
function run() {
|
|
327
|
+
const app = new CliController();
|
|
328
|
+
app.adapter(new eventCli.MoostCli({
|
|
329
|
+
globalCliOptions: [
|
|
330
|
+
// { keys: ['ts'], description: '' },
|
|
331
|
+
{ keys: ['http'], description: 'Use Moost HTTP' },
|
|
332
|
+
{ keys: ['cli'], description: 'Use Moost CLI' },
|
|
333
|
+
{ keys: ['eslint'], description: 'Add ESLint' },
|
|
334
|
+
{ keys: ['prettier'], description: 'Add Prettier' },
|
|
335
|
+
{ keys: ['force'], description: 'Force Overwrite' },
|
|
336
|
+
{ keys: ['esbuild'], description: 'Use esbuild for builds' },
|
|
337
|
+
{ keys: ['rollup'], description: 'Use rollup for builds' },
|
|
338
|
+
],
|
|
339
|
+
}));
|
|
340
|
+
void app.init();
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
exports.run = run;
|
package/dist/index.d.ts
ADDED
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
import { Param, Controller, Moost } from 'moost';
|
|
2
|
+
import { Cli, MoostCli } from '@moostjs/event-cli';
|
|
3
|
+
import { useAutoHelp, useCliOption } from '@wooksjs/event-cli';
|
|
4
|
+
import { existsSync, readdirSync, readFileSync, mkdirSync, lstatSync, rmdirSync, unlinkSync } from 'fs';
|
|
5
|
+
import prompts from 'prompts';
|
|
6
|
+
import { ProstoRewrite } from '@prostojs/rewrite';
|
|
7
|
+
import { join } from 'path';
|
|
8
|
+
|
|
9
|
+
/******************************************************************************
|
|
10
|
+
Copyright (c) Microsoft Corporation.
|
|
11
|
+
|
|
12
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
13
|
+
purpose with or without fee is hereby granted.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
16
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
17
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
18
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
19
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
20
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
21
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
22
|
+
***************************************************************************** */
|
|
23
|
+
/* global Reflect, Promise */
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
function __decorate(decorators, target, key, desc) {
|
|
27
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
28
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
29
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
30
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function __param(paramIndex, decorator) {
|
|
34
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function __metadata(metadataKey, metadataValue) {
|
|
38
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
42
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
43
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
44
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
45
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
46
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
47
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const defaultProjectName = 'moost-app';
|
|
52
|
+
function getPrompts(inputs) {
|
|
53
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
54
|
+
const predefined = {
|
|
55
|
+
targetDir: inputs.name || '',
|
|
56
|
+
projectName: inputs.name || '',
|
|
57
|
+
packageName: inputs.name || '',
|
|
58
|
+
prettier: !!inputs.prettier,
|
|
59
|
+
eslint: !!inputs.eslint,
|
|
60
|
+
};
|
|
61
|
+
try {
|
|
62
|
+
const results = yield prompts([
|
|
63
|
+
{
|
|
64
|
+
name: 'projectName',
|
|
65
|
+
type: predefined.targetDir ? null : 'text',
|
|
66
|
+
message: 'Project name:',
|
|
67
|
+
initial: defaultProjectName,
|
|
68
|
+
onState: (state) => (predefined.targetDir =
|
|
69
|
+
String(state.value).trim() || defaultProjectName),
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: 'overwrite',
|
|
73
|
+
type: () => canSkipEmptying(predefined.targetDir) || inputs.force
|
|
74
|
+
? null
|
|
75
|
+
: 'confirm',
|
|
76
|
+
message: () => {
|
|
77
|
+
const dirForPrompt = predefined.targetDir === '.'
|
|
78
|
+
? 'Current directory'
|
|
79
|
+
: `Target directory "${predefined.targetDir}"`;
|
|
80
|
+
return `${dirForPrompt} is not empty. Remove existing files and continue?`;
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'overwriteChecker',
|
|
85
|
+
type: (prev, values) => {
|
|
86
|
+
if (values.overwrite === false) {
|
|
87
|
+
throw new Error('Operation cancelled');
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
name: 'type',
|
|
94
|
+
type: () => {
|
|
95
|
+
if (inputs.cli && !inputs.http) {
|
|
96
|
+
predefined.type = 'cli';
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
if (!inputs.cli && inputs.http) {
|
|
100
|
+
predefined.type = 'http';
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
return 'select';
|
|
104
|
+
},
|
|
105
|
+
message: 'Moost Adapter:',
|
|
106
|
+
choices: [
|
|
107
|
+
{ title: 'HTTP (Web) Application', value: 'http' },
|
|
108
|
+
{ title: 'CLI Application', value: 'cli' },
|
|
109
|
+
],
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: 'bundler',
|
|
113
|
+
type: () => {
|
|
114
|
+
if (inputs.esbuild && !inputs.rollup) {
|
|
115
|
+
predefined.bundler = 'esbuild';
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
if (!inputs.esbuild && inputs.rollup) {
|
|
119
|
+
predefined.bundler = 'rollup';
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
return 'select';
|
|
123
|
+
},
|
|
124
|
+
message: 'Bundler:',
|
|
125
|
+
choices: [
|
|
126
|
+
{ title: 'ESBuild (with nodemon for dev)', value: 'esbuild' },
|
|
127
|
+
{ title: 'Rollup', value: 'rollup' },
|
|
128
|
+
],
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
name: 'packageName',
|
|
132
|
+
type: () => (isValidPackageName(predefined.targetDir) ? null : 'text'),
|
|
133
|
+
message: 'Package name:',
|
|
134
|
+
initial: () => toValidPackageName(predefined.targetDir),
|
|
135
|
+
validate: (dir) => isValidPackageName(dir) || 'Invalid package.json name',
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: 'eslint',
|
|
139
|
+
type: () => (inputs.eslint ? null : 'toggle'),
|
|
140
|
+
message: 'Add ESLint for code quality?',
|
|
141
|
+
initial: false,
|
|
142
|
+
active: 'Yes',
|
|
143
|
+
inactive: 'No',
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
name: 'prettier',
|
|
147
|
+
type: (prev, values) => {
|
|
148
|
+
if (!values.eslint) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
return 'toggle';
|
|
152
|
+
},
|
|
153
|
+
message: 'Add Prettier for code formatting?',
|
|
154
|
+
initial: false,
|
|
155
|
+
active: 'Yes',
|
|
156
|
+
inactive: 'No',
|
|
157
|
+
},
|
|
158
|
+
], {
|
|
159
|
+
onCancel: () => {
|
|
160
|
+
throw new Error('Operation cancelled');
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
return Object.assign(Object.assign(Object.assign({}, predefined), results), { packageName: (results.packageName || results.targetDir || predefined.targetDir) });
|
|
164
|
+
}
|
|
165
|
+
catch (e) {
|
|
166
|
+
console.log(e.message);
|
|
167
|
+
process.exit(1);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
function canSkipEmptying(dir) {
|
|
172
|
+
if (!existsSync(dir)) {
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
const files = readdirSync(dir);
|
|
176
|
+
if (files.length === 0) {
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
if (files.length === 1 && files[0] === '.git') {
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
function isValidPackageName(projectName) {
|
|
185
|
+
return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(projectName);
|
|
186
|
+
}
|
|
187
|
+
function toValidPackageName(projectName) {
|
|
188
|
+
return projectName
|
|
189
|
+
.trim()
|
|
190
|
+
.toLowerCase()
|
|
191
|
+
.replace(/\s+/g, '-')
|
|
192
|
+
.replace(/^[._]/, '')
|
|
193
|
+
.replace(/[^a-z0-9-~]+/g, '-');
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const rw = new ProstoRewrite({
|
|
197
|
+
textPattern: [
|
|
198
|
+
'*.{js,jsx,ts,tsx,txt,json,yml,yaml,md,ini}',
|
|
199
|
+
'Dockerfile',
|
|
200
|
+
'*config',
|
|
201
|
+
'.gitignore',
|
|
202
|
+
'.eslintrc.json',
|
|
203
|
+
'.prettierignore',
|
|
204
|
+
'.prettierrc',
|
|
205
|
+
],
|
|
206
|
+
});
|
|
207
|
+
const root = process.cwd();
|
|
208
|
+
const { version } = JSON.parse(readFileSync(join(__dirname, '../package.json')).toString());
|
|
209
|
+
function scaffold(data) {
|
|
210
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
211
|
+
const projectDir = join(root, data.targetDir);
|
|
212
|
+
if (existsSync(projectDir)) {
|
|
213
|
+
if (data.overwrite) {
|
|
214
|
+
emptyDirectorySync(projectDir);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
mkdirSync(projectDir);
|
|
219
|
+
}
|
|
220
|
+
const templatePath = join(__dirname, '../templates', data.type);
|
|
221
|
+
const commonPath = join(__dirname, '../templates/common');
|
|
222
|
+
const context = Object.assign(Object.assign({}, data), { version });
|
|
223
|
+
const excludeCommon = [];
|
|
224
|
+
if (!data.eslint) {
|
|
225
|
+
excludeCommon.push('.eslintrc.json');
|
|
226
|
+
}
|
|
227
|
+
if (!data.prettier) {
|
|
228
|
+
excludeCommon.push('.prettierignore');
|
|
229
|
+
excludeCommon.push('.prettierrc');
|
|
230
|
+
}
|
|
231
|
+
if (data.bundler !== 'rollup') {
|
|
232
|
+
excludeCommon.push('rollup.config.js');
|
|
233
|
+
}
|
|
234
|
+
yield rw.rewriteDir({
|
|
235
|
+
baseDir: templatePath,
|
|
236
|
+
output: projectDir,
|
|
237
|
+
}, context);
|
|
238
|
+
yield rw.rewriteDir({
|
|
239
|
+
baseDir: commonPath,
|
|
240
|
+
output: projectDir,
|
|
241
|
+
exclude: excludeCommon,
|
|
242
|
+
}, context);
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
function emptyDirectorySync(directory) {
|
|
246
|
+
if (existsSync(directory)) {
|
|
247
|
+
readdirSync(directory).forEach((file) => {
|
|
248
|
+
const currentPath = join(directory, file);
|
|
249
|
+
if (lstatSync(currentPath).isDirectory()) {
|
|
250
|
+
// Recurse if the current path is a directory
|
|
251
|
+
emptyDirectorySync(currentPath);
|
|
252
|
+
rmdirSync(currentPath); // Remove the empty directory
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
// Delete file
|
|
256
|
+
unlinkSync(currentPath);
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
let CliController = class CliController extends Moost {
|
|
263
|
+
root() {
|
|
264
|
+
return this.execute();
|
|
265
|
+
}
|
|
266
|
+
withName(name) {
|
|
267
|
+
return this.execute(name);
|
|
268
|
+
}
|
|
269
|
+
execute(name) {
|
|
270
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
271
|
+
useAutoHelp() && process.exit(0);
|
|
272
|
+
const prompts = yield getPrompts({
|
|
273
|
+
name,
|
|
274
|
+
eslint: !!useCliOption('eslint'),
|
|
275
|
+
prettier: !!useCliOption('prettier'),
|
|
276
|
+
http: !!useCliOption('http'),
|
|
277
|
+
cli: !!useCliOption('cli'),
|
|
278
|
+
force: !!useCliOption('force'),
|
|
279
|
+
esbuild: !!useCliOption('esbuild'),
|
|
280
|
+
rollup: !!useCliOption('rollup'),
|
|
281
|
+
});
|
|
282
|
+
console.log('\nScaffolding a new project...');
|
|
283
|
+
yield scaffold(prompts);
|
|
284
|
+
const cli = prompts.type === 'cli';
|
|
285
|
+
return `
|
|
286
|
+
${'[97m' + '[1m'}Success! ${'[22m'}Your new "${prompts.projectName}" project has been created successfully. ${'[39m'}
|
|
287
|
+
|
|
288
|
+
Follow these next steps to start your development server:
|
|
289
|
+
|
|
290
|
+
1. Navigate to your new project:
|
|
291
|
+
${'[36m'}cd ${prompts.targetDir} ${'[39m'}
|
|
292
|
+
|
|
293
|
+
2. Install the dependencies:
|
|
294
|
+
${'[36m'}npm install ${'[39m'}
|
|
295
|
+
${cli ? `
|
|
296
|
+
3. Make bin.js executable:
|
|
297
|
+
${'[36m'}chmod +x ./bin.js ${'[39m'}
|
|
298
|
+
` : ''}
|
|
299
|
+
${cli ? '4' : '3'}. Start the development server:
|
|
300
|
+
${'[36m'}npm run dev${cli ? ' -- hello World' : ''}${'[39m'}
|
|
301
|
+
|
|
302
|
+
${'[32m'}You're all set! The development server will help you in building your application.
|
|
303
|
+
Enjoy coding, and build something amazing!${'[39m'}
|
|
304
|
+
`;
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
__decorate([
|
|
309
|
+
Cli(''),
|
|
310
|
+
__metadata("design:type", Function),
|
|
311
|
+
__metadata("design:paramtypes", []),
|
|
312
|
+
__metadata("design:returntype", void 0)
|
|
313
|
+
], CliController.prototype, "root", null);
|
|
314
|
+
__decorate([
|
|
315
|
+
Cli(':name'),
|
|
316
|
+
__param(0, Param('name')),
|
|
317
|
+
__metadata("design:type", Function),
|
|
318
|
+
__metadata("design:paramtypes", [String]),
|
|
319
|
+
__metadata("design:returntype", void 0)
|
|
320
|
+
], CliController.prototype, "withName", null);
|
|
321
|
+
CliController = __decorate([
|
|
322
|
+
Controller()
|
|
323
|
+
], CliController);
|
|
324
|
+
function run() {
|
|
325
|
+
const app = new CliController();
|
|
326
|
+
app.adapter(new MoostCli({
|
|
327
|
+
globalCliOptions: [
|
|
328
|
+
// { keys: ['ts'], description: '' },
|
|
329
|
+
{ keys: ['http'], description: 'Use Moost HTTP' },
|
|
330
|
+
{ keys: ['cli'], description: 'Use Moost CLI' },
|
|
331
|
+
{ keys: ['eslint'], description: 'Add ESLint' },
|
|
332
|
+
{ keys: ['prettier'], description: 'Add Prettier' },
|
|
333
|
+
{ keys: ['force'], description: 'Force Overwrite' },
|
|
334
|
+
{ keys: ['esbuild'], description: 'Use esbuild for builds' },
|
|
335
|
+
{ keys: ['rollup'], description: 'Use rollup for builds' },
|
|
336
|
+
],
|
|
337
|
+
}));
|
|
338
|
+
void app.init();
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export { run };
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-moost",
|
|
3
|
+
"version": "0.2.32",
|
|
4
|
+
"description": "create-moost",
|
|
5
|
+
"main": "dist/index.cjs",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"create-moost": "./bin.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"bin.js"
|
|
14
|
+
],
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/moostjs/moostjs.git",
|
|
18
|
+
"directory": "packages/create-moost"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"moost",
|
|
22
|
+
"moostjs",
|
|
23
|
+
"composables",
|
|
24
|
+
"framework",
|
|
25
|
+
"wooksjs",
|
|
26
|
+
"prostojs"
|
|
27
|
+
],
|
|
28
|
+
"author": "Artem Maltsev",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/moostjs/moostjs/issues"
|
|
32
|
+
},
|
|
33
|
+
"homepage": "https://github.com/moostjs/moostjs/tree/main/packages/create-moost#readme",
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@moostjs/event-cli": "0.2.32",
|
|
36
|
+
"@wooksjs/event-cli": "^0.3.3",
|
|
37
|
+
"@prostojs/rewrite": "^0.0.4",
|
|
38
|
+
"moost": "0.2.32",
|
|
39
|
+
"prompts": "^2.4.2"
|
|
40
|
+
}
|
|
41
|
+
}
|