@bouygues-telecom/staticjs 0.1.1 → 0.1.3

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.
@@ -0,0 +1,80 @@
1
+ import fs from "fs";
2
+ import crypto from "node:crypto";
3
+ import path from "path";
4
+ const getDefaultExportFunctionName = (code) => {
5
+ const defaultExportRegex = /export\s+default\s+function\s+(\w+)/;
6
+ const match = code.match(defaultExportRegex);
7
+ if (match && match[1])
8
+ return match[1];
9
+ const defaultVarExportRegex = /export\s+default\s+(\w+)/;
10
+ const varMatch = code.match(defaultVarExportRegex);
11
+ if (varMatch && varMatch[1])
12
+ return varMatch[1];
13
+ return null;
14
+ };
15
+ export const addHydrationCodePlugin = (entries) => {
16
+ return {
17
+ name: "add-hydration-code",
18
+ transform(code, id) {
19
+ if (!Object.values(entries).includes(id))
20
+ return null;
21
+ const componentName = getDefaultExportFunctionName(code);
22
+ if (!componentName) {
23
+ console.warn(`No default export found in ${id}`);
24
+ return null;
25
+ }
26
+ const importReactDOM = `import ReactDOM from 'react-dom/client';`;
27
+ const importApp = `import { App } from "@/app";`;
28
+ const rootId = crypto
29
+ .createHash("sha256")
30
+ .update(`app-${id}`)
31
+ .digest("hex")
32
+ .slice(0, 10);
33
+ const initialDatasId = crypto
34
+ .createHash("sha256")
35
+ .update(`initial-data-${id}`)
36
+ .digest("hex")
37
+ .slice(0, 10);
38
+ const additionalCode = `
39
+ export const rootId = 'app-${rootId}';
40
+ export const initialDatasId = 'initial-data-${initialDatasId}';
41
+
42
+ if (typeof document !== 'undefined') {
43
+ document.addEventListener('DOMContentLoaded', () => {
44
+ const initialDataScript = document.getElementById(initialDatasId);
45
+ const initialData = initialDataScript ? JSON.parse(initialDataScript.textContent || '{}') : {title: ''};
46
+ ReactDOM.hydrateRoot(document.getElementById(rootId), App({Component:${componentName}, props: {data: initialData}}));
47
+ });
48
+ }
49
+ `;
50
+ const transformedCode = importReactDOM + "\n" + importApp + "\n" + code + "\n" + additionalCode;
51
+ return {
52
+ code: transformedCode,
53
+ map: null,
54
+ };
55
+ },
56
+ };
57
+ };
58
+ export const noJsPlugin = (entries) => {
59
+ return {
60
+ name: "no-js-plugin",
61
+ buildStart() {
62
+ const excludedFiles = [];
63
+ Object.entries(entries).forEach(([name, path]) => {
64
+ const content = fs.readFileSync(path, "utf8");
65
+ const firstLine = content.split("\n")[0];
66
+ if (firstLine.includes("no scripts")) {
67
+ delete entries[name];
68
+ excludedFiles.push(name);
69
+ console.log(`Excluding ${name} from build due to "no scripts" directive.`);
70
+ }
71
+ });
72
+ const cacheDir = path.resolve(process.cwd(), "cache");
73
+ const excludedFilePath = path.resolve(cacheDir, "excludedFiles.json");
74
+ if (!fs.existsSync(cacheDir)) {
75
+ fs.mkdirSync(cacheDir, { recursive: true });
76
+ }
77
+ fs.writeFileSync(excludedFilePath, JSON.stringify(excludedFiles, null, 2), "utf8");
78
+ },
79
+ };
80
+ };
@@ -0,0 +1,26 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { readPages } from "./readPages.js";
4
+ const pagesDir = path.resolve(process.cwd(), "src/pages");
5
+ const args = process.argv.slice(2);
6
+ const cacheDir = path.resolve(process.cwd(), "cache");
7
+ const cacheFilePath = path.resolve(cacheDir, "pagesCache.json");
8
+ let entries;
9
+ if (args.length > 0) {
10
+ entries = args
11
+ .filter((arg) => arg.endsWith(".tsx"))
12
+ .reduce((obj, tsxFile) => {
13
+ console.log(`Processing arg: ${tsxFile}`);
14
+ const relativePathWithoutExtension = tsxFile.replace(/\.tsx$/, "");
15
+ const fullPath = path.resolve(pagesDir, tsxFile);
16
+ obj[relativePathWithoutExtension] = fullPath;
17
+ return obj;
18
+ }, {});
19
+ }
20
+ else {
21
+ entries = readPages(pagesDir);
22
+ }
23
+ if (!fs.existsSync(cacheDir))
24
+ fs.mkdirSync(cacheDir, { recursive: true });
25
+ fs.writeFileSync(cacheFilePath, JSON.stringify(entries, null, 2), "utf8");
26
+ console.log("Pages cached successfully.");
@@ -0,0 +1,23 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import React from "react";
4
+ import ReactDOMServer from "react-dom/server";
5
+ const outputDir = path.resolve(process.cwd(), "dist");
6
+ export const createPage = ({ data, AppComponent, PageComponent, initialDatasId, rootId, pageName, JSfileName, }) => {
7
+ const template = `
8
+ <div id=app-{{rootId}}>{{html}}
9
+ ${data ? `<script id=initial-data-{{initialDatasId}} type="application/json">${JSON.stringify(data)}</script>` : ""}
10
+ ${JSfileName ? `<script type="module" src="{{scriptPath}}"></script>` : ""}
11
+ </div>
12
+ `;
13
+ const component = React.createElement(AppComponent, {
14
+ Component: PageComponent,
15
+ props: { data },
16
+ });
17
+ const htmlContent = template
18
+ .replace("{{initialDatasId}}", initialDatasId)
19
+ .replace("{{rootId}}", rootId)
20
+ .replace("{{html}}", ReactDOMServer.renderToString(component))
21
+ .replace("{{scriptPath}}", `${JSfileName}.js`);
22
+ fs.writeFileSync(path.join(outputDir, `${pageName}.html`), htmlContent);
23
+ };
@@ -0,0 +1,19 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ export function readPages(dir, baseDir = dir) {
4
+ let result = {};
5
+ const files = fs.readdirSync(dir);
6
+ for (const file of files) {
7
+ const fullPath = path.join(dir, file);
8
+ const stat = fs.statSync(fullPath);
9
+ if (stat.isDirectory()) {
10
+ const nested = readPages(fullPath, baseDir);
11
+ result = { ...result, ...nested };
12
+ }
13
+ else if (file.endsWith(".tsx")) {
14
+ const relPath = path.relative(baseDir, fullPath).replace(/\.tsx$/, "");
15
+ result[relPath] = fullPath;
16
+ }
17
+ }
18
+ return result;
19
+ }
@@ -0,0 +1,82 @@
1
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
2
+ import fs from "fs/promises";
3
+ import crypto from "node:crypto";
4
+ import path from "path";
5
+ import { createPage } from "../helpers/createPage.js";
6
+ const rootDir = path.resolve(process.cwd(), "./src");
7
+ async function loadJson(filePath) {
8
+ const data = await fs.readFile(filePath, "utf-8");
9
+ return JSON.parse(data);
10
+ }
11
+ async function main() {
12
+ const excludedJSFiles = await loadJson(path.join(path.resolve(process.cwd()), "./cache/excludedFiles.json"));
13
+ const files = await loadJson(path.join(path.resolve(process.cwd()), "./cache/pagesCache.json"));
14
+ const processPage = async (page) => {
15
+ try {
16
+ let data;
17
+ const absolutePath = page.path;
18
+ const pageModule = await import(absolutePath);
19
+ const appModule = await import(`${rootDir}/app.tsx`);
20
+ const fileName = path.basename(page.path, path.extname(page.path));
21
+ const AppComponent = appModule.App;
22
+ const PageComponent = pageModule.default;
23
+ const getStaticProps = pageModule?.getStaticProps;
24
+ const getStaticPaths = pageModule?.getStaticPaths;
25
+ const injectJS = !excludedJSFiles.includes(page.pageName);
26
+ const rootId = crypto
27
+ .createHash("sha256")
28
+ .update(`app-${absolutePath}`)
29
+ .digest("hex")
30
+ .slice(0, 10);
31
+ const initialDatasId = crypto
32
+ .createHash("sha256")
33
+ .update(`initial-data-${absolutePath}`)
34
+ .digest("hex")
35
+ .slice(0, 10);
36
+ if (!PageComponent) {
37
+ throw new Error(`Failed to import PageComponent from ${page.pageName}.tsx`);
38
+ }
39
+ if (getStaticProps && getStaticPaths) {
40
+ const { paths } = await getStaticPaths();
41
+ return paths.forEach(async (param) => {
42
+ const slug = param.params[fileName.replace(/[\[\]]/g, "")];
43
+ const { props } = await getStaticProps(param);
44
+ const pageName = page.pageName.replace(/\[.*?\]/, slug);
45
+ const JSfileName = injectJS && fileName.replace(/\[(.*?)\]/g, "_$1_");
46
+ createPage({
47
+ data: props.data,
48
+ AppComponent,
49
+ PageComponent,
50
+ initialDatasId,
51
+ rootId,
52
+ pageName,
53
+ JSfileName: JSfileName,
54
+ });
55
+ });
56
+ }
57
+ if (getStaticProps) {
58
+ const { props } = await getStaticProps();
59
+ data = props.data;
60
+ }
61
+ createPage({
62
+ data,
63
+ AppComponent,
64
+ PageComponent,
65
+ initialDatasId,
66
+ rootId,
67
+ pageName: page.pageName,
68
+ JSfileName: injectJS && fileName,
69
+ });
70
+ console.log(`Successfully wrote: dist/${page.pageName}.html`);
71
+ }
72
+ catch (error) {
73
+ console.error(`Error processing ${page.pageName}:`, error);
74
+ }
75
+ };
76
+ const pages = Object.entries(files).map(([pageName, path]) => ({
77
+ pageName: pageName,
78
+ path: path,
79
+ }));
80
+ pages.forEach(processPage);
81
+ }
82
+ main();
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env node
2
+ import { program } from "commander";
3
+ import { execSync } from "node:child_process";
4
+ import { dirname } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ import path from "path";
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+ program
9
+ .command("build")
10
+ .description("Build with static.js configuration")
11
+ .action(() => {
12
+ try {
13
+ const cachePagesPath = path.resolve(__dirname, "../helpers/cachePages.js");
14
+ const htmlConfig = path.resolve(__dirname, "./build-html.js");
15
+ const dest = process.cwd();
16
+ console.log("Executing static.js config...");
17
+ execSync("rimraf dist", {
18
+ cwd: dest,
19
+ stdio: "inherit",
20
+ });
21
+ execSync(`rimraf cache && node ${cachePagesPath}`, {
22
+ cwd: dest,
23
+ stdio: "inherit",
24
+ });
25
+ execSync(`vite build && tsx ${htmlConfig}`, {
26
+ cwd: dest,
27
+ stdio: "inherit",
28
+ });
29
+ console.log("Build completed successfully");
30
+ }
31
+ catch (error) {
32
+ console.error("Build failed:", error);
33
+ process.exit(1);
34
+ }
35
+ });
36
+ program.parse(process.argv);
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env node
2
+ import { Spinner } from "cli-spinner";
3
+ import { downloadTemplate } from "giget";
4
+ import path from "path";
5
+ import readline from "readline";
6
+ const rl = readline.createInterface({
7
+ input: process.stdin,
8
+ output: process.stdout,
9
+ });
10
+ async function createReactPowerStatic(projectName) {
11
+ const dest = path.join(process.cwd(), projectName);
12
+ const spinner = new Spinner("Creating react project... %s");
13
+ spinner.setSpinnerString("|/-\\");
14
+ spinner.start();
15
+ try {
16
+ await downloadTemplate(`github:BouyguesTelecom/static.js/templates/react`, {
17
+ force: true,
18
+ provider: "github",
19
+ cwd: dest,
20
+ dir: `.`,
21
+ });
22
+ spinner.stop(true);
23
+ console.log("React project created successfully in " + dest);
24
+ }
25
+ catch (error) {
26
+ spinner.stop(true);
27
+ console.error("Error can't create react project:", error);
28
+ process.exit(1);
29
+ }
30
+ finally {
31
+ rl.close();
32
+ }
33
+ }
34
+ rl.question("Enter the name for your new project: ", (projectName) => {
35
+ createReactPowerStatic(projectName);
36
+ });
@@ -0,0 +1,31 @@
1
+ import { exec } from "child_process";
2
+ import { dirname } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import path from "path";
5
+ const __dirname = dirname(fileURLToPath(import.meta.url));
6
+ export const revalidate = (req, res) => {
7
+ try {
8
+ const paths = req?.body?.paths || [];
9
+ const pathsArg = paths.length > 0 ? paths.join(" ") : "";
10
+ const cachePages = path.resolve(__dirname, "../helpers/cachePages.js");
11
+ const buildHtmlConfig = path.resolve(__dirname, "./build-html.js");
12
+ const buildCommand = `NODE_TLS_REJECT_UNAUTHORIZED=0 node ${cachePages} ${pathsArg && `${pathsArg}`} && npx tsx ${buildHtmlConfig}`;
13
+ exec(buildCommand, (error, stdout, stderr) => {
14
+ if (error) {
15
+ console.error(`Exec error: ${error}`);
16
+ return;
17
+ }
18
+ if (!error) {
19
+ console.log(`stdout: ${stdout}`);
20
+ console.error(`stderr: ${stderr}`);
21
+ }
22
+ });
23
+ return res
24
+ .status(200)
25
+ .send(`Revalidation triggered, paths: ${paths.length > 0 ? paths.join(", ") : "all pages"} built!`);
26
+ }
27
+ catch (error) {
28
+ console.error("Revalidation error:", error);
29
+ res.status(500).send("Error during revalidation.");
30
+ }
31
+ };
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@bouygues-telecom/staticjs",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "files": [
6
- "config",
7
- "helpers",
8
- "scripts",
6
+ "dist/config",
7
+ "dist/helpers",
8
+ "dist/scripts",
9
9
  "package.json",
