@aligent/create-workspace 0.0.1
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 +142 -0
- package/bin/index.d.ts +2 -0
- package/bin/index.js +129 -0
- package/bin/lib/helpers.d.ts +19 -0
- package/bin/lib/helpers.js +94 -0
- package/package.json +25 -0
package/README.md
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# @aligent/create-workspace
|
|
2
|
+
|
|
3
|
+
A command-line tool for creating new Nx workspaces with opinionated presets and configurations. This tool wraps `create-nx-workspace` and provides a streamlined experience for initializing Aligent microservice projects.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Interactive prompts for workspace configuration
|
|
8
|
+
- Support for custom Nx presets (e.g., `@aligent/nx-cdk`)
|
|
9
|
+
- Automatic workspace cleanup (removes unnecessary files)
|
|
10
|
+
- Built-in validation for workspace names and presets
|
|
11
|
+
|
|
12
|
+
## Prerequisites
|
|
13
|
+
|
|
14
|
+
- **Node.js**: v16.9 or higher (LTS recommended)
|
|
15
|
+
- **Corepack**: Must be enabled on your system
|
|
16
|
+
|
|
17
|
+
### Enable Corepack
|
|
18
|
+
|
|
19
|
+
Corepack is included with Node.js 16.9+ but needs to be enabled:
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
corepack enable
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
For more information, visit the [official Corepack documentation](https://nodejs.org/api/corepack.html).
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
### Using npx (Recommended)
|
|
30
|
+
|
|
31
|
+
Run the tool directly without installation:
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
npx @aligent/create-workspace
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Global Installation
|
|
38
|
+
|
|
39
|
+
Install globally for repeated use:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
npm install -g @aligent/create-workspace
|
|
43
|
+
create-workspace
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Interactive Mode
|
|
47
|
+
|
|
48
|
+
Simply run the command and follow the prompts:
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
npx @aligent/create-workspace
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
You'll be asked to provide:
|
|
55
|
+
1. **Preset**: The Nx preset to use (e.g., `@aligent/nx-cdk`)
|
|
56
|
+
2. **Workspace name**: Must contain only lowercase letters, numbers, and hyphens
|
|
57
|
+
|
|
58
|
+
### CLI Arguments
|
|
59
|
+
|
|
60
|
+
Skip the interactive prompts by providing arguments:
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
npx @aligent/create-workspace --preset @aligent/nx-cdk --name my-workspace
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
#### Available Options
|
|
67
|
+
|
|
68
|
+
| Option | Type | Description | Example |
|
|
69
|
+
|--------|------|-------------|---------|
|
|
70
|
+
| `--preset` | string | The Nx preset to use (supports version pinning) | `@aligent/nx-cdk@1.0.0` |
|
|
71
|
+
| `--name` | string | The workspace name (lowercase, alphanumeric, hyphens only) | `my-app` |
|
|
72
|
+
| `--debug` | boolean | Keep failed workspace directory for debugging | `--debug` |
|
|
73
|
+
| `--version` | - | Show version number | - |
|
|
74
|
+
| `--help` | - | Show help | - |
|
|
75
|
+
|
|
76
|
+
### Examples
|
|
77
|
+
|
|
78
|
+
Create a workspace with the default CDK preset:
|
|
79
|
+
|
|
80
|
+
```sh
|
|
81
|
+
npx @aligent/create-workspace --preset @aligent/nx-cdk --name my-cdk-app
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Create a workspace with a specific preset version:
|
|
85
|
+
|
|
86
|
+
```sh
|
|
87
|
+
npx @aligent/create-workspace --preset @aligent/nx-cdk@1.2.3 --name my-app
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## What Happens During Creation
|
|
91
|
+
|
|
92
|
+
1. Validates prerequisites (Corepack availability)
|
|
93
|
+
2. Collects workspace configuration (preset and name)
|
|
94
|
+
3. Creates Nx workspace using the specified preset
|
|
95
|
+
4. Cleans up unnecessary files:
|
|
96
|
+
- `package-lock.json` (in favor of Yarn)
|
|
97
|
+
- `.nx` cache directory
|
|
98
|
+
- `.vscode` settings
|
|
99
|
+
- `node_modules` (to be reinstalled with Yarn)
|
|
100
|
+
5. Displays next steps for getting started
|
|
101
|
+
|
|
102
|
+
## Next Steps After Creation
|
|
103
|
+
|
|
104
|
+
After successful workspace creation, follow these steps:
|
|
105
|
+
|
|
106
|
+
```sh
|
|
107
|
+
# Navigate to your workspace
|
|
108
|
+
cd your-workspace-name
|
|
109
|
+
|
|
110
|
+
# Activate the Node.js version
|
|
111
|
+
nvm use
|
|
112
|
+
|
|
113
|
+
# Install dependencies
|
|
114
|
+
yarn install
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Development
|
|
118
|
+
|
|
119
|
+
This package is written in TypeScript and built using Nx.
|
|
120
|
+
|
|
121
|
+
### Build
|
|
122
|
+
|
|
123
|
+
```sh
|
|
124
|
+
npm install
|
|
125
|
+
npm run build
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Testing & Linting
|
|
129
|
+
|
|
130
|
+
Run tests, linting, and type-checking:
|
|
131
|
+
|
|
132
|
+
```sh
|
|
133
|
+
npm run test
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## License
|
|
137
|
+
|
|
138
|
+
MIT
|
|
139
|
+
|
|
140
|
+
## Repository
|
|
141
|
+
|
|
142
|
+
[microservice-development-utilities](https://github.com/aligent/microservice-development-utilities)
|
package/bin/index.d.ts
ADDED
package/bin/index.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const devkit_1 = require("@nx/devkit");
|
|
8
|
+
const create_nx_workspace_1 = require("create-nx-workspace");
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const prompts_1 = __importDefault(require("prompts"));
|
|
12
|
+
const yargs_1 = __importDefault(require("yargs"));
|
|
13
|
+
const helpers_1 = require("./lib/helpers");
|
|
14
|
+
const PACKAGE_MANAGER = 'npm';
|
|
15
|
+
const ITEMS_TO_REMOVE = ['package-lock.json', '.nx', '.vscode', 'node_modules'];
|
|
16
|
+
async function main() {
|
|
17
|
+
// Handle Ctrl+C gracefully
|
|
18
|
+
process.on('SIGINT', helpers_1.handleCancellation);
|
|
19
|
+
const corepackAvailable = (0, helpers_1.isCommandAvailable)('corepack');
|
|
20
|
+
if (!corepackAvailable) {
|
|
21
|
+
(0, helpers_1.showCorepackInstructions)();
|
|
22
|
+
(0, helpers_1.logErrorThenExit)('Corepack is not available on your system');
|
|
23
|
+
}
|
|
24
|
+
const commandIndex = process.argv.findIndex(text => text.includes('create-workspace'));
|
|
25
|
+
const args = await (0, yargs_1.default)(process.argv.slice(commandIndex + 1))
|
|
26
|
+
.options({
|
|
27
|
+
preset: {
|
|
28
|
+
type: 'string',
|
|
29
|
+
demandOption: false,
|
|
30
|
+
description: 'The preset to use (e.g., @aligent/nx-cdk)',
|
|
31
|
+
},
|
|
32
|
+
name: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
demandOption: false,
|
|
35
|
+
description: 'The workspace name',
|
|
36
|
+
},
|
|
37
|
+
debug: {
|
|
38
|
+
type: 'boolean',
|
|
39
|
+
demandOption: false,
|
|
40
|
+
default: false,
|
|
41
|
+
},
|
|
42
|
+
})
|
|
43
|
+
.usage('Usage: $0 --preset [preset] --name [name]')
|
|
44
|
+
.example('$0 --preset @aligent/nx-cdk --name my-app', '')
|
|
45
|
+
.showHelpOnFail(false, 'Specify --help for available options')
|
|
46
|
+
.version()
|
|
47
|
+
.parse();
|
|
48
|
+
const responses = await (0, prompts_1.default)([
|
|
49
|
+
{
|
|
50
|
+
type: args.preset ? null : 'text',
|
|
51
|
+
name: 'preset',
|
|
52
|
+
message: 'Which preset would you like to use?',
|
|
53
|
+
initial: '@aligent/nx-cdk',
|
|
54
|
+
validate: (value) => value.length > 0 || 'Preset is required (e.g., @aligent/nx-cdk)',
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
type: args.name ? null : 'text',
|
|
58
|
+
name: 'name',
|
|
59
|
+
message: 'What is your workspace name?',
|
|
60
|
+
validate: (value) => {
|
|
61
|
+
if (value.length === 0)
|
|
62
|
+
return 'Workspace name is required';
|
|
63
|
+
if (!/^[a-z0-9-]+$/.test(value))
|
|
64
|
+
return 'Workspace name must contain only lowercase letters, numbers, and hyphens';
|
|
65
|
+
return true;
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
], { onCancel: helpers_1.handleCancellation });
|
|
69
|
+
const preset = args.preset || responses.preset;
|
|
70
|
+
const name = args.name || responses.name;
|
|
71
|
+
if (!preset || !name) {
|
|
72
|
+
(0, helpers_1.logErrorThenExit)('Missing required information');
|
|
73
|
+
}
|
|
74
|
+
const targetDir = path_1.default.join(process.cwd(), name);
|
|
75
|
+
if (fs_1.default.existsSync(targetDir)) {
|
|
76
|
+
(0, helpers_1.logErrorThenExit)(`Directory "${name}" already exists in the current location`, 'Please choose a different name or remove the existing directory.');
|
|
77
|
+
}
|
|
78
|
+
const { presetName, version } = (0, helpers_1.parsePreset)(preset);
|
|
79
|
+
if (!version) {
|
|
80
|
+
(0, helpers_1.logErrorThenExit)('Malfunction required preset');
|
|
81
|
+
}
|
|
82
|
+
const presetWithVersion = `${presetName}@${version}`;
|
|
83
|
+
devkit_1.logger.info('\n📋 Configuration:');
|
|
84
|
+
devkit_1.logger.info(` Workspace name: ${name}`);
|
|
85
|
+
devkit_1.logger.info(` Preset: ${presetWithVersion}`);
|
|
86
|
+
devkit_1.logger.info(` Target directory: ${targetDir}`);
|
|
87
|
+
devkit_1.logger.info('');
|
|
88
|
+
const { confirmed } = await (0, prompts_1.default)({
|
|
89
|
+
type: 'confirm',
|
|
90
|
+
name: 'confirmed',
|
|
91
|
+
message: 'Create workspace with these settings?',
|
|
92
|
+
initial: true,
|
|
93
|
+
}, { onCancel: helpers_1.handleCancellation });
|
|
94
|
+
if (!confirmed) {
|
|
95
|
+
(0, helpers_1.handleCancellation)();
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
const { directory } = await (0, create_nx_workspace_1.createWorkspace)(presetWithVersion, {
|
|
99
|
+
name,
|
|
100
|
+
nxCloud: 'skip',
|
|
101
|
+
packageManager: PACKAGE_MANAGER,
|
|
102
|
+
});
|
|
103
|
+
(0, helpers_1.cleanupWorkspace)(directory, ITEMS_TO_REMOVE);
|
|
104
|
+
// Show summary and next steps
|
|
105
|
+
devkit_1.logger.info('\n✨ Summary:');
|
|
106
|
+
devkit_1.logger.info(` Successfully created workspace "${name}"`);
|
|
107
|
+
devkit_1.logger.info(` Using preset: ${presetWithVersion}`);
|
|
108
|
+
devkit_1.logger.info(` Location: ${directory}`);
|
|
109
|
+
devkit_1.logger.info('');
|
|
110
|
+
devkit_1.logger.info('📝 Next steps:');
|
|
111
|
+
devkit_1.logger.info(` 1. cd ${name}`);
|
|
112
|
+
devkit_1.logger.info(' Navigate to your new workspace directory');
|
|
113
|
+
devkit_1.logger.info('');
|
|
114
|
+
devkit_1.logger.info(' 2. nvm use');
|
|
115
|
+
devkit_1.logger.info(' Activate the Node.js version specified in .nvmrc');
|
|
116
|
+
devkit_1.logger.info('');
|
|
117
|
+
devkit_1.logger.info(' 3. yarn install');
|
|
118
|
+
devkit_1.logger.info(' Install all workspace dependencies');
|
|
119
|
+
devkit_1.logger.info('');
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
devkit_1.logger.error('Failed to create workspace');
|
|
123
|
+
const dirPath = path_1.default.join(process.cwd(), name);
|
|
124
|
+
await (0, helpers_1.failedWorkspaceCleanup)(dirPath, args.debug);
|
|
125
|
+
devkit_1.logger.error('Error details:');
|
|
126
|
+
(0, helpers_1.logErrorThenExit)(err);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
main();
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts package name and version from a preset string
|
|
3
|
+
*/
|
|
4
|
+
export declare function parsePreset(preset: string): {
|
|
5
|
+
presetName: string | undefined;
|
|
6
|
+
version: string;
|
|
7
|
+
} | {
|
|
8
|
+
presetName: string;
|
|
9
|
+
version?: never;
|
|
10
|
+
};
|
|
11
|
+
export declare function isCommandAvailable(command: string): boolean;
|
|
12
|
+
export declare function showCorepackInstructions(): void;
|
|
13
|
+
/**
|
|
14
|
+
* Handle graceful exit on user cancellation
|
|
15
|
+
*/
|
|
16
|
+
export declare function handleCancellation(): never;
|
|
17
|
+
export declare function logErrorThenExit(error: unknown, suggestion?: string): never;
|
|
18
|
+
export declare function cleanupWorkspace(directory: string, items: string[]): void;
|
|
19
|
+
export declare function failedWorkspaceCleanup(directory: string, debug: boolean): Promise<void>;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parsePreset = parsePreset;
|
|
7
|
+
exports.isCommandAvailable = isCommandAvailable;
|
|
8
|
+
exports.showCorepackInstructions = showCorepackInstructions;
|
|
9
|
+
exports.handleCancellation = handleCancellation;
|
|
10
|
+
exports.logErrorThenExit = logErrorThenExit;
|
|
11
|
+
exports.cleanupWorkspace = cleanupWorkspace;
|
|
12
|
+
exports.failedWorkspaceCleanup = failedWorkspaceCleanup;
|
|
13
|
+
const devkit_1 = require("@nx/devkit");
|
|
14
|
+
const child_process_1 = require("child_process");
|
|
15
|
+
const fs_1 = __importDefault(require("fs"));
|
|
16
|
+
const path_1 = __importDefault(require("path"));
|
|
17
|
+
/**
|
|
18
|
+
* Extracts package name and version from a preset string
|
|
19
|
+
*/
|
|
20
|
+
function parsePreset(preset) {
|
|
21
|
+
const defaultVersion = 'latest';
|
|
22
|
+
// Handle scoped packages: @scope/package@version or @scope/package
|
|
23
|
+
const scoped = preset.match(/^(@[^/]+\/[^@]+)(?:@(.+))?$/);
|
|
24
|
+
if (scoped) {
|
|
25
|
+
return { presetName: scoped[1], version: scoped[2] || defaultVersion };
|
|
26
|
+
}
|
|
27
|
+
// Handle regular packages: package@version or package
|
|
28
|
+
const regular = preset.match(/^([^@]+)(?:@(.+))?$/);
|
|
29
|
+
if (regular) {
|
|
30
|
+
return {
|
|
31
|
+
presetName: regular[1],
|
|
32
|
+
version: regular[2] || defaultVersion,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
return { presetName: preset };
|
|
36
|
+
}
|
|
37
|
+
function isCommandAvailable(command) {
|
|
38
|
+
try {
|
|
39
|
+
(0, child_process_1.execSync)(`${command} --version`, { stdio: 'ignore' });
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function showCorepackInstructions() {
|
|
47
|
+
devkit_1.logger.info('\n');
|
|
48
|
+
devkit_1.logger.info('This tool requires Yarn via Corepack.\n');
|
|
49
|
+
devkit_1.logger.info('To enable corepack, run: corepack enable');
|
|
50
|
+
devkit_1.logger.info('\n');
|
|
51
|
+
devkit_1.logger.info('If corepack is not installed, you need Node.js 16.9+ or higher.');
|
|
52
|
+
devkit_1.logger.info('Corepack is included with Node.js but may need to be enabled.\n');
|
|
53
|
+
devkit_1.logger.info('For more information, visit:');
|
|
54
|
+
devkit_1.logger.info(' https://nodejs.org/api/corepack.html\n');
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Handle graceful exit on user cancellation
|
|
58
|
+
*/
|
|
59
|
+
function handleCancellation() {
|
|
60
|
+
devkit_1.logger.warn('\nWorkspace creation cancelled\n');
|
|
61
|
+
process.exit(0);
|
|
62
|
+
}
|
|
63
|
+
function logErrorThenExit(error, suggestion) {
|
|
64
|
+
devkit_1.logger.info('\n');
|
|
65
|
+
devkit_1.logger.error(error);
|
|
66
|
+
if (suggestion)
|
|
67
|
+
devkit_1.logger.info(suggestion);
|
|
68
|
+
devkit_1.logger.info('\n');
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
function cleanupWorkspace(directory, items) {
|
|
72
|
+
for (const item of items) {
|
|
73
|
+
const itemPath = path_1.default.join(directory, item);
|
|
74
|
+
if (fs_1.default.existsSync(itemPath)) {
|
|
75
|
+
try {
|
|
76
|
+
fs_1.default.rmSync(itemPath, { recursive: true, force: true });
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
devkit_1.logger.warn(`Failed to remove ${item}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async function failedWorkspaceCleanup(directory, debug) {
|
|
85
|
+
if (!debug && fs_1.default.existsSync(directory)) {
|
|
86
|
+
try {
|
|
87
|
+
fs_1.default.rmSync(directory, { recursive: true, force: true });
|
|
88
|
+
devkit_1.logger.info('Cleaned up incomplete workspace');
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
devkit_1.logger.warn('Failed to clean up directory. You may need to remove it manually.');
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aligent/create-workspace",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "A command line tool for creating new workspace",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"main": "./bin/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"create-workspace": "./bin/index.js"
|
|
9
|
+
},
|
|
10
|
+
"typings": "./bin/index.d.ts",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/aligent/microservice-development-utilities.git",
|
|
14
|
+
"directory": "packages/create-workspace"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@nx/devkit": "22.4.2",
|
|
18
|
+
"create-nx-workspace": "22.4.2",
|
|
19
|
+
"prompts": "^2.4.2",
|
|
20
|
+
"yargs": "^18.0.0"
|
|
21
|
+
},
|
|
22
|
+
"author": "Aligent",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"types": "./bin/index.d.ts"
|
|
25
|
+
}
|