@wirechunk/cli 0.0.9 → 0.1.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 +75 -0
- package/build/main.js +57 -27
- package/package.json +1 -17
package/README.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Wirechunk CLI
|
|
2
|
+
|
|
3
|
+
The Wirechunk CLI (`wirechunk`) is the official command-line tool for Wirechunk. It provides essential utilities for platform management and is the primary tool for developing Wirechunk extensions.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
npm install -D @wirechunk/cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Getting Started with Extension Development
|
|
12
|
+
|
|
13
|
+
The CLI simplifies the extension development workflow by allowing you to run a local instance of the Wirechunk core platform that loads your extension code directly.
|
|
14
|
+
|
|
15
|
+
### Prerequisites
|
|
16
|
+
|
|
17
|
+
- **Node.js**: Must be version 24+.
|
|
18
|
+
- **Docker**: Required for running the core development server.
|
|
19
|
+
|
|
20
|
+
### Development Workflow
|
|
21
|
+
|
|
22
|
+
1. **Configure Environment**:
|
|
23
|
+
Ensure you have a `.env` file with the necessary configuration, including a core database URL (e.g., `WIRECHUNK_CORE_DATABASE_URL`). You can override the core dev server image with `WIRECHUNK_CORE_DEV_SERVER_IMAGE`; otherwise the CLI uses the latest.
|
|
24
|
+
|
|
25
|
+
2. **Start the Core Server**:
|
|
26
|
+
Run the development server which spins up a Docker container with the Wirechunk platform. It mounts your current working directory inside the container, allowing hot reload for frontend code as you develop.
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
wirechunk ext-dev start-core
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
- Adds `-d` to run in detached mode.
|
|
33
|
+
- Exposes port `8080` (Web) and `9001` (Vite).
|
|
34
|
+
|
|
35
|
+
3. **Create Extension**:
|
|
36
|
+
Register your extension with the platform to generate an ID and configure your environment. If your `extension.json` enables a database, this command will set up the connection details automatically.
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
wirechunk create-extension --dev
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Key Commands
|
|
43
|
+
|
|
44
|
+
### Extension Management
|
|
45
|
+
|
|
46
|
+
- **`wirechunk create-extension`**: Register a new extension on the platform.
|
|
47
|
+
- **`wirechunk create-extension-version`**: Publish a new version of an extension. Uploads configuration and code.
|
|
48
|
+
|
|
49
|
+
### Platform & User Management
|
|
50
|
+
|
|
51
|
+
- **`wirechunk bootstrap`**: Initialize a new platform.
|
|
52
|
+
- **`wirechunk create-user`**: Create a new user account. Useful for setting up test users or initial admins.
|
|
53
|
+
- **`wirechunk edit-admin`**: Grant or revoke admin privileges for a user on a platform.
|
|
54
|
+
|
|
55
|
+
### Development Utilities (`ext-dev`)
|
|
56
|
+
|
|
57
|
+
- **`wirechunk ext-dev start-core`**: Starts the local Docker-based development server.
|
|
58
|
+
- **`wirechunk ext-dev init-db`**: Initializes a development database for an extension.
|
|
59
|
+
- **`wirechunk ext-dev get-db-url`**: writes `DATABASE_URL` to `.env.local` (or `.env.<env-mode>.local`) with the extension’s development database connection string.
|
|
60
|
+
|
|
61
|
+
### Utility
|
|
62
|
+
|
|
63
|
+
- **`wirechunk version`**: Prints the CLI version.
|
|
64
|
+
|
|
65
|
+
## Configuration
|
|
66
|
+
|
|
67
|
+
The CLI automatically loads environment variables from `.env` and `.env.local` files in your current directory.
|
|
68
|
+
|
|
69
|
+
You can specify a custom environment mode using the `--env-mode` flag:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
wirechunk --env-mode test create-user ...
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
This will load variables from `.env.test` and `.env.test.local` in addition to the standard files.
|
package/build/main.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import EventEmitter from "node:events";
|
|
3
3
|
import require$$1$1, { spawn } from "node:child_process";
|
|
4
|
-
import require$$2$2, { resolve as resolve$1 } from "node:path";
|
|
4
|
+
import require$$2$2, { resolve as resolve$1, dirname } from "node:path";
|
|
5
5
|
import require$$3$1, { readFileSync, existsSync } from "node:fs";
|
|
6
6
|
import process$2 from "node:process";
|
|
7
7
|
import os from "node:os";
|
|
@@ -31,7 +31,7 @@ import require$$0$d from "os";
|
|
|
31
31
|
import require$$1$4 from "tty";
|
|
32
32
|
import require$$0$e from "constants";
|
|
33
33
|
import require$$5$1 from "assert";
|
|
34
|
-
import require$$2$4 from "node:url";
|
|
34
|
+
import require$$2$4, { fileURLToPath } from "node:url";
|
|
35
35
|
import require$$2$3 from "node:string_decoder";
|
|
36
36
|
import require$$0$f from "zlib";
|
|
37
37
|
var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
|
|
@@ -6834,7 +6834,7 @@ let Doc$1 = class Doc {
|
|
|
6834
6834
|
return new F(...args, lines.join("\n"));
|
|
6835
6835
|
}
|
|
6836
6836
|
};
|
|
6837
|
-
const version$
|
|
6837
|
+
const version$2 = {
|
|
6838
6838
|
major: 4,
|
|
6839
6839
|
minor: 1,
|
|
6840
6840
|
patch: 13
|
|
@@ -6844,7 +6844,7 @@ const $ZodType$1 = /* @__PURE__ */ $constructor$1("$ZodType", (inst, def) => {
|
|
|
6844
6844
|
inst ?? (inst = {});
|
|
6845
6845
|
inst._zod.def = def;
|
|
6846
6846
|
inst._zod.bag = inst._zod.bag || {};
|
|
6847
|
-
inst._zod.version = version$
|
|
6847
|
+
inst._zod.version = version$2;
|
|
6848
6848
|
const checks = [...inst._zod.def.checks ?? []];
|
|
6849
6849
|
if (inst._zod.traits.has("$ZodCheck")) {
|
|
6850
6850
|
checks.unshift(inst);
|
|
@@ -23897,7 +23897,7 @@ class Doc2 {
|
|
|
23897
23897
|
return new F(...args, lines.join("\n"));
|
|
23898
23898
|
}
|
|
23899
23899
|
}
|
|
23900
|
-
const version = {
|
|
23900
|
+
const version$1 = {
|
|
23901
23901
|
major: 4,
|
|
23902
23902
|
minor: 1,
|
|
23903
23903
|
patch: 13
|
|
@@ -23907,7 +23907,7 @@ const $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
|
|
|
23907
23907
|
inst ?? (inst = {});
|
|
23908
23908
|
inst._zod.def = def;
|
|
23909
23909
|
inst._zod.bag = inst._zod.bag || {};
|
|
23910
|
-
inst._zod.version = version;
|
|
23910
|
+
inst._zod.version = version$1;
|
|
23911
23911
|
const checks = [...inst._zod.def.checks ?? []];
|
|
23912
23912
|
if (inst._zod.traits.has("$ZodCheck")) {
|
|
23913
23913
|
checks.unshift(inst);
|
|
@@ -26007,9 +26007,11 @@ function superRefine(fn) {
|
|
|
26007
26007
|
const localhostRegex1 = /localhost:\d{2,4}$/;
|
|
26008
26008
|
const localhostRegex2 = /localhost$/;
|
|
26009
26009
|
const isLocalhost = (domain) => localhostRegex1.test(domain) || localhostRegex2.test(domain);
|
|
26010
|
+
const envModeSymbol = Symbol("envMode");
|
|
26011
|
+
const mainEnvFilePathSymbol = Symbol("mainEnvFilePath");
|
|
26012
|
+
const mainEnvFileExistsSymbol = Symbol("mainEnvFileExists");
|
|
26010
26013
|
const envFilePath = ".env";
|
|
26011
26014
|
const envLocalFilePath = ".env.local";
|
|
26012
|
-
const hasEnvFile = existsSync(envFilePath);
|
|
26013
26015
|
const requireApiToken = (env2) => {
|
|
26014
26016
|
if (!env2.WIRECHUNK_API_TOKEN) {
|
|
26015
26017
|
console.error(
|
|
@@ -26023,10 +26025,10 @@ const requireCoreDbUrl = (env2) => {
|
|
|
26023
26025
|
const url = env2.WIRECHUNK_CORE_DATABASE_URL;
|
|
26024
26026
|
if (!url) {
|
|
26025
26027
|
const message = "Missing WIRECHUNK_CORE_DATABASE_URL in environment";
|
|
26026
|
-
if (
|
|
26028
|
+
if (env2[mainEnvFileExistsSymbol]) {
|
|
26027
26029
|
console.error(message);
|
|
26028
26030
|
} else {
|
|
26029
|
-
console.error(`${message}, no ${
|
|
26031
|
+
console.error(`${message}, no ${env2[mainEnvFilePathSymbol]} file found`);
|
|
26030
26032
|
}
|
|
26031
26033
|
process$2.exit(1);
|
|
26032
26034
|
}
|
|
@@ -26045,16 +26047,20 @@ const coreServerUrlFromEnv = (env2) => {
|
|
|
26045
26047
|
};
|
|
26046
26048
|
const parseEnv = async (envMode) => {
|
|
26047
26049
|
const env2 = {};
|
|
26048
|
-
|
|
26049
|
-
|
|
26050
|
-
Object.assign(env2, parseEnv$1(envFileRaw));
|
|
26051
|
-
}
|
|
26050
|
+
const mainEnvFilePath = envMode ? `.env.${envMode}` : envFilePath;
|
|
26051
|
+
const mainEnvFileExists = existsSync(mainEnvFilePath);
|
|
26052
26052
|
if (envMode) {
|
|
26053
|
-
|
|
26054
|
-
|
|
26055
|
-
|
|
26053
|
+
if (existsSync(envFilePath)) {
|
|
26054
|
+
const envFileRaw = await readFile(envFilePath, "utf8");
|
|
26055
|
+
Object.assign(env2, parseEnv$1(envFileRaw));
|
|
26056
|
+
}
|
|
26057
|
+
if (mainEnvFileExists) {
|
|
26058
|
+
const modeFileRaw = await readFile(mainEnvFilePath, "utf8");
|
|
26056
26059
|
Object.assign(env2, parseEnv$1(modeFileRaw));
|
|
26057
26060
|
}
|
|
26061
|
+
} else if (mainEnvFileExists) {
|
|
26062
|
+
const envFileRaw = await readFile(mainEnvFilePath, "utf8");
|
|
26063
|
+
Object.assign(env2, parseEnv$1(envFileRaw));
|
|
26058
26064
|
}
|
|
26059
26065
|
if (existsSync(envLocalFilePath)) {
|
|
26060
26066
|
const envLocalFileRaw = await readFile(envLocalFilePath, "utf8");
|
|
@@ -26070,7 +26076,10 @@ const parseEnv = async (envMode) => {
|
|
|
26070
26076
|
Object.assign(env2, process$2.env);
|
|
26071
26077
|
return {
|
|
26072
26078
|
...env2,
|
|
26073
|
-
WIRECHUNK_CORE_SERVER_URL: coreServerUrlFromEnv(env2)
|
|
26079
|
+
WIRECHUNK_CORE_SERVER_URL: coreServerUrlFromEnv(env2),
|
|
26080
|
+
[envModeSymbol]: envMode,
|
|
26081
|
+
[mainEnvFilePathSymbol]: mainEnvFilePath,
|
|
26082
|
+
[mainEnvFileExistsSymbol]: mainEnvFileExists
|
|
26074
26083
|
};
|
|
26075
26084
|
};
|
|
26076
26085
|
var dist$1 = {};
|
|
@@ -66402,6 +66411,7 @@ const initDb = async (opts, env2) => {
|
|
|
66402
66411
|
coreDbUrl: coreDbUrlObject
|
|
66403
66412
|
});
|
|
66404
66413
|
};
|
|
66414
|
+
const defaultDevServerImage = "us-docker.pkg.dev/wirechunk/dev-server/core:latest";
|
|
66405
66415
|
const parseStartFlag = (value, name) => {
|
|
66406
66416
|
const trimmed = value?.trim();
|
|
66407
66417
|
if (!trimmed) {
|
|
@@ -66414,11 +66424,7 @@ const parseStartFlag = (value, name) => {
|
|
|
66414
66424
|
process.exit(1);
|
|
66415
66425
|
};
|
|
66416
66426
|
const startCore = async (opts, env2) => {
|
|
66417
|
-
const image = env2.WIRECHUNK_CORE_DEV_SERVER_IMAGE;
|
|
66418
|
-
if (!image) {
|
|
66419
|
-
console.error("Missing WIRECHUNK_CORE_DEV_SERVER_IMAGE in environment");
|
|
66420
|
-
process.exit(1);
|
|
66421
|
-
}
|
|
66427
|
+
const image = env2.WIRECHUNK_CORE_DEV_SERVER_IMAGE?.trim() || defaultDevServerImage;
|
|
66422
66428
|
const databaseUrl = env2.WIRECHUNK_CORE_DATABASE_URL_DOCKER || env2.WIRECHUNK_CORE_DATABASE_URL;
|
|
66423
66429
|
if (!databaseUrl) {
|
|
66424
66430
|
console.error(
|
|
@@ -66486,18 +66492,41 @@ const startCore = async (opts, env2) => {
|
|
|
66486
66492
|
process.exit(exitCode);
|
|
66487
66493
|
}
|
|
66488
66494
|
};
|
|
66495
|
+
const hasVersion = (value) => typeof value === "object" && value !== null && "version" in value;
|
|
66496
|
+
const packageJsonPath = resolve$1(dirname(fileURLToPath(import.meta.url)), "../package.json");
|
|
66497
|
+
const getCliVersion = () => {
|
|
66498
|
+
const parsed = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
66499
|
+
if (!hasVersion(parsed) || typeof parsed.version !== "string" || parsed.version.length === 0) {
|
|
66500
|
+
throw new Error("package.json is missing a version string");
|
|
66501
|
+
}
|
|
66502
|
+
return parsed.version;
|
|
66503
|
+
};
|
|
66504
|
+
const version = (_options) => {
|
|
66505
|
+
console.log(getCliVersion());
|
|
66506
|
+
};
|
|
66489
66507
|
const program = new Command().name("wirechunk").option("--verbose", "output debug logging").option(
|
|
66490
66508
|
"--env-mode <mode>",
|
|
66491
|
-
'the mode to use for finding .env files to load environment variables, such as "test" to load .env, .env.test, .env.local, and .env.test.local; also for finding config files to include when creating an extension or extension version, such as config.production.json'
|
|
66509
|
+
'the mode to use for finding .env files to load environment variables, such as "test" to load .env, .env.test, .env.local, and .env.test.local (in that order); also for finding config files to include when creating an extension or extension version, such as config.production.json'
|
|
66492
66510
|
).description(`The official Wirechunk CLI
|
|
66493
66511
|
|
|
66494
|
-
By default, environment variables are loaded from the .env file in the current working directory,
|
|
66495
|
-
|
|
66496
|
-
|
|
66512
|
+
By default, environment variables are loaded from the .env file in the current working directory, then the .env.local file, and then from the environment.
|
|
66513
|
+
|
|
66514
|
+
When --env-mode is used, variables are loaded from .env, then .env.<mode>, then .env.local, then .env.<mode>.local, and finally from the environment.
|
|
66515
|
+
|
|
66516
|
+
Variables loaded later overwrite those loaded earlier. Variables from the environment have the highest precedence.
|
|
66497
66517
|
|
|
66498
66518
|
Environment variables used by some commands:
|
|
66499
66519
|
WIRECHUNK_CORE_SERVER_URL (the core admin server URL for commands using the API)
|
|
66500
|
-
WIRECHUNK_CORE_DATABASE_URL (the core database URL for commands requiring direct database access)
|
|
66520
|
+
WIRECHUNK_CORE_DATABASE_URL (the core database URL for commands requiring direct database access)
|
|
66521
|
+
WIRECHUNK_API_TOKEN (the API token for authentication)
|
|
66522
|
+
WIRECHUNK_CORE_JWT_SECRET (the JWT secret for creating new tokens)`);
|
|
66523
|
+
const withOptions = (action) => async (options, cmd) => {
|
|
66524
|
+
const mergedOptions = { ...program.opts(), ...options };
|
|
66525
|
+
if (mergedOptions.verbose) {
|
|
66526
|
+
console.log(`Running ${chalk.green.bold(cmd.name())}`);
|
|
66527
|
+
}
|
|
66528
|
+
return action(mergedOptions);
|
|
66529
|
+
};
|
|
66501
66530
|
const withOptionsAndEnv = (action) => async (options, cmd) => {
|
|
66502
66531
|
const mergedOptions = { ...program.opts(), ...options };
|
|
66503
66532
|
if (mergedOptions.verbose) {
|
|
@@ -66506,6 +66535,7 @@ const withOptionsAndEnv = (action) => async (options, cmd) => {
|
|
|
66506
66535
|
const env2 = await parseEnv(mergedOptions.envMode);
|
|
66507
66536
|
return action(mergedOptions, env2);
|
|
66508
66537
|
};
|
|
66538
|
+
program.command("version").description("print the CLI version").action(withOptions(version));
|
|
66509
66539
|
program.command("bootstrap").description("create a platform").option("--dev", "bootstrap with development defaults").option("--name <string>", "the name of the platform").option("--handle <string>", "the handle of the platform").option("--admin-site-domain <string>", "the domain of the admin site (dashboard)").action(withOptionsAndEnv(bootstrap));
|
|
66510
66540
|
program.command("create-extension").description("create an extension").option("--platform-id <string>", "the ID of the platform").option("--name <string>", "the name of the extension").option(
|
|
66511
66541
|
"--config-file <string>",
|
package/package.json
CHANGED
|
@@ -1,22 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wirechunk/cli",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"lint": "eslint --fix",
|
|
8
|
-
"lint:check": "eslint",
|
|
9
|
-
"format": "prettier --write .",
|
|
10
|
-
"format:check": "prettier --check .",
|
|
11
|
-
"typecheck": "tsc",
|
|
12
|
-
"typecheck-src": "tsc --skipLibCheck",
|
|
13
|
-
"typecheck-src:tsgo": "tsgo --skipLibCheck",
|
|
14
|
-
"test": "echo 'no tests yet'",
|
|
15
|
-
"build": "npm run build:clean && npm run build:cli",
|
|
16
|
-
"build:clean": "rm -rf build",
|
|
17
|
-
"build:cli": "vite build",
|
|
18
|
-
"prepublishOnly": "npm run typecheck-src && npm run lint:check && npm run build"
|
|
19
|
-
},
|
|
20
6
|
"bin": {
|
|
21
7
|
"wirechunk": "build/main.js"
|
|
22
8
|
},
|
|
@@ -35,8 +21,6 @@
|
|
|
35
21
|
"@commander-js/extra-typings": "^14.0.0",
|
|
36
22
|
"@graphql-typed-document-node/core": "^3.2.0",
|
|
37
23
|
"@types/archiver": "^6.0.3",
|
|
38
|
-
"@wirechunk/backend-lib": "0.0.0",
|
|
39
|
-
"@wirechunk/lib": "0.0.0",
|
|
40
24
|
"archiver": "^7.0.1",
|
|
41
25
|
"chalk": "^5.6.2",
|
|
42
26
|
"commander": "^14.0.2",
|