11import fs from "node:fs/promises" ;
22import path from "node:path" ;
33import { injectable } from "inversify" ;
4- import { parse as parseToml , stringify as stringifyToml } from "smol-toml" ;
4+ import { parse as parseToml } from "smol-toml" ;
55import {
66 type CreateEnvironmentInput ,
77 type Environment ,
8- type EnvironmentAction ,
98 environmentSchema ,
9+ slugifyEnvironmentName ,
1010 type UpdateEnvironmentInput ,
1111} from "./schemas" ;
1212
@@ -16,11 +16,41 @@ function environmentsDir(repoPath: string): string {
1616 return path . join ( repoPath , ENVIRONMENTS_DIR ) ;
1717}
1818
19- function slugify ( name : string ) : string {
20- return name
21- . toLowerCase ( )
22- . replace ( / [ ^ a - z 0 - 9 ] + / g, "-" )
23- . replace ( / ^ - + | - + $ / g, "" ) ;
19+ function tomlString ( value : string ) : string {
20+ if ( value . includes ( "\n" ) ) {
21+ return `'''\n${ value } '''` ;
22+ }
23+ return JSON . stringify ( value ) ;
24+ }
25+
26+ function serializeEnvironment ( env : Environment ) : string {
27+ const lines : string [ ] = [ ] ;
28+
29+ lines . push ( `id = ${ JSON . stringify ( env . id ) } # DO NOT EDIT MANUALLY` ) ;
30+ lines . push ( `version = ${ env . version } ` ) ;
31+ lines . push ( "" ) ;
32+ lines . push ( `name = ${ JSON . stringify ( env . name ) } ` ) ;
33+
34+ if ( env . setup ?. script ) {
35+ lines . push ( "" ) ;
36+ lines . push ( "[setup]" ) ;
37+ lines . push ( `script = ${ tomlString ( env . setup . script ) } ` ) ;
38+ }
39+
40+ if ( env . actions && env . actions . length > 0 ) {
41+ for ( const action of env . actions ) {
42+ lines . push ( "" ) ;
43+ lines . push ( "[[actions]]" ) ;
44+ lines . push ( `name = ${ JSON . stringify ( action . name ) } ` ) ;
45+ if ( action . icon ) {
46+ lines . push ( `icon = ${ JSON . stringify ( action . icon ) } ` ) ;
47+ }
48+ lines . push ( `command = ${ tomlString ( action . command ) } ` ) ;
49+ }
50+ }
51+
52+ lines . push ( "" ) ;
53+ return lines . join ( "\n" ) ;
2454}
2555
2656interface ScannedEnvironment {
@@ -102,25 +132,17 @@ export class EnvironmentService {
102132 const dir = environmentsDir ( repoPath ) ;
103133 await fs . mkdir ( dir , { recursive : true } ) ;
104134
105- const id = crypto . randomUUID ( ) ;
106- const actions : EnvironmentAction [ ] | undefined = input . actions ?. map (
107- ( a ) => ( {
108- ...a ,
109- id : crypto . randomUUID ( ) ,
110- } ) ,
111- ) ;
112-
113135 const environment : Environment = {
114- id,
136+ id : crypto . randomUUID ( ) ,
115137 version : 1 ,
116138 name : input . name ,
117139 setup : input . setup ,
118- actions,
140+ actions : input . actions ,
119141 } ;
120142
121- const slug = slugify ( input . name ) ;
143+ const slug = slugifyEnvironmentName ( input . name ) ;
122144 const filePath = await this . uniqueFilePath ( dir , slug || "environment" ) ;
123- await fs . writeFile ( filePath , stringifyToml ( environment ) , "utf-8" ) ;
145+ await fs . writeFile ( filePath , serializeEnvironment ( environment ) , "utf-8" ) ;
124146
125147 return environment ;
126148 }
@@ -136,22 +158,15 @@ export class EnvironmentService {
136158
137159 const existing = found . environment ;
138160
139- const actions : EnvironmentAction [ ] | undefined = input . actions ?. map (
140- ( a ) => ( {
141- ...a ,
142- id : a . id ?? crypto . randomUUID ( ) ,
143- } ) ,
144- ) ;
145-
146161 const updated : Environment = {
147162 id : existing . id ,
148163 version : existing . version ,
149164 name : input . name ?? existing . name ,
150165 setup : input . setup !== undefined ? input . setup : existing . setup ,
151- actions : actions !== undefined ? actions : existing . actions ,
166+ actions : input . actions !== undefined ? input . actions : existing . actions ,
152167 } ;
153168
154- await fs . writeFile ( found . filePath , stringifyToml ( updated ) , "utf-8" ) ;
169+ await fs . writeFile ( found . filePath , serializeEnvironment ( updated ) , "utf-8" ) ;
155170
156171 return updated ;
157172 }
0 commit comments