Skip to content

Commit f6b651b

Browse files
authored
Merge branch 'main' into docs/data-fetching-guide
2 parents 6df1cde + a8e2980 commit f6b651b

39 files changed

+1151
-15
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
* @vuestorefront/integrations-team
1+
* @vuestorefront/application-team
22
actions/check-licenses/* @filrak @rsurowieckivsf
33
docs/**/*.md

docs/content/3.middleware/4.reference/change-log.md

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,18 @@
66

77
- **[FIXED]** Fix /readyz returning 503 if readinessProbes not passed in middleware.config.ts
88

9-
Before this fix, sending a GET request to `http://localhost:4000/readyz` would return { "status": "error" } and a HTTP 503 status. This happened only when `readinessProbes` wasn't added to middleware options (the default behavior)
9+
Before this fix, sending a GET request to `http://localhost:4000/readyz` would return { "status": "error" } and a HTTP 503 status. This happened only when `readinessProbes` wasn't added to middleware options (the default behavior). From now on, the `readinessProbes` is not required and can be removed from `./apps/storefront-middleware/src/index.ts`.
10+
11+
```diff
12+
import { createServer, type CreateServerOptions } from "@vue-storefront/middleware";
13+
14+
async function runApp() {
15+
const app = await createServer(config, {
16+
cors: process.env.NODE_ENV === "production" ? undefined : developmentCorsConfig,
17+
- readinessProbes: []
18+
});
19+
}
20+
```
1021

1122
## 5.3.1
1223

