diff --git a/.gitignore b/.gitignore index 090f961404..737a25334f 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ dist .cache .openapi-generator +/openapitools.json clients/algoliasearch-client-javascript/packages/*/.openapi-generator-ignore tests/output/*/.openapi-generator-ignore diff --git a/.prettierignore b/.prettierignore index 7293b8344b..dce15f15cb 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,7 @@ dist node_modules vendor +build +.gradle +target +bin diff --git a/openapitools.json b/config/openapitools.json similarity index 58% rename from openapitools.json rename to config/openapitools.json index a5ecbc2bd3..c20e704deb 100644 --- a/openapitools.json +++ b/config/openapitools.json @@ -1,15 +1,8 @@ { - "$schema": "./node_modules/@experimental-api-clients-automation/openapi-generator-cli/config.schema.json", "generator-cli": { "version": "5.4.0", "generators": { "javascript-search": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/search.yml", - "templateDir": "#{cwd}/templates/javascript/", - "generatorName": "algolia-javascript", "apiPackage": "src", "output": "#{cwd}/clients/algoliasearch-client-javascript/packages/client-search", "gitRepoId": "algoliasearch-client-javascript", @@ -23,12 +16,6 @@ } }, "javascript-algoliasearch-lite": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/algoliasearch-lite.yml", - "templateDir": "#{cwd}/templates/javascript/", - "generatorName": "algolia-javascript", "apiPackage": "src", "output": "#{cwd}/clients/algoliasearch-client-javascript/packages/algoliasearch-lite", "gitRepoId": "algoliasearch-client-javascript", @@ -42,12 +29,6 @@ } }, "javascript-recommend": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/recommend.yml", - "templateDir": "#{cwd}/templates/javascript/", - "generatorName": "algolia-javascript", "apiPackage": "src", "output": "#{cwd}/clients/algoliasearch-client-javascript/packages/recommend", "gitRepoId": "algoliasearch-client-javascript", @@ -61,12 +42,6 @@ } }, "javascript-personalization": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/personalization.yml", - "templateDir": "#{cwd}/templates/javascript/", - "generatorName": "algolia-javascript", "apiPackage": "src", "output": "#{cwd}/clients/algoliasearch-client-javascript/packages/client-personalization", "gitRepoId": "algoliasearch-client-javascript", @@ -75,20 +50,11 @@ "buildFile": "client-personalization", "packageVersion": "0.2.0", "packageName": "@experimental-api-clients-automation/client-personalization", - "hasRegionalHost": true, - "isEuHost": true, - "host": "personalization", - "topLevelDomain": "com", - "utilsPackageVersion": "0.2.0" + "utilsPackageVersion": "0.2.0", + "hasRegionalHost": true } }, "javascript-analytics": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/analytics.yml", - "templateDir": "#{cwd}/templates/javascript/", - "generatorName": "algolia-javascript", "apiPackage": "src", "output": "#{cwd}/clients/algoliasearch-client-javascript/packages/client-analytics", "gitRepoId": "algoliasearch-client-javascript", @@ -97,21 +63,11 @@ "buildFile": "client-analytics", "packageVersion": "0.2.0", "packageName": "@experimental-api-clients-automation/client-analytics", - "fallbackToAliasHost": true, - "hasRegionalHost": true, - "isDeHost": true, - "host": "analytics", - "topLevelDomain": "com", - "utilsPackageVersion": "0.2.0" + "utilsPackageVersion": "0.2.0", + "hasRegionalHost": true } }, "javascript-insights": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/insights.yml", - "templateDir": "#{cwd}/templates/javascript/", - "generatorName": "algolia-javascript", "apiPackage": "src", "output": "#{cwd}/clients/algoliasearch-client-javascript/packages/client-insights", "gitRepoId": "algoliasearch-client-javascript", @@ -120,21 +76,11 @@ "buildFile": "client-insights", "packageVersion": "0.2.0", "packageName": "@experimental-api-clients-automation/client-insights", - "fallbackToAliasHost": true, - "hasRegionalHost": true, - "isDeHost": true, - "host": "insights", - "topLevelDomain": "io", - "utilsPackageVersion": "0.2.0" + "utilsPackageVersion": "0.2.0", + "hasRegionalHost": true } }, "javascript-abtesting": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/abtesting.yml", - "templateDir": "#{cwd}/templates/javascript/", - "generatorName": "algolia-javascript", "apiPackage": "src", "output": "#{cwd}/clients/algoliasearch-client-javascript/packages/client-abtesting", "gitRepoId": "algoliasearch-client-javascript", @@ -143,21 +89,11 @@ "buildFile": "client-abtesting", "packageVersion": "0.2.0", "packageName": "@experimental-api-clients-automation/client-abtesting", - "hasRegionalHost": true, - "fallbackToAliasHost": true, - "isDeHost": true, - "host": "analytics", - "topLevelDomain": "com", - "utilsPackageVersion": "0.2.0" + "utilsPackageVersion": "0.2.0", + "hasRegionalHost": true } }, "javascript-query-suggestions": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/query-suggestions.yml", - "templateDir": "#{cwd}/templates/javascript/", - "generatorName": "algolia-javascript", "apiPackage": "src", "output": "#{cwd}/clients/algoliasearch-client-javascript/packages/client-query-suggestions", "gitRepoId": "algoliasearch-client-javascript", @@ -166,20 +102,11 @@ "buildFile": "client-query-suggestions", "packageVersion": "0.2.0", "packageName": "@experimental-api-clients-automation/client-query-suggestions", - "hasRegionalHost": true, - "isEuHost": true, - "host": "query-suggestions", - "topLevelDomain": "com", - "utilsPackageVersion": "0.2.0" + "utilsPackageVersion": "0.2.0", + "hasRegionalHost": true } }, "javascript-sources": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/sources.yml", - "templateDir": "#{cwd}/templates/javascript/", - "generatorName": "algolia-javascript", "apiPackage": "src", "output": "#{cwd}/clients/algoliasearch-client-javascript/packages/client-sources", "gitRepoId": "algoliasearch-client-javascript", @@ -188,20 +115,12 @@ "buildFile": "client-sources", "packageVersion": "0.2.0", "packageName": "@experimental-api-clients-automation/client-sources", - "hasRegionalHost": true, - "isDeHost": true, - "host": "data", - "topLevelDomain": "com", - "utilsPackageVersion": "0.2.0" + "utilsPackageVersion": "0.2.0", + "hasRegionalHost": true } }, "javascript-predict": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/predict.yml", "templateDir": "#{cwd}/templates/javascript/", - "generatorName": "algolia-javascript", "apiPackage": "src", "output": "#{cwd}/clients/algoliasearch-client-javascript/packages/client-predict", "gitRepoId": "algoliasearch-client-javascript", @@ -210,17 +129,11 @@ "buildFile": "client-predict", "packageVersion": "0.2.0", "packageName": "@experimental-api-clients-automation/client-predict", - "experimentalHost": "predict-api-432xa6wemq-ew.a.run.app", - "utilsPackageVersion": "0.2.0" + "utilsPackageVersion": "0.2.0", + "hasRegionalHost": true } }, "java-search": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/search.yml", - "templateDir": "#{cwd}/templates/java/", - "generatorName": "algolia-java", "output": "#{cwd}/clients/algoliasearch-client-java-2", "artifactId": "algoliasearch-client-java-2", "groupId": "com.algolia", @@ -235,12 +148,6 @@ } }, "java-recommend": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/recommend.yml", - "templateDir": "#{cwd}/templates/java/", - "generatorName": "algolia-java", "output": "#{cwd}/clients/algoliasearch-client-java-2", "artifactId": "algoliasearch-client-java-2", "groupId": "com.algolia", @@ -255,12 +162,6 @@ } }, "java-personalization": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/personalization.yml", - "templateDir": "#{cwd}/templates/java/", - "generatorName": "algolia-java", "output": "#{cwd}/clients/algoliasearch-client-java-2", "artifactId": "algoliasearch-client-java-2", "groupId": "com.algolia", @@ -272,19 +173,10 @@ "additionalProperties": { "packageName": "algoliasearch-client-java-2", "packageVersion": "0.0.1", - "hasRegionalHost": true, - "isEuHost": true, - "host": "personalization", - "topLevelDomain": "com" + "hasRegionalHost": true } }, "java-analytics": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/analytics.yml", - "templateDir": "#{cwd}/templates/java/", - "generatorName": "algolia-java", "output": "#{cwd}/clients/algoliasearch-client-java-2", "artifactId": "algoliasearch-client-java-2", "groupId": "com.algolia", @@ -296,20 +188,10 @@ "additionalProperties": { "packageName": "algoliasearch-client-java-2", "packageVersion": "0.0.1", - "hasRegionalHost": true, - "fallbackToAliasHost": true, - "isDeHost": true, - "host": "analytics", - "topLevelDomain": "com" + "hasRegionalHost": true } }, "java-insights": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/insights.yml", - "templateDir": "#{cwd}/templates/java/", - "generatorName": "algolia-java", "output": "#{cwd}/clients/algoliasearch-client-java-2", "artifactId": "algoliasearch-client-java-2", "groupId": "com.algolia", @@ -321,20 +203,10 @@ "additionalProperties": { "packageName": "algoliasearch-client-java-2", "packageVersion": "0.0.1", - "hasRegionalHost": true, - "fallbackToAliasHost": true, - "isDeHost": true, - "host": "insights", - "topLevelDomain": "io" + "hasRegionalHost": true } }, "java-abtesting": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/abtesting.yml", - "templateDir": "#{cwd}/templates/java/", - "generatorName": "algolia-java", "output": "#{cwd}/clients/algoliasearch-client-java-2", "artifactId": "algoliasearch-client-java-2", "groupId": "com.algolia", @@ -346,20 +218,10 @@ "additionalProperties": { "packageName": "algoliasearch-client-java-2", "packageVersion": "0.0.1", - "hasRegionalHost": true, - "fallbackToAliasHost": true, - "isDeHost": true, - "host": "analytics", - "topLevelDomain": "com" + "hasRegionalHost": true } }, "java-query-suggestions": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/query-suggestions.yml", - "templateDir": "#{cwd}/templates/java/", - "generatorName": "algolia-java", "output": "#{cwd}/clients/algoliasearch-client-java-2", "artifactId": "algoliasearch-client-java-2", "groupId": "com.algolia", @@ -371,19 +233,10 @@ "additionalProperties": { "packageName": "algoliasearch-client-java-2", "packageVersion": "0.0.1", - "hasRegionalHost": true, - "isEuHost": true, - "host": "query-suggestions", - "topLevelDomain": "com" + "hasRegionalHost": true } }, "java-predict": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/predict.yml", - "templateDir": "#{cwd}/templates/java/", - "generatorName": "algolia-java", "output": "#{cwd}/clients/algoliasearch-client-java-2", "artifactId": "algoliasearch-client-java-2", "groupId": "com.algolia", @@ -394,17 +247,10 @@ "gitRepoId": "algoliasearch-client-java-2", "additionalProperties": { "packageName": "algoliasearch-client-java-2", - "packageVersion": "0.0.1", - "experimentalHost": "predict-api-432xa6wemq-ew.a.run.app" + "packageVersion": "0.0.1" } }, "php-search": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/search.yml", - "templateDir": "#{cwd}/templates/php/", - "generatorName": "algolia-php", "output": "#{cwd}/clients/algoliasearch-client-php", "gitRepoId": "algoliasearch-client-php", "invokerPackage": "Algolia\\AlgoliaSearch", @@ -415,12 +261,6 @@ } }, "php-recommend": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/recommend.yml", - "templateDir": "#{cwd}/templates/php/", - "generatorName": "algolia-php", "output": "#{cwd}/clients/algoliasearch-client-php", "gitRepoId": "algoliasearch-client-php", "invokerPackage": "Algolia\\AlgoliaSearch", @@ -431,90 +271,47 @@ } }, "php-personalization": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/personalization.yml", - "templateDir": "#{cwd}/templates/php/", - "generatorName": "algolia-php", "output": "#{cwd}/clients/algoliasearch-client-php", "gitRepoId": "algoliasearch-client-php", "invokerPackage": "Algolia\\AlgoliaSearch", "modelPackage": "Model\\Personalization", "additionalProperties": { - "hasRegionalHost": true, - "allowedRegions": "us-eu", "packageName": "algoliasearch-client-php", "packageVersion": "0.0.1", - "isEuHost": true, - "host": "personalization", - "topLevelDomain": "com" + "hasRegionalHost": true } }, "php-analytics": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/analytics.yml", - "templateDir": "#{cwd}/templates/php/", - "generatorName": "algolia-php", "output": "#{cwd}/clients/algoliasearch-client-php", "gitRepoId": "algoliasearch-client-php", "invokerPackage": "Algolia\\AlgoliaSearch", "modelPackage": "Model\\Analytics", "additionalProperties": { - "hasRegionalHost": true, - "allowedRegions": "us-de", "packageName": "algoliasearch-client-php", "packageVersion": "0.0.1", - "fallbackToAliasHost": true, - "isDeHost": true, - "host": "analytics", - "topLevelDomain": "com" + "hasRegionalHost": true } }, "php-insights": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/insights.yml", - "templateDir": "#{cwd}/templates/php/", - "generatorName": "algolia-php", "output": "#{cwd}/clients/algoliasearch-client-php", "gitRepoId": "algoliasearch-client-php", "invokerPackage": "Algolia\\AlgoliaSearch", "modelPackage": "Model\\Insights", "additionalProperties": { - "hasRegionalHost": true, - "allowedRegions": "us-de", "packageName": "algoliasearch-client-php", "packageVersion": "0.0.1", - "fallbackToAliasHost": true, - "isDeHost": true, - "host": "insights", - "topLevelDomain": "io" + "hasRegionalHost": true } }, "php-abtesting": { - "config": "#{cwd}/openapitools.json", - "gitHost": "algolia", - "gitUserId": "algolia", - "glob": "specs/bundled/abtesting.yml", - "templateDir": "#{cwd}/templates/php/", - "generatorName": "algolia-php", "output": "#{cwd}/clients/algoliasearch-client-php", "gitRepoId": "algoliasearch-client-php", "invokerPackage": "Algolia\\AlgoliaSearch", "modelPackage": "Model\\Abtesting", "additionalProperties": { - "hasRegionalHost": true, - "allowedRegions": "us-de", "packageName": "algoliasearch-client-php", "packageVersion": "0.0.1", - "fallbackToAliasHost": true, - "isDeHost": true, - "host": "analytics", - "topLevelDomain": "com" + "hasRegionalHost": true } }, "php-query-suggestions": { @@ -529,13 +326,8 @@ "invokerPackage": "Algolia\\AlgoliaSearch", "modelPackage": "Model\\QuerySuggestions", "additionalProperties": { - "hasRegionalHost": true, - "allowedRegions": "us-eu", "packageName": "algoliasearch-client-php", - "packageVersion": "0.0.1", - "isEuHost": true, - "host": "query-suggestions", - "topLevelDomain": "com" + "packageVersion": "0.0.1" } } } diff --git a/generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java b/generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java index ddc5b868fb..d37e1fe206 100644 --- a/generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java +++ b/generators/src/main/java/com/algolia/codegen/AlgoliaJavaGenerator.java @@ -3,13 +3,10 @@ import io.swagger.v3.oas.models.Operation; import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.servers.Server; -import java.io.FileInputStream; -import java.net.URL; import java.util.*; import org.openapitools.codegen.*; import org.openapitools.codegen.languages.JavaClientCodegen; import org.openapitools.codegen.utils.ModelUtils; -import org.yaml.snakeyaml.Yaml; @SuppressWarnings("unchecked") public class AlgoliaJavaGenerator extends JavaClientCodegen { @@ -25,90 +22,6 @@ public String getName() { return "algolia-java"; } - /** Inject server info into the client to generate the right URL */ - private void generateServer(Map client) { - String clientName = (String) client.get("pathPrefix"); - Yaml yaml = new Yaml(); - try { - Map spec = yaml.load( - new FileInputStream("specs/" + clientName + "/spec.yml") - ); - List> servers = (List>) spec.get( - "servers" - ); - - boolean hasRegionalHost = false; - boolean fallbackToAliasHost = false; - - boolean isEuHost = false; - boolean isDeHost = false; - String host = ""; - String topLevelDomain = ""; - for (Map server : servers) { - if (!server.containsKey("url")) { - throw new GenerationException( - "Invalid server, does not contains 'url'" - ); - } - - // Determine if the current URL with `region` also have an alias without - // variables. - for (Map otherServer : servers) { - if (server == otherServer) { - continue; - } - String otherUrl = (String) otherServer.getOrDefault("url", ""); - if (otherUrl.replace(".{region}", "").equals(server.get("url"))) { - fallbackToAliasHost = true; - break; - } - } - - if (!server.containsKey("variables")) { - continue; - } - - Map> variables = (Map>) server.get( - "variables" - ); - - if ( - !variables.containsKey("region") || - !variables.get("region").containsKey("enum") - ) { - continue; - } - ArrayList enums = (ArrayList) variables - .get("region") - .get("enum"); - hasRegionalHost = true; - - URL url = new URL((String) server.get("url")); - - if (enums.contains("eu")) { - isEuHost = true; - } - - if (enums.contains("de")) { - isDeHost = true; - } - - // This is used for hosts like `insights` that uses `.io` - String[] hostParts = url.getHost().split("\\."); - host = hostParts[0]; - topLevelDomain = hostParts[hostParts.length - 1]; - } - client.put("hasRegionalHost", hasRegionalHost); - client.put("fallbackToAliasHost", fallbackToAliasHost); - client.put("isEuHost", isEuHost); - client.put("isDeHost", isDeHost); - client.put("host", host); - client.put("topLevelDomain", topLevelDomain); - } catch (Exception e) { - e.printStackTrace(); - } - } - @Override public CodegenOperation fromOperation( String path, @@ -131,11 +44,11 @@ public Map postProcessOperationsWithModels( objs, allModels ); - Map client = (Map) results.get( - "operations" - ); - generateServer(client); + Utils.generateServer( + Utils.getClientNameKebabCase(results), + additionalProperties + ); return results; } diff --git a/generators/src/main/java/com/algolia/codegen/AlgoliaJavascriptGenerator.java b/generators/src/main/java/com/algolia/codegen/AlgoliaJavascriptGenerator.java index c23e54fc88..c0773913d9 100644 --- a/generators/src/main/java/com/algolia/codegen/AlgoliaJavascriptGenerator.java +++ b/generators/src/main/java/com/algolia/codegen/AlgoliaJavascriptGenerator.java @@ -54,8 +54,7 @@ public void processOpts() { } /** Set default generator options */ - private void setDefaultGeneratorOptions(Map client) { - CLIENT = (String) client.get("pathPrefix"); + private void setDefaultGeneratorOptions() { String apiName = CLIENT + Utils.API_SUFFIX; additionalProperties.put("apiName", apiName); @@ -73,11 +72,14 @@ public Map postProcessOperationsWithModels( objs, allModels ); - Map client = (Map) results.get( - "operations" - ); - setDefaultGeneratorOptions(client); + CLIENT = Utils.getClientNameCamelCase(results); + + setDefaultGeneratorOptions(); + Utils.generateServer( + Utils.getClientNameKebabCase(results), + additionalProperties + ); return results; } diff --git a/generators/src/main/java/com/algolia/codegen/AlgoliaPhpGenerator.java b/generators/src/main/java/com/algolia/codegen/AlgoliaPhpGenerator.java index 3d761dd6cb..8ca265b09d 100644 --- a/generators/src/main/java/com/algolia/codegen/AlgoliaPhpGenerator.java +++ b/generators/src/main/java/com/algolia/codegen/AlgoliaPhpGenerator.java @@ -28,16 +28,14 @@ public CodegenOperation fromOperation( } /** Set default generator options */ - public void setDefaultGeneratorOptions(Map client) { - String spec = (String) client.get("pathPrefix"); - - if (spec.equals("search") || spec.equals("recommend")) { + public void setDefaultGeneratorOptions(String client) { + if (client.equals("search") || client.equals("recommend")) { additionalProperties.put("useCache", true); } additionalProperties.put( "configClassname", - Utils.createClientName(spec, "php") + "Config" + Utils.createClientName(client, "php") + "Config" ); } @@ -51,11 +49,11 @@ public Map postProcessOperationsWithModels( objs, allModels ); - Map client = (Map) results.get( - "operations" - ); + + String client = Utils.getClientNameKebabCase(results); setDefaultGeneratorOptions(client); + Utils.generateServer(client, additionalProperties); return results; } diff --git a/generators/src/main/java/com/algolia/codegen/Utils.java b/generators/src/main/java/com/algolia/codegen/Utils.java index 947dfd4600..e53afcf85e 100644 --- a/generators/src/main/java/com/algolia/codegen/Utils.java +++ b/generators/src/main/java/com/algolia/codegen/Utils.java @@ -1,8 +1,11 @@ package com.algolia.codegen; import com.google.common.collect.Sets; -import java.util.Set; +import java.io.FileInputStream; +import java.net.URL; +import java.util.*; import org.openapitools.codegen.CodegenOperation; +import org.yaml.snakeyaml.Yaml; public class Utils { @@ -49,4 +52,109 @@ public static String createClientName(String client, String language) { return clientName; } + + public static String getClientNameKebabCase(Map data) { + String client = (String) ((Map) data.get("operations")).get( + "pathPrefix" + ); + return client + .replaceAll("(.+?)([A-Z]|[0-9])", "$1-$2") + .toLowerCase(Locale.ROOT); + } + + public static String getClientNameCamelCase(Map data) { + return (String) ((Map) data.get("operations")).get( + "pathPrefix" + ); + } + + /** Inject server info into the client to generate the right URL */ + public static void generateServer( + String clientKebab, + Map additionalProperties + ) { + Yaml yaml = new Yaml(); + try { + Map spec = yaml.load( + new FileInputStream("specs/bundled/" + clientKebab + ".yml") + ); + List> servers = (List>) spec.get( + "servers" + ); + + boolean hasRegionalHost = false; + boolean fallbackToAliasHost = false; + String host = ""; + String topLevelDomain = ""; + Set allowedRegions = new HashSet<>(); + for (Map server : servers) { + if (!server.containsKey("url")) { + throw new GenerationException( + "Invalid server, does not contains 'url'" + ); + } + + // Determine if the current URL with `region` also have an alias without + // variables. + for (Map otherServer : servers) { + if (server == otherServer) { + continue; + } + String otherUrl = (String) otherServer.getOrDefault("url", ""); + if (otherUrl.replace(".{region}", "").equals(server.get("url"))) { + fallbackToAliasHost = true; + break; + } + } + + if (!server.containsKey("variables")) { + continue; + } + + Map> variables = (Map>) server.get( + "variables" + ); + + if ( + !variables.containsKey("region") || + !variables.get("region").containsKey("enum") + ) { + continue; + } + ArrayList regions = (ArrayList) variables + .get("region") + .get("enum"); + hasRegionalHost = true; + + for (String region : regions) { + allowedRegions.add(region); + } + + // This is used for hosts like `insights` that uses `.io` + URL url = new URL((String) server.get("url")); + String[] hostParts = url.getHost().split("\\."); + host = hostParts[0]; + topLevelDomain = hostParts[hostParts.length - 1]; + } + additionalProperties.put("hasRegionalHost", hasRegionalHost); + additionalProperties.put("fallbackToAliasHost", fallbackToAliasHost); + additionalProperties.put("host", host); + additionalProperties.put("topLevelDomain", topLevelDomain); + additionalProperties.put( + "allowedRegions", + allowedRegions.toArray(new String[0]) + ); + + if (clientKebab.equals("predict")) { + additionalProperties.put("isExperimentalHost", true); + additionalProperties.put( + "host", + new URL((String) servers.get(0).get("url")).getHost() + ); + } + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + } } diff --git a/generators/src/main/java/com/algolia/codegen/cts/AlgoliaCtsGenerator.java b/generators/src/main/java/com/algolia/codegen/cts/AlgoliaCtsGenerator.java index b09873e0d6..945275f143 100644 --- a/generators/src/main/java/com/algolia/codegen/cts/AlgoliaCtsGenerator.java +++ b/generators/src/main/java/com/algolia/codegen/cts/AlgoliaCtsGenerator.java @@ -22,7 +22,6 @@ public class AlgoliaCtsGenerator extends DefaultCodegen { private String language; private String client; private String packageName; - private boolean hasRegionalHost; /** * Configures the type of generator. @@ -64,8 +63,6 @@ public void processOpts() { language = (String) additionalProperties.get("language"); client = (String) additionalProperties.get("client"); packageName = (String) additionalProperties.get("packageName"); - hasRegionalHost = - additionalProperties.get("hasRegionalHost").equals("true"); try { JsonNode config = Json @@ -130,6 +127,15 @@ public Map postProcessSupportingFileData( // The return value of this function is not used, we need to modify the param // itself. Object lambda = objs.get("lambda"); + List servers = (List) objs.get("servers"); + boolean hasRegionalHost = servers + .stream() + .anyMatch(server -> + server.variables + .stream() + .anyMatch(variable -> variable.name.equals("region")) + ); + Map bundle = objs; bundle.clear(); diff --git a/package.json b/package.json index 79d0672200..ba0bd90768 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "website:build": "yarn workspace website build" }, "devDependencies": { - "@experimental-api-clients-automation/openapi-generator-cli": "0.0.1", + "@openapitools/openapi-generator-cli": "2.5.1", "@prettier/plugin-php": "0.18.4", "@redocly/openapi-cli": "1.0.0-beta.93", "@typescript-eslint/eslint-plugin": "5.18.0", diff --git a/scripts/ci/codegen/pushGeneratedCode.ts b/scripts/ci/codegen/pushGeneratedCode.ts index e0937d5a73..72f7f5d614 100644 --- a/scripts/ci/codegen/pushGeneratedCode.ts +++ b/scripts/ci/codegen/pushGeneratedCode.ts @@ -6,7 +6,8 @@ import { getNbGitDiff } from '../utils'; import text from './text'; const PR_NUMBER = parseInt(process.env.PR_NUMBER || '0', 10); -const FOLDERS_TO_CHECK = 'yarn.lock openapitools.json clients specs/bundled'; +const FOLDERS_TO_CHECK = + 'yarn.lock config/openapitools.json clients specs/bundled'; async function isUpToDate(baseBranch: string): Promise { await run('git fetch origin'); diff --git a/scripts/ci/githubActions/setRunVariables.ts b/scripts/ci/githubActions/setRunVariables.ts index a81082083a..f0907f018a 100644 --- a/scripts/ci/githubActions/setRunVariables.ts +++ b/scripts/ci/githubActions/setRunVariables.ts @@ -9,7 +9,7 @@ const PHP_CLIENT_FOLDER = getLanguageFolder('php'); // Files that are common to every clients const CLIENTS_COMMON_FILES = [ - 'openapitools.json', + 'config/openapitools.json', 'config/clients.config.json', ]; diff --git a/scripts/common.ts b/scripts/common.ts index 796e5bece4..48c4055cd6 100644 --- a/scripts/common.ts +++ b/scripts/common.ts @@ -6,8 +6,8 @@ import { hashElement } from 'folder-hash'; import { remove } from 'fs-extra'; import clientsConfig from '../config/clients.config.json'; -import config from '../config/release.config.json'; -import openapitools from '../openapitools.json'; +import openapiConfig from '../config/openapitools.json'; +import releaseConfig from '../config/release.config.json'; import { createSpinner } from './oraLog'; import type { @@ -17,9 +17,9 @@ import type { RunOptions, } from './types'; -export const MAIN_BRANCH = config.mainBranch; -export const OWNER = config.owner; -export const REPO = config.repo; +export const MAIN_BRANCH = releaseConfig.mainBranch; +export const OWNER = releaseConfig.owner; +export const REPO = releaseConfig.repo; export const REPO_URL = `https://github.com/${OWNER}/${REPO}`; export const CI = Boolean(process.env.CI); @@ -41,7 +41,7 @@ export const GENERATORS: Record = { buildFile: 'algoliasearch', packageName: '@experimental-api-clients-automation/algoliasearch', packageVersion: - openapitools['generator-cli'].generators[ + openapiConfig['generator-cli'].generators[ clientsConfig.javascript.mainPackage ].additionalProperties.packageVersion, }, @@ -49,7 +49,7 @@ export const GENERATORS: Record = { }; // Build `GENERATORS` from the openapitools file -Object.entries(openapitools['generator-cli'].generators).forEach( +Object.entries(openapiConfig['generator-cli'].generators).forEach( ([key, gen]) => { GENERATORS[key] = { ...gen, @@ -103,14 +103,14 @@ export const getGitHubUrl: GitHubUrl = ( lang: string, { token } = {} ): string => { - const entry = Object.entries(openapitools['generator-cli'].generators).find( + const entry = Object.entries(openapiConfig['generator-cli'].generators).find( (_entry) => _entry[0].startsWith(`${lang}-`) ); if (!entry) { throw new Error(`\`${lang}\` is not found from \`openapitools.json\`.`); } - const { gitHost, gitRepoId } = entry[1]; + const { gitRepoId } = entry[1]; // GitHub Action provides a default token for authentication // https://docs.github.com/en/actions/security-guides/automatic-token-authentication @@ -118,8 +118,8 @@ export const getGitHubUrl: GitHubUrl = ( // If we want to do something like pushing commits to other repositories, // we need to specify a token with more access. return token - ? `https://${token}:${token}@github.com/${gitHost}/${gitRepoId}` - : `https://github.com/${gitHost}/${gitRepoId}`; + ? `https://${token}:${token}@github.com/algolia/${gitRepoId}` + : `https://github.com/algolia/${gitRepoId}`; }; export function createGeneratorKey({ diff --git a/scripts/cts/generate.ts b/scripts/cts/generate.ts index 0542cb1a50..5473af1337 100644 --- a/scripts/cts/generate.ts +++ b/scripts/cts/generate.ts @@ -2,6 +2,7 @@ import { buildCustomGenerators, run, toAbsolutePath } from '../common'; import { getTestOutputFolder } from '../config'; import { formatter } from '../formatter'; import { createSpinner } from '../oraLog'; +import { generateOpenapitools } from '../pre-gen'; import type { Generator } from '../types'; import { generateClientTests } from './client/generate'; @@ -14,7 +15,7 @@ async function ctsGenerate(gen: Generator, verbose: boolean): Promise { ).start(); await run( `yarn openapi-generator-cli --custom-generator=generators/build/libs/algolia-java-openapi-generator-1.0.0.jar generate \ - -g algolia-cts -i specs/bundled/${gen.client}.yml --additional-properties="language=${gen.language},client=${gen.client},packageName=${gen.additionalProperties.packageName},hasRegionalHost=${gen.additionalProperties.hasRegionalHost}"`, + -g algolia-cts -i specs/bundled/${gen.client}.yml --additional-properties="language=${gen.language},client=${gen.client},packageName=${gen.additionalProperties.packageName}"`, { verbose } ); spinner.succeed(); @@ -31,6 +32,7 @@ export async function ctsGenerateMany( verbose: boolean ): Promise { await buildCustomGenerators(verbose); + await generateOpenapitools(generators); for (const gen of generators) { if (!getTestOutputFolder(gen.language)) { diff --git a/scripts/generate.ts b/scripts/generate.ts index b168b2933f..f8676168b1 100644 --- a/scripts/generate.ts +++ b/scripts/generate.ts @@ -3,13 +3,11 @@ import { buildCustomGenerators, CI, run } from './common'; import { getCustomGenerator, getLanguageFolder } from './config'; import { formatter } from './formatter'; import { createSpinner } from './oraLog'; -import { removeExistingCodegen, setDefaultGeneratorOptions } from './pre-gen'; +import { generateOpenapitools, removeExistingCodegen } from './pre-gen'; import type { Generator } from './types'; async function preGen(gen: Generator, verbose?: boolean): Promise { await removeExistingCodegen(gen, verbose); - - await setDefaultGeneratorOptions(gen); } async function generateClient( @@ -38,6 +36,8 @@ export async function generate( await buildSpecs(clients, 'yml', verbose, true); } + await generateOpenapitools(generators); + const availableWorkspaces = await run('yarn workspaces list', { verbose }); const langs = [...new Set(generators.map((gen) => gen.language))]; const useCustomGenerator = langs diff --git a/scripts/pre-gen/generateOpenapitools.ts b/scripts/pre-gen/generateOpenapitools.ts new file mode 100644 index 0000000000..a625e1ccf0 --- /dev/null +++ b/scripts/pre-gen/generateOpenapitools.ts @@ -0,0 +1,49 @@ +import { writeFile } from 'fs/promises'; + +import clientsConfig from '../../config/clients.config.json'; +import openapiConfig from '../../config/openapitools.json'; +import { toAbsolutePath } from '../common'; +import type { Generator } from '../types'; + +const AVAILABLE_CUSTOM_GEN = Object.values(clientsConfig) + .map((gen) => ('customGenerator' in gen ? gen.customGenerator : null)) + .filter(Boolean); + +/** + * Create openapitools.json file with default options for all generators. + * + * Defaults options are used to + * - Set config path. + */ +export async function generateOpenapitools( + generators: Generator[] +): Promise { + const result = {}; + for (const { key, client, language, ...rest } of generators) { + result[key] = { + config: '#{cwd}/openapitools.json', + gitHost: 'algolia', + gitUserId: 'algolia', + glob: `specs/bundled/${client}.yml`, + templateDir: `#{cwd}/templates/${language}/`, + generatorName: AVAILABLE_CUSTOM_GEN.includes(`algolia-${language}`) + ? `algolia-${language}` + : rest.generatorName, + ...rest, + output: `#{cwd}/${rest.output}`, + }; + } + await writeFile( + toAbsolutePath('openapitools.json'), + JSON.stringify( + { + 'generator-cli': { + version: openapiConfig['generator-cli'].version, + generators: result, + }, + }, + null, + 2 + ).concat('\n') + ); +} diff --git a/scripts/pre-gen/getHostsOptions.ts b/scripts/pre-gen/getHostsOptions.ts deleted file mode 100644 index e2b19b77a6..0000000000 --- a/scripts/pre-gen/getHostsOptions.ts +++ /dev/null @@ -1,81 +0,0 @@ -import { readFile } from 'fs/promises'; -import { URL } from 'url'; - -import yaml from 'js-yaml'; - -import { exists, toAbsolutePath } from '../common'; -import type { AdditionalProperties, Generator, Spec } from '../types'; - -/** - * Retrieve hosts options from the bundled spec file to define them - * in the `additionalProperties` of a generator. - * - * Those options are used to determine which host method should be generated - * in the template. - */ -export async function getHostsOptions({ - client, - key, -}: Pick): Promise { - const specPath = toAbsolutePath(`specs/bundled/${client}.yml`); - - if (!(await exists(specPath))) { - throw new Error( - `File not found ${specPath}.\nMake sure your run scripts from the root directory using yarn workspace.` - ); - } - - try { - const { servers } = yaml.load(await readFile(specPath, 'utf8')) as Spec; - const additionalProperties: AdditionalProperties = {}; - - for (const [index, { url, variables }] of servers.entries()) { - if (!url) { - throw new Error(`Invalid server: ${url}`); - } - - const { host } = new URL(url); - - // Edge case for `predict`, we should maybe have a proper way to detect - // experimental/staging hosts - if (client === 'predict') { - additionalProperties.experimentalHost = host; - } - - if (!variables?.region || !variables?.region?.enum) { - continue; - } - - additionalProperties.hasRegionalHost = true; - - if (!additionalProperties.fallbackToAliasHost) { - // Determine if the current URL with `region` also have an alias without variables. - additionalProperties.fallbackToAliasHost = - servers.some((curr, i) => { - // we skip current item - if (i === index) { - return false; - } - - return curr.url === url.replace('.{region}', ''); - }) || undefined; - } - - if (variables.region.enum.includes('eu')) { - additionalProperties.isEuHost = true; - } - - if (variables.region.enum.includes('de')) { - additionalProperties.isDeHost = true; - } - - // This is used for hosts like `insights` that uses `.io` - additionalProperties.host = host.split('.')[0]; - additionalProperties.topLevelDomain = host.split('.').pop(); - } - - return additionalProperties; - } catch (e) { - throw new Error(`Error reading yaml file ${key}: ${e}`); - } -} diff --git a/scripts/pre-gen/index.ts b/scripts/pre-gen/index.ts index 30f042dae8..271643e64c 100644 --- a/scripts/pre-gen/index.ts +++ b/scripts/pre-gen/index.ts @@ -1,2 +1,2 @@ export * from './removeExistingCodegen'; -export * from './setDefaultGeneratorOptions'; +export * from './generateOpenapitools'; diff --git a/scripts/pre-gen/setDefaultGeneratorOptions.ts b/scripts/pre-gen/setDefaultGeneratorOptions.ts deleted file mode 100644 index c4b55001d2..0000000000 --- a/scripts/pre-gen/setDefaultGeneratorOptions.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { readFile, stat, writeFile } from 'fs/promises'; - -import clientsConfig from '../../config/clients.config.json'; -import { toAbsolutePath } from '../common'; -import type { Generator } from '../types'; - -import { getHostsOptions } from './getHostsOptions'; - -const AVAILABLE_CUSTOM_GEN = Object.entries(clientsConfig).reduce( - (clients, [lang, clientOptions]) => { - if (clientOptions.customGenerator) { - return [...new Set([...clients, lang])]; - } - - return clients; - }, - [] as string[] -); - -/** - * Sets default generator options to the openapitools.json config file. - * - * Defaults options are used to - * - Set the hosts option based on the `servers` of input spec. - * - Set config path. - */ -export async function setDefaultGeneratorOptions({ - language, - client, - key, -}: Generator): Promise { - const openapitoolsPath = toAbsolutePath('openapitools.json'); - if (!(await stat(openapitoolsPath))) { - throw new Error( - `File not found ${openapitoolsPath}.\nMake sure your run scripts from the root directory using yarn workspace.` - ); - } - const openapitools = JSON.parse(await readFile(openapitoolsPath, 'utf-8')); - const generatorOptions = openapitools['generator-cli'].generators[key]; - - if (!key || !generatorOptions) { - throw new Error(`Generator not found: ${key}`); - } - - const hostsOptions = await getHostsOptions({ client, key }); - - openapitools['generator-cli'].generators[key] = { - config: '#{cwd}/openapitools.json', - gitHost: 'algolia', - gitUserId: 'algolia', - glob: `specs/bundled/${client}.yml`, - templateDir: `#{cwd}/templates/${language}/`, - generatorName: AVAILABLE_CUSTOM_GEN.includes(language) - ? `algolia-${language}` - : generatorOptions.generatorName, - ...generatorOptions, - additionalProperties: { - ...generatorOptions.additionalProperties, - ...hostsOptions, - }, - }; - - await writeFile( - openapitoolsPath, - JSON.stringify(openapitools, null, 2).concat('\n') - ); -} diff --git a/scripts/release/process-release.ts b/scripts/release/process-release.ts index 1156ba2ca4..17d40ed0ad 100755 --- a/scripts/release/process-release.ts +++ b/scripts/release/process-release.ts @@ -7,7 +7,7 @@ import { copy } from 'fs-extra'; import semver from 'semver'; import type { ReleaseType } from 'semver'; -import openapitools from '../../openapitools.json'; +import openapiConfig from '../../config/openapitools.json'; import { ROOT_ENV_PATH, toAbsolutePath, @@ -105,16 +105,16 @@ async function updateOpenApiTools( versionsToRelease: VersionsToRelease ): Promise { const nextUtilsPackageVersion = semver.inc( - openapitools['generator-cli'].generators[MAIN_PACKAGE.javascript] + openapiConfig['generator-cli'].generators[MAIN_PACKAGE.javascript] .additionalProperties.utilsPackageVersion, versionsToRelease.javascript?.releaseType ); - Object.keys(openapitools['generator-cli'].generators).forEach((client) => { + Object.keys(openapiConfig['generator-cli'].generators).forEach((client) => { const lang = client.split('-')[0]; if (versionsToRelease[lang]) { const additionalProperties = - openapitools['generator-cli'].generators[client].additionalProperties; + openapiConfig['generator-cli'].generators[client].additionalProperties; const releaseType = versionsToRelease[lang].releaseType; const newVersion = semver.inc( @@ -137,8 +137,8 @@ async function updateOpenApiTools( } }); await fsp.writeFile( - toAbsolutePath('openapitools.json'), - JSON.stringify(openapitools, null, 2) + toAbsolutePath('config/openapitools.json'), + JSON.stringify(openapiConfig, null, 2) ); } diff --git a/scripts/types.ts b/scripts/types.ts index f36b75f84a..b4b5a03d20 100644 --- a/scripts/types.ts +++ b/scripts/types.ts @@ -10,15 +10,6 @@ export type Generator = Record & { export type AdditionalProperties = Partial<{ packageName: string; hasRegionalHost: boolean; - fallbackToAliasHost: boolean; - isEuHost: boolean; - isDeHost: boolean; - host: string; - topLevelDomain: string; - /** - * Client name needs to be explicitly set, no variables required in the host. - */ - experimentalHost: string; }> & Record; diff --git a/templates/java/libraries/okhttp-gson/api.mustache b/templates/java/libraries/okhttp-gson/api.mustache index 3e81da3d81..de7a0b9a56 100644 --- a/templates/java/libraries/okhttp-gson/api.mustache +++ b/templates/java/libraries/okhttp-gson/api.mustache @@ -50,11 +50,11 @@ public class {{classname}} extends ApiClient { {{^hasRegionalHost}} public {{classname}}(String appId, String apiKey) { - this(appId, apiKey, new HttpRequester(getDefaultHosts({{^experimentalHost}}appId{{/experimentalHost}})), null); + this(appId, apiKey, new HttpRequester(getDefaultHosts({{^isExperimentalHost}}appId{{/isExperimentalHost}})), null); } public {{classname}}(String appId, String apiKey, UserAgent.Segment[] userAgentSegments) { - this(appId, apiKey, new HttpRequester(getDefaultHosts({{^experimentalHost}}appId{{/experimentalHost}})), userAgentSegments); + this(appId, apiKey, new HttpRequester(getDefaultHosts({{^isExperimentalHost}}appId{{/isExperimentalHost}})), userAgentSegments); } {{/hasRegionalHost}} @@ -66,7 +66,7 @@ public class {{classname}} extends ApiClient { super(appId, apiKey, requester, "{{{baseName}}}", userAgentSegments); } - {{^hasRegionalHost}}{{^experimentalHost}} + {{^hasRegionalHost}}{{^isExperimentalHost}} private static List getDefaultHosts(String appId) { List hosts = new ArrayList(); hosts.add(new StatefulHost(appId + "-dsn.algolia.net", "https", EnumSet.of(CallType.READ))); @@ -81,20 +81,20 @@ public class {{classname}} extends ApiClient { return Stream.concat(hosts.stream(), commonHosts.stream()).collect(Collectors.toList()); } - {{/experimentalHost}}{{/hasRegionalHost}} + {{/isExperimentalHost}}{{/hasRegionalHost}} - {{#experimentalHost}} + {{#isExperimentalHost}} private static List getDefaultHosts() { List hosts = new ArrayList(); - hosts.add(new StatefulHost("{{{experimentalHost}}}", "https", EnumSet.of(CallType.READ, CallType.WRITE))); + hosts.add(new StatefulHost("{{{host}}}", "https", EnumSet.of(CallType.READ, CallType.WRITE))); return hosts; } - {{/experimentalHost}} + {{/isExperimentalHost}} {{#hasRegionalHost}} private static List getDefaultHosts(String region) { List hosts = new ArrayList(); - hosts.add(new StatefulHost("{{{host}}}." + (region == null ? "" : region + ".") + "algolia.{{#topLevelDomain}}{{.}}{{/topLevelDomain}}{{^topLevelDomain}}com{{/topLevelDomain}}", "https", EnumSet.of(CallType.READ, CallType.WRITE))); + hosts.add(new StatefulHost("{{{host}}}." + {{#fallbackToAliasHost}}(region == null ? "" : region + "."){{/fallbackToAliasHost}}{{^fallbackToAliasHost}}region{{/fallbackToAliasHost}} + "algolia.{{#topLevelDomain}}{{.}}{{/topLevelDomain}}{{^topLevelDomain}}com{{/topLevelDomain}}", "https", EnumSet.of(CallType.READ, CallType.WRITE))); return hosts; } {{/hasRegionalHost}} diff --git a/templates/javascript/api-single.mustache b/templates/javascript/api-single.mustache index f5e242eb0e..8409110960 100644 --- a/templates/javascript/api-single.mustache +++ b/templates/javascript/api-single.mustache @@ -28,10 +28,10 @@ export const apiClientVersion = '{{packageVersion}}'; {{/description}} {{#hasRegionalHost}} -export type Region = {{#isDeHost}}'de'{{/isDeHost}}{{#isEuHost}}'eu'{{/isEuHost}} | 'us'; +export type Region = {{#allowedRegions}}'{{.}}'{{^-last}}|{{/-last}}{{/allowedRegions}}; {{/hasRegionalHost}} -{{^hasRegionalHost}}{{^experimentalHost}} +{{^hasRegionalHost}}{{^isExperimentalHost}} function getDefaultHosts(appId: string): Host[] { return ( [ @@ -66,13 +66,13 @@ function getDefaultHosts(appId: string): Host[] { ]) ); } -{{/experimentalHost}}{{/hasRegionalHost}} +{{/isExperimentalHost}}{{/hasRegionalHost}} -{{#experimentalHost}} +{{#isExperimentalHost}} function getDefaultHosts(): Host[] { - return [{ url: '{{experimentalHost}}', accept: 'readWrite', protocol: 'https' }]; + return [{ url: '{{host}}', accept: 'readWrite', protocol: 'https' }]; } -{{/experimentalHost}} +{{/isExperimentalHost}} {{#hasRegionalHost}} function getDefaultHosts(region{{#fallbackToAliasHost}}?{{/fallbackToAliasHost}}: Region): Host[] { @@ -86,7 +86,7 @@ function getDefaultHosts(region{{#fallbackToAliasHost}}?{{/fallbackToAliasHost}} export function create{{capitalizedApiName}}(options: CreateClientOptions{{#hasRegionalHost}} & {region{{#fallbackToAliasHost}}?{{/fallbackToAliasHost}}: Region }{{/hasRegionalHost}}) { const auth = createAuth(options.appId, options.apiKey, options.authMode); const transporter = createTransporter({ - hosts: options?.hosts ?? getDefaultHosts({{^hasRegionalHost}}{{^experimentalHost}}options.appId{{/experimentalHost}}{{/hasRegionalHost}}{{#hasRegionalHost}}options.region{{/hasRegionalHost}}), + hosts: options?.hosts ?? getDefaultHosts({{^hasRegionalHost}}{{^isExperimentalHost}}options.appId{{/isExperimentalHost}}{{/hasRegionalHost}}{{#hasRegionalHost}}options.region{{/hasRegionalHost}}), hostsCache: options.hostsCache, requestsCache: options.requestsCache, responsesCache: options.responsesCache, diff --git a/templates/php/api.mustache b/templates/php/api.mustache index e69512ee76..4cdb99e280 100644 --- a/templates/php/api.mustache +++ b/templates/php/api.mustache @@ -54,7 +54,7 @@ use {{invokerPackage}}\RetryStrategy\ClusterHosts; */ public static function create($appId = null, $apiKey = null, $region = null) { - $allowedRegions = explode('-', '{{{allowedRegions}}}'); + $allowedRegions = [{{#allowedRegions}}'{{.}}'{{^-last}},{{/-last}}{{/allowedRegions}}]; $config = {{configClassname}}::create($appId, $apiKey, $region, $allowedRegions); return static::createWithConfig($config); diff --git a/website/docs/automation/add-new-api-client.md b/website/docs/automation/add-new-api-client.md index 56bbd5a1f6..990e719164 100644 --- a/website/docs/automation/add-new-api-client.md +++ b/website/docs/automation/add-new-api-client.md @@ -45,11 +45,11 @@ Path definition of the paths defined in the [spec file](#specyml-file) ## 2. Configuring the environment -> The generator follows its own configuration file named `openapitools.json` +> The generator follows its own configuration file named `config/openapitools.json` ### Generation config -[openapitools.json](https://github.com/algolia/api-clients-automation/blob/main/openapitools.json) hosts the configuration of all of the generated clients with their available languages. +[config/openapitools.json](https://github.com/algolia/api-clients-automation/blob/main/config/openapitools.json) hosts the configuration of all of the generated clients with their available languages. #### `generators` diff --git a/website/docs/automation/add-new-language.md b/website/docs/automation/add-new-language.md index a8db1dded9..f49ba1c275 100644 --- a/website/docs/automation/add-new-language.md +++ b/website/docs/automation/add-new-language.md @@ -34,7 +34,7 @@ openapi-generator author template -g typescript-node -o templates/javascript/ ## Update the generator config -Add each client in the file [`openapitools.json`](https://github.com/algolia/api-clients-automation/blob/main/openapitools.json), following the others client structure. +Add each client in the file [`config/openapitools.json`](https://github.com/algolia/api-clients-automation/blob/main/config/openapitools.json), following the others client structure. > See [`add a new client`](/docs/automation/add-new-api-client) for informations on how to structure your new client. diff --git a/website/docs/automation/release-process.md b/website/docs/automation/release-process.md index 404ad65e2d..2b53920299 100644 --- a/website/docs/automation/release-process.md +++ b/website/docs/automation/release-process.md @@ -85,7 +85,7 @@ If it's not a snapshot, you can ignore the sonatype repository. ### JavaScript 1. [Get an NPM `publish` token](https://www.npmjs.com/settings/YOUR_USER_NAME/tokens) and put it in your `.env` file at the root of the repository -2. Go to `openapitools.json` and update every `packageVersion` and `utilsPackageVersion` fields for the `javascript-` generators +2. Go to `config/openapitools.json` and update every `packageVersion` and `utilsPackageVersion` fields for the `javascript-` generators 3. Run and build the JavaScript clients `yarn docker generate javascript && yarn docker build clients javascript` 4. Update the [JavaScript CTS package](https://github.com/algolia/api-clients-automation/blob/main/tests/output/javascript/package.json) and the [playground package]([JavaScript CTS package](https://github.com/algolia/api-clients-automation/blob/main/playground/javascript/node/package.json)) 5. Go to each folder of the packages, at the `package.json` level (e.g. [this folder](https://github.com/algolia/api-clients-automation/tree/main/clients/algoliasearch-client-javascript/packages/algoliasearch/)) and run `npm publish --access public` diff --git a/yarn.lock b/yarn.lock index df9b8710d6..19410b407d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,7 +9,7 @@ __metadata: version: 0.0.0-use.local resolution: "@algolia/api-client-automation@workspace:." dependencies: - "@experimental-api-clients-automation/openapi-generator-cli": 0.0.1 + "@openapitools/openapi-generator-cli": 2.5.1 "@prettier/plugin-php": 0.18.4 "@redocly/openapi-cli": 1.0.0-beta.93 "@typescript-eslint/eslint-plugin": 5.18.0 @@ -2761,30 +2761,6 @@ __metadata: languageName: unknown linkType: soft -"@experimental-api-clients-automation/openapi-generator-cli@npm:0.0.1": - version: 0.0.1 - resolution: "@experimental-api-clients-automation/openapi-generator-cli@npm:0.0.1" - dependencies: - "@nestjs/common": 8.2.6 - "@nestjs/core": 8.2.6 - chalk: 4.1.2 - commander: 8.3.0 - compare-versions: 3.6.0 - concurrently: 6.5.1 - console.table: 0.10.0 - fs-extra: 10.0.0 - glob: 7.1.6 - inquirer: 8.2.0 - lodash: 4.17.21 - reflect-metadata: 0.1.13 - rxjs: 7.5.2 - tslib: 2.0.3 - bin: - openapi-generator-cli: main.js - checksum: 4d0073d5520b0beec0dd08a20d11d0201727d28fd7d1a720add0ca8fae67557c2df61d7def1da4358856c7901d89fd701857c1354a1b6633a76b4885d54bf630 - languageName: node - linkType: hard - "@experimental-api-clients-automation/recommend@0.2.0, @experimental-api-clients-automation/recommend@workspace:clients/algoliasearch-client-javascript/packages/recommend": version: 0.0.0-use.local resolution: "@experimental-api-clients-automation/recommend@workspace:clients/algoliasearch-client-javascript/packages/recommend" @@ -3949,11 +3925,11 @@ __metadata: languageName: node linkType: hard -"@nestjs/common@npm:8.2.6": - version: 8.2.6 - resolution: "@nestjs/common@npm:8.2.6" +"@nestjs/common@npm:8.4.4": + version: 8.4.4 + resolution: "@nestjs/common@npm:8.4.4" dependencies: - axios: 0.24.0 + axios: 0.26.1 iterare: 1.2.1 tslib: 2.3.1 uuid: 8.3.2 @@ -3970,18 +3946,18 @@ __metadata: optional: true class-validator: optional: true - checksum: 3999376069a9adade0d5a60bdaabd05756195ee5a8621c0d3b9f77353446188e183dfe5ec6ccb5d696c96f24da48b7edaeb3e554d9d5c3e20946ba1b030c8f54 + checksum: bd0326a7a52b4ca819ca8790cec1e649ba0067d2eee54a32aabe890729f5d7dd6ecbf834cf68aa6727974a693981a4a6c119574dd12560914041380010632174 languageName: node linkType: hard -"@nestjs/core@npm:8.2.6": - version: 8.2.6 - resolution: "@nestjs/core@npm:8.2.6" +"@nestjs/core@npm:8.4.4": + version: 8.4.4 + resolution: "@nestjs/core@npm:8.4.4" dependencies: "@nuxtjs/opencollective": 0.3.2 fast-safe-stringify: 2.1.1 iterare: 1.2.1 - object-hash: 2.2.0 + object-hash: 3.0.0 path-to-regexp: 3.2.0 tslib: 2.3.1 uuid: 8.3.2 @@ -3999,7 +3975,7 @@ __metadata: optional: true "@nestjs/websockets": optional: true - checksum: abf275dbe309302a16fa77132e362d30ed275ffbca46e51a93bdafdd99daa12a970af3f903a09f9e034af9f4372fe436b7a68bd09c81e9ea7aab00d939482ff2 + checksum: 65cc143c8e43cf009a94988a25e5c85cdab4c915990b8f840a06e7029d364e52baa381e3e0d05590f057332e0bd8c4ffce73b59f61e062ebe50ba166de156b58 languageName: node linkType: hard @@ -4264,6 +4240,31 @@ __metadata: languageName: node linkType: hard +"@openapitools/openapi-generator-cli@npm:2.5.1": + version: 2.5.1 + resolution: "@openapitools/openapi-generator-cli@npm:2.5.1" + dependencies: + "@nestjs/common": 8.4.4 + "@nestjs/core": 8.4.4 + "@nuxtjs/opencollective": 0.3.2 + chalk: 4.1.2 + commander: 8.3.0 + compare-versions: 4.1.3 + concurrently: 6.5.1 + console.table: 0.10.0 + fs-extra: 10.0.1 + glob: 7.1.6 + inquirer: 8.2.2 + lodash: 4.17.21 + reflect-metadata: 0.1.13 + rxjs: 7.5.5 + tslib: 2.0.3 + bin: + openapi-generator-cli: main.js + checksum: 9d5df24f950d2e1a4ae5a34deb0c2a4744ec58747b93a2a05e5230b25a21817b9acbc770e0513fcaa74901c64648477e5401ae440345ae285748c57879305897 + languageName: node + linkType: hard + "@parcel/bundler-default@npm:2.4.1": version: 2.4.1 resolution: "@parcel/bundler-default@npm:2.4.1" @@ -7023,12 +7024,12 @@ __metadata: languageName: node linkType: hard -"axios@npm:0.24.0": - version: 0.24.0 - resolution: "axios@npm:0.24.0" +"axios@npm:0.26.1": + version: 0.26.1 + resolution: "axios@npm:0.26.1" dependencies: - follow-redirects: ^1.14.4 - checksum: 468cf496c08a6aadfb7e699bebdac02851e3043d4e7d282350804ea8900e30d368daa6e3cd4ab83b8ddb5a3b1e17a5a21ada13fc9cebd27b74828f47a4236316 + follow-redirects: ^1.14.8 + checksum: d9eb58ff4bc0b36a04783fc9ff760e9245c829a5a1052ee7ca6013410d427036b1d10d04e7380c02f3508c5eaf3485b1ae67bd2adbfec3683704745c8d7a6e1a languageName: node linkType: hard @@ -8432,10 +8433,10 @@ __metadata: languageName: node linkType: hard -"compare-versions@npm:3.6.0": - version: 3.6.0 - resolution: "compare-versions@npm:3.6.0" - checksum: 7492a50cdaa2c27f5254eee7c4b38856e1c164991bab3d98d7fd067fe4b570d47123ecb92523b78338be86aa221668fd3868bfe8caa5587dc3ebbe1a03d52b5d +"compare-versions@npm:4.1.3": + version: 4.1.3 + resolution: "compare-versions@npm:4.1.3" + checksum: 54460756ab2d62f8a9d672db249b248fec7ca41c3e8ed242925e2f2257793ad3e83cecb2cdfd60b46a3aabc962a3a4cbf37a4b928c8f30517822d2bde937a3d1 languageName: node linkType: hard @@ -11056,7 +11057,7 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.14.4, follow-redirects@npm:^1.14.7": +"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.14.7, follow-redirects@npm:^1.14.8": version: 1.14.9 resolution: "follow-redirects@npm:1.14.9" peerDependenciesMeta: @@ -11161,25 +11162,25 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:10.0.0, fs-extra@npm:^10.0.0": - version: 10.0.0 - resolution: "fs-extra@npm:10.0.0" +"fs-extra@npm:10.0.1, fs-extra@npm:^10.0.1": + version: 10.0.1 + resolution: "fs-extra@npm:10.0.1" dependencies: graceful-fs: ^4.2.0 jsonfile: ^6.0.1 universalify: ^2.0.0 - checksum: 5285a3d8f34b917cf2b66af8c231a40c1623626e9d701a20051d3337be16c6d7cac94441c8b3732d47a92a2a027886ca93c69b6a4ae6aee3c89650d2a8880c0a + checksum: c1faaa5eb9e1c5c7c7ff09f966e93922ecb068ae1b04801cfc983ef05fcc1f66bfbb8d8d0b745c910014c7a2e7317fb6cf3bfe7390450c1157e3cc1a218f221d languageName: node linkType: hard -"fs-extra@npm:10.0.1, fs-extra@npm:^10.0.1": - version: 10.0.1 - resolution: "fs-extra@npm:10.0.1" +"fs-extra@npm:^10.0.0": + version: 10.0.0 + resolution: "fs-extra@npm:10.0.0" dependencies: graceful-fs: ^4.2.0 jsonfile: ^6.0.1 universalify: ^2.0.0 - checksum: c1faaa5eb9e1c5c7c7ff09f966e93922ecb068ae1b04801cfc983ef05fcc1f66bfbb8d8d0b745c910014c7a2e7317fb6cf3bfe7390450c1157e3cc1a218f221d + checksum: 5285a3d8f34b917cf2b66af8c231a40c1623626e9d701a20051d3337be16c6d7cac94441c8b3732d47a92a2a027886ca93c69b6a4ae6aee3c89650d2a8880c0a languageName: node linkType: hard @@ -12484,28 +12485,6 @@ __metadata: languageName: node linkType: hard -"inquirer@npm:8.2.0": - version: 8.2.0 - resolution: "inquirer@npm:8.2.0" - dependencies: - ansi-escapes: ^4.2.1 - chalk: ^4.1.1 - cli-cursor: ^3.1.0 - cli-width: ^3.0.0 - external-editor: ^3.0.3 - figures: ^3.0.0 - lodash: ^4.17.21 - mute-stream: 0.0.8 - ora: ^5.4.1 - run-async: ^2.4.0 - rxjs: ^7.2.0 - string-width: ^4.1.0 - strip-ansi: ^6.0.0 - through: ^2.3.6 - checksum: 861d1a9324ae933b49126b3541d94e4d6a2f2a25411b3f3cc00c34bf1bdab34146362d702cf289efe6d8034900dc5905bcf2ea716092a02b6fc390e5986dd236 - languageName: node - linkType: hard - "inquirer@npm:8.2.2": version: 8.2.2 resolution: "inquirer@npm:8.2.2" @@ -15842,10 +15821,10 @@ __metadata: languageName: node linkType: hard -"object-hash@npm:2.2.0": - version: 2.2.0 - resolution: "object-hash@npm:2.2.0" - checksum: 55ba841e3adce9c4f1b9b46b41983eda40f854e0d01af2802d3ae18a7085a17168d6b81731d43fdf1d6bcbb3c9f9c56d22c8fea992203ad90a38d7d919bc28f1 +"object-hash@npm:3.0.0": + version: 3.0.0 + resolution: "object-hash@npm:3.0.0" + checksum: 80b4904bb3857c52cc1bfd0b52c0352532ca12ed3b8a6ff06a90cd209dfda1b95cee059a7625eb9da29537027f68ac4619363491eedb2f5d3dddbba97494fd6c languageName: node linkType: hard @@ -18983,12 +18962,12 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:7.5.2": - version: 7.5.2 - resolution: "rxjs@npm:7.5.2" +"rxjs@npm:7.5.5, rxjs@npm:^7.5.5": + version: 7.5.5 + resolution: "rxjs@npm:7.5.5" dependencies: tslib: ^2.1.0 - checksum: daf1fe7289de500b25d822fd96cde3c138c7902e8bf0e6aa12a3e70847a5cabeeb4d677f10e19387e1db44b12c5b1be0ff5c79b8cd63ed6ce891d765e566cf4d + checksum: e034f60805210cce756dd2f49664a8108780b117cf5d0e2281506e9e6387f7b4f1532d974a8c8b09314fa7a16dd2f6cff3462072a5789672b5dcb45c4173f3c6 languageName: node linkType: hard @@ -19010,15 +18989,6 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:^7.5.5": - version: 7.5.5 - resolution: "rxjs@npm:7.5.5" - dependencies: - tslib: ^2.1.0 - checksum: e034f60805210cce756dd2f49664a8108780b117cf5d0e2281506e9e6387f7b4f1532d974a8c8b09314fa7a16dd2f6cff3462072a5789672b5dcb45c4173f3c6 - languageName: node - linkType: hard - "safe-buffer@npm:5.1.2, safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": version: 5.1.2 resolution: "safe-buffer@npm:5.1.2"