Skip to content
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
3 changes: 0 additions & 3 deletions .eslintrc.js

This file was deleted.

4 changes: 4 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { defineConfig } from 'eslint/config';
import frontifyConfig from '@frontify/eslint-config-basic';

export default defineConfig([frontifyConfig]);
5,327 changes: 3,652 additions & 1,675 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@
},
"homepage": "https://developer.frontify.com/",
"devDependencies": {
"@frontify/eslint-config-typescript": "^0.16.2",
"@frontify/eslint-config-basic": "^1.0.11",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^16.0.1",
"@types/node": "^16.7.13",
"esbuild": "^0.25.5",
"eslint": "^8.27.0",
"eslint": "^9.39.2",
"prettier": "^3.5.3",
"rollup": "^4.42.0",
"rollup-plugin-dts": "^6.2.1",
Expand Down
7 changes: 4 additions & 3 deletions src/Api.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { version } from '../package.json';

import { FinderError } from './Exception';
import { logMessage } from './Logger';
import { httpCall } from './Utils';
Expand Down Expand Up @@ -221,9 +222,9 @@ fragment onVideo on Video {

export async function requestAssetsById(
{ domain, bearerToken, permanentDownloadUrls }: Options,
ids: Asset[],
ids: (string | number)[],
): Promise<FrontifyAsset[]> {
const response = (await httpCall(`https://${domain}/graphql`, {
const response = await httpCall<AssetsResponse>(`https://${domain}/graphql`, {
method: 'POST',
headers: {
'content-type': 'application/json',
Expand All @@ -239,7 +240,7 @@ export async function requestAssetsById(
permanent: permanentDownloadUrls,
},
}),
})) as AssetsResponse;
});

if (response.errors) {
logMessage('error', {
Expand Down
53 changes: 32 additions & 21 deletions src/Finder.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Asset, FrontifyAsset, requestAssetsById } from './Api';
import { Token } from './Storage';
import { type Asset, type FrontifyAsset, requestAssetsById } from './Api';
import { FinderError } from './Exception';
import { logMessage } from './Logger';
import { type Token } from './Storage';

export type { FrontifyAsset };

Expand All @@ -20,11 +20,23 @@ type FinderFilter = {
inverted: boolean;
};

type FinderCallbacks = {
cancel?: () => void;
assetsChosen?: (assets: FrontifyAsset[]) => void;
};

type FinderMessage = {
configurationRequested?: boolean;
assetsChosen?: Asset[];
aborted?: boolean;
logout?: boolean;
};

export class FrontifyFinder {
private parentNode: HTMLElement | undefined;
private readonly iFrame: HTMLIFrameElement;
private listeners: { [key: string]: CallableFunction } = {};
private unsubscribe: CallableFunction | undefined;
private callbacks: FinderCallbacks = {};
private unsubscribe: (() => void) | undefined;

private static get VERSION(): number {
return 2.0;
Expand All @@ -46,26 +58,25 @@ export class FrontifyFinder {
return;
}

if (event.data.configurationRequested) {
const data = event.data as FinderMessage;

if (data.configurationRequested) {
this.initialize();
return;
}

if (event.data.assetsChosen) {
try {
this.handleAssetsChosen(event.data.assetsChosen.map((asset: Asset) => asset.id));
} catch (error) {
throw error;
}
if (data.assetsChosen) {
// eslint-disable-next-line no-void
void this.handleAssetsChosen(data.assetsChosen.map((asset: Asset) => asset.id));
return;
}

if (event.data.aborted) {
if (data.aborted) {
this.handleFinderCancel();
return;
}

if (event.data.logout) {
if (data.logout) {
this.onLogoutRequested();
this.handleFinderCancel();
return;
Expand Down Expand Up @@ -111,12 +122,12 @@ export class FrontifyFinder {
this.close();
}

if (this.listeners['cancel']) {
this.listeners['cancel']();
if (this.callbacks.cancel) {
this.callbacks.cancel();
}
}

private async handleAssetsChosen(assetIds: Asset[]): Promise<void> {
private async handleAssetsChosen(assetIds: (string | number)[]): Promise<void> {
try {
const assets: FrontifyAsset[] = await requestAssetsById(
{
Expand All @@ -131,8 +142,8 @@ export class FrontifyFinder {
this.close();
}

if (this.listeners['assetsChosen']) {
this.listeners['assetsChosen'](assets);
if (this.callbacks.assetsChosen) {
this.callbacks.assetsChosen(assets);
}
} catch (error) {
if (!(error instanceof FinderError)) {
Expand All @@ -145,12 +156,12 @@ export class FrontifyFinder {
}

public onAssetsChosen(callback: (assets: FrontifyAsset[]) => void): FrontifyFinder {
this.listeners['assetsChosen'] = callback;
this.callbacks.assetsChosen = callback;
return this;
}

public onCancel(callback: () => void): FrontifyFinder {
this.listeners['cancel'] = callback;
this.callbacks.cancel = callback;
return this;
}

Expand All @@ -173,7 +184,7 @@ export class FrontifyFinder {
if (this.parentNode) {
this.parentNode.removeChild(this.iFrame);
}
} catch (error) {
} catch {
logMessage('error', {
code: 'ERR_FINDER_CLOSE',
message: 'Error closing Frontify Finder.',
Expand Down
2 changes: 1 addition & 1 deletion src/Logger.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export type LogInfo = {
code: string;
message: string;
error?: any;
error?: unknown;
};

const disabledLogs: {
Expand Down
4 changes: 2 additions & 2 deletions src/Storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ function isStorageAvailable(storageName: 'localStorage' | 'sessionStorage'): boo
return false;
}

const storage = window[storageName] as Storage;
const storage = window[storageName];

storage.setItem(FINDER_STORAGE_ITEM_TEST.key, FINDER_STORAGE_ITEM_TEST.value);
if (storage.getItem(FINDER_STORAGE_ITEM_TEST.key) === FINDER_STORAGE_ITEM_TEST.value) {
Expand All @@ -112,7 +112,7 @@ function isStorageAvailable(storageName: 'localStorage' | 'sessionStorage'): boo
}

return false;
} catch (error) {
} catch {
return false;
}
}
1 change: 1 addition & 0 deletions src/Store.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export class Store implements Storage {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Required by Storage interface
[name: string]: any;

readonly length: number = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/Utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export async function httpCall<JsonResponse>(url: string, init?: RequestInit): P
throw new FinderError('ERR_FINDER_HTTP_REQUEST', response.statusText);
}

return await response.json();
return (await response.json()) as JsonResponse;
} catch (error) {
if (error instanceof FinderError) {
throw error;
Expand Down
22 changes: 13 additions & 9 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { PopupConfiguration, authorize, revoke } from '@frontify/frontify-authenticator';
import { Token, getItem, popItem, setItem } from './Storage';
import { FinderOptions, FrontifyAsset, FrontifyFinder } from './Finder';
import { type PopupConfiguration, authorize, revoke } from '@frontify/frontify-authenticator';

import { FinderError } from './Exception';
import { type FinderOptions, type FrontifyAsset, FrontifyFinder } from './Finder';
import { logMessage } from './Logger';
import { type Token, getItem, popItem, setItem } from './Storage';
import { computeStorageKey } from './Utils';
import { FinderError } from './Exception';

const FINDER_CLIENT_SCOPES = ['basic:read', 'finder:read'];
const EXPIRES_IN_LEEWAY = 300;
Expand Down Expand Up @@ -48,11 +49,14 @@ export async function create(
throw new FinderError('ERR_FINDER_ACCESS_STORED_TOKEN', 'Error accessing stored token.');
}

return new FrontifyFinder(token, options ?? DEFAULT_OPTIONS, async () => {
await logout({ clientId });
logMessage('warning', {
code: 'WARN_USER_LOGOUT',
message: 'User successfully logged out',
return new FrontifyFinder(token, options ?? DEFAULT_OPTIONS, () => {
// eslint-disable-next-line no-void
void logout({ clientId }).then(() => {
logMessage('warning', {
code: 'WARN_USER_LOGOUT',
message: 'User successfully logged out',
});
return;
});
});
}
Expand Down
Loading