Skip to content

Commit

Permalink
chore: merge pull request #181
Browse files Browse the repository at this point in the history
  • Loading branch information
ntorga authored Oct 30, 2024
2 parents 02e896c + 01f0fa1 commit ba25439
Show file tree
Hide file tree
Showing 49 changed files with 1,167 additions and 358 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Changelog

```log
0.1.2 - 2024/X/X
refactor(front): marketplace page with HTMX+Alpine.js
0.1.1 - 2024/X/X
refactor(front): accounts page with HTMX+Alpine.js
Expand Down
2 changes: 1 addition & 1 deletion src/domain/valueObject/dataFieldType.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type DataFieldType string

var validDataFieldTypes = []string{
"checkbox", "color", "date", "email", "image", "number", "password", "radio",
"range", "search", "tel", "text", "time", "url",
"range", "search", "select", "tel", "text", "time", "url",
}

func NewDataFieldType(value interface{}) (
Expand Down
2 changes: 1 addition & 1 deletion src/domain/valueObject/dataFieldType_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ func TestDataFieldType(t *testing.T) {
t.Run("ValidDataFieldType", func(t *testing.T) {
validDataFieldTypes := []interface{}{
"checkbox", "color", "date", "email", "image", "number", "password",
"radio", "range", "search", "tel", "text", "time", "url",
"radio", "range", "search", "select", "tel", "text", "time", "url",
}

for _, dataFieldType := range validDataFieldTypes {
Expand Down
2 changes: 1 addition & 1 deletion src/infra/envs/envs.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package infraEnvs

const (
InfiniteOsVersion string = "0.1.1"
InfiniteOsVersion string = "0.1.2"
InfiniteOsBinary string = "/infinite/os"
PersistentDatabaseFilePath string = "/infinite/os.db"
TrailDatabaseFilePath string = "/infinite/trail.db"
Expand Down
20 changes: 10 additions & 10 deletions src/infra/marketplace/assets/adobeCommerce.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
slugs:
- adobe-commerce
- adobeCommerce
- adobe-commerce
- magento2
- mage2
name: AdobeCommerce
name: Adobe Commerce
type: app
description: Adobe Commerce is a commerce platform that lets you create uniquely personalized B2B and B2C experiences, no matter how many brands you have. At least 2GB of RAM is required to run Adobe Commerce.
services:
Expand All @@ -22,7 +22,7 @@ mappings:
dataFields:
- name: locale
label: Adobe Commerce Language
type: text
type: select
defaultValue: en_US
options:
- en_US
Expand All @@ -34,7 +34,7 @@ dataFields:
- fr_FR
- name: timezone
label: Adobe Commerce Timezone
type: text
type: select
defaultValue: America/Los_Angeles
options:
- Africa/Abidjan
Expand Down Expand Up @@ -458,7 +458,7 @@ dataFields:
- UTC
- name: currency
label: Adobe Commerce Currency
type: text
type: select
defaultValue: USD
options:
- AFN
Expand Down Expand Up @@ -746,17 +746,17 @@ dataFields:
- ZWD
- ZWR
- ZWL
- name: adobeCommerceMarketplacePublicKey
label: Adobe Commerce Marketplace Public Key
- name: adobeCommercePublicKey
label: Adobe Commerce Public Key
type: text
isRequired: true
- name: adobeCommerceMarketplacePrivateKey
label: Adobe Commerce Marketplace Private Key
- name: adobeCommercePrivateKey
label: Adobe Commerce Private Key
type: text
isRequired: true
- name: edition
label: Adobe Commerce Edition
type: text
type: select
defaultValue: community
options:
- community
Expand Down
2 changes: 1 addition & 1 deletion src/infra/marketplace/assets/laravel.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
id: 4
slugs:
- laravel
name: laravel
name: Laravel
type: framework
description: Laravel is a web application framework with expressive, elegant syntax. We've already laid the foundation — freeing you to create without sweating the small things.
services:
Expand Down
6 changes: 3 additions & 3 deletions src/infra/marketplace/assets/openmage.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@
{
"name": "locale",
"label": "OpenMage Language",
"type": "text",
"type": "select",
"defaultValue": "en_US",
"options": ["en_US", "pt_BR", "pt_PT", "es_ES", "de_DE", "it_IT", "fr_FR"]
},
{
"name": "timezone",
"label": "OpenMage Timezone",
"type": "text",
"type": "select",
"defaultValue": "America/Los_Angeles",
"options": [
"Africa/Abidjan",
Expand Down Expand Up @@ -456,7 +456,7 @@
{
"name": "currency",
"label": "OpenMage Default Currency",
"type": "text",
"type": "select",
"defaultValue": "USD",
"options": [
"AFN",
Expand Down
2 changes: 1 addition & 1 deletion src/infra/marketplace/assets/wordpress.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
{
"name": "locale",
"label": "WordPress Language",
"type": "text",
"type": "select",
"defaultValue": "en_US",
"options": ["en_US", "pt_BR", "pt_PT", "es_ES", "de_DE", "it_IT", "fr_FR"]
},
Expand Down
19 changes: 16 additions & 3 deletions src/infra/webServer/webServerSetup.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,23 @@ func (ws *WebServerSetup) OnStartSetup() {
log.Fatalf("%sGetNginxWorkersCountFailed", defaultLogPrefix)
}

servicesQueryRepo := servicesInfra.NewServicesQueryRepo(ws.persistentDbSvc)
servicesCmdRepo := servicesInfra.NewServicesCmdRepo(ws.persistentDbSvc)
serviceName, _ := valueObject.NewServiceName("nginx")
if workerCount == cpuCoresStr {
nginxService, err := servicesQueryRepo.ReadByName(serviceName)
if err != nil {
log.Fatalf("ReadNginxServiceFailed: %s", err.Error())
}

if nginxService.Status.String() == "running" {
return
}

err = servicesCmdRepo.Start(serviceName)
if err != nil {
log.Fatalf("StartNginxServiceFailed: %s", err.Error())
}
return
}

Expand All @@ -160,14 +176,11 @@ func (ws *WebServerSetup) OnStartSetup() {
log.Fatalf("%sUpdateNginxWorkersCountFailed", defaultLogPrefix)
}

servicesCmdRepo := servicesInfra.NewServicesCmdRepo(ws.persistentDbSvc)
serviceName, _ := valueObject.NewServiceName("nginx")
err = servicesCmdRepo.Restart(serviceName)
if err != nil {
log.Fatalf("%sRestartNginxFailed", defaultLogPrefix)
}

servicesQueryRepo := servicesInfra.NewServicesQueryRepo(ws.persistentDbSvc)
_, err = servicesQueryRepo.ReadByName("php-webserver")
if err == nil {
err = ws.updatePhpMaxChildProcesses(
Expand Down
2 changes: 1 addition & 1 deletion src/presentation/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const (
)

// @title OsApi
// @version 0.1.1
// @version 0.1.2
// @description Infinite OS API
// @termsOfService https://goinfinite.net/tos/

Expand Down
133 changes: 87 additions & 46 deletions src/presentation/api/controller/marketplace.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package apiController

import (
"errors"
"net/http"
"strconv"
"log/slog"
"strings"

"github.com/goinfinite/os/src/domain/valueObject"
internalDbInfra "github.com/goinfinite/os/src/infra/internalDatabase"
Expand Down Expand Up @@ -41,49 +40,107 @@ func (controller *MarketplaceController) ReadCatalog(c echo.Context) error {
)
}

func (controller *MarketplaceController) parseDataFields(
rawDataFields []interface{},
) ([]valueObject.MarketplaceInstallableItemDataField, error) {
dataFields := []valueObject.MarketplaceInstallableItemDataField{}

for fieldIndex, rawDataField := range rawDataFields {
errPrefix := "[index " + strconv.Itoa(fieldIndex) + "] "
func (controller *MarketplaceController) transformDataFieldsIntoMap(
rawDataFields string,
) []map[string]interface{} {
dataFieldsMapSlice := []map[string]interface{}{}
if len(rawDataFields) == 0 {
return dataFieldsMapSlice
}

rawDataFieldMap, assertOk := rawDataField.(map[string]interface{})
if !assertOk {
return dataFields, errors.New(errPrefix + "InvalidDataFieldStructure")
rawDataFieldsSlice := strings.Split(rawDataFields, ";")
for _, rawDataField := range rawDataFieldsSlice {
rawDataFieldParts := strings.Split(rawDataField, ":")
if len(rawDataFieldParts) != 2 {
slog.Error(
"InvalidDataFieldStringStructure",
slog.String("rawDataField", rawDataField),
)
continue
}

rawName, exists := rawDataFieldMap["name"]
if !exists {
rawName, exists = rawDataFieldMap["key"]
if !exists {
return dataFields, errors.New(errPrefix + "DataFieldNameNotFound")
}
rawDataFieldMap["name"] = rawName
}
dataFieldsMapSlice = append(
dataFieldsMapSlice,
map[string]interface{}{rawDataFieldParts[0]: rawDataFieldParts[1]},
)
}

fieldName, err := valueObject.NewDataFieldName(rawName)
return dataFieldsMapSlice
}

func (controller *MarketplaceController) parseDataFieldMap(
rawDataFields map[string]interface{},
) []valueObject.MarketplaceInstallableItemDataField {
dataFields := []valueObject.MarketplaceInstallableItemDataField{}

fieldIndex := 0
for rawFieldName, rawFieldValue := range rawDataFields {
fieldIndex++

fieldName, err := valueObject.NewDataFieldName(rawFieldName)
if err != nil {
return dataFields, errors.New(errPrefix + err.Error())
slog.Error(err.Error(), slog.Int("fieldIndex", fieldIndex))
continue
}

fieldValue, err := valueObject.NewDataFieldValue(rawDataFieldMap["value"])
fieldValue, err := valueObject.NewDataFieldValue(rawFieldValue)
if err != nil {
return dataFields, errors.New(errPrefix + err.Error())
slog.Error(err.Error(), slog.String("fieldName", fieldName.String()))
continue
}

dataField, err := valueObject.NewMarketplaceInstallableItemDataField(
fieldName, fieldValue,
)
if err != nil {
return dataFields, errors.New(errPrefix + err.Error())
slog.Error(
err.Error(),
slog.String("fieldName", fieldName.String()),
slog.String("fieldValue", fieldValue.String()),
)
continue
}

dataFields = append(dataFields, dataField)
}

return dataFields, nil
return dataFields
}

// DataFields has multiple possible structures which this parser can handle:
// "dataFieldName:dataFieldValue;dataFieldName:dataFieldValue" (string slice, semicolon separated items)
// { "dataFieldName": "dataFieldValue" } (map[string]interface{})
// [{ "dataFieldName": "dataFieldValue" }] (map[string]interface{} slice)
func (controller *MarketplaceController) parseDataFields(
dataFieldsAsUnknownType any,
) []valueObject.MarketplaceInstallableItemDataField {
dataFields := []valueObject.MarketplaceInstallableItemDataField{}

rawDataFieldsSlice := []interface{}{}
switch dataFieldsValues := dataFieldsAsUnknownType.(type) {
case map[string]interface{}:
rawDataFieldsSlice = []interface{}{dataFieldsValues}
case string:
dataFieldsMaps := controller.transformDataFieldsIntoMap(dataFieldsValues)
for _, dataFieldMap := range dataFieldsMaps {
rawDataFieldsSlice = append(rawDataFieldsSlice, dataFieldMap)
}
case []interface{}:
rawDataFieldsSlice = dataFieldsValues
}

for _, rawDataField := range rawDataFieldsSlice {
rawDataFieldMap, assertOk := rawDataField.(map[string]interface{})
if !assertOk {
slog.Error(
"InvalidDataFieldStructure", slog.Any("rawDataField", rawDataField),
)
continue
}
dataFields = append(dataFields, controller.parseDataFieldMap(rawDataFieldMap)...)
}

return dataFields
}

// InstallCatalogItem godoc
Expand All @@ -93,7 +150,7 @@ func (controller *MarketplaceController) parseDataFields(
// @Accept json
// @Produce json
// @Param InstallMarketplaceCatalogItem body dto.InstallMarketplaceCatalogItem true "urlPath is both the install directory and HTTP sub-directory."
// @Success 201 {object} object{} "MarketplaceCatalogItemInstalled"
// @Success 201 {object} object{} "MarketplaceCatalogItemInstallationScheduled"
// @Router /v1/marketplace/catalog/ [post]
func (controller *MarketplaceController) InstallCatalogItem(c echo.Context) error {
requestBody, err := apiHelper.ReadRequestBody(c)
Expand All @@ -112,23 +169,7 @@ func (controller *MarketplaceController) InstallCatalogItem(c echo.Context) erro
}

if requestBody["dataFields"] != nil {
_, isMapStringInterface := requestBody["dataFields"].(map[string]interface{})
if isMapStringInterface {
requestBody["dataFields"] = []interface{}{requestBody["dataFields"]}
}

dataFieldsSlice, assertOk := requestBody["dataFields"].([]interface{})
if !assertOk {
return apiHelper.ResponseWrapper(
c, http.StatusBadRequest, "DataFieldsMustBeArray",
)
}

dataFields, err := controller.parseDataFields(dataFieldsSlice)
if err != nil {
return apiHelper.ResponseWrapper(c, http.StatusBadRequest, err.Error())
}
requestBody["dataFields"] = dataFields
requestBody["dataFields"] = controller.parseDataFields(requestBody["dataFields"])
}

return apiHelper.ServiceResponseWrapper(
Expand Down Expand Up @@ -172,6 +213,6 @@ func (controller *MarketplaceController) DeleteInstalledItem(c echo.Context) err
}

return apiHelper.ServiceResponseWrapper(
c, controller.marketplaceService.DeleteInstalledItem(requestBody),
c, controller.marketplaceService.DeleteInstalledItem(requestBody, true),
)
}
4 changes: 2 additions & 2 deletions src/presentation/api/docs/docs.go
Original file line number Diff line number Diff line change
Expand Up @@ -970,7 +970,7 @@ const docTemplate = `{
],
"responses": {
"201": {
"description": "MarketplaceCatalogItemInstalled",
"description": "MarketplaceCatalogItemInstallationScheduled",
"schema": {
"type": "object"
}
Expand Down Expand Up @@ -3247,7 +3247,7 @@ const docTemplate = `{

// SwaggerInfo holds exported Swagger Info so clients can modify it
var SwaggerInfo = &swag.Spec{
Version: "0.1.1",
Version: "0.1.2",
Host: "localhost:1618",
BasePath: "/api",
Schemes: []string{},
Expand Down
Loading

0 comments on commit ba25439

Please sign in to comment.