@plttn/mkd 0.2.0 → 0.2.1
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/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +7 -2
package/dist/index.cjs
CHANGED
|
@@ -103,7 +103,7 @@ async function generateFrontmatter(title, config) {
|
|
|
103
103
|
const description = await makeDescription(title);
|
|
104
104
|
const data = {
|
|
105
105
|
[config.titleKey]: title,
|
|
106
|
-
[config.publishedAtKey]: "3000-01-01T00:00:00Z",
|
|
106
|
+
[config.publishedAtKey]: /* @__PURE__ */ new Date("3000-01-01T00:00:00Z"),
|
|
107
107
|
[config.authorKey]: config.author,
|
|
108
108
|
[config.draftKey]: true,
|
|
109
109
|
[config.descriptionKey]: description,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/lib/deps.ts","../src/commands/new.ts","../src/commands/publish.ts","../src/lib/commands.ts","../src/commands/update.ts","../src/commands/unpublish.ts","../src/commands/init.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { run, subcommands } from \"cmd-ts\";\nimport { PoweredFileSystem } from \"pwd-fs\";\nimport { loadConfig } from \"./lib/deps\";\nimport { makeNewCommand } from \"./commands/new\";\nimport { makePublishCommand } from \"./commands/publish\";\nimport { makeUpdateCommand } from \"./commands/update\";\nimport { makeUnPublishCommand } from \"./commands/unpublish\";\nimport { makeInitCommand } from \"./commands/init\";\n\nasync function main() {\n const pfs = new PoweredFileSystem();\n const config = await loadConfig(pfs);\n const deps = { config, pfs };\n\n const app = subcommands({\n name: \"mkd\",\n cmds: {\n new: makeNewCommand(deps),\n publish: makePublishCommand(deps),\n update: makeUpdateCommand(deps),\n unpublish: makeUnPublishCommand(deps),\n init: makeInitCommand(deps),\n },\n });\n\n await run(app, process.argv.slice(2));\n}\n\nmain().catch((error) => {\n console.error(error);\n process.exit(1);\n});\n","import type { PoweredFileSystem } from \"pwd-fs\";\n\nexport type Config = {\n blogDir: string;\n titleKey: string;\n author: string;\n publishedAtKey: string;\n modifiedAtKey: string;\n authorKey: string;\n draftKey: string;\n descriptionKey: string;\n tagsKey: string;\n};\n\nexport type Deps = {\n config: Config;\n pfs: PoweredFileSystem;\n};\n\nconst defaultConfig: Config = {\n blogDir: \"./src/blog\",\n titleKey: \"title\",\n author: \"\",\n publishedAtKey: \"publishedAt\",\n modifiedAtKey: \"updatedAt\",\n authorKey: \"author\",\n draftKey: \"draft\",\n descriptionKey: \"description\",\n tagsKey: \"tags\",\n};\n\nexport async function loadConfig(pfs: PoweredFileSystem): Promise<Config> {\n try {\n const raw = await pfs.read(\"./mkd.json\");\n\n if (!raw.trim()) {\n return defaultConfig;\n }\n\n const parsed = JSON.parse(raw);\n\n if (!isRecord(parsed)) {\n return defaultConfig;\n }\n\n const { $schema: _schema, ...config } = parsed;\n\n return {\n ...defaultConfig,\n ...config,\n };\n } catch {\n return defaultConfig;\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { command, restPositionals, string } from \"cmd-ts\";\nimport path from \"node:path\";\nimport slugify from \"@sindresorhus/slugify\";\nimport filenamify from \"filenamify\";\nimport matter from \"gray-matter\";\nimport { isCancel, text, intro, outro } from \"@clack/prompts\";\nimport type { Config, Deps } from \"../lib/deps\";\n\nexport function makeNewCommand({ config, pfs }: Deps) {\n return command({\n name: \"new\",\n description: \"Create a new post\",\n args: {\n new: restPositionals({\n type: string,\n displayName: \"file\",\n description: \"name of the new post\",\n }),\n },\n handler: async ({ new: titleArray }) => {\n intro(\"Create a new post\");\n let title: string;\n if (titleArray.length === 0) {\n title = await generateTitle();\n if (title === \"\") {\n return;\n }\n } else {\n title = titleArray.join(\" \");\n }\n const slug = slugify(title);\n const fileName = filenamify(slug);\n const frontmatter = await generateFrontmatter(title, config);\n const filePath = path.join(config.blogDir, `${fileName}.md`);\n\n await pfs.write(filePath, frontmatter);\n },\n });\n}\n\nasync function generateFrontmatter(\n title: string,\n config: Config,\n): Promise<string> {\n const description = await makeDescription(title);\n // const now = new Date();\n\n const data = {\n [config.titleKey]: title,\n [config.publishedAtKey]: \"3000-01-01T00:00:00Z\",\n [config.authorKey]: config.author,\n [config.draftKey]: true,\n [config.descriptionKey]: description,\n [config.tagsKey]: [],\n };\n\n return matter.stringify(\"\", data);\n}\n\nasync function makeDescription(title: string): Promise<string> {\n const description = await text({\n message: \"Enter a description for the post:\",\n defaultValue: title,\n });\n\n if (isCancel(description)) {\n return \"\";\n }\n\n return description;\n}\n\nasync function generateTitle(): Promise<string> {\n const title = await text({\n message: \"Enter a title for the post:\",\n validate: (value) => {\n if (!value) {\n return \"Title required\";\n }\n return undefined;\n },\n });\n\n if (isCancel(title)) {\n return \"\";\n }\n\n return title;\n}\n","import { command } from \"cmd-ts\";\nimport { isCancel, intro, outro, autocomplete } from \"@clack/prompts\";\nimport matter from \"gray-matter\";\nimport type { Config, Deps } from \"../lib/deps\";\nimport {\n readPosts,\n parseFrontmatter,\n postsToOptions,\n selectedValuesToPosts,\n Post,\n} from \"../lib/commands\";\n\nexport function makePublishCommand({ config, pfs }: Deps) {\n return command({\n name: \"publish\",\n description: \"Undraft a post\",\n args: {},\n handler: async () => {\n const posts = await readPosts(pfs, config);\n const drafts = posts.filter(\n (post) => parseFrontmatter(post)[config.draftKey] === true,\n );\n const selected = await getPostsToPublish(drafts, config);\n\n for (const draft of selected) {\n await updateDraftFrontMatter(draft, { config, pfs });\n }\n },\n });\n}\n\nasync function getPostsToPublish(\n drafts: Post[],\n config: Config,\n): Promise<Post[]> {\n const options = postsToOptions(drafts, config);\n intro(\"Publishing posts\");\n\n const selected = await autocomplete({\n message: \"Select post to publish\",\n options,\n });\n\n if (isCancel(selected)) {\n outro(\"Publishing cancelled.\");\n return [];\n }\n\n outro(\"Posts undrafted...\");\n\n return selectedValuesToPosts(\n Array.isArray(selected) ? selected : [selected],\n drafts,\n );\n}\n\nasync function updateDraftFrontMatter(draft: Post, deps: Deps) {\n const now = new Date();\n const parsed = matter(draft.content);\n const fm = parsed.data as Record<string, unknown>;\n fm[deps.config.draftKey] = false;\n fm[deps.config.publishedAtKey] = now;\n const updatedContent = matter.stringify(parsed.content, fm);\n await deps.pfs.write(`${deps.config.blogDir}/${draft.file}`, updatedContent);\n return { ...draft, content: updatedContent };\n}\n","import matter from \"gray-matter\";\nimport type { Config, Deps } from \"./deps\";\n\nexport type Post = {\n file: string;\n content: string;\n};\n\nexport type Frontmatter = Record<string, unknown>;\n\n/** Read all files from the blog directory and return them as Post objects */\nexport async function readPosts(pfs: Deps[\"pfs\"], config: Config): Promise<Post[]> {\n const files = (await pfs.readdir(config.blogDir)) as string[];\n const posts: Post[] = [];\n\n for (const file of files) {\n const content = await pfs.read(`${config.blogDir}/${file}`);\n posts.push({ file, content });\n }\n\n return posts;\n}\n\n/** Parse frontmatter from a Post */\nexport function parseFrontmatter(post: Post): Frontmatter {\n const { data } = matter(post.content);\n return data as Frontmatter;\n}\n\n/** Convert Posts to prompt option objects (value/label/hint) */\nexport function postsToOptions(posts: Post[], config: Config) {\n return posts.map((post) => {\n const fm = parseFrontmatter(post);\n const title = String(fm[config.titleKey] ?? post.file);\n\n return {\n value: post.file,\n label: title,\n hint: post.file,\n };\n });\n}\n\n/** Take the raw selected values returned by the prompt and return matching Post[] */\nexport function selectedValuesToPosts(selected: string[] | symbol, posts: Post[]): Post[] {\n if (typeof selected === \"symbol\") return [];\n return posts.filter((p) => selected.includes(p.file));\n}\n\nexport function findPostByFile(posts: Post[], fileName: string): Post | undefined {\n return posts.find((p) => p.file === fileName);\n}\n","import { command } from \"cmd-ts\";\nimport { autocomplete, isCancel, intro, outro } from \"@clack/prompts\";\nimport matter from \"gray-matter\";\nimport type { Config, Deps } from \"../lib/deps\";\nimport {\n readPosts,\n postsToOptions,\n findPostByFile,\n Post,\n} from \"../lib/commands\";\n\ntype Frontmatter = Record<string, unknown>;\n\nexport function makeUpdateCommand({ config, pfs }: Deps) {\n return command({\n name: \"update\",\n description: \"Update a post's modified date\",\n args: {},\n handler: async () => {\n const posts = await readPosts(pfs, config);\n const post = await getPostToUpdate(posts, config);\n if (!post) return;\n\n await updatePostDate(post, { config, pfs });\n },\n });\n}\n\nasync function getPostToUpdate(\n posts: Post[],\n config: Config,\n): Promise<Post | null> {\n const options = postsToOptions(posts, config);\n\n intro(\"Update a post\");\n\n const selected = await autocomplete({\n message: \"Select post to update\",\n options,\n });\n\n if (isCancel(selected)) {\n outro(\"Update cancelled.\");\n return null;\n }\n outro(\"Post updated.\");\n\n const found = findPostByFile(posts, selected as string);\n return found ?? null;\n}\n\nasync function updatePostDate(post: Post, deps: Deps) {\n const parsed = matter(post.content);\n const fm = parsed.data as Record<string, unknown>;\n fm[deps.config.modifiedAtKey] = new Date();\n const updatedContent = matter.stringify(parsed.content, fm);\n await deps.pfs.write(`${deps.config.blogDir}/${post.file}`, updatedContent);\n return { ...post, content: updatedContent };\n}\n","import { command } from \"cmd-ts\";\nimport { autocomplete, isCancel, intro, outro } from \"@clack/prompts\";\nimport matter from \"gray-matter\";\nimport type { Config, Deps } from \"../lib/deps\";\nimport {\n readPosts,\n postsToOptions,\n findPostByFile,\n Post,\n} from \"../lib/commands\";\n\ntype Frontmatter = Record<string, unknown>;\n\nexport function makeUnPublishCommand({ config, pfs }: Deps) {\n return command({\n name: \"unpublish\",\n description: \"Unpublish a post\",\n args: {},\n handler: async () => {\n const posts = await readPosts(pfs, config);\n const post = await getPostToUnpub(posts, config);\n if (!post) return;\n\n await unpubPost(post, { config, pfs });\n },\n });\n}\n\nasync function getPostToUnpub(\n posts: Post[],\n config: Config,\n): Promise<Post | null> {\n const options = postsToOptions(posts, config);\n\n intro(\"Unpublish a post\");\n\n const selected = await autocomplete({\n message: \"Select post to unpublish\",\n options,\n });\n\n if (isCancel(selected)) {\n outro(\"Unpublish cancelled.\");\n return null;\n }\n outro(\"Post unpublished.\");\n\n const found = findPostByFile(posts, selected as string);\n return found ?? null;\n}\n\nasync function unpubPost(post: Post, deps: Deps) {\n const parsed = matter(post.content);\n const fm = parsed.data as Record<string, unknown>;\n fm[deps.config.draftKey] = true;\n const updatedContent = matter.stringify(parsed.content, fm);\n await deps.pfs.write(`${deps.config.blogDir}/${post.file}`, updatedContent);\n return { ...post, content: updatedContent };\n}\n","import { command } from \"cmd-ts\";\nimport { text, isCancel, intro, outro } from \"@clack/prompts\";\nimport type { Deps } from \"../lib/deps\";\n\nexport function makeInitCommand({ config, pfs }: Deps) {\n return command({\n name: \"init\",\n description: \"Create or update mkd.json configuration\",\n args: {},\n handler: async () => {\n intro(\"Initialize mkd configuration\");\n\n const blogDir = await text({\n message: \"Directory where generated posts are written\",\n defaultValue: String(config.blogDir ?? \"./src/blog\"),\n });\n if (isCancel(blogDir)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const author = await text({\n message: \"Default author\",\n defaultValue: String(config.author ?? \"\"),\n });\n if (isCancel(author)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const titleKey = await text({\n message: \"Title frontmatter key\",\n defaultValue: String(config.titleKey ?? \"title\"),\n });\n if (isCancel(titleKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const publishedAtKey = await text({\n message: \"Published date frontmatter key\",\n defaultValue: String(config.publishedAtKey ?? \"publishedAt\"),\n });\n if (isCancel(publishedAtKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const modifiedAtKey = await text({\n message: \"Modified date frontmatter key\",\n defaultValue: String(config.modifiedAtKey ?? \"updatedAt\"),\n });\n if (isCancel(modifiedAtKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const authorKey = await text({\n message: \"Author frontmatter key\",\n defaultValue: String(config.authorKey ?? \"author\"),\n });\n if (isCancel(authorKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const draftKey = await text({\n message: \"Draft frontmatter key\",\n defaultValue: String(config.draftKey ?? \"draft\"),\n });\n if (isCancel(draftKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const descriptionKey = await text({\n message: \"Description frontmatter key\",\n defaultValue: String(config.descriptionKey ?? \"description\"),\n });\n if (isCancel(descriptionKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const tagsKey = await text({\n message: \"Tags frontmatter key\",\n defaultValue: String(config.tagsKey ?? \"tags\"),\n });\n if (isCancel(tagsKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const newConfig = {\n blogDir: String(blogDir),\n author: String(author),\n publishedAtKey: String(publishedAtKey),\n modifiedAtKey: String(modifiedAtKey),\n authorKey: String(authorKey),\n draftKey: String(draftKey),\n descriptionKey: String(descriptionKey),\n tagsKey: String(tagsKey),\n titleKey: String(titleKey),\n };\n\n await pfs.write(\"./mkd.json\", JSON.stringify(newConfig, null, 2) + \"\\n\");\n\n outro(\"Configuration saved to mkd.json\");\n },\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AACA,IAAAA,iBAAiC;AACjC,oBAAkC;;;ACiBlC,IAAM,gBAAwB;AAAA,EAC5B,SAAS;AAAA,EACT,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,WAAW;AAAA,EACX,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB,SAAS;AACX;AAEA,eAAsB,WAAW,KAAyC;AACxE,MAAI;AACF,UAAM,MAAM,MAAM,IAAI,KAAK,YAAY;AAEvC,QAAI,CAAC,IAAI,KAAK,GAAG;AACf,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,KAAK,MAAM,GAAG;AAE7B,QAAI,CAAC,SAAS,MAAM,GAAG;AACrB,aAAO;AAAA,IACT;AAEA,UAAM,EAAE,SAAS,SAAS,GAAG,OAAO,IAAI;AAExC,WAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;;;AC1DA,oBAAiD;AACjD,uBAAiB;AACjB,qBAAoB;AACpB,wBAAuB;AACvB,yBAAmB;AACnB,qBAA6C;AAGtC,SAAS,eAAe,EAAE,QAAQ,IAAI,GAAS;AACpD,aAAO,uBAAQ;AAAA,IACb,MAAM;AAAA,IACN,aAAa;AAAA,IACb,MAAM;AAAA,MACJ,SAAK,+BAAgB;AAAA,QACnB,MAAM;AAAA,QACN,aAAa;AAAA,QACb,aAAa;AAAA,MACf,CAAC;AAAA,IACH;AAAA,IACA,SAAS,OAAO,EAAE,KAAK,WAAW,MAAM;AACtC,gCAAM,mBAAmB;AACzB,UAAI;AACJ,UAAI,WAAW,WAAW,GAAG;AAC3B,gBAAQ,MAAM,cAAc;AAC5B,YAAI,UAAU,IAAI;AAChB;AAAA,QACF;AAAA,MACF,OAAO;AACL,gBAAQ,WAAW,KAAK,GAAG;AAAA,MAC7B;AACA,YAAM,WAAO,eAAAC,SAAQ,KAAK;AAC1B,YAAM,eAAW,kBAAAC,SAAW,IAAI;AAChC,YAAM,cAAc,MAAM,oBAAoB,OAAO,MAAM;AAC3D,YAAM,WAAW,iBAAAC,QAAK,KAAK,OAAO,SAAS,GAAG,QAAQ,KAAK;AAE3D,YAAM,IAAI,MAAM,UAAU,WAAW;AAAA,IACvC;AAAA,EACF,CAAC;AACH;AAEA,eAAe,oBACb,OACA,QACiB;AACjB,QAAM,cAAc,MAAM,gBAAgB,KAAK;AAG/C,QAAM,OAAO;AAAA,IACX,CAAC,OAAO,QAAQ,GAAG;AAAA,IACnB,CAAC,OAAO,cAAc,GAAG;AAAA,IACzB,CAAC,OAAO,SAAS,GAAG,OAAO;AAAA,IAC3B,CAAC,OAAO,QAAQ,GAAG;AAAA,IACnB,CAAC,OAAO,cAAc,GAAG;AAAA,IACzB,CAAC,OAAO,OAAO,GAAG,CAAC;AAAA,EACrB;AAEA,SAAO,mBAAAC,QAAO,UAAU,IAAI,IAAI;AAClC;AAEA,eAAe,gBAAgB,OAAgC;AAC7D,QAAM,cAAc,UAAM,qBAAK;AAAA,IAC7B,SAAS;AAAA,IACT,cAAc;AAAA,EAChB,CAAC;AAED,UAAI,yBAAS,WAAW,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,eAAe,gBAAiC;AAC9C,QAAM,QAAQ,UAAM,qBAAK;AAAA,IACvB,SAAS;AAAA,IACT,UAAU,CAAC,UAAU;AACnB,UAAI,CAAC,OAAO;AACV,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,UAAI,yBAAS,KAAK,GAAG;AACnB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;ACxFA,IAAAC,iBAAwB;AACxB,IAAAC,kBAAqD;AACrD,IAAAC,sBAAmB;;;ACFnB,IAAAC,sBAAmB;AAWnB,eAAsB,UAAU,KAAkB,QAAiC;AACjF,QAAM,QAAS,MAAM,IAAI,QAAQ,OAAO,OAAO;AAC/C,QAAM,QAAgB,CAAC;AAEvB,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,MAAM,IAAI,KAAK,GAAG,OAAO,OAAO,IAAI,IAAI,EAAE;AAC1D,UAAM,KAAK,EAAE,MAAM,QAAQ,CAAC;AAAA,EAC9B;AAEA,SAAO;AACT;AAGO,SAAS,iBAAiB,MAAyB;AACxD,QAAM,EAAE,KAAK,QAAI,oBAAAC,SAAO,KAAK,OAAO;AACpC,SAAO;AACT;AAGO,SAAS,eAAe,OAAe,QAAgB;AAC5D,SAAO,MAAM,IAAI,CAAC,SAAS;AACzB,UAAM,KAAK,iBAAiB,IAAI;AAChC,UAAM,QAAQ,OAAO,GAAG,OAAO,QAAQ,KAAK,KAAK,IAAI;AAErD,WAAO;AAAA,MACL,OAAO,KAAK;AAAA,MACZ,OAAO;AAAA,MACP,MAAM,KAAK;AAAA,IACb;AAAA,EACF,CAAC;AACH;AAGO,SAAS,sBAAsB,UAA6B,OAAuB;AACxF,MAAI,OAAO,aAAa,SAAU,QAAO,CAAC;AAC1C,SAAO,MAAM,OAAO,CAAC,MAAM,SAAS,SAAS,EAAE,IAAI,CAAC;AACtD;AAEO,SAAS,eAAe,OAAe,UAAoC;AAChF,SAAO,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ;AAC9C;;;ADvCO,SAAS,mBAAmB,EAAE,QAAQ,IAAI,GAAS;AACxD,aAAO,wBAAQ;AAAA,IACb,MAAM;AAAA,IACN,aAAa;AAAA,IACb,MAAM,CAAC;AAAA,IACP,SAAS,YAAY;AACnB,YAAM,QAAQ,MAAM,UAAU,KAAK,MAAM;AACzC,YAAM,SAAS,MAAM;AAAA,QACnB,CAAC,SAAS,iBAAiB,IAAI,EAAE,OAAO,QAAQ,MAAM;AAAA,MACxD;AACA,YAAM,WAAW,MAAM,kBAAkB,QAAQ,MAAM;AAEvD,iBAAW,SAAS,UAAU;AAC5B,cAAM,uBAAuB,OAAO,EAAE,QAAQ,IAAI,CAAC;AAAA,MACrD;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,eAAe,kBACb,QACA,QACiB;AACjB,QAAM,UAAU,eAAe,QAAQ,MAAM;AAC7C,6BAAM,kBAAkB;AAExB,QAAM,WAAW,UAAM,8BAAa;AAAA,IAClC,SAAS;AAAA,IACT;AAAA,EACF,CAAC;AAED,UAAI,0BAAS,QAAQ,GAAG;AACtB,+BAAM,uBAAuB;AAC7B,WAAO,CAAC;AAAA,EACV;AAEA,6BAAM,oBAAoB;AAE1B,SAAO;AAAA,IACL,MAAM,QAAQ,QAAQ,IAAI,WAAW,CAAC,QAAQ;AAAA,IAC9C;AAAA,EACF;AACF;AAEA,eAAe,uBAAuB,OAAa,MAAY;AAC7D,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,aAAS,oBAAAC,SAAO,MAAM,OAAO;AACnC,QAAM,KAAK,OAAO;AAClB,KAAG,KAAK,OAAO,QAAQ,IAAI;AAC3B,KAAG,KAAK,OAAO,cAAc,IAAI;AACjC,QAAM,iBAAiB,oBAAAA,QAAO,UAAU,OAAO,SAAS,EAAE;AAC1D,QAAM,KAAK,IAAI,MAAM,GAAG,KAAK,OAAO,OAAO,IAAI,MAAM,IAAI,IAAI,cAAc;AAC3E,SAAO,EAAE,GAAG,OAAO,SAAS,eAAe;AAC7C;;;AEjEA,IAAAC,iBAAwB;AACxB,IAAAC,kBAAqD;AACrD,IAAAC,sBAAmB;AAWZ,SAAS,kBAAkB,EAAE,QAAQ,IAAI,GAAS;AACvD,aAAO,wBAAQ;AAAA,IACb,MAAM;AAAA,IACN,aAAa;AAAA,IACb,MAAM,CAAC;AAAA,IACP,SAAS,YAAY;AACnB,YAAM,QAAQ,MAAM,UAAU,KAAK,MAAM;AACzC,YAAM,OAAO,MAAM,gBAAgB,OAAO,MAAM;AAChD,UAAI,CAAC,KAAM;AAEX,YAAM,eAAe,MAAM,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC5C;AAAA,EACF,CAAC;AACH;AAEA,eAAe,gBACb,OACA,QACsB;AACtB,QAAM,UAAU,eAAe,OAAO,MAAM;AAE5C,6BAAM,eAAe;AAErB,QAAM,WAAW,UAAM,8BAAa;AAAA,IAClC,SAAS;AAAA,IACT;AAAA,EACF,CAAC;AAED,UAAI,0BAAS,QAAQ,GAAG;AACtB,+BAAM,mBAAmB;AACzB,WAAO;AAAA,EACT;AACA,6BAAM,eAAe;AAErB,QAAM,QAAQ,eAAe,OAAO,QAAkB;AACtD,SAAO,SAAS;AAClB;AAEA,eAAe,eAAe,MAAY,MAAY;AACpD,QAAM,aAAS,oBAAAC,SAAO,KAAK,OAAO;AAClC,QAAM,KAAK,OAAO;AAClB,KAAG,KAAK,OAAO,aAAa,IAAI,oBAAI,KAAK;AACzC,QAAM,iBAAiB,oBAAAA,QAAO,UAAU,OAAO,SAAS,EAAE;AAC1D,QAAM,KAAK,IAAI,MAAM,GAAG,KAAK,OAAO,OAAO,IAAI,KAAK,IAAI,IAAI,cAAc;AAC1E,SAAO,EAAE,GAAG,MAAM,SAAS,eAAe;AAC5C;;;AC1DA,IAAAC,iBAAwB;AACxB,IAAAC,kBAAqD;AACrD,IAAAC,sBAAmB;AAWZ,SAAS,qBAAqB,EAAE,QAAQ,IAAI,GAAS;AAC1D,aAAO,wBAAQ;AAAA,IACb,MAAM;AAAA,IACN,aAAa;AAAA,IACb,MAAM,CAAC;AAAA,IACP,SAAS,YAAY;AACnB,YAAM,QAAQ,MAAM,UAAU,KAAK,MAAM;AACzC,YAAM,OAAO,MAAM,eAAe,OAAO,MAAM;AAC/C,UAAI,CAAC,KAAM;AAEX,YAAM,UAAU,MAAM,EAAE,QAAQ,IAAI,CAAC;AAAA,IACvC;AAAA,EACF,CAAC;AACH;AAEA,eAAe,eACb,OACA,QACsB;AACtB,QAAM,UAAU,eAAe,OAAO,MAAM;AAE5C,6BAAM,kBAAkB;AAExB,QAAM,WAAW,UAAM,8BAAa;AAAA,IAClC,SAAS;AAAA,IACT;AAAA,EACF,CAAC;AAED,UAAI,0BAAS,QAAQ,GAAG;AACtB,+BAAM,sBAAsB;AAC5B,WAAO;AAAA,EACT;AACA,6BAAM,mBAAmB;AAEzB,QAAM,QAAQ,eAAe,OAAO,QAAkB;AACtD,SAAO,SAAS;AAClB;AAEA,eAAe,UAAU,MAAY,MAAY;AAC/C,QAAM,aAAS,oBAAAC,SAAO,KAAK,OAAO;AAClC,QAAM,KAAK,OAAO;AAClB,KAAG,KAAK,OAAO,QAAQ,IAAI;AAC3B,QAAM,iBAAiB,oBAAAA,QAAO,UAAU,OAAO,SAAS,EAAE;AAC1D,QAAM,KAAK,IAAI,MAAM,GAAG,KAAK,OAAO,OAAO,IAAI,KAAK,IAAI,IAAI,cAAc;AAC1E,SAAO,EAAE,GAAG,MAAM,SAAS,eAAe;AAC5C;;;AC1DA,IAAAC,iBAAwB;AACxB,IAAAC,kBAA6C;AAGtC,SAAS,gBAAgB,EAAE,QAAQ,IAAI,GAAS;AACrD,aAAO,wBAAQ;AAAA,IACb,MAAM;AAAA,IACN,aAAa;AAAA,IACb,MAAM,CAAC;AAAA,IACP,SAAS,YAAY;AACnB,iCAAM,8BAA8B;AAEpC,YAAM,UAAU,UAAM,sBAAK;AAAA,QACzB,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,WAAW,YAAY;AAAA,MACrD,CAAC;AACD,cAAI,0BAAS,OAAO,GAAG;AACrB,mCAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,SAAS,UAAM,sBAAK;AAAA,QACxB,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,UAAU,EAAE;AAAA,MAC1C,CAAC;AACD,cAAI,0BAAS,MAAM,GAAG;AACpB,mCAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,WAAW,UAAM,sBAAK;AAAA,QAC1B,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,YAAY,OAAO;AAAA,MACjD,CAAC;AACD,cAAI,0BAAS,QAAQ,GAAG;AACtB,mCAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,iBAAiB,UAAM,sBAAK;AAAA,QAChC,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,kBAAkB,aAAa;AAAA,MAC7D,CAAC;AACD,cAAI,0BAAS,cAAc,GAAG;AAC5B,mCAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,gBAAgB,UAAM,sBAAK;AAAA,QAC/B,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,iBAAiB,WAAW;AAAA,MAC1D,CAAC;AACD,cAAI,0BAAS,aAAa,GAAG;AAC3B,mCAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,YAAY,UAAM,sBAAK;AAAA,QAC3B,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,aAAa,QAAQ;AAAA,MACnD,CAAC;AACD,cAAI,0BAAS,SAAS,GAAG;AACvB,mCAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,WAAW,UAAM,sBAAK;AAAA,QAC1B,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,YAAY,OAAO;AAAA,MACjD,CAAC;AACD,cAAI,0BAAS,QAAQ,GAAG;AACtB,mCAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,iBAAiB,UAAM,sBAAK;AAAA,QAChC,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,kBAAkB,aAAa;AAAA,MAC7D,CAAC;AACD,cAAI,0BAAS,cAAc,GAAG;AAC5B,mCAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,UAAU,UAAM,sBAAK;AAAA,QACzB,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,WAAW,MAAM;AAAA,MAC/C,CAAC;AACD,cAAI,0BAAS,OAAO,GAAG;AACrB,mCAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,YAAY;AAAA,QAChB,SAAS,OAAO,OAAO;AAAA,QACvB,QAAQ,OAAO,MAAM;AAAA,QACrB,gBAAgB,OAAO,cAAc;AAAA,QACrC,eAAe,OAAO,aAAa;AAAA,QACnC,WAAW,OAAO,SAAS;AAAA,QAC3B,UAAU,OAAO,QAAQ;AAAA,QACzB,gBAAgB,OAAO,cAAc;AAAA,QACrC,SAAS,OAAO,OAAO;AAAA,QACvB,UAAU,OAAO,QAAQ;AAAA,MAC3B;AAEA,YAAM,IAAI,MAAM,cAAc,KAAK,UAAU,WAAW,MAAM,CAAC,IAAI,IAAI;AAEvE,iCAAM,iCAAiC;AAAA,IACzC;AAAA,EACF,CAAC;AACH;;;APpGA,eAAe,OAAO;AACpB,QAAM,MAAM,IAAI,gCAAkB;AAClC,QAAM,SAAS,MAAM,WAAW,GAAG;AACnC,QAAM,OAAO,EAAE,QAAQ,IAAI;AAE3B,QAAM,UAAM,4BAAY;AAAA,IACtB,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,KAAK,eAAe,IAAI;AAAA,MACxB,SAAS,mBAAmB,IAAI;AAAA,MAChC,QAAQ,kBAAkB,IAAI;AAAA,MAC9B,WAAW,qBAAqB,IAAI;AAAA,MACpC,MAAM,gBAAgB,IAAI;AAAA,IAC5B;AAAA,EACF,CAAC;AAED,YAAM,oBAAI,KAAK,QAAQ,KAAK,MAAM,CAAC,CAAC;AACtC;AAEA,KAAK,EAAE,MAAM,CAAC,UAAU;AACtB,UAAQ,MAAM,KAAK;AACnB,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["import_cmd_ts","slugify","filenamify","path","matter","import_cmd_ts","import_prompts","import_gray_matter","import_gray_matter","matter","matter","import_cmd_ts","import_prompts","import_gray_matter","matter","import_cmd_ts","import_prompts","import_gray_matter","matter","import_cmd_ts","import_prompts"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/lib/deps.ts","../src/commands/new.ts","../src/commands/publish.ts","../src/lib/commands.ts","../src/commands/update.ts","../src/commands/unpublish.ts","../src/commands/init.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { run, subcommands } from \"cmd-ts\";\nimport { PoweredFileSystem } from \"pwd-fs\";\nimport { loadConfig } from \"./lib/deps\";\nimport { makeNewCommand } from \"./commands/new\";\nimport { makePublishCommand } from \"./commands/publish\";\nimport { makeUpdateCommand } from \"./commands/update\";\nimport { makeUnPublishCommand } from \"./commands/unpublish\";\nimport { makeInitCommand } from \"./commands/init\";\n\nasync function main() {\n const pfs = new PoweredFileSystem();\n const config = await loadConfig(pfs);\n const deps = { config, pfs };\n\n const app = subcommands({\n name: \"mkd\",\n cmds: {\n new: makeNewCommand(deps),\n publish: makePublishCommand(deps),\n update: makeUpdateCommand(deps),\n unpublish: makeUnPublishCommand(deps),\n init: makeInitCommand(deps),\n },\n });\n\n await run(app, process.argv.slice(2));\n}\n\nmain().catch((error) => {\n console.error(error);\n process.exit(1);\n});\n","import type { PoweredFileSystem } from \"pwd-fs\";\n\nexport type Config = {\n blogDir: string;\n titleKey: string;\n author: string;\n publishedAtKey: string;\n modifiedAtKey: string;\n authorKey: string;\n draftKey: string;\n descriptionKey: string;\n tagsKey: string;\n};\n\nexport type Deps = {\n config: Config;\n pfs: PoweredFileSystem;\n};\n\nconst defaultConfig: Config = {\n blogDir: \"./src/blog\",\n titleKey: \"title\",\n author: \"\",\n publishedAtKey: \"publishedAt\",\n modifiedAtKey: \"updatedAt\",\n authorKey: \"author\",\n draftKey: \"draft\",\n descriptionKey: \"description\",\n tagsKey: \"tags\",\n};\n\nexport async function loadConfig(pfs: PoweredFileSystem): Promise<Config> {\n try {\n const raw = await pfs.read(\"./mkd.json\");\n\n if (!raw.trim()) {\n return defaultConfig;\n }\n\n const parsed = JSON.parse(raw);\n\n if (!isRecord(parsed)) {\n return defaultConfig;\n }\n\n const { $schema: _schema, ...config } = parsed;\n\n return {\n ...defaultConfig,\n ...config,\n };\n } catch {\n return defaultConfig;\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { command, restPositionals, string } from \"cmd-ts\";\nimport path from \"node:path\";\nimport slugify from \"@sindresorhus/slugify\";\nimport filenamify from \"filenamify\";\nimport matter from \"gray-matter\";\nimport { isCancel, text, intro, outro } from \"@clack/prompts\";\nimport type { Config, Deps } from \"../lib/deps\";\n\nexport function makeNewCommand({ config, pfs }: Deps) {\n return command({\n name: \"new\",\n description: \"Create a new post\",\n args: {\n new: restPositionals({\n type: string,\n displayName: \"file\",\n description: \"name of the new post\",\n }),\n },\n handler: async ({ new: titleArray }) => {\n intro(\"Create a new post\");\n let title: string;\n if (titleArray.length === 0) {\n title = await generateTitle();\n if (title === \"\") {\n return;\n }\n } else {\n title = titleArray.join(\" \");\n }\n const slug = slugify(title);\n const fileName = filenamify(slug);\n const frontmatter = await generateFrontmatter(title, config);\n const filePath = path.join(config.blogDir, `${fileName}.md`);\n\n await pfs.write(filePath, frontmatter);\n },\n });\n}\n\nasync function generateFrontmatter(\n title: string,\n config: Config,\n): Promise<string> {\n const description = await makeDescription(title);\n // const now = new Date();\n\n const data = {\n [config.titleKey]: title,\n [config.publishedAtKey]: new Date(\"3000-01-01T00:00:00Z\"),\n [config.authorKey]: config.author,\n [config.draftKey]: true,\n [config.descriptionKey]: description,\n [config.tagsKey]: [],\n };\n\n return matter.stringify(\"\", data);\n}\n\nasync function makeDescription(title: string): Promise<string> {\n const description = await text({\n message: \"Enter a description for the post:\",\n defaultValue: title,\n });\n\n if (isCancel(description)) {\n return \"\";\n }\n\n return description;\n}\n\nasync function generateTitle(): Promise<string> {\n const title = await text({\n message: \"Enter a title for the post:\",\n validate: (value) => {\n if (!value) {\n return \"Title required\";\n }\n return undefined;\n },\n });\n\n if (isCancel(title)) {\n return \"\";\n }\n\n return title;\n}\n","import { command } from \"cmd-ts\";\nimport { isCancel, intro, outro, autocomplete } from \"@clack/prompts\";\nimport matter from \"gray-matter\";\nimport type { Config, Deps } from \"../lib/deps\";\nimport {\n readPosts,\n parseFrontmatter,\n postsToOptions,\n selectedValuesToPosts,\n Post,\n} from \"../lib/commands\";\n\nexport function makePublishCommand({ config, pfs }: Deps) {\n return command({\n name: \"publish\",\n description: \"Undraft a post\",\n args: {},\n handler: async () => {\n const posts = await readPosts(pfs, config);\n const drafts = posts.filter(\n (post) => parseFrontmatter(post)[config.draftKey] === true,\n );\n const selected = await getPostsToPublish(drafts, config);\n\n for (const draft of selected) {\n await updateDraftFrontMatter(draft, { config, pfs });\n }\n },\n });\n}\n\nasync function getPostsToPublish(\n drafts: Post[],\n config: Config,\n): Promise<Post[]> {\n const options = postsToOptions(drafts, config);\n intro(\"Publishing posts\");\n\n const selected = await autocomplete({\n message: \"Select post to publish\",\n options,\n });\n\n if (isCancel(selected)) {\n outro(\"Publishing cancelled.\");\n return [];\n }\n\n outro(\"Posts undrafted...\");\n\n return selectedValuesToPosts(\n Array.isArray(selected) ? selected : [selected],\n drafts,\n );\n}\n\nasync function updateDraftFrontMatter(draft: Post, deps: Deps) {\n const now = new Date();\n const parsed = matter(draft.content);\n const fm = parsed.data as Record<string, unknown>;\n fm[deps.config.draftKey] = false;\n fm[deps.config.publishedAtKey] = now;\n const updatedContent = matter.stringify(parsed.content, fm);\n await deps.pfs.write(`${deps.config.blogDir}/${draft.file}`, updatedContent);\n return { ...draft, content: updatedContent };\n}\n","import matter from \"gray-matter\";\nimport type { Config, Deps } from \"./deps\";\n\nexport type Post = {\n file: string;\n content: string;\n};\n\nexport type Frontmatter = Record<string, unknown>;\n\n/** Read all files from the blog directory and return them as Post objects */\nexport async function readPosts(pfs: Deps[\"pfs\"], config: Config): Promise<Post[]> {\n const files = (await pfs.readdir(config.blogDir)) as string[];\n const posts: Post[] = [];\n\n for (const file of files) {\n const content = await pfs.read(`${config.blogDir}/${file}`);\n posts.push({ file, content });\n }\n\n return posts;\n}\n\n/** Parse frontmatter from a Post */\nexport function parseFrontmatter(post: Post): Frontmatter {\n const { data } = matter(post.content);\n return data as Frontmatter;\n}\n\n/** Convert Posts to prompt option objects (value/label/hint) */\nexport function postsToOptions(posts: Post[], config: Config) {\n return posts.map((post) => {\n const fm = parseFrontmatter(post);\n const title = String(fm[config.titleKey] ?? post.file);\n\n return {\n value: post.file,\n label: title,\n hint: post.file,\n };\n });\n}\n\n/** Take the raw selected values returned by the prompt and return matching Post[] */\nexport function selectedValuesToPosts(selected: string[] | symbol, posts: Post[]): Post[] {\n if (typeof selected === \"symbol\") return [];\n return posts.filter((p) => selected.includes(p.file));\n}\n\nexport function findPostByFile(posts: Post[], fileName: string): Post | undefined {\n return posts.find((p) => p.file === fileName);\n}\n","import { command } from \"cmd-ts\";\nimport { autocomplete, isCancel, intro, outro } from \"@clack/prompts\";\nimport matter from \"gray-matter\";\nimport type { Config, Deps } from \"../lib/deps\";\nimport {\n readPosts,\n postsToOptions,\n findPostByFile,\n Post,\n} from \"../lib/commands\";\n\ntype Frontmatter = Record<string, unknown>;\n\nexport function makeUpdateCommand({ config, pfs }: Deps) {\n return command({\n name: \"update\",\n description: \"Update a post's modified date\",\n args: {},\n handler: async () => {\n const posts = await readPosts(pfs, config);\n const post = await getPostToUpdate(posts, config);\n if (!post) return;\n\n await updatePostDate(post, { config, pfs });\n },\n });\n}\n\nasync function getPostToUpdate(\n posts: Post[],\n config: Config,\n): Promise<Post | null> {\n const options = postsToOptions(posts, config);\n\n intro(\"Update a post\");\n\n const selected = await autocomplete({\n message: \"Select post to update\",\n options,\n });\n\n if (isCancel(selected)) {\n outro(\"Update cancelled.\");\n return null;\n }\n outro(\"Post updated.\");\n\n const found = findPostByFile(posts, selected as string);\n return found ?? null;\n}\n\nasync function updatePostDate(post: Post, deps: Deps) {\n const parsed = matter(post.content);\n const fm = parsed.data as Record<string, unknown>;\n fm[deps.config.modifiedAtKey] = new Date();\n const updatedContent = matter.stringify(parsed.content, fm);\n await deps.pfs.write(`${deps.config.blogDir}/${post.file}`, updatedContent);\n return { ...post, content: updatedContent };\n}\n","import { command } from \"cmd-ts\";\nimport { autocomplete, isCancel, intro, outro } from \"@clack/prompts\";\nimport matter from \"gray-matter\";\nimport type { Config, Deps } from \"../lib/deps\";\nimport {\n readPosts,\n postsToOptions,\n findPostByFile,\n Post,\n} from \"../lib/commands\";\n\ntype Frontmatter = Record<string, unknown>;\n\nexport function makeUnPublishCommand({ config, pfs }: Deps) {\n return command({\n name: \"unpublish\",\n description: \"Unpublish a post\",\n args: {},\n handler: async () => {\n const posts = await readPosts(pfs, config);\n const post = await getPostToUnpub(posts, config);\n if (!post) return;\n\n await unpubPost(post, { config, pfs });\n },\n });\n}\n\nasync function getPostToUnpub(\n posts: Post[],\n config: Config,\n): Promise<Post | null> {\n const options = postsToOptions(posts, config);\n\n intro(\"Unpublish a post\");\n\n const selected = await autocomplete({\n message: \"Select post to unpublish\",\n options,\n });\n\n if (isCancel(selected)) {\n outro(\"Unpublish cancelled.\");\n return null;\n }\n outro(\"Post unpublished.\");\n\n const found = findPostByFile(posts, selected as string);\n return found ?? null;\n}\n\nasync function unpubPost(post: Post, deps: Deps) {\n const parsed = matter(post.content);\n const fm = parsed.data as Record<string, unknown>;\n fm[deps.config.draftKey] = true;\n const updatedContent = matter.stringify(parsed.content, fm);\n await deps.pfs.write(`${deps.config.blogDir}/${post.file}`, updatedContent);\n return { ...post, content: updatedContent };\n}\n","import { command } from \"cmd-ts\";\nimport { text, isCancel, intro, outro } from \"@clack/prompts\";\nimport type { Deps } from \"../lib/deps\";\n\nexport function makeInitCommand({ config, pfs }: Deps) {\n return command({\n name: \"init\",\n description: \"Create or update mkd.json configuration\",\n args: {},\n handler: async () => {\n intro(\"Initialize mkd configuration\");\n\n const blogDir = await text({\n message: \"Directory where generated posts are written\",\n defaultValue: String(config.blogDir ?? \"./src/blog\"),\n });\n if (isCancel(blogDir)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const author = await text({\n message: \"Default author\",\n defaultValue: String(config.author ?? \"\"),\n });\n if (isCancel(author)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const titleKey = await text({\n message: \"Title frontmatter key\",\n defaultValue: String(config.titleKey ?? \"title\"),\n });\n if (isCancel(titleKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const publishedAtKey = await text({\n message: \"Published date frontmatter key\",\n defaultValue: String(config.publishedAtKey ?? \"publishedAt\"),\n });\n if (isCancel(publishedAtKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const modifiedAtKey = await text({\n message: \"Modified date frontmatter key\",\n defaultValue: String(config.modifiedAtKey ?? \"updatedAt\"),\n });\n if (isCancel(modifiedAtKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const authorKey = await text({\n message: \"Author frontmatter key\",\n defaultValue: String(config.authorKey ?? \"author\"),\n });\n if (isCancel(authorKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const draftKey = await text({\n message: \"Draft frontmatter key\",\n defaultValue: String(config.draftKey ?? \"draft\"),\n });\n if (isCancel(draftKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const descriptionKey = await text({\n message: \"Description frontmatter key\",\n defaultValue: String(config.descriptionKey ?? \"description\"),\n });\n if (isCancel(descriptionKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const tagsKey = await text({\n message: \"Tags frontmatter key\",\n defaultValue: String(config.tagsKey ?? \"tags\"),\n });\n if (isCancel(tagsKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const newConfig = {\n blogDir: String(blogDir),\n author: String(author),\n publishedAtKey: String(publishedAtKey),\n modifiedAtKey: String(modifiedAtKey),\n authorKey: String(authorKey),\n draftKey: String(draftKey),\n descriptionKey: String(descriptionKey),\n tagsKey: String(tagsKey),\n titleKey: String(titleKey),\n };\n\n await pfs.write(\"./mkd.json\", JSON.stringify(newConfig, null, 2) + \"\\n\");\n\n outro(\"Configuration saved to mkd.json\");\n },\n });\n}\n"],"mappings":"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","names":["import_cmd_ts","slugify","filenamify","path","matter","import_cmd_ts","import_prompts","import_gray_matter","import_gray_matter","matter","matter","import_cmd_ts","import_prompts","import_gray_matter","matter","import_cmd_ts","import_prompts","import_gray_matter","matter","import_cmd_ts","import_prompts"]}
|
package/dist/index.js
CHANGED
|
@@ -80,7 +80,7 @@ async function generateFrontmatter(title, config) {
|
|
|
80
80
|
const description = await makeDescription(title);
|
|
81
81
|
const data = {
|
|
82
82
|
[config.titleKey]: title,
|
|
83
|
-
[config.publishedAtKey]: "3000-01-01T00:00:00Z",
|
|
83
|
+
[config.publishedAtKey]: /* @__PURE__ */ new Date("3000-01-01T00:00:00Z"),
|
|
84
84
|
[config.authorKey]: config.author,
|
|
85
85
|
[config.draftKey]: true,
|
|
86
86
|
[config.descriptionKey]: description,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/lib/deps.ts","../src/commands/new.ts","../src/commands/publish.ts","../src/lib/commands.ts","../src/commands/update.ts","../src/commands/unpublish.ts","../src/commands/init.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { run, subcommands } from \"cmd-ts\";\nimport { PoweredFileSystem } from \"pwd-fs\";\nimport { loadConfig } from \"./lib/deps\";\nimport { makeNewCommand } from \"./commands/new\";\nimport { makePublishCommand } from \"./commands/publish\";\nimport { makeUpdateCommand } from \"./commands/update\";\nimport { makeUnPublishCommand } from \"./commands/unpublish\";\nimport { makeInitCommand } from \"./commands/init\";\n\nasync function main() {\n const pfs = new PoweredFileSystem();\n const config = await loadConfig(pfs);\n const deps = { config, pfs };\n\n const app = subcommands({\n name: \"mkd\",\n cmds: {\n new: makeNewCommand(deps),\n publish: makePublishCommand(deps),\n update: makeUpdateCommand(deps),\n unpublish: makeUnPublishCommand(deps),\n init: makeInitCommand(deps),\n },\n });\n\n await run(app, process.argv.slice(2));\n}\n\nmain().catch((error) => {\n console.error(error);\n process.exit(1);\n});\n","import type { PoweredFileSystem } from \"pwd-fs\";\n\nexport type Config = {\n blogDir: string;\n titleKey: string;\n author: string;\n publishedAtKey: string;\n modifiedAtKey: string;\n authorKey: string;\n draftKey: string;\n descriptionKey: string;\n tagsKey: string;\n};\n\nexport type Deps = {\n config: Config;\n pfs: PoweredFileSystem;\n};\n\nconst defaultConfig: Config = {\n blogDir: \"./src/blog\",\n titleKey: \"title\",\n author: \"\",\n publishedAtKey: \"publishedAt\",\n modifiedAtKey: \"updatedAt\",\n authorKey: \"author\",\n draftKey: \"draft\",\n descriptionKey: \"description\",\n tagsKey: \"tags\",\n};\n\nexport async function loadConfig(pfs: PoweredFileSystem): Promise<Config> {\n try {\n const raw = await pfs.read(\"./mkd.json\");\n\n if (!raw.trim()) {\n return defaultConfig;\n }\n\n const parsed = JSON.parse(raw);\n\n if (!isRecord(parsed)) {\n return defaultConfig;\n }\n\n const { $schema: _schema, ...config } = parsed;\n\n return {\n ...defaultConfig,\n ...config,\n };\n } catch {\n return defaultConfig;\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { command, restPositionals, string } from \"cmd-ts\";\nimport path from \"node:path\";\nimport slugify from \"@sindresorhus/slugify\";\nimport filenamify from \"filenamify\";\nimport matter from \"gray-matter\";\nimport { isCancel, text, intro, outro } from \"@clack/prompts\";\nimport type { Config, Deps } from \"../lib/deps\";\n\nexport function makeNewCommand({ config, pfs }: Deps) {\n return command({\n name: \"new\",\n description: \"Create a new post\",\n args: {\n new: restPositionals({\n type: string,\n displayName: \"file\",\n description: \"name of the new post\",\n }),\n },\n handler: async ({ new: titleArray }) => {\n intro(\"Create a new post\");\n let title: string;\n if (titleArray.length === 0) {\n title = await generateTitle();\n if (title === \"\") {\n return;\n }\n } else {\n title = titleArray.join(\" \");\n }\n const slug = slugify(title);\n const fileName = filenamify(slug);\n const frontmatter = await generateFrontmatter(title, config);\n const filePath = path.join(config.blogDir, `${fileName}.md`);\n\n await pfs.write(filePath, frontmatter);\n },\n });\n}\n\nasync function generateFrontmatter(\n title: string,\n config: Config,\n): Promise<string> {\n const description = await makeDescription(title);\n // const now = new Date();\n\n const data = {\n [config.titleKey]: title,\n [config.publishedAtKey]: \"3000-01-01T00:00:00Z\",\n [config.authorKey]: config.author,\n [config.draftKey]: true,\n [config.descriptionKey]: description,\n [config.tagsKey]: [],\n };\n\n return matter.stringify(\"\", data);\n}\n\nasync function makeDescription(title: string): Promise<string> {\n const description = await text({\n message: \"Enter a description for the post:\",\n defaultValue: title,\n });\n\n if (isCancel(description)) {\n return \"\";\n }\n\n return description;\n}\n\nasync function generateTitle(): Promise<string> {\n const title = await text({\n message: \"Enter a title for the post:\",\n validate: (value) => {\n if (!value) {\n return \"Title required\";\n }\n return undefined;\n },\n });\n\n if (isCancel(title)) {\n return \"\";\n }\n\n return title;\n}\n","import { command } from \"cmd-ts\";\nimport { isCancel, intro, outro, autocomplete } from \"@clack/prompts\";\nimport matter from \"gray-matter\";\nimport type { Config, Deps } from \"../lib/deps\";\nimport {\n readPosts,\n parseFrontmatter,\n postsToOptions,\n selectedValuesToPosts,\n Post,\n} from \"../lib/commands\";\n\nexport function makePublishCommand({ config, pfs }: Deps) {\n return command({\n name: \"publish\",\n description: \"Undraft a post\",\n args: {},\n handler: async () => {\n const posts = await readPosts(pfs, config);\n const drafts = posts.filter(\n (post) => parseFrontmatter(post)[config.draftKey] === true,\n );\n const selected = await getPostsToPublish(drafts, config);\n\n for (const draft of selected) {\n await updateDraftFrontMatter(draft, { config, pfs });\n }\n },\n });\n}\n\nasync function getPostsToPublish(\n drafts: Post[],\n config: Config,\n): Promise<Post[]> {\n const options = postsToOptions(drafts, config);\n intro(\"Publishing posts\");\n\n const selected = await autocomplete({\n message: \"Select post to publish\",\n options,\n });\n\n if (isCancel(selected)) {\n outro(\"Publishing cancelled.\");\n return [];\n }\n\n outro(\"Posts undrafted...\");\n\n return selectedValuesToPosts(\n Array.isArray(selected) ? selected : [selected],\n drafts,\n );\n}\n\nasync function updateDraftFrontMatter(draft: Post, deps: Deps) {\n const now = new Date();\n const parsed = matter(draft.content);\n const fm = parsed.data as Record<string, unknown>;\n fm[deps.config.draftKey] = false;\n fm[deps.config.publishedAtKey] = now;\n const updatedContent = matter.stringify(parsed.content, fm);\n await deps.pfs.write(`${deps.config.blogDir}/${draft.file}`, updatedContent);\n return { ...draft, content: updatedContent };\n}\n","import matter from \"gray-matter\";\nimport type { Config, Deps } from \"./deps\";\n\nexport type Post = {\n file: string;\n content: string;\n};\n\nexport type Frontmatter = Record<string, unknown>;\n\n/** Read all files from the blog directory and return them as Post objects */\nexport async function readPosts(pfs: Deps[\"pfs\"], config: Config): Promise<Post[]> {\n const files = (await pfs.readdir(config.blogDir)) as string[];\n const posts: Post[] = [];\n\n for (const file of files) {\n const content = await pfs.read(`${config.blogDir}/${file}`);\n posts.push({ file, content });\n }\n\n return posts;\n}\n\n/** Parse frontmatter from a Post */\nexport function parseFrontmatter(post: Post): Frontmatter {\n const { data } = matter(post.content);\n return data as Frontmatter;\n}\n\n/** Convert Posts to prompt option objects (value/label/hint) */\nexport function postsToOptions(posts: Post[], config: Config) {\n return posts.map((post) => {\n const fm = parseFrontmatter(post);\n const title = String(fm[config.titleKey] ?? post.file);\n\n return {\n value: post.file,\n label: title,\n hint: post.file,\n };\n });\n}\n\n/** Take the raw selected values returned by the prompt and return matching Post[] */\nexport function selectedValuesToPosts(selected: string[] | symbol, posts: Post[]): Post[] {\n if (typeof selected === \"symbol\") return [];\n return posts.filter((p) => selected.includes(p.file));\n}\n\nexport function findPostByFile(posts: Post[], fileName: string): Post | undefined {\n return posts.find((p) => p.file === fileName);\n}\n","import { command } from \"cmd-ts\";\nimport { autocomplete, isCancel, intro, outro } from \"@clack/prompts\";\nimport matter from \"gray-matter\";\nimport type { Config, Deps } from \"../lib/deps\";\nimport {\n readPosts,\n postsToOptions,\n findPostByFile,\n Post,\n} from \"../lib/commands\";\n\ntype Frontmatter = Record<string, unknown>;\n\nexport function makeUpdateCommand({ config, pfs }: Deps) {\n return command({\n name: \"update\",\n description: \"Update a post's modified date\",\n args: {},\n handler: async () => {\n const posts = await readPosts(pfs, config);\n const post = await getPostToUpdate(posts, config);\n if (!post) return;\n\n await updatePostDate(post, { config, pfs });\n },\n });\n}\n\nasync function getPostToUpdate(\n posts: Post[],\n config: Config,\n): Promise<Post | null> {\n const options = postsToOptions(posts, config);\n\n intro(\"Update a post\");\n\n const selected = await autocomplete({\n message: \"Select post to update\",\n options,\n });\n\n if (isCancel(selected)) {\n outro(\"Update cancelled.\");\n return null;\n }\n outro(\"Post updated.\");\n\n const found = findPostByFile(posts, selected as string);\n return found ?? null;\n}\n\nasync function updatePostDate(post: Post, deps: Deps) {\n const parsed = matter(post.content);\n const fm = parsed.data as Record<string, unknown>;\n fm[deps.config.modifiedAtKey] = new Date();\n const updatedContent = matter.stringify(parsed.content, fm);\n await deps.pfs.write(`${deps.config.blogDir}/${post.file}`, updatedContent);\n return { ...post, content: updatedContent };\n}\n","import { command } from \"cmd-ts\";\nimport { autocomplete, isCancel, intro, outro } from \"@clack/prompts\";\nimport matter from \"gray-matter\";\nimport type { Config, Deps } from \"../lib/deps\";\nimport {\n readPosts,\n postsToOptions,\n findPostByFile,\n Post,\n} from \"../lib/commands\";\n\ntype Frontmatter = Record<string, unknown>;\n\nexport function makeUnPublishCommand({ config, pfs }: Deps) {\n return command({\n name: \"unpublish\",\n description: \"Unpublish a post\",\n args: {},\n handler: async () => {\n const posts = await readPosts(pfs, config);\n const post = await getPostToUnpub(posts, config);\n if (!post) return;\n\n await unpubPost(post, { config, pfs });\n },\n });\n}\n\nasync function getPostToUnpub(\n posts: Post[],\n config: Config,\n): Promise<Post | null> {\n const options = postsToOptions(posts, config);\n\n intro(\"Unpublish a post\");\n\n const selected = await autocomplete({\n message: \"Select post to unpublish\",\n options,\n });\n\n if (isCancel(selected)) {\n outro(\"Unpublish cancelled.\");\n return null;\n }\n outro(\"Post unpublished.\");\n\n const found = findPostByFile(posts, selected as string);\n return found ?? null;\n}\n\nasync function unpubPost(post: Post, deps: Deps) {\n const parsed = matter(post.content);\n const fm = parsed.data as Record<string, unknown>;\n fm[deps.config.draftKey] = true;\n const updatedContent = matter.stringify(parsed.content, fm);\n await deps.pfs.write(`${deps.config.blogDir}/${post.file}`, updatedContent);\n return { ...post, content: updatedContent };\n}\n","import { command } from \"cmd-ts\";\nimport { text, isCancel, intro, outro } from \"@clack/prompts\";\nimport type { Deps } from \"../lib/deps\";\n\nexport function makeInitCommand({ config, pfs }: Deps) {\n return command({\n name: \"init\",\n description: \"Create or update mkd.json configuration\",\n args: {},\n handler: async () => {\n intro(\"Initialize mkd configuration\");\n\n const blogDir = await text({\n message: \"Directory where generated posts are written\",\n defaultValue: String(config.blogDir ?? \"./src/blog\"),\n });\n if (isCancel(blogDir)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const author = await text({\n message: \"Default author\",\n defaultValue: String(config.author ?? \"\"),\n });\n if (isCancel(author)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const titleKey = await text({\n message: \"Title frontmatter key\",\n defaultValue: String(config.titleKey ?? \"title\"),\n });\n if (isCancel(titleKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const publishedAtKey = await text({\n message: \"Published date frontmatter key\",\n defaultValue: String(config.publishedAtKey ?? \"publishedAt\"),\n });\n if (isCancel(publishedAtKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const modifiedAtKey = await text({\n message: \"Modified date frontmatter key\",\n defaultValue: String(config.modifiedAtKey ?? \"updatedAt\"),\n });\n if (isCancel(modifiedAtKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const authorKey = await text({\n message: \"Author frontmatter key\",\n defaultValue: String(config.authorKey ?? \"author\"),\n });\n if (isCancel(authorKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const draftKey = await text({\n message: \"Draft frontmatter key\",\n defaultValue: String(config.draftKey ?? \"draft\"),\n });\n if (isCancel(draftKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const descriptionKey = await text({\n message: \"Description frontmatter key\",\n defaultValue: String(config.descriptionKey ?? \"description\"),\n });\n if (isCancel(descriptionKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const tagsKey = await text({\n message: \"Tags frontmatter key\",\n defaultValue: String(config.tagsKey ?? \"tags\"),\n });\n if (isCancel(tagsKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const newConfig = {\n blogDir: String(blogDir),\n author: String(author),\n publishedAtKey: String(publishedAtKey),\n modifiedAtKey: String(modifiedAtKey),\n authorKey: String(authorKey),\n draftKey: String(draftKey),\n descriptionKey: String(descriptionKey),\n tagsKey: String(tagsKey),\n titleKey: String(titleKey),\n };\n\n await pfs.write(\"./mkd.json\", JSON.stringify(newConfig, null, 2) + \"\\n\");\n\n outro(\"Configuration saved to mkd.json\");\n },\n });\n}\n"],"mappings":";;;AACA,SAAS,KAAK,mBAAmB;AACjC,SAAS,yBAAyB;;;ACiBlC,IAAM,gBAAwB;AAAA,EAC5B,SAAS;AAAA,EACT,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,WAAW;AAAA,EACX,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB,SAAS;AACX;AAEA,eAAsB,WAAW,KAAyC;AACxE,MAAI;AACF,UAAM,MAAM,MAAM,IAAI,KAAK,YAAY;AAEvC,QAAI,CAAC,IAAI,KAAK,GAAG;AACf,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,KAAK,MAAM,GAAG;AAE7B,QAAI,CAAC,SAAS,MAAM,GAAG;AACrB,aAAO;AAAA,IACT;AAEA,UAAM,EAAE,SAAS,SAAS,GAAG,OAAO,IAAI;AAExC,WAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;;;AC1DA,SAAS,SAAS,iBAAiB,cAAc;AACjD,OAAO,UAAU;AACjB,OAAO,aAAa;AACpB,OAAO,gBAAgB;AACvB,OAAO,YAAY;AACnB,SAAS,UAAU,MAAM,aAAoB;AAGtC,SAAS,eAAe,EAAE,QAAQ,IAAI,GAAS;AACpD,SAAO,QAAQ;AAAA,IACb,MAAM;AAAA,IACN,aAAa;AAAA,IACb,MAAM;AAAA,MACJ,KAAK,gBAAgB;AAAA,QACnB,MAAM;AAAA,QACN,aAAa;AAAA,QACb,aAAa;AAAA,MACf,CAAC;AAAA,IACH;AAAA,IACA,SAAS,OAAO,EAAE,KAAK,WAAW,MAAM;AACtC,YAAM,mBAAmB;AACzB,UAAI;AACJ,UAAI,WAAW,WAAW,GAAG;AAC3B,gBAAQ,MAAM,cAAc;AAC5B,YAAI,UAAU,IAAI;AAChB;AAAA,QACF;AAAA,MACF,OAAO;AACL,gBAAQ,WAAW,KAAK,GAAG;AAAA,MAC7B;AACA,YAAM,OAAO,QAAQ,KAAK;AAC1B,YAAM,WAAW,WAAW,IAAI;AAChC,YAAM,cAAc,MAAM,oBAAoB,OAAO,MAAM;AAC3D,YAAM,WAAW,KAAK,KAAK,OAAO,SAAS,GAAG,QAAQ,KAAK;AAE3D,YAAM,IAAI,MAAM,UAAU,WAAW;AAAA,IACvC;AAAA,EACF,CAAC;AACH;AAEA,eAAe,oBACb,OACA,QACiB;AACjB,QAAM,cAAc,MAAM,gBAAgB,KAAK;AAG/C,QAAM,OAAO;AAAA,IACX,CAAC,OAAO,QAAQ,GAAG;AAAA,IACnB,CAAC,OAAO,cAAc,GAAG;AAAA,IACzB,CAAC,OAAO,SAAS,GAAG,OAAO;AAAA,IAC3B,CAAC,OAAO,QAAQ,GAAG;AAAA,IACnB,CAAC,OAAO,cAAc,GAAG;AAAA,IACzB,CAAC,OAAO,OAAO,GAAG,CAAC;AAAA,EACrB;AAEA,SAAO,OAAO,UAAU,IAAI,IAAI;AAClC;AAEA,eAAe,gBAAgB,OAAgC;AAC7D,QAAM,cAAc,MAAM,KAAK;AAAA,IAC7B,SAAS;AAAA,IACT,cAAc;AAAA,EAChB,CAAC;AAED,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,eAAe,gBAAiC;AAC9C,QAAM,QAAQ,MAAM,KAAK;AAAA,IACvB,SAAS;AAAA,IACT,UAAU,CAAC,UAAU;AACnB,UAAI,CAAC,OAAO;AACV,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,MAAI,SAAS,KAAK,GAAG;AACnB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;ACxFA,SAAS,WAAAA,gBAAe;AACxB,SAAS,YAAAC,WAAU,SAAAC,QAAO,SAAAC,QAAO,oBAAoB;AACrD,OAAOC,aAAY;;;ACFnB,OAAOC,aAAY;AAWnB,eAAsB,UAAU,KAAkB,QAAiC;AACjF,QAAM,QAAS,MAAM,IAAI,QAAQ,OAAO,OAAO;AAC/C,QAAM,QAAgB,CAAC;AAEvB,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,MAAM,IAAI,KAAK,GAAG,OAAO,OAAO,IAAI,IAAI,EAAE;AAC1D,UAAM,KAAK,EAAE,MAAM,QAAQ,CAAC;AAAA,EAC9B;AAEA,SAAO;AACT;AAGO,SAAS,iBAAiB,MAAyB;AACxD,QAAM,EAAE,KAAK,IAAIA,QAAO,KAAK,OAAO;AACpC,SAAO;AACT;AAGO,SAAS,eAAe,OAAe,QAAgB;AAC5D,SAAO,MAAM,IAAI,CAAC,SAAS;AACzB,UAAM,KAAK,iBAAiB,IAAI;AAChC,UAAM,QAAQ,OAAO,GAAG,OAAO,QAAQ,KAAK,KAAK,IAAI;AAErD,WAAO;AAAA,MACL,OAAO,KAAK;AAAA,MACZ,OAAO;AAAA,MACP,MAAM,KAAK;AAAA,IACb;AAAA,EACF,CAAC;AACH;AAGO,SAAS,sBAAsB,UAA6B,OAAuB;AACxF,MAAI,OAAO,aAAa,SAAU,QAAO,CAAC;AAC1C,SAAO,MAAM,OAAO,CAAC,MAAM,SAAS,SAAS,EAAE,IAAI,CAAC;AACtD;AAEO,SAAS,eAAe,OAAe,UAAoC;AAChF,SAAO,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ;AAC9C;;;ADvCO,SAAS,mBAAmB,EAAE,QAAQ,IAAI,GAAS;AACxD,SAAOC,SAAQ;AAAA,IACb,MAAM;AAAA,IACN,aAAa;AAAA,IACb,MAAM,CAAC;AAAA,IACP,SAAS,YAAY;AACnB,YAAM,QAAQ,MAAM,UAAU,KAAK,MAAM;AACzC,YAAM,SAAS,MAAM;AAAA,QACnB,CAAC,SAAS,iBAAiB,IAAI,EAAE,OAAO,QAAQ,MAAM;AAAA,MACxD;AACA,YAAM,WAAW,MAAM,kBAAkB,QAAQ,MAAM;AAEvD,iBAAW,SAAS,UAAU;AAC5B,cAAM,uBAAuB,OAAO,EAAE,QAAQ,IAAI,CAAC;AAAA,MACrD;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,eAAe,kBACb,QACA,QACiB;AACjB,QAAM,UAAU,eAAe,QAAQ,MAAM;AAC7C,EAAAC,OAAM,kBAAkB;AAExB,QAAM,WAAW,MAAM,aAAa;AAAA,IAClC,SAAS;AAAA,IACT;AAAA,EACF,CAAC;AAED,MAAIC,UAAS,QAAQ,GAAG;AACtB,IAAAC,OAAM,uBAAuB;AAC7B,WAAO,CAAC;AAAA,EACV;AAEA,EAAAA,OAAM,oBAAoB;AAE1B,SAAO;AAAA,IACL,MAAM,QAAQ,QAAQ,IAAI,WAAW,CAAC,QAAQ;AAAA,IAC9C;AAAA,EACF;AACF;AAEA,eAAe,uBAAuB,OAAa,MAAY;AAC7D,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,SAASC,QAAO,MAAM,OAAO;AACnC,QAAM,KAAK,OAAO;AAClB,KAAG,KAAK,OAAO,QAAQ,IAAI;AAC3B,KAAG,KAAK,OAAO,cAAc,IAAI;AACjC,QAAM,iBAAiBA,QAAO,UAAU,OAAO,SAAS,EAAE;AAC1D,QAAM,KAAK,IAAI,MAAM,GAAG,KAAK,OAAO,OAAO,IAAI,MAAM,IAAI,IAAI,cAAc;AAC3E,SAAO,EAAE,GAAG,OAAO,SAAS,eAAe;AAC7C;;;AEjEA,SAAS,WAAAC,gBAAe;AACxB,SAAS,gBAAAC,eAAc,YAAAC,WAAU,SAAAC,QAAO,SAAAC,cAAa;AACrD,OAAOC,aAAY;AAWZ,SAAS,kBAAkB,EAAE,QAAQ,IAAI,GAAS;AACvD,SAAOC,SAAQ;AAAA,IACb,MAAM;AAAA,IACN,aAAa;AAAA,IACb,MAAM,CAAC;AAAA,IACP,SAAS,YAAY;AACnB,YAAM,QAAQ,MAAM,UAAU,KAAK,MAAM;AACzC,YAAM,OAAO,MAAM,gBAAgB,OAAO,MAAM;AAChD,UAAI,CAAC,KAAM;AAEX,YAAM,eAAe,MAAM,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC5C;AAAA,EACF,CAAC;AACH;AAEA,eAAe,gBACb,OACA,QACsB;AACtB,QAAM,UAAU,eAAe,OAAO,MAAM;AAE5C,EAAAC,OAAM,eAAe;AAErB,QAAM,WAAW,MAAMC,cAAa;AAAA,IAClC,SAAS;AAAA,IACT;AAAA,EACF,CAAC;AAED,MAAIC,UAAS,QAAQ,GAAG;AACtB,IAAAC,OAAM,mBAAmB;AACzB,WAAO;AAAA,EACT;AACA,EAAAA,OAAM,eAAe;AAErB,QAAM,QAAQ,eAAe,OAAO,QAAkB;AACtD,SAAO,SAAS;AAClB;AAEA,eAAe,eAAe,MAAY,MAAY;AACpD,QAAM,SAASC,QAAO,KAAK,OAAO;AAClC,QAAM,KAAK,OAAO;AAClB,KAAG,KAAK,OAAO,aAAa,IAAI,oBAAI,KAAK;AACzC,QAAM,iBAAiBA,QAAO,UAAU,OAAO,SAAS,EAAE;AAC1D,QAAM,KAAK,IAAI,MAAM,GAAG,KAAK,OAAO,OAAO,IAAI,KAAK,IAAI,IAAI,cAAc;AAC1E,SAAO,EAAE,GAAG,MAAM,SAAS,eAAe;AAC5C;;;AC1DA,SAAS,WAAAC,gBAAe;AACxB,SAAS,gBAAAC,eAAc,YAAAC,WAAU,SAAAC,QAAO,SAAAC,cAAa;AACrD,OAAOC,aAAY;AAWZ,SAAS,qBAAqB,EAAE,QAAQ,IAAI,GAAS;AAC1D,SAAOC,SAAQ;AAAA,IACb,MAAM;AAAA,IACN,aAAa;AAAA,IACb,MAAM,CAAC;AAAA,IACP,SAAS,YAAY;AACnB,YAAM,QAAQ,MAAM,UAAU,KAAK,MAAM;AACzC,YAAM,OAAO,MAAM,eAAe,OAAO,MAAM;AAC/C,UAAI,CAAC,KAAM;AAEX,YAAM,UAAU,MAAM,EAAE,QAAQ,IAAI,CAAC;AAAA,IACvC;AAAA,EACF,CAAC;AACH;AAEA,eAAe,eACb,OACA,QACsB;AACtB,QAAM,UAAU,eAAe,OAAO,MAAM;AAE5C,EAAAC,OAAM,kBAAkB;AAExB,QAAM,WAAW,MAAMC,cAAa;AAAA,IAClC,SAAS;AAAA,IACT;AAAA,EACF,CAAC;AAED,MAAIC,UAAS,QAAQ,GAAG;AACtB,IAAAC,OAAM,sBAAsB;AAC5B,WAAO;AAAA,EACT;AACA,EAAAA,OAAM,mBAAmB;AAEzB,QAAM,QAAQ,eAAe,OAAO,QAAkB;AACtD,SAAO,SAAS;AAClB;AAEA,eAAe,UAAU,MAAY,MAAY;AAC/C,QAAM,SAASC,QAAO,KAAK,OAAO;AAClC,QAAM,KAAK,OAAO;AAClB,KAAG,KAAK,OAAO,QAAQ,IAAI;AAC3B,QAAM,iBAAiBA,QAAO,UAAU,OAAO,SAAS,EAAE;AAC1D,QAAM,KAAK,IAAI,MAAM,GAAG,KAAK,OAAO,OAAO,IAAI,KAAK,IAAI,IAAI,cAAc;AAC1E,SAAO,EAAE,GAAG,MAAM,SAAS,eAAe;AAC5C;;;AC1DA,SAAS,WAAAC,gBAAe;AACxB,SAAS,QAAAC,OAAM,YAAAC,WAAU,SAAAC,QAAO,SAAAC,cAAa;AAGtC,SAAS,gBAAgB,EAAE,QAAQ,IAAI,GAAS;AACrD,SAAOJ,SAAQ;AAAA,IACb,MAAM;AAAA,IACN,aAAa;AAAA,IACb,MAAM,CAAC;AAAA,IACP,SAAS,YAAY;AACnB,MAAAG,OAAM,8BAA8B;AAEpC,YAAM,UAAU,MAAMF,MAAK;AAAA,QACzB,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,WAAW,YAAY;AAAA,MACrD,CAAC;AACD,UAAIC,UAAS,OAAO,GAAG;AACrB,QAAAE,OAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,SAAS,MAAMH,MAAK;AAAA,QACxB,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,UAAU,EAAE;AAAA,MAC1C,CAAC;AACD,UAAIC,UAAS,MAAM,GAAG;AACpB,QAAAE,OAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,WAAW,MAAMH,MAAK;AAAA,QAC1B,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,YAAY,OAAO;AAAA,MACjD,CAAC;AACD,UAAIC,UAAS,QAAQ,GAAG;AACtB,QAAAE,OAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,iBAAiB,MAAMH,MAAK;AAAA,QAChC,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,kBAAkB,aAAa;AAAA,MAC7D,CAAC;AACD,UAAIC,UAAS,cAAc,GAAG;AAC5B,QAAAE,OAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,gBAAgB,MAAMH,MAAK;AAAA,QAC/B,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,iBAAiB,WAAW;AAAA,MAC1D,CAAC;AACD,UAAIC,UAAS,aAAa,GAAG;AAC3B,QAAAE,OAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,YAAY,MAAMH,MAAK;AAAA,QAC3B,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,aAAa,QAAQ;AAAA,MACnD,CAAC;AACD,UAAIC,UAAS,SAAS,GAAG;AACvB,QAAAE,OAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,WAAW,MAAMH,MAAK;AAAA,QAC1B,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,YAAY,OAAO;AAAA,MACjD,CAAC;AACD,UAAIC,UAAS,QAAQ,GAAG;AACtB,QAAAE,OAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,iBAAiB,MAAMH,MAAK;AAAA,QAChC,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,kBAAkB,aAAa;AAAA,MAC7D,CAAC;AACD,UAAIC,UAAS,cAAc,GAAG;AAC5B,QAAAE,OAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,UAAU,MAAMH,MAAK;AAAA,QACzB,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,WAAW,MAAM;AAAA,MAC/C,CAAC;AACD,UAAIC,UAAS,OAAO,GAAG;AACrB,QAAAE,OAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,YAAY;AAAA,QAChB,SAAS,OAAO,OAAO;AAAA,QACvB,QAAQ,OAAO,MAAM;AAAA,QACrB,gBAAgB,OAAO,cAAc;AAAA,QACrC,eAAe,OAAO,aAAa;AAAA,QACnC,WAAW,OAAO,SAAS;AAAA,QAC3B,UAAU,OAAO,QAAQ;AAAA,QACzB,gBAAgB,OAAO,cAAc;AAAA,QACrC,SAAS,OAAO,OAAO;AAAA,QACvB,UAAU,OAAO,QAAQ;AAAA,MAC3B;AAEA,YAAM,IAAI,MAAM,cAAc,KAAK,UAAU,WAAW,MAAM,CAAC,IAAI,IAAI;AAEvE,MAAAA,OAAM,iCAAiC;AAAA,IACzC;AAAA,EACF,CAAC;AACH;;;APpGA,eAAe,OAAO;AACpB,QAAM,MAAM,IAAI,kBAAkB;AAClC,QAAM,SAAS,MAAM,WAAW,GAAG;AACnC,QAAM,OAAO,EAAE,QAAQ,IAAI;AAE3B,QAAM,MAAM,YAAY;AAAA,IACtB,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,KAAK,eAAe,IAAI;AAAA,MACxB,SAAS,mBAAmB,IAAI;AAAA,MAChC,QAAQ,kBAAkB,IAAI;AAAA,MAC9B,WAAW,qBAAqB,IAAI;AAAA,MACpC,MAAM,gBAAgB,IAAI;AAAA,IAC5B;AAAA,EACF,CAAC;AAED,QAAM,IAAI,KAAK,QAAQ,KAAK,MAAM,CAAC,CAAC;AACtC;AAEA,KAAK,EAAE,MAAM,CAAC,UAAU;AACtB,UAAQ,MAAM,KAAK;AACnB,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["command","isCancel","intro","outro","matter","matter","command","intro","isCancel","outro","matter","command","autocomplete","isCancel","intro","outro","matter","command","intro","autocomplete","isCancel","outro","matter","command","autocomplete","isCancel","intro","outro","matter","command","intro","autocomplete","isCancel","outro","matter","command","text","isCancel","intro","outro"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/lib/deps.ts","../src/commands/new.ts","../src/commands/publish.ts","../src/lib/commands.ts","../src/commands/update.ts","../src/commands/unpublish.ts","../src/commands/init.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { run, subcommands } from \"cmd-ts\";\nimport { PoweredFileSystem } from \"pwd-fs\";\nimport { loadConfig } from \"./lib/deps\";\nimport { makeNewCommand } from \"./commands/new\";\nimport { makePublishCommand } from \"./commands/publish\";\nimport { makeUpdateCommand } from \"./commands/update\";\nimport { makeUnPublishCommand } from \"./commands/unpublish\";\nimport { makeInitCommand } from \"./commands/init\";\n\nasync function main() {\n const pfs = new PoweredFileSystem();\n const config = await loadConfig(pfs);\n const deps = { config, pfs };\n\n const app = subcommands({\n name: \"mkd\",\n cmds: {\n new: makeNewCommand(deps),\n publish: makePublishCommand(deps),\n update: makeUpdateCommand(deps),\n unpublish: makeUnPublishCommand(deps),\n init: makeInitCommand(deps),\n },\n });\n\n await run(app, process.argv.slice(2));\n}\n\nmain().catch((error) => {\n console.error(error);\n process.exit(1);\n});\n","import type { PoweredFileSystem } from \"pwd-fs\";\n\nexport type Config = {\n blogDir: string;\n titleKey: string;\n author: string;\n publishedAtKey: string;\n modifiedAtKey: string;\n authorKey: string;\n draftKey: string;\n descriptionKey: string;\n tagsKey: string;\n};\n\nexport type Deps = {\n config: Config;\n pfs: PoweredFileSystem;\n};\n\nconst defaultConfig: Config = {\n blogDir: \"./src/blog\",\n titleKey: \"title\",\n author: \"\",\n publishedAtKey: \"publishedAt\",\n modifiedAtKey: \"updatedAt\",\n authorKey: \"author\",\n draftKey: \"draft\",\n descriptionKey: \"description\",\n tagsKey: \"tags\",\n};\n\nexport async function loadConfig(pfs: PoweredFileSystem): Promise<Config> {\n try {\n const raw = await pfs.read(\"./mkd.json\");\n\n if (!raw.trim()) {\n return defaultConfig;\n }\n\n const parsed = JSON.parse(raw);\n\n if (!isRecord(parsed)) {\n return defaultConfig;\n }\n\n const { $schema: _schema, ...config } = parsed;\n\n return {\n ...defaultConfig,\n ...config,\n };\n } catch {\n return defaultConfig;\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { command, restPositionals, string } from \"cmd-ts\";\nimport path from \"node:path\";\nimport slugify from \"@sindresorhus/slugify\";\nimport filenamify from \"filenamify\";\nimport matter from \"gray-matter\";\nimport { isCancel, text, intro, outro } from \"@clack/prompts\";\nimport type { Config, Deps } from \"../lib/deps\";\n\nexport function makeNewCommand({ config, pfs }: Deps) {\n return command({\n name: \"new\",\n description: \"Create a new post\",\n args: {\n new: restPositionals({\n type: string,\n displayName: \"file\",\n description: \"name of the new post\",\n }),\n },\n handler: async ({ new: titleArray }) => {\n intro(\"Create a new post\");\n let title: string;\n if (titleArray.length === 0) {\n title = await generateTitle();\n if (title === \"\") {\n return;\n }\n } else {\n title = titleArray.join(\" \");\n }\n const slug = slugify(title);\n const fileName = filenamify(slug);\n const frontmatter = await generateFrontmatter(title, config);\n const filePath = path.join(config.blogDir, `${fileName}.md`);\n\n await pfs.write(filePath, frontmatter);\n },\n });\n}\n\nasync function generateFrontmatter(\n title: string,\n config: Config,\n): Promise<string> {\n const description = await makeDescription(title);\n // const now = new Date();\n\n const data = {\n [config.titleKey]: title,\n [config.publishedAtKey]: new Date(\"3000-01-01T00:00:00Z\"),\n [config.authorKey]: config.author,\n [config.draftKey]: true,\n [config.descriptionKey]: description,\n [config.tagsKey]: [],\n };\n\n return matter.stringify(\"\", data);\n}\n\nasync function makeDescription(title: string): Promise<string> {\n const description = await text({\n message: \"Enter a description for the post:\",\n defaultValue: title,\n });\n\n if (isCancel(description)) {\n return \"\";\n }\n\n return description;\n}\n\nasync function generateTitle(): Promise<string> {\n const title = await text({\n message: \"Enter a title for the post:\",\n validate: (value) => {\n if (!value) {\n return \"Title required\";\n }\n return undefined;\n },\n });\n\n if (isCancel(title)) {\n return \"\";\n }\n\n return title;\n}\n","import { command } from \"cmd-ts\";\nimport { isCancel, intro, outro, autocomplete } from \"@clack/prompts\";\nimport matter from \"gray-matter\";\nimport type { Config, Deps } from \"../lib/deps\";\nimport {\n readPosts,\n parseFrontmatter,\n postsToOptions,\n selectedValuesToPosts,\n Post,\n} from \"../lib/commands\";\n\nexport function makePublishCommand({ config, pfs }: Deps) {\n return command({\n name: \"publish\",\n description: \"Undraft a post\",\n args: {},\n handler: async () => {\n const posts = await readPosts(pfs, config);\n const drafts = posts.filter(\n (post) => parseFrontmatter(post)[config.draftKey] === true,\n );\n const selected = await getPostsToPublish(drafts, config);\n\n for (const draft of selected) {\n await updateDraftFrontMatter(draft, { config, pfs });\n }\n },\n });\n}\n\nasync function getPostsToPublish(\n drafts: Post[],\n config: Config,\n): Promise<Post[]> {\n const options = postsToOptions(drafts, config);\n intro(\"Publishing posts\");\n\n const selected = await autocomplete({\n message: \"Select post to publish\",\n options,\n });\n\n if (isCancel(selected)) {\n outro(\"Publishing cancelled.\");\n return [];\n }\n\n outro(\"Posts undrafted...\");\n\n return selectedValuesToPosts(\n Array.isArray(selected) ? selected : [selected],\n drafts,\n );\n}\n\nasync function updateDraftFrontMatter(draft: Post, deps: Deps) {\n const now = new Date();\n const parsed = matter(draft.content);\n const fm = parsed.data as Record<string, unknown>;\n fm[deps.config.draftKey] = false;\n fm[deps.config.publishedAtKey] = now;\n const updatedContent = matter.stringify(parsed.content, fm);\n await deps.pfs.write(`${deps.config.blogDir}/${draft.file}`, updatedContent);\n return { ...draft, content: updatedContent };\n}\n","import matter from \"gray-matter\";\nimport type { Config, Deps } from \"./deps\";\n\nexport type Post = {\n file: string;\n content: string;\n};\n\nexport type Frontmatter = Record<string, unknown>;\n\n/** Read all files from the blog directory and return them as Post objects */\nexport async function readPosts(pfs: Deps[\"pfs\"], config: Config): Promise<Post[]> {\n const files = (await pfs.readdir(config.blogDir)) as string[];\n const posts: Post[] = [];\n\n for (const file of files) {\n const content = await pfs.read(`${config.blogDir}/${file}`);\n posts.push({ file, content });\n }\n\n return posts;\n}\n\n/** Parse frontmatter from a Post */\nexport function parseFrontmatter(post: Post): Frontmatter {\n const { data } = matter(post.content);\n return data as Frontmatter;\n}\n\n/** Convert Posts to prompt option objects (value/label/hint) */\nexport function postsToOptions(posts: Post[], config: Config) {\n return posts.map((post) => {\n const fm = parseFrontmatter(post);\n const title = String(fm[config.titleKey] ?? post.file);\n\n return {\n value: post.file,\n label: title,\n hint: post.file,\n };\n });\n}\n\n/** Take the raw selected values returned by the prompt and return matching Post[] */\nexport function selectedValuesToPosts(selected: string[] | symbol, posts: Post[]): Post[] {\n if (typeof selected === \"symbol\") return [];\n return posts.filter((p) => selected.includes(p.file));\n}\n\nexport function findPostByFile(posts: Post[], fileName: string): Post | undefined {\n return posts.find((p) => p.file === fileName);\n}\n","import { command } from \"cmd-ts\";\nimport { autocomplete, isCancel, intro, outro } from \"@clack/prompts\";\nimport matter from \"gray-matter\";\nimport type { Config, Deps } from \"../lib/deps\";\nimport {\n readPosts,\n postsToOptions,\n findPostByFile,\n Post,\n} from \"../lib/commands\";\n\ntype Frontmatter = Record<string, unknown>;\n\nexport function makeUpdateCommand({ config, pfs }: Deps) {\n return command({\n name: \"update\",\n description: \"Update a post's modified date\",\n args: {},\n handler: async () => {\n const posts = await readPosts(pfs, config);\n const post = await getPostToUpdate(posts, config);\n if (!post) return;\n\n await updatePostDate(post, { config, pfs });\n },\n });\n}\n\nasync function getPostToUpdate(\n posts: Post[],\n config: Config,\n): Promise<Post | null> {\n const options = postsToOptions(posts, config);\n\n intro(\"Update a post\");\n\n const selected = await autocomplete({\n message: \"Select post to update\",\n options,\n });\n\n if (isCancel(selected)) {\n outro(\"Update cancelled.\");\n return null;\n }\n outro(\"Post updated.\");\n\n const found = findPostByFile(posts, selected as string);\n return found ?? null;\n}\n\nasync function updatePostDate(post: Post, deps: Deps) {\n const parsed = matter(post.content);\n const fm = parsed.data as Record<string, unknown>;\n fm[deps.config.modifiedAtKey] = new Date();\n const updatedContent = matter.stringify(parsed.content, fm);\n await deps.pfs.write(`${deps.config.blogDir}/${post.file}`, updatedContent);\n return { ...post, content: updatedContent };\n}\n","import { command } from \"cmd-ts\";\nimport { autocomplete, isCancel, intro, outro } from \"@clack/prompts\";\nimport matter from \"gray-matter\";\nimport type { Config, Deps } from \"../lib/deps\";\nimport {\n readPosts,\n postsToOptions,\n findPostByFile,\n Post,\n} from \"../lib/commands\";\n\ntype Frontmatter = Record<string, unknown>;\n\nexport function makeUnPublishCommand({ config, pfs }: Deps) {\n return command({\n name: \"unpublish\",\n description: \"Unpublish a post\",\n args: {},\n handler: async () => {\n const posts = await readPosts(pfs, config);\n const post = await getPostToUnpub(posts, config);\n if (!post) return;\n\n await unpubPost(post, { config, pfs });\n },\n });\n}\n\nasync function getPostToUnpub(\n posts: Post[],\n config: Config,\n): Promise<Post | null> {\n const options = postsToOptions(posts, config);\n\n intro(\"Unpublish a post\");\n\n const selected = await autocomplete({\n message: \"Select post to unpublish\",\n options,\n });\n\n if (isCancel(selected)) {\n outro(\"Unpublish cancelled.\");\n return null;\n }\n outro(\"Post unpublished.\");\n\n const found = findPostByFile(posts, selected as string);\n return found ?? null;\n}\n\nasync function unpubPost(post: Post, deps: Deps) {\n const parsed = matter(post.content);\n const fm = parsed.data as Record<string, unknown>;\n fm[deps.config.draftKey] = true;\n const updatedContent = matter.stringify(parsed.content, fm);\n await deps.pfs.write(`${deps.config.blogDir}/${post.file}`, updatedContent);\n return { ...post, content: updatedContent };\n}\n","import { command } from \"cmd-ts\";\nimport { text, isCancel, intro, outro } from \"@clack/prompts\";\nimport type { Deps } from \"../lib/deps\";\n\nexport function makeInitCommand({ config, pfs }: Deps) {\n return command({\n name: \"init\",\n description: \"Create or update mkd.json configuration\",\n args: {},\n handler: async () => {\n intro(\"Initialize mkd configuration\");\n\n const blogDir = await text({\n message: \"Directory where generated posts are written\",\n defaultValue: String(config.blogDir ?? \"./src/blog\"),\n });\n if (isCancel(blogDir)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const author = await text({\n message: \"Default author\",\n defaultValue: String(config.author ?? \"\"),\n });\n if (isCancel(author)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const titleKey = await text({\n message: \"Title frontmatter key\",\n defaultValue: String(config.titleKey ?? \"title\"),\n });\n if (isCancel(titleKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const publishedAtKey = await text({\n message: \"Published date frontmatter key\",\n defaultValue: String(config.publishedAtKey ?? \"publishedAt\"),\n });\n if (isCancel(publishedAtKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const modifiedAtKey = await text({\n message: \"Modified date frontmatter key\",\n defaultValue: String(config.modifiedAtKey ?? \"updatedAt\"),\n });\n if (isCancel(modifiedAtKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const authorKey = await text({\n message: \"Author frontmatter key\",\n defaultValue: String(config.authorKey ?? \"author\"),\n });\n if (isCancel(authorKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const draftKey = await text({\n message: \"Draft frontmatter key\",\n defaultValue: String(config.draftKey ?? \"draft\"),\n });\n if (isCancel(draftKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const descriptionKey = await text({\n message: \"Description frontmatter key\",\n defaultValue: String(config.descriptionKey ?? \"description\"),\n });\n if (isCancel(descriptionKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const tagsKey = await text({\n message: \"Tags frontmatter key\",\n defaultValue: String(config.tagsKey ?? \"tags\"),\n });\n if (isCancel(tagsKey)) {\n outro(\"Init cancelled\");\n return;\n }\n\n const newConfig = {\n blogDir: String(blogDir),\n author: String(author),\n publishedAtKey: String(publishedAtKey),\n modifiedAtKey: String(modifiedAtKey),\n authorKey: String(authorKey),\n draftKey: String(draftKey),\n descriptionKey: String(descriptionKey),\n tagsKey: String(tagsKey),\n titleKey: String(titleKey),\n };\n\n await pfs.write(\"./mkd.json\", JSON.stringify(newConfig, null, 2) + \"\\n\");\n\n outro(\"Configuration saved to mkd.json\");\n },\n });\n}\n"],"mappings":";;;AACA,SAAS,KAAK,mBAAmB;AACjC,SAAS,yBAAyB;;;ACiBlC,IAAM,gBAAwB;AAAA,EAC5B,SAAS;AAAA,EACT,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,WAAW;AAAA,EACX,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB,SAAS;AACX;AAEA,eAAsB,WAAW,KAAyC;AACxE,MAAI;AACF,UAAM,MAAM,MAAM,IAAI,KAAK,YAAY;AAEvC,QAAI,CAAC,IAAI,KAAK,GAAG;AACf,aAAO;AAAA,IACT;AAEA,UAAM,SAAS,KAAK,MAAM,GAAG;AAE7B,QAAI,CAAC,SAAS,MAAM,GAAG;AACrB,aAAO;AAAA,IACT;AAEA,UAAM,EAAE,SAAS,SAAS,GAAG,OAAO,IAAI;AAExC,WAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;;;AC1DA,SAAS,SAAS,iBAAiB,cAAc;AACjD,OAAO,UAAU;AACjB,OAAO,aAAa;AACpB,OAAO,gBAAgB;AACvB,OAAO,YAAY;AACnB,SAAS,UAAU,MAAM,aAAoB;AAGtC,SAAS,eAAe,EAAE,QAAQ,IAAI,GAAS;AACpD,SAAO,QAAQ;AAAA,IACb,MAAM;AAAA,IACN,aAAa;AAAA,IACb,MAAM;AAAA,MACJ,KAAK,gBAAgB;AAAA,QACnB,MAAM;AAAA,QACN,aAAa;AAAA,QACb,aAAa;AAAA,MACf,CAAC;AAAA,IACH;AAAA,IACA,SAAS,OAAO,EAAE,KAAK,WAAW,MAAM;AACtC,YAAM,mBAAmB;AACzB,UAAI;AACJ,UAAI,WAAW,WAAW,GAAG;AAC3B,gBAAQ,MAAM,cAAc;AAC5B,YAAI,UAAU,IAAI;AAChB;AAAA,QACF;AAAA,MACF,OAAO;AACL,gBAAQ,WAAW,KAAK,GAAG;AAAA,MAC7B;AACA,YAAM,OAAO,QAAQ,KAAK;AAC1B,YAAM,WAAW,WAAW,IAAI;AAChC,YAAM,cAAc,MAAM,oBAAoB,OAAO,MAAM;AAC3D,YAAM,WAAW,KAAK,KAAK,OAAO,SAAS,GAAG,QAAQ,KAAK;AAE3D,YAAM,IAAI,MAAM,UAAU,WAAW;AAAA,IACvC;AAAA,EACF,CAAC;AACH;AAEA,eAAe,oBACb,OACA,QACiB;AACjB,QAAM,cAAc,MAAM,gBAAgB,KAAK;AAG/C,QAAM,OAAO;AAAA,IACX,CAAC,OAAO,QAAQ,GAAG;AAAA,IACnB,CAAC,OAAO,cAAc,GAAG,oBAAI,KAAK,sBAAsB;AAAA,IACxD,CAAC,OAAO,SAAS,GAAG,OAAO;AAAA,IAC3B,CAAC,OAAO,QAAQ,GAAG;AAAA,IACnB,CAAC,OAAO,cAAc,GAAG;AAAA,IACzB,CAAC,OAAO,OAAO,GAAG,CAAC;AAAA,EACrB;AAEA,SAAO,OAAO,UAAU,IAAI,IAAI;AAClC;AAEA,eAAe,gBAAgB,OAAgC;AAC7D,QAAM,cAAc,MAAM,KAAK;AAAA,IAC7B,SAAS;AAAA,IACT,cAAc;AAAA,EAChB,CAAC;AAED,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEA,eAAe,gBAAiC;AAC9C,QAAM,QAAQ,MAAM,KAAK;AAAA,IACvB,SAAS;AAAA,IACT,UAAU,CAAC,UAAU;AACnB,UAAI,CAAC,OAAO;AACV,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,MAAI,SAAS,KAAK,GAAG;AACnB,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;ACxFA,SAAS,WAAAA,gBAAe;AACxB,SAAS,YAAAC,WAAU,SAAAC,QAAO,SAAAC,QAAO,oBAAoB;AACrD,OAAOC,aAAY;;;ACFnB,OAAOC,aAAY;AAWnB,eAAsB,UAAU,KAAkB,QAAiC;AACjF,QAAM,QAAS,MAAM,IAAI,QAAQ,OAAO,OAAO;AAC/C,QAAM,QAAgB,CAAC;AAEvB,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,MAAM,IAAI,KAAK,GAAG,OAAO,OAAO,IAAI,IAAI,EAAE;AAC1D,UAAM,KAAK,EAAE,MAAM,QAAQ,CAAC;AAAA,EAC9B;AAEA,SAAO;AACT;AAGO,SAAS,iBAAiB,MAAyB;AACxD,QAAM,EAAE,KAAK,IAAIA,QAAO,KAAK,OAAO;AACpC,SAAO;AACT;AAGO,SAAS,eAAe,OAAe,QAAgB;AAC5D,SAAO,MAAM,IAAI,CAAC,SAAS;AACzB,UAAM,KAAK,iBAAiB,IAAI;AAChC,UAAM,QAAQ,OAAO,GAAG,OAAO,QAAQ,KAAK,KAAK,IAAI;AAErD,WAAO;AAAA,MACL,OAAO,KAAK;AAAA,MACZ,OAAO;AAAA,MACP,MAAM,KAAK;AAAA,IACb;AAAA,EACF,CAAC;AACH;AAGO,SAAS,sBAAsB,UAA6B,OAAuB;AACxF,MAAI,OAAO,aAAa,SAAU,QAAO,CAAC;AAC1C,SAAO,MAAM,OAAO,CAAC,MAAM,SAAS,SAAS,EAAE,IAAI,CAAC;AACtD;AAEO,SAAS,eAAe,OAAe,UAAoC;AAChF,SAAO,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,QAAQ;AAC9C;;;ADvCO,SAAS,mBAAmB,EAAE,QAAQ,IAAI,GAAS;AACxD,SAAOC,SAAQ;AAAA,IACb,MAAM;AAAA,IACN,aAAa;AAAA,IACb,MAAM,CAAC;AAAA,IACP,SAAS,YAAY;AACnB,YAAM,QAAQ,MAAM,UAAU,KAAK,MAAM;AACzC,YAAM,SAAS,MAAM;AAAA,QACnB,CAAC,SAAS,iBAAiB,IAAI,EAAE,OAAO,QAAQ,MAAM;AAAA,MACxD;AACA,YAAM,WAAW,MAAM,kBAAkB,QAAQ,MAAM;AAEvD,iBAAW,SAAS,UAAU;AAC5B,cAAM,uBAAuB,OAAO,EAAE,QAAQ,IAAI,CAAC;AAAA,MACrD;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,eAAe,kBACb,QACA,QACiB;AACjB,QAAM,UAAU,eAAe,QAAQ,MAAM;AAC7C,EAAAC,OAAM,kBAAkB;AAExB,QAAM,WAAW,MAAM,aAAa;AAAA,IAClC,SAAS;AAAA,IACT;AAAA,EACF,CAAC;AAED,MAAIC,UAAS,QAAQ,GAAG;AACtB,IAAAC,OAAM,uBAAuB;AAC7B,WAAO,CAAC;AAAA,EACV;AAEA,EAAAA,OAAM,oBAAoB;AAE1B,SAAO;AAAA,IACL,MAAM,QAAQ,QAAQ,IAAI,WAAW,CAAC,QAAQ;AAAA,IAC9C;AAAA,EACF;AACF;AAEA,eAAe,uBAAuB,OAAa,MAAY;AAC7D,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,SAASC,QAAO,MAAM,OAAO;AACnC,QAAM,KAAK,OAAO;AAClB,KAAG,KAAK,OAAO,QAAQ,IAAI;AAC3B,KAAG,KAAK,OAAO,cAAc,IAAI;AACjC,QAAM,iBAAiBA,QAAO,UAAU,OAAO,SAAS,EAAE;AAC1D,QAAM,KAAK,IAAI,MAAM,GAAG,KAAK,OAAO,OAAO,IAAI,MAAM,IAAI,IAAI,cAAc;AAC3E,SAAO,EAAE,GAAG,OAAO,SAAS,eAAe;AAC7C;;;AEjEA,SAAS,WAAAC,gBAAe;AACxB,SAAS,gBAAAC,eAAc,YAAAC,WAAU,SAAAC,QAAO,SAAAC,cAAa;AACrD,OAAOC,aAAY;AAWZ,SAAS,kBAAkB,EAAE,QAAQ,IAAI,GAAS;AACvD,SAAOC,SAAQ;AAAA,IACb,MAAM;AAAA,IACN,aAAa;AAAA,IACb,MAAM,CAAC;AAAA,IACP,SAAS,YAAY;AACnB,YAAM,QAAQ,MAAM,UAAU,KAAK,MAAM;AACzC,YAAM,OAAO,MAAM,gBAAgB,OAAO,MAAM;AAChD,UAAI,CAAC,KAAM;AAEX,YAAM,eAAe,MAAM,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC5C;AAAA,EACF,CAAC;AACH;AAEA,eAAe,gBACb,OACA,QACsB;AACtB,QAAM,UAAU,eAAe,OAAO,MAAM;AAE5C,EAAAC,OAAM,eAAe;AAErB,QAAM,WAAW,MAAMC,cAAa;AAAA,IAClC,SAAS;AAAA,IACT;AAAA,EACF,CAAC;AAED,MAAIC,UAAS,QAAQ,GAAG;AACtB,IAAAC,OAAM,mBAAmB;AACzB,WAAO;AAAA,EACT;AACA,EAAAA,OAAM,eAAe;AAErB,QAAM,QAAQ,eAAe,OAAO,QAAkB;AACtD,SAAO,SAAS;AAClB;AAEA,eAAe,eAAe,MAAY,MAAY;AACpD,QAAM,SAASC,QAAO,KAAK,OAAO;AAClC,QAAM,KAAK,OAAO;AAClB,KAAG,KAAK,OAAO,aAAa,IAAI,oBAAI,KAAK;AACzC,QAAM,iBAAiBA,QAAO,UAAU,OAAO,SAAS,EAAE;AAC1D,QAAM,KAAK,IAAI,MAAM,GAAG,KAAK,OAAO,OAAO,IAAI,KAAK,IAAI,IAAI,cAAc;AAC1E,SAAO,EAAE,GAAG,MAAM,SAAS,eAAe;AAC5C;;;AC1DA,SAAS,WAAAC,gBAAe;AACxB,SAAS,gBAAAC,eAAc,YAAAC,WAAU,SAAAC,QAAO,SAAAC,cAAa;AACrD,OAAOC,aAAY;AAWZ,SAAS,qBAAqB,EAAE,QAAQ,IAAI,GAAS;AAC1D,SAAOC,SAAQ;AAAA,IACb,MAAM;AAAA,IACN,aAAa;AAAA,IACb,MAAM,CAAC;AAAA,IACP,SAAS,YAAY;AACnB,YAAM,QAAQ,MAAM,UAAU,KAAK,MAAM;AACzC,YAAM,OAAO,MAAM,eAAe,OAAO,MAAM;AAC/C,UAAI,CAAC,KAAM;AAEX,YAAM,UAAU,MAAM,EAAE,QAAQ,IAAI,CAAC;AAAA,IACvC;AAAA,EACF,CAAC;AACH;AAEA,eAAe,eACb,OACA,QACsB;AACtB,QAAM,UAAU,eAAe,OAAO,MAAM;AAE5C,EAAAC,OAAM,kBAAkB;AAExB,QAAM,WAAW,MAAMC,cAAa;AAAA,IAClC,SAAS;AAAA,IACT;AAAA,EACF,CAAC;AAED,MAAIC,UAAS,QAAQ,GAAG;AACtB,IAAAC,OAAM,sBAAsB;AAC5B,WAAO;AAAA,EACT;AACA,EAAAA,OAAM,mBAAmB;AAEzB,QAAM,QAAQ,eAAe,OAAO,QAAkB;AACtD,SAAO,SAAS;AAClB;AAEA,eAAe,UAAU,MAAY,MAAY;AAC/C,QAAM,SAASC,QAAO,KAAK,OAAO;AAClC,QAAM,KAAK,OAAO;AAClB,KAAG,KAAK,OAAO,QAAQ,IAAI;AAC3B,QAAM,iBAAiBA,QAAO,UAAU,OAAO,SAAS,EAAE;AAC1D,QAAM,KAAK,IAAI,MAAM,GAAG,KAAK,OAAO,OAAO,IAAI,KAAK,IAAI,IAAI,cAAc;AAC1E,SAAO,EAAE,GAAG,MAAM,SAAS,eAAe;AAC5C;;;AC1DA,SAAS,WAAAC,gBAAe;AACxB,SAAS,QAAAC,OAAM,YAAAC,WAAU,SAAAC,QAAO,SAAAC,cAAa;AAGtC,SAAS,gBAAgB,EAAE,QAAQ,IAAI,GAAS;AACrD,SAAOJ,SAAQ;AAAA,IACb,MAAM;AAAA,IACN,aAAa;AAAA,IACb,MAAM,CAAC;AAAA,IACP,SAAS,YAAY;AACnB,MAAAG,OAAM,8BAA8B;AAEpC,YAAM,UAAU,MAAMF,MAAK;AAAA,QACzB,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,WAAW,YAAY;AAAA,MACrD,CAAC;AACD,UAAIC,UAAS,OAAO,GAAG;AACrB,QAAAE,OAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,SAAS,MAAMH,MAAK;AAAA,QACxB,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,UAAU,EAAE;AAAA,MAC1C,CAAC;AACD,UAAIC,UAAS,MAAM,GAAG;AACpB,QAAAE,OAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,WAAW,MAAMH,MAAK;AAAA,QAC1B,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,YAAY,OAAO;AAAA,MACjD,CAAC;AACD,UAAIC,UAAS,QAAQ,GAAG;AACtB,QAAAE,OAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,iBAAiB,MAAMH,MAAK;AAAA,QAChC,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,kBAAkB,aAAa;AAAA,MAC7D,CAAC;AACD,UAAIC,UAAS,cAAc,GAAG;AAC5B,QAAAE,OAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,gBAAgB,MAAMH,MAAK;AAAA,QAC/B,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,iBAAiB,WAAW;AAAA,MAC1D,CAAC;AACD,UAAIC,UAAS,aAAa,GAAG;AAC3B,QAAAE,OAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,YAAY,MAAMH,MAAK;AAAA,QAC3B,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,aAAa,QAAQ;AAAA,MACnD,CAAC;AACD,UAAIC,UAAS,SAAS,GAAG;AACvB,QAAAE,OAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,WAAW,MAAMH,MAAK;AAAA,QAC1B,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,YAAY,OAAO;AAAA,MACjD,CAAC;AACD,UAAIC,UAAS,QAAQ,GAAG;AACtB,QAAAE,OAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,iBAAiB,MAAMH,MAAK;AAAA,QAChC,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,kBAAkB,aAAa;AAAA,MAC7D,CAAC;AACD,UAAIC,UAAS,cAAc,GAAG;AAC5B,QAAAE,OAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,UAAU,MAAMH,MAAK;AAAA,QACzB,SAAS;AAAA,QACT,cAAc,OAAO,OAAO,WAAW,MAAM;AAAA,MAC/C,CAAC;AACD,UAAIC,UAAS,OAAO,GAAG;AACrB,QAAAE,OAAM,gBAAgB;AACtB;AAAA,MACF;AAEA,YAAM,YAAY;AAAA,QAChB,SAAS,OAAO,OAAO;AAAA,QACvB,QAAQ,OAAO,MAAM;AAAA,QACrB,gBAAgB,OAAO,cAAc;AAAA,QACrC,eAAe,OAAO,aAAa;AAAA,QACnC,WAAW,OAAO,SAAS;AAAA,QAC3B,UAAU,OAAO,QAAQ;AAAA,QACzB,gBAAgB,OAAO,cAAc;AAAA,QACrC,SAAS,OAAO,OAAO;AAAA,QACvB,UAAU,OAAO,QAAQ;AAAA,MAC3B;AAEA,YAAM,IAAI,MAAM,cAAc,KAAK,UAAU,WAAW,MAAM,CAAC,IAAI,IAAI;AAEvE,MAAAA,OAAM,iCAAiC;AAAA,IACzC;AAAA,EACF,CAAC;AACH;;;APpGA,eAAe,OAAO;AACpB,QAAM,MAAM,IAAI,kBAAkB;AAClC,QAAM,SAAS,MAAM,WAAW,GAAG;AACnC,QAAM,OAAO,EAAE,QAAQ,IAAI;AAE3B,QAAM,MAAM,YAAY;AAAA,IACtB,MAAM;AAAA,IACN,MAAM;AAAA,MACJ,KAAK,eAAe,IAAI;AAAA,MACxB,SAAS,mBAAmB,IAAI;AAAA,MAChC,QAAQ,kBAAkB,IAAI;AAAA,MAC9B,WAAW,qBAAqB,IAAI;AAAA,MACpC,MAAM,gBAAgB,IAAI;AAAA,IAC5B;AAAA,EACF,CAAC;AAED,QAAM,IAAI,KAAK,QAAQ,KAAK,MAAM,CAAC,CAAC;AACtC;AAEA,KAAK,EAAE,MAAM,CAAC,UAAU;AACtB,UAAQ,MAAM,KAAK;AACnB,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["command","isCancel","intro","outro","matter","matter","command","intro","isCancel","outro","matter","command","autocomplete","isCancel","intro","outro","matter","command","intro","autocomplete","isCancel","outro","matter","command","autocomplete","isCancel","intro","outro","matter","command","intro","autocomplete","isCancel","outro","matter","command","text","isCancel","intro","outro"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plttn/mkd",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "A tool for managing markdown blog posts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -42,8 +42,13 @@
|
|
|
42
42
|
"type": "git",
|
|
43
43
|
"url": "https://github.com/plttn/mkd.git"
|
|
44
44
|
},
|
|
45
|
+
"publishConfig": {
|
|
46
|
+
"access": "public",
|
|
47
|
+
"provenance": true
|
|
48
|
+
},
|
|
45
49
|
"scripts": {
|
|
46
50
|
"dev": "tsx ./src/index.ts",
|
|
47
|
-
"build": "tsup"
|
|
51
|
+
"build": "tsup",
|
|
52
|
+
"ci:publish": "pnpm build && changeset publish"
|
|
48
53
|
}
|
|
49
54
|
}
|