graphql.kickstart.autoconfigure.editor.voyager.VoyagerIndexHtmlTemplate Maven / Gradle / Ivy
package graphql.kickstart.autoconfigure.editor.voyager;
import static graphql.kickstart.autoconfigure.editor.EditorConstants.CSRF_ATTRIBUTE_NAME;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringSubstitutor;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.RequestParam;
/** @author Guilherme Blanco */
@RequiredArgsConstructor
public class VoyagerIndexHtmlTemplate {
private static final String CDNJS_CLOUDFLARE_COM_AJAX_LIBS = "//cdnjs.cloudflare.com/ajax/libs/";
private static final String CDN_JSDELIVR_NET_NPM = "//cdn.jsdelivr.net/npm/";
private static final String VOYAGER = "graphql-voyager";
private static final String FAVICON_APIS_GURU =
"//apis.guru/graphql-voyager/icons/favicon-16x16.png";
private final ObjectMapper objectMapper = new ObjectMapper();
private final VoyagerPropertiesConfiguration voyagerConfiguration;
public String fillIndexTemplate(String contextPath, Object csrf, Map params)
throws IOException {
String template =
StreamUtils.copyToString(
new ClassPathResource("templates/voyager.html").getInputStream(),
Charset.defaultCharset());
String basePath = voyagerConfiguration.getBasePath();
String voyagerCdnVersion = voyagerConfiguration.getCdn().getVersion();
Map replacements = new HashMap<>();
if (csrf != null) {
replacements.put(CSRF_ATTRIBUTE_NAME, objectMapper.writeValueAsString(csrf));
} else {
replacements.put(CSRF_ATTRIBUTE_NAME, "null");
}
replacements.put("graphqlEndpoint", constructGraphQlEndpoint(contextPath, params));
replacements.put("pageTitle", voyagerConfiguration.getPageTitle());
replacements.put("pageFavicon", getResourceUrl(basePath, "favicon.ico", FAVICON_APIS_GURU));
replacements.put(
"es6PromiseJsUrl",
getResourceUrl(
basePath,
"es6-promise.auto.min.js",
joinCdnjsPath("es6-promise", "4.1.1", "es6-promise.auto.min.js")));
replacements.put(
"fetchJsUrl",
getResourceUrl(basePath, "fetch.min.js", joinCdnjsPath("fetch", "2.0.4", "fetch.min.js")));
replacements.put(
"reactJsUrl",
getResourceUrl(
basePath,
"react.min.js",
joinCdnjsPath("react", "16.8.3", "umd/react.production.min.js")));
replacements.put(
"reactDomJsUrl",
getResourceUrl(
basePath,
"react-dom.min.js",
joinCdnjsPath("react-dom", "16.8.3", "umd/react-dom.production.min.js")));
replacements.put(
"voyagerCssUrl",
getResourceUrl(
basePath, "voyager.css", joinJsDelivrPath(voyagerCdnVersion, "dist/voyager.css")));
replacements.put(
"voyagerJsUrl",
getResourceUrl(
basePath,
"voyager.min.js",
joinJsDelivrPath(voyagerCdnVersion, "dist/voyager.min.js")));
replacements.put(
"voyagerWorkerJsUrl",
getResourceUrl(
basePath,
"voyager.worker.js",
joinJsDelivrPath(voyagerCdnVersion, "dist/voyager.worker.min.js")));
replacements.put("contextPath", contextPath);
replacements.put(
"voyagerDisplayOptionsSkipRelay",
Boolean.toString(voyagerConfiguration.getDisplayOptions().isSkipRelay()));
replacements.put(
"voyagerDisplayOptionsSkipDeprecated",
Boolean.toString(voyagerConfiguration.getDisplayOptions().isSkipDeprecated()));
replacements.put(
"voyagerDisplayOptionsRootType", voyagerConfiguration.getDisplayOptions().getRootType());
replacements.put(
"voyagerDisplayOptionsSortByAlphabet",
Boolean.toString(voyagerConfiguration.getDisplayOptions().isSortByAlphabet()));
replacements.put(
"voyagerDisplayOptionsShowLeafFields",
Boolean.toString(voyagerConfiguration.getDisplayOptions().isShowLeafFields()));
replacements.put(
"voyagerDisplayOptionsHideRoot",
Boolean.toString(voyagerConfiguration.getDisplayOptions().isHideRoot()));
replacements.put("voyagerHideDocs", Boolean.toString(voyagerConfiguration.isHideDocs()));
replacements.put(
"voyagerHideSettings", Boolean.toString(voyagerConfiguration.isHideSettings()));
return StringSubstitutor.replace(template, replacements);
}
private String constructGraphQlEndpoint(
String contextPath, @RequestParam Map params) {
String endpoint = voyagerConfiguration.getEndpoint();
for (Map.Entry param : params.entrySet()) {
endpoint = endpoint.replaceAll("\\{" + Pattern.quote(param.getKey()) + "}", param.getValue());
}
if (StringUtils.isNotBlank(contextPath) && !endpoint.startsWith(contextPath)) {
return contextPath + endpoint;
}
return endpoint;
}
private String getResourceUrl(String staticBasePath, String staticFileName, String cdnUrl) {
if (voyagerConfiguration.getCdn().isEnabled() && StringUtils.isNotBlank(cdnUrl)) {
return cdnUrl;
}
return joinStaticPath(staticBasePath, staticFileName);
}
private String joinStaticPath(String staticBasePath, String staticFileName) {
return staticBasePath + "vendor/voyager/" + staticFileName;
}
private String joinCdnjsPath(String library, String cdnVersion, String cdnFileName) {
return CDNJS_CLOUDFLARE_COM_AJAX_LIBS + library + "/" + cdnVersion + "/" + cdnFileName;
}
private String joinJsDelivrPath(String cdnVersion, String cdnFileName) {
return CDN_JSDELIVR_NET_NPM
+ VoyagerIndexHtmlTemplate.VOYAGER
+ "@"
+ cdnVersion
+ "/"
+ cdnFileName;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy