@docsalot/previewing 0.1.0-beta.6 → 0.1.0-beta.7

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.
Binary file
@@ -1,4 +1,4 @@
1
- export declare const TARGET_CLIENT_VERSION = "v0.0.9";
1
+ export declare const TARGET_CLIENT_VERSION = "v0.1.0-runtime.1";
2
2
  export declare const INSTALL_PATH: string;
3
3
  export declare const BUNDLED_CLIENT_TARBALL_PATH: string;
4
4
  export declare const HOME_DIR: string;
package/dist/constants.js CHANGED
@@ -4,7 +4,7 @@ import path from "path";
4
4
  import * as url from "url";
5
5
  import os from "os";
6
6
  // Change this to bump to a newer version of the bundled client.
7
- export const TARGET_CLIENT_VERSION = "v0.0.9";
7
+ export const TARGET_CLIENT_VERSION = "v0.1.0-runtime.1";
8
8
  // package installation location
9
9
  export const INSTALL_PATH = url.fileURLToPath(new URL(".", import.meta.url));
10
10
  export const BUNDLED_CLIENT_TARBALL_PATH = path.join(INSTALL_PATH, "assets", "client.tar.gz");
@@ -1,8 +1,7 @@
1
1
  import shell from "shelljs";
2
2
  import fse, { pathExists } from "fs-extra";
3
- import path from "path";
4
3
  import { BUNDLED_CLIENT_TARBALL_PATH, CLIENT_PATH, MINT_PATH, TARGET_CLIENT_VERSION, VERSION_PATH, } from "../../constants.js";
