@docsalot/previewing 0.1.0-beta.5 → 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.
- package/dist/assets/client.tar.gz +0 -0
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/local-preview/helper-commands/installDepsCommand.js +4 -17
- package/dist/local-preview/helper-commands/syncLocalContentCommand.d.ts +2 -0
- package/dist/local-preview/helper-commands/syncLocalContentCommand.js +75 -0
- package/dist/local-preview/index.js +17 -57
- package/dist/local-preview/prod.js +15 -67
- package/package.json +4 -3
|
Binary file
|
package/dist/constants.d.ts
CHANGED
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.
|
|
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
|
|
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,27 +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
|
|
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");
|
|
44
|
-
if (installResult.code !== 0) {
|
|
45
|
-
logger.fail("Failed to install dependencies.");
|
|
46
|
-
process.exit(1);
|
|
47
|
-
}
|
|
48
|
-
logger.succeed("Dependencies installed.");
|
|
35
|
+
logger.succeed("DocsALot runtime installed.");
|
|
49
36
|
return;
|
|
50
37
|
}
|
|
51
|
-
logger.succeed("
|
|
38
|
+
logger.succeed("DocsALot runtime already installed.");
|
|
52
39
|
};
|
|
53
40
|
export default installDeps;
|
|
@@ -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
|
|
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 {
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
70
|
-
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const isProduction = process.env.BIND_ALL_INTERFACES === "true";
|
|
81
|
-
const devScript = isProduction ? "npm run dev-host" : "npm run dev-watch";
|
|
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 (
|
|
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
|
|
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 {
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
68
|
-
|
|
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
|
-
|
|
76
|
-
|
|
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
|
-
|
|
105
|
-
|
|
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.
|
|
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.
|
|
33
|
-
"@docsalot/validation": "^0.1.0-beta.
|
|
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",
|