@jakubmazanec/carson 0.1.0-c5ebb6f → 0.1.0-next.336fe21

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.
Files changed (225) hide show
  1. package/README.md +65 -10
  2. package/dist/commands/create-project/CreateProject.js.map +1 -1
  3. package/dist/commands/create-project/CreateProjectInput.js +1 -1
  4. package/dist/commands/create-project/CreateProjectInput.js.map +1 -1
  5. package/dist/commands/create-project/createProjectCommand.js +3 -4
  6. package/dist/commands/create-project/createProjectCommand.js.map +1 -1
  7. package/dist/commands/create-project/runCreateProject.js +3 -13
  8. package/dist/commands/create-project/runCreateProject.js.map +1 -1
  9. package/dist/commands/create-workspace/CreateWorkspace.d.ts +1 -2
  10. package/dist/commands/create-workspace/CreateWorkspace.js +7 -5
  11. package/dist/commands/create-workspace/CreateWorkspace.js.map +1 -1
  12. package/dist/commands/create-workspace/createWorkspaceCommand.js +1 -11
  13. package/dist/commands/create-workspace/createWorkspaceCommand.js.map +1 -1
  14. package/dist/commands/create-workspace/runCreateWorkspace.js +3 -12
  15. package/dist/commands/create-workspace/runCreateWorkspace.js.map +1 -1
  16. package/dist/commands/internals/CommandStatus.d.ts +1 -0
  17. package/dist/commands/internals/CommandStatus.js +3 -0
  18. package/dist/commands/internals/CommandStatus.js.map +1 -0
  19. package/dist/commands/internals.d.ts +1 -0
  20. package/dist/commands/internals.js +1 -0
  21. package/dist/commands/internals.js.map +1 -1
  22. package/dist/commands/update-workspace/UpdateWorkspace.js +1 -1
  23. package/dist/commands/update-workspace/UpdateWorkspace.js.map +1 -1
  24. package/dist/commands/update-workspace/updateWorkspaceCommand.js +3 -4
  25. package/dist/commands/update-workspace/updateWorkspaceCommand.js.map +1 -1
  26. package/dist/template/CarsonTemplate.d.ts +1 -1
  27. package/dist/template/CarsonTemplate.js.map +1 -1
  28. package/dist/template/CarsonTemplateConfig.d.ts +1 -1
  29. package/dist/template/CarsonTemplateConfig.js.map +1 -1
  30. package/dist/template/CarsonTemplateError.d.ts +8 -0
  31. package/dist/template/CarsonTemplateError.js +13 -0
  32. package/dist/template/CarsonTemplateError.js.map +1 -0
  33. package/dist/template/TemplateAttributes.d.ts +3 -3
  34. package/dist/template/TemplateAttributes.js +2 -1
  35. package/dist/template/TemplateAttributes.js.map +1 -1
  36. package/dist/template/TemplateRender.d.ts +6 -2
  37. package/dist/template/TemplateRender.js.map +1 -1
  38. package/dist/template/TemplateRenders.d.ts +1 -1
  39. package/dist/template/TemplateRenders.js.map +1 -1
  40. package/dist/template/applyTemplateRenders.d.ts +3 -0
  41. package/dist/template/applyTemplateRenders.js +36 -6
  42. package/dist/template/applyTemplateRenders.js.map +1 -1
  43. package/dist/template/internals/TemplateRenderSnapshot.d.ts +18 -5
  44. package/dist/template/internals/TemplateRenderSnapshot.js +4 -1
  45. package/dist/template/internals/TemplateRenderSnapshot.js.map +1 -1
  46. package/dist/template/internals/TemplateRenderSnapshots.d.ts +18 -5
  47. package/dist/template/internals/deleteUsingTemplateRender.d.ts +4 -1
  48. package/dist/template/internals/deleteUsingTemplateRender.js +16 -3
  49. package/dist/template/internals/deleteUsingTemplateRender.js.map +1 -1
  50. package/dist/template/internals/insertUsingTemplateRender.js +11 -1
  51. package/dist/template/internals/insertUsingTemplateRender.js.map +1 -1
  52. package/dist/template/internals/loadTemplateRenderSnapshots.d.ts +4 -1
  53. package/dist/template/internals/mergeUsingTemplateRender.js +11 -1
  54. package/dist/template/internals/mergeUsingTemplateRender.js.map +1 -1
  55. package/dist/template/internals/parseCarsonTemplateId.js +6 -1
  56. package/dist/template/internals/parseCarsonTemplateId.js.map +1 -1
  57. package/dist/template/internals/readCarsonTemplate.js +7 -1
  58. package/dist/template/internals/readCarsonTemplate.js.map +1 -1
  59. package/dist/template/internals/saveTemplateRenderSnapshots.js +4 -4
  60. package/dist/template/internals/saveTemplateRenderSnapshots.js.map +1 -1
  61. package/dist/template/internals/uninsertUsingTemplateRender.js +11 -1
  62. package/dist/template/internals/uninsertUsingTemplateRender.js.map +1 -1
  63. package/dist/template/internals/unmerge.d.ts +1 -1
  64. package/dist/template/internals/unmerge.js +1 -1
  65. package/dist/template/internals/unmerge.js.map +1 -1
  66. package/dist/template/internals/unmergeUsingTemplateRender.js +11 -1
  67. package/dist/template/internals/unmergeUsingTemplateRender.js.map +1 -1
  68. package/dist/template/renderCarsonTemplate.d.ts +3 -0
  69. package/dist/template/renderCarsonTemplate.js +15 -4
  70. package/dist/template/renderCarsonTemplate.js.map +1 -1
  71. package/dist/template.d.ts +1 -0
  72. package/dist/template.js +1 -0
  73. package/dist/template.js.map +1 -1
  74. package/dist/workspace/Project.d.ts +2 -2
  75. package/dist/workspace/Project.js +19 -4
  76. package/dist/workspace/Project.js.map +1 -1
  77. package/dist/workspace/ProjectConfig.d.ts +3 -0
  78. package/dist/workspace/ProjectConfig.js.map +1 -1
  79. package/dist/workspace/ProjectCreateOptions.d.ts +3 -0
  80. package/dist/workspace/ProjectCreateOptions.js.map +1 -1
  81. package/dist/workspace/ProjectError.d.ts +5 -2
  82. package/dist/workspace/ProjectError.js +6 -2
  83. package/dist/workspace/ProjectError.js.map +1 -1
  84. package/dist/workspace/ProjectOptions.d.ts +1 -1
  85. package/dist/workspace/ProjectOptions.js.map +1 -1
  86. package/dist/workspace/ProjectUpdateOptions.d.ts +3 -0
  87. package/dist/workspace/ProjectUpdateOptions.js +3 -1
  88. package/dist/workspace/ProjectUpdateOptions.js.map +1 -1
  89. package/dist/workspace/Workspace.d.ts +8 -6
  90. package/dist/workspace/Workspace.js +106 -33
  91. package/dist/workspace/Workspace.js.map +1 -1
  92. package/dist/workspace/WorkspaceConfig.d.ts +3 -0
  93. package/dist/workspace/WorkspaceConfig.js.map +1 -1
  94. package/dist/workspace/WorkspaceCreateOptions.d.ts +3 -0
  95. package/dist/workspace/WorkspaceCreateOptions.js +3 -1
  96. package/dist/workspace/WorkspaceCreateOptions.js.map +1 -1
  97. package/dist/workspace/WorkspaceCreateProjectOptions.d.ts +3 -0
  98. package/dist/workspace/WorkspaceCreateProjectOptions.js +3 -1
  99. package/dist/workspace/WorkspaceCreateProjectOptions.js.map +1 -1
  100. package/dist/workspace/WorkspaceDependencies.d.ts +26 -19
  101. package/dist/workspace/WorkspaceDependencies.js +27 -9
  102. package/dist/workspace/WorkspaceDependencies.js.map +1 -1
  103. package/dist/workspace/WorkspaceDependenciesFromWorkspaceOptions.d.ts +8 -0
  104. package/dist/workspace/WorkspaceDependenciesFromWorkspaceOptions.js +5 -0
  105. package/dist/workspace/WorkspaceDependenciesFromWorkspaceOptions.js.map +1 -0
  106. package/dist/workspace/WorkspaceDependenciesGetVersionsOptions.d.ts +6 -0
  107. package/dist/workspace/WorkspaceDependenciesGetVersionsOptions.js +5 -0
  108. package/dist/workspace/WorkspaceDependenciesGetVersionsOptions.js.map +1 -0
  109. package/dist/workspace/WorkspaceDependency.d.ts +14 -0
  110. package/dist/workspace/WorkspaceDependency.js +3 -0
  111. package/dist/workspace/WorkspaceDependency.js.map +1 -0
  112. package/dist/workspace/WorkspaceDependencyProject.d.ts +11 -0
  113. package/dist/workspace/WorkspaceDependencyProject.js +5 -0
  114. package/dist/workspace/WorkspaceDependencyProject.js.map +1 -0
  115. package/dist/workspace/WorkspaceError.d.ts +5 -2
  116. package/dist/workspace/WorkspaceError.js +10 -3
  117. package/dist/workspace/WorkspaceError.js.map +1 -1
  118. package/dist/workspace/WorkspaceFindAndReadOptions.d.ts +6 -0
  119. package/dist/workspace/WorkspaceFindAndReadOptions.js +5 -0
  120. package/dist/workspace/WorkspaceFindAndReadOptions.js.map +1 -0
  121. package/dist/workspace/WorkspaceOptions.d.ts +4 -4
  122. package/dist/workspace/WorkspaceOptions.js.map +1 -1
  123. package/dist/workspace/{WorkspaceOptionsProjectOptions.d.ts → WorkspaceOptionsProject.d.ts} +4 -1
  124. package/dist/workspace/WorkspaceOptionsProject.js +3 -0
  125. package/dist/workspace/WorkspaceOptionsProject.js.map +1 -0
  126. package/dist/workspace/WorkspacePackageJson.d.ts +3 -0
  127. package/dist/workspace/WorkspacePackageJson.js.map +1 -1
  128. package/dist/workspace/WorkspaceProjectGlobs.d.ts +3 -0
  129. package/dist/workspace/WorkspaceProjectGlobs.js +3 -1
  130. package/dist/workspace/WorkspaceProjectGlobs.js.map +1 -1
  131. package/dist/workspace/WorkspaceProjects.d.ts +3 -0
  132. package/dist/workspace/WorkspaceProjects.js.map +1 -1
  133. package/dist/workspace/WorkspaceRepository.d.ts +4 -1
  134. package/dist/workspace/WorkspaceRepository.js +3 -1
  135. package/dist/workspace/WorkspaceRepository.js.map +1 -1
  136. package/dist/workspace/WorkspaceUpdateOptions.d.ts +3 -0
  137. package/dist/workspace/WorkspaceUpdateOptions.js +3 -1
  138. package/dist/workspace/WorkspaceUpdateOptions.js.map +1 -1
  139. package/dist/workspace/internals/compareProjectPath.d.ts +2 -0
  140. package/dist/workspace/internals/compareProjectPath.js +10 -0
  141. package/dist/workspace/internals/compareProjectPath.js.map +1 -0
  142. package/dist/workspace/internals/compareWorkspaceDependencyProjectName.d.ts +2 -0
  143. package/dist/workspace/internals/compareWorkspaceDependencyProjectName.js +10 -0
  144. package/dist/workspace/internals/compareWorkspaceDependencyProjectName.js.map +1 -0
  145. package/dist/workspace/internals/getRepositoryBranches.js +6 -0
  146. package/dist/workspace/internals/getRepositoryBranches.js.map +1 -1
  147. package/dist/workspace/internals/getRepositoryUrl.js +0 -1
  148. package/dist/workspace/internals/getRepositoryUrl.js.map +1 -1
  149. package/dist/workspace/internals.d.ts +2 -0
  150. package/dist/workspace/internals.js +2 -0
  151. package/dist/workspace/internals.js.map +1 -1
  152. package/dist/workspace/saveProjectConfig.d.ts +8 -0
  153. package/dist/workspace/saveProjectConfig.js +5 -1
  154. package/dist/workspace/saveProjectConfig.js.map +1 -1
  155. package/dist/workspace/saveWorkspaceConfig.d.ts +8 -0
  156. package/dist/workspace/saveWorkspaceConfig.js +5 -1
  157. package/dist/workspace/saveWorkspaceConfig.js.map +1 -1
  158. package/dist/workspace.d.ts +12 -0
  159. package/dist/workspace.js +12 -0
  160. package/dist/workspace.js.map +1 -1
  161. package/package.json +10 -10
  162. package/src/commands/create-project/CreateProject.tsx +2 -2
  163. package/src/commands/create-project/CreateProjectInput.ts +1 -1
  164. package/src/commands/create-project/createProjectCommand.tsx +1 -5
  165. package/src/commands/create-project/runCreateProject.ts +4 -17
  166. package/src/commands/create-workspace/CreateWorkspace.tsx +8 -6
  167. package/src/commands/create-workspace/createWorkspaceCommand.tsx +1 -14
  168. package/src/commands/create-workspace/runCreateWorkspace.ts +4 -16
  169. package/src/commands/internals/CommandStatus.ts +1 -0
  170. package/src/commands/internals.ts +1 -0
  171. package/src/commands/update-workspace/UpdateWorkspace.tsx +1 -1
  172. package/src/commands/update-workspace/updateWorkspaceCommand.tsx +1 -5
  173. package/src/template/CarsonTemplate.ts +1 -2
  174. package/src/template/CarsonTemplateConfig.ts +1 -1
  175. package/src/template/CarsonTemplateError.ts +19 -0
  176. package/src/template/TemplateAttributes.ts +2 -1
  177. package/src/template/TemplateRender.ts +6 -2
  178. package/src/template/TemplateRenders.ts +1 -1
  179. package/src/template/applyTemplateRenders.ts +40 -4
  180. package/src/template/internals/TemplateRenderSnapshot.ts +5 -0
  181. package/src/template/internals/deleteUsingTemplateRender.ts +21 -2
  182. package/src/template/internals/insertUsingTemplateRender.ts +11 -1
  183. package/src/template/internals/mergeUsingTemplateRender.ts +11 -1
  184. package/src/template/internals/parseCarsonTemplateId.ts +5 -1
  185. package/src/template/internals/readCarsonTemplate.ts +4 -1
  186. package/src/template/internals/saveTemplateRenderSnapshots.ts +3 -2
  187. package/src/template/internals/uninsertUsingTemplateRender.ts +11 -1
  188. package/src/template/internals/unmerge.ts +1 -1
  189. package/src/template/internals/unmergeUsingTemplateRender.ts +11 -1
  190. package/src/template/renderCarsonTemplate.ts +28 -7
  191. package/src/template.ts +1 -0
  192. package/src/workspace/Project.ts +16 -4
  193. package/src/workspace/ProjectConfig.ts +3 -0
  194. package/src/workspace/ProjectCreateOptions.ts +3 -0
  195. package/src/workspace/ProjectError.ts +5 -0
  196. package/src/workspace/ProjectOptions.ts +1 -1
  197. package/src/workspace/ProjectUpdateOptions.ts +3 -0
  198. package/src/workspace/Workspace.ts +125 -42
  199. package/src/workspace/WorkspaceConfig.ts +3 -0
  200. package/src/workspace/WorkspaceCreateOptions.ts +3 -0
  201. package/src/workspace/WorkspaceCreateProjectOptions.ts +3 -0
  202. package/src/workspace/WorkspaceDependencies.ts +30 -27
  203. package/src/workspace/WorkspaceDependenciesFromWorkspaceOptions.ts +8 -0
  204. package/src/workspace/WorkspaceDependenciesGetVersionsOptions.ts +6 -0
  205. package/src/workspace/WorkspaceDependency.ts +18 -0
  206. package/src/workspace/WorkspaceDependencyProject.ts +13 -0
  207. package/src/workspace/WorkspaceError.ts +10 -1
  208. package/src/workspace/WorkspaceFindAndReadOptions.ts +6 -0
  209. package/src/workspace/WorkspaceOptions.ts +4 -4
  210. package/src/workspace/{WorkspaceOptionsProjectOptions.ts → WorkspaceOptionsProject.ts} +4 -1
  211. package/src/workspace/WorkspacePackageJson.ts +3 -0
  212. package/src/workspace/WorkspaceProjectGlobs.ts +3 -0
  213. package/src/workspace/WorkspaceProjects.ts +3 -0
  214. package/src/workspace/WorkspaceRepository.ts +4 -1
  215. package/src/workspace/WorkspaceUpdateOptions.ts +3 -0
  216. package/src/workspace/internals/compareProjectPath.ts +14 -0
  217. package/src/workspace/internals/compareWorkspaceDependencyProjectName.ts +14 -0
  218. package/src/workspace/internals/getRepositoryBranches.ts +8 -0
  219. package/src/workspace/internals/getRepositoryUrl.ts +0 -1
  220. package/src/workspace/internals.ts +2 -0
  221. package/src/workspace/saveProjectConfig.ts +8 -0
  222. package/src/workspace/saveWorkspaceConfig.ts +8 -0
  223. package/src/workspace.ts +12 -0
  224. package/dist/workspace/WorkspaceOptionsProjectOptions.js +0 -3
  225. package/dist/workspace/WorkspaceOptionsProjectOptions.js.map +0 -1
