@jakubmazanec/carson 0.1.0-11dd4a3
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/LICENSE.md +661 -0
- package/README.md +237 -0
- package/bin/carson.js +3 -0
- package/dist/commands/create-project/CreateProject.d.ts +8 -0
- package/dist/commands/create-project/CreateProject.js +138 -0
- package/dist/commands/create-project/CreateProject.js.map +1 -0
- package/dist/commands/create-project/CreateProjectInput.d.ts +20 -0
- package/dist/commands/create-project/CreateProjectInput.js +31 -0
- package/dist/commands/create-project/CreateProjectInput.js.map +1 -0
- package/dist/commands/create-project/createProjectCommand.d.ts +12 -0
- package/dist/commands/create-project/createProjectCommand.js +31 -0
- package/dist/commands/create-project/createProjectCommand.js.map +1 -0
- package/dist/commands/create-project/runCreateProject.d.ts +13 -0
- package/dist/commands/create-project/runCreateProject.js +34 -0
- package/dist/commands/create-project/runCreateProject.js.map +1 -0
- package/dist/commands/create-project.d.ts +4 -0
- package/dist/commands/create-project.js +6 -0
- package/dist/commands/create-project.js.map +1 -0
- package/dist/commands/create-workspace/CreateWorkspace.d.ts +7 -0
- package/dist/commands/create-workspace/CreateWorkspace.js +102 -0
- package/dist/commands/create-workspace/CreateWorkspace.js.map +1 -0
- package/dist/commands/create-workspace/CreateWorkspaceInput.d.ts +11 -0
- package/dist/commands/create-workspace/CreateWorkspaceInput.js +17 -0
- package/dist/commands/create-workspace/CreateWorkspaceInput.js.map +1 -0
- package/dist/commands/create-workspace/createWorkspaceCommand.d.ts +9 -0
- package/dist/commands/create-workspace/createWorkspaceCommand.js +30 -0
- package/dist/commands/create-workspace/createWorkspaceCommand.js.map +1 -0
- package/dist/commands/create-workspace/runCreateWorkspace.d.ts +10 -0
- package/dist/commands/create-workspace/runCreateWorkspace.js +33 -0
- package/dist/commands/create-workspace/runCreateWorkspace.js.map +1 -0
- package/dist/commands/create-workspace.d.ts +4 -0
- package/dist/commands/create-workspace.js +6 -0
- package/dist/commands/create-workspace.js.map +1 -0
- package/dist/commands/internals/packageNameToDirectory.d.ts +1 -0
- package/dist/commands/internals/packageNameToDirectory.js +12 -0
- package/dist/commands/internals/packageNameToDirectory.js.map +1 -0
- package/dist/commands/internals.d.ts +1 -0
- package/dist/commands/internals.js +3 -0
- package/dist/commands/internals.js.map +1 -0
- package/dist/commands/update-workspace/UpdateWorkspace.d.ts +8 -0
- package/dist/commands/update-workspace/UpdateWorkspace.js +71 -0
- package/dist/commands/update-workspace/UpdateWorkspace.js.map +1 -0
- package/dist/commands/update-workspace/runUpdateWorkspace.d.ts +10 -0
- package/dist/commands/update-workspace/runUpdateWorkspace.js +25 -0
- package/dist/commands/update-workspace/runUpdateWorkspace.js.map +1 -0
- package/dist/commands/update-workspace/updateWorkspaceCommand.d.ts +6 -0
- package/dist/commands/update-workspace/updateWorkspaceCommand.js +25 -0
- package/dist/commands/update-workspace/updateWorkspaceCommand.js.map +1 -0
- package/dist/commands/update-workspace.d.ts +3 -0
- package/dist/commands/update-workspace.js +5 -0
- package/dist/commands/update-workspace.js.map +1 -0
- package/dist/commands.d.ts +3 -0
- package/dist/commands.js +5 -0
- package/dist/commands.js.map +1 -0
- package/dist/constants.d.ts +7 -0
- package/dist/constants.js +16 -0
- package/dist/constants.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.js +5 -0
- package/dist/main.js.map +1 -0
- package/dist/modules.d.js +2 -0
- package/dist/modules.d.js.map +1 -0
- package/dist/run.d.ts +1 -0
- package/dist/run.js +18 -0
- package/dist/run.js.map +1 -0
- package/dist/template/CarsonTemplate.d.ts +9 -0
- package/dist/template/CarsonTemplate.js +3 -0
- package/dist/template/CarsonTemplate.js.map +1 -0
- package/dist/template/CarsonTemplateConfig.d.ts +12 -0
- package/dist/template/CarsonTemplateConfig.js +7 -0
- package/dist/template/CarsonTemplateConfig.js.map +1 -0
- package/dist/template/TemplateAttributes.d.ts +9 -0
- package/dist/template/TemplateAttributes.js +16 -0
- package/dist/template/TemplateAttributes.js.map +1 -0
- package/dist/template/TemplateData.d.ts +35 -0
- package/dist/template/TemplateData.js +13 -0
- package/dist/template/TemplateData.js.map +1 -0
- package/dist/template/TemplateRender.d.ts +4 -0
- package/dist/template/TemplateRender.js +3 -0
- package/dist/template/TemplateRender.js.map +1 -0
- package/dist/template/TemplateRenderSnapshot.d.ts +27 -0
- package/dist/template/TemplateRenderSnapshot.js +11 -0
- package/dist/template/TemplateRenderSnapshot.js.map +1 -0
- package/dist/template/TemplateRenderSnapshots.d.ts +27 -0
- package/dist/template/TemplateRenderSnapshots.js +4 -0
- package/dist/template/TemplateRenderSnapshots.js.map +1 -0
- package/dist/template/TemplateRenders.d.ts +2 -0
- package/dist/template/TemplateRenders.js +3 -0
- package/dist/template/TemplateRenders.js.map +1 -0
- package/dist/template/applyTemplateRenders.d.ts +8 -0
- package/dist/template/applyTemplateRenders.js +60 -0
- package/dist/template/applyTemplateRenders.js.map +1 -0
- package/dist/template/createFileUsingTemplateRender.d.ts +2 -0
- package/dist/template/createFileUsingTemplateRender.js +12 -0
- package/dist/template/createFileUsingTemplateRender.js.map +1 -0
- package/dist/template/deleteFileUsingTemplateRender.d.ts +2 -0
- package/dist/template/deleteFileUsingTemplateRender.js +10 -0
- package/dist/template/deleteFileUsingTemplateRender.js.map +1 -0
- package/dist/template/importCarsonTemplate.d.ts +3 -0
- package/dist/template/importCarsonTemplate.js +8 -0
- package/dist/template/importCarsonTemplate.js.map +1 -0
- package/dist/template/insertUsingTemplateRender.d.ts +2 -0
- package/dist/template/insertUsingTemplateRender.js +29 -0
- package/dist/template/insertUsingTemplateRender.js.map +1 -0
- package/dist/template/internals/merge.d.ts +4 -0
- package/dist/template/internals/merge.js +30 -0
- package/dist/template/internals/merge.js.map +1 -0
- package/dist/template/internals/prettify.d.ts +1 -0
- package/dist/template/internals/prettify.js +25 -0
- package/dist/template/internals/prettify.js.map +1 -0
- package/dist/template/internals/unmerge.d.ts +4 -0
- package/dist/template/internals/unmerge.js +31 -0
- package/dist/template/internals/unmerge.js.map +1 -0
- package/dist/template/internals.d.ts +3 -0
- package/dist/template/internals.js +5 -0
- package/dist/template/internals.js.map +1 -0
- package/dist/template/loadTemplateRenderSnapshots.d.ts +7 -0
- package/dist/template/loadTemplateRenderSnapshots.js +14 -0
- package/dist/template/loadTemplateRenderSnapshots.js.map +1 -0
- package/dist/template/mergeFileUsingTemplateRender.d.ts +2 -0
- package/dist/template/mergeFileUsingTemplateRender.js +39 -0
- package/dist/template/mergeFileUsingTemplateRender.js.map +1 -0
- package/dist/template/overwriteFileUsingTemplateRender.d.ts +2 -0
- package/dist/template/overwriteFileUsingTemplateRender.js +12 -0
- package/dist/template/overwriteFileUsingTemplateRender.js.map +1 -0
- package/dist/template/parseTemplateId.d.ts +1 -0
- package/dist/template/parseTemplateId.js +12 -0
- package/dist/template/parseTemplateId.js.map +1 -0
- package/dist/template/readCarsonTemplate.d.ts +2 -0
- package/dist/template/readCarsonTemplate.js +39 -0
- package/dist/template/readCarsonTemplate.js.map +1 -0
- package/dist/template/renderTemplate.d.ts +7 -0
- package/dist/template/renderTemplate.js +19 -0
- package/dist/template/renderTemplate.js.map +1 -0
- package/dist/template/resolveTemplateModule.d.ts +1 -0
- package/dist/template/resolveTemplateModule.js +9 -0
- package/dist/template/resolveTemplateModule.js.map +1 -0
- package/dist/template/saveTemplateRenderSnapshots.d.ts +2 -0
- package/dist/template/saveTemplateRenderSnapshots.js +23 -0
- package/dist/template/saveTemplateRenderSnapshots.js.map +1 -0
- package/dist/template/uninsertUsingTemplateRender.d.ts +2 -0
- package/dist/template/uninsertUsingTemplateRender.js +29 -0
- package/dist/template/uninsertUsingTemplateRender.js.map +1 -0
- package/dist/template/unmergeFileUsingTemplateRender.d.ts +2 -0
- package/dist/template/unmergeFileUsingTemplateRender.js +39 -0
- package/dist/template/unmergeFileUsingTemplateRender.js.map +1 -0
- package/dist/template.d.ts +20 -0
- package/dist/template.js +22 -0
- package/dist/template.js.map +1 -0
- package/dist/workspace/Project.d.ts +33 -0
- package/dist/workspace/Project.js +184 -0
- package/dist/workspace/Project.js.map +1 -0
- package/dist/workspace/ProjectConfig.d.ts +9 -0
- package/dist/workspace/ProjectConfig.js +6 -0
- package/dist/workspace/ProjectConfig.js.map +1 -0
- package/dist/workspace/ProjectCreateOptions.d.ts +8 -0
- package/dist/workspace/ProjectCreateOptions.js +3 -0
- package/dist/workspace/ProjectCreateOptions.js.map +1 -0
- package/dist/workspace/ProjectError.d.ts +8 -0
- package/dist/workspace/ProjectError.js +11 -0
- package/dist/workspace/ProjectError.js.map +1 -0
- package/dist/workspace/ProjectOptions.d.ts +15 -0
- package/dist/workspace/ProjectOptions.js +3 -0
- package/dist/workspace/ProjectOptions.js.map +1 -0
- package/dist/workspace/ProjectUpdateOptions.d.ts +3 -0
- package/dist/workspace/ProjectUpdateOptions.js +3 -0
- package/dist/workspace/ProjectUpdateOptions.js.map +1 -0
- package/dist/workspace/Workspace.d.ts +68 -0
- package/dist/workspace/Workspace.js +426 -0
- package/dist/workspace/Workspace.js.map +1 -0
- package/dist/workspace/WorkspaceConfig.d.ts +9 -0
- package/dist/workspace/WorkspaceConfig.js +6 -0
- package/dist/workspace/WorkspaceConfig.js.map +1 -0
- package/dist/workspace/WorkspaceCreateOptions.d.ts +5 -0
- package/dist/workspace/WorkspaceCreateOptions.js +3 -0
- package/dist/workspace/WorkspaceCreateOptions.js.map +1 -0
- package/dist/workspace/WorkspaceCreateProjectOptions.d.ts +6 -0
- package/dist/workspace/WorkspaceCreateProjectOptions.js +3 -0
- package/dist/workspace/WorkspaceCreateProjectOptions.js.map +1 -0
- package/dist/workspace/WorkspaceDependencies.d.ts +30 -0
- package/dist/workspace/WorkspaceDependencies.js +126 -0
- package/dist/workspace/WorkspaceDependencies.js.map +1 -0
- package/dist/workspace/WorkspaceError.d.ts +8 -0
- package/dist/workspace/WorkspaceError.js +13 -0
- package/dist/workspace/WorkspaceError.js.map +1 -0
- package/dist/workspace/WorkspaceOptions.d.ts +25 -0
- package/dist/workspace/WorkspaceOptions.js +3 -0
- package/dist/workspace/WorkspaceOptions.js.map +1 -0
- package/dist/workspace/WorkspaceOptionsProjectOptions.d.ts +7 -0
- package/dist/workspace/WorkspaceOptionsProjectOptions.js +3 -0
- package/dist/workspace/WorkspaceOptionsProjectOptions.js.map +1 -0
- package/dist/workspace/WorkspacePackageJson.d.ts +2 -0
- package/dist/workspace/WorkspacePackageJson.js +3 -0
- package/dist/workspace/WorkspacePackageJson.js.map +1 -0
- package/dist/workspace/WorkspaceProjectGlobs.d.ts +1 -0
- package/dist/workspace/WorkspaceProjectGlobs.js +3 -0
- package/dist/workspace/WorkspaceProjectGlobs.js.map +1 -0
- package/dist/workspace/WorkspaceProjects.d.ts +2 -0
- package/dist/workspace/WorkspaceProjects.js +3 -0
- package/dist/workspace/WorkspaceProjects.js.map +1 -0
- package/dist/workspace/WorkspaceRepository.d.ts +4 -0
- package/dist/workspace/WorkspaceRepository.js +3 -0
- package/dist/workspace/WorkspaceRepository.js.map +1 -0
- package/dist/workspace/WorkspaceUpdateOptions.d.ts +3 -0
- package/dist/workspace/WorkspaceUpdateOptions.js +3 -0
- package/dist/workspace/WorkspaceUpdateOptions.js.map +1 -0
- package/dist/workspace/internals/compareSemver.d.ts +8 -0
- package/dist/workspace/internals/compareSemver.js +27 -0
- package/dist/workspace/internals/compareSemver.js.map +1 -0
- package/dist/workspace/internals/getPackageJsonWorkspaces.d.ts +2 -0
- package/dist/workspace/internals/getPackageJsonWorkspaces.js +11 -0
- package/dist/workspace/internals/getPackageJsonWorkspaces.js.map +1 -0
- package/dist/workspace/internals/getRepositoryBranches.d.ts +1 -0
- package/dist/workspace/internals/getRepositoryBranches.js +21 -0
- package/dist/workspace/internals/getRepositoryBranches.js.map +1 -0
- package/dist/workspace/internals/getRepositoryUrl.d.ts +1 -0
- package/dist/workspace/internals/getRepositoryUrl.js +21 -0
- package/dist/workspace/internals/getRepositoryUrl.js.map +1 -0
- package/dist/workspace/internals.d.ts +4 -0
- package/dist/workspace/internals.js +6 -0
- package/dist/workspace/internals.js.map +1 -0
- package/dist/workspace/saveProjectConfig.d.ts +6 -0
- package/dist/workspace/saveProjectConfig.js +13 -0
- package/dist/workspace/saveProjectConfig.js.map +1 -0
- package/dist/workspace/saveWorkspaceConfig.d.ts +6 -0
- package/dist/workspace/saveWorkspaceConfig.js +13 -0
- package/dist/workspace/saveWorkspaceConfig.js.map +1 -0
- package/dist/workspace.d.ts +10 -0
- package/dist/workspace.js +12 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +84 -0
- package/src/commands/create-project/CreateProject.tsx +130 -0
- package/src/commands/create-project/CreateProjectInput.ts +37 -0
- package/src/commands/create-project/createProjectCommand.tsx +33 -0
- package/src/commands/create-project/runCreateProject.ts +59 -0
- package/src/commands/create-project.ts +4 -0
- package/src/commands/create-workspace/CreateWorkspace.tsx +90 -0
- package/src/commands/create-workspace/CreateWorkspaceInput.ts +21 -0
- package/src/commands/create-workspace/createWorkspaceCommand.tsx +34 -0
- package/src/commands/create-workspace/runCreateWorkspace.ts +49 -0
- package/src/commands/create-workspace.ts +4 -0
- package/src/commands/internals/packageNameToDirectory.ts +13 -0
- package/src/commands/internals.ts +1 -0
- package/src/commands/update-workspace/UpdateWorkspace.tsx +59 -0
- package/src/commands/update-workspace/runUpdateWorkspace.ts +36 -0
- package/src/commands/update-workspace/updateWorkspaceCommand.tsx +27 -0
- package/src/commands/update-workspace.ts +3 -0
- package/src/commands.ts +3 -0
- package/src/constants.ts +21 -0
- package/src/main.ts +3 -0
- package/src/modules.d.ts +1 -0
- package/src/run.ts +21 -0
- package/src/template/CarsonTemplate.ts +11 -0
- package/src/template/CarsonTemplateConfig.ts +12 -0
- package/src/template/TemplateAttributes.ts +16 -0
- package/src/template/TemplateData.ts +17 -0
- package/src/template/TemplateRender.ts +9 -0
- package/src/template/TemplateRenderSnapshot.ts +13 -0
- package/src/template/TemplateRenderSnapshots.ts +7 -0
- package/src/template/TemplateRenders.ts +3 -0
- package/src/template/applyTemplateRenders.ts +89 -0
- package/src/template/createFileUsingTemplateRender.ts +12 -0
- package/src/template/deleteFileUsingTemplateRender.ts +15 -0
- package/src/template/importCarsonTemplate.ts +13 -0
- package/src/template/insertUsingTemplateRender.ts +33 -0
- package/src/template/internals/merge.ts +44 -0
- package/src/template/internals/prettify.ts +24 -0
- package/src/template/internals/unmerge.ts +48 -0
- package/src/template/internals.ts +3 -0
- package/src/template/loadTemplateRenderSnapshots.ts +18 -0
- package/src/template/mergeFileUsingTemplateRender.ts +39 -0
- package/src/template/overwriteFileUsingTemplateRender.ts +12 -0
- package/src/template/parseTemplateId.ts +9 -0
- package/src/template/readCarsonTemplate.ts +46 -0
- package/src/template/renderTemplate.ts +30 -0
- package/src/template/resolveTemplateModule.ts +9 -0
- package/src/template/saveTemplateRenderSnapshots.ts +34 -0
- package/src/template/uninsertUsingTemplateRender.ts +36 -0
- package/src/template/unmergeFileUsingTemplateRender.ts +42 -0
- package/src/template.ts +20 -0
- package/src/workspace/Project.ts +246 -0
- package/src/workspace/ProjectConfig.ts +9 -0
- package/src/workspace/ProjectCreateOptions.ts +9 -0
- package/src/workspace/ProjectError.ts +15 -0
- package/src/workspace/ProjectOptions.ts +17 -0
- package/src/workspace/ProjectUpdateOptions.ts +3 -0
- package/src/workspace/Workspace.ts +553 -0
- package/src/workspace/WorkspaceConfig.ts +9 -0
- package/src/workspace/WorkspaceCreateOptions.ts +5 -0
- package/src/workspace/WorkspaceCreateProjectOptions.ts +6 -0
- package/src/workspace/WorkspaceDependencies.ts +196 -0
- package/src/workspace/WorkspaceError.ts +18 -0
- package/src/workspace/WorkspaceOptions.ts +29 -0
- package/src/workspace/WorkspaceOptionsProjectOptions.ts +9 -0
- package/src/workspace/WorkspacePackageJson.ts +3 -0
- package/src/workspace/WorkspaceProjectGlobs.ts +1 -0
- package/src/workspace/WorkspaceProjects.ts +3 -0
- package/src/workspace/WorkspaceRepository.ts +4 -0
- package/src/workspace/WorkspaceUpdateOptions.ts +3 -0
- package/src/workspace/internals/compareSemver.ts +35 -0
- package/src/workspace/internals/getPackageJsonWorkspaces.ts +11 -0
- package/src/workspace/internals/getRepositoryBranches.ts +25 -0
- package/src/workspace/internals/getRepositoryUrl.ts +23 -0
- package/src/workspace/internals.ts +4 -0
- package/src/workspace/saveProjectConfig.ts +23 -0
- package/src/workspace/saveWorkspaceConfig.ts +30 -0
- package/src/workspace.ts +10 -0
package/README.md
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# @jakubmazanec/carson
|
|
4
|
+
|
|
5
|
+
<!-- description -->Tool for managing workspace and project configuration.<!-- description -->
|
|
6
|
+
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install @jakubmazanec/carson -g
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
⚠️ This is an [ESM](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c) package!
|
|
16
|
+
It cannot be required from a CommonJS module.
|
|
17
|
+
|
|
18
|
+
#### Prerequisites
|
|
19
|
+
|
|
20
|
+
- Node.js 16 or later
|
|
21
|
+
|
|
22
|
+
## Usage
|
|
23
|
+
|
|
24
|
+
Software development is constantly evolving and best practices often change. If you want to migrate
|
|
25
|
+
to a new tool, or merely update some settings, it can be time-consuming to do it in multiple
|
|
26
|
+
repositories. Instead, Carson lets you write and use a template that defines what files should exist
|
|
27
|
+
and what content should they have. Instead of updating files in your repositories manually, you
|
|
28
|
+
change only the template and Carson handles the updates automatically for you, and keeps every
|
|
29
|
+
repository in sync. With a template, creating new projects is also super fast and simple.
|
|
30
|
+
|
|
31
|
+
### Quick overview
|
|
32
|
+
|
|
33
|
+
Update workspace:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
npx carson update workspace
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Create a new project in an existing workspace:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
npx carson create project
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
See [CLI documentation](#cli) for the complete overview.
|
|
46
|
+
|
|
47
|
+
### How it works
|
|
48
|
+
|
|
49
|
+
Carson assumes your codebase is organized in a workspace, which is simply a directory, and also
|
|
50
|
+
usually a git repository, that contains one or multiple projects. A project is a self-contained
|
|
51
|
+
piece of code, e.g. a package, or an app.
|
|
52
|
+
|
|
53
|
+
> ⚠️ Currently only Node.js projects are supported.
|
|
54
|
+
|
|
55
|
+
Take a look at this simplified example of a workspace:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
workspace/
|
|
59
|
+
├── .carson/
|
|
60
|
+
│ ├── .snapshots
|
|
61
|
+
│ └── workspace.json
|
|
62
|
+
├── packages/
|
|
63
|
+
│ ├── foo/
|
|
64
|
+
│ │ ├── .carson/
|
|
65
|
+
│ │ │ ├── .snapshots
|
|
66
|
+
│ │ │ └── project.json
|
|
67
|
+
│ │ ├── src/
|
|
68
|
+
│ │ │ └── main.js
|
|
69
|
+
│ │ └── package.json
|
|
70
|
+
│ └── bar/
|
|
71
|
+
│ ├── .carson/
|
|
72
|
+
│ │ ├── .snapshots
|
|
73
|
+
│ │ └── project.json
|
|
74
|
+
│ ├── src/
|
|
75
|
+
│ │ └── main.js
|
|
76
|
+
│ └── package.json
|
|
77
|
+
└── package.json
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Notice that the workspace and each of the two packages in it (`foo` and `bar`) have a directory
|
|
81
|
+
named `.carson` with 2 files:
|
|
82
|
+
|
|
83
|
+
1. Configuration file, which specifies the ID of the Carson template that is used to define the
|
|
84
|
+
files (or just some parts of the files) in the workspace or the project.
|
|
85
|
+
2. Snapshots file with all the information necessary to revert any changes.
|
|
86
|
+
|
|
87
|
+
Let's say config files `workspace/packages/foo/.carson/project.json` and
|
|
88
|
+
`workspace/packages/bar/.carson/project.json` both contain this:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"template": "carson-templates:project"
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
That means they're using a Carson template named `project` from a package named `carson-templates`.
|
|
97
|
+
Carson template is just a directory containing `*.ejs` files parsed and rendered via
|
|
98
|
+
`@jakubmazanec/template` package; these files are actually [EJS](https://ejs.co/) templates with
|
|
99
|
+
YAML front matter. Please read [`@jakubmazanec/template` documentation](../template/README.md) to
|
|
100
|
+
find out in more detail how they work. Simply, they're for generating content using JavaScript as a
|
|
101
|
+
templating language.
|
|
102
|
+
|
|
103
|
+
> Yes, each "Carson template" is composed of multiple "EJS templates". Hopefully, the existence of
|
|
104
|
+
> these two different template "types" isn't very confusing.
|
|
105
|
+
|
|
106
|
+
Take a look at this simplified example of `carson-templates` with two templates named `workspace`
|
|
107
|
+
and `project`:
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
carson-templates@1.0.0
|
|
111
|
+
└── templates
|
|
112
|
+
├── project
|
|
113
|
+
│ └── package.json.ejs
|
|
114
|
+
└── workspace
|
|
115
|
+
└── package.json.ejs
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Because we're interested in the `project` template, let's see file
|
|
119
|
+
`carson-templates@1.0.0/templates/project/package.json.ejs`:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
---
|
|
123
|
+
to: 'package.json'
|
|
124
|
+
strategy: merge
|
|
125
|
+
---
|
|
126
|
+
{
|
|
127
|
+
"repository": {
|
|
128
|
+
"directory": "<%- project.relativePath %>"
|
|
129
|
+
},
|
|
130
|
+
"type": "module",
|
|
131
|
+
"exports": "./dist/main.js",
|
|
132
|
+
"files": [
|
|
133
|
+
"dist",
|
|
134
|
+
"src"
|
|
135
|
+
],
|
|
136
|
+
"scripts": {
|
|
137
|
+
"build": "swc src -d dist"
|
|
138
|
+
},
|
|
139
|
+
"devDependencies": {
|
|
140
|
+
"@swc/cli": "^0.1.62",
|
|
141
|
+
"@swc/core": "^1.3.56"
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
When Carson performs a workspace update, `carson-templates:project` template is rendered for each
|
|
147
|
+
project that uses it, and `foo`, and `bar` have their files changed accordingly. In this example
|
|
148
|
+
that means `foo/package.json` and `bar/package.json` are recursively merged with the JSONs obtained
|
|
149
|
+
from the EJS template above (so SWC is added to development dependencies, or field
|
|
150
|
+
`repository.directory` is set to always be the value of a variable `project.relativePath`, i.e.
|
|
151
|
+
`'packages/foo'` or `'packages/bar'`). Updating the workspace works the same way (although using a
|
|
152
|
+
different Carson template, e.g. `carson-templates:workspace`).
|
|
153
|
+
|
|
154
|
+
When you install a newer version of `carson-templates` that e.g. replaces SWC with another tool,
|
|
155
|
+
before Carson does fresh update, it first uses saved (and committed to git) snapshots from the
|
|
156
|
+
previous update to revert all its changes. This way you don't need to keep the previous version of
|
|
157
|
+
`carson-templates` around and the updates can be always done automatically from the current state of
|
|
158
|
+
the workspace.
|
|
159
|
+
|
|
160
|
+
The fact that EJS templates are just JavaScript means Carson can support almost any use case. For
|
|
161
|
+
that, there are also more Carson template features you need to learn than this example showcases:
|
|
162
|
+
mainly additional strategies (you can e.g. instead of merging simply overwrite the whole file, or
|
|
163
|
+
just create a file with some default content and then let the user change it freely) and what
|
|
164
|
+
variables with what information is available during EJS template rendering. Please read
|
|
165
|
+
[Carson templates documentation](#carson-templates) to find out in more detail how they work, or see
|
|
166
|
+
[`@jakubmazanec/carson-templates`](../template/README.md) for examples.
|
|
167
|
+
|
|
168
|
+
## Documentation
|
|
169
|
+
|
|
170
|
+
### API
|
|
171
|
+
|
|
172
|
+
See [API reference](./docs) for auto-generated documentation.
|
|
173
|
+
|
|
174
|
+
### Configuration
|
|
175
|
+
|
|
176
|
+
Carson configuration files are located in a directory named `.carson` directory. Files named
|
|
177
|
+
`workspace.json` and `project.json` are used to configure workspace and project respectively (in
|
|
178
|
+
case of single-project workspace they're both in the same `.carson` directory).
|
|
179
|
+
|
|
180
|
+
You can add arbitrary data to these JSONs in addition to the options described below. Because
|
|
181
|
+
workspace and project configurations are available as JavaScript variables during the rendering of
|
|
182
|
+
Carson templates, they can be used to store ad-hoc data or to allow custom, per-project
|
|
183
|
+
configuration.
|
|
184
|
+
|
|
185
|
+
#### `workspace.json`
|
|
186
|
+
|
|
187
|
+
| Option | Type | Description |
|
|
188
|
+
| -------- | ------ | ------------------ |
|
|
189
|
+
| template | string | Carson template ID |
|
|
190
|
+
|
|
191
|
+
#### `project.json`
|
|
192
|
+
|
|
193
|
+
| Option | Type | Description |
|
|
194
|
+
| -------- | ------ | ------------------ |
|
|
195
|
+
| template | string | Carson template ID |
|
|
196
|
+
|
|
197
|
+
### CLI
|
|
198
|
+
|
|
199
|
+
#### `update workspace [<options>]`
|
|
200
|
+
|
|
201
|
+
Updates workspace and all projects using the configured Carson templates.
|
|
202
|
+
|
|
203
|
+
| Option | Description |
|
|
204
|
+
| ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
205
|
+
| --path | Path to the workspace. A relative path is appended to the current working directory. The file system is traversed up to the root when looking for a workspace. |
|
|
206
|
+
|
|
207
|
+
#### `create project [<options>]`
|
|
208
|
+
|
|
209
|
+
Creates a new project in a workspace.
|
|
210
|
+
|
|
211
|
+
| Option | Description |
|
|
212
|
+
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
213
|
+
| --path | Path to the workspace in which the project should be created. A relative path is appended to the current working directory. The file system is traversed up to the root when looking for a workspace. |
|
|
214
|
+
| --template | ID of the Carson template used to create the project. |
|
|
215
|
+
| --name | Project name. |
|
|
216
|
+
|
|
217
|
+
#### `create workspace [<options>]`
|
|
218
|
+
|
|
219
|
+
Creates new workspace.
|
|
220
|
+
|
|
221
|
+
| Option | Description |
|
|
222
|
+
| ---------- | --------------------------------------------------------------------------------------------------------- |
|
|
223
|
+
| --path | Path where the workspace should be created. A relative path is appended to the current working directory. |
|
|
224
|
+
| --template | ID of the Carson template used to create the workspace. |
|
|
225
|
+
|
|
226
|
+
### Carson templates
|
|
227
|
+
|
|
228
|
+
🚧 This section is under development. Please check back later for updates.
|
|
229
|
+
|
|
230
|
+
## Contributing
|
|
231
|
+
|
|
232
|
+
If you want to contribute, see [CONTRIBUTING](./CONTRIBUTING.md) for details.
|
|
233
|
+
|
|
234
|
+
## License
|
|
235
|
+
|
|
236
|
+
This package is licensed under the GNU Affero General Public License v3. See [LICENSE](./LICENSE.md)
|
|
237
|
+
for details.
|
package/bin/carson.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type CommandArguments } from '@jakubmazanec/cli';
|
|
2
|
+
import { type createProjectCommand } from './createProjectCommand.js';
|
|
3
|
+
import { type Workspace } from '../../workspace.js';
|
|
4
|
+
export type CreateProjectProps = {
|
|
5
|
+
args: CommandArguments<typeof createProjectCommand>;
|
|
6
|
+
workspace: Workspace | Workspace<false>;
|
|
7
|
+
};
|
|
8
|
+
export declare function CreateProject({ args, workspace }: CreateProjectProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Header, icons, colors, useProgram } from '@jakubmazanec/cli';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { Box, Text } from 'ink';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { useEffect, useState } from 'react';
|
|
7
|
+
import { CreateProjectInput } from './CreateProjectInput.js';
|
|
8
|
+
import { runCreateProject } from './runCreateProject.js';
|
|
9
|
+
import { packageNameToDirectory } from '../internals.js';
|
|
10
|
+
const ONLY_ONE_STAR_REGEXP = /^(?!(.*?\*){2,}|.*? |\*$).*?\*.*$/;
|
|
11
|
+
export function CreateProject({ args , workspace }) {
|
|
12
|
+
let [status, setStatus] = useState('not-started');
|
|
13
|
+
let [subscription, setSubscription] = useState(null);
|
|
14
|
+
let [jobs, setJobs] = useState([]);
|
|
15
|
+
let [createProjectInputResult, setCreateProjectInputResult] = useState(()=>({
|
|
16
|
+
projectName: {
|
|
17
|
+
value: args.options.name ?? '',
|
|
18
|
+
isComplete: !!args.options.name
|
|
19
|
+
},
|
|
20
|
+
projectPath: {
|
|
21
|
+
value: '',
|
|
22
|
+
isComplete: false
|
|
23
|
+
},
|
|
24
|
+
templateId: {
|
|
25
|
+
value: args.options.template ?? '',
|
|
26
|
+
isComplete: !!args.options.template
|
|
27
|
+
}
|
|
28
|
+
}));
|
|
29
|
+
let { exit } = useProgram();
|
|
30
|
+
useEffect(()=>{
|
|
31
|
+
if (Object.entries(createProjectInputResult).every(([, result])=>result.isComplete)) {
|
|
32
|
+
setStatus('in-progress');
|
|
33
|
+
}
|
|
34
|
+
}, [
|
|
35
|
+
createProjectInputResult
|
|
36
|
+
]);
|
|
37
|
+
useEffect(()=>{
|
|
38
|
+
if (status === 'in-progress' && !subscription) {
|
|
39
|
+
let newSubscription = runCreateProject({
|
|
40
|
+
projectPath: createProjectInputResult.projectPath.value,
|
|
41
|
+
templateId: createProjectInputResult.templateId.value,
|
|
42
|
+
projectName: createProjectInputResult.projectName.value,
|
|
43
|
+
workspace,
|
|
44
|
+
args
|
|
45
|
+
}).subscribe({
|
|
46
|
+
next (value) {
|
|
47
|
+
setJobs((previousJobs)=>[
|
|
48
|
+
...previousJobs,
|
|
49
|
+
value
|
|
50
|
+
]);
|
|
51
|
+
},
|
|
52
|
+
error (error) {
|
|
53
|
+
exit(error);
|
|
54
|
+
},
|
|
55
|
+
complete () {
|
|
56
|
+
newSubscription.unsubscribe();
|
|
57
|
+
setStatus('finished');
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
setSubscription(newSubscription);
|
|
61
|
+
}
|
|
62
|
+
return ()=>{
|
|
63
|
+
if (subscription) {
|
|
64
|
+
subscription.unsubscribe();
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
}, [
|
|
68
|
+
args,
|
|
69
|
+
createProjectInputResult,
|
|
70
|
+
exit,
|
|
71
|
+
status,
|
|
72
|
+
subscription,
|
|
73
|
+
workspace
|
|
74
|
+
]);
|
|
75
|
+
let possiblePaths = [];
|
|
76
|
+
if (createProjectInputResult.projectName.value) {
|
|
77
|
+
let destinationDirectory = packageNameToDirectory(createProjectInputResult.projectName.value);
|
|
78
|
+
if (workspace.projectGlobs) {
|
|
79
|
+
possiblePaths = workspace.projectGlobs.filter((projectGlob)=>ONLY_ONE_STAR_REGEXP.test(projectGlob)).map((projectGlob)=>projectGlob.replace(/\*/, destinationDirectory)).map((projectGlob)=>path.join(workspace.path, projectGlob)).map((projectPath)=>({
|
|
80
|
+
value: projectPath,
|
|
81
|
+
label: path.relative(workspace.path, projectPath).replace('\\', '/')
|
|
82
|
+
}));
|
|
83
|
+
} else {
|
|
84
|
+
possiblePaths = [
|
|
85
|
+
{
|
|
86
|
+
value: workspace.path,
|
|
87
|
+
label: workspace.path
|
|
88
|
+
}
|
|
89
|
+
];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return /*#__PURE__*/ _jsxs(Box, {
|
|
93
|
+
flexDirection: "column",
|
|
94
|
+
children: [
|
|
95
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
96
|
+
color: colors.body,
|
|
97
|
+
children: `Creating project in the workspace at ${chalk[colors.info](workspace.path)}.`
|
|
98
|
+
}),
|
|
99
|
+
/*#__PURE__*/ _jsx(CreateProjectInput, {
|
|
100
|
+
rows: {
|
|
101
|
+
projectPath: {
|
|
102
|
+
choices: possiblePaths
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
values: createProjectInputResult,
|
|
106
|
+
marginTop: 1,
|
|
107
|
+
onChange: setCreateProjectInputResult,
|
|
108
|
+
onComplete: setCreateProjectInputResult
|
|
109
|
+
}),
|
|
110
|
+
status === 'in-progress' || status === 'finished' ? /*#__PURE__*/ _jsxs(Box, {
|
|
111
|
+
marginTop: 1,
|
|
112
|
+
flexDirection: "column",
|
|
113
|
+
children: [
|
|
114
|
+
/*#__PURE__*/ _jsx(Header, {
|
|
115
|
+
showSpinner: status === 'in-progress',
|
|
116
|
+
icon: icons.success,
|
|
117
|
+
marginBottom: 1,
|
|
118
|
+
children: /*#__PURE__*/ _jsx(Text, {
|
|
119
|
+
children: "Creating project..."
|
|
120
|
+
})
|
|
121
|
+
}),
|
|
122
|
+
jobs.map((job)=>/*#__PURE__*/ _jsx(Text, {
|
|
123
|
+
children: `${icons.info} ${job}`
|
|
124
|
+
}, job))
|
|
125
|
+
]
|
|
126
|
+
}) : null,
|
|
127
|
+
status === 'finished' ? /*#__PURE__*/ _jsx(Header, {
|
|
128
|
+
marginTop: 1,
|
|
129
|
+
icon: icons.success,
|
|
130
|
+
children: /*#__PURE__*/ _jsx(Text, {
|
|
131
|
+
children: "Done."
|
|
132
|
+
})
|
|
133
|
+
}) : null
|
|
134
|
+
]
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
//# sourceMappingURL=CreateProject.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/create-project/CreateProject.tsx"],"sourcesContent":["import {Header, icons, colors, type CommandArguments, useProgram} from '@jakubmazanec/cli';\nimport chalk from 'chalk';\nimport {Box, Text} from 'ink';\nimport path from 'node:path';\nimport {useEffect, useState} from 'react';\n\nimport {type createProjectCommand} from './createProjectCommand.js';\nimport {CreateProjectInput, type CreateProjectInputResult} from './CreateProjectInput.js';\nimport {runCreateProject} from './runCreateProject.js';\nimport {type Workspace} from '../../workspace.js';\nimport {packageNameToDirectory} from '../internals.js';\n\nconst ONLY_ONE_STAR_REGEXP = /^(?!(.*?\\*){2,}|.*? |\\*$).*?\\*.*$/;\n\nexport type CreateProjectProps = {\n args: CommandArguments<typeof createProjectCommand>;\n workspace: Workspace | Workspace<false>;\n};\n\nexport function CreateProject({args, workspace}: CreateProjectProps) {\n let [status, setStatus] = useState<'finished' | 'in-progress' | 'not-started'>('not-started');\n let [subscription, setSubscription] = useState<ZenObservable.Subscription | null>(null);\n let [jobs, setJobs] = useState<string[]>([]);\n let [createProjectInputResult, setCreateProjectInputResult] = useState<CreateProjectInputResult>(\n () => ({\n projectName: {value: args.options.name ?? '', isComplete: !!args.options.name},\n projectPath: {value: '', isComplete: false},\n templateId: {value: args.options.template ?? '', isComplete: !!args.options.template},\n }),\n );\n let {exit} = useProgram();\n\n useEffect(() => {\n if (Object.entries(createProjectInputResult).every(([, result]) => result.isComplete)) {\n setStatus('in-progress');\n }\n }, [createProjectInputResult]);\n\n useEffect(() => {\n if (status === 'in-progress' && !subscription) {\n let newSubscription = runCreateProject({\n projectPath: createProjectInputResult.projectPath.value,\n templateId: createProjectInputResult.templateId.value,\n projectName: createProjectInputResult.projectName.value,\n workspace,\n args,\n }).subscribe({\n next(value) {\n setJobs((previousJobs) => [...previousJobs, value]);\n },\n error(error) {\n exit(error);\n },\n complete() {\n newSubscription.unsubscribe();\n setStatus('finished');\n },\n });\n setSubscription(newSubscription);\n }\n\n return () => {\n if (subscription) {\n subscription.unsubscribe();\n }\n };\n }, [args, createProjectInputResult, exit, status, subscription, workspace]);\n\n let possiblePaths: Array<{value: string; label: string}> = [];\n\n if (createProjectInputResult.projectName.value) {\n let destinationDirectory = packageNameToDirectory(createProjectInputResult.projectName.value);\n\n if (workspace.projectGlobs) {\n possiblePaths = workspace.projectGlobs\n .filter((projectGlob) => ONLY_ONE_STAR_REGEXP.test(projectGlob))\n .map((projectGlob) => projectGlob.replace(/\\*/, destinationDirectory))\n .map((projectGlob) => path.join(workspace.path, projectGlob))\n .map((projectPath) => ({\n value: projectPath,\n label: path.relative(workspace.path, projectPath).replace('\\\\', '/'),\n }));\n } else {\n possiblePaths = [\n {\n value: workspace.path,\n label: workspace.path,\n },\n ];\n }\n }\n\n return (\n <Box flexDirection=\"column\">\n <Text color={colors.body}>\n {`Creating project in the workspace at ${chalk[colors.info](workspace.path)}.`}\n </Text>\n\n <CreateProjectInput\n rows={{\n projectPath: {\n choices: possiblePaths,\n },\n }}\n values={createProjectInputResult}\n marginTop={1}\n onChange={setCreateProjectInputResult}\n onComplete={setCreateProjectInputResult}\n />\n\n {status === 'in-progress' || status === 'finished' ? (\n <Box marginTop={1} flexDirection=\"column\">\n <Header showSpinner={status === 'in-progress'} icon={icons.success} marginBottom={1}>\n <Text>Creating project...</Text>\n </Header>\n\n {jobs.map((job) => (\n <Text key={job}>{`${icons.info} ${job}`}</Text>\n ))}\n </Box>\n ) : null}\n\n {status === 'finished' ? (\n <Header marginTop={1} icon={icons.success}>\n <Text>Done.</Text>\n </Header>\n ) : null}\n </Box>\n );\n}\n"],"names":["Header","icons","colors","useProgram","chalk","Box","Text","path","useEffect","useState","CreateProjectInput","runCreateProject","packageNameToDirectory","ONLY_ONE_STAR_REGEXP","CreateProject","args","workspace","status","setStatus","subscription","setSubscription","jobs","setJobs","createProjectInputResult","setCreateProjectInputResult","projectName","value","options","name","isComplete","projectPath","templateId","template","exit","Object","entries","every","result","newSubscription","subscribe","next","previousJobs","error","complete","unsubscribe","possiblePaths","destinationDirectory","projectGlobs","filter","projectGlob","test","map","replace","join","label","relative","flexDirection","color","body","info","rows","choices","values","marginTop","onChange","onComplete","showSpinner","icon","success","marginBottom","job"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type FormResult } from '@jakubmazanec/cli';
|
|
2
|
+
export declare const CreateProjectInput: import("@jakubmazanec/cli").Form<{
|
|
3
|
+
rows: {
|
|
4
|
+
templateId: {
|
|
5
|
+
type: "text";
|
|
6
|
+
label: string;
|
|
7
|
+
validate: (value: string) => void;
|
|
8
|
+
};
|
|
9
|
+
projectName: {
|
|
10
|
+
type: "text";
|
|
11
|
+
label: string;
|
|
12
|
+
validate: (value: string) => void;
|
|
13
|
+
};
|
|
14
|
+
projectPath: {
|
|
15
|
+
type: "select";
|
|
16
|
+
label: string;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
}>;
|
|
20
|
+
export type CreateProjectInputResult = FormResult<typeof CreateProjectInput>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createForm } from '@jakubmazanec/cli';
|
|
2
|
+
const TEMPLATE_ID_REGEXP = /^.+:.+$/;
|
|
3
|
+
const PROJECT_NAME_ID_REGEXP = /^[\d./@a-z-]+$/;
|
|
4
|
+
export const CreateProjectInput = createForm({
|
|
5
|
+
rows: {
|
|
6
|
+
templateId: {
|
|
7
|
+
type: 'text',
|
|
8
|
+
label: 'What template do you want to use?',
|
|
9
|
+
validate: (value)=>{
|
|
10
|
+
if (!TEMPLATE_ID_REGEXP.test(value)) {
|
|
11
|
+
throw new Error('Template ID must consist of a module ID and a template name separated by a colon.');
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
projectName: {
|
|
16
|
+
type: 'text',
|
|
17
|
+
label: 'What is the project name?',
|
|
18
|
+
validate: (value)=>{
|
|
19
|
+
if (!PROJECT_NAME_ID_REGEXP.test(value)) {
|
|
20
|
+
throw new Error('Project name can containg only lowercase letters, numbers, hyphen, @, dot or /.');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
projectPath: {
|
|
25
|
+
type: 'select',
|
|
26
|
+
label: 'What is the project location?'
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=CreateProjectInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/create-project/CreateProjectInput.ts"],"sourcesContent":["import {type FormResult, createForm} from '@jakubmazanec/cli';\n\nconst TEMPLATE_ID_REGEXP = /^.+:.+$/;\nconst PROJECT_NAME_ID_REGEXP = /^[\\d./@a-z-]+$/;\n\nexport const CreateProjectInput = createForm({\n rows: {\n templateId: {\n type: 'text',\n label: 'What template do you want to use?',\n validate: (value: string) => {\n if (!TEMPLATE_ID_REGEXP.test(value)) {\n throw new Error(\n 'Template ID must consist of a module ID and a template name separated by a colon.',\n );\n }\n },\n },\n projectName: {\n type: 'text',\n label: 'What is the project name?',\n validate: (value: string) => {\n if (!PROJECT_NAME_ID_REGEXP.test(value)) {\n throw new Error(\n 'Project name can containg only lowercase letters, numbers, hyphen, @, dot or /.',\n );\n }\n },\n },\n projectPath: {\n type: 'select',\n label: 'What is the project location?',\n },\n },\n});\n\nexport type CreateProjectInputResult = FormResult<typeof CreateProjectInput>;\n"],"names":["createForm","TEMPLATE_ID_REGEXP","PROJECT_NAME_ID_REGEXP","CreateProjectInput","rows","templateId","type","label","validate","value","test","Error","projectName","projectPath"],"mappings":"AAAA,SAAyBA,UAAU,QAAO,oBAAoB;AAE9D,MAAMC,qBAAqB;AAC3B,MAAMC,yBAAyB;AAE/B,OAAO,MAAMC,qBAAqBH,WAAW;IAC3CI,MAAM;QACJC,YAAY;YACVC,MAAM;YACNC,OAAO;YACPC,UAAU,CAACC;gBACT,IAAI,CAACR,mBAAmBS,KAAKD,QAAQ;oBACnC,MAAM,IAAIE,MACR;gBAEJ;YACF;QACF;QACAC,aAAa;YACXN,MAAM;YACNC,OAAO;YACPC,UAAU,CAACC;gBACT,IAAI,CAACP,uBAAuBQ,KAAKD,QAAQ;oBACvC,MAAM,IAAIE,MACR;gBAEJ;YACF;QACF;QACAE,aAAa;YACXP,MAAM;YACNC,OAAO;QACT;IACF;AACF,GAAG"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Command } from '@jakubmazanec/cli';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { CreateProject } from './CreateProject.js';
|
|
5
|
+
import { Workspace } from '../../workspace.js';
|
|
6
|
+
export const createProjectCommand = new Command('create project', async (args, program)=>{
|
|
7
|
+
let targetPath = path.resolve(process.cwd(), args.options.path ?? '');
|
|
8
|
+
let workspace = await Workspace.findAndRead(targetPath);
|
|
9
|
+
if (!workspace) {
|
|
10
|
+
throw new Error(`No workspace found at "${targetPath}"!`);
|
|
11
|
+
}
|
|
12
|
+
await program.renderElement(/*#__PURE__*/ _jsx(CreateProject, {
|
|
13
|
+
args: args,
|
|
14
|
+
workspace: workspace
|
|
15
|
+
}));
|
|
16
|
+
}, {
|
|
17
|
+
description: 'Creates a new project in an existing workspace.',
|
|
18
|
+
options: {
|
|
19
|
+
path: {
|
|
20
|
+
type: 'string'
|
|
21
|
+
},
|
|
22
|
+
template: {
|
|
23
|
+
type: 'string'
|
|
24
|
+
},
|
|
25
|
+
name: {
|
|
26
|
+
type: 'string'
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=createProjectCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/create-project/createProjectCommand.tsx"],"sourcesContent":["import {Command} from '@jakubmazanec/cli';\nimport path from 'node:path';\n\nimport {CreateProject} from './CreateProject.js';\nimport {Workspace} from '../../workspace.js';\n\nexport const createProjectCommand = new Command(\n 'create project',\n async (args, program) => {\n let targetPath = path.resolve(process.cwd(), args.options.path ?? '');\n let workspace = await Workspace.findAndRead(targetPath);\n\n if (!workspace) {\n throw new Error(`No workspace found at \"${targetPath}\"!`);\n }\n\n await program.renderElement(<CreateProject args={args} workspace={workspace} />);\n },\n {\n description: 'Creates a new project in an existing workspace.',\n options: {\n path: {\n type: 'string',\n },\n template: {\n type: 'string',\n },\n name: {\n type: 'string',\n },\n },\n },\n);\n"],"names":["Command","path","CreateProject","Workspace","createProjectCommand","args","program","targetPath","resolve","process","cwd","options","workspace","findAndRead","Error","renderElement","description","type","template","name"],"mappings":";AAAA,SAAQA,OAAO,QAAO,oBAAoB;AAC1C,OAAOC,UAAU,YAAY;AAE7B,SAAQC,aAAa,QAAO,qBAAqB;AACjD,SAAQC,SAAS,QAAO,qBAAqB;AAE7C,OAAO,MAAMC,uBAAuB,IAAIJ,QACtC,kBACA,OAAOK,MAAMC;IACX,IAAIC,aAAaN,KAAKO,QAAQC,QAAQC,OAAOL,KAAKM,QAAQV,QAAQ;IAClE,IAAIW,YAAY,MAAMT,UAAUU,YAAYN;IAE5C,IAAI,CAACK,WAAW;QACd,MAAM,IAAIE,MAAM,CAAC,uBAAuB,EAAEP,WAAW,EAAE,CAAC;IAC1D;IAEA,MAAMD,QAAQS,4BAAc,KAACb;QAAcG,MAAMA;QAAMO,WAAWA;;AACpE,GACA;IACEI,aAAa;IACbL,SAAS;QACPV,MAAM;YACJgB,MAAM;QACR;QACAC,UAAU;YACRD,MAAM;QACR;QACAE,MAAM;YACJF,MAAM;QACR;IACF;AACF,GACA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type CommandArguments } from '@jakubmazanec/cli';
|
|
2
|
+
import Observable from 'zen-observable';
|
|
3
|
+
import { type createProjectCommand } from './createProjectCommand.js';
|
|
4
|
+
import { type Workspace } from '../../workspace.js';
|
|
5
|
+
export type CreateProjectOptions = {
|
|
6
|
+
projectPath: string;
|
|
7
|
+
projectName: string;
|
|
8
|
+
templateId: string;
|
|
9
|
+
workspace: Workspace | Workspace<false>;
|
|
10
|
+
args: CommandArguments<typeof createProjectCommand>;
|
|
11
|
+
};
|
|
12
|
+
export type CreateProjectStatus = string;
|
|
13
|
+
export declare function runCreateProject({ projectPath, templateId, projectName, workspace, args, }: CreateProjectOptions): Observable<string>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { isEmptyDirectory } from '@jakubmazanec/fs-utils';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import Observable from 'zen-observable';
|
|
5
|
+
export function runCreateProject({ projectPath , templateId , projectName , workspace , args }) {
|
|
6
|
+
return new Observable((observer)=>{
|
|
7
|
+
(async ()=>{
|
|
8
|
+
observer.next('TODO');
|
|
9
|
+
let resolvedProjectPath = path.resolve(projectPath);
|
|
10
|
+
// check if path is ok
|
|
11
|
+
await fs.ensureDir(resolvedProjectPath);
|
|
12
|
+
let isProjectPathEmpty = await isEmptyDirectory(resolvedProjectPath);
|
|
13
|
+
if (!isProjectPathEmpty) {
|
|
14
|
+
throw new Error(`Directory "${resolvedProjectPath}" must be empty`);
|
|
15
|
+
}
|
|
16
|
+
// create new project
|
|
17
|
+
let project = await workspace.createProject({
|
|
18
|
+
projectPath: resolvedProjectPath,
|
|
19
|
+
projectName,
|
|
20
|
+
templateId,
|
|
21
|
+
args
|
|
22
|
+
});
|
|
23
|
+
await project.update({
|
|
24
|
+
args
|
|
25
|
+
});
|
|
26
|
+
})().then(()=>{
|
|
27
|
+
observer.complete();
|
|
28
|
+
}).catch((error)=>{
|
|
29
|
+
observer.error(error);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=runCreateProject.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/create-project/runCreateProject.ts"],"sourcesContent":["import {type CommandArguments} from '@jakubmazanec/cli';\nimport {isEmptyDirectory} from '@jakubmazanec/fs-utils';\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport Observable from 'zen-observable';\n\nimport {type createProjectCommand} from './createProjectCommand.js';\nimport {type Workspace} from '../../workspace.js';\n\nexport type CreateProjectOptions = {\n projectPath: string;\n projectName: string;\n templateId: string;\n workspace: Workspace | Workspace<false>;\n args: CommandArguments<typeof createProjectCommand>;\n};\n\nexport type CreateProjectStatus = string;\n\nexport function runCreateProject({\n projectPath,\n templateId,\n projectName,\n workspace,\n args,\n}: CreateProjectOptions) {\n return new Observable<CreateProjectStatus>((observer) => {\n (async () => {\n observer.next('TODO');\n\n let resolvedProjectPath = path.resolve(projectPath);\n\n // check if path is ok\n await fs.ensureDir(resolvedProjectPath);\n\n let isProjectPathEmpty = await isEmptyDirectory(resolvedProjectPath);\n\n if (!isProjectPathEmpty) {\n throw new Error(`Directory \"${resolvedProjectPath}\" must be empty`);\n }\n\n // create new project\n let project = await workspace.createProject({\n projectPath: resolvedProjectPath,\n projectName,\n templateId,\n args,\n });\n\n await project.update({args});\n })()\n .then(() => {\n observer.complete();\n })\n .catch((error) => {\n observer.error(error);\n });\n });\n}\n"],"names":["isEmptyDirectory","fs","path","Observable","runCreateProject","projectPath","templateId","projectName","workspace","args","observer","next","resolvedProjectPath","resolve","ensureDir","isProjectPathEmpty","Error","project","createProject","update","then","complete","catch","error"],"mappings":"AACA,SAAQA,gBAAgB,QAAO,yBAAyB;AACxD,OAAOC,QAAQ,WAAW;AAC1B,OAAOC,UAAU,YAAY;AAC7B,OAAOC,gBAAgB,iBAAiB;AAexC,OAAO,SAASC,iBAAiB,EAC/BC,YAAW,EACXC,WAAU,EACVC,YAAW,EACXC,UAAS,EACTC,KAAI,EACiB;IACrB,OAAO,IAAIN,WAAgC,CAACO;QACzC,CAAA;YACCA,SAASC,KAAK;YAEd,IAAIC,sBAAsBV,KAAKW,QAAQR;YAEvC,sBAAsB;YACtB,MAAMJ,GAAGa,UAAUF;YAEnB,IAAIG,qBAAqB,MAAMf,iBAAiBY;YAEhD,IAAI,CAACG,oBAAoB;gBACvB,MAAM,IAAIC,MAAM,CAAC,WAAW,EAAEJ,oBAAoB,eAAe,CAAC;YACpE;YAEA,qBAAqB;YACrB,IAAIK,UAAU,MAAMT,UAAUU,cAAc;gBAC1Cb,aAAaO;gBACbL;gBACAD;gBACAG;YACF;YAEA,MAAMQ,QAAQE,OAAO;gBAACV;YAAI;QAC5B,CAAA,IACGW,KAAK;YACJV,SAASW;QACX,GACCC,MAAM,CAACC;YACNb,SAASa,MAAMA;QACjB;IACJ;AACF"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * from './create-project/CreateProjectInput.js';
|
|
2
|
+
export * from './create-project/runCreateProject.js';
|
|
3
|
+
export * from './create-project/CreateProject.js';
|
|
4
|
+
export * from './create-project/createProjectCommand.js';
|
|
5
|
+
|
|
6
|
+
//# sourceMappingURL=create-project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/commands/create-project.ts"],"sourcesContent":["export * from './create-project/CreateProjectInput.js';\nexport * from './create-project/runCreateProject.js';\nexport * from './create-project/CreateProject.js';\nexport * from './create-project/createProjectCommand.js';\n"],"names":[],"mappings":"AAAA,cAAc,yCAAyC;AACvD,cAAc,uCAAuC;AACrD,cAAc,oCAAoC;AAClD,cAAc,2CAA2C"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type CommandArguments } from '@jakubmazanec/cli';
|
|
2
|
+
import { type createWorkspaceCommand } from './createWorkspaceCommand.js';
|
|
3
|
+
export type CreateWorkspaceProps = {
|
|
4
|
+
args: CommandArguments<typeof createWorkspaceCommand>;
|
|
5
|
+
path: string;
|
|
6
|
+
};
|
|
7
|
+
export declare function CreateWorkspace({ args, path }: CreateWorkspaceProps): import("react/jsx-runtime").JSX.Element;
|