altair-static
Version:
Static package for altair graphql client
126 lines (114 loc) • 4.07 kB
text/typescript
import getAltairHtml from './get-altair-html';
import type { AltairConfigOptions } from 'altair-graphql-core/build/config/options';
export interface RenderOptions extends AltairConfigOptions {
/**
* URL to be used as a base for relative URLs
*/
baseURL?: string;
/**
* Whether to render the initial options in a seperate javascript file or not.
* Use this to be able to enforce strict CSP rules.
* @default false
*/
serveInitialOptionsInSeperateRequest?: boolean | string;
}
/**
* this type assertion is used to ensure that all properties of AltairConfigOptions are included in the RenderOptions.
* When new properties are added to AltairConfigOptions, this type assertion will throw an error and force the developer to update it accordingly.
*/
type AltairConfigOptionsObject = Record<keyof AltairConfigOptions, undefined>;
const optionsProperties: AltairConfigOptionsObject = {
endpointURL: undefined,
subscriptionsEndpoint: undefined,
subscriptionsProtocol: undefined,
initialQuery: undefined,
initialVariables: undefined,
initialPreRequestScript: undefined,
initialPostRequestScript: undefined,
initialHeaders: undefined,
initialEnvironments: undefined,
instanceStorageNamespace: undefined,
initialSettings: undefined,
initialSubscriptionRequestHandlerId: undefined,
initialSubscriptionsPayload: undefined,
initialRequestHandlerId: undefined,
initialRequestHandlerAdditionalParams: undefined,
preserveState: undefined,
initialHttpMethod: undefined,
initialWindows: undefined,
disableAccount: undefined,
persistedSettings: undefined,
initialName: undefined,
initialAuthorization: undefined,
};
const allowedProperties = Object.keys(
optionsProperties
) as (keyof AltairConfigOptions)[];
const getObjectPropertyForOption = (
option: unknown,
propertyName: keyof AltairConfigOptions
) => {
if (typeof option !== 'undefined') {
switch (typeof option) {
case 'object':
return `${propertyName}: ${JSON.stringify(option)},`;
case 'boolean':
return `${propertyName}: ${option},`;
}
return `${propertyName}: \`${option}\`,`;
}
return '';
};
/**
* Render Altair Initial options as a string using the provided renderOptions
* @param renderOptions
* @deprecated Use renderInitSnippet instead
*/
export const renderInitialOptions = (options: RenderOptions = {}) => {
return renderInitSnippet(options);
};
/**
* Render Altair init JS snippet as a string using the provided renderOptions
* @param renderOptions
*/
export const renderInitSnippet = (options: RenderOptions = {}) => {
return `
AltairGraphQL.init(${getRenderedAltairOpts(options)});
`;
};
/**
* Render Altair as a string using the provided renderOptions
* @param renderOptions
*/
export const renderAltair = (options: RenderOptions = {}) => {
const altairHtml = getAltairHtml();
const initialOptions = renderInitSnippet(options);
const baseURL = options.baseURL || './';
if (options.serveInitialOptionsInSeperateRequest) {
const scriptName =
typeof options.serveInitialOptionsInSeperateRequest === 'string'
? options.serveInitialOptionsInSeperateRequest
: 'initial_options.js';
return altairHtml
.replace(/<base.*>/, `<base href="${baseURL}">`)
.replace(
'</body>',
() => `<script src="${scriptName.replace(/["'<>=]/g, '')}"></script></body>`
);
} else {
return altairHtml
.replace(/<base.*>/, `<base href="${baseURL}">`)
.replace('</body>', () => `<script>${initialOptions}</script></body>`);
}
};
const getRenderedAltairOpts = (renderOptions: RenderOptions) => {
const optProps = Object.keys(renderOptions)
.filter((key): key is keyof AltairConfigOptions =>
allowedProperties.includes(key as keyof AltairConfigOptions)
)
.map((key) => getObjectPropertyForOption(renderOptions[key], key));
return ['{', ...optProps, '}'].join('\n');
};
export { getDistDirectory } from './get-dist';
export { getAltairHtml };
export default renderAltair;