Skip to content

Commit

Permalink
sorted debugging
Browse files Browse the repository at this point in the history
  • Loading branch information
FranciscoMoretti committed Jul 7, 2024
1 parent 425c053 commit 4dd2628
Show file tree
Hide file tree
Showing 4 changed files with 277 additions and 5 deletions.
14 changes: 11 additions & 3 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,21 @@
"version": "0.2.0",
"configurations": [
{
"name": "Debug cli",
"name": "Debug CLI",
"type": "node",
"request": "launch",
"skipFiles": ["<node_internals>/**"],
"program": "${workspaceFolder}/packages/cli/src/index.ts",
"outFiles": ["${workspaceFolder}/packages/cli/dist/**/*.js"],
"runtimeArgs": ["--experimental-specifier-resolution=node"]
"args": [
"pull",
"-n",
"secret_US5rR3rRRcWC2V23QAHu1QveMvcOQCDVzEUH4jOXu9J",
"-r",
"1a3e1cedb64341ab95defc6ae0294de5",
"--log-level",
"debug"
],
"outFiles": ["${workspaceFolder}/packages/cli/dist/**/*.js"]
}
]
}
262 changes: 262 additions & 0 deletions packages/cli/src/commands/pull.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
import { existsSync, promises as fs } from "fs"
import path from "path"
import { getConfig } from "@/src/utils/get-config"
import { getPackageManager } from "@/src/utils/get-package-manager"
import { handleError } from "@/src/utils/handle-error"
import { logger } from "@/src/utils/logger"
import {
fetchTree,
getItemTargetPath,
getRegistryBaseColor,
getRegistryIndex,
resolveTree,
} from "@/src/utils/registry"
import { transform } from "@/src/utils/transformers"
import chalk from "chalk"
import { Command, Option } from "commander"
import { execa } from "execa"
import ora from "ora"
import prompts from "prompts"
import { z } from "zod"

const pullOptionsSchema = z.object({
notionToken: z.string(),
rootPage: z.string(),
markdownOutputPath: z.string(),
statusTag: z.string(),
logLevel: z.string().default("info"),
imgPrefixInMarkdown: z.optional(z.boolean()),
imgOutputPath: z.optional(z.string()),
overwrite: z.boolean(),
cwd: z.string(),
})

