mirror of
https://github.com/10h30/wordpress-export-to-markdown.git
synced 2026-07-14 04:06:45 +09:00
@@ -1,25 +1,32 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
import * as commander from 'commander';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import process from 'process';
|
|
||||||
import * as parser from './src/parser.js';
|
import * as parser from './src/parser.js';
|
||||||
import * as wizard from './src/wizard.js';
|
import * as settings from './src/settings.js';
|
||||||
|
import * as intake from './src/intake.js';
|
||||||
import * as writer from './src/writer.js';
|
import * as writer from './src/writer.js';
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
// parse any command line arguments and run wizard
|
// configure command line help output
|
||||||
const config = await wizard.getConfig(process.argv);
|
commander.program
|
||||||
|
.name('node index.js')
|
||||||
|
.helpOption('-h, --help', 'See the thing you\'re looking at right now')
|
||||||
|
.addHelpText('after', '\nMore documentation is at https://github.com/lonekorean/wordpress-export-to-markdown')
|
||||||
|
|
||||||
|
// gather config options from command line and wizard
|
||||||
|
const config = await intake.getConfig();
|
||||||
|
|
||||||
// parse data from XML and do Markdown translations
|
// parse data from XML and do Markdown translations
|
||||||
const posts = await parser.parseFilePromise(config)
|
const posts = await parser.parseFilePromise(config)
|
||||||
|
|
||||||
// write files, downloading images as needed
|
// write files and download images
|
||||||
await writer.writeFilesPromise(posts, config);
|
await writer.writeFilesPromise(posts, config);
|
||||||
|
|
||||||
// happy goodbye
|
// happy goodbye
|
||||||
console.log('\nAll done!');
|
console.log('\nAll done!');
|
||||||
console.log('Look for your output files in: ' + path.resolve(config.output));
|
console.log('Look for your output files in: ' + path.resolve(settings.output_directory));
|
||||||
})().catch(ex => {
|
})().catch((ex) => {
|
||||||
// sad goodbye
|
// sad goodbye
|
||||||
console.log('\nSomething went wrong, execution halted early.');
|
console.log('\nSomething went wrong, execution halted early.');
|
||||||
console.error(ex);
|
console.error(ex);
|
||||||
|
|||||||
Generated
+137
-168
@@ -9,11 +9,11 @@
|
|||||||
"version": "2.4.2",
|
"version": "2.4.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@inquirer/prompts": "^7.2.3",
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
"camelcase": "^8.0.0",
|
"camelcase": "^8.0.0",
|
||||||
"chalk": "^5.4.1",
|
"chalk": "^5.4.1",
|
||||||
"commander": "^13.0.0",
|
"commander": "^13.0.0",
|
||||||
"inquirer": "^10.2.2",
|
|
||||||
"luxon": "^3.5.0",
|
"luxon": "^3.5.0",
|
||||||
"turndown": "^7.2.0",
|
"turndown": "^7.2.0",
|
||||||
"turndown-plugin-gfm": "^1.0.2",
|
"turndown-plugin-gfm": "^1.0.2",
|
||||||
@@ -124,45 +124,48 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@inquirer/checkbox": {
|
"node_modules/@inquirer/checkbox": {
|
||||||
"version": "2.5.0",
|
"version": "4.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-2.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.0.6.tgz",
|
||||||
"integrity": "sha512-sMgdETOfi2dUHT8r7TT1BTKOwNvdDGFDXYWtQ2J69SvlYNntk9I/gJe7r5yvMwwsuKnYbuRs3pNhx4tgNck5aA==",
|
"integrity": "sha512-PgP35JfmGjHU0LSXOyRew0zHuA9N6OJwOlos1fZ20b7j8ISeAdib3L+n0jIxBtX958UeEpte6xhG/gxJ5iUqMw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@inquirer/core": "^9.1.0",
|
"@inquirer/core": "^10.1.4",
|
||||||
"@inquirer/figures": "^1.0.5",
|
"@inquirer/figures": "^1.0.9",
|
||||||
"@inquirer/type": "^1.5.3",
|
"@inquirer/type": "^3.0.2",
|
||||||
"ansi-escapes": "^4.3.2",
|
"ansi-escapes": "^4.3.2",
|
||||||
"yoctocolors-cjs": "^2.1.2"
|
"yoctocolors-cjs": "^2.1.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@inquirer/confirm": {
|
"node_modules/@inquirer/confirm": {
|
||||||
"version": "3.2.0",
|
"version": "5.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.3.tgz",
|
||||||
"integrity": "sha512-oOIwPs0Dvq5220Z8lGL/6LHRTEr9TgLHmiI99Rj1PJ1p1czTys+olrgBqZk4E2qC0YTzeHprxSQmoHioVdJ7Lw==",
|
"integrity": "sha512-fuF9laMmHoOgWapF9h9hv6opA5WvmGFHsTYGCmuFxcghIhEhb3dN0CdQR4BUMqa2H506NCj8cGX4jwMsE4t6dA==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@inquirer/core": "^9.1.0",
|
"@inquirer/core": "^10.1.4",
|
||||||
"@inquirer/type": "^1.5.3"
|
"@inquirer/type": "^3.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@inquirer/core": {
|
"node_modules/@inquirer/core": {
|
||||||
"version": "9.2.1",
|
"version": "10.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/core/-/core-9.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.4.tgz",
|
||||||
"integrity": "sha512-F2VBt7W/mwqEU4bL0RnHNZmC/OxzNx9cOYxHqnXX3MP6ruYvZUZAW9imgN9+h/uBT/oP8Gh888J2OZSbjSeWcg==",
|
"integrity": "sha512-5y4/PUJVnRb4bwWY67KLdebWOhOc7xj5IP2J80oWXa64mVag24rwQ1VAdnj7/eDY/odhguW0zQ1Mp1pj6fO/2w==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@inquirer/figures": "^1.0.6",
|
"@inquirer/figures": "^1.0.9",
|
||||||
"@inquirer/type": "^2.0.0",
|
"@inquirer/type": "^3.0.2",
|
||||||
"@types/mute-stream": "^0.0.4",
|
|
||||||
"@types/node": "^22.5.5",
|
|
||||||
"@types/wrap-ansi": "^3.0.0",
|
|
||||||
"ansi-escapes": "^4.3.2",
|
"ansi-escapes": "^4.3.2",
|
||||||
"cli-width": "^4.1.0",
|
"cli-width": "^4.1.0",
|
||||||
"mute-stream": "^1.0.0",
|
"mute-stream": "^2.0.0",
|
||||||
"signal-exit": "^4.1.0",
|
"signal-exit": "^4.1.0",
|
||||||
"strip-ansi": "^6.0.1",
|
"strip-ansi": "^6.0.1",
|
||||||
"wrap-ansi": "^6.2.0",
|
"wrap-ansi": "^6.2.0",
|
||||||
@@ -172,41 +175,36 @@
|
|||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@inquirer/core/node_modules/@inquirer/type": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/type/-/type-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-XvJRx+2KR3YXyYtPUUy+qd9i7p+GO9Ko6VIIpWlBrpWwXDv8WLFeHTxz35CfQFUiBMLXlGHhGzys7lqit9gWag==",
|
|
||||||
"dependencies": {
|
|
||||||
"mute-stream": "^1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@inquirer/editor": {
|
"node_modules/@inquirer/editor": {
|
||||||
"version": "2.2.0",
|
"version": "4.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.3.tgz",
|
||||||
"integrity": "sha512-9KHOpJ+dIL5SZli8lJ6xdaYLPPzB8xB9GZItg39MBybzhxA16vxmszmQFrRwbOA918WA2rvu8xhDEg/p6LXKbw==",
|
"integrity": "sha512-S9KnIOJuTZpb9upeRSBBhoDZv7aSV3pG9TECrBj0f+ZsFwccz886hzKBrChGrXMJwd4NKY+pOA9Vy72uqnd6Eg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@inquirer/core": "^9.1.0",
|
"@inquirer/core": "^10.1.4",
|
||||||
"@inquirer/type": "^1.5.3",
|
"@inquirer/type": "^3.0.2",
|
||||||
"external-editor": "^3.1.0"
|
"external-editor": "^3.1.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@inquirer/expand": {
|
"node_modules/@inquirer/expand": {
|
||||||
"version": "2.3.0",
|
"version": "4.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.6.tgz",
|
||||||
"integrity": "sha512-qnJsUcOGCSG1e5DTOErmv2BPQqrtT6uzqn1vI/aYGiPKq+FgslGZmtdnXbhuI7IlT7OByDoEEqdnhUnVR2hhLw==",
|
"integrity": "sha512-TRTfi1mv1GeIZGyi9PQmvAaH65ZlG4/FACq6wSzs7Vvf1z5dnNWsAAXBjWMHt76l+1hUY8teIqJFrWBk5N6gsg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@inquirer/core": "^9.1.0",
|
"@inquirer/core": "^10.1.4",
|
||||||
"@inquirer/type": "^1.5.3",
|
"@inquirer/type": "^3.0.2",
|
||||||
"yoctocolors-cjs": "^2.1.2"
|
"yoctocolors-cjs": "^2.1.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@inquirer/figures": {
|
"node_modules/@inquirer/figures": {
|
||||||
@@ -218,113 +216,134 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@inquirer/input": {
|
"node_modules/@inquirer/input": {
|
||||||
"version": "2.3.0",
|
"version": "4.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/input/-/input-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.1.3.tgz",
|
||||||
"integrity": "sha512-XfnpCStx2xgh1LIRqPXrTNEEByqQWoxsWYzNRSEUxJ5c6EQlhMogJ3vHKu8aXuTacebtaZzMAHwEL0kAflKOBw==",
|
"integrity": "sha512-zeo++6f7hxaEe7OjtMzdGZPHiawsfmCZxWB9X1NpmYgbeoyerIbWemvlBxxl+sQIlHC0WuSAG19ibMq3gbhaqQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@inquirer/core": "^9.1.0",
|
"@inquirer/core": "^10.1.4",
|
||||||
"@inquirer/type": "^1.5.3"
|
"@inquirer/type": "^3.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@inquirer/number": {
|
"node_modules/@inquirer/number": {
|
||||||
"version": "1.1.0",
|
"version": "3.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/number/-/number-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.6.tgz",
|
||||||
"integrity": "sha512-ilUnia/GZUtfSZy3YEErXLJ2Sljo/mf9fiKc08n18DdwdmDbOzRcTv65H1jjDvlsAuvdFXf4Sa/aL7iw/NanVA==",
|
"integrity": "sha512-xO07lftUHk1rs1gR0KbqB+LJPhkUNkyzV/KhH+937hdkMazmAYHLm1OIrNKpPelppeV1FgWrgFDjdUD8mM+XUg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@inquirer/core": "^9.1.0",
|
"@inquirer/core": "^10.1.4",
|
||||||
"@inquirer/type": "^1.5.3"
|
"@inquirer/type": "^3.0.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@inquirer/password": {
|
"node_modules/@inquirer/password": {
|
||||||
"version": "2.2.0",
|
"version": "4.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/password/-/password-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.6.tgz",
|
||||||
"integrity": "sha512-5otqIpgsPYIshqhgtEwSspBQE40etouR8VIxzpJkv9i0dVHIpyhiivbkH9/dGiMLdyamT54YRdGJLfl8TFnLHg==",
|
"integrity": "sha512-QLF0HmMpHZPPMp10WGXh6F+ZPvzWE7LX6rNoccdktv/Rov0B+0f+eyXkAcgqy5cH9V+WSpbLxu2lo3ysEVK91w==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@inquirer/core": "^9.1.0",
|
"@inquirer/core": "^10.1.4",
|
||||||
"@inquirer/type": "^1.5.3",
|
"@inquirer/type": "^3.0.2",
|
||||||
"ansi-escapes": "^4.3.2"
|
"ansi-escapes": "^4.3.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@inquirer/prompts": {
|
"node_modules/@inquirer/prompts": {
|
||||||
"version": "5.5.0",
|
"version": "7.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-5.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.2.3.tgz",
|
||||||
"integrity": "sha512-BHDeL0catgHdcHbSFFUddNzvx/imzJMft+tWDPwTm3hfu8/tApk1HrooNngB2Mb4qY+KaRWF+iZqoVUPeslEog==",
|
"integrity": "sha512-hzfnm3uOoDySDXfDNOm9usOuYIaQvTgKp/13l1uJoe6UNY+Zpcn2RYt0jXz3yA+yemGHvDOxVzqWl3S5sQq53Q==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@inquirer/checkbox": "^2.5.0",
|
"@inquirer/checkbox": "^4.0.6",
|
||||||
"@inquirer/confirm": "^3.2.0",
|
"@inquirer/confirm": "^5.1.3",
|
||||||
"@inquirer/editor": "^2.2.0",
|
"@inquirer/editor": "^4.2.3",
|
||||||
"@inquirer/expand": "^2.3.0",
|
"@inquirer/expand": "^4.0.6",
|
||||||
"@inquirer/input": "^2.3.0",
|
"@inquirer/input": "^4.1.3",
|
||||||
"@inquirer/number": "^1.1.0",
|
"@inquirer/number": "^3.0.6",
|
||||||
"@inquirer/password": "^2.2.0",
|
"@inquirer/password": "^4.0.6",
|
||||||
"@inquirer/rawlist": "^2.3.0",
|
"@inquirer/rawlist": "^4.0.6",
|
||||||
"@inquirer/search": "^1.1.0",
|
"@inquirer/search": "^3.0.6",
|
||||||
"@inquirer/select": "^2.5.0"
|
"@inquirer/select": "^4.0.6"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@inquirer/rawlist": {
|
"node_modules/@inquirer/rawlist": {
|
||||||
"version": "2.3.0",
|
"version": "4.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.0.6.tgz",
|
||||||
"integrity": "sha512-zzfNuINhFF7OLAtGHfhwOW2TlYJyli7lOUoJUXw/uyklcwalV6WRXBXtFIicN8rTRK1XTiPWB4UY+YuW8dsnLQ==",
|
"integrity": "sha512-QoE4s1SsIPx27FO4L1b1mUjVcoHm1pWE/oCmm4z/Hl+V1Aw5IXl8FYYzGmfXaBT0l/sWr49XmNSiq7kg3Kd/Lg==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@inquirer/core": "^9.1.0",
|
"@inquirer/core": "^10.1.4",
|
||||||
"@inquirer/type": "^1.5.3",
|
"@inquirer/type": "^3.0.2",
|
||||||
"yoctocolors-cjs": "^2.1.2"
|
"yoctocolors-cjs": "^2.1.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@inquirer/search": {
|
"node_modules/@inquirer/search": {
|
||||||
"version": "1.1.0",
|
"version": "3.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/search/-/search-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.6.tgz",
|
||||||
"integrity": "sha512-h+/5LSj51dx7hp5xOn4QFnUaKeARwUCLs6mIhtkJ0JYPBLmEYjdHSYh7I6GrLg9LwpJ3xeX0FZgAG1q0QdCpVQ==",
|
"integrity": "sha512-eFZ2hiAq0bZcFPuFFBmZEtXU1EarHLigE+ENCtpO+37NHCl4+Yokq1P/d09kUblObaikwfo97w+0FtG/EXl5Ng==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@inquirer/core": "^9.1.0",
|
"@inquirer/core": "^10.1.4",
|
||||||
"@inquirer/figures": "^1.0.5",
|
"@inquirer/figures": "^1.0.9",
|
||||||
"@inquirer/type": "^1.5.3",
|
"@inquirer/type": "^3.0.2",
|
||||||
"yoctocolors-cjs": "^2.1.2"
|
"yoctocolors-cjs": "^2.1.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@inquirer/select": {
|
"node_modules/@inquirer/select": {
|
||||||
"version": "2.5.0",
|
"version": "4.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/select/-/select-2.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.0.6.tgz",
|
||||||
"integrity": "sha512-YmDobTItPP3WcEI86GvPo+T2sRHkxxOq/kXmsBjHS5BVXUgvgZ5AfJjkvQvZr03T81NnI3KrrRuMzeuYUQRFOA==",
|
"integrity": "sha512-yANzIiNZ8fhMm4NORm+a74+KFYHmf7BZphSOBovIzYPVLquseTGEkU5l2UTnBOf5k0VLmTgPighNDLE9QtbViQ==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@inquirer/core": "^9.1.0",
|
"@inquirer/core": "^10.1.4",
|
||||||
"@inquirer/figures": "^1.0.5",
|
"@inquirer/figures": "^1.0.9",
|
||||||
"@inquirer/type": "^1.5.3",
|
"@inquirer/type": "^3.0.2",
|
||||||
"ansi-escapes": "^4.3.2",
|
"ansi-escapes": "^4.3.2",
|
||||||
"yoctocolors-cjs": "^2.1.2"
|
"yoctocolors-cjs": "^2.1.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@inquirer/type": {
|
"node_modules/@inquirer/type": {
|
||||||
"version": "1.5.5",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.5.tgz",
|
"resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.2.tgz",
|
||||||
"integrity": "sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==",
|
"integrity": "sha512-ZhQ4TvhwHZF+lGhQ2O/rsjo80XoZR5/5qhOY3t6FJuX5XBg5Be8YzYTvaUGJnc12AUGI2nr4QSUE4PhKSigx7g==",
|
||||||
"dependencies": {
|
|
||||||
"mute-stream": "^1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/node": ">=18"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@mixmark-io/domino": {
|
"node_modules/@mixmark-io/domino": {
|
||||||
@@ -367,27 +386,15 @@
|
|||||||
"node": ">= 8"
|
"node": ">= 8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/mute-stream": {
|
|
||||||
"version": "0.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/mute-stream/-/mute-stream-0.0.4.tgz",
|
|
||||||
"integrity": "sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/node": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "22.10.7",
|
"version": "22.10.7",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.7.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.7.tgz",
|
||||||
"integrity": "sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg==",
|
"integrity": "sha512-V09KvXxFiutGp6B7XkpaDXlNadZxrzajcY50EuoLIpQ6WWYCSvf19lVIazzfIzQvhUN2HjX12spLojTnhuKlGg==",
|
||||||
|
"peer": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~6.20.0"
|
"undici-types": "~6.20.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/wrap-ansi": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/wrap-ansi/-/wrap-ansi-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g=="
|
|
||||||
},
|
|
||||||
"node_modules/@ungap/structured-clone": {
|
"node_modules/@ungap/structured-clone": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.1.tgz",
|
||||||
@@ -445,17 +452,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ansi-escapes/node_modules/type-fest": {
|
|
||||||
"version": "0.21.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
|
|
||||||
"integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/ansi-regex": {
|
"node_modules/ansi-regex": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||||
@@ -587,9 +583,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/commander": {
|
"node_modules/commander": {
|
||||||
"version": "13.0.0",
|
"version": "13.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/commander/-/commander-13.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz",
|
||||||
"integrity": "sha512-oPYleIY8wmTVzkvQq10AEok6YcTC4sRUBl8F9gVuwchGVUCTbl/vhLTaQqutuuySYOsu8YTgV+OxKc/8Yvx+mQ==",
|
"integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
}
|
}
|
||||||
@@ -1007,6 +1003,18 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/globals/node_modules/type-fest": {
|
||||||
|
"version": "0.20.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
||||||
|
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
||||||
|
"dev": true,
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/graphemer": {
|
"node_modules/graphemer": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
|
||||||
@@ -1084,24 +1092,6 @@
|
|||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/inquirer": {
|
|
||||||
"version": "10.2.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-10.2.2.tgz",
|
|
||||||
"integrity": "sha512-tyao/4Vo36XnUItZ7DnUXX4f1jVao2mSrleV/5IPtW/XAEA26hRVsbc68nuTEKWcr5vMP/1mVoT2O7u8H4v1Vg==",
|
|
||||||
"dependencies": {
|
|
||||||
"@inquirer/core": "^9.1.0",
|
|
||||||
"@inquirer/prompts": "^5.5.0",
|
|
||||||
"@inquirer/type": "^1.5.3",
|
|
||||||
"@types/mute-stream": "^0.0.4",
|
|
||||||
"ansi-escapes": "^4.3.2",
|
|
||||||
"mute-stream": "^1.0.0",
|
|
||||||
"run-async": "^3.0.0",
|
|
||||||
"rxjs": "^7.8.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=18"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/is-extglob": {
|
"node_modules/is-extglob": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
|
||||||
@@ -1265,11 +1255,11 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/mute-stream": {
|
"node_modules/mute-stream": {
|
||||||
"version": "1.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz",
|
||||||
"integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==",
|
"integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
|
"node": "^18.17.0 || >=20.5.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/natural-compare": {
|
"node_modules/natural-compare": {
|
||||||
@@ -1459,14 +1449,6 @@
|
|||||||
"url": "https://github.com/sponsors/isaacs"
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/run-async": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/run-async/-/run-async-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-540WwVDOMxA6dN6We19EcT9sc3hkXPw5mzRNGM3FkdN/vtE9NFvj5lFAPNwUDmJjXidm3v7TC1cTE7t17Ulm1Q==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.12.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/run-parallel": {
|
"node_modules/run-parallel": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||||
@@ -1490,14 +1472,6 @@
|
|||||||
"queue-microtask": "^1.2.2"
|
"queue-microtask": "^1.2.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/rxjs": {
|
|
||||||
"version": "7.8.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
|
|
||||||
"integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
|
|
||||||
"dependencies": {
|
|
||||||
"tslib": "^2.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/safer-buffer": {
|
"node_modules/safer-buffer": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
@@ -1605,11 +1579,6 @@
|
|||||||
"node": ">=0.6.0"
|
"node": ">=0.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tslib": {
|
|
||||||
"version": "2.8.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
|
||||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
|
||||||
},
|
|
||||||
"node_modules/turndown": {
|
"node_modules/turndown": {
|
||||||
"version": "7.2.0",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/turndown/-/turndown-7.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/turndown/-/turndown-7.2.0.tgz",
|
||||||
@@ -1636,10 +1605,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/type-fest": {
|
"node_modules/type-fest": {
|
||||||
"version": "0.20.2",
|
"version": "0.21.3",
|
||||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
|
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
|
||||||
"integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
|
"integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
},
|
},
|
||||||
@@ -1650,7 +1618,8 @@
|
|||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "6.20.0",
|
"version": "6.20.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
|
||||||
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="
|
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
|
||||||
|
"peer": true
|
||||||
},
|
},
|
||||||
"node_modules/uri-js": {
|
"node_modules/uri-js": {
|
||||||
"version": "4.4.1",
|
"version": "4.4.1",
|
||||||
|
|||||||
+1
-1
@@ -21,11 +21,11 @@
|
|||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@inquirer/prompts": "^7.2.3",
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
"camelcase": "^8.0.0",
|
"camelcase": "^8.0.0",
|
||||||
"chalk": "^5.4.1",
|
"chalk": "^5.4.1",
|
||||||
"commander": "^13.0.0",
|
"commander": "^13.0.0",
|
||||||
"inquirer": "^10.2.2",
|
|
||||||
"luxon": "^3.5.0",
|
"luxon": "^3.5.0",
|
||||||
"turndown": "^7.2.0",
|
"turndown": "^7.2.0",
|
||||||
"turndown-plugin-gfm": "^1.0.2",
|
"turndown-plugin-gfm": "^1.0.2",
|
||||||
|
|||||||
+159
@@ -0,0 +1,159 @@
|
|||||||
|
import camelcase from 'camelcase';
|
||||||
|
import chalk from 'chalk';
|
||||||
|
import * as commander from 'commander';
|
||||||
|
import * as luxon from 'luxon';
|
||||||
|
import path from 'path';
|
||||||
|
import * as normalizers from './normalizers.js';
|
||||||
|
import * as questions from './questions.js';
|
||||||
|
import * as shared from './shared.js';
|
||||||
|
|
||||||
|
// visual formatting for wizard
|
||||||
|
const promptTheme = {
|
||||||
|
prefix: {
|
||||||
|
idle: chalk.gray('\n?'),
|
||||||
|
done: chalk.green('✓')
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
description: (text) => chalk.gray('example: ' + text)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function getConfig() {
|
||||||
|
// check command line for any config options
|
||||||
|
const commandLineQuestions = questions.all;
|
||||||
|
const commandLineAnswers = getCommandLineAnswers(commandLineQuestions);
|
||||||
|
|
||||||
|
let wizardAnswers;
|
||||||
|
if (commandLineAnswers.wizard) {
|
||||||
|
console.log('\nStarting wizard...');
|
||||||
|
|
||||||
|
// run wizard for remaining config options
|
||||||
|
const wizardQuestions = questions.all.filter((question) => !(camelcase(question.name) in commandLineAnswers));
|
||||||
|
wizardAnswers = await getWizardAnswers(wizardQuestions, commandLineAnswers);
|
||||||
|
} else {
|
||||||
|
console.log('\nSkipping wizard...');
|
||||||
|
}
|
||||||
|
|
||||||
|
return { ...commandLineAnswers, ...wizardAnswers };
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCommandLineAnswers(questions) {
|
||||||
|
// show errors in red
|
||||||
|
commander.program.configureOutput({
|
||||||
|
outputError: (str, write) => write(chalk.red(str))
|
||||||
|
});
|
||||||
|
|
||||||
|
questions.forEach((question) => {
|
||||||
|
const option = new commander.Option('--' + question.name + ' <' + question.type + '>', question.description);
|
||||||
|
option.default(question.default);
|
||||||
|
|
||||||
|
if (question.choices && question.type !== 'boolean') {
|
||||||
|
// let commander handle non-boolean multiple choice validation
|
||||||
|
option.choices(question.choices.map((choice) => choice.value));
|
||||||
|
} else {
|
||||||
|
option.argParser((value) => normalize(value, question.type, (errorMessage) => {
|
||||||
|
throw new commander.InvalidArgumentError(errorMessage);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
commander.program.addOption(option);
|
||||||
|
});
|
||||||
|
|
||||||
|
const answers = commander.program.parse().opts();
|
||||||
|
|
||||||
|
// do some post-processing on the answers
|
||||||
|
for (const [key, value] of Object.entries(answers)) {
|
||||||
|
// the "wizard" answer and any user-provided (not defaulted) answers are left alone
|
||||||
|
if (key === 'wizard' || commander.program.getOptionValueSource(key) !== 'default') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (answers.wizard) {
|
||||||
|
// remove this default answer so the wizard will ask about it later
|
||||||
|
delete answers[key];
|
||||||
|
} else {
|
||||||
|
// normalize and validate default answer
|
||||||
|
const question = questions.find((question) => camelcase(question.name) === key);
|
||||||
|
answers[key] = normalize(value, question.type, (errorMessage) => {
|
||||||
|
// this is formatted to match how commander displays other errors
|
||||||
|
commander.program.error(`error: option '--${question.name} <${question.type}>' argument '${value}' is invalid. ${errorMessage}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return answers;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getWizardAnswers(questions, commandLineAnswers) {
|
||||||
|
const answers = {};
|
||||||
|
for (const question of questions) {
|
||||||
|
let answerKey = camelcase(question.name);
|
||||||
|
let normalizedAnswer; // holds normalized answer value potentially returned during validation
|
||||||
|
|
||||||
|
const promptConfig = {
|
||||||
|
theme: promptTheme,
|
||||||
|
message: question.description + '?',
|
||||||
|
default: question.default,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (question.choices) {
|
||||||
|
promptConfig.choices = question.choices;
|
||||||
|
promptConfig.loop = false;
|
||||||
|
|
||||||
|
if (question.isPathQuestion) {
|
||||||
|
// create a snapshot config of command line answers and wizard answers so far
|
||||||
|
const config = { ...commandLineAnswers, ...answers };
|
||||||
|
|
||||||
|
promptConfig.choices.forEach((choice) => {
|
||||||
|
// show example path if this choice is selected
|
||||||
|
config[answerKey] = choice.value;
|
||||||
|
choice.description = buildSamplePostPath(config);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
promptConfig.validate = (value) => {
|
||||||
|
let validationErrorMessage;
|
||||||
|
normalizedAnswer = normalize(value, question.type, (errorMessage) => {
|
||||||
|
validationErrorMessage = errorMessage;
|
||||||
|
});
|
||||||
|
return validationErrorMessage ?? true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const answer = await question.prompt(promptConfig).catch((ex) => {
|
||||||
|
// exit gracefully if user hits ctrl + c during wizard
|
||||||
|
if (ex instanceof Error && ex.name === 'ExitPromptError') {
|
||||||
|
console.log('\nUser quit wizard early.');
|
||||||
|
process.exit(0);
|
||||||
|
} else {
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
answers[answerKey] = normalizedAnswer ?? answer;
|
||||||
|
}
|
||||||
|
|
||||||
|
return answers;
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalize(value, type, onError) {
|
||||||
|
const normalizer = normalizers[camelcase(type)];
|
||||||
|
if (!normalizer) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return normalizer(value);
|
||||||
|
} catch (ex) {
|
||||||
|
onError(ex.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildSamplePostPath(config) {
|
||||||
|
const outputDir = path.sep;
|
||||||
|
const type = '';
|
||||||
|
const date = luxon.DateTime.now().toFormat('yyyy-LL-dd');
|
||||||
|
const slug = 'my-post';
|
||||||
|
|
||||||
|
return shared.buildPostPath(outputDir, type, date, slug, config);
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
export function boolean(value) {
|
||||||
|
if (typeof value === 'boolean') {
|
||||||
|
return value;
|
||||||
|
} else if (value === 'true') {
|
||||||
|
return true;
|
||||||
|
} else if (value === 'false') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('Must be true or false.');
|
||||||
|
}
|
||||||
|
|
||||||
|
export function filePath(value) {
|
||||||
|
const unwrapped = value.replace(/"(.*?)"/, '$1');
|
||||||
|
const absolute = path.resolve(unwrapped);
|
||||||
|
|
||||||
|
let fileExists;
|
||||||
|
try {
|
||||||
|
fileExists = fs.existsSync(absolute) && fs.statSync(absolute).isFile();
|
||||||
|
} catch (ex) {
|
||||||
|
fileExists = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileExists) {
|
||||||
|
return absolute;
|
||||||
|
} else {
|
||||||
|
throw new Error('File not found at ' + absolute + '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
-15
@@ -14,14 +14,14 @@ export async function parseFilePromise(config) {
|
|||||||
});
|
});
|
||||||
const channelData = allData.rss.channel[0].item;
|
const channelData = allData.rss.channel[0].item;
|
||||||
|
|
||||||
const postTypes = getPostTypes(channelData, config);
|
const postTypes = getPostTypes(channelData);
|
||||||
const posts = collectPosts(channelData, postTypes, config);
|
const posts = collectPosts(channelData, postTypes, config);
|
||||||
|
|
||||||
const images = [];
|
const images = [];
|
||||||
if (config.saveAttachedImages) {
|
if (config.saveImages === 'attached' || config.saveImages === 'all') {
|
||||||
images.push(...collectAttachedImages(channelData));
|
images.push(...collectAttachedImages(channelData));
|
||||||
}
|
}
|
||||||
if (config.saveScrapedImages) {
|
if (config.saveImages === 'scraped' || config.saveImages === 'all') {
|
||||||
images.push(...collectScrapedImages(channelData, postTypes));
|
images.push(...collectScrapedImages(channelData, postTypes));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,18 +31,12 @@ export async function parseFilePromise(config) {
|
|||||||
return posts;
|
return posts;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPostTypes(channelData, config) {
|
function getPostTypes(channelData) {
|
||||||
if (config.includeOtherTypes) {
|
// search export file for all post types minus some specific types we don't want
|
||||||
// search export file for all post types minus some default types we don't want
|
const types = channelData
|
||||||
// effectively this will be 'post', 'page', and custom post types
|
.map(item => item.post_type[0])
|
||||||
const types = channelData
|
.filter(type => !settings.filter_post_types.includes(type));
|
||||||
.map(item => item.post_type[0])
|
return [...new Set(types)]; // remove duplicates
|
||||||
.filter(type => !['attachment', 'revision', 'nav_menu_item', 'custom_css', 'customize_changeset'].includes(type));
|
|
||||||
return [...new Set(types)]; // remove duplicates
|
|
||||||
} else {
|
|
||||||
// just plain old vanilla "post" posts
|
|
||||||
return ['post'];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getItemsOfType(channelData, type) {
|
function getItemsOfType(channelData, type) {
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
import * as inquirer from '@inquirer/prompts';
|
||||||
|
|
||||||
|
export const all = [
|
||||||
|
{
|
||||||
|
name: 'wizard',
|
||||||
|
type: 'boolean',
|
||||||
|
description: 'Use wizard',
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'input',
|
||||||
|
type: 'file-path',
|
||||||
|
description: 'Path to WordPress export file',
|
||||||
|
default: 'export.xml',
|
||||||
|
prompt: inquirer.input
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'post-folders',
|
||||||
|
type: 'boolean',
|
||||||
|
description: 'Put each post into its own folder',
|
||||||
|
default: true,
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
name: 'Yes',
|
||||||
|
value: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'No',
|
||||||
|
value: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
isPathQuestion: true,
|
||||||
|
prompt: inquirer.select
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'prefix-date',
|
||||||
|
type: 'boolean',
|
||||||
|
description: 'Prefix with date',
|
||||||
|
default: false,
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
name: 'Yes',
|
||||||
|
value: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'No',
|
||||||
|
value: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
isPathQuestion: true,
|
||||||
|
prompt: inquirer.select
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'date-folders',
|
||||||
|
type: 'choice',
|
||||||
|
description: 'Organize into folders based on date',
|
||||||
|
default: 'none',
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
name: 'Year folders',
|
||||||
|
value: 'year'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Year and month folders',
|
||||||
|
value: 'year-month'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'No',
|
||||||
|
value: 'none'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
isPathQuestion: true,
|
||||||
|
prompt: inquirer.select
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'save-images',
|
||||||
|
type: 'choice',
|
||||||
|
description: 'Save images',
|
||||||
|
default: 'all',
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
name: 'Images attached to posts',
|
||||||
|
value: 'attached'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Images scraped from post body content',
|
||||||
|
value: 'scraped'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Both',
|
||||||
|
value: 'all'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'No',
|
||||||
|
value: 'none'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
prompt: inquirer.select
|
||||||
|
}
|
||||||
|
];
|
||||||
@@ -38,3 +38,17 @@ export const filter_categories = ['uncategorized'];
|
|||||||
// Strict SSL is enabled as the safe default when downloading images, but will not work with
|
// Strict SSL is enabled as the safe default when downloading images, but will not work with
|
||||||
// self-signed servers. You can disable it if you're getting a "self-signed certificate" error.
|
// self-signed servers. You can disable it if you're getting a "self-signed certificate" error.
|
||||||
export const strict_ssl = true;
|
export const strict_ssl = true;
|
||||||
|
|
||||||
|
// Post types to exclude from output.
|
||||||
|
export const filter_post_types = [
|
||||||
|
'attachment',
|
||||||
|
'revision',
|
||||||
|
'nav_menu_item',
|
||||||
|
'custom_css',
|
||||||
|
'customize_changeset',
|
||||||
|
'wp_global_styles',
|
||||||
|
'wp_navigation'
|
||||||
|
];
|
||||||
|
|
||||||
|
// Output directory.
|
||||||
|
export const output_directory = 'output';
|
||||||
|
|||||||
@@ -1,3 +1,42 @@
|
|||||||
|
import * as luxon from 'luxon';
|
||||||
|
import path from 'path';
|
||||||
|
import * as settings from './settings.js';
|
||||||
|
|
||||||
|
export function buildPostPath(outputDir, type, date, slug, config) {
|
||||||
|
let dt;
|
||||||
|
if (settings.custom_date_formatting) {
|
||||||
|
dt = luxon.DateTime.fromFormat(date, settings.custom_date_formatting);
|
||||||
|
} else {
|
||||||
|
dt = luxon.DateTime.fromISO(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
// start with base output dir and post type
|
||||||
|
const pathSegments = [outputDir, type];
|
||||||
|
|
||||||
|
if (config.dateFolders === 'year' || config.dateFolders === 'year-month') {
|
||||||
|
pathSegments.push(dt.toFormat('yyyy'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.dateFolders === 'year-month') {
|
||||||
|
pathSegments.push(dt.toFormat('LL'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// create slug fragment, possibly date prefixed
|
||||||
|
let slugFragment = slug;
|
||||||
|
if (config.prefixDate) {
|
||||||
|
slugFragment = dt.toFormat('yyyy-LL-dd') + '-' + slugFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use slug fragment as folder or filename as specified
|
||||||
|
if (config.postFolders) {
|
||||||
|
pathSegments.push(slugFragment, 'index.md');
|
||||||
|
} else {
|
||||||
|
pathSegments.push(slugFragment + '.md');
|
||||||
|
}
|
||||||
|
|
||||||
|
return path.join(...pathSegments);
|
||||||
|
}
|
||||||
|
|
||||||
export function getFilenameFromUrl(url) {
|
export function getFilenameFromUrl(url) {
|
||||||
let filename = url.split('/').slice(-1)[0];
|
let filename = url.split('/').slice(-1)[0];
|
||||||
try {
|
try {
|
||||||
|
|||||||
-196
@@ -1,196 +0,0 @@
|
|||||||
import camelcase from 'camelcase';
|
|
||||||
import * as commander from 'commander';
|
|
||||||
import fs from 'fs';
|
|
||||||
import inquirer from 'inquirer';
|
|
||||||
import path from 'path';
|
|
||||||
|
|
||||||
// all user options for command line and wizard are declared here
|
|
||||||
const options = [
|
|
||||||
// wizard must always be first
|
|
||||||
{
|
|
||||||
name: 'wizard',
|
|
||||||
type: 'boolean',
|
|
||||||
description: 'Use wizard',
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'input',
|
|
||||||
type: 'file',
|
|
||||||
description: 'Path to WordPress export file',
|
|
||||||
default: 'export.xml'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'output',
|
|
||||||
type: 'folder',
|
|
||||||
description: 'Path to output folder',
|
|
||||||
default: 'output'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'year-folders',
|
|
||||||
aliases: ['yearfolders', 'yearmonthfolders'],
|
|
||||||
type: 'boolean',
|
|
||||||
description: 'Create year folders',
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'month-folders',
|
|
||||||
aliases: ['yearmonthfolders'],
|
|
||||||
type: 'boolean',
|
|
||||||
description: 'Create month folders',
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'post-folders',
|
|
||||||
aliases: ['postfolders'],
|
|
||||||
type: 'boolean',
|
|
||||||
description: 'Create a folder for each post',
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'prefix-date',
|
|
||||||
aliases: ['prefixdate'],
|
|
||||||
type: 'boolean',
|
|
||||||
description: 'Prefix post folders/files with date',
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'save-attached-images',
|
|
||||||
aliases: ['saveimages'],
|
|
||||||
type: 'boolean',
|
|
||||||
description: 'Save images attached to posts',
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'save-scraped-images',
|
|
||||||
aliases: ['addcontentimages'],
|
|
||||||
type: 'boolean',
|
|
||||||
description: 'Save images scraped from post body content',
|
|
||||||
default: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'include-other-types',
|
|
||||||
type: 'boolean',
|
|
||||||
description: 'Include custom post types and pages',
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
export async function getConfig(argv) {
|
|
||||||
extendOptionsData();
|
|
||||||
const unaliasedArgv = replaceAliases(argv);
|
|
||||||
const opts = parseCommandLine(unaliasedArgv);
|
|
||||||
|
|
||||||
let answers;
|
|
||||||
if (opts.wizard) {
|
|
||||||
console.log('\nStarting wizard...');
|
|
||||||
const questions = options.map(option => ({
|
|
||||||
when: option.name !== 'wizard' && !option.isProvided,
|
|
||||||
name: camelcase(option.name),
|
|
||||||
type: option.prompt,
|
|
||||||
message: option.description + '?',
|
|
||||||
default: option.default,
|
|
||||||
|
|
||||||
// these are not used for all option types and that's fine
|
|
||||||
filter: option.coerce,
|
|
||||||
validate: option.validate
|
|
||||||
}));
|
|
||||||
answers = await inquirer.prompt(questions);
|
|
||||||
} else {
|
|
||||||
console.log('\nSkipping wizard...');
|
|
||||||
answers = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const config = { ...opts, ...answers };
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
function extendOptionsData() {
|
|
||||||
// add more data to each option based on its type
|
|
||||||
const map = {
|
|
||||||
boolean: {
|
|
||||||
prompt: 'confirm',
|
|
||||||
coerce: coerceBoolean,
|
|
||||||
},
|
|
||||||
file: {
|
|
||||||
prompt: 'input',
|
|
||||||
coerce: coercePath,
|
|
||||||
validate: validateFile
|
|
||||||
},
|
|
||||||
folder: {
|
|
||||||
prompt: 'input',
|
|
||||||
coerce: coercePath
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
options.forEach(option => {
|
|
||||||
Object.assign(option, map[option.type]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function replaceAliases(argv) {
|
|
||||||
let paths = argv.slice(0, 2);
|
|
||||||
let replaced = [];
|
|
||||||
let unmodified = [];
|
|
||||||
|
|
||||||
argv.slice(2).forEach(arg => {
|
|
||||||
let aliasFound = false;
|
|
||||||
|
|
||||||
// this loop does not short circuit because an alias can map to multiple options
|
|
||||||
options.forEach(option => {
|
|
||||||
const aliases = option.aliases || [];
|
|
||||||
aliases.forEach(alias => {
|
|
||||||
if (arg.includes('--' + alias)) {
|
|
||||||
replaced.push(arg.replace('--' + alias, '--' + option.name));
|
|
||||||
aliasFound = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!aliasFound) {
|
|
||||||
unmodified.push(arg);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return [...paths, ...replaced, ...unmodified];
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseCommandLine(argv) {
|
|
||||||
// setup for help output
|
|
||||||
commander.program
|
|
||||||
.name('node index.js')
|
|
||||||
.helpOption('-h, --help', 'See the thing you\'re looking at right now')
|
|
||||||
.addHelpText('after', '\nMore documentation is at https://github.com/lonekorean/wordpress-export-to-markdown');
|
|
||||||
|
|
||||||
options.forEach(input => {
|
|
||||||
const flag = '--' + input.name + ' <' + input.type + '>';
|
|
||||||
const coerce = (value) => {
|
|
||||||
// commander only calls coerce when an input is provided on the command line, which
|
|
||||||
// makes for an easy way to flag (for later) if it should be excluded from the wizard
|
|
||||||
input.isProvided = true;
|
|
||||||
return input.coerce(value);
|
|
||||||
};
|
|
||||||
commander.program.option(flag, input.description, coerce, input.default);
|
|
||||||
});
|
|
||||||
|
|
||||||
commander.program.parse(argv);
|
|
||||||
return commander.program.opts();
|
|
||||||
}
|
|
||||||
|
|
||||||
function coerceBoolean(value) {
|
|
||||||
return !['false', 'no', '0'].includes(value.toString().toLowerCase());
|
|
||||||
}
|
|
||||||
|
|
||||||
function coercePath(value) {
|
|
||||||
return path.normalize(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function validateFile(value) {
|
|
||||||
let isValid;
|
|
||||||
try {
|
|
||||||
isValid = fs.existsSync(value) && fs.statSync(value).isFile();
|
|
||||||
} catch (ex) {
|
|
||||||
isValid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return isValid ? true : 'Unable to find file: ' + path.resolve(value);
|
|
||||||
}
|
|
||||||
+11
-43
@@ -3,7 +3,6 @@ import chalk from 'chalk';
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import http from 'http';
|
import http from 'http';
|
||||||
import https from 'https';
|
import https from 'https';
|
||||||
import * as luxon from 'luxon';
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import * as settings from './settings.js';
|
import * as settings from './settings.js';
|
||||||
import * as shared from './shared.js';
|
import * as shared from './shared.js';
|
||||||
@@ -22,7 +21,7 @@ async function processPayloadsPromise(payloads, loadFunc) {
|
|||||||
console.log(chalk.green('[OK]') + ' ' + payload.name);
|
console.log(chalk.green('[OK]') + ' ' + payload.name);
|
||||||
resolve();
|
resolve();
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
console.log(chalk.red('[FAILED]') + ' ' + payload.name + ' ' + chalk.red('(' + ex.toString() + ')'));
|
console.log(chalk.red('[FAILED]') + ' ' + payload.name + ' ' + chalk.red('(' + ex.message + ')'));
|
||||||
reject();
|
reject();
|
||||||
}
|
}
|
||||||
}, payload.delay);
|
}, payload.delay);
|
||||||
@@ -47,7 +46,7 @@ async function writeMarkdownFilesPromise(posts, config) {
|
|||||||
let skipCount = 0;
|
let skipCount = 0;
|
||||||
let delay = 0;
|
let delay = 0;
|
||||||
const payloads = posts.flatMap(post => {
|
const payloads = posts.flatMap(post => {
|
||||||
const destinationPath = getPostPath(post, config);
|
const destinationPath = buildPostPath(post, config);
|
||||||
if (checkFile(destinationPath)) {
|
if (checkFile(destinationPath)) {
|
||||||
// already exists, don't need to save again
|
// already exists, don't need to save again
|
||||||
skipCount++;
|
skipCount++;
|
||||||
@@ -55,7 +54,7 @@ async function writeMarkdownFilesPromise(posts, config) {
|
|||||||
} else {
|
} else {
|
||||||
const payload = {
|
const payload = {
|
||||||
item: post,
|
item: post,
|
||||||
name: (config.includeOtherTypes ? post.meta.type + ' - ' : '') + post.meta.slug,
|
name: post.meta.type + ' - ' + post.meta.slug,
|
||||||
destinationPath,
|
destinationPath,
|
||||||
delay
|
delay
|
||||||
};
|
};
|
||||||
@@ -105,7 +104,7 @@ async function writeImageFilesPromise(posts, config) {
|
|||||||
let skipCount = 0;
|
let skipCount = 0;
|
||||||
let delay = 0;
|
let delay = 0;
|
||||||
const payloads = posts.flatMap(post => {
|
const payloads = posts.flatMap(post => {
|
||||||
const postPath = getPostPath(post, config);
|
const postPath = buildPostPath(post, config);
|
||||||
const imagesDir = path.join(path.dirname(postPath), 'images');
|
const imagesDir = path.join(path.dirname(postPath), 'images');
|
||||||
return post.meta.imageUrls.flatMap(imageUrl => {
|
return post.meta.imageUrls.flatMap(imageUrl => {
|
||||||
const filename = shared.getFilenameFromUrl(imageUrl);
|
const filename = shared.getFilenameFromUrl(imageUrl);
|
||||||
@@ -162,7 +161,7 @@ async function loadImageFilePromise(imageUrl) {
|
|||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
if (ex.response) {
|
if (ex.response) {
|
||||||
// request was made, but server responded with an error status code
|
// request was made, but server responded with an error status code
|
||||||
throw 'StatusCodeError: ' + ex.response.status;
|
throw new Error('StatusCodeError: ' + ex.response.status);
|
||||||
} else {
|
} else {
|
||||||
// something else went wrong, rethrow
|
// something else went wrong, rethrow
|
||||||
throw ex;
|
throw ex;
|
||||||
@@ -171,44 +170,13 @@ async function loadImageFilePromise(imageUrl) {
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPostPath(post, config) {
|
function buildPostPath(post, config) {
|
||||||
let dt;
|
const outputDir = settings.output_directory;
|
||||||
if (settings.custom_date_formatting) {
|
const type = post.meta.type;
|
||||||
dt = luxon.DateTime.fromFormat(post.frontmatter.date, settings.custom_date_formatting);
|
const date = post.frontmatter.date;
|
||||||
} else {
|
const slug = post.meta.slug;
|
||||||
dt = luxon.DateTime.fromISO(post.frontmatter.date);
|
|
||||||
}
|
|
||||||
|
|
||||||
// start with base output dir
|
return shared.buildPostPath(outputDir, type, date, slug, config);
|
||||||
const pathSegments = [config.output];
|
|
||||||
|
|
||||||
// create segment for post type if we're dealing with more than just "post"
|
|
||||||
if (config.includeOtherTypes) {
|
|
||||||
pathSegments.push(post.meta.type);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.yearFolders) {
|
|
||||||
pathSegments.push(dt.toFormat('yyyy'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.monthFolders) {
|
|
||||||
pathSegments.push(dt.toFormat('LL'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// create slug fragment, possibly date prefixed
|
|
||||||
let slugFragment = post.meta.slug;
|
|
||||||
if (config.prefixDate) {
|
|
||||||
slugFragment = dt.toFormat('yyyy-LL-dd') + '-' + slugFragment;
|
|
||||||
}
|
|
||||||
|
|
||||||
// use slug fragment as folder or filename as specified
|
|
||||||
if (config.postFolders) {
|
|
||||||
pathSegments.push(slugFragment, 'index.md');
|
|
||||||
} else {
|
|
||||||
pathSegments.push(slugFragment + '.md');
|
|
||||||
}
|
|
||||||
|
|
||||||
return path.join(...pathSegments);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkFile(path) {
|
function checkFile(path) {
|
||||||
|
|||||||
Reference in New Issue
Block a user