diff --git a/application-templates/django-fastapi/backend/django_baseapp/settings.py b/application-templates/django-fastapi/backend/django_baseapp/settings.py index bc58437b3..78ba0cbc9 100644 --- a/application-templates/django-fastapi/backend/django_baseapp/settings.py +++ b/application-templates/django-fastapi/backend/django_baseapp/settings.py @@ -20,7 +20,7 @@ # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/ -# SECURITY WARNING: keep the secret key used in production secret! TODO change this +# SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = "django-insecure-81kv$0=07xac7r(pgz6ndb5t0at4-z@ae6&f@u6_3jo&9d#4kl" # SECURITY WARNING: don't run with debug turned on in production! @@ -164,4 +164,3 @@ ] KC_DEFAULT_USER_ROLE = None # don't add the user role to the realm default role -SESSION_COOKIE_AGE = 3600 diff --git a/application-templates/django-ninja/backend/django_baseapp/settings.py b/application-templates/django-ninja/backend/django_baseapp/settings.py index be59d8823..e54f20f0d 100644 --- a/application-templates/django-ninja/backend/django_baseapp/settings.py +++ b/application-templates/django-ninja/backend/django_baseapp/settings.py @@ -20,7 +20,7 @@ # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/ -# SECURITY WARNING: keep the secret key used in production secret! TODO change this +# SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = "django-insecure-81kv$0=07xac7r(pgz6ndb5t0at4-z@ae6&f@u6_3jo&9d#4kl" # SECURITY WARNING: don't run with debug turned on in production! @@ -165,4 +165,3 @@ ] KC_DEFAULT_USER_ROLE = None # don't add the user role to the realm default role -SESSION_COOKIE_AGE = 3600 diff --git a/application-templates/flask-server/backend/requirements.txt b/application-templates/flask-server/backend/requirements.txt index d63e3bb37..43562728e 100644 --- a/application-templates/flask-server/backend/requirements.txt +++ b/application-templates/flask-server/backend/requirements.txt @@ -1,6 +1,7 @@ -connexion[swagger-ui,flask,gunicorn]>=3.0.0,<4.0.0 -swagger-ui-bundle>=1.1.0 -python_dateutil >= 2.9.0 +connexion[swagger-ui]==2.14.2 +Flask == 2.2.5 +swagger-ui-bundle==0.0.9 +python_dateutil >= 2.6.0 setuptools >= 21.0.0 -gunicorn + diff --git a/applications/accounts/Dockerfile b/applications/accounts/Dockerfile index 5e10566d9..19c330c13 100644 --- a/applications/accounts/Dockerfile +++ b/applications/accounts/Dockerfile @@ -1,4 +1,4 @@ -FROM quay.io/keycloak/keycloak:26.4 +FROM quay.io/keycloak/keycloak:26.4.0 EXPOSE 9000 EXPOSE 8080 @@ -12,7 +12,7 @@ USER keycloak COPY themes/custom /opt/keycloak/themes/custom # # keycloak kafka listener plugin -COPY plugins/* /opt/keycloak/providers/ +COPY plugins/metacell-admin-event-listener-module-1.0.0.jar /opt/keycloak/providers/ ENTRYPOINT [ "/opt/keycloak/bin/kc-entrypoint.sh" ] -CMD [ "start", "--import-realm" ] +CMD [ "start-dev", "--import-realm", "--health-enabled=true", "--metrics-enabled=true" ] \ No newline at end of file diff --git a/applications/accounts/admin-event-listener/README.md b/applications/accounts/admin-event-listener/README.md index 08e96d6c2..ab7c9f6ef 100755 --- a/applications/accounts/admin-event-listener/README.md +++ b/applications/accounts/admin-event-listener/README.md @@ -3,7 +3,7 @@ ## Building ``` mvn clean install -cp ./ear-module/target/metacell-admin-event-listener-bundle-0.1.0.ear ../plugins/ +cp ./jar-module/target/metacell-admin-event-listener-module-1.0.0.jar ../plugins/ ``` ## Install diff --git a/applications/accounts/deploy/resources/realm.json b/applications/accounts/deploy/resources/realm.json index def7e2971..af17f73da 100644 --- a/applications/accounts/deploy/resources/realm.json +++ b/applications/accounts/deploy/resources/realm.json @@ -1,177 +1,24 @@ -{{- define "deploy_accounts_utils.role" }} - { - "id": {{ uuidv4 | quote }}, - "name": {{ .role| quote }}, - "composite": false, - "clientRole": true, - "containerId": {{ .app.harness.name | quote }}, - "attributes": {} - } -{{- end}} -{{- define "deploy_accounts_utils.user" }} - { - "username": {{ .user.username | default .user.email | quote }}, - "email": {{ .user.email | default .user.username | quote }}, - "enabled": true, - "firstName": {{ .user.firstName | default "Test" | quote }}, - "lastName": {{ .user.lastName | default "User" | quote }}, - "credentials": [ - { - "type": "password", - "value": {{ .user.password | default "test" | quote }} - } - ], - "realmRoles": {{ .user.realmRoles | toJson }}, - "clientRoles": { - {{ .app.harness.name | quote }}: {{ .user.clientRoles | toJson }} - } - } - -{{- end}} { "id": {{ .Values.namespace | quote }}, "realm": {{ .Values.namespace | quote }}, "enabled": true, "sslRequired": {{ ternary "none" "external" (not .Values.tls) | quote }}, - "loginTheme": "keycloak", - "accountTheme": "keycloak", - "adminTheme": "keycloak", - "emailTheme": "keycloak", - "registrationAllowed": true, - "registrationEmailAsUsername": false, + "loginTheme": {{ .Values.apps.accounts.theme.login | default "keycloak" | quote }}, + "accountTheme": {{ .Values.apps.accounts.theme.account | default "keycloak" | quote }}, + "adminTheme": {{ .Values.apps.accounts.theme.admiin | default "keycloak" | quote }}, + "emailTheme": {{ .Values.apps.accounts.theme.email | default "keycloak" | quote }}, + "registrationAllowed": {{ .Values.apps.accounts.registrationAllowed | default true }}, + "registrationEmailAsUsername": {{ .Values.apps.accounts.registrationEmailAsUsername | default false }}, "rememberMe": true, "verifyEmail": false, "loginWithEmailAllowed": true, "duplicateEmailsAllowed": false, "resetPasswordAllowed": true, - "editUsernameAllowed": true, - "components": { - "org.keycloak.userprofile.UserProfileProvider": [ - { - "id": "002b69df-9702-40dd-b73e-3a66d161bf11", - "providerId": "declarative-user-profile", - "subComponents": {}, - "config": { - "kc.user.profile.config": [ - "{\"attributes\":[{\"name\":\"username\",\"displayName\":\"${username}\",\"validations\":{\"length\":{\"min\":3,\"max\":255},\"username-prohibited-characters\":{},\"up-username-not-idn-homograph\":{}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"email\",\"displayName\":\"${email}\",\"validations\":{\"email\":{},\"length\":{\"max\":255}},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"firstName\",\"displayName\":\"${firstName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"lastName\",\"displayName\":\"${lastName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false}],\"groups\":[{\"name\":\"user-metadata\",\"displayHeader\":\"User metadata\",\"displayDescription\":\"Attributes, which refer to user metadata\"}]}" - ] - } - } - ], - "org.keycloak.keys.KeyProvider": [ - { - "id": "e632ce46-36ad-421a-b1a5-776383cc1565", - "name": "rsa-generated", - "providerId": "rsa-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ] - } - }, - { - "id": "b68bee45-a8f0-46ca-b7d9-0df90189736a", - "name": "hmac-generated-hs512", - "providerId": "hmac-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ], - "algorithm": [ - "HS512" - ] - } - }, - { - "id": "55960a57-af77-4f4c-8b6e-925c74bb44db", - "name": "aes-generated", - "providerId": "aes-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ] - } - }, - { - "id": "ce068675-5cae-434e-851f-09f653ccc604", - "name": "rsa-enc-generated", - "providerId": "rsa-enc-generated", - "subComponents": {}, - "config": { - "priority": [ - "100" - ], - "algorithm": [ - "RSA-OAEP" - ] - } - } - ] - }, - "users": [ - {{- $j := 0}} - {{- range $app := .Values.apps }} - {{- if (hasKey $app.harness "accounts") }} - {{- if $j}},{{end}} - {{- if $app.harness.accounts.users}} - {{- $j = add1 $j }} - {{- end }} - {{- range $i, $user := $app.harness.accounts.users }}{{if $i}},{{end}} - {{ include "deploy_accounts_utils.user" (dict "root" $ "app" $app "user" $user) }} - {{- end }} - {{- end }} - - {{- end }} - ], - "roles": { - "realm": [ - { - "id": "70835ad6-1454-4bc5-86a4-f1597e776b75", - "name": {{ .Values.apps.accounts.admin.role | quote }}, - "composite": false, - "clientRole": false, - "containerId": {{ .Values.namespace | quote }}, - "attributes": {} - }, - { - "id": "498353dd-88eb-4a5e-99b8-d912e0f20f23", - "name": "uma_authorization", - "description": "${role_uma_authorization}", - "composite": false, - "clientRole": false, - "containerId": {{ .Values.namespace | quote }}, - "attributes": {} - }, - { - "id": "f99970f1-958b-4bb8-8b39-0d7498b0ecc4", - "name": "offline_access", - "description": "${role_offline-access}", - "composite": false, - "clientRole": false, - "containerId": {{ .Values.namespace | quote }}, - "attributes": {} - } - ], - "client": { - {{- $k := 0}} - {{- range $app := .Values.apps }} - - {{- if (hasKey $app.harness "accounts") }} - {{- if $k}},{{end}} - {{ $app.harness.name | quote }}: [ - {{- range $i, $role := $app.harness.accounts.roles }} - {{if $i}},{{end}} - {{- include "deploy_accounts_utils.role" (dict "root" $ "app" $app "role" $role) }} - {{- end }} - ] - {{- $k = add1 $k }} - {{- end }} - {{- end }} - } - }, + "editUsernameAllowed": {{ .Values.apps.accounts.editUsernameAllowed }}, + {{- include "deploy_accounts_utils.events" (dict "app" .Values.apps.accounts) | indent 8 -}} + {{- include "deploy_accounts_utils.identity_providers" (dict "app" .Values.apps.accounts) | indent 8 -}} + {{- include "deploy_accounts_utils.components" . | indent 8 -}} + {{- include "deploy_accounts_utils.users_roles" (dict "Values" .Values) | indent 8 -}} "clientScopeMappings": { "account": [ { @@ -775,6 +622,17 @@ "jsonType.label": "String" } }, + { + "id": "0b8d0cf7-eebc-4c51-892e-2b65212856b4", + "name": "sub", + "protocol": "openid-connect", + "protocolMapper": "oidc-sub-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "access.token.claim": "true" + } + }, { "id": "3d763f84-d417-4b4e-99e4-2b0e05bf861a", "name": "family name", diff --git a/applications/accounts/deploy/templates/_components.tpl b/applications/accounts/deploy/templates/_components.tpl new file mode 100644 index 000000000..4f8180d52 --- /dev/null +++ b/applications/accounts/deploy/templates/_components.tpl @@ -0,0 +1,75 @@ +{{- define "deploy_accounts_utils.user_profile_provider_component" -}} + "org.keycloak.userprofile.UserProfileProvider": [ + { + "id": "002b69df-9702-40dd-b73e-3a66d161bf11", + "providerId": "declarative-user-profile", + "subComponents": {}, + "config": { + "kc.user.profile.config": [ + "{\"attributes\":[{\"name\":\"username\",\"displayName\":\"${username}\",\"validations\":{\"length\":{\"min\":3,\"max\":255},\"username-prohibited-characters\":{},\"up-username-not-idn-homograph\":{}},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"email\",\"displayName\":\"${email}\",\"validations\":{\"email\":{},\"length\":{\"max\":255}},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"firstName\",\"displayName\":\"${firstName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false},{\"name\":\"lastName\",\"displayName\":\"${lastName}\",\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"annotations\":{},\"permissions\":{\"view\":[\"admin\",\"user\"],\"edit\":[\"admin\",\"user\"]},\"multivalued\":false}],\"groups\":[{\"name\":\"user-metadata\",\"displayHeader\":\"User metadata\",\"displayDescription\":\"Attributes, which refer to user metadata\"}],\"unmanagedAttributePolicy\":\"ENABLED\"}" + ] + } + } + ] +{{- end -}} +{{- define "deploy_accounts_utils.key_provider_component" -}} + "org.keycloak.keys.KeyProvider": [ + { + "id": "e632ce46-36ad-421a-b1a5-776383cc1565", + "name": "rsa-generated", + "providerId": "rsa-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ] + } + }, + { + "id": "b68bee45-a8f0-46ca-b7d9-0df90189736a", + "name": "hmac-generated-hs512", + "providerId": "hmac-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ], + "algorithm": [ + "HS512" + ] + } + }, + { + "id": "55960a57-af77-4f4c-8b6e-925c74bb44db", + "name": "aes-generated", + "providerId": "aes-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ] + } + }, + { + "id": "ce068675-5cae-434e-851f-09f653ccc604", + "name": "rsa-enc-generated", + "providerId": "rsa-enc-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ], + "algorithm": [ + "RSA-OAEP" + ] + } + } + ] +{{- end -}} +# +{{- define "deploy_accounts_utils.components" -}} + "components": { + {{template "deploy_accounts_utils.user_profile_provider_component" }}, + {{template "deploy_accounts_utils.key_provider_component" }} + }, +{{- end -}} \ No newline at end of file diff --git a/applications/accounts/deploy/templates/_events.tpl b/applications/accounts/deploy/templates/_events.tpl new file mode 100644 index 000000000..efd2d701a --- /dev/null +++ b/applications/accounts/deploy/templates/_events.tpl @@ -0,0 +1,100 @@ +# Accounts _helper.tpl +{{- define "deploy_accounts_utils.event_listeners" -}} + "eventsListeners": [ + "metacell-admin-event-listener", + "jboss-logging" + ], +{{- end -}} +# +{{- define "deploy_accounts_utils.event_types" -}} + "enabledEventTypes": [ + "SEND_RESET_PASSWORD", + "UPDATE_CONSENT_ERROR", + "GRANT_CONSENT", + "VERIFY_PROFILE_ERROR", + "REMOVE_TOTP", + "REVOKE_GRANT", + "UPDATE_TOTP", + "LOGIN_ERROR", + "CLIENT_LOGIN", + "RESET_PASSWORD_ERROR", + "IMPERSONATE_ERROR", + "CODE_TO_TOKEN_ERROR", + "CUSTOM_REQUIRED_ACTION", + "OAUTH2_DEVICE_CODE_TO_TOKEN_ERROR", + "RESTART_AUTHENTICATION", + "IMPERSONATE", + "UPDATE_PROFILE_ERROR", + "LOGIN", + "OAUTH2_DEVICE_VERIFY_USER_CODE", + "UPDATE_PASSWORD_ERROR", + "CLIENT_INITIATED_ACCOUNT_LINKING", + "TOKEN_EXCHANGE", + "AUTHREQID_TO_TOKEN", + "LOGOUT", + "REGISTER", + "DELETE_ACCOUNT_ERROR", + "CLIENT_REGISTER", + "IDENTITY_PROVIDER_LINK_ACCOUNT", + "DELETE_ACCOUNT", + "UPDATE_PASSWORD", + "CLIENT_DELETE", + "FEDERATED_IDENTITY_LINK_ERROR", + "IDENTITY_PROVIDER_FIRST_LOGIN", + "CLIENT_DELETE_ERROR", + "VERIFY_EMAIL", + "CLIENT_LOGIN_ERROR", + "RESTART_AUTHENTICATION_ERROR", + "EXECUTE_ACTIONS", + "REMOVE_FEDERATED_IDENTITY_ERROR", + "TOKEN_EXCHANGE_ERROR", + "PERMISSION_TOKEN", + "SEND_IDENTITY_PROVIDER_LINK_ERROR", + "EXECUTE_ACTION_TOKEN_ERROR", + "SEND_VERIFY_EMAIL", + "OAUTH2_DEVICE_AUTH", + "EXECUTE_ACTIONS_ERROR", + "REMOVE_FEDERATED_IDENTITY", + "OAUTH2_DEVICE_CODE_TO_TOKEN", + "IDENTITY_PROVIDER_POST_LOGIN", + "IDENTITY_PROVIDER_LINK_ACCOUNT_ERROR", + "OAUTH2_DEVICE_VERIFY_USER_CODE_ERROR", + "UPDATE_EMAIL", + "REGISTER_ERROR", + "REVOKE_GRANT_ERROR", + "EXECUTE_ACTION_TOKEN", + "LOGOUT_ERROR", + "UPDATE_EMAIL_ERROR", + "CLIENT_UPDATE_ERROR", + "AUTHREQID_TO_TOKEN_ERROR", + "UPDATE_PROFILE", + "CLIENT_REGISTER_ERROR", + "FEDERATED_IDENTITY_LINK", + "SEND_IDENTITY_PROVIDER_LINK", + "SEND_VERIFY_EMAIL_ERROR", + "RESET_PASSWORD", + "CLIENT_INITIATED_ACCOUNT_LINKING_ERROR", + "OAUTH2_DEVICE_AUTH_ERROR", + "UPDATE_CONSENT", + "REMOVE_TOTP_ERROR", + "VERIFY_EMAIL_ERROR", + "SEND_RESET_PASSWORD_ERROR", + "CLIENT_UPDATE", + "CUSTOM_REQUIRED_ACTION_ERROR", + "IDENTITY_PROVIDER_POST_LOGIN_ERROR", + "UPDATE_TOTP_ERROR", + "CODE_TO_TOKEN", + "VERIFY_PROFILE", + "GRANT_CONSENT_ERROR", + "IDENTITY_PROVIDER_FIRST_LOGIN_ERROR" + ], +{{- end -}} +# +{{- define "deploy_accounts_utils.events" -}} + {{- if eq .app.useEvents true }} + {{template "deploy_accounts_utils.event_listeners" }} + {{template "deploy_accounts_utils.event_types" }} + "adminEventsEnabled": true, + "adminEventsDetailsEnabled": true, + {{- end }} +{{- end -}} \ No newline at end of file diff --git a/libraries/models/cloudharness_model/py.typed b/applications/accounts/deploy/templates/_helpers.tpl similarity index 100% rename from libraries/models/cloudharness_model/py.typed rename to applications/accounts/deploy/templates/_helpers.tpl diff --git a/applications/accounts/deploy/templates/_identity_providers.tpl b/applications/accounts/deploy/templates/_identity_providers.tpl new file mode 100644 index 000000000..4664120b4 --- /dev/null +++ b/applications/accounts/deploy/templates/_identity_providers.tpl @@ -0,0 +1,54 @@ +# +{{- define "deploy_accounts_utils.github_identity_provider" -}} + { + "alias": "github", + "internalId": "a3b32961-038c-41df-8e7c-815cda420aac", + "providerId": "github", + "enabled": true, + "updateProfileFirstLoginMode": "on", + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "syncMode": "IMPORT", + "clientSecret": {{ .app.harness.secrets.github_clientSecret | default "" | quote }}, + "clientId": {{ .app.harness.secrets.github_clientId | default "" | quote }}, + "useJwksUrl": "true" + } + } +{{- end -}} +# +{{- define "deploy_accounts_utils.google_identity_provider" -}} + { + "alias": "google", + "internalId": "7f65669a-e52f-426b-a9f6-f37253b00dae", + "providerId": "google", + "enabled": true, + "updateProfileFirstLoginMode": "on", + "trustEmail": false, + "storeToken": false, + "addReadTokenRoleOnCreate": false, + "authenticateByDefault": false, + "linkOnly": false, + "firstBrokerLoginFlowAlias": "first broker login", + "config": { + "syncMode": "IMPORT", + "clientSecret": {{ .app.harness.secrets.google_clientSecret | default "" | quote }}, + "clientId": {{ .app.harness.secrets.google_clientId | default "" | quote }}, + "useJwksUrl": "true" + } + } +{{- end -}} +# +{{- define "deploy_accounts_utils.identity_providers" -}} + {{- if hasKey .app "identityProviders" -}} + "identityProviders": [ + {{- range $provider := .app.identityProviders }} + {{ include (printf "deploy_accounts_utils.%s_identity_provider" $provider) (dict "app" $.app) | indent 12 }} + {{- end -}} + ], + {{- end }} +{{- end -}} \ No newline at end of file diff --git a/applications/accounts/deploy/templates/_users_roles.tpl b/applications/accounts/deploy/templates/_users_roles.tpl new file mode 100644 index 000000000..e83fbf5cc --- /dev/null +++ b/applications/accounts/deploy/templates/_users_roles.tpl @@ -0,0 +1,95 @@ +# Accounts _helper.tpl +{{- define "deploy_accounts_utils.role" }} + { + "id": {{ uuidv4 | quote }}, + "name": {{ .role| quote }}, + "composite": false, + "clientRole": true, + "containerId": {{ .app.harness.name | quote }}, + "attributes": {} + } +{{- end}} +# +{{- define "deploy_accounts_utils.user" }} + { + "username": {{ .user.username | default .user.email | quote }}, + "email": {{ .user.email | default .user.username | quote }}, + "enabled": true, + "firstName": {{ .user.firstName | default "Test" | quote }}, + "lastName": {{ .user.lastName | default "User" | quote }}, + "credentials": [ + { + "type": "password", + "value": {{ .user.password | default "test" | quote }} + } + ], + "realmRoles": {{ .user.realmRoles | toJson }}, + "clientRoles": { + {{ .app.harness.name | quote }}: {{ .user.clientRoles | toJson }} + } + } +{{- end}} +# +{{- define "deploy_accounts_utils.users_roles" }} + "users": [ + {{- $j := 0}} + {{- range $app := .Values.apps }} + {{- if (hasKey $app.harness "accounts") }} + {{- if $j}},{{end}} + {{- if $app.harness.accounts.users}} + {{- $j = add1 $j }} + {{- end }} + {{- range $i, $user := $app.harness.accounts.users }}{{if $i}},{{end}} + {{ include "deploy_accounts_utils.user" (dict "root" $ "app" $app "user" $user) }} + {{- end }} + {{- end }} + + {{- end }} + ], + "roles": { + "realm": [ + { + "id": "70835ad6-1454-4bc5-86a4-f1597e776b75", + "name": {{ .Values.apps.accounts.admin.role | quote }}, + "composite": false, + "clientRole": false, + "containerId": {{ .Values.namespace | quote }}, + "attributes": {} + }, + { + "id": "498353dd-88eb-4a5e-99b8-d912e0f20f23", + "name": "uma_authorization", + "description": "${role_uma_authorization}", + "composite": false, + "clientRole": false, + "containerId": {{ .Values.namespace | quote }}, + "attributes": {} + }, + { + "id": "f99970f1-958b-4bb8-8b39-0d7498b0ecc4", + "name": "offline_access", + "description": "${role_offline-access}", + "composite": false, + "clientRole": false, + "containerId": {{ .Values.namespace | quote }}, + "attributes": {} + } + ], + "client": { + {{- $k := 0}} + {{- range $app := .Values.apps }} + + {{- if (hasKey $app.harness "accounts") }} + {{- if $k}},{{end}} + {{ $app.harness.name | quote }}: [ + {{- range $i, $role := $app.harness.accounts.roles }} + {{if $i}},{{end}} + {{- include "deploy_accounts_utils.role" (dict "root" $ "app" $app "role" $role) }} + {{- end }} + ] + {{- $k = add1 $k }} + {{- end }} + {{- end }} + } + }, +{{- end -}} diff --git a/applications/accounts/deploy/values-local.yaml b/applications/accounts/deploy/values-local.yaml deleted file mode 100644 index 02efcde49..000000000 --- a/applications/accounts/deploy/values-local.yaml +++ /dev/null @@ -1,3 +0,0 @@ -harness: - service: - port: 80 diff --git a/applications/accounts/deploy/values.yaml b/applications/accounts/deploy/values.yaml index 01401824a..421818922 100644 --- a/applications/accounts/deploy/values.yaml +++ b/applications/accounts/deploy/values.yaml @@ -32,18 +32,6 @@ harness: value: "user" - name: KC_DB_PASSWORD value: "password" - - name: KC_HTTP_ENABLED - value: "true" - - name: KC_PROXY - value: "edge" - - name: KC_HOSTNAME_STRICT - value: "false" - - name: KC_HOSTNAME_STRICT_HTTPS - value: "false" - - name: KC_HEALTH_ENABLED - value: "true" - - name: KC_METRICS_ENABLED - value: "true" - name: JAVA_OPTS value: -server -Xms64m -Xmx896m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true --add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED --add-exports=jdk.unsupported/sun.reflect=ALL-UNNAMED database: @@ -85,3 +73,13 @@ admin: pass: metacell user: admin role: administrator +editUsernameAllowed: true +useEvents: false +identityProviders: +- github +- google +theme: + login: "keycloak" + account: "keycloak" + admin: "keycloak" + email: "keycloak" \ No newline at end of file diff --git a/applications/accounts/dev/disable-theme-cache.cli b/applications/accounts/dev/disable-theme-cache.cli new file mode 100644 index 000000000..4eca62b37 --- /dev/null +++ b/applications/accounts/dev/disable-theme-cache.cli @@ -0,0 +1,5 @@ +embed-server --std-out=echo --server-config=standalone-ha.xml +/subsystem=keycloak-server/theme=defaults/:write-attribute(name=cacheThemes,value=false) +/subsystem=keycloak-server/theme=defaults/:write-attribute(name=cacheTemplates,value=false) +/subsystem=keycloak-server/theme=defaults/:write-attribute(name=staticMaxAge,value=-1) +stop-embedded-server \ No newline at end of file diff --git a/applications/accounts/dev/docker-compose.yaml b/applications/accounts/dev/docker-compose.yaml index ed3be6f03..fc043360b 100644 --- a/applications/accounts/dev/docker-compose.yaml +++ b/applications/accounts/dev/docker-compose.yaml @@ -1,43 +1,45 @@ -name: keycloak-dev +version: '3.2' + services: postgres: - image: postgres - environment: - POSTGRES_DB: keycloak - POSTGRES_USER: keycloak - POSTGRES_PASSWORD: password - PGDATA: /var/lib/postgresql/data/pgdata - volumes: - - pg_data:/var/lib/postgresql/data/pgdata + image: postgres + environment: + POSTGRES_DB: keycloak + POSTGRES_USER: keycloak + POSTGRES_PASSWORD: password + PGDATA: /var/lib/postgresql/data/pgdata + volumes: + - pg_data:/var/lib/postgresql/data/pgdata + keycloak: - image: quay.io/keycloak/keycloak:26.3.4 - command: ["start-dev", - "--spi-theme-static-max-age=1", - "--spi-theme-cache-themes=false", - "--spi-theme-cache-templates=false", - "--hostname", "http://localhost:8080", - "--hostname-backchannel-dynamic", "true"] - environment: - KC_DB_VENDOR: POSTGRES - KC_DB_URL_HOST: postgres - KC_DB: postgres - KC_DB_URL_DATABASE: "postgres" - KC_DB_USERNAME: keycloak - KC_DB_PASSWORD: password - KC_BOOTSTRAP_ADMIN_USERNAME: admin - KC_BOOTSTRAP_ADMIN_PASSWORD: Pa55w0rd - KC_HEALTH_ENABLED: "true" - KC_METRICS_ENABLED: "true" - KC_HTTP_ENABLED: "true" - KC_HOSTNAME_STRICT: "false" - KC_HOSTNAME_STRICT_HTTPS: "false" - ports: - - "8080:8080" - depends_on: - - postgres - volumes: - - type: bind - source: ../themes/custom - target: /opt/keycloak/themes/custom + image: quay.io/keycloak/keycloak:16.1.1 + environment: + DB_VENDOR: POSTGRES + DB_ADDR: postgres + DB_DATABASE: keycloak + DB_USER: keycloak + DB_SCHEMA: public + DB_PASSWORD: password + KEYCLOAK_USER: admin + KEYCLOAK_PASSWORD: Pa55w0rd + + ports: + - 8080:8080 + depends_on: + - postgres + volumes: + - type: bind + source: ../themes/custom + target: /opt/jboss/keycloak/themes/custom + # disable cache + - type: bind + source: ./disable-theme-cache.cli + target: /opt/jboss/startup-scripts/disable-theme-cache.cli + - type: bind + source: ../scripts/create_api_user.sh + target: /opt/jboss/startup-scripts/create_api_user.sh + - type: bind + source: ../plugins/metacell-admin-event-listener-bundle-1.0.0.ear + target: /opt/jboss/keycloak/standalone/deployments/metacell-admin-event-listener-bundle-1.0.0.ear volumes: - pg_data: + pg_data: \ No newline at end of file diff --git a/applications/accounts/plugins/metacell-admin-event-listener-module-1.0.0.jar b/applications/accounts/plugins/metacell-admin-event-listener-module-1.0.0.jar index 8b6f5deb4..097546319 100644 Binary files a/applications/accounts/plugins/metacell-admin-event-listener-module-1.0.0.jar and b/applications/accounts/plugins/metacell-admin-event-listener-module-1.0.0.jar differ diff --git a/applications/accounts/scripts/create_api_user.sh b/applications/accounts/scripts/create_api_user.sh index caf92fff5..8d0936449 100755 --- a/applications/accounts/scripts/create_api_user.sh +++ b/applications/accounts/scripts/create_api_user.sh @@ -1,25 +1,85 @@ #!/bin/bash -NAMESPACE=${CH_ACCOUNTS_REALM} -USERNAME=admin_api -PASSWORD=$(cat /opt/cloudharness/resources/auth/api_user_password) +export API_USERNAME="admin_api" +export API_PASSWORD=$(cat /opt/cloudharness/resources/auth/api_user_password 2>/dev/null || echo "") +export TMP_CLIENT="tmp_api_client" +export TMP_CLIENT_SECRET="${KC_BOOTSTRAP_ADMIN_USERNAME}" -echo "Checking if API user exists..." +check_kc_ready() { + if echo >/dev/tcp/127.0.0.1/${ACCOUNTS_SERVICE_PORT}; then + return 0 + fi 2> /dev/null + return 1 +} -# Check if user already exists -if /opt/keycloak/bin/kcadm.sh get users -q "username=$USERNAME" | grep -q "$USERNAME"; then - echo "ERROR: API user $USERNAME already exists, but password is out of sync. You may need to reset it manually." - # /opt/keycloak/bin/kcadm.sh set-password --username "$USERNAME" --new-password "$PASSWORD" - # Removed automatic password reset as that would only work if the main admin password is unchanged from the default password - # That would create the false impression that the password is reset successfully when in fact it has not on production systems +while ! check_kc_ready; do + echo "create_api_user: waiting for Keycloak to be ready..." + sleep 10 +done + +create_temporary_client() { + /opt/keycloak/bin/kc.sh bootstrap-admin service --client-id=${TMP_CLIENT} --client-secret:env=TMP_CLIENT_SECRET --http-management-port 9876 +} + +delete_temporary_client() { + CLIENT_ID=$(/opt/keycloak/bin/kcadm.sh get clients -r master -q clientId=${TMP_CLIENT} --fields id --format csv|tr -d '"') + if [ -n "$CLIENT_ID" ]; then + /opt/keycloak/bin/kcadm.sh delete clients/$CLIENT_ID -r master + fi +} + +create_kc_config() { + /opt/keycloak/bin/kcadm.sh config credentials --server http://localhost:${ACCOUNTS_SERVICE_PORT} --realm master --client ${TMP_CLIENT} --secret ${TMP_CLIENT_SECRET} +} + +api_user_exists() { + return $(/opt/keycloak/bin/kcadm.sh get users -q "username=$API_USERNAME" | grep -q "$API_USERNAME"; echo $?) +} + +create_api_user() { + /opt/keycloak/bin/kcadm.sh create users -s "username=${API_USERNAME}" -s enabled=True +} + +set_password_and_roles() { + /opt/keycloak/bin/kcadm.sh set-password --username "$API_USERNAME" --new-password "$API_PASSWORD" + /opt/keycloak/bin/kcadm.sh add-roles --uusername "$API_USERNAME" --rolename admin +} + +# Wait for Keycloak to be ready - just give it some time to start up + + +echo "create_api_user: attempting authentication..." + +# First, try to authenticate as admin_api +if [ -n "$API_PASSWORD" ] && /opt/keycloak/bin/kcadm.sh config credentials \ + --server http://localhost:${ACCOUNTS_SERVICE_PORT} \ + --realm master \ + --user "$API_USERNAME" \ + --password "$API_PASSWORD" 2>/dev/null; then + echo "create_api_user: successfully authenticated as $API_USERNAME" + echo "create_api_user: sStartup scripts not needed (admin_api user already exists)" exit 0 fi -echo "Creating API user $USERNAME" -set -e -# create the user and reload keycloak -/opt/keycloak/bin/kcadm.sh create users -s "username=$USERNAME" -s enabled=True -/opt/keycloak/bin/kcadm.sh set-password --username "$USERNAME" --new-password "$PASSWORD" -/opt/keycloak/bin/kcadm.sh add-roles --uusername "$USERNAME" --rolename admin +echo "create_api_user: admin_api user does not exist or authentication failed. Authenticating to create the user..." + +set -e +create_temporary_client +create_kc_config +echo "create_api_user: temporary credentials successfully created." + +echo "create_api_user: checking if API user exists..." +# Check if user already exists +if ! api_user_exists; then + echo "create_api_user: API user $API_USERNAME doesn't exists, creating..." + create_api_user + echo "create_api_user: API user created successfully" +else + echo "create_api_user: API user $API_USERNAME already exists." +fi + +echo "create_api_user: setting password and role." +set_password_and_roles -echo "API user created successfully" \ No newline at end of file +echo "create_api_user: cleaning up temporary client." +delete_temporary_client diff --git a/applications/accounts/scripts/kc-entrypoint.sh b/applications/accounts/scripts/kc-entrypoint.sh index 2657b53ce..e21814cbf 100644 --- a/applications/accounts/scripts/kc-entrypoint.sh +++ b/applications/accounts/scripts/kc-entrypoint.sh @@ -21,7 +21,7 @@ if [ -n "$API_PASSWORD" ] && /opt/keycloak/bin/kcadm.sh config credentials \ echo "Successfully authenticated as $API_USERNAME" echo "Startup scripts not needed (admin_api user already exists)" else - echo "admin_api user does not exist or authentication failed. Authenticating as bootstrap admin to create the user..." + echo "admin_api user does not exist or authentication failed. Authenticating as bootstrap admin to create/update the user..." # Authenticate as bootstrap admin to create admin_api user if ! /opt/keycloak/bin/kcadm.sh config credentials \ diff --git a/applications/common/api/openapi.yaml b/applications/common/api/openapi.yaml index 7d5b75b43..33c2b91a9 100644 --- a/applications/common/api/openapi.yaml +++ b/applications/common/api/openapi.yaml @@ -10,6 +10,46 @@ servers: url: /api description: SwaggerHub API Auto Mocking paths: + '/sentry/getdsn/{appname}': + get: + tags: + - Sentry + responses: + '200': + content: + application/json: + schema: + type: object + description: Sentry DSN for the given application + '400': + content: + application/json: + schema: + type: object + text/html: + schema: + type: string + description: Sentry not configured for the given application + '404': + content: + application/problem+json: + schema: + type: object + text/html: + schema: + type: string + description: Sentry not configured for the given application + operationId: getdsn + summary: Gets the Sentry DSN for a given application + description: Gets the Sentry DSN for a given application + x-openapi-router-controller: common.controllers.sentry_controller + parameters: + - + name: appname + schema: + type: string + in: path + required: true /accounts/config: get: tags: diff --git a/applications/common/deploy/values.yaml b/applications/common/deploy/values.yaml index eec864503..256492adb 100644 --- a/applications/common/deploy/values.yaml +++ b/applications/common/deploy/values.yaml @@ -5,9 +5,6 @@ harness: auto: true port: 8080 name: common - proxy: - gatekeeper: - replicas: 1 deployment: auto: true name: common diff --git a/applications/common/server/.openapi-generator-ignore b/applications/common/server/.openapi-generator-ignore index 20636ed89..12e95840e 100644 --- a/applications/common/server/.openapi-generator-ignore +++ b/applications/common/server/.openapi-generator-ignore @@ -27,5 +27,4 @@ Dockerfile */__main__.py */test/* test-requirements.txt -.dockerignore -*/requirements.txt \ No newline at end of file +.dockerignore \ No newline at end of file diff --git a/applications/common/server/Dockerfile b/applications/common/server/Dockerfile index f1b4dba1b..962f117ea 100644 --- a/applications/common/server/Dockerfile +++ b/applications/common/server/Dockerfile @@ -17,3 +17,4 @@ COPY . /usr/src/app ENV FLASK_ENV=production ENV APP_SETTINGS=common.config.ProductionConfig RUN pip3 install -e /usr/src/app +ENTRYPOINT gunicorn --workers=$WORKERS --bind=0.0.0.0:$PORT $MODULE_NAME.__main__:app diff --git a/applications/common/server/common/__main__.py b/applications/common/server/common/__main__.py index ffcf7ebd9..0a81a3f80 100644 --- a/applications/common/server/common/__main__.py +++ b/applications/common/server/common/__main__.py @@ -2,9 +2,19 @@ from cloudharness.utils.server import init_flask, main from cloudharness import log +from flask_cors import CORS +from common.repository.db import open_db +from common.controllers.sentry_controller import global_dsn -app = init_flask() +def init_fn(app): + log.info("initializing database from app") + cors = CORS(app, resources={r"/api/*": {"origins": "*"}}) + if not global_dsn: + open_db(app) + + +app = init_flask(init_app_fn=init_fn) if __name__ == '__main__': main() diff --git a/applications/common/server/common/controllers/sentry_controller.py b/applications/common/server/common/controllers/sentry_controller.py new file mode 100644 index 000000000..4d0727825 --- /dev/null +++ b/applications/common/server/common/controllers/sentry_controller.py @@ -0,0 +1,53 @@ +import os +import requests + +from cloudharness import applications, log +from cloudharness.utils.env import get_sentry_service_cluster_address +from common.repository.sentry import get_token, get_dsn, SentryProjectNotFound + + +try: + global_dsn = os.environ.get("SENTRY_DSN", "") + if len(global_dsn) < 1: + global_dsn = None +except: + global_dsn = None + + +def getdsn(appname): # noqa: E501 + """ + Gets the Sentry DSN for a given application or returns the global dsn when set + global dsn can be set using the kubectl command + kubectl create secret generic -n mnp mnp-sentry --from-literal=dsn= + :param appname: + :type appname: str + :rtype: str + """ + try: + ch_app = applications.get_configuration(appname) + except applications.ConfigurationCallException as e: + return {"error": f"Application `{appname}` does not exist"}, 400 + if ch_app.is_sentry_enabled(): + if global_dsn: + # if a global dsn env var is set and not empty then use this + dsn = global_dsn + else: + try: + dsn = get_dsn(appname) + except SentryProjectNotFound as e: + # if project not found, create one + try: + sentry_api_token = get_token() + headers = {'Authorization': 'Bearer ' + sentry_api_token} + url = get_sentry_service_cluster_address() + f'/api/0/teams/sentry/sentry/projects/' + data = {'name': appname} + response = requests.post( + url, data, headers=headers, verify=False) + dsn = get_dsn(appname) + except: + log.error("Error on Sentry initialization", exc_info=True) + # FIXME temporary fix + return {"error": "Sentry not initialized"}, 400 + else: + dsn = '' + return {'dsn': dsn} diff --git a/applications/common/server/common/encoder.py b/applications/common/server/common/encoder.py index a044b9363..a88fe1fc6 100644 --- a/applications/common/server/common/encoder.py +++ b/applications/common/server/common/encoder.py @@ -1,6 +1,7 @@ from connexion.apps.flask_app import FlaskJSONEncoder +import six -from common.models.base_model import Model +from common.models.base_model_ import Model class JSONEncoder(FlaskJSONEncoder): @@ -9,7 +10,7 @@ class JSONEncoder(FlaskJSONEncoder): def default(self, o): if isinstance(o, Model): dikt = {} - for attr in o.openapi_types: + for attr, _ in six.iteritems(o.openapi_types): value = getattr(o, attr) if value is None and not self.include_nulls: continue diff --git a/applications/common/server/common/models/__init__.py b/applications/common/server/common/models/__init__.py index c5d082c01..6baf66764 100644 --- a/applications/common/server/common/models/__init__.py +++ b/applications/common/server/common/models/__init__.py @@ -1,4 +1,7 @@ +# coding: utf-8 + # flake8: noqa +from __future__ import absolute_import # import models into model package from common.models.app_version import AppVersion from common.models.get_config200_response import GetConfig200Response diff --git a/applications/common/server/common/models/app_version.py b/applications/common/server/common/models/app_version.py index 5c09d813b..629b4546b 100644 --- a/applications/common/server/common/models/app_version.py +++ b/applications/common/server/common/models/app_version.py @@ -1,8 +1,11 @@ +# coding: utf-8 + +from __future__ import absolute_import from datetime import date, datetime # noqa: F401 from typing import List, Dict # noqa: F401 -from common.models.base_model import Model +from common.models.base_model_ import Model from common import util @@ -45,7 +48,7 @@ def from_dict(cls, dikt) -> 'AppVersion': return util.deserialize_model(dikt, cls) @property - def build(self) -> str: + def build(self): """Gets the build of this AppVersion. @@ -55,7 +58,7 @@ def build(self) -> str: return self._build @build.setter - def build(self, build: str): + def build(self, build): """Sets the build of this AppVersion. @@ -66,7 +69,7 @@ def build(self, build: str): self._build = build @property - def tag(self) -> str: + def tag(self): """Gets the tag of this AppVersion. @@ -76,7 +79,7 @@ def tag(self) -> str: return self._tag @tag.setter - def tag(self, tag: str): + def tag(self, tag): """Sets the tag of this AppVersion. diff --git a/applications/common/server/common/models/base_model.py b/applications/common/server/common/models/base_model.py deleted file mode 100644 index 3a09d2a72..000000000 --- a/applications/common/server/common/models/base_model.py +++ /dev/null @@ -1,68 +0,0 @@ -import pprint - -import typing - -from common import util - -T = typing.TypeVar('T') - - -class Model: - # openapiTypes: The key is attribute name and the - # value is attribute type. - openapi_types: typing.Dict[str, type] = {} - - # attributeMap: The key is attribute name and the - # value is json key in definition. - attribute_map: typing.Dict[str, str] = {} - - @classmethod - def from_dict(cls: typing.Type[T], dikt) -> T: - """Returns the dict as a model""" - return util.deserialize_model(dikt, cls) - - def to_dict(self): - """Returns the model properties as a dict - - :rtype: dict - """ - result = {} - - for attr in self.openapi_types: - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result - - def to_str(self): - """Returns the string representation of the model - - :rtype: str - """ - return pprint.pformat(self.to_dict()) - - def __repr__(self): - """For `print` and `pprint`""" - return self.to_str() - - def __eq__(self, other): - """Returns true if both objects are equal""" - return self.__dict__ == other.__dict__ - - def __ne__(self, other): - """Returns true if both objects are not equal""" - return not self == other diff --git a/applications/common/server/common/models/get_config200_response.py b/applications/common/server/common/models/get_config200_response.py index 5fac5cfe9..48e3b40e4 100644 --- a/applications/common/server/common/models/get_config200_response.py +++ b/applications/common/server/common/models/get_config200_response.py @@ -1,8 +1,11 @@ +# coding: utf-8 + +from __future__ import absolute_import from datetime import date, datetime # noqa: F401 from typing import List, Dict # noqa: F401 -from common.models.base_model import Model +from common.models.base_model_ import Model from common import util @@ -50,7 +53,7 @@ def from_dict(cls, dikt) -> 'GetConfig200Response': return util.deserialize_model(dikt, cls) @property - def url(self) -> str: + def url(self): """Gets the url of this GetConfig200Response. The auth URL. # noqa: E501 @@ -61,7 +64,7 @@ def url(self) -> str: return self._url @url.setter - def url(self, url: str): + def url(self, url): """Sets the url of this GetConfig200Response. The auth URL. # noqa: E501 @@ -73,7 +76,7 @@ def url(self, url: str): self._url = url @property - def realm(self) -> str: + def realm(self): """Gets the realm of this GetConfig200Response. The realm. # noqa: E501 @@ -84,7 +87,7 @@ def realm(self) -> str: return self._realm @realm.setter - def realm(self, realm: str): + def realm(self, realm): """Sets the realm of this GetConfig200Response. The realm. # noqa: E501 @@ -96,7 +99,7 @@ def realm(self, realm: str): self._realm = realm @property - def client_id(self) -> str: + def client_id(self): """Gets the client_id of this GetConfig200Response. The clientID. # noqa: E501 @@ -107,7 +110,7 @@ def client_id(self) -> str: return self._client_id @client_id.setter - def client_id(self, client_id: str): + def client_id(self, client_id): """Sets the client_id of this GetConfig200Response. The clientID. # noqa: E501 diff --git a/applications/common/server/common/openapi/openapi.yaml b/applications/common/server/common/openapi/openapi.yaml index 2ee74ae1d..02e7b77fb 100644 --- a/applications/common/server/common/openapi/openapi.yaml +++ b/applications/common/server/common/openapi/openapi.yaml @@ -27,6 +27,47 @@ paths: tags: - Accounts x-openapi-router-controller: common.controllers.accounts_controller + /sentry/getdsn/{appname}: + get: + description: Gets the Sentry DSN for a given application + operationId: getdsn + parameters: + - explode: false + in: path + name: appname + required: true + schema: + type: string + style: simple + responses: + "200": + content: + application/json: + schema: + type: object + description: Sentry DSN for the given application + "400": + content: + application/json: + schema: + type: object + text/html: + schema: + type: string + description: Sentry not configured for the given application + "404": + content: + application/problem+json: + schema: + type: object + text/html: + schema: + type: string + description: Sentry not configured for the given application + summary: Gets the Sentry DSN for a given application + tags: + - Sentry + x-openapi-router-controller: common.controllers.sentry_controller /version: get: operationId: get_version diff --git a/applications/common/server/common/repository/__init__.py b/applications/common/server/common/repository/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/applications/common/server/common/repository/db.py b/applications/common/server/common/repository/db.py new file mode 100644 index 000000000..8433b3a9d --- /dev/null +++ b/applications/common/server/common/repository/db.py @@ -0,0 +1,21 @@ +from flask_sqlalchemy import SQLAlchemy +from cloudharness import log + +db = None + + +def get_db(): + global db + if not db: + raise Exception('Database not open!') + return db + + +def open_db(app): + global db + try: + if not db: + db = SQLAlchemy(app) + except Exception as e: + log.exception("Sentry database cannot be initialized") + return db diff --git a/applications/common/server/common/repository/sentry.py b/applications/common/server/common/repository/sentry.py new file mode 100644 index 000000000..4ad449ac0 --- /dev/null +++ b/applications/common/server/common/repository/sentry.py @@ -0,0 +1,71 @@ + +import sqlalchemy +from sqlalchemy.sql import text + +from cloudharness.utils.env import get_service_public_address + +from .db import get_db + + +class SentryProjectNotFound(Exception): + pass + + +def _get_api_token(): + # ToDo: may be we can use here a dynamic token, but for now let's use a hard coded one + api_token = 'afe75d802007405dbc0c2fb1db4cc8b06b981017f58944d0afac700f743ee06a' + s = text(''' + select token from sentry_apitoken + where token=:api_token + ''') + token = get_db().engine.execute(s, + api_token=api_token + ).fetchall() + if len(token) == 0: + # token is not present in the Sentry database, let's create it + s = text(''' + insert into sentry_apitoken(user_id, token, scopes, date_added, scope_list) + values (1, :api_token, 0, now(), :scope_list) + ''') + get_db().engine.execute(s, + api_token=api_token, + scope_list='{event:admin,event:read,' + 'member:read,member:admin,' + 'project:read,project:releases,project:admin,project:write,' + 'team:read,team:write,team:admin,' + 'org:read,org:write,org:admin}' + ) + return _get_api_token() + else: + # return the first column from the first row of the query result + return token[0][0] + + +def get_token(): + return _get_api_token() + + +def get_dsn(appname): + s = text(''' + select public_key, p.id + from sentry_projectkey pkey + join sentry_project p on pkey.project_id=p.id + where p.slug=:project_slug + ''') + try: + public_key = get_db().engine.execute(s, + project_slug=appname + ).fetchall() + except sqlalchemy.exc.OperationalError: + raise SentryProjectNotFound('Sentry is not initialized.') + + if len(public_key) == 0: + raise SentryProjectNotFound('Application not found!') + else: + dsn = public_key[0][0] + app_id = public_key[0][1] + sentry_host = get_service_public_address('sentry') + dsn = f'https://{dsn}@{sentry_host}/{app_id}' + + # return the first column from the first row of the query result + return dsn diff --git a/applications/common/server/common/typing_utils.py b/applications/common/server/common/typing_utils.py index 74e3c913a..0563f81fd 100644 --- a/applications/common/server/common/typing_utils.py +++ b/applications/common/server/common/typing_utils.py @@ -1,3 +1,5 @@ +# coding: utf-8 + import sys if sys.version_info < (3, 7): diff --git a/applications/common/server/common/util.py b/applications/common/server/common/util.py index 40b3c9a55..8e7e71e62 100644 --- a/applications/common/server/common/util.py +++ b/applications/common/server/common/util.py @@ -1,5 +1,6 @@ import datetime +import six import typing from common import typing_utils @@ -15,7 +16,7 @@ def _deserialize(data, klass): if data is None: return None - if klass in (int, float, str, bool, bytearray): + if klass in six.integer_types or klass in (float, str, bool, bytearray): return _deserialize_primitive(data, klass) elif klass == object: return _deserialize_object(data) @@ -44,7 +45,7 @@ def _deserialize_primitive(data, klass): try: value = klass(data) except UnicodeEncodeError: - value = data + value = six.u(data) except TypeError: value = data return value @@ -109,7 +110,7 @@ def deserialize_model(data, klass): if not instance.openapi_types: return data - for attr, attr_type in instance.openapi_types.items(): + for attr, attr_type in six.iteritems(instance.openapi_types): if data is not None \ and instance.attribute_map[attr] in data \ and isinstance(data, (list, dict)): @@ -144,4 +145,4 @@ def _deserialize_dict(data, boxed_type): :rtype: dict """ return {k: _deserialize(v, boxed_type) - for k, v in data.items()} + for k, v in six.iteritems(data)} diff --git a/applications/common/server/requirements.txt b/applications/common/server/requirements.txt index 9098dc4b2..8acc510d2 100644 --- a/applications/common/server/requirements.txt +++ b/applications/common/server/requirements.txt @@ -1,6 +1,7 @@ -connexion[swagger-ui,flask,uvicorn]>=3.0.0,<4.0.0 -swagger-ui-bundle>=1.1.0 -python_dateutil>=2.9.0 -setuptools>=21.0.0 -uvicorn +connexion[swagger-ui]==2.14.2 +swagger-ui-bundle >= 0.0.2 +python_dateutil >= 2.6.0 +setuptools >= 21.0.0 +Flask<3.0.0 flask_sqlalchemy==3.0.2 +sqlalchemy<2.0.0 \ No newline at end of file diff --git a/applications/common/server/tox.ini b/applications/common/server/tox.ini index 33148af3c..2596bae26 100644 --- a/applications/common/server/tox.ini +++ b/applications/common/server/tox.ini @@ -5,7 +5,7 @@ skipsdist=True [testenv] deps=-r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt - {toxinidir} + {toxinidir} commands= pytest --cov=common diff --git a/applications/elasticsearch/.ch-manifest b/applications/elasticsearch/.ch-manifest deleted file mode 100644 index b0552fe4d..000000000 --- a/applications/elasticsearch/.ch-manifest +++ /dev/null @@ -1,4 +0,0 @@ -app-name: elasticsearch -inferred: true -templates: [base] -version: '2' diff --git a/applications/jupyterhub/src/harness_jupyter/harness_jupyter/jupyterhub.py b/applications/jupyterhub/src/harness_jupyter/harness_jupyter/jupyterhub.py index 01b97c8eb..98159a030 100644 --- a/applications/jupyterhub/src/harness_jupyter/harness_jupyter/jupyterhub.py +++ b/applications/jupyterhub/src/harness_jupyter/harness_jupyter/jupyterhub.py @@ -193,6 +193,17 @@ def change_pod_manifest(self: KubeSpawner): # set user quota cpu/mem usage if value has a "value" else don't change the value + logging.info("Setting user quota cpu/mem usage") + + if self.cpu_guarantee is None: # This eventually comes from the current profile. Profile wins over user quota, if set. + set_key_value(self, key="cpu_guarantee", value=float(user_quotas.get("quota-ws-guaranteecpu"))) + if self.cpu_limit is None: + set_key_value(self, key="cpu_limit", value=float(user_quotas.get("quota-ws-maxcpu"))) + if self.mem_guarantee is None: + set_key_value(self, key="mem_guarantee", value=user_quotas.get("quota-ws-guaranteemem"), unit="G") + if self.mem_limit is None: + set_key_value(self, key="mem_limit", value=user_quotas.get("quota-ws-maxmem"), unit="G") + # Default value, might be overwritten by the app config self.storage_pvc_ensure = bool(self.pvc_name) @@ -246,23 +257,14 @@ def change_pod_manifest(self: KubeSpawner): except: logging.error("Error loading Spawner extra configuration", exc_info=True) - logging.info("Setting user quota cpu/mem usage") - - set_key_value(self, key="cpu_guarantee", value=float(user_quotas.get("quota-ws-guaranteecpu", self.cpu_guarantee))) - set_key_value(self, key="cpu_limit", value=float(user_quotas.get("quota-ws-maxcpu", self.cpu_limit))) - set_key_value(self, key="mem_guarantee", value=user_quotas.get("quota-ws-guaranteemem", self.mem_guarantee), unit="G") - set_key_value(self, key="mem_limit", value=user_quotas.get("quota-ws-maxmem", self.mem_limit), unit="G") - - # check if there is an applicationHook defined in the values.yaml - # if so then execute the applicationHook function with "self" as parameter - # - # e.g. - # jupyterhub: - # applicationHook: "jupyter.change_pod_manifest" - # - # this will execute jupyter.change_pod_manifest(self=self) - - if 'jupyterhub' in harness and harness['jupyterhub']: + # check if there is an applicationHook defined in the values.yaml + # if so then execute the applicationHook function with "self" as parameter + # + # e.g. + # jupyterhub: + # applicationHook: "jupyter.change_pod_manifest" + # + # this will execute jupyter.change_pod_manifest(self=self) if 'applicationHook' in harness['jupyterhub']: func_name = harness['jupyterhub']['applicationHook'].split('.') logging.info(f"Executing application hook {func_name}") diff --git a/applications/samples/Dockerfile b/applications/samples/Dockerfile index a0b9f8c86..522de3c9e 100644 --- a/applications/samples/Dockerfile +++ b/applications/samples/Dockerfile @@ -33,3 +33,5 @@ COPY backend/ /usr/src/app COPY --from=frontend app/dist/ /usr/src/app/www RUN pip3 install -e . + +CMD gunicorn --workers=$WORKERS --bind=0.0.0.0:$PORT $MODULE_NAME.__main__:app --timeout 180 \ No newline at end of file diff --git a/applications/samples/backend/.openapi-generator-ignore b/applications/samples/backend/.openapi-generator-ignore index c89f830d0..00f73c37f 100644 --- a/applications/samples/backend/.openapi-generator-ignore +++ b/applications/samples/backend/.openapi-generator-ignore @@ -25,5 +25,4 @@ setup.py */controllers/* Dockerfile */__main__.py -*/test/* -*/requirements.txt \ No newline at end of file +*/test/* \ No newline at end of file diff --git a/applications/samples/backend/requirements.txt b/applications/samples/backend/requirements.txt index 68760177c..f9d4fe449 100644 --- a/applications/samples/backend/requirements.txt +++ b/applications/samples/backend/requirements.txt @@ -1,9 +1,3 @@ -connexion[swagger-ui,flask,uvicorn]>=3.0.0,<4.0.0 -swagger-ui-bundle>=1.1.0 -python_dateutil>=2.9.0 -setuptools>=21.0.0 -uvicorn -# Following some unnecessary requirements to make sure they can be installed -psycopg2-binary -sqlalchemy<2.0.0 -scipy \ No newline at end of file +connexion[swagger-ui]==2.14.2 +Flask == 2.2.5 +swagger-ui-bundle==0.0.9 \ No newline at end of file diff --git a/applications/samples/backend/samples/controllers/auth_controller.py b/applications/samples/backend/samples/controllers/auth_controller.py index 2a34df65c..e144a976c 100644 --- a/applications/samples/backend/samples/controllers/auth_controller.py +++ b/applications/samples/backend/samples/controllers/auth_controller.py @@ -1,6 +1,7 @@ import connexion import six +from samples.models.valid import Valid # noqa: E501 from samples import util @@ -26,5 +27,7 @@ def valid_cookie(): # noqa: E501 :rtype: List[Valid] """ from cloudharness.middleware import get_authentication_token + from cloudharness.auth import decode_token token = get_authentication_token() + assert decode_token(token) return 'OK' diff --git a/applications/samples/backend/samples/controllers/resource_controller.py b/applications/samples/backend/samples/controllers/resource_controller.py index 4693dbe0e..4f17d3da5 100644 --- a/applications/samples/backend/samples/controllers/resource_controller.py +++ b/applications/samples/backend/samples/controllers/resource_controller.py @@ -1,6 +1,5 @@ import connexion import six -from flask import request from samples.models.sample_resource import SampleResource # noqa: E501 from samples import util @@ -17,14 +16,13 @@ def create_sample_resource(sample_resource=None): # noqa: E501 :rtype: None """ - # Connexion 3.x with pythonic_params should auto-deserialize, but if not, get from Flask request - if sample_resource is None: - sample_resource = request.get_json() + if connexion.request.is_json: + try: + sample_resource = SampleResource.from_dict(connexion.request.get_json()) # noqa: E501 + except: + return "Payload is not of type SampleResource", 400 - if isinstance(sample_resource, dict): - sample_resource = SampleResource.from_dict(sample_resource) - - # Create a file inside the volume + # Create a file inside the nfs with open("/tmp/myvolume/myfile", "w") as f: print("test", file=f) @@ -92,13 +90,10 @@ def update_sample_resource(sampleresource_id, sample_resource=None): # noqa: E5 :rtype: None """ - # Connexion 3.x with pythonic_params should auto-deserialize, but if not, get from Flask request - if sample_resource is None: - sample_resource = request.get_json() - - if isinstance(sample_resource, dict): - sample_resource = SampleResource.from_dict(sample_resource) - + try: + sample_resource = SampleResource.from_dict(connexion.request.get_json()) # noqa: E501 + except: + return "Payload is not of type SampleResource", 400 try: resource = resource_service.update_sample_resource( int(sampleresource_id), sample_resource) diff --git a/applications/samples/backend/samples/controllers/security_controller_.py b/applications/samples/backend/samples/controllers/security_controller_.py index 7f25b88fc..c052e680f 100644 --- a/applications/samples/backend/samples/controllers/security_controller_.py +++ b/applications/samples/backend/samples/controllers/security_controller_.py @@ -1,6 +1,4 @@ from typing import List -from cloudharness.auth import decode_token -from cloudharness.middleware import set_authentication_token def info_from_bearerAuth(token): @@ -15,31 +13,3 @@ def info_from_bearerAuth(token): :rtype: dict | None """ return {'uid': 'user_id'} - - -def info_from_cookieAuth(api_key): - """ - Check and retrieve authentication information from cookie-based API key. - This function is called by Connexion when cookieAuth security is used. - - :param api_key Token provided by the kc-access cookie - :type api_key: str - :return: Decoded token information or None if token is invalid - :rtype: dict | None - """ - if not api_key: - return None - - # Set the authentication token in the middleware context - # so that get_authentication_token() can access it - set_authentication_token(api_key) - - # Decode and validate the token - try: - decoded = decode_token(api_key) - if decoded: - return decoded - except Exception: - pass - - return None diff --git a/applications/samples/backend/samples/controllers/test_controller.py b/applications/samples/backend/samples/controllers/test_controller.py index 256ef08f9..f3580dc3d 100644 --- a/applications/samples/backend/samples/controllers/test_controller.py +++ b/applications/samples/backend/samples/controllers/test_controller.py @@ -25,6 +25,20 @@ def ping(): # noqa: E501 import os + expected_environment_variables = { + 'WORKERS': '3', + 'ENVIRONMENT_TEST_A': 'value', + 'ENVIRONMENT_TEST_B': '123', + } + + for key, expected_value in expected_environment_variables.items(): + try: + environment_value = os.environ[key] + if environment_value != expected_value: + raise Exception(f'Expected environment variable {key} to be {expected_value}, but got {environment_value}') + except KeyError: + raise Exception(f'Expected to have an environment variable {key} defined') + import time return time.time() diff --git a/applications/volumemanager/server/volumemanager/models/base_model.py b/applications/samples/backend/samples/models/base_model_.py similarity index 93% rename from applications/volumemanager/server/volumemanager/models/base_model.py rename to applications/samples/backend/samples/models/base_model_.py index 872b4b309..edf327c8b 100644 --- a/applications/volumemanager/server/volumemanager/models/base_model.py +++ b/applications/samples/backend/samples/models/base_model_.py @@ -1,13 +1,14 @@ import pprint +import six import typing -from volumemanager import util +from samples import util T = typing.TypeVar('T') -class Model: +class Model(object): # openapiTypes: The key is attribute name and the # value is attribute type. openapi_types: typing.Dict[str, type] = {} @@ -28,7 +29,7 @@ def to_dict(self): """ result = {} - for attr in self.openapi_types: + for attr, _ in six.iteritems(self.openapi_types): value = getattr(self, attr) if isinstance(value, list): result[attr] = list(map( diff --git a/applications/samples/backend/samples/models/valid.py b/applications/samples/backend/samples/models/valid.py new file mode 100644 index 000000000..769834e82 --- /dev/null +++ b/applications/samples/backend/samples/models/valid.py @@ -0,0 +1,64 @@ +# coding: utf-8 + +from __future__ import absolute_import +from datetime import date, datetime # noqa: F401 + +from typing import List, Dict # noqa: F401 + +from samples.models.base_model_ import Model +from samples import util + + +class Valid(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + + Do not edit the class manually. + """ + + def __init__(self, response=None): # noqa: E501 + """Valid - a model defined in OpenAPI + + :param response: The response of this Valid. # noqa: E501 + :type response: str + """ + self.openapi_types = { + 'response': str + } + + self.attribute_map = { + 'response': 'response' + } + + self._response = response + + @classmethod + def from_dict(cls, dikt) -> 'Valid': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The Valid of this Valid. # noqa: E501 + :rtype: Valid + """ + return util.deserialize_model(dikt, cls) + + @property + def response(self): + """Gets the response of this Valid. + + + :return: The response of this Valid. + :rtype: str + """ + return self._response + + @response.setter + def response(self, response): + """Sets the response of this Valid. + + + :param response: The response of this Valid. + :type response: str + """ + + self._response = response diff --git a/applications/samples/backend/samples/openapi/openapi.yaml b/applications/samples/backend/samples/openapi/openapi.yaml index 401ba448e..6a8757716 100644 --- a/applications/samples/backend/samples/openapi/openapi.yaml +++ b/applications/samples/backend/samples/openapi/openapi.yaml @@ -17,6 +17,7 @@ tags: paths: /error: get: + deprecated: true operationId: error responses: "200": @@ -47,6 +48,7 @@ paths: x-openapi-router-controller: samples.controllers.workflows_controller /operation_sync: get: + deprecated: true operationId: submit_sync responses: "200": @@ -61,6 +63,7 @@ paths: x-openapi-router-controller: samples.controllers.workflows_controller /operation_sync_results: get: + deprecated: true operationId: submit_sync_with_results parameters: - description: first number to sum @@ -336,4 +339,4 @@ components: in: cookie name: kc-access type: apiKey - x-apikeyInfoFunc: samples.controllers.security_controller_.info_from_cookieAuth + x-apikeyInfoFunc: cloudharness.auth.decode_token diff --git a/applications/samples/backend/setup.py b/applications/samples/backend/setup.py index 2189bda50..a7a64a899 100644 --- a/applications/samples/backend/setup.py +++ b/applications/samples/backend/setup.py @@ -14,11 +14,11 @@ # http://pypi.python.org/pypi/setuptools REQUIRES = [ - "connexion[swagger-ui,flask,uvicorn]>=3.0.0,<4.0.0", - "Flask", - "python_dateutil", - "pyjwt", - "swagger-ui-bundle", + "connexion[swagger-ui]==2.14.2", + "Flask >= 2.2.5", + "python_dateutil>=2.6.0", + "pyjwt>=2.6.0", + "swagger-ui-bundle>=0.0.2", "cloudharness", ] diff --git a/applications/samples/deploy/values-test.yaml b/applications/samples/deploy/values-test.yaml index bf4b15280..e897ad996 100644 --- a/applications/samples/deploy/values-test.yaml +++ b/applications/samples/deploy/values-test.yaml @@ -6,10 +6,6 @@ harness: - common - jupyterhub - volumemanager - build: - - cloudharness-flask - - cloudharness-frontend-build - - cloudharness-django accounts: roles: - role1 diff --git a/applications/samples/deploy/values.yaml b/applications/samples/deploy/values.yaml index ed04be7c7..1006e7a1f 100644 --- a/applications/samples/deploy/values.yaml +++ b/applications/samples/deploy/values.yaml @@ -17,9 +17,6 @@ harness: usenfs: false auto: true port: 8080 - proxy: - gatekeeper: - replicas: 1 uri_role_mapping: - uri: / white-listed: true diff --git a/applications/samples/dev-setup.sh b/applications/samples/dev-setup.sh deleted file mode 100755 index 18057a5e1..000000000 --- a/applications/samples/dev-setup.sh +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env bash - -CURRENT_PATH=$(pwd) -CH_DIRECTORY="../.." -INSTALL_PYTEST=false -CURRENT_DIRECTORY="$(pwd)" -APP_NAME="samples" - -pip_upgrade_error() { - echo "Unable to upgrade pip" - exit 1 -} - -install_error () { - echo "Unable to install $1" 1>&2 - exit 1 -} - -while getopts ch_directory:pytest arg; -do - case "$arg" in - ch_directory) CH_DIRECTORY=${OPTARG};; - pytest) INSTALL_PYTEST=true;; - esac -done - -pip install --upgrade pip || pip_upgrade_error - -# Install pip dependencies from cloudharness-base-debian image - -if $INSTALL_PYTEST; then - pip install pytest || install_error pytest -fi - -pip install -r "$CH_DIRECTORY/libraries/models/requirements.txt" || install_error "models requirements" -pip install -r "$CH_DIRECTORY/libraries/cloudharness-common/requirements.txt" || install_error "cloudharness-common requirements" -pip install -r "$CH_DIRECTORY/libraries/client/cloudharness_cli/requirements.txt" || install_error "cloudharness_cli requirements" - -pip install -e "$CH_DIRECTORY/libraries/models" || install_error models -pip install -e "$CH_DIRECTORY/libraries/cloudharness-common" || install_error cloudharness-common -pip install -e "$CH_DIRECTORY/libraries/client/cloudharness_cli" || install_error cloudharness_cli - -# Install pip dependencies from cloudharness-django image -pip install -r "$CH_DIRECTORY/infrastructure/common-images/cloudharness-flask/requirements.txt" || install_error cloudharness-flask - -# Install application - -pip install -r "$CURRENT_DIRECTORY/backend/requirements.txt" || install_error "$APP_NAME dependencies" -pip install -e "$CURRENT_DIRECTORY/backend" || install_error "$APP_NAME" \ No newline at end of file diff --git a/applications/samples/tasks/sum/Dockerfile b/applications/samples/tasks/sum/Dockerfile index da1ae310e..fea3c1d5a 100644 --- a/applications/samples/tasks/sum/Dockerfile +++ b/applications/samples/tasks/sum/Dockerfile @@ -1,5 +1,5 @@ -ARG SAMPLES -FROM $SAMPLES +ARG CLOUDHARNESS_BASE +FROM $CLOUDHARNESS_BASE ADD . / diff --git a/applications/volumemanager/deploy/values-test.yaml b/applications/volumemanager/deploy/values-test.yaml index 139597f9c..5f5c264cf 100644 --- a/applications/volumemanager/deploy/values-test.yaml +++ b/applications/volumemanager/deploy/values-test.yaml @@ -1,2 +1,14 @@ +harness: + accounts: + roles: + - role1 + - role2 + - role3 + users: + - username: volumes@testuser.com + clientRoles: + - role1 + realmRoles: + - administrator diff --git a/applications/volumemanager/deploy/values.yaml b/applications/volumemanager/deploy/values.yaml index 763fcec9d..0b10b02d0 100644 --- a/applications/volumemanager/deploy/values.yaml +++ b/applications/volumemanager/deploy/values.yaml @@ -1,9 +1,6 @@ harness: name: volumemanager subdomain: volumemanager - proxy: - gatekeeper: - replicas: 1 service: port: 8080 auto: true @@ -18,7 +15,7 @@ harness: - cloudharness-flask test: api: - enabled: false + enabled: true autotest: true checks: - all \ No newline at end of file diff --git a/applications/volumemanager/server/.openapi-generator-ignore b/applications/volumemanager/server/.openapi-generator-ignore index 20636ed89..12e95840e 100644 --- a/applications/volumemanager/server/.openapi-generator-ignore +++ b/applications/volumemanager/server/.openapi-generator-ignore @@ -27,5 +27,4 @@ Dockerfile */__main__.py */test/* test-requirements.txt -.dockerignore -*/requirements.txt \ No newline at end of file +.dockerignore \ No newline at end of file diff --git a/applications/volumemanager/server/Dockerfile b/applications/volumemanager/server/Dockerfile index 578165c37..c098bfb5e 100644 --- a/applications/volumemanager/server/Dockerfile +++ b/applications/volumemanager/server/Dockerfile @@ -15,3 +15,5 @@ RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip & COPY . /usr/src/app RUN pip3 install -e . + +ENTRYPOINT gunicorn --workers=$WORKERS --bind=0.0.0.0:$PORT $MODULE_NAME.__main__:app diff --git a/applications/volumemanager/server/requirements.txt b/applications/volumemanager/server/requirements.txt index 89d041dd0..b3db72c8a 100644 --- a/applications/volumemanager/server/requirements.txt +++ b/applications/volumemanager/server/requirements.txt @@ -1,5 +1,5 @@ -connexion[swagger-ui,flask,uvicorn]>=3.0.0,<4.0.0 -swagger-ui-bundle>=1.1.0 -python_dateutil>=2.9.0 -setuptools>=21.0.0 -uvicorn +connexion[swagger-ui]==2.14.2 +swagger-ui-bundle >= 0.0.2 +python_dateutil >= 2.6.0 +setuptools >= 21.0.0 +Flask<3.0.0 diff --git a/applications/volumemanager/server/tox.ini b/applications/volumemanager/server/tox.ini index 455712524..cf2d20a38 100644 --- a/applications/volumemanager/server/tox.ini +++ b/applications/volumemanager/server/tox.ini @@ -5,7 +5,7 @@ skipsdist=True [testenv] deps=-r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt - {toxinidir} + {toxinidir} commands= pytest --cov=volumemanager diff --git a/applications/volumemanager/server/volumemanager/encoder.py b/applications/volumemanager/server/volumemanager/encoder.py index c1366fd5d..50e16388d 100644 --- a/applications/volumemanager/server/volumemanager/encoder.py +++ b/applications/volumemanager/server/volumemanager/encoder.py @@ -1,6 +1,7 @@ from connexion.apps.flask_app import FlaskJSONEncoder +import six -from volumemanager.models.base_model import Model +from volumemanager.models.base_model_ import Model class JSONEncoder(FlaskJSONEncoder): @@ -9,7 +10,7 @@ class JSONEncoder(FlaskJSONEncoder): def default(self, o): if isinstance(o, Model): dikt = {} - for attr in o.openapi_types: + for attr, _ in six.iteritems(o.openapi_types): value = getattr(o, attr) if value is None and not self.include_nulls: continue diff --git a/applications/volumemanager/server/volumemanager/models/__init__.py b/applications/volumemanager/server/volumemanager/models/__init__.py index cdf0530f4..48dcdcbc4 100644 --- a/applications/volumemanager/server/volumemanager/models/__init__.py +++ b/applications/volumemanager/server/volumemanager/models/__init__.py @@ -1,4 +1,7 @@ +# coding: utf-8 + # flake8: noqa +from __future__ import absolute_import # import models into model package from volumemanager.models.persistent_volume_claim import PersistentVolumeClaim from volumemanager.models.persistent_volume_claim_create import PersistentVolumeClaimCreate diff --git a/applications/volumemanager/server/volumemanager/models/persistent_volume_claim.py b/applications/volumemanager/server/volumemanager/models/persistent_volume_claim.py index 4d40d905a..36664245d 100644 --- a/applications/volumemanager/server/volumemanager/models/persistent_volume_claim.py +++ b/applications/volumemanager/server/volumemanager/models/persistent_volume_claim.py @@ -1,8 +1,11 @@ +# coding: utf-8 + +from __future__ import absolute_import from datetime import date, datetime # noqa: F401 from typing import List, Dict # noqa: F401 -from volumemanager.models.base_model import Model +from volumemanager.models.base_model_ import Model from volumemanager import util @@ -55,7 +58,7 @@ def from_dict(cls, dikt) -> 'PersistentVolumeClaim': return util.deserialize_model(dikt, cls) @property - def name(self) -> str: + def name(self): """Gets the name of this PersistentVolumeClaim. Unique name for the Persisten Volume Claim # noqa: E501 @@ -66,7 +69,7 @@ def name(self) -> str: return self._name @name.setter - def name(self, name: str): + def name(self, name): """Sets the name of this PersistentVolumeClaim. Unique name for the Persisten Volume Claim # noqa: E501 @@ -78,7 +81,7 @@ def name(self, name: str): self._name = name @property - def namespace(self) -> str: + def namespace(self): """Gets the namespace of this PersistentVolumeClaim. The namespace where the Persistent Volume Claim resides in # noqa: E501 @@ -89,7 +92,7 @@ def namespace(self) -> str: return self._namespace @namespace.setter - def namespace(self, namespace: str): + def namespace(self, namespace): """Sets the namespace of this PersistentVolumeClaim. The namespace where the Persistent Volume Claim resides in # noqa: E501 @@ -101,7 +104,7 @@ def namespace(self, namespace: str): self._namespace = namespace @property - def accessmode(self) -> str: + def accessmode(self): """Gets the accessmode of this PersistentVolumeClaim. The accessmode of the Persistent Volume Claim # noqa: E501 @@ -112,7 +115,7 @@ def accessmode(self) -> str: return self._accessmode @accessmode.setter - def accessmode(self, accessmode: str): + def accessmode(self, accessmode): """Sets the accessmode of this PersistentVolumeClaim. The accessmode of the Persistent Volume Claim # noqa: E501 @@ -124,7 +127,7 @@ def accessmode(self, accessmode: str): self._accessmode = accessmode @property - def size(self) -> str: + def size(self): """Gets the size of this PersistentVolumeClaim. The size of the Persistent Volume Claim. # noqa: E501 @@ -135,7 +138,7 @@ def size(self) -> str: return self._size @size.setter - def size(self, size: str): + def size(self, size): """Sets the size of this PersistentVolumeClaim. The size of the Persistent Volume Claim. # noqa: E501 diff --git a/applications/volumemanager/server/volumemanager/models/persistent_volume_claim_create.py b/applications/volumemanager/server/volumemanager/models/persistent_volume_claim_create.py index 30ba41687..dd84f5ee2 100644 --- a/applications/volumemanager/server/volumemanager/models/persistent_volume_claim_create.py +++ b/applications/volumemanager/server/volumemanager/models/persistent_volume_claim_create.py @@ -1,8 +1,11 @@ +# coding: utf-8 + +from __future__ import absolute_import from datetime import date, datetime # noqa: F401 from typing import List, Dict # noqa: F401 -from volumemanager.models.base_model import Model +from volumemanager.models.base_model_ import Model from volumemanager import util @@ -45,7 +48,7 @@ def from_dict(cls, dikt) -> 'PersistentVolumeClaimCreate': return util.deserialize_model(dikt, cls) @property - def name(self) -> str: + def name(self): """Gets the name of this PersistentVolumeClaimCreate. Unique name for the Persisten Volume Claim to create. # noqa: E501 @@ -56,7 +59,7 @@ def name(self) -> str: return self._name @name.setter - def name(self, name: str): + def name(self, name): """Sets the name of this PersistentVolumeClaimCreate. Unique name for the Persisten Volume Claim to create. # noqa: E501 @@ -68,7 +71,7 @@ def name(self, name: str): self._name = name @property - def size(self) -> str: + def size(self): """Gets the size of this PersistentVolumeClaimCreate. The size of the Persistent Volume Claim to create. # noqa: E501 @@ -79,7 +82,7 @@ def size(self) -> str: return self._size @size.setter - def size(self, size: str): + def size(self, size): """Sets the size of this PersistentVolumeClaimCreate. The size of the Persistent Volume Claim to create. # noqa: E501 diff --git a/applications/volumemanager/server/volumemanager/typing_utils.py b/applications/volumemanager/server/volumemanager/typing_utils.py index 74e3c913a..0563f81fd 100644 --- a/applications/volumemanager/server/volumemanager/typing_utils.py +++ b/applications/volumemanager/server/volumemanager/typing_utils.py @@ -1,3 +1,5 @@ +# coding: utf-8 + import sys if sys.version_info < (3, 7): diff --git a/applications/volumemanager/server/volumemanager/util.py b/applications/volumemanager/server/volumemanager/util.py index a6faf5dd4..6f7117ad0 100644 --- a/applications/volumemanager/server/volumemanager/util.py +++ b/applications/volumemanager/server/volumemanager/util.py @@ -1,5 +1,6 @@ import datetime +import six import typing from volumemanager import typing_utils @@ -15,7 +16,7 @@ def _deserialize(data, klass): if data is None: return None - if klass in (int, float, str, bool, bytearray): + if klass in six.integer_types or klass in (float, str, bool, bytearray): return _deserialize_primitive(data, klass) elif klass == object: return _deserialize_object(data) @@ -44,7 +45,7 @@ def _deserialize_primitive(data, klass): try: value = klass(data) except UnicodeEncodeError: - value = data + value = six.u(data) except TypeError: value = data return value @@ -109,7 +110,7 @@ def deserialize_model(data, klass): if not instance.openapi_types: return data - for attr, attr_type in instance.openapi_types.items(): + for attr, attr_type in six.iteritems(instance.openapi_types): if data is not None \ and instance.attribute_map[attr] in data \ and isinstance(data, (list, dict)): @@ -144,4 +145,4 @@ def _deserialize_dict(data, boxed_type): :rtype: dict """ return {k: _deserialize(v, boxed_type) - for k, v in data.items()} + for k, v in six.iteritems(data)} diff --git a/applications/workflows/server/.openapi-generator-ignore b/applications/workflows/server/.openapi-generator-ignore index e1e9bf3b6..bb1b45c8b 100644 --- a/applications/workflows/server/.openapi-generator-ignore +++ b/applications/workflows/server/.openapi-generator-ignore @@ -28,5 +28,4 @@ Dockerfile */__main__.py */test/* test-requirements.txt -.dockerignore -*/requirements.txt \ No newline at end of file +.dockerignore \ No newline at end of file diff --git a/applications/workflows/server/Dockerfile b/applications/workflows/server/Dockerfile index b4c3ddd30..6d2efaf48 100644 --- a/applications/workflows/server/Dockerfile +++ b/applications/workflows/server/Dockerfile @@ -13,3 +13,5 @@ COPY . /usr/src/app EXPOSE 8080 RUN pip3 install -e . + +ENTRYPOINT gunicorn --workers=$WORKERS --bind=0.0.0.0:$PORT $MODULE_NAME.__main__:app \ No newline at end of file diff --git a/applications/workflows/server/requirements.txt b/applications/workflows/server/requirements.txt index 89d041dd0..7c5714ba0 100644 --- a/applications/workflows/server/requirements.txt +++ b/applications/workflows/server/requirements.txt @@ -1,5 +1,5 @@ -connexion[swagger-ui,flask,uvicorn]>=3.0.0,<4.0.0 -swagger-ui-bundle>=1.1.0 -python_dateutil>=2.9.0 -setuptools>=21.0.0 -uvicorn +connexion[swagger-ui]==2.14.2 +swagger-ui-bundle > 0.0.2 +python_dateutil >= 2.6.0 +setuptools >= 21.0.0 +Flask >= 2.1.0 diff --git a/applications/workflows/server/tox.ini b/applications/workflows/server/tox.ini index 2a7347342..63745caf8 100644 --- a/applications/workflows/server/tox.ini +++ b/applications/workflows/server/tox.ini @@ -5,7 +5,7 @@ skipsdist=True [testenv] deps=-r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt - {toxinidir} + {toxinidir} commands= pytest --cov=workflows_api diff --git a/applications/workflows/server/workflows_api/encoder.py b/applications/workflows/server/workflows_api/encoder.py index c15d45653..ffc6e492e 100644 --- a/applications/workflows/server/workflows_api/encoder.py +++ b/applications/workflows/server/workflows_api/encoder.py @@ -1,6 +1,7 @@ from connexion.apps.flask_app import FlaskJSONEncoder +import six -from workflows_api.models.base_model import Model +from workflows_api.models.base_model_ import Model class JSONEncoder(FlaskJSONEncoder): @@ -9,7 +10,7 @@ class JSONEncoder(FlaskJSONEncoder): def default(self, o): if isinstance(o, Model): dikt = {} - for attr in o.openapi_types: + for attr, _ in six.iteritems(o.openapi_types): value = getattr(o, attr) if value is None and not self.include_nulls: continue diff --git a/applications/workflows/server/workflows_api/models/__init__.py b/applications/workflows/server/workflows_api/models/__init__.py index 3101e0321..ba414fcd1 100644 --- a/applications/workflows/server/workflows_api/models/__init__.py +++ b/applications/workflows/server/workflows_api/models/__init__.py @@ -1,4 +1,7 @@ +# coding: utf-8 + # flake8: noqa +from __future__ import absolute_import # import models into model package from workflows_api.models.operation import Operation from workflows_api.models.operation_search_result import OperationSearchResult diff --git a/applications/workflows/server/workflows_api/models/base_model.py b/applications/workflows/server/workflows_api/models/base_model.py deleted file mode 100644 index 12666b9d4..000000000 --- a/applications/workflows/server/workflows_api/models/base_model.py +++ /dev/null @@ -1,68 +0,0 @@ -import pprint - -import typing - -from workflows_api import util - -T = typing.TypeVar('T') - - -class Model: - # openapiTypes: The key is attribute name and the - # value is attribute type. - openapi_types: typing.Dict[str, type] = {} - - # attributeMap: The key is attribute name and the - # value is json key in definition. - attribute_map: typing.Dict[str, str] = {} - - @classmethod - def from_dict(cls: typing.Type[T], dikt) -> T: - """Returns the dict as a model""" - return util.deserialize_model(dikt, cls) - - def to_dict(self): - """Returns the model properties as a dict - - :rtype: dict - """ - result = {} - - for attr in self.openapi_types: - value = getattr(self, attr) - if isinstance(value, list): - result[attr] = list(map( - lambda x: x.to_dict() if hasattr(x, "to_dict") else x, - value - )) - elif hasattr(value, "to_dict"): - result[attr] = value.to_dict() - elif isinstance(value, dict): - result[attr] = dict(map( - lambda item: (item[0], item[1].to_dict()) - if hasattr(item[1], "to_dict") else item, - value.items() - )) - else: - result[attr] = value - - return result - - def to_str(self): - """Returns the string representation of the model - - :rtype: str - """ - return pprint.pformat(self.to_dict()) - - def __repr__(self): - """For `print` and `pprint`""" - return self.to_str() - - def __eq__(self, other): - """Returns true if both objects are equal""" - return self.__dict__ == other.__dict__ - - def __ne__(self, other): - """Returns true if both objects are not equal""" - return not self == other diff --git a/applications/workflows/server/workflows_api/models/operation.py b/applications/workflows/server/workflows_api/models/operation.py index c4362134e..c4d7ab750 100644 --- a/applications/workflows/server/workflows_api/models/operation.py +++ b/applications/workflows/server/workflows_api/models/operation.py @@ -1,8 +1,11 @@ +# coding: utf-8 + +from __future__ import absolute_import from datetime import date, datetime # noqa: F401 from typing import List, Dict # noqa: F401 -from workflows_api.models.base_model import Model +from workflows_api.models.base_model_ import Model from workflows_api.models.operation_status import OperationStatus from workflows_api import util @@ -14,7 +17,7 @@ class Operation(Model): Do not edit the class manually. """ - def __init__(self, message=None, name=None, create_time=None, status=OperationStatus.PENDING, workflow=None): # noqa: E501 + def __init__(self, message=None, name=None, create_time=None, status=None, workflow=None): # noqa: E501 """Operation - a model defined in OpenAPI :param message: The message of this Operation. # noqa: E501 @@ -62,7 +65,7 @@ def from_dict(cls, dikt) -> 'Operation': return util.deserialize_model(dikt, cls) @property - def message(self) -> str: + def message(self): """Gets the message of this Operation. usually set when an error occurred # noqa: E501 @@ -73,7 +76,7 @@ def message(self) -> str: return self._message @message.setter - def message(self, message: str): + def message(self, message): """Sets the message of this Operation. usually set when an error occurred # noqa: E501 @@ -85,7 +88,7 @@ def message(self, message: str): self._message = message @property - def name(self) -> str: + def name(self): """Gets the name of this Operation. operation name # noqa: E501 @@ -96,7 +99,7 @@ def name(self) -> str: return self._name @name.setter - def name(self, name: str): + def name(self, name): """Sets the name of this Operation. operation name # noqa: E501 @@ -108,7 +111,7 @@ def name(self, name: str): self._name = name @property - def create_time(self) -> datetime: + def create_time(self): """Gets the create_time of this Operation. @@ -118,7 +121,7 @@ def create_time(self) -> datetime: return self._create_time @create_time.setter - def create_time(self, create_time: datetime): + def create_time(self, create_time): """Sets the create_time of this Operation. @@ -129,7 +132,7 @@ def create_time(self, create_time: datetime): self._create_time = create_time @property - def status(self) -> OperationStatus: + def status(self): """Gets the status of this Operation. @@ -139,7 +142,7 @@ def status(self) -> OperationStatus: return self._status @status.setter - def status(self, status: OperationStatus): + def status(self, status): """Sets the status of this Operation. @@ -150,7 +153,7 @@ def status(self, status: OperationStatus): self._status = status @property - def workflow(self) -> str: + def workflow(self): """Gets the workflow of this Operation. low level representation as an Argo json # noqa: E501 @@ -161,7 +164,7 @@ def workflow(self) -> str: return self._workflow @workflow.setter - def workflow(self, workflow: str): + def workflow(self, workflow): """Sets the workflow of this Operation. low level representation as an Argo json # noqa: E501 diff --git a/applications/workflows/server/workflows_api/models/operation_search_result.py b/applications/workflows/server/workflows_api/models/operation_search_result.py index d284b10e6..d51b1b9b1 100644 --- a/applications/workflows/server/workflows_api/models/operation_search_result.py +++ b/applications/workflows/server/workflows_api/models/operation_search_result.py @@ -1,8 +1,11 @@ +# coding: utf-8 + +from __future__ import absolute_import from datetime import date, datetime # noqa: F401 from typing import List, Dict # noqa: F401 -from workflows_api.models.base_model import Model +from workflows_api.models.base_model_ import Model from workflows_api.models.operation import Operation from workflows_api.models.search_result_data import SearchResultData from workflows_api import util @@ -49,7 +52,7 @@ def from_dict(cls, dikt) -> 'OperationSearchResult': return util.deserialize_model(dikt, cls) @property - def meta(self) -> SearchResultData: + def meta(self): """Gets the meta of this OperationSearchResult. @@ -59,7 +62,7 @@ def meta(self) -> SearchResultData: return self._meta @meta.setter - def meta(self, meta: SearchResultData): + def meta(self, meta): """Sets the meta of this OperationSearchResult. @@ -70,7 +73,7 @@ def meta(self, meta: SearchResultData): self._meta = meta @property - def items(self) -> List[Operation]: + def items(self): """Gets the items of this OperationSearchResult. @@ -80,7 +83,7 @@ def items(self) -> List[Operation]: return self._items @items.setter - def items(self, items: List[Operation]): + def items(self, items): """Sets the items of this OperationSearchResult. diff --git a/applications/workflows/server/workflows_api/models/operation_status.py b/applications/workflows/server/workflows_api/models/operation_status.py index e53277800..e4492c7d7 100644 --- a/applications/workflows/server/workflows_api/models/operation_status.py +++ b/applications/workflows/server/workflows_api/models/operation_status.py @@ -1,8 +1,11 @@ +# coding: utf-8 + +from __future__ import absolute_import from datetime import date, datetime # noqa: F401 from typing import List, Dict # noqa: F401 -from workflows_api.models.base_model import Model +from workflows_api.models.base_model_ import Model from workflows_api import util @@ -15,12 +18,12 @@ class OperationStatus(Model): """ allowed enum values """ - PENDING = 'Pending' - RUNNING = 'Running' - ERROR = 'Error' - SUCCEEDED = 'Succeeded' - SKIPPED = 'Skipped' - FAILED = 'Failed' + PENDING = "Pending" + RUNNING = "Running" + ERROR = "Error" + SUCCEEDED = "Succeeded" + SKIPPED = "Skipped" + FAILED = "Failed" def __init__(self): # noqa: E501 """OperationStatus - a model defined in OpenAPI diff --git a/applications/workflows/server/workflows_api/models/search_result_data.py b/applications/workflows/server/workflows_api/models/search_result_data.py index f198e5ce5..e50fafecb 100644 --- a/applications/workflows/server/workflows_api/models/search_result_data.py +++ b/applications/workflows/server/workflows_api/models/search_result_data.py @@ -1,8 +1,11 @@ +# coding: utf-8 + +from __future__ import absolute_import from datetime import date, datetime # noqa: F401 from typing import List, Dict # noqa: F401 -from workflows_api.models.base_model import Model +from workflows_api.models.base_model_ import Model from workflows_api import util @@ -40,7 +43,7 @@ def from_dict(cls, dikt) -> 'SearchResultData': return util.deserialize_model(dikt, cls) @property - def continue_token(self) -> str: + def continue_token(self): """Gets the continue_token of this SearchResultData. token to use for pagination # noqa: E501 @@ -51,7 +54,7 @@ def continue_token(self) -> str: return self._continue_token @continue_token.setter - def continue_token(self, continue_token: str): + def continue_token(self, continue_token): """Sets the continue_token of this SearchResultData. token to use for pagination # noqa: E501 diff --git a/applications/workflows/server/workflows_api/openapi/openapi.yaml b/applications/workflows/server/workflows_api/openapi/openapi.yaml index bb969c058..638b9f9a7 100644 --- a/applications/workflows/server/workflows_api/openapi/openapi.yaml +++ b/applications/workflows/server/workflows_api/openapi/openapi.yaml @@ -1,4 +1,4 @@ -openapi: 3.0.3 +openapi: 3.0.0 info: contact: email: cloudharness@metacell.us @@ -21,9 +21,7 @@ paths: operationId: list_operations parameters: - description: filter by status - examples: - p: - value: Pending + example: Pending explode: true in: query name: status @@ -43,9 +41,6 @@ paths: type: string style: form - description: maximum number of records to return per page - examples: - e1: - value: "10" explode: true in: query name: limit @@ -75,8 +70,7 @@ paths: delete operation by its name operationId: delete_operation parameters: - - example: my-workflow - explode: false + - explode: false in: path name: name required: true @@ -110,7 +104,9 @@ paths: content: application/json: schema: - type: string + items: + $ref: '#/components/schemas/Operation' + type: array description: search results matching criteria "400": description: Bad request @@ -167,12 +163,12 @@ components: createTime: 2016-08-29T09:12:33.001Z name: name message: "" - status: Pending + status: null - workflow: workflow createTime: 2016-08-29T09:12:33.001Z name: name message: "" - status: Pending + status: null properties: meta: $ref: '#/components/schemas/SearchResultData' @@ -199,7 +195,7 @@ components: createTime: 2016-08-29T09:12:33.001Z name: name message: "" - status: Pending + status: null properties: message: description: usually set when an error occurred diff --git a/applications/workflows/server/workflows_api/typing_utils.py b/applications/workflows/server/workflows_api/typing_utils.py index 74e3c913a..0563f81fd 100644 --- a/applications/workflows/server/workflows_api/typing_utils.py +++ b/applications/workflows/server/workflows_api/typing_utils.py @@ -1,3 +1,5 @@ +# coding: utf-8 + import sys if sys.version_info < (3, 7): diff --git a/applications/workflows/server/workflows_api/util.py b/applications/workflows/server/workflows_api/util.py index 5dda3383e..04f3df25e 100644 --- a/applications/workflows/server/workflows_api/util.py +++ b/applications/workflows/server/workflows_api/util.py @@ -1,5 +1,6 @@ import datetime +import six import typing from workflows_api import typing_utils @@ -15,7 +16,7 @@ def _deserialize(data, klass): if data is None: return None - if klass in (int, float, str, bool, bytearray): + if klass in six.integer_types or klass in (float, str, bool, bytearray): return _deserialize_primitive(data, klass) elif klass == object: return _deserialize_object(data) @@ -44,7 +45,7 @@ def _deserialize_primitive(data, klass): try: value = klass(data) except UnicodeEncodeError: - value = data + value = six.u(data) except TypeError: value = data return value @@ -109,7 +110,7 @@ def deserialize_model(data, klass): if not instance.openapi_types: return data - for attr, attr_type in instance.openapi_types.items(): + for attr, attr_type in six.iteritems(instance.openapi_types): if data is not None \ and instance.attribute_map[attr] in data \ and isinstance(data, (list, dict)): @@ -144,4 +145,4 @@ def _deserialize_dict(data, boxed_type): :rtype: dict """ return {k: _deserialize(v, boxed_type) - for k, v in data.items()} + for k, v in six.iteritems(data)} diff --git a/deployment-configuration/compose/templates/_helpers.yaml b/deployment-configuration/compose/templates/_helpers.yaml index 8f107690b..49c3c4563 100644 --- a/deployment-configuration/compose/templates/_helpers.yaml +++ b/deployment-configuration/compose/templates/_helpers.yaml @@ -1,13 +1,9 @@ {{- define "convertToDecimal" -}} {{- $value := . -}} - {{- if kindIs "string" $value -}} - {{- if hasSuffix "m" $value -}} - {{- $number := replace "m" "" $value | float64 -}} - {{- $result := divf $number 1000.0 -}} - {{- printf "%.3f" $result -}} - {{- else -}} - {{- $value -}} - {{- end -}} + {{- if hasSuffix "m" $value -}} + {{- $number := replace "m" "" $value | float64 -}} + {{- $result := divf $number 1000.0 -}} + {{- printf "%.3f" $result -}} {{- else -}} {{- $value -}} {{- end -}} diff --git a/deployment-configuration/helm/templates/auto-database-mongo.yaml b/deployment-configuration/helm/templates/auto-database-mongo.yaml index 420e14f7d..fce3f4b36 100644 --- a/deployment-configuration/helm/templates/auto-database-mongo.yaml +++ b/deployment-configuration/helm/templates/auto-database-mongo.yaml @@ -12,7 +12,7 @@ livenessProbe: exec: command: - - mongo + - mongosh - --eval - "db.adminCommand('ping')" initialDelaySeconds: 30 @@ -21,7 +21,7 @@ readinessProbe: exec: command: - - mongo + - mongosh - --eval - "db.adminCommand('ping')" initialDelaySeconds: 5 diff --git a/deployment-configuration/helm/templates/auto-gatekeepers.yaml b/deployment-configuration/helm/templates/auto-gatekeepers.yaml index 2e1e6197a..32c66b0ef 100644 --- a/deployment-configuration/helm/templates/auto-gatekeepers.yaml +++ b/deployment-configuration/helm/templates/auto-gatekeepers.yaml @@ -121,7 +121,7 @@ metadata: labels: app: "{{ .subdomain }}-gk" spec: - replicas: {{ .app.harness.proxy.gatekeeper.replicas | default .root.Values.proxy.gatekeeper.replicas | default 5 }} + replicas: 1 selector: matchLabels: app: "{{ .subdomain }}-gk" @@ -135,7 +135,7 @@ spec: {{ include "deploy_utils.etcHosts" .root | indent 6 }} containers: - name: {{ .app.harness.service.name | quote }} - image: {{ .app.harness.proxy.gatekeeper.image | default .root.Values.proxy.gatekeeper.image | default "quay.io/gogatekeeper/gatekeeper:2.14.3" }} + image: "quay.io/gogatekeeper/gatekeeper:2.14.3" imagePullPolicy: IfNotPresent {{ if .root.Values.local }} securityContext: @@ -163,7 +163,12 @@ spec: - name: https containerPort: 8443 resources: -{{ .app.harness.proxy.gatekeeper.resources | default .root.Values.proxy.gatekeeper.resources | toYaml | nindent 10 }} + requests: + memory: "32Mi" + cpu: "5m" + limits: + memory: "64Mi" + cpu: "100m" volumes: - name: "{{ .subdomain }}-gk-proxy-config" configMap: diff --git a/deployment-configuration/helm/templates/ingress.yaml b/deployment-configuration/helm/templates/ingress.yaml index 5d3ea8ee7..425ac3beb 100644 --- a/deployment-configuration/helm/templates/ingress.yaml +++ b/deployment-configuration/helm/templates/ingress.yaml @@ -1,52 +1,15 @@ {{- define "deploy_utils.ingress.http" }} {{ $domain := .root.Values.domain }} {{ $secured_gatekeepers := and .root.Values.secured_gatekeepers }} - {{ $app := .app }} http: paths: -{{- if and $app.harness.secured $secured_gatekeepers $app.harness.uri_role_mapping }} - {{- range $mapping := $app.harness.uri_role_mapping }} - {{- if and (hasKey $mapping "white-listed") (index $mapping "white-listed") }} - {{- $uri := $mapping.uri }} - {{- if eq $uri "/" }} - - path: /() - pathType: ImplementationSpecific - backend: - service: - name: {{ $app.harness.service.name | quote }} - port: - number: {{ $app.harness.service.port | default 80 }} - {{- else if hasSuffix "/*" $uri }} - {{- $cleanPath := trimSuffix "/*" $uri }} - {{- $pathWithoutSlash := trimPrefix "/" $cleanPath }} - - path: {{ printf "/(%s/.*)" $pathWithoutSlash }} - pathType: ImplementationSpecific - backend: - service: - name: {{ $app.harness.service.name | quote }} - port: - number: {{ $app.harness.service.port | default 80 }} - {{- else if not (contains "*" $uri) }} - {{- $pathWithoutSlash := trimPrefix "/" $uri }} - - path: {{ printf "/(%s)" $pathWithoutSlash }} - pathType: ImplementationSpecific - backend: - service: - name: {{ $app.harness.service.name | quote }} - port: - number: {{ $app.harness.service.port | default 80 }} - {{- end }} - {{- end }} - {{- end }} -{{- end }} - path: /(.*) pathType: ImplementationSpecific backend: service: - name: {{ if (and $app.harness.secured $secured_gatekeepers) }}{{ printf "%s-gk" .subdomain }}{{ else }}{{ $app.harness.service.name | quote }}{{ end }} + name: {{ if (and .app.harness.secured $secured_gatekeepers) }}{{ printf "%s-gk" .subdomain }}{{ else }}{{ .app.harness.service.name | quote }}{{ end }} port: - number: {{- if (and $app.harness.secured $secured_gatekeepers) }} 8080 {{- else }} {{ $app.harness.service.port | default 80 }}{{- end }} - + number: {{- if (and .app.harness.secured $secured_gatekeepers) }} 8080 {{- else }} {{ .app.harness.service.port | default 80 }}{{- end }} {{- end }} {{- define "deploy_utils.ingress.service" }} {{ $domain := .root.Values.domain }} @@ -77,9 +40,6 @@ metadata: nginx.ingress.kubernetes.io/ssl-redirect: {{ (and $tls .Values.ingress.ssl_redirect) | quote }} nginx.ingress.kubernetes.io/proxy-body-size: '{{ .Values.proxy.payload.max }}m' nginx.ingress.kubernetes.io/proxy-buffer-size: '128k' - nginx.ingress.kubernetes.io/proxy-buffering: "on" - nginx.ingress.kubernetes.io/proxy-buffers-number: "8" - nginx.ingress.kubernetes.io/proxy-max-temp-file-size: "1024m" nginx.ingress.kubernetes.io/from-to-www-redirect: 'true' nginx.ingress.kubernetes.io/rewrite-target: /$1 nginx.ingress.kubernetes.io/auth-keepalive-timeout: {{ .Values.proxy.timeout.keepalive | quote }} diff --git a/deployment-configuration/helm/values.yaml b/deployment-configuration/helm/values.yaml index ec38061b0..75a14f3ab 100644 --- a/deployment-configuration/helm/values.yaml +++ b/deployment-configuration/helm/values.yaml @@ -76,13 +76,3 @@ proxy: payload: # -- Maximum size of payload in MB max: 250 - gatekeeper: - # -- Default gatekeeper image - image: "quay.io/gogatekeeper/gatekeeper:2.14.3" - # -- Default number of gatekeeper replicas - replicas: 1 - resources: - requests: - memory: "32Mi" - limits: - memory: "64Mi" diff --git a/deployment-configuration/tilt-deploy.ext b/deployment-configuration/tilt-deploy.ext new file mode 100644 index 000000000..1d1ed04a7 --- /dev/null +++ b/deployment-configuration/tilt-deploy.ext @@ -0,0 +1,67 @@ +load('ext://namespace', 'namespace_create', "namespace_inject") + + +def deploy(name, namespace, extra_env, watch): + + # create namespaces + namespace_create(namespace) + + # load helm chart + yaml = decode_yaml_stream(helm( + "deployment/helm", + # The release name, equivalent to helm --name + name=name, + # The namespace to install in, equivalent to helm --namespace + namespace=namespace, + # The values file to substitute into the chart. + values=["deployment/helm/values.yaml"], + # Values to set from the command-line + set=["service.port=1234", "ingress.enabled=true"] + ) + ) + + source_root = os.path.abspath(os.getcwd()) + # modify deployments + for r in yaml: + if r.get("kind") == "Deployment": + deployment_name = r["metadata"]["name"] + print("+ patching deployment:", deployment_name) + r["spec"]["template"]["spec"].setdefault("volumes", []).append({ + "name": name + "-root", + "hostPath": { + "path": source_root + } + }) + for container in r["spec"]["template"]["spec"]["containers"]: + print(" + modifying container:", container["name"]) + print(" - add " + name + " root folder") + container.setdefault("volumeMounts", []).append({ + "mountPath": "/usr/src/" + name, + "name": name + "-root" + }) + if "resources" in container: + print(" - modifying resource requests and limits") + if "limits" not in container["resources"]: + container["resources"]["limits"] = {} + if "requests" not in container["resources"]: + container["resources"]["requests"] = {} + container["resources"]["requests"]["cpu"] = "100m" + container["resources"]["requests"]["memory"] = "256Mi" + container["resources"]["limits"]["cpu"] = "8000m" + container["resources"]["limits"]["memory"] = "4096Mi" + + if deployment_name in extra_env and len(extra_env[deployment_name]) > 0: + print("Adding tasks images dependencies to env ", deployment_name) + for env in extra_env[deployment_name]: + container["env"].append({ + "name": env, "value": env + }) + + if not watch: + # don't watch mnp folder + watch_settings(ignore=source_root) + else: + print("Watching for file changes") + + # install applications + k8s_yaml(namespace_inject(encode_yaml_stream(yaml), namespace)) diff --git a/deployment-configuration/value-template.yaml b/deployment-configuration/value-template.yaml index 31f1b7eb9..50cc7b11b 100644 --- a/deployment-configuration/value-template.yaml +++ b/deployment-configuration/value-template.yaml @@ -139,13 +139,3 @@ harness: payload: # -- Maximum size of payload in MB max: - gatekeeper: - # -- Default gatekeeper image - image: "quay.io/gogatekeeper/gatekeeper:2.14.3" - # -- Default number of gatekeeper replicas - replicas: 1 - resources: - requests: - memory: "32Mi" - limits: - memory: "64Mi" \ No newline at end of file diff --git a/deployment/codefresh-test.yaml b/deployment/codefresh-test.yaml index 81086444b..e9699e95a 100644 --- a/deployment/codefresh-test.yaml +++ b/deployment/codefresh-test.yaml @@ -13,26 +13,13 @@ steps: repo: '${{CF_REPO_OWNER}}/${{CF_REPO_NAME}}' revision: '${{CF_BRANCH}}' git: github - post_main_clone: - title: Post main clone - type: parallel - stage: prepare - steps: - clone_cloud_harness: - title: Cloning cloud-harness repository... - type: git-clone - stage: prepare - repo: https://github.com/MetaCell/cloud-harness.git - revision: '${{CLOUDHARNESS_BRANCH}}' - working_directory: . - git: github prepare_deployment: title: Prepare helm chart image: python:3.12 stage: prepare working_directory: . commands: - - bash cloud-harness/install.sh + - bash ./install.sh - harness-deployment . -n test-${{NAMESPACE_BASENAME}} -d ${{DOMAIN}} -r ${{REGISTRY}} -rs ${{REGISTRY_SECRET}} -e test --write-env --cache-url '${{IMAGE_CACHE_URL}}' -N -i samples @@ -51,28 +38,6 @@ steps: type: parallel stage: build steps: - cloudharness-frontend-build: - type: build - stage: build - dockerfile: infrastructure/base-images/cloudharness-frontend-build/Dockerfile - registry: '${{CODEFRESH_REGISTRY}}' - buildkit: true - build_arguments: - - NOCACHE=${{CF_BUILD_ID}} - image_name: cloud-harness/cloudharness-frontend-build - title: Cloudharness frontend build - working_directory: ./. - tags: - - '${{CLOUDHARNESS_FRONTEND_BUILD_TAG}}' - - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - when: - condition: - any: - buildDoesNotExist: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}', - '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}', - '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}') == false accounts: type: build stage: build @@ -117,6 +82,28 @@ steps: == true forceNoCache: includes('${{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_BASE_TAG_FORCE_BUILD}}') == false + cloudharness-frontend-build: + type: build + stage: build + dockerfile: infrastructure/base-images/cloudharness-frontend-build/Dockerfile + registry: '${{CODEFRESH_REGISTRY}}' + buildkit: true + build_arguments: + - NOCACHE=${{CF_BUILD_ID}} + image_name: cloud-harness/cloudharness-frontend-build + title: Cloudharness frontend build + working_directory: ./. + tags: + - '${{CLOUDHARNESS_FRONTEND_BUILD_TAG}}' + - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' + - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + when: + condition: + any: + buildDoesNotExist: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}', + '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_EXISTS}}') == true + forceNoCache: includes('${{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}', + '{{CLOUDHARNESS_FRONTEND_BUILD_TAG_FORCE_BUILD}}') == false test-e2e: type: build stage: build @@ -145,7 +132,7 @@ steps: type: parallel stage: build steps: - workflows-extract-download: + jupyterhub: type: build stage: build dockerfile: Dockerfile @@ -154,21 +141,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-extract-download - title: Workflows extract download - working_directory: ./applications/workflows/tasks/extract-download + image_name: cloud-harness/jupyterhub + title: Jupyterhub + working_directory: ./applications/jupyterhub tags: - - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' + - '${{JUPYTERHUB_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false - samples-secret: + buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') + == true + forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') + == false + workflows-extract-download: type: build stage: build dockerfile: Dockerfile @@ -177,21 +164,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-secret - title: Samples secret - working_directory: ./applications/samples/tasks/secret + image_name: cloud-harness/workflows-extract-download + title: Workflows extract download + working_directory: ./applications/workflows/tasks/extract-download tags: - - '${{SAMPLES_SECRET_TAG}}' + - '${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') - == true - forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') - == false - workflows-send-result-event: + buildDoesNotExist: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_EXTRACT_DOWNLOAD_TAG_FORCE_BUILD}}') == false + workflows-notify-queue: type: build stage: build dockerfile: Dockerfile @@ -200,21 +187,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-send-result-event - title: Workflows send result event - working_directory: ./applications/workflows/tasks/send-result-event + image_name: cloud-harness/workflows-notify-queue + title: Workflows notify queue + working_directory: ./applications/workflows/tasks/notify-queue tags: - - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' + - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false - cloudharness-flask: + buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false + samples-print-file: type: build stage: build dockerfile: Dockerfile @@ -223,21 +210,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/cloudharness-flask - title: Cloudharness flask - working_directory: ./infrastructure/common-images/cloudharness-flask + image_name: cloud-harness/samples-print-file + title: Samples print file + working_directory: ./applications/samples/tasks/print-file tags: - - '${{CLOUDHARNESS_FLASK_TAG}}' + - '${{SAMPLES_PRINT_FILE_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') == false - jupyterhub: + workflows-send-result-event: type: build stage: build dockerfile: Dockerfile @@ -246,44 +233,45 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/jupyterhub - title: Jupyterhub - working_directory: ./applications/jupyterhub + image_name: cloud-harness/workflows-send-result-event + title: Workflows send result event + working_directory: ./applications/workflows/tasks/send-result-event tags: - - '${{JUPYTERHUB_TAG}}' + - '${{WORKFLOWS_SEND_RESULT_EVENT_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{JUPYTERHUB_TAG_EXISTS}}', '{{JUPYTERHUB_TAG_EXISTS}}') - == true - forceNoCache: includes('${{JUPYTERHUB_TAG_FORCE_BUILD}}', '{{JUPYTERHUB_TAG_FORCE_BUILD}}') - == false - samples-print-file: + buildDoesNotExist: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_EXISTS}}') == true + forceNoCache: includes('${{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}', + '{{WORKFLOWS_SEND_RESULT_EVENT_TAG_FORCE_BUILD}}') == false + test-api: type: build stage: build - dockerfile: Dockerfile + dockerfile: test/test-api/Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/samples-print-file - title: Samples print file - working_directory: ./applications/samples/tasks/print-file + image_name: cloud-harness/test-api + title: Test api + working_directory: ./. tags: - - '${{SAMPLES_PRINT_FILE_TAG}}' + - '${{TEST_API_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' + - latest when: condition: any: - buildDoesNotExist: includes('${{SAMPLES_PRINT_FILE_TAG_EXISTS}}', '{{SAMPLES_PRINT_FILE_TAG_EXISTS}}') + buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') == true - forceNoCache: includes('${{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}', '{{SAMPLES_PRINT_FILE_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') == false - cloudharness-django: + samples-secret: type: build stage: build dockerfile: Dockerfile @@ -292,21 +280,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/cloudharness-django - title: Cloudharness django - working_directory: ./infrastructure/common-images/cloudharness-django + image_name: cloud-harness/samples-secret + title: Samples secret + working_directory: ./applications/samples/tasks/secret tags: - - '${{CLOUDHARNESS_DJANGO_TAG}}' + - '${{SAMPLES_SECRET_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{CLOUDHARNESS_DJANGO_TAG_EXISTS}}', '{{CLOUDHARNESS_DJANGO_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_SECRET_TAG_EXISTS}}', '{{SAMPLES_SECRET_TAG_EXISTS}}') == true - forceNoCache: includes('${{CLOUDHARNESS_DJANGO_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_DJANGO_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_SECRET_TAG_FORCE_BUILD}}', '{{SAMPLES_SECRET_TAG_FORCE_BUILD}}') == false - workflows-notify-queue: + cloudharness-flask: type: build stage: build dockerfile: Dockerfile @@ -315,43 +303,42 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/workflows-notify-queue - title: Workflows notify queue - working_directory: ./applications/workflows/tasks/notify-queue + image_name: cloud-harness/cloudharness-flask + title: Cloudharness flask + working_directory: ./infrastructure/common-images/cloudharness-flask tags: - - '${{WORKFLOWS_NOTIFY_QUEUE_TAG}}' + - '${{CLOUDHARNESS_FLASK_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}', - '{{WORKFLOWS_NOTIFY_QUEUE_TAG_FORCE_BUILD}}') == false - test-api: + buildDoesNotExist: includes('${{CLOUDHARNESS_FLASK_TAG_EXISTS}}', '{{CLOUDHARNESS_FLASK_TAG_EXISTS}}') + == true + forceNoCache: includes('${{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}', '{{CLOUDHARNESS_FLASK_TAG_FORCE_BUILD}}') + == false + samples-sum: type: build stage: build - dockerfile: test/test-api/Dockerfile + dockerfile: Dockerfile registry: '${{CODEFRESH_REGISTRY}}' buildkit: true build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_BASE=${{REGISTRY}}/cloud-harness/cloudharness-base:${{CLOUDHARNESS_BASE_TAG}} - image_name: cloud-harness/test-api - title: Test api - working_directory: ./. + image_name: cloud-harness/samples-sum + title: Samples sum + working_directory: ./applications/samples/tasks/sum tags: - - '${{TEST_API_TAG}}' + - '${{SAMPLES_SUM_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - - latest when: condition: any: - buildDoesNotExist: includes('${{TEST_API_TAG_EXISTS}}', '{{TEST_API_TAG_EXISTS}}') + buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') == true - forceNoCache: includes('${{TEST_API_TAG_FORCE_BUILD}}', '{{TEST_API_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') == false title: Build parallel step 2 build_application_images_2: @@ -382,7 +369,7 @@ steps: == true forceNoCache: includes('${{SAMPLES_TAG_FORCE_BUILD}}', '{{SAMPLES_TAG_FORCE_BUILD}}') == false - workflows: + common: type: build stage: build dockerfile: Dockerfile @@ -391,19 +378,19 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/workflows - title: Workflows - working_directory: ./applications/workflows/server + image_name: cloud-harness/common + title: Common + working_directory: ./applications/common/server tags: - - '${{WORKFLOWS_TAG}}' + - '${{COMMON_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') + buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') == true - forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') == false volumemanager: type: build @@ -428,7 +415,7 @@ steps: == true forceNoCache: includes('${{VOLUMEMANAGER_TAG_FORCE_BUILD}}', '{{VOLUMEMANAGER_TAG_FORCE_BUILD}}') == false - common: + workflows: type: build stage: build dockerfile: Dockerfile @@ -437,49 +424,21 @@ steps: build_arguments: - NOCACHE=${{CF_BUILD_ID}} - CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}} - image_name: cloud-harness/common - title: Common - working_directory: ./applications/common/server + image_name: cloud-harness/workflows + title: Workflows + working_directory: ./applications/workflows/server tags: - - '${{COMMON_TAG}}' + - '${{WORKFLOWS_TAG}}' - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' when: condition: any: - buildDoesNotExist: includes('${{COMMON_TAG_EXISTS}}', '{{COMMON_TAG_EXISTS}}') + buildDoesNotExist: includes('${{WORKFLOWS_TAG_EXISTS}}', '{{WORKFLOWS_TAG_EXISTS}}') == true - forceNoCache: includes('${{COMMON_TAG_FORCE_BUILD}}', '{{COMMON_TAG_FORCE_BUILD}}') + forceNoCache: includes('${{WORKFLOWS_TAG_FORCE_BUILD}}', '{{WORKFLOWS_TAG_FORCE_BUILD}}') == false title: Build parallel step 3 - build_application_images_3: - type: parallel - stage: build - steps: - samples-sum: - type: build - stage: build - dockerfile: Dockerfile - registry: '${{CODEFRESH_REGISTRY}}' - buildkit: true - build_arguments: - - NOCACHE=${{CF_BUILD_ID}} - - SAMPLES=${{REGISTRY}}/cloud-harness/samples:${{SAMPLES_TAG}} - image_name: cloud-harness/samples-sum - title: Samples sum - working_directory: ./applications/samples/tasks/sum - tags: - - '${{SAMPLES_SUM_TAG}}' - - '${{DEPLOYMENT_PUBLISH_TAG}}-dev' - - '${{CF_BRANCH_TAG_NORMALIZED_LOWER_CASE}}' - when: - condition: - any: - buildDoesNotExist: includes('${{SAMPLES_SUM_TAG_EXISTS}}', '{{SAMPLES_SUM_TAG_EXISTS}}') - == true - forceNoCache: includes('${{SAMPLES_SUM_TAG_FORCE_BUILD}}', '{{SAMPLES_SUM_TAG_FORCE_BUILD}}') - == false - title: Build parallel step 4 tests_unit: stage: unittest type: parallel @@ -513,12 +472,12 @@ steps: commands: - kubectl config use-context ${{CLUSTER_NAME}} - kubectl config set-context --current --namespace=test-${{NAMESPACE_BASENAME}} - - kubectl rollout status deployment/accounts + - kubectl rollout status deployment/volumemanager + - kubectl rollout status deployment/workflows - kubectl rollout status deployment/samples - kubectl rollout status deployment/samples-gk - - kubectl rollout status deployment/workflows + - kubectl rollout status deployment/accounts - kubectl rollout status deployment/common - - kubectl rollout status deployment/volumemanager - kubectl rollout status deployment/argo-gk - sleep 60 tests_api: @@ -530,6 +489,18 @@ steps: commands: - echo $APP_NAME scale: + volumemanager_api_test: + title: volumemanager api test + volumes: + - '${{CF_REPO_NAME}}/applications/volumemanager:/home/test' + - '${{CF_REPO_NAME}}/deployment/helm/values.yaml:/opt/cloudharness/resources/allvalues.yaml' + environment: + - APP_URL=https://volumemanager.${{DOMAIN}}/api + - USERNAME=volumes@testuser.com + - PASSWORD=test + commands: + - st --pre-run cloudharness_test.apitest_init run api/openapi.yaml --base-url + https://volumemanager.${{DOMAIN}}/api -c all samples_api_test: title: samples api test volumes: @@ -605,7 +576,7 @@ steps: approval: type: pending-approval stage: qa - title: Approve anyway + title: Approve anyway and delete deployment description: The pipeline will fail after ${{WAIT_ON_FAIL}} minutes timeout: timeUnit: minutes diff --git a/docs/applications/dependencies.md b/docs/applications/dependencies.md index a15fbc72f..5a9606be1 100644 --- a/docs/applications/dependencies.md +++ b/docs/applications/dependencies.md @@ -70,15 +70,14 @@ harness: branch_tag: v1.0.0 path: myrepo ``` -> Note that the path parameter is optional and unnecessary unless name clashes occur, like same repo and different branches +> Note that the path parameter is optional and its use should be restricted to necessity (e.g. name clashes) The directory structure will be as following: ``` Dockerfile dependencies - b + b.git myrepo - d .dockerignore ``` @@ -90,7 +89,7 @@ COPY dependencies . or ```dockerfile COPY dependencies/b/src . -COPY dependencies/myrepo/d . +COPY dependencies/myrepo/b . ``` > Note that Cloud Harness does not add the COPY/ADD statements to the Dockerfile \ No newline at end of file diff --git a/docs/model/ApiTestsConfig.md b/docs/model/ApiTestsConfig.md index b026fa448..c0c0a347e 100644 --- a/docs/model/ApiTestsConfig.md +++ b/docs/model/ApiTestsConfig.md @@ -21,12 +21,12 @@ json = "{}" # create an instance of ApiTestsConfig from a JSON string api_tests_config_instance = ApiTestsConfig.from_json(json) # print the JSON string representation of the object -print(ApiTestsConfig.to_json()) +print ApiTestsConfig.to_json() # convert the object into a dict api_tests_config_dict = api_tests_config_instance.to_dict() # create an instance of ApiTestsConfig from a dict -api_tests_config_from_dict = ApiTestsConfig.from_dict(api_tests_config_dict) +api_tests_config_form_dict = api_tests_config.from_dict(api_tests_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/ApplicationAccountsConfig.md b/docs/model/ApplicationAccountsConfig.md index 39cc91dbc..542dc891b 100644 --- a/docs/model/ApplicationAccountsConfig.md +++ b/docs/model/ApplicationAccountsConfig.md @@ -19,12 +19,12 @@ json = "{}" # create an instance of ApplicationAccountsConfig from a JSON string application_accounts_config_instance = ApplicationAccountsConfig.from_json(json) # print the JSON string representation of the object -print(ApplicationAccountsConfig.to_json()) +print ApplicationAccountsConfig.to_json() # convert the object into a dict application_accounts_config_dict = application_accounts_config_instance.to_dict() # create an instance of ApplicationAccountsConfig from a dict -application_accounts_config_from_dict = ApplicationAccountsConfig.from_dict(application_accounts_config_dict) +application_accounts_config_form_dict = application_accounts_config.from_dict(application_accounts_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/ApplicationConfig.md b/docs/model/ApplicationConfig.md index 8a2013df1..c62c5523c 100644 --- a/docs/model/ApplicationConfig.md +++ b/docs/model/ApplicationConfig.md @@ -18,12 +18,12 @@ json = "{}" # create an instance of ApplicationConfig from a JSON string application_config_instance = ApplicationConfig.from_json(json) # print the JSON string representation of the object -print(ApplicationConfig.to_json()) +print ApplicationConfig.to_json() # convert the object into a dict application_config_dict = application_config_instance.to_dict() # create an instance of ApplicationConfig from a dict -application_config_from_dict = ApplicationConfig.from_dict(application_config_dict) +application_config_form_dict = application_config.from_dict(application_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/ApplicationDependenciesConfig.md b/docs/model/ApplicationDependenciesConfig.md index ce27a1cdf..1adfc23c5 100644 --- a/docs/model/ApplicationDependenciesConfig.md +++ b/docs/model/ApplicationDependenciesConfig.md @@ -21,12 +21,12 @@ json = "{}" # create an instance of ApplicationDependenciesConfig from a JSON string application_dependencies_config_instance = ApplicationDependenciesConfig.from_json(json) # print the JSON string representation of the object -print(ApplicationDependenciesConfig.to_json()) +print ApplicationDependenciesConfig.to_json() # convert the object into a dict application_dependencies_config_dict = application_dependencies_config_instance.to_dict() # create an instance of ApplicationDependenciesConfig from a dict -application_dependencies_config_from_dict = ApplicationDependenciesConfig.from_dict(application_dependencies_config_dict) +application_dependencies_config_form_dict = application_dependencies_config.from_dict(application_dependencies_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/ApplicationHarnessConfig.md b/docs/model/ApplicationHarnessConfig.md index eb4795303..ed250e7e0 100644 --- a/docs/model/ApplicationHarnessConfig.md +++ b/docs/model/ApplicationHarnessConfig.md @@ -12,10 +12,10 @@ Name | Type | Description | Notes **aliases** | **List[str]** | If specified, an ingress will be created at [alias].[.Values.domain] for each alias | [optional] **domain** | **str** | If specified, an ingress will be created at [domain] | [optional] **dependencies** | [**ApplicationDependenciesConfig**](ApplicationDependenciesConfig.md) | | [optional] -**secured** | **object** | When true, the application is shielded with a getekeeper | [optional] +**secured** | **bool** | When true, the application is shielded with a getekeeper | [optional] **uri_role_mapping** | [**List[UriRoleMappingConfig]**](UriRoleMappingConfig.md) | Map uri/roles to secure with the Gatekeeper (if `secured: true`) | [optional] **secrets** | **Dict[str, object]** | | [optional] -**use_services** | [**List[NamedObject]**](NamedObject.md) | Specify which services this application uses in the frontend to create proxy ingresses. e.g. ``` - name: samples ``` | [optional] +**use_services** | **List[str]** | Specify which services this application uses in the frontend to create proxy ingresses. e.g. ``` - name: samples ``` | [optional] **database** | [**DatabaseDeploymentConfig**](DatabaseDeploymentConfig.md) | | [optional] **resources** | [**List[FileResourcesConfig]**](FileResourcesConfig.md) | Application file resources. Maps from deploy/resources folder and mounts as configmaps | [optional] **readiness_probe** | [**ApplicationProbe**](ApplicationProbe.md) | | [optional] @@ -30,8 +30,6 @@ Name | Type | Description | Notes **env** | [**List[NameValue]**](NameValue.md) | Environmental variables added to all containers (deprecated, please use envmap) | [optional] **envmap** | **Dict[str, object]** | | [optional] **dockerfile** | [**DockerfileConfig**](DockerfileConfig.md) | | [optional] -**sentry** | **bool** | | [optional] -**proxy** | [**ProxyConf**](ProxyConf.md) | | [optional] ## Example @@ -43,12 +41,12 @@ json = "{}" # create an instance of ApplicationHarnessConfig from a JSON string application_harness_config_instance = ApplicationHarnessConfig.from_json(json) # print the JSON string representation of the object -print(ApplicationHarnessConfig.to_json()) +print ApplicationHarnessConfig.to_json() # convert the object into a dict application_harness_config_dict = application_harness_config_instance.to_dict() # create an instance of ApplicationHarnessConfig from a dict -application_harness_config_from_dict = ApplicationHarnessConfig.from_dict(application_harness_config_dict) +application_harness_config_form_dict = application_harness_config.from_dict(application_harness_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/ApplicationProbe.md b/docs/model/ApplicationProbe.md index d868f815c..18d08d6d0 100644 --- a/docs/model/ApplicationProbe.md +++ b/docs/model/ApplicationProbe.md @@ -22,12 +22,12 @@ json = "{}" # create an instance of ApplicationProbe from a JSON string application_probe_instance = ApplicationProbe.from_json(json) # print the JSON string representation of the object -print(ApplicationProbe.to_json()) +print ApplicationProbe.to_json() # convert the object into a dict application_probe_dict = application_probe_instance.to_dict() # create an instance of ApplicationProbe from a dict -application_probe_from_dict = ApplicationProbe.from_dict(application_probe_dict) +application_probe_form_dict = application_probe.from_dict(application_probe_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/ApplicationTestConfig.md b/docs/model/ApplicationTestConfig.md index 64397ffc4..c0922e1f6 100644 --- a/docs/model/ApplicationTestConfig.md +++ b/docs/model/ApplicationTestConfig.md @@ -20,12 +20,12 @@ json = "{}" # create an instance of ApplicationTestConfig from a JSON string application_test_config_instance = ApplicationTestConfig.from_json(json) # print the JSON string representation of the object -print(ApplicationTestConfig.to_json()) +print ApplicationTestConfig.to_json() # convert the object into a dict application_test_config_dict = application_test_config_instance.to_dict() # create an instance of ApplicationTestConfig from a dict -application_test_config_from_dict = ApplicationTestConfig.from_dict(application_test_config_dict) +application_test_config_form_dict = application_test_config.from_dict(application_test_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/ApplicationUser.md b/docs/model/ApplicationUser.md index 78737d6c0..d276a0386 100644 --- a/docs/model/ApplicationUser.md +++ b/docs/model/ApplicationUser.md @@ -21,12 +21,12 @@ json = "{}" # create an instance of ApplicationUser from a JSON string application_user_instance = ApplicationUser.from_json(json) # print the JSON string representation of the object -print(ApplicationUser.to_json()) +print ApplicationUser.to_json() # convert the object into a dict application_user_dict = application_user_instance.to_dict() # create an instance of ApplicationUser from a dict -application_user_from_dict = ApplicationUser.from_dict(application_user_dict) +application_user_form_dict = application_user.from_dict(application_user_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/AutoArtifactSpec.md b/docs/model/AutoArtifactSpec.md index 9efefab2f..f637301c0 100644 --- a/docs/model/AutoArtifactSpec.md +++ b/docs/model/AutoArtifactSpec.md @@ -6,7 +6,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**auto** | **bool** | When true, enables automatic template | [optional] +**auto** | **bool** | When true, enables automatic template | **name** | **str** | | [optional] ## Example @@ -19,12 +19,12 @@ json = "{}" # create an instance of AutoArtifactSpec from a JSON string auto_artifact_spec_instance = AutoArtifactSpec.from_json(json) # print the JSON string representation of the object -print(AutoArtifactSpec.to_json()) +print AutoArtifactSpec.to_json() # convert the object into a dict auto_artifact_spec_dict = auto_artifact_spec_instance.to_dict() # create an instance of AutoArtifactSpec from a dict -auto_artifact_spec_from_dict = AutoArtifactSpec.from_dict(auto_artifact_spec_dict) +auto_artifact_spec_form_dict = auto_artifact_spec.from_dict(auto_artifact_spec_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/BackupConfig.md b/docs/model/BackupConfig.md index 64990c798..9f18eb44b 100644 --- a/docs/model/BackupConfig.md +++ b/docs/model/BackupConfig.md @@ -7,11 +7,11 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **active** | **bool** | | [optional] -**keep_days** | **object** | | [optional] -**keep_weeks** | **object** | | [optional] -**keep_months** | **object** | | [optional] +**keep_days** | **int** | | [optional] +**keep_weeks** | **int** | | [optional] +**keep_months** | **int** | | [optional] **schedule** | **str** | Cron expression | [optional] -**suffix** | **str** | The file suffix added to backup files | [optional] +**suffix** | **object** | The file suffix added to backup files | [optional] **volumesize** | **str** | The volume size for backups (all backups share the same volume) | [optional] **dir** | **str** | | **resources** | [**DeploymentResourcesConf**](DeploymentResourcesConf.md) | | @@ -26,12 +26,12 @@ json = "{}" # create an instance of BackupConfig from a JSON string backup_config_instance = BackupConfig.from_json(json) # print the JSON string representation of the object -print(BackupConfig.to_json()) +print BackupConfig.to_json() # convert the object into a dict backup_config_dict = backup_config_instance.to_dict() # create an instance of BackupConfig from a dict -backup_config_from_dict = BackupConfig.from_dict(backup_config_dict) +backup_config_form_dict = backup_config.from_dict(backup_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/CDCEvent.md b/docs/model/CDCEvent.md index baeef0e7a..faf90671d 100644 --- a/docs/model/CDCEvent.md +++ b/docs/model/CDCEvent.md @@ -7,7 +7,7 @@ A message sent to the orchestration queue. Applications can listen to these even Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **operation** | **str** | the operation on the object e.g. create / update / delete | -**uid** | **object** | the unique identifier attribute of the object | +**uid** | **str** | the unique identifier attribute of the object | **message_type** | **str** | the type of the message (relates to the object type) e.g. jobs | **resource** | **Dict[str, object]** | | [optional] **meta** | [**CDCEventMeta**](CDCEventMeta.md) | | @@ -22,12 +22,12 @@ json = "{}" # create an instance of CDCEvent from a JSON string cdc_event_instance = CDCEvent.from_json(json) # print the JSON string representation of the object -print(CDCEvent.to_json()) +print CDCEvent.to_json() # convert the object into a dict cdc_event_dict = cdc_event_instance.to_dict() # create an instance of CDCEvent from a dict -cdc_event_from_dict = CDCEvent.from_dict(cdc_event_dict) +cdc_event_form_dict = cdc_event.from_dict(cdc_event_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/CDCEventMeta.md b/docs/model/CDCEventMeta.md index 95f8f2199..b3d633f06 100644 --- a/docs/model/CDCEventMeta.md +++ b/docs/model/CDCEventMeta.md @@ -22,12 +22,12 @@ json = "{}" # create an instance of CDCEventMeta from a JSON string cdc_event_meta_instance = CDCEventMeta.from_json(json) # print the JSON string representation of the object -print(CDCEventMeta.to_json()) +print CDCEventMeta.to_json() # convert the object into a dict cdc_event_meta_dict = cdc_event_meta_instance.to_dict() # create an instance of CDCEventMeta from a dict -cdc_event_meta_from_dict = CDCEventMeta.from_dict(cdc_event_meta_dict) +cdc_event_meta_form_dict = cdc_event_meta.from_dict(cdc_event_meta_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/CpuMemoryConfig.md b/docs/model/CpuMemoryConfig.md index 3cac8b987..7819d202e 100644 --- a/docs/model/CpuMemoryConfig.md +++ b/docs/model/CpuMemoryConfig.md @@ -6,8 +6,8 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**cpu** | **object** | | [optional] -**memory** | **object** | | [optional] +**cpu** | **str** | | [optional] +**memory** | **str** | | [optional] ## Example @@ -19,12 +19,12 @@ json = "{}" # create an instance of CpuMemoryConfig from a JSON string cpu_memory_config_instance = CpuMemoryConfig.from_json(json) # print the JSON string representation of the object -print(CpuMemoryConfig.to_json()) +print CpuMemoryConfig.to_json() # convert the object into a dict cpu_memory_config_dict = cpu_memory_config_instance.to_dict() # create an instance of CpuMemoryConfig from a dict -cpu_memory_config_from_dict = CpuMemoryConfig.from_dict(cpu_memory_config_dict) +cpu_memory_config_form_dict = cpu_memory_config.from_dict(cpu_memory_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/DatabaseDeploymentConfig.md b/docs/model/DatabaseDeploymentConfig.md index ae920cd1e..45db673bf 100644 --- a/docs/model/DatabaseDeploymentConfig.md +++ b/docs/model/DatabaseDeploymentConfig.md @@ -6,7 +6,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**auto** | **bool** | When true, enables automatic template | [optional] +**auto** | **bool** | When true, enables automatic template | **name** | **str** | | [optional] **type** | **str** | Define the database type. One of (mongo, postgres, neo4j, sqlite3) | [optional] **size** | **str** | Specify database disk size | [optional] @@ -28,12 +28,12 @@ json = "{}" # create an instance of DatabaseDeploymentConfig from a JSON string database_deployment_config_instance = DatabaseDeploymentConfig.from_json(json) # print the JSON string representation of the object -print(DatabaseDeploymentConfig.to_json()) +print DatabaseDeploymentConfig.to_json() # convert the object into a dict database_deployment_config_dict = database_deployment_config_instance.to_dict() # create an instance of DatabaseDeploymentConfig from a dict -database_deployment_config_from_dict = DatabaseDeploymentConfig.from_dict(database_deployment_config_dict) +database_deployment_config_form_dict = database_deployment_config.from_dict(database_deployment_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/DeploymentAutoArtifactConfig.md b/docs/model/DeploymentAutoArtifactConfig.md index e2f7abfb1..707059d07 100644 --- a/docs/model/DeploymentAutoArtifactConfig.md +++ b/docs/model/DeploymentAutoArtifactConfig.md @@ -6,9 +6,9 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**auto** | **bool** | When true, enables automatic template | [optional] +**auto** | **bool** | When true, enables automatic template | **name** | **str** | | [optional] -**port** | **object** | Deployment port | [optional] +**port** | **str** | Deployment port | [optional] **replicas** | **int** | Number of replicas | [optional] **image** | **str** | Image name to use in the deployment. Leave it blank to set from the application's Docker file | [optional] **resources** | [**DeploymentResourcesConf**](DeploymentResourcesConf.md) | | [optional] @@ -24,12 +24,12 @@ json = "{}" # create an instance of DeploymentAutoArtifactConfig from a JSON string deployment_auto_artifact_config_instance = DeploymentAutoArtifactConfig.from_json(json) # print the JSON string representation of the object -print(DeploymentAutoArtifactConfig.to_json()) +print DeploymentAutoArtifactConfig.to_json() # convert the object into a dict deployment_auto_artifact_config_dict = deployment_auto_artifact_config_instance.to_dict() # create an instance of DeploymentAutoArtifactConfig from a dict -deployment_auto_artifact_config_from_dict = DeploymentAutoArtifactConfig.from_dict(deployment_auto_artifact_config_dict) +deployment_auto_artifact_config_form_dict = deployment_auto_artifact_config.from_dict(deployment_auto_artifact_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/DeploymentResourcesConf.md b/docs/model/DeploymentResourcesConf.md index 5ed4369a6..7a0c10d1f 100644 --- a/docs/model/DeploymentResourcesConf.md +++ b/docs/model/DeploymentResourcesConf.md @@ -19,12 +19,12 @@ json = "{}" # create an instance of DeploymentResourcesConf from a JSON string deployment_resources_conf_instance = DeploymentResourcesConf.from_json(json) # print the JSON string representation of the object -print(DeploymentResourcesConf.to_json()) +print DeploymentResourcesConf.to_json() # convert the object into a dict deployment_resources_conf_dict = deployment_resources_conf_instance.to_dict() # create an instance of DeploymentResourcesConf from a dict -deployment_resources_conf_from_dict = DeploymentResourcesConf.from_dict(deployment_resources_conf_dict) +deployment_resources_conf_form_dict = deployment_resources_conf.from_dict(deployment_resources_conf_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/DeploymentVolumeSpec.md b/docs/model/DeploymentVolumeSpec.md index a22a912ba..66693cb82 100644 --- a/docs/model/DeploymentVolumeSpec.md +++ b/docs/model/DeploymentVolumeSpec.md @@ -6,7 +6,7 @@ Defines a volume attached to the deployment. Automatically created the volume cl Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**auto** | **bool** | When true, enables automatic template | [optional] +**auto** | **bool** | When true, enables automatic template | **name** | **str** | | [optional] **mountpath** | **str** | The mount path for the volume | **size** | **object** | The volume size. E.g. 5Gi | [optional] @@ -22,12 +22,12 @@ json = "{}" # create an instance of DeploymentVolumeSpec from a JSON string deployment_volume_spec_instance = DeploymentVolumeSpec.from_json(json) # print the JSON string representation of the object -print(DeploymentVolumeSpec.to_json()) +print DeploymentVolumeSpec.to_json() # convert the object into a dict deployment_volume_spec_dict = deployment_volume_spec_instance.to_dict() # create an instance of DeploymentVolumeSpec from a dict -deployment_volume_spec_from_dict = DeploymentVolumeSpec.from_dict(deployment_volume_spec_dict) +deployment_volume_spec_form_dict = deployment_volume_spec.from_dict(deployment_volume_spec_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/DockerfileConfig.md b/docs/model/DockerfileConfig.md index 4be6d38bb..5b1925261 100644 --- a/docs/model/DockerfileConfig.md +++ b/docs/model/DockerfileConfig.md @@ -18,12 +18,12 @@ json = "{}" # create an instance of DockerfileConfig from a JSON string dockerfile_config_instance = DockerfileConfig.from_json(json) # print the JSON string representation of the object -print(DockerfileConfig.to_json()) +print DockerfileConfig.to_json() # convert the object into a dict dockerfile_config_dict = dockerfile_config_instance.to_dict() # create an instance of DockerfileConfig from a dict -dockerfile_config_from_dict = DockerfileConfig.from_dict(dockerfile_config_dict) +dockerfile_config_form_dict = dockerfile_config.from_dict(dockerfile_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/E2ETestsConfig.md b/docs/model/E2ETestsConfig.md index 28e8731c8..1f5756f2e 100644 --- a/docs/model/E2ETestsConfig.md +++ b/docs/model/E2ETestsConfig.md @@ -21,12 +21,12 @@ json = "{}" # create an instance of E2ETestsConfig from a JSON string e2_e_tests_config_instance = E2ETestsConfig.from_json(json) # print the JSON string representation of the object -print(E2ETestsConfig.to_json()) +print E2ETestsConfig.to_json() # convert the object into a dict e2_e_tests_config_dict = e2_e_tests_config_instance.to_dict() # create an instance of E2ETestsConfig from a dict -e2_e_tests_config_from_dict = E2ETestsConfig.from_dict(e2_e_tests_config_dict) +e2_e_tests_config_form_dict = e2_e_tests_config.from_dict(e2_e_tests_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/FileResourcesConfig.md b/docs/model/FileResourcesConfig.md index ecd5a4ddd..4d72981ef 100644 --- a/docs/model/FileResourcesConfig.md +++ b/docs/model/FileResourcesConfig.md @@ -20,12 +20,12 @@ json = "{}" # create an instance of FileResourcesConfig from a JSON string file_resources_config_instance = FileResourcesConfig.from_json(json) # print the JSON string representation of the object -print(FileResourcesConfig.to_json()) +print FileResourcesConfig.to_json() # convert the object into a dict file_resources_config_dict = file_resources_config_instance.to_dict() # create an instance of FileResourcesConfig from a dict -file_resources_config_from_dict = FileResourcesConfig.from_dict(file_resources_config_dict) +file_resources_config_form_dict = file_resources_config.from_dict(file_resources_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/GatekeeperConf.md b/docs/model/GatekeeperConf.md deleted file mode 100644 index e27090fbf..000000000 --- a/docs/model/GatekeeperConf.md +++ /dev/null @@ -1,31 +0,0 @@ -# GatekeeperConf - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**image** | **str** | | [optional] -**replicas** | **int** | | [optional] - -## Example - -```python -from cloudharness_model.models.gatekeeper_conf import GatekeeperConf - -# TODO update the JSON string below -json = "{}" -# create an instance of GatekeeperConf from a JSON string -gatekeeper_conf_instance = GatekeeperConf.from_json(json) -# print the JSON string representation of the object -print(GatekeeperConf.to_json()) - -# convert the object into a dict -gatekeeper_conf_dict = gatekeeper_conf_instance.to_dict() -# create an instance of GatekeeperConf from a dict -gatekeeper_conf_from_dict = GatekeeperConf.from_dict(gatekeeper_conf_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/docs/model/GitDependencyConfig.md b/docs/model/GitDependencyConfig.md index 0911db471..51779d4dd 100644 --- a/docs/model/GitDependencyConfig.md +++ b/docs/model/GitDependencyConfig.md @@ -20,12 +20,12 @@ json = "{}" # create an instance of GitDependencyConfig from a JSON string git_dependency_config_instance = GitDependencyConfig.from_json(json) # print the JSON string representation of the object -print(GitDependencyConfig.to_json()) +print GitDependencyConfig.to_json() # convert the object into a dict git_dependency_config_dict = git_dependency_config_instance.to_dict() # create an instance of GitDependencyConfig from a dict -git_dependency_config_from_dict = GitDependencyConfig.from_dict(git_dependency_config_dict) +git_dependency_config_form_dict = git_dependency_config.from_dict(git_dependency_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/HarnessMainConfig.md b/docs/model/HarnessMainConfig.md index 7940b51cc..2034bcc09 100644 --- a/docs/model/HarnessMainConfig.md +++ b/docs/model/HarnessMainConfig.md @@ -15,12 +15,11 @@ Name | Type | Description | Notes **tag** | **str** | Docker tag used to push/pull the built images. | [optional] **apps** | [**Dict[str, ApplicationConfig]**](ApplicationConfig.md) | | **env** | [**List[NameValue]**](NameValue.md) | Environmental variables added to all pods | [optional] -**privenv** | [**List[NameValue]**](NameValue.md) | Private environmental variables added to all pods | [optional] +**privenv** | [**NameValue**](NameValue.md) | | [optional] **backup** | [**BackupConfig**](BackupConfig.md) | | [optional] **name** | **str** | Base name | [optional] **task_images** | **Dict[str, object]** | | [optional] **build_hash** | **str** | | [optional] -**ingress** | [**IngressConfig**](IngressConfig.md) | | [optional] ## Example @@ -32,12 +31,12 @@ json = "{}" # create an instance of HarnessMainConfig from a JSON string harness_main_config_instance = HarnessMainConfig.from_json(json) # print the JSON string representation of the object -print(HarnessMainConfig.to_json()) +print HarnessMainConfig.to_json() # convert the object into a dict harness_main_config_dict = harness_main_config_instance.to_dict() # create an instance of HarnessMainConfig from a dict -harness_main_config_from_dict = HarnessMainConfig.from_dict(harness_main_config_dict) +harness_main_config_form_dict = harness_main_config.from_dict(harness_main_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/IngressConfig.md b/docs/model/IngressConfig.md index 5e2add2f3..0c53184e0 100644 --- a/docs/model/IngressConfig.md +++ b/docs/model/IngressConfig.md @@ -6,11 +6,10 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**auto** | **bool** | When true, enables automatic template | [optional] +**auto** | **bool** | When true, enables automatic template | **name** | **str** | | [optional] **ssl_redirect** | **bool** | | [optional] **letsencrypt** | [**IngressConfigAllOfLetsencrypt**](IngressConfigAllOfLetsencrypt.md) | | [optional] -**enabled** | **bool** | | [optional] ## Example @@ -22,12 +21,12 @@ json = "{}" # create an instance of IngressConfig from a JSON string ingress_config_instance = IngressConfig.from_json(json) # print the JSON string representation of the object -print(IngressConfig.to_json()) +print IngressConfig.to_json() # convert the object into a dict ingress_config_dict = ingress_config_instance.to_dict() # create an instance of IngressConfig from a dict -ingress_config_from_dict = IngressConfig.from_dict(ingress_config_dict) +ingress_config_form_dict = ingress_config.from_dict(ingress_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/IngressConfigAllOfLetsencrypt.md b/docs/model/IngressConfigAllOfLetsencrypt.md index fa4ec0909..836a9ee97 100644 --- a/docs/model/IngressConfigAllOfLetsencrypt.md +++ b/docs/model/IngressConfigAllOfLetsencrypt.md @@ -18,12 +18,12 @@ json = "{}" # create an instance of IngressConfigAllOfLetsencrypt from a JSON string ingress_config_all_of_letsencrypt_instance = IngressConfigAllOfLetsencrypt.from_json(json) # print the JSON string representation of the object -print(IngressConfigAllOfLetsencrypt.to_json()) +print IngressConfigAllOfLetsencrypt.to_json() # convert the object into a dict ingress_config_all_of_letsencrypt_dict = ingress_config_all_of_letsencrypt_instance.to_dict() # create an instance of IngressConfigAllOfLetsencrypt from a dict -ingress_config_all_of_letsencrypt_from_dict = IngressConfigAllOfLetsencrypt.from_dict(ingress_config_all_of_letsencrypt_dict) +ingress_config_all_of_letsencrypt_form_dict = ingress_config_all_of_letsencrypt.from_dict(ingress_config_all_of_letsencrypt_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/JupyterHubConfig.md b/docs/model/JupyterHubConfig.md index 7ba09ad00..ccc2e304a 100644 --- a/docs/model/JupyterHubConfig.md +++ b/docs/model/JupyterHubConfig.md @@ -21,12 +21,12 @@ json = "{}" # create an instance of JupyterHubConfig from a JSON string jupyter_hub_config_instance = JupyterHubConfig.from_json(json) # print the JSON string representation of the object -print(JupyterHubConfig.to_json()) +print JupyterHubConfig.to_json() # convert the object into a dict jupyter_hub_config_dict = jupyter_hub_config_instance.to_dict() # create an instance of JupyterHubConfig from a dict -jupyter_hub_config_from_dict = JupyterHubConfig.from_dict(jupyter_hub_config_dict) +jupyter_hub_config_form_dict = jupyter_hub_config.from_dict(jupyter_hub_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/NameValue.md b/docs/model/NameValue.md index 634ac9744..cfcf6f346 100644 --- a/docs/model/NameValue.md +++ b/docs/model/NameValue.md @@ -19,12 +19,12 @@ json = "{}" # create an instance of NameValue from a JSON string name_value_instance = NameValue.from_json(json) # print the JSON string representation of the object -print(NameValue.to_json()) +print NameValue.to_json() # convert the object into a dict name_value_dict = name_value_instance.to_dict() # create an instance of NameValue from a dict -name_value_from_dict = NameValue.from_dict(name_value_dict) +name_value_form_dict = name_value.from_dict(name_value_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/NamedObject.md b/docs/model/NamedObject.md deleted file mode 100644 index 930d1be50..000000000 --- a/docs/model/NamedObject.md +++ /dev/null @@ -1,30 +0,0 @@ -# NamedObject - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**name** | **str** | | [optional] - -## Example - -```python -from cloudharness_model.models.named_object import NamedObject - -# TODO update the JSON string below -json = "{}" -# create an instance of NamedObject from a JSON string -named_object_instance = NamedObject.from_json(json) -# print the JSON string representation of the object -print(NamedObject.to_json()) - -# convert the object into a dict -named_object_dict = named_object_instance.to_dict() -# create an instance of NamedObject from a dict -named_object_from_dict = NamedObject.from_dict(named_object_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/docs/model/Organization.md b/docs/model/Organization.md deleted file mode 100644 index 9fbff8042..000000000 --- a/docs/model/Organization.md +++ /dev/null @@ -1,34 +0,0 @@ -# Organization - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**name** | **str** | | [optional] -**domains** | [**List[NamedObject]**](NamedObject.md) | | [optional] -**alias** | **str** | | [optional] -**enabled** | **bool** | | [optional] -**id** | **str** | | [optional] - -## Example - -```python -from cloudharness_model.models.organization import Organization - -# TODO update the JSON string below -json = "{}" -# create an instance of Organization from a JSON string -organization_instance = Organization.from_json(json) -# print the JSON string representation of the object -print(Organization.to_json()) - -# convert the object into a dict -organization_dict = organization_instance.to_dict() -# create an instance of Organization from a dict -organization_from_dict = Organization.from_dict(organization_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/docs/model/ProxyConf.md b/docs/model/ProxyConf.md deleted file mode 100644 index dc47913aa..000000000 --- a/docs/model/ProxyConf.md +++ /dev/null @@ -1,33 +0,0 @@ -# ProxyConf - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**forwarded_headers** | **bool** | | [optional] -**payload** | [**ProxyPayloadConf**](ProxyPayloadConf.md) | | [optional] -**timeout** | [**ProxyTimeoutConf**](ProxyTimeoutConf.md) | | [optional] -**gatekeeper** | [**GatekeeperConf**](GatekeeperConf.md) | | [optional] - -## Example - -```python -from cloudharness_model.models.proxy_conf import ProxyConf - -# TODO update the JSON string below -json = "{}" -# create an instance of ProxyConf from a JSON string -proxy_conf_instance = ProxyConf.from_json(json) -# print the JSON string representation of the object -print(ProxyConf.to_json()) - -# convert the object into a dict -proxy_conf_dict = proxy_conf_instance.to_dict() -# create an instance of ProxyConf from a dict -proxy_conf_from_dict = ProxyConf.from_dict(proxy_conf_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/docs/model/ProxyPayloadConf.md b/docs/model/ProxyPayloadConf.md deleted file mode 100644 index a512e010d..000000000 --- a/docs/model/ProxyPayloadConf.md +++ /dev/null @@ -1,30 +0,0 @@ -# ProxyPayloadConf - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**max** | **int** | | [optional] - -## Example - -```python -from cloudharness_model.models.proxy_payload_conf import ProxyPayloadConf - -# TODO update the JSON string below -json = "{}" -# create an instance of ProxyPayloadConf from a JSON string -proxy_payload_conf_instance = ProxyPayloadConf.from_json(json) -# print the JSON string representation of the object -print(ProxyPayloadConf.to_json()) - -# convert the object into a dict -proxy_payload_conf_dict = proxy_payload_conf_instance.to_dict() -# create an instance of ProxyPayloadConf from a dict -proxy_payload_conf_from_dict = ProxyPayloadConf.from_dict(proxy_payload_conf_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/docs/model/ProxyTimeoutConf.md b/docs/model/ProxyTimeoutConf.md deleted file mode 100644 index 74439fa31..000000000 --- a/docs/model/ProxyTimeoutConf.md +++ /dev/null @@ -1,32 +0,0 @@ -# ProxyTimeoutConf - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**keepalive** | **int** | | [optional] -**read** | **int** | | [optional] -**send** | **int** | | [optional] - -## Example - -```python -from cloudharness_model.models.proxy_timeout_conf import ProxyTimeoutConf - -# TODO update the JSON string below -json = "{}" -# create an instance of ProxyTimeoutConf from a JSON string -proxy_timeout_conf_instance = ProxyTimeoutConf.from_json(json) -# print the JSON string representation of the object -print(ProxyTimeoutConf.to_json()) - -# convert the object into a dict -proxy_timeout_conf_dict = proxy_timeout_conf_instance.to_dict() -# create an instance of ProxyTimeoutConf from a dict -proxy_timeout_conf_from_dict = ProxyTimeoutConf.from_dict(proxy_timeout_conf_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/docs/model/RegistryConfig.md b/docs/model/RegistryConfig.md index b91c107f5..88bbdd7b9 100644 --- a/docs/model/RegistryConfig.md +++ b/docs/model/RegistryConfig.md @@ -19,12 +19,12 @@ json = "{}" # create an instance of RegistryConfig from a JSON string registry_config_instance = RegistryConfig.from_json(json) # print the JSON string representation of the object -print(RegistryConfig.to_json()) +print RegistryConfig.to_json() # convert the object into a dict registry_config_dict = registry_config_instance.to_dict() # create an instance of RegistryConfig from a dict -registry_config_from_dict = RegistryConfig.from_dict(registry_config_dict) +registry_config_form_dict = registry_config.from_dict(registry_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/ServiceAutoArtifactConfig.md b/docs/model/ServiceAutoArtifactConfig.md index 52feb35c2..dc4c74d87 100644 --- a/docs/model/ServiceAutoArtifactConfig.md +++ b/docs/model/ServiceAutoArtifactConfig.md @@ -6,7 +6,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- -**auto** | **bool** | When true, enables automatic template | [optional] +**auto** | **bool** | When true, enables automatic template | **name** | **str** | | [optional] **port** | **int** | Service port | [optional] @@ -20,12 +20,12 @@ json = "{}" # create an instance of ServiceAutoArtifactConfig from a JSON string service_auto_artifact_config_instance = ServiceAutoArtifactConfig.from_json(json) # print the JSON string representation of the object -print(ServiceAutoArtifactConfig.to_json()) +print ServiceAutoArtifactConfig.to_json() # convert the object into a dict service_auto_artifact_config_dict = service_auto_artifact_config_instance.to_dict() # create an instance of ServiceAutoArtifactConfig from a dict -service_auto_artifact_config_from_dict = ServiceAutoArtifactConfig.from_dict(service_auto_artifact_config_dict) +service_auto_artifact_config_form_dict = service_auto_artifact_config.from_dict(service_auto_artifact_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/UnitTestsConfig.md b/docs/model/UnitTestsConfig.md index 9510d9e00..9aed04ebf 100644 --- a/docs/model/UnitTestsConfig.md +++ b/docs/model/UnitTestsConfig.md @@ -19,12 +19,12 @@ json = "{}" # create an instance of UnitTestsConfig from a JSON string unit_tests_config_instance = UnitTestsConfig.from_json(json) # print the JSON string representation of the object -print(UnitTestsConfig.to_json()) +print UnitTestsConfig.to_json() # convert the object into a dict unit_tests_config_dict = unit_tests_config_instance.to_dict() # create an instance of UnitTestsConfig from a dict -unit_tests_config_from_dict = UnitTestsConfig.from_dict(unit_tests_config_dict) +unit_tests_config_form_dict = unit_tests_config.from_dict(unit_tests_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/UriRoleMappingConfig.md b/docs/model/UriRoleMappingConfig.md index 4438687a4..11f780731 100644 --- a/docs/model/UriRoleMappingConfig.md +++ b/docs/model/UriRoleMappingConfig.md @@ -7,8 +7,7 @@ Defines the application Gatekeeper configuration, if enabled (i.e. `secured: tru Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **uri** | **str** | | -**roles** | **List[str]** | Roles allowed to access the present uri | [optional] -**white_listed** | **bool** | | [optional] +**roles** | **List[str]** | Roles allowed to access the present uri | ## Example @@ -20,12 +19,12 @@ json = "{}" # create an instance of UriRoleMappingConfig from a JSON string uri_role_mapping_config_instance = UriRoleMappingConfig.from_json(json) # print the JSON string representation of the object -print(UriRoleMappingConfig.to_json()) +print UriRoleMappingConfig.to_json() # convert the object into a dict uri_role_mapping_config_dict = uri_role_mapping_config_instance.to_dict() # create an instance of UriRoleMappingConfig from a dict -uri_role_mapping_config_from_dict = UriRoleMappingConfig.from_dict(uri_role_mapping_config_dict) +uri_role_mapping_config_form_dict = uri_role_mapping_config.from_dict(uri_role_mapping_config_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/User.md b/docs/model/User.md index 9e9071e46..e5864f666 100644 --- a/docs/model/User.md +++ b/docs/model/User.md @@ -24,8 +24,6 @@ Name | Type | Description | Notes **service_account_client_id** | **str** | | [optional] **username** | **str** | | [optional] **additional_properties** | **object** | | [optional] -**user_groups** | [**List[UserGroup]**](UserGroup.md) | | [optional] -**organizations** | [**List[Organization]**](Organization.md) | | [optional] ## Example @@ -37,12 +35,12 @@ json = "{}" # create an instance of User from a JSON string user_instance = User.from_json(json) # print the JSON string representation of the object -print(User.to_json()) +print User.to_json() # convert the object into a dict user_dict = user_instance.to_dict() # create an instance of User from a dict -user_from_dict = User.from_dict(user_dict) +user_form_dict = user.from_dict(user_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/UserCredential.md b/docs/model/UserCredential.md index 135ed08bb..8dd7e316e 100644 --- a/docs/model/UserCredential.md +++ b/docs/model/UserCredential.md @@ -25,12 +25,12 @@ json = "{}" # create an instance of UserCredential from a JSON string user_credential_instance = UserCredential.from_json(json) # print the JSON string representation of the object -print(UserCredential.to_json()) +print UserCredential.to_json() # convert the object into a dict user_credential_dict = user_credential_instance.to_dict() # create an instance of UserCredential from a dict -user_credential_from_dict = UserCredential.from_dict(user_credential_dict) +user_credential_form_dict = user_credential.from_dict(user_credential_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/UserGroup.md b/docs/model/UserGroup.md index fa033ac7b..a8a2bf145 100644 --- a/docs/model/UserGroup.md +++ b/docs/model/UserGroup.md @@ -24,12 +24,12 @@ json = "{}" # create an instance of UserGroup from a JSON string user_group_instance = UserGroup.from_json(json) # print the JSON string representation of the object -print(UserGroup.to_json()) +print UserGroup.to_json() # convert the object into a dict user_group_dict = user_group_instance.to_dict() # create an instance of UserGroup from a dict -user_group_from_dict = UserGroup.from_dict(user_group_dict) +user_group_form_dict = user_group.from_dict(user_group_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/docs/model/UserRole.md b/docs/model/UserRole.md index 19446feae..9e244bb11 100644 --- a/docs/model/UserRole.md +++ b/docs/model/UserRole.md @@ -23,12 +23,12 @@ json = "{}" # create an instance of UserRole from a JSON string user_role_instance = UserRole.from_json(json) # print the JSON string representation of the object -print(UserRole.to_json()) +print UserRole.to_json() # convert the object into a dict user_role_dict = user_role_instance.to_dict() # create an instance of UserRole from a dict -user_role_from_dict = UserRole.from_dict(user_role_dict) +user_role_form_dict = user_role.from_dict(user_role_dict) ``` [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/infrastructure/base-images/cloudharness-base/Dockerfile b/infrastructure/base-images/cloudharness-base/Dockerfile index 58cb04bae..ebcee52eb 100644 --- a/infrastructure/base-images/cloudharness-base/Dockerfile +++ b/infrastructure/base-images/cloudharness-base/Dockerfile @@ -1,13 +1,7 @@ -ARG PARENT=python:3.12-slim-trixie +ARG PARENT=python:3.12 FROM ${PARENT} -RUN apt update && apt install -y --no-install-recommends \ - gcc \ - g++ \ - python3-dev \ - libpq-dev \ - nfs-common \ - && rm -rf /var/lib/apt/lists/* +RUN apt-get update && apt-get install -y nfs-common && rm -rf /var/lib/apt/lists/* RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip &&\ pip install pytest --prefer-binary diff --git a/infrastructure/base-images/cloudharness-frontend-build/Dockerfile b/infrastructure/base-images/cloudharness-frontend-build/Dockerfile index 0a4d02061..412125e67 100644 --- a/infrastructure/base-images/cloudharness-frontend-build/Dockerfile +++ b/infrastructure/base-images/cloudharness-frontend-build/Dockerfile @@ -1,3 +1,3 @@ -FROM node:22-alpine +FROM node:20 diff --git a/infrastructure/cluster-configuration/storageclass-dockerdesktop.yaml b/infrastructure/cluster-configuration/storageclass-dockerdesktop.yaml deleted file mode 100644 index 5292c7e49..000000000 --- a/infrastructure/cluster-configuration/storageclass-dockerdesktop.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: storage.k8s.io/v1 -kind: StorageClass -metadata: - name: standard -provisioner: docker.io/hostpath -reclaimPolicy: Delete -volumeBindingMode: Immediate ---- - diff --git a/infrastructure/cluster-configuration/storageclass.yaml b/infrastructure/cluster-configuration/storageclass.yaml index 3389d2343..97e42d96e 100644 --- a/infrastructure/cluster-configuration/storageclass.yaml +++ b/infrastructure/cluster-configuration/storageclass.yaml @@ -2,8 +2,7 @@ apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: persisted -provisioner: kubernetes.io/gce-pd reclaimPolicy: Retain +volumeProvisioner: kubernetes.io/gce-pd volumeBindingMode: Immediate ---- - +--- \ No newline at end of file diff --git a/infrastructure/common-images/cloudharness-django/Dockerfile b/infrastructure/common-images/cloudharness-django/Dockerfile index 875972aeb..89a090891 100644 --- a/infrastructure/common-images/cloudharness-django/Dockerfile +++ b/infrastructure/common-images/cloudharness-django/Dockerfile @@ -12,7 +12,7 @@ RUN apt-get update && apt-get install -y libjpeg-dev zlib1g-dev git && rm -rf / RUN python3 -m pip install --upgrade pip -COPY libraries/cloudharness-django/requirements.txt /tmp +COPY libraries/fastapi/requirements.txt /tmp RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip &&\ python3 -m pip install -r /tmp/requirements.txt --prefer-binary && \ diff --git a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/admin.py b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/admin.py index 30635fe3b..ea3d423d6 100644 --- a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/admin.py +++ b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/admin.py @@ -5,7 +5,7 @@ from admin_extra_buttons.api import ExtraButtonsMixin, button from .models import Member - +from cloudharness_django.services import get_user_service # Register your models here. @@ -32,7 +32,6 @@ def has_delete_permission(self, request, obj=None): @button() def sync_keycloak(self, request): - from cloudharness_django.services import get_user_service get_user_service().sync_kc_users_groups() self.message_user(request, 'Keycloak users & groups synced.') @@ -50,7 +49,6 @@ def has_delete_permission(self, request, obj=None): @button() def sync_keycloak(self, request): - from cloudharness_django.services import get_user_service get_user_service().sync_kc_users_groups() self.message_user(request, 'Keycloak users & groups synced.') diff --git a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/apps.py b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/apps.py index fae83e067..2aa7edd2d 100644 --- a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/apps.py +++ b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/apps.py @@ -4,3 +4,30 @@ class cloudharness_djangoConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'cloudharness_django' + + def ready(self): + # imports + import sys + for skip_cmd in [ + "--help", + "collectstatic", + "compilemessages", + "compress", + "dbshell", + "dumpdata", + "loaddata", + "makemessages", + "makemigrations", + "migrate", + "reset_db", + "showmigrations", + "sqlmigrate", + "squashmigrations", + "test", + ]: + # for these commands we skip initializing the event listener + if skip_cmd in sys.argv: + return + + from cloudharness_django.services.events import init_listener_in_background + init_listener_in_background() diff --git a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/middleware.py b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/middleware.py index 9b2d70842..56f707e79 100644 --- a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/middleware.py +++ b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/middleware.py @@ -2,103 +2,38 @@ import jwt from django.contrib.auth.models import User -from django.contrib.auth import logout -from django.db import transaction + from keycloak.exceptions import KeycloakGetError +from cloudharness.middleware import get_authentication_token from cloudharness.auth.exceptions import InvalidToken -from cloudharness_django.services import get_user_service -from .models import Member +from cloudharness_django.services import get_user_service, get_auth_service from cloudharness import log -from cloudharness.auth.keycloak import AuthClient, User as KcUser, get_authentication_token -from psycopg2.errors import UniqueViolation - - -def _get_user(kc_user_id: str) -> User: - """ - Get or create a Django user for the given Keycloak user ID. - - CRITICAL SAFETY GUARANTEE: This function will NEVER return a User without a valid Member. - If we cannot ensure a Member exists, we return None (which triggers anonymous user behavior). - Returns: - User: A Django User with a guaranteed Member relationship, or None for anonymous - """ - user = None - if kc_user_id is None: - return None - try: - # Try to get existing user by member relationship +def _get_user(): + bearer = get_authentication_token() + if bearer: + # found bearer token get the Django user try: - user = User.objects.get(member__kc_id=kc_user_id) - - # SAFETY CHECK: Verify member relationship is intact - try: - _ = user.member # Access to verify it exists - except Member.DoesNotExist: - # Member was deleted between the query and now - return None for safety - log.error("User %s found but Member missing. Returning anonymous.", user.id) - return None - - except User.DoesNotExist: - # User doesn't exist - create it via sync_kc_user - user_svc = get_user_service() - kc_user = user_svc.auth_client.get_current_user() + token = bearer.split(" ")[-1] + payload = jwt.decode(token, algorithms=["RS256"], options={"verify_signature": False}, audience="web-client") + kc_id = payload["sub"] try: - # sync_kc_user is atomic and guarantees Member creation - user = user_svc.sync_kc_user(kc_user) - user_svc.sync_kc_user_groups(kc_user) - - # SAFETY CHECK: Final verification that Member exists - try: - _ = user.member - except Member.DoesNotExist: - # This should NEVER happen due to sync_kc_user safety, but be defensive - log.error("sync_kc_user returned user %s without Member! Returning anonymous.", user.id) - return None - - except UniqueViolation as e: - # Race condition while creating the Member object - log.warning("UniqueViolation error for kc_id %s. Probably a race condition. %s", kc_user_id, str(e)) - # Try to get the user again - try: - user = User.objects.get(member__kc_id=kc_user_id) - # Verify member exists - _ = user.member - except (User.DoesNotExist, Member.DoesNotExist): - log.error("Failed to retrieve user after UniqueViolation. Returning anonymous.") - return None - - except User.MultipleObjectsReturned: - # Race condition, multiple users created for the same kc_id - log.warning("Multiple users found for kc_id %s, cleaning up...", kc_user_id) - user = User.objects.filter(member__kc_id=kc_user_id).order_by('id').first() - User.objects.filter(member__kc_id=kc_user_id).exclude(id=user.id).delete() - - # SAFETY CHECK: Verify the kept user has a Member - try: - _ = user.member - except: - log.error("Cleaned up user %s has no Member. Returning anonymous.", user.id) - return None - + user = User.objects.get(member__kc_id=kc_id) + except User.DoesNotExist: + user = get_user_service().sync_kc_user(get_auth_service().get_auth_client().get_current_user()) return user - + except KeycloakGetError: + # KC user not found + return None + except InvalidToken: + return None except Exception as e: - log.exception("User sync error, %s", kc_user.email) + log.exception("User mapping error, %s", payload["email"]) return None - return user - - except KeycloakGetError: - # KC user not found - return None - except InvalidToken: - return None - except Exception as e: - log.exception("User %s mapping error, %s", kc_user_id, e) - return None + return None class BearerTokenMiddleware: @@ -106,40 +41,13 @@ def __init__(self, get_response=None): # One-time configuration and initialization. self.get_response = get_response - @transaction.atomic def __call__(self, request): - user = getattr(request, "user", None) - authentication_token = get_authentication_token() - if not authentication_token or authentication_token == 'Bearer undefined': - return self.get_response(request) - try: - kc_user = AuthClient.decode_token(authentication_token.split(' ')[-1]) - kc_user_id = kc_user.get('sub') - except InvalidToken: - logout(request) - response = self.get_response(request) - response.delete_cookie('kc-access') - return response - - if kc_user: - if not user or user.is_anonymous or getattr(user, "member", None) is None or user.member.kc_id != kc_user_id: - user = _get_user(kc_user_id) - if user: - # CRITICAL SAFETY CHECK: Never assign user without Member - # This is the final defense to ensure request.user always has a Member - try: - _ = user.member # Verify member exists - # Safe to assign - user has a valid Member - request.user = user - request._cached_user = user - except: - # This should NEVER happen due to _get_user safety checks, - # but if it does, DO NOT assign the user - keep anonymous - log.error("CRITICAL: _get_user returned user %s without Member! Keeping anonymous.", user.id) - logout(request) - # Don't assign user - request will remain anonymous - # elif not request.path.startswith('/admin/'): - # logout(request) + if getattr(getattr(request, "user", {}), "is_anonymous", True): + user = _get_user() + if user: + # auto login, set the user + request.user = user + request._cached_user = user return self.get_response(request) @@ -147,33 +55,7 @@ def __call__(self, request): class BearerTokenAuthentication: # for django rest framework usage def authenticate(self, request): - authentication_token = get_authentication_token() - if not authentication_token or authentication_token == 'Bearer undefined': - return None - user: User = getattr(request._request, 'user', None) + user = getattr(request._request, 'user', None) if user and user.is_authenticated: - # SAFETY CHECK: Verify authenticated user has Member - try: - _ = user.member - return (user, None) - except Member.DoesNotExist: - log.error("Authenticated user %s has no Member! Falling back to _get_user.", user.id) - # Fall through to _get_user which will handle this safely - - try: - kc_user = AuthClient.decode_token(authentication_token.split(' ')[-1]) - kc_user_id = kc_user.get('sub') - except InvalidToken: - logout(request) - return self.get_response(request) - user = _get_user(kc_user_id) - if user: - # FINAL SAFETY CHECK: Ensure Member exists before returning - try: - _ = user.member - return (user, None) - except Member.DoesNotExist: - log.error("CRITICAL: _get_user returned user %s without Member! Returning None.", user.id) - return None - - return None + return (user, None) + return (_get_user(), None) diff --git a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/__init__.py b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/__init__.py index 1b258d988..330a760eb 100644 --- a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/__init__.py +++ b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/__init__.py @@ -1,8 +1,7 @@ from typing import List from django.conf import settings -from .auth import AuthService -from .user import UserService + from cloudharness_django.exceptions import \ KeycloakOIDCAuthServiceNotInitError, \ KeycloakOIDUserServiceNotInitError, \ @@ -12,17 +11,17 @@ _user_service = None -def get_auth_service() -> AuthService: +def get_auth_service(): global _auth_service if not _auth_service: - init_services() + raise KeycloakOIDCAuthServiceNotInitError("Auth Service not initialized") return _auth_service -def get_user_service() -> UserService: +def get_user_service(): global _user_service if not _user_service: - init_services() + raise KeycloakOIDUserServiceNotInitError("User Service not initialized") return _user_service @@ -33,7 +32,8 @@ def init_services( admin_role: str = settings.KC_ADMIN_ROLE, default_user_role: str = settings.KC_DEFAULT_USER_ROLE ): - + from cloudharness_django.services.auth import AuthService + from cloudharness_django.services.user import UserService global _auth_service, _user_service _auth_service = AuthService( client_name=client_name, diff --git a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/auth.py b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/auth.py index 753e0d1d2..5c808e9e9 100644 --- a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/auth.py +++ b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/auth.py @@ -50,7 +50,7 @@ def __init__( self.admin_role = admin_role @classmethod - def get_auth_client(cls) -> AuthClient: + def get_auth_client(cls): return auth_client def get_client_name(self): diff --git a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/events.py b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/events.py index e1b0c5214..880d2ee5f 100644 --- a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/events.py +++ b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/events.py @@ -1,3 +1,5 @@ +import time + from cloudharness.applications import ConfigurationCallException from django.conf import settings @@ -23,9 +25,9 @@ def event_handler(app, event_client, message): operation = message["operation-type"] resource_path = message["resource-path"].split("/") - log.info(f"{event_client} {message}") - if resource in ["CLIENT_ROLE_MAPPING", "GROUP", "USER", "GROUP_MEMBERSHIP", "ORGANIZATION_MEMBERSHIP"]: + if resource in ["CLIENT_ROLE_MAPPING", "GROUP", "USER", "GROUP_MEMBERSHIP"]: try: + time.sleep(1) # wait a bit to let kc db transactions finish init_services() user_service = get_user_service() auth_client = get_auth_service().get_auth_client() @@ -33,19 +35,23 @@ def event_handler(app, event_client, message): if resource == "GROUP": kc_group = auth_client.get_group(resource_path[1]) user_service.sync_kc_group(kc_group) + return if resource == "USER": kc_user = auth_client.get_user(resource_path[1]) user_service.sync_kc_user(kc_user, delete=operation == "DELETE") + return if resource == "CLIENT_ROLE_MAPPING": # adding/deleting user client roles # set/user user is_superuser kc_user = auth_client.get_user(resource_path[1]) user_service.sync_kc_user(kc_user) - if resource == "GROUP_MEMBERSHIP" or resource == "ORGANIZATION_MEMBERSHIP": + return + if resource == "GROUP_MEMBERSHIP": # adding / deleting users from groups, update the user # updating the user will also update the user groups kc_user = auth_client.get_user(resource_path[1]) user_service.sync_kc_user(kc_user) + return except Exception as e: log.error(e) raise e @@ -91,26 +97,22 @@ def init_listener(): if not hasattr(settings, "PROJECT_NAME"): raise KeycloakOIDCNoProjectError("Project name not found, please set PROJECT_NAME in your settings module") + kafka_group_id = settings.PROJECT_NAME.lower() global _message_service_singleton if _message_service_singleton is None: - _message_service_singleton = KeycloakMessageService(settings.PROJECT_NAME) - - _message_service_singleton.setup_event_service() + _message_service_singleton = KeycloakMessageService(kafka_group_id) + _message_service_singleton.setup_event_service() def init_listener_in_background(): import threading - import time - from cloudharness import log def background_operation(): - listener_initialized = False - - while not listener_initialized: + while True: try: init_listener() log.info('User sync events listener started') - listener_initialized = True + break except: log.exception('Error initializing event queue. Retrying in 5 seconds...') time.sleep(5) diff --git a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/user.py b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/user.py index 0fb0d61cc..189e6516d 100644 --- a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/user.py +++ b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/cloudharness_django/services/user.py @@ -1,9 +1,7 @@ from django.contrib.auth.models import User, Group -from django.db import transaction from cloudharness_django.models import Team, Member -from cloudharness_django.services.auth import AuthService, AuthorizationLevel -from cloudharness import models as ch_models +from cloudharness_django.services.auth import AuthorizationLevel def get_user_by_kc_id(kc_id) -> User: @@ -14,7 +12,7 @@ def get_user_by_kc_id(kc_id) -> User: class UserService: - def __init__(self, auth_service: AuthService): + def __init__(self, auth_service): self.auth_service = auth_service self.auth_client = auth_service.get_auth_client() @@ -23,7 +21,7 @@ def _get_kc_user(self, user): all_users = self.auth_client.get_users() return [kc_user for kc_user in all_users if kc_user["email"] == user.email][0] - def _map_kc_user(self, user: User, kc_user: ch_models.User = None, is_superuser=False, delete=False): + def _map_kc_user(self, user, kc_user=None, is_superuser=False, delete=False): # map a kc user to a django user if not kc_user: kc_user = self._get_kc_user(user) @@ -35,10 +33,10 @@ def _map_kc_user(self, user: User, kc_user: ch_models.User = None, is_superuser= user.is_staff = is_superuser user.is_superuser = is_superuser - user.username = kc_user.username or kc_user.email - user.first_name = kc_user.first_name or "" - user.last_name = kc_user.last_name or "" - user.email = kc_user.email or "" + user.username = kc_user.get("username", kc_user["email"]) + user.first_name = kc_user.get("firstName", "") + user.last_name = kc_user.get("lastName", "") + user.email = kc_user.get("email", "") user.is_active = kc_user.get("enabled", delete) return user @@ -68,14 +66,14 @@ def rm_user_from_team(self, user, team_name): kc_user_id = user.member.kc_id self.auth_client.group_user_remove(kc_user_id, kc_group_id) - def sync_kc_group(self, kc_group: ch_models.UserGroup): + def sync_kc_group(self, kc_group): # sync the kc group with the django group try: - team = Team.objects.get(kc_id=kc_group.id) + team = Team.objects.get(kc_id=kc_group["id"]) group, created = Group.objects.get_or_create(team=team) - group.name = kc_group.name + group.name = kc_group["name"] except Team.DoesNotExist: - group, created = Group.objects.get_or_create(name=kc_group.name) + group, created = Group.objects.get_or_create(name=kc_group["name"]) try: # check if group has a team team = group.team @@ -85,7 +83,7 @@ def sync_kc_group(self, kc_group: ch_models.UserGroup): if superusers and len(superusers) > 0: team = Team.objects.create( owner=superusers[0], # one of the superusers will be the default team owner - kc_id=kc_group.id, + kc_id=kc_group["id"], group=group) team.save() group.save() @@ -97,71 +95,32 @@ def sync_kc_groups(self, kc_groups=None): for kc_group in kc_groups: self.sync_kc_group(kc_group) - @transaction.atomic - def sync_kc_user(self, kc_user: ch_models.User, is_superuser=False, delete=False): - """ - Sync the kc user with the django user using kc_id for reliable lookups. - ALWAYS creates both User and Member atomically - never returns a User without a Member. - """ - user = get_user_by_kc_id(kc_user.id) + def sync_kc_user(self, kc_user, is_superuser=False, delete=False): + # sync the kc user with the django user - if user is None: - # User doesn't exist, create new one WITH Member atomically - username = kc_user.username or kc_user.email - if not username: - raise ValueError(f"Keycloak user {kc_user.id} has no username or email") + user, created = User.objects.get_or_create(username=kc_user["username"]) - # Create user and member atomically - user, user_created = User.objects.get_or_create(username=username) - - # CRITICAL: Ensure Member exists before proceeding - try: - member = Member.objects.get(user=user) - # Member exists but might have wrong kc_id - if member.kc_id != kc_user.id: - member.kc_id = kc_user.id - member.save() - except Member.DoesNotExist: - # Create the member relationship - Member.objects.create(kc_id=kc_user.id, user=user) - - # Update user attributes + member, created = Member.objects.get_or_create(user=user) + member.kc_id = kc_user["id"] + member.save() user = self._map_kc_user(user, kc_user, is_superuser, delete) - self.sync_kc_user_groups(kc_user) user.save() - - # FINAL SAFETY CHECK: Verify Member exists before returning - # This ensures we never return a user without a Member - try: - _ = user.member # Access member to trigger DoesNotExist if missing - except: - # This should never happen, but if it does, create Member immediately - Member.objects.create(kc_id=kc_user.id, user=user) - return user - def sync_kc_user_groups(self, kc_user: ch_models.User): - # Sync the user usergroups and memberships using kc_id for reliable lookups - user = get_user_by_kc_id(kc_user.id) - - if user is None: - raise ValueError(f"Django user not found for Keycloak user {kc_user.id}") - + def sync_kc_user_groups(self, kc_user): + # Sync the user usergroups and memberships + user = User.objects.get(username=kc_user["email"]) user_groups = [] - for kc_group in [*kc_user.user_groups, *kc_user.organizations]: - group, _ = Group.objects.get_or_create(name=kc_group.name) - user_groups.append(group) + for kc_group in kc_user["userGroups"]: + user_groups += [Group.objects.get(name=kc_group["name"])] user.groups.set(user_groups) user.save() - # Ensure the member relationship exists and is correct try: - member = user.member - if member.kc_id != kc_user.id: - member.kc_id = kc_user.id - member.save() + if user.member.kc_id != kc_user["id"]: + user.member.kc_id = kc_user["id"] except Member.DoesNotExist: - member = Member(user=user, kc_id=kc_user.id) + member = Member(user=user, kc_id=kc_user["id"]) member.save() def sync_kc_users_groups(self): @@ -172,12 +131,14 @@ def sync_kc_users_groups(self): ) # sync the users - users = self.auth_client.get_users() - for kc_user in users: + for kc_user in self.auth_client.get_users(): # check if user in all_admin_users - is_superuser = any([admin_user for admin_user in all_admin_users if admin_user["id"] == kc_user["id"]]) + is_superuser = any([admin_user for admin_user in all_admin_users if admin_user["email"] == kc_user["email"]]) self.sync_kc_user(kc_user, is_superuser) + # sync the groups + self.sync_kc_groups() + # sync the user groups and memberships - for kc_user in users: + for kc_user in self.auth_client.get_users(): self.sync_kc_user_groups(kc_user) diff --git a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/requirements.txt b/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/requirements.txt deleted file mode 100644 index 7eaa25147..000000000 --- a/infrastructure/common-images/cloudharness-django/libraries/cloudharness-django/requirements.txt +++ /dev/null @@ -1,7 +0,0 @@ -Django>=5 -django-admin-extra-buttons>=1.4.2 -psycopg2-binary>=2.9.3 -Pillow>=9.2.0 -python-keycloak -django-prometheus -uvicorn \ No newline at end of file diff --git a/infrastructure/common-images/cloudharness-django/libraries/fastapi/requirements.txt b/infrastructure/common-images/cloudharness-django/libraries/fastapi/requirements.txt new file mode 100644 index 000000000..24ea43e72 --- /dev/null +++ b/infrastructure/common-images/cloudharness-django/libraries/fastapi/requirements.txt @@ -0,0 +1,3 @@ +fastapi==0.109.1 +fastapi-code-generator==0.3.5 +uvicorn==0.17.6 diff --git a/infrastructure/common-images/cloudharness-fastapi/libraries/fastapi/requirements.txt b/infrastructure/common-images/cloudharness-fastapi/libraries/fastapi/requirements.txt index 840e9167d..24ea43e72 100644 --- a/infrastructure/common-images/cloudharness-fastapi/libraries/fastapi/requirements.txt +++ b/infrastructure/common-images/cloudharness-fastapi/libraries/fastapi/requirements.txt @@ -1,2 +1,3 @@ -fastapi>=0.117.1 -uvicorn>=0.36.0 +fastapi==0.109.1 +fastapi-code-generator==0.3.5 +uvicorn==0.17.6 diff --git a/infrastructure/common-images/cloudharness-flask/Dockerfile b/infrastructure/common-images/cloudharness-flask/Dockerfile index f2bdb5c94..d8046b0b1 100644 --- a/infrastructure/common-images/cloudharness-flask/Dockerfile +++ b/infrastructure/common-images/cloudharness-flask/Dockerfile @@ -16,5 +16,4 @@ RUN --mount=type=cache,target=/root/.cache python -m pip install --upgrade pip & pip install --prefer-binary -r requirements.txt --default-timeout=1000 EXPOSE $PORT - -CMD gunicorn -k uvicorn.workers.UvicornWorker --workers=$WORKERS --bind=0.0.0.0:$PORT $MODULE_NAME.__main__:app --timeout 180 \ No newline at end of file +CMD gunicorn --workers=$WORKERS --bind=0.0.0.0:$PORT $MODULE_NAME.__main__:app \ No newline at end of file diff --git a/infrastructure/common-images/cloudharness-flask/requirements.txt b/infrastructure/common-images/cloudharness-flask/requirements.txt index 1665cca69..b3d67d348 100644 --- a/infrastructure/common-images/cloudharness-flask/requirements.txt +++ b/infrastructure/common-images/cloudharness-flask/requirements.txt @@ -1,9 +1,12 @@ -connexion[swagger-ui,flask,uvicorn]>=3.0.0,<4.0.0 -Flask>=2.0.0,<4.0.0 -swagger-ui-bundle>=1.1.0 +connexion[swagger-ui]==2.14.2 +Flask<3.0.0 +Flask-Cors>=4.0.0 gunicorn>=21.2.0 itsdangerous>=2.1.2 Jinja2>=3.1.3 jsonschema>=4.20.0 openapi-spec-validator<0.5.0 -sentry-sdk +sentry-sdk>=0.14.4 +SQLAlchemy>=2.0.0 +swagger-ui-bundle>=0.0.2 +werkzeug<2.3 \ No newline at end of file diff --git a/libraries/api/config.json b/libraries/api/config.json new file mode 100644 index 000000000..8c57239d7 --- /dev/null +++ b/libraries/api/config.json @@ -0,0 +1,4 @@ +{ + "packageName": "cloudharness_model", + "disallowAdditionalPropertiesIfNotPresent": false +} \ No newline at end of file diff --git a/libraries/api/openapi.yaml b/libraries/api/openapi.yaml new file mode 100644 index 000000000..a2d8400e8 --- /dev/null +++ b/libraries/api/openapi.yaml @@ -0,0 +1,839 @@ +--- +openapi: 3.0.2 +info: + title: cloudharness + version: 1.0.0 +components: + schemas: + AutoArtifactSpec: + description: "" + required: + - auto + type: object + properties: + auto: + description: "When true, enables automatic template" + type: boolean + name: + description: "" + type: string + UriRoleMappingConfig: + description: + "Defines the application Gatekeeper configuration, if enabled (i.e.\ + \ `secured: true`." + required: + - roles + - uri + type: object + properties: + uri: + $ref: "#/components/schemas/PathSpecifier" + description: Path to secure + roles: + description: Roles allowed to access the present uri + type: array + items: + type: string + ServiceAutoArtifactConfig: + description: "" + type: object + allOf: + - type: object + properties: + port: + description: Service port + type: integer + - $ref: "#/components/schemas/AutoArtifactSpec" + ApplicationDependenciesConfig: + description: "" + type: object + properties: + hard: + description: + Hard dependencies indicate that the application may not start + without these other applications. + type: array + items: + type: string + soft: + description: + Soft dependencies indicate that the application will work partially + without these other applications. + type: array + items: + type: string + build: + description: + Hard dependencies indicate that the application Docker image + build requires these base/common images + type: array + items: + type: string + DeploymentResourcesConf: + description: "" + type: object + properties: + requests: + $ref: "#/components/schemas/CpuMemoryConfig" + description: "" + limits: + $ref: "#/components/schemas/CpuMemoryConfig" + description: "" + CpuMemoryConfig: + description: "" + type: object + properties: + cpu: + description: "" + type: string + memory: + description: "" + type: string + FileResourcesConfig: + description: "" + required: + - name + - src + - dst + type: object + properties: + name: + $ref: "#/components/schemas/Filename" + description: "" + src: + $ref: "#/components/schemas/Filename" + description: "" + dst: + description: "" + type: string + ApplicationProbe: + description: |- + Define a Kubernetes probe See also the + [official documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) + required: + - path + type: object + properties: + path: + $ref: "#/components/schemas/URL" + description: "" + periodSeconds: + description: "" + type: number + failureThreshold: + description: "" + type: number + initialDelaySeconds: + description: "" + type: number + URL: + description: "" + type: string + ApplicationConfig: + description: Place here the values to configure your application helm templates. + required: + - harness + type: object + properties: + harness: + $ref: "#/components/schemas/ApplicationHarnessConfig" + description: + Values inside this section have a special meaning to cloudharness + (e.g. enabling and configuring automatic deployment) + additionalProperties: true + HarnessMainConfig: + description: "" + required: + - local + - secured_gatekeepers + - domain + - namespace + - mainapp + - apps + type: object + properties: + local: + description: "If set to true, local DNS mapping is added to pods." + type: boolean + secured_gatekeepers: + description: + Enables/disables Gatekeepers on secured applications. Set to + false for testing/development + type: boolean + domain: + description: The root domain + type: string + example: The root domain. + namespace: + description: The K8s namespace. + type: string + mainapp: + description: Defines the app to map to the root domain + type: string + registry: + $ref: "#/components/schemas/RegistryConfig" + description: "" + tag: + description: Docker tag used to push/pull the built images. + type: string + apps: + $ref: "#/components/schemas/ApplicationsConfigsMap" + description: "" + env: + description: Environmental variables added to all pods + type: array + items: + $ref: "#/components/schemas/NameValue" + privenv: + $ref: "#/components/schemas/NameValue" + description: Private environmental variables added to all pods + backup: + $ref: "#/components/schemas/BackupConfig" + description: "" + name: + description: Base name + type: string + task-images: + $ref: "#/components/schemas/SimpleMap" + description: "" + RegistryConfig: + description: "" + required: + - name + type: object + properties: + name: + $ref: "#/components/schemas/URL" + description: The docker registry where built images are pushed + secret: + description: Optional secret used for pulling from docker registry. + type: string + SimpleMap: + description: "" + type: object + additionalProperties: + type: string + FreeObject: + description: "" + type: object + additionalProperties: true + DatabaseDeploymentConfig: + description: "" + type: object + allOf: + - type: object + properties: + type: + description: |- + Define the database type. + + One of (mongo, postgres, neo4j, sqlite3) + pattern: ^(mongo|postgres|neo4j|sqlite3)$ + type: string + example: '"neo4j"' + size: + description: Specify database disk size + type: string + example: 1Gi + user: + description: database username + type: string + pass: + format: password + description: Database password + type: string + image_ref: + description: Used for referencing images from the build + type: string + example: "image_ref: myownpgimage" + mongo: + $ref: "#/components/schemas/FreeObject" + description: Mongo db specific configuration + postgres: + $ref: "#/components/schemas/FreeObject" + description: Postgres database specific configuration + neo4j: + description: Neo4j database specific configuration + resources: + $ref: "#/components/schemas/DeploymentResourcesConf" + description: Database deployment resources + - $ref: "#/components/schemas/AutoArtifactSpec" + ApplicationsConfigsMap: + description: "" + type: object + additionalProperties: + $ref: "#/components/schemas/ApplicationConfig" + NameValue: + description: "" + required: + - name + type: object + properties: + name: + description: "" + type: string + value: + description: "" + type: string + IngressConfig: + description: "" + type: object + allOf: + - type: object + properties: + ssl_redirect: + description: "" + type: boolean + letsencrypt: + description: "" + type: object + properties: + email: + type: string + - $ref: "#/components/schemas/AutoArtifactSpec" + BackupConfig: + description: "" + required: + - dir + - resources + type: object + properties: + active: + description: "" + type: boolean + keep_days: + description: "" + type: integer + keep_weeks: + description: "" + type: integer + keep_months: + description: "" + type: integer + schedule: + description: Cron expression + pattern: + "/(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every\ + \ (\\d+(ns|us|µs|ms|s|m|h))+)|((((\\d+,)+\\d+|(\\d+(\\/|-)\\d+)|\\d+|\\\ + *) ?){5,7})/" + type: string + suffix: + description: The file suffix added to backup files + volumesize: + description: The volume size for backups (all backups share the same volume) + type: string + dir: + $ref: "#/components/schemas/Filename" + description: + "Target directory of backups, the mount point of the persistent\ + \ volume." + resources: + $ref: "#/components/schemas/DeploymentResourcesConf" + description: "" + Quota: + description: "" + type: object + additionalProperties: + type: string + example: + quota-ws-max: 5 + quota-storage-max: 1G + UserGroup: + type: object + properties: + access: + type: object + additionalProperties: true + attributes: + $ref: "#/components/schemas/SimpleMap" + additionalProperties: true + clientRoles: + type: object + additionalProperties: true + id: + type: string + name: + type: string + path: + type: string + realmRoles: + type: array + items: + type: string + subGroups: + type: array + items: + $ref: "#/components/schemas/UserGroup" + UserCredential: + type: object + properties: + createdDate: + format: int64 + type: integer + credentialData: + type: string + id: + type: string + priority: + format: int32 + type: integer + secretData: + type: string + temporary: + type: boolean + type: + type: string + userLabel: + type: string + value: + type: string + User: + type: object + properties: + access: + type: object + additionalProperties: true + attributes: + type: object + additionalProperties: true + clientRoles: + type: object + additionalProperties: true + createdTimestamp: + format: int64 + type: integer + credentials: + type: array + items: + $ref: "#/components/schemas/UserCredential" + disableableCredentialTypes: + type: array + items: + type: string + email: + type: string + emailVerified: + type: boolean + enabled: + type: boolean + federationLink: + type: string + firstName: + type: string + groups: + type: array + items: + type: string + id: + type: string + lastName: + type: string + realmRoles: + type: array + items: + type: string + requiredActions: + type: array + items: + type: string + serviceAccountClientId: + type: string + username: + type: string + additionalProperties: {} + Filename: + description: "" + pattern: "^[^<>:;,?*|]+$" + type: string + PathSpecifier: + description: "" + pattern: "^[^<>:;,?|]+$" + type: string + CDCEvent: + description: |- + A message sent to the orchestration queue. + Applications can listen to these events to react to data change events happening + on other applications. + required: + - message_type + - operation + - uid + - meta + type: object + properties: + operation: + description: the operation on the object e.g. create / update / delete + enum: + - create + - update + - delete + - other + type: string + uid: + description: the unique identifier attribute of the object + type: string + message_type: + description: the type of the message (relates to the object type) e.g. jobs + type: string + resource: + $ref: "#/components/schemas/FreeObject" + description: The target object + meta: + $ref: "#/components/schemas/CDCEventMeta" + description: "" + CDCEventMeta: + description: "" + required: + - app_name + type: object + properties: + app_name: + description: The name of the application/microservice sending the message + type: string + user: + $ref: "#/components/schemas/User" + description: "" + args: + description: the caller function arguments + type: array + items: + $ref: "#/components/schemas/FreeObject" + kwargs: + description: the caller function keyword arguments + description: + description: General description -- for human consumption + type: string + ApplicationHarnessConfig: + description: + "Define helm variables that allow CloudHarness to enable and configure\ + \ your \napplication's deployment" + required: [] + type: object + properties: + deployment: + $ref: "#/components/schemas/DeploymentAutoArtifactConfig" + description: + Defines reference deployment parameters. Values maps to k8s + spec + service: + $ref: "#/components/schemas/ServiceAutoArtifactConfig" + description: Defines automatic service parameters. + subdomain: + description: "If specified, an ingress will be created at [subdomain].[.Values.domain]" + type: string + aliases: + description: + "If specified, an ingress will be created at [alias].[.Values.domain]\ + \ for each alias" + type: array + items: + type: string + domain: + description: "If specified, an ingress will be created at [domain]" + type: string + dependencies: + $ref: "#/components/schemas/ApplicationDependenciesConfig" + description: + Application dependencies are used to define what is required + in the deployment when --include (-i) is used. Specify application names + in the list. + secured: + description: "When true, the application is shielded with a getekeeper" + type: boolean + uri_role_mapping: + description: + "Map uri/roles to secure with the Gatekeeper (if `secured:\ + \ true`)" + type: array + items: + $ref: "#/components/schemas/UriRoleMappingConfig" + secrets: + $ref: "#/components/schemas/SimpleMap" + description: |- + Define secrets will be mounted in the deployment + + Define as + + ```yaml + secrets: + secret_name: 'value' + + ``` + + Values if left empty are randomly generated + use_services: + description: + "Specify which services this application uses in the frontend\ + \ to create proxy ingresses. e.g. \n```\n- name: samples\n```" + type: array + items: + type: string + database: + $ref: "#/components/schemas/DatabaseDeploymentConfig" + description: "" + resources: + description: |- + Application file resources. Maps from deploy/resources folder and mounts as + configmaps + type: array + items: + $ref: "#/components/schemas/FileResourcesConfig" + readinessProbe: + $ref: "#/components/schemas/ApplicationProbe" + description: Kubernetes readiness probe configuration + startupProbe: + $ref: "#/components/schemas/ApplicationProbe" + description: "" + livenessProbe: + $ref: "#/components/schemas/ApplicationProbe" + description: Kubernetes liveness probe configuration + sourceRoot: + $ref: "#/components/schemas/Filename" + description: "" + name: + description: |- + Application's name. Do not edit, the value is automatically set from the + application directory's name + type: string + jupyterhub: + $ref: "#/components/schemas/JupyterHubConfig" + description: | + Configurations specific to jupyterhub. Edit only if your application is + configured as a jupyterhub deployment + accounts: + $ref: "#/components/schemas/ApplicationAccountsConfig" + description: Define specific test users and roles for this application + test: + $ref: "#/components/schemas/ApplicationTestConfig" + description: Enable and configure automated testing for this application. + additionalProperties: true + JupyterHubConfig: + description: "" + type: object + properties: + args: + description: arguments passed to the container + type: array + items: + type: string + extraConfig: + $ref: "#/components/schemas/SimpleMap" + description: + allows you to add Python snippets to the jupyterhub_config.py + file + spawnerExtraConfig: + $ref: "#/components/schemas/FreeObject" + description: + allows you to add values to the spawner object without the + need of creating a new hook + applicationHook: + description: + "change the hook function (advanced)\n\nSpecify the Python\ + \ name of the function (full module path, the module must be \ninstalled\ + \ in the Docker image)" + example: my_lib.change_pod_manifest + additionalProperties: true + UserRole: + type: object + properties: + attributes: + type: object + additionalProperties: true + clientRole: + type: boolean + composite: + type: boolean + containerId: + type: string + description: + type: string + id: + type: string + name: + type: string + additionalProperties: true + ApplicationAccountsConfig: + description: "" + type: object + properties: + roles: + description: + Specify roles to be created in this deployment specific for + this application + type: array + items: + type: string + users: + description: + "Defines test users to be added to the deployment, specific\ + \ for this application" + type: array + items: + $ref: "#/components/schemas/ApplicationUser" + ApplicationUser: + description: Defines a user + required: + - username + type: object + properties: + username: + description: "" + type: string + password: + format: password + description: "" + type: string + clientRoles: + description: "" + type: array + items: + type: string + realmRoles: + description: "" + type: array + items: + type: string + ApplicationTestConfig: + description: "" + required: + - unit + - e2e + - api + type: object + properties: + unit: + $ref: "#/components/schemas/UnitTestsConfig" + description: "" + api: + $ref: "#/components/schemas/ApiTestsConfig" + description: "" + e2e: + $ref: "#/components/schemas/E2ETestsConfig" + description: "" + UnitTestsConfig: + description: "" + required: + - enabled + - commands + type: object + properties: + enabled: + description: "Enables unit tests for this application (default: true)" + type: boolean + commands: + description: Commands to run unit tests + type: array + items: + type: string + example: '["pytest /usr/src/app/samples/test"]' + E2ETestsConfig: + description: "" + required: + - enabled + - smoketest + type: object + properties: + enabled: + description: + "Enables end to end testing for this application (default:\ + \ false)" + type: boolean + smoketest: + description: Specify whether to run the common smoke tests + type: boolean + ignoreConsoleErrors: + description: "" + type: boolean + ignoreRequestErrors: + description: "" + type: boolean + ApiTestsConfig: + description: "" + required: + - enabled + - autotest + - checks + type: object + properties: + enabled: + description: "Enables api tests for this application (default: false)" + type: boolean + autotest: + description: Specify whether to run the common smoke tests + type: boolean + runParams: + description: Additional schemathesis parameters + type: array + items: + type: string + checks: + description: |- + One of the Schemathesis checks: + + - not_a_server_error. The response has 5xx HTTP status; + - status_code_conformance. The response status is not defined in the API schema; + - content_type_conformance. The response content type is not defined in the API schema; + - response_schema_conformance. The response content does not conform to the schema defined for this specific response; + - response_headers_conformance. The response headers does not contain all defined headers. + type: array + items: + type: string + example: '["not_a_server_error", "status_code_conformance"]' + DeploymentAutoArtifactConfig: + description: "" + type: object + allOf: + - type: object + properties: + port: + description: Deployment port + type: string + replicas: + description: Number of replicas + type: integer + image: + description: |- + Image name to use in the deployment. Leave it blank to set from the application's + Docker file + pattern: "(?:[a-z]+/)?([a-z]+)(?::[0-9]+)?" + type: string + resources: + $ref: "#/components/schemas/DeploymentResourcesConf" + description: Deployment resources + volume: + $ref: "#/components/schemas/DeploymentVolumeSpec" + description: Volume specification + resources: + description: Deployment resources + type: string + test: + description: ssaa + type: string + - $ref: "#/components/schemas/AutoArtifactSpec" + DeploymentVolumeSpec: + description: |- + Defines a volume attached to the deployment. + Automatically created the volume claim and mounts. + type: object + allOf: + - required: + - mountpath + type: object + properties: + mountpath: + description: The mount path for the volume + type: string + size: + description: "The volume size. \n\nE.g. 5Gi" + usenfs: + description: + Set to `true` to use the nfs on the created volume and mount + as ReadWriteMany. + type: boolean + - $ref: "#/components/schemas/AutoArtifactSpec" + example: + auto: true + mountpath: /usr/src/app/persistent + name: my-files + size: 5Gi + usenfs: true diff --git a/libraries/client/cloudharness_cli/requirements.txt b/libraries/client/cloudharness_cli/requirements.txt index 7d45544de..cc85509ec 100644 --- a/libraries/client/cloudharness_cli/requirements.txt +++ b/libraries/client/cloudharness_cli/requirements.txt @@ -1,5 +1,5 @@ python_dateutil >= 2.5.3 setuptools >= 21.0.0 -urllib3 >= 1.25.3, < 3.0.0 +urllib3 >= 1.25.3, < 2.1.0 pydantic >= 2 typing-extensions >= 4.7.1 diff --git a/libraries/cloudharness-common/cloudharness/__init__.py b/libraries/cloudharness-common/cloudharness/__init__.py index 163942400..b09092791 100644 --- a/libraries/cloudharness-common/cloudharness/__init__.py +++ b/libraries/cloudharness-common/cloudharness/__init__.py @@ -1,4 +1,4 @@ -import json +import json as js from cloudharness_model.encoder import CloudHarnessJSONEncoder import logging import sys @@ -16,7 +16,7 @@ def set_debug(): # TODO log will write through a rest service -json_dumps = json.dumps +json_dumps = js.dumps def dumps(o, *args, **kwargs): @@ -24,23 +24,15 @@ def dumps(o, *args, **kwargs): if "cls" not in kwargs: return json_dumps(o, cls=CloudHarnessJSONEncoder, *args, **kwargs) return json_dumps(o, *args, **kwargs) - except TypeError as e: - # If serialization fails, try converting objects with to_dict method - if "not JSON serializable" in str(e): - if hasattr(o, "to_dict") and callable(getattr(o, "to_dict")): - o = o.to_dict() - return json_dumps(o, *args, **kwargs) - # Handle lists/tuples of objects with to_dict - if isinstance(o, (list, tuple)): - converted = [item.to_dict() if hasattr(item, "to_dict") and callable(getattr(item, "to_dict")) else item for item in o] - return json_dumps(converted, *args, **kwargs) - # If we still can't serialize, try without cls parameter - if "cls" in kwargs: - kwargs_no_cls = {k: v for k, v in kwargs.items() if k != "cls"} - return json_dumps(o, *args, **kwargs_no_cls) + except: + logging.error(repr(o)) raise +json = js +json.dumps = dumps + + class NotCorrectlyInitialized(Exception): pass diff --git a/libraries/cloudharness-common/cloudharness/applications.py b/libraries/cloudharness-common/cloudharness/applications.py index a4512e551..855f8c82b 100644 --- a/libraries/cloudharness-common/cloudharness/applications.py +++ b/libraries/cloudharness-common/cloudharness/applications.py @@ -13,14 +13,12 @@ class ApplicationConfiguration(ApplicationConfig): def __new__(cls, *args, **kwargs): if len(args) == 1 and type(args[0]) == dict: return ApplicationConfiguration.from_dict(args[0]) - return super().__new__(cls) + return super().__new__(cls, *args, **kwargs) def __init__(self, *args, **kargs): if len(args) == 1 and type(args[0]) == dict: - self.__conf = None return ApplicationConfig.__init__(self, *args, **kargs) - # Set __conf after parent initialization to ensure it's not overwritten self.__conf = None def is_auto_service(self) -> bool: @@ -33,7 +31,7 @@ def is_auto_db(self) -> bool: return self.harness.database.auto def is_sentry_enabled(self) -> bool: - return self.harness.sentry + return self.harness["sentry"] def get_db_connection_string(self, **kwargs) -> str: if not self.is_auto_db(): diff --git a/libraries/cloudharness-common/cloudharness/auth/keycloak.py b/libraries/cloudharness-common/cloudharness/auth/keycloak.py index 5d5421b60..f5a70662d 100644 --- a/libraries/cloudharness-common/cloudharness/auth/keycloak.py +++ b/libraries/cloudharness-common/cloudharness/auth/keycloak.py @@ -1,8 +1,5 @@ -from base64 import b64decode import os from typing import List -from cloudharness_model.models.organization import Organization -from cryptography.hazmat.primitives import serialization import jwt import json import requests @@ -12,7 +9,7 @@ from cloudharness import log from cloudharness.middleware import get_authentication_token -from cloudharness.models import User, UserGroup +from cloudharness.models import UserGroup, User from .exceptions import UserNotFound, InvalidToken, AuthSecretNotFound @@ -46,7 +43,7 @@ def wrapper(self, *args, **kwargs): return wrapper -def decode_token(token, **kwargs) -> dict | None: +def decode_token(token, **kwargs): """ Check and retrieve authentication information from custom bearer token. Returned value will be passed in 'token_info' parameter of your operation function, if there is one. @@ -64,20 +61,6 @@ def decode_token(token, **kwargs) -> dict | None: return decoded -def get_current_user_id() -> str | None: - - authentication_token = get_authentication_token() - - if not authentication_token or authentication_token == 'Bearer undefined': - return None - - user_dict = decode_token(authentication_token.split(' ')[-1]) - if user_dict: - return user_dict.get('sub') - - return None - - def get_server_url(): accounts_app = get_configuration('accounts') @@ -183,10 +166,13 @@ def refresh_token(self): @classmethod def get_public_key(cls): if not cls.__public_key: - public_key_url = os.path.join(get_server_url(), "realms", get_auth_realm()) - key_der_base64 = requests.get(public_key_url).json()['public_key'] - key_der = b64decode(key_der_base64.encode()) - cls.__public_key = serialization.load_der_public_key(key_der) + AUTH_PUBLIC_KEY_URL = os.path.join( + get_server_url(), "realms", get_auth_realm()) + + KEY = json.loads(requests.get(AUTH_PUBLIC_KEY_URL, + verify=False).text)['public_key'] + cls.__public_key = b"-----BEGIN PUBLIC KEY-----\n" + \ + str.encode(KEY) + b"\n-----END PUBLIC KEY-----" return cls.__public_key @classmethod @@ -203,7 +189,7 @@ def decode_token(cls, token, audience="web-client"): """ try: decoded = jwt.decode(token, cls.get_public_key(), - algorithms=['RS256'], audience=audience) + algorithms='RS256', audience=audience) except jwt.exceptions.InvalidTokenError as e: raise InvalidToken(e) from e return decoded @@ -424,9 +410,11 @@ def get_users(self, query=None, with_details=False) -> List[User]: admin_client = self.get_admin_client() users = [] for user in admin_client.get_users(query=query): - user = User.from_dict(user) - self._add_related_to_user(user, with_details, admin_client) - users.append(user) + user.update({ + "userGroups": admin_client.get_user_groups(user['id'], brief_representation=not with_details), + 'realmRoles': admin_client.get_realm_roles_of_user(user['id']) + }) + users.append(User.from_dict(user)) return users @with_refreshtoken @@ -466,15 +454,11 @@ def get_user(self, user_id, with_details=False) -> User: except InvalidToken as e: raise UserNotFound(user_id) - user = User.from_dict(user) - self._add_related_to_user(user, with_details, admin_client) - return user - - def _add_related_to_user(self, user: User, with_details: bool, admin_client): - user.user_groups = [UserGroup.from_dict(group) for group in admin_client.get_user_groups(user_id=user['id'], brief_representation=not with_details)] - user.realm_roles = admin_client.get_realm_roles_of_user(user['id']) - user.organizations = [Organization.from_dict(org) for org in admin_client.get_user_organizations(user['id'])] - return user + user.update({ + "userGroups": admin_client.get_user_groups(user_id=user['id'], brief_representation=not with_details), + 'realmRoles': admin_client.get_realm_roles_of_user(user['id']) + }) + return User.from_dict(user) def get_current_user(self) -> User: """ @@ -616,6 +600,8 @@ def user_add_update_attribute(self, user_id, attribute_name, attribute_value): { 'attributes': attributes, 'username': user.username, + 'firstName': user.first_name, + 'lastName': user.last_name, 'email': user.email, } ) diff --git a/libraries/cloudharness-common/cloudharness/events/client.py b/libraries/cloudharness-common/cloudharness/events/client.py index c7ec8adea..f7c00391f 100644 --- a/libraries/cloudharness-common/cloudharness/events/client.py +++ b/libraries/cloudharness-common/cloudharness/events/client.py @@ -8,6 +8,7 @@ from time import sleep from cloudharness import json, dumps +from cloudharness_model.util import DeserializationException from keycloak.exceptions import KeycloakGetError from kafka import KafkaProducer, KafkaConsumer from kafka.admin import KafkaAdminClient, NewTopic @@ -195,7 +196,7 @@ def consume_all_cdc(self, group_id='default') -> Generator[CDCEvent, None, None] try: if "operation" in record.value: yield CDCEvent.from_dict(record.value) - except Exception as e: + except DeserializationException as e: log.error("Message is not in the proper CDC format: %s", record.value) continue except Exception as e: diff --git a/libraries/cloudharness-common/cloudharness/utils/env.py b/libraries/cloudharness-common/cloudharness/utils/env.py index cf3d47b8d..bc06fd4ca 100644 --- a/libraries/cloudharness-common/cloudharness/utils/env.py +++ b/libraries/cloudharness-common/cloudharness/utils/env.py @@ -84,7 +84,7 @@ def get_cloudharness_events_client_id(): def get_cloudharness_events_service(): - return get_service_cluster_address('BOOTSTRAP') + return get_service_cluster_address('bootstrap') def get_service_cluster_address(cloudharness_app_name): diff --git a/libraries/cloudharness-common/cloudharness/utils/server.py b/libraries/cloudharness-common/cloudharness/utils/server.py index 355d554dd..3df184549 100644 --- a/libraries/cloudharness-common/cloudharness/utils/server.py +++ b/libraries/cloudharness-common/cloudharness/utils/server.py @@ -4,7 +4,7 @@ import flask import connexion -from flask.json.provider import DefaultJSONProvider +from connexion.apps.flask_app import FlaskJSONEncoder import six from cloudharness import log as logging @@ -14,18 +14,10 @@ app = None -class JSONEncoder(DefaultJSONProvider): +class JSONEncoder(FlaskJSONEncoder): include_nulls = False def default(self, o): - # Check if object has a to_dict method (preferred for OpenAPI models) - if hasattr(o, 'to_dict') and callable(getattr(o, 'to_dict')): - result = o.to_dict() - if not self.include_nulls: - # Filter out None values if include_nulls is False - result = {k: v for k, v in result.items() if v is not None} - return result - # Fallback to openapi_types handling for backwards compatibility if hasattr(o, 'openapi_types'): dikt = {} for attr, _ in six.iteritems(o.openapi_types): @@ -35,15 +27,7 @@ def default(self, o): attr = o.attribute_map[attr] dikt[attr] = value return dikt - return super().default(o) - - def dumps(self, obj, **kwargs): - """Override dumps to ensure our default method is used - - Uses stdlib_json to avoid issues with cloudharness monkeypatch - """ - kwargs.setdefault('default', self.default) - return json.dumps(obj, **kwargs) + return FlaskJSONEncoder.default(self, o) def init_webapp_routes(app: flask.Flask, www_path): @@ -73,30 +57,6 @@ def send_static(path): return flask.send_from_directory(os.path.join(www_path, 'static'), path) -def setup_cors(app: flask.Flask): - """ - Setup CORS headers for Flask app to work with Connexion 3.x - This replaces Flask-CORS which is no longer compatible - """ - @app.after_request - def after_request(response): - # Allow CORS for API endpoints - if flask.request.path.startswith('/api/'): - response.headers.add('Access-Control-Allow-Origin', '*') - response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization') - response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS') - return response - - @app.before_request - def handle_preflight(): - if flask.request.method == "OPTIONS" and flask.request.path.startswith('/api/'): - response = flask.Response() - response.headers.add("Access-Control-Allow-Origin", "*") - response.headers.add('Access-Control-Allow-Headers', "Content-Type,Authorization") - response.headers.add('Access-Control-Allow-Methods', "GET,PUT,POST,DELETE,OPTIONS") - return response - - class Config(object): DEBUG = False TESTING = False @@ -104,7 +64,7 @@ class Config(object): def init_flask(title='CH service API', init_app_fn=None, webapp=False, json_encoder=JSONEncoder, resolver=None, - config=Config, enable_cors=True): + config=Config): """ """ @@ -117,12 +77,12 @@ def init_flask(title='CH service API', init_app_fn=None, webapp=False, json_enco mod = inspect.getmodule(frm[0]) caller_path = os.path.dirname(os.path.realpath(mod.__file__)) - connexion_app = connexion.FlaskApp(__name__) + connexion_app = connexion.App(__name__) app = connexion_app.app obj_config = os.environ.get('APP_SETTINGS', config) if obj_config: app.config.from_object(obj_config) - app.json = json_encoder(app) + app.json_encoder = json_encoder # activate the CH middleware app.wsgi_app = middleware(app.wsgi_app) @@ -132,10 +92,6 @@ def init_flask(title='CH service API', init_app_fn=None, webapp=False, json_enco app.logger.handlers = gunicorn_logger.handlers app.logger.setLevel(gunicorn_logger.level) - # Setup CORS if enabled (replacement for Flask-CORS) - if enable_cors: - setup_cors(app) - if webapp: init_webapp_routes(app, www_path=os.path.join( os.path.dirname(caller_path), 'www')) @@ -146,63 +102,25 @@ def init_flask(title='CH service API', init_app_fn=None, webapp=False, json_enco if init_app_fn: init_app_fn(app) - def handle_exception(request, exc: Exception): + @app.errorhandler(Exception) + def handle_exception(e: Exception): data = { - "description": str(exc), - "type": type(exc).__name__ + "description": str(e), + "type": type(e).__name__ } try: - # Try to check sentry configuration, but don't fail if config is not available - try: - if not get_current_configuration().is_sentry_enabled(): - data['trace'] = traceback.format_exc() - except Exception as config_error: - # If configuration check fails, include trace anyway - logging.warning(f"Could not check sentry configuration: {config_error}") + if not get_current_configuration().is_sentry_enabled(): data['trace'] = traceback.format_exc() - except Exception as general_error: - logging.error(f"Error in error handler: {general_error}", exc_info=True) + except: + logging.error( + "Error checking sentry configuration", exc_info=True) data['trace'] = traceback.format_exc() - - logging.error(str(exc), exc_info=True) + logging.error(str(e), exc_info=True) return json.dumps(data), 500 - # Register error handler with Flask app directly for better compatibility - @app.errorhandler(Exception) - def flask_handle_exception(*args): - # Flask error handlers can be called with different signatures - # Handle both single argument (exc) and multiple arguments flexibly - if len(args) == 1: - exc = args[0] - elif len(args) >= 2: - exc = args[0] if isinstance(args[0], Exception) else args[1] - else: - exc = Exception("Unknown error") - - # For Flask error handlers, we don't get the request object, - # but we can access it via flask.request if needed - try: - import flask - request = flask.request if flask.has_request_context() else None - except: - request = None - return handle_exception(request, exc) - - return connexion_app + return app def main(): - # Get the global connexion app from init_flask and run it - import inspect - frm = inspect.stack()[1] - mod = inspect.getmodule(frm[0]) - - # Get the connexion app variable from the calling module - connexion_app = getattr(mod, 'app', None) - if connexion_app and hasattr(connexion_app, 'run'): - connexion_app.run(host='0.0.0.0', port=int(os.getenv('PORT', 5001))) - else: - # Fallback to the global app variable (Flask app) - if app: - app.run(host='0.0.0.0', port=int(os.getenv('PORT', 5001))) + app.run(host='0.0.0.0', port=os.getenv('PORT', 5001)) diff --git a/libraries/cloudharness-common/cloudharness/workflows/operations.py b/libraries/cloudharness-common/cloudharness/workflows/operations.py index 22a71667e..7bb6d2f2e 100644 --- a/libraries/cloudharness-common/cloudharness/workflows/operations.py +++ b/libraries/cloudharness-common/cloudharness/workflows/operations.py @@ -169,19 +169,14 @@ def spec(self): return spec def add_on_exit_notify_handler(self, spec): - env_args = { - 'workflow_result': '{{workflow.status}}' - } - - if 'queue' in self.on_exit_notify: - env_args['queue_name'] = self.on_exit_notify['queue'] - if 'payload' in self.on_exit_notify: - env_args['payload'] = self.on_exit_notify['payload'] - + queue = self.on_exit_notify['queue'] + payload = self.on_exit_notify['payload'] exit_task = CustomTask( name="exit-handler", image_name=self.on_exit_notify.get('image', 'workflows-notify-queue'), - **env_args + workflow_result='{{workflow.status}}', + queue_name=queue, + payload=payload ) spec['onExit'] = 'exit-handler' spec['templates'].append( diff --git a/libraries/cloudharness-common/requirements.txt b/libraries/cloudharness-common/requirements.txt index ff943336a..e69de29bb 100644 --- a/libraries/cloudharness-common/requirements.txt +++ b/libraries/cloudharness-common/requirements.txt @@ -1,15 +0,0 @@ -kubernetes >= 29.0.0 -PyYAML >= 6.0.1 -oyaml >= 1.0 -pyjwt>=2.6.0 -cryptography -requests>=2.21.0 -python-keycloak >= 4.7.0 -argo-workflows==5.0.0 -cachetools >= 5.3.2 -blinker >= 1.7.0 -jinja2 >= 3.1.4 -kafka-python-ng >= 2.2.0 -requests >= 2.31.0 -python-dateutil >= 2.8.2 -sentry-sdk >= 1.39.2 \ No newline at end of file diff --git a/libraries/cloudharness-common/tests/test_applications.py b/libraries/cloudharness-common/tests/test_applications.py index d57ae0c4c..c8a9e5ee2 100644 --- a/libraries/cloudharness-common/tests/test_applications.py +++ b/libraries/cloudharness-common/tests/test_applications.py @@ -63,7 +63,7 @@ def test_application_conf(): assert uut.is_auto_deployment() assert uut.is_sentry_enabled() - d2 = {'admin': {'pass': 'metacell', 'role': 'administrator', 'user': 'admin'}, 'client': {'id': 'rest-client', 'secret': '5678eb6e-9e2c-4ee5-bd54-34e7411339e8'}, 'enabled': True, 'harness': {'aliases': [], 'database': {'auto': True, 'mongo': {'image': 'mongo:5', 'ports': [{'name': 'http', 'port': 27017}]}, 'name': 'keycloak-postgres', 'neo4j': {'dbms_security_auth_enabled': 'false', 'image': 'neo4j:4.1.9', 'memory': {'heap': {'initial': '64M', 'max': '128M'}, 'pagecache': {'size': '64M'}, 'size': '256M'}, 'ports': [{'name': 'http', 'port': 7474}, {'name': 'bolt', 'port': 7687}]}, 'pass': 'password', 'postgres': {'image': 'postgres:10.4', 'initialdb': 'auth_db', 'ports': [{'name': 'http', 'port': 5432}]}, 'resources': {'limits': {'cpu': '1000m', 'memory': '2Gi'}, 'requests': {'cpu': '100m', 'memory': '512Mi'}}, 'size': '2Gi', 'type': 'postgres', 'user': 'user'}, 'dependencies': {'build': [], 'hard': [], 'soft': []}, 'deployment': {'auto': True, 'image': 'osb/accounts:3e02a15477b4696ed554e08cedf4109c67908cbe6b03331072b5b73e83b4fc2b', 'name': 'accounts', 'port': 8080, 'replicas': 1, 'resources': {'limits': {'cpu': '500m', 'memory': '1024Mi'}, 'requests': {'cpu': '10m', 'memory': '512Mi'}}}, 'domain': None, 'env': [{'name': 'KEYCLOAK_IMPORT', 'value': '/tmp/realm.json'}, {'name': 'KEYCLOAK_USER', 'value': 'admin'}, {'name': 'KEYCLOAK_PASSWORD', 'value': 'metacell'}, {'name': 'PROXY_ADDRESS_FORWARDING', 'value': 'true'}, {'name': 'DB_VENDOR', 'value': 'POSTGRES'}, {'name': 'DB_ADDR', 'value': 'keycloak-postgres'}, {'name': 'DB_DATABASE', 'value': 'auth_db'}, {'name': 'DB_USER', 'value': 'user'}, {'name': 'DB_PASSWORD', 'value': 'password'}, {'name': 'JAVA_OPTS', 'value': '-server -Xms64m -Xmx896m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true --add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED --add-exports=jdk.unsupported/sun.reflect=ALL-UNNAMED'}], 'name': 'accounts', 'readinessProbe': {'path': '/realms/master'}, 'resources': [{'dst': '/tmp/realm.json', 'name': 'realm-config', 'src': 'realm.json'}], 'secrets': {}, 'secured': False, 'service': {'auto': True, 'name': 'accounts', 'port': 8080}, 'subdomain': 'accounts', 'uri_role_mapping': [{'roles': ['administrator'], 'uri': '/*'}], 'use_services': []}, 'harvest': True, 'image': 'osb/accounts:latest', 'name': 'accounts', 'port': 8080, 'resources': {'limits': {'cpu': '500m', 'memory': '1024Mi'}, 'requests': {'cpu': '10m', 'memory': '512Mi'}}, 'task-images': {}, 'webclient': {'id': 'web-client', 'secret': '452952ae-922c-4766-b912-7b106271e34b'}} + d2 = {'admin': {'pass': 'metacell', 'role': 'administrator', 'user': 'admin'}, 'client': {'id': 'rest-client', 'secret': '5678eb6e-9e2c-4ee5-bd54-34e7411339e8'}, 'enabled': True, 'harness': {'aliases': [], 'database': {'auto': True, 'mongo': {'image': 'mongo:5', 'ports': [{'name': 'http', 'port': 27017}]}, 'name': 'keycloak-postgres', 'neo4j': {'dbms_security_auth_enabled': 'false', 'image': 'neo4j:4.1.9', 'memory': {'heap': {'initial': '64M', 'max': '128M'}, 'pagecache': {'size': '64M'}, 'size': '256M'}, 'ports': [{'name': 'http', 'port': 7474}, {'name': 'bolt', 'port': 7687}]}, 'pass': 'password', 'postgres': {'image': 'postgres:10.4', 'initialdb': 'auth_db', 'ports': [{'name': 'http', 'port': 5432}]}, 'resources': {'limits': {'cpu': '1000m', 'memory': '2Gi'}, 'requests': {'cpu': '100m', 'memory': '512Mi'}}, 'size': '2Gi', 'type': 'postgres', 'user': 'user'}, 'dependencies': {'build': [], 'hard': [], 'soft': []}, 'deployment': {'auto': True, 'image': 'osb/accounts:3e02a15477b4696ed554e08cedf4109c67908cbe6b03331072b5b73e83b4fc2b', 'name': 'accounts', 'port': 8080, 'replicas': 1, 'resources': {'limits': {'cpu': '500m', 'memory': '1024Mi'}, 'requests': {'cpu': '10m', 'memory': '512Mi'}}}, 'domain': None, 'env': [{'name': 'KEYCLOAK_IMPORT', 'value': '/tmp/realm.json'}, {'name': 'KEYCLOAK_USER', 'value': 'admin'}, {'name': 'KEYCLOAK_PASSWORD', 'value': 'metacell'}, {'name': 'PROXY_ADDRESS_FORWARDING', 'value': 'true'}, {'name': 'DB_VENDOR', 'value': 'POSTGRES'}, {'name': 'DB_ADDR', 'value': 'keycloak-postgres'}, {'name': 'DB_DATABASE', 'value': 'auth_db'}, {'name': 'DB_USER', 'value': 'user'}, {'name': 'DB_PASSWORD', 'value': 'password'}, {'name': 'JAVA_OPTS', 'value': '-server -Xms64m -Xmx896m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true --add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED --add-exports=jdk.unsupported/sun.reflect=ALL-UNNAMED'}], 'name': 'accounts', 'readinessProbe': {'path': '/realms/master'}, 'resources': [{'dst': '/tmp/realm.json', 'name': 'realm-config', 'src': 'realm.json'}], 'secrets': '', 'secured': False, 'service': {'auto': True, 'name': 'accounts', 'port': 8080}, 'subdomain': 'accounts', 'uri_role_mapping': [{'roles': ['administrator'], 'uri': '/*'}], 'use_services': []}, 'harvest': True, 'image': 'osb/accounts:latest', 'name': 'accounts', 'port': 8080, 'resources': {'limits': {'cpu': '500m', 'memory': '1024Mi'}, 'requests': {'cpu': '10m', 'memory': '512Mi'}}, 'task-images': {}, 'webclient': {'id': 'web-client', 'secret': '452952ae-922c-4766-b912-7b106271e34b'}} uut = ApplicationConfiguration.from_dict(d2) assert uut.conf assert uut.conf.admin.role == 'administrator' @@ -87,7 +87,6 @@ def test_get_configuration(): assert uut["freefield"]["a"] == 1 assert uut["freefield"].a == 1 assert uut["freefield.a"] == 1 - assert uut["harness.deployment.auto"] == True assert uut.freefield.a == 1 diff --git a/libraries/cloudharness-common/tests/test_on_exit_notify.py b/libraries/cloudharness-common/tests/test_on_exit_notify.py deleted file mode 100644 index d5375e616..000000000 --- a/libraries/cloudharness-common/tests/test_on_exit_notify.py +++ /dev/null @@ -1,183 +0,0 @@ -"""Test on_exit_notify functionality with optional queue and payload parameters""" - -from cloudharness.workflows import operations, tasks -from cloudharness import set_debug -from .test_env import set_test_environment - -# Set up test environment -set_test_environment() -set_debug() - - -def test_on_exit_notify_custom_image_only(): - """Test that on_exit_notify works with just a custom image, no queue/payload""" - print("Testing on_exit_notify with custom image only...") - - def test_function(): - return "test" - - task = tasks.PythonTask('test-task', test_function) - - # Test with custom image only (no queue/payload) - on_exit_notify = { - 'image': 'my-custom-exit-handler' - } - - op = operations.PipelineOperation('test-custom-exit', [task], on_exit_notify=on_exit_notify) - wf = op.to_workflow() - - # Verify the exit handler was added - assert 'onExit' in wf['spec'], "onExit should be present in spec" - assert wf['spec']['onExit'] == 'exit-handler', "onExit should reference exit-handler template" - - # Find the exit-handler template - exit_template = None - for template in wf['spec']['templates']: - if template['name'] == 'exit-handler': - exit_template = template - break - - assert exit_template is not None, "exit-handler template should exist" - assert 'my-custom-exit-handler' in exit_template['container']['image'], f"Image should contain my-custom-exit-handler, got {exit_template['container']['image']}" - - # Check environment variables - should only have workflow_result - env_vars = {} - for env in exit_template['container']['env']: - if 'value' in env: - env_vars[env['name']] = env['value'] - elif 'valueFrom' in env: - env_vars[env['name']] = env['valueFrom'] - - assert 'workflow_result' in env_vars, "workflow_result should be present" - assert env_vars['workflow_result'] == '{{workflow.status}}', "workflow_result should have correct value" - - # queue_name and payload should NOT be present since they weren't specified - assert 'queue_name' not in env_vars, "queue_name should not be present when not specified" - assert 'payload' not in env_vars, "payload should not be present when not specified" - - print("✓ Test passed: Custom image without queue/payload works correctly") - - -def test_on_exit_notify_with_queue_and_payload(): - """Test that the traditional usage still works (backward compatibility)""" - print("Testing on_exit_notify with queue and payload (backward compatibility)...") - - def test_function(): - return "test" - - task = tasks.PythonTask('test-task', test_function) - - # Traditional usage with queue and payload - on_exit_notify = { - 'queue': 'my_queue', - 'payload': '{"test": true}', - 'image': 'custom-image' - } - - op = operations.PipelineOperation('test-traditional-exit', [task], on_exit_notify=on_exit_notify) - wf = op.to_workflow() - - # Find the exit-handler template - exit_template = None - for template in wf['spec']['templates']: - if template['name'] == 'exit-handler': - exit_template = template - break - - assert exit_template is not None, "exit-handler template should exist" - - # Check environment variables - should have all three - env_vars = {} - for env in exit_template['container']['env']: - if 'value' in env: - env_vars[env['name']] = env['value'] - elif 'valueFrom' in env: - env_vars[env['name']] = env['valueFrom'] - - assert 'workflow_result' in env_vars, "workflow_result should be present" - assert 'queue_name' in env_vars, "queue_name should be present" - assert 'payload' in env_vars, "payload should be present" - - assert env_vars['queue_name'] == 'my_queue', f"queue_name should be 'my_queue', got {env_vars['queue_name']}" - assert env_vars['payload'] == '{"test": true}', f"payload should be correct, got {env_vars['payload']}" - - print("✓ Test passed: Backward compatibility works correctly") - - -def test_on_exit_notify_mixed_usage(): - """Test mixed usage with some optional parameters""" - print("Testing on_exit_notify with mixed usage (queue but no payload)...") - - def test_function(): - return "test" - - task = tasks.PythonTask('test-task', test_function) - - # Mixed usage - queue but no payload - on_exit_notify = { - 'image': 'my-custom-image', - 'queue': 'my_queue' - # No payload specified - } - - op = operations.PipelineOperation('test-mixed-exit', [task], on_exit_notify=on_exit_notify) - wf = op.to_workflow() - - # Find the exit-handler template - exit_template = None - for template in wf['spec']['templates']: - if template['name'] == 'exit-handler': - exit_template = template - break - - assert exit_template is not None, "exit-handler template should exist" - - # Check environment variables - env_vars = {} - for env in exit_template['container']['env']: - if 'value' in env: - env_vars[env['name']] = env['value'] - elif 'valueFrom' in env: - env_vars[env['name']] = env['valueFrom'] - - assert 'workflow_result' in env_vars, "workflow_result should be present" - assert 'queue_name' in env_vars, "queue_name should be present" - assert 'payload' not in env_vars, "payload should not be present when not specified" - - assert env_vars['queue_name'] == 'my_queue', f"queue_name should be 'my_queue', got {env_vars['queue_name']}" - - print("✓ Test passed: Mixed usage works correctly") - - -def test_on_exit_notify_default_image(): - """Test that default image still works when no custom image is specified""" - print("Testing on_exit_notify with default image...") - - def test_function(): - return "test" - - task = tasks.PythonTask('test-task', test_function) - - # Traditional usage without custom image - on_exit_notify = { - 'queue': 'my_queue', - 'payload': '{"test": true}' - # No image specified - should use default - } - - op = operations.PipelineOperation('test-default-exit', [task], on_exit_notify=on_exit_notify) - wf = op.to_workflow() - - # Find the exit-handler template - exit_template = None - for template in wf['spec']['templates']: - if template['name'] == 'exit-handler': - exit_template = template - break - - assert exit_template is not None, "exit-handler template should exist" - - # Should use default image - assert 'workflows-notify-queue' in exit_template['container']['image'], f"Should use default image, got {exit_template['container']['image']}" - - print("✓ Test passed: Default image works correctly") diff --git a/libraries/cloudharness-common/tests/test_quota.py b/libraries/cloudharness-common/tests/test_quota.py index 82ed8837c..4c886bd76 100644 --- a/libraries/cloudharness-common/tests/test_quota.py +++ b/libraries/cloudharness-common/tests/test_quota.py @@ -12,7 +12,6 @@ assert jh_config is not None -# pip install pytest-mock def test_get_quotas(mocker): def mock_get_admin_client(self): return None @@ -32,13 +31,9 @@ def mock_get_user(self, user_id, with_details): {"path": "/Low CU", "attributes": {'quota-ws-maxmem': [3], 'quota-ws-maxcpu': [2.5], 'quota-ws-open': [1]}} ] } - - def mock_get_api_password(): - return "password" mocker.patch('cloudharness.auth.keycloak.AuthClient.get_admin_client', mock_get_admin_client) mocker.patch('cloudharness.auth.keycloak.AuthClient.get_current_user', mock_get_current_user) mocker.patch('cloudharness.auth.keycloak.AuthClient.get_user', mock_get_user) - mocker.patch('cloudharness.auth.keycloak.get_api_password', mock_get_api_password) user_quotas_jh = get_user_quotas(jh_config, user_id=None) assert user_quotas_jh.get("quota-ws-maxmem") == 8.0 diff --git a/libraries/cloudharness-utils/cloudharness_utils/testing/api.py b/libraries/cloudharness-utils/cloudharness_utils/testing/api.py index 6506804bc..57032519e 100644 --- a/libraries/cloudharness-utils/cloudharness_utils/testing/api.py +++ b/libraries/cloudharness-utils/cloudharness_utils/testing/api.py @@ -22,7 +22,7 @@ def get_schemathesis_params(app_config: ApplicationHarnessConfig, app_domain: st for c in api_config.checks: params += ["-c", c] - return [*params, *api_config.run_params] + return [*params, *api_config.runParams] def get_urls_from_api_file(api_filename): diff --git a/libraries/cloudharness-utils/cloudharness_utils/testing/util.py b/libraries/cloudharness-utils/cloudharness_utils/testing/util.py index 7bb665584..7cbcf6593 100644 --- a/libraries/cloudharness-utils/cloudharness_utils/testing/util.py +++ b/libraries/cloudharness-utils/cloudharness_utils/testing/util.py @@ -22,8 +22,8 @@ def get_app_environment(app_config: ApplicationHarnessConfig, app_domain, use_lo e2e_config: E2ETestsConfig = test_config.e2e if not e2e_config.smoketest: my_env["SKIP_SMOKETEST"] = "true" - if e2e_config.ignore_console_errors: + if e2e_config.ignoreConsoleErrors: my_env["IGNORE_CONSOLE_ERRORS"] = "true" - if e2e_config.ignore_request_errors: + if e2e_config.ignoreRequestErrors: my_env["IGNORE_REQUEST_ERRORS"] = "true" return my_env diff --git a/libraries/cloudharness-utils/tox.ini b/libraries/cloudharness-utils/tox.ini index 3bed59ad0..925ab7e5f 100644 --- a/libraries/cloudharness-utils/tox.ini +++ b/libraries/cloudharness-utils/tox.ini @@ -1,18 +1,15 @@ [tox] envlist = py3{9,12} -skipsdist = False [pytest] addopts = --ignore-glob=**/application-templates/** [testenv] -deps = - ruamel.yaml - docker - -e {toxinidir}/../models +deps=-r{toxinidir}/test-requirements.txt -commands = - python -c "print('cloudharness-utils: No tests to run - utility library only')" - python -c "import cloudharness_utils; print('Import successful')" + +commands= + coverage run --source cloudharness_utilities -m pytest -v + coverage report -m diff --git a/libraries/models/.github/workflows/python.yml b/libraries/models/.github/workflows/python.yml deleted file mode 100644 index 38f653808..000000000 --- a/libraries/models/.github/workflows/python.yml +++ /dev/null @@ -1,38 +0,0 @@ -# NOTE: This file is auto generated by OpenAPI Generator. -# URL: https://openapi-generator.tech -# -# ref: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python - -name: cloudharness_model Python package - -on: [push, pull_request] - -jobs: - build: - - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] - - steps: - - uses: actions/checkout@v3 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install flake8 pytest - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - if [ -f test-requirements.txt ]; then pip install -r test-requirements.txt; fi - - name: Lint with flake8 - run: | - # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - - name: Test with pytest - run: | - pytest diff --git a/libraries/models/.gitlab-ci.yml b/libraries/models/.gitlab-ci.yml index 6cf2a74da..1bdad293e 100644 --- a/libraries/models/.gitlab-ci.yml +++ b/libraries/models/.gitlab-ci.yml @@ -1,31 +1,24 @@ -# NOTE: This file is auto generated by OpenAPI Generator. -# URL: https://openapi-generator.tech -# # ref: https://docs.gitlab.com/ee/ci/README.html -# ref: https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Python.gitlab-ci.yml stages: - test -.pytest: +.tests: stage: test script: - pip install -r requirements.txt - pip install -r test-requirements.txt - pytest --cov=cloudharness_model -pytest-3.7: - extends: .pytest +test-3.6: + extends: .tests + image: python:3.6-alpine +test-3.7: + extends: .tests image: python:3.7-alpine -pytest-3.8: - extends: .pytest +test-3.8: + extends: .tests image: python:3.8-alpine -pytest-3.9: - extends: .pytest +test-3.9: + extends: .tests image: python:3.9-alpine -pytest-3.10: - extends: .pytest - image: python:3.10-alpine -pytest-3.11: - extends: .pytest - image: python:3.11-alpine diff --git a/libraries/models/.openapi-generator-ignore b/libraries/models/.openapi-generator-ignore index a177bbf84..1be9a0d1d 100644 --- a/libraries/models/.openapi-generator-ignore +++ b/libraries/models/.openapi-generator-ignore @@ -36,8 +36,7 @@ setup.py encoder.py *.sh */util.py -*/models/base_model.py -*/models/user_group.py # keep user_group model as there it is generated with an internal reference in it +*/models/base_model_.py requirements.txt */encoder.py -*/model_utils.py +*/model_utils.py \ No newline at end of file diff --git a/libraries/models/.travis.yml b/libraries/models/.travis.yml index 3bef7fa58..ad71ee5ca 100644 --- a/libraries/models/.travis.yml +++ b/libraries/models/.travis.yml @@ -1,17 +1,14 @@ # ref: https://docs.travis-ci.com/user/languages/python language: python python: + - "3.2" + - "3.3" + - "3.4" + - "3.5" + - "3.6" - "3.7" - "3.8" - - "3.9" - - "3.10" - - "3.11" - # uncomment the following if needed - #- "3.11-dev" # 3.11 development branch - #- "nightly" # nightly build # command to install dependencies -install: - - "pip install -r requirements.txt" - - "pip install -r test-requirements.txt" +install: "pip install -r requirements.txt" # command to run tests -script: pytest --cov=cloudharness_model +script: nosetests diff --git a/libraries/models/README.md b/libraries/models/README.md index 4cab56aa4..4d60f9b94 100644 --- a/libraries/models/README.md +++ b/libraries/models/README.md @@ -1,121 +1,49 @@ -# cloudharness-model -No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +# OpenAPI generated server -This Python package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: +## Overview +This server was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the +[OpenAPI-Spec](https://openapis.org) from a remote server, you can easily generate a server stub. This +is an example of building a OpenAPI-enabled Flask server. -- API version: 1.0.0 -- Package version: 1.0.0 -- Generator version: 7.7.0 -- Build package: org.openapitools.codegen.languages.PythonClientCodegen +This example uses the [Connexion](https://github.com/zalando/connexion) library on top of Flask. -## Requirements. +## Requirements +Python 3.5.2+ -Python 3.7+ +## Usage +To run the server, please execute the following from the root directory: -## Installation & Usage -### pip install - -If the python package is hosted on a repository, you can install directly using: - -```sh -pip install git+https://github.com/GIT_USER_ID/GIT_REPO_ID.git ``` -(you may need to run `pip` with root permission: `sudo pip install git+https://github.com/GIT_USER_ID/GIT_REPO_ID.git`) - -Then import the package: -```python -import cloudharness_model +pip3 install -r requirements.txt +python3 -m cloudharness_model ``` -### Setuptools +and open your browser to here: -Install via [Setuptools](http://pypi.python.org/pypi/setuptools). - -```sh -python setup.py install --user ``` -(or `sudo python setup.py install` to install the package for all users) - -Then import the package: -```python -import cloudharness_model +http://localhost:8080/ui/ ``` -### Tests - -Execute `pytest` to run the tests. - -## Getting Started - -Please follow the [installation procedure](#installation--usage) and then run the following: - -```python - -import cloudharness_model -from cloudharness_model.rest import ApiException -from pprint import pprint +Your OpenAPI definition lives here: +``` +http://localhost:8080/openapi.json ``` -## Documentation for API Endpoints - -All URIs are relative to *http://localhost* - -Class | Method | HTTP request | Description ------------- | ------------- | ------------- | ------------- - - -## Documentation For Models - - - [ApiTestsConfig](docs/ApiTestsConfig.md) - - [ApplicationAccountsConfig](docs/ApplicationAccountsConfig.md) - - [ApplicationConfig](docs/ApplicationConfig.md) - - [ApplicationDependenciesConfig](docs/ApplicationDependenciesConfig.md) - - [ApplicationHarnessConfig](docs/ApplicationHarnessConfig.md) - - [ApplicationProbe](docs/ApplicationProbe.md) - - [ApplicationTestConfig](docs/ApplicationTestConfig.md) - - [ApplicationUser](docs/ApplicationUser.md) - - [AutoArtifactSpec](docs/AutoArtifactSpec.md) - - [BackupConfig](docs/BackupConfig.md) - - [CDCEvent](docs/CDCEvent.md) - - [CDCEventMeta](docs/CDCEventMeta.md) - - [CpuMemoryConfig](docs/CpuMemoryConfig.md) - - [DatabaseDeploymentConfig](docs/DatabaseDeploymentConfig.md) - - [DeploymentAutoArtifactConfig](docs/DeploymentAutoArtifactConfig.md) - - [DeploymentResourcesConf](docs/DeploymentResourcesConf.md) - - [DeploymentVolumeSpec](docs/DeploymentVolumeSpec.md) - - [DockerfileConfig](docs/DockerfileConfig.md) - - [E2ETestsConfig](docs/E2ETestsConfig.md) - - [FileResourcesConfig](docs/FileResourcesConfig.md) - - [GatekeeperConf](docs/GatekeeperConf.md) - - [GitDependencyConfig](docs/GitDependencyConfig.md) - - [HarnessMainConfig](docs/HarnessMainConfig.md) - - [IngressConfig](docs/IngressConfig.md) - - [IngressConfigAllOfLetsencrypt](docs/IngressConfigAllOfLetsencrypt.md) - - [JupyterHubConfig](docs/JupyterHubConfig.md) - - [NameValue](docs/NameValue.md) - - [NamedObject](docs/NamedObject.md) - - [Organization](docs/Organization.md) - - [ProxyConf](docs/ProxyConf.md) - - [ProxyPayloadConf](docs/ProxyPayloadConf.md) - - [ProxyTimeoutConf](docs/ProxyTimeoutConf.md) - - [RegistryConfig](docs/RegistryConfig.md) - - [ServiceAutoArtifactConfig](docs/ServiceAutoArtifactConfig.md) - - [UnitTestsConfig](docs/UnitTestsConfig.md) - - [UriRoleMappingConfig](docs/UriRoleMappingConfig.md) - - [User](docs/User.md) - - [UserCredential](docs/UserCredential.md) - - [UserGroup](docs/UserGroup.md) - - [UserRole](docs/UserRole.md) - - - -## Documentation For Authorization - -Endpoints do not require authorization. - +To launch the integration tests, use tox: +``` +sudo pip install tox +tox +``` -## Author +## Running with Docker +To run the server on a Docker container, please execute the following from the root directory: +```bash +# building the image +docker build -t cloudharness_model . +# starting up a container +docker run -p 8080:8080 cloudharness_model +``` \ No newline at end of file diff --git a/libraries/models/api/openapi.yaml b/libraries/models/api/openapi.yaml index a378751c1..a3b9387ef 100644 --- a/libraries/models/api/openapi.yaml +++ b/libraries/models/api/openapi.yaml @@ -6,7 +6,8 @@ components: schemas: AutoArtifactSpec: description: '' - required: [] + required: + - auto type: object properties: auto: @@ -15,6 +16,21 @@ components: name: description: '' type: string + UriRoleMappingConfig: + description: 'Defines the application Gatekeeper configuration, if enabled (i.e. `secured: true`.' + required: + - roles + - uri + type: object + properties: + uri: + $ref: '#/components/schemas/PathSpecifier' + description: Path to secure + roles: + description: Roles allowed to access the present uri + type: array + items: + type: string ServiceAutoArtifactConfig: description: '' type: object @@ -67,6 +83,16 @@ components: limits: $ref: '#/components/schemas/CpuMemoryConfig' description: '' + CpuMemoryConfig: + description: '' + type: object + properties: + cpu: + description: '' + type: string + memory: + description: '' + type: string FileResourcesConfig: description: '' required: @@ -157,6 +183,60 @@ components: value: description: '' type: string + IngressConfig: + description: '' + type: object + allOf: + - + type: object + properties: + ssl_redirect: + description: '' + type: boolean + letsencrypt: + description: '' + type: object + properties: + email: + type: string + - + $ref: '#/components/schemas/AutoArtifactSpec' + BackupConfig: + description: '' + required: + - dir + - resources + type: object + properties: + active: + description: '' + type: boolean + keep_days: + description: '' + type: integer + keep_weeks: + description: '' + type: integer + keep_months: + description: '' + type: integer + schedule: + description: Cron expression + pattern: >- + /(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every + (\d+(ns|us|µs|ms|s|m|h))+)|((((\d+,)+\d+|(\d+(\/|-)\d+)|\d+|\*) ?){5,7})/ + type: string + suffix: + description: The file suffix added to backup files + volumesize: + description: The volume size for backups (all backups share the same volume) + type: string + dir: + $ref: '#/components/schemas/Filename' + description: 'Target directory of backups, the mount point of the persistent volume.' + resources: + $ref: '#/components/schemas/DeploymentResourcesConf' + description: '' UserGroup: type: object properties: @@ -260,16 +340,6 @@ components: username: type: string additionalProperties: {} - userGroups: - description: '' - type: array - items: - $ref: '#/components/schemas/UserGroup' - organizations: - description: '' - type: array - items: - $ref: '#/components/schemas/Organization' Filename: description: '' pattern: '^[^<>:;,?*|]+$' @@ -278,6 +348,38 @@ components: description: '' pattern: '^[^<>:;,?|]+$' type: string + CDCEvent: + description: |- + A message sent to the orchestration queue. + Applications can listen to these events to react to data change events happening + on other applications. + required: + - message_type + - operation + - uid + - meta + type: object + properties: + operation: + description: the operation on the object e.g. create / update / delete + enum: + - create + - update + - delete + - other + type: string + uid: + description: the unique identifier attribute of the object + type: string + message_type: + description: the type of the message (relates to the object type) e.g. jobs + type: string + resource: + $ref: '#/components/schemas/FreeObject' + description: The target object + meta: + $ref: '#/components/schemas/CDCEventMeta' + description: '' CDCEventMeta: description: '' required: @@ -366,6 +468,7 @@ components: description: '' type: string password: + format: password description: '' type: string clientRoles: @@ -470,6 +573,71 @@ components: items: type: string example: '["not_a_server_error", "status_code_conformance"]' + DeploymentAutoArtifactConfig: + description: '' + type: object + allOf: + - + type: object + properties: + port: + description: Deployment port + type: string + replicas: + description: Number of replicas + type: integer + image: + description: >- + Image name to use in the deployment. Leave it blank to set from the + application's + + Docker file + pattern: '(?:[a-z]+/)?([a-z]+)(?::[0-9]+)?' + type: string + resources: + $ref: '#/components/schemas/DeploymentResourcesConf' + description: Deployment resources + volume: + $ref: '#/components/schemas/DeploymentVolumeSpec' + description: Volume specification + resources: + description: Deployment resources + type: string + test: + description: ssaa + type: string + - + $ref: '#/components/schemas/AutoArtifactSpec' + DeploymentVolumeSpec: + description: |- + Defines a volume attached to the deployment. + Automatically created the volume claim and mounts. + type: object + allOf: + - + required: + - mountpath + type: object + properties: + mountpath: + description: The mount path for the volume + type: string + size: + description: |- + The volume size. + + E.g. 5Gi + usenfs: + description: Set to `true` to use the nfs on the created volume and mount as ReadWriteMany. + type: boolean + - + $ref: '#/components/schemas/AutoArtifactSpec' + example: + auto: true + mountpath: /usr/src/app/persistent + name: my-files + size: 5Gi + usenfs: true SimpleMap: description: '' type: object @@ -500,6 +668,50 @@ components: url: 'https://github.com/MetaCell/nwb-explorer.git' branch_tag: master path: /git + DatabaseDeploymentConfig: + description: '' + type: object + allOf: + - + type: object + properties: + type: + description: |- + Define the database type. + + One of (mongo, postgres, neo4j, sqlite3) + pattern: ^(mongo|postgres|neo4j|sqlite3)$ + type: string + example: '"neo4j"' + size: + description: Specify database disk size + type: string + example: 1Gi + user: + description: database username + type: string + pass: + format: password + description: Database password + type: string + image_ref: + description: Used for referencing images from the build + type: string + example: 'image_ref: myownpgimage' + mongo: + $ref: '#/components/schemas/FreeObject' + description: Mongo db specific configuration + postgres: + $ref: '#/components/schemas/FreeObject' + description: Postgres database specific configuration + neo4j: + description: Neo4j database specific configuration + resources: + $ref: '#/components/schemas/DeploymentResourcesConf' + description: Database deployment resources + - + $ref: '#/components/schemas/AutoArtifactSpec' + additionalAttributes: true DockerfileConfig: description: Configuration for a dockerfile type: object @@ -513,7 +725,7 @@ components: The use of this feature is to aid in development (e.g. not running tests on every local build) and not for setting environment variables in different environments; caution should be taken when using this feature as it can lead to inconsistent - behaviour across environments. + behaviour across environments. HarnessMainConfig: description: '' required: @@ -558,10 +770,8 @@ components: items: $ref: '#/components/schemas/NameValue' privenv: + $ref: '#/components/schemas/NameValue' description: Private environmental variables added to all pods - type: array - items: - $ref: '#/components/schemas/NameValue' backup: $ref: '#/components/schemas/BackupConfig' description: '' @@ -574,331 +784,7 @@ components: build_hash: description: '' type: string - ingress: - $ref: '#/components/schemas/IngressConfig' - description: '' additionalProperties: true - Organization: - description: '' - type: object - allOf: - - - type: object - properties: - domains: - description: '' - type: array - items: - $ref: '#/components/schemas/NamedObject' - alias: - description: '' - type: string - enabled: - description: '' - type: boolean - id: - description: '' - type: string - - - $ref: '#/components/schemas/NamedObject' - DatabaseDeploymentConfig: - description: '' - type: object - allOf: - - - type: object - properties: - type: - description: |- - Define the database type. - - One of (mongo, postgres, neo4j, sqlite3) - pattern: ^(mongo|postgres|neo4j|sqlite3)$ - type: string - example: '"neo4j"' - size: - description: Specify database disk size - type: string - example: 1Gi - user: - description: database username - type: string - pass: - description: Database password - type: string - image_ref: - description: Used for referencing images from the build - type: string - example: 'image_ref: myownpgimage' - mongo: - $ref: '#/components/schemas/FreeObject' - description: Mongo db specific configuration - postgres: - $ref: '#/components/schemas/FreeObject' - description: Postgres database specific configuration - neo4j: - description: Neo4j database specific configuration - resources: - $ref: '#/components/schemas/DeploymentResourcesConf' - description: Database deployment resources - - - $ref: '#/components/schemas/AutoArtifactSpec' - additionalProperties: true - UriRoleMappingConfig: - description: 'Defines the application Gatekeeper configuration, if enabled (i.e. `secured: true`.' - required: - - uri - type: object - properties: - uri: - $ref: '#/components/schemas/PathSpecifier' - description: Path to secure - roles: - description: Roles allowed to access the present uri - type: array - items: - type: string - white-listed: - description: '' - type: boolean - additionalProperties: true - BackupConfig: - description: '' - required: - - dir - - resources - type: object - properties: - active: - description: '' - type: boolean - keep_days: - description: '' - keep_weeks: - description: '' - keep_months: - description: '' - schedule: - description: Cron expression - type: string - suffix: - description: The file suffix added to backup files - type: string - volumesize: - description: The volume size for backups (all backups share the same volume) - type: string - dir: - $ref: '#/components/schemas/Filename' - description: 'Target directory of backups, the mount point of the persistent volume.' - resources: - $ref: '#/components/schemas/DeploymentResourcesConf' - description: '' - CpuMemoryConfig: - description: '' - type: object - properties: - cpu: - description: '' - memory: - description: '' - DeploymentAutoArtifactConfig: - description: '' - type: object - allOf: - - - type: object - properties: - port: - description: Deployment port - replicas: - description: Number of replicas - type: integer - image: - description: >- - Image name to use in the deployment. Leave it blank to set from the - application's - - Docker file - pattern: '(?:[a-z]+/)?([a-z]+)(?::[0-9]+)?' - type: string - resources: - $ref: '#/components/schemas/DeploymentResourcesConf' - description: Deployment resources - volume: - $ref: '#/components/schemas/DeploymentVolumeSpec' - description: Volume specification - - - $ref: '#/components/schemas/AutoArtifactSpec' - DeploymentVolumeSpec: - description: |- - Defines a volume attached to the deployment. - Automatically created the volume claim and mounts. - type: object - allOf: - - - required: - - mountpath - type: object - properties: - mountpath: - description: The mount path for the volume - type: string - size: - description: |- - The volume size. - - E.g. 5Gi - usenfs: - description: Set to `true` to use the nfs on the created volume and mount as ReadWriteMany. - type: boolean - - - $ref: '#/components/schemas/AutoArtifactSpec' - example: - auto: true - mountpath: /usr/src/app/persistent - name: my-files - size: 5Gi - usenfs: true - CDCEvent: - description: |- - A message sent to the orchestration queue. - Applications can listen to these events to react to data change events happening - on other applications. - required: - - message_type - - operation - - uid - - meta - type: object - properties: - operation: - description: the operation on the object e.g. create / update / delete - enum: - - create - - update - - delete - - other - type: string - uid: - description: the unique identifier attribute of the object - message_type: - description: the type of the message (relates to the object type) e.g. jobs - type: string - resource: - $ref: '#/components/schemas/FreeObject' - description: The target object - meta: - $ref: '#/components/schemas/CDCEventMeta' - description: '' - ProxyConf: - title: Root Type for ProxyConf - description: '' - type: object - properties: - forwardedHeaders: - type: boolean - payload: - $ref: '#/components/schemas/ProxyPayloadConf' - properties: - max: - format: int32 - type: integer - timeout: - $ref: '#/components/schemas/ProxyTimeoutConf' - properties: - keepalive: - format: int32 - type: integer - read: - format: int32 - type: integer - send: - format: int32 - type: integer - gatekeeper: - $ref: '#/components/schemas/GatekeeperConf' - description: '' - example: - forwardedHeaders: true - payload: - max: 250 - timeout: - keepalive: 60 - read: 60 - send: 60 - ProxyPayloadConf: - title: Root Type for ProxyPayloadConf - description: '' - type: object - properties: - max: - format: int32 - type: integer - example: - max: 250 - ProxyTimeoutConf: - title: Root Type for ProxyTimeoutConf - description: '' - type: object - properties: - keepalive: - format: int32 - type: integer - read: - format: int32 - type: integer - send: - format: int32 - type: integer - example: - keepalive: 60 - read: 60 - send: 60 - NamedObject: - title: Root Type for NamedObject - description: '' - type: object - properties: - name: - type: string - additionalProperties: true - example: - name: a name - IngressConfig: - description: '' - type: object - allOf: - - - type: object - properties: - ssl_redirect: - description: '' - type: boolean - letsencrypt: - description: '' - type: object - properties: - email: - type: string - enabled: - description: '' - type: boolean - - - $ref: '#/components/schemas/AutoArtifactSpec' - additionalProperties: true - GatekeeperConf: - title: Root Type for GatekeeperConf - description: '' - type: object - properties: - image: - type: string - replicas: - format: int32 - type: integer - example: - image: 'quay.io/gogatekeeper/gatekeeper:2.14.3' - replicas: 5 ApplicationHarnessConfig: description: |- Define helm variables that allow CloudHarness to enable and configure your @@ -930,6 +816,7 @@ components: --include (-i) is used. Specify application names in the list. secured: description: 'When true, the application is shielded with a getekeeper' + type: boolean uri_role_mapping: description: 'Map uri/roles to secure with the Gatekeeper (if `secured: true`)' type: array @@ -961,7 +848,7 @@ components: ``` type: array items: - $ref: '#/components/schemas/NamedObject' + type: string database: $ref: '#/components/schemas/DatabaseDeploymentConfig' description: '' @@ -1014,10 +901,4 @@ components: dockerfile: $ref: '#/components/schemas/DockerfileConfig' description: Configuration for the dockerfile used to build the app - sentry: - description: '' - type: boolean - proxy: - $ref: '#/components/schemas/ProxyConf' - description: '' additionalProperties: true diff --git a/libraries/models/cloudharness_model/__init__.py b/libraries/models/cloudharness_model/__init__.py index 865f55b76..cf4f59d6c 100644 --- a/libraries/models/cloudharness_model/__init__.py +++ b/libraries/models/cloudharness_model/__init__.py @@ -1,2 +1 @@ -# Import the CloudHarnessBaseModel for use by generated models from .models import * \ No newline at end of file diff --git a/libraries/models/cloudharness_model/api_client.py b/libraries/models/cloudharness_model/api_client.py index ad7921436..0093392ea 100644 --- a/libraries/models/cloudharness_model/api_client.py +++ b/libraries/models/cloudharness_model/api_client.py @@ -1,47 +1,45 @@ -# coding: utf-8 - """ cloudharness - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) # noqa: E501 The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 + Generated by: https://openapi-generator.tech +""" -import datetime -from dateutil.parser import parse -from enum import Enum import json +import atexit import mimetypes +from multiprocessing.pool import ThreadPool +import io import os import re -import tempfile - +import typing from urllib.parse import quote -from typing import Tuple, Optional, List, Dict, Union -from pydantic import SecretStr +from urllib3.fields import RequestField + -from cloudharness_model.configuration import Configuration -from cloudharness_model.api_response import ApiResponse, T as ApiResponseT -import cloudharness_model.models from cloudharness_model import rest -from cloudharness_model.exceptions import ( - ApiValueError, - ApiException, - BadRequestException, - UnauthorizedException, - ForbiddenException, - NotFoundException, - ServiceException +from cloudharness_model.configuration import Configuration +from cloudharness_model.exceptions import ApiTypeError, ApiValueError, ApiException +from cloudharness_model.model_utils import ( + ModelNormal, + ModelSimple, + ModelComposed, + check_allowed_values, + check_validations, + date, + datetime, + deserialize_file, + file_type, + model_to_dict, + none_type, + validate_and_convert_types ) -RequestSerialized = Tuple[str, str, Dict[str, str], Optional[str], List[str]] -class ApiClient: +class ApiClient(object): """Generic API client for OpenAPI client library builds. OpenAPI generic API client. This client handles the client- @@ -49,38 +47,28 @@ class ApiClient: the methods and models for each application are generated from the OpenAPI templates. + NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + Do not edit the class manually. + :param configuration: .Configuration object for this client :param header_name: a header to pass when making calls to the API. :param header_value: a header value to pass when making calls to the API. :param cookie: a cookie to include in the header when making calls to the API + :param pool_threads: The number of threads to use for async requests + to the API. More threads means more concurrent API requests. """ - PRIMITIVE_TYPES = (float, bool, bytes, str, int) - NATIVE_TYPES_MAPPING = { - 'int': int, - 'long': int, # TODO remove as only py3 is supported? - 'float': float, - 'str': str, - 'bool': bool, - 'date': datetime.date, - 'datetime': datetime.datetime, - 'object': object, - } _pool = None - def __init__( - self, - configuration=None, - header_name=None, - header_value=None, - cookie=None - ) -> None: - # use default configuration if none is provided + def __init__(self, configuration=None, header_name=None, header_value=None, + cookie=None, pool_threads=1): if configuration is None: - configuration = Configuration.get_default() + configuration = Configuration.get_default_copy() self.configuration = configuration + self.pool_threads = pool_threads self.rest_client = rest.RESTClientObject(configuration) self.default_headers = {} @@ -89,13 +77,30 @@ def __init__( self.cookie = cookie # Set default User-Agent. self.user_agent = 'OpenAPI-Generator/1.0.0/python' - self.client_side_validation = configuration.client_side_validation def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): - pass + self.close() + + def close(self): + if self._pool: + self._pool.close() + self._pool.join() + self._pool = None + if hasattr(atexit, 'unregister'): + atexit.unregister(self.close) + + @property + def pool(self): + """Create thread pool on first request + avoids instantiating unused threadpool for blocking clients. + """ + if self._pool is None: + atexit.register(self.close) + self._pool = ThreadPool(self.pool_threads) + return self._pool @property def user_agent(self): @@ -109,69 +114,26 @@ def user_agent(self, value): def set_default_header(self, header_name, header_value): self.default_headers[header_name] = header_value - - _default = None - - @classmethod - def get_default(cls): - """Return new instance of ApiClient. - - This method returns newly created, based on default constructor, - object of ApiClient class or returns a copy of default - ApiClient. - - :return: The ApiClient object. - """ - if cls._default is None: - cls._default = ApiClient() - return cls._default - - @classmethod - def set_default(cls, default): - """Set default instance of ApiClient. - - It stores default ApiClient. - - :param default: object of ApiClient. - """ - cls._default = default - - def param_serialize( + def __call_api( self, - method, - resource_path, - path_params=None, - query_params=None, - header_params=None, - body=None, - post_params=None, - files=None, auth_settings=None, - collection_formats=None, - _host=None, - _request_auth=None - ) -> RequestSerialized: - - """Builds the HTTP request params needed by the request. - :param method: Method to call. - :param resource_path: Path to method endpoint. - :param path_params: Path parameters in the url. - :param query_params: Query parameters in the url. - :param header_params: Header parameters to be - placed in the request header. - :param body: Request body. - :param post_params dict: Request post form parameters, - for `application/x-www-form-urlencoded`, `multipart/form-data`. - :param auth_settings list: Auth Settings names for the request. - :param files dict: key -> filename, value -> filepath, - for `multipart/form-data`. - :param collection_formats: dict of collection formats for path, query, - header, and post parameters. - :param _request_auth: set to override the auth_settings for an a single - request; this effectively ignores the authentication - in the spec for a single request. - :return: tuple of form (path, http_method, query_params, header_params, - body, post_params, files) - """ + resource_path: str, + method: str, + path_params: typing.Optional[typing.Dict[str, typing.Any]] = None, + query_params: typing.Optional[typing.List[typing.Tuple[str, typing.Any]]] = None, + header_params: typing.Optional[typing.Dict[str, typing.Any]] = None, + body: typing.Optional[typing.Any] = None, + post_params: typing.Optional[typing.List[typing.Tuple[str, typing.Any]]] = None, + files: typing.Optional[typing.Dict[str, typing.List[io.IOBase]]] = None, + response_type: typing.Optional[typing.Tuple[typing.Any]] = None, + auth_settings: typing.Optional[typing.List[str]] = None, + _return_http_data_only: typing.Optional[bool] = None, + collection_formats: typing.Optional[typing.Dict[str, str]] = None, + _preload_content: bool = True, + _request_timeout: typing.Optional[typing.Union[int, float, typing.Tuple]] = None, + _host: typing.Optional[str] = None, + _check_type: typing.Optional[bool] = None, + _content_type: typing.Optional[str] = None + ): config = self.configuration @@ -182,17 +144,14 @@ def param_serialize( header_params['Cookie'] = self.cookie if header_params: header_params = self.sanitize_for_serialization(header_params) - header_params = dict( - self.parameters_to_tuples(header_params,collection_formats) - ) + header_params = dict(self.parameters_to_tuples(header_params, + collection_formats)) # path parameters if path_params: path_params = self.sanitize_for_serialization(path_params) - path_params = self.parameters_to_tuples( - path_params, - collection_formats - ) + path_params = self.parameters_to_tuples(path_params, + collection_formats) for k, v in path_params: # specified safe chars, encode everything resource_path = resource_path.replace( @@ -200,264 +159,334 @@ def param_serialize( quote(str(v), safe=config.safe_chars_for_path_param) ) + # query parameters + if query_params: + query_params = self.sanitize_for_serialization(query_params) + query_params = self.parameters_to_tuples(query_params, + collection_formats) + # post parameters if post_params or files: post_params = post_params if post_params else [] post_params = self.sanitize_for_serialization(post_params) - post_params = self.parameters_to_tuples( - post_params, - collection_formats - ) - if files: - post_params.extend(self.files_parameters(files)) - - # auth setting - self.update_params_for_auth( - header_params, - query_params, - auth_settings, - resource_path, - method, - body, - request_auth=_request_auth - ) + post_params = self.parameters_to_tuples(post_params, + collection_formats) + post_params.extend(self.files_parameters(files)) + if header_params['Content-Type'].startswith("multipart"): + post_params = self.parameters_to_multipart(post_params, + (dict) ) # body if body: body = self.sanitize_for_serialization(body) + # auth setting + self.update_params_for_auth(header_params, query_params, + auth_settings, resource_path, method, body) + # request url - if _host is None or self.configuration.ignore_operation_servers: + if _host is None: url = self.configuration.host + resource_path else: # use server/host defined in path or operation instead url = _host + resource_path - # query parameters - if query_params: - query_params = self.sanitize_for_serialization(query_params) - url_query = self.parameters_to_url_query( - query_params, - collection_formats - ) - url += "?" + url_query - - return method, url, header_params, body, post_params - - - def call_api( - self, - method, - url, - header_params=None, - body=None, - post_params=None, - _request_timeout=None - ) -> rest.RESTResponse: - """Makes the HTTP request (synchronous) - :param method: Method to call. - :param url: Path to method endpoint. - :param header_params: Header parameters to be - placed in the request header. - :param body: Request body. - :param post_params dict: Request post form parameters, - for `application/x-www-form-urlencoded`, `multipart/form-data`. - :param _request_timeout: timeout setting for this request. - :return: RESTResponse - """ - try: # perform request and return response - response_data = self.rest_client.request( - method, url, - headers=header_params, - body=body, post_params=post_params, - _request_timeout=_request_timeout - ) - + response_data = self.request( + method, url, query_params=query_params, headers=header_params, + post_params=post_params, body=body, + _preload_content=_preload_content, + _request_timeout=_request_timeout) except ApiException as e: + e.body = e.body.decode('utf-8') raise e - return response_data + self.last_response = response_data - def response_deserialize( - self, - response_data: rest.RESTResponse, - response_types_map: Optional[Dict[str, ApiResponseT]]=None - ) -> ApiResponse[ApiResponseT]: - """Deserializes response into an object. - :param response_data: RESTResponse object to be deserialized. - :param response_types_map: dict of response types. - :return: ApiResponse - """ + return_data = response_data - msg = "RESTResponse.read() must be called before passing it to response_deserialize()" - assert response_data.data is not None, msg - - response_type = response_types_map.get(str(response_data.status), None) - if not response_type and isinstance(response_data.status, int) and 100 <= response_data.status <= 599: - # if not found, look for '1XX', '2XX', etc. - response_type = response_types_map.get(str(response_data.status)[0] + "XX", None) + if not _preload_content: + return (return_data) + return return_data # deserialize response data - response_text = None - return_data = None - try: - if response_type == "bytearray": - return_data = response_data.data - elif response_type == "file": - return_data = self.__deserialize_file(response_data) - elif response_type is not None: - match = None + if response_type: + if response_type != (file_type,): + encoding = "utf-8" content_type = response_data.getheader('content-type') if content_type is not None: - match = re.search(r"charset=([a-zA-Z\-\d]+)[\s;]?", content_type) - encoding = match.group(1) if match else "utf-8" - response_text = response_data.data.decode(encoding) - return_data = self.deserialize(response_text, response_type, content_type) - finally: - if not 200 <= response_data.status <= 299: - raise ApiException.from_response( - http_resp=response_data, - body=response_text, - data=return_data, - ) + match = re.search(r"charset=([a-zA-Z\-\d]+)[\s\;]?", content_type) + if match: + encoding = match.group(1) + response_data.data = response_data.data.decode(encoding) + + return_data = self.deserialize( + response_data, + response_type, + _check_type + ) + else: + return_data = None - return ApiResponse( - status_code = response_data.status, - data = return_data, - headers = response_data.getheaders(), - raw_data = response_data.data - ) + if _return_http_data_only: + return (return_data) + else: + return (return_data, response_data.status, + response_data.getheaders()) + + def parameters_to_multipart(self, params, collection_types): + """Get parameters as list of tuples, formatting as json if value is collection_types - def sanitize_for_serialization(self, obj): - """Builds a JSON POST object. + :param params: Parameters as list of two-tuples + :param dict collection_types: Parameter collection types + :return: Parameters as list of tuple or urllib3.fields.RequestField + """ + new_params = [] + if collection_types is None: + collection_types = (dict) + for k, v in params.items() if isinstance(params, dict) else params: # noqa: E501 + if isinstance(v, collection_types): # v is instance of collection_type, formatting as application/json + v = json.dumps(v, ensure_ascii=False).encode("utf-8") + field = RequestField(k, v) + field.make_multipart(content_type="application/json; charset=utf-8") + new_params.append(field) + else: + new_params.append((k, v)) + return new_params + @classmethod + def sanitize_for_serialization(cls, obj): + """Prepares data for transmission before it is sent with the rest client If obj is None, return None. - If obj is SecretStr, return obj.get_secret_value() If obj is str, int, long, float, bool, return directly. If obj is datetime.datetime, datetime.date convert to string in iso8601 format. If obj is list, sanitize each element in the list. If obj is dict, return the dict. If obj is OpenAPI model, return the properties dict. - + If obj is io.IOBase, return the bytes :param obj: The data to serialize. :return: The serialized form of data. """ - if obj is None: - return None - elif isinstance(obj, Enum): - return obj.value - elif isinstance(obj, SecretStr): - return obj.get_secret_value() - elif isinstance(obj, self.PRIMITIVE_TYPES): + if isinstance(obj, (ModelNormal, ModelComposed)): + return { + key: cls.sanitize_for_serialization(val) for key, val in model_to_dict(obj, serialize=True).items() + } + elif isinstance(obj, io.IOBase): + return cls.get_file_data_and_close_file(obj) + elif isinstance(obj, (str, int, float, none_type, bool)): return obj - elif isinstance(obj, list): - return [ - self.sanitize_for_serialization(sub_obj) for sub_obj in obj - ] - elif isinstance(obj, tuple): - return tuple( - self.sanitize_for_serialization(sub_obj) for sub_obj in obj - ) - elif isinstance(obj, (datetime.datetime, datetime.date)): + elif isinstance(obj, (datetime, date)): return obj.isoformat() - - elif isinstance(obj, dict): - obj_dict = obj - else: - # Convert model obj to dict except - # attributes `openapi_types`, `attribute_map` - # and attributes which value is not None. - # Convert attribute name to json key in - # model definition for request. - if hasattr(obj, 'to_dict') and callable(getattr(obj, 'to_dict')): - obj_dict = obj.to_dict() - else: - obj_dict = obj.__dict__ - - return { - key: self.sanitize_for_serialization(val) - for key, val in obj_dict.items() - } - - def deserialize(self, response_text: str, response_type: str, content_type: Optional[str]): + elif isinstance(obj, ModelSimple): + return cls.sanitize_for_serialization(obj.value) + elif isinstance(obj, (list, tuple)): + return [cls.sanitize_for_serialization(item) for item in obj] + if isinstance(obj, dict): + return {key: cls.sanitize_for_serialization(val) for key, val in obj.items()} + raise ApiValueError('Unable to prepare type {} for serialization'.format(obj.__class__.__name__)) + + def deserialize(self, response, response_type, _check_type): """Deserializes response into an object. :param response: RESTResponse object to be deserialized. - :param response_type: class literal for - deserialized object, or string of class name. - :param content_type: content type of response. + :param response_type: For the response, a tuple containing: + valid classes + a list containing valid classes (for list schemas) + a dict containing a tuple of valid classes as the value + Example values: + (str,) + (Pet,) + (float, none_type) + ([int, none_type],) + ({str: (bool, str, int, float, date, datetime, str, none_type)},) + :param _check_type: boolean, whether to check the types of the data + received from the server + :type _check_type: bool :return: deserialized object. """ + # handle file downloading + # save response body into a tmp file and return the instance + if response_type == (file_type,): + content_disposition = response.getheader("Content-Disposition") + return deserialize_file(response.data, self.configuration, + content_disposition=content_disposition) # fetch data from response object - if content_type is None: - try: - data = json.loads(response_text) - except ValueError: - data = response_text - elif content_type.startswith("application/json"): - if response_text == "": - data = "" - else: - data = json.loads(response_text) - elif content_type.startswith("text/plain"): - data = response_text - else: - raise ApiException( - status=0, - reason="Unsupported content type: {0}".format(content_type) - ) - - return self.__deserialize(data, response_type) - - def __deserialize(self, data, klass): - """Deserializes dict, list, str into an object. + try: + received_data = json.loads(response.data) + except ValueError: + received_data = response.data + + # store our data under the key of 'received_data' so users have some + # context if they are deserializing a string and the data type is wrong + deserialized_data = validate_and_convert_types( + received_data, + response_type, + ['received_data'], + True, + _check_type, + configuration=self.configuration + ) + return deserialized_data - :param data: dict, list or str. - :param klass: class literal, or string of class name. + def call_api( + self, + resource_path: str, + method: str, + path_params: typing.Optional[typing.Dict[str, typing.Any]] = None, + query_params: typing.Optional[typing.List[typing.Tuple[str, typing.Any]]] = None, + header_params: typing.Optional[typing.Dict[str, typing.Any]] = None, + body: typing.Optional[typing.Any] = None, + post_params: typing.Optional[typing.List[typing.Tuple[str, typing.Any]]] = None, + files: typing.Optional[typing.Dict[str, typing.List[io.IOBase]]] = None, + response_type: typing.Optional[typing.Tuple[typing.Any]] = None, + auth_settings: typing.Optional[typing.List[str]] = None, + async_req: typing.Optional[bool] = None, + _return_http_data_only: typing.Optional[bool] = None, + collection_formats: typing.Optional[typing.Dict[str, str]] = None, + _preload_content: bool = True, + _request_timeout: typing.Optional[typing.Union[int, float, typing.Tuple]] = None, + _host: typing.Optional[str] = None, + _check_type: typing.Optional[bool] = None + ): + """Makes the HTTP request (synchronous) and returns deserialized data. + + To make an async_req request, set the async_req parameter. - :return: object. + :param resource_path: Path to method endpoint. + :param method: Method to call. + :param path_params: Path parameters in the url. + :param query_params: Query parameters in the url. + :param header_params: Header parameters to be + placed in the request header. + :param body: Request body. + :param post_params dict: Request post form parameters, + for `application/x-www-form-urlencoded`, `multipart/form-data`. + :param auth_settings list: Auth Settings names for the request. + :param response_type: For the response, a tuple containing: + valid classes + a list containing valid classes (for list schemas) + a dict containing a tuple of valid classes as the value + Example values: + (str,) + (Pet,) + (float, none_type) + ([int, none_type],) + ({str: (bool, str, int, float, date, datetime, str, none_type)},) + :param files: key -> field name, value -> a list of open file + objects for `multipart/form-data`. + :type files: dict + :param async_req bool: execute request asynchronously + :type async_req: bool, optional + :param _return_http_data_only: response data without head status code + and headers + :type _return_http_data_only: bool, optional + :param collection_formats: dict of collection formats for path, query, + header, and post parameters. + :type collection_formats: dict, optional + :param _preload_content: if False, the urllib3.HTTPResponse object will + be returned without reading/decoding response + data. Default is True. + :type _preload_content: bool, optional + :param _request_timeout: timeout setting for this request. If one + number provided, it will be total request + timeout. It can also be a pair (tuple) of + (connection, read) timeouts. + :param _check_type: boolean describing if the data back from the server + should have its type checked. + :type _check_type: bool, optional + :return: + If async_req parameter is True, + the request will be called asynchronously. + The method will return the request thread. + If parameter async_req is False or missing, + then the method will return the response directly. """ - if data is None: - return None - - if isinstance(klass, str): - if klass.startswith('List['): - m = re.match(r'List\[(.*)]', klass) - assert m is not None, "Malformed List type definition" - sub_kls = m.group(1) - return [self.__deserialize(sub_data, sub_kls) - for sub_data in data] - - if klass.startswith('Dict['): - m = re.match(r'Dict\[([^,]*), (.*)]', klass) - assert m is not None, "Malformed Dict type definition" - sub_kls = m.group(2) - return {k: self.__deserialize(v, sub_kls) - for k, v in data.items()} - - # convert str to class - if klass in self.NATIVE_TYPES_MAPPING: - klass = self.NATIVE_TYPES_MAPPING[klass] - else: - klass = getattr(cloudharness_model.models, klass) - - if klass in self.PRIMITIVE_TYPES: - return self.__deserialize_primitive(data, klass) - elif klass == object: - return self.__deserialize_object(data) - elif klass == datetime.date: - return self.__deserialize_date(data) - elif klass == datetime.datetime: - return self.__deserialize_datetime(data) - elif issubclass(klass, Enum): - return self.__deserialize_enum(data, klass) + if not async_req: + return self.__call_api(resource_path, method, + path_params, query_params, header_params, + body, post_params, files, + response_type, auth_settings, + _return_http_data_only, collection_formats, + _preload_content, _request_timeout, _host, + _check_type) + + return self.pool.apply_async(self.__call_api, (resource_path, + method, path_params, + query_params, + header_params, body, + post_params, files, + response_type, + auth_settings, + _return_http_data_only, + collection_formats, + _preload_content, + _request_timeout, + _host, _check_type)) + + def request(self, method, url, query_params=None, headers=None, + post_params=None, body=None, _preload_content=True, + _request_timeout=None): + """Makes the HTTP request using RESTClient.""" + if method == "GET": + return self.rest_client.GET(url, + query_params=query_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + headers=headers) + elif method == "HEAD": + return self.rest_client.HEAD(url, + query_params=query_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + headers=headers) + elif method == "OPTIONS": + return self.rest_client.OPTIONS(url, + query_params=query_params, + headers=headers, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + elif method == "POST": + return self.rest_client.POST(url, + query_params=query_params, + headers=headers, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + elif method == "PUT": + return self.rest_client.PUT(url, + query_params=query_params, + headers=headers, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + elif method == "PATCH": + return self.rest_client.PATCH(url, + query_params=query_params, + headers=headers, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + elif method == "DELETE": + return self.rest_client.DELETE(url, + query_params=query_params, + headers=headers, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) else: - return self.__deserialize_model(data, klass) + raise ApiValueError( + "http method must be `GET`, `HEAD`, `OPTIONS`," + " `POST`, `PATCH`, `PUT` or `DELETE`." + ) def parameters_to_tuples(self, params, collection_formats): """Get parameters as list of tuples, formatting collections. @@ -466,10 +495,10 @@ def parameters_to_tuples(self, params, collection_formats): :param dict collection_formats: Parameter collection formats :return: Parameters as list of tuples, collections formatted """ - new_params: List[Tuple[str, str]] = [] + new_params = [] if collection_formats is None: collection_formats = {} - for k, v in params.items() if isinstance(params, dict) else params: + for k, v in params.items() if isinstance(params, dict) else params: # noqa: E501 if k in collection_formats: collection_format = collection_formats[k] if collection_format == 'multi': @@ -489,293 +518,343 @@ def parameters_to_tuples(self, params, collection_formats): new_params.append((k, v)) return new_params - def parameters_to_url_query(self, params, collection_formats): - """Get parameters as list of tuples, formatting collections. + @staticmethod + def get_file_data_and_close_file(file_instance: io.IOBase) -> bytes: + file_data = file_instance.read() + file_instance.close() + return file_data - :param params: Parameters as dict or list of two-tuples - :param dict collection_formats: Parameter collection formats - :return: URL query string (e.g. a=Hello%20World&b=123) - """ - new_params: List[Tuple[str, str]] = [] - if collection_formats is None: - collection_formats = {} - for k, v in params.items() if isinstance(params, dict) else params: - if isinstance(v, bool): - v = str(v).lower() - if isinstance(v, (int, float)): - v = str(v) - if isinstance(v, dict): - v = json.dumps(v) - - if k in collection_formats: - collection_format = collection_formats[k] - if collection_format == 'multi': - new_params.extend((k, str(value)) for value in v) - else: - if collection_format == 'ssv': - delimiter = ' ' - elif collection_format == 'tsv': - delimiter = '\t' - elif collection_format == 'pipes': - delimiter = '|' - else: # csv is the default - delimiter = ',' - new_params.append( - (k, delimiter.join(quote(str(value)) for value in v)) - ) - else: - new_params.append((k, quote(str(v)))) - - return "&".join(["=".join(map(str, item)) for item in new_params]) - - def files_parameters(self, files: Dict[str, Union[str, bytes]]): + def files_parameters(self, files: typing.Optional[typing.Dict[str, typing.List[io.IOBase]]] = None): """Builds form parameters. - :param files: File parameters. - :return: Form parameters with files. + :param files: None or a dict with key=param_name and + value is a list of open file objects + :return: List of tuples of form parameters with file data """ + if files is None: + return [] + params = [] - for k, v in files.items(): - if isinstance(v, str): - with open(v, 'rb') as f: - filename = os.path.basename(f.name) - filedata = f.read() - elif isinstance(v, bytes): - filename = k - filedata = v - else: - raise ValueError("Unsupported file value") - mimetype = ( - mimetypes.guess_type(filename)[0] - or 'application/octet-stream' - ) - params.append( - tuple([k, tuple([filename, filedata, mimetype])]) - ) + for param_name, file_instances in files.items(): + if file_instances is None: + # if the file field is nullable, skip None values + continue + for file_instance in file_instances: + if file_instance is None: + # if the file field is nullable, skip None values + continue + if file_instance.closed is True: + raise ApiValueError( + "Cannot read a closed file. The passed in file_type " + "for %s must be open." % param_name + ) + filename = os.path.basename(file_instance.name) + filedata = self.get_file_data_and_close_file(file_instance) + mimetype = (mimetypes.guess_type(filename)[0] or + 'application/octet-stream') + params.append( + tuple([param_name, tuple([filename, filedata, mimetype])])) + return params - def select_header_accept(self, accepts: List[str]) -> Optional[str]: + def select_header_accept(self, accepts): """Returns `Accept` based on an array of accepts provided. :param accepts: List of headers. :return: Accept (e.g. application/json). """ if not accepts: - return None + return - for accept in accepts: - if re.search('json', accept, re.IGNORECASE): - return accept + accepts = [x.lower() for x in accepts] - return accepts[0] + if 'application/json' in accepts: + return 'application/json' + else: + return ', '.join(accepts) - def select_header_content_type(self, content_types): + def select_header_content_type(self, content_types, method=None, body=None): """Returns `Content-Type` based on an array of content_types provided. :param content_types: List of content-types. + :param method: http method (e.g. POST, PATCH). + :param body: http body to send. :return: Content-Type (e.g. application/json). """ if not content_types: - return None + return 'application/json' - for content_type in content_types: - if re.search('json', content_type, re.IGNORECASE): - return content_type + content_types = [x.lower() for x in content_types] - return content_types[0] + if (method == 'PATCH' and + 'application/json-patch+json' in content_types and + isinstance(body, list)): + return 'application/json-patch+json' - def update_params_for_auth( - self, - headers, - queries, - auth_settings, - resource_path, - method, - body, - request_auth=None - ) -> None: + if 'application/json' in content_types or '*/*' in content_types: + return 'application/json' + else: + return content_types[0] + + def update_params_for_auth(self, headers, queries, auth_settings, + resource_path, method, body): """Updates header and query params based on authentication setting. :param headers: Header parameters dict to be updated. :param queries: Query parameters tuple list to be updated. :param auth_settings: Authentication setting identifiers list. - :resource_path: A string representation of the HTTP request resource path. - :method: A string representation of the HTTP request method. - :body: A object representing the body of the HTTP request. - The object type is the return value of sanitize_for_serialization(). - :param request_auth: if set, the provided settings will - override the token in the configuration. + :param resource_path: A string representation of the HTTP request resource path. + :param method: A string representation of the HTTP request method. + :param body: A object representing the body of the HTTP request. + The object type is the return value of _encoder.default(). """ if not auth_settings: return - if request_auth: - self._apply_auth_params( - headers, - queries, - resource_path, - method, - body, - request_auth - ) - else: - for auth in auth_settings: - auth_setting = self.configuration.auth_settings().get(auth) - if auth_setting: - self._apply_auth_params( - headers, - queries, - resource_path, - method, - body, - auth_setting + for auth in auth_settings: + auth_setting = self.configuration.auth_settings().get(auth) + if auth_setting: + if auth_setting['in'] == 'cookie': + headers['Cookie'] = auth_setting['value'] + elif auth_setting['in'] == 'header': + if auth_setting['type'] != 'http-signature': + headers[auth_setting['key']] = auth_setting['value'] + elif auth_setting['in'] == 'query': + queries.append((auth_setting['key'], auth_setting['value'])) + else: + raise ApiValueError( + 'Authentication token must be in `query` or `header`' ) - def _apply_auth_params( - self, - headers, - queries, - resource_path, - method, - body, - auth_setting - ) -> None: - """Updates the request parameters based on a single auth_setting - :param headers: Header parameters dict to be updated. - :param queries: Query parameters tuple list to be updated. - :resource_path: A string representation of the HTTP request resource path. - :method: A string representation of the HTTP request method. - :body: A object representing the body of the HTTP request. - The object type is the return value of sanitize_for_serialization(). - :param auth_setting: auth settings for the endpoint +class Endpoint(object): + def __init__(self, settings=None, params_map=None, root_map=None, + headers_map=None, api_client=None, callable=None): + """Creates an endpoint + + Args: + settings (dict): see below key value pairs + 'response_type' (tuple/None): response type + 'auth' (list): a list of auth type keys + 'endpoint_path' (str): the endpoint path + 'operation_id' (str): endpoint string identifier + 'http_method' (str): POST/PUT/PATCH/GET etc + 'servers' (list): list of str servers that this endpoint is at + params_map (dict): see below key value pairs + 'all' (list): list of str endpoint parameter names + 'required' (list): list of required parameter names + 'nullable' (list): list of nullable parameter names + 'enum' (list): list of parameters with enum values + 'validation' (list): list of parameters with validations + root_map + 'validations' (dict): the dict mapping endpoint parameter tuple + paths to their validation dictionaries + 'allowed_values' (dict): the dict mapping endpoint parameter + tuple paths to their allowed_values (enum) dictionaries + 'openapi_types' (dict): param_name to openapi type + 'attribute_map' (dict): param_name to camelCase name + 'location_map' (dict): param_name to 'body', 'file', 'form', + 'header', 'path', 'query' + collection_format_map (dict): param_name to `csv` etc. + headers_map (dict): see below key value pairs + 'accept' (list): list of Accept header strings + 'content_type' (list): list of Content-Type header strings + api_client (ApiClient) api client instance + callable (function): the function which is invoked when the + Endpoint is called """ - if auth_setting['in'] == 'cookie': - headers['Cookie'] = auth_setting['value'] - elif auth_setting['in'] == 'header': - if auth_setting['type'] != 'http-signature': - headers[auth_setting['key']] = auth_setting['value'] - elif auth_setting['in'] == 'query': - queries.append((auth_setting['key'], auth_setting['value'])) - else: - raise ApiValueError( - 'Authentication token must be in `query` or `header`' - ) - - def __deserialize_file(self, response): - """Deserializes body to file + self.settings = settings + self.params_map = params_map + self.params_map['all'].extend([ + 'async_req', + '_host_index', + '_preload_content', + '_request_timeout', + '_return_http_data_only', + '_check_input_type', + '_check_return_type', + '_content_type', + '_spec_property_naming' + ]) + self.params_map['nullable'].extend(['_request_timeout']) + self.validations = root_map['validations'] + self.allowed_values = root_map['allowed_values'] + self.openapi_types = root_map['openapi_types'] + extra_types = { + 'async_req': (bool,), + '_host_index': (none_type, int), + '_preload_content': (bool,), + '_request_timeout': (none_type, float, (float,), [float], int, (int,), [int]), + '_return_http_data_only': (bool,), + '_check_input_type': (bool,), + '_check_return_type': (bool,), + '_spec_property_naming': (bool,), + '_content_type': (none_type, str) + } + self.openapi_types.update(extra_types) + self.attribute_map = root_map['attribute_map'] + self.location_map = root_map['location_map'] + self.collection_format_map = root_map['collection_format_map'] + self.headers_map = headers_map + self.api_client = api_client + self.callable = callable + + def __validate_inputs(self, kwargs): + for param in self.params_map['enum']: + if param in kwargs: + check_allowed_values( + self.allowed_values, + (param,), + kwargs[param] + ) - Saves response body into a file in a temporary folder, - using the filename from the `Content-Disposition` header if provided. + for param in self.params_map['validation']: + if param in kwargs: + check_validations( + self.validations, + (param,), + kwargs[param], + configuration=self.api_client.configuration + ) - handle file downloading - save response body into a tmp file and return the instance + if kwargs['_check_input_type'] is False: + return - :param response: RESTResponse. - :return: file path. - """ - fd, path = tempfile.mkstemp(dir=self.configuration.temp_folder_path) - os.close(fd) - os.remove(path) - - content_disposition = response.getheader("Content-Disposition") - if content_disposition: - m = re.search( - r'filename=[\'"]?([^\'"\s]+)[\'"]?', - content_disposition + for key, value in kwargs.items(): + fixed_val = validate_and_convert_types( + value, + self.openapi_types[key], + [key], + kwargs['_spec_property_naming'], + kwargs['_check_input_type'], + configuration=self.api_client.configuration ) - assert m is not None, "Unexpected 'content-disposition' header value" - filename = m.group(1) - path = os.path.join(os.path.dirname(path), filename) - - with open(path, "wb") as f: - f.write(response.data) - - return path - - def __deserialize_primitive(self, data, klass): - """Deserializes string to primitive type. + kwargs[key] = fixed_val + + def __gather_params(self, kwargs): + params = { + 'body': None, + 'collection_format': {}, + 'file': {}, + 'form': [], + 'header': {}, + 'path': {}, + 'query': [] + } - :param data: str. - :param klass: class literal. + for param_name, param_value in kwargs.items(): + param_location = self.location_map.get(param_name) + if param_location is None: + continue + if param_location: + if param_location == 'body': + params['body'] = param_value + continue + base_name = self.attribute_map[param_name] + if (param_location == 'form' and + self.openapi_types[param_name] == (file_type,)): + params['file'][base_name] = [param_value] + elif (param_location == 'form' and + self.openapi_types[param_name] == ([file_type],)): + # param_value is already a list + params['file'][base_name] = param_value + elif param_location in {'form', 'query'}: + param_value_full = (base_name, param_value) + params[param_location].append(param_value_full) + if param_location not in {'form', 'query'}: + params[param_location][base_name] = param_value + collection_format = self.collection_format_map.get(param_name) + if collection_format: + params['collection_format'][base_name] = collection_format - :return: int, long, float, str, bool. - """ - try: - return klass(data) - except UnicodeEncodeError: - return str(data) - except TypeError: - return data + return params - def __deserialize_object(self, value): - """Return an original value. + def __call__(self, *args, **kwargs): + """ This method is invoked when endpoints are called + Example: - :return: object. """ - return value + return self.callable(self, *args, **kwargs) - def __deserialize_date(self, string): - """Deserializes string to date. + def call_with_http_info(self, **kwargs): - :param string: str. - :return: date. - """ try: - return parse(string).date() - except ImportError: - return string - except ValueError: - raise rest.ApiException( - status=0, - reason="Failed to parse `{0}` as date object".format(string) + index = self.api_client.configuration.server_operation_index.get( + self.settings['operation_id'], self.api_client.configuration.server_index + ) if kwargs['_host_index'] is None else kwargs['_host_index'] + server_variables = self.api_client.configuration.server_operation_variables.get( + self.settings['operation_id'], self.api_client.configuration.server_variables ) - - def __deserialize_datetime(self, string): - """Deserializes string to datetime. - - The string should be in iso8601 datetime format. - - :param string: str. - :return: datetime. - """ - try: - return parse(string) - except ImportError: - return string - except ValueError: - raise rest.ApiException( - status=0, - reason=( - "Failed to parse `{0}` as datetime object" - .format(string) - ) + _host = self.api_client.configuration.get_host_from_settings( + index, variables=server_variables, servers=self.settings['servers'] ) + except IndexError: + if self.settings['servers']: + raise ApiValueError( + "Invalid host index. Must be 0 <= index < %s" % + len(self.settings['servers']) + ) + _host = None + + for key, value in kwargs.items(): + if key not in self.params_map['all']: + raise ApiTypeError( + "Got an unexpected parameter '%s'" + " to method `%s`" % + (key, self.settings['operation_id']) + ) + # only throw this nullable ApiValueError if _check_input_type + # is False, if _check_input_type==True we catch this case + # in self.__validate_inputs + if (key not in self.params_map['nullable'] and value is None + and kwargs['_check_input_type'] is False): + raise ApiValueError( + "Value may not be None for non-nullable parameter `%s`" + " when calling `%s`" % + (key, self.settings['operation_id']) + ) - def __deserialize_enum(self, data, klass): - """Deserializes primitive type to enum. - - :param data: primitive type. - :param klass: class literal. - :return: enum value. - """ - try: - return klass(data) - except ValueError: - raise rest.ApiException( - status=0, - reason=( - "Failed to parse `{0}` as `{1}`" - .format(data, klass) + for key in self.params_map['required']: + if key not in kwargs.keys(): + raise ApiValueError( + "Missing the required parameter `%s` when calling " + "`%s`" % (key, self.settings['operation_id']) ) - ) - def __deserialize_model(self, data, klass): - """Deserializes list or dict to model. + self.__validate_inputs(kwargs) - :param data: dict, list. - :param klass: class literal. - :return: model object. - """ + params = self.__gather_params(kwargs) + + accept_headers_list = self.headers_map['accept'] + if accept_headers_list: + params['header']['Accept'] = self.api_client.select_header_accept( + accept_headers_list) - return klass.from_dict(data) + if kwargs.get('_content_type'): + params['header']['Content-Type'] = kwargs['_content_type'] + else: + content_type_headers_list = self.headers_map['content_type'] + if content_type_headers_list: + if params['body'] != "": + header_list = self.api_client.select_header_content_type( + content_type_headers_list, self.settings['http_method'], + params['body']) + params['header']['Content-Type'] = header_list + + return self.api_client.call_api( + self.settings['endpoint_path'], self.settings['http_method'], + params['path'], + params['query'], + params['header'], + body=params['body'], + post_params=params['form'], + files=params['file'], + response_type=self.settings['response_type'], + auth_settings=self.settings['auth'], + async_req=kwargs['async_req'], + _check_type=kwargs['_check_return_type'], + _return_http_data_only=kwargs['_return_http_data_only'], + _preload_content=kwargs['_preload_content'], + _request_timeout=kwargs['_request_timeout'], + _host=_host, + collection_formats=params['collection_format']) diff --git a/libraries/models/cloudharness_model/api_response.py b/libraries/models/cloudharness_model/api_response.py deleted file mode 100644 index 9bc7c11f6..000000000 --- a/libraries/models/cloudharness_model/api_response.py +++ /dev/null @@ -1,21 +0,0 @@ -"""API response object.""" - -from __future__ import annotations -from typing import Optional, Generic, Mapping, TypeVar -from pydantic import Field, StrictInt, StrictBytes, BaseModel - -T = TypeVar("T") - -class ApiResponse(BaseModel, Generic[T]): - """ - API response object - """ - - status_code: StrictInt = Field(description="HTTP status code") - headers: Optional[Mapping[str, str]] = Field(None, description="HTTP headers") - data: T = Field(description="Deserialized data given the data type") - raw_data: StrictBytes = Field(description="Raw data (HTTP response body)") - - model_config = { - "arbitrary_types_allowed": True - } diff --git a/libraries/models/cloudharness_model/base_model.py b/libraries/models/cloudharness_model/base_model.py deleted file mode 100644 index c228e33fa..000000000 --- a/libraries/models/cloudharness_model/base_model.py +++ /dev/null @@ -1,469 +0,0 @@ -# coding: utf-8 -""" -CloudHarness Base Model - -A custom Pydantic BaseModel subclass that provides enhanced functionality for -CloudHarness generated models, replacing the previous monkey patching approach. -""" - -from __future__ import annotations -import re -from typing import Any, Dict, List, Union -from pydantic import BaseModel - - -def _convert_to_attrdict(value): - """Helper function to convert nested structures to AttrDict""" - if isinstance(value, dict) and not isinstance(value, AttrDict): - return AttrDict(value) - elif isinstance(value, list): - # Convert list items that are dictionaries to AttrDict - return [_convert_to_attrdict(item) for item in value] - return value - - -def _get_value_from_additional_properties(obj, key): - """Helper function to get value from additional_properties without triggering __getattr__ recursion""" - # Use object.__getattribute__ to directly access additional_properties without triggering our override - try: - additional_properties = object.__getattribute__(obj, 'additional_properties') - if key in additional_properties: - value = additional_properties[key] - return _convert_to_attrdict(value) - except AttributeError: - # Object doesn't have additional_properties - pass - return None - - -def _try_camelcase_conversions(obj, key, check_attributes=False): - """Helper function to try camelCase/snake_case conversions""" - try: - import humps - except ImportError: - # Fallback to simple conversion if humps is not available - def decamelize(name): - s1 = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name) - return s1.lower() - - def camelize(name): - components = name.split('_') - return components[0] + ''.join(word.capitalize() for word in components[1:]) - - humps = type('MockHumps', (), {'decamelize': decamelize, 'camelize': camelize})() - - # Try snake_case version of the key - snake_case_key = humps.decamelize(key) - if snake_case_key != key: - # Check additional_properties - value = _get_value_from_additional_properties(obj, snake_case_key) - if value is not None: - return value - # Check attributes if requested - if check_attributes: - try: - return object.__getattribute__(obj, snake_case_key) - except AttributeError: - pass - - # Try camelCase version of the key - camel_case_key = humps.camelize(key) - if camel_case_key != key: - # Check additional_properties - value = _get_value_from_additional_properties(obj, camel_case_key) - if value is not None: - return value - # Check attributes if requested - if check_attributes: - try: - return object.__getattribute__(obj, camel_case_key) - except AttributeError: - pass - - return None - - -def _check_field_aliases(obj, key): - """Helper function to check if key is an alias for a field""" - # Check pydantic v2 - try: - model_fields = object.__getattribute__(obj, 'model_fields') - for field_name, field_info in model_fields.items(): - if hasattr(field_info, 'alias') and field_info.alias == key: - return object.__getattribute__(obj, field_name) - except AttributeError: - pass - - return None - - -class AttrDict(dict): - """Dictionary that supports attribute access and nested AttrDict conversion""" - def __getattr__(self, key): - try: - value = self[key] - # Recursively convert nested dictionaries to AttrDict - value = _convert_to_attrdict(value) - self[key] = value # Cache the converted value - return value - except KeyError: - raise AttributeError(f"'{type(self).__name__}' object has no attribute '{key}'") - - def __setattr__(self, key, value): - self[key] = value - - def __getitem__(self, key): - value = super().__getitem__(key) - # Recursively convert nested dictionaries to AttrDict for item access too - value = _convert_to_attrdict(value) - self[key] = value # Cache the converted value - return value - - def __contains__(self, key): - """Support for 'in' operator with dot notation""" - if "." in key: - keys = key.split(".", 1) - if super().__contains__(keys[0]): - nested = self[keys[0]] - if hasattr(nested, '__contains__'): - return keys[1] in nested - return False - return super().__contains__(key) - - -class CloudHarnessBaseModel(BaseModel): - """ - Enhanced Pydantic BaseModel for CloudHarness with backward compatibility features. - - This class provides: - - Automatic conversion of dict fields to AttrDict for dot-notation access - - Access to additional_properties through attribute and item notation - - CamelCase/snake_case field name conversion - - Dictionary-like interface methods (get, keys, etc.) - - Field name to alias conversion during initialization - """ - - def __init__(self, **data): - """Enhanced initialization that handles field name to alias conversion.""" - # Convert field names to aliases if needed - converted_data = {} - - # Get field information - model_fields = getattr(self.__class__, 'model_fields', {}) - - for key, value in data.items(): - # Check if this key matches a field name that has an alias - found_alias = False - for field_name, field_info in model_fields.items(): - if key == field_name and hasattr(field_info, 'alias') and field_info.alias: - # Use the alias instead of the field name - converted_data[field_info.alias] = value - found_alias = True - break - - if not found_alias: - # Use the original key - converted_data[key] = value - - super().__init__(**converted_data) - -class CloudHarnessBaseModel(BaseModel): - """ - Enhanced Pydantic BaseModel for CloudHarness with backward compatibility features. - - This class provides enhanced functionality through inheritance: - - Automatic conversion of dict fields to AttrDict for dot-notation access - - Access to additional_properties through attribute and item notation - - CamelCase/snake_case field name conversion - - Dictionary-like interface methods (get, keys, etc.) - - Field name to alias conversion during initialization - - Item assignment support - """ - - def __init__(self, **data): - """Enhanced initialization that handles field name to alias conversion.""" - # Convert field names to aliases if needed - converted_data = {} - - # Get field information - model_fields = getattr(self.__class__, 'model_fields', {}) - - for key, value in data.items(): - # Check if this key matches a field name that has an alias - found_alias = False - for field_name, field_info in model_fields.items(): - if key == field_name and hasattr(field_info, 'alias') and field_info.alias: - # Use the alias instead of the field name - converted_data[field_info.alias] = value - found_alias = True - break - - if not found_alias: - # Use the original key - converted_data[key] = value - - super().__init__(**converted_data) - - def __getattribute__(self, name: str) -> Any: - """Enhanced attribute access with minimal interference for proper property handling.""" - # Get the attribute using the original __getattribute__ - value = object.__getattribute__(self, name) - - # Special handling for additional_properties - don't convert to AttrDict - if name == 'additional_properties': - return value - - # Check if this is a property - avoid recursion by directly accessing type's __dict__ - cls = type(self) - if hasattr(cls, '__dict__') and name in cls.__dict__ and isinstance(cls.__dict__[name], property): - # This is a property, don't convert its return value - return value - - # For pydantic model fields containing dicts, convert to AttrDict for better access - try: - model_fields = object.__getattribute__(self, 'model_fields') - if name in model_fields: - return _convert_to_attrdict(value) - except AttributeError: - pass - - # Return other attributes unchanged - return value - - def __getitem__(self, key: str) -> Any: - """Enhanced dictionary-style access with support for additional_properties and dot notation.""" - # Handle dot notation for nested access - if "." in key: - keys = key.split(".", 1) # Split only on first dot - try: - # Try to get the first part as an attribute - first_part = getattr(self, keys[0]) - except AttributeError: - # If not found as attribute, try additional_properties - first_part = _get_value_from_additional_properties(self, keys[0]) - if first_part is None: - raise KeyError(key) - - # Recursively access the remaining part - if hasattr(first_part, '__getitem__'): - return first_part[keys[1]] - else: - raise KeyError(key) - - # Non-dot notation access - # First check additional_properties (for keys like 'task-images' that aren't valid Python attributes) - value = _get_value_from_additional_properties(self, key) - if value is not None: - return value - - # Then check if key is an alias for a field - value = _check_field_aliases(self, key) - if value is not None: - return value - - # Try camelCase conversions - value = _try_camelcase_conversions(self, key, check_attributes=False) - if value is not None: - return value - - # Then try getattr for regular attributes - try: - return getattr(self, key) - except AttributeError: - raise KeyError(key) - - def __getattr__(self, name: str) -> Any: - """Enhanced attribute access to check additional_properties when an attribute is not found.""" - # Check if the attribute exists in additional_properties first - value = _get_value_from_additional_properties(self, name) - if value is not None: - return value - - # Try camelCase conversions for additional_properties only (not attributes to avoid recursion) - try: - import humps - except ImportError: - # Fallback to simple conversion if humps is not available - def decamelize(name): - import re - s1 = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name) - return s1.lower() - - def camelize(name): - components = name.split('_') - return components[0] + ''.join(word.capitalize() for word in components[1:]) - - humps = type('MockHumps', (), {'decamelize': decamelize, 'camelize': camelize})() - - snake_case_name = humps.decamelize(name) - if snake_case_name != name: - value = _get_value_from_additional_properties(self, snake_case_name) - if value is not None: - return value - - camel_case_name = humps.camelize(name) - if camel_case_name != name: - value = _get_value_from_additional_properties(self, camel_case_name) - if value is not None: - return value - - # Try fallback to var_{name} pattern for Python keywords like 'pass' - var_name = f"var_{name}" - try: - return object.__getattribute__(self, var_name) - except AttributeError: - pass - - # Try fallback to _{name} pattern for Python keywords like 'pass' - underscore_name = f"_{name}" - try: - return object.__getattribute__(self, underscore_name) - except AttributeError: - pass - - # If not found, raise AttributeError as expected - raise AttributeError(f"'{type(self).__name__}' object has no attribute '{name}'. Fix this by falling back to var_{name} in case of attribute error") - - def __setitem__(self, key: str, value): - """Support item assignment with additional_properties and field aliases.""" - # Check if key is an alias for a field - if hasattr(self, 'model_fields'): - for field_name, field_info in self.model_fields.items(): - if hasattr(field_info, 'alias') and field_info.alias == key: - setattr(self, field_name, value) - return - - # Check if key is a defined pydantic field (not just any attribute) - if hasattr(self, 'model_fields') and key in self.model_fields: - setattr(self, key, value) - return - - # Try camelCase conversions for defined fields only - try: - import humps - except ImportError: - # Fallback to simple conversion if humps is not available - def decamelize(name): - import re - s1 = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name) - return s1.lower() - - def camelize(name): - components = name.split('_') - return components[0] + ''.join(word.capitalize() for word in components[1:]) - - humps = type('MockHumps', (), {'decamelize': decamelize, 'camelize': camelize})() - - snake_case_key = humps.decamelize(key) - if hasattr(self, 'model_fields') and snake_case_key in self.model_fields: - setattr(self, snake_case_key, value) - return - - camel_case_key = humps.camelize(key) - if hasattr(self, 'model_fields') and camel_case_key in self.model_fields: - setattr(self, camel_case_key, value) - return - - # For any key that doesn't match a defined field, always use additional_properties - # This prevents validation errors on non-existent fields - if not hasattr(self, 'additional_properties'): - self.additional_properties = {} - self.additional_properties[key] = value - - def __setattr__(self, name: str, value): - """Handle camelCase attributes and prevent validation errors on non-existent fields.""" - # First check if this is a property - if so, use the standard mechanism - try: - cls_dict = object.__getattribute__(self.__class__, '__dict__') - if name in cls_dict and isinstance(cls_dict[name], property): - # This is a property, use the standard __setattr__ to trigger the setter - object.__setattr__(self, name, value) - return - except (AttributeError, TypeError): - pass - - # Handle private attributes (starting with _) - always set them directly - if name.startswith('_'): - object.__setattr__(self, name, value) - return - - # Check if name is a defined pydantic field - if hasattr(self, 'model_fields') and name in self.model_fields: - # Use the original __setattr__ for defined fields - super(BaseModel, self).__setattr__(name, value) - return - - # Check if name is camelCase version of a defined field - try: - import humps - except ImportError: - # Fallback to simple conversion if humps is not available - def decamelize(name): - import re - s1 = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name) - return s1.lower() - - humps = type('MockHumps', (), {'decamelize': decamelize})() - - snake_case_name = humps.decamelize(name) - if hasattr(self, 'model_fields') and snake_case_name in self.model_fields: - super(BaseModel, self).__setattr__(snake_case_name, value) - return - - # For non-field attributes, store in additional_properties to avoid validation errors - if not hasattr(self, 'additional_properties'): - object.__setattr__(self, 'additional_properties', {}) - - # If additional_properties already exists, update it - if hasattr(self, 'additional_properties'): - self.additional_properties[name] = value - else: - # Fallback to object.__setattr__ for internal attributes - object.__setattr__(self, name, value) - - def get(self, key: str, default=None): - """Dictionary-like get method with support for additional_properties and dot notation.""" - try: - return self[key] - except KeyError: - return default - - def __contains__(self, key: str) -> bool: - """Support 'in' operator with additional_properties and dot notation.""" - # Handle dot notation for nested access - if "." in key: - keys = key.split(".", 1) # Split only on first dot - try: - # Try to get the first part as an attribute - first_part = getattr(self, keys[0]) - except AttributeError: - # If not found as attribute, try additional_properties - first_part = _get_value_from_additional_properties(self, keys[0]) - if first_part is None: - return False - - # Check if the remaining part exists in the nested object - if hasattr(first_part, '__contains__'): - return keys[1] in first_part - else: - return False - - # Non-dot notation access - # First check if it's a defined field in the model - if hasattr(self, 'model_fields') and key in self.model_fields: - return True - - # Check if it's a regular attribute - if hasattr(self, key): - return True - - # Check additional_properties - if hasattr(self, 'additional_properties') and key in self.additional_properties: - return True - - return False - - def to_dict(self) -> Dict[str, Any]: - """Enhanced to_dict that converts nested models to AttrDict for backward compatibility.""" - result = super().model_dump(by_alias=True, exclude_none=True) - return _convert_to_attrdict(result) diff --git a/libraries/models/cloudharness_model/base_model_fixed.py b/libraries/models/cloudharness_model/base_model_fixed.py deleted file mode 100644 index 036c01971..000000000 --- a/libraries/models/cloudharness_model/base_model_fixed.py +++ /dev/null @@ -1,267 +0,0 @@ -# coding: utf-8 -""" -CloudHarness Base Model - -A custom Pydantic BaseModel subclass that provides enhanced functionality for -CloudHarness generated models, replacing the previous monkey patching approach. -""" - -from __future__ import annotations -import re -from typing import Any, Dict, List, Union -from pydantic import BaseModel - - -class AttrDict(dict): - """Dictionary that supports attribute-style access.""" - - def __getattr__(self, key: str) -> Any: - try: - value = self[key] - # Recursively convert nested dictionaries to AttrDict - if isinstance(value, dict) and not isinstance(value, AttrDict): - value = AttrDict(value) - self[key] = value # Cache the converted value - elif isinstance(value, list): - # Convert list items that are dictionaries to AttrDict - value = [AttrDict(item) if isinstance(item, dict) and not isinstance(item, AttrDict) else item for item in value] - self[key] = value # Cache the converted value - return value - except KeyError: - raise AttributeError(f"'{type(self).__name__}' object has no attribute '{key}'") - - def __setattr__(self, key: str, value: Any) -> None: - self[key] = value - - def __getitem__(self, key: str) -> Any: - value = super().__getitem__(key) - # Recursively convert nested dictionaries to AttrDict for item access too - if isinstance(value, dict) and not isinstance(value, AttrDict): - value = AttrDict(value) - self[key] = value # Cache the converted value - elif isinstance(value, list): - # Convert list items that are dictionaries to AttrDict - value = [AttrDict(item) if isinstance(item, dict) and not isinstance(item, AttrDict) else item for item in value] - self[key] = value # Cache the converted value - return value - - def get(self, key: str, default: Any = None) -> Any: - """Get method with default value, similar to regular dict.""" - try: - return self[key] - except KeyError: - return default - - -class CloudHarnessBaseModel(BaseModel): - """ - Enhanced Pydantic BaseModel for CloudHarness with backward compatibility features. - - This class provides: - - Automatic conversion of dict fields to AttrDict for dot-notation access - - Access to additional_properties through attribute and item notation - - CamelCase/snake_case field name conversion - - Dictionary-like interface methods (get, keys, etc.) - """ - - def _camel_to_snake(self, name: str) -> str: - """Convert camelCase to snake_case.""" - s1 = re.sub('([a-z0-9])([A-Z])', r'\1_\2', name) - return s1.lower() - - def _snake_to_camel(self, name: str) -> str: - """Convert snake_case to camelCase.""" - components = name.split('_') - return components[0] + ''.join(word.capitalize() for word in components[1:]) - - @staticmethod - def _convert_to_attr_dict_static(value): - """Static method to convert nested structures to AttrDict.""" - if isinstance(value, dict) and not isinstance(value, AttrDict): - return AttrDict(value) - elif isinstance(value, list): - # Convert list items that are dictionaries to AttrDict - return [CloudHarnessBaseModel._convert_to_attr_dict_static(item) for item in value] - return value - - def _get_value_from_additional_properties(self, key: str): - """Helper function to get value from additional_properties without triggering __getattr__ recursion""" - # Use object.__getattribute__ to directly access additional_properties without triggering our override - try: - additional_properties = object.__getattribute__(self, 'additional_properties') - if key in additional_properties: - value = additional_properties[key] - return self._convert_to_attr_dict_static(value) - except AttributeError: - # Object doesn't have additional_properties - pass - return None - - def __getattribute__(self, name: str) -> Any: - """Enhanced attribute access with AttrDict conversion, preserving original pydantic_utils logic.""" - # Get the attribute using the original __getattribute__ - value = object.__getattribute__(self, name) - - # Special handling for additional_properties - don't convert to AttrDict on direct access - if name == 'additional_properties': - return value - - # Check if this is a property - avoid recursion by directly accessing type's __dict__ - cls = type(self) - if hasattr(cls, '__dict__') and name in cls.__dict__ and isinstance(cls.__dict__[name], property): - # This is a property, don't convert its return value - return value - - # For pydantic model fields containing dicts, convert to AttrDict for better access - try: - model_fields = object.__getattribute__(self, 'model_fields') - if name in model_fields: - return self._convert_to_attr_dict_static(value) - except AttributeError: - pass - - # Return other attributes unchanged - return value - - def __getitem__(self, key: str) -> Any: - """Enhanced dictionary-style access with support for additional_properties and dot notation, preserving original pydantic_utils logic.""" - # Handle dot notation for nested access - if "." in key: - keys = key.split(".", 1) # Split only on first dot - try: - # Try to get the first part as an attribute - first_part = getattr(self, keys[0]) - except AttributeError: - # If not found as attribute, try additional_properties - first_part = self._get_value_from_additional_properties(keys[0]) - if first_part is None: - raise KeyError(key) - - # Recursively access the remaining part - if hasattr(first_part, '__getitem__'): - return first_part[keys[1]] - else: - raise KeyError(key) - - # Non-dot notation access - # First check additional_properties (for keys like 'task-images' that aren't valid Python attributes) - value = self._get_value_from_additional_properties(key) - if value is not None: - return value - - # Try camelCase conversions - snake_case_key = self._camel_to_snake(key) - if snake_case_key != key: - value = self._get_value_from_additional_properties(snake_case_key) - if value is not None: - return value - - camel_case_key = self._snake_to_camel(key) - if camel_case_key != key: - value = self._get_value_from_additional_properties(camel_case_key) - if value is not None: - return value - - # Then try getattr for regular attributes - try: - return getattr(self, key) - except AttributeError: - raise KeyError(key) - - def __getattr__(self, name: str) -> Any: - """Enhanced attribute access with camelCase/snake_case conversion, preserving original pydantic_utils logic.""" - # Avoid infinite recursion for special attributes - if name.startswith('__') and name.endswith('__'): - raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'") - - # Check if the attribute exists in additional_properties first - value = self._get_value_from_additional_properties(name) - if value is not None: - return value - - # Try camelCase conversions for additional_properties only (not attributes to avoid recursion) - snake_case_name = self._camel_to_snake(name) - if snake_case_name != name: - value = self._get_value_from_additional_properties(snake_case_name) - if value is not None: - return value - - camel_case_name = self._snake_to_camel(name) - if camel_case_name != name: - value = self._get_value_from_additional_properties(camel_case_name) - if value is not None: - return value - - # Check extra fields - if hasattr(self, '__pydantic_extra__') and name in self.__pydantic_extra__: - value = self.__pydantic_extra__[name] - # Convert dict to AttrDict on access for backward compatibility - if isinstance(value, dict) and not isinstance(value, AttrDict): - return self._convert_to_attr_dict_static(value) - return value - - raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'") - - def get(self, key: str, default: Any = None) -> Any: - """Get a field value with optional default, similar to dict.get().""" - try: - return self[key] - except KeyError: - return default - - def keys(self): - """Return keys of all fields and additional properties.""" - keys = set(self.model_fields.keys()) - if hasattr(self, 'additional_properties'): - keys.update(self.additional_properties.keys()) - if hasattr(self, '__pydantic_extra__'): - keys.update(self.__pydantic_extra__.keys()) - return keys - - def values(self): - """Return values of all fields and additional properties.""" - return [self[key] for key in self.keys()] - - def items(self): - """Return items of all fields and additional properties.""" - return [(key, self[key]) for key in self.keys()] - - def __contains__(self, key: str) -> bool: - """Check if key exists in model fields or additional properties.""" - # Handle dot notation for nested access - if "." in key: - keys = key.split(".", 1) # Split only on first dot - try: - # Try to get the first part as an attribute - first_part = getattr(self, keys[0]) - except AttributeError: - # If not found as attribute, try additional_properties - first_part = self._get_value_from_additional_properties(keys[0]) - if first_part is None: - return False - - # Check if the remaining part exists in the nested object - if hasattr(first_part, '__contains__'): - return keys[1] in first_part - else: - return False - - # Non-dot notation access - # First check if it's a defined field in the model - if hasattr(self, 'model_fields') and key in self.model_fields: - return True - - # Check if it's a regular attribute - if hasattr(self, key): - return True - - # Check additional_properties - if hasattr(self, 'additional_properties') and key in self.additional_properties: - return True - - return False - - def to_dict(self) -> Dict[str, Any]: - """Enhanced to_dict that converts nested models to AttrDict for backward compatibility.""" - result = super().model_dump(by_alias=True, exclude_none=True) - return self._convert_to_attr_dict_static(result) diff --git a/libraries/models/cloudharness_model/configuration.py b/libraries/models/cloudharness_model/configuration.py index a8fc99a3b..48470064a 100644 --- a/libraries/models/cloudharness_model/configuration.py +++ b/libraries/models/cloudharness_model/configuration.py @@ -1,26 +1,22 @@ -# coding: utf-8 - """ cloudharness - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) # noqa: E501 The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 + Generated by: https://openapi-generator.tech +""" import copy import logging -from logging import FileHandler import multiprocessing import sys -from typing import Optional import urllib3 -import http.client as httplib +from http import client as http_client +from cloudharness_model.exceptions import ApiValueError + JSON_SCHEMA_VALIDATION_KEYWORDS = { 'multipleOf', 'maximum', 'exclusiveMaximum', @@ -28,23 +24,46 @@ 'minLength', 'pattern', 'maxItems', 'minItems' } -class Configuration: - """This class contains various settings of the API client. +class Configuration(object): + """NOTE: This class is auto generated by OpenAPI Generator + + Ref: https://openapi-generator.tech + Do not edit the class manually. - :param host: Base url. - :param ignore_operation_servers - Boolean to ignore operation servers for the API client. - Config will use `host` as the base url regardless of the operation servers. + :param host: Base url :param api_key: Dict to store API key(s). Each entry in the dict specifies an API key. The dict key is the name of the security scheme in the OAS specification. The dict value is the API key secret. - :param api_key_prefix: Dict to store API prefix (e.g. Bearer). + :param api_key_prefix: Dict to store API prefix (e.g. Bearer) The dict key is the name of the security scheme in the OAS specification. The dict value is an API key prefix when generating the auth data. - :param username: Username for HTTP basic authentication. - :param password: Password for HTTP basic authentication. - :param access_token: Access token. + :param username: Username for HTTP basic authentication + :param password: Password for HTTP basic authentication + :param discard_unknown_keys: Boolean value indicating whether to discard + unknown properties. A server may send a response that includes additional + properties that are not known by the client in the following scenarios: + 1. The OpenAPI document is incomplete, i.e. it does not match the server + implementation. + 2. The client was generated using an older version of the OpenAPI document + and the server has been upgraded since then. + If a schema in the OpenAPI document defines the additionalProperties attribute, + then all undeclared properties received by the server are injected into the + additional properties map. In that case, there are undeclared properties, and + nothing to discard. + :param disabled_client_side_validations (string): Comma-separated list of + JSON schema validation keywords to disable JSON schema structural validation + rules. The following keywords may be specified: multipleOf, maximum, + exclusiveMaximum, minimum, exclusiveMinimum, maxLength, minLength, pattern, + maxItems, minItems. + By default, the validation is performed for data generated locally by the client + and data received from the server, independent of any validation performed by + the server side. If the input data does not satisfy the JSON schema validation + rules specified in the OpenAPI document, an exception is raised. + If disabled_client_side_validations is set, structural validation is + disabled. This can be useful to troubleshoot data validation problem, such as + when the OpenAPI document validation rules do not match the actual API data + received by the server. :param server_index: Index to servers configuration. :param server_variables: Mapping with string values to replace variables in templated server configuration. The validation of enums is performed for @@ -53,11 +72,9 @@ class Configuration: configuration. :param server_operation_variables: Mapping from operation ID to a mapping with string values to replace variables in templated server configuration. - The validation of enums is performed for variables with defined enum - values before. + The validation of enums is performed for variables with defined enum values before. :param ssl_ca_cert: str - the path to a file of concatenated CA certificates - in PEM format. - :param retries: Number of retries for API requests. + in PEM format """ @@ -65,16 +82,14 @@ class Configuration: def __init__(self, host=None, api_key=None, api_key_prefix=None, - username=None, password=None, access_token=None, + username=None, password=None, + discard_unknown_keys=False, + disabled_client_side_validations="", server_index=None, server_variables=None, server_operation_index=None, server_operation_variables=None, - ignore_operation_servers=False, ssl_ca_cert=None, - retries=None, - *, - debug: Optional[bool] = None - ) -> None: + ): """Constructor """ self._base_path = "http://localhost" if host is None else host @@ -88,13 +103,11 @@ def __init__(self, host=None, self.server_operation_variables = server_operation_variables or {} """Default server variables """ - self.ignore_operation_servers = ignore_operation_servers - """Ignore operation servers - """ self.temp_folder_path = None """Temp file folder for downloading files """ # Authentication Settings + self.access_token = access_token self.api_key = {} if api_key: self.api_key = api_key @@ -114,9 +127,8 @@ def __init__(self, host=None, self.password = password """Password for HTTP basic authentication """ - self.access_token = access_token - """Access token - """ + self.discard_unknown_keys = discard_unknown_keys + self.disabled_client_side_validations = disabled_client_side_validations self.logger = {} """Logging Settings """ @@ -128,16 +140,13 @@ def __init__(self, host=None, self.logger_stream_handler = None """Log stream handler """ - self.logger_file_handler: Optional[FileHandler] = None + self.logger_file_handler = None """Log file handler """ self.logger_file = None """Debug file location """ - if debug is not None: - self.debug = debug - else: - self.__debug = False + self.debug = False """Debug switch """ @@ -158,10 +167,6 @@ def __init__(self, host=None, self.assert_hostname = None """Set this to True/False to enable/disable SSL hostname verification. """ - self.tls_server_name = None - """SSL/TLS Server Name Indication (SNI) - Set this to the SNI value expected by the server. - """ self.connection_pool_maxsize = multiprocessing.cpu_count() * 5 """urllib3 connection pool's maximum number of connections saved @@ -171,32 +176,26 @@ def __init__(self, host=None, cpu_count * 5 is used as default value to increase performance. """ - self.proxy: Optional[str] = None + self.proxy = None """Proxy URL """ + self.no_proxy = None + """bypass proxy for host in the no_proxy list. + """ self.proxy_headers = None """Proxy headers """ self.safe_chars_for_path_param = '' """Safe chars for path_param """ - self.retries = retries + self.retries = None """Adding retries to override urllib3 default value 3 """ # Enable client side validation self.client_side_validation = True + # Options to pass down to the underlying urllib3 socket self.socket_options = None - """Options to pass down to the underlying urllib3 socket - """ - - self.datetime_format = "%Y-%m-%dT%H:%M:%S.%f%z" - """datetime format - """ - - self.date_format = "%Y-%m-%d" - """date format - """ def __deepcopy__(self, memo): cls = self.__class__ @@ -214,6 +213,13 @@ def __deepcopy__(self, memo): def __setattr__(self, name, value): object.__setattr__(self, name, value) + if name == 'disabled_client_side_validations': + s = set(filter(None, value.split(','))) + for v in s: + if v not in JSON_SCHEMA_VALIDATION_KEYWORDS: + raise ApiValueError( + "Invalid keyword: '{0}''".format(v)) + self._disabled_client_side_validations = s @classmethod def set_default(cls, default): @@ -224,31 +230,21 @@ def set_default(cls, default): :param default: object of Configuration """ - cls._default = default + cls._default = copy.deepcopy(default) @classmethod def get_default_copy(cls): - """Deprecated. Please use `get_default` instead. - - Deprecated. Please use `get_default` instead. - - :return: The configuration object. - """ - return cls.get_default() - - @classmethod - def get_default(cls): - """Return the default configuration. + """Return new instance of configuration. This method returns newly created, based on default constructor, object of Configuration class or returns a copy of default - configuration. + configuration passed by the set_default method. :return: The configuration object. """ - if cls._default is None: - cls._default = Configuration() - return cls._default + if cls._default is not None: + return copy.deepcopy(cls._default) + return Configuration() @property def logger_file(self): @@ -302,15 +298,15 @@ def debug(self, value): # if debug status is True, turn on debug logging for _, logger in self.logger.items(): logger.setLevel(logging.DEBUG) - # turn on httplib debug - httplib.HTTPConnection.debuglevel = 1 + # turn on http_client debug + http_client.HTTPConnection.debuglevel = 1 else: # if debug status is False, turn off debug logging, # setting log level to default `logging.WARNING` for _, logger in self.logger.items(): logger.setLevel(logging.WARNING) - # turn off httplib debug - httplib.HTTPConnection.debuglevel = 0 + # turn off http_client debug + http_client.HTTPConnection.debuglevel = 0 @property def logger_format(self): diff --git a/libraries/models/cloudharness_model/encoder.py b/libraries/models/cloudharness_model/encoder.py index 90264613e..a201ec254 100644 --- a/libraries/models/cloudharness_model/encoder.py +++ b/libraries/models/cloudharness_model/encoder.py @@ -1,15 +1,13 @@ from json import JSONEncoder +import six + +from cloudharness_model.models.base_model_ import Model class CloudHarnessJSONEncoder(JSONEncoder): include_nulls = False - def encode(self, o): - if hasattr(o, "to_json"): - return o.to_json() - return super().encode(o) def default(self, o): - if hasattr(o, "to_dict"): return o.to_dict() return JSONEncoder.default(self, o) \ No newline at end of file diff --git a/libraries/models/cloudharness_model/exceptions.py b/libraries/models/cloudharness_model/exceptions.py index 3566fb1fa..281e3d1a5 100644 --- a/libraries/models/cloudharness_model/exceptions.py +++ b/libraries/models/cloudharness_model/exceptions.py @@ -1,18 +1,13 @@ -# coding: utf-8 - """ cloudharness - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) # noqa: E501 The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) + Generated by: https://openapi-generator.tech +""" - Do not edit the class manually. -""" # noqa: E501 -from typing import Any, Optional -from typing_extensions import Self class OpenApiException(Exception): """The base exception class for all OpenAPIExceptions""" @@ -20,7 +15,7 @@ class OpenApiException(Exception): class ApiTypeError(OpenApiException, TypeError): def __init__(self, msg, path_to_item=None, valid_classes=None, - key_type=None) -> None: + key_type=None): """ Raises an exception for TypeErrors Args: @@ -48,7 +43,7 @@ def __init__(self, msg, path_to_item=None, valid_classes=None, class ApiValueError(OpenApiException, ValueError): - def __init__(self, msg, path_to_item=None) -> None: + def __init__(self, msg, path_to_item=None): """ Args: msg (str): the exception message @@ -66,7 +61,7 @@ def __init__(self, msg, path_to_item=None) -> None: class ApiAttributeError(OpenApiException, AttributeError): - def __init__(self, msg, path_to_item=None) -> None: + def __init__(self, msg, path_to_item=None): """ Raised when an attribute reference or assignment fails. @@ -85,7 +80,7 @@ def __init__(self, msg, path_to_item=None) -> None: class ApiKeyError(OpenApiException, KeyError): - def __init__(self, msg, path_to_item=None) -> None: + def __init__(self, msg, path_to_item=None): """ Args: msg (str): the exception message @@ -103,56 +98,17 @@ def __init__(self, msg, path_to_item=None) -> None: class ApiException(OpenApiException): - def __init__( - self, - status=None, - reason=None, - http_resp=None, - *, - body: Optional[str] = None, - data: Optional[Any] = None, - ) -> None: - self.status = status - self.reason = reason - self.body = body - self.data = data - self.headers = None - + def __init__(self, status=None, reason=None, http_resp=None): if http_resp: - if self.status is None: - self.status = http_resp.status - if self.reason is None: - self.reason = http_resp.reason - if self.body is None: - try: - self.body = http_resp.data.decode('utf-8') - except Exception: - pass + self.status = http_resp.status + self.reason = http_resp.reason + self.body = http_resp.data self.headers = http_resp.getheaders() - - @classmethod - def from_response( - cls, - *, - http_resp, - body: Optional[str], - data: Optional[Any], - ) -> Self: - if http_resp.status == 400: - raise BadRequestException(http_resp=http_resp, body=body, data=data) - - if http_resp.status == 401: - raise UnauthorizedException(http_resp=http_resp, body=body, data=data) - - if http_resp.status == 403: - raise ForbiddenException(http_resp=http_resp, body=body, data=data) - - if http_resp.status == 404: - raise NotFoundException(http_resp=http_resp, body=body, data=data) - - if 500 <= http_resp.status <= 599: - raise ServiceException(http_resp=http_resp, body=body, data=data) - raise ApiException(http_resp=http_resp, body=body, data=data) + else: + self.status = status + self.reason = reason + self.body = None + self.headers = None def __str__(self): """Custom error messages for exception""" @@ -162,30 +118,34 @@ def __str__(self): error_message += "HTTP response headers: {0}\n".format( self.headers) - if self.data or self.body: - error_message += "HTTP response body: {0}\n".format(self.data or self.body) + if self.body: + error_message += "HTTP response body: {0}\n".format(self.body) return error_message -class BadRequestException(ApiException): - pass - - class NotFoundException(ApiException): - pass + + def __init__(self, status=None, reason=None, http_resp=None): + super(NotFoundException, self).__init__(status, reason, http_resp) class UnauthorizedException(ApiException): - pass + + def __init__(self, status=None, reason=None, http_resp=None): + super(UnauthorizedException, self).__init__(status, reason, http_resp) class ForbiddenException(ApiException): - pass + + def __init__(self, status=None, reason=None, http_resp=None): + super(ForbiddenException, self).__init__(status, reason, http_resp) class ServiceException(ApiException): - pass + + def __init__(self, status=None, reason=None, http_resp=None): + super(ServiceException, self).__init__(status, reason, http_resp) def render_path(path_to_item): diff --git a/libraries/models/cloudharness_model/models/.gitattributes b/libraries/models/cloudharness_model/models/.gitattributes deleted file mode 100644 index a5ca8e67b..000000000 --- a/libraries/models/cloudharness_model/models/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -* linguist-generated=true \ No newline at end of file diff --git a/libraries/models/cloudharness_model/models/__init__.py b/libraries/models/cloudharness_model/models/__init__.py index 82af9e911..13238dc74 100644 --- a/libraries/models/cloudharness_model/models/__init__.py +++ b/libraries/models/cloudharness_model/models/__init__.py @@ -1,18 +1,4 @@ -# coding: utf-8 - # flake8: noqa -""" - cloudharness - - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) - - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - # import models into model package from cloudharness_model.models.api_tests_config import ApiTestsConfig from cloudharness_model.models.application_accounts_config import ApplicationAccountsConfig @@ -34,18 +20,12 @@ from cloudharness_model.models.dockerfile_config import DockerfileConfig from cloudharness_model.models.e2_e_tests_config import E2ETestsConfig from cloudharness_model.models.file_resources_config import FileResourcesConfig -from cloudharness_model.models.gatekeeper_conf import GatekeeperConf from cloudharness_model.models.git_dependency_config import GitDependencyConfig from cloudharness_model.models.harness_main_config import HarnessMainConfig from cloudharness_model.models.ingress_config import IngressConfig from cloudharness_model.models.ingress_config_all_of_letsencrypt import IngressConfigAllOfLetsencrypt from cloudharness_model.models.jupyter_hub_config import JupyterHubConfig from cloudharness_model.models.name_value import NameValue -from cloudharness_model.models.named_object import NamedObject -from cloudharness_model.models.organization import Organization -from cloudharness_model.models.proxy_conf import ProxyConf -from cloudharness_model.models.proxy_payload_conf import ProxyPayloadConf -from cloudharness_model.models.proxy_timeout_conf import ProxyTimeoutConf from cloudharness_model.models.registry_config import RegistryConfig from cloudharness_model.models.service_auto_artifact_config import ServiceAutoArtifactConfig from cloudharness_model.models.unit_tests_config import UnitTestsConfig diff --git a/libraries/models/cloudharness_model/models/api_tests_config.py b/libraries/models/cloudharness_model/models/api_tests_config.py index b3eb619fb..a7965a55b 100644 --- a/libraries/models/cloudharness_model/models/api_tests_config.py +++ b/libraries/models/cloudharness_model/models/api_tests_config.py @@ -1,89 +1,153 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model import util - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) + +class ApiTestsConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, enabled=None, autotest=None, run_params=None, checks=None): # noqa: E501 + """ApiTestsConfig - a model defined in OpenAPI + + :param enabled: The enabled of this ApiTestsConfig. # noqa: E501 + :type enabled: bool + :param autotest: The autotest of this ApiTestsConfig. # noqa: E501 + :type autotest: bool + :param run_params: The run_params of this ApiTestsConfig. # noqa: E501 + :type run_params: List[str] + :param checks: The checks of this ApiTestsConfig. # noqa: E501 + :type checks: List[str] + """ + self.openapi_types = { + 'enabled': bool, + 'autotest': bool, + 'run_params': List[str], + 'checks': List[str] + } + + self.attribute_map = { + 'enabled': 'enabled', + 'autotest': 'autotest', + 'run_params': 'runParams', + 'checks': 'checks' + } + + self._enabled = enabled + self._autotest = autotest + self._run_params = run_params + self._checks = checks -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + @classmethod + def from_dict(cls, dikt) -> 'ApiTestsConfig': + """Returns the dict as a model -from typing import Optional, Set -from typing_extensions import Self + :param dikt: A dict. + :type: dict + :return: The ApiTestsConfig of this ApiTestsConfig. # noqa: E501 + :rtype: ApiTestsConfig + """ + return util.deserialize_model(dikt, cls) + @property + def enabled(self) -> bool: + """Gets the enabled of this ApiTestsConfig. -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib + Enables api tests for this application (default: false) # noqa: E501 -class ApiTestsConfig(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - enabled: StrictBool = Field(description="Enables api tests for this application (default: false)") - autotest: StrictBool = Field(description="Specify whether to run the common smoke tests") - run_params: Optional[List[StrictStr]] = Field(default=None, description="Additional schemathesis parameters", alias="runParams") - checks: List[StrictStr] = Field(description="One of the Schemathesis checks: - not_a_server_error. The response has 5xx HTTP status; - status_code_conformance. The response status is not defined in the API schema; - content_type_conformance. The response content type is not defined in the API schema; - response_schema_conformance. The response content does not conform to the schema defined for this specific response; - response_headers_conformance. The response headers does not contain all defined headers.") - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["enabled", "autotest", "runParams", "checks"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :return: The enabled of this ApiTestsConfig. + :rtype: bool """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + return self._enabled - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of ApiTestsConfig from a dict""" - if obj is None: - return None + @enabled.setter + def enabled(self, enabled: bool): + """Sets the enabled of this ApiTestsConfig. - if not isinstance(obj, dict): - return cls.model_validate(obj) + Enables api tests for this application (default: false) # noqa: E501 + + :param enabled: The enabled of this ApiTestsConfig. + :type enabled: bool + """ + if enabled is None: + raise ValueError("Invalid value for `enabled`, must not be `None`") # noqa: E501 - _obj = cls.model_validate({ - "enabled": obj.get("enabled"), - "autotest": obj.get("autotest"), - "runParams": obj.get("runParams"), - "checks": obj.get("checks") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + self._enabled = enabled + + @property + def autotest(self) -> bool: + """Gets the autotest of this ApiTestsConfig. + + Specify whether to run the common smoke tests # noqa: E501 + + :return: The autotest of this ApiTestsConfig. + :rtype: bool + """ + return self._autotest + + @autotest.setter + def autotest(self, autotest: bool): + """Sets the autotest of this ApiTestsConfig. + + Specify whether to run the common smoke tests # noqa: E501 + + :param autotest: The autotest of this ApiTestsConfig. + :type autotest: bool + """ + if autotest is None: + raise ValueError("Invalid value for `autotest`, must not be `None`") # noqa: E501 - return _obj + self._autotest = autotest + @property + def run_params(self) -> List[str]: + """Gets the run_params of this ApiTestsConfig. + + Additional schemathesis parameters # noqa: E501 + + :return: The run_params of this ApiTestsConfig. + :rtype: List[str] + """ + return self._run_params + + @run_params.setter + def run_params(self, run_params: List[str]): + """Sets the run_params of this ApiTestsConfig. + + Additional schemathesis parameters # noqa: E501 + + :param run_params: The run_params of this ApiTestsConfig. + :type run_params: List[str] + """ + + self._run_params = run_params + + @property + def checks(self) -> List[str]: + """Gets the checks of this ApiTestsConfig. + + One of the Schemathesis checks: - not_a_server_error. The response has 5xx HTTP status; - status_code_conformance. The response status is not defined in the API schema; - content_type_conformance. The response content type is not defined in the API schema; - response_schema_conformance. The response content does not conform to the schema defined for this specific response; - response_headers_conformance. The response headers does not contain all defined headers. # noqa: E501 + + :return: The checks of this ApiTestsConfig. + :rtype: List[str] + """ + return self._checks + + @checks.setter + def checks(self, checks: List[str]): + """Sets the checks of this ApiTestsConfig. + + One of the Schemathesis checks: - not_a_server_error. The response has 5xx HTTP status; - status_code_conformance. The response status is not defined in the API schema; - content_type_conformance. The response content type is not defined in the API schema; - response_schema_conformance. The response content does not conform to the schema defined for this specific response; - response_headers_conformance. The response headers does not contain all defined headers. # noqa: E501 + + :param checks: The checks of this ApiTestsConfig. + :type checks: List[str] + """ + if checks is None: + raise ValueError("Invalid value for `checks`, must not be `None`") # noqa: E501 + self._checks = checks diff --git a/libraries/models/cloudharness_model/models/application_accounts_config.py b/libraries/models/cloudharness_model/models/application_accounts_config.py index bad494a30..9dc8b124b 100644 --- a/libraries/models/cloudharness_model/models/application_accounts_config.py +++ b/libraries/models/cloudharness_model/models/application_accounts_config.py @@ -1,93 +1,93 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model.models.application_user import ApplicationUser +from cloudharness_model import util + +from cloudharness_model.models.application_user import ApplicationUser # noqa: E501 - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) +class ApplicationAccountsConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, roles=None, users=None): # noqa: E501 + """ApplicationAccountsConfig - a model defined in OpenAPI -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + :param roles: The roles of this ApplicationAccountsConfig. # noqa: E501 + :type roles: List[str] + :param users: The users of this ApplicationAccountsConfig. # noqa: E501 + :type users: List[ApplicationUser] + """ + self.openapi_types = { + 'roles': List[str], + 'users': List[ApplicationUser] + } -from typing import Optional, Set -from typing_extensions import Self + self.attribute_map = { + 'roles': 'roles', + 'users': 'users' + } + self._roles = roles + self._users = users -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib -from cloudharness_model.models.application_user import ApplicationUser + @classmethod + def from_dict(cls, dikt) -> 'ApplicationAccountsConfig': + """Returns the dict as a model -class ApplicationAccountsConfig(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - roles: Optional[List[StrictStr]] = Field(default=None, description="Specify roles to be created in this deployment specific for this application") - users: Optional[List[ApplicationUser]] = Field(default=None, description="Defines test users to be added to the deployment, specific for this application") - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["roles", "users"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :param dikt: A dict. + :type: dict + :return: The ApplicationAccountsConfig of this ApplicationAccountsConfig. # noqa: E501 + :rtype: ApplicationAccountsConfig """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # override the default output from pydantic by calling `to_dict()` of each item in users (list) - _items = [] - if self.users: - for _item_users in self.users: - if _item_users: - _items.append(_item_users.to_dict()) - _dict['users'] = _items - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + return util.deserialize_model(dikt, cls) - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of ApplicationAccountsConfig from a dict""" - if obj is None: - return None + @property + def roles(self) -> List[str]: + """Gets the roles of this ApplicationAccountsConfig. + + Specify roles to be created in this deployment specific for this application # noqa: E501 + + :return: The roles of this ApplicationAccountsConfig. + :rtype: List[str] + """ + return self._roles + + @roles.setter + def roles(self, roles: List[str]): + """Sets the roles of this ApplicationAccountsConfig. + + Specify roles to be created in this deployment specific for this application # noqa: E501 + + :param roles: The roles of this ApplicationAccountsConfig. + :type roles: List[str] + """ - if not isinstance(obj, dict): - return cls.model_validate(obj) + self._roles = roles - _obj = cls.model_validate({ - "roles": obj.get("roles"), - "users": [ApplicationUser.from_dict(_item) for _item in obj["users"]] if obj.get("users") is not None else None - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + @property + def users(self) -> List[ApplicationUser]: + """Gets the users of this ApplicationAccountsConfig. - return _obj + Defines test users to be added to the deployment, specific for this application # noqa: E501 + :return: The users of this ApplicationAccountsConfig. + :rtype: List[ApplicationUser] + """ + return self._users + + @users.setter + def users(self, users: List[ApplicationUser]): + """Sets the users of this ApplicationAccountsConfig. + + Defines test users to be added to the deployment, specific for this application # noqa: E501 + + :param users: The users of this ApplicationAccountsConfig. + :type users: List[ApplicationUser] + """ + self._users = users diff --git a/libraries/models/cloudharness_model/models/application_config.py b/libraries/models/cloudharness_model/models/application_config.py index 98c44e3d0..26a6c8137 100644 --- a/libraries/models/cloudharness_model/models/application_config.py +++ b/libraries/models/cloudharness_model/models/application_config.py @@ -1,87 +1,65 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model.models.application_harness_config import ApplicationHarnessConfig +from cloudharness_model import util + +from cloudharness_model.models.application_harness_config import ApplicationHarnessConfig # noqa: E501 - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) +class ApplicationConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, harness=None): # noqa: E501 + """ApplicationConfig - a model defined in OpenAPI -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + :param harness: The harness of this ApplicationConfig. # noqa: E501 + :type harness: ApplicationHarnessConfig + """ + self.openapi_types = { + 'harness': ApplicationHarnessConfig + } -from typing import Optional, Set -from typing_extensions import Self + self.attribute_map = { + 'harness': 'harness' + } + self._harness = harness -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib -from cloudharness_model.models.application_harness_config import ApplicationHarnessConfig + @classmethod + def from_dict(cls, dikt) -> 'ApplicationConfig': + """Returns the dict as a model -class ApplicationConfig(CloudHarnessBaseModel): - """ - Place here the values to configure your application helm templates. - """ # noqa: E501 - harness: ApplicationHarnessConfig - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["harness"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :param dikt: A dict. + :type: dict + :return: The ApplicationConfig of this ApplicationConfig. # noqa: E501 + :rtype: ApplicationConfig """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # override the default output from pydantic by calling `to_dict()` of harness - if self.harness: - _dict['harness'] = self.harness.to_dict() - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + return util.deserialize_model(dikt, cls) - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of ApplicationConfig from a dict""" - if obj is None: - return None + @property + def harness(self) -> ApplicationHarnessConfig: + """Gets the harness of this ApplicationConfig. - if not isinstance(obj, dict): - return cls.model_validate(obj) - _obj = cls.model_validate({ - "harness": ApplicationHarnessConfig.from_dict(obj["harness"]) if obj.get("harness") is not None else None - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + :return: The harness of this ApplicationConfig. + :rtype: ApplicationHarnessConfig + """ + return self._harness - return _obj + @harness.setter + def harness(self, harness: ApplicationHarnessConfig): + """Sets the harness of this ApplicationConfig. + :param harness: The harness of this ApplicationConfig. + :type harness: ApplicationHarnessConfig + """ + if harness is None: + raise ValueError("Invalid value for `harness`, must not be `None`") # noqa: E501 + + self._harness = harness diff --git a/libraries/models/cloudharness_model/models/application_dependencies_config.py b/libraries/models/cloudharness_model/models/application_dependencies_config.py index fdd236af0..1bfd211e5 100644 --- a/libraries/models/cloudharness_model/models/application_dependencies_config.py +++ b/libraries/models/cloudharness_model/models/application_dependencies_config.py @@ -1,97 +1,149 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model.models.git_dependency_config import GitDependencyConfig +from cloudharness_model import util + +from cloudharness_model.models.git_dependency_config import GitDependencyConfig # noqa: E501 - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) +class ApplicationDependenciesConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, hard=None, soft=None, build=None, git=None): # noqa: E501 + """ApplicationDependenciesConfig - a model defined in OpenAPI + + :param hard: The hard of this ApplicationDependenciesConfig. # noqa: E501 + :type hard: List[str] + :param soft: The soft of this ApplicationDependenciesConfig. # noqa: E501 + :type soft: List[str] + :param build: The build of this ApplicationDependenciesConfig. # noqa: E501 + :type build: List[str] + :param git: The git of this ApplicationDependenciesConfig. # noqa: E501 + :type git: List[GitDependencyConfig] + """ + self.openapi_types = { + 'hard': List[str], + 'soft': List[str], + 'build': List[str], + 'git': List[GitDependencyConfig] + } + + self.attribute_map = { + 'hard': 'hard', + 'soft': 'soft', + 'build': 'build', + 'git': 'git' + } + + self._hard = hard + self._soft = soft + self._build = build + self._git = git -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + @classmethod + def from_dict(cls, dikt) -> 'ApplicationDependenciesConfig': + """Returns the dict as a model -from typing import Optional, Set -from typing_extensions import Self + :param dikt: A dict. + :type: dict + :return: The ApplicationDependenciesConfig of this ApplicationDependenciesConfig. # noqa: E501 + :rtype: ApplicationDependenciesConfig + """ + return util.deserialize_model(dikt, cls) + @property + def hard(self) -> List[str]: + """Gets the hard of this ApplicationDependenciesConfig. -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib -from cloudharness_model.models.git_dependency_config import GitDependencyConfig + Hard dependencies indicate that the application may not start without these other applications. # noqa: E501 -class ApplicationDependenciesConfig(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - hard: Optional[List[StrictStr]] = Field(default=None, description="Hard dependencies indicate that the application may not start without these other applications.") - soft: Optional[List[StrictStr]] = Field(default=None, description="Soft dependencies indicate that the application will work partially without these other applications.") - build: Optional[List[StrictStr]] = Field(default=None, description="Hard dependencies indicate that the application Docker image build requires these base/common images") - git: Optional[List[GitDependencyConfig]] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["hard", "soft", "build", "git"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :return: The hard of this ApplicationDependenciesConfig. + :rtype: List[str] """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # override the default output from pydantic by calling `to_dict()` of each item in git (list) - _items = [] - if self.git: - for _item_git in self.git: - if _item_git: - _items.append(_item_git.to_dict()) - _dict['git'] = _items - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + return self._hard - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of ApplicationDependenciesConfig from a dict""" - if obj is None: - return None + @hard.setter + def hard(self, hard: List[str]): + """Sets the hard of this ApplicationDependenciesConfig. - if not isinstance(obj, dict): - return cls.model_validate(obj) + Hard dependencies indicate that the application may not start without these other applications. # noqa: E501 - _obj = cls.model_validate({ - "hard": obj.get("hard"), - "soft": obj.get("soft"), - "build": obj.get("build"), - "git": [GitDependencyConfig.from_dict(_item) for _item in obj["git"]] if obj.get("git") is not None else None - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + :param hard: The hard of this ApplicationDependenciesConfig. + :type hard: List[str] + """ + + self._hard = hard + + @property + def soft(self) -> List[str]: + """Gets the soft of this ApplicationDependenciesConfig. - return _obj + Soft dependencies indicate that the application will work partially without these other applications. # noqa: E501 + + :return: The soft of this ApplicationDependenciesConfig. + :rtype: List[str] + """ + return self._soft + + @soft.setter + def soft(self, soft: List[str]): + """Sets the soft of this ApplicationDependenciesConfig. + + Soft dependencies indicate that the application will work partially without these other applications. # noqa: E501 + + :param soft: The soft of this ApplicationDependenciesConfig. + :type soft: List[str] + """ + self._soft = soft + + @property + def build(self) -> List[str]: + """Gets the build of this ApplicationDependenciesConfig. + + Hard dependencies indicate that the application Docker image build requires these base/common images # noqa: E501 + + :return: The build of this ApplicationDependenciesConfig. + :rtype: List[str] + """ + return self._build + + @build.setter + def build(self, build: List[str]): + """Sets the build of this ApplicationDependenciesConfig. + + Hard dependencies indicate that the application Docker image build requires these base/common images # noqa: E501 + + :param build: The build of this ApplicationDependenciesConfig. + :type build: List[str] + """ + + self._build = build + + @property + def git(self) -> List[GitDependencyConfig]: + """Gets the git of this ApplicationDependenciesConfig. + + # noqa: E501 + + :return: The git of this ApplicationDependenciesConfig. + :rtype: List[GitDependencyConfig] + """ + return self._git + + @git.setter + def git(self, git: List[GitDependencyConfig]): + """Sets the git of this ApplicationDependenciesConfig. + + # noqa: E501 + + :param git: The git of this ApplicationDependenciesConfig. + :type git: List[GitDependencyConfig] + """ + self._git = git diff --git a/libraries/models/cloudharness_model/models/application_harness_config.py b/libraries/models/cloudharness_model/models/application_harness_config.py index 5fd4473f2..264b0ebcd 100644 --- a/libraries/models/cloudharness_model/models/application_harness_config.py +++ b/libraries/models/cloudharness_model/models/application_harness_config.py @@ -1,30 +1,8 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) - - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -from __future__ import annotations -import pprint -import re # noqa: F401 -import json - -from typing import Optional, Set -from typing_extensions import Self - - -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib +from cloudharness_model.models.base_model_ import Model from cloudharness_model.models.application_accounts_config import ApplicationAccountsConfig from cloudharness_model.models.application_dependencies_config import ApplicationDependenciesConfig from cloudharness_model.models.application_probe import ApplicationProbe @@ -35,192 +13,701 @@ from cloudharness_model.models.file_resources_config import FileResourcesConfig from cloudharness_model.models.jupyter_hub_config import JupyterHubConfig from cloudharness_model.models.name_value import NameValue -from cloudharness_model.models.named_object import NamedObject -from cloudharness_model.models.proxy_conf import ProxyConf from cloudharness_model.models.service_auto_artifact_config import ServiceAutoArtifactConfig from cloudharness_model.models.uri_role_mapping_config import UriRoleMappingConfig +import re +from cloudharness_model import util -class ApplicationHarnessConfig(CloudHarnessBaseModel): +from cloudharness_model.models.application_accounts_config import ApplicationAccountsConfig # noqa: E501 +from cloudharness_model.models.application_dependencies_config import ApplicationDependenciesConfig # noqa: E501 +from cloudharness_model.models.application_probe import ApplicationProbe # noqa: E501 +from cloudharness_model.models.application_test_config import ApplicationTestConfig # noqa: E501 +from cloudharness_model.models.database_deployment_config import DatabaseDeploymentConfig # noqa: E501 +from cloudharness_model.models.deployment_auto_artifact_config import DeploymentAutoArtifactConfig # noqa: E501 +from cloudharness_model.models.dockerfile_config import DockerfileConfig # noqa: E501 +from cloudharness_model.models.file_resources_config import FileResourcesConfig # noqa: E501 +from cloudharness_model.models.jupyter_hub_config import JupyterHubConfig # noqa: E501 +from cloudharness_model.models.name_value import NameValue # noqa: E501 +from cloudharness_model.models.service_auto_artifact_config import ServiceAutoArtifactConfig # noqa: E501 +from cloudharness_model.models.uri_role_mapping_config import UriRoleMappingConfig # noqa: E501 +import re # noqa: E501 + +class ApplicationHarnessConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). + + Do not edit the class manually. """ - Define helm variables that allow CloudHarness to enable and configure your application's deployment - """ # noqa: E501 - deployment: Optional[DeploymentAutoArtifactConfig] = None - service: Optional[ServiceAutoArtifactConfig] = None - subdomain: Optional[StrictStr] = Field(default=None, description="If specified, an ingress will be created at [subdomain].[.Values.domain]") - aliases: Optional[List[StrictStr]] = Field(default=None, description="If specified, an ingress will be created at [alias].[.Values.domain] for each alias") - domain: Optional[StrictStr] = Field(default=None, description="If specified, an ingress will be created at [domain]") - dependencies: Optional[ApplicationDependenciesConfig] = None - secured: Optional[Any] = Field(default=None, description="When true, the application is shielded with a getekeeper") - uri_role_mapping: Optional[List[UriRoleMappingConfig]] = Field(default=None, description="Map uri/roles to secure with the Gatekeeper (if `secured: true`)") - secrets: Optional[Dict[str, Any]] = None - use_services: Optional[List[NamedObject]] = Field(default=None, description="Specify which services this application uses in the frontend to create proxy ingresses. e.g. ``` - name: samples ```") - database: Optional[DatabaseDeploymentConfig] = None - resources: Optional[List[FileResourcesConfig]] = Field(default=None, description="Application file resources. Maps from deploy/resources folder and mounts as configmaps") - readiness_probe: Optional[ApplicationProbe] = Field(default=None, alias="readinessProbe") - startup_probe: Optional[ApplicationProbe] = Field(default=None, alias="startupProbe") - liveness_probe: Optional[ApplicationProbe] = Field(default=None, alias="livenessProbe") - source_root: Optional[Annotated[str, Field(strict=True)]] = Field(default=None, alias="sourceRoot") - name: Optional[StrictStr] = Field(default=None, description="Application's name. Do not edit, the value is automatically set from the application directory's name") - jupyterhub: Optional[JupyterHubConfig] = None - accounts: Optional[ApplicationAccountsConfig] = None - test: Optional[ApplicationTestConfig] = None - quotas: Optional[Dict[str, Any]] = None - env: Optional[List[NameValue]] = Field(default=None, description="Environmental variables added to all containers (deprecated, please use envmap)") - envmap: Optional[Dict[str, Any]] = None - dockerfile: Optional[DockerfileConfig] = None - sentry: Optional[StrictBool] = None - proxy: Optional[ProxyConf] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["deployment", "service", "subdomain", "aliases", "domain", "dependencies", "secured", "uri_role_mapping", "secrets", "use_services", "database", "resources", "readinessProbe", "startupProbe", "livenessProbe", "sourceRoot", "name", "jupyterhub", "accounts", "test", "quotas", "env", "envmap", "dockerfile", "sentry", "proxy"] - - @field_validator('source_root') - def source_root_validate_regular_expression(cls, value): - """Validates the regular expression""" - if value is None: - return value - - if not re.match(r"^[^<>:;,?*|]+$", value): - raise ValueError(r"must validate the regular expression /^[^<>:;,?*|]+$/") - return value - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # override the default output from pydantic by calling `to_dict()` of deployment - if self.deployment: - _dict['deployment'] = self.deployment.to_dict() - # override the default output from pydantic by calling `to_dict()` of service - if self.service: - _dict['service'] = self.service.to_dict() - # override the default output from pydantic by calling `to_dict()` of dependencies - if self.dependencies: - _dict['dependencies'] = self.dependencies.to_dict() - # override the default output from pydantic by calling `to_dict()` of each item in uri_role_mapping (list) - _items = [] - if self.uri_role_mapping: - for _item_uri_role_mapping in self.uri_role_mapping: - if _item_uri_role_mapping: - _items.append(_item_uri_role_mapping.to_dict()) - _dict['uri_role_mapping'] = _items - # override the default output from pydantic by calling `to_dict()` of each item in use_services (list) - _items = [] - if self.use_services: - for _item_use_services in self.use_services: - if _item_use_services: - _items.append(_item_use_services.to_dict()) - _dict['use_services'] = _items - # override the default output from pydantic by calling `to_dict()` of database - if self.database: - _dict['database'] = self.database.to_dict() - # override the default output from pydantic by calling `to_dict()` of each item in resources (list) - _items = [] - if self.resources: - for _item_resources in self.resources: - if _item_resources: - _items.append(_item_resources.to_dict()) - _dict['resources'] = _items - # override the default output from pydantic by calling `to_dict()` of readiness_probe - if self.readiness_probe: - _dict['readinessProbe'] = self.readiness_probe.to_dict() - # override the default output from pydantic by calling `to_dict()` of startup_probe - if self.startup_probe: - _dict['startupProbe'] = self.startup_probe.to_dict() - # override the default output from pydantic by calling `to_dict()` of liveness_probe - if self.liveness_probe: - _dict['livenessProbe'] = self.liveness_probe.to_dict() - # override the default output from pydantic by calling `to_dict()` of jupyterhub - if self.jupyterhub: - _dict['jupyterhub'] = self.jupyterhub.to_dict() - # override the default output from pydantic by calling `to_dict()` of accounts - if self.accounts: - _dict['accounts'] = self.accounts.to_dict() - # override the default output from pydantic by calling `to_dict()` of test - if self.test: - _dict['test'] = self.test.to_dict() - # override the default output from pydantic by calling `to_dict()` of each item in env (list) - _items = [] - if self.env: - for _item_env in self.env: - if _item_env: - _items.append(_item_env.to_dict()) - _dict['env'] = _items - # override the default output from pydantic by calling `to_dict()` of dockerfile - if self.dockerfile: - _dict['dockerfile'] = self.dockerfile.to_dict() - # override the default output from pydantic by calling `to_dict()` of proxy - if self.proxy: - _dict['proxy'] = self.proxy.to_dict() - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - # set to None if secured (nullable) is None - # and model_fields_set contains the field - if self.secured is None and "secured" in self.model_fields_set: - _dict['secured'] = None - - return _dict + + def __init__(self, deployment=None, service=None, subdomain=None, aliases=None, domain=None, dependencies=None, secured=None, uri_role_mapping=None, secrets=None, use_services=None, database=None, resources=None, readiness_probe=None, startup_probe=None, liveness_probe=None, source_root=None, name=None, jupyterhub=None, accounts=None, test=None, quotas=None, env=None, envmap=None, dockerfile=None): # noqa: E501 + """ApplicationHarnessConfig - a model defined in OpenAPI + + :param deployment: The deployment of this ApplicationHarnessConfig. # noqa: E501 + :type deployment: DeploymentAutoArtifactConfig + :param service: The service of this ApplicationHarnessConfig. # noqa: E501 + :type service: ServiceAutoArtifactConfig + :param subdomain: The subdomain of this ApplicationHarnessConfig. # noqa: E501 + :type subdomain: str + :param aliases: The aliases of this ApplicationHarnessConfig. # noqa: E501 + :type aliases: List[str] + :param domain: The domain of this ApplicationHarnessConfig. # noqa: E501 + :type domain: str + :param dependencies: The dependencies of this ApplicationHarnessConfig. # noqa: E501 + :type dependencies: ApplicationDependenciesConfig + :param secured: The secured of this ApplicationHarnessConfig. # noqa: E501 + :type secured: bool + :param uri_role_mapping: The uri_role_mapping of this ApplicationHarnessConfig. # noqa: E501 + :type uri_role_mapping: List[UriRoleMappingConfig] + :param secrets: The secrets of this ApplicationHarnessConfig. # noqa: E501 + :type secrets: Dict[str, object] + :param use_services: The use_services of this ApplicationHarnessConfig. # noqa: E501 + :type use_services: List[str] + :param database: The database of this ApplicationHarnessConfig. # noqa: E501 + :type database: DatabaseDeploymentConfig + :param resources: The resources of this ApplicationHarnessConfig. # noqa: E501 + :type resources: List[FileResourcesConfig] + :param readiness_probe: The readiness_probe of this ApplicationHarnessConfig. # noqa: E501 + :type readiness_probe: ApplicationProbe + :param startup_probe: The startup_probe of this ApplicationHarnessConfig. # noqa: E501 + :type startup_probe: ApplicationProbe + :param liveness_probe: The liveness_probe of this ApplicationHarnessConfig. # noqa: E501 + :type liveness_probe: ApplicationProbe + :param source_root: The source_root of this ApplicationHarnessConfig. # noqa: E501 + :type source_root: str + :param name: The name of this ApplicationHarnessConfig. # noqa: E501 + :type name: str + :param jupyterhub: The jupyterhub of this ApplicationHarnessConfig. # noqa: E501 + :type jupyterhub: JupyterHubConfig + :param accounts: The accounts of this ApplicationHarnessConfig. # noqa: E501 + :type accounts: ApplicationAccountsConfig + :param test: The test of this ApplicationHarnessConfig. # noqa: E501 + :type test: ApplicationTestConfig + :param quotas: The quotas of this ApplicationHarnessConfig. # noqa: E501 + :type quotas: Dict[str, object] + :param env: The env of this ApplicationHarnessConfig. # noqa: E501 + :type env: List[NameValue] + :param envmap: The envmap of this ApplicationHarnessConfig. # noqa: E501 + :type envmap: Dict[str, object] + :param dockerfile: The dockerfile of this ApplicationHarnessConfig. # noqa: E501 + :type dockerfile: DockerfileConfig + """ + self.openapi_types = { + 'deployment': DeploymentAutoArtifactConfig, + 'service': ServiceAutoArtifactConfig, + 'subdomain': str, + 'aliases': List[str], + 'domain': str, + 'dependencies': ApplicationDependenciesConfig, + 'secured': bool, + 'uri_role_mapping': List[UriRoleMappingConfig], + 'secrets': Dict[str, object], + 'use_services': List[str], + 'database': DatabaseDeploymentConfig, + 'resources': List[FileResourcesConfig], + 'readiness_probe': ApplicationProbe, + 'startup_probe': ApplicationProbe, + 'liveness_probe': ApplicationProbe, + 'source_root': str, + 'name': str, + 'jupyterhub': JupyterHubConfig, + 'accounts': ApplicationAccountsConfig, + 'test': ApplicationTestConfig, + 'quotas': Dict[str, object], + 'env': List[NameValue], + 'envmap': Dict[str, object], + 'dockerfile': DockerfileConfig + } + + self.attribute_map = { + 'deployment': 'deployment', + 'service': 'service', + 'subdomain': 'subdomain', + 'aliases': 'aliases', + 'domain': 'domain', + 'dependencies': 'dependencies', + 'secured': 'secured', + 'uri_role_mapping': 'uri_role_mapping', + 'secrets': 'secrets', + 'use_services': 'use_services', + 'database': 'database', + 'resources': 'resources', + 'readiness_probe': 'readinessProbe', + 'startup_probe': 'startupProbe', + 'liveness_probe': 'livenessProbe', + 'source_root': 'sourceRoot', + 'name': 'name', + 'jupyterhub': 'jupyterhub', + 'accounts': 'accounts', + 'test': 'test', + 'quotas': 'quotas', + 'env': 'env', + 'envmap': 'envmap', + 'dockerfile': 'dockerfile' + } + + self._deployment = deployment + self._service = service + self._subdomain = subdomain + self._aliases = aliases + self._domain = domain + self._dependencies = dependencies + self._secured = secured + self._uri_role_mapping = uri_role_mapping + self._secrets = secrets + self._use_services = use_services + self._database = database + self._resources = resources + self._readiness_probe = readiness_probe + self._startup_probe = startup_probe + self._liveness_probe = liveness_probe + self._source_root = source_root + self._name = name + self._jupyterhub = jupyterhub + self._accounts = accounts + self._test = test + self._quotas = quotas + self._env = env + self._envmap = envmap + self._dockerfile = dockerfile @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of ApplicationHarnessConfig from a dict""" - if obj is None: - return None - - if not isinstance(obj, dict): - return cls.model_validate(obj) - - _obj = cls.model_validate({ - "deployment": DeploymentAutoArtifactConfig.from_dict(obj["deployment"]) if obj.get("deployment") is not None else None, - "service": ServiceAutoArtifactConfig.from_dict(obj["service"]) if obj.get("service") is not None else None, - "subdomain": obj.get("subdomain"), - "aliases": obj.get("aliases"), - "domain": obj.get("domain"), - "dependencies": ApplicationDependenciesConfig.from_dict(obj["dependencies"]) if obj.get("dependencies") is not None else None, - "secured": obj.get("secured"), - "uri_role_mapping": [UriRoleMappingConfig.from_dict(_item) for _item in obj["uri_role_mapping"]] if obj.get("uri_role_mapping") is not None else None, - "secrets": obj.get("secrets"), - "use_services": [NamedObject.from_dict(_item) for _item in obj["use_services"]] if obj.get("use_services") is not None else None, - "database": DatabaseDeploymentConfig.from_dict(obj["database"]) if obj.get("database") is not None else None, - "resources": [FileResourcesConfig.from_dict(_item) for _item in obj["resources"]] if obj.get("resources") is not None else None, - "readinessProbe": ApplicationProbe.from_dict(obj["readinessProbe"]) if obj.get("readinessProbe") is not None else None, - "startupProbe": ApplicationProbe.from_dict(obj["startupProbe"]) if obj.get("startupProbe") is not None else None, - "livenessProbe": ApplicationProbe.from_dict(obj["livenessProbe"]) if obj.get("livenessProbe") is not None else None, - "sourceRoot": obj.get("sourceRoot"), - "name": obj.get("name"), - "jupyterhub": JupyterHubConfig.from_dict(obj["jupyterhub"]) if obj.get("jupyterhub") is not None else None, - "accounts": ApplicationAccountsConfig.from_dict(obj["accounts"]) if obj.get("accounts") is not None else None, - "test": ApplicationTestConfig.from_dict(obj["test"]) if obj.get("test") is not None else None, - "quotas": obj.get("quotas"), - "env": [NameValue.from_dict(_item) for _item in obj["env"]] if obj.get("env") is not None else None, - "envmap": obj.get("envmap"), - "dockerfile": DockerfileConfig.from_dict(obj["dockerfile"]) if obj.get("dockerfile") is not None else None, - "sentry": obj.get("sentry"), - "proxy": ProxyConf.from_dict(obj["proxy"]) if obj.get("proxy") is not None else None - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj + def from_dict(cls, dikt) -> 'ApplicationHarnessConfig': + """Returns the dict as a model + + :param dikt: A dict. + :type: dict + :return: The ApplicationHarnessConfig of this ApplicationHarnessConfig. # noqa: E501 + :rtype: ApplicationHarnessConfig + """ + return util.deserialize_model(dikt, cls) + + @property + def deployment(self) -> DeploymentAutoArtifactConfig: + """Gets the deployment of this ApplicationHarnessConfig. + + + :return: The deployment of this ApplicationHarnessConfig. + :rtype: DeploymentAutoArtifactConfig + """ + return self._deployment + + @deployment.setter + def deployment(self, deployment: DeploymentAutoArtifactConfig): + """Sets the deployment of this ApplicationHarnessConfig. + + + :param deployment: The deployment of this ApplicationHarnessConfig. + :type deployment: DeploymentAutoArtifactConfig + """ + + self._deployment = deployment + + @property + def service(self) -> ServiceAutoArtifactConfig: + """Gets the service of this ApplicationHarnessConfig. + + + :return: The service of this ApplicationHarnessConfig. + :rtype: ServiceAutoArtifactConfig + """ + return self._service + + @service.setter + def service(self, service: ServiceAutoArtifactConfig): + """Sets the service of this ApplicationHarnessConfig. + + + :param service: The service of this ApplicationHarnessConfig. + :type service: ServiceAutoArtifactConfig + """ + + self._service = service + + @property + def subdomain(self) -> str: + """Gets the subdomain of this ApplicationHarnessConfig. + + If specified, an ingress will be created at [subdomain].[.Values.domain] # noqa: E501 + + :return: The subdomain of this ApplicationHarnessConfig. + :rtype: str + """ + return self._subdomain + + @subdomain.setter + def subdomain(self, subdomain: str): + """Sets the subdomain of this ApplicationHarnessConfig. + + If specified, an ingress will be created at [subdomain].[.Values.domain] # noqa: E501 + + :param subdomain: The subdomain of this ApplicationHarnessConfig. + :type subdomain: str + """ + + self._subdomain = subdomain + + @property + def aliases(self) -> List[str]: + """Gets the aliases of this ApplicationHarnessConfig. + + If specified, an ingress will be created at [alias].[.Values.domain] for each alias # noqa: E501 + + :return: The aliases of this ApplicationHarnessConfig. + :rtype: List[str] + """ + return self._aliases + + @aliases.setter + def aliases(self, aliases: List[str]): + """Sets the aliases of this ApplicationHarnessConfig. + + If specified, an ingress will be created at [alias].[.Values.domain] for each alias # noqa: E501 + + :param aliases: The aliases of this ApplicationHarnessConfig. + :type aliases: List[str] + """ + + self._aliases = aliases + + @property + def domain(self) -> str: + """Gets the domain of this ApplicationHarnessConfig. + + If specified, an ingress will be created at [domain] # noqa: E501 + + :return: The domain of this ApplicationHarnessConfig. + :rtype: str + """ + return self._domain + + @domain.setter + def domain(self, domain: str): + """Sets the domain of this ApplicationHarnessConfig. + + If specified, an ingress will be created at [domain] # noqa: E501 + + :param domain: The domain of this ApplicationHarnessConfig. + :type domain: str + """ + + self._domain = domain + + @property + def dependencies(self) -> ApplicationDependenciesConfig: + """Gets the dependencies of this ApplicationHarnessConfig. + + + :return: The dependencies of this ApplicationHarnessConfig. + :rtype: ApplicationDependenciesConfig + """ + return self._dependencies + + @dependencies.setter + def dependencies(self, dependencies: ApplicationDependenciesConfig): + """Sets the dependencies of this ApplicationHarnessConfig. + + + :param dependencies: The dependencies of this ApplicationHarnessConfig. + :type dependencies: ApplicationDependenciesConfig + """ + + self._dependencies = dependencies + + @property + def secured(self) -> bool: + """Gets the secured of this ApplicationHarnessConfig. + + When true, the application is shielded with a getekeeper # noqa: E501 + + :return: The secured of this ApplicationHarnessConfig. + :rtype: bool + """ + return self._secured + + @secured.setter + def secured(self, secured: bool): + """Sets the secured of this ApplicationHarnessConfig. + + When true, the application is shielded with a getekeeper # noqa: E501 + + :param secured: The secured of this ApplicationHarnessConfig. + :type secured: bool + """ + + self._secured = secured + + @property + def uri_role_mapping(self) -> List[UriRoleMappingConfig]: + """Gets the uri_role_mapping of this ApplicationHarnessConfig. + + Map uri/roles to secure with the Gatekeeper (if `secured: true`) # noqa: E501 + + :return: The uri_role_mapping of this ApplicationHarnessConfig. + :rtype: List[UriRoleMappingConfig] + """ + return self._uri_role_mapping + + @uri_role_mapping.setter + def uri_role_mapping(self, uri_role_mapping: List[UriRoleMappingConfig]): + """Sets the uri_role_mapping of this ApplicationHarnessConfig. + + Map uri/roles to secure with the Gatekeeper (if `secured: true`) # noqa: E501 + + :param uri_role_mapping: The uri_role_mapping of this ApplicationHarnessConfig. + :type uri_role_mapping: List[UriRoleMappingConfig] + """ + + self._uri_role_mapping = uri_role_mapping + + @property + def secrets(self) -> Dict[str, object]: + """Gets the secrets of this ApplicationHarnessConfig. + + # noqa: E501 + + :return: The secrets of this ApplicationHarnessConfig. + :rtype: Dict[str, object] + """ + return self._secrets + + @secrets.setter + def secrets(self, secrets: Dict[str, object]): + """Sets the secrets of this ApplicationHarnessConfig. + + # noqa: E501 + + :param secrets: The secrets of this ApplicationHarnessConfig. + :type secrets: Dict[str, object] + """ + + self._secrets = secrets + + @property + def use_services(self) -> List[str]: + """Gets the use_services of this ApplicationHarnessConfig. + + Specify which services this application uses in the frontend to create proxy ingresses. e.g. ``` - name: samples ``` # noqa: E501 + + :return: The use_services of this ApplicationHarnessConfig. + :rtype: List[str] + """ + return self._use_services + + @use_services.setter + def use_services(self, use_services: List[str]): + """Sets the use_services of this ApplicationHarnessConfig. + + Specify which services this application uses in the frontend to create proxy ingresses. e.g. ``` - name: samples ``` # noqa: E501 + + :param use_services: The use_services of this ApplicationHarnessConfig. + :type use_services: List[str] + """ + + self._use_services = use_services + + @property + def database(self) -> DatabaseDeploymentConfig: + """Gets the database of this ApplicationHarnessConfig. + + + :return: The database of this ApplicationHarnessConfig. + :rtype: DatabaseDeploymentConfig + """ + return self._database + + @database.setter + def database(self, database: DatabaseDeploymentConfig): + """Sets the database of this ApplicationHarnessConfig. + + + :param database: The database of this ApplicationHarnessConfig. + :type database: DatabaseDeploymentConfig + """ + self._database = database + + @property + def resources(self) -> List[FileResourcesConfig]: + """Gets the resources of this ApplicationHarnessConfig. + + Application file resources. Maps from deploy/resources folder and mounts as configmaps # noqa: E501 + + :return: The resources of this ApplicationHarnessConfig. + :rtype: List[FileResourcesConfig] + """ + return self._resources + + @resources.setter + def resources(self, resources: List[FileResourcesConfig]): + """Sets the resources of this ApplicationHarnessConfig. + + Application file resources. Maps from deploy/resources folder and mounts as configmaps # noqa: E501 + + :param resources: The resources of this ApplicationHarnessConfig. + :type resources: List[FileResourcesConfig] + """ + + self._resources = resources + + @property + def readiness_probe(self) -> ApplicationProbe: + """Gets the readiness_probe of this ApplicationHarnessConfig. + + + :return: The readiness_probe of this ApplicationHarnessConfig. + :rtype: ApplicationProbe + """ + return self._readiness_probe + + @readiness_probe.setter + def readiness_probe(self, readiness_probe: ApplicationProbe): + """Sets the readiness_probe of this ApplicationHarnessConfig. + + + :param readiness_probe: The readiness_probe of this ApplicationHarnessConfig. + :type readiness_probe: ApplicationProbe + """ + + self._readiness_probe = readiness_probe + + @property + def startup_probe(self) -> ApplicationProbe: + """Gets the startup_probe of this ApplicationHarnessConfig. + + + :return: The startup_probe of this ApplicationHarnessConfig. + :rtype: ApplicationProbe + """ + return self._startup_probe + + @startup_probe.setter + def startup_probe(self, startup_probe: ApplicationProbe): + """Sets the startup_probe of this ApplicationHarnessConfig. + + + :param startup_probe: The startup_probe of this ApplicationHarnessConfig. + :type startup_probe: ApplicationProbe + """ + + self._startup_probe = startup_probe + + @property + def liveness_probe(self) -> ApplicationProbe: + """Gets the liveness_probe of this ApplicationHarnessConfig. + + + :return: The liveness_probe of this ApplicationHarnessConfig. + :rtype: ApplicationProbe + """ + return self._liveness_probe + + @liveness_probe.setter + def liveness_probe(self, liveness_probe: ApplicationProbe): + """Sets the liveness_probe of this ApplicationHarnessConfig. + + + :param liveness_probe: The liveness_probe of this ApplicationHarnessConfig. + :type liveness_probe: ApplicationProbe + """ + + self._liveness_probe = liveness_probe + + @property + def source_root(self) -> str: + """Gets the source_root of this ApplicationHarnessConfig. + + # noqa: E501 + + :return: The source_root of this ApplicationHarnessConfig. + :rtype: str + """ + return self._source_root + + @source_root.setter + def source_root(self, source_root: str): + """Sets the source_root of this ApplicationHarnessConfig. + + # noqa: E501 + + :param source_root: The source_root of this ApplicationHarnessConfig. + :type source_root: str + """ + if source_root is not None and not re.search(r'^[^<>:;,?*|]+$', source_root): # noqa: E501 + raise ValueError("Invalid value for `source_root`, must be a follow pattern or equal to `/^[^<>:;,?*|]+$/`") # noqa: E501 + + self._source_root = source_root + + @property + def name(self) -> str: + """Gets the name of this ApplicationHarnessConfig. + + Application's name. Do not edit, the value is automatically set from the application directory's name # noqa: E501 + + :return: The name of this ApplicationHarnessConfig. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name: str): + """Sets the name of this ApplicationHarnessConfig. + + Application's name. Do not edit, the value is automatically set from the application directory's name # noqa: E501 + + :param name: The name of this ApplicationHarnessConfig. + :type name: str + """ + + self._name = name + + @property + def jupyterhub(self) -> JupyterHubConfig: + """Gets the jupyterhub of this ApplicationHarnessConfig. + + + :return: The jupyterhub of this ApplicationHarnessConfig. + :rtype: JupyterHubConfig + """ + return self._jupyterhub + + @jupyterhub.setter + def jupyterhub(self, jupyterhub: JupyterHubConfig): + """Sets the jupyterhub of this ApplicationHarnessConfig. + + + :param jupyterhub: The jupyterhub of this ApplicationHarnessConfig. + :type jupyterhub: JupyterHubConfig + """ + + self._jupyterhub = jupyterhub + + @property + def accounts(self) -> ApplicationAccountsConfig: + """Gets the accounts of this ApplicationHarnessConfig. + + + :return: The accounts of this ApplicationHarnessConfig. + :rtype: ApplicationAccountsConfig + """ + return self._accounts + + @accounts.setter + def accounts(self, accounts: ApplicationAccountsConfig): + """Sets the accounts of this ApplicationHarnessConfig. + + + :param accounts: The accounts of this ApplicationHarnessConfig. + :type accounts: ApplicationAccountsConfig + """ + + self._accounts = accounts + + @property + def test(self) -> ApplicationTestConfig: + """Gets the test of this ApplicationHarnessConfig. + + + :return: The test of this ApplicationHarnessConfig. + :rtype: ApplicationTestConfig + """ + return self._test + + @test.setter + def test(self, test: ApplicationTestConfig): + """Sets the test of this ApplicationHarnessConfig. + + + :param test: The test of this ApplicationHarnessConfig. + :type test: ApplicationTestConfig + """ + + self._test = test + + @property + def quotas(self) -> Dict[str, object]: + """Gets the quotas of this ApplicationHarnessConfig. + + # noqa: E501 + + :return: The quotas of this ApplicationHarnessConfig. + :rtype: Dict[str, object] + """ + return self._quotas + + @quotas.setter + def quotas(self, quotas: Dict[str, object]): + """Sets the quotas of this ApplicationHarnessConfig. + + # noqa: E501 + + :param quotas: The quotas of this ApplicationHarnessConfig. + :type quotas: Dict[str, object] + """ + + self._quotas = quotas + + @property + def env(self) -> List[NameValue]: + """Gets the env of this ApplicationHarnessConfig. + + Environmental variables added to all containers (deprecated, please use envmap) # noqa: E501 + + :return: The env of this ApplicationHarnessConfig. + :rtype: List[NameValue] + """ + return self._env + + @env.setter + def env(self, env: List[NameValue]): + """Sets the env of this ApplicationHarnessConfig. + + Environmental variables added to all containers (deprecated, please use envmap) # noqa: E501 + + :param env: The env of this ApplicationHarnessConfig. + :type env: List[NameValue] + """ + + self._env = env + + @property + def envmap(self) -> Dict[str, object]: + """Gets the envmap of this ApplicationHarnessConfig. + + # noqa: E501 + + :return: The envmap of this ApplicationHarnessConfig. + :rtype: Dict[str, object] + """ + return self._envmap + + @envmap.setter + def envmap(self, envmap: Dict[str, object]): + """Sets the envmap of this ApplicationHarnessConfig. + + # noqa: E501 + + :param envmap: The envmap of this ApplicationHarnessConfig. + :type envmap: Dict[str, object] + """ + + self._envmap = envmap + + @property + def dockerfile(self) -> DockerfileConfig: + """Gets the dockerfile of this ApplicationHarnessConfig. + + + :return: The dockerfile of this ApplicationHarnessConfig. + :rtype: DockerfileConfig + """ + return self._dockerfile + + @dockerfile.setter + def dockerfile(self, dockerfile: DockerfileConfig): + """Sets the dockerfile of this ApplicationHarnessConfig. + + + :param dockerfile: The dockerfile of this ApplicationHarnessConfig. + :type dockerfile: DockerfileConfig + """ + self._dockerfile = dockerfile diff --git a/libraries/models/cloudharness_model/models/application_probe.py b/libraries/models/cloudharness_model/models/application_probe.py index fec6a7086..70a67906b 100644 --- a/libraries/models/cloudharness_model/models/application_probe.py +++ b/libraries/models/cloudharness_model/models/application_probe.py @@ -1,91 +1,177 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model import util - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) + +class ApplicationProbe(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, path=None, period_seconds=None, failure_threshold=None, initial_delay_seconds=None, port=None): # noqa: E501 + """ApplicationProbe - a model defined in OpenAPI + + :param path: The path of this ApplicationProbe. # noqa: E501 + :type path: str + :param period_seconds: The period_seconds of this ApplicationProbe. # noqa: E501 + :type period_seconds: float + :param failure_threshold: The failure_threshold of this ApplicationProbe. # noqa: E501 + :type failure_threshold: float + :param initial_delay_seconds: The initial_delay_seconds of this ApplicationProbe. # noqa: E501 + :type initial_delay_seconds: float + :param port: The port of this ApplicationProbe. # noqa: E501 + :type port: float + """ + self.openapi_types = { + 'path': str, + 'period_seconds': float, + 'failure_threshold': float, + 'initial_delay_seconds': float, + 'port': float + } + + self.attribute_map = { + 'path': 'path', + 'period_seconds': 'periodSeconds', + 'failure_threshold': 'failureThreshold', + 'initial_delay_seconds': 'initialDelaySeconds', + 'port': 'port' + } + + self._path = path + self._period_seconds = period_seconds + self._failure_threshold = failure_threshold + self._initial_delay_seconds = initial_delay_seconds + self._port = port -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + @classmethod + def from_dict(cls, dikt) -> 'ApplicationProbe': + """Returns the dict as a model -from typing import Optional, Set -from typing_extensions import Self + :param dikt: A dict. + :type: dict + :return: The ApplicationProbe of this ApplicationProbe. # noqa: E501 + :rtype: ApplicationProbe + """ + return util.deserialize_model(dikt, cls) + @property + def path(self) -> str: + """Gets the path of this ApplicationProbe. -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib + # noqa: E501 -class ApplicationProbe(CloudHarnessBaseModel): - """ - Define a Kubernetes probe See also the [official documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) - """ # noqa: E501 - path: StrictStr - period_seconds: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, alias="periodSeconds") - failure_threshold: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, alias="failureThreshold") - initial_delay_seconds: Optional[Union[StrictFloat, StrictInt]] = Field(default=None, alias="initialDelaySeconds") - port: Optional[Union[StrictFloat, StrictInt]] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["path", "periodSeconds", "failureThreshold", "initialDelaySeconds", "port"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :return: The path of this ApplicationProbe. + :rtype: str """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + return self._path - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of ApplicationProbe from a dict""" - if obj is None: - return None + @path.setter + def path(self, path: str): + """Sets the path of this ApplicationProbe. + + # noqa: E501 + + :param path: The path of this ApplicationProbe. + :type path: str + """ + if path is None: + raise ValueError("Invalid value for `path`, must not be `None`") # noqa: E501 + + self._path = path + + @property + def period_seconds(self) -> float: + """Gets the period_seconds of this ApplicationProbe. + + # noqa: E501 + + :return: The period_seconds of this ApplicationProbe. + :rtype: float + """ + return self._period_seconds + + @period_seconds.setter + def period_seconds(self, period_seconds: float): + """Sets the period_seconds of this ApplicationProbe. + + # noqa: E501 + + :param period_seconds: The period_seconds of this ApplicationProbe. + :type period_seconds: float + """ + + self._period_seconds = period_seconds + + @property + def failure_threshold(self) -> float: + """Gets the failure_threshold of this ApplicationProbe. - if not isinstance(obj, dict): - return cls.model_validate(obj) + # noqa: E501 - _obj = cls.model_validate({ - "path": obj.get("path"), - "periodSeconds": obj.get("periodSeconds"), - "failureThreshold": obj.get("failureThreshold"), - "initialDelaySeconds": obj.get("initialDelaySeconds"), - "port": obj.get("port") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + :return: The failure_threshold of this ApplicationProbe. + :rtype: float + """ + return self._failure_threshold + + @failure_threshold.setter + def failure_threshold(self, failure_threshold: float): + """Sets the failure_threshold of this ApplicationProbe. + + # noqa: E501 + + :param failure_threshold: The failure_threshold of this ApplicationProbe. + :type failure_threshold: float + """ + + self._failure_threshold = failure_threshold + + @property + def initial_delay_seconds(self) -> float: + """Gets the initial_delay_seconds of this ApplicationProbe. + + # noqa: E501 + + :return: The initial_delay_seconds of this ApplicationProbe. + :rtype: float + """ + return self._initial_delay_seconds + + @initial_delay_seconds.setter + def initial_delay_seconds(self, initial_delay_seconds: float): + """Sets the initial_delay_seconds of this ApplicationProbe. - return _obj + # noqa: E501 + :param initial_delay_seconds: The initial_delay_seconds of this ApplicationProbe. + :type initial_delay_seconds: float + """ + + self._initial_delay_seconds = initial_delay_seconds + + @property + def port(self) -> float: + """Gets the port of this ApplicationProbe. + + # noqa: E501 + + :return: The port of this ApplicationProbe. + :rtype: float + """ + return self._port + + @port.setter + def port(self, port: float): + """Sets the port of this ApplicationProbe. + + # noqa: E501 + + :param port: The port of this ApplicationProbe. + :type port: float + """ + self._port = port diff --git a/libraries/models/cloudharness_model/models/application_test_config.py b/libraries/models/cloudharness_model/models/application_test_config.py index 7c14273ed..73b76e537 100644 --- a/libraries/models/cloudharness_model/models/application_test_config.py +++ b/libraries/models/cloudharness_model/models/application_test_config.py @@ -1,99 +1,125 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model.models.api_tests_config import ApiTestsConfig +from cloudharness_model.models.e2_e_tests_config import E2ETestsConfig +from cloudharness_model.models.unit_tests_config import UnitTestsConfig +from cloudharness_model import util + +from cloudharness_model.models.api_tests_config import ApiTestsConfig # noqa: E501 +from cloudharness_model.models.e2_e_tests_config import E2ETestsConfig # noqa: E501 +from cloudharness_model.models.unit_tests_config import UnitTestsConfig # noqa: E501 - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) +class ApplicationTestConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + + def __init__(self, unit=None, api=None, e2e=None): # noqa: E501 + """ApplicationTestConfig - a model defined in OpenAPI + :param unit: The unit of this ApplicationTestConfig. # noqa: E501 + :type unit: UnitTestsConfig + :param api: The api of this ApplicationTestConfig. # noqa: E501 + :type api: ApiTestsConfig + :param e2e: The e2e of this ApplicationTestConfig. # noqa: E501 + :type e2e: E2ETestsConfig + """ + self.openapi_types = { + 'unit': UnitTestsConfig, + 'api': ApiTestsConfig, + 'e2e': E2ETestsConfig + } + + self.attribute_map = { + 'unit': 'unit', + 'api': 'api', + 'e2e': 'e2e' + } + + self._unit = unit + self._api = api + self._e2e = e2e -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + @classmethod + def from_dict(cls, dikt) -> 'ApplicationTestConfig': + """Returns the dict as a model -from typing import Optional, Set -from typing_extensions import Self + :param dikt: A dict. + :type: dict + :return: The ApplicationTestConfig of this ApplicationTestConfig. # noqa: E501 + :rtype: ApplicationTestConfig + """ + return util.deserialize_model(dikt, cls) + @property + def unit(self) -> UnitTestsConfig: + """Gets the unit of this ApplicationTestConfig. -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib -from cloudharness_model.models.api_tests_config import ApiTestsConfig -from cloudharness_model.models.e2_e_tests_config import E2ETestsConfig -from cloudharness_model.models.unit_tests_config import UnitTestsConfig -class ApplicationTestConfig(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - unit: UnitTestsConfig - api: ApiTestsConfig - e2e: E2ETestsConfig - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["unit", "api", "e2e"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :return: The unit of this ApplicationTestConfig. + :rtype: UnitTestsConfig """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # override the default output from pydantic by calling `to_dict()` of unit - if self.unit: - _dict['unit'] = self.unit.to_dict() - # override the default output from pydantic by calling `to_dict()` of api - if self.api: - _dict['api'] = self.api.to_dict() - # override the default output from pydantic by calling `to_dict()` of e2e - if self.e2e: - _dict['e2e'] = self.e2e.to_dict() - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + return self._unit - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of ApplicationTestConfig from a dict""" - if obj is None: - return None + @unit.setter + def unit(self, unit: UnitTestsConfig): + """Sets the unit of this ApplicationTestConfig. - if not isinstance(obj, dict): - return cls.model_validate(obj) - _obj = cls.model_validate({ - "unit": UnitTestsConfig.from_dict(obj["unit"]) if obj.get("unit") is not None else None, - "api": ApiTestsConfig.from_dict(obj["api"]) if obj.get("api") is not None else None, - "e2e": E2ETestsConfig.from_dict(obj["e2e"]) if obj.get("e2e") is not None else None - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + :param unit: The unit of this ApplicationTestConfig. + :type unit: UnitTestsConfig + """ + if unit is None: + raise ValueError("Invalid value for `unit`, must not be `None`") # noqa: E501 + + self._unit = unit - return _obj + @property + def api(self) -> ApiTestsConfig: + """Gets the api of this ApplicationTestConfig. + :return: The api of this ApplicationTestConfig. + :rtype: ApiTestsConfig + """ + return self._api + + @api.setter + def api(self, api: ApiTestsConfig): + """Sets the api of this ApplicationTestConfig. + + + :param api: The api of this ApplicationTestConfig. + :type api: ApiTestsConfig + """ + if api is None: + raise ValueError("Invalid value for `api`, must not be `None`") # noqa: E501 + + self._api = api + + @property + def e2e(self) -> E2ETestsConfig: + """Gets the e2e of this ApplicationTestConfig. + + + :return: The e2e of this ApplicationTestConfig. + :rtype: E2ETestsConfig + """ + return self._e2e + + @e2e.setter + def e2e(self, e2e: E2ETestsConfig): + """Sets the e2e of this ApplicationTestConfig. + + + :param e2e: The e2e of this ApplicationTestConfig. + :type e2e: E2ETestsConfig + """ + if e2e is None: + raise ValueError("Invalid value for `e2e`, must not be `None`") # noqa: E501 + + self._e2e = e2e diff --git a/libraries/models/cloudharness_model/models/application_user.py b/libraries/models/cloudharness_model/models/application_user.py index 827f4e09f..78c3479cb 100644 --- a/libraries/models/cloudharness_model/models/application_user.py +++ b/libraries/models/cloudharness_model/models/application_user.py @@ -1,89 +1,149 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model import util - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) + +class ApplicationUser(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, username=None, password=None, client_roles=None, realm_roles=None): # noqa: E501 + """ApplicationUser - a model defined in OpenAPI + + :param username: The username of this ApplicationUser. # noqa: E501 + :type username: str + :param password: The password of this ApplicationUser. # noqa: E501 + :type password: str + :param client_roles: The client_roles of this ApplicationUser. # noqa: E501 + :type client_roles: List[str] + :param realm_roles: The realm_roles of this ApplicationUser. # noqa: E501 + :type realm_roles: List[str] + """ + self.openapi_types = { + 'username': str, + 'password': str, + 'client_roles': List[str], + 'realm_roles': List[str] + } + + self.attribute_map = { + 'username': 'username', + 'password': 'password', + 'client_roles': 'clientRoles', + 'realm_roles': 'realmRoles' + } + + self._username = username + self._password = password + self._client_roles = client_roles + self._realm_roles = realm_roles -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + @classmethod + def from_dict(cls, dikt) -> 'ApplicationUser': + """Returns the dict as a model -from typing import Optional, Set -from typing_extensions import Self + :param dikt: A dict. + :type: dict + :return: The ApplicationUser of this ApplicationUser. # noqa: E501 + :rtype: ApplicationUser + """ + return util.deserialize_model(dikt, cls) + @property + def username(self) -> str: + """Gets the username of this ApplicationUser. -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib + # noqa: E501 -class ApplicationUser(CloudHarnessBaseModel): - """ - Defines a user - """ # noqa: E501 - username: StrictStr - password: Optional[StrictStr] = None - client_roles: Optional[List[StrictStr]] = Field(default=None, alias="clientRoles") - realm_roles: Optional[List[StrictStr]] = Field(default=None, alias="realmRoles") - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["username", "password", "clientRoles", "realmRoles"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :return: The username of this ApplicationUser. + :rtype: str """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + return self._username - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of ApplicationUser from a dict""" - if obj is None: - return None + @username.setter + def username(self, username: str): + """Sets the username of this ApplicationUser. - if not isinstance(obj, dict): - return cls.model_validate(obj) + # noqa: E501 + + :param username: The username of this ApplicationUser. + :type username: str + """ + if username is None: + raise ValueError("Invalid value for `username`, must not be `None`") # noqa: E501 - _obj = cls.model_validate({ - "username": obj.get("username"), - "password": obj.get("password"), - "clientRoles": obj.get("clientRoles"), - "realmRoles": obj.get("realmRoles") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + self._username = username + + @property + def password(self) -> str: + """Gets the password of this ApplicationUser. + + # noqa: E501 + + :return: The password of this ApplicationUser. + :rtype: str + """ + return self._password + + @password.setter + def password(self, password: str): + """Sets the password of this ApplicationUser. + + # noqa: E501 + + :param password: The password of this ApplicationUser. + :type password: str + """ - return _obj + self._password = password + @property + def client_roles(self) -> List[str]: + """Gets the client_roles of this ApplicationUser. + + # noqa: E501 + + :return: The client_roles of this ApplicationUser. + :rtype: List[str] + """ + return self._client_roles + + @client_roles.setter + def client_roles(self, client_roles: List[str]): + """Sets the client_roles of this ApplicationUser. + + # noqa: E501 + + :param client_roles: The client_roles of this ApplicationUser. + :type client_roles: List[str] + """ + + self._client_roles = client_roles + + @property + def realm_roles(self) -> List[str]: + """Gets the realm_roles of this ApplicationUser. + + # noqa: E501 + + :return: The realm_roles of this ApplicationUser. + :rtype: List[str] + """ + return self._realm_roles + + @realm_roles.setter + def realm_roles(self, realm_roles: List[str]): + """Sets the realm_roles of this ApplicationUser. + + # noqa: E501 + + :param realm_roles: The realm_roles of this ApplicationUser. + :type realm_roles: List[str] + """ + self._realm_roles = realm_roles diff --git a/libraries/models/cloudharness_model/models/auto_artifact_spec.py b/libraries/models/cloudharness_model/models/auto_artifact_spec.py index 7fd1b02e8..1280a0554 100644 --- a/libraries/models/cloudharness_model/models/auto_artifact_spec.py +++ b/libraries/models/cloudharness_model/models/auto_artifact_spec.py @@ -1,85 +1,93 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model import util - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) + +class AutoArtifactSpec(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, auto=None, name=None): # noqa: E501 + """AutoArtifactSpec - a model defined in OpenAPI -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + :param auto: The auto of this AutoArtifactSpec. # noqa: E501 + :type auto: bool + :param name: The name of this AutoArtifactSpec. # noqa: E501 + :type name: str + """ + self.openapi_types = { + 'auto': bool, + 'name': str + } -from typing import Optional, Set -from typing_extensions import Self + self.attribute_map = { + 'auto': 'auto', + 'name': 'name' + } + self._auto = auto + self._name = name -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib + @classmethod + def from_dict(cls, dikt) -> 'AutoArtifactSpec': + """Returns the dict as a model -class AutoArtifactSpec(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - auto: Optional[StrictBool] = Field(default=None, description="When true, enables automatic template") - name: Optional[StrictStr] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["auto", "name"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :param dikt: A dict. + :type: dict + :return: The AutoArtifactSpec of this AutoArtifactSpec. # noqa: E501 + :rtype: AutoArtifactSpec """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + return util.deserialize_model(dikt, cls) - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of AutoArtifactSpec from a dict""" - if obj is None: - return None + @property + def auto(self) -> bool: + """Gets the auto of this AutoArtifactSpec. + + When true, enables automatic template # noqa: E501 + + :return: The auto of this AutoArtifactSpec. + :rtype: bool + """ + return self._auto - if not isinstance(obj, dict): - return cls.model_validate(obj) + @auto.setter + def auto(self, auto: bool): + """Sets the auto of this AutoArtifactSpec. - _obj = cls.model_validate({ - "auto": obj.get("auto"), - "name": obj.get("name") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + When true, enables automatic template # noqa: E501 - return _obj + :param auto: The auto of this AutoArtifactSpec. + :type auto: bool + """ + if auto is None: + raise ValueError("Invalid value for `auto`, must not be `None`") # noqa: E501 + + self._auto = auto + + @property + def name(self) -> str: + """Gets the name of this AutoArtifactSpec. + # noqa: E501 + + :return: The name of this AutoArtifactSpec. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name: str): + """Sets the name of this AutoArtifactSpec. + + # noqa: E501 + + :param name: The name of this AutoArtifactSpec. + :type name: str + """ + self._name = name diff --git a/libraries/models/cloudharness_model/models/backup_config.py b/libraries/models/cloudharness_model/models/backup_config.py index 97d136e4a..8d2d49f14 100644 --- a/libraries/models/cloudharness_model/models/backup_config.py +++ b/libraries/models/cloudharness_model/models/backup_config.py @@ -1,125 +1,297 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model.models.deployment_resources_conf import DeploymentResourcesConf +import re +from cloudharness_model import util + +from cloudharness_model.models.deployment_resources_conf import DeploymentResourcesConf # noqa: E501 +import re # noqa: E501 - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) +class BackupConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, active=None, keep_days=None, keep_weeks=None, keep_months=None, schedule=None, suffix=None, volumesize=None, dir=None, resources=None): # noqa: E501 + """BackupConfig - a model defined in OpenAPI -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + :param active: The active of this BackupConfig. # noqa: E501 + :type active: bool + :param keep_days: The keep_days of this BackupConfig. # noqa: E501 + :type keep_days: int + :param keep_weeks: The keep_weeks of this BackupConfig. # noqa: E501 + :type keep_weeks: int + :param keep_months: The keep_months of this BackupConfig. # noqa: E501 + :type keep_months: int + :param schedule: The schedule of this BackupConfig. # noqa: E501 + :type schedule: str + :param suffix: The suffix of this BackupConfig. # noqa: E501 + :type suffix: object + :param volumesize: The volumesize of this BackupConfig. # noqa: E501 + :type volumesize: str + :param dir: The dir of this BackupConfig. # noqa: E501 + :type dir: str + :param resources: The resources of this BackupConfig. # noqa: E501 + :type resources: DeploymentResourcesConf + """ + self.openapi_types = { + 'active': bool, + 'keep_days': int, + 'keep_weeks': int, + 'keep_months': int, + 'schedule': str, + 'suffix': object, + 'volumesize': str, + 'dir': str, + 'resources': DeploymentResourcesConf + } -from typing import Optional, Set -from typing_extensions import Self + self.attribute_map = { + 'active': 'active', + 'keep_days': 'keep_days', + 'keep_weeks': 'keep_weeks', + 'keep_months': 'keep_months', + 'schedule': 'schedule', + 'suffix': 'suffix', + 'volumesize': 'volumesize', + 'dir': 'dir', + 'resources': 'resources' + } + self._active = active + self._keep_days = keep_days + self._keep_weeks = keep_weeks + self._keep_months = keep_months + self._schedule = schedule + self._suffix = suffix + self._volumesize = volumesize + self._dir = dir + self._resources = resources -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib -from cloudharness_model.models.deployment_resources_conf import DeploymentResourcesConf + @classmethod + def from_dict(cls, dikt) -> 'BackupConfig': + """Returns the dict as a model -class BackupConfig(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - active: Optional[StrictBool] = None - keep_days: Optional[Any] = None - keep_weeks: Optional[Any] = None - keep_months: Optional[Any] = None - schedule: Optional[StrictStr] = Field(default=None, description="Cron expression") - suffix: Optional[StrictStr] = Field(default=None, description="The file suffix added to backup files") - volumesize: Optional[StrictStr] = Field(default=None, description="The volume size for backups (all backups share the same volume)") - dir: Annotated[str, Field(strict=True)] - resources: DeploymentResourcesConf - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["active", "keep_days", "keep_weeks", "keep_months", "schedule", "suffix", "volumesize", "dir", "resources"] - - @field_validator('dir') - def dir_validate_regular_expression(cls, value): - """Validates the regular expression""" - if not re.match(r"^[^<>:;,?*|]+$", value): - raise ValueError(r"must validate the regular expression /^[^<>:;,?*|]+$/") - return value - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # override the default output from pydantic by calling `to_dict()` of resources - if self.resources: - _dict['resources'] = self.resources.to_dict() - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - # set to None if keep_days (nullable) is None - # and model_fields_set contains the field - if self.keep_days is None and "keep_days" in self.model_fields_set: - _dict['keep_days'] = None - - # set to None if keep_weeks (nullable) is None - # and model_fields_set contains the field - if self.keep_weeks is None and "keep_weeks" in self.model_fields_set: - _dict['keep_weeks'] = None - - # set to None if keep_months (nullable) is None - # and model_fields_set contains the field - if self.keep_months is None and "keep_months" in self.model_fields_set: - _dict['keep_months'] = None - - return _dict + :param dikt: A dict. + :type: dict + :return: The BackupConfig of this BackupConfig. # noqa: E501 + :rtype: BackupConfig + """ + return util.deserialize_model(dikt, cls) - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of BackupConfig from a dict""" - if obj is None: - return None - - if not isinstance(obj, dict): - return cls.model_validate(obj) - - _obj = cls.model_validate({ - "active": obj.get("active"), - "keep_days": obj.get("keep_days"), - "keep_weeks": obj.get("keep_weeks"), - "keep_months": obj.get("keep_months"), - "schedule": obj.get("schedule"), - "suffix": obj.get("suffix"), - "volumesize": obj.get("volumesize"), - "dir": obj.get("dir"), - "resources": DeploymentResourcesConf.from_dict(obj["resources"]) if obj.get("resources") is not None else None - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj + @property + def active(self) -> bool: + """Gets the active of this BackupConfig. + + # noqa: E501 + + :return: The active of this BackupConfig. + :rtype: bool + """ + return self._active + + @active.setter + def active(self, active: bool): + """Sets the active of this BackupConfig. + + # noqa: E501 + + :param active: The active of this BackupConfig. + :type active: bool + """ + + self._active = active + + @property + def keep_days(self) -> int: + """Gets the keep_days of this BackupConfig. + + # noqa: E501 + + :return: The keep_days of this BackupConfig. + :rtype: int + """ + return self._keep_days + + @keep_days.setter + def keep_days(self, keep_days: int): + """Sets the keep_days of this BackupConfig. + + # noqa: E501 + + :param keep_days: The keep_days of this BackupConfig. + :type keep_days: int + """ + + self._keep_days = keep_days + + @property + def keep_weeks(self) -> int: + """Gets the keep_weeks of this BackupConfig. + + # noqa: E501 + + :return: The keep_weeks of this BackupConfig. + :rtype: int + """ + return self._keep_weeks + + @keep_weeks.setter + def keep_weeks(self, keep_weeks: int): + """Sets the keep_weeks of this BackupConfig. + + # noqa: E501 + + :param keep_weeks: The keep_weeks of this BackupConfig. + :type keep_weeks: int + """ + + self._keep_weeks = keep_weeks + + @property + def keep_months(self) -> int: + """Gets the keep_months of this BackupConfig. + + # noqa: E501 + + :return: The keep_months of this BackupConfig. + :rtype: int + """ + return self._keep_months + + @keep_months.setter + def keep_months(self, keep_months: int): + """Sets the keep_months of this BackupConfig. + + # noqa: E501 + + :param keep_months: The keep_months of this BackupConfig. + :type keep_months: int + """ + + self._keep_months = keep_months + @property + def schedule(self) -> str: + """Gets the schedule of this BackupConfig. + + Cron expression # noqa: E501 + + :return: The schedule of this BackupConfig. + :rtype: str + """ + return self._schedule + + @schedule.setter + def schedule(self, schedule: str): + """Sets the schedule of this BackupConfig. + + Cron expression # noqa: E501 + + :param schedule: The schedule of this BackupConfig. + :type schedule: str + """ + if schedule is not None and not re.search(r'(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|µs|ms|s|m|h))+)|((((\d+,)+\d+|(\d+(\/|-)\d+)|\d+|\*) ?){5,7})', schedule): # noqa: E501 + raise ValueError(r"Invalid value for `schedule`, must be a follow pattern or equal to `/(@(annually|yearly|monthly|weekly|daily|hourly|reboot))|(@every (\d+(ns|us|µs|ms|s|m|h))+)|((((\d+,)+\d+|(\d+(\/|-)\d+)|\d+|\*) ?){5,7})/`") # noqa: E501 + + self._schedule = schedule + + @property + def suffix(self) -> object: + """Gets the suffix of this BackupConfig. + + The file suffix added to backup files # noqa: E501 + + :return: The suffix of this BackupConfig. + :rtype: object + """ + return self._suffix + + @suffix.setter + def suffix(self, suffix: object): + """Sets the suffix of this BackupConfig. + + The file suffix added to backup files # noqa: E501 + + :param suffix: The suffix of this BackupConfig. + :type suffix: object + """ + + self._suffix = suffix + + @property + def volumesize(self) -> str: + """Gets the volumesize of this BackupConfig. + + The volume size for backups (all backups share the same volume) # noqa: E501 + + :return: The volumesize of this BackupConfig. + :rtype: str + """ + return self._volumesize + + @volumesize.setter + def volumesize(self, volumesize: str): + """Sets the volumesize of this BackupConfig. + + The volume size for backups (all backups share the same volume) # noqa: E501 + + :param volumesize: The volumesize of this BackupConfig. + :type volumesize: str + """ + + self._volumesize = volumesize + + @property + def dir(self) -> str: + """Gets the dir of this BackupConfig. + + # noqa: E501 + + :return: The dir of this BackupConfig. + :rtype: str + """ + return self._dir + + @dir.setter + def dir(self, dir: str): + """Sets the dir of this BackupConfig. + + # noqa: E501 + + :param dir: The dir of this BackupConfig. + :type dir: str + """ + if dir is None: + raise ValueError("Invalid value for `dir`, must not be `None`") # noqa: E501 + if dir is not None and not re.search(r'^[^<>:;,?*|]+$', dir): # noqa: E501 + raise ValueError("Invalid value for `dir`, must be a follow pattern or equal to `/^[^<>:;,?*|]+$/`") # noqa: E501 + + self._dir = dir + + @property + def resources(self) -> DeploymentResourcesConf: + """Gets the resources of this BackupConfig. + + + :return: The resources of this BackupConfig. + :rtype: DeploymentResourcesConf + """ + return self._resources + + @resources.setter + def resources(self, resources: DeploymentResourcesConf): + """Sets the resources of this BackupConfig. + + + :param resources: The resources of this BackupConfig. + :type resources: DeploymentResourcesConf + """ + if resources is None: + raise ValueError("Invalid value for `resources`, must not be `None`") # noqa: E501 + self._resources = resources diff --git a/libraries/models/cloudharness_model/models/base_model_.py b/libraries/models/cloudharness_model/models/base_model_.py index e69de29bb..456f58b07 100644 --- a/libraries/models/cloudharness_model/models/base_model_.py +++ b/libraries/models/cloudharness_model/models/base_model_.py @@ -0,0 +1,156 @@ +import pprint + +import six +import typing +import json + +import humps + +from cloudharness_model import util + +T = typing.TypeVar('T') + + +def clean_snake_cased(adict: dict): + return {k:v for k, v in adict.items() if not (humps.is_snakecase(k) and not humps.is_camelcase(k) and humps.camelize(k) in adict)} + +class Model(object): + # openapiTypes: The key is attribute name and the + # value is attribute type. + openapi_types = {} + + # attributeMap: The key is attribute name and the + # value is json key in definition. + attribute_map = {} + + + def __new__(cls, *args, **kwargs): + obj = object.__new__(cls) + obj._raw_dict = {} + return obj + + @classmethod + def from_dict(cls: typing.Type[T], dikt) -> T: + """Returns the dict as a model""" + + obj = util.deserialize_model(dikt, cls) + return obj + + def toJSON(self): + return json.dumps(self.to_dict()) + + def __getattr__(self, key: str) -> typing.Any: + try: + return self.get_from_raw(key) + except KeyError: + raise AttributeError(key) + + def __getitem__(self, key: str): + if "." not in key: + return getattr(self, key) + keys = key.split(".") + return self[keys[0]][key[len(keys[0]) + 1::]] + + def get_from_raw(self, key): + item = self._raw_dict[key] + if type(item) == dict: + return Model.from_dict(item) + elif type(item) in [list, tuple]: + return [Model.from_dict(i) if type(i) == dict else i for i in item] + return item + + + def __setitem__(self, key, value): + if hasattr(self, key): + setattr(self, key, value) + + self._raw_dict[key] = value + + + def __setattr__(self, key: str, value) -> None: + if humps.is_camelcase(key): + object.__setattr__(self, humps.decamelize(key), value) + elif humps.is_snakecase(key): + object.__setattr__(self, humps.camelize(key), value) + object.__setattr__(self, key, value) + + def get(self, key, _default=None): + if key in self: + return self[key] + return _default + + def __contains__(self, key): + if key in self.attribute_map: + return True + elif hasattr(self, "_raw_dict"): + return key in self._raw_dict + return False + + def to_dict(self): + """Returns the model properties as a dict + :rtype: dict + """ + result = {} + + for attr, _ in six.iteritems(self.openapi_types): + value = getattr(self, attr) + if isinstance(value, list): + result[attr] = list(map( + lambda x: x.to_dict() if hasattr(x, "to_dict") else x, + value + )) + elif hasattr(value, "to_dict"): + result[attr] = value.to_dict() + elif isinstance(value, dict): + result[attr] = dict(map( + lambda item: (item[0], item[1].to_dict()) + if hasattr(item[1], "to_dict") else item, + value.items() + )) + else: + result[attr] = value + if humps.is_camelcase(attr): + result[humps.decamelize(attr)] = result[attr] + elif humps.is_snakecase(attr): + result[humps.camelize(attr)] = result[attr] + + + if hasattr(self, "_raw_dict"): + merged = dict(self._raw_dict) + merged.update(result) + return clean_snake_cased(merged) + + return clean_snake_cased(result) + + def to_str(self): + """Returns the string representation of the model + :rtype: str + """ + return pprint.pformat(self.to_dict()) + + def __repr__(self): + """For `print` and `pprint`""" + return self.to_str() + + def __eq__(self, other): + """Returns true if both objects are equal""" + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + """Returns true if both objects are not equal""" + return not self == other + + def __iter__(self): + return iter(self._raw_dict) + + def __len__(self): + return len(self._raw_dict) + + def values(self): + return self._raw_dict.values() + + def keys(self): + return self._raw_dict.keys() + + def items(self): + return self._raw_dict.items() \ No newline at end of file diff --git a/libraries/models/cloudharness_model/models/cdc_event.py b/libraries/models/cloudharness_model/models/cdc_event.py index 5b5770fba..b1db28fec 100644 --- a/libraries/models/cloudharness_model/models/cdc_event.py +++ b/libraries/models/cloudharness_model/models/cdc_event.py @@ -1,107 +1,187 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model.models.cdc_event_meta import CDCEventMeta +from cloudharness_model import util + +from cloudharness_model.models.cdc_event_meta import CDCEventMeta # noqa: E501 - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) +class CDCEvent(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, operation=None, uid=None, message_type=None, resource=None, meta=None): # noqa: E501 + """CDCEvent - a model defined in OpenAPI + + :param operation: The operation of this CDCEvent. # noqa: E501 + :type operation: str + :param uid: The uid of this CDCEvent. # noqa: E501 + :type uid: str + :param message_type: The message_type of this CDCEvent. # noqa: E501 + :type message_type: str + :param resource: The resource of this CDCEvent. # noqa: E501 + :type resource: Dict[str, object] + :param meta: The meta of this CDCEvent. # noqa: E501 + :type meta: CDCEventMeta + """ + self.openapi_types = { + 'operation': str, + 'uid': str, + 'message_type': str, + 'resource': Dict[str, object], + 'meta': CDCEventMeta + } + + self.attribute_map = { + 'operation': 'operation', + 'uid': 'uid', + 'message_type': 'message_type', + 'resource': 'resource', + 'meta': 'meta' + } + + self._operation = operation + self._uid = uid + self._message_type = message_type + self._resource = resource + self._meta = meta -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + @classmethod + def from_dict(cls, dikt) -> 'CDCEvent': + """Returns the dict as a model -from typing import Optional, Set -from typing_extensions import Self + :param dikt: A dict. + :type: dict + :return: The CDCEvent of this CDCEvent. # noqa: E501 + :rtype: CDCEvent + """ + return util.deserialize_model(dikt, cls) + @property + def operation(self) -> str: + """Gets the operation of this CDCEvent. -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib -from cloudharness_model.models.cdc_event_meta import CDCEventMeta + the operation on the object e.g. create / update / delete # noqa: E501 -class CDCEvent(CloudHarnessBaseModel): - """ - A message sent to the orchestration queue. Applications can listen to these events to react to data change events happening on other applications. - """ # noqa: E501 - operation: StrictStr = Field(description="the operation on the object e.g. create / update / delete") - uid: Optional[Any] = Field(description="the unique identifier attribute of the object") - message_type: StrictStr = Field(description="the type of the message (relates to the object type) e.g. jobs") - resource: Optional[Dict[str, Any]] = None - meta: CDCEventMeta - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["operation", "uid", "message_type", "resource", "meta"] - - @field_validator('operation') - def operation_validate_enum(cls, value): - """Validates the enum""" - if value not in set(['create', 'update', 'delete', 'other']): - raise ValueError("must be one of enum values ('create', 'update', 'delete', 'other')") - return value - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :return: The operation of this CDCEvent. + :rtype: str """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # override the default output from pydantic by calling `to_dict()` of meta - if self.meta: - _dict['meta'] = self.meta.to_dict() - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - # set to None if uid (nullable) is None - # and model_fields_set contains the field - if self.uid is None and "uid" in self.model_fields_set: - _dict['uid'] = None - - return _dict + return self._operation - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of CDCEvent from a dict""" - if obj is None: - return None + @operation.setter + def operation(self, operation: str): + """Sets the operation of this CDCEvent. + + the operation on the object e.g. create / update / delete # noqa: E501 + + :param operation: The operation of this CDCEvent. + :type operation: str + """ + allowed_values = ["create", "update", "delete", "other"] # noqa: E501 + if operation not in allowed_values: + raise ValueError( + "Invalid value for `operation` ({0}), must be one of {1}" + .format(operation, allowed_values) + ) + + self._operation = operation + + @property + def uid(self) -> str: + """Gets the uid of this CDCEvent. + + the unique identifier attribute of the object # noqa: E501 + + :return: The uid of this CDCEvent. + :rtype: str + """ + return self._uid + + @uid.setter + def uid(self, uid: str): + """Sets the uid of this CDCEvent. + + the unique identifier attribute of the object # noqa: E501 + + :param uid: The uid of this CDCEvent. + :type uid: str + """ + if uid is None: + raise ValueError("Invalid value for `uid`, must not be `None`") # noqa: E501 + + self._uid = uid - if not isinstance(obj, dict): - return cls.model_validate(obj) + @property + def message_type(self) -> str: + """Gets the message_type of this CDCEvent. - _obj = cls.model_validate({ - "operation": obj.get("operation"), - "uid": obj.get("uid"), - "message_type": obj.get("message_type"), - "resource": obj.get("resource"), - "meta": CDCEventMeta.from_dict(obj["meta"]) if obj.get("meta") is not None else None - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + the type of the message (relates to the object type) e.g. jobs # noqa: E501 - return _obj + :return: The message_type of this CDCEvent. + :rtype: str + """ + return self._message_type + + @message_type.setter + def message_type(self, message_type: str): + """Sets the message_type of this CDCEvent. + + the type of the message (relates to the object type) e.g. jobs # noqa: E501 + + :param message_type: The message_type of this CDCEvent. + :type message_type: str + """ + if message_type is None: + raise ValueError("Invalid value for `message_type`, must not be `None`") # noqa: E501 + + self._message_type = message_type + + @property + def resource(self) -> Dict[str, object]: + """Gets the resource of this CDCEvent. + + # noqa: E501 + + :return: The resource of this CDCEvent. + :rtype: Dict[str, object] + """ + return self._resource + + @resource.setter + def resource(self, resource: Dict[str, object]): + """Sets the resource of this CDCEvent. + # noqa: E501 + + :param resource: The resource of this CDCEvent. + :type resource: Dict[str, object] + """ + + self._resource = resource + + @property + def meta(self) -> CDCEventMeta: + """Gets the meta of this CDCEvent. + + + :return: The meta of this CDCEvent. + :rtype: CDCEventMeta + """ + return self._meta + + @meta.setter + def meta(self, meta: CDCEventMeta): + """Sets the meta of this CDCEvent. + + + :param meta: The meta of this CDCEvent. + :type meta: CDCEventMeta + """ + if meta is None: + raise ValueError("Invalid value for `meta`, must not be `None`") # noqa: E501 + self._meta = meta diff --git a/libraries/models/cloudharness_model/models/cdc_event_meta.py b/libraries/models/cloudharness_model/models/cdc_event_meta.py index ce279865e..305912878 100644 --- a/libraries/models/cloudharness_model/models/cdc_event_meta.py +++ b/libraries/models/cloudharness_model/models/cdc_event_meta.py @@ -1,100 +1,177 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model.models.user import User +from cloudharness_model import util + +from cloudharness_model.models.user import User # noqa: E501 - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) +class CDCEventMeta(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, app_name=None, user=None, args=None, kwargs=None, description=None): # noqa: E501 + """CDCEventMeta - a model defined in OpenAPI + + :param app_name: The app_name of this CDCEventMeta. # noqa: E501 + :type app_name: str + :param user: The user of this CDCEventMeta. # noqa: E501 + :type user: User + :param args: The args of this CDCEventMeta. # noqa: E501 + :type args: List[Dict[str, object]] + :param kwargs: The kwargs of this CDCEventMeta. # noqa: E501 + :type kwargs: object + :param description: The description of this CDCEventMeta. # noqa: E501 + :type description: str + """ + self.openapi_types = { + 'app_name': str, + 'user': User, + 'args': List[Dict[str, object]], + 'kwargs': object, + 'description': str + } + + self.attribute_map = { + 'app_name': 'app_name', + 'user': 'user', + 'args': 'args', + 'kwargs': 'kwargs', + 'description': 'description' + } + + self._app_name = app_name + self._user = user + self._args = args + self._kwargs = kwargs + self._description = description -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + @classmethod + def from_dict(cls, dikt) -> 'CDCEventMeta': + """Returns the dict as a model -from typing import Optional, Set -from typing_extensions import Self + :param dikt: A dict. + :type: dict + :return: The CDCEventMeta of this CDCEventMeta. # noqa: E501 + :rtype: CDCEventMeta + """ + return util.deserialize_model(dikt, cls) + @property + def app_name(self) -> str: + """Gets the app_name of this CDCEventMeta. -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib -from cloudharness_model.models.user import User + The name of the application/microservice sending the message # noqa: E501 -class CDCEventMeta(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - app_name: StrictStr = Field(description="The name of the application/microservice sending the message") - user: Optional[User] = None - args: Optional[List[Dict[str, Any]]] = Field(default=None, description="the caller function arguments") - kwargs: Optional[Any] = Field(default=None, description="the caller function keyword arguments") - description: Optional[StrictStr] = Field(default=None, description="General description -- for human consumption") - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["app_name", "user", "args", "kwargs", "description"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :return: The app_name of this CDCEventMeta. + :rtype: str """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # override the default output from pydantic by calling `to_dict()` of user - if self.user: - _dict['user'] = self.user.to_dict() - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - # set to None if kwargs (nullable) is None - # and model_fields_set contains the field - if self.kwargs is None and "kwargs" in self.model_fields_set: - _dict['kwargs'] = None - - return _dict + return self._app_name - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of CDCEventMeta from a dict""" - if obj is None: - return None + @app_name.setter + def app_name(self, app_name: str): + """Sets the app_name of this CDCEventMeta. + + The name of the application/microservice sending the message # noqa: E501 + + :param app_name: The app_name of this CDCEventMeta. + :type app_name: str + """ + if app_name is None: + raise ValueError("Invalid value for `app_name`, must not be `None`") # noqa: E501 + + self._app_name = app_name + + @property + def user(self) -> User: + """Gets the user of this CDCEventMeta. + + + :return: The user of this CDCEventMeta. + :rtype: User + """ + return self._user + + @user.setter + def user(self, user: User): + """Sets the user of this CDCEventMeta. + + + :param user: The user of this CDCEventMeta. + :type user: User + """ + + self._user = user - if not isinstance(obj, dict): - return cls.model_validate(obj) + @property + def args(self) -> List[Dict[str, object]]: + """Gets the args of this CDCEventMeta. - _obj = cls.model_validate({ - "app_name": obj.get("app_name"), - "user": User.from_dict(obj["user"]) if obj.get("user") is not None else None, - "args": obj.get("args"), - "kwargs": obj.get("kwargs"), - "description": obj.get("description") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + the caller function arguments # noqa: E501 - return _obj + :return: The args of this CDCEventMeta. + :rtype: List[Dict[str, object]] + """ + return self._args + + @args.setter + def args(self, args: List[Dict[str, object]]): + """Sets the args of this CDCEventMeta. + + the caller function arguments # noqa: E501 + + :param args: The args of this CDCEventMeta. + :type args: List[Dict[str, object]] + """ + + self._args = args + + @property + def kwargs(self) -> object: + """Gets the kwargs of this CDCEventMeta. + + the caller function keyword arguments # noqa: E501 + + :return: The kwargs of this CDCEventMeta. + :rtype: object + """ + return self._kwargs + + @kwargs.setter + def kwargs(self, kwargs: object): + """Sets the kwargs of this CDCEventMeta. + the caller function keyword arguments # noqa: E501 + + :param kwargs: The kwargs of this CDCEventMeta. + :type kwargs: object + """ + + self._kwargs = kwargs + + @property + def description(self) -> str: + """Gets the description of this CDCEventMeta. + + General description -- for human consumption # noqa: E501 + + :return: The description of this CDCEventMeta. + :rtype: str + """ + return self._description + + @description.setter + def description(self, description: str): + """Sets the description of this CDCEventMeta. + + General description -- for human consumption # noqa: E501 + + :param description: The description of this CDCEventMeta. + :type description: str + """ + self._description = description diff --git a/libraries/models/cloudharness_model/models/cpu_memory_config.py b/libraries/models/cloudharness_model/models/cpu_memory_config.py index e7d17b831..63fcee6a8 100644 --- a/libraries/models/cloudharness_model/models/cpu_memory_config.py +++ b/libraries/models/cloudharness_model/models/cpu_memory_config.py @@ -1,95 +1,91 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model import util - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) + +class CpuMemoryConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, cpu=None, memory=None): # noqa: E501 + """CpuMemoryConfig - a model defined in OpenAPI -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + :param cpu: The cpu of this CpuMemoryConfig. # noqa: E501 + :type cpu: str + :param memory: The memory of this CpuMemoryConfig. # noqa: E501 + :type memory: str + """ + self.openapi_types = { + 'cpu': str, + 'memory': str + } -from typing import Optional, Set -from typing_extensions import Self + self.attribute_map = { + 'cpu': 'cpu', + 'memory': 'memory' + } + self._cpu = cpu + self._memory = memory -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib + @classmethod + def from_dict(cls, dikt) -> 'CpuMemoryConfig': + """Returns the dict as a model -class CpuMemoryConfig(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - cpu: Optional[Any] = None - memory: Optional[Any] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["cpu", "memory"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :param dikt: A dict. + :type: dict + :return: The CpuMemoryConfig of this CpuMemoryConfig. # noqa: E501 + :rtype: CpuMemoryConfig """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - # set to None if cpu (nullable) is None - # and model_fields_set contains the field - if self.cpu is None and "cpu" in self.model_fields_set: - _dict['cpu'] = None - - # set to None if memory (nullable) is None - # and model_fields_set contains the field - if self.memory is None and "memory" in self.model_fields_set: - _dict['memory'] = None - - return _dict + return util.deserialize_model(dikt, cls) - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of CpuMemoryConfig from a dict""" - if obj is None: - return None + @property + def cpu(self) -> str: + """Gets the cpu of this CpuMemoryConfig. + + # noqa: E501 + + :return: The cpu of this CpuMemoryConfig. + :rtype: str + """ + return self._cpu - if not isinstance(obj, dict): - return cls.model_validate(obj) + @cpu.setter + def cpu(self, cpu: str): + """Sets the cpu of this CpuMemoryConfig. - _obj = cls.model_validate({ - "cpu": obj.get("cpu"), - "memory": obj.get("memory") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + # noqa: E501 - return _obj + :param cpu: The cpu of this CpuMemoryConfig. + :type cpu: str + """ + + self._cpu = cpu + + @property + def memory(self) -> str: + """Gets the memory of this CpuMemoryConfig. + # noqa: E501 + + :return: The memory of this CpuMemoryConfig. + :rtype: str + """ + return self._memory + + @memory.setter + def memory(self, memory: str): + """Sets the memory of this CpuMemoryConfig. + + # noqa: E501 + + :param memory: The memory of this CpuMemoryConfig. + :type memory: str + """ + self._memory = memory diff --git a/libraries/models/cloudharness_model/models/database_deployment_config.py b/libraries/models/cloudharness_model/models/database_deployment_config.py index d87a45ad0..b9b7faa50 100644 --- a/libraries/models/cloudharness_model/models/database_deployment_config.py +++ b/libraries/models/cloudharness_model/models/database_deployment_config.py @@ -1,122 +1,349 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model.models.deployment_resources_conf import DeploymentResourcesConf +import re +from cloudharness_model import util + +from cloudharness_model.models.deployment_resources_conf import DeploymentResourcesConf # noqa: E501 +import re # noqa: E501 - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) +class DatabaseDeploymentConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, auto=None, name=None, type=None, size=None, user=None, _pass=None, image_ref=None, mongo=None, postgres=None, neo4j=None, resources=None): # noqa: E501 + """DatabaseDeploymentConfig - a model defined in OpenAPI -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + :param auto: The auto of this DatabaseDeploymentConfig. # noqa: E501 + :type auto: bool + :param name: The name of this DatabaseDeploymentConfig. # noqa: E501 + :type name: str + :param type: The type of this DatabaseDeploymentConfig. # noqa: E501 + :type type: str + :param size: The size of this DatabaseDeploymentConfig. # noqa: E501 + :type size: str + :param user: The user of this DatabaseDeploymentConfig. # noqa: E501 + :type user: str + :param _pass: The _pass of this DatabaseDeploymentConfig. # noqa: E501 + :type _pass: str + :param image_ref: The image_ref of this DatabaseDeploymentConfig. # noqa: E501 + :type image_ref: str + :param mongo: The mongo of this DatabaseDeploymentConfig. # noqa: E501 + :type mongo: Dict[str, object] + :param postgres: The postgres of this DatabaseDeploymentConfig. # noqa: E501 + :type postgres: Dict[str, object] + :param neo4j: The neo4j of this DatabaseDeploymentConfig. # noqa: E501 + :type neo4j: object + :param resources: The resources of this DatabaseDeploymentConfig. # noqa: E501 + :type resources: DeploymentResourcesConf + """ + self.openapi_types = { + 'auto': bool, + 'name': str, + 'type': str, + 'size': str, + 'user': str, + '_pass': str, + 'image_ref': str, + 'mongo': Dict[str, object], + 'postgres': Dict[str, object], + 'neo4j': object, + 'resources': DeploymentResourcesConf + } -from typing import Optional, Set -from typing_extensions import Self + self.attribute_map = { + 'auto': 'auto', + 'name': 'name', + 'type': 'type', + 'size': 'size', + 'user': 'user', + '_pass': 'pass', + 'image_ref': 'image_ref', + 'mongo': 'mongo', + 'postgres': 'postgres', + 'neo4j': 'neo4j', + 'resources': 'resources' + } + self._auto = auto + self._name = name + self._type = type + self._size = size + self._user = user + self.__pass = _pass + self._image_ref = image_ref + self._mongo = mongo + self._postgres = postgres + self._neo4j = neo4j + self._resources = resources -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib -from cloudharness_model.models.deployment_resources_conf import DeploymentResourcesConf + @classmethod + def from_dict(cls, dikt) -> 'DatabaseDeploymentConfig': + """Returns the dict as a model -class DatabaseDeploymentConfig(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - auto: Optional[StrictBool] = Field(default=None, description="When true, enables automatic template") - name: Optional[StrictStr] = None - type: Optional[Annotated[str, Field(strict=True)]] = Field(default=None, description="Define the database type. One of (mongo, postgres, neo4j, sqlite3)") - size: Optional[StrictStr] = Field(default=None, description="Specify database disk size") - user: Optional[StrictStr] = Field(default=None, description="database username") - var_pass: Optional[StrictStr] = Field(default=None, description="Database password", alias="pass") - image_ref: Optional[StrictStr] = Field(default=None, description="Used for referencing images from the build") - mongo: Optional[Dict[str, Any]] = None - postgres: Optional[Dict[str, Any]] = None - neo4j: Optional[Any] = Field(default=None, description="Neo4j database specific configuration") - resources: Optional[DeploymentResourcesConf] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["auto", "name", "type", "size", "user", "pass", "image_ref", "mongo", "postgres", "neo4j", "resources"] - - @field_validator('type') - def type_validate_regular_expression(cls, value): - """Validates the regular expression""" - if value is None: - return value - - if not re.match(r"^(mongo|postgres|neo4j|sqlite3)$", value): - raise ValueError(r"must validate the regular expression /^(mongo|postgres|neo4j|sqlite3)$/") - return value - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # override the default output from pydantic by calling `to_dict()` of resources - if self.resources: - _dict['resources'] = self.resources.to_dict() - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - # set to None if neo4j (nullable) is None - # and model_fields_set contains the field - if self.neo4j is None and "neo4j" in self.model_fields_set: - _dict['neo4j'] = None - - return _dict + :param dikt: A dict. + :type: dict + :return: The DatabaseDeploymentConfig of this DatabaseDeploymentConfig. # noqa: E501 + :rtype: DatabaseDeploymentConfig + """ + return util.deserialize_model(dikt, cls) - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of DatabaseDeploymentConfig from a dict""" - if obj is None: - return None - - if not isinstance(obj, dict): - return cls.model_validate(obj) - - _obj = cls.model_validate({ - "auto": obj.get("auto"), - "name": obj.get("name"), - "type": obj.get("type"), - "size": obj.get("size"), - "user": obj.get("user"), - "pass": obj.get("pass"), - "image_ref": obj.get("image_ref"), - "mongo": obj.get("mongo"), - "postgres": obj.get("postgres"), - "neo4j": obj.get("neo4j"), - "resources": DeploymentResourcesConf.from_dict(obj["resources"]) if obj.get("resources") is not None else None - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj + @property + def auto(self) -> bool: + """Gets the auto of this DatabaseDeploymentConfig. + + When true, enables automatic template # noqa: E501 + + :return: The auto of this DatabaseDeploymentConfig. + :rtype: bool + """ + return self._auto + + @auto.setter + def auto(self, auto: bool): + """Sets the auto of this DatabaseDeploymentConfig. + + When true, enables automatic template # noqa: E501 + + :param auto: The auto of this DatabaseDeploymentConfig. + :type auto: bool + """ + if auto is None: + raise ValueError("Invalid value for `auto`, must not be `None`") # noqa: E501 + + self._auto = auto + + @property + def name(self) -> str: + """Gets the name of this DatabaseDeploymentConfig. + + # noqa: E501 + + :return: The name of this DatabaseDeploymentConfig. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name: str): + """Sets the name of this DatabaseDeploymentConfig. + + # noqa: E501 + + :param name: The name of this DatabaseDeploymentConfig. + :type name: str + """ + + self._name = name + + @property + def type(self) -> str: + """Gets the type of this DatabaseDeploymentConfig. + + Define the database type. One of (mongo, postgres, neo4j, sqlite3) # noqa: E501 + + :return: The type of this DatabaseDeploymentConfig. + :rtype: str + """ + return self._type + + @type.setter + def type(self, type: str): + """Sets the type of this DatabaseDeploymentConfig. + + Define the database type. One of (mongo, postgres, neo4j, sqlite3) # noqa: E501 + + :param type: The type of this DatabaseDeploymentConfig. + :type type: str + """ + if type is not None and not re.search(r'^(mongo|postgres|neo4j|sqlite3)$', type): # noqa: E501 + raise ValueError("Invalid value for `type`, must be a follow pattern or equal to `/^(mongo|postgres|neo4j|sqlite3)$/`") # noqa: E501 + + self._type = type + + @property + def size(self) -> str: + """Gets the size of this DatabaseDeploymentConfig. + + Specify database disk size # noqa: E501 + + :return: The size of this DatabaseDeploymentConfig. + :rtype: str + """ + return self._size + + @size.setter + def size(self, size: str): + """Sets the size of this DatabaseDeploymentConfig. + + Specify database disk size # noqa: E501 + + :param size: The size of this DatabaseDeploymentConfig. + :type size: str + """ + + self._size = size + + @property + def user(self) -> str: + """Gets the user of this DatabaseDeploymentConfig. + + database username # noqa: E501 + + :return: The user of this DatabaseDeploymentConfig. + :rtype: str + """ + return self._user + + @user.setter + def user(self, user: str): + """Sets the user of this DatabaseDeploymentConfig. + + database username # noqa: E501 + + :param user: The user of this DatabaseDeploymentConfig. + :type user: str + """ + + self._user = user + @property + def _pass(self) -> str: + """Gets the _pass of this DatabaseDeploymentConfig. + + Database password # noqa: E501 + + :return: The _pass of this DatabaseDeploymentConfig. + :rtype: str + """ + return self.__pass + + @_pass.setter + def _pass(self, _pass: str): + """Sets the _pass of this DatabaseDeploymentConfig. + + Database password # noqa: E501 + + :param _pass: The _pass of this DatabaseDeploymentConfig. + :type _pass: str + """ + + self.__pass = _pass + + @property + def image_ref(self) -> str: + """Gets the image_ref of this DatabaseDeploymentConfig. + + Used for referencing images from the build # noqa: E501 + + :return: The image_ref of this DatabaseDeploymentConfig. + :rtype: str + """ + return self._image_ref + + @image_ref.setter + def image_ref(self, image_ref: str): + """Sets the image_ref of this DatabaseDeploymentConfig. + + Used for referencing images from the build # noqa: E501 + + :param image_ref: The image_ref of this DatabaseDeploymentConfig. + :type image_ref: str + """ + + self._image_ref = image_ref + + @property + def mongo(self) -> Dict[str, object]: + """Gets the mongo of this DatabaseDeploymentConfig. + + # noqa: E501 + + :return: The mongo of this DatabaseDeploymentConfig. + :rtype: Dict[str, object] + """ + return self._mongo + + @mongo.setter + def mongo(self, mongo: Dict[str, object]): + """Sets the mongo of this DatabaseDeploymentConfig. + + # noqa: E501 + + :param mongo: The mongo of this DatabaseDeploymentConfig. + :type mongo: Dict[str, object] + """ + + self._mongo = mongo + + @property + def postgres(self) -> Dict[str, object]: + """Gets the postgres of this DatabaseDeploymentConfig. + + # noqa: E501 + + :return: The postgres of this DatabaseDeploymentConfig. + :rtype: Dict[str, object] + """ + return self._postgres + + @postgres.setter + def postgres(self, postgres: Dict[str, object]): + """Sets the postgres of this DatabaseDeploymentConfig. + + # noqa: E501 + + :param postgres: The postgres of this DatabaseDeploymentConfig. + :type postgres: Dict[str, object] + """ + + self._postgres = postgres + + @property + def neo4j(self) -> object: + """Gets the neo4j of this DatabaseDeploymentConfig. + + Neo4j database specific configuration # noqa: E501 + + :return: The neo4j of this DatabaseDeploymentConfig. + :rtype: object + """ + return self._neo4j + + @neo4j.setter + def neo4j(self, neo4j: object): + """Sets the neo4j of this DatabaseDeploymentConfig. + + Neo4j database specific configuration # noqa: E501 + + :param neo4j: The neo4j of this DatabaseDeploymentConfig. + :type neo4j: object + """ + + self._neo4j = neo4j + + @property + def resources(self) -> DeploymentResourcesConf: + """Gets the resources of this DatabaseDeploymentConfig. + + + :return: The resources of this DatabaseDeploymentConfig. + :rtype: DeploymentResourcesConf + """ + return self._resources + + @resources.setter + def resources(self, resources: DeploymentResourcesConf): + """Sets the resources of this DatabaseDeploymentConfig. + + + :param resources: The resources of this DatabaseDeploymentConfig. + :type resources: DeploymentResourcesConf + """ + self._resources = resources diff --git a/libraries/models/cloudharness_model/models/deployment_auto_artifact_config.py b/libraries/models/cloudharness_model/models/deployment_auto_artifact_config.py index 8b50995ec..7d84aff5c 100644 --- a/libraries/models/cloudharness_model/models/deployment_auto_artifact_config.py +++ b/libraries/models/cloudharness_model/models/deployment_auto_artifact_config.py @@ -1,118 +1,237 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model.models.deployment_resources_conf import DeploymentResourcesConf +from cloudharness_model.models.deployment_volume_spec import DeploymentVolumeSpec +import re +from cloudharness_model import util + +from cloudharness_model.models.deployment_resources_conf import DeploymentResourcesConf # noqa: E501 +from cloudharness_model.models.deployment_volume_spec import DeploymentVolumeSpec # noqa: E501 +import re # noqa: E501 - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) +class DeploymentAutoArtifactConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, auto=None, name=None, port=None, replicas=None, image=None, resources=None, volume=None): # noqa: E501 + """DeploymentAutoArtifactConfig - a model defined in OpenAPI + + :param auto: The auto of this DeploymentAutoArtifactConfig. # noqa: E501 + :type auto: bool + :param name: The name of this DeploymentAutoArtifactConfig. # noqa: E501 + :type name: str + :param port: The port of this DeploymentAutoArtifactConfig. # noqa: E501 + :type port: str + :param replicas: The replicas of this DeploymentAutoArtifactConfig. # noqa: E501 + :type replicas: int + :param image: The image of this DeploymentAutoArtifactConfig. # noqa: E501 + :type image: str + :param resources: The resources of this DeploymentAutoArtifactConfig. # noqa: E501 + :type resources: DeploymentResourcesConf + :param volume: The volume of this DeploymentAutoArtifactConfig. # noqa: E501 + :type volume: DeploymentVolumeSpec + """ + self.openapi_types = { + 'auto': bool, + 'name': str, + 'port': str, + 'replicas': int, + 'image': str, + 'resources': DeploymentResourcesConf, + 'volume': DeploymentVolumeSpec + } + + self.attribute_map = { + 'auto': 'auto', + 'name': 'name', + 'port': 'port', + 'replicas': 'replicas', + 'image': 'image', + 'resources': 'resources', + 'volume': 'volume' + } + + self._auto = auto + self._name = name + self._port = port + self._replicas = replicas + self._image = image + self._resources = resources + self._volume = volume -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + @classmethod + def from_dict(cls, dikt) -> 'DeploymentAutoArtifactConfig': + """Returns the dict as a model -from typing import Optional, Set -from typing_extensions import Self + :param dikt: A dict. + :type: dict + :return: The DeploymentAutoArtifactConfig of this DeploymentAutoArtifactConfig. # noqa: E501 + :rtype: DeploymentAutoArtifactConfig + """ + return util.deserialize_model(dikt, cls) + @property + def auto(self) -> bool: + """Gets the auto of this DeploymentAutoArtifactConfig. -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib -from cloudharness_model.models.deployment_resources_conf import DeploymentResourcesConf -from cloudharness_model.models.deployment_volume_spec import DeploymentVolumeSpec + When true, enables automatic template # noqa: E501 -class DeploymentAutoArtifactConfig(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - auto: Optional[StrictBool] = Field(default=None, description="When true, enables automatic template") - name: Optional[StrictStr] = None - port: Optional[Any] = Field(default=None, description="Deployment port") - replicas: Optional[StrictInt] = Field(default=None, description="Number of replicas") - image: Optional[Annotated[str, Field(strict=True)]] = Field(default=None, description="Image name to use in the deployment. Leave it blank to set from the application's Docker file") - resources: Optional[DeploymentResourcesConf] = None - volume: Optional[DeploymentVolumeSpec] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["auto", "name", "port", "replicas", "image", "resources", "volume"] - - @field_validator('image') - def image_validate_regular_expression(cls, value): - """Validates the regular expression""" - if value is None: - return value - - if not re.match(r"(?:[a-z]+\/)?([a-z]+)(?::[0-9]+)?", value): - raise ValueError(r"must validate the regular expression /(?:[a-z]+\/)?([a-z]+)(?::[0-9]+)?/") - return value - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # override the default output from pydantic by calling `to_dict()` of resources - if self.resources: - _dict['resources'] = self.resources.to_dict() - # override the default output from pydantic by calling `to_dict()` of volume - if self.volume: - _dict['volume'] = self.volume.to_dict() - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - # set to None if port (nullable) is None - # and model_fields_set contains the field - if self.port is None and "port" in self.model_fields_set: - _dict['port'] = None - - return _dict + :return: The auto of this DeploymentAutoArtifactConfig. + :rtype: bool + """ + return self._auto - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of DeploymentAutoArtifactConfig from a dict""" - if obj is None: - return None - - if not isinstance(obj, dict): - return cls.model_validate(obj) - - _obj = cls.model_validate({ - "auto": obj.get("auto"), - "name": obj.get("name"), - "port": obj.get("port"), - "replicas": obj.get("replicas"), - "image": obj.get("image"), - "resources": DeploymentResourcesConf.from_dict(obj["resources"]) if obj.get("resources") is not None else None, - "volume": DeploymentVolumeSpec.from_dict(obj["volume"]) if obj.get("volume") is not None else None - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj + @auto.setter + def auto(self, auto: bool): + """Sets the auto of this DeploymentAutoArtifactConfig. + + When true, enables automatic template # noqa: E501 + + :param auto: The auto of this DeploymentAutoArtifactConfig. + :type auto: bool + """ + if auto is None: + raise ValueError("Invalid value for `auto`, must not be `None`") # noqa: E501 + + self._auto = auto + + @property + def name(self) -> str: + """Gets the name of this DeploymentAutoArtifactConfig. + + # noqa: E501 + + :return: The name of this DeploymentAutoArtifactConfig. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name: str): + """Sets the name of this DeploymentAutoArtifactConfig. + + # noqa: E501 + + :param name: The name of this DeploymentAutoArtifactConfig. + :type name: str + """ + + self._name = name + + @property + def port(self) -> str: + """Gets the port of this DeploymentAutoArtifactConfig. + + Deployment port # noqa: E501 + + :return: The port of this DeploymentAutoArtifactConfig. + :rtype: str + """ + return self._port + + @port.setter + def port(self, port: str): + """Sets the port of this DeploymentAutoArtifactConfig. + + Deployment port # noqa: E501 + + :param port: The port of this DeploymentAutoArtifactConfig. + :type port: str + """ + + self._port = port + @property + def replicas(self) -> int: + """Gets the replicas of this DeploymentAutoArtifactConfig. + + Number of replicas # noqa: E501 + + :return: The replicas of this DeploymentAutoArtifactConfig. + :rtype: int + """ + return self._replicas + + @replicas.setter + def replicas(self, replicas: int): + """Sets the replicas of this DeploymentAutoArtifactConfig. + + Number of replicas # noqa: E501 + + :param replicas: The replicas of this DeploymentAutoArtifactConfig. + :type replicas: int + """ + + self._replicas = replicas + + @property + def image(self) -> str: + """Gets the image of this DeploymentAutoArtifactConfig. + + Image name to use in the deployment. Leave it blank to set from the application's Docker file # noqa: E501 + + :return: The image of this DeploymentAutoArtifactConfig. + :rtype: str + """ + return self._image + + @image.setter + def image(self, image: str): + """Sets the image of this DeploymentAutoArtifactConfig. + + Image name to use in the deployment. Leave it blank to set from the application's Docker file # noqa: E501 + + :param image: The image of this DeploymentAutoArtifactConfig. + :type image: str + """ + if image is not None and not re.search(r'(?:[a-z]+\/)?([a-z]+)(?::[0-9]+)?', image): # noqa: E501 + raise ValueError(r"Invalid value for `image`, must be a follow pattern or equal to `/(?:[a-z]+\/)?([a-z]+)(?::[0-9]+)?/`") # noqa: E501 + + self._image = image + + @property + def resources(self) -> DeploymentResourcesConf: + """Gets the resources of this DeploymentAutoArtifactConfig. + + + :return: The resources of this DeploymentAutoArtifactConfig. + :rtype: DeploymentResourcesConf + """ + return self._resources + + @resources.setter + def resources(self, resources: DeploymentResourcesConf): + """Sets the resources of this DeploymentAutoArtifactConfig. + + + :param resources: The resources of this DeploymentAutoArtifactConfig. + :type resources: DeploymentResourcesConf + """ + + self._resources = resources + + @property + def volume(self) -> DeploymentVolumeSpec: + """Gets the volume of this DeploymentAutoArtifactConfig. + + + :return: The volume of this DeploymentAutoArtifactConfig. + :rtype: DeploymentVolumeSpec + """ + return self._volume + + @volume.setter + def volume(self, volume: DeploymentVolumeSpec): + """Sets the volume of this DeploymentAutoArtifactConfig. + + + :param volume: The volume of this DeploymentAutoArtifactConfig. + :type volume: DeploymentVolumeSpec + """ + self._volume = volume diff --git a/libraries/models/cloudharness_model/models/deployment_resources_conf.py b/libraries/models/cloudharness_model/models/deployment_resources_conf.py index e52c14755..2d122230b 100644 --- a/libraries/models/cloudharness_model/models/deployment_resources_conf.py +++ b/libraries/models/cloudharness_model/models/deployment_resources_conf.py @@ -1,92 +1,89 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model.models.cpu_memory_config import CpuMemoryConfig +from cloudharness_model import util + +from cloudharness_model.models.cpu_memory_config import CpuMemoryConfig # noqa: E501 - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) +class DeploymentResourcesConf(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, requests=None, limits=None): # noqa: E501 + """DeploymentResourcesConf - a model defined in OpenAPI -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + :param requests: The requests of this DeploymentResourcesConf. # noqa: E501 + :type requests: CpuMemoryConfig + :param limits: The limits of this DeploymentResourcesConf. # noqa: E501 + :type limits: CpuMemoryConfig + """ + self.openapi_types = { + 'requests': CpuMemoryConfig, + 'limits': CpuMemoryConfig + } -from typing import Optional, Set -from typing_extensions import Self + self.attribute_map = { + 'requests': 'requests', + 'limits': 'limits' + } + self._requests = requests + self._limits = limits -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib -from cloudharness_model.models.cpu_memory_config import CpuMemoryConfig + @classmethod + def from_dict(cls, dikt) -> 'DeploymentResourcesConf': + """Returns the dict as a model -class DeploymentResourcesConf(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - requests: Optional[CpuMemoryConfig] = None - limits: Optional[CpuMemoryConfig] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["requests", "limits"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :param dikt: A dict. + :type: dict + :return: The DeploymentResourcesConf of this DeploymentResourcesConf. # noqa: E501 + :rtype: DeploymentResourcesConf """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # override the default output from pydantic by calling `to_dict()` of requests - if self.requests: - _dict['requests'] = self.requests.to_dict() - # override the default output from pydantic by calling `to_dict()` of limits - if self.limits: - _dict['limits'] = self.limits.to_dict() - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + return util.deserialize_model(dikt, cls) - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of DeploymentResourcesConf from a dict""" - if obj is None: - return None + @property + def requests(self) -> CpuMemoryConfig: + """Gets the requests of this DeploymentResourcesConf. + + + :return: The requests of this DeploymentResourcesConf. + :rtype: CpuMemoryConfig + """ + return self._requests + + @requests.setter + def requests(self, requests: CpuMemoryConfig): + """Sets the requests of this DeploymentResourcesConf. + + + :param requests: The requests of this DeploymentResourcesConf. + :type requests: CpuMemoryConfig + """ - if not isinstance(obj, dict): - return cls.model_validate(obj) + self._requests = requests - _obj = cls.model_validate({ - "requests": CpuMemoryConfig.from_dict(obj["requests"]) if obj.get("requests") is not None else None, - "limits": CpuMemoryConfig.from_dict(obj["limits"]) if obj.get("limits") is not None else None - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + @property + def limits(self) -> CpuMemoryConfig: + """Gets the limits of this DeploymentResourcesConf. - return _obj + :return: The limits of this DeploymentResourcesConf. + :rtype: CpuMemoryConfig + """ + return self._limits + + @limits.setter + def limits(self, limits: CpuMemoryConfig): + """Sets the limits of this DeploymentResourcesConf. + + + :param limits: The limits of this DeploymentResourcesConf. + :type limits: CpuMemoryConfig + """ + self._limits = limits diff --git a/libraries/models/cloudharness_model/models/deployment_volume_spec.py b/libraries/models/cloudharness_model/models/deployment_volume_spec.py index e38b01871..7843eae92 100644 --- a/libraries/models/cloudharness_model/models/deployment_volume_spec.py +++ b/libraries/models/cloudharness_model/models/deployment_volume_spec.py @@ -1,96 +1,179 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model import util - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) + +class DeploymentVolumeSpec(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, auto=None, name=None, mountpath=None, size=None, usenfs=None): # noqa: E501 + """DeploymentVolumeSpec - a model defined in OpenAPI + + :param auto: The auto of this DeploymentVolumeSpec. # noqa: E501 + :type auto: bool + :param name: The name of this DeploymentVolumeSpec. # noqa: E501 + :type name: str + :param mountpath: The mountpath of this DeploymentVolumeSpec. # noqa: E501 + :type mountpath: str + :param size: The size of this DeploymentVolumeSpec. # noqa: E501 + :type size: object + :param usenfs: The usenfs of this DeploymentVolumeSpec. # noqa: E501 + :type usenfs: bool + """ + self.openapi_types = { + 'auto': bool, + 'name': str, + 'mountpath': str, + 'size': object, + 'usenfs': bool + } + + self.attribute_map = { + 'auto': 'auto', + 'name': 'name', + 'mountpath': 'mountpath', + 'size': 'size', + 'usenfs': 'usenfs' + } + + self._auto = auto + self._name = name + self._mountpath = mountpath + self._size = size + self._usenfs = usenfs -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + @classmethod + def from_dict(cls, dikt) -> 'DeploymentVolumeSpec': + """Returns the dict as a model -from typing import Optional, Set -from typing_extensions import Self + :param dikt: A dict. + :type: dict + :return: The DeploymentVolumeSpec of this DeploymentVolumeSpec. # noqa: E501 + :rtype: DeploymentVolumeSpec + """ + return util.deserialize_model(dikt, cls) + @property + def auto(self) -> bool: + """Gets the auto of this DeploymentVolumeSpec. -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib + When true, enables automatic template # noqa: E501 -class DeploymentVolumeSpec(CloudHarnessBaseModel): - """ - Defines a volume attached to the deployment. Automatically created the volume claim and mounts. - """ # noqa: E501 - auto: Optional[StrictBool] = Field(default=None, description="When true, enables automatic template") - name: Optional[StrictStr] = None - mountpath: StrictStr = Field(description="The mount path for the volume") - size: Optional[Any] = Field(default=None, description="The volume size. E.g. 5Gi") - usenfs: Optional[StrictBool] = Field(default=None, description="Set to `true` to use the nfs on the created volume and mount as ReadWriteMany.") - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["auto", "name", "mountpath", "size", "usenfs"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :return: The auto of this DeploymentVolumeSpec. + :rtype: bool """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - # set to None if size (nullable) is None - # and model_fields_set contains the field - if self.size is None and "size" in self.model_fields_set: - _dict['size'] = None - - return _dict + return self._auto - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of DeploymentVolumeSpec from a dict""" - if obj is None: - return None + @auto.setter + def auto(self, auto: bool): + """Sets the auto of this DeploymentVolumeSpec. + + When true, enables automatic template # noqa: E501 + + :param auto: The auto of this DeploymentVolumeSpec. + :type auto: bool + """ + if auto is None: + raise ValueError("Invalid value for `auto`, must not be `None`") # noqa: E501 + + self._auto = auto + + @property + def name(self) -> str: + """Gets the name of this DeploymentVolumeSpec. + + # noqa: E501 + + :return: The name of this DeploymentVolumeSpec. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name: str): + """Sets the name of this DeploymentVolumeSpec. + + # noqa: E501 + + :param name: The name of this DeploymentVolumeSpec. + :type name: str + """ + + self._name = name + + @property + def mountpath(self) -> str: + """Gets the mountpath of this DeploymentVolumeSpec. - if not isinstance(obj, dict): - return cls.model_validate(obj) + The mount path for the volume # noqa: E501 - _obj = cls.model_validate({ - "auto": obj.get("auto"), - "name": obj.get("name"), - "mountpath": obj.get("mountpath"), - "size": obj.get("size"), - "usenfs": obj.get("usenfs") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + :return: The mountpath of this DeploymentVolumeSpec. + :rtype: str + """ + return self._mountpath + + @mountpath.setter + def mountpath(self, mountpath: str): + """Sets the mountpath of this DeploymentVolumeSpec. + + The mount path for the volume # noqa: E501 + + :param mountpath: The mountpath of this DeploymentVolumeSpec. + :type mountpath: str + """ + if mountpath is None: + raise ValueError("Invalid value for `mountpath`, must not be `None`") # noqa: E501 + + self._mountpath = mountpath + + @property + def size(self) -> object: + """Gets the size of this DeploymentVolumeSpec. + + The volume size. E.g. 5Gi # noqa: E501 + + :return: The size of this DeploymentVolumeSpec. + :rtype: object + """ + return self._size + + @size.setter + def size(self, size: object): + """Sets the size of this DeploymentVolumeSpec. - return _obj + The volume size. E.g. 5Gi # noqa: E501 + :param size: The size of this DeploymentVolumeSpec. + :type size: object + """ + + self._size = size + + @property + def usenfs(self) -> bool: + """Gets the usenfs of this DeploymentVolumeSpec. + + Set to `true` to use the nfs on the created volume and mount as ReadWriteMany. # noqa: E501 + + :return: The usenfs of this DeploymentVolumeSpec. + :rtype: bool + """ + return self._usenfs + + @usenfs.setter + def usenfs(self, usenfs: bool): + """Sets the usenfs of this DeploymentVolumeSpec. + + Set to `true` to use the nfs on the created volume and mount as ReadWriteMany. # noqa: E501 + + :param usenfs: The usenfs of this DeploymentVolumeSpec. + :type usenfs: bool + """ + self._usenfs = usenfs diff --git a/libraries/models/cloudharness_model/models/dockerfile_config.py b/libraries/models/cloudharness_model/models/dockerfile_config.py index 90a2eda3d..4dde44cb3 100644 --- a/libraries/models/cloudharness_model/models/dockerfile_config.py +++ b/libraries/models/cloudharness_model/models/dockerfile_config.py @@ -1,83 +1,63 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model import util - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) + +class DockerfileConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, build_args=None): # noqa: E501 + """DockerfileConfig - a model defined in OpenAPI -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + :param build_args: The build_args of this DockerfileConfig. # noqa: E501 + :type build_args: Dict[str, object] + """ + self.openapi_types = { + 'build_args': Dict[str, object] + } -from typing import Optional, Set -from typing_extensions import Self + self.attribute_map = { + 'build_args': 'buildArgs' + } + self._build_args = build_args -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib + @classmethod + def from_dict(cls, dikt) -> 'DockerfileConfig': + """Returns the dict as a model -class DockerfileConfig(CloudHarnessBaseModel): - """ - Configuration for a dockerfile - """ # noqa: E501 - build_args: Optional[Dict[str, Any]] = Field(default=None, alias="buildArgs") - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["buildArgs"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :param dikt: A dict. + :type: dict + :return: The DockerfileConfig of this DockerfileConfig. # noqa: E501 + :rtype: DockerfileConfig """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + return util.deserialize_model(dikt, cls) - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of DockerfileConfig from a dict""" - if obj is None: - return None + @property + def build_args(self) -> Dict[str, object]: + """Gets the build_args of this DockerfileConfig. + + # noqa: E501 - if not isinstance(obj, dict): - return cls.model_validate(obj) + :return: The build_args of this DockerfileConfig. + :rtype: Dict[str, object] + """ + return self._build_args - _obj = cls.model_validate({ - "buildArgs": obj.get("buildArgs") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + @build_args.setter + def build_args(self, build_args: Dict[str, object]): + """Sets the build_args of this DockerfileConfig. - return _obj + # noqa: E501 + :param build_args: The build_args of this DockerfileConfig. + :type build_args: Dict[str, object] + """ + self._build_args = build_args diff --git a/libraries/models/cloudharness_model/models/e2_e_tests_config.py b/libraries/models/cloudharness_model/models/e2_e_tests_config.py index 462d1a0c2..baba68df9 100644 --- a/libraries/models/cloudharness_model/models/e2_e_tests_config.py +++ b/libraries/models/cloudharness_model/models/e2_e_tests_config.py @@ -1,89 +1,151 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model import util - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) + +class E2ETestsConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, enabled=None, smoketest=None, ignore_console_errors=None, ignore_request_errors=None): # noqa: E501 + """E2ETestsConfig - a model defined in OpenAPI + + :param enabled: The enabled of this E2ETestsConfig. # noqa: E501 + :type enabled: bool + :param smoketest: The smoketest of this E2ETestsConfig. # noqa: E501 + :type smoketest: bool + :param ignore_console_errors: The ignore_console_errors of this E2ETestsConfig. # noqa: E501 + :type ignore_console_errors: bool + :param ignore_request_errors: The ignore_request_errors of this E2ETestsConfig. # noqa: E501 + :type ignore_request_errors: bool + """ + self.openapi_types = { + 'enabled': bool, + 'smoketest': bool, + 'ignore_console_errors': bool, + 'ignore_request_errors': bool + } + + self.attribute_map = { + 'enabled': 'enabled', + 'smoketest': 'smoketest', + 'ignore_console_errors': 'ignoreConsoleErrors', + 'ignore_request_errors': 'ignoreRequestErrors' + } + + self._enabled = enabled + self._smoketest = smoketest + self._ignore_console_errors = ignore_console_errors + self._ignore_request_errors = ignore_request_errors -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + @classmethod + def from_dict(cls, dikt) -> 'E2ETestsConfig': + """Returns the dict as a model -from typing import Optional, Set -from typing_extensions import Self + :param dikt: A dict. + :type: dict + :return: The E2ETestsConfig of this E2ETestsConfig. # noqa: E501 + :rtype: E2ETestsConfig + """ + return util.deserialize_model(dikt, cls) + @property + def enabled(self) -> bool: + """Gets the enabled of this E2ETestsConfig. -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib + Enables end to end testing for this application (default: false) # noqa: E501 -class E2ETestsConfig(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - enabled: StrictBool = Field(description="Enables end to end testing for this application (default: false)") - smoketest: StrictBool = Field(description="Specify whether to run the common smoke tests") - ignore_console_errors: Optional[StrictBool] = Field(default=None, alias="ignoreConsoleErrors") - ignore_request_errors: Optional[StrictBool] = Field(default=None, alias="ignoreRequestErrors") - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["enabled", "smoketest", "ignoreConsoleErrors", "ignoreRequestErrors"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :return: The enabled of this E2ETestsConfig. + :rtype: bool """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + return self._enabled - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of E2ETestsConfig from a dict""" - if obj is None: - return None + @enabled.setter + def enabled(self, enabled: bool): + """Sets the enabled of this E2ETestsConfig. - if not isinstance(obj, dict): - return cls.model_validate(obj) + Enables end to end testing for this application (default: false) # noqa: E501 + + :param enabled: The enabled of this E2ETestsConfig. + :type enabled: bool + """ + if enabled is None: + raise ValueError("Invalid value for `enabled`, must not be `None`") # noqa: E501 - _obj = cls.model_validate({ - "enabled": obj.get("enabled"), - "smoketest": obj.get("smoketest"), - "ignoreConsoleErrors": obj.get("ignoreConsoleErrors"), - "ignoreRequestErrors": obj.get("ignoreRequestErrors") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + self._enabled = enabled + + @property + def smoketest(self) -> bool: + """Gets the smoketest of this E2ETestsConfig. + + Specify whether to run the common smoke tests # noqa: E501 + + :return: The smoketest of this E2ETestsConfig. + :rtype: bool + """ + return self._smoketest + + @smoketest.setter + def smoketest(self, smoketest: bool): + """Sets the smoketest of this E2ETestsConfig. + + Specify whether to run the common smoke tests # noqa: E501 + + :param smoketest: The smoketest of this E2ETestsConfig. + :type smoketest: bool + """ + if smoketest is None: + raise ValueError("Invalid value for `smoketest`, must not be `None`") # noqa: E501 - return _obj + self._smoketest = smoketest + @property + def ignore_console_errors(self) -> bool: + """Gets the ignore_console_errors of this E2ETestsConfig. + + # noqa: E501 + + :return: The ignore_console_errors of this E2ETestsConfig. + :rtype: bool + """ + return self._ignore_console_errors + + @ignore_console_errors.setter + def ignore_console_errors(self, ignore_console_errors: bool): + """Sets the ignore_console_errors of this E2ETestsConfig. + + # noqa: E501 + + :param ignore_console_errors: The ignore_console_errors of this E2ETestsConfig. + :type ignore_console_errors: bool + """ + + self._ignore_console_errors = ignore_console_errors + + @property + def ignore_request_errors(self) -> bool: + """Gets the ignore_request_errors of this E2ETestsConfig. + + # noqa: E501 + + :return: The ignore_request_errors of this E2ETestsConfig. + :rtype: bool + """ + return self._ignore_request_errors + + @ignore_request_errors.setter + def ignore_request_errors(self, ignore_request_errors: bool): + """Sets the ignore_request_errors of this E2ETestsConfig. + + # noqa: E501 + + :param ignore_request_errors: The ignore_request_errors of this E2ETestsConfig. + :type ignore_request_errors: bool + """ + self._ignore_request_errors = ignore_request_errors diff --git a/libraries/models/cloudharness_model/models/file_resources_config.py b/libraries/models/cloudharness_model/models/file_resources_config.py index 03b8d76d5..2c73b702d 100644 --- a/libraries/models/cloudharness_model/models/file_resources_config.py +++ b/libraries/models/cloudharness_model/models/file_resources_config.py @@ -1,101 +1,131 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +import re +from cloudharness_model import util - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) +import re # noqa: E501 + +class FileResourcesConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, name=None, src=None, dst=None): # noqa: E501 + """FileResourcesConfig - a model defined in OpenAPI -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + :param name: The name of this FileResourcesConfig. # noqa: E501 + :type name: str + :param src: The src of this FileResourcesConfig. # noqa: E501 + :type src: str + :param dst: The dst of this FileResourcesConfig. # noqa: E501 + :type dst: str + """ + self.openapi_types = { + 'name': str, + 'src': str, + 'dst': str + } + + self.attribute_map = { + 'name': 'name', + 'src': 'src', + 'dst': 'dst' + } + + self._name = name + self._src = src + self._dst = dst -from typing import Optional, Set -from typing_extensions import Self + @classmethod + def from_dict(cls, dikt) -> 'FileResourcesConfig': + """Returns the dict as a model + :param dikt: A dict. + :type: dict + :return: The FileResourcesConfig of this FileResourcesConfig. # noqa: E501 + :rtype: FileResourcesConfig + """ + return util.deserialize_model(dikt, cls) -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib + @property + def name(self) -> str: + """Gets the name of this FileResourcesConfig. -class FileResourcesConfig(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - name: Annotated[str, Field(strict=True)] - src: Annotated[str, Field(strict=True)] - dst: StrictStr - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["name", "src", "dst"] - - @field_validator('name') - def name_validate_regular_expression(cls, value): - """Validates the regular expression""" - if not re.match(r"^[^<>:;,?*|]+$", value): - raise ValueError(r"must validate the regular expression /^[^<>:;,?*|]+$/") - return value - - @field_validator('src') - def src_validate_regular_expression(cls, value): - """Validates the regular expression""" - if not re.match(r"^[^<>:;,?*|]+$", value): - raise ValueError(r"must validate the regular expression /^[^<>:;,?*|]+$/") - return value - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + # noqa: E501 + + :return: The name of this FileResourcesConfig. + :rtype: str """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + return self._name - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of FileResourcesConfig from a dict""" - if obj is None: - return None + @name.setter + def name(self, name: str): + """Sets the name of this FileResourcesConfig. + + # noqa: E501 + + :param name: The name of this FileResourcesConfig. + :type name: str + """ + if name is None: + raise ValueError("Invalid value for `name`, must not be `None`") # noqa: E501 + if name is not None and not re.search(r'^[^<>:;,?*|]+$', name): # noqa: E501 + raise ValueError("Invalid value for `name`, must be a follow pattern or equal to `/^[^<>:;,?*|]+$/`") # noqa: E501 + + self._name = name - if not isinstance(obj, dict): - return cls.model_validate(obj) + @property + def src(self) -> str: + """Gets the src of this FileResourcesConfig. - _obj = cls.model_validate({ - "name": obj.get("name"), - "src": obj.get("src"), - "dst": obj.get("dst") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + # noqa: E501 - return _obj + :return: The src of this FileResourcesConfig. + :rtype: str + """ + return self._src + @src.setter + def src(self, src: str): + """Sets the src of this FileResourcesConfig. + + # noqa: E501 + + :param src: The src of this FileResourcesConfig. + :type src: str + """ + if src is None: + raise ValueError("Invalid value for `src`, must not be `None`") # noqa: E501 + if src is not None and not re.search(r'^[^<>:;,?*|]+$', src): # noqa: E501 + raise ValueError("Invalid value for `src`, must be a follow pattern or equal to `/^[^<>:;,?*|]+$/`") # noqa: E501 + + self._src = src + + @property + def dst(self) -> str: + """Gets the dst of this FileResourcesConfig. + + # noqa: E501 + + :return: The dst of this FileResourcesConfig. + :rtype: str + """ + return self._dst + + @dst.setter + def dst(self, dst: str): + """Sets the dst of this FileResourcesConfig. + + # noqa: E501 + + :param dst: The dst of this FileResourcesConfig. + :type dst: str + """ + if dst is None: + raise ValueError("Invalid value for `dst`, must not be `None`") # noqa: E501 + self._dst = dst diff --git a/libraries/models/cloudharness_model/models/gatekeeper_conf.py b/libraries/models/cloudharness_model/models/gatekeeper_conf.py deleted file mode 100644 index 2e757429a..000000000 --- a/libraries/models/cloudharness_model/models/gatekeeper_conf.py +++ /dev/null @@ -1,85 +0,0 @@ -# coding: utf-8 - -""" - cloudharness - - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) - - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -from __future__ import annotations -import pprint -import re # noqa: F401 -import json - -from typing import Optional, Set -from typing_extensions import Self - - -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib - -class GatekeeperConf(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - image: Optional[StrictStr] = None - replicas: Optional[StrictInt] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["image", "replicas"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict - - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of GatekeeperConf from a dict""" - if obj is None: - return None - - if not isinstance(obj, dict): - return cls.model_validate(obj) - - _obj = cls.model_validate({ - "image": obj.get("image"), - "replicas": obj.get("replicas") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj - - diff --git a/libraries/models/cloudharness_model/models/git_dependency_config.py b/libraries/models/cloudharness_model/models/git_dependency_config.py index bd87c890a..8b3808153 100644 --- a/libraries/models/cloudharness_model/models/git_dependency_config.py +++ b/libraries/models/cloudharness_model/models/git_dependency_config.py @@ -1,87 +1,119 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model import util - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) + +class GitDependencyConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, url=None, branch_tag=None, path=None): # noqa: E501 + """GitDependencyConfig - a model defined in OpenAPI -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + :param url: The url of this GitDependencyConfig. # noqa: E501 + :type url: str + :param branch_tag: The branch_tag of this GitDependencyConfig. # noqa: E501 + :type branch_tag: str + :param path: The path of this GitDependencyConfig. # noqa: E501 + :type path: str + """ + self.openapi_types = { + 'url': str, + 'branch_tag': str, + 'path': str + } + + self.attribute_map = { + 'url': 'url', + 'branch_tag': 'branch_tag', + 'path': 'path' + } + + self._url = url + self._branch_tag = branch_tag + self._path = path -from typing import Optional, Set -from typing_extensions import Self + @classmethod + def from_dict(cls, dikt) -> 'GitDependencyConfig': + """Returns the dict as a model + :param dikt: A dict. + :type: dict + :return: The GitDependencyConfig of this GitDependencyConfig. # noqa: E501 + :rtype: GitDependencyConfig + """ + return util.deserialize_model(dikt, cls) -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib + @property + def url(self) -> str: + """Gets the url of this GitDependencyConfig. -class GitDependencyConfig(CloudHarnessBaseModel): - """ - Defines a git repo to be cloned inside the application path - """ # noqa: E501 - url: StrictStr - branch_tag: StrictStr - path: Optional[StrictStr] = Field(default=None, description="Defines the path where the repo is cloned. default: /git") - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["url", "branch_tag", "path"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + + :return: The url of this GitDependencyConfig. + :rtype: str """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + return self._url - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of GitDependencyConfig from a dict""" - if obj is None: - return None + @url.setter + def url(self, url: str): + """Sets the url of this GitDependencyConfig. + + + :param url: The url of this GitDependencyConfig. + :type url: str + """ + if url is None: + raise ValueError("Invalid value for `url`, must not be `None`") # noqa: E501 + + self._url = url - if not isinstance(obj, dict): - return cls.model_validate(obj) + @property + def branch_tag(self) -> str: + """Gets the branch_tag of this GitDependencyConfig. - _obj = cls.model_validate({ - "url": obj.get("url"), - "branch_tag": obj.get("branch_tag"), - "path": obj.get("path") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - return _obj + :return: The branch_tag of this GitDependencyConfig. + :rtype: str + """ + return self._branch_tag + @branch_tag.setter + def branch_tag(self, branch_tag: str): + """Sets the branch_tag of this GitDependencyConfig. + + + :param branch_tag: The branch_tag of this GitDependencyConfig. + :type branch_tag: str + """ + if branch_tag is None: + raise ValueError("Invalid value for `branch_tag`, must not be `None`") # noqa: E501 + + self._branch_tag = branch_tag + + @property + def path(self) -> str: + """Gets the path of this GitDependencyConfig. + + Defines the path where the repo is cloned. default: /git # noqa: E501 + + :return: The path of this GitDependencyConfig. + :rtype: str + """ + return self._path + + @path.setter + def path(self, path: str): + """Sets the path of this GitDependencyConfig. + + Defines the path where the repo is cloned. default: /git # noqa: E501 + + :param path: The path of this GitDependencyConfig. + :type path: str + """ + self._path = path diff --git a/libraries/models/cloudharness_model/models/harness_main_config.py b/libraries/models/cloudharness_model/models/harness_main_config.py index 58de55813..9075268b4 100644 --- a/libraries/models/cloudharness_model/models/harness_main_config.py +++ b/libraries/models/cloudharness_model/models/harness_main_config.py @@ -1,151 +1,441 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model.models.application_config import ApplicationConfig +from cloudharness_model.models.backup_config import BackupConfig +from cloudharness_model.models.name_value import NameValue +from cloudharness_model.models.registry_config import RegistryConfig +from cloudharness_model import util + +from cloudharness_model.models.application_config import ApplicationConfig # noqa: E501 +from cloudharness_model.models.backup_config import BackupConfig # noqa: E501 +from cloudharness_model.models.name_value import NameValue # noqa: E501 +from cloudharness_model.models.registry_config import RegistryConfig # noqa: E501 - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) +class HarnessMainConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, local=None, secured_gatekeepers=None, domain=None, namespace=None, mainapp=None, registry=None, tag=None, apps=None, env=None, privenv=None, backup=None, name=None, task_images=None, build_hash=None): # noqa: E501 + """HarnessMainConfig - a model defined in OpenAPI -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + :param local: The local of this HarnessMainConfig. # noqa: E501 + :type local: bool + :param secured_gatekeepers: The secured_gatekeepers of this HarnessMainConfig. # noqa: E501 + :type secured_gatekeepers: bool + :param domain: The domain of this HarnessMainConfig. # noqa: E501 + :type domain: str + :param namespace: The namespace of this HarnessMainConfig. # noqa: E501 + :type namespace: str + :param mainapp: The mainapp of this HarnessMainConfig. # noqa: E501 + :type mainapp: str + :param registry: The registry of this HarnessMainConfig. # noqa: E501 + :type registry: RegistryConfig + :param tag: The tag of this HarnessMainConfig. # noqa: E501 + :type tag: str + :param apps: The apps of this HarnessMainConfig. # noqa: E501 + :type apps: Dict[str, ApplicationConfig] + :param env: The env of this HarnessMainConfig. # noqa: E501 + :type env: List[NameValue] + :param privenv: The privenv of this HarnessMainConfig. # noqa: E501 + :type privenv: NameValue + :param backup: The backup of this HarnessMainConfig. # noqa: E501 + :type backup: BackupConfig + :param name: The name of this HarnessMainConfig. # noqa: E501 + :type name: str + :param task_images: The task_images of this HarnessMainConfig. # noqa: E501 + :type task_images: Dict[str, object] + :param build_hash: The build_hash of this HarnessMainConfig. # noqa: E501 + :type build_hash: str + """ + self.openapi_types = { + 'local': bool, + 'secured_gatekeepers': bool, + 'domain': str, + 'namespace': str, + 'mainapp': str, + 'registry': RegistryConfig, + 'tag': str, + 'apps': Dict[str, ApplicationConfig], + 'env': List[NameValue], + 'privenv': NameValue, + 'backup': BackupConfig, + 'name': str, + 'task_images': Dict[str, object], + 'build_hash': str + } -from typing import Optional, Set -from typing_extensions import Self + self.attribute_map = { + 'local': 'local', + 'secured_gatekeepers': 'secured_gatekeepers', + 'domain': 'domain', + 'namespace': 'namespace', + 'mainapp': 'mainapp', + 'registry': 'registry', + 'tag': 'tag', + 'apps': 'apps', + 'env': 'env', + 'privenv': 'privenv', + 'backup': 'backup', + 'name': 'name', + 'task_images': 'task-images', + 'build_hash': 'build_hash' + } + self._local = local + self._secured_gatekeepers = secured_gatekeepers + self._domain = domain + self._namespace = namespace + self._mainapp = mainapp + self._registry = registry + self._tag = tag + self._apps = apps + self._env = env + self._privenv = privenv + self._backup = backup + self._name = name + self._task_images = task_images + self._build_hash = build_hash -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib -from cloudharness_model.models.application_config import ApplicationConfig -from cloudharness_model.models.backup_config import BackupConfig -from cloudharness_model.models.ingress_config import IngressConfig -from cloudharness_model.models.name_value import NameValue -from cloudharness_model.models.registry_config import RegistryConfig + @classmethod + def from_dict(cls, dikt) -> 'HarnessMainConfig': + """Returns the dict as a model -class HarnessMainConfig(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - local: StrictBool = Field(description="If set to true, local DNS mapping is added to pods.") - secured_gatekeepers: StrictBool = Field(description="Enables/disables Gatekeepers on secured applications. Set to false for testing/development") - domain: StrictStr = Field(description="The root domain") - namespace: StrictStr = Field(description="The K8s namespace.") - mainapp: StrictStr = Field(description="Defines the app to map to the root domain") - registry: Optional[RegistryConfig] = None - tag: Optional[StrictStr] = Field(default=None, description="Docker tag used to push/pull the built images.") - apps: Dict[str, ApplicationConfig] - env: Optional[List[NameValue]] = Field(default=None, description="Environmental variables added to all pods") - privenv: Optional[List[NameValue]] = Field(default=None, description="Private environmental variables added to all pods") - backup: Optional[BackupConfig] = None - name: Optional[StrictStr] = Field(default=None, description="Base name") - task_images: Optional[Dict[str, Any]] = Field(default=None, alias="task-images") - build_hash: Optional[StrictStr] = None - ingress: Optional[IngressConfig] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["local", "secured_gatekeepers", "domain", "namespace", "mainapp", "registry", "tag", "apps", "env", "privenv", "backup", "name", "task-images", "build_hash", "ingress"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # override the default output from pydantic by calling `to_dict()` of registry - if self.registry: - _dict['registry'] = self.registry.to_dict() - # override the default output from pydantic by calling `to_dict()` of each value in apps (dict) - _field_dict = {} - if self.apps: - for _key_apps in self.apps: - if self.apps[_key_apps]: - _field_dict[_key_apps] = self.apps[_key_apps].to_dict() - _dict['apps'] = _field_dict - # override the default output from pydantic by calling `to_dict()` of each item in env (list) - _items = [] - if self.env: - for _item_env in self.env: - if _item_env: - _items.append(_item_env.to_dict()) - _dict['env'] = _items - # override the default output from pydantic by calling `to_dict()` of each item in privenv (list) - _items = [] - if self.privenv: - for _item_privenv in self.privenv: - if _item_privenv: - _items.append(_item_privenv.to_dict()) - _dict['privenv'] = _items - # override the default output from pydantic by calling `to_dict()` of backup - if self.backup: - _dict['backup'] = self.backup.to_dict() - # override the default output from pydantic by calling `to_dict()` of ingress - if self.ingress: - _dict['ingress'] = self.ingress.to_dict() - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + :param dikt: A dict. + :type: dict + :return: The HarnessMainConfig of this HarnessMainConfig. # noqa: E501 + :rtype: HarnessMainConfig + """ + return util.deserialize_model(dikt, cls) - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of HarnessMainConfig from a dict""" - if obj is None: - return None - - if not isinstance(obj, dict): - return cls.model_validate(obj) - - _obj = cls.model_validate({ - "local": obj.get("local"), - "secured_gatekeepers": obj.get("secured_gatekeepers"), - "domain": obj.get("domain"), - "namespace": obj.get("namespace"), - "mainapp": obj.get("mainapp"), - "registry": RegistryConfig.from_dict(obj["registry"]) if obj.get("registry") is not None else None, - "tag": obj.get("tag"), - "apps": dict( - (_k, ApplicationConfig.from_dict(_v)) - for _k, _v in obj["apps"].items() - ) - if obj.get("apps") is not None - else None, - "env": [NameValue.from_dict(_item) for _item in obj["env"]] if obj.get("env") is not None else None, - "privenv": [NameValue.from_dict(_item) for _item in obj["privenv"]] if obj.get("privenv") is not None else None, - "backup": BackupConfig.from_dict(obj["backup"]) if obj.get("backup") is not None else None, - "name": obj.get("name"), - "task-images": obj.get("task-images"), - "build_hash": obj.get("build_hash"), - "ingress": IngressConfig.from_dict(obj["ingress"]) if obj.get("ingress") is not None else None - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj + @property + def local(self) -> bool: + """Gets the local of this HarnessMainConfig. + + If set to true, local DNS mapping is added to pods. # noqa: E501 + + :return: The local of this HarnessMainConfig. + :rtype: bool + """ + return self._local + + @local.setter + def local(self, local: bool): + """Sets the local of this HarnessMainConfig. + + If set to true, local DNS mapping is added to pods. # noqa: E501 + + :param local: The local of this HarnessMainConfig. + :type local: bool + """ + if local is None: + raise ValueError("Invalid value for `local`, must not be `None`") # noqa: E501 + + self._local = local + + @property + def secured_gatekeepers(self) -> bool: + """Gets the secured_gatekeepers of this HarnessMainConfig. + + Enables/disables Gatekeepers on secured applications. Set to false for testing/development # noqa: E501 + + :return: The secured_gatekeepers of this HarnessMainConfig. + :rtype: bool + """ + return self._secured_gatekeepers + + @secured_gatekeepers.setter + def secured_gatekeepers(self, secured_gatekeepers: bool): + """Sets the secured_gatekeepers of this HarnessMainConfig. + + Enables/disables Gatekeepers on secured applications. Set to false for testing/development # noqa: E501 + + :param secured_gatekeepers: The secured_gatekeepers of this HarnessMainConfig. + :type secured_gatekeepers: bool + """ + if secured_gatekeepers is None: + raise ValueError("Invalid value for `secured_gatekeepers`, must not be `None`") # noqa: E501 + + self._secured_gatekeepers = secured_gatekeepers + + @property + def domain(self) -> str: + """Gets the domain of this HarnessMainConfig. + + The root domain # noqa: E501 + + :return: The domain of this HarnessMainConfig. + :rtype: str + """ + return self._domain + + @domain.setter + def domain(self, domain: str): + """Sets the domain of this HarnessMainConfig. + + The root domain # noqa: E501 + + :param domain: The domain of this HarnessMainConfig. + :type domain: str + """ + if domain is None: + raise ValueError("Invalid value for `domain`, must not be `None`") # noqa: E501 + + self._domain = domain + + @property + def namespace(self) -> str: + """Gets the namespace of this HarnessMainConfig. + + The K8s namespace. # noqa: E501 + + :return: The namespace of this HarnessMainConfig. + :rtype: str + """ + return self._namespace + + @namespace.setter + def namespace(self, namespace: str): + """Sets the namespace of this HarnessMainConfig. + + The K8s namespace. # noqa: E501 + + :param namespace: The namespace of this HarnessMainConfig. + :type namespace: str + """ + if namespace is None: + raise ValueError("Invalid value for `namespace`, must not be `None`") # noqa: E501 + + self._namespace = namespace + + @property + def mainapp(self) -> str: + """Gets the mainapp of this HarnessMainConfig. + + Defines the app to map to the root domain # noqa: E501 + + :return: The mainapp of this HarnessMainConfig. + :rtype: str + """ + return self._mainapp + + @mainapp.setter + def mainapp(self, mainapp: str): + """Sets the mainapp of this HarnessMainConfig. + + Defines the app to map to the root domain # noqa: E501 + + :param mainapp: The mainapp of this HarnessMainConfig. + :type mainapp: str + """ + if mainapp is None: + raise ValueError("Invalid value for `mainapp`, must not be `None`") # noqa: E501 + + self._mainapp = mainapp + + @property + def registry(self) -> RegistryConfig: + """Gets the registry of this HarnessMainConfig. + + + :return: The registry of this HarnessMainConfig. + :rtype: RegistryConfig + """ + return self._registry + + @registry.setter + def registry(self, registry: RegistryConfig): + """Sets the registry of this HarnessMainConfig. + + + :param registry: The registry of this HarnessMainConfig. + :type registry: RegistryConfig + """ + + self._registry = registry + + @property + def tag(self) -> str: + """Gets the tag of this HarnessMainConfig. + Docker tag used to push/pull the built images. # noqa: E501 + + :return: The tag of this HarnessMainConfig. + :rtype: str + """ + return self._tag + + @tag.setter + def tag(self, tag: str): + """Sets the tag of this HarnessMainConfig. + + Docker tag used to push/pull the built images. # noqa: E501 + + :param tag: The tag of this HarnessMainConfig. + :type tag: str + """ + + self._tag = tag + + @property + def apps(self) -> Dict[str, ApplicationConfig]: + """Gets the apps of this HarnessMainConfig. + + # noqa: E501 + + :return: The apps of this HarnessMainConfig. + :rtype: Dict[str, ApplicationConfig] + """ + return self._apps + + @apps.setter + def apps(self, apps: Dict[str, ApplicationConfig]): + """Sets the apps of this HarnessMainConfig. + + # noqa: E501 + + :param apps: The apps of this HarnessMainConfig. + :type apps: Dict[str, ApplicationConfig] + """ + if apps is None: + raise ValueError("Invalid value for `apps`, must not be `None`") # noqa: E501 + + self._apps = apps + + @property + def env(self) -> List[NameValue]: + """Gets the env of this HarnessMainConfig. + + Environmental variables added to all pods # noqa: E501 + + :return: The env of this HarnessMainConfig. + :rtype: List[NameValue] + """ + return self._env + + @env.setter + def env(self, env: List[NameValue]): + """Sets the env of this HarnessMainConfig. + + Environmental variables added to all pods # noqa: E501 + + :param env: The env of this HarnessMainConfig. + :type env: List[NameValue] + """ + + self._env = env + + @property + def privenv(self) -> NameValue: + """Gets the privenv of this HarnessMainConfig. + + + :return: The privenv of this HarnessMainConfig. + :rtype: NameValue + """ + return self._privenv + + @privenv.setter + def privenv(self, privenv: NameValue): + """Sets the privenv of this HarnessMainConfig. + + + :param privenv: The privenv of this HarnessMainConfig. + :type privenv: NameValue + """ + + self._privenv = privenv + + @property + def backup(self) -> BackupConfig: + """Gets the backup of this HarnessMainConfig. + + + :return: The backup of this HarnessMainConfig. + :rtype: BackupConfig + """ + return self._backup + + @backup.setter + def backup(self, backup: BackupConfig): + """Sets the backup of this HarnessMainConfig. + + + :param backup: The backup of this HarnessMainConfig. + :type backup: BackupConfig + """ + + self._backup = backup + + @property + def name(self) -> str: + """Gets the name of this HarnessMainConfig. + + Base name # noqa: E501 + + :return: The name of this HarnessMainConfig. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name: str): + """Sets the name of this HarnessMainConfig. + + Base name # noqa: E501 + + :param name: The name of this HarnessMainConfig. + :type name: str + """ + + self._name = name + + @property + def task_images(self) -> Dict[str, object]: + """Gets the task_images of this HarnessMainConfig. + + # noqa: E501 + + :return: The task_images of this HarnessMainConfig. + :rtype: Dict[str, object] + """ + return self._task_images + + @task_images.setter + def task_images(self, task_images: Dict[str, object]): + """Sets the task_images of this HarnessMainConfig. + + # noqa: E501 + + :param task_images: The task_images of this HarnessMainConfig. + :type task_images: Dict[str, object] + """ + + self._task_images = task_images + + @property + def build_hash(self) -> str: + """Gets the build_hash of this HarnessMainConfig. + + # noqa: E501 + + :return: The build_hash of this HarnessMainConfig. + :rtype: str + """ + return self._build_hash + + @build_hash.setter + def build_hash(self, build_hash: str): + """Sets the build_hash of this HarnessMainConfig. + + # noqa: E501 + + :param build_hash: The build_hash of this HarnessMainConfig. + :type build_hash: str + """ + self._build_hash = build_hash diff --git a/libraries/models/cloudharness_model/models/ingress_config.py b/libraries/models/cloudharness_model/models/ingress_config.py index 9e9154f5a..d0b5352d0 100644 --- a/libraries/models/cloudharness_model/models/ingress_config.py +++ b/libraries/models/cloudharness_model/models/ingress_config.py @@ -1,95 +1,149 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model.models.ingress_config_all_of_letsencrypt import IngressConfigAllOfLetsencrypt +from cloudharness_model import util + +from cloudharness_model.models.ingress_config_all_of_letsencrypt import IngressConfigAllOfLetsencrypt # noqa: E501 - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) +class IngressConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, auto=None, name=None, ssl_redirect=None, letsencrypt=None): # noqa: E501 + """IngressConfig - a model defined in OpenAPI + + :param auto: The auto of this IngressConfig. # noqa: E501 + :type auto: bool + :param name: The name of this IngressConfig. # noqa: E501 + :type name: str + :param ssl_redirect: The ssl_redirect of this IngressConfig. # noqa: E501 + :type ssl_redirect: bool + :param letsencrypt: The letsencrypt of this IngressConfig. # noqa: E501 + :type letsencrypt: IngressConfigAllOfLetsencrypt + """ + self.openapi_types = { + 'auto': bool, + 'name': str, + 'ssl_redirect': bool, + 'letsencrypt': IngressConfigAllOfLetsencrypt + } + + self.attribute_map = { + 'auto': 'auto', + 'name': 'name', + 'ssl_redirect': 'ssl_redirect', + 'letsencrypt': 'letsencrypt' + } + + self._auto = auto + self._name = name + self._ssl_redirect = ssl_redirect + self._letsencrypt = letsencrypt -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + @classmethod + def from_dict(cls, dikt) -> 'IngressConfig': + """Returns the dict as a model -from typing import Optional, Set -from typing_extensions import Self + :param dikt: A dict. + :type: dict + :return: The IngressConfig of this IngressConfig. # noqa: E501 + :rtype: IngressConfig + """ + return util.deserialize_model(dikt, cls) + @property + def auto(self) -> bool: + """Gets the auto of this IngressConfig. -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib -from cloudharness_model.models.ingress_config_all_of_letsencrypt import IngressConfigAllOfLetsencrypt + When true, enables automatic template # noqa: E501 -class IngressConfig(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - auto: Optional[StrictBool] = Field(default=None, description="When true, enables automatic template") - name: Optional[StrictStr] = None - ssl_redirect: Optional[StrictBool] = None - letsencrypt: Optional[IngressConfigAllOfLetsencrypt] = None - enabled: Optional[StrictBool] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["auto", "name", "ssl_redirect", "letsencrypt", "enabled"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :return: The auto of this IngressConfig. + :rtype: bool """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # override the default output from pydantic by calling `to_dict()` of letsencrypt - if self.letsencrypt: - _dict['letsencrypt'] = self.letsencrypt.to_dict() - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + return self._auto - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of IngressConfig from a dict""" - if obj is None: - return None + @auto.setter + def auto(self, auto: bool): + """Sets the auto of this IngressConfig. - if not isinstance(obj, dict): - return cls.model_validate(obj) + When true, enables automatic template # noqa: E501 - _obj = cls.model_validate({ - "auto": obj.get("auto"), - "name": obj.get("name"), - "ssl_redirect": obj.get("ssl_redirect"), - "letsencrypt": IngressConfigAllOfLetsencrypt.from_dict(obj["letsencrypt"]) if obj.get("letsencrypt") is not None else None, - "enabled": obj.get("enabled") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + :param auto: The auto of this IngressConfig. + :type auto: bool + """ + if auto is None: + raise ValueError("Invalid value for `auto`, must not be `None`") # noqa: E501 + + self._auto = auto + + @property + def name(self) -> str: + """Gets the name of this IngressConfig. - return _obj + # noqa: E501 + + :return: The name of this IngressConfig. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name: str): + """Sets the name of this IngressConfig. + + # noqa: E501 + + :param name: The name of this IngressConfig. + :type name: str + """ + self._name = name + + @property + def ssl_redirect(self) -> bool: + """Gets the ssl_redirect of this IngressConfig. + + # noqa: E501 + + :return: The ssl_redirect of this IngressConfig. + :rtype: bool + """ + return self._ssl_redirect + + @ssl_redirect.setter + def ssl_redirect(self, ssl_redirect: bool): + """Sets the ssl_redirect of this IngressConfig. + + # noqa: E501 + + :param ssl_redirect: The ssl_redirect of this IngressConfig. + :type ssl_redirect: bool + """ + + self._ssl_redirect = ssl_redirect + + @property + def letsencrypt(self) -> IngressConfigAllOfLetsencrypt: + """Gets the letsencrypt of this IngressConfig. + + + :return: The letsencrypt of this IngressConfig. + :rtype: IngressConfigAllOfLetsencrypt + """ + return self._letsencrypt + + @letsencrypt.setter + def letsencrypt(self, letsencrypt: IngressConfigAllOfLetsencrypt): + """Sets the letsencrypt of this IngressConfig. + + + :param letsencrypt: The letsencrypt of this IngressConfig. + :type letsencrypt: IngressConfigAllOfLetsencrypt + """ + self._letsencrypt = letsencrypt diff --git a/libraries/models/cloudharness_model/models/ingress_config_all_of_letsencrypt.py b/libraries/models/cloudharness_model/models/ingress_config_all_of_letsencrypt.py index 37a99cc5d..a9286c070 100644 --- a/libraries/models/cloudharness_model/models/ingress_config_all_of_letsencrypt.py +++ b/libraries/models/cloudharness_model/models/ingress_config_all_of_letsencrypt.py @@ -1,83 +1,61 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model import util - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) + +class IngressConfigAllOfLetsencrypt(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, email=None): # noqa: E501 + """IngressConfigAllOfLetsencrypt - a model defined in OpenAPI -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + :param email: The email of this IngressConfigAllOfLetsencrypt. # noqa: E501 + :type email: str + """ + self.openapi_types = { + 'email': str + } -from typing import Optional, Set -from typing_extensions import Self + self.attribute_map = { + 'email': 'email' + } + self._email = email -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib + @classmethod + def from_dict(cls, dikt) -> 'IngressConfigAllOfLetsencrypt': + """Returns the dict as a model -class IngressConfigAllOfLetsencrypt(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - email: Optional[StrictStr] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["email"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :param dikt: A dict. + :type: dict + :return: The IngressConfig_allOf_letsencrypt of this IngressConfigAllOfLetsencrypt. # noqa: E501 + :rtype: IngressConfigAllOfLetsencrypt """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + return util.deserialize_model(dikt, cls) + + @property + def email(self) -> str: + """Gets the email of this IngressConfigAllOfLetsencrypt. - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of IngressConfigAllOfLetsencrypt from a dict""" - if obj is None: - return None - if not isinstance(obj, dict): - return cls.model_validate(obj) + :return: The email of this IngressConfigAllOfLetsencrypt. + :rtype: str + """ + return self._email - _obj = cls.model_validate({ - "email": obj.get("email") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + @email.setter + def email(self, email: str): + """Sets the email of this IngressConfigAllOfLetsencrypt. - return _obj + :param email: The email of this IngressConfigAllOfLetsencrypt. + :type email: str + """ + self._email = email diff --git a/libraries/models/cloudharness_model/models/jupyter_hub_config.py b/libraries/models/cloudharness_model/models/jupyter_hub_config.py index 433772b1d..35095ce4c 100644 --- a/libraries/models/cloudharness_model/models/jupyter_hub_config.py +++ b/libraries/models/cloudharness_model/models/jupyter_hub_config.py @@ -1,94 +1,147 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model import util - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) + +class JupyterHubConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, args=None, extra_config=None, spawner_extra_config=None, application_hook=None): # noqa: E501 + """JupyterHubConfig - a model defined in OpenAPI + + :param args: The args of this JupyterHubConfig. # noqa: E501 + :type args: List[str] + :param extra_config: The extra_config of this JupyterHubConfig. # noqa: E501 + :type extra_config: Dict[str, object] + :param spawner_extra_config: The spawner_extra_config of this JupyterHubConfig. # noqa: E501 + :type spawner_extra_config: Dict[str, object] + :param application_hook: The application_hook of this JupyterHubConfig. # noqa: E501 + :type application_hook: object + """ + self.openapi_types = { + 'args': List[str], + 'extra_config': Dict[str, object], + 'spawner_extra_config': Dict[str, object], + 'application_hook': object + } + + self.attribute_map = { + 'args': 'args', + 'extra_config': 'extraConfig', + 'spawner_extra_config': 'spawnerExtraConfig', + 'application_hook': 'applicationHook' + } + + self._args = args + self._extra_config = extra_config + self._spawner_extra_config = spawner_extra_config + self._application_hook = application_hook -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + @classmethod + def from_dict(cls, dikt) -> 'JupyterHubConfig': + """Returns the dict as a model -from typing import Optional, Set -from typing_extensions import Self + :param dikt: A dict. + :type: dict + :return: The JupyterHubConfig of this JupyterHubConfig. # noqa: E501 + :rtype: JupyterHubConfig + """ + return util.deserialize_model(dikt, cls) + @property + def args(self) -> List[str]: + """Gets the args of this JupyterHubConfig. -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib + arguments passed to the container # noqa: E501 -class JupyterHubConfig(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - args: Optional[List[StrictStr]] = Field(default=None, description="arguments passed to the container") - extra_config: Optional[Dict[str, Any]] = Field(default=None, alias="extraConfig") - spawner_extra_config: Optional[Dict[str, Any]] = Field(default=None, alias="spawnerExtraConfig") - application_hook: Optional[Any] = Field(default=None, description="change the hook function (advanced) Specify the Python name of the function (full module path, the module must be installed in the Docker image)", alias="applicationHook") - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["args", "extraConfig", "spawnerExtraConfig", "applicationHook"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :return: The args of this JupyterHubConfig. + :rtype: List[str] """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - # set to None if application_hook (nullable) is None - # and model_fields_set contains the field - if self.application_hook is None and "application_hook" in self.model_fields_set: - _dict['applicationHook'] = None - - return _dict + return self._args - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of JupyterHubConfig from a dict""" - if obj is None: - return None + @args.setter + def args(self, args: List[str]): + """Sets the args of this JupyterHubConfig. - if not isinstance(obj, dict): - return cls.model_validate(obj) + arguments passed to the container # noqa: E501 + + :param args: The args of this JupyterHubConfig. + :type args: List[str] + """ - _obj = cls.model_validate({ - "args": obj.get("args"), - "extraConfig": obj.get("extraConfig"), - "spawnerExtraConfig": obj.get("spawnerExtraConfig"), - "applicationHook": obj.get("applicationHook") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + self._args = args + + @property + def extra_config(self) -> Dict[str, object]: + """Gets the extra_config of this JupyterHubConfig. + + # noqa: E501 + + :return: The extra_config of this JupyterHubConfig. + :rtype: Dict[str, object] + """ + return self._extra_config + + @extra_config.setter + def extra_config(self, extra_config: Dict[str, object]): + """Sets the extra_config of this JupyterHubConfig. + + # noqa: E501 + + :param extra_config: The extra_config of this JupyterHubConfig. + :type extra_config: Dict[str, object] + """ - return _obj + self._extra_config = extra_config + @property + def spawner_extra_config(self) -> Dict[str, object]: + """Gets the spawner_extra_config of this JupyterHubConfig. + + # noqa: E501 + + :return: The spawner_extra_config of this JupyterHubConfig. + :rtype: Dict[str, object] + """ + return self._spawner_extra_config + + @spawner_extra_config.setter + def spawner_extra_config(self, spawner_extra_config: Dict[str, object]): + """Sets the spawner_extra_config of this JupyterHubConfig. + + # noqa: E501 + + :param spawner_extra_config: The spawner_extra_config of this JupyterHubConfig. + :type spawner_extra_config: Dict[str, object] + """ + + self._spawner_extra_config = spawner_extra_config + + @property + def application_hook(self) -> object: + """Gets the application_hook of this JupyterHubConfig. + + change the hook function (advanced) Specify the Python name of the function (full module path, the module must be installed in the Docker image) # noqa: E501 + + :return: The application_hook of this JupyterHubConfig. + :rtype: object + """ + return self._application_hook + + @application_hook.setter + def application_hook(self, application_hook: object): + """Sets the application_hook of this JupyterHubConfig. + + change the hook function (advanced) Specify the Python name of the function (full module path, the module must be installed in the Docker image) # noqa: E501 + + :param application_hook: The application_hook of this JupyterHubConfig. + :type application_hook: object + """ + self._application_hook = application_hook diff --git a/libraries/models/cloudharness_model/models/name_value.py b/libraries/models/cloudharness_model/models/name_value.py index e0117f145..22c0f511a 100644 --- a/libraries/models/cloudharness_model/models/name_value.py +++ b/libraries/models/cloudharness_model/models/name_value.py @@ -1,85 +1,93 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model import util - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) + +class NameValue(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, name=None, value=None): # noqa: E501 + """NameValue - a model defined in OpenAPI -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + :param name: The name of this NameValue. # noqa: E501 + :type name: str + :param value: The value of this NameValue. # noqa: E501 + :type value: str + """ + self.openapi_types = { + 'name': str, + 'value': str + } -from typing import Optional, Set -from typing_extensions import Self + self.attribute_map = { + 'name': 'name', + 'value': 'value' + } + self._name = name + self._value = value -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib + @classmethod + def from_dict(cls, dikt) -> 'NameValue': + """Returns the dict as a model -class NameValue(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - name: StrictStr - value: Optional[StrictStr] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["name", "value"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :param dikt: A dict. + :type: dict + :return: The NameValue of this NameValue. # noqa: E501 + :rtype: NameValue """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + return util.deserialize_model(dikt, cls) - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of NameValue from a dict""" - if obj is None: - return None + @property + def name(self) -> str: + """Gets the name of this NameValue. + + # noqa: E501 + + :return: The name of this NameValue. + :rtype: str + """ + return self._name - if not isinstance(obj, dict): - return cls.model_validate(obj) + @name.setter + def name(self, name: str): + """Sets the name of this NameValue. - _obj = cls.model_validate({ - "name": obj.get("name"), - "value": obj.get("value") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + # noqa: E501 - return _obj + :param name: The name of this NameValue. + :type name: str + """ + if name is None: + raise ValueError("Invalid value for `name`, must not be `None`") # noqa: E501 + + self._name = name + + @property + def value(self) -> str: + """Gets the value of this NameValue. + # noqa: E501 + + :return: The value of this NameValue. + :rtype: str + """ + return self._value + + @value.setter + def value(self, value: str): + """Sets the value of this NameValue. + + # noqa: E501 + + :param value: The value of this NameValue. + :type value: str + """ + self._value = value diff --git a/libraries/models/cloudharness_model/models/named_object.py b/libraries/models/cloudharness_model/models/named_object.py deleted file mode 100644 index 0b514317f..000000000 --- a/libraries/models/cloudharness_model/models/named_object.py +++ /dev/null @@ -1,83 +0,0 @@ -# coding: utf-8 - -""" - cloudharness - - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) - - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -from __future__ import annotations -import pprint -import re # noqa: F401 -import json - -from typing import Optional, Set -from typing_extensions import Self - - -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib - -class NamedObject(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - name: Optional[StrictStr] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["name"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict - - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of NamedObject from a dict""" - if obj is None: - return None - - if not isinstance(obj, dict): - return cls.model_validate(obj) - - _obj = cls.model_validate({ - "name": obj.get("name") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj - - diff --git a/libraries/models/cloudharness_model/models/organization.py b/libraries/models/cloudharness_model/models/organization.py deleted file mode 100644 index aa8b66925..000000000 --- a/libraries/models/cloudharness_model/models/organization.py +++ /dev/null @@ -1,99 +0,0 @@ -# coding: utf-8 - -""" - cloudharness - - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) - - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -from __future__ import annotations -import pprint -import re # noqa: F401 -import json - -from typing import Optional, Set -from typing_extensions import Self - - -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib -from cloudharness_model.models.named_object import NamedObject - -class Organization(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - name: Optional[StrictStr] = None - domains: Optional[List[NamedObject]] = None - alias: Optional[StrictStr] = None - enabled: Optional[StrictBool] = None - id: Optional[StrictStr] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["name", "domains", "alias", "enabled", "id"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # override the default output from pydantic by calling `to_dict()` of each item in domains (list) - _items = [] - if self.domains: - for _item_domains in self.domains: - if _item_domains: - _items.append(_item_domains.to_dict()) - _dict['domains'] = _items - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict - - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of Organization from a dict""" - if obj is None: - return None - - if not isinstance(obj, dict): - return cls.model_validate(obj) - - _obj = cls.model_validate({ - "name": obj.get("name"), - "domains": [NamedObject.from_dict(_item) for _item in obj["domains"]] if obj.get("domains") is not None else None, - "alias": obj.get("alias"), - "enabled": obj.get("enabled"), - "id": obj.get("id") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj - - diff --git a/libraries/models/cloudharness_model/models/organization_one_of.py b/libraries/models/cloudharness_model/models/organization_one_of.py deleted file mode 100644 index 36ab47620..000000000 --- a/libraries/models/cloudharness_model/models/organization_one_of.py +++ /dev/null @@ -1,114 +0,0 @@ -# coding: utf-8 - -""" - cloudharness - - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) - - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -from __future__ import annotations -import pprint -import re # noqa: F401 -import json - -from pydantic import BaseModel, ConfigDict, StrictBool, StrictStr -from typing import Any, ClassVar, Dict, List, Optional -from cloudharness_model.models.named_object import NamedObject -from typing import Optional, Set -from typing_extensions import Self - -class OrganizationOneOf(BaseModel): - """ - OrganizationOneOf - """ # noqa: E501 - domains: Optional[List[NamedObject]] = None - alias: Optional[StrictStr] = None - enabled: Optional[StrictBool] = None - id: Optional[StrictStr] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["domains", "alias", "enabled", "id"] - - model_config = ConfigDict( - populate_by_name=True, - validate_assignment=True, - protected_namespaces=(), - ) - - - def to_str(self) -> str: - """Returns the string representation of the model using alias""" - return pprint.pformat(self.model_dump(by_alias=True)) - - def to_json(self) -> str: - """Returns the JSON representation of the model using alias""" - # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead - return json.dumps(self.to_dict()) - - @classmethod - def from_json(cls, json_str: str) -> Optional[Self]: - """Create an instance of OrganizationOneOf from a JSON string""" - return cls.from_dict(json.loads(json_str)) - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # override the default output from pydantic by calling `to_dict()` of each item in domains (list) - _items = [] - if self.domains: - for _item in self.domains: - if _item: - _items.append(_item.to_dict()) - _dict['domains'] = _items - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict - - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of OrganizationOneOf from a dict""" - if obj is None: - return None - - if not isinstance(obj, dict): - return cls.model_validate(obj) - - _obj = cls.model_validate({ - "domains": [NamedObject.from_dict(_item) for _item in obj["domains"]] if obj.get("domains") is not None else None, - "alias": obj.get("alias"), - "enabled": obj.get("enabled"), - "id": obj.get("id") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj - - diff --git a/libraries/models/cloudharness_model/models/proxy_conf.py b/libraries/models/cloudharness_model/models/proxy_conf.py deleted file mode 100644 index 7fc250f24..000000000 --- a/libraries/models/cloudharness_model/models/proxy_conf.py +++ /dev/null @@ -1,101 +0,0 @@ -# coding: utf-8 - -""" - cloudharness - - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) - - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -from __future__ import annotations -import pprint -import re # noqa: F401 -import json - -from typing import Optional, Set -from typing_extensions import Self - - -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib -from cloudharness_model.models.gatekeeper_conf import GatekeeperConf -from cloudharness_model.models.proxy_payload_conf import ProxyPayloadConf -from cloudharness_model.models.proxy_timeout_conf import ProxyTimeoutConf - -class ProxyConf(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - forwarded_headers: Optional[StrictBool] = Field(default=None, alias="forwardedHeaders") - payload: Optional[ProxyPayloadConf] = None - timeout: Optional[ProxyTimeoutConf] = None - gatekeeper: Optional[GatekeeperConf] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["forwardedHeaders", "payload", "timeout", "gatekeeper"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # override the default output from pydantic by calling `to_dict()` of payload - if self.payload: - _dict['payload'] = self.payload.to_dict() - # override the default output from pydantic by calling `to_dict()` of timeout - if self.timeout: - _dict['timeout'] = self.timeout.to_dict() - # override the default output from pydantic by calling `to_dict()` of gatekeeper - if self.gatekeeper: - _dict['gatekeeper'] = self.gatekeeper.to_dict() - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict - - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of ProxyConf from a dict""" - if obj is None: - return None - - if not isinstance(obj, dict): - return cls.model_validate(obj) - - _obj = cls.model_validate({ - "forwardedHeaders": obj.get("forwardedHeaders"), - "payload": ProxyPayloadConf.from_dict(obj["payload"]) if obj.get("payload") is not None else None, - "timeout": ProxyTimeoutConf.from_dict(obj["timeout"]) if obj.get("timeout") is not None else None, - "gatekeeper": GatekeeperConf.from_dict(obj["gatekeeper"]) if obj.get("gatekeeper") is not None else None - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj - - diff --git a/libraries/models/cloudharness_model/models/proxy_payload_conf.py b/libraries/models/cloudharness_model/models/proxy_payload_conf.py deleted file mode 100644 index 7e41c5646..000000000 --- a/libraries/models/cloudharness_model/models/proxy_payload_conf.py +++ /dev/null @@ -1,83 +0,0 @@ -# coding: utf-8 - -""" - cloudharness - - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) - - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -from __future__ import annotations -import pprint -import re # noqa: F401 -import json - -from typing import Optional, Set -from typing_extensions import Self - - -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib - -class ProxyPayloadConf(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - max: Optional[StrictInt] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["max"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict - - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of ProxyPayloadConf from a dict""" - if obj is None: - return None - - if not isinstance(obj, dict): - return cls.model_validate(obj) - - _obj = cls.model_validate({ - "max": obj.get("max") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj - - diff --git a/libraries/models/cloudharness_model/models/proxy_timeout_conf.py b/libraries/models/cloudharness_model/models/proxy_timeout_conf.py deleted file mode 100644 index 703a83c98..000000000 --- a/libraries/models/cloudharness_model/models/proxy_timeout_conf.py +++ /dev/null @@ -1,87 +0,0 @@ -# coding: utf-8 - -""" - cloudharness - - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) - - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 - - -from __future__ import annotations -import pprint -import re # noqa: F401 -import json - -from typing import Optional, Set -from typing_extensions import Self - - -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib - -class ProxyTimeoutConf(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - keepalive: Optional[StrictInt] = None - read: Optional[StrictInt] = None - send: Optional[StrictInt] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["keepalive", "read", "send"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict - - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of ProxyTimeoutConf from a dict""" - if obj is None: - return None - - if not isinstance(obj, dict): - return cls.model_validate(obj) - - _obj = cls.model_validate({ - "keepalive": obj.get("keepalive"), - "read": obj.get("read"), - "send": obj.get("send") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj - - diff --git a/libraries/models/cloudharness_model/models/registry_config.py b/libraries/models/cloudharness_model/models/registry_config.py index d77b4426f..8e2830c6b 100644 --- a/libraries/models/cloudharness_model/models/registry_config.py +++ b/libraries/models/cloudharness_model/models/registry_config.py @@ -1,85 +1,93 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model import util - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) + +class RegistryConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, name=None, secret=None): # noqa: E501 + """RegistryConfig - a model defined in OpenAPI -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + :param name: The name of this RegistryConfig. # noqa: E501 + :type name: str + :param secret: The secret of this RegistryConfig. # noqa: E501 + :type secret: str + """ + self.openapi_types = { + 'name': str, + 'secret': str + } -from typing import Optional, Set -from typing_extensions import Self + self.attribute_map = { + 'name': 'name', + 'secret': 'secret' + } + self._name = name + self._secret = secret -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib + @classmethod + def from_dict(cls, dikt) -> 'RegistryConfig': + """Returns the dict as a model -class RegistryConfig(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - name: StrictStr - secret: Optional[StrictStr] = Field(default=None, description="Optional secret used for pulling from docker registry.") - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["name", "secret"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :param dikt: A dict. + :type: dict + :return: The RegistryConfig of this RegistryConfig. # noqa: E501 + :rtype: RegistryConfig """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + return util.deserialize_model(dikt, cls) - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of RegistryConfig from a dict""" - if obj is None: - return None + @property + def name(self) -> str: + """Gets the name of this RegistryConfig. + + # noqa: E501 + + :return: The name of this RegistryConfig. + :rtype: str + """ + return self._name - if not isinstance(obj, dict): - return cls.model_validate(obj) + @name.setter + def name(self, name: str): + """Sets the name of this RegistryConfig. - _obj = cls.model_validate({ - "name": obj.get("name"), - "secret": obj.get("secret") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + # noqa: E501 - return _obj + :param name: The name of this RegistryConfig. + :type name: str + """ + if name is None: + raise ValueError("Invalid value for `name`, must not be `None`") # noqa: E501 + + self._name = name + + @property + def secret(self) -> str: + """Gets the secret of this RegistryConfig. + Optional secret used for pulling from docker registry. # noqa: E501 + + :return: The secret of this RegistryConfig. + :rtype: str + """ + return self._secret + + @secret.setter + def secret(self, secret: str): + """Sets the secret of this RegistryConfig. + + Optional secret used for pulling from docker registry. # noqa: E501 + + :param secret: The secret of this RegistryConfig. + :type secret: str + """ + self._secret = secret diff --git a/libraries/models/cloudharness_model/models/service_auto_artifact_config.py b/libraries/models/cloudharness_model/models/service_auto_artifact_config.py index db99e6a4a..4225711bd 100644 --- a/libraries/models/cloudharness_model/models/service_auto_artifact_config.py +++ b/libraries/models/cloudharness_model/models/service_auto_artifact_config.py @@ -1,87 +1,121 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model import util - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) + +class ServiceAutoArtifactConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, auto=None, name=None, port=None): # noqa: E501 + """ServiceAutoArtifactConfig - a model defined in OpenAPI -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + :param auto: The auto of this ServiceAutoArtifactConfig. # noqa: E501 + :type auto: bool + :param name: The name of this ServiceAutoArtifactConfig. # noqa: E501 + :type name: str + :param port: The port of this ServiceAutoArtifactConfig. # noqa: E501 + :type port: int + """ + self.openapi_types = { + 'auto': bool, + 'name': str, + 'port': int + } + + self.attribute_map = { + 'auto': 'auto', + 'name': 'name', + 'port': 'port' + } + + self._auto = auto + self._name = name + self._port = port -from typing import Optional, Set -from typing_extensions import Self + @classmethod + def from_dict(cls, dikt) -> 'ServiceAutoArtifactConfig': + """Returns the dict as a model + :param dikt: A dict. + :type: dict + :return: The ServiceAutoArtifactConfig of this ServiceAutoArtifactConfig. # noqa: E501 + :rtype: ServiceAutoArtifactConfig + """ + return util.deserialize_model(dikt, cls) -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib + @property + def auto(self) -> bool: + """Gets the auto of this ServiceAutoArtifactConfig. -class ServiceAutoArtifactConfig(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - auto: Optional[StrictBool] = Field(default=None, description="When true, enables automatic template") - name: Optional[StrictStr] = None - port: Optional[StrictInt] = Field(default=None, description="Service port") - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["auto", "name", "port"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + When true, enables automatic template # noqa: E501 + + :return: The auto of this ServiceAutoArtifactConfig. + :rtype: bool """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + return self._auto - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of ServiceAutoArtifactConfig from a dict""" - if obj is None: - return None + @auto.setter + def auto(self, auto: bool): + """Sets the auto of this ServiceAutoArtifactConfig. + + When true, enables automatic template # noqa: E501 + + :param auto: The auto of this ServiceAutoArtifactConfig. + :type auto: bool + """ + if auto is None: + raise ValueError("Invalid value for `auto`, must not be `None`") # noqa: E501 + + self._auto = auto - if not isinstance(obj, dict): - return cls.model_validate(obj) + @property + def name(self) -> str: + """Gets the name of this ServiceAutoArtifactConfig. - _obj = cls.model_validate({ - "auto": obj.get("auto"), - "name": obj.get("name"), - "port": obj.get("port") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + # noqa: E501 - return _obj + :return: The name of this ServiceAutoArtifactConfig. + :rtype: str + """ + return self._name + @name.setter + def name(self, name: str): + """Sets the name of this ServiceAutoArtifactConfig. + + # noqa: E501 + + :param name: The name of this ServiceAutoArtifactConfig. + :type name: str + """ + + self._name = name + + @property + def port(self) -> int: + """Gets the port of this ServiceAutoArtifactConfig. + + Service port # noqa: E501 + + :return: The port of this ServiceAutoArtifactConfig. + :rtype: int + """ + return self._port + + @port.setter + def port(self, port: int): + """Sets the port of this ServiceAutoArtifactConfig. + + Service port # noqa: E501 + + :param port: The port of this ServiceAutoArtifactConfig. + :type port: int + """ + self._port = port diff --git a/libraries/models/cloudharness_model/models/unit_tests_config.py b/libraries/models/cloudharness_model/models/unit_tests_config.py index f8d2f8580..6983c7fb6 100644 --- a/libraries/models/cloudharness_model/models/unit_tests_config.py +++ b/libraries/models/cloudharness_model/models/unit_tests_config.py @@ -1,85 +1,95 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model import util - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) + +class UnitTestsConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, enabled=None, commands=None): # noqa: E501 + """UnitTestsConfig - a model defined in OpenAPI -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + :param enabled: The enabled of this UnitTestsConfig. # noqa: E501 + :type enabled: bool + :param commands: The commands of this UnitTestsConfig. # noqa: E501 + :type commands: List[str] + """ + self.openapi_types = { + 'enabled': bool, + 'commands': List[str] + } -from typing import Optional, Set -from typing_extensions import Self + self.attribute_map = { + 'enabled': 'enabled', + 'commands': 'commands' + } + self._enabled = enabled + self._commands = commands -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib + @classmethod + def from_dict(cls, dikt) -> 'UnitTestsConfig': + """Returns the dict as a model -class UnitTestsConfig(CloudHarnessBaseModel): - """ - - """ # noqa: E501 - enabled: StrictBool = Field(description="Enables unit tests for this application (default: true)") - commands: List[StrictStr] = Field(description="Commands to run unit tests") - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["enabled", "commands"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :param dikt: A dict. + :type: dict + :return: The UnitTestsConfig of this UnitTestsConfig. # noqa: E501 + :rtype: UnitTestsConfig """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + return util.deserialize_model(dikt, cls) - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of UnitTestsConfig from a dict""" - if obj is None: - return None + @property + def enabled(self) -> bool: + """Gets the enabled of this UnitTestsConfig. + + Enables unit tests for this application (default: true) # noqa: E501 + + :return: The enabled of this UnitTestsConfig. + :rtype: bool + """ + return self._enabled - if not isinstance(obj, dict): - return cls.model_validate(obj) + @enabled.setter + def enabled(self, enabled: bool): + """Sets the enabled of this UnitTestsConfig. - _obj = cls.model_validate({ - "enabled": obj.get("enabled"), - "commands": obj.get("commands") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + Enables unit tests for this application (default: true) # noqa: E501 - return _obj + :param enabled: The enabled of this UnitTestsConfig. + :type enabled: bool + """ + if enabled is None: + raise ValueError("Invalid value for `enabled`, must not be `None`") # noqa: E501 + + self._enabled = enabled + + @property + def commands(self) -> List[str]: + """Gets the commands of this UnitTestsConfig. + Commands to run unit tests # noqa: E501 + + :return: The commands of this UnitTestsConfig. + :rtype: List[str] + """ + return self._commands + + @commands.setter + def commands(self, commands: List[str]): + """Sets the commands of this UnitTestsConfig. + + Commands to run unit tests # noqa: E501 + + :param commands: The commands of this UnitTestsConfig. + :type commands: List[str] + """ + if commands is None: + raise ValueError("Invalid value for `commands`, must not be `None`") # noqa: E501 + self._commands = commands diff --git a/libraries/models/cloudharness_model/models/uri_role_mapping_config.py b/libraries/models/cloudharness_model/models/uri_role_mapping_config.py index 7ef35c249..4a86884cc 100644 --- a/libraries/models/cloudharness_model/models/uri_role_mapping_config.py +++ b/libraries/models/cloudharness_model/models/uri_role_mapping_config.py @@ -1,94 +1,99 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +import re +from cloudharness_model import util - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) +import re # noqa: E501 + +class UriRoleMappingConfig(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, uri=None, roles=None): # noqa: E501 + """UriRoleMappingConfig - a model defined in OpenAPI -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + :param uri: The uri of this UriRoleMappingConfig. # noqa: E501 + :type uri: str + :param roles: The roles of this UriRoleMappingConfig. # noqa: E501 + :type roles: List[str] + """ + self.openapi_types = { + 'uri': str, + 'roles': List[str] + } -from typing import Optional, Set -from typing_extensions import Self + self.attribute_map = { + 'uri': 'uri', + 'roles': 'roles' + } + self._uri = uri + self._roles = roles -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib + @classmethod + def from_dict(cls, dikt) -> 'UriRoleMappingConfig': + """Returns the dict as a model -class UriRoleMappingConfig(CloudHarnessBaseModel): - """ - Defines the application Gatekeeper configuration, if enabled (i.e. `secured: true`. - """ # noqa: E501 - uri: Annotated[str, Field(strict=True)] - roles: Optional[List[StrictStr]] = Field(default=None, description="Roles allowed to access the present uri") - white_listed: Optional[StrictBool] = Field(default=None, alias="white-listed") - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["uri", "roles", "white-listed"] - - @field_validator('uri') - def uri_validate_regular_expression(cls, value): - """Validates the regular expression""" - if not re.match(r"^[^<>:;,?|]+$", value): - raise ValueError(r"must validate the regular expression /^[^<>:;,?|]+$/") - return value - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. + :param dikt: A dict. + :type: dict + :return: The UriRoleMappingConfig of this UriRoleMappingConfig. # noqa: E501 + :rtype: UriRoleMappingConfig """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + return util.deserialize_model(dikt, cls) - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of UriRoleMappingConfig from a dict""" - if obj is None: - return None + @property + def uri(self) -> str: + """Gets the uri of this UriRoleMappingConfig. + + # noqa: E501 + + :return: The uri of this UriRoleMappingConfig. + :rtype: str + """ + return self._uri - if not isinstance(obj, dict): - return cls.model_validate(obj) + @uri.setter + def uri(self, uri: str): + """Sets the uri of this UriRoleMappingConfig. - _obj = cls.model_validate({ - "uri": obj.get("uri"), - "roles": obj.get("roles"), - "white-listed": obj.get("white-listed") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) + # noqa: E501 - return _obj + :param uri: The uri of this UriRoleMappingConfig. + :type uri: str + """ + if uri is None: + raise ValueError("Invalid value for `uri`, must not be `None`") # noqa: E501 + if uri is not None and not re.search(r'^[^<>:;,?|]+$', uri): # noqa: E501 + raise ValueError("Invalid value for `uri`, must be a follow pattern or equal to `/^[^<>:;,?|]+$/`") # noqa: E501 + + self._uri = uri + + @property + def roles(self) -> List[str]: + """Gets the roles of this UriRoleMappingConfig. + Roles allowed to access the present uri # noqa: E501 + + :return: The roles of this UriRoleMappingConfig. + :rtype: List[str] + """ + return self._roles + + @roles.setter + def roles(self, roles: List[str]): + """Sets the roles of this UriRoleMappingConfig. + + Roles allowed to access the present uri # noqa: E501 + + :param roles: The roles of this UriRoleMappingConfig. + :type roles: List[str] + """ + if roles is None: + raise ValueError("Invalid value for `roles`, must not be `None`") # noqa: E501 + self._roles = roles diff --git a/libraries/models/cloudharness_model/models/user.py b/libraries/models/cloudharness_model/models/user.py index bfc2a10fc..698ad2ce4 100644 --- a/libraries/models/cloudharness_model/models/user.py +++ b/libraries/models/cloudharness_model/models/user.py @@ -1,152 +1,531 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model.models.user_credential import UserCredential +from cloudharness_model import util + +from cloudharness_model.models.user_credential import UserCredential # noqa: E501 - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) +class User(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, access=None, attributes=None, client_roles=None, created_timestamp=None, credentials=None, disableable_credential_types=None, email=None, email_verified=None, enabled=None, federation_link=None, first_name=None, groups=None, id=None, last_name=None, realm_roles=None, required_actions=None, service_account_client_id=None, username=None, additional_properties=None): # noqa: E501 + """User - a model defined in OpenAPI -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + :param access: The access of this User. # noqa: E501 + :type access: Dict[str, object] + :param attributes: The attributes of this User. # noqa: E501 + :type attributes: Dict[str, object] + :param client_roles: The client_roles of this User. # noqa: E501 + :type client_roles: Dict[str, object] + :param created_timestamp: The created_timestamp of this User. # noqa: E501 + :type created_timestamp: int + :param credentials: The credentials of this User. # noqa: E501 + :type credentials: List[UserCredential] + :param disableable_credential_types: The disableable_credential_types of this User. # noqa: E501 + :type disableable_credential_types: List[str] + :param email: The email of this User. # noqa: E501 + :type email: str + :param email_verified: The email_verified of this User. # noqa: E501 + :type email_verified: bool + :param enabled: The enabled of this User. # noqa: E501 + :type enabled: bool + :param federation_link: The federation_link of this User. # noqa: E501 + :type federation_link: str + :param first_name: The first_name of this User. # noqa: E501 + :type first_name: str + :param groups: The groups of this User. # noqa: E501 + :type groups: List[str] + :param id: The id of this User. # noqa: E501 + :type id: str + :param last_name: The last_name of this User. # noqa: E501 + :type last_name: str + :param realm_roles: The realm_roles of this User. # noqa: E501 + :type realm_roles: List[str] + :param required_actions: The required_actions of this User. # noqa: E501 + :type required_actions: List[str] + :param service_account_client_id: The service_account_client_id of this User. # noqa: E501 + :type service_account_client_id: str + :param username: The username of this User. # noqa: E501 + :type username: str + :param additional_properties: The additional_properties of this User. # noqa: E501 + :type additional_properties: object + """ + self.openapi_types = { + 'access': Dict[str, object], + 'attributes': Dict[str, object], + 'client_roles': Dict[str, object], + 'created_timestamp': int, + 'credentials': List[UserCredential], + 'disableable_credential_types': List[str], + 'email': str, + 'email_verified': bool, + 'enabled': bool, + 'federation_link': str, + 'first_name': str, + 'groups': List[str], + 'id': str, + 'last_name': str, + 'realm_roles': List[str], + 'required_actions': List[str], + 'service_account_client_id': str, + 'username': str, + 'additional_properties': object + } -from typing import Optional, Set -from typing_extensions import Self + self.attribute_map = { + 'access': 'access', + 'attributes': 'attributes', + 'client_roles': 'clientRoles', + 'created_timestamp': 'createdTimestamp', + 'credentials': 'credentials', + 'disableable_credential_types': 'disableableCredentialTypes', + 'email': 'email', + 'email_verified': 'emailVerified', + 'enabled': 'enabled', + 'federation_link': 'federationLink', + 'first_name': 'firstName', + 'groups': 'groups', + 'id': 'id', + 'last_name': 'lastName', + 'realm_roles': 'realmRoles', + 'required_actions': 'requiredActions', + 'service_account_client_id': 'serviceAccountClientId', + 'username': 'username', + 'additional_properties': 'additionalProperties' + } + self._access = access + self._attributes = attributes + self._client_roles = client_roles + self._created_timestamp = created_timestamp + self._credentials = credentials + self._disableable_credential_types = disableable_credential_types + self._email = email + self._email_verified = email_verified + self._enabled = enabled + self._federation_link = federation_link + self._first_name = first_name + self._groups = groups + self._id = id + self._last_name = last_name + self._realm_roles = realm_roles + self._required_actions = required_actions + self._service_account_client_id = service_account_client_id + self._username = username + self._additional_properties = additional_properties -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib -from cloudharness_model.models.organization import Organization -from cloudharness_model.models.user_credential import UserCredential -from cloudharness_model.models.user_group import UserGroup + @classmethod + def from_dict(cls, dikt) -> 'User': + """Returns the dict as a model -class User(CloudHarnessBaseModel): - """ - User - """ # noqa: E501 - access: Optional[Dict[str, Any]] = None - attributes: Optional[Dict[str, Any]] = None - client_roles: Optional[Dict[str, Any]] = Field(default=None, alias="clientRoles") - created_timestamp: Optional[StrictInt] = Field(default=None, alias="createdTimestamp") - credentials: Optional[List[UserCredential]] = None - disableable_credential_types: Optional[List[StrictStr]] = Field(default=None, alias="disableableCredentialTypes") - email: Optional[StrictStr] = None - email_verified: Optional[StrictBool] = Field(default=None, alias="emailVerified") - enabled: Optional[StrictBool] = None - federation_link: Optional[StrictStr] = Field(default=None, alias="federationLink") - first_name: Optional[StrictStr] = Field(default=None, alias="firstName") - groups: Optional[List[StrictStr]] = None - id: Optional[StrictStr] = None - last_name: Optional[StrictStr] = Field(default=None, alias="lastName") - realm_roles: Optional[List[StrictStr]] = Field(default=None, alias="realmRoles") - required_actions: Optional[List[StrictStr]] = Field(default=None, alias="requiredActions") - service_account_client_id: Optional[StrictStr] = Field(default=None, alias="serviceAccountClientId") - username: Optional[StrictStr] = None - additional_properties: Optional[Any] = Field(default=None, alias="additionalProperties") - user_groups: Optional[List[UserGroup]] = Field(default=None, alias="userGroups") - organizations: Optional[List[Organization]] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["access", "attributes", "clientRoles", "createdTimestamp", "credentials", "disableableCredentialTypes", "email", "emailVerified", "enabled", "federationLink", "firstName", "groups", "id", "lastName", "realmRoles", "requiredActions", "serviceAccountClientId", "username", "additionalProperties", "userGroups", "organizations"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # override the default output from pydantic by calling `to_dict()` of each item in credentials (list) - _items = [] - if self.credentials: - for _item_credentials in self.credentials: - if _item_credentials: - _items.append(_item_credentials.to_dict()) - _dict['credentials'] = _items - # override the default output from pydantic by calling `to_dict()` of each item in user_groups (list) - _items = [] - if self.user_groups: - for _item_user_groups in self.user_groups: - if _item_user_groups: - _items.append(_item_user_groups.to_dict()) - _dict['userGroups'] = _items - # override the default output from pydantic by calling `to_dict()` of each item in organizations (list) - _items = [] - if self.organizations: - for _item_organizations in self.organizations: - if _item_organizations: - _items.append(_item_organizations.to_dict()) - _dict['organizations'] = _items - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - # set to None if additional_properties (nullable) is None - # and model_fields_set contains the field - if self.additional_properties is None and "additional_properties" in self.model_fields_set: - _dict['additionalProperties'] = None - - return _dict + :param dikt: A dict. + :type: dict + :return: The User of this User. # noqa: E501 + :rtype: User + """ + return util.deserialize_model(dikt, cls) - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of User from a dict""" - if obj is None: - return None - - if not isinstance(obj, dict): - return cls.model_validate(obj) - - _obj = cls.model_validate({ - "access": obj.get("access"), - "attributes": obj.get("attributes"), - "clientRoles": obj.get("clientRoles"), - "createdTimestamp": obj.get("createdTimestamp"), - "credentials": [UserCredential.from_dict(_item) for _item in obj["credentials"]] if obj.get("credentials") is not None else None, - "disableableCredentialTypes": obj.get("disableableCredentialTypes"), - "email": obj.get("email"), - "emailVerified": obj.get("emailVerified"), - "enabled": obj.get("enabled"), - "federationLink": obj.get("federationLink"), - "firstName": obj.get("firstName"), - "groups": obj.get("groups"), - "id": obj.get("id"), - "lastName": obj.get("lastName"), - "realmRoles": obj.get("realmRoles"), - "requiredActions": obj.get("requiredActions"), - "serviceAccountClientId": obj.get("serviceAccountClientId"), - "username": obj.get("username"), - "additionalProperties": obj.get("additionalProperties"), - "userGroups": [UserGroup.from_dict(_item) for _item in obj["userGroups"]] if obj.get("userGroups") is not None else None, - "organizations": [Organization.from_dict(_item) for _item in obj["organizations"]] if obj.get("organizations") is not None else None - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj + @property + def access(self) -> Dict[str, object]: + """Gets the access of this User. + + + :return: The access of this User. + :rtype: Dict[str, object] + """ + return self._access + + @access.setter + def access(self, access: Dict[str, object]): + """Sets the access of this User. + + + :param access: The access of this User. + :type access: Dict[str, object] + """ + + self._access = access + + @property + def attributes(self) -> Dict[str, object]: + """Gets the attributes of this User. + + + :return: The attributes of this User. + :rtype: Dict[str, object] + """ + return self._attributes + + @attributes.setter + def attributes(self, attributes: Dict[str, object]): + """Sets the attributes of this User. + + + :param attributes: The attributes of this User. + :type attributes: Dict[str, object] + """ + + self._attributes = attributes + + @property + def client_roles(self) -> Dict[str, object]: + """Gets the client_roles of this User. + + + :return: The client_roles of this User. + :rtype: Dict[str, object] + """ + return self._client_roles + + @client_roles.setter + def client_roles(self, client_roles: Dict[str, object]): + """Sets the client_roles of this User. + + + :param client_roles: The client_roles of this User. + :type client_roles: Dict[str, object] + """ + + self._client_roles = client_roles + + @property + def created_timestamp(self) -> int: + """Gets the created_timestamp of this User. + + + :return: The created_timestamp of this User. + :rtype: int + """ + return self._created_timestamp + + @created_timestamp.setter + def created_timestamp(self, created_timestamp: int): + """Sets the created_timestamp of this User. + + + :param created_timestamp: The created_timestamp of this User. + :type created_timestamp: int + """ + + self._created_timestamp = created_timestamp + + @property + def credentials(self) -> List[UserCredential]: + """Gets the credentials of this User. + + + :return: The credentials of this User. + :rtype: List[UserCredential] + """ + return self._credentials + + @credentials.setter + def credentials(self, credentials: List[UserCredential]): + """Sets the credentials of this User. + + + :param credentials: The credentials of this User. + :type credentials: List[UserCredential] + """ + + self._credentials = credentials + + @property + def disableable_credential_types(self) -> List[str]: + """Gets the disableable_credential_types of this User. + + + :return: The disableable_credential_types of this User. + :rtype: List[str] + """ + return self._disableable_credential_types + + @disableable_credential_types.setter + def disableable_credential_types(self, disableable_credential_types: List[str]): + """Sets the disableable_credential_types of this User. + + + :param disableable_credential_types: The disableable_credential_types of this User. + :type disableable_credential_types: List[str] + """ + + self._disableable_credential_types = disableable_credential_types + + @property + def email(self) -> str: + """Gets the email of this User. + + + :return: The email of this User. + :rtype: str + """ + return self._email + + @email.setter + def email(self, email: str): + """Sets the email of this User. + + + :param email: The email of this User. + :type email: str + """ + + self._email = email + + @property + def email_verified(self) -> bool: + """Gets the email_verified of this User. + + + :return: The email_verified of this User. + :rtype: bool + """ + return self._email_verified + + @email_verified.setter + def email_verified(self, email_verified: bool): + """Sets the email_verified of this User. + + + :param email_verified: The email_verified of this User. + :type email_verified: bool + """ + + self._email_verified = email_verified + + @property + def enabled(self) -> bool: + """Gets the enabled of this User. + + + :return: The enabled of this User. + :rtype: bool + """ + return self._enabled + + @enabled.setter + def enabled(self, enabled: bool): + """Sets the enabled of this User. + + + :param enabled: The enabled of this User. + :type enabled: bool + """ + + self._enabled = enabled + @property + def federation_link(self) -> str: + """Gets the federation_link of this User. + + + :return: The federation_link of this User. + :rtype: str + """ + return self._federation_link + + @federation_link.setter + def federation_link(self, federation_link: str): + """Sets the federation_link of this User. + + + :param federation_link: The federation_link of this User. + :type federation_link: str + """ + + self._federation_link = federation_link + + @property + def first_name(self) -> str: + """Gets the first_name of this User. + + + :return: The first_name of this User. + :rtype: str + """ + return self._first_name + + @first_name.setter + def first_name(self, first_name: str): + """Sets the first_name of this User. + + + :param first_name: The first_name of this User. + :type first_name: str + """ + + self._first_name = first_name + + @property + def groups(self) -> List[str]: + """Gets the groups of this User. + + + :return: The groups of this User. + :rtype: List[str] + """ + return self._groups + + @groups.setter + def groups(self, groups: List[str]): + """Sets the groups of this User. + + + :param groups: The groups of this User. + :type groups: List[str] + """ + + self._groups = groups + + @property + def id(self) -> str: + """Gets the id of this User. + + + :return: The id of this User. + :rtype: str + """ + return self._id + + @id.setter + def id(self, id: str): + """Sets the id of this User. + + + :param id: The id of this User. + :type id: str + """ + + self._id = id + + @property + def last_name(self) -> str: + """Gets the last_name of this User. + + + :return: The last_name of this User. + :rtype: str + """ + return self._last_name + + @last_name.setter + def last_name(self, last_name: str): + """Sets the last_name of this User. + + + :param last_name: The last_name of this User. + :type last_name: str + """ + + self._last_name = last_name + + @property + def realm_roles(self) -> List[str]: + """Gets the realm_roles of this User. + + + :return: The realm_roles of this User. + :rtype: List[str] + """ + return self._realm_roles + + @realm_roles.setter + def realm_roles(self, realm_roles: List[str]): + """Sets the realm_roles of this User. + + + :param realm_roles: The realm_roles of this User. + :type realm_roles: List[str] + """ + + self._realm_roles = realm_roles + + @property + def required_actions(self) -> List[str]: + """Gets the required_actions of this User. + + + :return: The required_actions of this User. + :rtype: List[str] + """ + return self._required_actions + + @required_actions.setter + def required_actions(self, required_actions: List[str]): + """Sets the required_actions of this User. + + + :param required_actions: The required_actions of this User. + :type required_actions: List[str] + """ + + self._required_actions = required_actions + + @property + def service_account_client_id(self) -> str: + """Gets the service_account_client_id of this User. + + + :return: The service_account_client_id of this User. + :rtype: str + """ + return self._service_account_client_id + + @service_account_client_id.setter + def service_account_client_id(self, service_account_client_id: str): + """Sets the service_account_client_id of this User. + + + :param service_account_client_id: The service_account_client_id of this User. + :type service_account_client_id: str + """ + + self._service_account_client_id = service_account_client_id + + @property + def username(self) -> str: + """Gets the username of this User. + + + :return: The username of this User. + :rtype: str + """ + return self._username + + @username.setter + def username(self, username: str): + """Sets the username of this User. + + + :param username: The username of this User. + :type username: str + """ + + self._username = username + + @property + def additional_properties(self) -> object: + """Gets the additional_properties of this User. + + + :return: The additional_properties of this User. + :rtype: object + """ + return self._additional_properties + + @additional_properties.setter + def additional_properties(self, additional_properties: object): + """Sets the additional_properties of this User. + + + :param additional_properties: The additional_properties of this User. + :type additional_properties: object + """ + self._additional_properties = additional_properties diff --git a/libraries/models/cloudharness_model/models/user_credential.py b/libraries/models/cloudharness_model/models/user_credential.py index 540ba8732..48f77e4fa 100644 --- a/libraries/models/cloudharness_model/models/user_credential.py +++ b/libraries/models/cloudharness_model/models/user_credential.py @@ -1,99 +1,269 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model import util - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) + +class UserCredential(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, created_date=None, credential_data=None, id=None, priority=None, secret_data=None, temporary=None, type=None, user_label=None, value=None): # noqa: E501 + """UserCredential - a model defined in OpenAPI -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + :param created_date: The created_date of this UserCredential. # noqa: E501 + :type created_date: int + :param credential_data: The credential_data of this UserCredential. # noqa: E501 + :type credential_data: str + :param id: The id of this UserCredential. # noqa: E501 + :type id: str + :param priority: The priority of this UserCredential. # noqa: E501 + :type priority: int + :param secret_data: The secret_data of this UserCredential. # noqa: E501 + :type secret_data: str + :param temporary: The temporary of this UserCredential. # noqa: E501 + :type temporary: bool + :param type: The type of this UserCredential. # noqa: E501 + :type type: str + :param user_label: The user_label of this UserCredential. # noqa: E501 + :type user_label: str + :param value: The value of this UserCredential. # noqa: E501 + :type value: str + """ + self.openapi_types = { + 'created_date': int, + 'credential_data': str, + 'id': str, + 'priority': int, + 'secret_data': str, + 'temporary': bool, + 'type': str, + 'user_label': str, + 'value': str + } -from typing import Optional, Set -from typing_extensions import Self + self.attribute_map = { + 'created_date': 'createdDate', + 'credential_data': 'credentialData', + 'id': 'id', + 'priority': 'priority', + 'secret_data': 'secretData', + 'temporary': 'temporary', + 'type': 'type', + 'user_label': 'userLabel', + 'value': 'value' + } + self._created_date = created_date + self._credential_data = credential_data + self._id = id + self._priority = priority + self._secret_data = secret_data + self._temporary = temporary + self._type = type + self._user_label = user_label + self._value = value -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib + @classmethod + def from_dict(cls, dikt) -> 'UserCredential': + """Returns the dict as a model -class UserCredential(CloudHarnessBaseModel): - """ - UserCredential - """ # noqa: E501 - created_date: Optional[StrictInt] = Field(default=None, alias="createdDate") - credential_data: Optional[StrictStr] = Field(default=None, alias="credentialData") - id: Optional[StrictStr] = None - priority: Optional[StrictInt] = None - secret_data: Optional[StrictStr] = Field(default=None, alias="secretData") - temporary: Optional[StrictBool] = None - type: Optional[StrictStr] = None - user_label: Optional[StrictStr] = Field(default=None, alias="userLabel") - value: Optional[StrictStr] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["createdDate", "credentialData", "id", "priority", "secretData", "temporary", "type", "userLabel", "value"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + :param dikt: A dict. + :type: dict + :return: The UserCredential of this UserCredential. # noqa: E501 + :rtype: UserCredential + """ + return util.deserialize_model(dikt, cls) - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of UserCredential from a dict""" - if obj is None: - return None - - if not isinstance(obj, dict): - return cls.model_validate(obj) - - _obj = cls.model_validate({ - "createdDate": obj.get("createdDate"), - "credentialData": obj.get("credentialData"), - "id": obj.get("id"), - "priority": obj.get("priority"), - "secretData": obj.get("secretData"), - "temporary": obj.get("temporary"), - "type": obj.get("type"), - "userLabel": obj.get("userLabel"), - "value": obj.get("value") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj + @property + def created_date(self) -> int: + """Gets the created_date of this UserCredential. + + + :return: The created_date of this UserCredential. + :rtype: int + """ + return self._created_date + + @created_date.setter + def created_date(self, created_date: int): + """Sets the created_date of this UserCredential. + + + :param created_date: The created_date of this UserCredential. + :type created_date: int + """ + + self._created_date = created_date + + @property + def credential_data(self) -> str: + """Gets the credential_data of this UserCredential. + + + :return: The credential_data of this UserCredential. + :rtype: str + """ + return self._credential_data + + @credential_data.setter + def credential_data(self, credential_data: str): + """Sets the credential_data of this UserCredential. + + + :param credential_data: The credential_data of this UserCredential. + :type credential_data: str + """ + + self._credential_data = credential_data + + @property + def id(self) -> str: + """Gets the id of this UserCredential. + + + :return: The id of this UserCredential. + :rtype: str + """ + return self._id + + @id.setter + def id(self, id: str): + """Sets the id of this UserCredential. + + + :param id: The id of this UserCredential. + :type id: str + """ + + self._id = id + + @property + def priority(self) -> int: + """Gets the priority of this UserCredential. + + + :return: The priority of this UserCredential. + :rtype: int + """ + return self._priority + + @priority.setter + def priority(self, priority: int): + """Sets the priority of this UserCredential. + + + :param priority: The priority of this UserCredential. + :type priority: int + """ + + self._priority = priority + + @property + def secret_data(self) -> str: + """Gets the secret_data of this UserCredential. + :return: The secret_data of this UserCredential. + :rtype: str + """ + return self._secret_data + + @secret_data.setter + def secret_data(self, secret_data: str): + """Sets the secret_data of this UserCredential. + + + :param secret_data: The secret_data of this UserCredential. + :type secret_data: str + """ + + self._secret_data = secret_data + + @property + def temporary(self) -> bool: + """Gets the temporary of this UserCredential. + + + :return: The temporary of this UserCredential. + :rtype: bool + """ + return self._temporary + + @temporary.setter + def temporary(self, temporary: bool): + """Sets the temporary of this UserCredential. + + + :param temporary: The temporary of this UserCredential. + :type temporary: bool + """ + + self._temporary = temporary + + @property + def type(self) -> str: + """Gets the type of this UserCredential. + + + :return: The type of this UserCredential. + :rtype: str + """ + return self._type + + @type.setter + def type(self, type: str): + """Sets the type of this UserCredential. + + + :param type: The type of this UserCredential. + :type type: str + """ + + self._type = type + + @property + def user_label(self) -> str: + """Gets the user_label of this UserCredential. + + + :return: The user_label of this UserCredential. + :rtype: str + """ + return self._user_label + + @user_label.setter + def user_label(self, user_label: str): + """Sets the user_label of this UserCredential. + + + :param user_label: The user_label of this UserCredential. + :type user_label: str + """ + + self._user_label = user_label + + @property + def value(self) -> str: + """Gets the value of this UserCredential. + + + :return: The value of this UserCredential. + :rtype: str + """ + return self._value + + @value.setter + def value(self, value: str): + """Sets the value of this UserCredential. + + + :param value: The value of this UserCredential. + :type value: str + """ + + self._value = value diff --git a/libraries/models/cloudharness_model/models/user_group.py b/libraries/models/cloudharness_model/models/user_group.py index 036ebd4ee..153f84fad 100644 --- a/libraries/models/cloudharness_model/models/user_group.py +++ b/libraries/models/cloudharness_model/models/user_group.py @@ -1,107 +1,245 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model import util - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) + +class UserGroup(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + + def __init__(self, access=None, attributes=None, client_roles=None, id=None, name=None, path=None, realm_roles=None, sub_groups=None): # noqa: E501 + """UserGroup - a model defined in OpenAPI + + :param access: The access of this UserGroup. # noqa: E501 + :type access: Dict[str, object] + :param attributes: The attributes of this UserGroup. # noqa: E501 + :type attributes: Dict[str, object] + :param client_roles: The client_roles of this UserGroup. # noqa: E501 + :type client_roles: Dict[str, object] + :param id: The id of this UserGroup. # noqa: E501 + :type id: str + :param name: The name of this UserGroup. # noqa: E501 + :type name: str + :param path: The path of this UserGroup. # noqa: E501 + :type path: str + :param realm_roles: The realm_roles of this UserGroup. # noqa: E501 + :type realm_roles: List[str] + :param sub_groups: The sub_groups of this UserGroup. # noqa: E501 + :type sub_groups: List[UserGroup] + """ + self.openapi_types = { + 'access': Dict[str, object], + 'attributes': Dict[str, object], + 'client_roles': Dict[str, object], + 'id': str, + 'name': str, + 'path': str, + 'realm_roles': List[str], + 'sub_groups': List[UserGroup] + } + + self.attribute_map = { + 'access': 'access', + 'attributes': 'attributes', + 'client_roles': 'clientRoles', + 'id': 'id', + 'name': 'name', + 'path': 'path', + 'realm_roles': 'realmRoles', + 'sub_groups': 'subGroups' + } + + self._access = access + self._attributes = attributes + self._client_roles = client_roles + self._id = id + self._name = name + self._path = path + self._realm_roles = realm_roles + self._sub_groups = sub_groups + + @classmethod + def from_dict(cls, dikt) -> 'UserGroup': + """Returns the dict as a model + :param dikt: A dict. + :type: dict + :return: The UserGroup of this UserGroup. # noqa: E501 + :rtype: UserGroup + """ + return util.deserialize_model(dikt, cls) -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + @property + def access(self) -> Dict[str, object]: + """Gets the access of this UserGroup. -from typing import Optional, Set -from typing_extensions import Self + :return: The access of this UserGroup. + :rtype: Dict[str, object] + """ + return self._access -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib + @access.setter + def access(self, access: Dict[str, object]): + """Sets the access of this UserGroup. -class UserGroup(CloudHarnessBaseModel): - """ - UserGroup - """ # noqa: E501 - access: Optional[Dict[str, Any]] = None - attributes: Optional[Dict[str, Any]] = None - client_roles: Optional[Dict[str, Any]] = Field(default=None, alias="clientRoles") - id: Optional[StrictStr] = None - name: Optional[StrictStr] = None - path: Optional[StrictStr] = None - realm_roles: Optional[List[StrictStr]] = Field(default=None, alias="realmRoles") - sub_groups: Optional[List[UserGroup]] = Field(default=None, alias="subGroups") - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["access", "attributes", "clientRoles", "id", "name", "path", "realmRoles", "subGroups"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # override the default output from pydantic by calling `to_dict()` of each item in sub_groups (list) - _items = [] - if self.sub_groups: - for _item_sub_groups in self.sub_groups: - if _item_sub_groups: - _items.append(_item_sub_groups.to_dict()) - _dict['subGroups'] = _items - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of UserGroup from a dict""" - if obj is None: - return None - - if not isinstance(obj, dict): - return cls.model_validate(obj) - - _obj = cls.model_validate({ - "access": obj.get("access"), - "attributes": obj.get("attributes"), - "clientRoles": obj.get("clientRoles"), - "id": obj.get("id"), - "name": obj.get("name"), - "path": obj.get("path"), - "realmRoles": obj.get("realmRoles"), - "subGroups": [UserGroup.from_dict(_item) for _item in obj["subGroups"]] if obj.get("subGroups") is not None else None - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj - - -# TODO: Rewrite to not use raise_errors -UserGroup.model_rebuild(raise_errors=False) + :param access: The access of this UserGroup. + :type access: Dict[str, object] + """ + + self._access = access + + @property + def attributes(self) -> Dict[str, object]: + """Gets the attributes of this UserGroup. + + # noqa: E501 + + :return: The attributes of this UserGroup. + :rtype: Dict[str, object] + """ + return self._attributes + + @attributes.setter + def attributes(self, attributes: Dict[str, object]): + """Sets the attributes of this UserGroup. + + # noqa: E501 + + :param attributes: The attributes of this UserGroup. + :type attributes: Dict[str, object] + """ + + self._attributes = attributes + + @property + def client_roles(self) -> Dict[str, object]: + """Gets the client_roles of this UserGroup. + + + :return: The client_roles of this UserGroup. + :rtype: Dict[str, object] + """ + return self._client_roles + + @client_roles.setter + def client_roles(self, client_roles: Dict[str, object]): + """Sets the client_roles of this UserGroup. + + + :param client_roles: The client_roles of this UserGroup. + :type client_roles: Dict[str, object] + """ + + self._client_roles = client_roles + + @property + def id(self) -> str: + """Gets the id of this UserGroup. + + + :return: The id of this UserGroup. + :rtype: str + """ + return self._id + + @id.setter + def id(self, id: str): + """Sets the id of this UserGroup. + + + :param id: The id of this UserGroup. + :type id: str + """ + + self._id = id + + @property + def name(self) -> str: + """Gets the name of this UserGroup. + + + :return: The name of this UserGroup. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name: str): + """Sets the name of this UserGroup. + + + :param name: The name of this UserGroup. + :type name: str + """ + + self._name = name + + @property + def path(self) -> str: + """Gets the path of this UserGroup. + + + :return: The path of this UserGroup. + :rtype: str + """ + return self._path + + @path.setter + def path(self, path: str): + """Sets the path of this UserGroup. + + + :param path: The path of this UserGroup. + :type path: str + """ + + self._path = path + + @property + def realm_roles(self) -> List[str]: + """Gets the realm_roles of this UserGroup. + + + :return: The realm_roles of this UserGroup. + :rtype: List[str] + """ + return self._realm_roles + + @realm_roles.setter + def realm_roles(self, realm_roles: List[str]): + """Sets the realm_roles of this UserGroup. + + + :param realm_roles: The realm_roles of this UserGroup. + :type realm_roles: List[str] + """ + + self._realm_roles = realm_roles + + @property + def sub_groups(self) -> List['UserGroup']: + """Gets the sub_groups of this UserGroup. + + + :return: The sub_groups of this UserGroup. + :rtype: List[UserGroup] + """ + return self._sub_groups + + @sub_groups.setter + def sub_groups(self, sub_groups: List['UserGroup']): + """Sets the sub_groups of this UserGroup. + + + :param sub_groups: The sub_groups of this UserGroup. + :type sub_groups: List[UserGroup] + """ + self._sub_groups = sub_groups diff --git a/libraries/models/cloudharness_model/models/user_role.py b/libraries/models/cloudharness_model/models/user_role.py index a7a629fe8..96be6a925 100644 --- a/libraries/models/cloudharness_model/models/user_role.py +++ b/libraries/models/cloudharness_model/models/user_role.py @@ -1,95 +1,217 @@ -# coding: utf-8 +from datetime import date, datetime # noqa: F401 -""" - cloudharness +from typing import List, Dict # noqa: F401 - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) +from cloudharness_model.models.base_model_ import Model +from cloudharness_model import util - The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) + +class UserRole(Model): + """NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). Do not edit the class manually. -""" # noqa: E501 + """ + def __init__(self, attributes=None, client_role=None, composite=None, container_id=None, description=None, id=None, name=None): # noqa: E501 + """UserRole - a model defined in OpenAPI + + :param attributes: The attributes of this UserRole. # noqa: E501 + :type attributes: Dict[str, object] + :param client_role: The client_role of this UserRole. # noqa: E501 + :type client_role: bool + :param composite: The composite of this UserRole. # noqa: E501 + :type composite: bool + :param container_id: The container_id of this UserRole. # noqa: E501 + :type container_id: str + :param description: The description of this UserRole. # noqa: E501 + :type description: str + :param id: The id of this UserRole. # noqa: E501 + :type id: str + :param name: The name of this UserRole. # noqa: E501 + :type name: str + """ + self.openapi_types = { + 'attributes': Dict[str, object], + 'client_role': bool, + 'composite': bool, + 'container_id': str, + 'description': str, + 'id': str, + 'name': str + } + + self.attribute_map = { + 'attributes': 'attributes', + 'client_role': 'clientRole', + 'composite': 'composite', + 'container_id': 'containerId', + 'description': 'description', + 'id': 'id', + 'name': 'name' + } + + self._attributes = attributes + self._client_role = client_role + self._composite = composite + self._container_id = container_id + self._description = description + self._id = id + self._name = name -from __future__ import annotations -import pprint -import re # noqa: F401 -import json + @classmethod + def from_dict(cls, dikt) -> 'UserRole': + """Returns the dict as a model -from typing import Optional, Set -from typing_extensions import Self + :param dikt: A dict. + :type: dict + :return: The UserRole of this UserRole. # noqa: E501 + :rtype: UserRole + """ + return util.deserialize_model(dikt, cls) + @property + def attributes(self) -> Dict[str, object]: + """Gets the attributes of this UserRole. -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib -class UserRole(CloudHarnessBaseModel): - """ - UserRole - """ # noqa: E501 - attributes: Optional[Dict[str, Any]] = None - client_role: Optional[StrictBool] = Field(default=None, alias="clientRole") - composite: Optional[StrictBool] = None - container_id: Optional[StrictStr] = Field(default=None, alias="containerId") - description: Optional[StrictStr] = None - id: Optional[StrictStr] = None - name: Optional[StrictStr] = None - additional_properties: Dict[str, Any] = {} - __properties: ClassVar[List[str]] = ["attributes", "clientRole", "composite", "containerId", "description", "id", "name"] - - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - * Fields in `self.additional_properties` are added to the output dict. - """ - excluded_fields: Set[str] = set([ - "additional_properties", - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - return _dict + :return: The attributes of this UserRole. + :rtype: Dict[str, object] + """ + return self._attributes + + @attributes.setter + def attributes(self, attributes: Dict[str, object]): + """Sets the attributes of this UserRole. + + + :param attributes: The attributes of this UserRole. + :type attributes: Dict[str, object] + """ + + self._attributes = attributes + + @property + def client_role(self) -> bool: + """Gets the client_role of this UserRole. + + + :return: The client_role of this UserRole. + :rtype: bool + """ + return self._client_role + + @client_role.setter + def client_role(self, client_role: bool): + """Sets the client_role of this UserRole. + + + :param client_role: The client_role of this UserRole. + :type client_role: bool + """ + + self._client_role = client_role + + @property + def composite(self) -> bool: + """Gets the composite of this UserRole. + + + :return: The composite of this UserRole. + :rtype: bool + """ + return self._composite + + @composite.setter + def composite(self, composite: bool): + """Sets the composite of this UserRole. + + + :param composite: The composite of this UserRole. + :type composite: bool + """ + + self._composite = composite + + @property + def container_id(self) -> str: + """Gets the container_id of this UserRole. - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of UserRole from a dict""" - if obj is None: - return None - - if not isinstance(obj, dict): - return cls.model_validate(obj) - - _obj = cls.model_validate({ - "attributes": obj.get("attributes"), - "clientRole": obj.get("clientRole"), - "composite": obj.get("composite"), - "containerId": obj.get("containerId"), - "description": obj.get("description"), - "id": obj.get("id"), - "name": obj.get("name") - }) - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - return _obj + :return: The container_id of this UserRole. + :rtype: str + """ + return self._container_id + + @container_id.setter + def container_id(self, container_id: str): + """Sets the container_id of this UserRole. + + + :param container_id: The container_id of this UserRole. + :type container_id: str + """ + + self._container_id = container_id + + @property + def description(self) -> str: + """Gets the description of this UserRole. + + + :return: The description of this UserRole. + :rtype: str + """ + return self._description + + @description.setter + def description(self, description: str): + """Sets the description of this UserRole. + + + :param description: The description of this UserRole. + :type description: str + """ + + self._description = description + + @property + def id(self) -> str: + """Gets the id of this UserRole. + + + :return: The id of this UserRole. + :rtype: str + """ + return self._id + + @id.setter + def id(self, id: str): + """Sets the id of this UserRole. + + + :param id: The id of this UserRole. + :type id: str + """ + + self._id = id + + @property + def name(self) -> str: + """Gets the name of this UserRole. + + + :return: The name of this UserRole. + :rtype: str + """ + return self._name + + @name.setter + def name(self, name: str): + """Sets the name of this UserRole. + + + :param name: The name of this UserRole. + :type name: str + """ + self._name = name diff --git a/libraries/models/cloudharness_model/pydantic_utils.py b/libraries/models/cloudharness_model/pydantic_utils.py deleted file mode 100644 index cda5b78d9..000000000 --- a/libraries/models/cloudharness_model/pydantic_utils.py +++ /dev/null @@ -1,370 +0,0 @@ -""" -Pydantic utility functions and monkey patches to improve object access with legacy support. - -This module provides enhancements to Pydantic BaseModel to support: -- Access to additional_properties through __getitem__ and __getattr__ -- Dot notation for nested property access -- Dictionary-like get() method with default values -""" - -import pydantic - - -def _convert_to_attrdict(value): - """Helper function to convert nested structures to AttrDict""" - if isinstance(value, dict) and not isinstance(value, AttrDict): - return AttrDict(value) - elif isinstance(value, list): - # Convert list items that are dictionaries to AttrDict - return [_convert_to_attrdict(item) for item in value] - return value - - -def _get_value_from_additional_properties(obj, key): - """Helper function to get value from additional_properties without triggering __getattr__ recursion""" - # Use object.__getattribute__ to directly access additional_properties without triggering our override - try: - additional_properties = object.__getattribute__(obj, 'additional_properties') - if key in additional_properties: - value = additional_properties[key] - return _convert_to_attrdict(value) - except AttributeError: - # Object doesn't have additional_properties - pass - return None - - -def _try_camelcase_conversions(obj, key, check_attributes=False): - """Helper function to try camelCase/snake_case conversions""" - import humps - - # Try snake_case version of the key - snake_case_key = humps.decamelize(key) - if snake_case_key != key: - # Check additional_properties - value = _get_value_from_additional_properties(obj, snake_case_key) - if value is not None: - return value - # Check attributes if requested - if check_attributes: - try: - return object.__getattribute__(obj, snake_case_key) - except AttributeError: - pass - - # Try camelCase version of the key - camel_case_key = humps.camelize(key) - if camel_case_key != key: - # Check additional_properties - value = _get_value_from_additional_properties(obj, camel_case_key) - if value is not None: - return value - # Check attributes if requested - if check_attributes: - try: - return object.__getattribute__(obj, camel_case_key) - except AttributeError: - pass - - return None - - -def _check_field_aliases(obj, key): - """Helper function to check if key is an alias for a field""" - # Check pydantic v2 - try: - model_fields = object.__getattribute__(obj, 'model_fields') - for field_name, field_info in model_fields.items(): - if hasattr(field_info, 'alias') and field_info.alias == key: - return object.__getattribute__(obj, field_name) - except AttributeError: - pass - - return None - - -class AttrDict(dict): - """Dictionary that supports attribute access and nested AttrDict conversion""" - def __getattr__(self, key): - try: - value = self[key] - # Recursively convert nested dictionaries to AttrDict - value = _convert_to_attrdict(value) - self[key] = value # Cache the converted value - return value - except KeyError: - raise AttributeError(f"'{type(self).__name__}' object has no attribute '{key}'") - - def __setattr__(self, key, value): - self[key] = value - - def __getitem__(self, key): - value = super().__getitem__(key) - # Recursively convert nested dictionaries to AttrDict for item access too - value = _convert_to_attrdict(value) - self[key] = value # Cache the converted value - return value - - def __contains__(self, key): - """Support for 'in' operator with dot notation""" - if "." in key: - keys = key.split(".", 1) - if super().__contains__(keys[0]): - nested = self[keys[0]] - if hasattr(nested, '__contains__'): - return keys[1] in nested - return False - return super().__contains__(key) - - -def _pydantic_getitem_override(self, key: str): - """ - Override for pydantic.BaseModel.__getitem__ to check additional_properties - when a field is not found with getattr. Supports dot notation for nested access. - """ - # Handle dot notation for nested access - if "." in key: - keys = key.split(".", 1) # Split only on first dot - try: - # Try to get the first part as an attribute - first_part = getattr(self, keys[0]) - except AttributeError: - # If not found as attribute, try additional_properties - first_part = _get_value_from_additional_properties(self, keys[0]) - if first_part is None: - raise KeyError(key) - - # Recursively access the remaining part - if hasattr(first_part, '__getitem__'): - return first_part[keys[1]] - else: - raise KeyError(key) - - # Non-dot notation access - # First check additional_properties (for keys like 'task-images' that aren't valid Python attributes) - value = _get_value_from_additional_properties(self, key) - if value is not None: - return value - - # Then check if key is an alias for a field - value = _check_field_aliases(self, key) - if value is not None: - return value - - # Try camelCase conversions - value = _try_camelcase_conversions(self, key, check_attributes=False) - if value is not None: - return value - - # Then try getattr for regular attributes - try: - return getattr(self, key) - except AttributeError: - raise KeyError(key) - - -def _pydantic_getattribute_override(self, name: str): - """ - Override for pydantic.BaseModel.__getattribute__ with minimal interference - """ - # Get the attribute using the original __getattribute__ - value = object.__getattribute__(self, name) - - # Special handling for additional_properties - don't convert to AttrDict - if name == 'additional_properties': - return value - - # Check if this is a property - avoid recursion by directly accessing type's __dict__ - cls = type(self) - if hasattr(cls, '__dict__') and name in cls.__dict__ and isinstance(cls.__dict__[name], property): - # This is a property, don't convert its return value - return value - - # For pydantic model fields containing dicts, convert to AttrDict for better access - try: - model_fields = object.__getattribute__(self, 'model_fields') - if name in model_fields: - return _convert_to_attrdict(value) - except AttributeError: - pass - - # Return other attributes unchanged - return value - - -def _pydantic_getattr_override(self, name: str): - """ - Override for pydantic.BaseModel.__getattr__ to check additional_properties - when an attribute is not found through normal means. - """ - # Check if the attribute exists in additional_properties first - value = _get_value_from_additional_properties(self, name) - if value is not None: - return value - - # Try camelCase conversions for additional_properties only (not attributes to avoid recursion) - import humps - snake_case_name = humps.decamelize(name) - if snake_case_name != name: - value = _get_value_from_additional_properties(self, snake_case_name) - if value is not None: - return value - - camel_case_name = humps.camelize(name) - if camel_case_name != name: - value = _get_value_from_additional_properties(self, camel_case_name) - if value is not None: - return value - - # If not found, raise AttributeError as expected - raise AttributeError(f"'{type(self).__name__}' object has no attribute '{name}'") - - -def _pydantic_get_override(self, key: str, default=None): - """ - Override for pydantic.BaseModel.get to provide dictionary-like interface - with support for additional_properties and dot notation. - """ - try: - return self[key] - except KeyError: - return default - - -def _pydantic_setitem_override(self, key: str, value): - """ - Override for pydantic.BaseModel.__setitem__ to support item assignment - with additional_properties and field aliases. - """ - # Check if key is an alias for a field - if hasattr(self, 'model_fields'): - for field_name, field_info in self.model_fields.items(): - if hasattr(field_info, 'alias') and field_info.alias == key: - setattr(self, field_name, value) - return - - # Check if key is a defined pydantic field (not just any attribute) - if hasattr(self, 'model_fields') and key in self.model_fields: - setattr(self, key, value) - return - - # Try camelCase conversions for defined fields only - import humps - snake_case_key = humps.decamelize(key) - if hasattr(self, 'model_fields') and snake_case_key in self.model_fields: - setattr(self, snake_case_key, value) - return - - camel_case_key = humps.camelize(key) - if hasattr(self, 'model_fields') and camel_case_key in self.model_fields: - setattr(self, camel_case_key, value) - return - - # For any key that doesn't match a defined field, always use additional_properties - # This prevents validation errors on non-existent fields - if not hasattr(self, 'additional_properties'): - self.additional_properties = {} - self.additional_properties[key] = value - - -def _pydantic_contains_override(self, key: str): - """ - Override for pydantic.BaseModel.__contains__ to support 'in' operator - with additional_properties and dot notation. - """ - # Handle dot notation for nested access - if "." in key: - keys = key.split(".", 1) # Split only on first dot - try: - # Try to get the first part as an attribute - first_part = getattr(self, keys[0]) - except AttributeError: - # If not found as attribute, try additional_properties - first_part = _get_value_from_additional_properties(self, keys[0]) - if first_part is None: - return False - - # Check if the remaining part exists in the nested object - if hasattr(first_part, '__contains__'): - return keys[1] in first_part - else: - return False - - # Non-dot notation access - # First check if it's a defined field in the model - if hasattr(self, 'model_fields') and key in self.model_fields: - return True - - # Check if it's a regular attribute - if hasattr(self, key): - return True - - # Check additional_properties - if hasattr(self, 'additional_properties') and key in self.additional_properties: - return True - - return False - - -def _pydantic_setattr_override(self, name: str, value): - """ - Override for pydantic.BaseModel.__setattr__ to handle camelCase attributes - and prevent validation errors on non-existent fields, while preserving property behavior. - """ - # First check if this is a property - if so, use the standard mechanism - cls_dict = object.__getattribute__(self.__class__, '__dict__') - if name in cls_dict and isinstance(cls_dict[name], property): - # This is a property, use the standard __setattr__ to trigger the setter - object.__setattr__(self, name, value) - return - - # Handle private attributes (starting with _) - always set them directly - if name.startswith('_'): - object.__setattr__(self, name, value) - return - - # Check if name is a defined pydantic field - if hasattr(self, 'model_fields') and name in self.model_fields: - # Use the original __setattr__ for defined fields - super(pydantic.BaseModel, self).__setattr__(name, value) - return - - # Check if name is camelCase version of a defined field - import humps - snake_case_name = humps.decamelize(name) - if hasattr(self, 'model_fields') and snake_case_name in self.model_fields: - super(pydantic.BaseModel, self).__setattr__(snake_case_name, value) - return - - # For non-field attributes, store in additional_properties to avoid validation errors - if not hasattr(self, 'additional_properties'): - object.__setattr__(self, 'additional_properties', {}) - - # If additional_properties already exists, update it - if hasattr(self, 'additional_properties'): - self.additional_properties[name] = value - else: - # Fallback to object.__setattr__ for internal attributes - object.__setattr__(self, name, value) - - -def apply_pydantic_patches(): - """ - Apply monkey patches to pydantic.BaseModel to enhance functionality. - - This function should be called once during module initialization to enable: - - Enhanced __getattribute__ to convert dict values to AttrDict - - Enhanced __getitem__ with additional_properties support and dot notation - - Enhanced __getattr__ with additional_properties support - - Enhanced __setitem__ for item assignment support - - Enhanced __setattr__ for attribute assignment support - - Dictionary-like get() method with default values - - Enhanced __contains__ for 'in' operator support with additional_properties - """ - pydantic.BaseModel.__getattribute__ = _pydantic_getattribute_override - pydantic.BaseModel.__getitem__ = _pydantic_getitem_override - pydantic.BaseModel.__getattr__ = _pydantic_getattr_override - pydantic.BaseModel.__setitem__ = _pydantic_setitem_override - pydantic.BaseModel.__setattr__ = _pydantic_setattr_override - pydantic.BaseModel.get = _pydantic_get_override - pydantic.BaseModel.__contains__ = _pydantic_contains_override diff --git a/libraries/models/cloudharness_model/rest.py b/libraries/models/cloudharness_model/rest.py index 82668bcd6..79d1da49c 100644 --- a/libraries/models/cloudharness_model/rest.py +++ b/libraries/models/cloudharness_model/rest.py @@ -1,68 +1,54 @@ -# coding: utf-8 - """ cloudharness - No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) + No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator) # noqa: E501 The version of the OpenAPI document: 1.0.0 - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 + Generated by: https://openapi-generator.tech +""" import io import json +import logging import re import ssl - +from urllib.parse import urlencode +from urllib.parse import urlparse +from urllib.request import proxy_bypass_environment import urllib3 +import ipaddress -from cloudharness_model.exceptions import ApiException, ApiValueError +from cloudharness_model.exceptions import ApiException, UnauthorizedException, ForbiddenException, NotFoundException, ServiceException, ApiValueError -SUPPORTED_SOCKS_PROXIES = {"socks5", "socks5h", "socks4", "socks4a"} -RESTResponseType = urllib3.HTTPResponse - -def is_socks_proxy_url(url): - if url is None: - return False - split_section = url.split("://") - if len(split_section) < 2: - return False - else: - return split_section[0].lower() in SUPPORTED_SOCKS_PROXIES +logger = logging.getLogger(__name__) class RESTResponse(io.IOBase): - def __init__(self, resp) -> None: - self.response = resp + def __init__(self, resp): + self.urllib3_response = resp self.status = resp.status self.reason = resp.reason - self.data = None - - def read(self): - if self.data is None: - self.data = self.response.data - return self.data + self.data = resp.data def getheaders(self): """Returns a dictionary of the response headers.""" - return self.response.headers + return self.urllib3_response.getheaders() def getheader(self, name, default=None): """Returns a given response header.""" - return self.response.headers.get(name, default) + return self.urllib3_response.getheader(name, default) -class RESTClientObject: +class RESTClientObject(object): - def __init__(self, configuration) -> None: + def __init__(self, configuration, pools_size=4, maxsize=None): # urllib3.PoolManager will pass all kw parameters to connectionpool # https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/poolmanager.py#L75 # noqa: E501 # https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/connectionpool.py#L680 # noqa: E501 + # maxsize is the number of requests to host that are allowed in parallel # noqa: E501 # Custom SSL certificates and client certificates: http://urllib3.readthedocs.io/en/latest/advanced-usage.html # noqa: E501 # cert_reqs @@ -71,79 +57,70 @@ def __init__(self, configuration) -> None: else: cert_reqs = ssl.CERT_NONE - pool_args = { - "cert_reqs": cert_reqs, - "ca_certs": configuration.ssl_ca_cert, - "cert_file": configuration.cert_file, - "key_file": configuration.key_file, - } + addition_pool_args = {} if configuration.assert_hostname is not None: - pool_args['assert_hostname'] = ( - configuration.assert_hostname - ) + addition_pool_args['assert_hostname'] = configuration.assert_hostname # noqa: E501 if configuration.retries is not None: - pool_args['retries'] = configuration.retries - - if configuration.tls_server_name: - pool_args['server_hostname'] = configuration.tls_server_name - + addition_pool_args['retries'] = configuration.retries if configuration.socket_options is not None: - pool_args['socket_options'] = configuration.socket_options + addition_pool_args['socket_options'] = configuration.socket_options - if configuration.connection_pool_maxsize is not None: - pool_args['maxsize'] = configuration.connection_pool_maxsize + if maxsize is None: + if configuration.connection_pool_maxsize is not None: + maxsize = configuration.connection_pool_maxsize + else: + maxsize = 4 # https pool manager - self.pool_manager: urllib3.PoolManager - - if configuration.proxy: - if is_socks_proxy_url(configuration.proxy): - from urllib3.contrib.socks import SOCKSProxyManager - pool_args["proxy_url"] = configuration.proxy - pool_args["headers"] = configuration.proxy_headers - self.pool_manager = SOCKSProxyManager(**pool_args) - else: - pool_args["proxy_url"] = configuration.proxy - pool_args["proxy_headers"] = configuration.proxy_headers - self.pool_manager = urllib3.ProxyManager(**pool_args) + if configuration.proxy and not should_bypass_proxies(configuration.host, no_proxy=configuration.no_proxy or ''): + self.pool_manager = urllib3.ProxyManager( + num_pools=pools_size, + maxsize=maxsize, + cert_reqs=cert_reqs, + ca_certs=configuration.ssl_ca_cert, + cert_file=configuration.cert_file, + key_file=configuration.key_file, + proxy_url=configuration.proxy, + proxy_headers=configuration.proxy_headers, + **addition_pool_args + ) else: - self.pool_manager = urllib3.PoolManager(**pool_args) - - def request( - self, - method, - url, - headers=None, - body=None, - post_params=None, - _request_timeout=None - ): + self.pool_manager = urllib3.PoolManager( + num_pools=pools_size, + maxsize=maxsize, + cert_reqs=cert_reqs, + ca_certs=configuration.ssl_ca_cert, + cert_file=configuration.cert_file, + key_file=configuration.key_file, + **addition_pool_args + ) + + def request(self, method, url, query_params=None, headers=None, + body=None, post_params=None, _preload_content=True, + _request_timeout=None): """Perform requests. :param method: http request method :param url: http request url + :param query_params: query parameters in the url :param headers: http request headers :param body: request json body, for `application/json` :param post_params: request post parameters, `application/x-www-form-urlencoded` and `multipart/form-data` + :param _preload_content: if False, the urllib3.HTTPResponse object will + be returned without reading/decoding response + data. Default is True. :param _request_timeout: timeout setting for this request. If one number provided, it will be total request timeout. It can also be a pair (tuple) of (connection, read) timeouts. """ method = method.upper() - assert method in [ - 'GET', - 'HEAD', - 'DELETE', - 'POST', - 'PUT', - 'PATCH', - 'OPTIONS' - ] + assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', + 'PATCH', 'OPTIONS'] if post_params and body: raise ApiValueError( @@ -155,83 +132,60 @@ def request( timeout = None if _request_timeout: - if isinstance(_request_timeout, (int, float)): + if isinstance(_request_timeout, (int, float)): # noqa: E501,F821 timeout = urllib3.Timeout(total=_request_timeout) - elif ( - isinstance(_request_timeout, tuple) - and len(_request_timeout) == 2 - ): + elif (isinstance(_request_timeout, tuple) and + len(_request_timeout) == 2): timeout = urllib3.Timeout( - connect=_request_timeout[0], - read=_request_timeout[1] - ) + connect=_request_timeout[0], read=_request_timeout[1]) try: # For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE` if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']: - - # no content type provided or payload is json - content_type = headers.get('Content-Type') - if ( - not content_type - or re.search('json', content_type, re.IGNORECASE) - ): + # Only set a default Content-Type for POST, PUT, PATCH and OPTIONS requests + if (method != 'DELETE') and ('Content-Type' not in headers): + headers['Content-Type'] = 'application/json' + if query_params: + url += '?' + urlencode(query_params) + if ('Content-Type' not in headers) or (re.search('json', headers['Content-Type'], re.IGNORECASE)): request_body = None if body is not None: request_body = json.dumps(body) r = self.pool_manager.request( - method, - url, + method, url, body=request_body, + preload_content=_preload_content, timeout=timeout, - headers=headers, - preload_content=False - ) - elif content_type == 'application/x-www-form-urlencoded': + headers=headers) + elif headers['Content-Type'] == 'application/x-www-form-urlencoded': # noqa: E501 r = self.pool_manager.request( - method, - url, + method, url, fields=post_params, encode_multipart=False, + preload_content=_preload_content, timeout=timeout, - headers=headers, - preload_content=False - ) - elif content_type == 'multipart/form-data': + headers=headers) + elif headers['Content-Type'] == 'multipart/form-data': # must del headers['Content-Type'], or the correct # Content-Type which generated by urllib3 will be # overwritten. del headers['Content-Type'] - # Ensures that dict objects are serialized - post_params = [(a, json.dumps(b)) if isinstance(b, dict) else (a,b) for a, b in post_params] r = self.pool_manager.request( - method, - url, + method, url, fields=post_params, encode_multipart=True, + preload_content=_preload_content, timeout=timeout, - headers=headers, - preload_content=False - ) + headers=headers) # Pass a `string` parameter directly in the body to support - # other content types than JSON when `body` argument is - # provided in serialized form. + # other content types than Json when `body` argument is + # provided in serialized form elif isinstance(body, str) or isinstance(body, bytes): + request_body = body r = self.pool_manager.request( - method, - url, - body=body, - timeout=timeout, - headers=headers, - preload_content=False - ) - elif headers['Content-Type'] == 'text/plain' and isinstance(body, bool): - request_body = "true" if body else "false" - r = self.pool_manager.request( - method, - url, + method, url, body=request_body, - preload_content=False, + preload_content=_preload_content, timeout=timeout, headers=headers) else: @@ -242,16 +196,151 @@ def request( raise ApiException(status=0, reason=msg) # For `GET`, `HEAD` else: - r = self.pool_manager.request( - method, - url, - fields={}, - timeout=timeout, - headers=headers, - preload_content=False - ) + r = self.pool_manager.request(method, url, + fields=query_params, + preload_content=_preload_content, + timeout=timeout, + headers=headers) except urllib3.exceptions.SSLError as e: - msg = "\n".join([type(e).__name__, str(e)]) + msg = "{0}\n{1}".format(type(e).__name__, str(e)) raise ApiException(status=0, reason=msg) - return RESTResponse(r) + if _preload_content: + r = RESTResponse(r) + + # log response body + logger.debug("response body: %s", r.data) + + if not 200 <= r.status <= 299: + if r.status == 401: + raise UnauthorizedException(http_resp=r) + + if r.status == 403: + raise ForbiddenException(http_resp=r) + + if r.status == 404: + raise NotFoundException(http_resp=r) + + if 500 <= r.status <= 599: + raise ServiceException(http_resp=r) + + raise ApiException(http_resp=r) + + return r + + def GET(self, url, headers=None, query_params=None, _preload_content=True, + _request_timeout=None): + return self.request("GET", url, + headers=headers, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + query_params=query_params) + + def HEAD(self, url, headers=None, query_params=None, _preload_content=True, + _request_timeout=None): + return self.request("HEAD", url, + headers=headers, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + query_params=query_params) + + def OPTIONS(self, url, headers=None, query_params=None, post_params=None, + body=None, _preload_content=True, _request_timeout=None): + return self.request("OPTIONS", url, + headers=headers, + query_params=query_params, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + + def DELETE(self, url, headers=None, query_params=None, body=None, + _preload_content=True, _request_timeout=None): + return self.request("DELETE", url, + headers=headers, + query_params=query_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + + def POST(self, url, headers=None, query_params=None, post_params=None, + body=None, _preload_content=True, _request_timeout=None): + return self.request("POST", url, + headers=headers, + query_params=query_params, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + + def PUT(self, url, headers=None, query_params=None, post_params=None, + body=None, _preload_content=True, _request_timeout=None): + return self.request("PUT", url, + headers=headers, + query_params=query_params, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + + def PATCH(self, url, headers=None, query_params=None, post_params=None, + body=None, _preload_content=True, _request_timeout=None): + return self.request("PATCH", url, + headers=headers, + query_params=query_params, + post_params=post_params, + _preload_content=_preload_content, + _request_timeout=_request_timeout, + body=body) + +# end of class RESTClientObject +def is_ipv4(target): + """ Test if IPv4 address or not + """ + try: + chk = ipaddress.IPv4Address(target) + return True + except ipaddress.AddressValueError: + return False + +def in_ipv4net(target, net): + """ Test if target belongs to given IPv4 network + """ + try: + nw = ipaddress.IPv4Network(net) + ip = ipaddress.IPv4Address(target) + if ip in nw: + return True + return False + except ipaddress.AddressValueError: + return False + except ipaddress.NetmaskValueError: + return False + +def should_bypass_proxies(url, no_proxy=None): + """ Yet another requests.should_bypass_proxies + Test if proxies should not be used for a particular url. + """ + + parsed = urlparse(url) + + # special cases + if parsed.hostname in [None, '']: + return True + + # special cases + if no_proxy in [None , '']: + return False + if no_proxy == '*': + return True + + no_proxy = no_proxy.lower().replace(' ',''); + entries = ( + host for host in no_proxy.split(',') if host + ) + + if is_ipv4(parsed.hostname): + for item in entries: + if in_ipv4net(parsed.hostname, item): + return True + return proxy_bypass_environment(parsed.hostname, {'no': no_proxy} ) diff --git a/libraries/models/cloudharness_model/typing_utils.py b/libraries/models/cloudharness_model/typing_utils.py new file mode 100644 index 000000000..74e3c913a --- /dev/null +++ b/libraries/models/cloudharness_model/typing_utils.py @@ -0,0 +1,30 @@ +import sys + +if sys.version_info < (3, 7): + import typing + + def is_generic(klass): + """ Determine whether klass is a generic class """ + return type(klass) == typing.GenericMeta + + def is_dict(klass): + """ Determine whether klass is a Dict """ + return klass.__extra__ == dict + + def is_list(klass): + """ Determine whether klass is a List """ + return klass.__extra__ == list + +else: + + def is_generic(klass): + """ Determine whether klass is a generic class """ + return hasattr(klass, '__origin__') + + def is_dict(klass): + """ Determine whether klass is a Dict """ + return klass.__origin__ == dict + + def is_list(klass): + """ Determine whether klass is a List """ + return klass.__origin__ == list diff --git a/libraries/models/cloudharness_model/util.py b/libraries/models/cloudharness_model/util.py new file mode 100644 index 000000000..8b21d7fbf --- /dev/null +++ b/libraries/models/cloudharness_model/util.py @@ -0,0 +1,175 @@ +import datetime +import logging +import humps + +import six +import typing +from cloudharness_model import typing_utils + + +def _deserialize(data, klass): + """Deserializes dict, list, str into an object. + :param data: dict, list or str. + :param klass: class literal, or string of class name. + :return: object. + """ + if data is None: + return None + + if klass in six.integer_types or klass in (float, str, bool, bytearray): + return _deserialize_primitive(data, klass) + elif klass == object: + return _deserialize_object(data) + elif klass == datetime.date: + return deserialize_date(data) + elif klass == datetime.datetime: + return deserialize_datetime(data) + elif typing_utils.is_generic(klass): + if typing_utils.is_list(klass): + if isinstance(klass.__args__[0], typing.TypeVar): + return data + return _deserialize_list(data, klass.__args__[0]) + if typing_utils.is_dict(klass): + if isinstance(klass.__args__[1], typing.TypeVar): + return data + return _deserialize_dict(data, klass.__args__[1]) + else: + return deserialize_model(data, klass) + + +def _deserialize_primitive(data, klass): + """Deserializes to primitive type. + :param data: data to deserialize. + :param klass: class literal. + :return: int, long, float, str, bool. + :rtype: int | long | float | str | bool + """ + try: + value = klass(data) + except UnicodeEncodeError: + value = six.u(data) + except TypeError: + value = data + return value + + +def _deserialize_object(value): + """Return an original value. + :return: object. + """ + return value + + +def deserialize_date(string): + """Deserializes string to date. + :param string: str. + :type string: str + :return: date. + :rtype: date + """ + if string is None: + return None + + try: + from dateutil.parser import parse + return parse(string).date() + except ImportError: + return string + + +def deserialize_datetime(string): + """Deserializes string to datetime. + The string should be in iso8601 datetime format. + :param string: str. + :type string: str + :return: datetime. + :rtype: datetime + """ + if string is None: + return None + + try: + from dateutil.parser import parse + return parse(string) + except ImportError: + return string + + +class DeserializationException(Exception): + pass + + +def deserialize_model(data, klass): + """Deserializes list or dict to model. + :param data: dict, list. + :type data: dict | list + :param klass: class literal. + :return: model object. + """ + + if isinstance(data, klass) or not klass or not hasattr(klass, "__call__"): + return data + try: + instance = klass() + except: + raise + if isinstance(data, dict): + instance._raw_dict = data + + if not hasattr(instance, "openapi_types") or isinstance(data, klass): + return data + if data is None: + return instance + try: + if isinstance(data, list): + for attr, attr_type in six.iteritems(instance.openapi_types): + if instance.attribute_map[attr] in data: + value = data[instance.attribute_map[attr]] + setattr(instance, attr, _deserialize(value, attr_type)) + + elif hasattr(data, "__getitem__"): + + for attr in data: + value = data[attr] + attr = humps.decamelize(attr) + if attr in instance.attribute_map: + try: + setattr(instance, attr, _deserialize(value, instance.openapi_types[attr])) + except Exception as e: + logging.warning( + "Deserialization error: could not set attribute `%s` to value `%s` in class `%s`.", attr, value, klass.__name__, exc_info=True) + from .models.base_model_ import Model + setattr(instance, attr, Model.from_dict(value)) + logging.debug("Instance is %s", instance, exc_info=True) + + except Exception as e: + logging.error("Deserialize error", exc_info=True) + raise DeserializationException( + f"Cannot convert data to class {klass.__name__}. Data is\n{repr(data)}") from e + + return instance + + +def _deserialize_list(data, boxed_type): + """Deserializes a list and its elements. + :param data: list to deserialize. + :type data: list + :param boxed_type: class literal. + :return: deserialized list. + :rtype: list + """ + return [_deserialize(sub_data, boxed_type) + for sub_data in data] + + +def _deserialize_dict(data, boxed_type): + """Deserializes a dict and its elements. + :param data: dict to deserialize. + :type data: dict + :param boxed_type: class literal. + :return: deserialized dict. + :rtype: dict + """ + from cloudharness_model.models.base_model_ import Model + return Model.from_dict({k: _deserialize(v, boxed_type) + for k, v in six.iteritems(data)}) diff --git a/libraries/models/docs/.gitattributes b/libraries/models/docs/.gitattributes deleted file mode 100644 index a5ca8e67b..000000000 --- a/libraries/models/docs/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -* linguist-generated=true \ No newline at end of file diff --git a/libraries/models/docs/ApiTestsConfig.md b/libraries/models/docs/ApiTestsConfig.md deleted file mode 100644 index b026fa448..000000000 --- a/libraries/models/docs/ApiTestsConfig.md +++ /dev/null @@ -1,33 +0,0 @@ -# ApiTestsConfig - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**enabled** | **bool** | Enables api tests for this application (default: false) | -**autotest** | **bool** | Specify whether to run the common smoke tests | -**run_params** | **List[str]** | Additional schemathesis parameters | [optional] -**checks** | **List[str]** | One of the Schemathesis checks: - not_a_server_error. The response has 5xx HTTP status; - status_code_conformance. The response status is not defined in the API schema; - content_type_conformance. The response content type is not defined in the API schema; - response_schema_conformance. The response content does not conform to the schema defined for this specific response; - response_headers_conformance. The response headers does not contain all defined headers. | - -## Example - -```python -from cloudharness_model.models.api_tests_config import ApiTestsConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of ApiTestsConfig from a JSON string -api_tests_config_instance = ApiTestsConfig.from_json(json) -# print the JSON string representation of the object -print(ApiTestsConfig.to_json()) - -# convert the object into a dict -api_tests_config_dict = api_tests_config_instance.to_dict() -# create an instance of ApiTestsConfig from a dict -api_tests_config_from_dict = ApiTestsConfig.from_dict(api_tests_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/ApplicationAccountsConfig.md b/libraries/models/docs/ApplicationAccountsConfig.md deleted file mode 100644 index 39cc91dbc..000000000 --- a/libraries/models/docs/ApplicationAccountsConfig.md +++ /dev/null @@ -1,31 +0,0 @@ -# ApplicationAccountsConfig - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**roles** | **List[str]** | Specify roles to be created in this deployment specific for this application | [optional] -**users** | [**List[ApplicationUser]**](ApplicationUser.md) | Defines test users to be added to the deployment, specific for this application | [optional] - -## Example - -```python -from cloudharness_model.models.application_accounts_config import ApplicationAccountsConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of ApplicationAccountsConfig from a JSON string -application_accounts_config_instance = ApplicationAccountsConfig.from_json(json) -# print the JSON string representation of the object -print(ApplicationAccountsConfig.to_json()) - -# convert the object into a dict -application_accounts_config_dict = application_accounts_config_instance.to_dict() -# create an instance of ApplicationAccountsConfig from a dict -application_accounts_config_from_dict = ApplicationAccountsConfig.from_dict(application_accounts_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/ApplicationConfig.md b/libraries/models/docs/ApplicationConfig.md deleted file mode 100644 index 8a2013df1..000000000 --- a/libraries/models/docs/ApplicationConfig.md +++ /dev/null @@ -1,30 +0,0 @@ -# ApplicationConfig - -Place here the values to configure your application helm templates. - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**harness** | [**ApplicationHarnessConfig**](ApplicationHarnessConfig.md) | | - -## Example - -```python -from cloudharness_model.models.application_config import ApplicationConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of ApplicationConfig from a JSON string -application_config_instance = ApplicationConfig.from_json(json) -# print the JSON string representation of the object -print(ApplicationConfig.to_json()) - -# convert the object into a dict -application_config_dict = application_config_instance.to_dict() -# create an instance of ApplicationConfig from a dict -application_config_from_dict = ApplicationConfig.from_dict(application_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/ApplicationDependenciesConfig.md b/libraries/models/docs/ApplicationDependenciesConfig.md deleted file mode 100644 index ce27a1cdf..000000000 --- a/libraries/models/docs/ApplicationDependenciesConfig.md +++ /dev/null @@ -1,33 +0,0 @@ -# ApplicationDependenciesConfig - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**hard** | **List[str]** | Hard dependencies indicate that the application may not start without these other applications. | [optional] -**soft** | **List[str]** | Soft dependencies indicate that the application will work partially without these other applications. | [optional] -**build** | **List[str]** | Hard dependencies indicate that the application Docker image build requires these base/common images | [optional] -**git** | [**List[GitDependencyConfig]**](GitDependencyConfig.md) | | [optional] - -## Example - -```python -from cloudharness_model.models.application_dependencies_config import ApplicationDependenciesConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of ApplicationDependenciesConfig from a JSON string -application_dependencies_config_instance = ApplicationDependenciesConfig.from_json(json) -# print the JSON string representation of the object -print(ApplicationDependenciesConfig.to_json()) - -# convert the object into a dict -application_dependencies_config_dict = application_dependencies_config_instance.to_dict() -# create an instance of ApplicationDependenciesConfig from a dict -application_dependencies_config_from_dict = ApplicationDependenciesConfig.from_dict(application_dependencies_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/ApplicationHarnessConfig.md b/libraries/models/docs/ApplicationHarnessConfig.md deleted file mode 100644 index eb4795303..000000000 --- a/libraries/models/docs/ApplicationHarnessConfig.md +++ /dev/null @@ -1,55 +0,0 @@ -# ApplicationHarnessConfig - -Define helm variables that allow CloudHarness to enable and configure your application's deployment - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**deployment** | [**DeploymentAutoArtifactConfig**](DeploymentAutoArtifactConfig.md) | | [optional] -**service** | [**ServiceAutoArtifactConfig**](ServiceAutoArtifactConfig.md) | | [optional] -**subdomain** | **str** | If specified, an ingress will be created at [subdomain].[.Values.domain] | [optional] -**aliases** | **List[str]** | If specified, an ingress will be created at [alias].[.Values.domain] for each alias | [optional] -**domain** | **str** | If specified, an ingress will be created at [domain] | [optional] -**dependencies** | [**ApplicationDependenciesConfig**](ApplicationDependenciesConfig.md) | | [optional] -**secured** | **object** | When true, the application is shielded with a getekeeper | [optional] -**uri_role_mapping** | [**List[UriRoleMappingConfig]**](UriRoleMappingConfig.md) | Map uri/roles to secure with the Gatekeeper (if `secured: true`) | [optional] -**secrets** | **Dict[str, object]** | | [optional] -**use_services** | [**List[NamedObject]**](NamedObject.md) | Specify which services this application uses in the frontend to create proxy ingresses. e.g. ``` - name: samples ``` | [optional] -**database** | [**DatabaseDeploymentConfig**](DatabaseDeploymentConfig.md) | | [optional] -**resources** | [**List[FileResourcesConfig]**](FileResourcesConfig.md) | Application file resources. Maps from deploy/resources folder and mounts as configmaps | [optional] -**readiness_probe** | [**ApplicationProbe**](ApplicationProbe.md) | | [optional] -**startup_probe** | [**ApplicationProbe**](ApplicationProbe.md) | | [optional] -**liveness_probe** | [**ApplicationProbe**](ApplicationProbe.md) | | [optional] -**source_root** | **str** | | [optional] -**name** | **str** | Application's name. Do not edit, the value is automatically set from the application directory's name | [optional] -**jupyterhub** | [**JupyterHubConfig**](JupyterHubConfig.md) | | [optional] -**accounts** | [**ApplicationAccountsConfig**](ApplicationAccountsConfig.md) | | [optional] -**test** | [**ApplicationTestConfig**](ApplicationTestConfig.md) | | [optional] -**quotas** | **Dict[str, object]** | | [optional] -**env** | [**List[NameValue]**](NameValue.md) | Environmental variables added to all containers (deprecated, please use envmap) | [optional] -**envmap** | **Dict[str, object]** | | [optional] -**dockerfile** | [**DockerfileConfig**](DockerfileConfig.md) | | [optional] -**sentry** | **bool** | | [optional] -**proxy** | [**ProxyConf**](ProxyConf.md) | | [optional] - -## Example - -```python -from cloudharness_model.models.application_harness_config import ApplicationHarnessConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of ApplicationHarnessConfig from a JSON string -application_harness_config_instance = ApplicationHarnessConfig.from_json(json) -# print the JSON string representation of the object -print(ApplicationHarnessConfig.to_json()) - -# convert the object into a dict -application_harness_config_dict = application_harness_config_instance.to_dict() -# create an instance of ApplicationHarnessConfig from a dict -application_harness_config_from_dict = ApplicationHarnessConfig.from_dict(application_harness_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/ApplicationProbe.md b/libraries/models/docs/ApplicationProbe.md deleted file mode 100644 index d868f815c..000000000 --- a/libraries/models/docs/ApplicationProbe.md +++ /dev/null @@ -1,34 +0,0 @@ -# ApplicationProbe - -Define a Kubernetes probe See also the [official documentation](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/) - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**path** | **str** | | -**period_seconds** | **float** | | [optional] -**failure_threshold** | **float** | | [optional] -**initial_delay_seconds** | **float** | | [optional] -**port** | **float** | | [optional] - -## Example - -```python -from cloudharness_model.models.application_probe import ApplicationProbe - -# TODO update the JSON string below -json = "{}" -# create an instance of ApplicationProbe from a JSON string -application_probe_instance = ApplicationProbe.from_json(json) -# print the JSON string representation of the object -print(ApplicationProbe.to_json()) - -# convert the object into a dict -application_probe_dict = application_probe_instance.to_dict() -# create an instance of ApplicationProbe from a dict -application_probe_from_dict = ApplicationProbe.from_dict(application_probe_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/ApplicationTestConfig.md b/libraries/models/docs/ApplicationTestConfig.md deleted file mode 100644 index 64397ffc4..000000000 --- a/libraries/models/docs/ApplicationTestConfig.md +++ /dev/null @@ -1,32 +0,0 @@ -# ApplicationTestConfig - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**unit** | [**UnitTestsConfig**](UnitTestsConfig.md) | | -**api** | [**ApiTestsConfig**](ApiTestsConfig.md) | | -**e2e** | [**E2ETestsConfig**](E2ETestsConfig.md) | | - -## Example - -```python -from cloudharness_model.models.application_test_config import ApplicationTestConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of ApplicationTestConfig from a JSON string -application_test_config_instance = ApplicationTestConfig.from_json(json) -# print the JSON string representation of the object -print(ApplicationTestConfig.to_json()) - -# convert the object into a dict -application_test_config_dict = application_test_config_instance.to_dict() -# create an instance of ApplicationTestConfig from a dict -application_test_config_from_dict = ApplicationTestConfig.from_dict(application_test_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/ApplicationUser.md b/libraries/models/docs/ApplicationUser.md deleted file mode 100644 index 78737d6c0..000000000 --- a/libraries/models/docs/ApplicationUser.md +++ /dev/null @@ -1,33 +0,0 @@ -# ApplicationUser - -Defines a user - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**username** | **str** | | -**password** | **str** | | [optional] -**client_roles** | **List[str]** | | [optional] -**realm_roles** | **List[str]** | | [optional] - -## Example - -```python -from cloudharness_model.models.application_user import ApplicationUser - -# TODO update the JSON string below -json = "{}" -# create an instance of ApplicationUser from a JSON string -application_user_instance = ApplicationUser.from_json(json) -# print the JSON string representation of the object -print(ApplicationUser.to_json()) - -# convert the object into a dict -application_user_dict = application_user_instance.to_dict() -# create an instance of ApplicationUser from a dict -application_user_from_dict = ApplicationUser.from_dict(application_user_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/AutoArtifactSpec.md b/libraries/models/docs/AutoArtifactSpec.md deleted file mode 100644 index 9efefab2f..000000000 --- a/libraries/models/docs/AutoArtifactSpec.md +++ /dev/null @@ -1,31 +0,0 @@ -# AutoArtifactSpec - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**auto** | **bool** | When true, enables automatic template | [optional] -**name** | **str** | | [optional] - -## Example - -```python -from cloudharness_model.models.auto_artifact_spec import AutoArtifactSpec - -# TODO update the JSON string below -json = "{}" -# create an instance of AutoArtifactSpec from a JSON string -auto_artifact_spec_instance = AutoArtifactSpec.from_json(json) -# print the JSON string representation of the object -print(AutoArtifactSpec.to_json()) - -# convert the object into a dict -auto_artifact_spec_dict = auto_artifact_spec_instance.to_dict() -# create an instance of AutoArtifactSpec from a dict -auto_artifact_spec_from_dict = AutoArtifactSpec.from_dict(auto_artifact_spec_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/BackupConfig.md b/libraries/models/docs/BackupConfig.md deleted file mode 100644 index 64990c798..000000000 --- a/libraries/models/docs/BackupConfig.md +++ /dev/null @@ -1,38 +0,0 @@ -# BackupConfig - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**active** | **bool** | | [optional] -**keep_days** | **object** | | [optional] -**keep_weeks** | **object** | | [optional] -**keep_months** | **object** | | [optional] -**schedule** | **str** | Cron expression | [optional] -**suffix** | **str** | The file suffix added to backup files | [optional] -**volumesize** | **str** | The volume size for backups (all backups share the same volume) | [optional] -**dir** | **str** | | -**resources** | [**DeploymentResourcesConf**](DeploymentResourcesConf.md) | | - -## Example - -```python -from cloudharness_model.models.backup_config import BackupConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of BackupConfig from a JSON string -backup_config_instance = BackupConfig.from_json(json) -# print the JSON string representation of the object -print(BackupConfig.to_json()) - -# convert the object into a dict -backup_config_dict = backup_config_instance.to_dict() -# create an instance of BackupConfig from a dict -backup_config_from_dict = BackupConfig.from_dict(backup_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/CDCEvent.md b/libraries/models/docs/CDCEvent.md deleted file mode 100644 index baeef0e7a..000000000 --- a/libraries/models/docs/CDCEvent.md +++ /dev/null @@ -1,34 +0,0 @@ -# CDCEvent - -A message sent to the orchestration queue. Applications can listen to these events to react to data change events happening on other applications. - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**operation** | **str** | the operation on the object e.g. create / update / delete | -**uid** | **object** | the unique identifier attribute of the object | -**message_type** | **str** | the type of the message (relates to the object type) e.g. jobs | -**resource** | **Dict[str, object]** | | [optional] -**meta** | [**CDCEventMeta**](CDCEventMeta.md) | | - -## Example - -```python -from cloudharness_model.models.cdc_event import CDCEvent - -# TODO update the JSON string below -json = "{}" -# create an instance of CDCEvent from a JSON string -cdc_event_instance = CDCEvent.from_json(json) -# print the JSON string representation of the object -print(CDCEvent.to_json()) - -# convert the object into a dict -cdc_event_dict = cdc_event_instance.to_dict() -# create an instance of CDCEvent from a dict -cdc_event_from_dict = CDCEvent.from_dict(cdc_event_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/CDCEventMeta.md b/libraries/models/docs/CDCEventMeta.md deleted file mode 100644 index 95f8f2199..000000000 --- a/libraries/models/docs/CDCEventMeta.md +++ /dev/null @@ -1,34 +0,0 @@ -# CDCEventMeta - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**app_name** | **str** | The name of the application/microservice sending the message | -**user** | [**User**](User.md) | | [optional] -**args** | **List[Dict[str, object]]** | the caller function arguments | [optional] -**kwargs** | **object** | the caller function keyword arguments | [optional] -**description** | **str** | General description -- for human consumption | [optional] - -## Example - -```python -from cloudharness_model.models.cdc_event_meta import CDCEventMeta - -# TODO update the JSON string below -json = "{}" -# create an instance of CDCEventMeta from a JSON string -cdc_event_meta_instance = CDCEventMeta.from_json(json) -# print the JSON string representation of the object -print(CDCEventMeta.to_json()) - -# convert the object into a dict -cdc_event_meta_dict = cdc_event_meta_instance.to_dict() -# create an instance of CDCEventMeta from a dict -cdc_event_meta_from_dict = CDCEventMeta.from_dict(cdc_event_meta_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/CpuMemoryConfig.md b/libraries/models/docs/CpuMemoryConfig.md deleted file mode 100644 index 3cac8b987..000000000 --- a/libraries/models/docs/CpuMemoryConfig.md +++ /dev/null @@ -1,31 +0,0 @@ -# CpuMemoryConfig - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**cpu** | **object** | | [optional] -**memory** | **object** | | [optional] - -## Example - -```python -from cloudharness_model.models.cpu_memory_config import CpuMemoryConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of CpuMemoryConfig from a JSON string -cpu_memory_config_instance = CpuMemoryConfig.from_json(json) -# print the JSON string representation of the object -print(CpuMemoryConfig.to_json()) - -# convert the object into a dict -cpu_memory_config_dict = cpu_memory_config_instance.to_dict() -# create an instance of CpuMemoryConfig from a dict -cpu_memory_config_from_dict = CpuMemoryConfig.from_dict(cpu_memory_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/DatabaseDeploymentConfig.md b/libraries/models/docs/DatabaseDeploymentConfig.md deleted file mode 100644 index ae920cd1e..000000000 --- a/libraries/models/docs/DatabaseDeploymentConfig.md +++ /dev/null @@ -1,40 +0,0 @@ -# DatabaseDeploymentConfig - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**auto** | **bool** | When true, enables automatic template | [optional] -**name** | **str** | | [optional] -**type** | **str** | Define the database type. One of (mongo, postgres, neo4j, sqlite3) | [optional] -**size** | **str** | Specify database disk size | [optional] -**user** | **str** | database username | [optional] -**var_pass** | **str** | Database password | [optional] -**image_ref** | **str** | Used for referencing images from the build | [optional] -**mongo** | **Dict[str, object]** | | [optional] -**postgres** | **Dict[str, object]** | | [optional] -**neo4j** | **object** | Neo4j database specific configuration | [optional] -**resources** | [**DeploymentResourcesConf**](DeploymentResourcesConf.md) | | [optional] - -## Example - -```python -from cloudharness_model.models.database_deployment_config import DatabaseDeploymentConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of DatabaseDeploymentConfig from a JSON string -database_deployment_config_instance = DatabaseDeploymentConfig.from_json(json) -# print the JSON string representation of the object -print(DatabaseDeploymentConfig.to_json()) - -# convert the object into a dict -database_deployment_config_dict = database_deployment_config_instance.to_dict() -# create an instance of DatabaseDeploymentConfig from a dict -database_deployment_config_from_dict = DatabaseDeploymentConfig.from_dict(database_deployment_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/DeploymentAutoArtifactConfig.md b/libraries/models/docs/DeploymentAutoArtifactConfig.md deleted file mode 100644 index e2f7abfb1..000000000 --- a/libraries/models/docs/DeploymentAutoArtifactConfig.md +++ /dev/null @@ -1,36 +0,0 @@ -# DeploymentAutoArtifactConfig - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**auto** | **bool** | When true, enables automatic template | [optional] -**name** | **str** | | [optional] -**port** | **object** | Deployment port | [optional] -**replicas** | **int** | Number of replicas | [optional] -**image** | **str** | Image name to use in the deployment. Leave it blank to set from the application's Docker file | [optional] -**resources** | [**DeploymentResourcesConf**](DeploymentResourcesConf.md) | | [optional] -**volume** | [**DeploymentVolumeSpec**](DeploymentVolumeSpec.md) | | [optional] - -## Example - -```python -from cloudharness_model.models.deployment_auto_artifact_config import DeploymentAutoArtifactConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of DeploymentAutoArtifactConfig from a JSON string -deployment_auto_artifact_config_instance = DeploymentAutoArtifactConfig.from_json(json) -# print the JSON string representation of the object -print(DeploymentAutoArtifactConfig.to_json()) - -# convert the object into a dict -deployment_auto_artifact_config_dict = deployment_auto_artifact_config_instance.to_dict() -# create an instance of DeploymentAutoArtifactConfig from a dict -deployment_auto_artifact_config_from_dict = DeploymentAutoArtifactConfig.from_dict(deployment_auto_artifact_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/DeploymentResourcesConf.md b/libraries/models/docs/DeploymentResourcesConf.md deleted file mode 100644 index 5ed4369a6..000000000 --- a/libraries/models/docs/DeploymentResourcesConf.md +++ /dev/null @@ -1,31 +0,0 @@ -# DeploymentResourcesConf - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**requests** | [**CpuMemoryConfig**](CpuMemoryConfig.md) | | [optional] -**limits** | [**CpuMemoryConfig**](CpuMemoryConfig.md) | | [optional] - -## Example - -```python -from cloudharness_model.models.deployment_resources_conf import DeploymentResourcesConf - -# TODO update the JSON string below -json = "{}" -# create an instance of DeploymentResourcesConf from a JSON string -deployment_resources_conf_instance = DeploymentResourcesConf.from_json(json) -# print the JSON string representation of the object -print(DeploymentResourcesConf.to_json()) - -# convert the object into a dict -deployment_resources_conf_dict = deployment_resources_conf_instance.to_dict() -# create an instance of DeploymentResourcesConf from a dict -deployment_resources_conf_from_dict = DeploymentResourcesConf.from_dict(deployment_resources_conf_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/DeploymentVolumeSpec.md b/libraries/models/docs/DeploymentVolumeSpec.md deleted file mode 100644 index a22a912ba..000000000 --- a/libraries/models/docs/DeploymentVolumeSpec.md +++ /dev/null @@ -1,34 +0,0 @@ -# DeploymentVolumeSpec - -Defines a volume attached to the deployment. Automatically created the volume claim and mounts. - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**auto** | **bool** | When true, enables automatic template | [optional] -**name** | **str** | | [optional] -**mountpath** | **str** | The mount path for the volume | -**size** | **object** | The volume size. E.g. 5Gi | [optional] -**usenfs** | **bool** | Set to `true` to use the nfs on the created volume and mount as ReadWriteMany. | [optional] - -## Example - -```python -from cloudharness_model.models.deployment_volume_spec import DeploymentVolumeSpec - -# TODO update the JSON string below -json = "{}" -# create an instance of DeploymentVolumeSpec from a JSON string -deployment_volume_spec_instance = DeploymentVolumeSpec.from_json(json) -# print the JSON string representation of the object -print(DeploymentVolumeSpec.to_json()) - -# convert the object into a dict -deployment_volume_spec_dict = deployment_volume_spec_instance.to_dict() -# create an instance of DeploymentVolumeSpec from a dict -deployment_volume_spec_from_dict = DeploymentVolumeSpec.from_dict(deployment_volume_spec_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/DockerfileConfig.md b/libraries/models/docs/DockerfileConfig.md deleted file mode 100644 index 4be6d38bb..000000000 --- a/libraries/models/docs/DockerfileConfig.md +++ /dev/null @@ -1,30 +0,0 @@ -# DockerfileConfig - -Configuration for a dockerfile - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**build_args** | **Dict[str, object]** | | [optional] - -## Example - -```python -from cloudharness_model.models.dockerfile_config import DockerfileConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of DockerfileConfig from a JSON string -dockerfile_config_instance = DockerfileConfig.from_json(json) -# print the JSON string representation of the object -print(DockerfileConfig.to_json()) - -# convert the object into a dict -dockerfile_config_dict = dockerfile_config_instance.to_dict() -# create an instance of DockerfileConfig from a dict -dockerfile_config_from_dict = DockerfileConfig.from_dict(dockerfile_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/E2ETestsConfig.md b/libraries/models/docs/E2ETestsConfig.md deleted file mode 100644 index 28e8731c8..000000000 --- a/libraries/models/docs/E2ETestsConfig.md +++ /dev/null @@ -1,33 +0,0 @@ -# E2ETestsConfig - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**enabled** | **bool** | Enables end to end testing for this application (default: false) | -**smoketest** | **bool** | Specify whether to run the common smoke tests | -**ignore_console_errors** | **bool** | | [optional] -**ignore_request_errors** | **bool** | | [optional] - -## Example - -```python -from cloudharness_model.models.e2_e_tests_config import E2ETestsConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of E2ETestsConfig from a JSON string -e2_e_tests_config_instance = E2ETestsConfig.from_json(json) -# print the JSON string representation of the object -print(E2ETestsConfig.to_json()) - -# convert the object into a dict -e2_e_tests_config_dict = e2_e_tests_config_instance.to_dict() -# create an instance of E2ETestsConfig from a dict -e2_e_tests_config_from_dict = E2ETestsConfig.from_dict(e2_e_tests_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/FileResourcesConfig.md b/libraries/models/docs/FileResourcesConfig.md deleted file mode 100644 index ecd5a4ddd..000000000 --- a/libraries/models/docs/FileResourcesConfig.md +++ /dev/null @@ -1,32 +0,0 @@ -# FileResourcesConfig - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**name** | **str** | | -**src** | **str** | | -**dst** | **str** | | - -## Example - -```python -from cloudharness_model.models.file_resources_config import FileResourcesConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of FileResourcesConfig from a JSON string -file_resources_config_instance = FileResourcesConfig.from_json(json) -# print the JSON string representation of the object -print(FileResourcesConfig.to_json()) - -# convert the object into a dict -file_resources_config_dict = file_resources_config_instance.to_dict() -# create an instance of FileResourcesConfig from a dict -file_resources_config_from_dict = FileResourcesConfig.from_dict(file_resources_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/GatekeeperConf.md b/libraries/models/docs/GatekeeperConf.md deleted file mode 100644 index e27090fbf..000000000 --- a/libraries/models/docs/GatekeeperConf.md +++ /dev/null @@ -1,31 +0,0 @@ -# GatekeeperConf - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**image** | **str** | | [optional] -**replicas** | **int** | | [optional] - -## Example - -```python -from cloudharness_model.models.gatekeeper_conf import GatekeeperConf - -# TODO update the JSON string below -json = "{}" -# create an instance of GatekeeperConf from a JSON string -gatekeeper_conf_instance = GatekeeperConf.from_json(json) -# print the JSON string representation of the object -print(GatekeeperConf.to_json()) - -# convert the object into a dict -gatekeeper_conf_dict = gatekeeper_conf_instance.to_dict() -# create an instance of GatekeeperConf from a dict -gatekeeper_conf_from_dict = GatekeeperConf.from_dict(gatekeeper_conf_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/GitDependencyConfig.md b/libraries/models/docs/GitDependencyConfig.md deleted file mode 100644 index 0911db471..000000000 --- a/libraries/models/docs/GitDependencyConfig.md +++ /dev/null @@ -1,32 +0,0 @@ -# GitDependencyConfig - -Defines a git repo to be cloned inside the application path - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**url** | **str** | | -**branch_tag** | **str** | | -**path** | **str** | Defines the path where the repo is cloned. default: /git | [optional] - -## Example - -```python -from cloudharness_model.models.git_dependency_config import GitDependencyConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of GitDependencyConfig from a JSON string -git_dependency_config_instance = GitDependencyConfig.from_json(json) -# print the JSON string representation of the object -print(GitDependencyConfig.to_json()) - -# convert the object into a dict -git_dependency_config_dict = git_dependency_config_instance.to_dict() -# create an instance of GitDependencyConfig from a dict -git_dependency_config_from_dict = GitDependencyConfig.from_dict(git_dependency_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/HarnessMainConfig.md b/libraries/models/docs/HarnessMainConfig.md deleted file mode 100644 index 7940b51cc..000000000 --- a/libraries/models/docs/HarnessMainConfig.md +++ /dev/null @@ -1,44 +0,0 @@ -# HarnessMainConfig - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**local** | **bool** | If set to true, local DNS mapping is added to pods. | -**secured_gatekeepers** | **bool** | Enables/disables Gatekeepers on secured applications. Set to false for testing/development | -**domain** | **str** | The root domain | -**namespace** | **str** | The K8s namespace. | -**mainapp** | **str** | Defines the app to map to the root domain | -**registry** | [**RegistryConfig**](RegistryConfig.md) | | [optional] -**tag** | **str** | Docker tag used to push/pull the built images. | [optional] -**apps** | [**Dict[str, ApplicationConfig]**](ApplicationConfig.md) | | -**env** | [**List[NameValue]**](NameValue.md) | Environmental variables added to all pods | [optional] -**privenv** | [**List[NameValue]**](NameValue.md) | Private environmental variables added to all pods | [optional] -**backup** | [**BackupConfig**](BackupConfig.md) | | [optional] -**name** | **str** | Base name | [optional] -**task_images** | **Dict[str, object]** | | [optional] -**build_hash** | **str** | | [optional] -**ingress** | [**IngressConfig**](IngressConfig.md) | | [optional] - -## Example - -```python -from cloudharness_model.models.harness_main_config import HarnessMainConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of HarnessMainConfig from a JSON string -harness_main_config_instance = HarnessMainConfig.from_json(json) -# print the JSON string representation of the object -print(HarnessMainConfig.to_json()) - -# convert the object into a dict -harness_main_config_dict = harness_main_config_instance.to_dict() -# create an instance of HarnessMainConfig from a dict -harness_main_config_from_dict = HarnessMainConfig.from_dict(harness_main_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/IngressConfig.md b/libraries/models/docs/IngressConfig.md deleted file mode 100644 index 5e2add2f3..000000000 --- a/libraries/models/docs/IngressConfig.md +++ /dev/null @@ -1,34 +0,0 @@ -# IngressConfig - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**auto** | **bool** | When true, enables automatic template | [optional] -**name** | **str** | | [optional] -**ssl_redirect** | **bool** | | [optional] -**letsencrypt** | [**IngressConfigAllOfLetsencrypt**](IngressConfigAllOfLetsencrypt.md) | | [optional] -**enabled** | **bool** | | [optional] - -## Example - -```python -from cloudharness_model.models.ingress_config import IngressConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of IngressConfig from a JSON string -ingress_config_instance = IngressConfig.from_json(json) -# print the JSON string representation of the object -print(IngressConfig.to_json()) - -# convert the object into a dict -ingress_config_dict = ingress_config_instance.to_dict() -# create an instance of IngressConfig from a dict -ingress_config_from_dict = IngressConfig.from_dict(ingress_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/IngressConfigAllOfLetsencrypt.md b/libraries/models/docs/IngressConfigAllOfLetsencrypt.md deleted file mode 100644 index fa4ec0909..000000000 --- a/libraries/models/docs/IngressConfigAllOfLetsencrypt.md +++ /dev/null @@ -1,30 +0,0 @@ -# IngressConfigAllOfLetsencrypt - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**email** | **str** | | [optional] - -## Example - -```python -from cloudharness_model.models.ingress_config_all_of_letsencrypt import IngressConfigAllOfLetsencrypt - -# TODO update the JSON string below -json = "{}" -# create an instance of IngressConfigAllOfLetsencrypt from a JSON string -ingress_config_all_of_letsencrypt_instance = IngressConfigAllOfLetsencrypt.from_json(json) -# print the JSON string representation of the object -print(IngressConfigAllOfLetsencrypt.to_json()) - -# convert the object into a dict -ingress_config_all_of_letsencrypt_dict = ingress_config_all_of_letsencrypt_instance.to_dict() -# create an instance of IngressConfigAllOfLetsencrypt from a dict -ingress_config_all_of_letsencrypt_from_dict = IngressConfigAllOfLetsencrypt.from_dict(ingress_config_all_of_letsencrypt_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/IntOrString.md b/libraries/models/docs/IntOrString.md deleted file mode 100644 index 516ab9fd0..000000000 --- a/libraries/models/docs/IntOrString.md +++ /dev/null @@ -1,29 +0,0 @@ -# IntOrString - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- - -## Example - -```python -from cloudharness_model.models.int_or_string import IntOrString - -# TODO update the JSON string below -json = "{}" -# create an instance of IntOrString from a JSON string -int_or_string_instance = IntOrString.from_json(json) -# print the JSON string representation of the object -print(IntOrString.to_json()) - -# convert the object into a dict -int_or_string_dict = int_or_string_instance.to_dict() -# create an instance of IntOrString from a dict -int_or_string_from_dict = IntOrString.from_dict(int_or_string_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/JupyterHubConfig.md b/libraries/models/docs/JupyterHubConfig.md deleted file mode 100644 index 7ba09ad00..000000000 --- a/libraries/models/docs/JupyterHubConfig.md +++ /dev/null @@ -1,33 +0,0 @@ -# JupyterHubConfig - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**args** | **List[str]** | arguments passed to the container | [optional] -**extra_config** | **Dict[str, object]** | | [optional] -**spawner_extra_config** | **Dict[str, object]** | | [optional] -**application_hook** | **object** | change the hook function (advanced) Specify the Python name of the function (full module path, the module must be installed in the Docker image) | [optional] - -## Example - -```python -from cloudharness_model.models.jupyter_hub_config import JupyterHubConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of JupyterHubConfig from a JSON string -jupyter_hub_config_instance = JupyterHubConfig.from_json(json) -# print the JSON string representation of the object -print(JupyterHubConfig.to_json()) - -# convert the object into a dict -jupyter_hub_config_dict = jupyter_hub_config_instance.to_dict() -# create an instance of JupyterHubConfig from a dict -jupyter_hub_config_from_dict = JupyterHubConfig.from_dict(jupyter_hub_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/NameValue.md b/libraries/models/docs/NameValue.md deleted file mode 100644 index 634ac9744..000000000 --- a/libraries/models/docs/NameValue.md +++ /dev/null @@ -1,31 +0,0 @@ -# NameValue - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**name** | **str** | | -**value** | **str** | | [optional] - -## Example - -```python -from cloudharness_model.models.name_value import NameValue - -# TODO update the JSON string below -json = "{}" -# create an instance of NameValue from a JSON string -name_value_instance = NameValue.from_json(json) -# print the JSON string representation of the object -print(NameValue.to_json()) - -# convert the object into a dict -name_value_dict = name_value_instance.to_dict() -# create an instance of NameValue from a dict -name_value_from_dict = NameValue.from_dict(name_value_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/NamedObject.md b/libraries/models/docs/NamedObject.md deleted file mode 100644 index 930d1be50..000000000 --- a/libraries/models/docs/NamedObject.md +++ /dev/null @@ -1,30 +0,0 @@ -# NamedObject - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**name** | **str** | | [optional] - -## Example - -```python -from cloudharness_model.models.named_object import NamedObject - -# TODO update the JSON string below -json = "{}" -# create an instance of NamedObject from a JSON string -named_object_instance = NamedObject.from_json(json) -# print the JSON string representation of the object -print(NamedObject.to_json()) - -# convert the object into a dict -named_object_dict = named_object_instance.to_dict() -# create an instance of NamedObject from a dict -named_object_from_dict = NamedObject.from_dict(named_object_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/Organization.md b/libraries/models/docs/Organization.md deleted file mode 100644 index 9fbff8042..000000000 --- a/libraries/models/docs/Organization.md +++ /dev/null @@ -1,34 +0,0 @@ -# Organization - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**name** | **str** | | [optional] -**domains** | [**List[NamedObject]**](NamedObject.md) | | [optional] -**alias** | **str** | | [optional] -**enabled** | **bool** | | [optional] -**id** | **str** | | [optional] - -## Example - -```python -from cloudharness_model.models.organization import Organization - -# TODO update the JSON string below -json = "{}" -# create an instance of Organization from a JSON string -organization_instance = Organization.from_json(json) -# print the JSON string representation of the object -print(Organization.to_json()) - -# convert the object into a dict -organization_dict = organization_instance.to_dict() -# create an instance of Organization from a dict -organization_from_dict = Organization.from_dict(organization_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/OrganizationOneOf.md b/libraries/models/docs/OrganizationOneOf.md deleted file mode 100644 index eefc6695e..000000000 --- a/libraries/models/docs/OrganizationOneOf.md +++ /dev/null @@ -1,32 +0,0 @@ -# OrganizationOneOf - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**domains** | [**List[NamedObject]**](NamedObject.md) | | [optional] -**alias** | **str** | | [optional] -**enabled** | **bool** | | [optional] -**id** | **str** | | [optional] - -## Example - -```python -from cloudharness_model.models.organization_one_of import OrganizationOneOf - -# TODO update the JSON string below -json = "{}" -# create an instance of OrganizationOneOf from a JSON string -organization_one_of_instance = OrganizationOneOf.from_json(json) -# print the JSON string representation of the object -print(OrganizationOneOf.to_json()) - -# convert the object into a dict -organization_one_of_dict = organization_one_of_instance.to_dict() -# create an instance of OrganizationOneOf from a dict -organization_one_of_from_dict = OrganizationOneOf.from_dict(organization_one_of_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/ProxyConf.md b/libraries/models/docs/ProxyConf.md deleted file mode 100644 index dc47913aa..000000000 --- a/libraries/models/docs/ProxyConf.md +++ /dev/null @@ -1,33 +0,0 @@ -# ProxyConf - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**forwarded_headers** | **bool** | | [optional] -**payload** | [**ProxyPayloadConf**](ProxyPayloadConf.md) | | [optional] -**timeout** | [**ProxyTimeoutConf**](ProxyTimeoutConf.md) | | [optional] -**gatekeeper** | [**GatekeeperConf**](GatekeeperConf.md) | | [optional] - -## Example - -```python -from cloudharness_model.models.proxy_conf import ProxyConf - -# TODO update the JSON string below -json = "{}" -# create an instance of ProxyConf from a JSON string -proxy_conf_instance = ProxyConf.from_json(json) -# print the JSON string representation of the object -print(ProxyConf.to_json()) - -# convert the object into a dict -proxy_conf_dict = proxy_conf_instance.to_dict() -# create an instance of ProxyConf from a dict -proxy_conf_from_dict = ProxyConf.from_dict(proxy_conf_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/ProxyPayloadConf.md b/libraries/models/docs/ProxyPayloadConf.md deleted file mode 100644 index a512e010d..000000000 --- a/libraries/models/docs/ProxyPayloadConf.md +++ /dev/null @@ -1,30 +0,0 @@ -# ProxyPayloadConf - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**max** | **int** | | [optional] - -## Example - -```python -from cloudharness_model.models.proxy_payload_conf import ProxyPayloadConf - -# TODO update the JSON string below -json = "{}" -# create an instance of ProxyPayloadConf from a JSON string -proxy_payload_conf_instance = ProxyPayloadConf.from_json(json) -# print the JSON string representation of the object -print(ProxyPayloadConf.to_json()) - -# convert the object into a dict -proxy_payload_conf_dict = proxy_payload_conf_instance.to_dict() -# create an instance of ProxyPayloadConf from a dict -proxy_payload_conf_from_dict = ProxyPayloadConf.from_dict(proxy_payload_conf_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/ProxyTimeoutConf.md b/libraries/models/docs/ProxyTimeoutConf.md deleted file mode 100644 index 74439fa31..000000000 --- a/libraries/models/docs/ProxyTimeoutConf.md +++ /dev/null @@ -1,32 +0,0 @@ -# ProxyTimeoutConf - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**keepalive** | **int** | | [optional] -**read** | **int** | | [optional] -**send** | **int** | | [optional] - -## Example - -```python -from cloudharness_model.models.proxy_timeout_conf import ProxyTimeoutConf - -# TODO update the JSON string below -json = "{}" -# create an instance of ProxyTimeoutConf from a JSON string -proxy_timeout_conf_instance = ProxyTimeoutConf.from_json(json) -# print the JSON string representation of the object -print(ProxyTimeoutConf.to_json()) - -# convert the object into a dict -proxy_timeout_conf_dict = proxy_timeout_conf_instance.to_dict() -# create an instance of ProxyTimeoutConf from a dict -proxy_timeout_conf_from_dict = ProxyTimeoutConf.from_dict(proxy_timeout_conf_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/RegistryConfig.md b/libraries/models/docs/RegistryConfig.md deleted file mode 100644 index b91c107f5..000000000 --- a/libraries/models/docs/RegistryConfig.md +++ /dev/null @@ -1,31 +0,0 @@ -# RegistryConfig - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**name** | **str** | | -**secret** | **str** | Optional secret used for pulling from docker registry. | [optional] - -## Example - -```python -from cloudharness_model.models.registry_config import RegistryConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of RegistryConfig from a JSON string -registry_config_instance = RegistryConfig.from_json(json) -# print the JSON string representation of the object -print(RegistryConfig.to_json()) - -# convert the object into a dict -registry_config_dict = registry_config_instance.to_dict() -# create an instance of RegistryConfig from a dict -registry_config_from_dict = RegistryConfig.from_dict(registry_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/ServiceAutoArtifactConfig.md b/libraries/models/docs/ServiceAutoArtifactConfig.md deleted file mode 100644 index 52feb35c2..000000000 --- a/libraries/models/docs/ServiceAutoArtifactConfig.md +++ /dev/null @@ -1,32 +0,0 @@ -# ServiceAutoArtifactConfig - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**auto** | **bool** | When true, enables automatic template | [optional] -**name** | **str** | | [optional] -**port** | **int** | Service port | [optional] - -## Example - -```python -from cloudharness_model.models.service_auto_artifact_config import ServiceAutoArtifactConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of ServiceAutoArtifactConfig from a JSON string -service_auto_artifact_config_instance = ServiceAutoArtifactConfig.from_json(json) -# print the JSON string representation of the object -print(ServiceAutoArtifactConfig.to_json()) - -# convert the object into a dict -service_auto_artifact_config_dict = service_auto_artifact_config_instance.to_dict() -# create an instance of ServiceAutoArtifactConfig from a dict -service_auto_artifact_config_from_dict = ServiceAutoArtifactConfig.from_dict(service_auto_artifact_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/UnitTestsConfig.md b/libraries/models/docs/UnitTestsConfig.md deleted file mode 100644 index 9510d9e00..000000000 --- a/libraries/models/docs/UnitTestsConfig.md +++ /dev/null @@ -1,31 +0,0 @@ -# UnitTestsConfig - - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**enabled** | **bool** | Enables unit tests for this application (default: true) | -**commands** | **List[str]** | Commands to run unit tests | - -## Example - -```python -from cloudharness_model.models.unit_tests_config import UnitTestsConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of UnitTestsConfig from a JSON string -unit_tests_config_instance = UnitTestsConfig.from_json(json) -# print the JSON string representation of the object -print(UnitTestsConfig.to_json()) - -# convert the object into a dict -unit_tests_config_dict = unit_tests_config_instance.to_dict() -# create an instance of UnitTestsConfig from a dict -unit_tests_config_from_dict = UnitTestsConfig.from_dict(unit_tests_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/UriRoleMappingConfig.md b/libraries/models/docs/UriRoleMappingConfig.md deleted file mode 100644 index 4438687a4..000000000 --- a/libraries/models/docs/UriRoleMappingConfig.md +++ /dev/null @@ -1,32 +0,0 @@ -# UriRoleMappingConfig - -Defines the application Gatekeeper configuration, if enabled (i.e. `secured: true`. - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**uri** | **str** | | -**roles** | **List[str]** | Roles allowed to access the present uri | [optional] -**white_listed** | **bool** | | [optional] - -## Example - -```python -from cloudharness_model.models.uri_role_mapping_config import UriRoleMappingConfig - -# TODO update the JSON string below -json = "{}" -# create an instance of UriRoleMappingConfig from a JSON string -uri_role_mapping_config_instance = UriRoleMappingConfig.from_json(json) -# print the JSON string representation of the object -print(UriRoleMappingConfig.to_json()) - -# convert the object into a dict -uri_role_mapping_config_dict = uri_role_mapping_config_instance.to_dict() -# create an instance of UriRoleMappingConfig from a dict -uri_role_mapping_config_from_dict = UriRoleMappingConfig.from_dict(uri_role_mapping_config_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/User.md b/libraries/models/docs/User.md deleted file mode 100644 index 9e9071e46..000000000 --- a/libraries/models/docs/User.md +++ /dev/null @@ -1,49 +0,0 @@ -# User - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**access** | **Dict[str, object]** | | [optional] -**attributes** | **Dict[str, object]** | | [optional] -**client_roles** | **Dict[str, object]** | | [optional] -**created_timestamp** | **int** | | [optional] -**credentials** | [**List[UserCredential]**](UserCredential.md) | | [optional] -**disableable_credential_types** | **List[str]** | | [optional] -**email** | **str** | | [optional] -**email_verified** | **bool** | | [optional] -**enabled** | **bool** | | [optional] -**federation_link** | **str** | | [optional] -**first_name** | **str** | | [optional] -**groups** | **List[str]** | | [optional] -**id** | **str** | | [optional] -**last_name** | **str** | | [optional] -**realm_roles** | **List[str]** | | [optional] -**required_actions** | **List[str]** | | [optional] -**service_account_client_id** | **str** | | [optional] -**username** | **str** | | [optional] -**additional_properties** | **object** | | [optional] -**user_groups** | [**List[UserGroup]**](UserGroup.md) | | [optional] -**organizations** | [**List[Organization]**](Organization.md) | | [optional] - -## Example - -```python -from cloudharness_model.models.user import User - -# TODO update the JSON string below -json = "{}" -# create an instance of User from a JSON string -user_instance = User.from_json(json) -# print the JSON string representation of the object -print(User.to_json()) - -# convert the object into a dict -user_dict = user_instance.to_dict() -# create an instance of User from a dict -user_from_dict = User.from_dict(user_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/UserCredential.md b/libraries/models/docs/UserCredential.md deleted file mode 100644 index 135ed08bb..000000000 --- a/libraries/models/docs/UserCredential.md +++ /dev/null @@ -1,37 +0,0 @@ -# UserCredential - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**created_date** | **int** | | [optional] -**credential_data** | **str** | | [optional] -**id** | **str** | | [optional] -**priority** | **int** | | [optional] -**secret_data** | **str** | | [optional] -**temporary** | **bool** | | [optional] -**type** | **str** | | [optional] -**user_label** | **str** | | [optional] -**value** | **str** | | [optional] - -## Example - -```python -from cloudharness_model.models.user_credential import UserCredential - -# TODO update the JSON string below -json = "{}" -# create an instance of UserCredential from a JSON string -user_credential_instance = UserCredential.from_json(json) -# print the JSON string representation of the object -print(UserCredential.to_json()) - -# convert the object into a dict -user_credential_dict = user_credential_instance.to_dict() -# create an instance of UserCredential from a dict -user_credential_from_dict = UserCredential.from_dict(user_credential_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/UserGroup.md b/libraries/models/docs/UserGroup.md deleted file mode 100644 index fa033ac7b..000000000 --- a/libraries/models/docs/UserGroup.md +++ /dev/null @@ -1,36 +0,0 @@ -# UserGroup - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**access** | **Dict[str, object]** | | [optional] -**attributes** | **Dict[str, object]** | | [optional] -**client_roles** | **Dict[str, object]** | | [optional] -**id** | **str** | | [optional] -**name** | **str** | | [optional] -**path** | **str** | | [optional] -**realm_roles** | **List[str]** | | [optional] -**sub_groups** | [**List[UserGroup]**](UserGroup.md) | | [optional] - -## Example - -```python -from cloudharness_model.models.user_group import UserGroup - -# TODO update the JSON string below -json = "{}" -# create an instance of UserGroup from a JSON string -user_group_instance = UserGroup.from_json(json) -# print the JSON string representation of the object -print(UserGroup.to_json()) - -# convert the object into a dict -user_group_dict = user_group_instance.to_dict() -# create an instance of UserGroup from a dict -user_group_from_dict = UserGroup.from_dict(user_group_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/docs/UserRole.md b/libraries/models/docs/UserRole.md deleted file mode 100644 index 19446feae..000000000 --- a/libraries/models/docs/UserRole.md +++ /dev/null @@ -1,35 +0,0 @@ -# UserRole - - -## Properties - -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -**attributes** | **Dict[str, object]** | | [optional] -**client_role** | **bool** | | [optional] -**composite** | **bool** | | [optional] -**container_id** | **str** | | [optional] -**description** | **str** | | [optional] -**id** | **str** | | [optional] -**name** | **str** | | [optional] - -## Example - -```python -from cloudharness_model.models.user_role import UserRole - -# TODO update the JSON string below -json = "{}" -# create an instance of UserRole from a JSON string -user_role_instance = UserRole.from_json(json) -# print the JSON string representation of the object -print(UserRole.to_json()) - -# convert the object into a dict -user_role_dict = user_role_instance.to_dict() -# create an instance of UserRole from a dict -user_role_from_dict = UserRole.from_dict(user_role_dict) -``` -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - - diff --git a/libraries/models/pyproject.toml b/libraries/models/pyproject.toml deleted file mode 100644 index 91bcda0f4..000000000 --- a/libraries/models/pyproject.toml +++ /dev/null @@ -1,71 +0,0 @@ -[tool.poetry] -name = "cloudharness_model" -version = "3.0.0" -description = "cloudharness" -authors = ["OpenAPI Generator Community "] -license = "NoLicense" -readme = "README.md" -repository = "https://github.com/GIT_USER_ID/GIT_REPO_ID" -keywords = ["OpenAPI", "OpenAPI-Generator", "cloudharness"] -include = ["cloudharness_model/py.typed"] - -[tool.poetry.dependencies] -python = "^3.7" - -urllib3 = ">= 1.25.3" -python-dateutil = ">=2.8.2" -pydantic = ">=2" -typing-extensions = ">=4.7.1" - -[tool.poetry.dev-dependencies] -pytest = ">=7.2.1" -tox = ">=3.9.0" -flake8 = ">=4.0.0" -types-python-dateutil = ">=2.8.19.14" -mypy = "1.4.1" - - -[build-system] -requires = ["setuptools"] -build-backend = "setuptools.build_meta" - -[tool.pylint.'MESSAGES CONTROL'] -extension-pkg-whitelist = "pydantic" - -[tool.mypy] -files = [ - "cloudharness_model", - #"test", # auto-generated tests - "tests", # hand-written tests -] -# TODO: enable "strict" once all these individual checks are passing -# strict = true - -# List from: https://mypy.readthedocs.io/en/stable/existing_code.html#introduce-stricter-options -warn_unused_configs = true -warn_redundant_casts = true -warn_unused_ignores = true - -## Getting these passing should be easy -strict_equality = true -strict_concatenate = true - -## Strongly recommend enabling this one as soon as you can -check_untyped_defs = true - -## These shouldn't be too much additional work, but may be tricky to -## get passing if you use a lot of untyped libraries -disallow_subclassing_any = true -disallow_untyped_decorators = true -disallow_any_generics = true - -### These next few are various gradations of forcing use of type annotations -#disallow_untyped_calls = true -#disallow_incomplete_defs = true -#disallow_untyped_defs = true -# -### This one isn't too hard to get passing, but return on investment is lower -#no_implicit_reexport = true -# -### This one can be tricky to get passing if you use a lot of untyped libraries -#warn_return_any = true diff --git a/libraries/models/requirements.txt b/libraries/models/requirements.txt index 8406288fd..e69de29bb 100644 --- a/libraries/models/requirements.txt +++ b/libraries/models/requirements.txt @@ -1,3 +0,0 @@ -pydantic >= 2 -typing-extensions >= 4.7.2 -pyhumps >= 3.8.0 \ No newline at end of file diff --git a/libraries/models/setup.cfg b/libraries/models/setup.cfg deleted file mode 100644 index 11433ee87..000000000 --- a/libraries/models/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[flake8] -max-line-length=99 diff --git a/libraries/models/setup.py b/libraries/models/setup.py index 767db408b..e2171e3fc 100644 --- a/libraries/models/setup.py +++ b/libraries/models/setup.py @@ -8,26 +8,16 @@ HERE = dn(realpath(__file__)) NAME = "cloudharness_model" -VERSION = "3.0.0" +VERSION = "2.5.0" REQUIREMENTS = [ - "pydantic >= 2", - "typing-extensions >= 4.7.1", - "pyhumps >= 3.8.0" + "Jinja2 >= 3.1.3", + "oyaml >= 1.0", + "psutil >= 5.9.4", + "pyhumps >= 3.8.0", + "python-dateutil >= 2.8.2", + "PyYAML >= 6.0.1", + "six >= 1.16.0" ] - -setup( - name=NAME, - version=VERSION, - description="CloudHarness model definitions", - author_email="cloudharness@metacell.us", - url="", - keywords=["CloudHarness", "models", "pydantic"], - install_requires=REQUIREMENTS, - packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]), - include_package_data=True, - package_data={'cloudharness_model': ['py.typed']}, - long_description="""\ - CloudHarness model library - Pure model definitions and utilities - """, - python_requires=">=3.7", -) +print(REQUIREMENTS) +setup(name=NAME, version=VERSION, + install_requires=REQUIREMENTS, packages=find_packages(),) diff --git a/libraries/models/test-requirements.txt b/libraries/models/test-requirements.txt index 5bc5ac9c9..58f51d6a0 100644 --- a/libraries/models/test-requirements.txt +++ b/libraries/models/test-requirements.txt @@ -1,6 +1,4 @@ -pytest~=7.1.3 +pytest~=7.1.0 pytest-cov>=2.8.1 -pytest-randomly>=3.12.0 -mypy>=1.4.1 -types-python-dateutil>=2.8.19 -oyaml \ No newline at end of file +pytest-randomly>=1.2.3 +Flask-Testing==0.8.1 diff --git a/libraries/models/test/resources/values.yaml b/libraries/models/test/resources/values.yaml index 6a45d9b69..d6f58cd80 100644 --- a/libraries/models/test/resources/values.yaml +++ b/libraries/models/test/resources/values.yaml @@ -8,7 +8,7 @@ mainapp: myapp registry: name: reg/ secret: null -tag: "1" +tag: 1 apps: accounts: harness: @@ -25,11 +25,11 @@ apps: roles: - administrator deployment: - auto: false + auto: overridden replicas: 1 image: reg/cloudharness/accounts:1 name: accounts - port: "80" + port: overridden resources: &id001 requests: memory: 512Mi @@ -131,9 +131,9 @@ apps: task-images: {} common: true a: dev - autodeploy: false + autodeploy: overridden name: accounts - port: "80" + port: overridden testlist: - a: 1 - a: 2 @@ -251,7 +251,7 @@ apps: memory: 500Mi cpu: 500m test: - api: {autotest: true, enabled: true, checks: []} + api: {autotest: true, enabled: true} e2e: {enabled: true, smoketest: true} unit: commands: ["pytest samples/test"] @@ -426,7 +426,7 @@ apps: roles: - administrator deployment: - auto: false + auto: legacy replicas: 1 image: null name: legacy @@ -582,9 +582,9 @@ apps: resources: *id006 env: - name: CH_VERSION - value: "0.0.1" + value: 0.0.1 - name: CH_CHART_VERSION - value: "0.0.1" + value: 0.0.1 - name: CH_ACCOUNTS_SUBDOMAIN value: accounts - name: CH_ACCOUNTS_NAME @@ -596,7 +596,7 @@ env: - name: CH_SAMPLES_SUBDOMAIN value: samples - name: CH_SAMPLES_PORT - value: "80" + value: 80 - name: CH_SAMPLES_NAME value: samples - name: CH_WORKFLOWS_SUBDOMAIN @@ -616,7 +616,7 @@ env: - name: CH_IMAGE_REGISTRY value: reg/ - name: CH_IMAGE_TAG - value: "1" + value: 1 privenv: - name: CH_SECRET value: "In God we trust; all others must bring data. \u2015 W. Edwards Deming" diff --git a/libraries/models/test/test_deserialize.py b/libraries/models/test/test_deserialize.py index 4a856df83..6c27244c5 100644 --- a/libraries/models/test/test_deserialize.py +++ b/libraries/models/test/test_deserialize.py @@ -29,9 +29,6 @@ def test_helm_values_deserialize(): app = ApplicationConfig.from_dict(values["apps"]["samples"]) assert type(app.harness.test) == ApplicationTestConfig - assert getattr(app.harness.database, "pass") == "metacell" - assert app.harness.database["pass"] == "metacell" - def test_camelcase(): u = User().from_dict(dict(lastName="a")) assert u.last_name == "a" @@ -39,7 +36,7 @@ def test_camelcase(): def test_robustness(): d = {'aliases': [], 'database': {'auto': True, 'mongo': {'image': 'mongo:5', 'ports': [{'name': 'http', 'port': 27017}]}, 'name': 'keycloak-postgres', 'neo4j': {'dbms_security_auth_enabled': 'false', 'image': 'neo4j:4.1.9', 'memory': {'heap': {'initial': '64M', 'max': '128M'}, 'pagecache': {'size': '64M'}, 'size': '256M'}, 'ports': [{'name': 'http', 'port': 7474}, {'name': 'bolt', 'port': 7687}]}, 'pass': 'password', 'postgres': {'image': 'postgres:10.4', 'initialdb': 'auth_db', 'ports': [{'name': 'http', 'port': 5432}]}, 'resources': {'limits': {'cpu': '1000m', 'memory': '2Gi'}, 'requests': {'cpu': '100m', 'memory': '512Mi'}}, 'size': '2Gi', 'type': 'postgres', 'user': 'user'}, 'dependencies': {'build': [], 'hard': [], 'soft': []}, 'deployment': {'auto': True, 'image': 'osb/accounts:3e02a15477b4696ed554e08cedf4109c67908cbe6b03331072b5b73e83b4fc2b', 'name': 'accounts', 'port': 8080, 'replicas': 1, 'resources': {'limits': {'cpu': '500m', 'memory': '1024Mi'}, 'requests': {'cpu': '10m', 'memory': '512Mi'}}}, 'domain': None, 'env': [{'name': 'KEYCLOAK_IMPORT', 'value': '/tmp/realm.json'}, - {'name': 'KEYCLOAK_USER', 'value': 'admin'}, {'name': 'KEYCLOAK_PASSWORD', 'value': 'metacell'}, {'name': 'PROXY_ADDRESS_FORWARDING', 'value': 'true'}, {'name': 'DB_VENDOR', 'value': 'POSTGRES'}, {'name': 'DB_ADDR', 'value': 'keycloak-postgres'}, {'name': 'DB_DATABASE', 'value': 'auth_db'}, {'name': 'DB_USER', 'value': 'user'}, {'name': 'DB_PASSWORD', 'value': 'password'}, {'name': 'JAVA_OPTS', 'value': '-server -Xms64m -Xmx896m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true --add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED --add-exports=jdk.unsupported/sun.reflect=ALL-UNNAMED'}], 'name': 'accounts', 'readinessProbe': {'path': '/realms/master'}, 'resources': [{'dst': '/tmp/realm.json', 'name': 'realm-config', 'src': 'realm.json'}], 'secrets': {}, 'secured': False, 'service': {'auto': True, 'name': 'accounts', 'port': 8080}, 'subdomain': 'accounts', 'uri_role_mapping': [{'roles': ['administrator'], 'uri': '/*'}], 'use_services': []} + {'name': 'KEYCLOAK_USER', 'value': 'admin'}, {'name': 'KEYCLOAK_PASSWORD', 'value': 'metacell'}, {'name': 'PROXY_ADDRESS_FORWARDING', 'value': 'true'}, {'name': 'DB_VENDOR', 'value': 'POSTGRES'}, {'name': 'DB_ADDR', 'value': 'keycloak-postgres'}, {'name': 'DB_DATABASE', 'value': 'auth_db'}, {'name': 'DB_USER', 'value': 'user'}, {'name': 'DB_PASSWORD', 'value': 'password'}, {'name': 'JAVA_OPTS', 'value': '-server -Xms64m -Xmx896m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true --add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED --add-exports=jdk.unsupported/sun.reflect=ALL-UNNAMED'}], 'name': 'accounts', 'readinessProbe': {'path': '/realms/master'}, 'resources': [{'dst': '/tmp/realm.json', 'name': 'realm-config', 'src': 'realm.json'}], 'secrets': '', 'secured': False, 'service': {'auto': True, 'name': 'accounts', 'port': 8080}, 'subdomain': 'accounts', 'uri_role_mapping': [{'roles': ['administrator'], 'uri': '/*'}], 'use_services': []} app = ApplicationHarnessConfig.from_dict(d) @@ -68,97 +65,6 @@ def test_robustness(): e = CDCEvent.from_dict(cdc) - app_dict = {'admin': {'pass': 'metacell', 'role': 'administrator', 'user': 'admin'}, 'client': {'id': 'rest-client', 'secret': '5678eb6e-9e2c-4ee5-bd54-34e7411339e8'}, 'enabled': True, 'harness': {'aliases': [], 'database': {'auto': True, 'mongo': {'image': 'mongo:5', 'ports': [{'name': 'http', 'port': 27017}]}, 'name': 'keycloak-postgres', 'neo4j': {'dbms_security_auth_enabled': 'false', 'image': 'neo4j:4.1.9', 'memory': {'heap': {'initial': '64M', 'max': '128M'}, 'pagecache': {'size': '64M'}, 'size': '256M'}, 'ports': [{'name': 'http', 'port': 7474}, {'name': 'bolt', 'port': 7687}]}, 'pass': 'password', 'postgres': {'image': 'postgres:10.4', 'initialdb': 'auth_db', 'ports': [{'name': 'http', 'port': 5432}]}, 'resources': {'limits': {'cpu': '1000m', 'memory': '2Gi'}, 'requests': {'cpu': '100m', 'memory': '512Mi'}}, 'size': '2Gi', 'type': 'postgres', 'user': 'user'}, 'dependencies': {'build': [], 'hard': [], 'soft': []}, 'deployment': {'auto': True, 'image': 'osb/accounts:3e02a15477b4696ed554e08cedf4109c67908cbe6b03331072b5b73e83b4fc2b', 'name': 'accounts', 'port': 8080, 'replicas': 1, 'resources': {'limits': {'cpu': '500m', 'memory': '1024Mi'}, 'requests': {'cpu': '10m', 'memory': '512Mi'}}}, 'domain': None, 'env': [{'name': 'KEYCLOAK_IMPORT', 'value': '/tmp/realm.json'}, {'name': 'KEYCLOAK_USER', 'value': 'admin'}, {'name': 'KEYCLOAK_PASSWORD', 'value': 'metacell'}, {'name': 'PROXY_ADDRESS_FORWARDING', 'value': 'true'}, {'name': 'DB_VENDOR', 'value': 'POSTGRES'}, {'name': 'DB_ADDR', 'value': 'keycloak-postgres'}, {'name': 'DB_DATABASE', 'value': 'auth_db'}, {'name': 'DB_USER', 'value': 'user'}, {'name': 'DB_PASSWORD', 'value': 'password'}, {'name': 'JAVA_OPTS', 'value': '-server -Xms64m -Xmx896m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true --add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED --add-exports=jdk.unsupported/sun.reflect=ALL-UNNAMED'}], 'name': 'accounts', 'readinessProbe': {'path': '/realms/master'}, 'resources': [{'dst': '/tmp/realm.json', 'name': 'realm-config', 'src': 'realm.json'}], 'secrets': {}, 'secured': False, 'service': {'auto': True, 'name': 'accounts', 'port': 8080}, 'subdomain': 'accounts', 'uri_role_mapping': [{'roles': ['administrator'], 'uri': '/*'}], 'use_services': []}, 'harvest': True, 'image': 'osb/accounts:latest', 'name': 'accounts', 'port': 8080, 'resources': {'limits': {'cpu': '500m', 'memory': '1024Mi'}, 'requests': {'cpu': '10m', 'memory': '512Mi'}}, 'task-images': {}, 'webclient': {'id': 'web-client', 'secret': '452952ae-922c-4766-b912-7b106271e34b'}} - - app = ApplicationConfig.from_dict(app_dict) - assert app.admin.get("pass") == "metacell" - - -def test_property_access(): - """Test that properties work correctly with CloudHarnessBaseModel inheritance""" - from cloudharness_model.base_model import CloudHarnessBaseModel - - class TestModelWithProperties(CloudHarnessBaseModel): - name: str = "test" - _internal_data: dict = {} - additional_properties: dict = {} - - @property - def computed_value(self): - """A property that returns a computed value""" - return f"computed_{self.name}" - - @computed_value.setter - def computed_value(self, value): - if value.startswith("computed_"): - self.name = value[9:] - else: - self.name = value - - @property - def data_dict(self): - """A property that returns a dictionary""" - return {"key": "value", "nested": {"inner": "data"}} - - @property - def internal_data(self): - """A property that accesses internal state""" - return self._internal_data - - @internal_data.setter - def internal_data(self, value): - self._internal_data = value - - # Create test instance - model = TestModelWithProperties(name="test") - - # Test property getter - assert model.computed_value == "computed_test" - - # Test property setter - model.computed_value = "computed_newname" - assert model.name == "newname" - assert model.computed_value == "computed_newname" - - # Test property that returns dict (should NOT be converted to AttrDict) - data = model.data_dict - assert isinstance(data, dict) - assert not hasattr(data, 'nested') # Should not have attribute access - assert data["nested"]["inner"] == "data" # Should work as regular dict - - # Test property that accesses internal state - model.internal_data = {"test": "value"} - retrieved = model.internal_data - assert isinstance(retrieved, dict) - assert retrieved["test"] == "value" - - # Test that monkey patch functionality still works - model.additional_properties["custom"] = {"nested": {"key": "value"}} - - # Access through __getattr__ should convert to AttrDict - custom = model.custom - assert hasattr(custom, 'nested') # Should have AttrDict attribute access - assert custom.nested.key == "value" - - # Test camelCase access - model.additional_properties["camelCaseKey"] = "camelValue" - assert model.camel_case_key == "camelValue" - - # Test __getitem__ access - assert model["name"] == "newname" - assert model["custom"]["nested"]["key"] == "value" - - # Test get() method - assert model.get("name") == "newname" - assert model.get("nonexistent", "default") == "default" - - # Test __contains__ - assert "name" in model - assert "custom" in model - assert "nonexistent" not in model - - print("All property access tests passed!") - + app = {'admin': {'pass': 'metacell', 'role': 'administrator', 'user': 'admin'}, 'client': {'id': 'rest-client', 'secret': '5678eb6e-9e2c-4ee5-bd54-34e7411339e8'}, 'enabled': True, 'harness': {'aliases': [], 'database': {'auto': True, 'mongo': {'image': 'mongo:5', 'ports': [{'name': 'http', 'port': 27017}]}, 'name': 'keycloak-postgres', 'neo4j': {'dbms_security_auth_enabled': 'false', 'image': 'neo4j:4.1.9', 'memory': {'heap': {'initial': '64M', 'max': '128M'}, 'pagecache': {'size': '64M'}, 'size': '256M'}, 'ports': [{'name': 'http', 'port': 7474}, {'name': 'bolt', 'port': 7687}]}, 'pass': 'password', 'postgres': {'image': 'postgres:10.4', 'initialdb': 'auth_db', 'ports': [{'name': 'http', 'port': 5432}]}, 'resources': {'limits': {'cpu': '1000m', 'memory': '2Gi'}, 'requests': {'cpu': '100m', 'memory': '512Mi'}}, 'size': '2Gi', 'type': 'postgres', 'user': 'user'}, 'dependencies': {'build': [], 'hard': [], 'soft': []}, 'deployment': {'auto': True, 'image': 'osb/accounts:3e02a15477b4696ed554e08cedf4109c67908cbe6b03331072b5b73e83b4fc2b', 'name': 'accounts', 'port': 8080, 'replicas': 1, 'resources': {'limits': {'cpu': '500m', 'memory': '1024Mi'}, 'requests': {'cpu': '10m', 'memory': '512Mi'}}}, 'domain': None, 'env': [{'name': 'KEYCLOAK_IMPORT', 'value': '/tmp/realm.json'}, {'name': 'KEYCLOAK_USER', 'value': 'admin'}, {'name': 'KEYCLOAK_PASSWORD', 'value': 'metacell'}, {'name': 'PROXY_ADDRESS_FORWARDING', 'value': 'true'}, {'name': 'DB_VENDOR', 'value': 'POSTGRES'}, {'name': 'DB_ADDR', 'value': 'keycloak-postgres'}, {'name': 'DB_DATABASE', 'value': 'auth_db'}, {'name': 'DB_USER', 'value': 'user'}, {'name': 'DB_PASSWORD', 'value': 'password'}, {'name': 'JAVA_OPTS', 'value': '-server -Xms64m -Xmx896m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true --add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED --add-exports=jdk.unsupported/sun.reflect=ALL-UNNAMED'}], 'name': 'accounts', 'readinessProbe': {'path': '/realms/master'}, 'resources': [{'dst': '/tmp/realm.json', 'name': 'realm-config', 'src': 'realm.json'}], 'secrets': '', 'secured': False, 'service': {'auto': True, 'name': 'accounts', 'port': 8080}, 'subdomain': 'accounts', 'uri_role_mapping': [{'roles': ['administrator'], 'uri': '/*'}], 'use_services': []}, 'harvest': True, 'image': 'osb/accounts:latest', 'name': 'accounts', 'port': 8080, 'resources': {'limits': {'cpu': '500m', 'memory': '1024Mi'}, 'requests': {'cpu': '10m', 'memory': '512Mi'}}, 'task-images': {}, 'webclient': {'id': 'web-client', 'secret': '452952ae-922c-4766-b912-7b106271e34b'}} -if __name__ == "__main__": - test_property_access() \ No newline at end of file + ApplicationConfig.from_dict(app) \ No newline at end of file diff --git a/libraries/models/tox.ini b/libraries/models/tox.ini index 35b63dfc2..132efa3e2 100644 --- a/libraries/models/tox.ini +++ b/libraries/models/tox.ini @@ -1,9 +1,11 @@ [tox] envlist = py3 +skipsdist=True [testenv] deps=-r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt + {toxinidir} commands= pytest --cov=cloudharness_model diff --git a/test/test-e2e/Dockerfile b/test/test-e2e/Dockerfile index 1b1742797..4630caed6 100644 --- a/test/test-e2e/Dockerfile +++ b/test/test-e2e/Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/puppeteer/puppeteer:24 +FROM ghcr.io/puppeteer/puppeteer:23 USER root RUN mkdir -p /home/test diff --git a/test/test-e2e/jest.config.js b/test/test-e2e/jest.config.js index c7e1282b3..c23a0c8be 100644 --- a/test/test-e2e/jest.config.js +++ b/test/test-e2e/jest.config.js @@ -1,5 +1,4 @@ module.exports = { - preset: "ts-jest", testEnvironment: "node", roots: [".", process.env.APP], testMatch: ["**__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[tj]s?(x)"], @@ -7,6 +6,6 @@ module.exports = { "testSequencer": "./testSequencer.js", setupFilesAfterEnv: ["./jest.setup.js"], transform: { - "^.+\\.tsx?$": ["ts-jest", {}] + "^.+\\.tsx?$": "ts-jest" } }; \ No newline at end of file diff --git a/test/test-e2e/package-lock.json b/test/test-e2e/package-lock.json deleted file mode 100644 index 82f9e83e7..000000000 --- a/test/test-e2e/package-lock.json +++ /dev/null @@ -1,6034 +0,0 @@ -{ - "name": "cloudharness-e2e-test", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "cloudharness-e2e-test", - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "jest": "^30.2.0", - "puppeteer": "^24.0.0", - "ts-jest": "^27.0.3", - "typescript": "^4.6.4" - }, - "devDependencies": { - "@types/jest": "26.0.24", - "@types/node": "13.13.52", - "@types/puppeteer": "3.0.8", - "husky": "6.0.0", - "lint-staged": "10.5.4", - "prettier": "2.6.2", - "tslint": "^5.8.0", - "tslint-config-prettier": "1.18.0", - "tslint-plugin-prettier": "2.3.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", - "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", - "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helpers": "^7.28.4", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.5", - "@babel/types": "^7.28.5", - "@jridgewell/remapping": "^2.3.5", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", - "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", - "license": "MIT", - "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.5" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", - "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", - "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", - "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", - "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.5", - "debug": "^4.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "license": "MIT" - }, - "node_modules/@emnapi/core": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.1.tgz", - "integrity": "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==", - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.1.0", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/core/node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD", - "optional": true - }, - "node_modules/@emnapi/runtime": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz", - "integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime/node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD", - "optional": true - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", - "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads/node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD", - "optional": true - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "license": "ISC", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.2.0.tgz", - "integrity": "sha512-+O1ifRjkvYIkBqASKWgLxrpEhQAAE7hY77ALLUufSk5717KfOShg6IbqLmdsLMPdUiFvA2kTs0R7YZy+l0IzZQ==", - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "jest-message-util": "30.2.0", - "jest-util": "30.2.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/core": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.2.0.tgz", - "integrity": "sha512-03W6IhuhjqTlpzh/ojut/pDB2LPRygyWX8ExpgHtQA8H/3K7+1vKmcINx5UzeOX1se6YEsBsOHQ1CRzf3fOwTQ==", - "license": "MIT", - "dependencies": { - "@jest/console": "30.2.0", - "@jest/pattern": "30.0.1", - "@jest/reporters": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", - "@types/node": "*", - "ansi-escapes": "^4.3.2", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "exit-x": "^0.2.2", - "graceful-fs": "^4.2.11", - "jest-changed-files": "30.2.0", - "jest-config": "30.2.0", - "jest-haste-map": "30.2.0", - "jest-message-util": "30.2.0", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.2.0", - "jest-resolve-dependencies": "30.2.0", - "jest-runner": "30.2.0", - "jest-runtime": "30.2.0", - "jest-snapshot": "30.2.0", - "jest-util": "30.2.0", - "jest-validate": "30.2.0", - "jest-watcher": "30.2.0", - "micromatch": "^4.0.8", - "pretty-format": "30.2.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/diff-sequences": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", - "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/environment": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz", - "integrity": "sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==", - "license": "MIT", - "dependencies": { - "@jest/fake-timers": "30.2.0", - "@jest/types": "30.2.0", - "@types/node": "*", - "jest-mock": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/expect": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.2.0.tgz", - "integrity": "sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==", - "license": "MIT", - "dependencies": { - "expect": "30.2.0", - "jest-snapshot": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/expect-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz", - "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==", - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz", - "integrity": "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==", - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@sinonjs/fake-timers": "^13.0.0", - "@types/node": "*", - "jest-message-util": "30.2.0", - "jest-mock": "30.2.0", - "jest-util": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/get-type": { - "version": "30.1.0", - "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", - "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.2.0.tgz", - "integrity": "sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==", - "license": "MIT", - "dependencies": { - "@jest/environment": "30.2.0", - "@jest/expect": "30.2.0", - "@jest/types": "30.2.0", - "jest-mock": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/pattern": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", - "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.0.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.2.0.tgz", - "integrity": "sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ==", - "license": "MIT", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", - "@jridgewell/trace-mapping": "^0.3.25", - "@types/node": "*", - "chalk": "^4.1.2", - "collect-v8-coverage": "^1.0.2", - "exit-x": "^0.2.2", - "glob": "^10.3.10", - "graceful-fs": "^4.2.11", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^5.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "30.2.0", - "jest-util": "30.2.0", - "jest-worker": "30.2.0", - "slash": "^3.0.0", - "string-length": "^4.0.2", - "v8-to-istanbul": "^9.0.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/reporters/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@jest/reporters/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@jest/reporters/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/snapshot-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.2.0.tgz", - "integrity": "sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==", - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "natural-compare": "^1.4.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/source-map": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz", - "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==", - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "callsites": "^3.1.0", - "graceful-fs": "^4.2.11" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/test-result": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.2.0.tgz", - "integrity": "sha512-RF+Z+0CCHkARz5HT9mcQCBulb1wgCP3FBvl9VFokMX27acKphwyQsNuWH3c+ojd1LeWBLoTYoxF0zm6S/66mjg==", - "license": "MIT", - "dependencies": { - "@jest/console": "30.2.0", - "@jest/types": "30.2.0", - "@types/istanbul-lib-coverage": "^2.0.6", - "collect-v8-coverage": "^1.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.2.0.tgz", - "integrity": "sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q==", - "license": "MIT", - "dependencies": { - "@jest/test-result": "30.2.0", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz", - "integrity": "sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.27.4", - "@jest/types": "30.2.0", - "@jridgewell/trace-mapping": "^0.3.25", - "babel-plugin-istanbul": "^7.0.1", - "chalk": "^4.1.2", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", - "jest-regex-util": "30.0.1", - "jest-util": "30.2.0", - "micromatch": "^4.0.8", - "pirates": "^4.0.7", - "slash": "^3.0.0", - "write-file-atomic": "^5.0.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", - "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/types/node_modules/@types/yargs": { - "version": "17.0.35", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", - "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", - "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.10.0" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@pkgr/core": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", - "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/pkgr" - } - }, - "node_modules/@puppeteer/browsers": { - "version": "2.10.13", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.10.13.tgz", - "integrity": "sha512-a9Ruw3j3qlnB5a/zHRTkruppynxqaeE4H9WNj5eYGRWqw0ZauZ23f4W2ARf3hghF5doozyD+CRtt7XSYuYRI/Q==", - "license": "Apache-2.0", - "dependencies": { - "debug": "^4.4.3", - "extract-zip": "^2.0.1", - "progress": "^2.0.3", - "proxy-agent": "^6.5.0", - "semver": "^7.7.3", - "tar-fs": "^3.1.1", - "yargs": "^17.7.2" - }, - "bin": { - "browsers": "lib/cjs/main-cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "license": "MIT" - }, - "node_modules/@sinonjs/commons": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "13.0.5", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", - "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^3.0.1" - } - }, - "node_modules/@tootallnate/quickjs-emscripten": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", - "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", - "license": "MIT" - }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", - "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@tybys/wasm-util/node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD", - "optional": true - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", - "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.2" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "26.0.24", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.24.tgz", - "integrity": "sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-diff": "^26.0.0", - "pretty-format": "^26.0.0" - } - }, - "node_modules/@types/jest/node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@types/jest/node_modules/@types/node": { - "version": "24.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", - "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~7.16.0" - } - }, - "node_modules/@types/jest/node_modules/diff-sequences": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", - "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@types/jest/node_modules/jest-diff": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", - "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^26.6.2", - "jest-get-type": "^26.3.0", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@types/jest/node_modules/jest-get-type": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", - "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@types/jest/node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@types/jest/node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "13.13.52", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz", - "integrity": "sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==", - "license": "MIT" - }, - "node_modules/@types/parse-json": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", - "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/puppeteer": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-3.0.8.tgz", - "integrity": "sha512-YmaPF3KLyDNJfTMlbONOWsAfUh9j0up8xA1G/uyz4c8yD80C2VUM5OTjf+sAS89EN6A6gas0oEzJThICf4OUpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/puppeteer/node_modules/@types/node": { - "version": "24.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", - "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~7.16.0" - } - }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "license": "MIT" - }, - "node_modules/@types/yargs": { - "version": "15.0.20", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.20.tgz", - "integrity": "sha512-KIkX+/GgfFitlASYCGoSF+T4XRXhOubJLhkLVtSfsRTe9jWMmuM2g28zQ41BtPTG7TRBb2xHW+LCNVE9QR/vsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "license": "MIT" - }, - "node_modules/@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yauzl/node_modules/@types/node": { - "version": "24.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", - "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "undici-types": "~7.16.0" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", - "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", - "license": "ISC" - }, - "node_modules/@unrs/resolver-binding-android-arm-eabi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", - "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-android-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", - "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", - "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", - "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", - "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", - "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", - "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", - "cpu": [ - "arm" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", - "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", - "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", - "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", - "cpu": [ - "ppc64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", - "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", - "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", - "cpu": [ - "riscv64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", - "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", - "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-linux-x64-musl": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", - "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", - "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", - "cpu": [ - "wasm32" - ], - "license": "MIT", - "optional": true, - "dependencies": { - "@napi-rs/wasm-runtime": "^0.2.11" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", - "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", - "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", - "cpu": [ - "ia32" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", - "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/agent-base": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", - "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/ast-types": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ast-types/node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/b4a": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", - "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", - "license": "Apache-2.0", - "peerDependencies": { - "react-native-b4a": "*" - }, - "peerDependenciesMeta": { - "react-native-b4a": { - "optional": true - } - } - }, - "node_modules/babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - } - }, - "node_modules/babel-code-frame/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/babel-code-frame/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/babel-code-frame/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/babel-code-frame/node_modules/js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", - "dev": true, - "license": "MIT" - }, - "node_modules/babel-code-frame/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/babel-code-frame/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/babel-jest": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz", - "integrity": "sha512-0YiBEOxWqKkSQWL9nNGGEgndoeL0ZpWrbLMNL5u/Kaxrli3Eaxlt3ZtIDktEvXt4L/R9r3ODr2zKwGM/2BjxVw==", - "license": "MIT", - "dependencies": { - "@jest/transform": "30.2.0", - "@types/babel__core": "^7.20.5", - "babel-plugin-istanbul": "^7.0.1", - "babel-preset-jest": "30.2.0", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "slash": "^3.0.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.11.0 || ^8.0.0-0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", - "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", - "license": "BSD-3-Clause", - "workspaces": [ - "test/babel-8" - ], - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-instrument": "^6.0.2", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.2.0.tgz", - "integrity": "sha512-ftzhzSGMUnOzcCXd6WHdBGMyuwy15Wnn0iyyWGKgBDLxf9/s5ABuraCSpBX2uG0jUg4rqJnxsLc5+oYBqoxVaA==", - "license": "MIT", - "dependencies": { - "@types/babel__core": "^7.20.5" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", - "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", - "license": "MIT", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.12.13", - "@babel/plugin-syntax-class-static-block": "^7.14.5", - "@babel/plugin-syntax-import-attributes": "^7.24.7", - "@babel/plugin-syntax-import-meta": "^7.10.4", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-private-property-in-object": "^7.14.5", - "@babel/plugin-syntax-top-level-await": "^7.14.5" - }, - "peerDependencies": { - "@babel/core": "^7.0.0 || ^8.0.0-0" - } - }, - "node_modules/babel-preset-jest": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.2.0.tgz", - "integrity": "sha512-US4Z3NOieAQumwFnYdUWKvUKh8+YSnS/gB3t6YBiz0bskpu7Pine8pPCheNxlPEW4wnUkma2a94YuW2q3guvCQ==", - "license": "MIT", - "dependencies": { - "babel-plugin-jest-hoist": "30.2.0", - "babel-preset-current-node-syntax": "^1.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.11.0 || ^8.0.0-beta.1" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/bare-events": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", - "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", - "license": "Apache-2.0", - "peerDependencies": { - "bare-abort-controller": "*" - }, - "peerDependenciesMeta": { - "bare-abort-controller": { - "optional": true - } - } - }, - "node_modules/bare-fs": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.5.1.tgz", - "integrity": "sha512-zGUCsm3yv/ePt2PHNbVxjjn0nNB1MkIaR4wOCxJ2ig5pCf5cCVAYJXVhQg/3OhhJV6DB1ts7Hv0oUaElc2TPQg==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "bare-events": "^2.5.4", - "bare-path": "^3.0.0", - "bare-stream": "^2.6.4", - "bare-url": "^2.2.2", - "fast-fifo": "^1.3.2" - }, - "engines": { - "bare": ">=1.16.0" - }, - "peerDependencies": { - "bare-buffer": "*" - }, - "peerDependenciesMeta": { - "bare-buffer": { - "optional": true - } - } - }, - "node_modules/bare-os": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.2.tgz", - "integrity": "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==", - "license": "Apache-2.0", - "optional": true, - "engines": { - "bare": ">=1.14.0" - } - }, - "node_modules/bare-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", - "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "bare-os": "^3.0.1" - } - }, - "node_modules/bare-stream": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.7.0.tgz", - "integrity": "sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "streamx": "^2.21.0" - }, - "peerDependencies": { - "bare-buffer": "*", - "bare-events": "*" - }, - "peerDependenciesMeta": { - "bare-buffer": { - "optional": true - }, - "bare-events": { - "optional": true - } - } - }, - "node_modules/bare-url": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.3.2.tgz", - "integrity": "sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "bare-path": "^3.0.0" - } - }, - "node_modules/baseline-browser-mapping": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.29.tgz", - "integrity": "sha512-sXdt2elaVnhpDNRDz+1BDx1JQoJRuNk7oVlAlbGiFkLikHCAQiccexF/9e91zVi6RCgqspl04aP+6Cnl9zRLrA==", - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.js" - } - }, - "node_modules/basic-ftp": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", - "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.28.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz", - "integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "baseline-browser-mapping": "^2.8.25", - "caniuse-lite": "^1.0.30001754", - "electron-to-chromium": "^1.5.249", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.1.4" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "license": "MIT", - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "license": "Apache-2.0", - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "license": "MIT" - }, - "node_modules/builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001755", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001755.tgz", - "integrity": "sha512-44V+Jm6ctPj7R52Na4TLi3Zri4dWUljJd+RDm+j8LtNCc/ihLCT+X1TzoOAkRETEWqjuLnh9581Tl80FvK7jVA==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/chromium-bidi": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-11.0.0.tgz", - "integrity": "sha512-cM3DI+OOb89T3wO8cpPSro80Q9eKYJ7hGVXoGS3GkDPxnYSqiv+6xwpIf6XERyJ9Tdsl09hmNmY94BkgZdVekw==", - "license": "Apache-2.0", - "dependencies": { - "mitt": "^3.0.1", - "zod": "^3.24.1" - }, - "peerDependencies": { - "devtools-protocol": "*" - } - }, - "node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cjs-module-lexer": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.1.1.tgz", - "integrity": "sha512-+CmxIZ/L2vNcEfvNtLdU0ZQ6mbq3FZnwAP2PPTiKP+1QOoKwlKlPgb8UKV0Dds7QVaMnHm+FwSft2VB0s/SLjQ==", - "license": "MIT" - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, - "license": "MIT", - "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "license": "MIT", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", - "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", - "license": "MIT" - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "license": "MIT" - }, - "node_modules/cosmiconfig": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", - "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/data-uri-to-buffer": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", - "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true, - "license": "MIT" - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/degenerator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", - "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", - "license": "MIT", - "dependencies": { - "ast-types": "^0.13.4", - "escodegen": "^2.1.0", - "esprima": "^4.0.1" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/devtools-protocol": { - "version": "0.0.1521046", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1521046.tgz", - "integrity": "sha512-vhE6eymDQSKWUXwwA37NtTTVEzjtGVfDr3pRbsWEQ5onH/Snp2c+2xZHWJJawG/0hCCJLRGt4xVtEVUVILol4w==", - "license": "BSD-3-Clause" - }, - "node_modules/diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "license": "MIT" - }, - "node_modules/electron-to-chromium": { - "version": "1.5.254", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.254.tgz", - "integrity": "sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg==", - "license": "ISC" - }, - "node_modules/emittery": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/end-of-stream": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enquirer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", - "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-colors": "^4.1.1", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/error-ex": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", - "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "license": "BSD-2-Clause", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz", - "integrity": "sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-diff": "^1.1.1", - "jest-docblock": "^21.0.0" - }, - "engines": { - "node": ">=4.0.0" - }, - "peerDependencies": { - "prettier": ">= 0.11.0" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/events-universal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", - "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", - "license": "Apache-2.0", - "dependencies": { - "bare-events": "^2.7.0" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/execa/node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/execa/node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/exit-x": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz", - "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz", - "integrity": "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==", - "license": "MIT", - "dependencies": { - "@jest/expect-utils": "30.2.0", - "@jest/get-type": "30.1.0", - "jest-matcher-utils": "30.2.0", - "jest-message-util": "30.2.0", - "jest-mock": "30.2.0", - "jest-util": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "license": "BSD-2-Clause", - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "license": "MIT" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "license": "MIT" - }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "license": "Apache-2.0", - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "license": "MIT", - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-own-enumerable-property-symbols": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz", - "integrity": "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==", - "dev": true, - "license": "ISC" - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "license": "MIT", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-uri": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", - "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", - "license": "MIT", - "dependencies": { - "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.2", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-ansi/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "license": "MIT" - }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8.12.0" - } - }, - "node_modules/husky": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz", - "integrity": "sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ==", - "dev": true, - "license": "MIT", - "bin": { - "husky": "lib/bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/import-local": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", - "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", - "license": "MIT", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ip-address": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", - "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "license": "MIT" - }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", - "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.23.9", - "@babel/parser": "^7.23.9", - "@istanbuljs/schema": "^0.1.3", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^7.5.4" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", - "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", - "license": "BSD-3-Clause", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.23", - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", - "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jest": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-30.2.0.tgz", - "integrity": "sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==", - "license": "MIT", - "dependencies": { - "@jest/core": "30.2.0", - "@jest/types": "30.2.0", - "import-local": "^3.2.0", - "jest-cli": "30.2.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.2.0.tgz", - "integrity": "sha512-L8lR1ChrRnSdfeOvTrwZMlnWV8G/LLjQ0nG9MBclwWZidA2N5FviRki0Bvh20WRMOX31/JYvzdqTJrk5oBdydQ==", - "license": "MIT", - "dependencies": { - "execa": "^5.1.1", - "jest-util": "30.2.0", - "p-limit": "^3.1.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-circus": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.2.0.tgz", - "integrity": "sha512-Fh0096NC3ZkFx05EP2OXCxJAREVxj1BcW/i6EWqqymcgYKWjyyDpral3fMxVcHXg6oZM7iULer9wGRFvfpl+Tg==", - "license": "MIT", - "dependencies": { - "@jest/environment": "30.2.0", - "@jest/expect": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "co": "^4.6.0", - "dedent": "^1.6.0", - "is-generator-fn": "^2.1.0", - "jest-each": "30.2.0", - "jest-matcher-utils": "30.2.0", - "jest-message-util": "30.2.0", - "jest-runtime": "30.2.0", - "jest-snapshot": "30.2.0", - "jest-util": "30.2.0", - "p-limit": "^3.1.0", - "pretty-format": "30.2.0", - "pure-rand": "^7.0.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.6" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-circus/node_modules/dedent": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz", - "integrity": "sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==", - "license": "MIT", - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } - } - }, - "node_modules/jest-cli": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.2.0.tgz", - "integrity": "sha512-Os9ukIvADX/A9sLt6Zse3+nmHtHaE6hqOsjQtNiugFTbKRHYIYtZXNGNK9NChseXy7djFPjndX1tL0sCTlfpAA==", - "license": "MIT", - "dependencies": { - "@jest/core": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/types": "30.2.0", - "chalk": "^4.1.2", - "exit-x": "^0.2.2", - "import-local": "^3.2.0", - "jest-config": "30.2.0", - "jest-util": "30.2.0", - "jest-validate": "30.2.0", - "yargs": "^17.7.2" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-config": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.2.0.tgz", - "integrity": "sha512-g4WkyzFQVWHtu6uqGmQR4CQxz/CH3yDSlhzXMWzNjDx843gYjReZnMRanjRCq5XZFuQrGDxgUaiYWE8BRfVckA==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.27.4", - "@jest/get-type": "30.1.0", - "@jest/pattern": "30.0.1", - "@jest/test-sequencer": "30.2.0", - "@jest/types": "30.2.0", - "babel-jest": "30.2.0", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "deepmerge": "^4.3.1", - "glob": "^10.3.10", - "graceful-fs": "^4.2.11", - "jest-circus": "30.2.0", - "jest-docblock": "30.2.0", - "jest-environment-node": "30.2.0", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.2.0", - "jest-runner": "30.2.0", - "jest-util": "30.2.0", - "jest-validate": "30.2.0", - "micromatch": "^4.0.8", - "parse-json": "^5.2.0", - "pretty-format": "30.2.0", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "peerDependencies": { - "@types/node": "*", - "esbuild-register": ">=3.4.0", - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "esbuild-register": { - "optional": true - }, - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-config/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/jest-config/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jest-config/node_modules/jest-docblock": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.2.0.tgz", - "integrity": "sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA==", - "license": "MIT", - "dependencies": { - "detect-newline": "^3.1.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-config/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jest-diff": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz", - "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==", - "license": "MIT", - "dependencies": { - "@jest/diff-sequences": "30.0.1", - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "pretty-format": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-docblock": { - "version": "21.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz", - "integrity": "sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw==", - "dev": true, - "license": "MIT" - }, - "node_modules/jest-each": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.2.0.tgz", - "integrity": "sha512-lpWlJlM7bCUf1mfmuqTA8+j2lNURW9eNafOy99knBM01i5CQeY5UH1vZjgT9071nDJac1M4XsbyI44oNOdhlDQ==", - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0", - "@jest/types": "30.2.0", - "chalk": "^4.1.2", - "jest-util": "30.2.0", - "pretty-format": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-environment-node": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.2.0.tgz", - "integrity": "sha512-ElU8v92QJ9UrYsKrxDIKCxu6PfNj4Hdcktcn0JX12zqNdqWHB0N+hwOnnBBXvjLd2vApZtuLUGs1QSY+MsXoNA==", - "license": "MIT", - "dependencies": { - "@jest/environment": "30.2.0", - "@jest/fake-timers": "30.2.0", - "@jest/types": "30.2.0", - "@types/node": "*", - "jest-mock": "30.2.0", - "jest-util": "30.2.0", - "jest-validate": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.2.0.tgz", - "integrity": "sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw==", - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "anymatch": "^3.1.3", - "fb-watchman": "^2.0.2", - "graceful-fs": "^4.2.11", - "jest-regex-util": "30.0.1", - "jest-util": "30.2.0", - "jest-worker": "30.2.0", - "micromatch": "^4.0.8", - "walker": "^1.0.8" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.3" - } - }, - "node_modules/jest-leak-detector": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.2.0.tgz", - "integrity": "sha512-M6jKAjyzjHG0SrQgwhgZGy9hFazcudwCNovY/9HPIicmNSBuockPSedAP9vlPK6ONFJ1zfyH/M2/YYJxOz5cdQ==", - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0", - "pretty-format": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz", - "integrity": "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==", - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0", - "chalk": "^4.1.2", - "jest-diff": "30.2.0", - "pretty-format": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz", - "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@jest/types": "30.2.0", - "@types/stack-utils": "^2.0.3", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "micromatch": "^4.0.8", - "pretty-format": "30.2.0", - "slash": "^3.0.0", - "stack-utils": "^2.0.6" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-mock": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz", - "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==", - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "jest-util": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "license": "MIT", - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", - "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", - "license": "MIT", - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.2.0.tgz", - "integrity": "sha512-TCrHSxPlx3tBY3hWNtRQKbtgLhsXa1WmbJEqBlTBrGafd5fiQFByy2GNCEoGR+Tns8d15GaL9cxEzKOO3GEb2A==", - "license": "MIT", - "dependencies": { - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", - "jest-pnp-resolver": "^1.2.3", - "jest-util": "30.2.0", - "jest-validate": "30.2.0", - "slash": "^3.0.0", - "unrs-resolver": "^1.7.11" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.2.0.tgz", - "integrity": "sha512-xTOIGug/0RmIe3mmCqCT95yO0vj6JURrn1TKWlNbhiAefJRWINNPgwVkrVgt/YaerPzY3iItufd80v3lOrFJ2w==", - "license": "MIT", - "dependencies": { - "jest-regex-util": "30.0.1", - "jest-snapshot": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runner": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.2.0.tgz", - "integrity": "sha512-PqvZ2B2XEyPEbclp+gV6KO/F1FIFSbIwewRgmROCMBo/aZ6J1w8Qypoj2pEOcg3G2HzLlaP6VUtvwCI8dM3oqQ==", - "license": "MIT", - "dependencies": { - "@jest/console": "30.2.0", - "@jest/environment": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "emittery": "^0.13.1", - "exit-x": "^0.2.2", - "graceful-fs": "^4.2.11", - "jest-docblock": "30.2.0", - "jest-environment-node": "30.2.0", - "jest-haste-map": "30.2.0", - "jest-leak-detector": "30.2.0", - "jest-message-util": "30.2.0", - "jest-resolve": "30.2.0", - "jest-runtime": "30.2.0", - "jest-util": "30.2.0", - "jest-watcher": "30.2.0", - "jest-worker": "30.2.0", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runner/node_modules/jest-docblock": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.2.0.tgz", - "integrity": "sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA==", - "license": "MIT", - "dependencies": { - "detect-newline": "^3.1.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runtime": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.2.0.tgz", - "integrity": "sha512-p1+GVX/PJqTucvsmERPMgCPvQJpFt4hFbM+VN3n8TMo47decMUcJbt+rgzwrEme0MQUA/R+1de2axftTHkKckg==", - "license": "MIT", - "dependencies": { - "@jest/environment": "30.2.0", - "@jest/fake-timers": "30.2.0", - "@jest/globals": "30.2.0", - "@jest/source-map": "30.0.1", - "@jest/test-result": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "cjs-module-lexer": "^2.1.0", - "collect-v8-coverage": "^1.0.2", - "glob": "^10.3.10", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", - "jest-message-util": "30.2.0", - "jest-mock": "30.2.0", - "jest-regex-util": "30.0.1", - "jest-resolve": "30.2.0", - "jest-snapshot": "30.2.0", - "jest-util": "30.2.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-runtime/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/jest-runtime/node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jest-runtime/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jest-snapshot": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.2.0.tgz", - "integrity": "sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA==", - "license": "MIT", - "dependencies": { - "@babel/core": "^7.27.4", - "@babel/generator": "^7.27.5", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/plugin-syntax-typescript": "^7.27.1", - "@babel/types": "^7.27.3", - "@jest/expect-utils": "30.2.0", - "@jest/get-type": "30.1.0", - "@jest/snapshot-utils": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", - "babel-preset-current-node-syntax": "^1.2.0", - "chalk": "^4.1.2", - "expect": "30.2.0", - "graceful-fs": "^4.2.11", - "jest-diff": "30.2.0", - "jest-matcher-utils": "30.2.0", - "jest-message-util": "30.2.0", - "jest-util": "30.2.0", - "pretty-format": "30.2.0", - "semver": "^7.7.2", - "synckit": "^0.11.8" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", - "license": "MIT", - "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-util/node_modules/picomatch": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", - "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/jest-validate": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.2.0.tgz", - "integrity": "sha512-FBGWi7dP2hpdi8nBoWxSsLvBFewKAg0+uSQwBaof4Y4DPgBabXgpSYC5/lR7VmnIlSpASmCi/ntRWPbv7089Pw==", - "license": "MIT", - "dependencies": { - "@jest/get-type": "30.1.0", - "@jest/types": "30.2.0", - "camelcase": "^6.3.0", - "chalk": "^4.1.2", - "leven": "^3.1.0", - "pretty-format": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watcher": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.2.0.tgz", - "integrity": "sha512-PYxa28dxJ9g777pGm/7PrbnMeA0Jr7osHP9bS7eJy9DuAjMgdGtxgf0uKMyoIsTWAkIbUW5hSDdJ3urmgXBqxg==", - "license": "MIT", - "dependencies": { - "@jest/test-result": "30.2.0", - "@jest/types": "30.2.0", - "@types/node": "*", - "ansi-escapes": "^4.3.2", - "chalk": "^4.1.2", - "emittery": "^0.13.1", - "jest-util": "30.2.0", - "string-length": "^4.0.2" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-worker": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz", - "integrity": "sha512-0Q4Uk8WF7BUwqXHuAjc23vmopWJw5WH7w2tqBoUOZpOjW/ZnR44GXXd1r82RvnmI2GZge3ivrYXk/BE2+VtW2g==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.2.0", - "merge-stream": "^2.0.0", - "supports-color": "^8.1.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", - "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", - "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "license": "MIT" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "license": "MIT" - }, - "node_modules/lint-staged": { - "version": "10.5.4", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.4.tgz", - "integrity": "sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "cli-truncate": "^2.1.0", - "commander": "^6.2.0", - "cosmiconfig": "^7.0.0", - "debug": "^4.2.0", - "dedent": "^0.7.0", - "enquirer": "^2.3.6", - "execa": "^4.1.0", - "listr2": "^3.2.2", - "log-symbols": "^4.0.0", - "micromatch": "^4.0.2", - "normalize-path": "^3.0.0", - "please-upgrade-node": "^3.2.0", - "string-argv": "0.3.1", - "stringify-object": "^3.3.0" - }, - "bin": { - "lint-staged": "bin/lint-staged.js" - }, - "funding": { - "url": "https://opencollective.com/lint-staged" - } - }, - "node_modules/lint-staged/node_modules/commander": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", - "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/lint-staged/node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/listr2": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz", - "integrity": "sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.16", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.5.1", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" - }, - "peerDependenciesMeta": { - "enquirer": { - "optional": true - } - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "license": "MIT" - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/log-update/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "license": "MIT", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "license": "ISC" - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "license": "BSD-3-Clause", - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "license": "MIT" - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/mitt": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", - "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", - "license": "MIT" - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/napi-postinstall": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", - "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", - "license": "MIT", - "bin": { - "napi-postinstall": "lib/cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/napi-postinstall" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "license": "MIT" - }, - "node_modules/netmask": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", - "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "license": "MIT" - }, - "node_modules/node-releases": { - "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", - "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", - "license": "MIT" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-locate/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/pac-proxy-agent": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", - "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", - "license": "MIT", - "dependencies": { - "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "get-uri": "^6.0.1", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.6", - "pac-resolver": "^7.0.1", - "socks-proxy-agent": "^8.0.5" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/pac-resolver": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", - "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", - "license": "MIT", - "dependencies": { - "degenerator": "^5.0.0", - "netmask": "^2.0.2" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "license": "BlueOak-1.0.0" - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT" - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "license": "ISC" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pirates": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", - "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/please-upgrade-node": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", - "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver-compare": "^1.0.0" - } - }, - "node_modules/prettier": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", - "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", - "license": "MIT", - "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/proxy-agent": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", - "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "http-proxy-agent": "^7.0.1", - "https-proxy-agent": "^7.0.6", - "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.1.0", - "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.5" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" - }, - "node_modules/pump": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", - "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/puppeteer": { - "version": "24.30.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.30.0.tgz", - "integrity": "sha512-A5OtCi9WpiXBQgJ2vQiZHSyrAzQmO/WDsvghqlN4kgw21PhxA5knHUaUQq/N3EMt8CcvSS0RM+kmYLJmedR3TQ==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@puppeteer/browsers": "2.10.13", - "chromium-bidi": "11.0.0", - "cosmiconfig": "^9.0.0", - "devtools-protocol": "0.0.1521046", - "puppeteer-core": "24.30.0", - "typed-query-selector": "^2.12.0" - }, - "bin": { - "puppeteer": "lib/cjs/puppeteer/node/cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/puppeteer-core": { - "version": "24.30.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.30.0.tgz", - "integrity": "sha512-2S3Smy0t0W4wJnNvDe7W0bE7wDmZjfZ3ljfMgJd6hn2Hq/f0jgN+x9PULZo2U3fu5UUIJ+JP8cNUGllu8P91Pg==", - "license": "Apache-2.0", - "dependencies": { - "@puppeteer/browsers": "2.10.13", - "chromium-bidi": "11.0.0", - "debug": "^4.4.3", - "devtools-protocol": "0.0.1521046", - "typed-query-selector": "^2.12.0", - "webdriver-bidi-protocol": "0.3.8", - "ws": "^8.18.3" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/puppeteer/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/puppeteer/node_modules/cosmiconfig": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", - "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.1", - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/puppeteer/node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/pure-rand": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz", - "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/dubzzz" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fast-check" - } - ], - "license": "MIT" - }, - "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "license": "MIT" - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.11", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", - "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true, - "license": "MIT" - }, - "node_modules/rxjs": { - "version": "7.8.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", - "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/rxjs/node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, - "license": "0BSD" - }, - "node_modules/semver": { - "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "dev": true, - "license": "MIT" - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "license": "MIT", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks": { - "version": "2.8.7", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", - "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", - "license": "MIT", - "dependencies": { - "ip-address": "^10.0.1", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "8.0.5", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", - "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "socks": "^2.8.3" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "license": "BSD-3-Clause" - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/streamx": { - "version": "2.23.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", - "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", - "license": "MIT", - "dependencies": { - "events-universal": "^1.0.0", - "fast-fifo": "^1.3.2", - "text-decoder": "^1.1.0" - } - }, - "node_modules/string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.6.19" - } - }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "license": "MIT", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/stringify-object": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", - "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "get-own-enumerable-property-symbols": "^3.0.0", - "is-obj": "^1.0.1", - "is-regexp": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/synckit": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz", - "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==", - "license": "MIT", - "dependencies": { - "@pkgr/core": "^0.2.9" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/synckit" - } - }, - "node_modules/tar-fs": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", - "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", - "license": "MIT", - "dependencies": { - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - }, - "optionalDependencies": { - "bare-fs": "^4.0.1", - "bare-path": "^3.0.0" - } - }, - "node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "license": "MIT", - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-decoder": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", - "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", - "license": "Apache-2.0", - "dependencies": { - "b4a": "^1.6.4" - } - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true, - "license": "MIT" - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "license": "BSD-3-Clause" - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/ts-jest": { - "version": "27.0.3", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.0.3.tgz", - "integrity": "sha512-U5rdMjnYam9Ucw+h0QvtNDbc5+88nxt7tbIvqaZUhFrfG4+SkWhMXjejCLVGcpILTPuV+H3W/GZDZrnZFpPeXw==", - "license": "MIT", - "dependencies": { - "bs-logger": "0.x", - "buffer-from": "1.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^27.0.0", - "json5": "2.x", - "lodash": "4.x", - "make-error": "1.x", - "mkdirp": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "jest": "^27.0.0", - "typescript": ">=3.8 <5.0" - } - }, - "node_modules/ts-jest/node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/ts-jest/node_modules/@types/yargs": { - "version": "16.0.11", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.11.tgz", - "integrity": "sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==", - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/ts-jest/node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-jest/node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/ts-jest/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true, - "license": "0BSD" - }, - "node_modules/tslint": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz", - "integrity": "sha512-2OBP2yqyQ5IsUfCqkhMzT0Knv2a7YMXZizhnSgTiRZulCzUuZcL8FEm2Djoytr5HakyemWbfWyf/U/YoMXccWA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "babel-code-frame": "^6.22.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.1.0", - "commander": "^2.9.0", - "diff": "^3.2.0", - "glob": "^7.1.1", - "minimatch": "^3.0.4", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.7.1", - "tsutils": "^2.12.1" - }, - "bin": { - "tslint": "bin/tslint" - }, - "engines": { - "node": ">=4.1.2" - }, - "peerDependencies": { - "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev" - } - }, - "node_modules/tslint-config-prettier": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", - "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", - "dev": true, - "license": "MIT", - "bin": { - "tslint-config-prettier-check": "bin/check.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/tslint-plugin-prettier": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tslint-plugin-prettier/-/tslint-plugin-prettier-2.3.0.tgz", - "integrity": "sha512-F9e4K03yc9xuvv+A0v1EmjcnDwpz8SpCD8HzqSDe0eyg34cBinwn9JjmnnRrNAs4HdleRQj7qijp+P/JTxt4vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-plugin-prettier": "^2.2.0", - "lines-and-columns": "^1.1.6", - "tslib": "^1.7.1" - }, - "engines": { - "node": ">= 4" - }, - "peerDependencies": { - "prettier": "^1.9.0 || ^2.0.0", - "tslint": "^5.0.0 || ^6.0.0" - } - }, - "node_modules/tslint/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslint/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslint/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/tslint/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/tslint/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/tslint/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/tslint/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^1.8.1" - }, - "peerDependencies": { - "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typed-query-selector": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz", - "integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==", - "license": "MIT" - }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/unrs-resolver": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", - "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "napi-postinstall": "^0.3.0" - }, - "funding": { - "url": "https://opencollective.com/unrs-resolver" - }, - "optionalDependencies": { - "@unrs/resolver-binding-android-arm-eabi": "1.11.1", - "@unrs/resolver-binding-android-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-arm64": "1.11.1", - "@unrs/resolver-binding-darwin-x64": "1.11.1", - "@unrs/resolver-binding-freebsd-x64": "1.11.1", - "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", - "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", - "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", - "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", - "@unrs/resolver-binding-linux-x64-musl": "1.11.1", - "@unrs/resolver-binding-wasm32-wasi": "1.11.1", - "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", - "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", - "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", - "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/v8-to-istanbul": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", - "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", - "license": "ISC", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "license": "Apache-2.0", - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/webdriver-bidi-protocol": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.3.8.tgz", - "integrity": "sha512-21Yi2GhGntMc671vNBCjiAeEVknXjVRoyu+k+9xOMShu+ZQfpGQwnBqbNz/Sv4GXZ6JmutlPAi2nIJcrymAWuQ==", - "license": "Apache-2.0" - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "node_modules/write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/write-file-atomic/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "license": "ISC" - }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zod": { - "version": "3.25.76", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", - "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - } - } -} diff --git a/test/test-e2e/package.json b/test/test-e2e/package.json index 8daded1a3..f184bb871 100644 --- a/test/test-e2e/package.json +++ b/test/test-e2e/package.json @@ -1,20 +1,20 @@ { "author": "Filippo Ledda ", "dependencies": { - "jest": "^30.2.0", - "puppeteer": "^24.0.0", - "ts-jest": "^29.2.5", + "jest": "^28.1.0", + "puppeteer": "^23.0.0", + "ts-jest": "^28.0.2", "typescript": "^4.6.4" }, "description": "Puppeteer end-to-end test automation base.", "devDependencies": { - "@types/jest": "^29.5.12", + "@types/jest": "26.0.24", "@types/node": "13.13.52", "@types/puppeteer": "3.0.8", "husky": "6.0.0", "lint-staged": "10.5.4", "prettier": "2.6.2", - "tslint": "^5.8.0", + "tslint": "6.1.3", "tslint-config-prettier": "1.18.0", "tslint-plugin-prettier": "2.3.0" }, diff --git a/test/test-e2e/yarn.lock b/test/test-e2e/yarn.lock index ae49e32e3..f3d2748dd 100644 --- a/test/test-e2e/yarn.lock +++ b/test/test-e2e/yarn.lock @@ -2,311 +2,291 @@ # yarn lockfile v1 -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.27.1": - version "7.27.1" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz" - integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== +"@ampproject/remapping@^2.2.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" + integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw== dependencies: - "@babel/helper-validator-identifier" "^7.27.1" - js-tokens "^4.0.0" - picocolors "^1.1.1" - -"@babel/compat-data@^7.27.2": - version "7.28.5" - resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz" - integrity sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA== - -"@babel/core@^7.23.9", "@babel/core@^7.27.4": - version "7.28.5" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz" - integrity sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw== - dependencies: - "@babel/code-frame" "^7.27.1" - "@babel/generator" "^7.28.5" - "@babel/helper-compilation-targets" "^7.27.2" - "@babel/helper-module-transforms" "^7.28.3" - "@babel/helpers" "^7.28.4" - "@babel/parser" "^7.28.5" - "@babel/template" "^7.27.2" - "@babel/traverse" "^7.28.5" - "@babel/types" "^7.28.5" - "@jridgewell/remapping" "^2.3.5" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.25.7.tgz#438f2c524071531d643c6f0188e1e28f130cebc7" + integrity sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g== + dependencies: + "@babel/highlight" "^7.25.7" + picocolors "^1.0.0" + +"@babel/compat-data@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.7.tgz#b8479fe0018ef0ac87b6b7a5c6916fcd67ae2c9c" + integrity sha512-9ickoLz+hcXCeh7jrcin+/SLWm+GkxE2kTvoYyp38p4WkdFXfQJxDFGWp/YHjiKLPx06z2A7W8XKuqbReXDzsw== + +"@babel/core@^7.11.6", "@babel/core@^7.12.3": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.25.7.tgz#1b3d144157575daf132a3bc80b2b18e6e3ca6ece" + integrity sha512-yJ474Zv3cwiSOO9nXJuqzvwEeM+chDuQ8GJirw+pZ91sCGCyOZ3dJkVE09fTV0VEVzXyLWhh3G/AolYTPX7Mow== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.25.7" + "@babel/generator" "^7.25.7" + "@babel/helper-compilation-targets" "^7.25.7" + "@babel/helper-module-transforms" "^7.25.7" + "@babel/helpers" "^7.25.7" + "@babel/parser" "^7.25.7" + "@babel/template" "^7.25.7" + "@babel/traverse" "^7.25.7" + "@babel/types" "^7.25.7" convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.27.5", "@babel/generator@^7.28.5": - version "7.28.5" - resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz" - integrity sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ== +"@babel/generator@^7.25.7", "@babel/generator@^7.7.2": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.7.tgz#de86acbeb975a3e11ee92dd52223e6b03b479c56" + integrity sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA== dependencies: - "@babel/parser" "^7.28.5" - "@babel/types" "^7.28.5" - "@jridgewell/gen-mapping" "^0.3.12" - "@jridgewell/trace-mapping" "^0.3.28" + "@babel/types" "^7.25.7" + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" jsesc "^3.0.2" -"@babel/helper-compilation-targets@^7.27.2": - version "7.27.2" - resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz" - integrity sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ== +"@babel/helper-compilation-targets@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz#11260ac3322dda0ef53edfae6e97b961449f5fa4" + integrity sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A== dependencies: - "@babel/compat-data" "^7.27.2" - "@babel/helper-validator-option" "^7.27.1" + "@babel/compat-data" "^7.25.7" + "@babel/helper-validator-option" "^7.25.7" browserslist "^4.24.0" lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-globals@^7.28.0": - version "7.28.0" - resolved "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz" - integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw== - -"@babel/helper-module-imports@^7.27.1": - version "7.27.1" - resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz" - integrity sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w== - dependencies: - "@babel/traverse" "^7.27.1" - "@babel/types" "^7.27.1" - -"@babel/helper-module-transforms@^7.28.3": - version "7.28.3" - resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz" - integrity sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw== - dependencies: - "@babel/helper-module-imports" "^7.27.1" - "@babel/helper-validator-identifier" "^7.27.1" - "@babel/traverse" "^7.28.3" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.8.0": - version "7.27.1" - resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz" - integrity sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw== - -"@babel/helper-string-parser@^7.27.1": - version "7.27.1" - resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz" - integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== - -"@babel/helper-validator-identifier@^7.27.1", "@babel/helper-validator-identifier@^7.28.5": - version "7.28.5" - resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz" - integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q== - -"@babel/helper-validator-option@^7.27.1": - version "7.27.1" - resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz" - integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== - -"@babel/helpers@^7.28.4": - version "7.28.4" - resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz" - integrity sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w== - dependencies: - "@babel/template" "^7.27.2" - "@babel/types" "^7.28.4" +"@babel/helper-module-imports@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz#dba00d9523539152906ba49263e36d7261040472" + integrity sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw== + dependencies: + "@babel/traverse" "^7.25.7" + "@babel/types" "^7.25.7" + +"@babel/helper-module-transforms@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz#2ac9372c5e001b19bc62f1fe7d96a18cb0901d1a" + integrity sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ== + dependencies: + "@babel/helper-module-imports" "^7.25.7" + "@babel/helper-simple-access" "^7.25.7" + "@babel/helper-validator-identifier" "^7.25.7" + "@babel/traverse" "^7.25.7" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.25.7", "@babel/helper-plugin-utils@^7.8.0": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz#8ec5b21812d992e1ef88a9b068260537b6f0e36c" + integrity sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw== + +"@babel/helper-simple-access@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz#5eb9f6a60c5d6b2e0f76057004f8dacbddfae1c0" + integrity sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ== + dependencies: + "@babel/traverse" "^7.25.7" + "@babel/types" "^7.25.7" + +"@babel/helper-string-parser@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz#d50e8d37b1176207b4fe9acedec386c565a44a54" + integrity sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g== + +"@babel/helper-validator-identifier@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz#77b7f60c40b15c97df735b38a66ba1d7c3e93da5" + integrity sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg== + +"@babel/helper-validator-option@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz#97d1d684448228b30b506d90cace495d6f492729" + integrity sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ== + +"@babel/helpers@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.25.7.tgz#091b52cb697a171fe0136ab62e54e407211f09c2" + integrity sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA== + dependencies: + "@babel/template" "^7.25.7" + "@babel/types" "^7.25.7" + +"@babel/highlight@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.25.7.tgz#20383b5f442aa606e7b5e3043b0b1aafe9f37de5" + integrity sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw== + dependencies: + "@babel/helper-validator-identifier" "^7.25.7" + chalk "^2.4.2" + js-tokens "^4.0.0" + picocolors "^1.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.27.2", "@babel/parser@^7.28.5": - version "7.28.5" - resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz" - integrity sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.7.tgz#99b927720f4ddbfeb8cd195a363ed4532f87c590" + integrity sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw== dependencies: - "@babel/types" "^7.28.5" + "@babel/types" "^7.25.7" "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-bigint@^7.8.3": version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-class-properties@^7.12.13": version "7.12.13" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-class-static-block@^7.14.5": version "7.14.5" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== dependencies: "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-import-attributes@^7.24.7": - version "7.27.1" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz" - integrity sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww== + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.7.tgz#d78dd0499d30df19a598e63ab895e21b909bc43f" + integrity sha512-AqVo+dguCgmpi/3mYBdu9lkngOBlQ2w2vnNpa6gfiCxQZLzV4ZbhsXitJ2Yblkoe1VQwtHSaNmIaGll/26YWRw== dependencies: - "@babel/helper-plugin-utils" "^7.27.1" + "@babel/helper-plugin-utils" "^7.25.7" "@babel/plugin-syntax-import-meta@^7.10.4": version "7.10.4" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-json-strings@^7.8.3": version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.27.1": - version "7.27.1" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz" - integrity sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/plugin-syntax-logical-assignment-operators@^7.10.4": version "7.10.4" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-numeric-separator@^7.10.4": version "7.10.4" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-optional-catch-binding@^7.8.3": version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-optional-chaining@^7.8.3": version "7.8.3" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-private-property-in-object@^7.14.5": version "7.14.5" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== dependencies: "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-top-level-await@^7.14.5": version "7.14.5" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.27.1": - version "7.27.1" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz" - integrity sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/template@^7.27.2": - version "7.27.2" - resolved "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz" - integrity sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw== - dependencies: - "@babel/code-frame" "^7.27.1" - "@babel/parser" "^7.27.2" - "@babel/types" "^7.27.1" - -"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.3", "@babel/traverse@^7.28.5": - version "7.28.5" - resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz" - integrity sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ== - dependencies: - "@babel/code-frame" "^7.27.1" - "@babel/generator" "^7.28.5" - "@babel/helper-globals" "^7.28.0" - "@babel/parser" "^7.28.5" - "@babel/template" "^7.27.2" - "@babel/types" "^7.28.5" - debug "^4.3.1" - -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2", "@babel/types@^7.28.4", "@babel/types@^7.28.5": - version "7.28.5" - resolved "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz" - integrity sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA== +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.7.tgz#bfc05b0cc31ebd8af09964650cee723bb228108b" + integrity sha512-rR+5FDjpCHqqZN2bzZm18bVYGaejGq5ZkpVCJLXor/+zlSrSoc4KWcHI0URVWjl/68Dyr1uwZUz/1njycEAv9g== dependencies: - "@babel/helper-string-parser" "^7.27.1" - "@babel/helper-validator-identifier" "^7.28.5" - -"@bcoe/v8-coverage@^0.2.3": - version "0.2.3" - resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz" - integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + "@babel/helper-plugin-utils" "^7.25.7" -"@emnapi/core@^1.4.3": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.7.1.tgz#3a79a02dbc84f45884a1806ebb98e5746bdfaac4" - integrity sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg== +"@babel/template@^7.25.7", "@babel/template@^7.3.3": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.7.tgz#27f69ce382855d915b14ab0fe5fb4cbf88fa0769" + integrity sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA== dependencies: - "@emnapi/wasi-threads" "1.1.0" - tslib "^2.4.0" + "@babel/code-frame" "^7.25.7" + "@babel/parser" "^7.25.7" + "@babel/types" "^7.25.7" -"@emnapi/runtime@^1.4.3": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.7.1.tgz#a73784e23f5d57287369c808197288b52276b791" - integrity sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA== +"@babel/traverse@^7.25.7", "@babel/traverse@^7.7.2": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.7.tgz#83e367619be1cab8e4f2892ef30ba04c26a40fa8" + integrity sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg== dependencies: - tslib "^2.4.0" + "@babel/code-frame" "^7.25.7" + "@babel/generator" "^7.25.7" + "@babel/parser" "^7.25.7" + "@babel/template" "^7.25.7" + "@babel/types" "^7.25.7" + debug "^4.3.1" + globals "^11.1.0" -"@emnapi/wasi-threads@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz#60b2102fddc9ccb78607e4a3cf8403ea69be41bf" - integrity sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ== +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.25.7", "@babel/types@^7.3.3": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.7.tgz#1b7725c1d3a59f328cb700ce704c46371e6eef9b" + integrity sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ== dependencies: - tslib "^2.4.0" + "@babel/helper-string-parser" "^7.25.7" + "@babel/helper-validator-identifier" "^7.25.7" + to-fast-properties "^2.0.0" -"@isaacs/cliui@^8.0.2": - version "8.0.2" - resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz" - integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== - dependencies: - string-width "^5.1.2" - string-width-cjs "npm:string-width@^4.2.0" - strip-ansi "^7.0.1" - strip-ansi-cjs "npm:strip-ansi@^6.0.1" - wrap-ansi "^8.1.0" - wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" - resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== dependencies: camelcase "^5.3.1" @@ -315,362 +295,288 @@ js-yaml "^3.13.1" resolve-from "^5.0.0" -"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": +"@istanbuljs/schema@^0.1.2": version "0.1.3" - resolved "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@30.2.0": - version "30.2.0" - resolved "https://registry.npmjs.org/@jest/console/-/console-30.2.0.tgz" - integrity sha512-+O1ifRjkvYIkBqASKWgLxrpEhQAAE7hY77ALLUufSk5717KfOShg6IbqLmdsLMPdUiFvA2kTs0R7YZy+l0IzZQ== +"@jest/console@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-28.1.3.tgz#2030606ec03a18c31803b8a36382762e447655df" + integrity sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw== dependencies: - "@jest/types" "30.2.0" + "@jest/types" "^28.1.3" "@types/node" "*" - chalk "^4.1.2" - jest-message-util "30.2.0" - jest-util "30.2.0" + chalk "^4.0.0" + jest-message-util "^28.1.3" + jest-util "^28.1.3" slash "^3.0.0" -"@jest/core@30.2.0": - version "30.2.0" - resolved "https://registry.npmjs.org/@jest/core/-/core-30.2.0.tgz" - integrity sha512-03W6IhuhjqTlpzh/ojut/pDB2LPRygyWX8ExpgHtQA8H/3K7+1vKmcINx5UzeOX1se6YEsBsOHQ1CRzf3fOwTQ== - dependencies: - "@jest/console" "30.2.0" - "@jest/pattern" "30.0.1" - "@jest/reporters" "30.2.0" - "@jest/test-result" "30.2.0" - "@jest/transform" "30.2.0" - "@jest/types" "30.2.0" +"@jest/core@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-28.1.3.tgz#0ebf2bd39840f1233cd5f2d1e6fc8b71bd5a1ac7" + integrity sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA== + dependencies: + "@jest/console" "^28.1.3" + "@jest/reporters" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" "@types/node" "*" - ansi-escapes "^4.3.2" - chalk "^4.1.2" - ci-info "^4.2.0" - exit-x "^0.2.2" - graceful-fs "^4.2.11" - jest-changed-files "30.2.0" - jest-config "30.2.0" - jest-haste-map "30.2.0" - jest-message-util "30.2.0" - jest-regex-util "30.0.1" - jest-resolve "30.2.0" - jest-resolve-dependencies "30.2.0" - jest-runner "30.2.0" - jest-runtime "30.2.0" - jest-snapshot "30.2.0" - jest-util "30.2.0" - jest-validate "30.2.0" - jest-watcher "30.2.0" - micromatch "^4.0.8" - pretty-format "30.2.0" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + ci-info "^3.2.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^28.1.3" + jest-config "^28.1.3" + jest-haste-map "^28.1.3" + jest-message-util "^28.1.3" + jest-regex-util "^28.0.2" + jest-resolve "^28.1.3" + jest-resolve-dependencies "^28.1.3" + jest-runner "^28.1.3" + jest-runtime "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" + jest-watcher "^28.1.3" + micromatch "^4.0.4" + pretty-format "^28.1.3" + rimraf "^3.0.0" slash "^3.0.0" + strip-ansi "^6.0.0" -"@jest/diff-sequences@30.0.1": - version "30.0.1" - resolved "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz" - integrity sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw== - -"@jest/environment@30.2.0": - version "30.2.0" - resolved "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz" - integrity sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g== +"@jest/environment@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-28.1.3.tgz#abed43a6b040a4c24fdcb69eab1f97589b2d663e" + integrity sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA== dependencies: - "@jest/fake-timers" "30.2.0" - "@jest/types" "30.2.0" + "@jest/fake-timers" "^28.1.3" + "@jest/types" "^28.1.3" "@types/node" "*" - jest-mock "30.2.0" + jest-mock "^28.1.3" -"@jest/expect-utils@30.2.0": - version "30.2.0" - resolved "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz" - integrity sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA== +"@jest/expect-utils@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-28.1.3.tgz#58561ce5db7cd253a7edddbc051fb39dda50f525" + integrity sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA== dependencies: - "@jest/get-type" "30.1.0" + jest-get-type "^28.0.2" -"@jest/expect-utils@^29.7.0": - version "29.7.0" - resolved "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz" - integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== +"@jest/expect@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-28.1.3.tgz#9ac57e1d4491baca550f6bdbd232487177ad6a72" + integrity sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw== dependencies: - jest-get-type "^29.6.3" + expect "^28.1.3" + jest-snapshot "^28.1.3" -"@jest/expect@30.2.0": - version "30.2.0" - resolved "https://registry.npmjs.org/@jest/expect/-/expect-30.2.0.tgz" - integrity sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA== +"@jest/fake-timers@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-28.1.3.tgz#230255b3ad0a3d4978f1d06f70685baea91c640e" + integrity sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw== dependencies: - expect "30.2.0" - jest-snapshot "30.2.0" - -"@jest/fake-timers@30.2.0": - version "30.2.0" - resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz" - integrity sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw== - dependencies: - "@jest/types" "30.2.0" - "@sinonjs/fake-timers" "^13.0.0" + "@jest/types" "^28.1.3" + "@sinonjs/fake-timers" "^9.1.2" "@types/node" "*" - jest-message-util "30.2.0" - jest-mock "30.2.0" - jest-util "30.2.0" - -"@jest/get-type@30.1.0": - version "30.1.0" - resolved "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz" - integrity sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA== - -"@jest/globals@30.2.0": - version "30.2.0" - resolved "https://registry.npmjs.org/@jest/globals/-/globals-30.2.0.tgz" - integrity sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw== - dependencies: - "@jest/environment" "30.2.0" - "@jest/expect" "30.2.0" - "@jest/types" "30.2.0" - jest-mock "30.2.0" - -"@jest/pattern@30.0.1": - version "30.0.1" - resolved "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz" - integrity sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA== + jest-message-util "^28.1.3" + jest-mock "^28.1.3" + jest-util "^28.1.3" + +"@jest/globals@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-28.1.3.tgz#a601d78ddc5fdef542728309894895b4a42dc333" + integrity sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA== dependencies: - "@types/node" "*" - jest-regex-util "30.0.1" + "@jest/environment" "^28.1.3" + "@jest/expect" "^28.1.3" + "@jest/types" "^28.1.3" -"@jest/reporters@30.2.0": - version "30.2.0" - resolved "https://registry.npmjs.org/@jest/reporters/-/reporters-30.2.0.tgz" - integrity sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ== +"@jest/reporters@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-28.1.3.tgz#9adf6d265edafc5fc4a434cfb31e2df5a67a369a" + integrity sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "30.2.0" - "@jest/test-result" "30.2.0" - "@jest/transform" "30.2.0" - "@jest/types" "30.2.0" - "@jridgewell/trace-mapping" "^0.3.25" + "@jest/console" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + "@jridgewell/trace-mapping" "^0.3.13" "@types/node" "*" - chalk "^4.1.2" - collect-v8-coverage "^1.0.2" - exit-x "^0.2.2" - glob "^10.3.10" - graceful-fs "^4.2.11" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.9" istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^6.0.0" + istanbul-lib-instrument "^5.1.0" istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^5.0.0" + istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.1.3" - jest-message-util "30.2.0" - jest-util "30.2.0" - jest-worker "30.2.0" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + jest-worker "^28.1.3" slash "^3.0.0" - string-length "^4.0.2" + string-length "^4.0.1" + strip-ansi "^6.0.0" + terminal-link "^2.0.0" v8-to-istanbul "^9.0.1" -"@jest/schemas@30.0.5": - version "30.0.5" - resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz" - integrity sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA== +"@jest/schemas@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.1.3.tgz#ad8b86a66f11f33619e3d7e1dcddd7f2d40ff905" + integrity sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg== dependencies: - "@sinclair/typebox" "^0.34.0" + "@sinclair/typebox" "^0.24.1" -"@jest/schemas@^29.6.3": - version "29.6.3" - resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz" - integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== +"@jest/source-map@^28.1.2": + version "28.1.2" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-28.1.2.tgz#7fe832b172b497d6663cdff6c13b0a920e139e24" + integrity sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww== dependencies: - "@sinclair/typebox" "^0.27.8" + "@jridgewell/trace-mapping" "^0.3.13" + callsites "^3.0.0" + graceful-fs "^4.2.9" -"@jest/snapshot-utils@30.2.0": - version "30.2.0" - resolved "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.2.0.tgz" - integrity sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug== +"@jest/test-result@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-28.1.3.tgz#5eae945fd9f4b8fcfce74d239e6f725b6bf076c5" + integrity sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg== dependencies: - "@jest/types" "30.2.0" - chalk "^4.1.2" - graceful-fs "^4.2.11" - natural-compare "^1.4.0" + "@jest/console" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" -"@jest/source-map@30.0.1": - version "30.0.1" - resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz" - integrity sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg== +"@jest/test-sequencer@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz#9d0c283d906ac599c74bde464bc0d7e6a82886c3" + integrity sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw== dependencies: - "@jridgewell/trace-mapping" "^0.3.25" - callsites "^3.1.0" - graceful-fs "^4.2.11" - -"@jest/test-result@30.2.0": - version "30.2.0" - resolved "https://registry.npmjs.org/@jest/test-result/-/test-result-30.2.0.tgz" - integrity sha512-RF+Z+0CCHkARz5HT9mcQCBulb1wgCP3FBvl9VFokMX27acKphwyQsNuWH3c+ojd1LeWBLoTYoxF0zm6S/66mjg== - dependencies: - "@jest/console" "30.2.0" - "@jest/types" "30.2.0" - "@types/istanbul-lib-coverage" "^2.0.6" - collect-v8-coverage "^1.0.2" - -"@jest/test-sequencer@30.2.0": - version "30.2.0" - resolved "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.2.0.tgz" - integrity sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q== - dependencies: - "@jest/test-result" "30.2.0" - graceful-fs "^4.2.11" - jest-haste-map "30.2.0" + "@jest/test-result" "^28.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" slash "^3.0.0" -"@jest/transform@30.2.0": - version "30.2.0" - resolved "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz" - integrity sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA== +"@jest/transform@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-28.1.3.tgz#59d8098e50ab07950e0f2fc0fc7ec462371281b0" + integrity sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA== dependencies: - "@babel/core" "^7.27.4" - "@jest/types" "30.2.0" - "@jridgewell/trace-mapping" "^0.3.25" - babel-plugin-istanbul "^7.0.1" - chalk "^4.1.2" - convert-source-map "^2.0.0" - fast-json-stable-stringify "^2.1.0" - graceful-fs "^4.2.11" - jest-haste-map "30.2.0" - jest-regex-util "30.0.1" - jest-util "30.2.0" - micromatch "^4.0.8" - pirates "^4.0.7" + "@babel/core" "^7.11.6" + "@jest/types" "^28.1.3" + "@jridgewell/trace-mapping" "^0.3.13" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" + jest-regex-util "^28.0.2" + jest-util "^28.1.3" + micromatch "^4.0.4" + pirates "^4.0.4" slash "^3.0.0" - write-file-atomic "^5.0.1" + write-file-atomic "^4.0.1" -"@jest/types@30.2.0": - version "30.2.0" - resolved "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz" - integrity sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg== +"@jest/types@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" + integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== dependencies: - "@jest/pattern" "30.0.1" - "@jest/schemas" "30.0.5" - "@types/istanbul-lib-coverage" "^2.0.6" - "@types/istanbul-reports" "^3.0.4" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" "@types/node" "*" - "@types/yargs" "^17.0.33" - chalk "^4.1.2" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" -"@jest/types@^29.6.3": - version "29.6.3" - resolved "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz" - integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== +"@jest/types@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.3.tgz#b05de80996ff12512bc5ceb1d208285a7d11748b" + integrity sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ== dependencies: - "@jest/schemas" "^29.6.3" + "@jest/schemas" "^28.1.3" "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^3.0.0" "@types/node" "*" "@types/yargs" "^17.0.8" chalk "^4.0.0" -"@jridgewell/gen-mapping@^0.3.12", "@jridgewell/gen-mapping@^0.3.5": - version "0.3.13" - resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz" - integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== - dependencies: - "@jridgewell/sourcemap-codec" "^1.5.0" - "@jridgewell/trace-mapping" "^0.3.24" - -"@jridgewell/remapping@^2.3.5": - version "2.3.5" - resolved "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz" - integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ== +"@jridgewell/gen-mapping@^0.3.5": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" + integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg== dependencies: - "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/set-array" "^1.2.1" + "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.24" "@jridgewell/resolve-uri@^3.1.0": version "3.1.2" - resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== -"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": - version "1.5.5" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz" - integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== +"@jridgewell/set-array@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280" + integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A== + +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.23", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.28": - version "0.3.31" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz" - integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.13", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": + version "0.3.25" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" + integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== dependencies: "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@napi-rs/wasm-runtime@^0.2.11": - version "0.2.12" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz#3e78a8b96e6c33a6c517e1894efbd5385a7cb6f2" - integrity sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ== +"@puppeteer/browsers@2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@puppeteer/browsers/-/browsers-2.4.0.tgz#a0dd0f4e381e53f509109ae83b891db5972750f5" + integrity sha512-x8J1csfIygOwf6D6qUAZ0ASk3z63zPb7wkNeHRerCMh82qWKUrOgkuP005AJC8lDL6/evtXETGEJVcwykKT4/g== dependencies: - "@emnapi/core" "^1.4.3" - "@emnapi/runtime" "^1.4.3" - "@tybys/wasm-util" "^0.10.0" - -"@pkgjs/parseargs@^0.11.0": - version "0.11.0" - resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" - integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== - -"@pkgr/core@^0.2.9": - version "0.2.9" - resolved "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz" - integrity sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA== - -"@puppeteer/browsers@2.10.13": - version "2.10.13" - resolved "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.10.13.tgz" - integrity sha512-a9Ruw3j3qlnB5a/zHRTkruppynxqaeE4H9WNj5eYGRWqw0ZauZ23f4W2ARf3hghF5doozyD+CRtt7XSYuYRI/Q== - dependencies: - debug "^4.4.3" + debug "^4.3.6" extract-zip "^2.0.1" progress "^2.0.3" - proxy-agent "^6.5.0" - semver "^7.7.3" - tar-fs "^3.1.1" + proxy-agent "^6.4.0" + semver "^7.6.3" + tar-fs "^3.0.6" + unbzip2-stream "^1.4.3" yargs "^17.7.2" -"@sinclair/typebox@^0.27.8": - version "0.27.8" - resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz" - integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== - -"@sinclair/typebox@^0.34.0": - version "0.34.41" - resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz" - integrity sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g== +"@sinclair/typebox@^0.24.1": + version "0.24.51" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" + integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== -"@sinonjs/commons@^3.0.1": - version "3.0.1" - resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz" - integrity sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ== +"@sinonjs/commons@^1.7.0": + version "1.8.6" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.6.tgz#80c516a4dc264c2a69115e7578d62581ff455ed9" + integrity sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ== dependencies: type-detect "4.0.8" -"@sinonjs/fake-timers@^13.0.0": - version "13.0.5" - resolved "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz" - integrity sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw== +"@sinonjs/fake-timers@^9.1.2": + version "9.1.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c" + integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== dependencies: - "@sinonjs/commons" "^3.0.1" + "@sinonjs/commons" "^1.7.0" "@tootallnate/quickjs-emscripten@^0.23.0": version "0.23.0" - resolved "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz" + resolved "https://registry.yarnpkg.com/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz#db4ecfd499a9765ab24002c3b696d02e6d32a12c" integrity sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA== -"@tybys/wasm-util@^0.10.0": - version "0.10.1" - resolved "https://registry.yarnpkg.com/@tybys/wasm-util/-/wasm-util-0.10.1.tgz#ecddd3205cf1e2d5274649ff0eedd2991ed7f414" - integrity sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg== - dependencies: - tslib "^2.4.0" - -"@types/babel__core@^7.20.5": +"@types/babel__core@^7.1.14": version "7.20.5" - resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== dependencies: "@babel/parser" "^7.20.7" @@ -680,205 +586,131 @@ "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.27.0" - resolved "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz" - integrity sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg== + version "7.6.8" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.8.tgz#f836c61f48b1346e7d2b0d93c6dacc5b9535d3ab" + integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== dependencies: "@babel/types" "^7.0.0" "@types/babel__template@*": version "7.4.4" - resolved "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" -"@types/babel__traverse@*": - version "7.28.0" - resolved "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz" - integrity sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q== +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.20.6" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.6.tgz#8dc9f0ae0f202c08d8d4dab648912c8d6038e3f7" + integrity sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg== + dependencies: + "@babel/types" "^7.20.7" + +"@types/graceful-fs@^4.1.3": + version "4.1.9" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" + integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== dependencies: - "@babel/types" "^7.28.2" + "@types/node" "*" -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1", "@types/istanbul-lib-coverage@^2.0.6": +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.6" - resolved "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== "@types/istanbul-lib-report@*": version "3.0.3" - resolved "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== dependencies: "@types/istanbul-lib-coverage" "*" -"@types/istanbul-reports@^3.0.0", "@types/istanbul-reports@^3.0.4": +"@types/istanbul-reports@^3.0.0": version "3.0.4" - resolved "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@^29.5.12": - version "29.5.14" - resolved "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz" - integrity sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ== +"@types/jest@26.0.24": + version "26.0.24" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.24.tgz#943d11976b16739185913a1936e0de0c4a7d595a" + integrity sha512-E/X5Vib8BWqZNRlDxj9vYXhsDwPYbPINqKF9BsnSoon4RQ0D9moEuLD8txgyypFLH7J4+Lho9Nr/c8H0Fi+17w== + dependencies: + jest-diff "^26.0.0" + pretty-format "^26.0.0" + +"@types/node@*": + version "22.7.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.4.tgz#e35d6f48dca3255ce44256ddc05dee1c23353fcc" + integrity sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg== dependencies: - expect "^29.0.0" - pretty-format "^29.0.0" + undici-types "~6.19.2" -"@types/node@*", "@types/node@13.13.52": +"@types/node@13.13.52": version "13.13.52" - resolved "https://registry.npmjs.org/@types/node/-/node-13.13.52.tgz" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.52.tgz#03c13be70b9031baaed79481c0c0cfb0045e53f7" integrity sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ== "@types/parse-json@^4.0.0": version "4.0.2" - resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== +"@types/prettier@^2.1.5": + version "2.7.3" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" + integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== + "@types/puppeteer@3.0.8": version "3.0.8" - resolved "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-3.0.8.tgz" + resolved "https://registry.yarnpkg.com/@types/puppeteer/-/puppeteer-3.0.8.tgz#f5431d58bd99d6ef9b6d93f0cc5a0f344559b6b3" integrity sha512-YmaPF3KLyDNJfTMlbONOWsAfUh9j0up8xA1G/uyz4c8yD80C2VUM5OTjf+sAS89EN6A6gas0oEzJThICf4OUpw== dependencies: "@types/node" "*" -"@types/stack-utils@^2.0.0", "@types/stack-utils@^2.0.3": +"@types/stack-utils@^2.0.0": version "2.0.3" - resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== "@types/yargs-parser@*": version "21.0.3" - resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== -"@types/yargs@^17.0.33", "@types/yargs@^17.0.8": - version "17.0.35" - resolved "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz" - integrity sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg== +"@types/yargs@^15.0.0": + version "15.0.19" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.19.tgz#328fb89e46109ecbdb70c295d96ff2f46dfd01b9" + integrity sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA== + dependencies: + "@types/yargs-parser" "*" + +"@types/yargs@^17.0.8": + version "17.0.33" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.33.tgz#8c32303da83eec050a84b3c7ae7b9f922d13e32d" + integrity sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA== dependencies: "@types/yargs-parser" "*" "@types/yauzl@^2.9.1": version "2.10.3" - resolved "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz" + resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.3.tgz#e9b2808b4f109504a03cda958259876f61017999" integrity sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q== dependencies: "@types/node" "*" -"@ungap/structured-clone@^1.3.0": - version "1.3.0" - resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz" - integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== - -"@unrs/resolver-binding-android-arm-eabi@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz#9f5b04503088e6a354295e8ea8fe3cb99e43af81" - integrity sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw== - -"@unrs/resolver-binding-android-arm64@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz#7414885431bd7178b989aedc4d25cccb3865bc9f" - integrity sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g== - -"@unrs/resolver-binding-darwin-arm64@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz#b4a8556f42171fb9c9f7bac8235045e82aa0cbdf" - integrity sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g== - -"@unrs/resolver-binding-darwin-x64@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz#fd4d81257b13f4d1a083890a6a17c00de571f0dc" - integrity sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ== - -"@unrs/resolver-binding-freebsd-x64@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz#d2513084d0f37c407757e22f32bd924a78cfd99b" - integrity sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw== - -"@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz#844d2605d057488d77fab09705f2866b86164e0a" - integrity sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw== - -"@unrs/resolver-binding-linux-arm-musleabihf@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz#204892995cefb6bd1d017d52d097193bc61ddad3" - integrity sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw== - -"@unrs/resolver-binding-linux-arm64-gnu@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz#023eb0c3aac46066a10be7a3f362e7b34f3bdf9d" - integrity sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ== - -"@unrs/resolver-binding-linux-arm64-musl@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz#9e6f9abb06424e3140a60ac996139786f5d99be0" - integrity sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w== - -"@unrs/resolver-binding-linux-ppc64-gnu@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz#b111417f17c9d1b02efbec8e08398f0c5527bb44" - integrity sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA== - -"@unrs/resolver-binding-linux-riscv64-gnu@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz#92ffbf02748af3e99873945c9a8a5ead01d508a9" - integrity sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ== - -"@unrs/resolver-binding-linux-riscv64-musl@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz#0bec6f1258fc390e6b305e9ff44256cb207de165" - integrity sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew== - -"@unrs/resolver-binding-linux-s390x-gnu@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz#577843a084c5952f5906770633ccfb89dac9bc94" - integrity sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg== - -"@unrs/resolver-binding-linux-x64-gnu@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz" - integrity sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w== - -"@unrs/resolver-binding-linux-x64-musl@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz" - integrity sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA== - -"@unrs/resolver-binding-wasm32-wasi@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz#752c359dd875684b27429500d88226d7cc72f71d" - integrity sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ== - dependencies: - "@napi-rs/wasm-runtime" "^0.2.11" - -"@unrs/resolver-binding-win32-arm64-msvc@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz#ce5735e600e4c2fbb409cd051b3b7da4a399af35" - integrity sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw== - -"@unrs/resolver-binding-win32-ia32-msvc@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz#72fc57bc7c64ec5c3de0d64ee0d1810317bc60a6" - integrity sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ== - -"@unrs/resolver-binding-win32-x64-msvc@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz#538b1e103bf8d9864e7b85cc96fa8d6fb6c40777" - integrity sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g== - -agent-base@^7.1.0, agent-base@^7.1.2: - version "7.1.4" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz" - integrity sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ== +agent-base@^7.0.2, agent-base@^7.1.0, agent-base@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.1.tgz#bdbded7dfb096b751a2a087eeeb9664725b2e317" + integrity sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA== + dependencies: + debug "^4.3.4" aggregate-error@^3.0.0: version "3.1.0" - resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== dependencies: clean-stack "^2.0.0" @@ -886,63 +718,43 @@ aggregate-error@^3.0.0: ansi-colors@^4.1.1: version "4.1.3" - resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== -ansi-escapes@^4.3.0, ansi-escapes@^4.3.2: +ansi-escapes@^4.2.1, ansi-escapes@^4.3.0: version "4.3.2" - resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== dependencies: type-fest "^0.21.3" -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" - integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== - -ansi-regex@^5.0.1: +ansi-regex@^5.0.0, ansi-regex@^5.0.1: version "5.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-regex@^6.0.1: - version "6.2.2" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz" - integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg== - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz" - integrity sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA== - ansi-styles@^3.2.1: version "3.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" -ansi-styles@^5.0.0, ansi-styles@^5.2.0: +ansi-styles@^5.0.0: version "5.2.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== -ansi-styles@^6.1.0: - version "6.2.3" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz" - integrity sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg== - -anymatch@^3.1.3: +anymatch@^3.0.3: version "3.1.3" - resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== dependencies: normalize-path "^3.0.0" @@ -950,77 +762,71 @@ anymatch@^3.1.3: argparse@^1.0.7: version "1.0.10" - resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" argparse@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== ast-types@^0.13.4: version "0.13.4" - resolved "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.4.tgz#ee0d77b343263965ecc3fb62da16e7222b2b6782" integrity sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w== dependencies: tslib "^2.0.1" astral-regex@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== -b4a@^1.6.4: - version "1.7.3" - resolved "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz" - integrity sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q== +b4a@^1.6.4, b4a@^1.6.6: + version "1.6.7" + resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.7.tgz#a99587d4ebbfbd5a6e3b21bdb5d5fa385767abe4" + integrity sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg== -babel-code-frame@^6.22.0: - version "6.26.0" - resolved "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz" - integrity sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g== +babel-jest@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-28.1.3.tgz#c1187258197c099072156a0a121c11ee1e3917d5" + integrity sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q== dependencies: - chalk "^1.1.3" - esutils "^2.0.2" - js-tokens "^3.0.2" - -babel-jest@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz" - integrity sha512-0YiBEOxWqKkSQWL9nNGGEgndoeL0ZpWrbLMNL5u/Kaxrli3Eaxlt3ZtIDktEvXt4L/R9r3ODr2zKwGM/2BjxVw== - dependencies: - "@jest/transform" "30.2.0" - "@types/babel__core" "^7.20.5" - babel-plugin-istanbul "^7.0.1" - babel-preset-jest "30.2.0" - chalk "^4.1.2" - graceful-fs "^4.2.11" + "@jest/transform" "^28.1.3" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^28.1.3" + chalk "^4.0.0" + graceful-fs "^4.2.9" slash "^3.0.0" -babel-plugin-istanbul@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz" - integrity sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA== +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@istanbuljs/load-nyc-config" "^1.0.0" - "@istanbuljs/schema" "^0.1.3" - istanbul-lib-instrument "^6.0.2" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" -babel-plugin-jest-hoist@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.2.0.tgz" - integrity sha512-ftzhzSGMUnOzcCXd6WHdBGMyuwy15Wnn0iyyWGKgBDLxf9/s5ABuraCSpBX2uG0jUg4rqJnxsLc5+oYBqoxVaA== +babel-plugin-jest-hoist@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz#1952c4d0ea50f2d6d794353762278d1d8cca3fbe" + integrity sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q== dependencies: - "@types/babel__core" "^7.20.5" + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" + "@types/babel__traverse" "^7.0.6" -babel-preset-current-node-syntax@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz" - integrity sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg== +babel-preset-current-node-syntax@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz#9a929eafece419612ef4ae4f60b1862ebad8ef30" + integrity sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw== dependencies: "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-bigint" "^7.8.3" @@ -1038,176 +844,157 @@ babel-preset-current-node-syntax@^1.2.0: "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-syntax-top-level-await" "^7.14.5" -babel-preset-jest@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.2.0.tgz" - integrity sha512-US4Z3NOieAQumwFnYdUWKvUKh8+YSnS/gB3t6YBiz0bskpu7Pine8pPCheNxlPEW4wnUkma2a94YuW2q3guvCQ== +babel-preset-jest@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz#5dfc20b99abed5db994406c2b9ab94c73aaa419d" + integrity sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A== dependencies: - babel-plugin-jest-hoist "30.2.0" - babel-preset-current-node-syntax "^1.2.0" + babel-plugin-jest-hoist "^28.1.3" + babel-preset-current-node-syntax "^1.0.0" balanced-match@^1.0.0: version "1.0.2" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -bare-events@^2.5.4, bare-events@^2.7.0: - version "2.8.2" - resolved "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz" - integrity sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ== +bare-events@^2.0.0, bare-events@^2.2.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/bare-events/-/bare-events-2.5.0.tgz#305b511e262ffd8b9d5616b056464f8e1b3329cc" + integrity sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A== -bare-fs@^4.0.1: - version "4.5.1" - resolved "https://registry.npmjs.org/bare-fs/-/bare-fs-4.5.1.tgz" - integrity sha512-zGUCsm3yv/ePt2PHNbVxjjn0nNB1MkIaR4wOCxJ2ig5pCf5cCVAYJXVhQg/3OhhJV6DB1ts7Hv0oUaElc2TPQg== +bare-fs@^2.1.1: + version "2.3.5" + resolved "https://registry.yarnpkg.com/bare-fs/-/bare-fs-2.3.5.tgz#05daa8e8206aeb46d13c2fe25a2cd3797b0d284a" + integrity sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw== dependencies: - bare-events "^2.5.4" - bare-path "^3.0.0" - bare-stream "^2.6.4" - bare-url "^2.2.2" - fast-fifo "^1.3.2" + bare-events "^2.0.0" + bare-path "^2.0.0" + bare-stream "^2.0.0" -bare-os@^3.0.1: - version "3.6.2" - resolved "https://registry.npmjs.org/bare-os/-/bare-os-3.6.2.tgz" - integrity sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A== +bare-os@^2.1.0: + version "2.4.4" + resolved "https://registry.yarnpkg.com/bare-os/-/bare-os-2.4.4.tgz#01243392eb0a6e947177bb7c8a45123d45c9b1a9" + integrity sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ== -bare-path@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz" - integrity sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw== - dependencies: - bare-os "^3.0.1" - -bare-stream@^2.6.4: - version "2.7.0" - resolved "https://registry.npmjs.org/bare-stream/-/bare-stream-2.7.0.tgz" - integrity sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A== +bare-path@^2.0.0, bare-path@^2.1.0: + version "2.1.3" + resolved "https://registry.yarnpkg.com/bare-path/-/bare-path-2.1.3.tgz#594104c829ef660e43b5589ec8daef7df6cedb3e" + integrity sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA== dependencies: - streamx "^2.21.0" + bare-os "^2.1.0" -bare-url@^2.2.2: - version "2.3.2" - resolved "https://registry.npmjs.org/bare-url/-/bare-url-2.3.2.tgz" - integrity sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw== +bare-stream@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/bare-stream/-/bare-stream-2.3.0.tgz#5bef1cab8222517315fca1385bd7f08dff57f435" + integrity sha512-pVRWciewGUeCyKEuRxwv06M079r+fRjAQjBEK2P6OYGrO43O+Z0LrPZZEjlc4mB6C2RpZ9AxJ1s7NLEtOHO6eA== dependencies: - bare-path "^3.0.0" + b4a "^1.6.6" + streamx "^2.20.0" -baseline-browser-mapping@^2.8.25: - version "2.8.29" - resolved "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.29.tgz" - integrity sha512-sXdt2elaVnhpDNRDz+1BDx1JQoJRuNk7oVlAlbGiFkLikHCAQiccexF/9e91zVi6RCgqspl04aP+6Cnl9zRLrA== +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== basic-ftp@^5.0.2: version "5.0.5" - resolved "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz" + resolved "https://registry.yarnpkg.com/basic-ftp/-/basic-ftp-5.0.5.tgz#14a474f5fffecca1f4f406f1c26b18f800225ac0" integrity sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg== brace-expansion@^1.1.7: - version "1.1.12" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz" - integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg== + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" -brace-expansion@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz" - integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ== - dependencies: - balanced-match "^1.0.0" - braces@^3.0.3: version "3.0.3" - resolved "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== dependencies: fill-range "^7.1.1" browserslist@^4.24.0: - version "4.28.0" - resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz" - integrity sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ== + version "4.24.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.0.tgz#a1325fe4bc80b64fda169629fc01b3d6cecd38d4" + integrity sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A== dependencies: - baseline-browser-mapping "^2.8.25" - caniuse-lite "^1.0.30001754" - electron-to-chromium "^1.5.249" - node-releases "^2.0.27" - update-browserslist-db "^1.1.4" + caniuse-lite "^1.0.30001663" + electron-to-chromium "^1.5.28" + node-releases "^2.0.18" + update-browserslist-db "^1.1.0" -bs-logger@^0.2.6: +bs-logger@0.x: version "0.2.6" - resolved "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== dependencies: fast-json-stable-stringify "2.x" bser@2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== dependencies: node-int64 "^0.4.0" buffer-crc32@~0.2.3: version "0.2.13" - resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== buffer-from@^1.0.0: version "1.1.2" - resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +buffer@^5.2.1: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + builtin-modules@^1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" integrity sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ== -callsites@^3.0.0, callsites@^3.1.0: +callsites@^3.0.0: version "3.1.0" - resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== camelcase@^5.3.1: version "5.3.1" - resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.3.0: +camelcase@^6.2.0: version "6.3.0" - resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001754: - version "1.0.30001755" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001755.tgz" - integrity sha512-44V+Jm6ctPj7R52Na4TLi3Zri4dWUljJd+RDm+j8LtNCc/ihLCT+X1TzoOAkRETEWqjuLnh9581Tl80FvK7jVA== +caniuse-lite@^1.0.30001663: + version "1.0.30001666" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001666.tgz#112d77e80f1762f62a1b71ba92164e0cb3f3dd13" + integrity sha512-gD14ICmoV5ZZM1OdzPWmpx+q4GyefaK06zi8hmfHV5xe4/2nOQX3+Dw5o+fSqOws2xVwL9j+anOPFwHzdEdV4g== -chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz" - integrity sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A== - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - -chalk@^2.1.0: +chalk@^2.3.0, chalk@^2.4.2: version "2.4.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: ansi-styles "^3.2.1" escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: +chalk@^4.0.0, chalk@^4.1.0: version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" @@ -1215,47 +1002,43 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: char-regex@^1.0.2: version "1.0.2" - resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== -chromium-bidi@11.0.0: - version "11.0.0" - resolved "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-11.0.0.tgz" - integrity sha512-cM3DI+OOb89T3wO8cpPSro80Q9eKYJ7hGVXoGS3GkDPxnYSqiv+6xwpIf6XERyJ9Tdsl09hmNmY94BkgZdVekw== +chromium-bidi@0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/chromium-bidi/-/chromium-bidi-0.8.0.tgz#ffd79dad7db1fcc874f1c55fcf46ded05a884269" + integrity sha512-uJydbGdTw0DEUjhoogGveneJVWX/9YuqkWePzMmkBYwtdAqo5d3J/ovNKFr+/2hWXYmYCr6it8mSSTIj6SS6Ug== dependencies: - mitt "^3.0.1" - zod "^3.24.1" + mitt "3.0.1" + urlpattern-polyfill "10.0.0" + zod "3.23.8" ci-info@^3.2.0: version "3.9.0" - resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== -ci-info@^4.2.0: - version "4.3.1" - resolved "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz" - integrity sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA== - -cjs-module-lexer@^2.1.0: - version "2.1.1" - resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.1.1.tgz" - integrity sha512-+CmxIZ/L2vNcEfvNtLdU0ZQ6mbq3FZnwAP2PPTiKP+1QOoKwlKlPgb8UKV0Dds7QVaMnHm+FwSft2VB0s/SLjQ== +cjs-module-lexer@^1.0.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz#707413784dbb3a72aa11c2f2b042a0bef4004170" + integrity sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA== clean-stack@^2.0.0: version "2.2.0" - resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== cli-cursor@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== dependencies: restore-cursor "^3.1.0" cli-truncate@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== dependencies: slice-ansi "^3.0.0" @@ -1263,7 +1046,7 @@ cli-truncate@^2.1.0: cliui@^8.0.1: version "8.0.1" - resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== dependencies: string-width "^4.2.0" @@ -1272,66 +1055,71 @@ cliui@^8.0.1: co@^4.6.0: version "4.6.0" - resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== -collect-v8-coverage@^1.0.2: - version "1.0.3" - resolved "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz" - integrity sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw== +collect-v8-coverage@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" + integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== color-convert@^1.9.0: version "1.9.3" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: color-name "1.1.3" color-convert@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== dependencies: color-name "~1.1.4" color-name@1.1.3: version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== color-name@~1.1.4: version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== colorette@^2.0.16: version "2.0.20" - resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== -commander@^2.9.0: +commander@^2.12.1: version "2.20.3" - resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== commander@^6.2.0: version "6.2.1" - resolved "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== concat-map@0.0.1: version "0.0.1" - resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== +convert-source-map@^1.4.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + convert-source-map@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== cosmiconfig@^7.0.0: version "7.1.0" - resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== dependencies: "@types/parse-json" "^4.0.0" @@ -1342,7 +1130,7 @@ cosmiconfig@^7.0.0: cosmiconfig@^9.0.0: version "9.0.0" - resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-9.0.0.tgz#34c3fc58287b915f3ae905ab6dc3de258b55ad9d" integrity sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg== dependencies: env-paths "^2.2.1" @@ -1350,10 +1138,10 @@ cosmiconfig@^9.0.0: js-yaml "^4.1.0" parse-json "^5.2.0" -cross-spawn@^7.0.0, cross-spawn@^7.0.3, cross-spawn@^7.0.6: - version "7.0.6" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz" - integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== +cross-spawn@^7.0.0, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: path-key "^3.1.0" shebang-command "^2.0.0" @@ -1361,95 +1149,85 @@ cross-spawn@^7.0.0, cross-spawn@^7.0.3, cross-spawn@^7.0.6: data-uri-to-buffer@^6.0.2: version "6.0.2" - resolved "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz#8a58bb67384b261a38ef18bea1810cb01badd28b" integrity sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw== -debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.4, debug@^4.4.3: - version "4.4.3" - resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz" - integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1, debug@^4.3.4, debug@^4.3.6, debug@^4.3.7: + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== dependencies: ms "^2.1.3" dedent@^0.7.0: version "0.7.0" - resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== -dedent@^1.6.0: - version "1.7.0" - resolved "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz" - integrity sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ== - -deepmerge@^4.3.1: +deepmerge@^4.2.2: version "4.3.1" - resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== degenerator@^5.0.0: version "5.0.1" - resolved "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz" + resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-5.0.1.tgz#9403bf297c6dad9a1ece409b37db27954f91f2f5" integrity sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ== dependencies: ast-types "^0.13.4" escodegen "^2.1.0" esprima "^4.0.1" -detect-newline@^3.1.0: +detect-newline@^3.0.0: version "3.1.0" - resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== -devtools-protocol@0.0.1521046: - version "0.0.1521046" - resolved "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1521046.tgz" - integrity sha512-vhE6eymDQSKWUXwwA37NtTTVEzjtGVfDr3pRbsWEQ5onH/Snp2c+2xZHWJJawG/0hCCJLRGt4xVtEVUVILol4w== +devtools-protocol@0.0.1342118: + version "0.0.1342118" + resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1342118.tgz#ea136fc1701572c0830233dcb414dc857e582e0a" + integrity sha512-75fMas7PkYNDTmDyb6PRJCH7ILmHLp+BhrZGeMsa4bCh40DTxgCz2NRy5UDzII4C5KuD0oBMZ9vXKhEl6UD/3w== -diff-sequences@^29.6.3: - version "29.6.3" - resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz" - integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== +diff-sequences@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" + integrity sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q== -diff@^3.2.0: - version "3.5.0" - resolved "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== +diff-sequences@^28.1.1: + version "28.1.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6" + integrity sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw== -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== -electron-to-chromium@^1.5.249: - version "1.5.254" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.254.tgz" - integrity sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg== +electron-to-chromium@^1.5.28: + version "1.5.31" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.31.tgz#b1478418769dec72ea70d9fdf147a81491857f10" + integrity sha512-QcDoBbQeYt0+3CWcK/rEbuHvwpbT/8SV9T3OSgs6cX1FlcUAkgrkqbg9zLnDrMM/rLamzQwal4LYFCiWk861Tg== -emittery@^0.13.1: - version "0.13.1" - resolved "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz" - integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== +emittery@^0.10.2: + version "0.10.2" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" + integrity sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw== emoji-regex@^8.0.0: version "8.0.0" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - end-of-stream@^1.1.0: - version "1.4.5" - resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz" - integrity sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg== + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" enquirer@^2.3.6: version "2.4.1" - resolved "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== dependencies: ansi-colors "^4.1.1" @@ -1457,34 +1235,34 @@ enquirer@^2.3.6: env-paths@^2.2.1: version "2.2.1" - resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== error-ex@^1.3.1: - version "1.3.4" - resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz" - integrity sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ== + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" escalade@^3.1.1, escalade@^3.2.0: version "3.2.0" - resolved "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== escape-string-regexp@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== escodegen@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17" integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w== dependencies: esprima "^4.0.1" @@ -1495,7 +1273,7 @@ escodegen@^2.1.0: eslint-plugin-prettier@^2.2.0: version "2.7.0" - resolved "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.7.0.tgz#b4312dcf2c1d965379d7f9d5b5f8aaadc6a45904" integrity sha512-CStQYJgALoQBw3FsBzH0VOVDRnJ/ZimUlpLm226U8qgqYJfPOY/CPK6wyRInMxh73HSKg5wyRwdS4BVYYHwokA== dependencies: fast-diff "^1.1.1" @@ -1503,29 +1281,22 @@ eslint-plugin-prettier@^2.2.0: esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" - resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== estraverse@^5.2.0: version "5.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== esutils@^2.0.2: version "2.0.3" - resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -events-universal@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz" - integrity sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw== - dependencies: - bare-events "^2.7.0" - execa@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== dependencies: cross-spawn "^7.0.0" @@ -1538,9 +1309,9 @@ execa@^4.1.0: signal-exit "^3.0.2" strip-final-newline "^2.0.0" -execa@^5.1.1: +execa@^5.0.0: version "5.1.1" - resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== dependencies: cross-spawn "^7.0.3" @@ -1553,37 +1324,25 @@ execa@^5.1.1: signal-exit "^3.0.3" strip-final-newline "^2.0.0" -exit-x@^0.2.2: - version "0.2.2" - resolved "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz" - integrity sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ== - -expect@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz" - integrity sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw== - dependencies: - "@jest/expect-utils" "30.2.0" - "@jest/get-type" "30.1.0" - jest-matcher-utils "30.2.0" - jest-message-util "30.2.0" - jest-mock "30.2.0" - jest-util "30.2.0" - -expect@^29.0.0: - version "29.7.0" - resolved "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz" - integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== - dependencies: - "@jest/expect-utils" "^29.7.0" - jest-get-type "^29.6.3" - jest-matcher-utils "^29.7.0" - jest-message-util "^29.7.0" - jest-util "^29.7.0" +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== + +expect@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/expect/-/expect-28.1.3.tgz#90a7c1a124f1824133dd4533cce2d2bdcb6603ec" + integrity sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g== + dependencies: + "@jest/expect-utils" "^28.1.3" + jest-get-type "^28.0.2" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-util "^28.1.3" extract-zip@^2.0.1: version "2.0.1" - resolved "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a" integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== dependencies: debug "^4.1.1" @@ -1594,127 +1353,117 @@ extract-zip@^2.0.1: fast-diff@^1.1.1: version "1.3.0" - resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== fast-fifo@^1.2.0, fast-fifo@^1.3.2: version "1.3.2" - resolved "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz" + resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.1.0: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fb-watchman@^2.0.2: +fb-watchman@^2.0.0: version "2.0.2" - resolved "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== dependencies: bser "2.1.1" fd-slicer@~1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e" integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g== dependencies: pend "~1.2.0" fill-range@^7.1.1: version "7.1.1" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== dependencies: to-regex-range "^5.0.1" find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== dependencies: locate-path "^5.0.0" path-exists "^4.0.0" -foreground-child@^3.1.0: - version "3.3.1" - resolved "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz" - integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw== +fs-extra@^11.2.0: + version "11.2.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" + integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== dependencies: - cross-spawn "^7.0.6" - signal-exit "^4.0.1" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@^2.3.3: +fsevents@^2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== function-bind@^1.1.2: version "1.1.2" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== gensync@^1.0.0-beta.2: version "1.0.0-beta.2" - resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== get-caller-file@^2.0.5: version "2.0.5" - resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== get-own-enumerable-property-symbols@^3.0.0: version "3.0.2" - resolved "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== get-package-type@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== get-stream@^5.0.0, get-stream@^5.1.0: version "5.2.0" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== dependencies: pump "^3.0.0" get-stream@^6.0.0: version "6.0.1" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== get-uri@^6.0.1: - version "6.0.5" - resolved "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz" - integrity sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg== + version "6.0.3" + resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-6.0.3.tgz#0d26697bc13cf91092e519aa63aa60ee5b6f385a" + integrity sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw== dependencies: basic-ftp "^5.0.2" data-uri-to-buffer "^6.0.2" debug "^4.3.4" + fs-extra "^11.2.0" -glob@^10.3.10: - version "10.4.5" - resolved "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz" - integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== - dependencies: - foreground-child "^3.1.0" - jackspeak "^3.1.2" - minimatch "^9.0.4" - minipass "^7.1.2" - package-json-from-dist "^1.0.0" - path-scurry "^1.11.1" - -glob@^7.1.1, glob@^7.1.4: +glob@^7.1.1, glob@^7.1.3, glob@^7.1.4: version "7.2.3" - resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== dependencies: fs.realpath "^1.0.0" @@ -1724,94 +1473,85 @@ glob@^7.1.1, glob@^7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" -graceful-fs@^4.2.11, graceful-fs@^4.2.9: +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.9: version "4.2.11" - resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== -handlebars@^4.7.8: - version "4.7.8" - resolved "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz" - integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== - dependencies: - minimist "^1.2.5" - neo-async "^2.6.2" - source-map "^0.6.1" - wordwrap "^1.0.0" - optionalDependencies: - uglify-js "^3.1.4" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz" - integrity sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg== - dependencies: - ansi-regex "^2.0.0" - has-flag@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== has-flag@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== hasown@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== dependencies: function-bind "^1.1.2" html-escaper@^2.0.0: version "2.0.2" - resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== http-proxy-agent@^7.0.0, http-proxy-agent@^7.0.1: version "7.0.2" - resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz#9a8b1f246866c028509486585f62b8f2c18c270e" integrity sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig== dependencies: agent-base "^7.1.0" debug "^4.3.4" -https-proxy-agent@^7.0.6: - version "7.0.6" - resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz" - integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw== +https-proxy-agent@^7.0.3, https-proxy-agent@^7.0.5: + version "7.0.5" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz#9e8b5013873299e11fab6fd548405da2d6c602b2" + integrity sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw== dependencies: - agent-base "^7.1.2" + agent-base "^7.0.2" debug "4" human-signals@^1.1.1: version "1.1.1" - resolved "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== human-signals@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== husky@6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/husky/-/husky-6.0.0.tgz" + resolved "https://registry.yarnpkg.com/husky/-/husky-6.0.0.tgz#810f11869adf51604c32ea577edbc377d7f9319e" integrity sha512-SQS2gDTB7tBN486QSoKPKQItZw97BMOd+Kdb6ghfpBc0yXyzrddI0oDV5MkDAbuB4X2mO3/nj60TRMcYxwzZeQ== +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + import-fresh@^3.2.1, import-fresh@^3.3.0: - version "3.3.1" - resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz" - integrity sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ== + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" resolve-from "^4.0.0" -import-local@^3.2.0: +import-local@^3.0.2: version "3.2.0" - resolved "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.2.0.tgz#c3d5c745798c02a6f8b897726aba5100186ee260" integrity sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA== dependencies: pkg-dir "^4.2.0" @@ -1819,17 +1559,17 @@ import-local@^3.2.0: imurmurhash@^0.1.4: version "0.1.4" - resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== indent-string@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== inflight@^1.0.4: version "1.0.6" - resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: once "^1.3.0" @@ -1837,583 +1577,556 @@ inflight@^1.0.4: inherits@2: version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -ip-address@^10.0.1: - version "10.1.0" - resolved "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz" - integrity sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q== +ip-address@^9.0.5: + version "9.0.5" + resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-9.0.5.tgz#117a960819b08780c3bd1f14ef3c1cc1d3f3ea5a" + integrity sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g== + dependencies: + jsbn "1.1.0" + sprintf-js "^1.1.3" is-arrayish@^0.2.1: version "0.2.1" - resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== -is-core-module@^2.16.1: - version "2.16.1" - resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz" - integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== +is-core-module@^2.13.0: + version "2.15.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.1.tgz#a7363a25bee942fefab0de13bf6aa372c82dcc37" + integrity sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ== dependencies: hasown "^2.0.2" is-fullwidth-code-point@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-generator-fn@^2.1.0: +is-generator-fn@^2.0.0: version "2.1.0" - resolved "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== is-number@^7.0.0: version "7.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== is-obj@^1.0.1: version "1.0.1" - resolved "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg== is-regexp@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" integrity sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA== is-stream@^2.0.0: version "2.0.1" - resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== is-unicode-supported@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== isexe@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.2" - resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== -istanbul-lib-instrument@^6.0.0, istanbul-lib-instrument@^6.0.2: - version "6.0.3" - resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz" - integrity sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q== +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== dependencies: - "@babel/core" "^7.23.9" - "@babel/parser" "^7.23.9" - "@istanbuljs/schema" "^0.1.3" + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" istanbul-lib-coverage "^3.2.0" - semver "^7.5.4" + semver "^6.3.0" istanbul-lib-report@^3.0.0: version "3.0.1" - resolved "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== dependencies: istanbul-lib-coverage "^3.0.0" make-dir "^4.0.0" supports-color "^7.1.0" -istanbul-lib-source-maps@^5.0.0: - version "5.0.6" - resolved "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz" - integrity sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A== +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== dependencies: - "@jridgewell/trace-mapping" "^0.3.23" debug "^4.1.1" istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" istanbul-reports@^3.1.3: - version "3.2.0" - resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz" - integrity sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA== + version "3.1.7" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.7.tgz#daed12b9e1dca518e15c056e1e537e741280fa0b" + integrity sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jackspeak@^3.1.2: - version "3.4.3" - resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz" - integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== - dependencies: - "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" - -jest-changed-files@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.2.0.tgz" - integrity sha512-L8lR1ChrRnSdfeOvTrwZMlnWV8G/LLjQ0nG9MBclwWZidA2N5FviRki0Bvh20WRMOX31/JYvzdqTJrk5oBdydQ== +jest-changed-files@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-28.1.3.tgz#d9aeee6792be3686c47cb988a8eaf82ff4238831" + integrity sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA== dependencies: - execa "^5.1.1" - jest-util "30.2.0" + execa "^5.0.0" p-limit "^3.1.0" -jest-circus@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-circus/-/jest-circus-30.2.0.tgz" - integrity sha512-Fh0096NC3ZkFx05EP2OXCxJAREVxj1BcW/i6EWqqymcgYKWjyyDpral3fMxVcHXg6oZM7iULer9wGRFvfpl+Tg== +jest-circus@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-28.1.3.tgz#d14bd11cf8ee1a03d69902dc47b6bd4634ee00e4" + integrity sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow== dependencies: - "@jest/environment" "30.2.0" - "@jest/expect" "30.2.0" - "@jest/test-result" "30.2.0" - "@jest/types" "30.2.0" + "@jest/environment" "^28.1.3" + "@jest/expect" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" "@types/node" "*" - chalk "^4.1.2" + chalk "^4.0.0" co "^4.6.0" - dedent "^1.6.0" - is-generator-fn "^2.1.0" - jest-each "30.2.0" - jest-matcher-utils "30.2.0" - jest-message-util "30.2.0" - jest-runtime "30.2.0" - jest-snapshot "30.2.0" - jest-util "30.2.0" + dedent "^0.7.0" + is-generator-fn "^2.0.0" + jest-each "^28.1.3" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-runtime "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" p-limit "^3.1.0" - pretty-format "30.2.0" - pure-rand "^7.0.0" + pretty-format "^28.1.3" slash "^3.0.0" - stack-utils "^2.0.6" - -jest-cli@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-cli/-/jest-cli-30.2.0.tgz" - integrity sha512-Os9ukIvADX/A9sLt6Zse3+nmHtHaE6hqOsjQtNiugFTbKRHYIYtZXNGNK9NChseXy7djFPjndX1tL0sCTlfpAA== - dependencies: - "@jest/core" "30.2.0" - "@jest/test-result" "30.2.0" - "@jest/types" "30.2.0" - chalk "^4.1.2" - exit-x "^0.2.2" - import-local "^3.2.0" - jest-config "30.2.0" - jest-util "30.2.0" - jest-validate "30.2.0" - yargs "^17.7.2" + stack-utils "^2.0.3" -jest-config@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-config/-/jest-config-30.2.0.tgz" - integrity sha512-g4WkyzFQVWHtu6uqGmQR4CQxz/CH3yDSlhzXMWzNjDx843gYjReZnMRanjRCq5XZFuQrGDxgUaiYWE8BRfVckA== - dependencies: - "@babel/core" "^7.27.4" - "@jest/get-type" "30.1.0" - "@jest/pattern" "30.0.1" - "@jest/test-sequencer" "30.2.0" - "@jest/types" "30.2.0" - babel-jest "30.2.0" - chalk "^4.1.2" - ci-info "^4.2.0" - deepmerge "^4.3.1" - glob "^10.3.10" - graceful-fs "^4.2.11" - jest-circus "30.2.0" - jest-docblock "30.2.0" - jest-environment-node "30.2.0" - jest-regex-util "30.0.1" - jest-resolve "30.2.0" - jest-runner "30.2.0" - jest-util "30.2.0" - jest-validate "30.2.0" - micromatch "^4.0.8" +jest-cli@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-28.1.3.tgz#558b33c577d06de55087b8448d373b9f654e46b2" + integrity sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ== + dependencies: + "@jest/core" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" + prompts "^2.0.1" + yargs "^17.3.1" + +jest-config@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-28.1.3.tgz#e315e1f73df3cac31447eed8b8740a477392ec60" + integrity sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ== + dependencies: + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^28.1.3" + "@jest/types" "^28.1.3" + babel-jest "^28.1.3" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-circus "^28.1.3" + jest-environment-node "^28.1.3" + jest-get-type "^28.0.2" + jest-regex-util "^28.0.2" + jest-resolve "^28.1.3" + jest-runner "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" + micromatch "^4.0.4" parse-json "^5.2.0" - pretty-format "30.2.0" + pretty-format "^28.1.3" slash "^3.0.0" strip-json-comments "^3.1.1" -jest-diff@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz" - integrity sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A== - dependencies: - "@jest/diff-sequences" "30.0.1" - "@jest/get-type" "30.1.0" - chalk "^4.1.2" - pretty-format "30.2.0" - -jest-diff@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz" - integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== +jest-diff@^26.0.0: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" + integrity sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA== dependencies: chalk "^4.0.0" - diff-sequences "^29.6.3" - jest-get-type "^29.6.3" - pretty-format "^29.7.0" + diff-sequences "^26.6.2" + jest-get-type "^26.3.0" + pretty-format "^26.6.2" -jest-docblock@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.2.0.tgz" - integrity sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA== +jest-diff@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-28.1.3.tgz#948a192d86f4e7a64c5264ad4da4877133d8792f" + integrity sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw== dependencies: - detect-newline "^3.1.0" + chalk "^4.0.0" + diff-sequences "^28.1.1" + jest-get-type "^28.0.2" + pretty-format "^28.1.3" jest-docblock@^21.0.0: version "21.2.0" - resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-21.2.0.tgz" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414" integrity sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw== -jest-each@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-each/-/jest-each-30.2.0.tgz" - integrity sha512-lpWlJlM7bCUf1mfmuqTA8+j2lNURW9eNafOy99knBM01i5CQeY5UH1vZjgT9071nDJac1M4XsbyI44oNOdhlDQ== - dependencies: - "@jest/get-type" "30.1.0" - "@jest/types" "30.2.0" - chalk "^4.1.2" - jest-util "30.2.0" - pretty-format "30.2.0" - -jest-environment-node@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.2.0.tgz" - integrity sha512-ElU8v92QJ9UrYsKrxDIKCxu6PfNj4Hdcktcn0JX12zqNdqWHB0N+hwOnnBBXvjLd2vApZtuLUGs1QSY+MsXoNA== - dependencies: - "@jest/environment" "30.2.0" - "@jest/fake-timers" "30.2.0" - "@jest/types" "30.2.0" - "@types/node" "*" - jest-mock "30.2.0" - jest-util "30.2.0" - jest-validate "30.2.0" - -jest-get-type@^29.6.3: - version "29.6.3" - resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz" - integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== +jest-docblock@^28.1.1: + version "28.1.1" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-28.1.1.tgz#6f515c3bf841516d82ecd57a62eed9204c2f42a8" + integrity sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA== + dependencies: + detect-newline "^3.0.0" -jest-haste-map@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.2.0.tgz" - integrity sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw== +jest-each@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-28.1.3.tgz#bdd1516edbe2b1f3569cfdad9acd543040028f81" + integrity sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g== dependencies: - "@jest/types" "30.2.0" + "@jest/types" "^28.1.3" + chalk "^4.0.0" + jest-get-type "^28.0.2" + jest-util "^28.1.3" + pretty-format "^28.1.3" + +jest-environment-node@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-28.1.3.tgz#7e74fe40eb645b9d56c0c4b70ca4357faa349be5" + integrity sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A== + dependencies: + "@jest/environment" "^28.1.3" + "@jest/fake-timers" "^28.1.3" + "@jest/types" "^28.1.3" "@types/node" "*" - anymatch "^3.1.3" - fb-watchman "^2.0.2" - graceful-fs "^4.2.11" - jest-regex-util "30.0.1" - jest-util "30.2.0" - jest-worker "30.2.0" - micromatch "^4.0.8" + jest-mock "^28.1.3" + jest-util "^28.1.3" + +jest-get-type@^26.3.0: + version "26.3.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" + integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== + +jest-get-type@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-28.0.2.tgz#34622e628e4fdcd793d46db8a242227901fcf203" + integrity sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA== + +jest-haste-map@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-28.1.3.tgz#abd5451129a38d9841049644f34b034308944e2b" + integrity sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA== + dependencies: + "@jest/types" "^28.1.3" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^28.0.2" + jest-util "^28.1.3" + jest-worker "^28.1.3" + micromatch "^4.0.4" walker "^1.0.8" optionalDependencies: - fsevents "^2.3.3" - -jest-leak-detector@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.2.0.tgz" - integrity sha512-M6jKAjyzjHG0SrQgwhgZGy9hFazcudwCNovY/9HPIicmNSBuockPSedAP9vlPK6ONFJ1zfyH/M2/YYJxOz5cdQ== - dependencies: - "@jest/get-type" "30.1.0" - pretty-format "30.2.0" + fsevents "^2.3.2" -jest-matcher-utils@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz" - integrity sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg== +jest-leak-detector@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz#a6685d9b074be99e3adee816ce84fd30795e654d" + integrity sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA== dependencies: - "@jest/get-type" "30.1.0" - chalk "^4.1.2" - jest-diff "30.2.0" - pretty-format "30.2.0" + jest-get-type "^28.0.2" + pretty-format "^28.1.3" -jest-matcher-utils@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz" - integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== +jest-matcher-utils@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz#5a77f1c129dd5ba3b4d7fc20728806c78893146e" + integrity sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw== dependencies: chalk "^4.0.0" - jest-diff "^29.7.0" - jest-get-type "^29.6.3" - pretty-format "^29.7.0" - -jest-message-util@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz" - integrity sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw== - dependencies: - "@babel/code-frame" "^7.27.1" - "@jest/types" "30.2.0" - "@types/stack-utils" "^2.0.3" - chalk "^4.1.2" - graceful-fs "^4.2.11" - micromatch "^4.0.8" - pretty-format "30.2.0" - slash "^3.0.0" - stack-utils "^2.0.6" + jest-diff "^28.1.3" + jest-get-type "^28.0.2" + pretty-format "^28.1.3" -jest-message-util@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz" - integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== +jest-message-util@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.1.3.tgz#232def7f2e333f1eecc90649b5b94b0055e7c43d" + integrity sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.6.3" + "@jest/types" "^28.1.3" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^29.7.0" + pretty-format "^28.1.3" slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz" - integrity sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw== +jest-mock@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-28.1.3.tgz#d4e9b1fc838bea595c77ab73672ebf513ab249da" + integrity sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA== dependencies: - "@jest/types" "30.2.0" + "@jest/types" "^28.1.3" "@types/node" "*" - jest-util "30.2.0" -jest-pnp-resolver@^1.2.3: +jest-pnp-resolver@^1.2.2: version "1.2.3" - resolved "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== -jest-regex-util@30.0.1: - version "30.0.1" - resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz" - integrity sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA== - -jest-resolve-dependencies@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.2.0.tgz" - integrity sha512-xTOIGug/0RmIe3mmCqCT95yO0vj6JURrn1TKWlNbhiAefJRWINNPgwVkrVgt/YaerPzY3iItufd80v3lOrFJ2w== - dependencies: - jest-regex-util "30.0.1" - jest-snapshot "30.2.0" - -jest-resolve@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.2.0.tgz" - integrity sha512-TCrHSxPlx3tBY3hWNtRQKbtgLhsXa1WmbJEqBlTBrGafd5fiQFByy2GNCEoGR+Tns8d15GaL9cxEzKOO3GEb2A== - dependencies: - chalk "^4.1.2" - graceful-fs "^4.2.11" - jest-haste-map "30.2.0" - jest-pnp-resolver "^1.2.3" - jest-util "30.2.0" - jest-validate "30.2.0" +jest-regex-util@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-28.0.2.tgz#afdc377a3b25fb6e80825adcf76c854e5bf47ead" + integrity sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw== + +jest-resolve-dependencies@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz#8c65d7583460df7275c6ea2791901fa975c1fe66" + integrity sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA== + dependencies: + jest-regex-util "^28.0.2" + jest-snapshot "^28.1.3" + +jest-resolve@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-28.1.3.tgz#cfb36100341ddbb061ec781426b3c31eb51aa0a8" + integrity sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ== + dependencies: + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" + jest-pnp-resolver "^1.2.2" + jest-util "^28.1.3" + jest-validate "^28.1.3" + resolve "^1.20.0" + resolve.exports "^1.1.0" slash "^3.0.0" - unrs-resolver "^1.7.11" - -jest-runner@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-runner/-/jest-runner-30.2.0.tgz" - integrity sha512-PqvZ2B2XEyPEbclp+gV6KO/F1FIFSbIwewRgmROCMBo/aZ6J1w8Qypoj2pEOcg3G2HzLlaP6VUtvwCI8dM3oqQ== - dependencies: - "@jest/console" "30.2.0" - "@jest/environment" "30.2.0" - "@jest/test-result" "30.2.0" - "@jest/transform" "30.2.0" - "@jest/types" "30.2.0" + +jest-runner@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-28.1.3.tgz#5eee25febd730b4713a2cdfd76bdd5557840f9a1" + integrity sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA== + dependencies: + "@jest/console" "^28.1.3" + "@jest/environment" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" "@types/node" "*" - chalk "^4.1.2" - emittery "^0.13.1" - exit-x "^0.2.2" - graceful-fs "^4.2.11" - jest-docblock "30.2.0" - jest-environment-node "30.2.0" - jest-haste-map "30.2.0" - jest-leak-detector "30.2.0" - jest-message-util "30.2.0" - jest-resolve "30.2.0" - jest-runtime "30.2.0" - jest-util "30.2.0" - jest-watcher "30.2.0" - jest-worker "30.2.0" + chalk "^4.0.0" + emittery "^0.10.2" + graceful-fs "^4.2.9" + jest-docblock "^28.1.1" + jest-environment-node "^28.1.3" + jest-haste-map "^28.1.3" + jest-leak-detector "^28.1.3" + jest-message-util "^28.1.3" + jest-resolve "^28.1.3" + jest-runtime "^28.1.3" + jest-util "^28.1.3" + jest-watcher "^28.1.3" + jest-worker "^28.1.3" p-limit "^3.1.0" source-map-support "0.5.13" -jest-runtime@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.2.0.tgz" - integrity sha512-p1+GVX/PJqTucvsmERPMgCPvQJpFt4hFbM+VN3n8TMo47decMUcJbt+rgzwrEme0MQUA/R+1de2axftTHkKckg== - dependencies: - "@jest/environment" "30.2.0" - "@jest/fake-timers" "30.2.0" - "@jest/globals" "30.2.0" - "@jest/source-map" "30.0.1" - "@jest/test-result" "30.2.0" - "@jest/transform" "30.2.0" - "@jest/types" "30.2.0" - "@types/node" "*" - chalk "^4.1.2" - cjs-module-lexer "^2.1.0" - collect-v8-coverage "^1.0.2" - glob "^10.3.10" - graceful-fs "^4.2.11" - jest-haste-map "30.2.0" - jest-message-util "30.2.0" - jest-mock "30.2.0" - jest-regex-util "30.0.1" - jest-resolve "30.2.0" - jest-snapshot "30.2.0" - jest-util "30.2.0" +jest-runtime@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-28.1.3.tgz#a57643458235aa53e8ec7821949e728960d0605f" + integrity sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw== + dependencies: + "@jest/environment" "^28.1.3" + "@jest/fake-timers" "^28.1.3" + "@jest/globals" "^28.1.3" + "@jest/source-map" "^28.1.2" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + execa "^5.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" + jest-message-util "^28.1.3" + jest-mock "^28.1.3" + jest-regex-util "^28.0.2" + jest-resolve "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" slash "^3.0.0" strip-bom "^4.0.0" -jest-snapshot@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.2.0.tgz" - integrity sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA== - dependencies: - "@babel/core" "^7.27.4" - "@babel/generator" "^7.27.5" - "@babel/plugin-syntax-jsx" "^7.27.1" - "@babel/plugin-syntax-typescript" "^7.27.1" - "@babel/types" "^7.27.3" - "@jest/expect-utils" "30.2.0" - "@jest/get-type" "30.1.0" - "@jest/snapshot-utils" "30.2.0" - "@jest/transform" "30.2.0" - "@jest/types" "30.2.0" - babel-preset-current-node-syntax "^1.2.0" - chalk "^4.1.2" - expect "30.2.0" - graceful-fs "^4.2.11" - jest-diff "30.2.0" - jest-matcher-utils "30.2.0" - jest-message-util "30.2.0" - jest-util "30.2.0" - pretty-format "30.2.0" - semver "^7.7.2" - synckit "^0.11.8" - -jest-util@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz" - integrity sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA== - dependencies: - "@jest/types" "30.2.0" - "@types/node" "*" - chalk "^4.1.2" - ci-info "^4.2.0" - graceful-fs "^4.2.11" - picomatch "^4.0.2" +jest-snapshot@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-28.1.3.tgz#17467b3ab8ddb81e2f605db05583d69388fc0668" + integrity sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg== + dependencies: + "@babel/core" "^7.11.6" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.3.3" + "@jest/expect-utils" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/babel__traverse" "^7.0.6" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^28.1.3" + graceful-fs "^4.2.9" + jest-diff "^28.1.3" + jest-get-type "^28.0.2" + jest-haste-map "^28.1.3" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + natural-compare "^1.4.0" + pretty-format "^28.1.3" + semver "^7.3.5" -jest-util@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz" - integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== +jest-util@^28.0.0, jest-util@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.1.3.tgz#f4f932aa0074f0679943220ff9cbba7e497028b0" + integrity sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ== dependencies: - "@jest/types" "^29.6.3" + "@jest/types" "^28.1.3" "@types/node" "*" chalk "^4.0.0" ci-info "^3.2.0" graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-validate@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-validate/-/jest-validate-30.2.0.tgz" - integrity sha512-FBGWi7dP2hpdi8nBoWxSsLvBFewKAg0+uSQwBaof4Y4DPgBabXgpSYC5/lR7VmnIlSpASmCi/ntRWPbv7089Pw== +jest-validate@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-28.1.3.tgz#e322267fd5e7c64cea4629612c357bbda96229df" + integrity sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA== dependencies: - "@jest/get-type" "30.1.0" - "@jest/types" "30.2.0" - camelcase "^6.3.0" - chalk "^4.1.2" + "@jest/types" "^28.1.3" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^28.0.2" leven "^3.1.0" - pretty-format "30.2.0" + pretty-format "^28.1.3" -jest-watcher@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.2.0.tgz" - integrity sha512-PYxa28dxJ9g777pGm/7PrbnMeA0Jr7osHP9bS7eJy9DuAjMgdGtxgf0uKMyoIsTWAkIbUW5hSDdJ3urmgXBqxg== +jest-watcher@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-28.1.3.tgz#c6023a59ba2255e3b4c57179fc94164b3e73abd4" + integrity sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g== dependencies: - "@jest/test-result" "30.2.0" - "@jest/types" "30.2.0" + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" "@types/node" "*" - ansi-escapes "^4.3.2" - chalk "^4.1.2" - emittery "^0.13.1" - jest-util "30.2.0" - string-length "^4.0.2" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.10.2" + jest-util "^28.1.3" + string-length "^4.0.1" -jest-worker@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz" - integrity sha512-0Q4Uk8WF7BUwqXHuAjc23vmopWJw5WH7w2tqBoUOZpOjW/ZnR44GXXd1r82RvnmI2GZge3ivrYXk/BE2+VtW2g== +jest-worker@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-28.1.3.tgz#7e3c4ce3fa23d1bb6accb169e7f396f98ed4bb98" + integrity sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g== dependencies: "@types/node" "*" - "@ungap/structured-clone" "^1.3.0" - jest-util "30.2.0" merge-stream "^2.0.0" - supports-color "^8.1.1" + supports-color "^8.0.0" -jest@^30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/jest/-/jest-30.2.0.tgz" - integrity sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A== +jest@^28.1.0: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest/-/jest-28.1.3.tgz#e9c6a7eecdebe3548ca2b18894a50f45b36dfc6b" + integrity sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA== dependencies: - "@jest/core" "30.2.0" - "@jest/types" "30.2.0" - import-local "^3.2.0" - jest-cli "30.2.0" - -js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz" - integrity sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg== + "@jest/core" "^28.1.3" + "@jest/types" "^28.1.3" + import-local "^3.0.2" + jest-cli "^28.1.3" js-tokens@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-yaml@^3.13.1: - version "3.14.2" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz" - integrity sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg== + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== dependencies: argparse "^1.0.7" esprima "^4.0.0" js-yaml@^4.1.0: - version "4.1.1" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz" - integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: argparse "^2.0.1" +jsbn@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040" + integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A== + jsesc@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz" - integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== + version "3.0.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e" + integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g== json-parse-even-better-errors@^2.3.0: version "2.3.1" - resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== -json5@^2.2.3: +json5@^2.2.1, json5@^2.2.3: version "2.2.3" - resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + leven@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== lines-and-columns@^1.1.6: version "1.2.4" - resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== lint-staged@10.5.4: version "10.5.4" - resolved "https://registry.npmjs.org/lint-staged/-/lint-staged-10.5.4.tgz" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-10.5.4.tgz#cd153b5f0987d2371fc1d2847a409a2fe705b665" integrity sha512-EechC3DdFic/TdOPgj/RB3FicqE6932LTHCUm0Y2fsD9KGlLB+RwJl2q1IYBIvEsKzDOgn0D4gll+YxG5RsrKg== dependencies: chalk "^4.1.0" @@ -2434,7 +2147,7 @@ lint-staged@10.5.4: listr2@^3.2.2: version "3.14.0" - resolved "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-3.14.0.tgz#23101cc62e1375fd5836b248276d1d2b51fdbe9e" integrity sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g== dependencies: cli-truncate "^2.1.0" @@ -2448,19 +2161,19 @@ listr2@^3.2.2: locate-path@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== dependencies: p-locate "^4.1.0" -lodash.memoize@^4.1.2: +lodash.memoize@4.x: version "4.1.2" - resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== log-symbols@^4.0.0: version "4.1.0" - resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== dependencies: chalk "^4.1.0" @@ -2468,7 +2181,7 @@ log-symbols@^4.0.0: log-update@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== dependencies: ansi-escapes "^4.3.0" @@ -2476,50 +2189,45 @@ log-update@^4.0.0: slice-ansi "^4.0.0" wrap-ansi "^6.2.0" -lru-cache@^10.2.0: - version "10.4.3" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz" - integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== - lru-cache@^5.1.1: version "5.1.1" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== dependencies: yallist "^3.0.2" lru-cache@^7.14.1: version "7.18.3" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== make-dir@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== dependencies: semver "^7.5.3" -make-error@^1.3.6: +make-error@1.x: version "1.3.6" - resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== makeerror@1.0.12: version "1.0.12" - resolved "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== dependencies: tmpl "1.0.5" merge-stream@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.8: +micromatch@^4.0.2, micromatch@^4.0.4: version "4.0.8" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== dependencies: braces "^3.0.3" @@ -2527,169 +2235,149 @@ micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.8: mimic-fn@^2.1.0: version "2.1.0" - resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== minimatch@^3.0.4, minimatch@^3.1.1: version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" -minimatch@^9.0.4: - version "9.0.5" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz" - integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== - dependencies: - brace-expansion "^2.0.1" - -minimist@^1.2.5: +minimist@^1.2.6: version "1.2.8" - resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2: - version "7.1.2" - resolved "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz" - integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== - -mitt@^3.0.1: +mitt@3.0.1: version "3.0.1" - resolved "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz" + resolved "https://registry.yarnpkg.com/mitt/-/mitt-3.0.1.tgz#ea36cf0cc30403601ae074c8f77b7092cdab36d1" integrity sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw== +mkdirp@^0.5.3: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + ms@^2.1.3: version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -napi-postinstall@^0.3.0: - version "0.3.4" - resolved "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz" - integrity sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ== - natural-compare@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -neo-async@^2.6.2: - version "2.6.2" - resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - netmask@^2.0.2: version "2.0.2" - resolved "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7" integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg== node-int64@^0.4.0: version "0.4.0" - resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -node-releases@^2.0.27: - version "2.0.27" - resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz" - integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== +node-releases@^2.0.18: + version "2.0.18" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f" + integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g== normalize-path@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== npm-run-path@^4.0.0, npm-run-path@^4.0.1: version "4.0.1" - resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: path-key "^3.0.0" once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" - resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" - resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: mimic-fn "^2.1.0" p-limit@^2.2.0: version "2.3.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" p-limit@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" p-locate@^4.1.0: version "4.1.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== dependencies: p-limit "^2.2.0" p-map@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== dependencies: aggregate-error "^3.0.0" p-try@^2.0.0: version "2.2.0" - resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== -pac-proxy-agent@^7.1.0: - version "7.2.0" - resolved "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz" - integrity sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA== +pac-proxy-agent@^7.0.1: + version "7.0.2" + resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz#0fb02496bd9fb8ae7eb11cfd98386daaac442f58" + integrity sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg== dependencies: "@tootallnate/quickjs-emscripten" "^0.23.0" - agent-base "^7.1.2" + agent-base "^7.0.2" debug "^4.3.4" get-uri "^6.0.1" http-proxy-agent "^7.0.0" - https-proxy-agent "^7.0.6" + https-proxy-agent "^7.0.5" pac-resolver "^7.0.1" - socks-proxy-agent "^8.0.5" + socks-proxy-agent "^8.0.4" pac-resolver@^7.0.1: version "7.0.1" - resolved "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz" + resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-7.0.1.tgz#54675558ea368b64d210fd9c92a640b5f3b8abb6" integrity sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg== dependencies: degenerator "^5.0.0" netmask "^2.0.2" -package-json-from-dist@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz" - integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== - parent-module@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== dependencies: callsites "^3.0.0" parse-json@^5.0.0, parse-json@^5.2.0: version "5.2.0" - resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== dependencies: "@babel/code-frame" "^7.0.0" @@ -2699,200 +2387,206 @@ parse-json@^5.0.0, parse-json@^5.2.0: path-exists@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== path-is-absolute@^1.0.0: version "1.0.1" - resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== path-parse@^1.0.7: version "1.0.7" - resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-scurry@^1.11.1: - version "1.11.1" - resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz" - integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== - dependencies: - lru-cache "^10.2.0" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - path-type@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== pend@~1.2.0: version "1.2.0" - resolved "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== -picocolors@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz" - integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== +picocolors@^1.0.0, picocolors@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.0.tgz#5358b76a78cde483ba5cef6a9dc9671440b27d59" + integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw== picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== -picomatch@^4.0.2: - version "4.0.3" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz" - integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== - -pirates@^4.0.7: - version "4.0.7" - resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz" - integrity sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA== +pirates@^4.0.4: + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== pkg-dir@^4.2.0: version "4.2.0" - resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== dependencies: find-up "^4.0.0" please-upgrade-node@^3.2.0: version "3.2.0" - resolved "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg== dependencies: semver-compare "^1.0.0" prettier@2.6.2: version "2.6.2" - resolved "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.6.2.tgz#e26d71a18a74c3d0f0597f55f01fb6c06c206032" integrity sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew== -pretty-format@30.2.0: - version "30.2.0" - resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz" - integrity sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA== +pretty-format@^26.0.0, pretty-format@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" + integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== dependencies: - "@jest/schemas" "30.0.5" - ansi-styles "^5.2.0" - react-is "^18.3.1" + "@jest/types" "^26.6.2" + ansi-regex "^5.0.0" + ansi-styles "^4.0.0" + react-is "^17.0.1" -pretty-format@^29.0.0, pretty-format@^29.7.0: - version "29.7.0" - resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz" - integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== +pretty-format@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.1.3.tgz#c9fba8cedf99ce50963a11b27d982a9ae90970d5" + integrity sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q== dependencies: - "@jest/schemas" "^29.6.3" + "@jest/schemas" "^28.1.3" + ansi-regex "^5.0.1" ansi-styles "^5.0.0" react-is "^18.0.0" progress@^2.0.3: version "2.0.3" - resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -proxy-agent@^6.5.0: - version "6.5.0" - resolved "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz" - integrity sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A== +prompts@^2.0.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +proxy-agent@^6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-6.4.0.tgz#b4e2dd51dee2b377748aef8d45604c2d7608652d" + integrity sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ== dependencies: - agent-base "^7.1.2" + agent-base "^7.0.2" debug "^4.3.4" http-proxy-agent "^7.0.1" - https-proxy-agent "^7.0.6" + https-proxy-agent "^7.0.3" lru-cache "^7.14.1" - pac-proxy-agent "^7.1.0" + pac-proxy-agent "^7.0.1" proxy-from-env "^1.1.0" - socks-proxy-agent "^8.0.5" + socks-proxy-agent "^8.0.2" proxy-from-env@^1.1.0: version "1.1.0" - resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== pump@^3.0.0: - version "3.0.3" - resolved "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz" - integrity sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA== + version "3.0.2" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.2.tgz#836f3edd6bc2ee599256c924ffe0d88573ddcbf8" + integrity sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw== dependencies: end-of-stream "^1.1.0" once "^1.3.1" -puppeteer-core@24.30.0: - version "24.30.0" - resolved "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.30.0.tgz" - integrity sha512-2S3Smy0t0W4wJnNvDe7W0bE7wDmZjfZ3ljfMgJd6hn2Hq/f0jgN+x9PULZo2U3fu5UUIJ+JP8cNUGllu8P91Pg== +puppeteer-core@23.5.0: + version "23.5.0" + resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-23.5.0.tgz#f7fb015f0a39b2d85f54df10864c0761b05953db" + integrity sha512-+5ed+625GuQ2emRHqYec8khT9LP14FWzv8hYl0HiM6hnnlNzdVU9uDJIPHeCPLIWxq15ost9MeF8kBk4R3eiFw== dependencies: - "@puppeteer/browsers" "2.10.13" - chromium-bidi "11.0.0" - debug "^4.4.3" - devtools-protocol "0.0.1521046" + "@puppeteer/browsers" "2.4.0" + chromium-bidi "0.8.0" + debug "^4.3.7" + devtools-protocol "0.0.1342118" typed-query-selector "^2.12.0" - webdriver-bidi-protocol "0.3.8" - ws "^8.18.3" + ws "^8.18.0" -puppeteer@^24.0.0: - version "24.30.0" - resolved "https://registry.npmjs.org/puppeteer/-/puppeteer-24.30.0.tgz" - integrity sha512-A5OtCi9WpiXBQgJ2vQiZHSyrAzQmO/WDsvghqlN4kgw21PhxA5knHUaUQq/N3EMt8CcvSS0RM+kmYLJmedR3TQ== +puppeteer@^23.0.0: + version "23.5.0" + resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-23.5.0.tgz#5cafaff6181beb930567c860482eccfe79dad3a8" + integrity sha512-jnUx5M0YtFva7vXr39qqsxgB46JiwXJavuM1Hgsqbd9WWiGTEUt9klGpTxyHi+ZQf3NUgleDhNsnI10IK8Ebsg== dependencies: - "@puppeteer/browsers" "2.10.13" - chromium-bidi "11.0.0" + "@puppeteer/browsers" "2.4.0" + chromium-bidi "0.8.0" cosmiconfig "^9.0.0" - devtools-protocol "0.0.1521046" - puppeteer-core "24.30.0" + devtools-protocol "0.0.1342118" + puppeteer-core "23.5.0" typed-query-selector "^2.12.0" -pure-rand@^7.0.0: - version "7.0.1" - resolved "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz" - integrity sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ== +queue-tick@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/queue-tick/-/queue-tick-1.0.1.tgz#f6f07ac82c1fd60f82e098b417a80e52f1f4c142" + integrity sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag== + +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-is@^18.0.0, react-is@^18.3.1: +react-is@^18.0.0: version "18.3.1" - resolved "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== require-directory@^2.1.1: version "2.1.1" - resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== resolve-cwd@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== dependencies: resolve-from "^5.0.0" resolve-from@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== resolve-from@^5.0.0: version "5.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve@^1.3.2: - version "1.22.11" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz" - integrity sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ== +resolve.exports@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.1.tgz#05cfd5b3edf641571fd46fa608b610dda9ead999" + integrity sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ== + +resolve@^1.20.0, resolve@^1.3.2: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== dependencies: - is-core-module "^2.16.1" + is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" restore-cursor@^3.1.0: version "3.1.0" - resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== dependencies: onetime "^5.1.0" @@ -2900,66 +2594,73 @@ restore-cursor@^3.1.0: rfdc@^1.3.0: version "1.4.1" - resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca" integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA== +rimraf@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + rxjs@^7.5.1: - version "7.8.2" - resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz" - integrity sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA== + version "7.8.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== dependencies: tslib "^2.1.0" semver-compare@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow== +semver@7.x, semver@^7.3.5, semver@^7.5.3, semver@^7.6.3: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + semver@^5.3.0: version "5.7.2" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^6.3.1: +semver@^6.3.0, semver@^6.3.1: version "6.3.1" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.5.3, semver@^7.5.4, semver@^7.7.2, semver@^7.7.3: - version "7.7.3" - resolved "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz" - integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== - shebang-command@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== dependencies: shebang-regex "^3.0.0" shebang-regex@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -signal-exit@^3.0.2, signal-exit@^3.0.3: +signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -signal-exit@^4.0.1: - version "4.1.0" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz" - integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== slash@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== slice-ansi@^3.0.0: version "3.0.0" - resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== dependencies: ansi-styles "^4.0.0" @@ -2968,7 +2669,7 @@ slice-ansi@^3.0.0: slice-ansi@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== dependencies: ansi-styles "^4.0.0" @@ -2977,29 +2678,29 @@ slice-ansi@^4.0.0: smart-buffer@^4.2.0: version "4.2.0" - resolved "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== -socks-proxy-agent@^8.0.5: - version "8.0.5" - resolved "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz" - integrity sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw== +socks-proxy-agent@^8.0.2, socks-proxy-agent@^8.0.4: + version "8.0.4" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz#9071dca17af95f483300316f4b063578fa0db08c" + integrity sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw== dependencies: - agent-base "^7.1.2" + agent-base "^7.1.1" debug "^4.3.4" socks "^2.8.3" socks@^2.8.3: - version "2.8.7" - resolved "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz" - integrity sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A== + version "2.8.3" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.3.tgz#1ebd0f09c52ba95a09750afe3f3f9f724a800cb5" + integrity sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw== dependencies: - ip-address "^10.0.1" + ip-address "^9.0.5" smart-buffer "^4.2.0" source-map-support@0.5.13: version "0.5.13" - resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== dependencies: buffer-from "^1.0.0" @@ -3007,167 +2708,155 @@ source-map-support@0.5.13: source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +sprintf-js@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a" + integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA== + sprintf-js@~1.0.2: version "1.0.3" - resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== -stack-utils@^2.0.3, stack-utils@^2.0.6: +stack-utils@^2.0.3: version "2.0.6" - resolved "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== dependencies: escape-string-regexp "^2.0.0" -streamx@^2.15.0, streamx@^2.21.0: - version "2.23.0" - resolved "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz" - integrity sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg== +streamx@^2.15.0, streamx@^2.20.0: + version "2.20.1" + resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.20.1.tgz#471c4f8b860f7b696feb83d5b125caab2fdbb93c" + integrity sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA== dependencies: - events-universal "^1.0.0" fast-fifo "^1.3.2" + queue-tick "^1.0.1" text-decoder "^1.1.0" + optionalDependencies: + bare-events "^2.2.0" string-argv@0.3.1: version "0.3.1" - resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== -string-length@^4.0.2: +string-length@^4.0.1: version "4.0.2" - resolved "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== dependencies: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^5.0.1, string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - stringify-object@^3.3.0: version "3.3.0" - resolved "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== dependencies: get-own-enumerable-property-symbols "^3.0.0" is-obj "^1.0.1" is-regexp "^1.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" -strip-ansi@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" - integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^7.0.1: - version "7.1.2" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz" - integrity sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA== - dependencies: - ansi-regex "^6.0.1" - strip-bom@^4.0.0: version "4.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== strip-final-newline@^2.0.0: version "2.0.0" - resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== strip-json-comments@^3.1.1: version "3.1.1" - resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" - integrity sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g== - supports-color@^5.3.0: version "5.5.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" -supports-color@^7.1.0: +supports-color@^7.0.0, supports-color@^7.1.0: version "7.2.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" -supports-color@^8.1.1: +supports-color@^8.0.0: version "8.1.1" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== dependencies: has-flag "^4.0.0" +supports-hyperlinks@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz#3943544347c1ff90b15effb03fc14ae45ec10624" + integrity sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" + supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" - resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -synckit@^0.11.8: - version "0.11.11" - resolved "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz" - integrity sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw== - dependencies: - "@pkgr/core" "^0.2.9" - -tar-fs@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz" - integrity sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg== +tar-fs@^3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.0.6.tgz#eaccd3a67d5672f09ca8e8f9c3d2b89fa173f217" + integrity sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w== dependencies: pump "^3.0.0" tar-stream "^3.1.5" optionalDependencies: - bare-fs "^4.0.1" - bare-path "^3.0.0" + bare-fs "^2.1.1" + bare-path "^2.1.0" tar-stream@^3.1.5: version "3.1.7" - resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-3.1.7.tgz#24b3fb5eabada19fe7338ed6d26e5f7c482e792b" integrity sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ== dependencies: b4a "^1.6.4" fast-fifo "^1.2.0" streamx "^2.15.0" +terminal-link@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" + integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + test-exclude@^6.0.0: version "6.0.0" - resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== dependencies: "@istanbuljs/schema" "^0.1.2" @@ -3175,160 +2864,152 @@ test-exclude@^6.0.0: minimatch "^3.0.4" text-decoder@^1.1.0: - version "1.2.3" - resolved "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz" - integrity sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA== + version "1.2.0" + resolved "https://registry.yarnpkg.com/text-decoder/-/text-decoder-1.2.0.tgz#85f19d4d5088e0b45cd841bdfaeac458dbffeefc" + integrity sha512-n1yg1mOj9DNpk3NeZOx7T6jchTbyJS3i3cucbNN6FcdPriMZx7NsgrGpWWdWZZGxD7ES1XB+3uoqHMgOKaN+fg== dependencies: b4a "^1.6.4" through@^2.3.8: version "2.3.8" - resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== tmpl@1.0.5: version "1.0.5" - resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + to-regex-range@^5.0.1: version "5.0.1" - resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: is-number "^7.0.0" -ts-jest@^29.2.5: - version "29.4.5" - resolved "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.5.tgz" - integrity sha512-HO3GyiWn2qvTQA4kTgjDcXiMwYQt68a1Y8+JuLRVpdIzm+UOLSHgl/XqR4c6nzJkq5rOkjc02O2I7P7l/Yof0Q== +ts-jest@^28.0.2: + version "28.0.8" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-28.0.8.tgz#cd204b8e7a2f78da32cf6c95c9a6165c5b99cc73" + integrity sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg== dependencies: - bs-logger "^0.2.6" - fast-json-stable-stringify "^2.1.0" - handlebars "^4.7.8" - json5 "^2.2.3" - lodash.memoize "^4.1.2" - make-error "^1.3.6" - semver "^7.7.3" - type-fest "^4.41.0" - yargs-parser "^21.1.1" - -tslib@^1.7.1, tslib@^1.8.1: + bs-logger "0.x" + fast-json-stable-stringify "2.x" + jest-util "^28.0.0" + json5 "^2.2.1" + lodash.memoize "4.x" + make-error "1.x" + semver "7.x" + yargs-parser "^21.0.1" + +tslib@^1.13.0, tslib@^1.7.1, tslib@^1.8.1: version "1.14.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.1, tslib@^2.1.0, tslib@^2.4.0: - version "2.8.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" - integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== +tslib@^2.0.1, tslib@^2.1.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" + integrity sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA== tslint-config-prettier@1.18.0: version "1.18.0" - resolved "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz" + resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz#75f140bde947d35d8f0d238e0ebf809d64592c37" integrity sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg== tslint-plugin-prettier@2.3.0: version "2.3.0" - resolved "https://registry.npmjs.org/tslint-plugin-prettier/-/tslint-plugin-prettier-2.3.0.tgz" + resolved "https://registry.yarnpkg.com/tslint-plugin-prettier/-/tslint-plugin-prettier-2.3.0.tgz#73fe71bf9f03842ac48c104122ca9b1de012ecf4" integrity sha512-F9e4K03yc9xuvv+A0v1EmjcnDwpz8SpCD8HzqSDe0eyg34cBinwn9JjmnnRrNAs4HdleRQj7qijp+P/JTxt4vA== dependencies: eslint-plugin-prettier "^2.2.0" lines-and-columns "^1.1.6" tslib "^1.7.1" -tslint@^5.8.0: - version "5.8.0" - resolved "https://registry.npmjs.org/tslint/-/tslint-5.8.0.tgz" - integrity sha512-2OBP2yqyQ5IsUfCqkhMzT0Knv2a7YMXZizhnSgTiRZulCzUuZcL8FEm2Djoytr5HakyemWbfWyf/U/YoMXccWA== +tslint@6.1.3: + version "6.1.3" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-6.1.3.tgz#5c23b2eccc32487d5523bd3a470e9aa31789d904" + integrity sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg== dependencies: - babel-code-frame "^6.22.0" + "@babel/code-frame" "^7.0.0" builtin-modules "^1.1.1" - chalk "^2.1.0" - commander "^2.9.0" - diff "^3.2.0" + chalk "^2.3.0" + commander "^2.12.1" + diff "^4.0.1" glob "^7.1.1" + js-yaml "^3.13.1" minimatch "^3.0.4" + mkdirp "^0.5.3" resolve "^1.3.2" semver "^5.3.0" - tslib "^1.7.1" - tsutils "^2.12.1" + tslib "^1.13.0" + tsutils "^2.29.0" -tsutils@^2.12.1: +tsutils@^2.29.0: version "2.29.0" - resolved "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== dependencies: tslib "^1.8.1" type-detect@4.0.8: version "4.0.8" - resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== type-fest@^0.21.3: version "0.21.3" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -type-fest@^4.41.0: - version "4.41.0" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz" - integrity sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA== - typed-query-selector@^2.12.0: version "2.12.0" - resolved "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz" + resolved "https://registry.yarnpkg.com/typed-query-selector/-/typed-query-selector-2.12.0.tgz#92b65dbc0a42655fccf4aeb1a08b1dddce8af5f2" integrity sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg== typescript@^4.6.4: version "4.9.5" - resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== -uglify-js@^3.1.4: - version "3.19.3" - resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz" - integrity sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ== - -unrs-resolver@^1.7.11: - version "1.11.1" - resolved "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz" - integrity sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg== +unbzip2-stream@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" + integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== dependencies: - napi-postinstall "^0.3.0" - optionalDependencies: - "@unrs/resolver-binding-android-arm-eabi" "1.11.1" - "@unrs/resolver-binding-android-arm64" "1.11.1" - "@unrs/resolver-binding-darwin-arm64" "1.11.1" - "@unrs/resolver-binding-darwin-x64" "1.11.1" - "@unrs/resolver-binding-freebsd-x64" "1.11.1" - "@unrs/resolver-binding-linux-arm-gnueabihf" "1.11.1" - "@unrs/resolver-binding-linux-arm-musleabihf" "1.11.1" - "@unrs/resolver-binding-linux-arm64-gnu" "1.11.1" - "@unrs/resolver-binding-linux-arm64-musl" "1.11.1" - "@unrs/resolver-binding-linux-ppc64-gnu" "1.11.1" - "@unrs/resolver-binding-linux-riscv64-gnu" "1.11.1" - "@unrs/resolver-binding-linux-riscv64-musl" "1.11.1" - "@unrs/resolver-binding-linux-s390x-gnu" "1.11.1" - "@unrs/resolver-binding-linux-x64-gnu" "1.11.1" - "@unrs/resolver-binding-linux-x64-musl" "1.11.1" - "@unrs/resolver-binding-wasm32-wasi" "1.11.1" - "@unrs/resolver-binding-win32-arm64-msvc" "1.11.1" - "@unrs/resolver-binding-win32-ia32-msvc" "1.11.1" - "@unrs/resolver-binding-win32-x64-msvc" "1.11.1" - -update-browserslist-db@^1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz" - integrity sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A== + buffer "^5.2.1" + through "^2.3.8" + +undici-types@~6.19.2: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" + integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== + +universalify@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== + +update-browserslist-db@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz#80846fba1d79e82547fb661f8d141e0945755fe5" + integrity sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A== dependencies: escalade "^3.2.0" - picocolors "^1.1.1" + picocolors "^1.1.0" + +urlpattern-polyfill@10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz#f0a03a97bfb03cdf33553e5e79a2aadd22cac8ec" + integrity sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg== v8-to-istanbul@^9.0.1: version "9.3.0" - resolved "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz#b9572abfa62bd556c16d75fdebc1a411d5ff3175" integrity sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA== dependencies: "@jridgewell/trace-mapping" "^0.3.12" @@ -3337,96 +3018,77 @@ v8-to-istanbul@^9.0.1: walker@^1.0.8: version "1.0.8" - resolved "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== dependencies: makeerror "1.0.12" -webdriver-bidi-protocol@0.3.8: - version "0.3.8" - resolved "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.3.8.tgz" - integrity sha512-21Yi2GhGntMc671vNBCjiAeEVknXjVRoyu+k+9xOMShu+ZQfpGQwnBqbNz/Sv4GXZ6JmutlPAi2nIJcrymAWuQ== - which@^2.0.1: version "2.0.2" - resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -wordwrap@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz" - integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== - -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^6.2.0: version "6.2.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== dependencies: ansi-styles "^4.0.0" string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" wrappy@1: version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -write-file-atomic@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz" - integrity sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw== +write-file-atomic@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" + integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== dependencies: imurmurhash "^0.1.4" - signal-exit "^4.0.1" + signal-exit "^3.0.7" -ws@^8.18.3: - version "8.18.3" - resolved "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz" - integrity sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg== +ws@^8.18.0: + version "8.18.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" + integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== y18n@^5.0.5: version "5.0.8" - resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== yallist@^3.0.2: version "3.1.1" - resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== yaml@^1.10.0: version "1.10.2" - resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== -yargs-parser@^21.1.1: +yargs-parser@^21.0.1, yargs-parser@^21.1.1: version "21.1.1" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== -yargs@^17.7.2: +yargs@^17.3.1, yargs@^17.7.2: version "17.7.2" - resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== dependencies: cliui "^8.0.1" @@ -3439,7 +3101,7 @@ yargs@^17.7.2: yauzl@^2.10.0: version "2.10.0" - resolved "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz" + resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== dependencies: buffer-crc32 "~0.2.3" @@ -3447,10 +3109,10 @@ yauzl@^2.10.0: yocto-queue@^0.1.0: version "0.1.0" - resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== -zod@^3.24.1: - version "3.25.76" - resolved "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz" - integrity sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ== +zod@3.23.8: + version "3.23.8" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d" + integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g== diff --git a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py index 3bb384c6f..683d30895 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/codefresh.py +++ b/tools/deployment-cli-tools/ch_cli_tools/codefresh.py @@ -240,7 +240,7 @@ def codefresh_steps_from_base_path(base_path, fixed_context=None, include=build_ if app_config and app_config.dependencies and app_config.dependencies.git: for dep in app_config.dependencies.git: - step_name = f"clone_{basename(dep.url).replace('.', '_')}_{dep.branch_tag}_{basename(dockerfile_relative_to_root).replace('.', '_')}" + step_name = f"clone_{basename(dep.url).replace('.', '_')}_{basename(dockerfile_relative_to_root).replace('.', '_')}" steps[CD_STEP_CLONE_DEPENDENCIES]['steps'][step_name] = clone_step_spec(dep, dockerfile_relative_to_root) build = None diff --git a/tools/deployment-cli-tools/ch_cli_tools/configurationgenerator.py b/tools/deployment-cli-tools/ch_cli_tools/configurationgenerator.py index 55253a52c..26eda8e98 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/configurationgenerator.py +++ b/tools/deployment-cli-tools/ch_cli_tools/configurationgenerator.py @@ -39,7 +39,7 @@ def __init__(self, root_paths: List[str], tag: Union[str, int, None] = 'latest', namespace: str = None, templates_path: str = HELM_PATH): assert domain, 'A domain must be specified' self.root_paths = [Path(r) for r in root_paths] - self.tag = str(tag) if tag else None + self.tag = tag if registry and not registry.endswith('/'): self.registry = f'{registry}/' else: @@ -487,7 +487,7 @@ def extract_env_variables_from_values(values, envs=tuple(), prefix=''): newenvs = list(envs) for key, value in values.items(): v = extract_env_variables_from_values( - str(value), envs, f"{prefix}_{key}".replace('-', '_').upper()) + value, envs, f"{prefix}_{key}".replace('-', '_').upper()) if key in ('name', 'port', 'subdomain'): newenvs.extend(v) return newenvs @@ -529,7 +529,8 @@ def hosts_info(values): f"127.0.0.1\t{' '.join('%s.%s' % (values[KEY_APPS][s][KEY_HARNESS][KEY_SERVICE]['name'], values['namespace']) for s in deployments)}") try: - ip = get_cluster_ip() + local = values.get('local', False) + ip = get_cluster_ip(local=local) except: logging.warning('Cannot get cluster ip') ip = "127.0.0.1" diff --git a/tools/deployment-cli-tools/ch_cli_tools/helm.py b/tools/deployment-cli-tools/ch_cli_tools/helm.py index 8e4f90ba9..5d026beaf 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/helm.py +++ b/tools/deployment-cli-tools/ch_cli_tools/helm.py @@ -109,7 +109,7 @@ def __finish_helm_values(self, values): values['local'] = self.local if self.local: try: - values['localIp'] = get_cluster_ip() + values['localIp'] = get_cluster_ip(local=True) except subprocess.TimeoutExpired: logging.warning("Minikube not available") except: diff --git a/tools/deployment-cli-tools/ch_cli_tools/openapi.py b/tools/deployment-cli-tools/ch_cli_tools/openapi.py index dc434d20e..bc3eda816 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/openapi.py +++ b/tools/deployment-cli-tools/ch_cli_tools/openapi.py @@ -93,17 +93,16 @@ def generate_fastapi_server(app_path: pathlib.Path) -> None: def generate_model(base_path=ROOT): get_dependencies() lib_path = f"{base_path}/libraries/models" - template_path = f"{base_path}/tools/deployment-cli-tools/ch_cli_tools/templates/python" # Generate model stuff: use python-flask generator - command = f"java -jar {CODEGEN} generate -i {base_path}/libraries/models/api/openapi.yaml -g python -o \ - {lib_path} --skip-validate-spec -c {base_path}/libraries/models/api/config.json -t {template_path}" + command = f"java -jar {CODEGEN} generate -i {base_path}/libraries/models/api/openapi.yaml -g python-flask -o \ + {lib_path} --skip-validate-spec -c {base_path}/libraries/models/api/config.json" os.system(command) # Generate docs: use python generator tmp_path = f"{lib_path}/tmp" command = f"java -jar {CODEGEN} generate -i {base_path}/libraries/models/api/openapi.yaml -g python -o \ - {tmp_path} --skip-validate-spec -c {base_path}/libraries/models/api/config.json -t {template_path}" + {tmp_path} --skip-validate-spec -c {base_path}/libraries/models/api/config.json" os.system(command) try: source_dir = join(tmp_path, "docs") diff --git a/tools/deployment-cli-tools/ch_cli_tools/skaffold.py b/tools/deployment-cli-tools/ch_cli_tools/skaffold.py index c42b6cad0..e5fa9ea03 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/skaffold.py +++ b/tools/deployment-cli-tools/ch_cli_tools/skaffold.py @@ -90,7 +90,7 @@ def process_build_dockerfile( if app_name is None: app_name = app_name_from_path(basename(dockerfile_path)) app_key = app_name - if app_key in helm_values.apps and ('build' not in helm_values.apps[app_key] or not helm_values.apps[app_key]['build']): + if app_key in helm_values.apps and not helm_values.apps[app_key]['build']: return if app_name in helm_values[KEY_TASK_IMAGES] or app_key in helm_values.apps: context_path = relpath_if(root_path, output_path) if global_context else relpath_if(dockerfile_path, output_path) @@ -173,7 +173,7 @@ def process_build_dockerfile( # app_image_tag, app_relative_to_skaffold, build_requirements) process_build_dockerfile(dockerfile_path, root_path, requirements=guess_build_dependencies_from_dockerfile(dockerfile_path), app_name=app_name) app = apps[app_key] - if 'build' not in app or not app['build']: + if not app['build']: continue if app[KEY_HARNESS][KEY_DEPLOYMENT]['image']: release_config['artifactOverrides']['apps'][app_key] = \ @@ -189,7 +189,7 @@ def process_build_dockerfile( def identify_unicorn_based_main(candidates): import re - gunicorn_pattern = re.compile(r"CLOUDHARNESS_FLASK|gunicorn|CLOUDHARNESS_DJANGO", re.IGNORECASE) + gunicorn_pattern = re.compile(r"gunicorn") # sort candidates, shortest path first for candidate in sorted(candidates, key=lambda x: len(x.split("/"))): dockerfile_path = f"{candidate}/.." @@ -261,7 +261,7 @@ def git_clone_hook(conf: GitDependencyConfig, context_path: str): join(os.path.dirname(os.path.dirname(HERE)), 'clone.sh'), conf.branch_tag, conf.url, - join(context_path, "dependencies", (conf.path + "/" if conf.path else "") + os.path.basename(conf.url).split('.')[0]) + join(context_path, "dependencies", conf.path or os.path.basename(conf.url).split('.')[0]) ] } @@ -317,7 +317,7 @@ def get_additional_build_args(helm_values: HarnessMainConfig, app_key: str) -> d if app_key not in helm_values.apps: return None - if not (helm_values.apps[app_key].harness.dockerfile and helm_values.apps[app_key].harness.dockerfile.build_args): + if not (helm_values.apps[app_key].harness.dockerfile and helm_values.apps[app_key].harness.dockerfile.buildArgs): return None - return helm_values.apps[app_key].harness.dockerfile.build_args + return helm_values.apps[app_key].harness.dockerfile.buildArgs diff --git a/tools/deployment-cli-tools/ch_cli_tools/templates/python/model.mustache b/tools/deployment-cli-tools/ch_cli_tools/templates/python/model.mustache deleted file mode 100644 index 9b795ddf3..000000000 --- a/tools/deployment-cli-tools/ch_cli_tools/templates/python/model.mustache +++ /dev/null @@ -1,41 +0,0 @@ -# coding: utf-8 - -{{>partial_header}} - -from __future__ import annotations -import pprint -import re # noqa: F401 -import json - -{{#vendorExtensions.x-py-other-imports}} -{{{.}}} -{{/vendorExtensions.x-py-other-imports}} -{{#vendorExtensions.x-py-model-imports}} -{{{.}}} -{{/vendorExtensions.x-py-model-imports}} -from typing import Optional, Set -from typing_extensions import Self - -{{#hasChildren}} -{{#discriminator}} -{{! If this model is a super class, importlib is used. So import the necessary modules for the type here. }} -from typing import TYPE_CHECKING -if TYPE_CHECKING: -{{#mappedModels}} - from {{packageName}}.models.{{model.classFilename}} import {{modelName}} -{{/mappedModels}} - -{{/discriminator}} -{{/hasChildren}} - -{{#models}} -{{#model}} -{{#isEnum}} -{{>model_enum}} - -{{/isEnum}} -{{^isEnum}} -{{#oneOf}}{{#-first}}{{>model_oneof}}{{/-first}}{{/oneOf}}{{^oneOf}}{{#anyOf}}{{#-first}}{{>model_anyof}}{{/-first}}{{/anyOf}}{{^anyOf}}{{>model_generic}}{{/anyOf}}{{/oneOf}} -{{/isEnum}} -{{/model}} -{{/models}} diff --git a/tools/deployment-cli-tools/ch_cli_tools/templates/python/model_enum.mustache b/tools/deployment-cli-tools/ch_cli_tools/templates/python/model_enum.mustache deleted file mode 100644 index 3f449b121..000000000 --- a/tools/deployment-cli-tools/ch_cli_tools/templates/python/model_enum.mustache +++ /dev/null @@ -1,36 +0,0 @@ -from __future__ import annotations -import json -from enum import Enum -{{#vendorExtensions.x-py-other-imports}} -{{{.}}} -{{/vendorExtensions.x-py-other-imports}} -from typing_extensions import Self - - -class {{classname}}({{vendorExtensions.x-py-enum-type}}, Enum): - """ - {{{description}}}{{^description}}{{{classname}}}{{/description}} - """ - - """ - allowed enum values - """ -{{#allowableValues}} - {{#enumVars}} - {{{name}}} = {{{value}}} - {{/enumVars}} - - @classmethod - def from_json(cls, json_str: str) -> Self: - """Create an instance of {{classname}} from a JSON string""" - return cls(json.loads(json_str)) - - {{#defaultValue}} - - # - @classmethod - def _missing_value_(cls, value): - if value is no_arg: - return cls.{{{.}}} - {{/defaultValue}} -{{/allowableValues}} diff --git a/tools/deployment-cli-tools/ch_cli_tools/templates/python/model_generic.mustache b/tools/deployment-cli-tools/ch_cli_tools/templates/python/model_generic.mustache deleted file mode 100644 index e05c01e78..000000000 --- a/tools/deployment-cli-tools/ch_cli_tools/templates/python/model_generic.mustache +++ /dev/null @@ -1,366 +0,0 @@ -from cloudharness_model.base_model import CloudHarnessBaseModel -from pydantic import BaseModel, Field, field_validator, StrictStr, StrictBool, StrictInt, StrictFloat -from typing import ClassVar, List, Dict, Any, Union, Optional, Annotated -import importlib -{{#vendorExtensions.x-py-model-imports}} -{{{.}}} -{{/vendorExtensions.x-py-model-imports}} - -class {{classname}}({{#parent}}{{{.}}}{{/parent}}{{^parent}}CloudHarnessBaseModel{{/parent}}): - """ - {{#description}}{{{description}}}{{/description}}{{^description}}{{{classname}}}{{/description}} - """ # noqa: E501 -{{#vars}} - {{name}}: {{{vendorExtensions.x-py-typing}}} -{{/vars}} -{{#isAdditionalPropertiesTrue}} - additional_properties: Dict[str, Any] = {} -{{/isAdditionalPropertiesTrue}} - __properties: ClassVar[List[str]] = [{{#allVars}}"{{baseName}}"{{^-last}}, {{/-last}}{{/allVars}}] -{{#vars}} -{{#vendorExtensions.x-regex}} - - @field_validator('{{{name}}}') - def {{{name}}}_validate_regular_expression(cls, value): - """Validates the regular expression""" - {{^required}} - if value is None: - return value - - {{/required}} - {{#required}} - {{#isNullable}} - if value is None: - return value - - {{/isNullable}} - {{/required}} - if not re.match(r"{{{.}}}", value{{#vendorExtensions.x-modifiers}}, re.{{{.}}}{{/vendorExtensions.x-modifiers}}): - raise ValueError(r"must validate the regular expression {{{vendorExtensions.x-pattern}}}") - return value - {{/vendorExtensions.x-regex}} - {{#isEnum}} - - @field_validator('{{{name}}}') - def {{{name}}}_validate_enum(cls, value): - """Validates the enum""" - {{^required}} - if value is None: - return value - - {{/required}} - {{#required}} - {{#isNullable}} - if value is None: - return value - - {{/isNullable}} - {{/required}} - {{#isContainer}} - {{#isArray}} - for i in value: - if i not in set([{{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}]): - raise ValueError("each list item must be one of ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}})") - {{/isArray}} - {{#isMap}} - for i in value.values(): - if i not in set([{{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}]): - raise ValueError("dict values must be one of enum values ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}})") - {{/isMap}} - {{/isContainer}} - {{^isContainer}} - if value not in set([{{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}}]): - raise ValueError("must be one of enum values ({{#allowableValues}}{{#enumVars}}{{{value}}}{{^-last}}, {{/-last}}{{/enumVars}}{{/allowableValues}})") - {{/isContainer}} - return value - {{/isEnum}} -{{/vars}} - -{{#hasChildren}} -{{#discriminator}} - # JSON field name that stores the object type - __discriminator_property_name: ClassVar[str] = '{{discriminator.propertyBaseName}}' - - # discriminator mappings - __discriminator_value_class_map: ClassVar[Dict[str, str]] = { - {{#mappedModels}}'{{{mappingName}}}': '{{{modelName}}}'{{^-last}},{{/-last}}{{/mappedModels}} - } - - @classmethod - def get_discriminator_value(cls, obj: Dict[str, Any]) -> Optional[str]: - """Returns the discriminator value (object type) of the data""" - discriminator_value = obj[cls.__discriminator_property_name] - if discriminator_value: - return cls.__discriminator_value_class_map.get(discriminator_value) - else: - return None - -{{/discriminator}} -{{/hasChildren}} - def to_dict(self) -> Dict[str, Any]: - """Return the dictionary representation of the model using alias. - - This has the following differences from calling pydantic's - `self.model_dump(by_alias=True)`: - - * `None` is only added to the output dict for nullable fields that - were set at model initialization. Other fields with value `None` - are ignored. - {{#vendorExtensions.x-py-readonly}} - * OpenAPI `readOnly` fields are excluded. - {{/vendorExtensions.x-py-readonly}} - {{#isAdditionalPropertiesTrue}} - * Fields in `self.additional_properties` are added to the output dict. - {{/isAdditionalPropertiesTrue}} - """ - excluded_fields: Set[str] = set([ - {{#vendorExtensions.x-py-readonly}} - "{{{.}}}", - {{/vendorExtensions.x-py-readonly}} - {{#isAdditionalPropertiesTrue}} - "additional_properties", - {{/isAdditionalPropertiesTrue}} - ]) - - _dict = self.model_dump( - by_alias=True, - exclude=excluded_fields, - exclude_none=True, - ) - {{#allVars}} - {{#isContainer}} - {{#isArray}} - {{#items.isArray}} - {{^items.items.isPrimitiveType}} - # override the default output from pydantic by calling `to_dict()` of each item in {{{name}}} (list of list) - _items = [] - if self.{{{name}}}: - for _item_{{{name}}} in self.{{{name}}}: - if _item_{{{name}}}: - _items.append( - [_inner_item.to_dict() for _inner_item in _item_{{{name}}} if _inner_item is not None] - ) - _dict['{{{baseName}}}'] = _items - {{/items.items.isPrimitiveType}} - {{/items.isArray}} - {{^items.isArray}} - {{^items.isPrimitiveType}} - {{^items.isEnumOrRef}} - # override the default output from pydantic by calling `to_dict()` of each item in {{{name}}} (list) - _items = [] - if self.{{{name}}}: - for _item_{{{name}}} in self.{{{name}}}: - if _item_{{{name}}}: - _items.append(_item_{{{name}}}.to_dict()) - _dict['{{{baseName}}}'] = _items - {{/items.isEnumOrRef}} - {{/items.isPrimitiveType}} - {{/items.isArray}} - {{/isArray}} - {{#isMap}} - {{#items.isArray}} - {{^items.items.isPrimitiveType}} - # override the default output from pydantic by calling `to_dict()` of each value in {{{name}}} (dict of array) - _field_dict_of_array = {} - if self.{{{name}}}: - for _key_{{{name}}} in self.{{{name}}}: - if self.{{{name}}}[_key_{{{name}}}] is not None: - _field_dict_of_array[_key_{{{name}}}] = [ - _item.to_dict() for _item in self.{{{name}}}[_key_{{{name}}}] - ] - _dict['{{{baseName}}}'] = _field_dict_of_array - {{/items.items.isPrimitiveType}} - {{/items.isArray}} - {{^items.isArray}} - {{^items.isPrimitiveType}} - {{^items.isEnumOrRef}} - # override the default output from pydantic by calling `to_dict()` of each value in {{{name}}} (dict) - _field_dict = {} - if self.{{{name}}}: - for _key_{{{name}}} in self.{{{name}}}: - if self.{{{name}}}[_key_{{{name}}}]: - _field_dict[_key_{{{name}}}] = self.{{{name}}}[_key_{{{name}}}].to_dict() - _dict['{{{baseName}}}'] = _field_dict - {{/items.isEnumOrRef}} - {{/items.isPrimitiveType}} - {{/items.isArray}} - {{/isMap}} - {{/isContainer}} - {{^isContainer}} - {{^isPrimitiveType}} - {{^isEnumOrRef}} - # override the default output from pydantic by calling `to_dict()` of {{{name}}} - if self.{{{name}}}: - _dict['{{{baseName}}}'] = self.{{{name}}}.to_dict() - {{/isEnumOrRef}} - {{/isPrimitiveType}} - {{/isContainer}} - {{/allVars}} - {{#isAdditionalPropertiesTrue}} - # puts key-value pairs in additional_properties in the top level - if self.additional_properties is not None: - for _key, _value in self.additional_properties.items(): - _dict[_key] = _value - - {{/isAdditionalPropertiesTrue}} - {{#allVars}} - {{#isNullable}} - # set to None if {{{name}}} (nullable) is None - # and model_fields_set contains the field - if self.{{name}} is None and "{{{name}}}" in self.model_fields_set: - _dict['{{{baseName}}}'] = None - - {{/isNullable}} - {{/allVars}} - return _dict - -{{#hasChildren}} - @classmethod - def from_dict(cls, obj: Dict[str, Any]) -> Optional[{{#discriminator}}Union[{{#mappedModels}}{{{modelName}}}{{^-last}}, {{/-last}}{{/mappedModels}}]{{/discriminator}}{{^discriminator}}Self{{/discriminator}}]: - """Create an instance of {{{classname}}} from a dict""" - {{#discriminator}} - # look up the object type based on discriminator mapping - object_type = cls.get_discriminator_value(obj) - {{#mappedModels}} - if object_type == '{{{modelName}}}': - return importlib.import_module("{{packageName}}.models.{{model.classFilename}}").{{modelName}}.from_dict(obj) - {{/mappedModels}} - - raise ValueError("{{{classname}}} failed to lookup discriminator value from " + - json.dumps(obj) + ". Discriminator property name: " + cls.__discriminator_property_name + - ", mapping: " + json.dumps(cls.__discriminator_value_class_map)) - {{/discriminator}} - {{/hasChildren}} - {{^hasChildren}} - @classmethod - def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]: - """Create an instance of {{{classname}}} from a dict""" - if obj is None: - return None - - if not isinstance(obj, dict): - return cls.model_validate(obj) - - {{#disallowAdditionalPropertiesIfNotPresent}} - {{^isAdditionalPropertiesTrue}} - # raise errors for additional fields in the input - for _key in obj.keys(): - if _key not in cls.__properties: - raise ValueError("Error due to additional fields (not defined in {{classname}}) in the input: " + _key) - - {{/isAdditionalPropertiesTrue}} - {{/disallowAdditionalPropertiesIfNotPresent}} - _obj = cls.model_validate({ - {{#allVars}} - {{#isContainer}} - {{#isArray}} - {{#items.isArray}} - {{#items.items.isPrimitiveType}} - "{{{baseName}}}": obj.get("{{{baseName}}}"){{^-last}},{{/-last}} - {{/items.items.isPrimitiveType}} - {{^items.items.isPrimitiveType}} - "{{{baseName}}}": [ - [{{{items.items.dataType}}}.from_dict(_inner_item) for _inner_item in _item] - for _item in obj["{{{baseName}}}"] - ] if obj.get("{{{baseName}}}") is not None else None{{^-last}},{{/-last}} - {{/items.items.isPrimitiveType}} - {{/items.isArray}} - {{^items.isArray}} - {{^items.isPrimitiveType}} - {{#items.isEnumOrRef}} - "{{{baseName}}}": obj.get("{{{baseName}}}"){{^-last}},{{/-last}} - {{/items.isEnumOrRef}} - {{^items.isEnumOrRef}} - "{{{baseName}}}": [{{{items.dataType}}}.from_dict(_item) for _item in obj["{{{baseName}}}"]] if obj.get("{{{baseName}}}") is not None else None{{^-last}},{{/-last}} - {{/items.isEnumOrRef}} - {{/items.isPrimitiveType}} - {{#items.isPrimitiveType}} - "{{{baseName}}}": obj.get("{{{baseName}}}"){{^-last}},{{/-last}} - {{/items.isPrimitiveType}} - {{/items.isArray}} - {{/isArray}} - {{#isMap}} - {{^items.isPrimitiveType}} - {{^items.isEnumOrRef}} - {{#items.isContainer}} - {{#items.isMap}} - "{{{baseName}}}": dict( - (_k, dict( - (_ik, {{{items.items.dataType}}}.from_dict(_iv)) - for _ik, _iv in _v.items() - ) - if _v is not None - else None - ) - for _k, _v in obj.get("{{{baseName}}}").items() - ) - if obj.get("{{{baseName}}}") is not None - else None{{^-last}},{{/-last}} - {{/items.isMap}} - {{#items.isArray}} - "{{{baseName}}}": dict( - (_k, - [{{{items.items.dataType}}}.from_dict(_item) for _item in _v] - if _v is not None - else None - ) - for _k, _v in obj.get("{{{baseName}}}", {}).items() - ){{^-last}},{{/-last}} - {{/items.isArray}} - {{/items.isContainer}} - {{^items.isContainer}} - "{{{baseName}}}": dict( - (_k, {{{items.dataType}}}.from_dict(_v)) - for _k, _v in obj["{{{baseName}}}"].items() - ) - if obj.get("{{{baseName}}}") is not None - else None{{^-last}},{{/-last}} - {{/items.isContainer}} - {{/items.isEnumOrRef}} - {{#items.isEnumOrRef}} - "{{{baseName}}}": dict((_k, _v) for _k, _v in obj.get("{{{baseName}}}").items()) if obj.get("{{{baseName}}}") is not None else None{{^-last}},{{/-last}} - {{/items.isEnumOrRef}} - {{/items.isPrimitiveType}} - {{#items.isPrimitiveType}} - "{{{baseName}}}": obj.get("{{{baseName}}}"){{^-last}},{{/-last}} - {{/items.isPrimitiveType}} - {{/isMap}} - {{/isContainer}} - {{^isContainer}} - {{^isPrimitiveType}} - {{^isEnumOrRef}} - "{{{baseName}}}": {{{dataType}}}.from_dict(obj["{{{baseName}}}"]) if obj.get("{{{baseName}}}") is not None else None{{^-last}},{{/-last}} - {{/isEnumOrRef}} - {{#isEnumOrRef}} - "{{{baseName}}}": obj.get("{{{baseName}}}"){{#defaultValue}} if obj.get("{{baseName}}") is not None else {{{defaultValue}}}{{/defaultValue}}{{^-last}},{{/-last}} - {{/isEnumOrRef}} - {{/isPrimitiveType}} - {{#isPrimitiveType}} - {{#defaultValue}} - "{{{baseName}}}": obj.get("{{{baseName}}}") if obj.get("{{{baseName}}}") is not None else {{{defaultValue}}}{{^-last}},{{/-last}} - {{/defaultValue}} - {{^defaultValue}} - "{{{baseName}}}": obj.get("{{{baseName}}}"){{^-last}},{{/-last}} - {{/defaultValue}} - {{/isPrimitiveType}} - {{/isContainer}} - {{/allVars}} - }) - {{#isAdditionalPropertiesTrue}} - # store additional fields in additional_properties - for _key in obj.keys(): - if _key not in cls.__properties: - _obj.additional_properties[_key] = obj.get(_key) - - {{/isAdditionalPropertiesTrue}} - return _obj - {{/hasChildren}} - -{{#vendorExtensions.x-py-postponed-model-imports.size}} -{{#vendorExtensions.x-py-postponed-model-imports}} -{{{.}}} -{{/vendorExtensions.x-py-postponed-model-imports}} - -# TODO: Rewrite to not use raise_errors -{{classname}}.model_rebuild(raise_errors=False) -{{/vendorExtensions.x-py-postponed-model-imports.size}} diff --git a/tools/deployment-cli-tools/ch_cli_tools/templates/python/partial_header.mustache b/tools/deployment-cli-tools/ch_cli_tools/templates/python/partial_header.mustache deleted file mode 100644 index 50aa81171..000000000 --- a/tools/deployment-cli-tools/ch_cli_tools/templates/python/partial_header.mustache +++ /dev/null @@ -1,19 +0,0 @@ -""" -{{#appName}} - {{{.}}} - -{{/appName}} -{{#appDescription}} - {{{.}}} - -{{/appDescription}} - {{#version}} - The version of the OpenAPI document: {{{.}}} - {{/version}} - {{#infoEmail}} - Contact: {{{.}}} - {{/infoEmail}} - Generated by OpenAPI Generator (https://openapi-generator.tech) - - Do not edit the class manually. -""" # noqa: E501 diff --git a/tools/deployment-cli-tools/ch_cli_tools/templates/tilt/tilt-template.tpl b/tools/deployment-cli-tools/ch_cli_tools/templates/tilt/tilt-template.tpl new file mode 100644 index 000000000..7c0ec06c2 --- /dev/null +++ b/tools/deployment-cli-tools/ch_cli_tools/templates/tilt/tilt-template.tpl @@ -0,0 +1,56 @@ +load('{{ch_root}}/deployment-configuration/tilt-deploy.ext', 'deploy') +load('ext://uibutton', 'cmd_button') + +config.define_bool('setup-infrastructure') +config.define_bool('watch') +cfg = config.parse() +setup_infrastructure = cfg.get('setup-infrastructure', False) +watch = cfg.get('watch', False) +if setup_infrastructure: + # setup ingress + print("Installing ingress controller") + # local("cd infrastructure/cluster-configuration && source cluster-init.sh") + local("kubectl get namespace ingress-nginx 2>/dev/null 1>/dev/null || bash -c 'helm upgrade --install ingress-nginx ingress-nginx --repo https://kubernetes.github.io/ingress-nginx --namespace ingress-nginx --create-namespace --version v4.2.5 && sleep 10'") + # print("Let's wait a few seconds...") + # local("sleep 30") +else: + print("To setup the infrastructure (f.e. ingress controller)") + print("run: tilt up -- --setup-infrastructure") + +if not watch: + print("To watch file changes, run: tilt up -- --watch") + + +# build images +{% for image in images -%} +docker_build(ref='{{image.image}}', context='{{image.context}}', dockerfile='{{image.docker.dockerfile}}', build_args={{image.docker.buildArgs}}{% if image.is_task %}, match_in_env_vars=True{% endif %}) +{% endfor %} + +extra_env = {} +{% for image in images -%} +{% if image.is_app -%} +extra_env.setdefault("{{ image.name }}", []) +{% for task in images -%} +{% if task.is_task and task.parent_app_name == image.name -%} +extra_env["{{ image.name }}"].append("{{ task.image }}") +{% endif -%} +{% endfor -%} +{% endif -%} +{% endfor %} + +# deploy +deploy(name='{{name}}', namespace='{{namespace}}', extra_env=extra_env, watch=watch) + +{% for app in apps -%} +# Add Tilt ui elements for: {{app.name}} +k8s_resource( + '{{app.app_key}}', + links=[link('http://{{app.name}}.{{domain}}', 'Open {{app.name}} page')] +) +cmd_button('{{app.app_key}}:set debug mode', + argv=["sh", "-c", "kubectl -n {{namespace}} patch deployment {{app.app_key}} --patch '{\"spec\": {\"template\": {\"spec\": {\"containers\": [{\"name\": \"{{app.app_key}}\", \"command\": [\"/bin/bash\"], \"args\": [\"-c\", \"sleep infinity\"], \"livenessProbe\": null, \"readinessProbe\": null}]}}}}'"], + resource='{{app.app_key}}', + icon_name='bug_report', + text='set debug mode', +) +{% endfor %} diff --git a/tools/deployment-cli-tools/ch_cli_tools/tilt.py b/tools/deployment-cli-tools/ch_cli_tools/tilt.py new file mode 100644 index 000000000..29738564e --- /dev/null +++ b/tools/deployment-cli-tools/ch_cli_tools/tilt.py @@ -0,0 +1,216 @@ +import os +import logging +import json +import time + +from os.path import join, relpath, basename, exists, abspath +from jinja2 import Environment, PackageLoader, select_autoescape +from cloudharness_model import ApplicationTestConfig, HarnessMainConfig, GitDependencyConfig + +from cloudharness_utils.constants import APPS_PATH, DEPLOYMENT_CONFIGURATION_PATH, \ + BASE_IMAGES_PATH, STATIC_IMAGES_PATH, HELM_ENGINE, COMPOSE_ENGINE +from .helm import KEY_APPS, KEY_HARNESS, KEY_DEPLOYMENT, KEY_TASK_IMAGES +from .utils import get_template, dict_merge, find_dockerfiles_paths, app_name_from_path, yaml, \ + find_file_paths, guess_build_dependencies_from_dockerfile, get_json_template, get_image_name + +from . import HERE, CH_ROOT + + +env = Environment( + loader=PackageLoader(package_name="ch_cli_tools", package_path="templates/tilt"), + autoescape=select_autoescape() +) + + +def relpath_if(p1, p2): + if os.path.isabs(p1): + return p1 + return relpath(p1, p2) + + +def get_all_images(helm_values: HarnessMainConfig) -> dict[str, str]: + all_images = {**helm_values[KEY_TASK_IMAGES]} + for app_name, app in helm_values.apps.items(): + if app.harness.deployment and app.harness.deployment.image: + all_images[app_name] = app.harness.deployment.image + return all_images + + +def create_tilt_configuration(root_paths, helm_values: HarnessMainConfig, manage_task_images=True, output_path='.', name='', namespace='', domain=''): + template_name = 'tilt-template.tpl' + tilt_template = env.get_template(template_name) + apps = helm_values.apps + artifacts = {} + overrides = {} + + all_images = get_all_images(helm_values) + + def remove_tag(image_name): + return image_name.split(":")[0] + + def get_image_tag(name): + return remove_tag(all_images[name]) + + builds = {} + + def build_artifact( + app_name: str, + context_path: str, + requirements: list[str] = None, + dockerfile_path: str = '', + additional_build_args: dict[str, str] = None, + is_app: bool = False, + is_task: bool = False, + parent_app_name: str = None, + app_key: str = None, + ) -> dict: + app_key = app_key or app_name + build_args = { + 'DEBUG': 'true' if helm_values.local or helm_values.debug else '' + } + + if additional_build_args: + build_args.update(additional_build_args) + + if requirements: + for req in requirements: + build_args.update({req.replace('-', '_').upper(): get_image_tag(req)}) + + image_name = get_image_tag(app_key) + + artifact_spec = { + 'name': app_name, + 'app_key': app_key, + 'image': image_name, + 'context': context_path, + 'is_app': is_app, + 'is_task': is_task, + 'parent_app_name': parent_app_name, + 'docker': { + 'dockerfile': join(dockerfile_path, 'Dockerfile'), + 'buildArgs': build_args + } + } + return artifact_spec + + base_images = set() + + def process_build_dockerfile( + dockerfile_path: str, + root_path: str, + global_context: bool = False, + requirements: list[str] = None, + app_name: str = None, + app_key: str = None, + is_app: bool = True + ) -> None: + if app_name is None: + app_name = app_name_from_path(basename(dockerfile_path)) + is_app = False + app_key = app_key or app_name + if app_key in helm_values.apps and not helm_values.apps[app_key]['build']: + return + if app_name in helm_values[KEY_TASK_IMAGES] or app_key in helm_values.apps: + context_path = relpath_if(root_path, output_path) if global_context else relpath_if(dockerfile_path, output_path) + + builds[app_name] = context_path + base_images.add(get_image_name(app_key)) + + artifacts[app_name] = build_artifact( + app_name, + context_path, + dockerfile_path=relpath(dockerfile_path, output_path), + requirements=requirements or guess_build_dependencies_from_dockerfile(dockerfile_path), + additional_build_args=get_additional_build_args(helm_values, app_key), + is_app=is_app, + app_key=app_key + ) + + if app_key in helm_values.apps and helm_values.apps[app_key].harness.dependencies and helm_values.apps[app_key].harness.dependencies.git: + artifacts[app_name]['hooks'] = { + 'before': [git_clone_hook(conf, context_path) for conf in helm_values.apps[app_key].harness.dependencies.git] + } + + images = set() + for root_path in root_paths: + base_dockerfiles = find_dockerfiles_paths( + join(root_path, BASE_IMAGES_PATH)) + + for dockerfile_path in base_dockerfiles: + process_build_dockerfile(dockerfile_path, root_path, global_context=True) + + static_images = set() + for root_path in root_paths: + static_dockerfiles = find_dockerfiles_paths( + join(root_path, STATIC_IMAGES_PATH)) + + for dockerfile_path in static_dockerfiles: + process_build_dockerfile(dockerfile_path, root_path) + + for root_path in root_paths: + apps_path = join(root_path, APPS_PATH) + + # Get all dockerfiles in the applications directory, including those in subdirectories + app_dockerfiles = find_dockerfiles_paths(apps_path) + + for dockerfile_path in app_dockerfiles: + app_relative_to_skaffold = os.path.relpath( + dockerfile_path, output_path) + app_relative_to_base = os.path.relpath(dockerfile_path, apps_path) + app_name = app_name_from_path(app_relative_to_base) + app_key = app_name + + if app_key not in apps: + if 'tasks' in app_relative_to_base and manage_task_images: + parent_app_name = app_name_from_path( + app_relative_to_base.split('/tasks')[0]) + parent_app_key = parent_app_name + + if parent_app_key in apps: + artifacts[app_key] = build_artifact( + app_name, + app_relative_to_skaffold, + guess_build_dependencies_from_dockerfile(dockerfile_path), + dockerfile_path=dockerfile_path, + is_task=True, + parent_app_name=parent_app_name) + elif app_name in helm_values[KEY_TASK_IMAGES]: + process_build_dockerfile(dockerfile_path, root_path, + requirements=guess_build_dependencies_from_dockerfile(dockerfile_path), dockerfile_path=dockerfile_path, app_name=app_name) + continue + + if app_name in helm_values["apps"]: + is_app = helm_values["apps"][app_name]["harness"]["service"]["auto"] + app_name = helm_values["apps"][app_name]["harness"]["subdomain"] + process_build_dockerfile(dockerfile_path, root_path, requirements=guess_build_dependencies_from_dockerfile(dockerfile_path), app_name=app_name, app_key=app_key, is_app=is_app) + app = apps[app_key] + if not app['build']: + continue + + images = [artifact for artifact in artifacts.values() if artifact['image']] + apps = [artifact for artifact in artifacts.values() if artifact['is_app']] + with open(os.path.join(output_path, 'Tiltfile'), "w") as f: + f.write(tilt_template.render(ch_root=CH_ROOT, name=name, namespace=namespace, images=images, apps=apps, domain=domain)) + return None + + +def git_clone_hook(conf: GitDependencyConfig, context_path: str): + return { + 'command': [ + 'sh', + join(os.path.dirname(os.path.dirname(HERE)), 'clone.sh'), + conf.branch_tag, + conf.url, + join(context_path, "dependencies", conf.path or os.path.basename(conf.url).split('.')[0]) + ] + } + + +def get_additional_build_args(helm_values: HarnessMainConfig, app_key: str) -> dict[str, str]: + if app_key not in helm_values.apps: + return None + + if not (helm_values.apps[app_key].harness.dockerfile and helm_values.apps[app_key].harness.dockerfile.buildArgs): + return None + + return helm_values.apps[app_key].harness.dockerfile.buildArgs diff --git a/tools/deployment-cli-tools/ch_cli_tools/utils.py b/tools/deployment-cli-tools/ch_cli_tools/utils.py index 4809998e5..f5af29af8 100644 --- a/tools/deployment-cli-tools/ch_cli_tools/utils.py +++ b/tools/deployment-cli-tools/ch_cli_tools/utils.py @@ -89,14 +89,56 @@ def get_image_name(app_name, base_name=None): def env_variable(name, value): - return {'name': f"{name}".upper(), 'value': str(value)} + return {'name': f"{name}".upper(), 'value': value} -def get_cluster_ip(): - out = subprocess.check_output( - ['kubectl', 'cluster-info'], timeout=10).decode("utf-8") - ips = re.findall(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", out) - return ips[0] if ips else get_host_address() +def get_cluster_ip(local=False): + if local: + # Try to get LoadBalancer IP from ingress-nginx first (preferred for local dev with minikube tunnel) + try: + out = subprocess.check_output([ + 'kubectl', '-n', 'ingress-nginx', 'get', 'svc', 'ingress-nginx-controller', + '-o', 'jsonpath={.status.loadBalancer.ingress[0].ip}' + ], timeout=5).decode("utf-8").strip() + if out and out != '': + return out + except: + pass + + # Try minikube with profile detection for local development + try: + # Get current kubectl context to extract minikube profile + context = subprocess.check_output(['kubectl', 'config', 'current-context'], timeout=5).decode("utf-8").strip() + + # Try with profile if context looks like minikube + if 'minikube' in context.lower(): + profile = context # Context name is often the profile name + try: + out = subprocess.check_output(['minikube', '-p', profile, 'ip'], timeout=5).decode("utf-8").strip() + if out: + return out + except: + pass + + # Try without profile (default minikube) + out = subprocess.check_output(['minikube', 'ip'], timeout=5).decode("utf-8").strip() + if out: + return out + except: + pass + + # Try kubectl cluster-info + try: + out = subprocess.check_output( + ['kubectl', 'cluster-info'], timeout=10).decode("utf-8") + ips = re.findall(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", out) + if ips: + return ips[0] + except: + pass + + # Fallback to host address (used for non-local deployments) + return get_host_address() def get_host_address(): diff --git a/tools/deployment-cli-tools/harness-deployment b/tools/deployment-cli-tools/harness-deployment index 4a587afaa..82473e067 100644 --- a/tools/deployment-cli-tools/harness-deployment +++ b/tools/deployment-cli-tools/harness-deployment @@ -8,6 +8,7 @@ from ch_cli_tools.dockercompose import create_docker_compose_configuration from ch_cli_tools.helm import create_helm_chart, deploy from ch_cli_tools.configurationgenerator import hosts_info from ch_cli_tools.skaffold import create_skaffold_configuration, create_vscode_debug_configuration +from ch_cli_tools.tilt import create_tilt_configuration from ch_cli_tools.codefresh import create_codefresh_deployment_scripts, write_env_file from ch_cli_tools.preprocessing import preprocess_build_overrides from ch_cli_tools.utils import merge_app_directories @@ -129,6 +130,7 @@ if __name__ == "__main__": write_env_file(helm_values, os.path.join(root_paths[-1], DEPLOYMENT_PATH, ".env"), args.image_cache_url) create_skaffold_configuration(merged_root_paths, helm_values, backend_deploy=COMPOSE_ENGINE if args.docker_compose else HELM_ENGINE) + create_tilt_configuration(merged_root_paths, helm_values, name=args.namespace, namespace=args.namespace, domain=args.domain) if not args.docker_compose: create_vscode_debug_configuration(root_paths, helm_values) diff --git a/tools/deployment-cli-tools/requirements.txt b/tools/deployment-cli-tools/requirements.txt index 266ae27f3..966ce8612 100644 --- a/tools/deployment-cli-tools/requirements.txt +++ b/tools/deployment-cli-tools/requirements.txt @@ -5,4 +5,5 @@ oyaml cloudharness_model cloudharness_utils dirhash +jinja2 StrEnum ; python_version < '3.11' \ No newline at end of file diff --git a/tools/deployment-cli-tools/tests/test_codefresh.py b/tools/deployment-cli-tools/tests/test_codefresh.py index a558f7cc0..b1b8e1c52 100644 --- a/tools/deployment-cli-tools/tests/test_codefresh.py +++ b/tools/deployment-cli-tools/tests/test_codefresh.py @@ -64,7 +64,7 @@ def test_create_codefresh_configuration(): assert "testprojectname/" in steps["cloudharness-base"]['image_name'], "cloudharness-base image should be overridden and take the main name" assert "cloudharness-base-debian" not in steps, "cloudharness-base image should not be included" assert "cloudharness-frontend-build" in steps, "cloudharness-frontend-build image should be included as dependency" - assert "testprojectname/" in steps["cloudharness-frontend-build"]['image_name'], "cloudharness-frontend-build image is not overridden" + assert "cloud-harness/" in steps["cloudharness-frontend-build"]['image_name'], "cloudharness-frontend-build image is not overridden and should keep the cloud-harness prefix" step = steps["cloudharness-frontend-build"] assert os.path.samefile(step['working_directory'], CLOUDHARNESS_ROOT) @@ -122,8 +122,8 @@ def test_create_codefresh_configuration(): assert "testprojectname/" in step['image_name'], f"myapp image should have the project name coming from the chart in its path, is {step['image_name']}" for build_argument in step['build_arguments']: if build_argument.startswith("CLOUDHARNESS_FLASK="): - assert "testprojectname" in build_argument, "Cloudharness flask image should have cloud-harness in its path" - assert build_argument == "CLOUDHARNESS_FLASK=${{REGISTRY}}/testprojectname/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}}", "Dependency is not properly set in the build arguments" + assert "cloud-harness" in build_argument, "Cloudharness flask image should have cloud-harness in its path" + assert build_argument == "CLOUDHARNESS_FLASK=${{REGISTRY}}/cloud-harness/cloudharness-flask:${{CLOUDHARNESS_FLASK_TAG}}", "Dependency is not properly set in the build arguments" assert os.path.samefile(step['working_directory'], os.path.join( RESOURCES, APPS_PATH, "myapp")) diff --git a/tools/deployment-cli-tools/tests/test_dockercompose.py b/tools/deployment-cli-tools/tests/test_dockercompose.py index a3662ea7b..02b064326 100644 --- a/tools/deployment-cli-tools/tests/test_dockercompose.py +++ b/tools/deployment-cli-tools/tests/test_dockercompose.py @@ -26,7 +26,7 @@ def test_collect_compose_values(tmp_path): assert values.apps['myapp'].harness.deployment.image == 'reg/testprojectname/myapp:1' assert values[KEY_APPS]['myapp'][KEY_HARNESS]['name'] == 'myapp' assert values[KEY_APPS]['legacy'][KEY_HARNESS]['name'] == 'legacy' - assert values[KEY_APPS]['accounts'][KEY_HARNESS]['deployment']['image'] == 'reg/testprojectname/accounts:1' + assert values[KEY_APPS]['accounts'][KEY_HARNESS]['deployment']['image'] == 'reg/cloud-harness/accounts:1' # First level include apps assert 'samples' in values[KEY_APPS] @@ -102,7 +102,7 @@ def test_collect_compose_values_noreg_noinclude(tmp_path): assert values[KEY_APPS]['myapp'][KEY_HARNESS]['deployment']['image'] == 'testprojectname/myapp:1' assert values[KEY_APPS]['myapp'][KEY_HARNESS]['name'] == 'myapp' assert values[KEY_APPS]['legacy'][KEY_HARNESS]['name'] == 'legacy' - assert values[KEY_APPS]['accounts'][KEY_HARNESS]['deployment']['image'] == 'testprojectname/accounts:1' + assert values[KEY_APPS]['accounts'][KEY_HARNESS]['deployment']['image'] == 'cloud-harness/accounts:1' # First level include apps assert 'samples' in values[KEY_APPS] diff --git a/tools/deployment-cli-tools/tests/test_helm.py b/tools/deployment-cli-tools/tests/test_helm.py index 2e4b93917..81a024cc5 100644 --- a/tools/deployment-cli-tools/tests/test_helm.py +++ b/tools/deployment-cli-tools/tests/test_helm.py @@ -40,7 +40,7 @@ def test_collect_helm_values(tmp_path): assert values.apps['myapp'].harness.deployment.image == 'reg/testprojectname/myapp:1' assert values[KEY_APPS]['myapp'][KEY_HARNESS]['name'] == 'myapp' assert values[KEY_APPS]['legacy'][KEY_HARNESS]['name'] == 'legacy' - assert values[KEY_APPS]['accounts'][KEY_HARNESS]['deployment']['image'] == 'reg/testprojectname/accounts:1' + assert values[KEY_APPS]['accounts'][KEY_HARNESS]['deployment']['image'] == 'reg/cloud-harness/accounts:1' # Base values kept assert values[KEY_APPS]['accounts'][KEY_HARNESS]['subdomain'] == 'accounts' @@ -74,9 +74,9 @@ def test_collect_helm_values(tmp_path): # Checl base and task images assert values[KEY_TASK_IMAGES] assert 'cloudharness-base' in values[KEY_TASK_IMAGES] - assert values[KEY_TASK_IMAGES]['cloudharness-base'] == 'reg/testprojectname/cloudharness-base:1' + assert values[KEY_TASK_IMAGES]['cloudharness-base'] == 'reg/testprojectname/cloudharness-base:1', "Cloudharness base image is overridden, so takes the main project name prefix" assert values[KEY_TASK_IMAGES]['myapp-mytask'] == 'reg/testprojectname/myapp-mytask:1' - assert values[KEY_TASK_IMAGES]['cloudharness-flask'] == 'reg/testprojectname/cloudharness-flask:1' + assert values[KEY_TASK_IMAGES]['cloudharness-flask'] == 'reg/cloud-harness/cloudharness-flask:1' # Not indicated as a build dependency assert 'cloudharness-base-debian' not in values[KEY_TASK_IMAGES] @@ -103,7 +103,7 @@ def test_collect_helm_values_noreg_noinclude(tmp_path): assert values[KEY_APPS]['myapp'][KEY_HARNESS]['deployment']['image'] == 'testprojectname/myapp:1' assert values[KEY_APPS]['myapp'][KEY_HARNESS]['name'] == 'myapp' assert values[KEY_APPS]['legacy'][KEY_HARNESS]['name'] == 'legacy' - assert values[KEY_APPS]['accounts'][KEY_HARNESS]['deployment']['image'] == 'testprojectname/accounts:1' + assert values[KEY_APPS]['accounts'][KEY_HARNESS]['deployment']['image'] == 'cloud-harness/accounts:1' # First level include apps assert 'samples' in values[KEY_APPS] diff --git a/tools/deployment-cli-tools/tests/test_skaffold.py b/tools/deployment-cli-tools/tests/test_skaffold.py index a52de3489..2e14245fd 100644 --- a/tools/deployment-cli-tools/tests/test_skaffold.py +++ b/tools/deployment-cli-tools/tests/test_skaffold.py @@ -59,7 +59,7 @@ def test_create_skaffold_configuration(tmp_path): assert overrides[KEY_APPS]['samples'][KEY_HARNESS][KEY_DEPLOYMENT]['args'] assert 'reg' == artifact_overrides[KEY_APPS]['accounts'][KEY_HARNESS][KEY_DEPLOYMENT]['image'][0:3] - assert 'harness' not in artifact_overrides[KEY_APPS]['accounts'][KEY_HARNESS][KEY_DEPLOYMENT]['image'] + assert 'harness' in artifact_overrides[KEY_APPS]['accounts'][KEY_HARNESS][KEY_DEPLOYMENT]['image'] cloudharness_base_artifact = next( a for a in sk['build']['artifacts'] if a['image'] == f'reg/testprojectname/cloudharness-base') @@ -67,7 +67,7 @@ def test_create_skaffold_configuration(tmp_path): assert 'requires' not in cloudharness_base_artifact cloudharness_flask_artifact = next( - a for a in sk['build']['artifacts'] if a['image'] == f'reg/testprojectname/cloudharness-flask') + a for a in sk['build']['artifacts'] if a['image'] == f'reg/{CLOUDHARNESS_DIRNAME}/cloudharness-flask') assert os.path.samefile(cloudharness_flask_artifact['context'], join(CLOUDHARNESS_ROOT, 'infrastructure/common-images/cloudharness-flask') @@ -76,7 +76,7 @@ def test_create_skaffold_configuration(tmp_path): assert len(cloudharness_flask_artifact['requires']) == 1 samples_artifact = next( - a for a in sk['build']['artifacts'] if a['image'] == f'reg/testprojectname/samples' + a for a in sk['build']['artifacts'] if a['image'] == f'reg/{CLOUDHARNESS_DIRNAME}/samples' ) assert os.path.samefile(samples_artifact['context'], join(CLOUDHARNESS_ROOT, 'applications/samples')) assert 'TEST_ARGUMENT' in samples_artifact['docker']['buildArgs'] @@ -89,14 +89,14 @@ def test_create_skaffold_configuration(tmp_path): assert myapp_artifact['hooks']['before'], 'The hook for dependencies should be included' assert len(myapp_artifact['hooks']['before']) == 2, 'The hook for dependencies should include 2 clone commands' accounts_artifact = next( - a for a in sk['build']['artifacts'] if a['image'] == f'reg/testprojectname/accounts') + a for a in sk['build']['artifacts'] if a['image'] == f'reg/{CLOUDHARNESS_DIRNAME}/accounts') assert os.path.samefile(accounts_artifact['context'], '/tmp/build/applications/accounts') # Custom unit tests assert len(sk['test']) == 2, 'Unit tests should be included' samples_test = sk['test'][0] - assert samples_test['image'] == f'reg/testprojectname/samples', 'Unit tests for samples should be included' + assert samples_test['image'] == f'reg/{CLOUDHARNESS_DIRNAME}/samples', 'Unit tests for samples should be included' assert "samples/test" in samples_test['custom'][0]['command'], "The test command must come from values.yaml test/unit/commands" assert len(sk['test'][1]['custom']) == 2