create-vault-cms 1.0.0 → 1.0.3
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 +27 -27
- package/package.json +2 -1
- package/src/cli.js +53 -21
package/README.md
CHANGED
|
@@ -25,48 +25,48 @@ Use [Obsidian](https://obsidian.md) as a content management system for your [Ast
|
|
|
25
25
|
|
|
26
26
|
## Installation Guide
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
2. Clone or download a zip of this repo.
|
|
30
|
-
3. Copy the contents of the `Starter Vault` folder into your Astro project. **Recommended location:** `src/content` folder, but it can be placed at the level of `src/content` or higher (like the project root).
|
|
31
|
-
4. Open Obsidian and select the "Open folder as vault" option, and select the folder containing the `.obsidian` directory.
|
|
32
|
-
5. The Vault CMS plugin will automatically detect your Astro project structure and guide you through setup via a wizard.
|
|
28
|
+
The easiest way to install Vault CMS is via the CLI:
|
|
33
29
|
|
|
34
|
-
|
|
30
|
+
```bash
|
|
31
|
+
# Using pnpm
|
|
32
|
+
pnpm create vault-cms
|
|
35
33
|
|
|
36
|
-
|
|
34
|
+
# Using npm
|
|
35
|
+
npm create vault-cms
|
|
37
36
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
37
|
+
# Using yarn
|
|
38
|
+
yarn create vault-cms
|
|
39
|
+
```
|
|
41
40
|
|
|
42
|
-
|
|
41
|
+
This will automatically:
|
|
42
|
+
1. Copy the necessary `_bases` and `.obsidian` configuration folders.
|
|
43
|
+
2. Setup a `README.md` for your vault.
|
|
44
|
+
3. Update your `.gitignore` with the recommended Obsidian excludes.
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
2. **Copy the CONTENTS** of that theme folder (not the folder itself) into your Astro project's `src/content` folder.
|
|
46
|
-
- ⚠️ **Important**: Copy the files and folders inside the theme folder, not the theme folder itself. For example, if using Slate, copy the contents of `Theme Examples/Slate/` (like `_bases/`, `post/`, etc.) into `src/content/`, not the `Slate` folder. (Note: `_bases` is the new standard, but `bases` is still supported for backwards compatibility).
|
|
47
|
-
3. Open Obsidian and select "Open folder as vault", then select your `src/content` folder (or the folder containing the `.obsidian` directory).
|
|
48
|
-
4. The vault should already be preconfigured for your theme.
|
|
46
|
+
### Manual Installation
|
|
49
47
|
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
If you prefer to install manually:
|
|
49
|
+
1. Clone or download a zip of this repo.
|
|
50
|
+
2. Copy the `_bases` and `.obsidian` folders into your Astro project (e.g., in `src/content`).
|
|
51
|
+
3. Open Obsidian and select "Open folder as vault", then select the folder containing the `.obsidian` directory.
|
|
52
52
|
|
|
53
53
|
## How Auto-Detection Works
|
|
54
54
|
|
|
55
55
|
Vault CMS automatically detects and configures itself based on your Astro project:
|
|
56
56
|
|
|
57
|
-
- **Project Detection**: Automatically finds your Astro project by locating `astro.config.mjs`, `astro.config.ts`, or other Astro config files
|
|
58
|
-
- **Content Type Detection**: Scans your content folders (like `posts`, `pages`, `docs`, etc.) and automatically identifies them as content types
|
|
59
|
-
- **Frontmatter Analysis**: Analyzes existing content files to detect frontmatter properties (title, date, description, etc.) and configures the plugin accordingly
|
|
60
|
-
- **Theme Adaptation**: Adapts to your Astro theme's specific quirks and requirements automatically
|
|
57
|
+
- **Project Detection**: Automatically finds your Astro project by locating `astro.config.mjs`, `astro.config.ts`, or other Astro config files.
|
|
58
|
+
- **Content Type Detection**: Scans your content folders (like `posts`, `pages`, `docs`, etc.) and automatically identifies them as content types.
|
|
59
|
+
- **Frontmatter Analysis**: Analyzes existing content files to detect frontmatter properties (title, date, description, etc.) and configures the plugin accordingly.
|
|
60
|
+
- **Theme Adaptation**: Adapts to your Astro theme's specific quirks and requirements automatically.
|
|
61
61
|
|
|
62
62
|
When you first open the vault, a setup wizard will guide you through the configuration process. The wizard uses the auto-detected information to pre-populate settings, making setup quick and easy. You can always run the wizard again later by using the "Open Setup Wizard" command.
|
|
63
63
|
|
|
64
64
|
### Recommended .gitignore
|
|
65
65
|
|
|
66
|
-
|
|
66
|
+
If you are not using the CLI, add the following to your Astro project's `.gitignore` file:
|
|
67
67
|
```
|
|
68
|
-
# Obsidian
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
# Obsidian
|
|
69
|
+
.obsidian/workspace.json
|
|
70
|
+
.obsidian/workspace-mobile.json
|
|
71
71
|
```
|
|
72
|
-
This prevents conflicts between multiple devices.
|
|
72
|
+
This prevents conflicts between multiple devices and keeps your vault clean.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-vault-cms",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Installer for Vault CMS",
|
|
5
5
|
"main": "src/cli.js",
|
|
6
6
|
"bin": {
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"homepage": "https://github.com/davidvkimball/vault-cms#readme",
|
|
29
29
|
"dependencies": {
|
|
30
|
+
"adm-zip": "^0.5.16",
|
|
30
31
|
"commander": "^14.0.2",
|
|
31
32
|
"fs-extra": "^11.3.3"
|
|
32
33
|
}
|
package/src/cli.js
CHANGED
|
@@ -3,56 +3,67 @@
|
|
|
3
3
|
const { Command } = require('commander');
|
|
4
4
|
const fs = require('fs-extra');
|
|
5
5
|
const path = require('path');
|
|
6
|
-
const
|
|
6
|
+
const https = require('https');
|
|
7
|
+
const AdmZip = require('adm-zip');
|
|
8
|
+
|
|
9
|
+
// Read version from package.json
|
|
10
|
+
const pkg = require('../package.json');
|
|
7
11
|
|
|
8
12
|
const program = new Command();
|
|
9
13
|
|
|
10
14
|
program
|
|
11
15
|
.name('create-vault-cms')
|
|
12
16
|
.description('Official installer for Vault CMS')
|
|
13
|
-
.version(
|
|
17
|
+
.version(pkg.version);
|
|
14
18
|
|
|
15
19
|
program
|
|
16
20
|
.argument('[target]', 'target directory', '.')
|
|
17
21
|
.option('-t, --template <name>', 'template to use (from vault-cms-presets)')
|
|
18
22
|
.action(async (target, options) => {
|
|
19
23
|
const targetDir = path.resolve(target);
|
|
20
|
-
const
|
|
24
|
+
const tempZip = path.join(targetDir, 'vault-cms-temp.zip');
|
|
25
|
+
const extractDir = path.join(targetDir, '.vault-cms-temp-extract');
|
|
21
26
|
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
: 'https://github.com/davidvkimball/vault-cms.git';
|
|
27
|
+
const repoName = options.template ? 'vault-cms-presets' : 'vault-cms';
|
|
28
|
+
const zipUrl = `https://github.com/davidvkimball/${repoName}/archive/refs/heads/master.zip`;
|
|
25
29
|
|
|
26
30
|
console.log(`🚀 Installing Vault CMS${options.template ? ` (template: ${options.template})` : ''}...`);
|
|
27
31
|
|
|
28
32
|
try {
|
|
29
|
-
// 1.
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
// 1. Create target directory
|
|
34
|
+
await fs.ensureDir(targetDir);
|
|
35
|
+
|
|
36
|
+
// 2. Download ZIP
|
|
37
|
+
console.log(' 📦 Downloading archive...');
|
|
38
|
+
await downloadFile(zipUrl, tempZip);
|
|
39
|
+
|
|
40
|
+
// 3. Extract ZIP
|
|
41
|
+
console.log(' 📂 Extracting files...');
|
|
42
|
+
const zip = new AdmZip(tempZip);
|
|
43
|
+
zip.extractAllTo(extractDir, true);
|
|
44
|
+
|
|
45
|
+
// 4. Identify the inner folder (GitHub zips wrap content in a folder named repo-branch)
|
|
46
|
+
const folders = await fs.readdir(extractDir);
|
|
47
|
+
const innerFolder = path.join(extractDir, folders[0]);
|
|
48
|
+
const sourcePath = options.template ? path.join(innerFolder, options.template) : innerFolder;
|
|
32
49
|
|
|
33
|
-
// 2. Determine source path
|
|
34
|
-
const sourcePath = options.template ? path.join(tempDir, options.template) : tempDir;
|
|
35
|
-
|
|
36
50
|
if (!(await fs.pathExists(sourcePath))) {
|
|
37
51
|
throw new Error(`Template "${options.template}" not found in presets repository.`);
|
|
38
52
|
}
|
|
39
53
|
|
|
40
|
-
//
|
|
54
|
+
// 5. Move selected files
|
|
41
55
|
const toKeep = ['_bases', '.obsidian', 'README.md'];
|
|
42
|
-
|
|
43
|
-
// 4. Move selected files
|
|
44
|
-
await fs.ensureDir(targetDir);
|
|
45
56
|
for (const item of toKeep) {
|
|
46
57
|
const src = path.join(sourcePath, item);
|
|
47
58
|
const dest = path.join(targetDir, item);
|
|
48
59
|
|
|
49
60
|
if (await fs.pathExists(src)) {
|
|
50
|
-
await fs.copy(src, dest);
|
|
61
|
+
await fs.copy(src, dest, { overwrite: true });
|
|
51
62
|
console.log(` ✓ Added ${item}`);
|
|
52
63
|
}
|
|
53
64
|
}
|
|
54
65
|
|
|
55
|
-
//
|
|
66
|
+
// 6. Handle .gitignore
|
|
56
67
|
const gitignorePath = path.join(targetDir, '.gitignore');
|
|
57
68
|
const ignores = '\n# Vault CMS / Obsidian\n.obsidian/workspace.json\n.obsidian/workspace-mobile.json\n.ref/\n';
|
|
58
69
|
|
|
@@ -67,15 +78,36 @@ program
|
|
|
67
78
|
console.log(' ✓ Created .gitignore');
|
|
68
79
|
}
|
|
69
80
|
|
|
70
|
-
//
|
|
71
|
-
await fs.remove(
|
|
81
|
+
// 7. Cleanup
|
|
82
|
+
await fs.remove(tempZip);
|
|
83
|
+
await fs.remove(extractDir);
|
|
72
84
|
|
|
73
85
|
console.log('\n✨ Vault CMS is ready!');
|
|
74
86
|
} catch (err) {
|
|
75
87
|
console.error('\n❌ Installation failed:', err.message);
|
|
76
|
-
if (await fs.pathExists(
|
|
88
|
+
if (await fs.pathExists(tempZip)) await fs.remove(tempZip);
|
|
89
|
+
if (await fs.pathExists(extractDir)) await fs.remove(extractDir);
|
|
77
90
|
process.exit(1);
|
|
78
91
|
}
|
|
79
92
|
});
|
|
80
93
|
|
|
94
|
+
function downloadFile(url, dest) {
|
|
95
|
+
return new Promise((resolve, reject) => {
|
|
96
|
+
https.get(url, (res) => {
|
|
97
|
+
if (res.statusCode === 301 || res.statusCode === 302) {
|
|
98
|
+
return downloadFile(res.headers.location, dest).then(resolve).catch(reject);
|
|
99
|
+
}
|
|
100
|
+
if (res.statusCode !== 200) {
|
|
101
|
+
return reject(new Error(`Failed to download: ${res.statusCode}`));
|
|
102
|
+
}
|
|
103
|
+
const file = fs.createWriteStream(dest);
|
|
104
|
+
res.pipe(file);
|
|
105
|
+
file.on('finish', () => {
|
|
106
|
+
file.close();
|
|
107
|
+
resolve();
|
|
108
|
+
});
|
|
109
|
+
}).on('error', reject);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
81
113
|
program.parse();
|