@newlogic-digital/cli 0.0.1 → 0.0.4

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.
@@ -1,11 +1,8 @@
1
- import init from './src/commands/init/index.js'
2
- import cms from './src/commands/cms/index.js'
1
+ import init from './src/commands/init/index.mjs'
2
+ import cms from './src/commands/cms/index.mjs'
3
3
  import pc from 'picocolors'
4
- import fs from 'fs'
5
- import { dirname, resolve } from 'path'
6
- import { fileURLToPath } from 'url'
4
+ import { version, name } from './src/utils.mjs'
7
5
 
8
- const { version, name } = JSON.parse(fs.readFileSync(resolve(dirname((fileURLToPath(import.meta.url))), 'package.json')).toString())
9
6
  const args = process.argv.slice(2)
10
7
  const command = args[0]
11
8
 
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@newlogic-digital/cli",
3
- "version": "0.0.1",
3
+ "version": "0.0.4",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
6
  "bin": {
7
- "newlogic": "index.js"
7
+ "newlogic": "index.mjs"
8
8
  },
9
9
  "scripts": {
10
- "eslint": "eslint '**/*.js' --fix"
10
+ "eslint": "eslint '**/*.mjs' --fix"
11
11
  },
12
12
  "dependencies": {
13
13
  "prompts": "^2.4.2",
@@ -20,7 +20,8 @@
20
20
  "eslint-config-standard": "^17.0.0"
21
21
  },
22
22
  "files": [
23
- "index.js"
23
+ "index.js",
24
+ "src"
24
25
  ],
