Init Commit
quality / commitlint (push) Skipped
CD / update-wiki (push) Failing after 7s
quality / changes (push) Successful in 4s
quality / docker-check (push) Skipped
quality / web (push) Failing after 38s
quality / api (push) Successful in 49s
CD / quality (push) Failing after 1m36s
CD / publish (push) Skipped
quality / commitlint (push) Skipped
CD / update-wiki (push) Failing after 7s
quality / changes (push) Successful in 4s
quality / docker-check (push) Skipped
quality / web (push) Failing after 38s
quality / api (push) Successful in 49s
CD / quality (push) Failing after 1m36s
CD / publish (push) Skipped
This commit is contained in:
Vendored
+201
@@ -0,0 +1,201 @@
|
||||
import * as drizzle_orm_sqlite_core from 'drizzle-orm/sqlite-core';
|
||||
import Database from 'better-sqlite3';
|
||||
import { drizzle } from 'drizzle-orm/better-sqlite3';
|
||||
|
||||
declare const appSettings: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
||||
name: "app_settings";
|
||||
schema: undefined;
|
||||
columns: {
|
||||
id: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "id";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: true;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
show_quick_actions: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "show_quick_actions";
|
||||
tableName: "app_settings";
|
||||
dataType: "boolean";
|
||||
columnType: "SQLiteBoolean";
|
||||
data: boolean;
|
||||
driverParam: number;
|
||||
notNull: true;
|
||||
hasDefault: true;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: undefined;
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {}>;
|
||||
created_at: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "created_at";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: true;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
updated_at: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "updated_at";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: true;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
};
|
||||
dialect: "sqlite";
|
||||
}>;
|
||||
declare const schema: {
|
||||
appSettings: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
||||
name: "app_settings";
|
||||
schema: undefined;
|
||||
columns: {
|
||||
id: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "id";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: false;
|
||||
isPrimaryKey: true;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
show_quick_actions: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "show_quick_actions";
|
||||
tableName: "app_settings";
|
||||
dataType: "boolean";
|
||||
columnType: "SQLiteBoolean";
|
||||
data: boolean;
|
||||
driverParam: number;
|
||||
notNull: true;
|
||||
hasDefault: true;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: undefined;
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {}>;
|
||||
created_at: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "created_at";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: true;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
updated_at: drizzle_orm_sqlite_core.SQLiteColumn<{
|
||||
name: "updated_at";
|
||||
tableName: "app_settings";
|
||||
dataType: "string";
|
||||
columnType: "SQLiteText";
|
||||
data: string;
|
||||
driverParam: string;
|
||||
notNull: true;
|
||||
hasDefault: true;
|
||||
isPrimaryKey: false;
|
||||
isAutoincrement: false;
|
||||
hasRuntimeDefault: false;
|
||||
enumValues: [string, ...string[]];
|
||||
baseColumn: never;
|
||||
identity: undefined;
|
||||
generated: undefined;
|
||||
}, {}, {
|
||||
length: number | undefined;
|
||||
}>;
|
||||
};
|
||||
dialect: "sqlite";
|
||||
}>;
|
||||
};
|
||||
|
||||
type Sqlite = Database.Database;
|
||||
type Db = ReturnType<typeof drizzle<typeof schema>>;
|
||||
declare function resolveDatabasePath(databaseUrl: string): string;
|
||||
declare function createDb(databaseUrl: string): {
|
||||
db: Db;
|
||||
sqlite: Sqlite;
|
||||
};
|
||||
declare function createMemoryDb(): {
|
||||
db: Db;
|
||||
sqlite: Sqlite;
|
||||
};
|
||||
declare function runMigrations(sqlite: Sqlite): void;
|
||||
declare function healthCheck(sqlite: Sqlite): void;
|
||||
|
||||
declare class NotFoundError extends Error {
|
||||
constructor(message: string);
|
||||
}
|
||||
declare class ConflictError extends Error {
|
||||
constructor(message: string);
|
||||
}
|
||||
|
||||
type AppSettingsDto = {
|
||||
id: string;
|
||||
showQuickActions: boolean;
|
||||
};
|
||||
type AppSettingsPatch = {
|
||||
showQuickActions?: boolean;
|
||||
};
|
||||
declare function getAppSettings(db: Db): AppSettingsDto;
|
||||
declare function updateAppSettings(db: Db, patch: AppSettingsPatch): AppSettingsDto;
|
||||
|
||||
export { type AppSettingsDto, type AppSettingsPatch, ConflictError, type Db, NotFoundError, type Sqlite, appSettings, createDb, createMemoryDb, getAppSettings, healthCheck, resolveDatabasePath, runMigrations, schema, updateAppSettings };
|
||||
Vendored
+120
@@ -0,0 +1,120 @@
|
||||
// src/schema.ts
|
||||
import { sql } from "drizzle-orm";
|
||||
import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
|
||||
var appSettings = sqliteTable("app_settings", {
|
||||
id: text("id").primaryKey(),
|
||||
show_quick_actions: integer("show_quick_actions", { mode: "boolean" }).notNull().default(true),
|
||||
created_at: text("created_at").notNull().default(sql`datetime('now')`),
|
||||
updated_at: text("updated_at").notNull().default(sql`datetime('now')`)
|
||||
});
|
||||
var schema = {
|
||||
appSettings
|
||||
};
|
||||
|
||||
// src/client.ts
|
||||
import { dirname, join } from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import { readFileSync, readdirSync } from "fs";
|
||||
import Database from "better-sqlite3";
|
||||
import { drizzle } from "drizzle-orm/better-sqlite3";
|
||||
var __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
function resolveDatabasePath(databaseUrl) {
|
||||
const url = databaseUrl.startsWith("sqlite:") ? databaseUrl.slice("sqlite:".length) : databaseUrl;
|
||||
return url;
|
||||
}
|
||||
function createDb(databaseUrl) {
|
||||
const path = resolveDatabasePath(databaseUrl);
|
||||
const sqlite = new Database(path);
|
||||
sqlite.pragma("journal_mode = WAL");
|
||||
sqlite.pragma("synchronous = NORMAL");
|
||||
sqlite.pragma("foreign_keys = ON");
|
||||
const db = drizzle(sqlite, { schema });
|
||||
return { db, sqlite };
|
||||
}
|
||||
function createMemoryDb() {
|
||||
const sqlite = new Database(":memory:");
|
||||
sqlite.pragma("foreign_keys = ON");
|
||||
const db = drizzle(sqlite, { schema });
|
||||
return { db, sqlite };
|
||||
}
|
||||
function runMigrations(sqlite) {
|
||||
const migrationsDir = join(__dirname, "..", "migrations");
|
||||
const files = readdirSync(migrationsDir).filter((f) => f.endsWith(".sql")).sort();
|
||||
sqlite.exec(
|
||||
`CREATE TABLE IF NOT EXISTS _migrations (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
)`
|
||||
);
|
||||
for (const file of files) {
|
||||
const applied = sqlite.prepare("SELECT 1 FROM _migrations WHERE name = ?").get(file);
|
||||
if (applied) continue;
|
||||
const sql2 = readFileSync(join(migrationsDir, file), "utf-8");
|
||||
sqlite.exec(sql2);
|
||||
sqlite.prepare("INSERT INTO _migrations (name) VALUES (?)").run(file);
|
||||
}
|
||||
}
|
||||
function healthCheck(sqlite) {
|
||||
sqlite.prepare("SELECT 1").get();
|
||||
}
|
||||
|
||||
// src/errors.ts
|
||||
var NotFoundError = class extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = "NotFoundError";
|
||||
}
|
||||
};
|
||||
var ConflictError = class extends Error {
|
||||
constructor(message) {
|
||||
super(message);
|
||||
this.name = "ConflictError";
|
||||
}
|
||||
};
|
||||
|
||||
// src/settings-repo.ts
|
||||
import { eq } from "drizzle-orm";
|
||||
var SETTINGS_ID = "settings-main";
|
||||
function toDto(row) {
|
||||
return {
|
||||
id: row.id,
|
||||
showQuickActions: row.show_quick_actions == null ? true : Boolean(row.show_quick_actions)
|
||||
};
|
||||
}
|
||||
function ensureRow(db) {
|
||||
const existing = db.select().from(appSettings).where(eq(appSettings.id, SETTINGS_ID)).get();
|
||||
if (existing) return existing;
|
||||
db.insert(appSettings).values({
|
||||
id: SETTINGS_ID,
|
||||
show_quick_actions: true
|
||||
}).run();
|
||||
return db.select().from(appSettings).where(eq(appSettings.id, SETTINGS_ID)).get();
|
||||
}
|
||||
function getAppSettings(db) {
|
||||
return toDto(ensureRow(db));
|
||||
}
|
||||
function updateAppSettings(db, patch) {
|
||||
ensureRow(db);
|
||||
const updates = {
|
||||
updated_at: (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19)
|
||||
};
|
||||
if (patch.showQuickActions !== void 0) {
|
||||
updates.show_quick_actions = patch.showQuickActions;
|
||||
}
|
||||
db.update(appSettings).set(updates).where(eq(appSettings.id, SETTINGS_ID)).run();
|
||||
return getAppSettings(db);
|
||||
}
|
||||
export {
|
||||
ConflictError,
|
||||
NotFoundError,
|
||||
appSettings,
|
||||
createDb,
|
||||
createMemoryDb,
|
||||
getAppSettings,
|
||||
healthCheck,
|
||||
resolveDatabasePath,
|
||||
runMigrations,
|
||||
schema,
|
||||
updateAppSettings
|
||||
};
|
||||
@@ -0,0 +1,10 @@
|
||||
import { defineConfig } from "drizzle-kit";
|
||||
|
||||
export default defineConfig({
|
||||
schema: "./src/schema.ts",
|
||||
out: "./drizzle",
|
||||
dialect: "sqlite",
|
||||
dbCredentials: {
|
||||
url: "data/app.db",
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
CREATE TABLE IF NOT EXISTS app_settings (
|
||||
id TEXT PRIMARY KEY NOT NULL,
|
||||
show_quick_actions INTEGER NOT NULL DEFAULT 1,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
);
|
||||
|
||||
INSERT OR IGNORE INTO app_settings (id, show_quick_actions)
|
||||
VALUES ('settings-main', 1);
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "@cdnmanager/db",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"files": [
|
||||
"dist",
|
||||
"migrations",
|
||||
"package.json"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"development": "./src/index.ts",
|
||||
"import": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsup src/index.ts --format esm --dts",
|
||||
"dev": "tsup src/index.ts --format esm --dts --watch",
|
||||
"db:generate": "drizzle-kit generate",
|
||||
"db:push": "drizzle-kit push"
|
||||
},
|
||||
"dependencies": {
|
||||
"@cdnmanager/shared": "workspace:*",
|
||||
"better-sqlite3": "^11.10.0",
|
||||
"drizzle-orm": "^0.44.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/better-sqlite3": "^7.6.13",
|
||||
"drizzle-kit": "^0.31.1",
|
||||
"tsup": "^8.5.0",
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import Database from "better-sqlite3";
|
||||
import { existsSync } from "node:fs";
|
||||
|
||||
const path = process.argv[2] ?? "../../data/app.db";
|
||||
if (!existsSync(path)) {
|
||||
console.log("missing:", path);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const db = new Database(path, { readonly: true });
|
||||
const tables = db
|
||||
.prepare("SELECT name FROM sqlite_master WHERE type='table' ORDER BY name")
|
||||
.all()
|
||||
.map((t) => t.name);
|
||||
console.log("path:", path);
|
||||
console.log("tables:", tables.join(", "));
|
||||
for (const t of [
|
||||
"domains",
|
||||
"groups",
|
||||
"dns_records",
|
||||
"services",
|
||||
"_migrations",
|
||||
]) {
|
||||
if (!tables.includes(t)) continue;
|
||||
console.log(t, db.prepare(`SELECT COUNT(*) as c FROM ${t}`).get().c);
|
||||
}
|
||||
if (tables.includes("domains")) {
|
||||
console.log(
|
||||
"sample:",
|
||||
db.prepare("SELECT id, zone_name FROM domains LIMIT 5").all(),
|
||||
);
|
||||
}
|
||||
if (tables.includes("_migrations")) {
|
||||
console.log(
|
||||
"migrations:",
|
||||
db.prepare("SELECT name FROM _migrations ORDER BY name").all(),
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
import { dirname, join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { readFileSync, readdirSync } from "node:fs";
|
||||
import Database from "better-sqlite3";
|
||||
import { drizzle } from "drizzle-orm/better-sqlite3";
|
||||
import { schema } from "./schema.js";
|
||||
|
||||
export type Sqlite = Database.Database;
|
||||
export type Db = ReturnType<typeof drizzle<typeof schema>>;
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
export function resolveDatabasePath(databaseUrl: string): string {
|
||||
const url = databaseUrl.startsWith("sqlite:")
|
||||
? databaseUrl.slice("sqlite:".length)
|
||||
: databaseUrl;
|
||||
return url;
|
||||
}
|
||||
|
||||
export function createDb(databaseUrl: string): { db: Db; sqlite: Sqlite } {
|
||||
const path = resolveDatabasePath(databaseUrl);
|
||||
const sqlite = new Database(path);
|
||||
sqlite.pragma("journal_mode = WAL");
|
||||
sqlite.pragma("synchronous = NORMAL");
|
||||
sqlite.pragma("foreign_keys = ON");
|
||||
const db = drizzle(sqlite, { schema });
|
||||
return { db, sqlite };
|
||||
}
|
||||
|
||||
export function createMemoryDb(): { db: Db; sqlite: Sqlite } {
|
||||
const sqlite = new Database(":memory:");
|
||||
sqlite.pragma("foreign_keys = ON");
|
||||
const db = drizzle(sqlite, { schema });
|
||||
return { db, sqlite };
|
||||
}
|
||||
|
||||
export function runMigrations(sqlite: Sqlite): void {
|
||||
const migrationsDir = join(__dirname, "..", "migrations");
|
||||
const files = readdirSync(migrationsDir)
|
||||
.filter((f) => f.endsWith(".sql"))
|
||||
.sort();
|
||||
|
||||
sqlite.exec(
|
||||
`CREATE TABLE IF NOT EXISTS _migrations (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL UNIQUE,
|
||||
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
)`,
|
||||
);
|
||||
|
||||
for (const file of files) {
|
||||
const applied = sqlite
|
||||
.prepare("SELECT 1 FROM _migrations WHERE name = ?")
|
||||
.get(file);
|
||||
if (applied) continue;
|
||||
|
||||
const sql = readFileSync(join(migrationsDir, file), "utf-8");
|
||||
sqlite.exec(sql);
|
||||
sqlite.prepare("INSERT INTO _migrations (name) VALUES (?)").run(file);
|
||||
}
|
||||
}
|
||||
|
||||
export function healthCheck(sqlite: Sqlite): void {
|
||||
sqlite.prepare("SELECT 1").get();
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export class NotFoundError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = "NotFoundError";
|
||||
}
|
||||
}
|
||||
|
||||
export class ConflictError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
this.name = "ConflictError";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export * from "./schema.js";
|
||||
export * from "./client.js";
|
||||
export * from "./errors.js";
|
||||
export * from "./settings-repo.js";
|
||||
@@ -0,0 +1,19 @@
|
||||
import { sql } from "drizzle-orm";
|
||||
import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
|
||||
|
||||
export const appSettings = sqliteTable("app_settings", {
|
||||
id: text("id").primaryKey(),
|
||||
show_quick_actions: integer("show_quick_actions", { mode: "boolean" })
|
||||
.notNull()
|
||||
.default(true),
|
||||
created_at: text("created_at")
|
||||
.notNull()
|
||||
.default(sql`datetime('now')`),
|
||||
updated_at: text("updated_at")
|
||||
.notNull()
|
||||
.default(sql`datetime('now')`),
|
||||
});
|
||||
|
||||
export const schema = {
|
||||
appSettings,
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
import { eq } from "drizzle-orm";
|
||||
import type { Db } from "./client.js";
|
||||
import { appSettings } from "./schema.js";
|
||||
|
||||
const SETTINGS_ID = "settings-main";
|
||||
|
||||
export type AppSettingsDto = {
|
||||
id: string;
|
||||
showQuickActions: boolean;
|
||||
};
|
||||
|
||||
export type AppSettingsPatch = {
|
||||
showQuickActions?: boolean;
|
||||
};
|
||||
|
||||
function toDto(row: typeof appSettings.$inferSelect): AppSettingsDto {
|
||||
return {
|
||||
id: row.id,
|
||||
showQuickActions:
|
||||
row.show_quick_actions == null ? true : Boolean(row.show_quick_actions),
|
||||
};
|
||||
}
|
||||
|
||||
function ensureRow(db: Db): typeof appSettings.$inferSelect {
|
||||
const existing = db
|
||||
.select()
|
||||
.from(appSettings)
|
||||
.where(eq(appSettings.id, SETTINGS_ID))
|
||||
.get();
|
||||
if (existing) return existing;
|
||||
|
||||
db.insert(appSettings)
|
||||
.values({
|
||||
id: SETTINGS_ID,
|
||||
show_quick_actions: true,
|
||||
})
|
||||
.run();
|
||||
|
||||
return db
|
||||
.select()
|
||||
.from(appSettings)
|
||||
.where(eq(appSettings.id, SETTINGS_ID))
|
||||
.get()!;
|
||||
}
|
||||
|
||||
export function getAppSettings(db: Db): AppSettingsDto {
|
||||
return toDto(ensureRow(db));
|
||||
}
|
||||
|
||||
export function updateAppSettings(
|
||||
db: Db,
|
||||
patch: AppSettingsPatch,
|
||||
): AppSettingsDto {
|
||||
ensureRow(db);
|
||||
const updates: Partial<typeof appSettings.$inferInsert> = {
|
||||
updated_at: new Date().toISOString().replace("T", " ").slice(0, 19),
|
||||
};
|
||||
if (patch.showQuickActions !== undefined) {
|
||||
updates.show_quick_actions = patch.showQuickActions;
|
||||
}
|
||||
db.update(appSettings)
|
||||
.set(updates)
|
||||
.where(eq(appSettings.id, SETTINGS_ID))
|
||||
.run();
|
||||
return getAppSettings(db);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"declaration": true,
|
||||
"outDir": "dist",
|
||||
"rootDir": "src"
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
Reference in New Issue
Block a user