
* feat: 🚧 add skeleton logs page * feat: ✨ add ClientLogsMetadataRepository * feat: ✨ add AvataxClientLogger and router * feat: ✨ implement avatax client logs in order confirmed * feat: 🚧 add skeleton ui for logs * feat: ✨ add avatax client logger * refactor: ♻️ move breadcrumbs to page lvl * feat: ✨ logger per config * feat: ✨ add logs to remaining events * refactor: ♻️ pass clientLogger from webhook service * feat: ✨ add taxjar logger * test: ✅ add tests for logs push * feat: ✅ add getAll test * feat: ✨ add missing taxjar page * refactor: ♻️ move unshiftItemToLimitedArray to log-utils and test * fix: 🐛 label * refactor: 💄 styles * build: 👷 changeset * fix: 🐛 typo * refactor: ♻️ address feedback on backend side * refactor: ♻️ adjust UI to merging of avatax & taxjar logs * feat: ✨ make client logs table box scrollable * fix: 🐛 size of container * fix: 🐛 loading on isRefetching, not isFetching * fix: 🐛 no lines early error
98 lines
2.8 KiB
TypeScript
98 lines
2.8 KiB
TypeScript
import { EncryptedMetadataManager, SettingsManager } from "@saleor/app-sdk/settings-manager";
|
|
import { ZodSchema, z } from "zod";
|
|
import { Logger, createLogger } from "../../lib/logger";
|
|
import { logUtils } from "./log-utils";
|
|
|
|
export interface MetadataLogs<TLog extends unknown> {
|
|
getAll(): Promise<TLog[]>;
|
|
push(payload: unknown): Promise<void>;
|
|
}
|
|
|
|
type ClientLogsMetadataRepositoryOptions = {
|
|
limit: number;
|
|
};
|
|
|
|
export type ClientLogsMetadataRepositoryParams<TLog extends unknown> = {
|
|
settingsManager: EncryptedMetadataManager;
|
|
schema: ZodSchema<TLog>;
|
|
metadataKey: string;
|
|
options: ClientLogsMetadataRepositoryOptions;
|
|
};
|
|
|
|
/**
|
|
* ClientLogsMetadataRepository is a generic class that can be used to store logs in the app metadata.
|
|
* The name "clientLogs" is used to distinguish it from the server logs. Client logs can appear in the app UI.
|
|
*/
|
|
export class ClientLogsMetadataRepository<TLog extends unknown> implements MetadataLogs<TLog> {
|
|
private readonly settingsManager: EncryptedMetadataManager;
|
|
private readonly schema: ZodSchema<TLog>;
|
|
private readonly metadataKey: string;
|
|
private readonly options: ClientLogsMetadataRepositoryOptions;
|
|
private readonly logger: Logger;
|
|
private logs: TLog[] = [];
|
|
|
|
constructor({
|
|
settingsManager,
|
|
schema,
|
|
metadataKey,
|
|
options,
|
|
}: ClientLogsMetadataRepositoryParams<TLog>) {
|
|
this.settingsManager = settingsManager;
|
|
this.schema = schema;
|
|
this.metadataKey = metadataKey;
|
|
this.options = options;
|
|
this.logger = createLogger({
|
|
name: "ClientLogsMetadataRepository",
|
|
});
|
|
}
|
|
|
|
async getAll() {
|
|
if (this.logs.length) {
|
|
this.logger.debug(`Returning cached logs for key ${this.metadataKey}`);
|
|
return this.logs;
|
|
}
|
|
|
|
const metadata = await this.settingsManager.get(this.metadataKey);
|
|
|
|
if (!metadata) {
|
|
this.logger.debug(`No metadata found for key ${this.metadataKey}`);
|
|
return [];
|
|
}
|
|
|
|
const parsedMetadata = JSON.parse(metadata);
|
|
const validation = z.array(this.schema).safeParse(parsedMetadata);
|
|
|
|
if (!validation.success) {
|
|
throw new Error(validation.error.message);
|
|
}
|
|
|
|
const logs = validation.data;
|
|
|
|
this.logs = logs;
|
|
|
|
this.logger.debug(`Returning logs for key ${this.metadataKey}`);
|
|
|
|
return logs;
|
|
}
|
|
|
|
async push(payload: unknown) {
|
|
const validation = this.schema.safeParse(payload);
|
|
|
|
if (!validation.success) {
|
|
throw new Error(validation.error.message);
|
|
}
|
|
|
|
const log = validation.data;
|
|
const logs = await this.getAll();
|
|
const nextLogs = logUtils.unshiftItemToLimitedArray(logs, log, this.options.limit);
|
|
|
|
this.logs = nextLogs;
|
|
|
|
this.logger.debug(`Pushing log to metadata for key ${this.metadataKey}`);
|
|
|
|
await this.settingsManager.set({
|
|
key: this.metadataKey,
|
|
value: JSON.stringify(nextLogs),
|
|
});
|
|
}
|
|
}
|