Skip to content

Commit

Permalink
Type fix: only allow user to pass collectionId / operationId OR docum…
Browse files Browse the repository at this point in the history
…ent, variables, headers (#223)

* only allow user to pass collectionId / operationId OR document, variables, headers

* require both collectionId & operationId or one of document, headers, variables

* either pass both collection Id & operation Id or some selection of document, headers, variables
  • Loading branch information
mayakoneval authored Mar 9, 2023
1 parent 58165cf commit 911c95b
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 79 deletions.
85 changes: 51 additions & 34 deletions packages/explorer/src/EmbeddedExplorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,34 @@ import { setupEmbedRelay } from './setupEmbedRelay';
import packageJSON from '../package.json';
import type { JSONObject } from './helpers/types';

type InitialState = {
displayOptions?: {
docsPanelState?: 'open' | 'closed'; // default to 'open',
showHeadersAndEnvVars?: boolean; // default to `false`
theme?: 'dark' | 'light';
};
} & (
| /**
* Pass collectionId, operationId to embed the document, headers, variables associated
* with this operation id if you have access to the operation via your collections.
*/
{
collectionId: string;
operationId: string;
}
| {
document?: string;
variables?: JSONObject;
headers?: Record<string, string>;

collectionId?: never;
operationId?: never;
}
);
export interface BaseEmbeddableExplorerOptions {
target: string | HTMLElement; // HTMLElement is to accomodate people who might prefer to pass in a ref

initialState?: {
document?: string;
variables?: JSONObject;
headers?: Record<string, string>;
/**
* If you pass a collectionId & operationId, we ignore document, variables, headers
* above, and embed the document, headers, variables associated with this operation id
* if you have access to the operation via your collections.
*/
collectionId?: string;
operationId?: string;
displayOptions: {
docsPanelState?: 'open' | 'closed'; // default to 'open',
showHeadersAndEnvVars?: boolean; // default to `false`
theme?: 'dark' | 'light';
};
};
initialState?: InitialState;
/**
* defaults to 'false'
*/
Expand Down Expand Up @@ -205,29 +213,38 @@ export class EmbeddedExplorer {
}

getEmbeddedExplorerURL = () => {
const {
document,
variables,
headers,
displayOptions,
operationId,
collectionId,
} = this.options.initialState || {};
const { displayOptions } = this.options.initialState || {};

const { persistExplorerState } = this.options;
const graphRef =
'graphRef' in this.options ? this.options.graphRef : undefined;
const queryParams = {
runtime: this.options.runtime,
graphRef,
defaultCollectionEntryId: operationId,
defaultCollectionId: collectionId,
defaultDocument: document ? encodeURIComponent(document) : undefined,
defaultVariables: variables
? encodeURIComponent(JSON.stringify(variables, null, 2))
: undefined,
defaultHeaders: headers
? encodeURIComponent(JSON.stringify(headers))
: undefined,
...(this.options.initialState &&
'collectionId' in this.options.initialState
? {
defaultCollectionEntryId: this.options.initialState.operationId,
defaultCollectionId: this.options.initialState.collectionId,
}
: {}),
...(this.options.initialState && 'document' in this.options.initialState
? {
defaultDocument: this.options.initialState.document
? encodeURIComponent(this.options.initialState.document)
: undefined,
defaultVariables: this.options.initialState.variables
? encodeURIComponent(
JSON.stringify(this.options.initialState.variables, null, 2)
)
: undefined,
defaultHeaders: this.options.initialState.headers
? encodeURIComponent(
JSON.stringify(this.options.initialState.headers)
)
: undefined,
}
: {}),
shouldPersistState: !!persistExplorerState,
docsPanelState: displayOptions?.docsPanelState ?? 'open',
showHeadersAndEnvVars: displayOptions?.showHeadersAndEnvVars !== false,
Expand Down
103 changes: 58 additions & 45 deletions packages/sandbox/src/EmbeddedSandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,42 @@ import { setupSandboxEmbedRelay } from './setupSandboxEmbedRelay';
import packageJSON from '../package.json';
import type { JSONObject } from './helpers/types';

type InitialState = {
/**
* optional. Set headers for every operation a user triggers from this Sandbox.
* Users can check and uncheck these headers, but not edit them.
*/
sharedHeaders?: Record<string, string>;
/**
* optional. defaults to false
*/
includeCookies?: boolean;
/**
* defaults to true. If false, sandbox will not poll your endpoint for your schema.
* */
pollForSchemaUpdates?: boolean;
} & (
| /**
* Pass collectionId, operationId to embed the document, headers, variables associated
* with this operation id if you have access to the operation via your collections.
*/
{
collectionId: string;
operationId: string;
}
| {
document?: string;
variables?: JSONObject;
headers?: Record<string, string>;

collectionId?: never;
operationId?: never;
}
);
export interface EmbeddableSandboxOptions {
target: string | HTMLElement; // HTMLElement is to accommodate people who might prefer to pass in a ref
initialEndpoint?: string;
initialState?: {
document?: string;
variables?: JSONObject;
headers?: Record<string, string>;
/**
* If you pass a collectionId & operationId, we ignore document, variables, headers
* above, and embed the document, headers, variables associated with this operation id
* if you have access to the operation via your collections.
*/
collectionId?: string;
operationId?: string;
/**
* optional. Set headers for every operation a user triggers from this Sandbox.
* Users can check and uncheck these headers, but not edit them.
*/
sharedHeaders?: Record<string, string>;
/**
* optional. defaults to false
*/
includeCookies?: boolean;
/**
* defaults to true. If false, sandbox will not poll your endpoint for your schema.
* */
pollForSchemaUpdates?: boolean;
};
initialState?: InitialState;

/**
* optional. defaults to `return fetch(url, fetchOptions)`
Expand Down Expand Up @@ -106,30 +114,35 @@ export class EmbeddedSandbox {
let element: HTMLElement | null;
const { target } = this.options;

const {
document: initialDocument,
variables,
headers,
includeCookies,
sharedHeaders,
operationId,
collectionId,
} = this.options.initialState || {};
const { includeCookies, sharedHeaders } = this.options.initialState || {};

const queryParams = {
runtime: this.options.runtime,
endpoint: this.options.initialEndpoint,
defaultCollectionId: collectionId,
defaultCollectionEntryId: operationId,
defaultDocument: initialDocument
? encodeURIComponent(initialDocument)
: undefined,
defaultVariables: variables
? encodeURIComponent(JSON.stringify(variables, null, 2))
: undefined,
defaultHeaders: headers
? encodeURIComponent(JSON.stringify(headers))
: undefined,
...(this.options.initialState &&
'collectionId' in this.options.initialState
? {
defaultCollectionEntryId: this.options.initialState.operationId,
defaultCollectionId: this.options.initialState.collectionId,
}
: {}),
...(this.options.initialState && 'document' in this.options.initialState
? {
defaultDocument: this.options.initialState.document
? encodeURIComponent(this.options.initialState.document)
: undefined,
defaultVariables: this.options.initialState.variables
? encodeURIComponent(
JSON.stringify(this.options.initialState.variables, null, 2)
)
: undefined,
defaultHeaders: this.options.initialState.headers
? encodeURIComponent(
JSON.stringify(this.options.initialState.headers)
)
: undefined,
}
: {}),
sharedHeaders: sharedHeaders
? encodeURIComponent(JSON.stringify(sharedHeaders))
: undefined,
Expand Down

0 comments on commit 911c95b

Please sign in to comment.