mirror of
https://github.com/formbricks/formbricks.git
synced 2026-02-22 10:08:42 -06:00
refactor: @formbricks/api package (#782)
* init: rewritten formbricks api package * restrucure: client prepended formbricks api package * feat: cleanup error templating and node-fetch for non browser access * feat: replace package (build error for js packge due to api) * fix: rename methods & move error type * fix: imports of api via js * remove node-fetch --------- Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
This commit is contained in:
committed by
GitHub
parent
e3069f7bab
commit
769ceb1fc2
@@ -3,7 +3,6 @@
|
||||
import { updateProfileAction } from "@/app/(app)/onboarding/actions";
|
||||
import { env } from "@/env.mjs";
|
||||
import { formbricksEnabled, updateResponse } from "@/lib/formbricks";
|
||||
import { ResponseId } from "@formbricks/js";
|
||||
import { cn } from "@formbricks/lib/cn";
|
||||
import { Objective } from "@formbricks/types/templates";
|
||||
import { TProfile } from "@formbricks/types/v1/profile";
|
||||
@@ -14,7 +13,7 @@ import { toast } from "react-hot-toast";
|
||||
type ObjectiveProps = {
|
||||
next: () => void;
|
||||
skip: () => void;
|
||||
formbricksResponseId?: ResponseId;
|
||||
formbricksResponseId?: string;
|
||||
profile: TProfile;
|
||||
};
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import Greeting from "./Greeting";
|
||||
import Objective from "./Objective";
|
||||
import Product from "./Product";
|
||||
import Role from "./Role";
|
||||
import { ResponseId } from "@formbricks/js";
|
||||
import { TProfile } from "@formbricks/types/v1/profile";
|
||||
import { TProduct } from "@formbricks/types/v1/product";
|
||||
import { updateProfileAction } from "@/app/(app)/onboarding/actions";
|
||||
@@ -25,7 +24,7 @@ interface OnboardingProps {
|
||||
}
|
||||
|
||||
export default function Onboarding({ session, environmentId, profile, product }: OnboardingProps) {
|
||||
const [formbricksResponseId, setFormbricksResponseId] = useState<ResponseId | undefined>();
|
||||
const [formbricksResponseId, setFormbricksResponseId] = useState<string | undefined>();
|
||||
const [currentStep, setCurrentStep] = useState(1);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const router = useRouter();
|
||||
|
||||
@@ -4,7 +4,6 @@ import { cn } from "@formbricks/lib/cn";
|
||||
import { updateProfileAction } from "@/app/(app)/onboarding/actions";
|
||||
import { env } from "@/env.mjs";
|
||||
import { createResponse, formbricksEnabled } from "@/lib/formbricks";
|
||||
import { ResponseId, SurveyId } from "@formbricks/js";
|
||||
import { TProfile } from "@formbricks/types/v1/profile";
|
||||
import { Button } from "@formbricks/ui";
|
||||
import { useState } from "react";
|
||||
@@ -13,7 +12,7 @@ import { toast } from "react-hot-toast";
|
||||
type RoleProps = {
|
||||
next: () => void;
|
||||
skip: () => void;
|
||||
setFormbricksResponseId: (id: ResponseId) => void;
|
||||
setFormbricksResponseId: (id: string) => void;
|
||||
profile: TProfile;
|
||||
};
|
||||
|
||||
@@ -49,7 +48,7 @@ const Role: React.FC<RoleProps> = ({ next, skip, setFormbricksResponseId, profil
|
||||
console.error(e);
|
||||
}
|
||||
if (formbricksEnabled && env.NEXT_PUBLIC_FORMBRICKS_ONBOARDING_SURVEY_ID) {
|
||||
const res = await createResponse(env.NEXT_PUBLIC_FORMBRICKS_ONBOARDING_SURVEY_ID as SurveyId, {
|
||||
const res = await createResponse(env.NEXT_PUBLIC_FORMBRICKS_ONBOARDING_SURVEY_ID, {
|
||||
role: selectedRole.label,
|
||||
});
|
||||
if (res.ok) {
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import formbricks, { PersonId, SurveyId, ResponseId } from "@formbricks/js";
|
||||
import formbricks from "@formbricks/js";
|
||||
import { env } from "@/env.mjs";
|
||||
|
||||
export const formbricksEnabled =
|
||||
typeof env.NEXT_PUBLIC_FORMBRICKS_API_HOST && env.NEXT_PUBLIC_FORMBRICKS_ENVIRONMENT_ID;
|
||||
|
||||
export const createResponse = async (
|
||||
surveyId: SurveyId,
|
||||
surveyId: string,
|
||||
data: { [questionId: string]: any },
|
||||
finished: boolean = false
|
||||
): Promise<any> => {
|
||||
const api = formbricks.getApi();
|
||||
const personId = formbricks.getPerson()?.id as PersonId;
|
||||
return await api.createResponse({
|
||||
const personId = formbricks.getPerson()?.id;
|
||||
return await api.client.response.create({
|
||||
surveyId,
|
||||
personId,
|
||||
finished,
|
||||
@@ -20,12 +20,12 @@ export const createResponse = async (
|
||||
};
|
||||
|
||||
export const updateResponse = async (
|
||||
responseId: ResponseId,
|
||||
responseId: string,
|
||||
data: { [questionId: string]: any },
|
||||
finished: boolean = false
|
||||
): Promise<any> => {
|
||||
const api = formbricks.getApi();
|
||||
return await api.updateResponse({
|
||||
return await api.client.response.update({
|
||||
responseId,
|
||||
finished,
|
||||
data,
|
||||
|
||||
@@ -17,13 +17,12 @@
|
||||
"lint": "eslint ./src --fix",
|
||||
"clean": "rimraf .turbo node_modules dist"
|
||||
},
|
||||
"dependencies": {
|
||||
"@formbricks/lib": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@formbricks/types": "workspace:*",
|
||||
"@formbricks/lib": "workspace:*",
|
||||
"@formbricks/tsconfig": "workspace:*",
|
||||
"eslint-config-formbricks": "workspace:*",
|
||||
"tsup": "^7.2.0"
|
||||
"tsup": "^7.2.0",
|
||||
"typescript": "5.1.6",
|
||||
"eslint-config-formbricks": "workspace:*"
|
||||
}
|
||||
}
|
||||
|
||||
23
packages/api/src/api/client/display.ts
Normal file
23
packages/api/src/api/client/display.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { Result } from "@formbricks/types/v1/errorHandlers";
|
||||
import { NetworkError } from "@formbricks/types/v1/errors";
|
||||
import { makeRequest } from "../../utils/makeRequest";
|
||||
import { TDisplay, TDisplayInput } from "@formbricks/types/v1/displays";
|
||||
|
||||
export class DisplayAPI {
|
||||
private apiHost: string;
|
||||
|
||||
constructor(baseUrl: string) {
|
||||
this.apiHost = baseUrl;
|
||||
}
|
||||
|
||||
async markDisplayedForPerson({
|
||||
surveyId,
|
||||
personId,
|
||||
}: TDisplayInput): Promise<Result<TDisplay, NetworkError | Error>> {
|
||||
return makeRequest(this.apiHost, "/api/v1/client/displays", "POST", { surveyId, personId });
|
||||
}
|
||||
|
||||
async markResponded({ displayId }: { displayId: string }): Promise<Result<TDisplay, NetworkError | Error>> {
|
||||
return makeRequest(this.apiHost, `/api/v1/client/displays/${displayId}/responded`, "POST");
|
||||
}
|
||||
}
|
||||
15
packages/api/src/api/client/index.ts
Normal file
15
packages/api/src/api/client/index.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { ResponseAPI } from "./response";
|
||||
import { DisplayAPI } from "./display";
|
||||
import { ApiConfig } from "../../types";
|
||||
|
||||
export class Client {
|
||||
response: ResponseAPI;
|
||||
display: DisplayAPI;
|
||||
|
||||
constructor(options: ApiConfig) {
|
||||
const { apiHost } = options;
|
||||
|
||||
this.response = new ResponseAPI(apiHost);
|
||||
this.display = new DisplayAPI(apiHost);
|
||||
}
|
||||
}
|
||||
39
packages/api/src/api/client/response.ts
Normal file
39
packages/api/src/api/client/response.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { makeRequest } from "../../utils/makeRequest";
|
||||
import { NetworkError } from "@formbricks/types/v1/errors";
|
||||
import { Result } from "@formbricks/types/v1/errorHandlers";
|
||||
import { TResponse, TResponseInput, TResponseUpdateInput } from "@formbricks/types/v1/responses";
|
||||
|
||||
type TResponseUpdateInputWithResponseId = TResponseUpdateInput & { responseId: string };
|
||||
|
||||
export class ResponseAPI {
|
||||
private apiHost: string;
|
||||
|
||||
constructor(apiHost: string) {
|
||||
this.apiHost = apiHost;
|
||||
}
|
||||
|
||||
async create({
|
||||
surveyId,
|
||||
personId,
|
||||
finished,
|
||||
data,
|
||||
}: TResponseInput): Promise<Result<TResponse, NetworkError | Error>> {
|
||||
return makeRequest(this.apiHost, "/api/v1/client/responses", "POST", {
|
||||
surveyId,
|
||||
personId,
|
||||
finished,
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
async update({
|
||||
responseId,
|
||||
finished,
|
||||
data,
|
||||
}: TResponseUpdateInputWithResponseId): Promise<Result<TResponse, NetworkError | Error>> {
|
||||
return makeRequest(this.apiHost, `/api/v1/client/responses/${responseId}`, "PUT", {
|
||||
finished,
|
||||
data,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export * from "./responses";
|
||||
@@ -1,24 +0,0 @@
|
||||
import { KeyValueData, PersonId, ResponseId, SurveyId } from "../types";
|
||||
|
||||
export interface CreateResponseResponse {
|
||||
id: ResponseId;
|
||||
}
|
||||
|
||||
export interface UpdateResponseResponse {
|
||||
id: ResponseId;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
finished: boolean;
|
||||
surveyId: SurveyId;
|
||||
personId: PersonId;
|
||||
data: KeyValueData;
|
||||
meta: {}; //TODO: figure out what this is
|
||||
userAttributes: string[]; //TODO: figure out what this is
|
||||
tags: string[]; //TODO: figure out what this is
|
||||
}
|
||||
|
||||
export interface UpdateResponseResponseFormatted
|
||||
extends Omit<UpdateResponseResponse, "createdAt" | "updatedAt"> {
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
import { Result, ok } from "@formbricks/types/v1/errorHandlers";
|
||||
import { ResponseCreateRequest, ResponseUpdateRequest } from "@formbricks/types/js";
|
||||
import {
|
||||
CreateResponseResponse,
|
||||
UpdateResponseResponse,
|
||||
UpdateResponseResponseFormatted,
|
||||
} from "../dtos/responses";
|
||||
import { NetworkError } from "../errors";
|
||||
import { EnvironmentId, KeyValueData, PersonId, RequestFn, ResponseId, SurveyId } from "../types";
|
||||
|
||||
export interface CreateResponseOptions {
|
||||
environmentId: EnvironmentId;
|
||||
surveyId: SurveyId;
|
||||
personId?: PersonId;
|
||||
data: KeyValueData;
|
||||
finished?: boolean;
|
||||
}
|
||||
|
||||
export const createResponse = async (
|
||||
request: RequestFn,
|
||||
options: CreateResponseOptions
|
||||
): Promise<Result<CreateResponseResponse, NetworkError>> => {
|
||||
const result = await request<CreateResponseResponse, any, ResponseCreateRequest>(
|
||||
`/api/v1/client/environments/${options.environmentId}/responses`,
|
||||
{
|
||||
surveyId: options.surveyId,
|
||||
personId: options.personId,
|
||||
response: {
|
||||
data: options.data,
|
||||
finished: options.finished || false,
|
||||
},
|
||||
},
|
||||
{ method: "POST" }
|
||||
);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
export interface UpdateResponseOptions {
|
||||
environmentId: EnvironmentId;
|
||||
data: KeyValueData;
|
||||
responseId: ResponseId;
|
||||
finished?: boolean;
|
||||
}
|
||||
|
||||
export const updateResponse = async (request: RequestFn, options: UpdateResponseOptions) => {
|
||||
const result = await request<UpdateResponseResponse, any, ResponseUpdateRequest>(
|
||||
`/api/v1/client/environments/${options.environmentId}/responses/${options.responseId}`,
|
||||
{
|
||||
response: {
|
||||
data: options.data,
|
||||
finished: options.finished || false,
|
||||
},
|
||||
},
|
||||
{
|
||||
method: "PUT",
|
||||
}
|
||||
);
|
||||
|
||||
if (result.ok === false) return result;
|
||||
|
||||
// convert timestamps to Dates
|
||||
const newResponse: UpdateResponseResponseFormatted = {
|
||||
...result.data,
|
||||
createdAt: new Date(result.data.createdAt),
|
||||
updatedAt: new Date(result.data.updatedAt),
|
||||
};
|
||||
|
||||
return ok(newResponse);
|
||||
};
|
||||
@@ -1,6 +0,0 @@
|
||||
export type NetworkError = {
|
||||
code: "network_error";
|
||||
message: string;
|
||||
status: number;
|
||||
url: URL;
|
||||
};
|
||||
@@ -1,6 +1,10 @@
|
||||
export * from "./dtos/";
|
||||
export * from "./errors";
|
||||
export * from "./lib";
|
||||
export { FormbricksAPI as default } from "./lib";
|
||||
// do not export RequestFn or Brand, they are internal
|
||||
export type { EnvironmentId, KeyValueData, PersonId, ResponseId, SurveyId } from "./types";
|
||||
import { ApiConfig } from "./types/index";
|
||||
import { Client } from "./api/client";
|
||||
|
||||
export class FormbricksAPI {
|
||||
client: Client;
|
||||
|
||||
constructor(options: ApiConfig) {
|
||||
this.client = new Client(options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
import { Result, err, ok, wrapThrows } from "@formbricks/types/v1/errorHandlers";
|
||||
import { CreateResponseResponse, UpdateResponseResponseFormatted } from "./dtos/responses";
|
||||
import { NetworkError } from "./errors";
|
||||
|
||||
import {
|
||||
CreateResponseOptions,
|
||||
UpdateResponseOptions,
|
||||
createResponse,
|
||||
updateResponse,
|
||||
} from "./endpoints/response";
|
||||
import { EnvironmentId, RequestFn } from "./types";
|
||||
|
||||
export interface FormbricksAPIOptions {
|
||||
apiHost?: string;
|
||||
environmentId: EnvironmentId;
|
||||
}
|
||||
|
||||
export class FormbricksAPI {
|
||||
private readonly baseUrl: string;
|
||||
private readonly environmentId: EnvironmentId;
|
||||
|
||||
constructor(options: FormbricksAPIOptions) {
|
||||
this.baseUrl = options.apiHost || "https://app.formbricks.com";
|
||||
this.environmentId = options.environmentId;
|
||||
this.request = this.request.bind(this);
|
||||
}
|
||||
|
||||
async createResponse(
|
||||
options: Omit<CreateResponseOptions, "environmentId">
|
||||
): Promise<Result<CreateResponseResponse, NetworkError>> {
|
||||
return this.runWithEnvironmentId(createResponse, options);
|
||||
}
|
||||
|
||||
async updateResponse(
|
||||
options: Omit<UpdateResponseOptions, "environmentId">
|
||||
): Promise<Result<UpdateResponseResponseFormatted, NetworkError>> {
|
||||
return this.runWithEnvironmentId(updateResponse, options);
|
||||
}
|
||||
|
||||
/*
|
||||
This was added to reduce code duplication
|
||||
|
||||
It checks that the function passed has the environmentId in the Options type
|
||||
and automatically adds it to the options
|
||||
*/
|
||||
private runWithEnvironmentId<T, E, Options extends { environmentId: EnvironmentId }>(
|
||||
fn: (request: RequestFn, options: Options) => Promise<Result<T, E>>,
|
||||
options: Omit<Options, "environmentId">
|
||||
): Promise<Result<T, E>> {
|
||||
const newOptions = { environmentId: this.environmentId, ...options } as Options;
|
||||
|
||||
return fn(this.request, newOptions);
|
||||
}
|
||||
|
||||
private async request<T = any, E = any, Data = any>(
|
||||
path: string,
|
||||
data: Data,
|
||||
options?: RequestInit
|
||||
): Promise<Result<T, E | NetworkError | Error>> {
|
||||
const url = new URL(path, this.baseUrl);
|
||||
const headers: HeadersInit = {
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
|
||||
const body = JSON.stringify(data);
|
||||
|
||||
const res = wrapThrows(fetch)(url, { headers, body, ...options });
|
||||
|
||||
if (res.ok === false) return err(res.error);
|
||||
|
||||
const response = await res.data;
|
||||
const resJson = await response.json();
|
||||
|
||||
if (!response.ok) {
|
||||
return err({
|
||||
code: "network_error",
|
||||
message: response.statusText,
|
||||
status: response.status,
|
||||
url,
|
||||
});
|
||||
}
|
||||
|
||||
return ok(resJson as T);
|
||||
}
|
||||
}
|
||||
27
packages/api/src/types.d.ts
vendored
27
packages/api/src/types.d.ts
vendored
@@ -1,27 +0,0 @@
|
||||
import { Result } from "@formbricks/types/v1/errorHandlers";
|
||||
import { NetworkError } from "./errors";
|
||||
|
||||
// by using Brand, we can check that you can't pass to an environmentId a surveyId
|
||||
type Brand<T, B> = T & { __brand: B };
|
||||
|
||||
export type EnvironmentId = Brand<string, "EnvironmentId">;
|
||||
export type SurveyId = Brand<string, "SurveyId">;
|
||||
export type PersonId = Brand<string, "PersonId">;
|
||||
export type ResponseId = Brand<string, "ResponseId">;
|
||||
|
||||
export type KeyValueData = { [key: string]: string | number | string[] | number[] | undefined };
|
||||
|
||||
export type RequestFn = <T = any, E = any, Data = any>(
|
||||
path: string,
|
||||
data: Data,
|
||||
options?: RequestInit
|
||||
) => Promise<Result<T, E | NetworkError | Error>>;
|
||||
|
||||
// https://github.com/formbricks/formbricks/blob/fbfc80dd4ed5d768f0c549e179fd1aa10edc400a/apps/web/lib/api/response.ts
|
||||
export interface ApiErrorResponse {
|
||||
code: string;
|
||||
message: string;
|
||||
details: {
|
||||
[key: string]: string | string[] | number | number[] | boolean | boolean[];
|
||||
};
|
||||
}
|
||||
8
packages/api/src/types/index.ts
Normal file
8
packages/api/src/types/index.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export interface ApiConfig {
|
||||
environmentId: string;
|
||||
apiHost: string;
|
||||
}
|
||||
|
||||
export type ApiResponse<T> = {
|
||||
data: T;
|
||||
};
|
||||
36
packages/api/src/utils/makeRequest.ts
Normal file
36
packages/api/src/utils/makeRequest.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { Result, err, ok, wrapThrows } from "@formbricks/types/v1/errorHandlers";
|
||||
import { NetworkError } from "@formbricks/types/v1/errors";
|
||||
import { ApiResponse } from "../types";
|
||||
|
||||
export async function makeRequest<T>(
|
||||
apiHost: string,
|
||||
endpoint: string,
|
||||
method: "GET" | "POST" | "PUT" | "DELETE",
|
||||
data?: any
|
||||
): Promise<Result<T, NetworkError | Error>> {
|
||||
const url = new URL(endpoint, apiHost);
|
||||
const body = JSON.stringify(data);
|
||||
|
||||
const res = wrapThrows(fetch)(url.toString(), {
|
||||
method,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body,
|
||||
});
|
||||
if (res.ok === false) return err(res.error);
|
||||
|
||||
const response = await res.data;
|
||||
const { data: innerData } = (await response.json()) as ApiResponse<T>;
|
||||
|
||||
if (!response.ok) {
|
||||
return err({
|
||||
code: "network_error",
|
||||
message: response.statusText,
|
||||
status: response.status,
|
||||
url,
|
||||
});
|
||||
}
|
||||
|
||||
return ok(innerData as T);
|
||||
}
|
||||
@@ -8,8 +8,6 @@ import { Logger } from "./lib/logger";
|
||||
import { checkPageUrl } from "./lib/noCodeEvents";
|
||||
import { resetPerson, setPersonAttribute, setPersonUserId, getPerson, logoutPerson } from "./lib/person";
|
||||
|
||||
export type { EnvironmentId, KeyValueData, PersonId, ResponseId, SurveyId } from "@formbricks/api";
|
||||
|
||||
const logger = Logger.getInstance();
|
||||
|
||||
logger.debug("Create command queue");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { FormbricksAPI, EnvironmentId } from "@formbricks/api";
|
||||
import { FormbricksAPI } from "@formbricks/api";
|
||||
import { Config } from "./config";
|
||||
|
||||
export const getApi = (): FormbricksAPI => {
|
||||
@@ -11,6 +11,6 @@ export const getApi = (): FormbricksAPI => {
|
||||
|
||||
return new FormbricksAPI({
|
||||
apiHost,
|
||||
environmentId: environmentId as EnvironmentId,
|
||||
environmentId,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
{
|
||||
"extends": "@formbricks/tsconfig/base.json",
|
||||
"include": ["."],
|
||||
"exclude": ["dist", "build", "node_modules"]
|
||||
"exclude": ["dist", "build", "node_modules"],
|
||||
"compilerOptions": {
|
||||
"composite": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,6 +70,13 @@ class AuthorizationError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
type NetworkError = {
|
||||
code: "network_error";
|
||||
message: string;
|
||||
status: number;
|
||||
url: URL;
|
||||
};
|
||||
|
||||
export {
|
||||
ResourceNotFoundError,
|
||||
InvalidInputError,
|
||||
@@ -81,3 +88,4 @@ export {
|
||||
AuthenticationError,
|
||||
AuthorizationError,
|
||||
};
|
||||
export type { NetworkError };
|
||||
|
||||
17
pnpm-lock.yaml
generated
17
pnpm-lock.yaml
generated
@@ -349,11 +349,10 @@ importers:
|
||||
version: link:../../packages/eslint-config-formbricks
|
||||
|
||||
packages/api:
|
||||
dependencies:
|
||||
devDependencies:
|
||||
'@formbricks/lib':
|
||||
specifier: workspace:*
|
||||
version: link:../lib
|
||||
devDependencies:
|
||||
'@formbricks/tsconfig':
|
||||
specifier: workspace:*
|
||||
version: link:../tsconfig
|
||||
@@ -365,7 +364,10 @@ importers:
|
||||
version: link:../eslint-config-formbricks
|
||||
tsup:
|
||||
specifier: ^7.2.0
|
||||
version: 7.2.0
|
||||
version: 7.2.0(typescript@5.1.6)
|
||||
typescript:
|
||||
specifier: 5.1.6
|
||||
version: 5.1.6
|
||||
|
||||
packages/database:
|
||||
dependencies:
|
||||
@@ -21967,7 +21969,7 @@ packages:
|
||||
/tslib@2.6.2:
|
||||
resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==}
|
||||
|
||||
/tsup@7.2.0:
|
||||
/tsup@7.2.0(typescript@5.1.6):
|
||||
resolution: {integrity: sha512-vDHlczXbgUvY3rWvqFEbSqmC1L7woozbzngMqTtL2PGBODTtWlRwGDDawhvWzr5c1QjKe4OAKqJGfE1xeXUvtQ==}
|
||||
engines: {node: '>=16.14'}
|
||||
hasBin: true
|
||||
@@ -21997,6 +21999,7 @@ packages:
|
||||
source-map: 0.8.0-beta.0
|
||||
sucrase: 3.32.0
|
||||
tree-kill: 1.2.2
|
||||
typescript: 5.1.6
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- ts-node
|
||||
@@ -22239,6 +22242,12 @@ packages:
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/typescript@5.1.6:
|
||||
resolution: {integrity: sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/typescript@5.2.2:
|
||||
resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==}
|
||||
engines: {node: '>=14.17'}
|
||||
|
||||
Reference in New Issue
Block a user