@@ -24,6 +24,7 @@ interface ServerConfig {
24
24
bunVersion? : string
25
25
database? : string
26
26
databaseName? : string
27
+ searchEngine? : string
27
28
userData? : string
28
29
}
29
30
@@ -652,17 +653,20 @@ export class StacksInfrastructureStack extends cdk.Stack {
652
653
const addServer = () => {
653
654
const id = Object .keys (cloudConfig .value .servers ).length + 1
654
655
const key = ` app${id } `
655
- cloudConfig . value . servers [ key ] = {
656
- name: ` app-server-${ id } ` ,
656
+ const newServer : ServerConfig = {
657
+ name: ` app-${ generateServerName ( ' app ' ) } ` ,
657
658
domain: ' stacksjs.org' ,
658
659
region: ' us-east-1' ,
659
660
type: ' app' ,
660
- size: ' t3.micro' ,
661
+ size: ' t3.micro' as InstanceType ,
661
662
diskSize: 20 ,
662
663
serverOS: defaultServerOS ,
663
664
bunVersion: defaultBunVersion ,
665
+ database: ' sqlite' ,
666
+ databaseName: ' stacks' ,
667
+ searchEngine: ' meilisearch'
664
668
}
665
- // Set edit mode for new server
669
+ cloudConfig . value . servers [ key ] = newServer
666
670
editMode .value [key ] = true
667
671
}
668
672
@@ -730,6 +734,72 @@ const saveWorkerConfig = async () => {
730
734
const formatFieldName = (field : string ) => {
731
735
return field .charAt (0 ).toUpperCase () + field .slice (1 )
732
736
}
737
+
738
+ // Add these functions after the formatFieldName function
739
+ const adjectives = [
740
+ ' weathered' , ' cosmic' , ' stellar' , ' quantum' , ' nebula' , ' astral' , ' galactic' , ' lunar' , ' solar' , ' celestial' ,
741
+ ' mystic' , ' ethereal' , ' void' , ' nova' , ' pulsar' , ' quasar' , ' cosmic' , ' starlit' , ' orbital' , ' meteor' ,
742
+ ' ancient' , ' blazing' , ' crystal' , ' digital' , ' electric' , ' fusion' , ' glowing' , ' hyper' , ' infinite' , ' kinetic' ,
743
+ ' luminous' , ' magnetic' , ' neon' , ' omega' , ' plasma' , ' radiant' , ' sonic' , ' temporal' , ' ultra' , ' virtual' ,
744
+ ' wild' , ' xenon' , ' zero' , ' atomic' , ' binary' , ' cyber' , ' dynamic' , ' eternal' , ' flux' , ' gamma'
745
+ ]
746
+
747
+ const nouns = [
748
+ ' galaxy' , ' nebula' , ' star' , ' comet' , ' aurora' , ' horizon' , ' nova' , ' zenith' , ' cosmos' , ' orbit' ,
749
+ ' vertex' , ' prism' , ' nexus' , ' cipher' , ' matrix' , ' beacon' , ' pulse' , ' echo' , ' flux' , ' core' ,
750
+ ' aegis' , ' blade' , ' cloud' , ' dawn' , ' edge' , ' forge' , ' grid' , ' helix' , ' iris' , ' jade' ,
751
+ ' knight' , ' light' , ' mist' , ' node' , ' oasis' , ' path' , ' quark' , ' rift' , ' sage' , ' titan' ,
752
+ ' unity' , ' vortex' , ' wave' , ' xray' , ' yeti' , ' zephyr' , ' atlas' , ' byte' , ' crest' , ' delta'
753
+ ]
754
+
755
+ const generateServerName = (type : string ) => {
756
+ const adj = adjectives [Math .floor (Math .random () * adjectives .length )]
757
+ const noun = nouns [Math .floor (Math .random () * nouns .length )]
758
+ return ` ${adj }-${noun } `
759
+ }
760
+
761
+ // Update server name when type changes
762
+ const updateServerName = (server : ServerConfig , type : string ) => {
763
+ const prefix = type === ' app' ? ' app' :
764
+ type === ' web' ? ' web' :
765
+ type === ' worker' ? ' worker' :
766
+ type === ' cache' ? ' cache' :
767
+ type === ' database' ? ' db' :
768
+ type === ' search' ? ' search' :
769
+ type === ' loadbalancer' ? ' lb' : ' server'
770
+
771
+ server .name = ` ${prefix }-${generateServerName (type )} `
772
+ }
773
+
774
+ // Update the updateServerDefaults function
775
+ const updateServerDefaults = (server : ServerConfig ) => {
776
+ // Reset database and search engine based on server type
777
+ if (server .type === ' web' ) {
778
+ server .database = ' '
779
+ server .searchEngine = ' '
780
+ } else if (server .type === ' loadbalancer' || server .type === ' cache' ) {
781
+ server .database = ' '
782
+ server .searchEngine = ' '
783
+ server .bunVersion = ' '
784
+ } else if (server .type === ' database' ) {
785
+ server .searchEngine = ' '
786
+ server .bunVersion = ' '
787
+ server .database = server .database || ' sqlite'
788
+ server .databaseName = server .databaseName || ' stacks'
789
+ } else if (server .type === ' search' ) {
790
+ server .database = ' '
791
+ server .databaseName = ' '
792
+ server .bunVersion = ' '
793
+ server .searchEngine = server .searchEngine || ' meilisearch'
794
+ }
795
+ }
796
+
797
+ // Add a watcher for server type changes
798
+ watch (() => Object .values (cloudConfig .value .servers ), (servers ) => {
799
+ servers .forEach (server => {
800
+ updateServerDefaults (server )
801
+ })
802
+ }, { deep: true })
733
803
</script >
734
804
735
805
<template >
@@ -886,11 +956,20 @@ const formatFieldName = (field: string) => {
886
956
<div class =" grid grid-cols-1 gap-6 sm:grid-cols-2" >
887
957
<div >
888
958
<label class =" block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" >Name</label >
889
- <input
890
- v-model =" workerConfig.name"
891
- type =" text"
892
- class =" block w-full h-9 text-sm border-0 rounded-md bg-gray-50 dark:bg-blue-gray-600 py-1.5 px-3 text-gray-900 dark:text-gray-100 ring-1 ring-inset ring-gray-300 dark:ring-gray-600 focus:ring-2 focus:ring-blue-600"
893
- >
959
+ <div class =" flex gap-2" >
960
+ <input
961
+ v-model =" workerConfig.name"
962
+ type =" text"
963
+ class =" block w-full h-10 text-sm border-0 rounded-md bg-gray-50 dark:bg-blue-gray-600 py-2 px-3 text-gray-900 dark:text-gray-100 ring-1 ring-inset ring-gray-300 dark:ring-gray-600 focus:ring-2 focus:ring-blue-600 transition-colors duration-200"
964
+ >
965
+ <button
966
+ @click =" workerConfig.name = generateServerName('worker')"
967
+ type =" button"
968
+ class =" inline-flex items-center px-3 py-2 text-sm font-medium text-white bg-blue-600 rounded-md shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 transition-colors duration-200"
969
+ >
970
+ <div class =" i-heroicons-sparkles w-5 h-5" ></div >
971
+ </button >
972
+ </div >
894
973
</div >
895
974
896
975
<div >
@@ -1060,11 +1139,20 @@ const formatFieldName = (field: string) => {
1060
1139
<div v-else class =" grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3" >
1061
1140
<div >
1062
1141
<label class =" block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" >Name</label >
1063
- <input
1064
- v-model =" server.name"
1065
- type =" text"
1066
- class =" block w-full h-10 text-sm border-0 rounded-md bg-gray-50 dark:bg-blue-gray-600 py-2 px-3 text-gray-900 dark:text-gray-100 ring-1 ring-inset ring-gray-300 dark:ring-gray-600 focus:ring-2 focus:ring-blue-600 transition-colors duration-200"
1067
- >
1142
+ <div class =" flex gap-2" >
1143
+ <input
1144
+ v-model =" server.name"
1145
+ type =" text"
1146
+ class =" block w-full h-10 text-sm border-0 rounded-md bg-gray-50 dark:bg-blue-gray-600 py-2 px-3 text-gray-900 dark:text-gray-100 ring-1 ring-inset ring-gray-300 dark:ring-gray-600 focus:ring-2 focus:ring-blue-600 transition-colors duration-200"
1147
+ >
1148
+ <button
1149
+ @click =" server.name = generateServerName(server.type)"
1150
+ type =" button"
1151
+ class =" inline-flex items-center px-3 py-2 text-sm font-medium text-white bg-blue-600 rounded-md shadow-sm hover:bg-blue-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-blue-600 transition-colors duration-200"
1152
+ >
1153
+ <div class =" i-heroicons-sparkles w-5 h-5" ></div >
1154
+ </button >
1155
+ </div >
1068
1156
</div >
1069
1157
<div >
1070
1158
<label class =" block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" >Domain</label >
@@ -1091,6 +1179,7 @@ const formatFieldName = (field: string) => {
1091
1179
<select
1092
1180
v-model =" server.type"
1093
1181
:disabled =" !editMode[key]"
1182
+ @change =" updateServerName(server, server.type)"
1094
1183
class =" block w-full h-10 text-sm border-0 rounded-md bg-gray-50 dark:bg-blue-gray-600 py-2 px-3 text-gray-900 dark:text-gray-100 ring-1 ring-inset ring-gray-300 dark:ring-gray-600 focus:ring-2 focus:ring-blue-600 transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed"
1095
1184
>
1096
1185
<option v-for =" type in serverTypes" :key =" type.value" :value =" type.value" >
@@ -1099,31 +1188,31 @@ const formatFieldName = (field: string) => {
1099
1188
</select >
1100
1189
</div >
1101
1190
</div >
1102
- <div >
1191
+ <div v-if = " ['app', 'web', 'worker'].includes(server.type) " >
1103
1192
<label class =" block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" >Bun Version</label >
1104
1193
<select
1105
1194
v-model =" server.bunVersion"
1106
1195
class =" block w-full h-10 text-sm border-0 rounded-md bg-gray-50 dark:bg-blue-gray-600 py-2 px-3 text-gray-900 dark:text-gray-100 ring-1 ring-inset ring-gray-300 dark:ring-gray-600 focus:ring-2 focus:ring-blue-600 transition-colors duration-200"
1107
1196
>
1197
+ <option value =" " disabled >Select a version</option >
1108
1198
<option v-for =" version in bunVersions" :key =" version" :value =" version" >
1109
1199
{{ version }}
1110
1200
</option >
1111
1201
</select >
1112
1202
</div >
1113
- <div >
1203
+ <div v-if = " !['loadbalancer', 'cache', 'search', 'database'].includes(server.type) " >
1114
1204
<label class =" block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" >Database</label >
1115
1205
<select
1116
1206
v-model =" server.database"
1117
1207
class =" block w-full h-10 text-sm border-0 rounded-md bg-gray-50 dark:bg-blue-gray-600 py-2 px-3 text-gray-900 dark:text-gray-100 ring-1 ring-inset ring-gray-300 dark:ring-gray-600 focus:ring-2 focus:ring-blue-600 transition-colors duration-200"
1118
1208
>
1119
- <option value =" " >None</option >
1209
+ <option value =" " v-if = " server.type !== 'database' " >None</option >
1120
1210
<option value =" mysql" >MySQL</option >
1121
1211
<option value =" postgresql" >PostgreSQL</option >
1122
1212
<option value =" sqlite" >SQLite</option >
1123
- <option value =" mongodb" >MongoDB</option >
1124
1213
</select >
1125
1214
</div >
1126
- <div v-if =" server.database" >
1215
+ <div v-if =" server.database && !['loadbalancer', 'cache', 'search'].includes(server.type) " >
1127
1216
<label class =" block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" >Database Name</label >
1128
1217
<input
1129
1218
v-model =" server.databaseName"
@@ -1152,6 +1241,17 @@ const formatFieldName = (field: string) => {
1152
1241
class =" block w-full h-10 text-sm border-0 rounded-md bg-gray-50 dark:bg-blue-gray-600 py-2 px-3 text-gray-900 dark:text-gray-100 ring-1 ring-inset ring-gray-300 dark:ring-gray-600 focus:ring-2 focus:ring-blue-600 transition-colors duration-200"
1153
1242
>
1154
1243
</div >
1244
+ <div v-if =" !['loadbalancer', 'cache', 'search', 'database'].includes(server.type)" >
1245
+ <label class =" block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" >Search Engine</label >
1246
+ <select
1247
+ v-model =" server.searchEngine"
1248
+ class =" block w-full h-10 text-sm border-0 rounded-md bg-gray-50 dark:bg-blue-gray-600 py-2 px-3 text-gray-900 dark:text-gray-100 ring-1 ring-inset ring-gray-300 dark:ring-gray-600 focus:ring-2 focus:ring-blue-600 transition-colors duration-200"
1249
+ >
1250
+ <option value =" " >None</option >
1251
+ <option value =" meilisearch" >Meilisearch</option >
1252
+ <option value =" typesense" >Typesense</option >
1253
+ </select >
1254
+ </div >
1155
1255
<div class =" sm:col-span-2 lg:col-span-3" >
1156
1256
<label class =" block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" >User Data Script</label >
1157
1257
<textarea
0 commit comments