10
10
  "README.md"
11
11
  ],
@@ -14,10 +14,12 @@
14
14
  "bt-staticjs": "./scripts/cli.js"
15
15
  },
16
16
  "scripts": {
17
- "build": "cd templates/react && rimraf dist && rimraf cache && node ../../helpers/cachePages.js && vite build --config ../../vite.config.js && tsx ../../scripts/build-html.js",
17
+ "prebuild": "tsc -p ./tsconfig.json",
18
+ "build": "cd templates/react && rimraf dist && rimraf cache && node ../../dist/helpers/cachePages.js && vite build --config ../../vite.config.js && tsx ../../dist/scripts/build-html.js",
18
19
  "start": "cd templates/react && npm start"
19
20
  },
20
21
  "dependencies": {
22
+ "@types/node": "^20",
21
23
  "cli-spinner": "^0.2.10",
22
24
  "commander": "^14.0.0",
23
25
  "giget": "^2.0.0",
@@ -25,12 +27,17 @@
25
27
  "path": "^0.12.7",
26
28
  "readline": "^1.3.0",
27
29
  "rimraf": "^6.0.1",
28
- "tsx": "^4.19.4"
30
+ "tsx": "^4.19.4",
31
+ "typescript": "^5"
29
32
  },
30
33
  "volta": {
31
34
  "node": "24.1.0"
32
35
  },
