@nexical/cli 0.1.6 → 0.10.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/.github/workflows/deploy.yml +3 -3
- package/README.md +317 -104
- package/dist/chunk-JYASTIIW.js +42 -0
- package/dist/chunk-JYASTIIW.js.map +1 -0
- package/dist/chunk-LZ3YQWAR.js +2204 -0
- package/dist/chunk-LZ3YQWAR.js.map +1 -0
- package/dist/chunk-OKXOCNXP.js +105 -0
- package/dist/chunk-OKXOCNXP.js.map +1 -0
- package/dist/chunk-OYFWMYPG.js +52 -0
- package/dist/chunk-OYFWMYPG.js.map +1 -0
- package/dist/chunk-WKERTCM6.js +74 -0
- package/dist/chunk-WKERTCM6.js.map +1 -0
- package/dist/index.js +33 -6
- package/dist/index.js.map +1 -1
- package/dist/src/commands/init.d.ts +11 -0
- package/dist/src/commands/init.js +88 -0
- package/dist/src/commands/init.js.map +1 -0
- package/dist/src/commands/module/add.d.ts +14 -0
- package/dist/src/commands/module/add.js +136 -0
- package/dist/src/commands/module/add.js.map +1 -0
- package/dist/src/commands/module/list.d.ts +10 -0
- package/dist/src/commands/module/list.js +73 -0
- package/dist/src/commands/module/list.js.map +1 -0
- package/dist/src/commands/module/remove.d.ts +12 -0
- package/dist/src/commands/module/remove.js +71 -0
- package/dist/src/commands/module/remove.js.map +1 -0
- package/dist/src/commands/module/update.d.ts +11 -0
- package/dist/src/commands/module/update.js +52 -0
- package/dist/src/commands/module/update.js.map +1 -0
- package/dist/src/commands/run.d.ts +11 -0
- package/dist/src/commands/run.js +93 -0
- package/dist/src/commands/run.js.map +1 -0
- package/dist/src/utils/discovery.d.ts +13 -0
- package/dist/src/utils/discovery.js +9 -0
- package/dist/src/utils/git.d.ts +16 -0
- package/dist/src/utils/git.js +29 -0
- package/dist/src/utils/git.js.map +1 -0
- package/dist/src/utils/url-resolver.d.ts +15 -0
- package/dist/src/utils/url-resolver.js +9 -0
- package/dist/src/utils/url-resolver.js.map +1 -0
- package/index.ts +29 -5
- package/package.json +32 -30
- package/src/commands/init.ts +85 -0
- package/src/commands/module/add.ts +169 -0
- package/src/commands/module/list.ts +69 -0
- package/src/commands/module/remove.ts +74 -0
- package/src/commands/module/update.ts +50 -0
- package/src/commands/run.ts +98 -0
- package/src/utils/discovery.ts +134 -0
- package/src/utils/git.ts +65 -0
- package/src/utils/url-resolver.ts +57 -0
- package/test/e2e/lifecycle.e2e.test.ts +152 -0
- package/test/integration/commands/init.integration.test.ts +82 -0
- package/test/integration/commands/module.integration.test.ts +144 -0
- package/test/integration/commands/run.integration.test.ts +90 -0
- package/test/integration/utils/command-loading.integration.test.ts +80 -0
- package/test/unit/commands/init.test.ts +153 -0
- package/test/unit/commands/module/add.test.ts +262 -0
- package/test/unit/commands/module/list.test.ts +115 -0
- package/test/unit/commands/module/remove.test.ts +89 -0
- package/test/unit/commands/module/update.test.ts +91 -0
- package/test/unit/commands/run.test.ts +252 -0
- package/test/unit/utils/command-discovery.test.ts +176 -0
- package/test/unit/utils/git.test.ts +152 -0
- package/test/unit/utils/integration-helpers.test.ts +72 -0
- package/test/unit/utils/url-resolver.test.ts +39 -0
- package/test/utils/integration-helpers.ts +66 -0
- package/vitest.e2e.config.ts +0 -1
- package/dist/chunk-JDRAVUKK.js +0 -48
- package/dist/chunk-JDRAVUKK.js.map +0 -1
- package/dist/src/commands/admin/create-user.d.ts +0 -15
- package/dist/src/commands/admin/create-user.js +0 -49
- package/dist/src/commands/admin/create-user.js.map +0 -1
- package/dist/src/commands/branch/create.d.ts +0 -19
- package/dist/src/commands/branch/create.js +0 -59
- package/dist/src/commands/branch/create.js.map +0 -1
- package/dist/src/commands/branch/delete.d.ts +0 -15
- package/dist/src/commands/branch/delete.js +0 -50
- package/dist/src/commands/branch/delete.js.map +0 -1
- package/dist/src/commands/branch/get.d.ts +0 -15
- package/dist/src/commands/branch/get.js +0 -53
- package/dist/src/commands/branch/get.js.map +0 -1
- package/dist/src/commands/branch/list.d.ts +0 -15
- package/dist/src/commands/branch/list.js +0 -51
- package/dist/src/commands/branch/list.js.map +0 -1
- package/dist/src/commands/job/get.d.ts +0 -15
- package/dist/src/commands/job/get.js +0 -62
- package/dist/src/commands/job/get.js.map +0 -1
- package/dist/src/commands/job/list.d.ts +0 -15
- package/dist/src/commands/job/list.js +0 -57
- package/dist/src/commands/job/list.js.map +0 -1
- package/dist/src/commands/job/logs.d.ts +0 -15
- package/dist/src/commands/job/logs.js +0 -67
- package/dist/src/commands/job/logs.js.map +0 -1
- package/dist/src/commands/job/trigger.d.ts +0 -19
- package/dist/src/commands/job/trigger.js +0 -74
- package/dist/src/commands/job/trigger.js.map +0 -1
- package/dist/src/commands/login.d.ts +0 -8
- package/dist/src/commands/login.js +0 -31
- package/dist/src/commands/login.js.map +0 -1
- package/dist/src/commands/project/create.d.ts +0 -24
- package/dist/src/commands/project/create.js +0 -63
- package/dist/src/commands/project/create.js.map +0 -1
- package/dist/src/commands/project/delete.d.ts +0 -20
- package/dist/src/commands/project/delete.js +0 -58
- package/dist/src/commands/project/delete.js.map +0 -1
- package/dist/src/commands/project/get.d.ts +0 -15
- package/dist/src/commands/project/get.js +0 -49
- package/dist/src/commands/project/get.js.map +0 -1
- package/dist/src/commands/project/list.d.ts +0 -15
- package/dist/src/commands/project/list.js +0 -45
- package/dist/src/commands/project/list.js.map +0 -1
- package/dist/src/commands/project/update.d.ts +0 -19
- package/dist/src/commands/project/update.js +0 -66
- package/dist/src/commands/project/update.js.map +0 -1
- package/dist/src/commands/team/create.d.ts +0 -19
- package/dist/src/commands/team/create.js +0 -45
- package/dist/src/commands/team/create.js.map +0 -1
- package/dist/src/commands/team/delete.d.ts +0 -20
- package/dist/src/commands/team/delete.js +0 -52
- package/dist/src/commands/team/delete.js.map +0 -1
- package/dist/src/commands/team/get.d.ts +0 -15
- package/dist/src/commands/team/get.js +0 -42
- package/dist/src/commands/team/get.js.map +0 -1
- package/dist/src/commands/team/list.d.ts +0 -8
- package/dist/src/commands/team/list.js +0 -30
- package/dist/src/commands/team/list.js.map +0 -1
- package/dist/src/commands/team/member/invite.d.ts +0 -20
- package/dist/src/commands/team/member/invite.js +0 -54
- package/dist/src/commands/team/member/invite.js.map +0 -1
- package/dist/src/commands/team/member/remove.d.ts +0 -15
- package/dist/src/commands/team/member/remove.js +0 -43
- package/dist/src/commands/team/member/remove.js.map +0 -1
- package/dist/src/commands/team/update.d.ts +0 -19
- package/dist/src/commands/team/update.js +0 -55
- package/dist/src/commands/team/update.js.map +0 -1
- package/dist/src/commands/token/generate.d.ts +0 -19
- package/dist/src/commands/token/generate.js +0 -48
- package/dist/src/commands/token/generate.js.map +0 -1
- package/dist/src/commands/token/list.d.ts +0 -8
- package/dist/src/commands/token/list.js +0 -31
- package/dist/src/commands/token/list.js.map +0 -1
- package/dist/src/commands/token/revoke.d.ts +0 -15
- package/dist/src/commands/token/revoke.js +0 -38
- package/dist/src/commands/token/revoke.js.map +0 -1
- package/dist/src/commands/whoami.d.ts +0 -8
- package/dist/src/commands/whoami.js +0 -26
- package/dist/src/commands/whoami.js.map +0 -1
- package/dist/src/utils/nexical-client.d.ts +0 -10
- package/dist/src/utils/nexical-client.js +0 -12
- package/src/commands/admin/create-user.ts +0 -46
- package/src/commands/branch/create.ts +0 -57
- package/src/commands/branch/delete.ts +0 -47
- package/src/commands/branch/get.ts +0 -50
- package/src/commands/branch/list.ts +0 -50
- package/src/commands/job/get.ts +0 -59
- package/src/commands/job/list.ts +0 -56
- package/src/commands/job/logs.ts +0 -67
- package/src/commands/job/trigger.ts +0 -73
- package/src/commands/login.ts +0 -31
- package/src/commands/project/create.ts +0 -61
- package/src/commands/project/delete.ts +0 -56
- package/src/commands/project/get.ts +0 -46
- package/src/commands/project/list.ts +0 -44
- package/src/commands/project/update.ts +0 -63
- package/src/commands/team/create.ts +0 -43
- package/src/commands/team/delete.ts +0 -50
- package/src/commands/team/get.ts +0 -39
- package/src/commands/team/list.ts +0 -26
- package/src/commands/team/member/invite.ts +0 -56
- package/src/commands/team/member/remove.ts +0 -40
- package/src/commands/team/update.ts +0 -53
- package/src/commands/token/generate.ts +0 -45
- package/src/commands/token/list.ts +0 -27
- package/src/commands/token/revoke.ts +0 -35
- package/src/commands/whoami.ts +0 -21
- package/src/utils/nexical-client.ts +0 -47
- package/test/e2e/auth.e2e.test.ts +0 -46
- package/test/e2e/job-workflow.e2e.test.ts +0 -33
- package/test/e2e/project-lifecycle.e2e.test.ts +0 -48
- package/test/e2e/setup.ts +0 -237
- package/test/e2e/utils.ts +0 -33
- package/test/integration/commands/admin/create-user.test.ts +0 -51
- package/test/integration/commands/branch/create.test.ts +0 -51
- package/test/integration/commands/branch/delete.test.ts +0 -43
- package/test/integration/commands/branch/get.test.ts +0 -49
- package/test/integration/commands/branch/list.test.ts +0 -47
- package/test/integration/commands/job/get.test.ts +0 -54
- package/test/integration/commands/job/list.test.ts +0 -47
- package/test/integration/commands/job/logs.test.ts +0 -47
- package/test/integration/commands/job/trigger.test.ts +0 -57
- package/test/integration/commands/login.test.ts +0 -62
- package/test/integration/commands/project/create.test.ts +0 -53
- package/test/integration/commands/project/delete.test.ts +0 -43
- package/test/integration/commands/project/get.test.ts +0 -51
- package/test/integration/commands/project/list.test.ts +0 -47
- package/test/integration/commands/project/update.test.ts +0 -53
- package/test/integration/commands/team/create.test.ts +0 -53
- package/test/integration/commands/team/delete.test.ts +0 -43
- package/test/integration/commands/team/get.test.ts +0 -50
- package/test/integration/commands/team/list.test.ts +0 -47
- package/test/integration/commands/team/member/invite.test.ts +0 -46
- package/test/integration/commands/team/member/remove.test.ts +0 -43
- package/test/integration/commands/team/update.test.ts +0 -50
- package/test/integration/commands/token/generate.test.ts +0 -51
- package/test/integration/commands/token/list.test.ts +0 -47
- package/test/integration/commands/token/revoke.test.ts +0 -43
- package/test/integration/commands/whoami.test.ts +0 -49
- package/test/unit/commands/admin/create-user.test.ts +0 -51
- package/test/unit/commands/branch/create.test.ts +0 -57
- package/test/unit/commands/branch/delete.test.ts +0 -49
- package/test/unit/commands/branch/get.test.ts +0 -67
- package/test/unit/commands/branch/list.test.ts +0 -62
- package/test/unit/commands/job/get.test.ts +0 -76
- package/test/unit/commands/job/list.test.ts +0 -62
- package/test/unit/commands/job/logs.test.ts +0 -60
- package/test/unit/commands/job/trigger.test.ts +0 -75
- package/test/unit/commands/login.test.ts +0 -64
- package/test/unit/commands/project/create.test.ts +0 -64
- package/test/unit/commands/project/delete.test.ts +0 -72
- package/test/unit/commands/project/get.test.ts +0 -73
- package/test/unit/commands/project/list.test.ts +0 -62
- package/test/unit/commands/project/update.test.ts +0 -58
- package/test/unit/commands/team/create.test.ts +0 -68
- package/test/unit/commands/team/delete.test.ts +0 -71
- package/test/unit/commands/team/get.test.ts +0 -70
- package/test/unit/commands/team/list.test.ts +0 -56
- package/test/unit/commands/team/member/invite.test.ts +0 -52
- package/test/unit/commands/team/member/remove.test.ts +0 -49
- package/test/unit/commands/team/update.test.ts +0 -63
- package/test/unit/commands/token/generate.test.ts +0 -65
- package/test/unit/commands/token/list.test.ts +0 -58
- package/test/unit/commands/token/revoke.test.ts +0 -49
- package/test/unit/commands/whoami.test.ts +0 -49
- package/test/unit/utils/nexical-client.test.ts +0 -113
- /package/dist/src/utils/{nexical-client.js.map → discovery.js.map} +0 -0
|
@@ -17,10 +17,10 @@ jobs:
|
|
|
17
17
|
uses: actions/setup-node@v4
|
|
18
18
|
with:
|
|
19
19
|
node-version: 22
|
|
20
|
-
registry-url:
|
|
20
|
+
registry-url: 'https://registry.npmjs.org'
|
|
21
21
|
|
|
22
22
|
- name: Install Dependencies
|
|
23
|
-
run: npm
|
|
23
|
+
run: npm install
|
|
24
24
|
|
|
25
25
|
- name: Build
|
|
26
26
|
run: npm run build
|
|
@@ -31,4 +31,4 @@ jobs:
|
|
|
31
31
|
- name: Publish to NPM
|
|
32
32
|
run: npm publish --access public
|
|
33
33
|
env:
|
|
34
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
34
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/README.md
CHANGED
|
@@ -1,183 +1,396 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @nexical/cli
|
|
2
2
|
|
|
3
|
-
The
|
|
3
|
+
The official Command Line Interface (CLI) for the Nexical framework.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This project serves as the primary entry point for managing Nexical projects, handling tasks such as project initialization, module management, and development workflows. It is designed to be **extensible**, **fast**, and **developer-friendly**, focusing on a clean architecture that allows for easy addition of new commands.
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Purpose](#purpose)
|
|
10
|
+
- [Architecture & Design](#architecture--design)
|
|
11
|
+
- [Getting Started](#getting-started)
|
|
12
|
+
- [Project Structure](#project-structure)
|
|
13
|
+
- [Development Workflow](#development-workflow)
|
|
14
|
+
- [Prerequisites](#prerequisites)
|
|
15
|
+
- [Setup](#setup)
|
|
16
|
+
- [Running Tests](#running-tests)
|
|
17
|
+
- [Adding New Commands](#adding-new-commands)
|
|
18
|
+
- [Contributing](#contributing)
|
|
19
|
+
- [License](#license)
|
|
6
20
|
|
|
7
21
|
---
|
|
8
22
|
|
|
9
|
-
##
|
|
23
|
+
## Purpose
|
|
10
24
|
|
|
11
|
-
|
|
25
|
+
The Nexical CLI allows developers to:
|
|
26
|
+
1. **Initialize** new Nexical projects with best practices built-in.
|
|
27
|
+
2. **Manage** project configuration and dependencies.
|
|
28
|
+
3. **Extend** the framework functionality through modular commands.
|
|
29
|
+
|
|
30
|
+
It acts as a unification layer, bringing together various tools and configurations into a cohesive developer experience.
|
|
31
|
+
|
|
32
|
+
## Architecture & Design
|
|
12
33
|
|
|
13
|
-
- **
|
|
14
|
-
|
|
34
|
+
This CLI is built with **TypeScript** and follows a **Class-Based Command Pattern** to ensure type safety and maintainability.
|
|
35
|
+
|
|
36
|
+
### Key Technologies
|
|
37
|
+
* **[CAC (Command And Conquer)](https://github.com/cacjs/cac)**: A lightweight, robust framework for building CLIs. It handles argument parsing, help generation, and command registration.
|
|
38
|
+
* **[Consola](https://github.com/unjs/consola)**: Elegant console logging with fallback and structured output capabilities.
|
|
39
|
+
* **[Lilconfig](https://github.com/antonk52/lilconfig)**: Configuration loading (searching for `nexical.yml`, `nexical.yaml`) akin to `cosmiconfig` but lighter.
|
|
40
|
+
* **Vitest**: A blazing fast unit test framework powered by Vite.
|
|
41
|
+
|
|
42
|
+
### Core Components
|
|
43
|
+
1. **`CLI` Class** (`src/core/CLI.ts`): The orchestrator. It initializes the CAC instance, discovers commands using the `CommandLoader`, registers them, and handles the execution lifecycle.
|
|
44
|
+
2. **`CommandLoader`** (`src/core/CommandLoader.ts`): Responsible for dynamically discovering and importing command files from the filesystem. It supports:
|
|
45
|
+
* Recursive directory scanning.
|
|
46
|
+
* Nested commands (e.g., `module/add.ts` -> `module add`).
|
|
47
|
+
* Index files as parent commands (e.g., `module/index.ts` -> `module`).
|
|
48
|
+
3. **`BaseCommand`** (`src/core/BaseCommand.ts`): The abstract base class that all commands MUST extend. It provides:
|
|
49
|
+
* Standardized `init()` and `run()` lifecycle methods.
|
|
50
|
+
* Built-in access to global options (like `--root-dir`).
|
|
51
|
+
* Helper methods for logging (`this.log`, `this.warn`, `this.error`).
|
|
52
|
+
* Project root detection (`this.projectRoot`).
|
|
53
|
+
|
|
54
|
+
### Design Goals
|
|
55
|
+
* **Zero-Config Defaults**: It should work out of the box but allow rich configuration via `nexical.yaml`.
|
|
56
|
+
* **Extensibility**: Adding a command should be as simple as adding a file.
|
|
57
|
+
* **Testability**: Every component is designed to be unit-testable, with dependency injection where appropriate (e.g., `CommandLoader` importer).
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Getting Started
|
|
15
62
|
|
|
16
63
|
### Installation
|
|
17
64
|
|
|
18
|
-
|
|
65
|
+
While currently in development, you can run the CLI from the repository source or link it.
|
|
19
66
|
|
|
20
67
|
```bash
|
|
21
|
-
|
|
68
|
+
# From within the package directory
|
|
69
|
+
npm install
|
|
70
|
+
npm run build
|
|
22
71
|
```
|
|
23
72
|
|
|
24
|
-
###
|
|
25
|
-
|
|
26
|
-
To run the CLI locally during development, you can use `npm start`. To pass arguments to the CLI, use the `--` separator:
|
|
73
|
+
### Usage
|
|
27
74
|
|
|
28
75
|
```bash
|
|
29
|
-
#
|
|
30
|
-
|
|
76
|
+
# Run the built CLI
|
|
77
|
+
npx nexical <command> [options]
|
|
78
|
+
|
|
79
|
+
# Example: Initialize a new project
|
|
80
|
+
npx nexical init my-new-project
|
|
31
81
|
|
|
32
|
-
#
|
|
33
|
-
|
|
82
|
+
# Get help
|
|
83
|
+
npx nexical help
|
|
84
|
+
|
|
85
|
+
# Get help for a specific command
|
|
86
|
+
npx nexical help init
|
|
87
|
+
npx nexical help module add
|
|
34
88
|
```
|
|
35
89
|
|
|
36
|
-
|
|
90
|
+
### Command Reference
|
|
91
|
+
|
|
92
|
+
#### `init`
|
|
37
93
|
|
|
94
|
+
Initializes a new Nexical project by cloning a starter repository, setting up dependencies, and preparing a fresh git history.
|
|
95
|
+
|
|
96
|
+
**Usage:**
|
|
38
97
|
```bash
|
|
39
|
-
|
|
40
|
-
nexical --help
|
|
98
|
+
npx nexical init <directory> [options]
|
|
41
99
|
```
|
|
42
100
|
|
|
101
|
+
**Arguments:**
|
|
102
|
+
- `directory` (Required): The directory to initialize the project in. If the directory does not exist, it will be created. If it does exist, it must be empty.
|
|
103
|
+
|
|
104
|
+
**Options:**
|
|
105
|
+
- `--repo <url>` (Default: `https://github.com/nexical/app-core`): The URL of the starter repository to clone.
|
|
106
|
+
- Supports standard Git URLs (e.g., `https://github.com/user/repo.git`).
|
|
107
|
+
- Supports GitHub short syntax `gh@owner/repo` (e.g., `gh@nexical/app-core`).
|
|
108
|
+
|
|
109
|
+
**What it does:**
|
|
110
|
+
1. **Clones** the specified starter repository (recursively, including submodules) into the target directory.
|
|
111
|
+
2. **Updates** all submodules to their latest `main` branch.
|
|
112
|
+
3. **Installs** dependencies using `npm install`.
|
|
113
|
+
4. **Resets** Git history:
|
|
114
|
+
- Creates an orphan branch (`new-main`).
|
|
115
|
+
- Commits all files as an "Initial commit".
|
|
116
|
+
- Deletes the old history (removes `main`/`master`).
|
|
117
|
+
- Renames the branch to `main`.
|
|
118
|
+
- Removes the `origin` remote to prevent accidental pushes to the starter repo.
|
|
119
|
+
|
|
120
|
+
**Output:**
|
|
121
|
+
- A ready-to-use Nexical project in the specified directory, with fresh git history and installed dependencies.
|
|
122
|
+
|
|
43
123
|
---
|
|
44
124
|
|
|
45
|
-
|
|
125
|
+
#### `dev`
|
|
126
|
+
|
|
127
|
+
Starts the development server in ephemeral mode. It constructs a temporary build environment in `site` and runs the Astro dev server with Hot Module Replacement (HMR).
|
|
128
|
+
|
|
129
|
+
**Usage:**
|
|
130
|
+
```bash
|
|
131
|
+
npx nexical dev
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
**What it does:**
|
|
135
|
+
2. **Starts** the Astro development server (accessible at `http://localhost:4321` by default).
|
|
136
|
+
3. **Watches** for changes in your project and updates the ephemeral build automatically.
|
|
137
|
+
|
|
138
|
+
---
|
|
46
139
|
|
|
47
|
-
|
|
140
|
+
#### `build`
|
|
48
141
|
|
|
49
|
-
|
|
50
|
-
Start the authentication process. This will provide a verification URL and a code.
|
|
142
|
+
Compiles the project for production. It assembles the final site structure in `site` and generates static assets.
|
|
51
143
|
|
|
144
|
+
**Usage:**
|
|
52
145
|
```bash
|
|
53
|
-
nexical
|
|
146
|
+
npx nexical build
|
|
54
147
|
```
|
|
55
|
-
*Follow the on-screen instructions to authorize the device via your browser.*
|
|
56
148
|
|
|
57
|
-
|
|
58
|
-
|
|
149
|
+
**What it does:**
|
|
150
|
+
1. **Cleans** the `site` directory to ensure a fresh build.
|
|
151
|
+
2. **Copies** all necessary source files (`src/`, `modules`, `src/content`, `public`) into `site`.
|
|
152
|
+
3. **Runs** `astro build` to generate the production output in `site/dist`.
|
|
59
153
|
|
|
154
|
+
**Output:**
|
|
155
|
+
- A production-ready static site in `site/dist`.
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
#### `preview`
|
|
160
|
+
|
|
161
|
+
Previews the locally built production site. This is useful for verifying the output of `nexical build` before deploying.
|
|
162
|
+
|
|
163
|
+
**Usage:**
|
|
60
164
|
```bash
|
|
61
|
-
nexical
|
|
165
|
+
npx nexical preview
|
|
62
166
|
```
|
|
63
167
|
|
|
168
|
+
**Prerequisites:**
|
|
169
|
+
- You must run `nexical build` first.
|
|
170
|
+
|
|
171
|
+
**What it does:**
|
|
172
|
+
- Starts a local web server serving the static files from `site/dist`.
|
|
173
|
+
|
|
64
174
|
---
|
|
65
175
|
|
|
66
|
-
|
|
176
|
+
#### `clean`
|
|
67
177
|
|
|
68
|
-
|
|
178
|
+
Removes generated build artifacts and temporary directories to ensure a clean state.
|
|
69
179
|
|
|
70
|
-
|
|
180
|
+
**Usage:**
|
|
181
|
+
```bash
|
|
182
|
+
npx nexical clean
|
|
183
|
+
```
|
|
71
184
|
|
|
72
|
-
|
|
185
|
+
**What it does:**
|
|
186
|
+
- Deletes `site`, `dist`, and `node_modules/.vite`.
|
|
73
187
|
|
|
74
|
-
|
|
75
|
-
| :--- | :--- | :--- |
|
|
76
|
-
| `list` | `nexical team list` | List all teams you belong to or own. |
|
|
77
|
-
| `create` | `nexical team create <name> [--slug <slug>]` | Create a new team. |
|
|
78
|
-
| `get` | `nexical team get <teamId>` | View details of a specific team. |
|
|
79
|
-
| `update` | `nexical team update <teamId> [--name <n>] [--slug <s>]` | Update team settings. |
|
|
80
|
-
| `invite` | `nexical team invite <teamId> <email> [--role <role>]` | Invite a user to a team. |
|
|
81
|
-
| `delete` | `nexical team delete <teamId> [--confirm]` | Delete a team permanently. |
|
|
188
|
+
---
|
|
82
189
|
|
|
83
|
-
|
|
190
|
+
#### `run`
|
|
84
191
|
|
|
85
|
-
|
|
192
|
+
Executes a script within the Nexical environment context. This handles path resolution and environment variable setup for you.
|
|
86
193
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
| `get` | `nexical project get <teamId> <projectId>` | Get project details. |
|
|
92
|
-
| `update` | `nexical project update <teamId> <projectId> ...` | Update project configuration. |
|
|
93
|
-
| `delete` | `nexical project delete <teamId> <projectId>` | Delete a project. |
|
|
194
|
+
**Usage:**
|
|
195
|
+
```bash
|
|
196
|
+
npx nexical run <script> [args...]
|
|
197
|
+
```
|
|
94
198
|
|
|
95
|
-
|
|
199
|
+
**Arguments:**
|
|
200
|
+
- `script` (Required): The name of the script to run.
|
|
201
|
+
- Can be a standard `package.json` script (e.g., `test`).
|
|
202
|
+
- Can be a module-specific script using `module:script` syntax (e.g., `blog:sync`).
|
|
203
|
+
- `args` (Optional): Additional arguments to pass to the script.
|
|
96
204
|
|
|
97
|
-
|
|
205
|
+
**Examples:**
|
|
206
|
+
```bash
|
|
207
|
+
# Run a core project script
|
|
208
|
+
npx nexical run test
|
|
98
209
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
| `delete` | `nexical branch delete ...` | Delete a branch. |
|
|
210
|
+
# Run a script defined in the 'blog' module's package.json
|
|
211
|
+
npx nexical run blog:sync --force
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
---
|
|
105
215
|
|
|
106
|
-
|
|
216
|
+
#### `module`
|
|
107
217
|
|
|
108
|
-
|
|
218
|
+
Manages the modular architecture of your Nexical project. Allows you to add, remove, update, and list Git-based modules.
|
|
109
219
|
|
|
110
|
-
|
|
111
|
-
| :--- | :--- | :--- |
|
|
112
|
-
| `list` | `nexical job list <teamId> <projectId> <branchId>` | List recent jobs. |
|
|
113
|
-
| `trigger`| `nexical job trigger ... <type> [--input <json>]` | Trigger a new job (e.g., deploy). |
|
|
114
|
-
| `get` | `nexical job get ... <jobId>` | Get job details. |
|
|
115
|
-
| `logs` | `nexical job logs ... <jobId>` | Stream or view logs for a job. |
|
|
220
|
+
##### `module add`
|
|
116
221
|
|
|
117
|
-
|
|
222
|
+
Adds a new module as a Git submodule.
|
|
118
223
|
|
|
119
|
-
|
|
224
|
+
**Usage:**
|
|
225
|
+
```bash
|
|
226
|
+
npx nexical module add <url> [name]
|
|
227
|
+
```
|
|
120
228
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
| `revoke` | `nexical token revoke <id>` | Revoke a token. |
|
|
229
|
+
**Arguments:**
|
|
230
|
+
- `url` (Required): The Git repository URL of the module.
|
|
231
|
+
- Supports `gh@owner/repo` shorthand.
|
|
232
|
+
- `name` (Optional): The folder name for the module. Defaults to the repository name.
|
|
126
233
|
|
|
127
|
-
|
|
234
|
+
**What it does:**
|
|
235
|
+
1. Adds the repository as a git submodule in `src/modules/<name>`.
|
|
236
|
+
2. Installs any new dependencies via `npm install`.
|
|
128
237
|
|
|
129
|
-
|
|
238
|
+
##### `module list`
|
|
130
239
|
|
|
131
|
-
|
|
132
|
-
| :--- | :--- | :--- |
|
|
133
|
-
| `create-user` | `nexical admin create-user <name> <email> <password>` | Create a system user. |
|
|
240
|
+
Lists all installed modules in the project.
|
|
134
241
|
|
|
135
|
-
|
|
242
|
+
**Usage:**
|
|
243
|
+
```bash
|
|
244
|
+
npx nexical module list
|
|
245
|
+
```
|
|
136
246
|
|
|
137
|
-
|
|
247
|
+
**Output:**
|
|
248
|
+
- A table showing the name, version, and description of each installed module found in `src/modules`.
|
|
138
249
|
|
|
139
|
-
|
|
250
|
+
##### `module update`
|
|
140
251
|
|
|
252
|
+
Updates one or all modules to their latest remote commit.
|
|
253
|
+
|
|
254
|
+
**Usage:**
|
|
255
|
+
```bash
|
|
256
|
+
npx nexical module update [name]
|
|
141
257
|
```
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
258
|
+
|
|
259
|
+
**Arguments:**
|
|
260
|
+
- `name` (Optional): The specific module to update. If omitted, all modules are updated.
|
|
261
|
+
|
|
262
|
+
**What it does:**
|
|
263
|
+
1. Runs `git submodule update --remote --merge` for the target(s).
|
|
264
|
+
2. Re-installs dependencies to ensure `package-lock.json` is consistent.
|
|
265
|
+
|
|
266
|
+
##### `module remove`
|
|
267
|
+
|
|
268
|
+
Removes an installed module and cleans up references.
|
|
269
|
+
|
|
270
|
+
**Usage:**
|
|
271
|
+
```bash
|
|
272
|
+
npx nexical module remove <name>
|
|
149
273
|
```
|
|
150
274
|
|
|
151
|
-
|
|
275
|
+
**Arguments:**
|
|
276
|
+
- `name` (Required): The name of the module to remove.
|
|
277
|
+
|
|
278
|
+
**What it does:**
|
|
279
|
+
1. De-initializes the git submodule.
|
|
280
|
+
2. Removes the module directory from `src/modules`.
|
|
281
|
+
3. Cleans up internal git metadata (`.git/modules`).
|
|
282
|
+
4. Updates `npm` dependencies.
|
|
152
283
|
|
|
153
284
|
---
|
|
154
285
|
|
|
155
|
-
##
|
|
286
|
+
## Project Structure
|
|
287
|
+
|
|
288
|
+
```mermaid
|
|
289
|
+
graph TD
|
|
290
|
+
src-->commands
|
|
291
|
+
src-->core
|
|
292
|
+
src-->utils
|
|
293
|
+
commands-->init.ts
|
|
294
|
+
core-->CLI.ts
|
|
295
|
+
core-->BaseCommand.ts
|
|
296
|
+
core-->CommandLoader.ts
|
|
297
|
+
utils-->config.ts
|
|
298
|
+
utils-->logger.ts
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
* **`src/commands/`**: Contains the implementations of individual CLI commands. File names correspond to command names.
|
|
302
|
+
* **`src/core/`**: The framework logic (Command loading, Base class, CLI orchestration).
|
|
303
|
+
* **`src/utils/`**: Shared utilities (Logging, Configuration parsing).
|
|
304
|
+
* **`test/unit/`**: Co-located unit tests. Mirrors the `src` structure.
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## Development Workflow
|
|
309
|
+
|
|
310
|
+
### Prerequisites
|
|
311
|
+
* Node.js (v18+ recommended)
|
|
312
|
+
* NPM
|
|
313
|
+
|
|
314
|
+
### Setup
|
|
315
|
+
|
|
316
|
+
1. **Install Dependencies**:
|
|
317
|
+
```bash
|
|
318
|
+
npm install
|
|
319
|
+
```
|
|
156
320
|
|
|
157
|
-
|
|
321
|
+
2. **Build in Watch Mode**:
|
|
322
|
+
```bash
|
|
323
|
+
npm run dev
|
|
324
|
+
```
|
|
325
|
+
This uses `tsup` to watch for changes and rebuild `dist/`.
|
|
326
|
+
|
|
327
|
+
### Running Tests
|
|
328
|
+
|
|
329
|
+
We prioritize **100% Test Coverage**. All logic branches, statements, and lines must be covered.
|
|
158
330
|
|
|
159
331
|
```bash
|
|
160
|
-
# Run unit tests
|
|
161
|
-
npm run test
|
|
332
|
+
# Run all unit tests (with coverage report)
|
|
333
|
+
npm run test
|
|
162
334
|
```
|
|
163
335
|
|
|
336
|
+
Tests are written using `vitest` and are located in `test/unit/`. When submitting changes, ensure coverage remains at 100%.
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Adding New Commands
|
|
341
|
+
|
|
342
|
+
To create a new command, add a TypeScript file to `src/commands/`.
|
|
343
|
+
|
|
344
|
+
**Example:** Create `src/commands/hello.ts`
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
import { BaseCommand } from '../core/BaseCommand.js';
|
|
348
|
+
|
|
349
|
+
export default class HelloCommand extends BaseCommand {
|
|
350
|
+
// 1. Define command metadata
|
|
351
|
+
static description = 'Say hello to the world';
|
|
352
|
+
|
|
353
|
+
static args = {
|
|
354
|
+
args: [
|
|
355
|
+
{ name: 'name', required: false, description: 'User name' }
|
|
356
|
+
],
|
|
357
|
+
options: [
|
|
358
|
+
{ name: '--shout', description: 'Say it loud', default: false }
|
|
359
|
+
]
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
// 2. Implement the run method
|
|
363
|
+
async run(options: any) {
|
|
364
|
+
const name = options.name || 'World';
|
|
365
|
+
|
|
366
|
+
if (options.shout) {
|
|
367
|
+
this.success(`HELLO ${name.toUpperCase()}!`);
|
|
368
|
+
} else {
|
|
369
|
+
this.log(`Hello ${name}`);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
**Key Requirement**: The file MUST default export a class extending `BaseCommand`.
|
|
376
|
+
|
|
377
|
+
* **File Naming**:
|
|
378
|
+
* `hello.ts` -> Command: `hello`
|
|
379
|
+
* `users/create.ts` -> Command: `users create`
|
|
380
|
+
* `users/index.ts` -> Command: `users` (Parent command)
|
|
381
|
+
|
|
164
382
|
---
|
|
165
383
|
|
|
166
|
-
##
|
|
384
|
+
## Contributing
|
|
167
385
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
- Extend `BaseCommand`.
|
|
174
|
-
- Define `static description` and `static args`.
|
|
175
|
-
- Implement `run()`.
|
|
176
|
-
5. **Test** your changes.
|
|
177
|
-
6. **Submit** a Pull Request.
|
|
386
|
+
Contributions are welcome! Please follow these steps:
|
|
387
|
+
1. Fork the repository.
|
|
388
|
+
2. Create a feature branch.
|
|
389
|
+
3. Add your changes and **ensure tests pass with 100% coverage**.
|
|
390
|
+
4. Submit a Pull Request.
|
|
178
391
|
|
|
179
392
|
---
|
|
180
393
|
|
|
181
394
|
## License
|
|
182
395
|
|
|
183
|
-
Apache
|
|
396
|
+
This project is licensed under the **Apache License 2.0**.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { createRequire } from "module"; const require = createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
init_esm_shims
|
|
4
|
+
} from "./chunk-OYFWMYPG.js";
|
|
5
|
+
|
|
6
|
+
// src/utils/url-resolver.ts
|
|
7
|
+
init_esm_shims();
|
|
8
|
+
function resolveGitUrl(url) {
|
|
9
|
+
if (!url) {
|
|
10
|
+
throw new Error("URL cannot be empty");
|
|
11
|
+
}
|
|
12
|
+
let resolved = url;
|
|
13
|
+
if (resolved.startsWith("gh@")) {
|
|
14
|
+
resolved = resolved.replace(/^gh@/, "https://github.com/");
|
|
15
|
+
}
|
|
16
|
+
const protocolMatch = resolved.match(/^[a-z0-9]+:\/\//i);
|
|
17
|
+
let splitIndex = -1;
|
|
18
|
+
if (protocolMatch) {
|
|
19
|
+
splitIndex = resolved.indexOf("//", protocolMatch[0].length);
|
|
20
|
+
} else {
|
|
21
|
+
splitIndex = resolved.indexOf("//");
|
|
22
|
+
}
|
|
23
|
+
let repoUrl = resolved;
|
|
24
|
+
let subPath = "";
|
|
25
|
+
if (splitIndex !== -1) {
|
|
26
|
+
repoUrl = resolved.substring(0, splitIndex);
|
|
27
|
+
subPath = resolved.substring(splitIndex + 2);
|
|
28
|
+
}
|
|
29
|
+
const isLocal = repoUrl.startsWith("/") || repoUrl.startsWith("./") || repoUrl.startsWith("../") || repoUrl.startsWith("file:") || repoUrl.startsWith("~");
|
|
30
|
+
if (!isLocal && !repoUrl.endsWith(".git")) {
|
|
31
|
+
repoUrl += ".git";
|
|
32
|
+
}
|
|
33
|
+
if (subPath) {
|
|
34
|
+
return `${repoUrl}//${subPath}`;
|
|
35
|
+
}
|
|
36
|
+
return repoUrl;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export {
|
|
40
|
+
resolveGitUrl
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=chunk-JYASTIIW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/url-resolver.ts"],"sourcesContent":["/**\n * Resolves a git URL from various shorthand formats.\n * \n * Supported formats:\n * - gh@org/repo -> https://github.com/org/repo.git\n * - gh@org/repo//path -> https://github.com/org/repo.git//path\n * - https://github.com/org/repo -> https://github.com/org/repo.git\n * - https://github.com/org/repo.git -> https://github.com/org/repo.git\n * \n * @param url The URL string to resolve\n * @returns The fully qualified git URL with .git extension\n */\nexport function resolveGitUrl(url: string): string {\n if (!url) {\n throw new Error('URL cannot be empty');\n }\n\n let resolved = url;\n\n // Handle gh@ syntax\n if (resolved.startsWith('gh@')) {\n resolved = resolved.replace(/^gh@/, 'https://github.com/');\n }\n\n // Handle subpaths (split by //)\n // We must be careful not to split the protocol (e.g. https://)\n const protocolMatch = resolved.match(/^[a-z0-9]+:\\/\\//i);\n let splitIndex = -1;\n\n if (protocolMatch) {\n splitIndex = resolved.indexOf('//', protocolMatch[0].length);\n } else {\n splitIndex = resolved.indexOf('//');\n }\n\n let repoUrl = resolved;\n let subPath = '';\n\n if (splitIndex !== -1) {\n repoUrl = resolved.substring(0, splitIndex);\n subPath = resolved.substring(splitIndex + 2);\n }\n\n // Ensure .git extension, but ONLY for remote URLs (not local paths)\n const isLocal = repoUrl.startsWith('/') || repoUrl.startsWith('./') || repoUrl.startsWith('../') || repoUrl.startsWith('file:') || repoUrl.startsWith('~');\n\n if (!isLocal && !repoUrl.endsWith('.git')) {\n repoUrl += '.git';\n }\n\n // Reconstruction\n if (subPath) {\n return `${repoUrl}//${subPath}`;\n }\n\n return repoUrl;\n}\n"],"mappings":";;;;;;AAAA;AAYO,SAAS,cAAc,KAAqB;AAC/C,MAAI,CAAC,KAAK;AACN,UAAM,IAAI,MAAM,qBAAqB;AAAA,EACzC;AAEA,MAAI,WAAW;AAGf,MAAI,SAAS,WAAW,KAAK,GAAG;AAC5B,eAAW,SAAS,QAAQ,QAAQ,qBAAqB;AAAA,EAC7D;AAIA,QAAM,gBAAgB,SAAS,MAAM,kBAAkB;AACvD,MAAI,aAAa;AAEjB,MAAI,eAAe;AACf,iBAAa,SAAS,QAAQ,MAAM,cAAc,CAAC,EAAE,MAAM;AAAA,EAC/D,OAAO;AACH,iBAAa,SAAS,QAAQ,IAAI;AAAA,EACtC;AAEA,MAAI,UAAU;AACd,MAAI,UAAU;AAEd,MAAI,eAAe,IAAI;AACnB,cAAU,SAAS,UAAU,GAAG,UAAU;AAC1C,cAAU,SAAS,UAAU,aAAa,CAAC;AAAA,EAC/C;AAGA,QAAM,UAAU,QAAQ,WAAW,GAAG,KAAK,QAAQ,WAAW,IAAI,KAAK,QAAQ,WAAW,KAAK,KAAK,QAAQ,WAAW,OAAO,KAAK,QAAQ,WAAW,GAAG;AAEzJ,MAAI,CAAC,WAAW,CAAC,QAAQ,SAAS,MAAM,GAAG;AACvC,eAAW;AAAA,EACf;AAGA,MAAI,SAAS;AACT,WAAO,GAAG,OAAO,KAAK,OAAO;AAAA,EACjC;AAEA,SAAO;AACX;","names":[]}
|