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 CHANGED
@@ -1,13 +1,19 @@
1
- #! /usr/bin/env node
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 { Command } from "commander";
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, flowershowDir, templateRepo } = this;
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
- pauseSpinner();
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(context)}. What do you want to do?:`,
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: false }
42
+ { name: 'Cancel', value: null }
48
43
  ]
49
44
  }
50
45
  ])
51
46
 
52
47
  if (!action) {
53
- return
54
- } else {
55
- fs.rmSync(flowershowDir, { recursive: true, force: true });
48
+ exit(0)
56
49
  }
57
- resumeSpinner();
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 content files',
57
+ message: 'Path to the folder with your markdown files',
78
58
  validate(input) {
79
- const contentPathAbsolute = path.resolve(context, input);
80
- if (!fs.existsSync(contentPathAbsolute)) {
81
- error(`Directory ${contentPathAbsolute} does not exist.`);
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(contentPath, `${flowershowDir}/content`);
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
- // symlink assets folder
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
- const { stdout, stderr } = await execa('npm', [ 'install' ], { cwd: flowershowDir });
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, FLOWERSHOW_RELATIVE_PATH);
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 FLOWERSHOW_RELATIVE_PATH = '.flowershow';
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(targetDir, options) {
10
+ export default async function install(dir, options) {
11
11
  const currentDir = process.cwd();
12
- const inCurrentDir = targetDir === '.';
13
- const targetDirAbsolute = path.resolve(currentDir, targetDir);
12
+ const inCurrentDir = dir === '.';
14
13
 
15
- if (fs.existsSync(targetDirAbsolute)) {
16
- if (inCurrentDir) {
17
- const { ok } = await inquirer.prompt([
18
- {
19
- name: "ok",
20
- type: "confirm",
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 installer = new Installer(targetDirAbsolute);
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 { FLOWERSHOW_RELATIVE_PATH } from './const.js';
8
+ import { FLOWERSHOW_FOLDER_NAME } from './const.js';
9
9
 
10
10
  export default async function preview(dir) {
11
- const flowershowDir = path.resolve(dir, FLOWERSHOW_RELATIVE_PATH);
11
+ const flowershowDir = path.resolve(dir, FLOWERSHOW_FOLDER_NAME);
12
12
 
13
13
  // check if flowershow is installed
14
14
  if (!fs.existsSync(flowershowDir)) {
@@ -1,3 +1,3 @@
1
- export { error, info, log } from './logger.js';
1
+ export { error, info, log, success, warn } from './logger.js';
2
2
  export { exit } from './exit.js';
3
3
  export { logWithSpinner, stopSpinner, pauseSpinner, resumeSpinner } from './spinner.js';
@@ -14,3 +14,11 @@ export const error = (msg) => {
14
14
  console.error(msg.stack)
15
15
  }
16
16
  }
17
+
18
+ export const success = (msg) => {
19
+ console.log(`${chalk.blue('🎊')} ${msg}`);
20
+ }
21
+
22
+ export const warn = (msg) => {
23
+ console.log(`${chalk.red('⚠')} ${msg}`);
24
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flowershow",
3
- "version": "0.0.4",
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"