25
26
  "engines": {
26
27
  "node": ">=16.0.0",
@@ -0,0 +1,38 @@
1
+ import prepare from './prepare.mjs'
2
+ import pc from 'picocolors'
3
+ import fs from 'fs'
4
+ import { join, resolve } from 'path'
5
+
6
+ export const options = {
7
+ path: {
8
+ src: {
9
+ templates: resolve(process.cwd(), 'playground/templates'),
10
+ sections: resolve(process.cwd(), 'playground/templates/Sections')
11
+ },
12
+ app: {
13
+ templates: resolve(process.cwd(), 'app/Templates'),
14
+ sections: resolve(process.cwd(), 'app/Sections'),
15
+ sectionsFactory: resolve(process.cwd(), 'app/Sections/Factory')
16
+ }
17
+ }
18
+ }
19
+
20
+ export default async function cms(action, name) {
21
+ if (action === 'prepare') {
22
+ await prepare(options).copy(name)
23
+ }
24
+
25
+ if (action === 'new-section') {
26
+ const nameFormatted = name.replaceAll('/', '')
27
+
28
+ if (fs.existsSync(join(options.path.app.sections, `${nameFormatted}.php`))) {
29
+ console.log(`${pc.red('✖')} section ${nameFormatted} already exists`)
30
+ process.exit(1)
31
+ }
32
+
33
+ prepare(options).writeSection(name)
34
+ prepare(options).writeSectionFactory(nameFormatted)
35
+
36
+ console.log(`${pc.green('✔')} section ${nameFormatted} created`)
37
+ }
38
+ }
@@ -0,0 +1,121 @@
1
+ import FastGlob from 'fast-glob'
2
+ import { join, relative, extname } from 'path'
3
+ import fs from 'fs'
4
+ import fse from 'fs-extra'
5
+ import { stripIndent } from '../../utils.mjs'
6
+ import pc from 'picocolors'
7
+
8
+ let sectionsCount = 0
9
+ let sectionsFactoryCount = 0
10
+ let templatesCount = 0
11
+
12
+ export default function prepare(options) {
13
+ return {
14
+ async copy(name) {
15
+ if (!name || name === 'sections') {
16
+ if (!fs.existsSync(options.path.src.sections)) {
17
+ console.log(`${pc.red('✖')} path ${options.path.src.sections} doesn't exists`)
18
+ process.exit(1)
19
+ }
20
+
21
+ if (!fs.existsSync(options.path.app.sections)) {
22
+ console.log(`${pc.red('✖')} path ${options.path.app.sections} doesn't exists`)
23
+ process.exit(1)
24
+ }
25
+
26
+ if (!fs.existsSync(options.path.app.sectionsFactory)) {
27
+ fs.mkdirSync(options.path.app.sectionsFactory)
28
+ }
29
+
30
+ await this.copySections(name === 'sections')
31
+ }
32
+
33
+ if (!name || name === 'templates') {
34
+ if (!fs.existsSync(options.path.src.templates)) {
35
+ console.log(`${pc.red('✖')} path ${options.path.src.templates} doesn't exists`)
36
+ process.exit(1)
37
+ }
38
+
39
+ if (!fs.existsSync(options.path.app.sections)) {
40
+ fs.mkdirSync(options.path.app.sections)
41
+ }
42
+
43
+ await this.copyTemplates(name === 'templates')
44
+ }
45
+ },
46
+ writeSection(name, path, force) {
47
+ if (!path) {
48
+ path = join(relative(options.path.src.templates, options.path.src.sections), name) + '.latte'
49
+ name = name.replaceAll('/', '')
50
+ }
51
+
52
+ if (!name.match(/(Ui)/)) {
53
+ if (!fs.existsSync(join(options.path.app.sections, `${name}.php`)) || force) {
54
+ fs.writeFileSync(join(options.path.app.sections, `${name}.php`),
55
+ stripIndent(`
56
+ <?php
57
+
58
+ namespace App\\Sections;
59
+
60
+ class ${name} extends BaseSection
61
+ {
62
+ public function render()
63
+ {
64
+ $this->getTemplate()->render(TEMPLATES_DIR . '/${path}');
65
+ }
66
+ }
67
+ `).replace(/^\s*\n/g, '')
68
+ )
69
+
70
+ sectionsCount += 1
71
+ }
72
+ }
73
+ },
74
+ writeSectionFactory(name, force) {
75
+ if (!name.match(/(Ui)/)) {
76
+ if (!fs.existsSync(join(options.path.app.sectionsFactory, `${name}Factory.php`)) || force) {
77
+ fs.writeFileSync(join(options.path.app.sectionsFactory, `${name}Factory.php`),
78
+ stripIndent(`
79
+ <?php
80
+
81
+ namespace App\\Sections\\Factory;
82
+
83
+ use App\\Sections\\${name};
84
+
85
+ interface ${name}Factory
86
+ {
87
+ public function create(): ${name};
88
+ }
89
+ `).replace(/^\s*\n/g, '')
90
+ )
91
+
92
+ sectionsFactoryCount += 1
93
+ }
94
+ }
95
+ },
96
+ async copySections(force = false) {
97
+ const sections = FastGlob.sync(join(options.path.src.sections, '/**'))
98
+
99
+ sections.forEach(path => {
100
+ const name = relative(options.path.src.sections, path).replace(extname(relative(options.path.src.sections, path)), '').replaceAll('/', '')
101
+
102
+ this.writeSection(name, relative(options.path.src.templates, path), force)
103
+ this.writeSectionFactory(name, force)
104
+ })
105
+
106
+ console.log(`${pc.green('✔')} ${sectionsCount} sections and ${sectionsFactoryCount} factory files copied to app`)
107
+ },
108
+ async copyTemplates(force = false) {
109
+ const templates = FastGlob.sync(join(options.path.src.templates, '/**')).filter(entry => {
110
+ return !fs.existsSync(join(options.path.app.templates, relative(options.path.src.templates, entry))) || force
111
+ })
112
+
113
+ for (const path of templates) {
114
+ await fse.copy(path, join(options.path.app.templates, relative(options.path.src.templates, path)))
115
+ templatesCount += 1
116
+ }
117
+
118
+ console.log(`${pc.green('✔')} ${templatesCount} template files copied to app`)
119
+ }
120
+ }
121
+ }
@@ -0,0 +1,53 @@
1
+ import { execSync } from '../../utils.mjs'
2
+ import { join, resolve } from 'path'
3
+ import fs from 'fs'
4
+ import os from 'os'
5
+ import pc from 'picocolors'
6
+ import fse from 'fs-extra'
7
+
8
+ const tempDir = join(os.tmpdir(), 'newlogic-cms-web')
9
+
10
+ async function move(path) {
11
+ await fse.move(join(tempDir, path), resolve(process.cwd(), path)).catch(err => console.log(pc.red(err)))
12
+ }
13
+
14
+ function clone(path, { variant, branch }) {
15
+ if (variant === 'cms-web') {
16
+ variant = 'newlogic-cms-next-web'
17
+ } else if (variant === 'cms-eshop') {
18
+ variant = 'newlogic-cms-next-eshop'
19
+ }
20
+
21
+ execSync(`git clone -b ${branch} --single-branch --depth 1 git@git.newlogic.cz:newlogic-dev/${variant}.git ${path}`)
22
+ }
23
+
24
+ export default async function cms(name, { variant, branch }) {
25
+ if (name) {
26
+ clone(name, { variant, branch })
27
+ return
28
+ }
29
+
30
+ if (fs.existsSync(tempDir)) {
31
+ fse.removeSync(tempDir)
32
+ }
33
+
34
+ clone(tempDir, { variant, branch })
35
+
36
+ await move('.docker')
37
+ await move('app')
38
+ await move('config')
39
+ await move('log')
40
+ await move('public/.htaccess')
41
+ await move('public/index.php')
42
+ await move('temp')
43
+ await move('.gitignore')
44
+ await move('.htaccess')
45
+ await move('Makefile')
46
+ await move('composer.json')
47
+ await move('composer.lock')
48
+ await move('docker-compose.yml')
49
+ await move('phpstan.neon')
50
+ await move('pint.json')
51
+
52
+ fse.removeSync(tempDir)
53
+ }
@@ -0,0 +1,58 @@
1
+ import prompts from 'prompts'
2
+ import ui from './ui.mjs'
3
+ import cms from './cms.mjs'
4
+
5
+ async function init(project, name) {
6
+ const nameAsProject = (project && !project.match(/^(ui|cms)$/))
7
+
8
+ if (!project || nameAsProject) {
9
+ const response = await prompts([
10
+ {
11
+ type: 'select',
12
+ name: 'project',
13
+ message: 'Select a project to init',
14
+ choices: [
15
+ { title: 'ui', value: 'ui' },
16
+ { title: 'cms', value: 'cms' }
17
+ ]
18
+ }
19
+ ])
20
+
21
+ name = nameAsProject ? project : name
22
+ project = response.project
23
+ }
24
+
25
+ const { branch } = await prompts([
26
+ {
27
+ type: 'select',
28
+ name: 'branch',
29
+ message: 'Select a git branch',
30
+ choices: [
31
+ { title: 'main', value: 'main' },
32
+ { title: 'dev', value: 'dev' }
33
+ ]
34
+ }
35
+ ])
36
+
37
+ if (project === 'ui') {
38
+ ui(name, { branch })
39
+ }
40
+
41
+ if (project === 'cms') {
42
+ const { variant } = await prompts([
43
+ {
44
+ type: 'select',
45
+ name: 'variant',
46
+ message: 'Select a variant to install',
47
+ choices: [
48
+ { title: 'cms-web', value: 'cms-web' },
49
+ { title: 'cms-eshop', value: 'cms-eshop' }
50
+ ]
51
+ }
52
+ ])
53
+
54
+ await cms(name, { branch, variant })
55
+ }
56
+ }
57
+
58
+ export default init
@@ -0,0 +1,5 @@
1
+ import { execSync } from '../../utils.mjs'
2
+
3
+ export default function ui(name, { branch }) {
4
+ execSync(`git clone -b ${branch} --single-branch --depth 1 git@git.newlogic.cz:newlogic-dev/newlogic-ui.git ${name || '.'}`)
5
+ }
package/src/utils.mjs ADDED
@@ -0,0 +1,36 @@
1
+ import childProcess from 'child_process'
2
+ import fs from 'fs'
3
+ import { dirname, resolve } from 'path'
4
+ import { fileURLToPath } from 'url'
5
+
6
+ const { version, name } = JSON.parse(fs.readFileSync(resolve(dirname((fileURLToPath(import.meta.url))), '../package.json')).toString())
7
+
8
+ const execSync = (cmd) => {
9
+ try {
10
+ childProcess.execSync(cmd, { stdio: [0, 1, 2] })
11
+ } catch {
12
+ process.exit(1)
13
+ }
14
+ }
15
+
16
+ const stripIndent = (string) => {
17
+ const indent = () => {
18
+ const match = string.match(/^[ \t]*(?=\S)/gm)
19
+
20
+ if (!match) {
21
+ return 0
22
+ }
23
+
24
+ return match.reduce((r, a) => Math.min(r, a.length), Infinity)
25
+ }
26
+
27
+ if (indent() === 0) {
28
+ return string
29
+ }
30
+
31
+ const regex = new RegExp(`^[ \\t]{${indent()}}`, 'gm')
32
+
33
+ return string.replace(regex, '')
34
+ }
35
+
36
+ export { execSync, stripIndent, version, name }