Skip to content

Commit

Permalink
fix: handling of url/base64 query parameters (#531)
Browse files Browse the repository at this point in the history
  • Loading branch information
magicmatatjahu authored Dec 16, 2022
1 parent a70b60e commit 8f426c2
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 34 deletions.
2 changes: 1 addition & 1 deletion src/components/Editor/MonacoWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const MonacoWrapper: FunctionComponent<MonacoEditorProps> = ({

const onChange = useMemo(() => {
return debounce((v: string) => {
editorSvc.updateState({ content: v });
editorSvc.updateState({ content: v, file: { from: 'storage', source: undefined } });
autoSaving && editorSvc.saveToLocalStorage(v, false);
parserSvc.parse('asyncapi', v);
}, savingDelay);
Expand Down
39 changes: 36 additions & 3 deletions src/services/app.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,27 @@ import { show } from '@ebay/nice-modal-react';

import { RedirectedModal } from '../components/Modals';

import { appState } from '../state';
import { appState, filesState } from '../state';

export class ApplicationService extends AbstractService {
public override onInit(): void {
override async onInit() {
// subscribe to state to hide preloader
this.hidePreloader();

const { readOnly, url, base64, redirectedFrom } = this.svcs.navigationSvc.getUrlParameters();

// readOnly state should be only set to true when someone pass also url or base64 parameter
const isStrictReadonly = Boolean(readOnly && (url || base64));
if (isStrictReadonly) {

let error: any;
try {
await this.fetchResource(url, base64);
} catch (err) {
error = err;
console.error(err);
}

if (isStrictReadonly && !error) {
appState.setState({
readOnly,
initialized: true,
Expand All @@ -28,6 +37,30 @@ export class ApplicationService extends AbstractService {
}
}

private async fetchResource(url: string | null, base64: string | null) {
if (!url && !base64) {
return;
}

const { updateFile } = filesState.getState();
let content = '';
if (url) {
content = await fetch(url).then(res => res.text());
} else if (base64) {
content = this.svcs.formatSvc.decodeBase64(base64);
}

const language = this.svcs.formatSvc.retrieveLangauge(content);
const source = url || undefined;
updateFile('asyncapi', {
content,
language,
source,
from: url ? 'url' : 'base64',
});
await this.svcs.parserSvc.parse('asyncapi', content, { source });
}

private hidePreloader() {
const unsunscribe = appState.subscribe((state, prevState) => {
if (!prevState.initialized && state.initialized) {
Expand Down
15 changes: 13 additions & 2 deletions src/services/editor.service.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface UpdateState {
}

export class EditorService extends AbstractService {
private created = false;
private decorations: Map<string, string[]> = new Map();
private instance: monacoAPI.editor.IStandaloneCodeEditor | undefined;

Expand All @@ -29,9 +30,19 @@ export class EditorService extends AbstractService {
}

async onDidCreate(editor: monacoAPI.editor.IStandaloneCodeEditor) {
if (this.created) {
return;
}
this.created = true;
this.instance = editor;
// parse on first run the spec
await this.svcs.parserSvc.parse('asyncapi', editor.getValue());

// parse on first run - only when document is undefined
const document = documentsState.getState().documents.asyncapi;
if (!document) {
await this.svcs.parserSvc.parse('asyncapi', editor.getValue());
} else {
this.applyMarkersAndDecorations(document.diagnostics.filtered);
}

// apply save command
editor.addCommand(
Expand Down
2 changes: 1 addition & 1 deletion src/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ export const ServicesProvider = servicesCtx.Provider;
export async function createServices() {
const services: Services = {} as Services;

services.parserSvc = new ParserService(services);
services.appSvc = new ApplicationService(services);
services.converterSvc = new ConverterService(services);
services.editorSvc = new EditorService(services);
services.formatSvc = new FormatService(services);
services.monacoSvc = new MonacoService(services);
services.navigationSvc = new NavigationService(services);
services.parserSvc = new ParserService(services);
services.serverAPISvc = new ServerAPIService(services);
services.settingsSvc = new SettingsService(services);
services.socketClientSvc = new SocketClient(services);
Expand Down
7 changes: 7 additions & 0 deletions src/services/parser.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ export class ParserService extends AbstractService {
private updateDocument = documentsState.getState().updateDocument;

private createDiagnostics(diagnostics: Diagnostic[]) {
// map messages of invalid ref to file
diagnostics.forEach(diagnostic => {
if (diagnostic.code === 'invalid-ref' && diagnostic.message.endsWith('readFile is not a function')) {
diagnostic.message = 'File references are not yet supported in Studio';
}
});

const collections: DocumentDiagnostics = {
original: diagnostics,
filtered: [],
Expand Down
45 changes: 18 additions & 27 deletions src/state/files.state.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import create from 'zustand';
import { persist } from 'zustand/middleware';

const schema =
localStorage.getItem('document') || `asyncapi: '2.5.0'
Expand Down Expand Up @@ -176,32 +175,24 @@ export type FilesActions = {
updateFile: (uri: string, file: Partial<File>) => void;
}

export const filesState = create(
persist<FilesState & FilesActions>(set =>
({
files: {
asyncapi: {
uri: 'asyncapi',
name: 'asyncapi',
content: schema,
from: 'storage',
source: undefined,
language: schema.trimStart()[0] === '{' ? 'json' : 'yaml',
modified: false,
stat: {
mtime: (new Date()).getTime(),
}
}
},
updateFile(uri: string, file: Partial<File>) {
set(state => ({ files: { ...state.files, [String(uri)]: { ...state.files[String(uri)] || {}, ...file } } }));
},
}),
{
name: 'studio-files',
getStorage: () => localStorage,
export const filesState = create<FilesState & FilesActions>(set => ({
files: {
asyncapi: {
uri: 'asyncapi',
name: 'asyncapi',
content: schema,
from: 'storage',
source: undefined,
language: schema.trimStart()[0] === '{' ? 'json' : 'yaml',
modified: false,
stat: {
mtime: (new Date()).getTime(),
}
}
},
updateFile(uri: string, file: Partial<File>) {
set(state => ({ files: { ...state.files, [String(uri)]: { ...state.files[String(uri)] || {}, ...file } } }));
}
),
);
}));

export const useFilesState = filesState;

0 comments on commit 8f426c2

Please sign in to comment.