flowershow 0.0.4 → 0.0.6
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/bin/flowershow.js +18 -2
- package/lib/Installer.js +87 -67
- package/lib/build.js +2 -3
- package/lib/buildStatic.js +15 -0
- package/lib/const.js +1 -1
- package/lib/install.js +19 -17
- package/lib/preview.js +2 -2
- package/lib/utils/index.js +1 -1
- package/lib/utils/logger.js +8 -0
- package/package.json +5 -2
- package/upgrade.sh +0 -28
package/bin/flowershow.js
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
const require = createRequire(import.meta.url);
|
|
4
|
+
import { warn, log } from '../lib/utils/index.js';
|
|
4
5
|
|
|
5
|
-
import
|
|
6
|
+
import os from 'os';
|
|
6
7
|
|
|
8
|
+
if (os.platform() === 'win32') {
|
|
9
|
+
warn("This may not work as expected. You're trying to run Flowreshow CLI on Windows, which is not supported yet...");
|
|
10
|
+
}
|
|
7
11
|
|
|
8
12
|
// TODO check current vs required node version (package.json engines)
|
|
9
13
|
// const requiredNodeVersion = require("../package.json").engines.node;
|
|
10
14
|
|
|
15
|
+
import { Command } from "commander";
|
|
16
|
+
|
|
11
17
|
const program = new Command();
|
|
12
18
|
|
|
13
19
|
program
|
|
@@ -35,6 +41,16 @@ program
|
|
|
35
41
|
build(projectPath);
|
|
36
42
|
})
|
|
37
43
|
|
|
44
|
+
|
|
45
|
+
program
|
|
46
|
+
.command('build-static')
|
|
47
|
+
.description('build static Flowershow website')
|
|
48
|
+
.argument('[project-dir]', 'Path to the folder where Flowershow template is installed (root folder of .flowershow)', '.')
|
|
49
|
+
.action(async (projectPath) => {
|
|
50
|
+
const { default: buildStatic } = await import ('../lib/buildStatic.js');
|
|
51
|
+
buildStatic(projectPath);
|
|
52
|
+
})
|
|
53
|
+
|
|
38
54
|
program
|
|
39
55
|
.command('preview')
|
|
40
56
|
.description('preview your Flowershow site')
|
package/lib/Installer.js
CHANGED
|
@@ -8,90 +8,133 @@ import degit from 'degit';
|
|
|
8
8
|
import { execa } from 'execa';
|
|
9
9
|
import inquirer from 'inquirer';
|
|
10
10
|
|
|
11
|
-
import { exit, error, log, logWithSpinner, stopSpinner, pauseSpinner, resumeSpinner } from './utils/index.js';
|
|
11
|
+
import { exit, error, log, success, logWithSpinner, stopSpinner, pauseSpinner, resumeSpinner } from './utils/index.js';
|
|
12
12
|
|
|
13
|
+
import { FLOWERSHOW_FOLDER_NAME } from './const.js';
|
|
13
14
|
|
|
14
|
-
import { FLOWERSHOW_RELATIVE_PATH } from './const.js';
|
|
15
15
|
|
|
16
16
|
export default class Creator {
|
|
17
|
-
constructor(context, template = 'default') {
|
|
17
|
+
constructor(context, targetDir, template = 'default') {
|
|
18
18
|
this.context = context;
|
|
19
|
+
this.targetDir = targetDir;
|
|
19
20
|
this.template = template; // tb configurable via command option in the future
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
get flowershowDir() {
|
|
23
|
-
return path.resolve(this.context, FLOWERSHOW_RELATIVE_PATH);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
23
|
get templateRepo() {
|
|
27
24
|
const flowershowRepo = require('../package.json').repository.url.replace("git+", "");
|
|
28
25
|
return `${flowershowRepo}/templates/${this.template}`
|
|
29
26
|
}
|
|
30
27
|
|
|
31
28
|
async install(options) {
|
|
32
|
-
const { context,
|
|
33
|
-
|
|
34
|
-
logWithSpinner({ symbol: '🌷', msg: `Installing Flowershow template in ${chalk.magenta(flowershowDir)}...` });
|
|
29
|
+
const { context, targetDir, templateRepo } = this;
|
|
30
|
+
const flowershowDir = path.resolve(targetDir, FLOWERSHOW_FOLDER_NAME)
|
|
35
31
|
|
|
32
|
+
let existsAction;
|
|
36
33
|
if (fs.existsSync(flowershowDir)) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const { action } = await inquirer.prompt([
|
|
34
|
+
let { action } = await inquirer.prompt([
|
|
40
35
|
{
|
|
41
36
|
name: 'action',
|
|
42
37
|
type: 'list',
|
|
43
|
-
message: `Flowershow template is already installed in directory ${chalk.magenta(
|
|
38
|
+
message: `Flowershow template is already installed in directory ${chalk.magenta(targetDir)}. What do you want to do?:`,
|
|
44
39
|
choices: [
|
|
45
40
|
{ name: 'Overwrite', value: 'overwrite' },
|
|
46
41
|
// { name: 'Merge', value: 'merge' },
|
|
47
|
-
{ name: 'Cancel', value:
|
|
42
|
+
{ name: 'Cancel', value: null }
|
|
48
43
|
]
|
|
49
44
|
}
|
|
50
45
|
])
|
|
51
46
|
|
|
52
47
|
if (!action) {
|
|
53
|
-
|
|
54
|
-
} else {
|
|
55
|
-
fs.rmSync(flowershowDir, { recursive: true, force: true });
|
|
48
|
+
exit(0)
|
|
56
49
|
}
|
|
57
|
-
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// clone flowershow template
|
|
61
|
-
try {
|
|
62
|
-
const emitter = degit(templateRepo);
|
|
63
|
-
await emitter.clone(flowershowDir);
|
|
64
|
-
} catch {
|
|
65
|
-
// TODO better error message
|
|
66
|
-
error(`Failed to clone Flowershow template.`)
|
|
67
|
-
exit(1);
|
|
50
|
+
existsAction = action;
|
|
68
51
|
}
|
|
69
52
|
|
|
70
|
-
// symlink content folder
|
|
71
|
-
pauseSpinner();
|
|
72
|
-
|
|
73
53
|
let { contentPath } = await inquirer.prompt([
|
|
74
54
|
{
|
|
75
55
|
name: 'contentPath',
|
|
76
56
|
type: 'input',
|
|
77
|
-
message: 'Path to the folder with your
|
|
57
|
+
message: 'Path to the folder with your markdown files',
|
|
78
58
|
validate(input) {
|
|
79
|
-
const
|
|
80
|
-
if (!fs.existsSync(
|
|
81
|
-
error(`Directory ${
|
|
59
|
+
const contentDir = path.resolve(context, input);
|
|
60
|
+
if (!fs.existsSync(contentDir)) {
|
|
61
|
+
error(`Directory ${contentDir} does not exist.`);
|
|
82
62
|
exit(1);
|
|
83
63
|
}
|
|
84
|
-
resumeSpinner();
|
|
85
64
|
return true;
|
|
86
65
|
}
|
|
87
66
|
}
|
|
88
67
|
])
|
|
89
68
|
|
|
90
|
-
contentPath = path.resolve(context, contentPath);
|
|
91
69
|
|
|
70
|
+
const contentDir = path.resolve(context, contentPath);
|
|
71
|
+
const assetFolderChoices = fs.readdirSync(contentDir, { withFileTypes: true })
|
|
72
|
+
.filter(d => d.isDirectory())
|
|
73
|
+
.map(d => ({ name: d.name, value: d.name }))
|
|
74
|
+
|
|
75
|
+
let assetsFolder = 'none';
|
|
76
|
+
|
|
77
|
+
if (!assetFolderChoices.length) {
|
|
78
|
+
const { foldersAction } = await inquirer.prompt([
|
|
79
|
+
{
|
|
80
|
+
name: 'foldersAction',
|
|
81
|
+
type: 'list',
|
|
82
|
+
message: 'There are no subfolders in your content folder, that could be used as assets folder',
|
|
83
|
+
choices: [
|
|
84
|
+
{ name: "I don't need assets folder", value: 'none' },
|
|
85
|
+
{ name: 'Cancel', value: null }
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
])
|
|
89
|
+
|
|
90
|
+
assetsFolder = foldersAction;
|
|
91
|
+
|
|
92
|
+
} else {
|
|
93
|
+
|
|
94
|
+
const { assets } = await inquirer.prompt([
|
|
95
|
+
{
|
|
96
|
+
name: 'assets',
|
|
97
|
+
type: 'list',
|
|
98
|
+
message: 'Select a folder with your assets (attachments)',
|
|
99
|
+
choices: [
|
|
100
|
+
...assetFolderChoices,
|
|
101
|
+
new inquirer.Separator(),
|
|
102
|
+
{ name: "I don't need assets folder", value: 'none' },
|
|
103
|
+
{ name: 'Cancel', value: null }
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
])
|
|
107
|
+
|
|
108
|
+
assetsFolder = assets;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (!assetsFolder) {
|
|
112
|
+
exit(0)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// install flowershow template
|
|
116
|
+
logWithSpinner({ symbol: '🌷', msg: `Installing Flowershow template in ${chalk.magenta(flowershowDir)}...` });
|
|
117
|
+
|
|
118
|
+
if (existsAction === 'overwrite') {
|
|
119
|
+
fs.rmSync(flowershowDir, { recursive: true, force: true });
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
const emitter = degit(templateRepo);
|
|
124
|
+
await emitter.clone(flowershowDir);
|
|
125
|
+
} catch {
|
|
126
|
+
error(`Failed to install Flowershow template in ${flowershowDir}.`)
|
|
127
|
+
exit(1);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// update content and assets symlinks
|
|
92
131
|
fs.unlinkSync(`${flowershowDir}/content`);
|
|
93
|
-
fs.symlinkSync(
|
|
132
|
+
fs.symlinkSync(contentDir, `${flowershowDir}/content`);
|
|
94
133
|
|
|
134
|
+
fs.unlinkSync(`${flowershowDir}/public/assets`);
|
|
135
|
+
if (assetsFolder !== 'none') {
|
|
136
|
+
fs.symlinkSync(path.resolve(contentDir, assetsFolder), `${flowershowDir}/public/${assetsFolder}`);
|
|
137
|
+
}
|
|
95
138
|
|
|
96
139
|
// // if there is no index.md file, create one
|
|
97
140
|
if (!fs.existsSync(`${contentPath}/index.md`)) {
|
|
@@ -104,44 +147,21 @@ export default class Creator {
|
|
|
104
147
|
fs.writeFile(`${contentPath}/config.js`, '{}', { flag: 'a' }, err => {});
|
|
105
148
|
}
|
|
106
149
|
|
|
107
|
-
//
|
|
108
|
-
pauseSpinner();
|
|
109
|
-
|
|
110
|
-
const { assetsFolder } = await inquirer.prompt([
|
|
111
|
-
{
|
|
112
|
-
name: 'assetsFolder',
|
|
113
|
-
type: 'input',
|
|
114
|
-
message: 'Name of your assets (attachements) folder',
|
|
115
|
-
validate(input) {
|
|
116
|
-
const assetsPathAbsolute = path.resolve(contentPath, input);
|
|
117
|
-
if (!fs.existsSync(assetsPathAbsolute)) {
|
|
118
|
-
error(`Directory ${assetsPathAbsolute} does not exist.`);
|
|
119
|
-
exit(1);
|
|
120
|
-
}
|
|
121
|
-
resumeSpinner();
|
|
122
|
-
return true;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
])
|
|
126
|
-
|
|
127
|
-
fs.unlinkSync(`${flowershowDir}/public/assets`);
|
|
128
|
-
fs.symlinkSync(path.resolve(contentPath, assetsFolder), `${flowershowDir}/public/assets`);
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
// // install flowershow dependencies
|
|
150
|
+
// install flowershow dependencies
|
|
132
151
|
logWithSpinner({ symbol: '🌸', msg: `Installing Flowershow dependencies...` });
|
|
133
152
|
|
|
134
153
|
try {
|
|
135
|
-
|
|
154
|
+
await execa('npm', [ 'set-script', 'prepare', '' ], { cwd: flowershowDir });
|
|
155
|
+
const { stdout, stderr } = await execa('npm', [ 'install'], { cwd: flowershowDir });
|
|
136
156
|
log(stdout);
|
|
137
157
|
log(stderr);
|
|
158
|
+
stopSpinner();
|
|
159
|
+
success("Successfuly installed Flowershow!")
|
|
138
160
|
} catch (err) {
|
|
139
161
|
error(
|
|
140
162
|
`Installing dependencies failed: ${err.message}`
|
|
141
163
|
);
|
|
142
164
|
exit(err.exitCode);
|
|
143
165
|
}
|
|
144
|
-
|
|
145
|
-
stopSpinner();
|
|
146
166
|
}
|
|
147
167
|
}
|
package/lib/build.js
CHANGED
|
@@ -3,12 +3,11 @@ import path from 'path';
|
|
|
3
3
|
import { execa } from 'execa';
|
|
4
4
|
|
|
5
5
|
import { exit, error, log } from './utils/index.js';
|
|
6
|
+
import { FLOWERSHOW_FOLDER_NAME } from './const.js';
|
|
6
7
|
|
|
7
8
|
|
|
8
|
-
import { FLOWERSHOW_RELATIVE_PATH } from './const.js';
|
|
9
|
-
|
|
10
9
|
export default async function build(dir) {
|
|
11
|
-
const flowershowDir = path.resolve(dir,
|
|
10
|
+
const flowershowDir = path.resolve(dir, FLOWERSHOW_FOLDER_NAME);
|
|
12
11
|
|
|
13
12
|
// check if flowershow is installed
|
|
14
13
|
if (!fs.existsSync(flowershowDir)) {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { execa } from 'execa';
|
|
4
|
+
|
|
5
|
+
import { exit, error, log } from './utils/index.js';
|
|
6
|
+
import { FLOWERSHOW_FOLDER_NAME } from './const.js';
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
export default async function buildStatic(dir) {
|
|
10
|
+
const flowershowDir = path.resolve(dir, FLOWERSHOW_FOLDER_NAME);
|
|
11
|
+
|
|
12
|
+
const subprocess = execa('npm', [ 'run', 'export' ], { cwd: flowershowDir });
|
|
13
|
+
|
|
14
|
+
subprocess.stdout.pipe(process.stdout);
|
|
15
|
+
}
|
package/lib/const.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const
|
|
1
|
+
export const FLOWERSHOW_FOLDER_NAME = '.flowershow';
|
package/lib/install.js
CHANGED
|
@@ -7,28 +7,30 @@ import Installer from './Installer.js';
|
|
|
7
7
|
import { error, log, exit } from './utils/index.js';
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
export default async function install(
|
|
10
|
+
export default async function install(dir, options) {
|
|
11
11
|
const currentDir = process.cwd();
|
|
12
|
-
const inCurrentDir =
|
|
13
|
-
const targetDirAbsolute = path.resolve(currentDir, targetDir);
|
|
12
|
+
const inCurrentDir = dir === '.';
|
|
14
13
|
|
|
15
|
-
if (
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
message: "Create Flowershow project in current directory?"
|
|
22
|
-
}
|
|
23
|
-
])
|
|
24
|
-
if (!ok) {
|
|
25
|
-
return
|
|
14
|
+
if (inCurrentDir) {
|
|
15
|
+
const { ok } = await inquirer.prompt([
|
|
16
|
+
{
|
|
17
|
+
name: "ok",
|
|
18
|
+
type: "confirm",
|
|
19
|
+
message: "Create Flowershow project in current directory?"
|
|
26
20
|
}
|
|
21
|
+
])
|
|
22
|
+
if (!ok) {
|
|
23
|
+
return
|
|
27
24
|
}
|
|
28
|
-
} else {
|
|
29
|
-
fs.mkdirSync(targetDirAbsolute);
|
|
30
25
|
}
|
|
31
26
|
|
|
32
|
-
const
|
|
27
|
+
const targetDir = path.resolve(dir);
|
|
28
|
+
|
|
29
|
+
if (!fs.existsSync(targetDir)) {
|
|
30
|
+
error(`Directory ${targetDir} does not exist.`);
|
|
31
|
+
exit(1);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const installer = new Installer(currentDir, targetDir);
|
|
33
35
|
await installer.install(options);
|
|
34
36
|
}
|
package/lib/preview.js
CHANGED
|
@@ -5,10 +5,10 @@ import { execa } from 'execa';
|
|
|
5
5
|
import { exit, error, log } from './utils/index.js';
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { FLOWERSHOW_FOLDER_NAME } from './const.js';
|
|
9
9
|
|
|
10
10
|
export default async function preview(dir) {
|
|
11
|
-
const flowershowDir = path.resolve(dir,
|
|
11
|
+
const flowershowDir = path.resolve(dir, FLOWERSHOW_FOLDER_NAME);
|
|
12
12
|
|
|
13
13
|
// check if flowershow is installed
|
|
14
14
|
if (!fs.existsSync(flowershowDir)) {
|
package/lib/utils/index.js
CHANGED
package/lib/utils/logger.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flowershow",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "Publish your digital garden",
|
|
5
5
|
"bin": {
|
|
6
6
|
"flowershow": "bin/flowershow.js"
|
|
@@ -14,6 +14,9 @@
|
|
|
14
14
|
"flowershow",
|
|
15
15
|
"cli"
|
|
16
16
|
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"test": "./e2e/bats/bin/bats ./e2e/test.bats --verbose-run"
|
|
19
|
+
},
|
|
17
20
|
"author": "Rufus Pollock",
|
|
18
21
|
"license": "MIT",
|
|
19
22
|
"bugs": {
|
|
@@ -34,6 +37,6 @@
|
|
|
34
37
|
},
|
|
35
38
|
"type": "module",
|
|
36
39
|
"engines": {
|
|
37
|
-
"node": ">=12.2.0"
|
|
40
|
+
"node": ">=12.2.0 || >=14.13.0"
|
|
38
41
|
}
|
|
39
42
|
}
|
package/upgrade.sh
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# upgrade an existing standard nextjs site
|
|
2
|
-
|
|
3
|
-
npx degit flowershow/flowershow/templates/default --force
|
|
4
|
-
|
|
5
|
-
# files that we should keep the original (probably)
|
|
6
|
-
git checkout README.md
|
|
7
|
-
git checkout .gitignore
|
|
8
|
-
|
|
9
|
-
# stuff that shouldn't be there
|
|
10
|
-
rm .env.example
|
|
11
|
-
rm -Rf tests
|
|
12
|
-
rm netlify.toml
|
|
13
|
-
rm netlify.toml
|
|
14
|
-
# data seems to be exampleData
|
|
15
|
-
rm -Rf data
|
|
16
|
-
rm -Rf components/TempCallout.jsx
|
|
17
|
-
|
|
18
|
-
# set up custom components
|
|
19
|
-
rm -Rf components/custom
|
|
20
|
-
|
|
21
|
-
# set up assets
|
|
22
|
-
mkdir -p content/assets
|
|
23
|
-
rm public/assets
|
|
24
|
-
ln -s content/assets public/assets
|
|
25
|
-
|
|
26
|
-
# notes
|
|
27
|
-
echo "You may need to hand merge the following files:"
|
|
28
|
-
echo "pacakge.json, package-lock.json"
|