export const pull = new Command()
.name("pull")
.description("pull pages from notion")
.requiredOption(
"-n, --notion-token <string>",
"notion api token, which looks like secret_3bc1b50XFYb15123RHF243x43450XFY33250XFYa343"
)
.requiredOption(
"-r, --root-page <string>",
"The 31 character ID of the page which is the root of your docs page in notion. The code will look like 9120ec9960244ead80fa2ef4bc1bba25. This page must have a child page named 'Outline'"
)
.option(
"-m, --markdown-output-path <string>",
"Root of the hierarchy for md files. WARNING: docu-notion will delete files from this directory. Note also that if it finds localized images, it will create an i18n/ directory as a sibling.",
"./docs"
)
.option(
"-t, --status-tag <string>",
"Database pages without a Notion page property 'status' matching this will be ignored. Use '*' to ignore status altogether.",
"Publish"
)
.addOption(
new Option("-l, --log-level <level>", "Log level").choices([
"info",
"verbose",
"debug",
])
)
.option(
"-p, --img-prefix-in-markdown <string>",
"When referencing an image from markdown, prefix with this path instead of the full img-output-path. Should be used only in conjunction with --img-output-path."
)
.option(
"-i, --img-output-path <string>",
"Path to directory where images will be stored. If this is not included, images will be placed in the same directory as the document that uses them, which then allows for localization of screenshots."
)
.option(
"--require-slugs",
"If set, docu-notion will fail if any pages it would otherwise publish are missing a slug in Notion.",
false
)
.addOption(
new Option(
"--image-file-name-format <format>",
"format:\n- default: {page slug (if any)}.{image block ID}\n- content-hash: Use a hash of the image content.\n- legacy: Use the legacy (before v0.16) method of determining file names. Set this to maintain backward compatibility.\nAll formats will use the original file extension."
)
.choices(["default", "content-hash", "legacy"])
.default("default")
)
.option("-o, --overwrite", "overwrite existing files.", false)
.option(
"-c, --cwd <cwd>",
"the working directory. defaults to the current directory.",
process.cwd()
)
.action(async (opts) => {
try {
const options = pullOptionsSchema.parse({
...opts,
})

const cwd = path.resolve(options.cwd)

if (!existsSync(cwd)) {
logger.error(`The path ${cwd} does not exist. Please try again.`)
process.exit(1)
}

const config = await getConfig(cwd)
if (!config) {
logger.warn(
`Configuration is missing. Please run ${chalk.green(
`init`
)} to create a components.json file.`
)
process.exit(1)
}

const registryIndex = await getRegistryIndex()

let selectedComponents = options.all
? registryIndex.map((entry) => entry.name)
: options.notion - token
if (!options.notion - token?.length && !options.all) {
const { components } = await prompts({
type: "multiselect",
name: "components",
message: "Which components would you like to add?",
hint: "Space to select. A to toggle all. Enter to submit.",
instructions: false,
choices: registryIndex.map((entry) => ({
title: entry.name,
value: entry.name,
selected: options.all
? true
: options.notion - token?.includes(entry.name),
})),
})
selectedComponents = components
}

if (!selectedComponents?.length) {
logger.warn("No components selected. Exiting.")
process.exit(0)
}

const tree = await resolveTree(registryIndex, selectedComponents)
const payload = await fetchTree(config.style, tree)
const baseColor = await getRegistryBaseColor(config.tailwind.baseColor)

if (!payload.length) {
logger.warn("Selected components not found. Exiting.")
process.exit(0)
}

if (!options.yes) {
const { proceed } = await prompts({
type: "confirm",
name: "proceed",
message: `Ready to install components and dependencies. Proceed?`,
initial: true,
})

if (!proceed) {
process.exit(0)
}
}

const spinner = ora(`Installing components...`).start()
for (const item of payload) {
spinner.text = `Installing ${item.name}...`
const targetDir = await getItemTargetPath(
config,
item,
options.path ? path.resolve(cwd, options.path) : undefined
)

if (!targetDir) {
continue
}

if (!existsSync(targetDir)) {
await fs.mkdir(targetDir, { recursive: true })
}

const existingComponent = item.files.filter((file) =>
existsSync(path.resolve(targetDir, file.name))
)

if (existingComponent.length && !options.overwrite) {
if (selectedComponents.includes(item.name)) {
spinner.stop()
const { overwrite } = await prompts({
type: "confirm",
name: "overwrite",
message: `Component ${item.name} already exists. Would you like to overwrite?`,
initial: false,
})

if (!overwrite) {
logger.info(
`Skipped ${item.name}. To overwrite, run with the ${chalk.green(
"--overwrite"
)} flag.`
)
continue
}

spinner.start(`Installing ${item.name}...`)
} else {
continue
}
}

for (const file of item.files) {
let filePath = path.resolve(targetDir, file.name)

// Run transformers.
const content = await transform({
filename: file.name,
raw: file.content,
config,
baseColor,
})

if (!config.tsx) {
filePath = filePath.replace(/\.tsx$/, ".jsx")
filePath = filePath.replace(/\.ts$/, ".js")
}

await fs.writeFile(filePath, content)
}

const packageManager = await getPackageManager(cwd)

// Install dependencies.
if (item.dependencies?.length) {
await execa(
packageManager,
[
packageManager === "npm" ? "install" : "add",
...item.dependencies,
],
{
cwd,
}
)
}

// Install devDependencies.
if (item.devDependencies?.length) {
await execa(
packageManager,
[
packageManager === "npm" ? "install" : "add",
"-D",
...item.devDependencies,
],
{
cwd,
}
)
}
}
spinner.succeed(`Done.`)
} catch (error) {
handleError(error)
}
})
3 changes: 2 additions & 1 deletion packages/cli/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { add } from "@/src/commands/add"
import { diff } from "@/src/commands/diff"
import { init } from "@/src/commands/init"
import { pull } from "@/src/commands/pull"
import { Command } from "commander"

import { getPackageInfo } from "./utils/get-package-info"
Expand All @@ -21,7 +22,7 @@ async function main() {
"display the version number"
)

program.addCommand(init).addCommand(add).addCommand(diff)
program.addCommand(init).addCommand(add).addCommand(diff).addCommand(pull)

program.parse()
}
Expand Down
3 changes: 2 additions & 1 deletion packages/cli/tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ export default defineConfig({
entry: ["src/index.ts"],
format: ["esm"],
sourcemap: true,
minify: true,
keepNames: true,
// minify: true, # Disable for meaningful names when debugging
target: "esnext",
outDir: "dist",
})

0 comments on commit 4dd2628

Please sign in to comment.