5
- import { buildLogger, ensureYarn } from "../../util.js";
4
+ import { buildLogger } from "../../util.js";
6
5
  const bootstrapBundledClient = async (logger) => {
7
6
  if (!(await pathExists(BUNDLED_CLIENT_TARBALL_PATH))) {
8
7
  logger.fail(`Bundled client tarball is missing at: ${BUNDLED_CLIENT_TARBALL_PATH}`);
@@ -27,30 +26,15 @@ const shouldBootstrapClient = async () => {
27
26
  return installedVersion !== TARGET_CLIENT_VERSION;
28
27
  };
29
28
  const installDeps = async () => {
30
- const logger = buildLogger("Preparing local DocsALot client...");
31
- ensureYarn(logger);
29
+ const logger = buildLogger("Preparing local DocsALot runtime...");
32
30
  await fse.ensureDir(MINT_PATH);
33
31
  const needsBootstrap = await shouldBootstrapClient();
34
32
  if (needsBootstrap) {
35
33
  await fse.remove(CLIENT_PATH);
36
34
  await bootstrapBundledClient(logger);
37
- }
38
- const nodeModulesPath = path.join(CLIENT_PATH, "node_modules");
39
- const dependenciesInstalled = await pathExists(nodeModulesPath);
40
- if (!dependenciesInstalled || needsBootstrap) {
41
- logger.text = "Installing local DocsALot dependencies...";
42
- shell.cd(CLIENT_PATH);
43
- const installResult = shell.exec("yarn install --production=true --ignore-scripts --silent", { silent: true });
44
- if (installResult.code !== 0) {
45
- logger.fail("Failed to install dependencies.");
46
- if (installResult.stderr) {
47
- console.error(installResult.stderr);
48
- }
49
- process.exit(1);
50
- }
51
- logger.succeed("Dependencies installed.");
35
+ logger.succeed("DocsALot runtime installed.");
52
36
  return;
53
37
  }
54
- logger.succeed("Dependencies already installed.");
38
+ logger.succeed("DocsALot runtime already installed.");
55
39
  };
56
40
  export default installDeps;
@@ -0,0 +1,2 @@
1
+ declare const syncLocalContentCommand: () => Promise<void>;
2
+ export default syncLocalContentCommand;
@@ -0,0 +1,75 @@
1
+ import Chalk from "chalk";
2
+ import mintValidation from "@docsalot/validation";
3
+ import fse from "fs-extra";
4
+ import path from "path";
5
+ import { promises as _promises } from "fs";
6
+ import { CLIENT_PATH, CMD_EXEC_PATH } from "../../constants.js";
7
+ import { categorizeFiles } from "../listener/categorize.js";
8
+ import { generateNav } from "../listener/generate.js";
9
+ import { isFileSizeValid } from "../listener/utils.js";
10
+ import createPage from "../listener/utils/createPage.js";
11
+ import { getConfigPath } from "../listener/utils/mintConfigFile.js";
12
+ const { readFile } = _promises;
13
+ const PROPS_PATH = path.join(CLIENT_PATH, "src", "_props");
14
+ const PUBLIC_PATH = path.join(CLIENT_PATH, "public");
15
+ const writePages = async (contentFilenames, openApiFiles) => {
16
+ const writes = contentFilenames.map(async (filename) => {
17
+ const sourcePath = path.join(CMD_EXEC_PATH, filename);
18
+ const targetPath = path.join(PROPS_PATH, filename);
19
+ const contentStr = (await readFile(sourcePath)).toString();
20
+ const { pageContent } = await createPage(filename, contentStr, CMD_EXEC_PATH, openApiFiles);
21
+ await fse.outputFile(targetPath, pageContent, { flag: "w" });
22
+ });
23
+ await Promise.all(writes);
24
+ };
25
+ const writeSnippets = async (snippets) => {
26
+ const writes = snippets.map(async (filename) => {
27
+ const sourcePath = path.join(CMD_EXEC_PATH, filename);
28
+ const targetPath = path.join(PROPS_PATH, filename);
29
+ await fse.copy(sourcePath, targetPath);
30
+ });
31
+ await Promise.all(writes);
32
+ };
33
+ const writeStaticFiles = async (staticFilenames) => {
34
+ for (const filename of staticFilenames) {
35
+ const sourcePath = path.join(CMD_EXEC_PATH, filename);
36
+ if (!(await isFileSizeValid(sourcePath, 5))) {
37
+ console.error(Chalk.red(`🚨 The file at ${filename} is too big. The maximum file size is 5 mb.`));
38
+ continue;
39
+ }
40
+ const targetPath = path.join(PUBLIC_PATH, filename);
41
+ await fse.copy(sourcePath, targetPath);
42
+ }
43
+ };
44
+ const copyAndValidateLayout = async () => {
45
+ const configPath = await getConfigPath(CMD_EXEC_PATH);
46
+ if (configPath == null) {
47
+ throw new Error("Could not find layout.json in the docs directory.");
48
+ }
49
+ const rawConfig = (await readFile(configPath)).toString();
50
+ const config = JSON.parse(rawConfig);
51
+ const { status, errors, warnings } = mintValidation.validateMintConfig(config);
52
+ errors.forEach((error) => {
53
+ console.error(`🚨 ${Chalk.red(error)}`);
54
+ });
55
+ warnings.forEach((warning) => {
56
+ console.warn(`⚠️ ${Chalk.yellow(warning)}`);
57
+ });
58
+ if (status !== "success") {
59
+ throw new Error("layout.json is invalid. Fix validation errors and try again.");
60
+ }
61
+ await fse.copy(configPath, path.join(PROPS_PATH, "layout.json"));
62
+ };
63
+ const syncLocalContentCommand = async () => {
64
+ await fse.ensureDir(PROPS_PATH);
65
+ await fse.ensureDir(PUBLIC_PATH);
66
+ const { contentFilenames, staticFilenames, openApiFiles, snippets } = await categorizeFiles(CMD_EXEC_PATH);
67
+ await copyAndValidateLayout();
68
+ await writePages(contentFilenames, openApiFiles);
69
+ await writeSnippets(snippets);
70
+ await writeStaticFiles(staticFilenames);
71
+ await fse.outputFile(path.join(PROPS_PATH, "openApiFiles.json"), JSON.stringify(openApiFiles, null, 2), { flag: "w" });
72
+ const generatedNav = await generateNav();
73
+ await fse.outputFile(path.join(PROPS_PATH, "generatedNav.json"), JSON.stringify(generatedNav, null, 2), { flag: "w" });
74
+ };
75
+ export default syncLocalContentCommand;
@@ -2,43 +2,16 @@
2
2
  import Chalk from "chalk";
3
3
  import child_process from "child_process";
4
4
  import open from "open";
5
- import fse, { pathExists } from "fs-extra";
6
- import inquirer from "inquirer";
7
- import { isInternetAvailable } from "is-internet-available";
8
- import path from "path";
5
+ import fse from "fs-extra";
9
6
  import shell from "shelljs";
10
- import { CLIENT_PATH, HOME_DIR, DOT_DOCSALOT, CMD_EXEC_PATH, MINT_PATH, } from "../constants.js";
7
+ import { HOME_DIR, CLIENT_PATH, MINT_PATH, } from "../constants.js";
11
8
  import { buildLogger } from "../util.js";
12
9
  import listener from "./listener/index.js";
13
10
  import { getConfigPath } from "./listener/utils/mintConfigFile.js";
14
11
  import installDepsCommand from "./helper-commands/installDepsCommand.js";
15
- const nodeModulesExists = async () => {
16
- return pathExists(path.join(DOT_DOCSALOT, "client", "node_modules"));
17
- };
18
- const promptForYarn = async () => {
19
- const yarnInstalled = shell.which("yarn");
20
- if (!yarnInstalled) {
21
- await inquirer
22
- .prompt([
23
- {
24
- type: "confirm",
25
- name: "confirm",
26
- message: "yarn must be globally installed. Install yarn?",
27
- default: true,
28
- },
29
- ])
30
- .then(({ confirm }) => {
31
- if (confirm) {
32
- shell.exec("npm install --global yarn");
33
- }
34
- else {
35
- console.log("Installation cancelled.");
36
- }
37
- });
38
- }
39
- };
12
+ import syncLocalContentCommand from "./helper-commands/syncLocalContentCommand.js";
40
13
  const checkForLayoutJson = async (logger) => {
41
- const configPath = await getConfigPath(CMD_EXEC_PATH);
14
+ const configPath = await getConfigPath(process.cwd());
42
15
  if (configPath == null) {
43
16
  logger.fail("Must be ran in a directory where a layout.json file exists.");
44
17
  process.exit(1);
@@ -46,43 +19,26 @@ const checkForLayoutJson = async (logger) => {
46
19
  return;
47
20
  };
48
21
  const dev = async (argv) => {
49
- buildLogger("DEVS");
50
22
  shell.cd(HOME_DIR);
51
- await promptForYarn();
52
23
  const logger = buildLogger("Preparing local Docsalot instance...");
53
24
  await fse.ensureDir(MINT_PATH);
54
- shell.cd(MINT_PATH);
55
- const internet = await isInternetAvailable();
56
- if (!(await nodeModulesExists())) {
57
- if (!internet) {
58
- logger.fail(`Dependencies are missing and you are offline. Connect to the internet and run
59
-
60
- docsalot install
61
-
62
- `);
63
- process.exit(1);
64
- }
65
- logger.info("Dependencies missing; running first-time bootstrap...");
66
- await installDepsCommand();
67
- }
25
+ await installDepsCommand();
68
26
  await checkForLayoutJson(logger);
69
- shell.cd(CLIENT_PATH);
70
- const relativePath = path.relative(CLIENT_PATH, CMD_EXEC_PATH);
71
- child_process.spawnSync("yarn preconfigure", [relativePath], { shell: true });
27
+ logger.text = "Syncing docs content into local runtime...";
28
+ await syncLocalContentCommand();
72
29
  logger.succeed("Local instance is ready. Launching your site...");
73
30
  run(argv.port || "3000");
74
31
  };
75
32
  const run = (port) => {
76
33
  shell.cd(CLIENT_PATH);
77
- console.log("CLIENT PATH", CLIENT_PATH);
78
- // For Cloud Run/Docker, use dev-host (binds to 0.0.0.0).
79
- // For local development, use next dev directly.
80
- const isProduction = process.env.BIND_ALL_INTERFACES === "true";
81
- const devScript = isProduction ? "npm run dev-host" : "npm run dev";
82
- const docsalotDevProcess = child_process.spawn(devScript, {
34
+ const host = process.env.BIND_ALL_INTERFACES === "true" ? "0.0.0.0" : "127.0.0.1";
35
+ let browserOpened = false;
36
+ const docsalotDevProcess = child_process.spawn("node server.js", {
83
37
  env: {
84
38
  ...process.env,
85
39
  PORT: port,
40
+ HOSTNAME: host,
41
+ NODE_ENV: "production",
86
42
  },
87
43
  cwd: CLIENT_PATH,
88
44
  stdio: "pipe",
@@ -91,7 +47,11 @@ const run = (port) => {
91
47
  docsalotDevProcess.stdout.on("data", (data) => {
92
48
  const output = data.toString();
93
49
  console.log(output);
94
- if (output.startsWith("> Ready on http://localhost:")) {
50
+ if (!browserOpened &&
51
+ (output.includes("Ready in") ||
52
+ output.includes("started server") ||
53
+ output.includes("http://localhost:"))) {
54
+ browserOpened = true;
95
55
  console.log(`🌿 ${Chalk.green(`Your local preview is available at http://localhost:${port}`)}`);
96
56
  console.log(`🌿 ${Chalk.green("Press Ctrl+C any time to stop the local preview.")}`);
97
57
  open(`http://localhost:${port}`);
@@ -2,42 +2,15 @@
2
2
  import Chalk from "chalk";
3
3
  import child_process from "child_process";
4
4
  import open from "open";
5
- import fse, { pathExists } from "fs-extra";
6
- import inquirer from "inquirer";
7
- import { isInternetAvailable } from "is-internet-available";
8
- import path from "path";
5
+ import fse from "fs-extra";
9
6
  import shell from "shelljs";
10
- import { CLIENT_PATH, HOME_DIR, DOT_DOCSALOT, CMD_EXEC_PATH, MINT_PATH, } from "../constants.js";
7
+ import { HOME_DIR, CLIENT_PATH, MINT_PATH, } from "../constants.js";
11
8
  import { buildLogger } from "../util.js";
12
9
  import { getConfigPath } from "./listener/utils/mintConfigFile.js";
13
10
  import installDepsCommand from "./helper-commands/installDepsCommand.js";
14
- const nodeModulesExists = async () => {
15
- return pathExists(path.join(DOT_DOCSALOT, "client", "node_modules"));
16
- };
17
- const promptForYarn = async () => {
18
- const yarnInstalled = shell.which("yarn");
19
- if (!yarnInstalled) {
20
- await inquirer
21
- .prompt([
22
- {
23
- type: "confirm",
24
- name: "confirm",
25
- message: "yarn must be globally installed. Install yarn?",
26
- default: true,
27
- },
28
- ])
29
- .then(({ confirm }) => {
30
- if (confirm) {
31
- shell.exec("npm install --global yarn");
32
- }
33
- else {
34
- console.log("Installation cancelled.");
35
- }
36
- });
37
- }
38
- };
11
+ import syncLocalContentCommand from "./helper-commands/syncLocalContentCommand.js";
39
12
  const checkForLayoutJson = async (logger) => {
40
- const configPath = await getConfigPath(CMD_EXEC_PATH);
13
+ const configPath = await getConfigPath(process.cwd());
41
14
  if (configPath == null) {
42
15
  logger.fail("Must be ran in a directory where a layout.json file exists.");
43
16
  process.exit(1);
@@ -46,51 +19,23 @@ const checkForLayoutJson = async (logger) => {
46
19
  };
47
20
  const prod = async (argv) => {
48
21
  shell.cd(HOME_DIR);
49
- await promptForYarn();
50
22
  const logger = buildLogger("Preparing production DocsALot instance...");
51
23
  await fse.ensureDir(MINT_PATH);
52
- shell.cd(MINT_PATH);
53
- const internet = await isInternetAvailable();
54
- if (!(await nodeModulesExists())) {
55
- if (!internet) {
56
- logger.fail(`Dependencies are missing and you are offline. Connect to the internet and run
57
-
58
- docsalot install
59
-
60
- `);
61
- process.exit(1);
62
- }
63
- logger.info("Dependencies missing; running first-time bootstrap...");
64
- await installDepsCommand();
65
- }
24
+ await installDepsCommand();
66
25
  await checkForLayoutJson(logger);
67
- shell.cd(CLIENT_PATH);
68
- const relativePath = path.relative(CLIENT_PATH, CMD_EXEC_PATH);
69
- child_process.spawnSync("yarn preconfigure", [relativePath], { shell: true });
26
+ logger.text = "Syncing docs content into local runtime...";
27
+ await syncLocalContentCommand();
70
28
  logger.succeed("Production instance is ready. Launching your site...");
71
29
  run(argv.port || "3000");
72
30
  };
73
31
  const run = (port) => {
74
32
  shell.cd(CLIENT_PATH);
75
- console.log("CLIENT PATH", CLIENT_PATH);
76
- // Build the production bundle
77
- console.log(`🔨 ${Chalk.cyan("Building production bundle...")}`);
78
- const buildResult = child_process.spawnSync("npm run build", {
79
- cwd: CLIENT_PATH,
80
- stdio: "inherit",
81
- shell: true,
82
- });
83
- if (buildResult.status !== 0) {
84
- console.error(`${Chalk.red("Build failed. Please fix the errors and try again.")}`);
85
- process.exit(1);
86
- }
87
- console.log(`✅ ${Chalk.green("Build complete! Starting production server...")}`);
88
- console.log("");
89
- // Start the production server (no file watching)
90
- const docsalotProdProcess = child_process.spawn("npm run start", {
33
+ const host = process.env.BIND_ALL_INTERFACES === "true" ? "0.0.0.0" : "127.0.0.1";
34
+ const docsalotProdProcess = child_process.spawn("node server.js", {
91
35
  env: {
92
36
  ...process.env,
93
37
  PORT: port,
38
+ HOSTNAME: host,
94
39
  NODE_ENV: "production",
95
40
  },
96
41
  cwd: CLIENT_PATH,
@@ -101,8 +46,11 @@ const run = (port) => {
101
46
  docsalotProdProcess.stdout.on("data", (data) => {
102
47
  const output = data.toString();
103
48
  console.log(output);
104
- // Next.js production server outputs "ready" or "started server"
105
- if (!serverStarted && (output.includes("started server") || output.includes("ready"))) {
49
+ if (!serverStarted &&
50
+ (output.includes("started server") ||
51
+ output.includes("ready") ||
52
+ output.includes("Ready in") ||
53
+ output.includes("http://localhost:"))) {
106
54
  serverStarted = true;
107
55
  console.log(`🌿 ${Chalk.green(`Your production preview is available at http://localhost:${port}`)}`);
108
56
  console.log(`🌿 ${Chalk.green("Press Ctrl+C any time to stop the production preview.")}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docsalot/previewing",
3
- "version": "0.1.0-beta.6",
3
+ "version": "0.1.0-beta.7",
4
4
  "description": "Preview DocsALot docs locally",
5
5
  "engines": {
6
6
  "node": ">=18.0.0"
@@ -23,14 +23,15 @@
23
23
  "dist"
24
24
  ],
25
25
  "scripts": {
26
+ "prepare": "npm run build",
26
27
  "build": "tsc",
27
28
  "watch": "tsc --watch",
28
29
  "lint": "eslint . --cache"
29
30
  },
30
31
  "dependencies": {
31
32
  "@apidevtools/swagger-parser": "^10.1.0",
32
- "@docsalot/prebuild": "^0.1.0-beta.6",
33
- "@docsalot/validation": "^0.1.0-beta.6",
33
+ "@docsalot/prebuild": "^0.1.0-beta.7",
34
+ "@docsalot/validation": "^0.1.0-beta.7",
34
35
  "@octokit/rest": "^19.0.5",
35
36
  "axios": "^1.2.2",
36
37
  "chalk": "^5.1.0",