create-nattyjs 0.0.1-beta.39
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/index.js +316 -0
- package/package.json +31 -0
- package/template-nattyjs-blank/app.ts +7 -0
- package/template-nattyjs-blank/controllers/requests.controller.ts +26 -0
- package/template-nattyjs-blank/natty.config.ts +5 -0
- package/template-nattyjs-blank/package.json +24 -0
- package/template-nattyjs-blank/tsconfig.json +21 -0
package/index.js
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'fs'
|
|
3
|
+
import path from 'path'
|
|
4
|
+
import minimist from 'minimist'
|
|
5
|
+
const argv = minimist(process.argv.slice(2), { string: ['_'] });
|
|
6
|
+
import prompts from 'prompts'
|
|
7
|
+
import {execa} from 'execa'
|
|
8
|
+
import {fileURLToPath} from 'url';
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
yellow,
|
|
12
|
+
green,
|
|
13
|
+
blue,
|
|
14
|
+
red,
|
|
15
|
+
reset
|
|
16
|
+
} from 'kolorist';
|
|
17
|
+
import { bold } from 'kleur/colors';
|
|
18
|
+
|
|
19
|
+
import chalk from 'chalk';
|
|
20
|
+
import ora from 'ora';
|
|
21
|
+
|
|
22
|
+
const gradients = [
|
|
23
|
+
`#00FF97`,
|
|
24
|
+
`#29FF8F`,
|
|
25
|
+
`#58FF38`,
|
|
26
|
+
`#3BFF24`,
|
|
27
|
+
`#93FF05`,
|
|
28
|
+
`#4EFF00`,
|
|
29
|
+
`#6FF500`,
|
|
30
|
+
`#14E684`,
|
|
31
|
+
`#36D629`,
|
|
32
|
+
`#38C266`,
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
export const arrow = '■■▶';
|
|
36
|
+
|
|
37
|
+
const gradientRefrences = [
|
|
38
|
+
...gradients,
|
|
39
|
+
...[...gradients].reverse(),
|
|
40
|
+
...gradients,
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
const sleepProcess = (time) =>
|
|
45
|
+
new Promise((resolve) => {
|
|
46
|
+
setTimeout(resolve, time);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
function getInstallAnimationFrames() {
|
|
50
|
+
const animationFrames = [];
|
|
51
|
+
for (let i = 0; i < gradients.length * 2; i++) {
|
|
52
|
+
const end = i + gradients.length - 1;
|
|
53
|
+
animationFrames.push(
|
|
54
|
+
gradientRefrences
|
|
55
|
+
.slice(i, end)
|
|
56
|
+
.map((g) => chalk.bgHex(g)(' '))
|
|
57
|
+
.join('')
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
return animationFrames;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function getAnimationFrames() {
|
|
64
|
+
const animationFrames = [];
|
|
65
|
+
for (let i = 1; i <= gradients.length; i++) {
|
|
66
|
+
const spaces = Array.from(
|
|
67
|
+
new Array(Math.abs(gradients.length - i - 1)),
|
|
68
|
+
() => ' '
|
|
69
|
+
);
|
|
70
|
+
const gradientColors = gradients.slice(0, i).map((item) => chalk.bgHex(item)(' '));
|
|
71
|
+
animationFrames.push([...spaces, ...gradientColors].join(''));
|
|
72
|
+
}
|
|
73
|
+
return animationFrames;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
async function showSpinner(text) {
|
|
78
|
+
const animationFrames = getAnimationFrames();
|
|
79
|
+
const startSpinner = ora({
|
|
80
|
+
spinner: {
|
|
81
|
+
interval: 30,
|
|
82
|
+
frames:animationFrames,
|
|
83
|
+
},
|
|
84
|
+
text: `${arrow} ${text}`,
|
|
85
|
+
});
|
|
86
|
+
startSpinner.start();
|
|
87
|
+
await sleepProcess((animationFrames.length - 1) * startSpinner.interval);
|
|
88
|
+
startSpinner.stop();
|
|
89
|
+
const spinner = ora({
|
|
90
|
+
spinner: {
|
|
91
|
+
interval: 80,
|
|
92
|
+
frames: getInstallAnimationFrames(),
|
|
93
|
+
},
|
|
94
|
+
text: `${arrow} ${text}`,
|
|
95
|
+
}).start();
|
|
96
|
+
|
|
97
|
+
return spinner;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const cwd = process.cwd()
|
|
101
|
+
|
|
102
|
+
const SCAFFOLDING_TEMPLATES = [
|
|
103
|
+
{
|
|
104
|
+
title:'Blank Project',
|
|
105
|
+
name: 'nattyjs-blank',
|
|
106
|
+
color: yellow
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
const renameFiles = {
|
|
113
|
+
_gitignore: '.gitignore'
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function readFileSync(path,isString=false) {
|
|
117
|
+
if(fs.existsSync(path)){
|
|
118
|
+
var content = fs.readFileSync(path, "utf-8");
|
|
119
|
+
content = isString ? content: JSON.parse(content);
|
|
120
|
+
return content;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function initNatty() {
|
|
125
|
+
let targetDir = argv._[0]
|
|
126
|
+
let template = argv.template || argv.t
|
|
127
|
+
|
|
128
|
+
const defaultProjectName = !targetDir ? 'nattyjs-project' : targetDir
|
|
129
|
+
|
|
130
|
+
let result = {}
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
result = await prompts(
|
|
134
|
+
[
|
|
135
|
+
{
|
|
136
|
+
type: targetDir ? null : 'text',
|
|
137
|
+
name: 'projectName',
|
|
138
|
+
message: reset('Project name:'),
|
|
139
|
+
initial: defaultProjectName,
|
|
140
|
+
onState: (state) =>
|
|
141
|
+
(targetDir = state.value.trim() || defaultProjectName)
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
type: () =>
|
|
145
|
+
!fs.existsSync(targetDir) || isEmpty(targetDir) ? null : 'confirm',
|
|
146
|
+
name: 'overwrite',
|
|
147
|
+
message: () =>
|
|
148
|
+
(targetDir === '.'
|
|
149
|
+
? 'Current directory'
|
|
150
|
+
: `Target directory "${targetDir}"`) +
|
|
151
|
+
` is not empty. Remove existing files and continue?`
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
type: (_, { overwrite } = {}) => {
|
|
155
|
+
if (overwrite === false) {
|
|
156
|
+
throw new Error(red('✖') + ' Operation cancelled')
|
|
157
|
+
}
|
|
158
|
+
return null
|
|
159
|
+
},
|
|
160
|
+
name: 'overwriteChecker'
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
type: () => (isValidPackageName(targetDir) ? null : 'text'),
|
|
164
|
+
name: 'packageName',
|
|
165
|
+
message: reset('Package name:'),
|
|
166
|
+
initial: () => toValidPackageName(targetDir),
|
|
167
|
+
validate: (dir) =>
|
|
168
|
+
isValidPackageName(dir) || 'Invalid package.json name'
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
type: 'select',
|
|
172
|
+
name: 'variant',
|
|
173
|
+
message: reset('Select a scaffolding template:'),
|
|
174
|
+
// @ts-ignore
|
|
175
|
+
choices: () =>
|
|
176
|
+
SCAFFOLDING_TEMPLATES.map((template) => {
|
|
177
|
+
const templateColor = template.color
|
|
178
|
+
return {
|
|
179
|
+
title: templateColor(template.title),
|
|
180
|
+
value: template.name
|
|
181
|
+
}
|
|
182
|
+
})
|
|
183
|
+
}
|
|
184
|
+
],
|
|
185
|
+
{
|
|
186
|
+
onCancel: () => {
|
|
187
|
+
throw new Error(red('✖') + ' Operation cancelled')
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
)
|
|
191
|
+
} catch (cancelled) {
|
|
192
|
+
console.log(cancelled.message)
|
|
193
|
+
return
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const { framework, overwrite, packageName, variant } = result
|
|
197
|
+
|
|
198
|
+
const root = path.join(cwd, targetDir)
|
|
199
|
+
|
|
200
|
+
if (overwrite) {
|
|
201
|
+
emptyDir(root)
|
|
202
|
+
} else if (!fs.existsSync(root)) {
|
|
203
|
+
fs.mkdirSync(root)
|
|
204
|
+
}
|
|
205
|
+
template = variant || framework || template
|
|
206
|
+
|
|
207
|
+
console.log(`\nScaffolding project in ${root}...`)
|
|
208
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
209
|
+
const __dirname = path.dirname(__filename);
|
|
210
|
+
const templateDir = path.join(__dirname, `template-${template}`)
|
|
211
|
+
const write = (file, content) => {
|
|
212
|
+
const targetPath = renameFiles[file]
|
|
213
|
+
? path.join(root, renameFiles[file])
|
|
214
|
+
: path.join(root, file)
|
|
215
|
+
if (content) {
|
|
216
|
+
fs.writeFileSync(targetPath, content)
|
|
217
|
+
} else {
|
|
218
|
+
copy(path.join(templateDir, file), targetPath)
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const files = fs.readdirSync(templateDir)
|
|
223
|
+
for (const file of files.filter((f) => f !== 'package.json')) {
|
|
224
|
+
write(file)
|
|
225
|
+
}
|
|
226
|
+
const pkg = readFileSync(path.join(templateDir, `package.json`))
|
|
227
|
+
|
|
228
|
+
pkg.name = packageName || targetDir
|
|
229
|
+
|
|
230
|
+
write('package.json', JSON.stringify(pkg, null, 2))
|
|
231
|
+
|
|
232
|
+
const pkgInfo = pkgFromUserAgent(process.env.npm_config_user_agent)
|
|
233
|
+
const pkgManager = pkgInfo ? pkgInfo.name : 'npm'
|
|
234
|
+
console.log(`\nDone. Now run:\n`)
|
|
235
|
+
if (root !== cwd) {
|
|
236
|
+
console.log(` cd ${path.relative(cwd, root)}`)
|
|
237
|
+
}
|
|
238
|
+
switch (pkgManager) {
|
|
239
|
+
case 'yarn':
|
|
240
|
+
console.log(' yarn')
|
|
241
|
+
console.log(' yarn dev')
|
|
242
|
+
break
|
|
243
|
+
default:
|
|
244
|
+
console.log(` ${pkgManager} install`)
|
|
245
|
+
console.log(` ${pkgManager} run dev`)
|
|
246
|
+
break
|
|
247
|
+
}
|
|
248
|
+
console.log()
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function copy(src, dest) {
|
|
252
|
+
const stat = fs.statSync(src)
|
|
253
|
+
if (stat.isDirectory()) {
|
|
254
|
+
copyDir(src, dest)
|
|
255
|
+
} else {
|
|
256
|
+
fs.copyFileSync(src, dest)
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function isValidPackageName(projectName) {
|
|
261
|
+
return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(
|
|
262
|
+
projectName
|
|
263
|
+
)
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
function toValidPackageName(projectName) {
|
|
267
|
+
return projectName
|
|
268
|
+
.trim()
|
|
269
|
+
.toLowerCase()
|
|
270
|
+
.replace(/\s+/g, '-')
|
|
271
|
+
.replace(/^[._]/, '')
|
|
272
|
+
.replace(/[^a-z0-9-~]+/g, '-')
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
function copyDir(srcDir, destDir) {
|
|
276
|
+
fs.mkdirSync(destDir, { recursive: true })
|
|
277
|
+
for (const file of fs.readdirSync(srcDir)) {
|
|
278
|
+
const srcFile = path.resolve(srcDir, file)
|
|
279
|
+
const destFile = path.resolve(destDir, file)
|
|
280
|
+
copy(srcFile, destFile)
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function isEmpty(path) {
|
|
285
|
+
const files = fs.readdirSync(path)
|
|
286
|
+
return files.length === 0 || (files.length === 1 && files[0] === '.git')
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function emptyDir(dir) {
|
|
290
|
+
if (!fs.existsSync(dir)) {
|
|
291
|
+
return
|
|
292
|
+
}
|
|
293
|
+
for (const file of fs.readdirSync(dir)) {
|
|
294
|
+
const abs = path.resolve(dir, file)
|
|
295
|
+
if (fs.lstatSync(abs).isDirectory()) {
|
|
296
|
+
emptyDir(abs)
|
|
297
|
+
fs.rmdirSync(abs)
|
|
298
|
+
} else {
|
|
299
|
+
fs.unlinkSync(abs)
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function pkgFromUserAgent(userAgent) {
|
|
305
|
+
if (!userAgent) return undefined
|
|
306
|
+
const pkgSpec = userAgent.split(' ')[0]
|
|
307
|
+
const pkgSpecArr = pkgSpec.split('/')
|
|
308
|
+
return {
|
|
309
|
+
name: pkgSpecArr[0],
|
|
310
|
+
version: pkgSpecArr[1]
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
initNatty().catch((e) => {
|
|
315
|
+
console.error(e)
|
|
316
|
+
})
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-nattyjs",
|
|
3
|
+
"version": "0.0.1-beta.39",
|
|
4
|
+
"description": "Create NattyJS API Project",
|
|
5
|
+
"main": "./index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"files": [
|
|
9
|
+
"template-nattyjs-blank"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
13
|
+
},
|
|
14
|
+
"author": "ajayojha",
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"bin": {
|
|
17
|
+
"create-nattyjs": "./index.js",
|
|
18
|
+
"nattyjs-app": "./index.js"
|
|
19
|
+
},
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=12.0.0"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"execa": "^6.1.0",
|
|
25
|
+
"kleur": "^4.1.4",
|
|
26
|
+
"kolorist": "^1.5.1",
|
|
27
|
+
"minimist": "^1.2.6",
|
|
28
|
+
"ora": "^6.1.0",
|
|
29
|
+
"prompts": "^2.4.2"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
|
|
2
|
+
export class RequestsController {
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Handles the GET request for the '/api/requests' endpoint.
|
|
6
|
+
* @example
|
|
7
|
+
* // API Endpoint: GET /api/requests
|
|
8
|
+
* // Response: [{ name: 'NattyJS' }]
|
|
9
|
+
*/
|
|
10
|
+
async get(): Promise<Array<Object>> {
|
|
11
|
+
return [{ name: 'NattyJS' }];
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Handles the GET request for the '/api/requests/:id' endpoint.
|
|
16
|
+
* @example
|
|
17
|
+
* // API Endpoint: GET /api/requests/1
|
|
18
|
+
* // Parameter: id = 1
|
|
19
|
+
* // Response: { name: 'NattyJS', id: 1 }
|
|
20
|
+
*/
|
|
21
|
+
async getBy(id: number): Promise<Object> {
|
|
22
|
+
// In a real application, this would query a database for the item
|
|
23
|
+
// matching the provided ID.
|
|
24
|
+
return { name: 'NattyJS', id: id };
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "nattyjs-blank",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "natty dev",
|
|
8
|
+
"build": "natty build",
|
|
9
|
+
"build:stage": "natty build --mode stage",
|
|
10
|
+
"build:prod": "natty build --mode prod"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@nattyjs/cli": "0.0.1-beta.39",
|
|
14
|
+
"@nattyjs/common": "0.0.1-beta.39",
|
|
15
|
+
"@nattyjs/core": "0.0.1-beta.39",
|
|
16
|
+
"@nattyjs/entity": "0.0.1-beta.39",
|
|
17
|
+
"@nattyjs/express": "0.0.1-beta.39",
|
|
18
|
+
"@nattyjs/orm": "0.0.1-beta.39",
|
|
19
|
+
"@nattyjs/types": "0.0.1-beta.39",
|
|
20
|
+
"@nattyjs/validation-decorators": "0.0.1-beta.39",
|
|
21
|
+
"mri": "^1.2.0",
|
|
22
|
+
"reflect-metadata": "^0.2.2"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"module": "commonjs",
|
|
4
|
+
"declaration": true,
|
|
5
|
+
"removeComments": true,
|
|
6
|
+
"emitDecoratorMetadata": true,
|
|
7
|
+
"experimentalDecorators": true,
|
|
8
|
+
"allowSyntheticDefaultImports": true,
|
|
9
|
+
"target": "ES2021",
|
|
10
|
+
"sourceMap": true,
|
|
11
|
+
"outDir": "./dist",
|
|
12
|
+
"incremental": true,
|
|
13
|
+
"skipLibCheck": true,
|
|
14
|
+
"strictNullChecks": false,
|
|
15
|
+
"noImplicitAny": false,
|
|
16
|
+
"strictBindCallApply": false,
|
|
17
|
+
"forceConsistentCasingInFileNames": false,
|
|
18
|
+
"noFallthroughCasesInSwitch": false
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|