33
36
  "workspaces": [
34
37
  "templates/react"
35
- ]
38
+ ],
39
+ "devDependencies": {
40
+ "@types/cli-spinner": "^0.2.3",
41
+ "@types/express": "^5.0.3"
42
+ }
36
43
  }
@@ -1,97 +0,0 @@
1
- import fs from "fs";
2
- import crypto from "node:crypto";
3
- import path from "path";
4
-
5
- const getDefaultExportFunctionName = (code) => {
6
- const defaultExportRegex = /export\s+default\s+function\s+(\w+)/;
7
- const match = code.match(defaultExportRegex);
8
- if (match && match[1]) return match[1];
9
- const defaultVarExportRegex = /export\s+default\s+(\w+)/;
10
- const varMatch = code.match(defaultVarExportRegex);
11
- if (varMatch && varMatch[1]) return varMatch[1];
12
- return null;
13
- };
14
-
15
- export const addHydrationCodePlugin = (entries) => {
16
- return {
17
- name: "add-hydration-code",
18
- transform(code, id) {
19
- if (!Object.values(entries).includes(id)) return null;
20
- const componentName = getDefaultExportFunctionName(code);
21
-
22
- if (!componentName) {
23
- console.warn(`No default export found in ${id}`);
24
- return null;
25
- }
26
-
27
- const importReactDOM = `import ReactDOM from 'react-dom/client';`;
28
- const importApp = `import { App } from "@/app";`;
29
-
30
- const rootId = crypto
31
- .createHash("sha256")
32
- .update(`app-${id}`)
33
- .digest("hex")
34
- .slice(0, 10);
35
-
36
- const initialDatasId = crypto
37
- .createHash("sha256")
38
- .update(`initial-data-${id}`)
39
- .digest("hex")
40
- .slice(0, 10);
41
-
42
- const additionalCode = `
43
- export const rootId = 'app-${rootId}';
44
- export const initialDatasId = 'initial-data-${initialDatasId}';
45
-
46
- if (typeof document !== 'undefined') {
47
- document.addEventListener('DOMContentLoaded', () => {
48
- const initialDataScript = document.getElementById(initialDatasId);
49
- const initialData = initialDataScript ? JSON.parse(initialDataScript.textContent || '{}') : {title: ''};
50
- ReactDOM.hydrateRoot(document.getElementById(rootId), App({Component:${componentName}, props: {data: initialData}}));
51
- });
52
- }
53
- `;
54
-
55
- const transformedCode =
56
- importReactDOM + "\n" + importApp + "\n" + code + "\n" + additionalCode;
57
-
58
- return {
59
- code: transformedCode,
60
- map: null,
61
- };
62
- },
63
- };
64
- };
65
-
66
- export const noJsPlugin = (entries) => {
67
- return {
68
- name: "no-js-plugin",
69
- buildStart() {
70
- const excludedFiles = [];
71
-
72
- Object.entries(entries).forEach(([name, path]) => {
73
- const content = fs.readFileSync(path, "utf8");
74
- const firstLine = content.split("\n")[0];
75
-
76
- if (firstLine.includes("no scripts")) {
77
- delete entries[name];
78
- excludedFiles.push(name);
79
- console.log(`Excluding ${name} from build due to "no scripts" directive.`);
80
- }
81
- });
82
-
83
- const cacheDir = path.resolve(process.cwd(), "cache");
84
- const excludedFilePath = path.resolve(cacheDir, "excludedFiles.json");
85
-
86
- if (!fs.existsSync(cacheDir)) {
87
- fs.mkdirSync(cacheDir, { recursive: true });
88
- }
89
-
90
- fs.writeFileSync(
91
- excludedFilePath,
92
- JSON.stringify(excludedFiles, null, 2),
93
- "utf8"
94
- );
95
- },
96
- };
97
- };
@@ -1,28 +0,0 @@
1
- import fs from "fs";
2
- import path from "path";
3
- import { readPages } from "./readPages.js";
4
-
5
- const pagesDir = path.resolve(process.cwd(), "src/pages");
6
- const args = process.argv.slice(2);
7
- const cacheDir = path.resolve(process.cwd(), "cache");
8
- const cacheFilePath = path.resolve(cacheDir, "pagesCache.json");
9
-
10
- let entries;
11
-
12
- if (args.length > 0) {
13
- entries = args
14
- .filter((arg) => arg.endsWith(".tsx"))
15
- .reduce((obj, tsxFile) => {
16
- console.log(`Processing arg: ${tsxFile}`);
17
- const relativePathWithoutExtension = tsxFile.replace(/\.tsx$/, "");
18
- const fullPath = path.resolve(pagesDir, tsxFile);
19
- obj[relativePathWithoutExtension] = fullPath;
20
- return obj;
21
- }, {});
22
- } else {
23
- entries = readPages(pagesDir);
24
- }
25
-
26
- if (!fs.existsSync(cacheDir)) fs.mkdirSync(cacheDir, { recursive: true });
27
- fs.writeFileSync(cacheFilePath, JSON.stringify(entries, null, 2), "utf8");
28
- console.log("Pages cached successfully.");
@@ -1,36 +0,0 @@
1
- import fs from "fs";
2
- import path from "path";
3
- import React from "react";
4
- import ReactDOMServer from "react-dom/server";
5
-
6
- const outputDir = path.resolve(process.cwd(), "dist");
7
-
8
- export const createPage = ({
9
- data,
10
- AppComponent,
11
- PageComponent,
12
- initialDatasId,
13
- rootId,
14
- pageName,
15
- JSfileName,
16
- }) => {
17
- const template = `
18
- <div id=app-{{rootId}}>{{html}}
19
- ${data ? `<script id=initial-data-{{initialDatasId}} type="application/json">${JSON.stringify(data)}</script>` : ""}
20
- ${JSfileName ? `<script type="module" src="{{scriptPath}}"></script>` : ""}
21
- </div>
22
- `;
23
-
24
- const component = React.createElement(AppComponent, {
25
- Component: PageComponent,
26
- props: { data },
27
- });
28
-
29
- const htmlContent = template
30
- .replace("{{initialDatasId}}", initialDatasId)
31
- .replace("{{rootId}}", rootId)
32
- .replace("{{html}}", ReactDOMServer.renderToString(component))
33
- .replace("{{scriptPath}}", `${JSfileName}.js`);
34
-
35
- fs.writeFileSync(path.join(outputDir, `${pageName}.html`), htmlContent);
36
- };
@@ -1,22 +0,0 @@
1
- import fs from "fs";
2
- import path from "path";
3
-
4
- export function readPages(dir, baseDir = dir) {
5
- let result = {};
6
- const files = fs.readdirSync(dir);
7
-
8
- for (const file of files) {
9
- const fullPath = path.join(dir, file);
10
- const stat = fs.statSync(fullPath);
11
-
12
- if (stat.isDirectory()) {
13
- const nested = readPages(fullPath, baseDir);
14
- result = { ...result, ...nested };
15
- } else if (file.endsWith(".tsx")) {
16
- const relPath = path.relative(baseDir, fullPath).replace(/\.tsx$/, "");
17
- result[relPath] = fullPath;
18
- }
19
- }
20
-
21
- return result;
22
- }
@@ -1,104 +0,0 @@
1
- process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
2
-
3
- import fs from "fs/promises";
4
- import crypto from "node:crypto";
5
- import path from "path";
6
- import { createPage } from "../helpers/createPage.js";
7
-
8
- const rootDir = path.resolve(process.cwd(), "./src");
9
-
10
- async function loadJson(filePath) {
11
- const data = await fs.readFile(filePath, "utf-8");
12
- return JSON.parse(data);
13
- }
14
-
15
- async function main() {
16
- const excludedJSFiles = await loadJson(
17
- path.join(path.resolve(process.cwd()), "./cache/excludedFiles.json")
18
- );
19
- const files = await loadJson(
20
- path.join(path.resolve(process.cwd()), "./cache/pagesCache.json")
21
- );
22
-
23
- const processPage = async (page) => {
24
- try {
25
- let data;
26
- const absolutePath = page.path;
27
- const pageModule = await import(absolutePath);
28
- const appModule = await import(`${rootDir}/app.tsx`);
29
- const fileName = path.basename(page.path, path.extname(page.path));
30
-
31
- const AppComponent = appModule.App;
32
- const PageComponent = pageModule.default;
33
- const getStaticProps = pageModule?.getStaticProps;
34
- const getStaticPaths = pageModule?.getStaticPaths;
35
- const injectJS = !excludedJSFiles.includes(page.pageName);
36
-
37
- const rootId = crypto
38
- .createHash("sha256")
39
- .update(`app-${absolutePath}`)
40
- .digest("hex")
41
- .slice(0, 10);
42
-
43
- const initialDatasId = crypto
44
- .createHash("sha256")
45
- .update(`initial-data-${absolutePath}`)
46
- .digest("hex")
47
- .slice(0, 10);
48
-
49
- if (!PageComponent) {
50
- throw new Error(
51
- `Failed to import PageComponent from ${page.pageName}.tsx`
52
- );
53
- }
54
-
55
- if (getStaticProps && getStaticPaths) {
56
- const { paths } = await getStaticPaths();
57
- paths.forEach(async (param) => {
58
- const slug = param.params[fileName.replace(/[\[\]]/g, "")];
59
- const { props } = await getStaticProps(param);
60
- const pageName = page.pageName.replace(/\[.*?\]/, slug);
61
- const JSfileName = injectJS && fileName.replace(/\[(.*?)\]/g, "_$1_");
62
-
63
- createPage({
64
- data: props.data,
65
- AppComponent,
66
- PageComponent,
67
- initialDatasId,
68
- rootId,
69
- pageName,
70
- JSfileName,
71
- });
72
- });
73
- }
74
-
75
- if (getStaticProps && !getStaticPaths) {
76
- const { props } = await getStaticProps();
77
- data = props.data;
78
-
79
- createPage({
80
- data,
81
- AppComponent,
82
- PageComponent,
83
- initialDatasId,
84
- rootId,
85
- pageName: page.pageName,
86
- JSfileName: injectJS && fileName,
87
- });
88
- }
89
-
90
- console.log(`Successfully wrote: dist/${page.pageName}.html`);
91
- } catch (error) {
92
- console.error(`Error processing ${page.pageName}:`, error);
93
- }
94
- };
95
-
96
- const pages = Object.entries(files).map(([pageName, path]) => ({
97
- pageName,
98
- path,
99
- }));
100
-
101
- pages.forEach(processPage);
102
- }
103
-
104
- main();
package/scripts/cli.js DELETED
@@ -1,46 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { program } from "commander";
4
- import { execSync } from "node:child_process";
5
- import { dirname } from "node:path";
6
- import { fileURLToPath } from "node:url";
7
- import path from "path";
8
-
9
- const __dirname = dirname(fileURLToPath(import.meta.url));
10
- program
11
- .command("build")
12
- .description("Build with static.js configuration")
13
- .action(() => {
14
- try {
15
- const cachePagesPath = path.resolve(
16
- __dirname,
17
- "../helpers/cachePages.js"
18
- );
19
-
20
- const htmlConfig = path.resolve(__dirname, "./build-html.js");
21
- const dest = process.cwd();
22
- console.log("Executing static.js config...");
23
-
24
- execSync("rimraf dist", {
25
- cwd: dest,
26
- stdio: "inherit",
27
- });
28
-
29
- execSync(`rimraf cache && node ${cachePagesPath}`, {
30
- cwd: dest,
31
- stdio: "inherit",
32
- });
33
-
34
- execSync(`vite build && tsx ${htmlConfig}`, {
35
- cwd: dest,
36
- stdio: "inherit",
37
- });
38
-
39
- console.log("Build completed successfully");
40
- } catch (error) {
41
- console.error("Build failed:", error);
42
- process.exit(1);
43
- }
44
- });
45
-
46
- program.parse(process.argv);
@@ -1,40 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { Spinner } from "cli-spinner";
4
- import { downloadTemplate } from "giget";
5
- import path from "path";
6
- import readline from "readline";
7
-
8
- const rl = readline.createInterface({
9
- input: process.stdin,
10
- output: process.stdout,
11
- });
12
-
13
- async function createReactPowerStatic(projectName) {
14
- const dest = path.join(process.cwd(), projectName);
15
- const spinner = new Spinner("Creating react project... %s");
16
- spinner.setSpinnerString("|/-\\");
17
- spinner.start();
18
-
19
- try {
20
- await downloadTemplate(`github:BouyguesTelecom/static.js/templates/react`, {
21
- force: true,
22
- provider: "github",
23
- cwd: dest,
24
- dir: `.`,
25
- });
26
-
27
- spinner.stop(true);
28
- console.log("React project created successfully in " + dest);
29
- } catch (error) {
30
- spinner.stop(true);
31
- console.error("Error can't create react project:", error);
32
- process.exit(1);
33
- } finally {
34
- rl.close();
35
- }
36
- }
37
-
38
- rl.question("Enter the name for your new project: ", (projectName) => {
39
- createReactPowerStatic(projectName);
40
- });
@@ -1,41 +0,0 @@
1
- import { exec } from "child_process";
2
- import { dirname } from "node:path";
3
- import { fileURLToPath } from "node:url";
4
- import path from "path";
5
-
6
- const __dirname = dirname(fileURLToPath(import.meta.url));
7
-
8
- export const revalidate = (req, res) => {
9
- try {
10
- const paths = req?.body?.paths || [];
11
- const pathsArg = paths.length > 0 ? paths.join(" ") : "";
12
- const cachePages = path.resolve(__dirname, "../helpers/cachePages.js");
13
- const buildHtmlConfig = path.resolve(__dirname, "./build-html.js");
14
-
15
- const buildCommand = `NODE_TLS_REJECT_UNAUTHORIZED=0 node ${cachePages} ${
16
- pathsArg && `${pathsArg}`
17
- } && npx tsx ${buildHtmlConfig}`;
18
-
19
- exec(buildCommand, (error, stdout, stderr) => {
20
- if (error) {
21
- console.error(`Exec error: ${error}`);
22
- return;
23
- }
24
- if (!error) {
25
- console.log(`stdout: ${stdout}`);
26
- console.error(`stderr: ${stderr}`);
27
- }
28
- });
29
-
30
- return res
31
- .status(200)
32
- .send(
33
- `Revalidation triggered, paths: ${
34
- paths.length > 0 ? paths.join(", ") : "all pages"
35
- } built!`
36
- );
37
- } catch (error) {
38
- console.error("Revalidation error:", error);
39
- res.status(500).send("Error during revalidation.");
40
- }
41
- };