diff --git a/content/blog/setup-a-react-native-monorepo/index.md b/content/blog/setup-a-react-native-monorepo/index.md index 8c62799d..4db8f9f6 100644 --- a/content/blog/setup-a-react-native-monorepo/index.md +++ b/content/blog/setup-a-react-native-monorepo/index.md @@ -37,7 +37,7 @@ By the end of it all, I had a monorepo structure that looked something like the - `apps/` - - `customer-portal/` + - `customer-portal/{open: false}` - `android/` - `ios/` - `src` @@ -54,7 +54,7 @@ By the end of it all, I had a monorepo structure that looked something like the - `node_modules` - `package.json` - `tsconfig.json` - - `admin-portal/` + - `admin-portal/{open: false}` - `android/` - `ios/` - `src` @@ -72,13 +72,13 @@ By the end of it all, I had a monorepo structure that looked something like the - `package.json` - `tsconfig.json` - `packages/` - - `config/` + - `config/{open: false}` - `.eslintrc.js` - `babel-config.js` - `eslint-preset.js` - `package.json` - `tsconfig.json` - - `shared-elements/` + - `shared-elements/{open: false}` - `src/` - `components/` - `hooks/` diff --git a/package-lock.json b/package-lock.json index 7a72a6a9..98d7649b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.3.0-alpha.1", "license": "MPL-2.0", "dependencies": { + "json5": "^2.2.3", "medium-zoom": "^1.0.8", "preact": "^10.12.1", "probe-image-size": "^7.2.3", @@ -28,6 +29,7 @@ "@testing-library/preact": "^3.2.3", "@types/classnames": "^2.3.1", "@types/jest": "^29.4.0", + "@types/json5": "^2.2.0", "@types/live-server": "^1.2.1", "@types/node": "^18.13.0", "@types/parse5": "^7.0.0", @@ -7872,11 +7874,14 @@ "dev": true }, "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-NrVug5woqbvNZ0WX+Gv4R+L4TGddtmFek2u8RtccAgFZWtS9QXF2xCXY22/M4nzkaKF0q9Fc6M/5rxLDhfwc/A==", + "deprecated": "This is a stub types definition. json5 provides its own type definitions, so you do not need this installed.", "dev": true, - "peer": true + "dependencies": { + "json5": "*" + } }, "node_modules/@types/keyv": { "version": "3.1.4", @@ -14829,6 +14834,13 @@ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" } }, + "node_modules/eslint-plugin-import/node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "peer": true + }, "node_modules/eslint-plugin-import/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -24941,9 +24953,9 @@ "dev": true }, "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "bin": { "json5": "lib/cli.js" }, @@ -44921,11 +44933,13 @@ "dev": true }, "@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-NrVug5woqbvNZ0WX+Gv4R+L4TGddtmFek2u8RtccAgFZWtS9QXF2xCXY22/M4nzkaKF0q9Fc6M/5rxLDhfwc/A==", "dev": true, - "peer": true + "requires": { + "json5": "*" + } }, "@types/keyv": { "version": "3.1.4", @@ -50554,6 +50568,13 @@ "tsconfig-paths": "^3.14.1" }, "dependencies": { + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "peer": true + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -57950,9 +57971,9 @@ "dev": true }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==" + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" }, "jsonc-parser": { "version": "2.3.1", diff --git a/package.json b/package.json index 1a79ec0e..77cf8f04 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "@testing-library/preact": "^3.2.3", "@types/classnames": "^2.3.1", "@types/jest": "^29.4.0", + "@types/json5": "^2.2.0", "@types/live-server": "^1.2.1", "@types/node": "^18.13.0", "@types/parse5": "^7.0.0", @@ -116,6 +117,7 @@ "*.{js,ts,astro,jsx}": "prettier --write" }, "dependencies": { + "json5": "^2.2.3", "medium-zoom": "^1.0.8", "preact": "^10.12.1", "probe-image-size": "^7.2.3", diff --git a/src/utils/markdown/file-tree/rehype-file-tree.ts b/src/utils/markdown/file-tree/rehype-file-tree.ts index a9b9fd12..87cfdf19 100644 --- a/src/utils/markdown/file-tree/rehype-file-tree.ts +++ b/src/utils/markdown/file-tree/rehype-file-tree.ts @@ -13,6 +13,7 @@ import { getIcon } from "./file-tree-icons"; import replaceAllBetween from "unist-util-replace-all-between"; import { Node } from "unist"; import { Root } from "hast"; +import JSON5 from "json5"; /** Make a text node with the pass string as its contents. */ const Text = (value = ""): { type: "text"; value: string } => ({ @@ -82,7 +83,22 @@ export const rehypeFileTree = () => { ); comment.push(...commentNodes); - const firstChildTextContent = toString(firstChild); + let firstChildTextContent = toString(firstChild); + + /** + * If a file or folder has an object at the end, assume it's a metadata object + * that we want to associate with the file or folder. + * + * @eg: `folder/ {open: false}` + */ + let metadata: { open?: boolean } = {}; + if (firstChildTextContent.endsWith("}")) { + const match = firstChildTextContent.match(/(.*)\s*({.*})\s*$/); + if (match) { + firstChildTextContent = match[1]; + metadata = JSON5.parse(match[2]); + } + } // Decide a node is a directory if it ends in a `/` or contains another list. const isDirectory = @@ -127,7 +143,7 @@ export const rehypeFileTree = () => { if (isDirectory) { node.children = [ - h("details", { open: hasContents }, [ + h("details", { open: metadata.open ?? hasContents }, [ h("summary", treeEntry), ...(hasContents ? otherChildren : [h("ul", h("li", "…"))]), ]),