@flowmetelev/wfkit 1.0.0
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/README.md +120 -0
- package/bin/wfkit.js +27 -0
- package/install.js +136 -0
- package/package.json +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# wfkit
|
|
2
|
+
|
|
3
|
+
`wfkit` is a CLI for building and publishing Webflow code projects.
|
|
4
|
+
|
|
5
|
+
The npm package installs the native Go binary for your platform during setup.
|
|
6
|
+
|
|
7
|
+
Supported npm targets:
|
|
8
|
+
|
|
9
|
+
- macOS `x64` and `arm64`
|
|
10
|
+
- Linux `x64` and `arm64`
|
|
11
|
+
- Windows `x64` and `arm64`
|
|
12
|
+
|
|
13
|
+
If your platform is outside that matrix, install from source instead of npm.
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
Run:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install -g @flowmetelev/wfkit
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick start
|
|
24
|
+
|
|
25
|
+
Create a project:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
wfkit init --name my-site
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Then:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
cd my-site
|
|
35
|
+
bun install
|
|
36
|
+
bun run start
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
This starts a local proxy on `http://localhost:3000` and injects your Vite scripts into proxied HTML only. The published `.webflow.io` site stays unchanged for everyone else.
|
|
40
|
+
|
|
41
|
+
To expose the proxy on your local network, run:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
wfkit proxy --host 192.168.1.25
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
When you're ready to ship:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
wfkit publish --env prod
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
To preview the publish plan without changing GitHub or Webflow:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
wfkit publish --env prod --dry-run
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Main commands
|
|
60
|
+
|
|
61
|
+
### `wfkit init`
|
|
62
|
+
|
|
63
|
+
Create a new project scaffold, including `wfkit.json`.
|
|
64
|
+
|
|
65
|
+
### `wfkit proxy`
|
|
66
|
+
|
|
67
|
+
Proxy your published `.webflow.io` site locally and inject local dev scripts.
|
|
68
|
+
|
|
69
|
+
### `wfkit publish`
|
|
70
|
+
|
|
71
|
+
Build and publish your code to Webflow.
|
|
72
|
+
|
|
73
|
+
### `wfkit doctor`
|
|
74
|
+
|
|
75
|
+
Check config, local tools, auth, and ports.
|
|
76
|
+
|
|
77
|
+
### `wfkit update`
|
|
78
|
+
|
|
79
|
+
Check for CLI updates.
|
|
80
|
+
|
|
81
|
+
## Configure the project
|
|
82
|
+
|
|
83
|
+
`wfkit.json` is the main project config file.
|
|
84
|
+
|
|
85
|
+
Example:
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"appName": "my-site",
|
|
90
|
+
"siteUrl": "https://my-site.webflow.io",
|
|
91
|
+
"ghUserName": "your-username",
|
|
92
|
+
"repositoryName": "your-repo",
|
|
93
|
+
"packageManager": "bun",
|
|
94
|
+
"branch": "main",
|
|
95
|
+
"buildDir": "dist/assets",
|
|
96
|
+
"devHost": "localhost",
|
|
97
|
+
"devPort": 5173,
|
|
98
|
+
"proxyHost": "localhost",
|
|
99
|
+
"proxyPort": 3000,
|
|
100
|
+
"openBrowser": true,
|
|
101
|
+
"globalEntry": "src/global/index.ts"
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Generated projects follow this structure:
|
|
106
|
+
|
|
107
|
+
```text
|
|
108
|
+
src/
|
|
109
|
+
global/
|
|
110
|
+
pages/
|
|
111
|
+
utils/
|
|
112
|
+
build/
|
|
113
|
+
dist/assets/
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
`wfkit` builds a `wfkit-manifest.json` file in `dist/assets` so page and global publish flows can resolve the right scripts without guessing filenames.
|
|
117
|
+
|
|
118
|
+
## Legacy dev mode
|
|
119
|
+
|
|
120
|
+
`wfkit publish --env dev` still works, but `wfkit proxy` is the recommended development flow.
|
package/bin/wfkit.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { existsSync } = require("fs");
|
|
4
|
+
const { join } = require("path");
|
|
5
|
+
const { spawnSync } = require("child_process");
|
|
6
|
+
|
|
7
|
+
const platform = process.platform;
|
|
8
|
+
const binaryName = platform === "win32" ? "wfkit.exe" : "wfkit";
|
|
9
|
+
const binaryPath = join(__dirname, binaryName);
|
|
10
|
+
|
|
11
|
+
if (!existsSync(binaryPath)) {
|
|
12
|
+
console.error(
|
|
13
|
+
`wfkit binary is missing at ${binaryPath}. Reinstall the package to run the postinstall download again.`,
|
|
14
|
+
);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const result = spawnSync(binaryPath, process.argv.slice(2), {
|
|
19
|
+
stdio: "inherit",
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
if (result.error) {
|
|
23
|
+
console.error(`Failed to start wfkit: ${result.error.message}`);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
process.exit(result.status === null ? 1 : result.status);
|
package/install.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
const { join } = require("path");
|
|
2
|
+
const { createWriteStream, existsSync, mkdirSync } = require("fs");
|
|
3
|
+
const { promisify } = require("util");
|
|
4
|
+
const { exec } = require("child_process");
|
|
5
|
+
const https = require("https");
|
|
6
|
+
const packageJSON = require("./package.json");
|
|
7
|
+
|
|
8
|
+
const pipeline = promisify(require("stream").pipeline);
|
|
9
|
+
const repositorySlug = "flowmetelev/wfkit";
|
|
10
|
+
const supportedTargets = new Map([
|
|
11
|
+
["darwin:arm64", "wfkit-darwin-arm64"],
|
|
12
|
+
["darwin:x64", "wfkit-darwin-amd64"],
|
|
13
|
+
["linux:arm64", "wfkit-linux-arm64"],
|
|
14
|
+
["linux:x64", "wfkit-linux-amd64"],
|
|
15
|
+
["win32:arm64", "wfkit-windows-arm64.exe"],
|
|
16
|
+
["win32:x64", "wfkit-windows-amd64.exe"],
|
|
17
|
+
]);
|
|
18
|
+
|
|
19
|
+
function resolveReleaseAsset(platform = process.platform, arch = process.arch) {
|
|
20
|
+
const targetKey = `${platform}:${arch}`;
|
|
21
|
+
const binaryName = supportedTargets.get(targetKey);
|
|
22
|
+
|
|
23
|
+
if (!binaryName) {
|
|
24
|
+
const supportedList = Array.from(supportedTargets.keys())
|
|
25
|
+
.map((target) => target.replace(":", "/"))
|
|
26
|
+
.join(", ");
|
|
27
|
+
throw new Error(
|
|
28
|
+
`Unsupported platform ${platform}/${arch}. Supported targets: ${supportedList}.`,
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return binaryName;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function resolveVersion() {
|
|
36
|
+
return process.env.npm_package_version || packageJSON.version;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function buildReleaseURL(binaryName, version = resolveVersion()) {
|
|
40
|
+
const normalizedVersion = String(version || "").trim();
|
|
41
|
+
if (!normalizedVersion) {
|
|
42
|
+
throw new Error("Package version is empty, cannot resolve release URL.");
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return `https://github.com/${repositorySlug}/releases/download/v${normalizedVersion}/${binaryName}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function download(url, destPath) {
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
const request = (downloadUrl, redirectCount = 0) => {
|
|
51
|
+
if (redirectCount > 5) {
|
|
52
|
+
reject(new Error("Too many redirects while downloading the binary."));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
https
|
|
57
|
+
.get(
|
|
58
|
+
downloadUrl,
|
|
59
|
+
{
|
|
60
|
+
headers: {
|
|
61
|
+
"user-agent": "wfkit-npm-installer",
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
(response) => {
|
|
65
|
+
if (
|
|
66
|
+
response.statusCode >= 300 &&
|
|
67
|
+
response.statusCode < 400 &&
|
|
68
|
+
response.headers.location
|
|
69
|
+
) {
|
|
70
|
+
response.resume();
|
|
71
|
+
request(response.headers.location, redirectCount + 1);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (response.statusCode !== 200) {
|
|
76
|
+
response.resume();
|
|
77
|
+
reject(
|
|
78
|
+
new Error(
|
|
79
|
+
`Failed to download binary: HTTP ${response.statusCode} ${response.statusMessage || ""}`.trim(),
|
|
80
|
+
),
|
|
81
|
+
);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const fileStream = createWriteStream(destPath);
|
|
86
|
+
pipeline(response, fileStream).then(resolve).catch(reject);
|
|
87
|
+
},
|
|
88
|
+
)
|
|
89
|
+
.on("error", reject);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
request(url);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function downloadBinary() {
|
|
97
|
+
const platform = process.platform;
|
|
98
|
+
const arch = process.arch;
|
|
99
|
+
const binaryName = resolveReleaseAsset(platform, arch);
|
|
100
|
+
const version = resolveVersion();
|
|
101
|
+
const url = buildReleaseURL(binaryName, version);
|
|
102
|
+
const binDir = join(__dirname, "bin");
|
|
103
|
+
|
|
104
|
+
if (!existsSync(binDir)) {
|
|
105
|
+
mkdirSync(binDir, { recursive: true });
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const destPath = join(binDir, platform === "win32" ? "wfkit.exe" : "wfkit");
|
|
109
|
+
|
|
110
|
+
console.log(`Downloading wfkit binary for ${platform} (${arch})...`);
|
|
111
|
+
console.log(`From: ${url}`);
|
|
112
|
+
|
|
113
|
+
await download(url, destPath);
|
|
114
|
+
|
|
115
|
+
if (platform !== "win32") {
|
|
116
|
+
await promisify(exec)(`chmod +x "${destPath}"`);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
console.log("wfkit installed successfully!");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
module.exports = {
|
|
123
|
+
buildReleaseURL,
|
|
124
|
+
downloadBinary,
|
|
125
|
+
repositorySlug,
|
|
126
|
+
resolveReleaseAsset,
|
|
127
|
+
resolveVersion,
|
|
128
|
+
supportedTargets,
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
if (require.main === module) {
|
|
132
|
+
downloadBinary().catch((err) => {
|
|
133
|
+
console.error("Failed to install wfkit:", err.message);
|
|
134
|
+
process.exit(1);
|
|
135
|
+
});
|
|
136
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flowmetelev/wfkit",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A powerful CLI utility for securely publishing Webflow projects with live development support.",
|
|
5
|
+
"main": "install.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"wfkit": "bin/wfkit.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"postinstall": "node install.js"
|
|
11
|
+
},
|
|
12
|
+
"os": [
|
|
13
|
+
"darwin",
|
|
14
|
+
"linux",
|
|
15
|
+
"win32"
|
|
16
|
+
],
|
|
17
|
+
"cpu": [
|
|
18
|
+
"x64",
|
|
19
|
+
"arm64"
|
|
20
|
+
],
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/flowmetelev/wfkit.git"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"webflow",
|
|
27
|
+
"cli",
|
|
28
|
+
"publish",
|
|
29
|
+
"development",
|
|
30
|
+
"deploy",
|
|
31
|
+
"sync"
|
|
32
|
+
],
|
|
33
|
+
"author": "Dmitry Metelev <mailmetelev@gmail.com>",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/flowmetelev/wfkit/issues"
|
|
37
|
+
},
|
|
38
|
+
"homepage": "https://github.com/flowmetelev/wfkit#readme",
|
|
39
|
+
"files": [
|
|
40
|
+
"bin/",
|
|
41
|
+
"install.js",
|
|
42
|
+
"package.json",
|
|
43
|
+
"README.md"
|
|
44
|
+
],
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=14.0.0"
|
|
47
|
+
}
|
|
48
|
+
}
|