Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactored request script evaluator engine #2492

Merged
merged 3 commits into from
Apr 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/pr-master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ jobs:
export CLOUDFLARE_ACCOUNT_ID="${{ secrets.CLOUDFLARE_ACCOUNT_ID }}"
cd packages/login-redirect
npx wrangler@2 pages publish "dist" --project-name="altair-login-redirect"
- run: |
export CLOUDFLARE_API_TOKEN="${{ secrets.CLOUDFLARE_API_TOKEN }}"
export CLOUDFLARE_ACCOUNT_ID="${{ secrets.CLOUDFLARE_ACCOUNT_ID }}"
cd packages/altair-iframe-sandbox
npx wrangler@2 pages publish "dist" --project-name="altair-iframe-sandbox"
test:
strategy:
matrix:
Expand Down
8 changes: 6 additions & 2 deletions packages/altair-api-utils/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export type ClientEnvironment = 'development' | 'production' | 'testing';
export interface APIClientOptions {
apiBaseUrl: string;
loginClientUrl: string;
sandboxUrl: string;
}
export const getClientConfig = (
env: ClientEnvironment = 'development'
Expand All @@ -10,16 +11,19 @@ export const getClientConfig = (
case 'production':
return {
apiBaseUrl:
process.env.ALTAIR_API_CLIENT_BASE_URL ??
'https://api.altairgraphql.dev',
process.env.ALTAIR_API_CLIENT_BASE_URL ?? 'https://api.altairgraphql.dev',
loginClientUrl:
process.env.ALTAIR_API_CLIENT_LOGIN_CLIENT_URL ??
'https://redir.altairgraphql.dev',
sandboxUrl:
process.env.ALTAIR_API_CLIENT_SANDBOX_URL ??
'https://sandbox.altairgraphql.dev',
};
}

return {
apiBaseUrl: 'http://localhost:3000',
loginClientUrl: 'http://localhost:1234',
sandboxUrl: 'http://localhost:5123',
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { Component, EventEmitter, Input, Output } from '@angular/core';

import { PostrequestState } from 'altair-graphql-core/build/types/state/postrequest.interfaces';
import { PreRequestService } from '../../services';
import { getGlobalContext } from '../../services/pre-request/helpers';
import { getRequestScriptExtensions } from '../../utils/editor/extensions';
import { getGlobalContext } from 'altair-graphql-core/build/script/context';

const AUTOCOMPLETE_CHARS = /^[a-zA-Z0-9_]$/;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Component, EventEmitter, Input, Output } from '@angular/core';
import { PrerequestState } from 'altair-graphql-core/build/types/state/prerequest.interfaces';
import { getRequestScriptExtensions } from '../../utils/editor/extensions';
import { PreRequestService } from '../../services';
import { getGlobalContext } from '../../services/pre-request/helpers';
import { getGlobalContext } from 'altair-graphql-core/build/script/context';

const AUTOCOMPLETE_CHARS = /^[a-zA-Z0-9_]$/;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,8 @@ import {
import { Store } from '@ngrx/store';
import { RootState } from 'altair-graphql-core/build/types/state/state.interfaces';
import { Subscription } from 'rxjs';
import {
EnvironmentService,
IEnvironment,
} from '../../services/environment/environment.service';
import { EnvironmentService } from '../../services/environment/environment.service';
import { IEnvironment } from 'altair-graphql-core/build/types/state/environments.interfaces';

const VariableRegex = /{{\s*([\w.]+)\s*}}/g;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ import { WEBSOCKET_PROVIDER_ID } from 'altair-graphql-core/build/subscriptions';
import { SubscriptionProvider } from 'altair-graphql-core/build/subscriptions/subscription-provider';
import { RequestScriptError } from '../services/pre-request/errors';
import { headerListToMap } from '../utils/headers';
import { RequestType } from '../services/pre-request/helpers';
import { BATCHED_REQUESTS_OPERATION } from '../services/gql/gql.service';
import { RequestType } from 'altair-graphql-core/build/script/types';

function notNullOrUndefined<T>(x: T | null | undefined): x is T {
return x !== null && x !== undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
EnvironmentState,
EnvironmentsState,
ExportEnvironmentState,
IEnvironment,
} from 'altair-graphql-core/build/types/state/environments.interfaces';
import { RootState } from 'altair-graphql-core/build/types/state/state.interfaces';
import { HeaderState } from 'altair-graphql-core/build/types/state/header.interfaces';
Expand All @@ -22,11 +23,8 @@ import { NotifyService } from '../notify/notify.service';
// Unfortunately, Safari doesn't support lookbehind in regex: https://caniuse.com/js-regexp-lookbehind
// So have to go with an alternative approach using lookahead instead
// export const VARIABLE_REGEX = /(?<!\\){{\s*[\w\.]+\s*}}/g;
export const VARIABLE_REGEX =
/(^{{\s*[\w.]+\s*}})|((?!\\)(.){{\s*[\w.]+\s*}})/g;
export interface IEnvironment extends IDictionary<any> {
headers?: IDictionary<string>;
}
export const VARIABLE_REGEX = /(^{{\s*[\w.]+\s*}})|((?!\\)(.){{\s*[\w.]+\s*}})/g;

interface HydrateEnvironmentOptions {
activeEnvironment?: IEnvironment;
}
Expand Down Expand Up @@ -158,15 +156,13 @@ export class EnvironmentService {
const environmentHeadersMap = activeEnvironment.headers;

if (environmentHeadersMap) {
const environmentHeaders = Object.keys(environmentHeadersMap).map(
(key) => {
return {
key: this.hydrate(key, options),
value: this.hydrate(environmentHeadersMap[key] || '', options),
enabled: true,
};
}
);
const environmentHeaders = Object.keys(environmentHeadersMap).map((key) => {
return {
key: this.hydrate(key, options),
value: this.hydrate(environmentHeadersMap[key] || '', options),
enabled: true,
};
});

return [...environmentHeaders, ...hydratedHeaders];
}
Expand Down Expand Up @@ -201,9 +197,7 @@ export class EnvironmentService {
);
}

getExportEnvironmentData(
environment: EnvironmentState
): ExportEnvironmentState {
getExportEnvironmentData(environment: EnvironmentState): ExportEnvironmentState {
const exportCollectionData: ExportEnvironmentState = {
version: 1,
type: 'environment',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import { prettify } from './prettifier';
import { Position } from '../../utils/editor/helpers';
import { ElectronAppService } from '../electron-app/electron-app.service';
import { ELECTRON_ALLOWED_FORBIDDEN_HEADERS } from '@altairgraphql/electron-interop/build/constants';
import { SendRequestResponse } from 'altair-graphql-core/build/script/types';

interface SendRequestOptions {
url: string;
Expand All @@ -66,16 +67,6 @@ interface SendRequestOptions {

export const BATCHED_REQUESTS_OPERATION = 'BatchedRequests';

export interface SendRequestResponse {
response: HttpResponse<any>;
meta: {
requestStartTime: number;
requestEndTime: number;
responseTime: number;
headers: IDictionary;
};
}

interface ResolvedFileVariable {
name: string;
data: File;
Expand Down Expand Up @@ -150,9 +141,7 @@ export class GqlService {

headers.forEach((header) => {
if (
!ELECTRON_ALLOWED_FORBIDDEN_HEADERS.includes(
header.key.toLowerCase()
) &&
!ELECTRON_ALLOWED_FORBIDDEN_HEADERS.includes(header.key.toLowerCase()) &&
header.enabled &&
header.key &&
header.value
Expand Down Expand Up @@ -219,9 +208,7 @@ export class GqlService {
);
}

getIntrospectionSchema(
introspection?: IntrospectionQuery
): GraphQLSchema | null {
getIntrospectionSchema(introspection?: IntrospectionQuery): GraphQLSchema | null {
if (!introspection?.__schema) {
return null;
}
Expand Down Expand Up @@ -340,9 +327,7 @@ export class GqlService {
getOperationAtIndex(query: string, index: number) {
return this.getOperations(query).find((operation) => {
return Boolean(
operation.loc &&
operation.loc.start <= index &&
operation.loc.end >= index
operation.loc && operation.loc.start <= index && operation.loc.end >= index
);
});
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import {
ScriptEvaluatorClient,
ScriptEvaluatorClientFactory,
ScriptEvent,
ScriptEventData,
} from 'altair-graphql-core/build/script/types';
import { getClientConfig } from '@altairgraphql/api-utils';
import { debug } from '../../utils/logger';
import { environment } from 'environments/environment';
import { EvaluatorWorkerClient } from './evaluator-worker-client';

export class EvaluatorFrameClient extends ScriptEvaluatorClient {
private config = getClientConfig(
environment.production ? 'production' : 'development'
);
private iframe = this.createIframe();

createIframe() {
const iframe = document.createElement('iframe');
iframe.style.display = 'none';
const sandboxUrl = new URL(this.config.sandboxUrl);
sandboxUrl.searchParams.set('sc', window.location.origin);
sandboxUrl.searchParams.set('action', 'evaluator');
iframe.src = sandboxUrl.toString();

iframe.sandbox.add('allow-scripts');
iframe.sandbox.add('allow-same-origin');
iframe.referrerPolicy = 'no-referrer';
document.body.appendChild(iframe);
return iframe;
}
subscribe<T extends ScriptEvent>(
type: T,
handler: (type: T, e: ScriptEventData<T>) => void
): void {
window.addEventListener('message', (e: MessageEvent<ScriptEventData<T>>) => {
if (e.origin !== new URL(this.config.sandboxUrl).origin) {
return;
}
const event = e.data;

// Handle script events
if (event.type === type) {
debug.log(event.type, event);
handler(type, event);
}
});
}
send(type: string, payload: any): void {
this.iframe.addEventListener('load', () => {
this.iframe.contentWindow?.postMessage(
{ type, payload },
this.config.sandboxUrl
);
});
}
onError(handler: (err: any) => void): void {
this.iframe.addEventListener('error', handler);
}
destroy(): void {
this.iframe.remove();
}
}
export class EvaluatorClientFactory implements ScriptEvaluatorClientFactory {
create() {
if (document.baseURI && new URL(document.baseURI).origin === window.origin) {
return new EvaluatorWorkerClient();
}
return new EvaluatorFrameClient();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {
ScriptEvaluatorClient,
ScriptEvent,
ScriptEventData,
} from 'altair-graphql-core/build/script/types';
import { debug } from '../../utils/logger';

export class EvaluatorWorkerClient extends ScriptEvaluatorClient {
private worker = new Worker(new URL('./evaluator.worker', import.meta.url), {
type: 'module',
});
subscribe<T extends ScriptEvent>(
type: T,
handler: (k: T, e: ScriptEventData<T>) => void
) {
this.worker.addEventListener(
'message',
(e: MessageEvent<ScriptEventData<T>>) => {
const event = e.data;

// Handle script events
if (event.type === type) {
debug.log(event.type, event);
handler(type, event);
}
}
);
}
send(type: string, payload: any): void {
this.worker.postMessage({
type,
payload,
});
}
onError(handler: (err: any) => void): void {
this.worker.addEventListener('error', handler);
}
destroy(): void {
this.worker.terminate();
}
}

This file was deleted.

Loading
Loading