@@ -103,7 +114,19 @@ If you're using that older template, please change the `Express` type to `Server
103114
- async function runMiddleware(app: Express) {
104115
```
105116
106-
- [ADDED] New GET /readyz endpoint for middleware for using with Kubernetes readiness probes. Please see https://docs.alokai.com/middleware/guides/readiness-probes for more information
117+
- [ADDED] New GET /readyz endpoint for middleware for using with Kubernetes readiness probes. Please see our [documentation](https://docs.alokai.com/guides/kubernetes-probe/readiness-probes) for more information. For the endpoint to work correctly, it is required to pass `readinessProbes` configuration (at least an empty array) to `createServer()` in `./apps/storefront-middleware/src/index.ts`:
118+
119+
```diff
120+
import { createServer, type CreateServerOptions } from "@vue-storefront/middleware";
121+
122+
async function runApp() {
123+
const app = await createServer(config, {
124+
cors: process.env.NODE_ENV === "production" ? undefined : developmentCorsConfig,
125+
+ readinessProbes: []
126+
});
127+
}
128+
129+
```
107130
108131
## 4.3.1
109132

docs/content/guides/6.best-practices/2.data-fetching.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,10 @@ Use direct direct browser to API calls only when communicating via middleware is
6767
- the communication requires extremely low latency - e.g. voice or video stream
6868
- communication with API is done via some SDK that requires direct client (browser) interaction - e.g. analytics or authentication services
6969

70+
7071
<!-- Uncomment below when CDN caching is availavble -->
7172
<!-- ## CDN Caching
73+
## CDN Caching
7274
7375
To further improve your application performance we encourage you to enable the CDN. The CDN is capable of caching responses from the server and the middleware to the browser.
7476

packages/cli/CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# @vue-storefront/cli
22

3+
## 6.0.2
4+
5+
### Patch Changes
6+
7+
- **[CHANGED]** Added back the previously removed `m2-only` command.
8+
9+
## 6.0.1
10+
11+
### Patch Changes
12+
13+
- **[FIXED]** Added back missing i18next infrastructure file to fix CLI error.
14+
315
## 6.0.0
416

517
### Major Changes

packages/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@vue-storefront/cli",
3-
"version": "6.0.0",
3+
"version": "6.0.2",
44
"description": "Vue Storefront's CLI.",
55
"bin": "./bin/run",
66
"homepage": "https://github.com/vuestorefront/vue-storefront",

packages/cli/src/commands/m2-only.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { intro } from "@clack/prompts";
2+
import { Command } from "@oclif/core";
3+
import picocolors from "picocolors";
4+
import { t } from "i18next";
5+
import { initLogger } from "../domains/generate/logging/logger";
6+
import {
7+
checkDocker,
8+
getMagentoDomainName,
9+
} from "../domains/generate/magento2/docker";
10+
import { getMagentoDetails } from "../domains/generate/magento2/functions";
11+
import { installMagento } from "../domains/generate/magento2/installMagento";
12+
import { simpleLog } from "../domains/generate/magento2/functions/terminalHelpers";
13+
14+
export default class M2Only extends Command {
15+
static override description = "Install local Magento 2 instance";
16+
17+
static override examples = ["<%= config.bin %> <%= command.id %>"];
18+
19+
static override flags = {};
20+
21+
static override args = [];
22+
23+
async run(): Promise<void> {
24+
const { writeLog, deleteLog } = initLogger();
25+
26+
intro("Welcome to the Magento 2 local instance installer!");
27+
28+
await checkDocker(writeLog);
29+
30+
const { magentoDirName, magentoAccessKey, magentoSecretKey } =
31+
await getMagentoDetails();
32+
33+
const magentoDomain = await getMagentoDomainName(
34+
t("command.generate_store.magento.domain")
35+
);
36+
37+
await installMagento({
38+
isInstallMagento: true,
39+
magentoDirName,
40+
magentoDomain,
41+
magentoAccessKey,
42+
magentoSecretKey,
43+
writeLog,
44+
});
45+
46+
deleteLog();
47+
48+
simpleLog("Happy coding! 🎉", picocolors.green);
49+
50+
this.exit(0);
51+
}
52+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import fs from "fs";
2+
3+
export const initLogger = () => {
4+
const logFile = fs.createWriteStream("CLI_logs.txt", { flags: "a" });
5+
6+
const writeLog = (message: string) => {
7+
logFile.write(`${message}\n`);
8+
};
9+
10+
const deleteLog = () => {
11+
fs.unlinkSync("CLI_logs.txt");
12+
};
13+
14+
return {
15+
writeLog,
16+
deleteLog,
17+
};
18+
};
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { spawn } from "child_process";
2+
import { t } from "i18next";
3+
import {
4+
logSimpleErrorMessage,
5+
logSimpleInfoMessage,
6+
simpleLog,
7+
} from "../functions/terminalHelpers";
8+
9+
/** Checking if Docker is installed and running on user's machine */
10+
const checkDocker = async (
11+
writeLog: (message: string) => void
12+
): Promise<void> => {
13+
const docker =
14+
process.platform === "darwin"
15+
? spawn("docker", ["info"])
16+
: spawn("sudo", ["docker", "info"]);
17+
18+
docker.stderr.on("data", (data) => {
19+
writeLog(data.toString());
20+
simpleLog(data.toString());
21+
});
22+
23+
const isDockerInstalled = await new Promise((resolve) => {
24+
docker.on("close", (code) => resolve(code === 0));
25+
});
26+
27+
if (!isDockerInstalled) {
28+
writeLog(
29+
"Docker is not installed or not running. Please make sure that prerequisites are complied with and run command again."
30+
);
31+
logSimpleErrorMessage(
32+
"Docker is not installed or not running. Please make sure that prerequisites are complied with and run command again."
33+
);
34+
logSimpleInfoMessage(t("command.generate_store.magento.failed_log"));
35+
process.exit(1);
36+
} else {
37+
writeLog("🐳 Docker is installed and running.");
38+
logSimpleInfoMessage("🐳 Docker is installed and running.");
39+
}
40+
};
41+
42+
export default checkDocker;
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import execa from "execa";
2+
3+
const checkExistingDockerContainers = async (magentoDirName = "server") => {
4+
const execaFunc =
5+
process.platform === "darwin"
6+
? execa("docker", ["container", "ls", "--format", "{{.Names}}"])
7+
: execa("sudo", ["docker", "container", "ls", "--format", "{{.Names}}"]);
8+
9+
const { stdout } = await execaFunc;
10+
11+
const isExistingDockerContainers = stdout.includes(magentoDirName);
12+
13+
return isExistingDockerContainers;
14+
};
15+
16+
export default checkExistingDockerContainers;
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export { default as checkDocker } from "./checkDocker";
2+
export { default as installMagentoImage } from "./installMagentoImage";
3+
export { default as getMagentoDomainName } from "../prompts/getMagentoDomain";
4+
export { default as checkExistingDockerContainers } from "./checkExistingDockerContainers";
5+
export { default as removeDockerContainer } from "./removeDocker";
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import { spawn } from "child_process";
2+
3+
import { note, spinner } from "@clack/prompts";
4+
import picocolors from "picocolors";
5+
import { t } from "i18next";
6+
import {
7+
logSimpleErrorMessage,
8+
logSimpleInfoMessage,
9+
} from "../functions/terminalHelpers";
10+
import removeDockerContainer from "./removeDocker";
11+
12+
/** Handles Magento 2 Docker Image installation */
13+
const installMagentoImage = async (
14+
magentoDirName: string,
15+
magentoDomainName: string,
16+
writeLog: (message: string) => void
17+
): Promise<any> => {
18+
const options = {
19+
cwd: magentoDirName,
20+
};
21+
22+
const sp = spinner();
23+
24+
return new Promise((resolve) => {
25+
const curl = spawn(
26+
"curl",
27+
[
28+
"-s",
29+
"https://raw.githubusercontent.com/markshust/docker-magento/master/lib/onelinesetup",
30+
],
31+
options
32+
);
33+
const bash = spawn("bash", ["-s", "--", magentoDomainName], options);
34+
35+
let stdout = "";
36+
37+
note(t("command.generate_store.magento.note_long"));
38+
39+
sp.start(
40+
picocolors.cyan(t("command.generate_store.progress.docker_start"))
41+
);
42+
43+
curl.stdout.pipe(bash.stdin);
44+
45+
bash.stdout.on("data", (data) => {
46+
if (
47+
data.toString().toLowerCase().includes("system") &&
48+
data.toString().toLowerCase().includes("password")
49+
) {
50+
sp.stop(
51+
picocolors.yellow(t("command.generate_store.magento.password"))
52+
);
53+
}
54+
55+
if (data.toString().includes("Restarting containers to apply updates")) {
56+
sp.start(
57+
picocolors.cyan(t("command.generate_store.progress.docker_start"))
58+
);
59+
}
60+
});
61+
62+
bash.stderr.on("data", async (data) => {
63+
stdout += data.toString();
64+
if (stdout.includes("port is already allocated")) {
65+
sp.stop();
66+
logSimpleErrorMessage(t("command.generate_store.magento.port_busy"));
67+
// delete the directory
68+
await removeDockerContainer(magentoDirName);
69+
}
70+
});
71+
72+
bash.on("exit", async (code) => {
73+
if (code === 0) {
74+
sp.stop(
75+
picocolors.green(t("command.generate_store.progress.docker_end"))
76+
);
77+
resolve(1);
78+
} else {
79+
sp.stop(
80+
picocolors.red(t("command.generate_store.progress.docker_failed"))
81+
);
82+
83+
if (
84+
stdout.includes('Project directory "/var/www/html/." is not empty')
85+
) {
86+
note(t("command.generate_store.magento.image_exists"));
87+
}
88+
// create a log file
89+
writeLog(stdout);
90+
91+
logSimpleInfoMessage(t("command.generate_store.magento.failed_log"));
92+
}
93+
});
94+
});
95+
};
96+
97+
export default installMagentoImage;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { spawn } from "child_process";
2+
import fs from "fs";
3+
4+
// rewrite with exec
5+
const removeDockerContainer = async (magentoDirName: string): Promise<any> => {
6+
const options = {
7+
cwd: magentoDirName,
8+
};
9+
10+
return new Promise(() => {
11+
const removeDocker = spawn("docker-compose", ["rm", "-f"], options);
12+
13+
removeDocker.on("exit", () => {
14+
fs.rmdirSync(magentoDirName, { recursive: true });
15+
});
16+
});
17+
};
18+
19+
export default removeDockerContainer;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { spawn } from "child_process";
2+
import { t } from "i18next";
3+
import {
4+
logSimpleErrorMessage,
5+
logSimpleSuccessMessage,
6+
} from "./terminalHelpers";
7+
8+
const checkNodeVersion = (nodeString: string): boolean => {
9+
const nodeVersion = nodeString.split("v")[1]?.split(".")[0];
10+
const subNodeVersion = nodeString.split("v")[1]?.split(".")[1];
11+
12+
if (Number(nodeVersion) === 16 && Number(subNodeVersion) >= 13) {
13+
return true;
14+
}
15+
16+
return false;
17+
};
18+
19+
/** Checking if Node version is correct as per prerequisites */
20+
const checkNode = async (
21+
writeLog: (message: string) => void
22+
): Promise<void> => {
23+
const node = spawn("node", ["-v"]);
24+
25+
return await new Promise((resolve) => {
26+
node.stdout.on("data", (data) => {
27+
writeLog(data.toString());
28+
if (!checkNodeVersion(data.toString())) {
29+
logSimpleErrorMessage(t("command.generate_store.magento.node_not_ok"));
30+
process.exit(1);
31+
}
32+
});
33+
34+
node.on("close", () => {
35+
writeLog(t("command.generate_store.magento.node_ok"));
36+
logSimpleSuccessMessage(t("command.generate_store.magento.node_ok"));
37+
resolve();
38+
});
39+
});
40+
};
41+
42+
export default checkNode;

0 commit comments

Comments
 (0)