package/README.md CHANGED
@@ -11,12 +11,26 @@ Tool for managing workspace and project configuration.
11
11
  ## Installation
12
12
 
13
13
  ```sh
14
- npm install @jakubmazanec/carson -g
14
+ npm install @jakubmazanec/carson
15
15
  ```
16
16
 
17
17
  ⚠️ This is an [ESM](https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c) package!
18
18
  It cannot be required from a CommonJS module.
19
19
 
20
+ Usually you also need a package containing Carson templates. Until you
21
+ [create your own](#carson-templates), you can use mine:
22
+
23
+ ```sh
24
+ npm install @jakubmazanec/carson-templates
25
+ ```
26
+
27
+ ⚠️ If you want to create new workspaces, you need to install both Carson and your template package
28
+ globally:
29
+
30
+ ```sh
31
+ npm install @jakubmazanec/carson @jakubmazanec/carson-templates -g
32
+ ```
33
+
20
34
  #### Prerequisites
21
35
 
22
36
  - Node.js 16 or later
@@ -176,9 +190,9 @@ See [API reference](./docs) for auto-generated documentation.
176
190
 
177
191
  ### Configuration
178
192
 
179
- Carson configuration files are located in a directory named `.carson` directory. Files named
180
- `workspace.json` and `project.json` are used to configure the workspace and project respectively (in
181
- the case of single-project workspace they're both in the same `.carson` directory).
193
+ Carson configuration files are located in a directory named `.carson`. Files named `workspace.json`
194
+ and `project.json` are used to configure the workspace and project respectively (in the case of
195
+ single-project workspace they're both in the same `.carson` directory).
182
196
 
183
197
  You can add arbitrary data to these JSONs in addition to the options described below. Because
184
198
  workspace and project configurations are available as JavaScript variables during the rendering of
@@ -269,6 +283,8 @@ there are 3 templates (for simplicity, each contains only one `*.ejs` file and a
269
283
  The package can also export some JavaScript code (defined in the `package.json` as usual); all named
270
284
  export are available as global variables during the rendering of the template files.
271
285
 
286
+ > ⚠️ Do NOT use asynchronous functions in the template files. Templates are rendered synchronously.
287
+
272
288
  #### Template files
273
289
 
274
290
  All those `*.ejs` files are parsed and rendered via `@jakubmazanec/template` package; they are
@@ -315,13 +331,15 @@ should be written at all.
315
331
 
316
332
  | Strategy name | Example `strategy` value | Description |
317
333
  | ------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
318
- | Create | `create` | The template render is written to the target file, but only when the Carson template is used to create a new workspace or project; when Carson performs an update, the template files with this strategy are not even rendered. |
319
- | Overwrite | `overwrite` | The template render is written to the target file, overwriting its existing content. |
320
- | Merge | `merge` | The template render is merged with the target file's existing content. Only simple objects, not arrays, are merged recursively. The only supported file formats are JSON and YAML. |
321
- | Check | `check` | Only the target file's existence is checked, the template render is discarded; when Carson doesn't perform an update, the template files with this strategy are not even rendered. |
322
- | Insert | `[insert, foobar]` | The template render is inserted between the first and last occurrence of an HTML comment containing configured string, e.g. `<!-- foobar -->`. The only supported file format is Markdown. |
334
+ | Create | `'create'` | The template render is written to the target file, but only when the Carson template is used to create a new workspace or project; when Carson performs an update, the template files with this strategy are not even rendered. |
335
+ | Ensure | `'ensure'` | The template render is written to the target file, but only when the target file doesn't exist; if it does, it is left unchanged. |
336
+ | Overwrite | `'overwrite'` | The template render is written to the target file, overwriting its existing content. |
337
+ | Merge | `'merge'` | The template render is merged with the target file's existing content. Only simple objects, not arrays, are merged recursively. The only supported file formats are JSON and YAML. |
338
+ | Check | `'check'` | Only the target file's existence is checked, the template render is discarded; when Carson doesn't perform an update, the template files with this strategy are not even rendered. |
339
+ | Insert | `['insert', <string>]` | The template render is inserted between the first and last occurrence of an HTML comment containing configured string, e.g. `<!-- foobar -->`. The only supported file format is Markdown. |
323
340
 
324
- The rest of the template file after the front matter is the actual EJS template.
341
+ The rest of the template file after the front matter is the actual EJS template. Please read
342
+ [`ejs` documentation](https://ejs.co/#docs) to find out in more detail how they work.
325
343
 
326
344
  > ⚠️ Because EJS templates can contain arbitrary JavaScript code which Carson will run, you
327
345
  > shouldn't use Carson templates from untrusted sources! Only use templates that you've written or
@@ -339,6 +357,43 @@ Global variables available during the rendering:
339
357
 
340
358
  Currently, the config isn't used for anything yet.
341
359
 
360
+ ### Carson philosophy
361
+
362
+ The fact that Carson templates are just JavaScript gives you a lot of freedom, but it may lead you
363
+ to use Carson just as a simple config generator. Because you can add arbitrary data to the workspace
364
+ and project configs, it is tempting to use them as a source of values for "parameters" of
365
+ configurations of various tools.
366
+
367
+ For example, you can add `"useSwc": true` or `"useSwc": false` to a project config and then use this
368
+ value in a template that generates build configuration for either SWC, or Babel. But this makes
369
+ updates little bit harder, because if you later remove Babel support, you have to remember to remove
370
+ now useless setting from the project config. It also makes the logic of the Carson template more
371
+ complex; it is better to have separate templates for projects that use Babel and for project that
372
+ use SWC.
373
+
374
+ Another approach that is not recommended is using project config to specify "overrides" for various
375
+ config files:
376
+
377
+ ```json
378
+ {
379
+ "template": "@jakubmazanec/carson-templates:projects/library",
380
+
381
+ "tsconfig": {
382
+ "compilerOptions": {
383
+ "strict": false
384
+ }
385
+ }
386
+ }
387
+ ```
388
+
389
+ The `tsconfig` object is then recursively merged with the defaults during the template rendering of
390
+ the resulting `tsconfig.json`, thus allowing you to change TypeScript configuration per project.
391
+ This is not ideal, because now the Carson template isn't the only thing that defines the project
392
+ configuration, which makes updates more unpredictable.
393
+
394
+ Generally, do not push the data onto the templates, let the templates pull the data they need. Since
395
+ you create your own templates, it should be easy to do.
396
+
342
397
  ## Contributing
343
398
 
344
399
  If you want to contribute, see [CONTRIBUTING](./CONTRIBUTING.md) for details.
@@ -1 +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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"}
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, type CommandStatus} 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<CommandStatus>('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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"}
@@ -17,7 +17,7 @@ export const CreateProjectInput = createForm({
17
17
  label: 'What is the project name?',
18
18
  validate: (value)=>{
19
19
  if (!PROJECT_NAME_ID_REGEXP.test(value)) {
20
- throw new Error('Project name can containg only lowercase letters, numbers, hyphen, @, dot or /.');
20
+ throw new Error('Project name can contain only lowercase letters, numbers, hyphen, @, dot or /.');
21
21
  }
22
22
  }
23
23
  },
@@ -1 +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,IAAI,CAACD,QAAQ;oBACnC,MAAM,IAAIE,MACR;gBAEJ;YACF;QACF;QACAC,aAAa;YACXN,MAAM;YACNC,OAAO;YACPC,UAAU,CAACC;gBACT,IAAI,CAACP,uBAAuBQ,IAAI,CAACD,QAAQ;oBACvC,MAAM,IAAIE,MACR;gBAEJ;YACF;QACF;QACAE,aAAa;YACXP,MAAM;YACNC,OAAO;QACT;IACF;AACF,GAAG"}
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 contain 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,IAAI,CAACD,QAAQ;oBACnC,MAAM,IAAIE,MACR;gBAEJ;YACF;QACF;QACAC,aAAa;YACXN,MAAM;YACNC,OAAO;YACPC,UAAU,CAACC;gBACT,IAAI,CAACP,uBAAuBQ,IAAI,CAACD,QAAQ;oBACvC,MAAM,IAAIE,MACR;gBAEJ;YACF;QACF;QACAE,aAAa;YACXP,MAAM;YACNC,OAAO;QACT;IACF;AACF,GAAG"}
@@ -5,10 +5,9 @@ import { CreateProject } from './CreateProject.js';
5
5
  import { Workspace } from '../../workspace.js';
6
6
  export const createProjectCommand = new Command('create project', async (args, program)=>{
7
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
- }
8
+ let workspace = await Workspace.findAndRead(targetPath, {
9
+ throwIfNotFound: true
10
+ });
12
11
  await program.renderElement(/*#__PURE__*/ _jsx(CreateProject, {
13
12
  args: args,
14
13
  workspace: workspace
@@ -1 +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,OAAO,CAACC,QAAQC,GAAG,IAAIL,KAAKM,OAAO,CAACV,IAAI,IAAI;IAClE,IAAIW,YAAY,MAAMT,UAAUU,WAAW,CAACN;IAE5C,IAAI,CAACK,WAAW;QACd,MAAM,IAAIE,MAAM,CAAC,uBAAuB,EAAEP,WAAW,EAAE,CAAC;IAC1D;IAEA,MAAMD,QAAQS,aAAa,eAAC,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"}
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, {throwIfNotFound: true});\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","throwIfNotFound","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,OAAO,CAACC,QAAQC,GAAG,IAAIL,KAAKM,OAAO,CAACV,IAAI,IAAI;IAClE,IAAIW,YAAY,MAAMT,UAAUU,WAAW,CAACN,YAAY;QAACO,iBAAiB;IAAI;IAE9E,MAAMR,QAAQS,aAAa,eAAC,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"}
@@ -1,25 +1,15 @@
1
- import { isEmptyDirectory } from '@jakubmazanec/fs-utils';
2
- import fs from 'fs-extra';
3
- import path from 'node:path';
4
1
  import Observable from 'zen-observable';
5
2
  export function runCreateProject({ projectPath, templateId, projectName, workspace, args }) {
6
3
  return new Observable((observer)=>{
7
4
  (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
5
+ observer.next('Creating files');
17
6
  let project = await workspace.createProject({
18
- projectPath: resolvedProjectPath,
7
+ projectPath,
19
8
  projectName,
20
9
  templateId,
21
10
  args
22
11
  });
12
+ observer.next('Updating the new project');
23
13
  await project.update({
24
14
  args
25
15
  });
@@ -1 +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,WAAW,EACXC,UAAU,EACVC,WAAW,EACXC,SAAS,EACTC,IAAI,EACiB;IACrB,OAAO,IAAIN,WAAgC,CAACO;QACzC,CAAA;YACCA,SAASC,IAAI,CAAC;YAEd,IAAIC,sBAAsBV,KAAKW,OAAO,CAACR;YAEvC,sBAAsB;YACtB,MAAMJ,GAAGa,SAAS,CAACF;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,aAAa,CAAC;gBAC1Cb,aAAaO;gBACbL;gBACAD;gBACAG;YACF;YAEA,MAAMQ,QAAQE,MAAM,CAAC;gBAACV;YAAI;QAC5B,CAAA,IACGW,IAAI,CAAC;YACJV,SAASW,QAAQ;QACnB,GACCC,KAAK,CAAC,CAACC;YACNb,SAASa,KAAK,CAACA;QACjB;IACJ;AACF"}
1
+ {"version":3,"sources":["../../../src/commands/create-project/runCreateProject.ts"],"sourcesContent":["import {type CommandArguments} from '@jakubmazanec/cli';\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('Creating files');\n\n let project = await workspace.createProject({\n projectPath,\n projectName,\n templateId,\n args,\n });\n\n observer.next('Updating the new project');\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":["Observable","runCreateProject","projectPath","templateId","projectName","workspace","args","observer","next","project","createProject","update","then","complete","catch","error"],"mappings":"AACA,OAAOA,gBAAgB,iBAAiB;AAexC,OAAO,SAASC,iBAAiB,EAC/BC,WAAW,EACXC,UAAU,EACVC,WAAW,EACXC,SAAS,EACTC,IAAI,EACiB;IACrB,OAAO,IAAIN,WAAgC,CAACO;QACzC,CAAA;YACCA,SAASC,IAAI,CAAC;YAEd,IAAIC,UAAU,MAAMJ,UAAUK,aAAa,CAAC;gBAC1CR;gBACAE;gBACAD;gBACAG;YACF;YAEAC,SAASC,IAAI,CAAC;YAEd,MAAMC,QAAQE,MAAM,CAAC;gBAACL;YAAI;QAC5B,CAAA,IACGM,IAAI,CAAC;YACJL,SAASM,QAAQ;QACnB,GACCC,KAAK,CAAC,CAACC;YACNR,SAASQ,KAAK,CAACA;QACjB;IACJ;AACF"}
@@ -2,6 +2,5 @@ import { type CommandArguments } from '@jakubmazanec/cli';
2
2
  import { type createWorkspaceCommand } from './createWorkspaceCommand.js';
3
3
  export type CreateWorkspaceProps = {
4
4
  args: CommandArguments<typeof createWorkspaceCommand>;
5
- path: string;
6
5
  };
7
- export declare function CreateWorkspace({ args, path }: CreateWorkspaceProps): import("react/jsx-runtime").JSX.Element;
6
+ export declare function CreateWorkspace({ args }: CreateWorkspaceProps): import("react/jsx-runtime").JSX.Element;
@@ -2,10 +2,11 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Header, icons, colors, useProgram } from '@jakubmazanec/cli';
3
3
  import chalk from 'chalk';
4
4
  import { Box, Text } from 'ink';
5
+ import path from 'node:path';
5
6
  import { useEffect, useState } from 'react';
6
7
  import { CreateWorkspaceInput } from './CreateWorkspaceInput.js';
7
8
  import { runCreateWorkspace } from './runCreateWorkspace.js';
8
- export function CreateWorkspace({ args, path }) {
9
+ export function CreateWorkspace({ args }) {
9
10
  let [status, setStatus] = useState('not-started');
10
11
  let [subscription, setSubscription] = useState(null);
11
12
  let [jobs, setJobs] = useState([]);
@@ -16,6 +17,7 @@ export function CreateWorkspace({ args, path }) {
16
17
  }
17
18
  }));
18
19
  let { exit } = useProgram();
20
+ let workspacePath = path.resolve(process.cwd(), args.options.path ?? '');
19
21
  useEffect(()=>{
20
22
  if (Object.entries(createWorkspaceInputResult).every(([, result])=>result.isComplete)) {
21
23
  setStatus('in-progress');
@@ -26,7 +28,7 @@ export function CreateWorkspace({ args, path }) {
26
28
  useEffect(()=>{
27
29
  if (status === 'in-progress' && !subscription) {
28
30
  let newSubscription = runCreateWorkspace({
29
- workspacePath: path,
31
+ workspacePath,
30
32
  templateId: createWorkspaceInputResult.templateId.value,
31
33
  args
32
34
  }).subscribe({
@@ -53,17 +55,17 @@ export function CreateWorkspace({ args, path }) {
53
55
  };
54
56
  }, [
55
57
  createWorkspaceInputResult,
56
- path,
57
58
  status,
58
59
  subscription,
59
60
  args,
60
- exit
61
+ exit,
62
+ workspacePath
61
63
  ]);
62
64
  return /*#__PURE__*/ _jsxs(Box, {
63
65
  flexDirection: "column",
64
66
  children: [
65
67
  /*#__PURE__*/ _jsx(Text, {
66
- children: `Creating workspace at ${chalk[colors.highlighted](path)}.`
68
+ children: `Creating workspace at ${chalk[colors.info](workspacePath)}.`
67
69
  }),
68
70
  /*#__PURE__*/ _jsx(CreateWorkspaceInput, {
69
71
  values: createWorkspaceInputResult,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/create-workspace/CreateWorkspace.tsx"],"sourcesContent":["import {Header, icons, colors, type CommandArguments, useProgram} from '@jakubmazanec/cli';\nimport chalk from 'chalk';\nimport {Box, Text} from 'ink';\nimport {useEffect, useState} from 'react';\n\nimport {type createWorkspaceCommand} from './createWorkspaceCommand.js';\nimport {CreateWorkspaceInput, type CreateWorkspaceInputResult} from './CreateWorkspaceInput.js';\nimport {runCreateWorkspace} from './runCreateWorkspace.js';\n\nexport type CreateWorkspaceProps = {\n args: CommandArguments<typeof createWorkspaceCommand>;\n path: string;\n};\n\nexport function CreateWorkspace({args, path}: CreateWorkspaceProps) {\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 [createWorkspaceInputResult, setCreateWorkspaceInputResult] =\n useState<CreateWorkspaceInputResult>(() => ({\n templateId: {value: args.options.template ?? '', isComplete: !!args.options.template},\n }));\n let {exit} = useProgram();\n\n useEffect(() => {\n if (Object.entries(createWorkspaceInputResult).every(([, result]) => result.isComplete)) {\n setStatus('in-progress');\n }\n }, [createWorkspaceInputResult]);\n\n useEffect(() => {\n if (status === 'in-progress' && !subscription) {\n let newSubscription = runCreateWorkspace({\n workspacePath: path,\n templateId: createWorkspaceInputResult.templateId.value,\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\n setSubscription(newSubscription);\n }\n\n return () => {\n if (subscription) {\n subscription.unsubscribe();\n }\n };\n }, [createWorkspaceInputResult, path, status, subscription, args, exit]);\n\n return (\n <Box flexDirection=\"column\">\n <Text>{`Creating workspace at ${chalk[colors.highlighted](path)}.`}</Text>\n\n <CreateWorkspaceInput\n values={createWorkspaceInputResult}\n marginTop={1}\n onChange={setCreateWorkspaceInputResult}\n onComplete={setCreateWorkspaceInputResult}\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 workspace...</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","useEffect","useState","CreateWorkspaceInput","runCreateWorkspace","CreateWorkspace","args","path","status","setStatus","subscription","setSubscription","jobs","setJobs","createWorkspaceInputResult","setCreateWorkspaceInputResult","templateId","value","options","template","isComplete","exit","Object","entries","every","result","newSubscription","workspacePath","subscribe","next","previousJobs","error","complete","unsubscribe","flexDirection","highlighted","values","marginTop","onChange","onComplete","showSpinner","icon","success","marginBottom","map","job","info"],"mappings":";AAAA,SAAQA,MAAM,EAAEC,KAAK,EAAEC,MAAM,EAAyBC,UAAU,QAAO,oBAAoB;AAC3F,OAAOC,WAAW,QAAQ;AAC1B,SAAQC,GAAG,EAAEC,IAAI,QAAO,MAAM;AAC9B,SAAQC,SAAS,EAAEC,QAAQ,QAAO,QAAQ;AAG1C,SAAQC,oBAAoB,QAAwC,4BAA4B;AAChG,SAAQC,kBAAkB,QAAO,0BAA0B;AAO3D,OAAO,SAASC,gBAAgB,EAACC,IAAI,EAAEC,IAAI,EAAuB;IAChE,IAAI,CAACC,QAAQC,UAAU,GAAGP,SAAqD;IAC/E,IAAI,CAACQ,cAAcC,gBAAgB,GAAGT,SAA4C;IAClF,IAAI,CAACU,MAAMC,QAAQ,GAAGX,SAAmB,EAAE;IAC3C,IAAI,CAACY,4BAA4BC,8BAA8B,GAC7Db,SAAqC,IAAO,CAAA;YAC1Cc,YAAY;gBAACC,OAAOX,KAAKY,OAAO,CAACC,QAAQ,IAAI;gBAAIC,YAAY,CAAC,CAACd,KAAKY,OAAO,CAACC,QAAQ;YAAA;QACtF,CAAA;IACF,IAAI,EAACE,IAAI,EAAC,GAAGxB;IAEbI,UAAU;QACR,IAAIqB,OAAOC,OAAO,CAACT,4BAA4BU,KAAK,CAAC,CAAC,GAAGC,OAAO,GAAKA,OAAOL,UAAU,GAAG;YACvFX,UAAU;QACZ;IACF,GAAG;QAACK;KAA2B;IAE/Bb,UAAU;QACR,IAAIO,WAAW,iBAAiB,CAACE,cAAc;YAC7C,IAAIgB,kBAAkBtB,mBAAmB;gBACvCuB,eAAepB;gBACfS,YAAYF,2BAA2BE,UAAU,CAACC,KAAK;gBACvDX;YACF,GAAGsB,SAAS,CAAC;gBACXC,MAAKZ,KAAK;oBACRJ,QAAQ,CAACiB,eAAiB;+BAAIA;4BAAcb;yBAAM;gBACpD;gBACAc,OAAMA,KAAK;oBACTV,KAAKU;gBACP;gBACAC;oBACEN,gBAAgBO,WAAW;oBAC3BxB,UAAU;gBACZ;YACF;YAEAE,gBAAgBe;QAClB;QAEA,OAAO;YACL,IAAIhB,cAAc;gBAChBA,aAAauB,WAAW;YAC1B;QACF;IACF,GAAG;QAACnB;QAA4BP;QAAMC;QAAQE;QAAcJ;QAAMe;KAAK;IAEvE,qBACE,MAACtB;QAAImC,eAAc;;0BACjB,KAAClC;0BAAM,CAAC,sBAAsB,EAAEF,KAAK,CAACF,OAAOuC,WAAW,CAAC,CAAC5B,MAAM,CAAC,CAAC;;0BAElE,KAACJ;gBACCiC,QAAQtB;gBACRuB,WAAW;gBACXC,UAAUvB;gBACVwB,YAAYxB;;YAGbP,WAAW,iBAAiBA,WAAW,2BACtC,MAACT;gBAAIsC,WAAW;gBAAGH,eAAc;;kCAC/B,KAACxC;wBAAO8C,aAAahC,WAAW;wBAAeiC,MAAM9C,MAAM+C,OAAO;wBAAEC,cAAc;kCAChF,cAAA,KAAC3C;sCAAK;;;oBAGPY,KAAKgC,GAAG,CAAC,CAACC,oBACT,KAAC7C;sCAAgB,CAAC,EAAEL,MAAMmD,IAAI,CAAC,CAAC,EAAED,IAAI,CAAC;2BAA5BA;;iBAGb;YAEHrC,WAAW,2BACV,KAACd;gBAAO2C,WAAW;gBAAGI,MAAM9C,MAAM+C,OAAO;0BACvC,cAAA,KAAC1C;8BAAK;;iBAEN;;;AAGV"}
1
+ {"version":3,"sources":["../../../src/commands/create-workspace/CreateWorkspace.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 createWorkspaceCommand} from './createWorkspaceCommand.js';\nimport {CreateWorkspaceInput, type CreateWorkspaceInputResult} from './CreateWorkspaceInput.js';\nimport {runCreateWorkspace} from './runCreateWorkspace.js';\nimport {type CommandStatus} from '../internals.js';\n\nexport type CreateWorkspaceProps = {\n args: CommandArguments<typeof createWorkspaceCommand>;\n};\n\nexport function CreateWorkspace({args}: CreateWorkspaceProps) {\n let [status, setStatus] = useState<CommandStatus>('not-started');\n let [subscription, setSubscription] = useState<ZenObservable.Subscription | null>(null);\n let [jobs, setJobs] = useState<string[]>([]);\n let [createWorkspaceInputResult, setCreateWorkspaceInputResult] =\n useState<CreateWorkspaceInputResult>(() => ({\n templateId: {value: args.options.template ?? '', isComplete: !!args.options.template},\n }));\n let {exit} = useProgram();\n let workspacePath = path.resolve(process.cwd(), args.options.path ?? '');\n\n useEffect(() => {\n if (Object.entries(createWorkspaceInputResult).every(([, result]) => result.isComplete)) {\n setStatus('in-progress');\n }\n }, [createWorkspaceInputResult]);\n\n useEffect(() => {\n if (status === 'in-progress' && !subscription) {\n let newSubscription = runCreateWorkspace({\n workspacePath,\n templateId: createWorkspaceInputResult.templateId.value,\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\n setSubscription(newSubscription);\n }\n\n return () => {\n if (subscription) {\n subscription.unsubscribe();\n }\n };\n }, [createWorkspaceInputResult, status, subscription, args, exit, workspacePath]);\n\n return (\n <Box flexDirection=\"column\">\n <Text>{`Creating workspace at ${chalk[colors.info](workspacePath)}.`}</Text>\n\n <CreateWorkspaceInput\n values={createWorkspaceInputResult}\n marginTop={1}\n onChange={setCreateWorkspaceInputResult}\n onComplete={setCreateWorkspaceInputResult}\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 workspace...</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","CreateWorkspaceInput","runCreateWorkspace","CreateWorkspace","args","status","setStatus","subscription","setSubscription","jobs","setJobs","createWorkspaceInputResult","setCreateWorkspaceInputResult","templateId","value","options","template","isComplete","exit","workspacePath","resolve","process","cwd","Object","entries","every","result","newSubscription","subscribe","next","previousJobs","error","complete","unsubscribe","flexDirection","info","values","marginTop","onChange","onComplete","showSpinner","icon","success","marginBottom","map","job"],"mappings":";AAAA,SAAQA,MAAM,EAAEC,KAAK,EAAEC,MAAM,EAAyBC,UAAU,QAAO,oBAAoB;AAC3F,OAAOC,WAAW,QAAQ;AAC1B,SAAQC,GAAG,EAAEC,IAAI,QAAO,MAAM;AAC9B,OAAOC,UAAU,YAAY;AAC7B,SAAQC,SAAS,EAAEC,QAAQ,QAAO,QAAQ;AAG1C,SAAQC,oBAAoB,QAAwC,4BAA4B;AAChG,SAAQC,kBAAkB,QAAO,0BAA0B;AAO3D,OAAO,SAASC,gBAAgB,EAACC,IAAI,EAAuB;IAC1D,IAAI,CAACC,QAAQC,UAAU,GAAGN,SAAwB;IAClD,IAAI,CAACO,cAAcC,gBAAgB,GAAGR,SAA4C;IAClF,IAAI,CAACS,MAAMC,QAAQ,GAAGV,SAAmB,EAAE;IAC3C,IAAI,CAACW,4BAA4BC,8BAA8B,GAC7DZ,SAAqC,IAAO,CAAA;YAC1Ca,YAAY;gBAACC,OAAOV,KAAKW,OAAO,CAACC,QAAQ,IAAI;gBAAIC,YAAY,CAAC,CAACb,KAAKW,OAAO,CAACC,QAAQ;YAAA;QACtF,CAAA;IACF,IAAI,EAACE,IAAI,EAAC,GAAGxB;IACb,IAAIyB,gBAAgBrB,KAAKsB,OAAO,CAACC,QAAQC,GAAG,IAAIlB,KAAKW,OAAO,CAACjB,IAAI,IAAI;IAErEC,UAAU;QACR,IAAIwB,OAAOC,OAAO,CAACb,4BAA4Bc,KAAK,CAAC,CAAC,GAAGC,OAAO,GAAKA,OAAOT,UAAU,GAAG;YACvFX,UAAU;QACZ;IACF,GAAG;QAACK;KAA2B;IAE/BZ,UAAU;QACR,IAAIM,WAAW,iBAAiB,CAACE,cAAc;YAC7C,IAAIoB,kBAAkBzB,mBAAmB;gBACvCiB;gBACAN,YAAYF,2BAA2BE,UAAU,CAACC,KAAK;gBACvDV;YACF,GAAGwB,SAAS,CAAC;gBACXC,MAAKf,KAAK;oBACRJ,QAAQ,CAACoB,eAAiB;+BAAIA;4BAAchB;yBAAM;gBACpD;gBACAiB,OAAMA,KAAK;oBACTb,KAAKa;gBACP;gBACAC;oBACEL,gBAAgBM,WAAW;oBAC3B3B,UAAU;gBACZ;YACF;YAEAE,gBAAgBmB;QAClB;QAEA,OAAO;YACL,IAAIpB,cAAc;gBAChBA,aAAa0B,WAAW;YAC1B;QACF;IACF,GAAG;QAACtB;QAA4BN;QAAQE;QAAcH;QAAMc;QAAMC;KAAc;IAEhF,qBACE,MAACvB;QAAIsC,eAAc;;0BACjB,KAACrC;0BAAM,CAAC,sBAAsB,EAAEF,KAAK,CAACF,OAAO0C,IAAI,CAAC,CAAChB,eAAe,CAAC,CAAC;;0BAEpE,KAAClB;gBACCmC,QAAQzB;gBACR0B,WAAW;gBACXC,UAAU1B;gBACV2B,YAAY3B;;YAGbP,WAAW,iBAAiBA,WAAW,2BACtC,MAACT;gBAAIyC,WAAW;gBAAGH,eAAc;;kCAC/B,KAAC3C;wBAAOiD,aAAanC,WAAW;wBAAeoC,MAAMjD,MAAMkD,OAAO;wBAAEC,cAAc;kCAChF,cAAA,KAAC9C;sCAAK;;;oBAGPY,KAAKmC,GAAG,CAAC,CAACC,oBACT,KAAChD;sCAAgB,CAAC,EAAEL,MAAM2C,IAAI,CAAC,CAAC,EAAEU,IAAI,CAAC;2BAA5BA;;iBAGb;YAEHxC,WAAW,2BACV,KAACd;gBAAO8C,WAAW;gBAAGI,MAAMjD,MAAMkD,OAAO;0BACvC,cAAA,KAAC7C;8BAAK;;iBAEN;;;AAGV"}
@@ -1,19 +1,9 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Command } from '@jakubmazanec/cli';
3
- import { isEmptyDirectory } from '@jakubmazanec/fs-utils';
4
- import fs from 'fs-extra';
5
- import path from 'node:path';
6
3
  import { CreateWorkspace } from './CreateWorkspace.js';
7
4
  export const createWorkspaceCommand = new Command('create workspace', async (args, program)=>{
8
- let workspacePath = path.resolve(process.cwd(), args.options.path ?? '');
9
- await fs.ensureDir(workspacePath);
10
- let isWorkspacePathEmpty = await isEmptyDirectory(workspacePath);
11
- if (!isWorkspacePathEmpty) {
12
- throw new Error(`Directory "${workspacePath}" must be empty`);
13
- }
14
5
  await program.renderElement(/*#__PURE__*/ _jsx(CreateWorkspace, {
15
- args: args,
16
- path: workspacePath
6
+ args: args
17
7
  }));
18
8
  }, {
19
9
  description: 'Creates a new workspacee.',
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/create-workspace/createWorkspaceCommand.tsx"],"sourcesContent":["import {Command} from '@jakubmazanec/cli';\nimport {isEmptyDirectory} from '@jakubmazanec/fs-utils';\nimport fs from 'fs-extra';\nimport path from 'node:path';\n\nimport {CreateWorkspace} from './CreateWorkspace.js';\n\nexport const createWorkspaceCommand = new Command(\n 'create workspace',\n async (args, program) => {\n let workspacePath = path.resolve(process.cwd(), args.options.path ?? '');\n\n await fs.ensureDir(workspacePath);\n\n let isWorkspacePathEmpty = await isEmptyDirectory(workspacePath);\n\n if (!isWorkspacePathEmpty) {\n throw new Error(`Directory \"${workspacePath}\" must be empty`);\n }\n\n await program.renderElement(<CreateWorkspace args={args} path={workspacePath} />);\n },\n {\n description: 'Creates a new workspacee.',\n options: {\n path: {\n type: 'string',\n },\n template: {\n type: 'string',\n },\n },\n },\n);\n"],"names":["Command","isEmptyDirectory","fs","path","CreateWorkspace","createWorkspaceCommand","args","program","workspacePath","resolve","process","cwd","options","ensureDir","isWorkspacePathEmpty","Error","renderElement","description","type","template"],"mappings":";AAAA,SAAQA,OAAO,QAAO,oBAAoB;AAC1C,SAAQC,gBAAgB,QAAO,yBAAyB;AACxD,OAAOC,QAAQ,WAAW;AAC1B,OAAOC,UAAU,YAAY;AAE7B,SAAQC,eAAe,QAAO,uBAAuB;AAErD,OAAO,MAAMC,yBAAyB,IAAIL,QACxC,oBACA,OAAOM,MAAMC;IACX,IAAIC,gBAAgBL,KAAKM,OAAO,CAACC,QAAQC,GAAG,IAAIL,KAAKM,OAAO,CAACT,IAAI,IAAI;IAErE,MAAMD,GAAGW,SAAS,CAACL;IAEnB,IAAIM,uBAAuB,MAAMb,iBAAiBO;IAElD,IAAI,CAACM,sBAAsB;QACzB,MAAM,IAAIC,MAAM,CAAC,WAAW,EAAEP,cAAc,eAAe,CAAC;IAC9D;IAEA,MAAMD,QAAQS,aAAa,eAAC,KAACZ;QAAgBE,MAAMA;QAAMH,MAAMK;;AACjE,GACA;IACES,aAAa;IACbL,SAAS;QACPT,MAAM;YACJe,MAAM;QACR;QACAC,UAAU;YACRD,MAAM;QACR;IACF;AACF,GACA"}
1
+ {"version":3,"sources":["../../../src/commands/create-workspace/createWorkspaceCommand.tsx"],"sourcesContent":["import {Command} from '@jakubmazanec/cli';\n\nimport {CreateWorkspace} from './CreateWorkspace.js';\n\nexport const createWorkspaceCommand = new Command(\n 'create workspace',\n async (args, program) => {\n await program.renderElement(<CreateWorkspace args={args} />);\n },\n {\n description: 'Creates a new workspacee.',\n options: {\n path: {\n type: 'string',\n },\n template: {\n type: 'string',\n },\n },\n },\n);\n"],"names":["Command","CreateWorkspace","createWorkspaceCommand","args","program","renderElement","description","options","path","type","template"],"mappings":";AAAA,SAAQA,OAAO,QAAO,oBAAoB;AAE1C,SAAQC,eAAe,QAAO,uBAAuB;AAErD,OAAO,MAAMC,yBAAyB,IAAIF,QACxC,oBACA,OAAOG,MAAMC;IACX,MAAMA,QAAQC,aAAa,eAAC,KAACJ;QAAgBE,MAAMA;;AACrD,GACA;IACEG,aAAa;IACbC,SAAS;QACPC,MAAM;YACJC,MAAM;QACR;QACAC,UAAU;YACRD,MAAM;QACR;IACF;AACF,GACA"}
@@ -1,24 +1,15 @@
1
- import { isEmptyDirectory } from '@jakubmazanec/fs-utils';
2
- import fs from 'fs-extra';
3
- import path from 'node:path';
4
1
  import Observable from 'zen-observable';
5
2
  import { Workspace } from '../../workspace.js';
6
3
  export function runCreateWorkspace({ workspacePath, templateId, args }) {
7
4
  return new Observable((observer)=>{
8
5
  (async ()=>{
9
- observer.next('TODO');
10
- let resolvedWorkspacePath = path.resolve(workspacePath);
11
- await fs.ensureDir(resolvedWorkspacePath);
12
- let isWorkspacePathEmpty = await isEmptyDirectory(resolvedWorkspacePath);
13
- if (!isWorkspacePathEmpty) {
14
- throw new Error(`Directory "${resolvedWorkspacePath}" must be empty`);
15
- }
16
- // create new workspace
6
+ observer.next('Creating files');
17
7
  let workspace = await Workspace.create({
18
8
  args,
19
- path: resolvedWorkspacePath,
9
+ path: workspacePath,
20
10
  templateId
21
11
  });
12
+ observer.next('Updating the new workspace');
22
13
  await workspace.update({
23
14
  args
24
15
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/create-workspace/runCreateWorkspace.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 createWorkspaceCommand} from './createWorkspaceCommand.js';\nimport {Workspace} from '../../workspace.js';\n\nexport type CreateWorkspaceOptions = {\n workspacePath: string;\n templateId: string;\n args: CommandArguments<typeof createWorkspaceCommand>;\n};\n\nexport type CreateWorkspaceStatus = string;\n\nexport function runCreateWorkspace({workspacePath, templateId, args}: CreateWorkspaceOptions) {\n return new Observable<CreateWorkspaceStatus>((observer) => {\n (async () => {\n observer.next('TODO');\n\n let resolvedWorkspacePath = path.resolve(workspacePath);\n\n await fs.ensureDir(resolvedWorkspacePath);\n\n let isWorkspacePathEmpty = await isEmptyDirectory(resolvedWorkspacePath);\n\n if (!isWorkspacePathEmpty) {\n throw new Error(`Directory \"${resolvedWorkspacePath}\" must be empty`);\n }\n\n // create new workspace\n let workspace = await Workspace.create({\n args,\n path: resolvedWorkspacePath,\n templateId,\n });\n\n await workspace.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","Workspace","runCreateWorkspace","workspacePath","templateId","args","observer","next","resolvedWorkspacePath","resolve","ensureDir","isWorkspacePathEmpty","Error","workspace","create","update","then","complete","catch","error"],"mappings":"AACA,SAAQA,gBAAgB,QAAO,yBAAyB;AACxD,OAAOC,QAAQ,WAAW;AAC1B,OAAOC,UAAU,YAAY;AAC7B,OAAOC,gBAAgB,iBAAiB;AAGxC,SAAQC,SAAS,QAAO,qBAAqB;AAU7C,OAAO,SAASC,mBAAmB,EAACC,aAAa,EAAEC,UAAU,EAAEC,IAAI,EAAyB;IAC1F,OAAO,IAAIL,WAAkC,CAACM;QAC3C,CAAA;YACCA,SAASC,IAAI,CAAC;YAEd,IAAIC,wBAAwBT,KAAKU,OAAO,CAACN;YAEzC,MAAML,GAAGY,SAAS,CAACF;YAEnB,IAAIG,uBAAuB,MAAMd,iBAAiBW;YAElD,IAAI,CAACG,sBAAsB;gBACzB,MAAM,IAAIC,MAAM,CAAC,WAAW,EAAEJ,sBAAsB,eAAe,CAAC;YACtE;YAEA,uBAAuB;YACvB,IAAIK,YAAY,MAAMZ,UAAUa,MAAM,CAAC;gBACrCT;gBACAN,MAAMS;gBACNJ;YACF;YAEA,MAAMS,UAAUE,MAAM,CAAC;gBAACV;YAAI;QAC9B,CAAA,IACGW,IAAI,CAAC;YACJV,SAASW,QAAQ;QACnB,GACCC,KAAK,CAAC,CAACC;YACNb,SAASa,KAAK,CAACA;QACjB;IACJ;AACF"}
1
+ {"version":3,"sources":["../../../src/commands/create-workspace/runCreateWorkspace.ts"],"sourcesContent":["import {type CommandArguments} from '@jakubmazanec/cli';\nimport Observable from 'zen-observable';\n\nimport {type createWorkspaceCommand} from './createWorkspaceCommand.js';\nimport {Workspace} from '../../workspace.js';\n\nexport type CreateWorkspaceOptions = {\n workspacePath: string;\n templateId: string;\n args: CommandArguments<typeof createWorkspaceCommand>;\n};\n\nexport type CreateWorkspaceStatus = string;\n\nexport function runCreateWorkspace({workspacePath, templateId, args}: CreateWorkspaceOptions) {\n return new Observable<CreateWorkspaceStatus>((observer) => {\n (async () => {\n observer.next('Creating files');\n\n let workspace = await Workspace.create({\n args,\n path: workspacePath,\n templateId,\n });\n\n observer.next('Updating the new workspace');\n\n await workspace.update({args});\n })()\n .then(() => {\n observer.complete();\n })\n .catch((error) => {\n observer.error(error);\n });\n });\n}\n"],"names":["Observable","Workspace","runCreateWorkspace","workspacePath","templateId","args","observer","next","workspace","create","path","update","then","complete","catch","error"],"mappings":"AACA,OAAOA,gBAAgB,iBAAiB;AAGxC,SAAQC,SAAS,QAAO,qBAAqB;AAU7C,OAAO,SAASC,mBAAmB,EAACC,aAAa,EAAEC,UAAU,EAAEC,IAAI,EAAyB;IAC1F,OAAO,IAAIL,WAAkC,CAACM;QAC3C,CAAA;YACCA,SAASC,IAAI,CAAC;YAEd,IAAIC,YAAY,MAAMP,UAAUQ,MAAM,CAAC;gBACrCJ;gBACAK,MAAMP;gBACNC;YACF;YAEAE,SAASC,IAAI,CAAC;YAEd,MAAMC,UAAUG,MAAM,CAAC;gBAACN;YAAI;QAC9B,CAAA,IACGO,IAAI,CAAC;YACJN,SAASO,QAAQ;QACnB,GACCC,KAAK,CAAC,CAACC;YACNT,SAASS,KAAK,CAACA;QACjB;IACJ;AACF"}
@@ -0,0 +1 @@
1
+ export type CommandStatus = 'finished' | 'in-progress' | 'not-started';
@@ -0,0 +1,3 @@
1
+ export { };
2
+
3
+ //# sourceMappingURL=CommandStatus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/commands/internals/CommandStatus.ts"],"sourcesContent":["export type CommandStatus = 'finished' | 'in-progress' | 'not-started';\n"],"names":[],"mappings":"AAAA,WAAuE"}
@@ -1 +1,2 @@
1
+ export * from './internals/CommandStatus.js';
1
2
  export * from './internals/packageNameToDirectory.js';
@@ -1,3 +1,4 @@
1
+ export * from './internals/CommandStatus.js';
1
2
  export * from './internals/packageNameToDirectory.js';
2
3
 
3
4
  //# sourceMappingURL=internals.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/internals.ts"],"sourcesContent":["export * from './internals/packageNameToDirectory.js';\n"],"names":[],"mappings":"AAAA,cAAc,wCAAwC"}
1
+ {"version":3,"sources":["../../src/commands/internals.ts"],"sourcesContent":["export * from './internals/CommandStatus.js';\nexport * from './internals/packageNameToDirectory.js';\n"],"names":[],"mappings":"AAAA,cAAc,+BAA+B;AAC7C,cAAc,wCAAwC"}
@@ -49,7 +49,7 @@ export function UpdateWorkspace({ workspace, args }) {
49
49
  icon: icons.success,
50
50
  marginBottom: 1,
51
51
  children: /*#__PURE__*/ _jsx(Text, {
52
- children: "Updating workspace..."
52
+ children: "Updating workspace and projects..."
53
53
  })
54
54
  }),
55
55
  jobs.map((job)=>/*#__PURE__*/ _jsx(Text, {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/update-workspace/UpdateWorkspace.tsx"],"sourcesContent":["import {type CommandArguments, Header, icons, colors, useProgram} from '@jakubmazanec/cli';\nimport chalk from 'chalk';\nimport {Box, Text} from 'ink';\nimport {useEffect, useState} from 'react';\n\nimport {runUpdateWorkspace} from './runUpdateWorkspace.js';\nimport {type updateWorkspaceCommand} from './updateWorkspaceCommand.js';\nimport {type Workspace} from '../../workspace.js';\n\nexport type UpdateWorkspaceProps = {\n args: CommandArguments<typeof updateWorkspaceCommand>;\n workspace: Workspace | Workspace<false>;\n};\n\nexport function UpdateWorkspace({workspace, args}: UpdateWorkspaceProps) {\n let [isFinished, setIsFinished] = useState(false);\n let [jobs, setJobs] = useState<string[]>([]);\n let {exit} = useProgram();\n\n useEffect(() => {\n let subscription = runUpdateWorkspace({workspace, args}).subscribe({\n next(value) {\n setJobs((previousJobs) => [...previousJobs, value]);\n },\n error(error) {\n exit(error);\n },\n complete() {\n setIsFinished(true);\n },\n });\n\n return () => {\n subscription.unsubscribe();\n };\n }, [args, exit, workspace]);\n\n return (\n <Box flexDirection=\"column\">\n <Text>{`Updating workspace at ${chalk[colors.info](workspace.path)}.`}</Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Header showSpinner={!isFinished} icon={icons.success} marginBottom={1}>\n <Text>Updating workspace...</Text>\n </Header>\n\n {jobs.map((job) => (\n <Text key={job}>{`${icons.info} ${job}`}</Text>\n ))}\n </Box>\n\n {isFinished ? (\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","useEffect","useState","runUpdateWorkspace","UpdateWorkspace","workspace","args","isFinished","setIsFinished","jobs","setJobs","exit","subscription","subscribe","next","value","previousJobs","error","complete","unsubscribe","flexDirection","info","path","marginTop","showSpinner","icon","success","marginBottom","map","job"],"mappings":";AAAA,SAA+BA,MAAM,EAAEC,KAAK,EAAEC,MAAM,EAAEC,UAAU,QAAO,oBAAoB;AAC3F,OAAOC,WAAW,QAAQ;AAC1B,SAAQC,GAAG,EAAEC,IAAI,QAAO,MAAM;AAC9B,SAAQC,SAAS,EAAEC,QAAQ,QAAO,QAAQ;AAE1C,SAAQC,kBAAkB,QAAO,0BAA0B;AAS3D,OAAO,SAASC,gBAAgB,EAACC,SAAS,EAAEC,IAAI,EAAuB;IACrE,IAAI,CAACC,YAAYC,cAAc,GAAGN,SAAS;IAC3C,IAAI,CAACO,MAAMC,QAAQ,GAAGR,SAAmB,EAAE;IAC3C,IAAI,EAACS,IAAI,EAAC,GAAGd;IAEbI,UAAU;QACR,IAAIW,eAAeT,mBAAmB;YAACE;YAAWC;QAAI,GAAGO,SAAS,CAAC;YACjEC,MAAKC,KAAK;gBACRL,QAAQ,CAACM,eAAiB;2BAAIA;wBAAcD;qBAAM;YACpD;YACAE,OAAMA,KAAK;gBACTN,KAAKM;YACP;YACAC;gBACEV,cAAc;YAChB;QACF;QAEA,OAAO;YACLI,aAAaO,WAAW;QAC1B;IACF,GAAG;QAACb;QAAMK;QAAMN;KAAU;IAE1B,qBACE,MAACN;QAAIqB,eAAc;;0BACjB,KAACpB;0BAAM,CAAC,sBAAsB,EAAEF,KAAK,CAACF,OAAOyB,IAAI,CAAC,CAAChB,UAAUiB,IAAI,EAAE,CAAC,CAAC;;0BAErE,MAACvB;gBAAIwB,WAAW;gBAAGH,eAAc;;kCAC/B,KAAC1B;wBAAO8B,aAAa,CAACjB;wBAAYkB,MAAM9B,MAAM+B,OAAO;wBAAEC,cAAc;kCACnE,cAAA,KAAC3B;sCAAK;;;oBAGPS,KAAKmB,GAAG,CAAC,CAACC,oBACT,KAAC7B;sCAAgB,CAAC,EAAEL,MAAM0B,IAAI,CAAC,CAAC,EAAEQ,IAAI,CAAC;2BAA5BA;;;YAIdtB,2BACC,KAACb;gBAAO6B,WAAW;gBAAGE,MAAM9B,MAAM+B,OAAO;0BACvC,cAAA,KAAC1B;8BAAK;;iBAEN;;;AAGV"}
1
+ {"version":3,"sources":["../../../src/commands/update-workspace/UpdateWorkspace.tsx"],"sourcesContent":["import {type CommandArguments, Header, icons, colors, useProgram} from '@jakubmazanec/cli';\nimport chalk from 'chalk';\nimport {Box, Text} from 'ink';\nimport {useEffect, useState} from 'react';\n\nimport {runUpdateWorkspace} from './runUpdateWorkspace.js';\nimport {type updateWorkspaceCommand} from './updateWorkspaceCommand.js';\nimport {type Workspace} from '../../workspace.js';\n\nexport type UpdateWorkspaceProps = {\n args: CommandArguments<typeof updateWorkspaceCommand>;\n workspace: Workspace | Workspace<false>;\n};\n\nexport function UpdateWorkspace({workspace, args}: UpdateWorkspaceProps) {\n let [isFinished, setIsFinished] = useState(false);\n let [jobs, setJobs] = useState<string[]>([]);\n let {exit} = useProgram();\n\n useEffect(() => {\n let subscription = runUpdateWorkspace({workspace, args}).subscribe({\n next(value) {\n setJobs((previousJobs) => [...previousJobs, value]);\n },\n error(error) {\n exit(error);\n },\n complete() {\n setIsFinished(true);\n },\n });\n\n return () => {\n subscription.unsubscribe();\n };\n }, [args, exit, workspace]);\n\n return (\n <Box flexDirection=\"column\">\n <Text>{`Updating workspace at ${chalk[colors.info](workspace.path)}.`}</Text>\n\n <Box marginTop={1} flexDirection=\"column\">\n <Header showSpinner={!isFinished} icon={icons.success} marginBottom={1}>\n <Text>Updating workspace and projects...</Text>\n </Header>\n\n {jobs.map((job) => (\n <Text key={job}>{`${icons.info} ${job}`}</Text>\n ))}\n </Box>\n\n {isFinished ? (\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","useEffect","useState","runUpdateWorkspace","UpdateWorkspace","workspace","args","isFinished","setIsFinished","jobs","setJobs","exit","subscription","subscribe","next","value","previousJobs","error","complete","unsubscribe","flexDirection","info","path","marginTop","showSpinner","icon","success","marginBottom","map","job"],"mappings":";AAAA,SAA+BA,MAAM,EAAEC,KAAK,EAAEC,MAAM,EAAEC,UAAU,QAAO,oBAAoB;AAC3F,OAAOC,WAAW,QAAQ;AAC1B,SAAQC,GAAG,EAAEC,IAAI,QAAO,MAAM;AAC9B,SAAQC,SAAS,EAAEC,QAAQ,QAAO,QAAQ;AAE1C,SAAQC,kBAAkB,QAAO,0BAA0B;AAS3D,OAAO,SAASC,gBAAgB,EAACC,SAAS,EAAEC,IAAI,EAAuB;IACrE,IAAI,CAACC,YAAYC,cAAc,GAAGN,SAAS;IAC3C,IAAI,CAACO,MAAMC,QAAQ,GAAGR,SAAmB,EAAE;IAC3C,IAAI,EAACS,IAAI,EAAC,GAAGd;IAEbI,UAAU;QACR,IAAIW,eAAeT,mBAAmB;YAACE;YAAWC;QAAI,GAAGO,SAAS,CAAC;YACjEC,MAAKC,KAAK;gBACRL,QAAQ,CAACM,eAAiB;2BAAIA;wBAAcD;qBAAM;YACpD;YACAE,OAAMA,KAAK;gBACTN,KAAKM;YACP;YACAC;gBACEV,cAAc;YAChB;QACF;QAEA,OAAO;YACLI,aAAaO,WAAW;QAC1B;IACF,GAAG;QAACb;QAAMK;QAAMN;KAAU;IAE1B,qBACE,MAACN;QAAIqB,eAAc;;0BACjB,KAACpB;0BAAM,CAAC,sBAAsB,EAAEF,KAAK,CAACF,OAAOyB,IAAI,CAAC,CAAChB,UAAUiB,IAAI,EAAE,CAAC,CAAC;;0BAErE,MAACvB;gBAAIwB,WAAW;gBAAGH,eAAc;;kCAC/B,KAAC1B;wBAAO8B,aAAa,CAACjB;wBAAYkB,MAAM9B,MAAM+B,OAAO;wBAAEC,cAAc;kCACnE,cAAA,KAAC3B;sCAAK;;;oBAGPS,KAAKmB,GAAG,CAAC,CAACC,oBACT,KAAC7B;sCAAgB,CAAC,EAAEL,MAAM0B,IAAI,CAAC,CAAC,EAAEQ,IAAI,CAAC;2BAA5BA;;;YAIdtB,2BACC,KAACb;gBAAO6B,WAAW;gBAAGE,MAAM9B,MAAM+B,OAAO;0BACvC,cAAA,KAAC1B;8BAAK;;iBAEN;;;AAGV"}
@@ -5,10 +5,9 @@ import { UpdateWorkspace } from './UpdateWorkspace.js';
5
5
  import { Workspace } from '../../workspace.js';
6
6
  export const updateWorkspaceCommand = new Command('update workspace', async (args, program)=>{
7
7
  let resolvedPath = path.resolve(process.cwd(), args.options.path ?? '');
8
- let workspace = await Workspace.findAndRead(resolvedPath);
9
- if (!workspace) {
10
- throw new Error(`No workspace found at "${resolvedPath}"!`);
11
- }
8
+ let workspace = await Workspace.findAndRead(resolvedPath, {
9
+ throwIfNotFound: true
10
+ });
12
11
  await program.renderElement(/*#__PURE__*/ _jsx(UpdateWorkspace, {
13
12
  workspace: workspace,
14
13
  args: args
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/update-workspace/updateWorkspaceCommand.tsx"],"sourcesContent":["import {Command} from '@jakubmazanec/cli';\nimport path from 'node:path';\n\nimport {UpdateWorkspace} from './UpdateWorkspace.js';\nimport {Workspace} from '../../workspace.js';\n\nexport const updateWorkspaceCommand = new Command(\n 'update workspace',\n async (args, program) => {\n let resolvedPath = path.resolve(process.cwd(), args.options.path ?? '');\n let workspace = await Workspace.findAndRead(resolvedPath);\n\n if (!workspace) {\n throw new Error(`No workspace found at \"${resolvedPath}\"!`);\n }\n\n await program.renderElement(<UpdateWorkspace workspace={workspace} args={args} />);\n },\n {\n description: 'Updates files in a workspace.',\n options: {\n path: {\n type: 'string',\n },\n },\n },\n);\n"],"names":["Command","path","UpdateWorkspace","Workspace","updateWorkspaceCommand","args","program","resolvedPath","resolve","process","cwd","options","workspace","findAndRead","Error","renderElement","description","type"],"mappings":";AAAA,SAAQA,OAAO,QAAO,oBAAoB;AAC1C,OAAOC,UAAU,YAAY;AAE7B,SAAQC,eAAe,QAAO,uBAAuB;AACrD,SAAQC,SAAS,QAAO,qBAAqB;AAE7C,OAAO,MAAMC,yBAAyB,IAAIJ,QACxC,oBACA,OAAOK,MAAMC;IACX,IAAIC,eAAeN,KAAKO,OAAO,CAACC,QAAQC,GAAG,IAAIL,KAAKM,OAAO,CAACV,IAAI,IAAI;IACpE,IAAIW,YAAY,MAAMT,UAAUU,WAAW,CAACN;IAE5C,IAAI,CAACK,WAAW;QACd,MAAM,IAAIE,MAAM,CAAC,uBAAuB,EAAEP,aAAa,EAAE,CAAC;IAC5D;IAEA,MAAMD,QAAQS,aAAa,eAAC,KAACb;QAAgBU,WAAWA;QAAWP,MAAMA;;AAC3E,GACA;IACEW,aAAa;IACbL,SAAS;QACPV,MAAM;YACJgB,MAAM;QACR;IACF;AACF,GACA"}
1
+ {"version":3,"sources":["../../../src/commands/update-workspace/updateWorkspaceCommand.tsx"],"sourcesContent":["import {Command} from '@jakubmazanec/cli';\nimport path from 'node:path';\n\nimport {UpdateWorkspace} from './UpdateWorkspace.js';\nimport {Workspace} from '../../workspace.js';\n\nexport const updateWorkspaceCommand = new Command(\n 'update workspace',\n async (args, program) => {\n let resolvedPath = path.resolve(process.cwd(), args.options.path ?? '');\n let workspace = await Workspace.findAndRead(resolvedPath, {throwIfNotFound: true});\n\n await program.renderElement(<UpdateWorkspace workspace={workspace} args={args} />);\n },\n {\n description: 'Updates files in a workspace.',\n options: {\n path: {\n type: 'string',\n },\n },\n },\n);\n"],"names":["Command","path","UpdateWorkspace","Workspace","updateWorkspaceCommand","args","program","resolvedPath","resolve","process","cwd","options","workspace","findAndRead","throwIfNotFound","renderElement","description","type"],"mappings":";AAAA,SAAQA,OAAO,QAAO,oBAAoB;AAC1C,OAAOC,UAAU,YAAY;AAE7B,SAAQC,eAAe,QAAO,uBAAuB;AACrD,SAAQC,SAAS,QAAO,qBAAqB;AAE7C,OAAO,MAAMC,yBAAyB,IAAIJ,QACxC,oBACA,OAAOK,MAAMC;IACX,IAAIC,eAAeN,KAAKO,OAAO,CAACC,QAAQC,GAAG,IAAIL,KAAKM,OAAO,CAACV,IAAI,IAAI;IACpE,IAAIW,YAAY,MAAMT,UAAUU,WAAW,CAACN,cAAc;QAACO,iBAAiB;IAAI;IAEhF,MAAMR,QAAQS,aAAa,eAAC,KAACb;QAAgBU,WAAWA;QAAWP,MAAMA;;AAC3E,GACA;IACEW,aAAa;IACbL,SAAS;QACPV,MAAM;YACJgB,MAAM;QACR;IACF;AACF,GACA"}
@@ -10,6 +10,6 @@ export type CarsonTemplate = {
10
10
  name: string;
11
11
  /** Carson template config. */
12
12
  config: CarsonTemplateConfig;
13
- /** Carson template files, actually instances of {@linkcode Template}. */
13
+ /** Carson template files, actually instances of {@link Template}. */
14
14
  files: Array<Template<typeof templateAttributesSchema, typeof templateDataSchema>>;
15
15
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/template/CarsonTemplate.ts"],"sourcesContent":["import {type Template} from '@jakubmazanec/template';\n\nimport {type CarsonTemplateConfig} from './CarsonTemplateConfig.js';\nimport {type templateAttributesSchema} from './TemplateAttributes.js';\nimport {type templateDataSchema} from './TemplateData.js';\n\n/**\n * Carson template.\n */\nexport type CarsonTemplate = {\n /** Carson template name. */\n\n name: string;\n\n /** Carson template config. */\n config: CarsonTemplateConfig;\n\n /** Carson template files, actually instances of {@linkcode Template}. */\n files: Array<Template<typeof templateAttributesSchema, typeof templateDataSchema>>;\n};\n"],"names":[],"mappings":"AAAA,WAmBE"}
1
+ {"version":3,"sources":["../../src/template/CarsonTemplate.ts"],"sourcesContent":["import {type Template} from '@jakubmazanec/template';\n\nimport {type CarsonTemplateConfig} from './CarsonTemplateConfig.js';\nimport {type templateAttributesSchema} from './TemplateAttributes.js';\nimport {type templateDataSchema} from './TemplateData.js';\n\n/**\n * Carson template.\n */\nexport type CarsonTemplate = {\n /** Carson template name. */\n name: string;\n\n /** Carson template config. */\n config: CarsonTemplateConfig;\n\n /** Carson template files, actually instances of {@link Template}. */\n files: Array<Template<typeof templateAttributesSchema, typeof templateDataSchema>>;\n};\n"],"names":[],"mappings":"AAAA,WAkBE"}
@@ -10,6 +10,6 @@ export declare const carsonTemplateConfigSchema: z.ZodObject<{
10
10
  disallowSingleProjectWorkspace?: boolean | undefined;
11
11
  }>;
12
12
  /**
13
- * Carson teamplate config.
13
+ * Carson template config.
14
14
  */
15
15
  export type CarsonTemplateConfig = z.infer<typeof carsonTemplateConfigSchema>;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/template/CarsonTemplateConfig.ts"],"sourcesContent":["import {z} from 'zod';\n\nexport const carsonTemplateConfigSchema = z\n .object({\n disallowMultiProjectWorkspace: z.boolean().optional(),\n disallowSingleProjectWorkspace: z.boolean().optional(),\n\n // TODO: add extends property to allow reuisng template files from another carson template\n })\n .strict();\n\n/**\n * Carson teamplate config.\n */\nexport type CarsonTemplateConfig = z.infer<typeof carsonTemplateConfigSchema>;\n"],"names":["z","carsonTemplateConfigSchema","object","disallowMultiProjectWorkspace","boolean","optional","disallowSingleProjectWorkspace","strict"],"mappings":"AAAA,SAAQA,CAAC,QAAO,MAAM;AAEtB,OAAO,MAAMC,6BAA6BD,EACvCE,MAAM,CAAC;IACNC,+BAA+BH,EAAEI,OAAO,GAAGC,QAAQ;IACnDC,gCAAgCN,EAAEI,OAAO,GAAGC,QAAQ;AAGtD,GACCE,MAAM,GAAG"}
1
+ {"version":3,"sources":["../../src/template/CarsonTemplateConfig.ts"],"sourcesContent":["import {z} from 'zod';\n\nexport const carsonTemplateConfigSchema = z\n .object({\n disallowMultiProjectWorkspace: z.boolean().optional(),\n disallowSingleProjectWorkspace: z.boolean().optional(),\n\n // TODO: add extends property to allow reuisng template files from another carson template\n })\n .strict();\n\n/**\n * Carson template config.\n */\nexport type CarsonTemplateConfig = z.infer<typeof carsonTemplateConfigSchema>;\n"],"names":["z","carsonTemplateConfigSchema","object","disallowMultiProjectWorkspace","boolean","optional","disallowSingleProjectWorkspace","strict"],"mappings":"AAAA,SAAQA,CAAC,QAAO,MAAM;AAEtB,OAAO,MAAMC,6BAA6BD,EACvCE,MAAM,CAAC;IACNC,+BAA+BH,EAAEI,OAAO,GAAGC,QAAQ;IACnDC,gCAAgCN,EAAEI,OAAO,GAAGC,QAAQ;AAGtD,GACCE,MAAM,GAAG"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * A subclass of `Error` that indicates a Carson template failure.
3
+ */
4
+ export declare const CarsonTemplateError: new (code: "INVALID_CARSON_TEMPLATE_ID" | "CARSON_TEMPLATE_NOT_FOUND" | "STRATEGY_UNSUPPORTED_EXTENSION" | "STRATEGY_MISSING_FILE", options?: import("@jakubmazanec/error").CustomErrorWithDataOptions<{
5
+ path?: string;
6
+ }> | undefined) => import("@jakubmazanec/error").CustomErrorWithData<"INVALID_CARSON_TEMPLATE_ID" | "CARSON_TEMPLATE_NOT_FOUND" | "STRATEGY_UNSUPPORTED_EXTENSION" | "STRATEGY_MISSING_FILE" | "UNKNOWN_ERROR", {
7
+ path?: string;
8
+ }>;
@@ -0,0 +1,13 @@
1
+ import { createCustomErrorWithData } from '@jakubmazanec/error';
2
+ /**
3
+ * A subclass of `Error` that indicates a Carson template failure.
4
+ */ export const CarsonTemplateError = createCustomErrorWithData('CarsonTemplateError', {
5
+ INVALID_CARSON_TEMPLATE_ID: 'Invalid Carson template ID "{0}". Carson template ID must consist of a module ID and a template name separated by a colon.',
6
+ CARSON_TEMPLATE_NOT_FOUND: 'Carson template "{0}" was not found in module "{1}".',
7
+ STRATEGY_UNSUPPORTED_EXTENSION: 'Strategy "{0}" in the template file "{1}" doesn\'t support extension "{2}".',
8
+ STRATEGY_MISSING_FILE: 'Strategy "{0}" in the template file "{1}" is missing file "{2}".'
9
+ }, class CarsonTemplateErrorData {
10
+ path;
11
+ });
12
+
13
+ //# sourceMappingURL=CarsonTemplateError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/template/CarsonTemplateError.ts"],"sourcesContent":["import {createCustomErrorWithData} from '@jakubmazanec/error';\n\n/**\n * A subclass of `Error` that indicates a Carson template failure.\n */\nexport const CarsonTemplateError = createCustomErrorWithData(\n 'CarsonTemplateError',\n {\n INVALID_CARSON_TEMPLATE_ID:\n 'Invalid Carson template ID \"{0}\". Carson template ID must consist of a module ID and a template name separated by a colon.',\n CARSON_TEMPLATE_NOT_FOUND: 'Carson template \"{0}\" was not found in module \"{1}\".',\n STRATEGY_UNSUPPORTED_EXTENSION:\n 'Strategy \"{0}\" in the template file \"{1}\" doesn\\'t support extension \"{2}\".',\n STRATEGY_MISSING_FILE: 'Strategy \"{0}\" in the template file \"{1}\" is missing file \"{2}\".',\n },\n class CarsonTemplateErrorData {\n path?: string;\n },\n);\n"],"names":["createCustomErrorWithData","CarsonTemplateError","INVALID_CARSON_TEMPLATE_ID","CARSON_TEMPLATE_NOT_FOUND","STRATEGY_UNSUPPORTED_EXTENSION","STRATEGY_MISSING_FILE","CarsonTemplateErrorData","path"],"mappings":"AAAA,SAAQA,yBAAyB,QAAO,sBAAsB;AAE9D;;CAEC,GACD,OAAO,MAAMC,sBAAsBD,0BACjC,uBACA;IACEE,4BACE;IACFC,2BAA2B;IAC3BC,gCACE;IACFC,uBAAuB;AACzB,GACA,MAAMC;IACJC,KAAc;AAChB,GACA"}