Merged in chore/eslint9 (pull request #2029)
chore: Update to ESLint 9 * wip: apply codemod and upgrade swc plugin * Update eslint to 9 in scandic-web apply code mod to config fix existing lint issues * Remove uneccessary fixupConfigRules * Update eslint to 9 in design-system * Add lint turbo dependency * Move redis-api to eslint and prettier instead of biome * Simplify eslint configs * Clean up * Apply linting Approved-by: Linus Flood
This commit is contained in:
@@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
|
|
||||||
"vcs": {
|
|
||||||
"enabled": false,
|
|
||||||
"clientKind": "git",
|
|
||||||
"useIgnoreFile": true,
|
|
||||||
},
|
|
||||||
"files": {
|
|
||||||
"ignoreUnknown": false,
|
|
||||||
"ignore": ["node_modules"],
|
|
||||||
},
|
|
||||||
"formatter": {
|
|
||||||
"enabled": true,
|
|
||||||
"indentStyle": "tab",
|
|
||||||
},
|
|
||||||
"organizeImports": {
|
|
||||||
"enabled": true,
|
|
||||||
},
|
|
||||||
"linter": {
|
|
||||||
"enabled": true,
|
|
||||||
"rules": {
|
|
||||||
"recommended": true,
|
|
||||||
"performance": {
|
|
||||||
"noBarrelFile": "error",
|
|
||||||
},
|
|
||||||
"style": {
|
|
||||||
"useImportType": "error",
|
|
||||||
"useExportType": "error",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"javascript": {
|
|
||||||
"formatter": {
|
|
||||||
"quoteStyle": "double",
|
|
||||||
"trailingCommas": "all",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
41
apps/redis-api/eslint.config.mjs
Normal file
41
apps/redis-api/eslint.config.mjs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
import { FlatCompat } from "@eslint/eslintrc";
|
||||||
|
import js from "@eslint/js";
|
||||||
|
import typescriptEslint from "@typescript-eslint/eslint-plugin";
|
||||||
|
import tsParser from "@typescript-eslint/parser";
|
||||||
|
import { defineConfig } from "eslint/config";
|
||||||
|
import simpleImportSort from "eslint-plugin-simple-import-sort";
|
||||||
|
|
||||||
|
const compat = new FlatCompat({
|
||||||
|
recommendedConfig: js.configs.recommended,
|
||||||
|
allConfig: js.configs.all,
|
||||||
|
});
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
{
|
||||||
|
extends: compat.extends("plugin:@typescript-eslint/recommended"),
|
||||||
|
plugins: {
|
||||||
|
"simple-import-sort": simpleImportSort,
|
||||||
|
"@typescript-eslint": typescriptEslint,
|
||||||
|
},
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
"no-unused-vars": "off",
|
||||||
|
"simple-import-sort/imports": "error",
|
||||||
|
"simple-import-sort/exports": "error",
|
||||||
|
"@typescript-eslint/no-unused-vars": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
args: "all",
|
||||||
|
argsIgnorePattern: "^_",
|
||||||
|
caughtErrors: "all",
|
||||||
|
caughtErrorsIgnorePattern: "^_",
|
||||||
|
destructuredArrayIgnorePattern: "^_",
|
||||||
|
varsIgnorePattern: "^_",
|
||||||
|
ignoreRestSiblings: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "redis-api",
|
"name": "@scandic-hotels/redis-api",
|
||||||
"module": "index.ts",
|
"module": "index.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "bun --watch src/index.ts | pino-pretty -o '{if module}[{module}] {end}{msg}' -i pid,hostname"
|
"dev": "bun --watch src/index.ts | pino-pretty -o '{if module}[{module}] {end}{msg}' -i pid,hostname",
|
||||||
|
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0 && tsc"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@elysiajs/server-timing": "^1.3.0",
|
"@elysiajs/server-timing": "^1.3.0",
|
||||||
@@ -17,9 +18,18 @@
|
|||||||
"pino": "^9.6.0"
|
"pino": "^9.6.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^1.9.4",
|
"@eslint/eslintrc": "^3.3.1",
|
||||||
|
"@eslint/js": "^9.26.0",
|
||||||
"@types/bun": "latest",
|
"@types/bun": "latest",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^8.32.0",
|
||||||
|
"@typescript-eslint/parser": "^8.32.0",
|
||||||
|
"eslint": "^9",
|
||||||
|
"eslint-plugin-simple-import-sort": "^10.0.0",
|
||||||
"pino-pretty": "^13.0.0",
|
"pino-pretty": "^13.0.0",
|
||||||
|
"prettier": "^3.5.3",
|
||||||
"typescript": "^5.7.2"
|
"typescript": "^5.7.2"
|
||||||
|
},
|
||||||
|
"prettier": {
|
||||||
|
"tabWidth": 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
import "@/server/sentry.server.config";
|
import "@/server/sentry.server.config";
|
||||||
|
|
||||||
|
import serverTiming from "@elysiajs/server-timing";
|
||||||
|
import { swagger } from "@elysiajs/swagger";
|
||||||
import * as Sentry from "@sentry/bun";
|
import * as Sentry from "@sentry/bun";
|
||||||
import { Elysia } from "elysia";
|
import { Elysia } from "elysia";
|
||||||
|
|
||||||
import { swagger } from "@elysiajs/swagger";
|
|
||||||
import { apiRoutes } from "@/routes/api";
|
|
||||||
import { healthRoutes } from "@/routes/health";
|
|
||||||
import { baseLogger } from "@/utils/logger";
|
|
||||||
import { env } from "@/env";
|
import { env } from "@/env";
|
||||||
import serverTiming from "@elysiajs/server-timing";
|
|
||||||
import { AuthenticationError } from "@/errors/AuthenticationError";
|
import { AuthenticationError } from "@/errors/AuthenticationError";
|
||||||
import { ModelValidationError } from "@/errors/ModelValidationError";
|
import { ModelValidationError } from "@/errors/ModelValidationError";
|
||||||
|
import { apiRoutes } from "@/routes/api";
|
||||||
|
import { healthRoutes } from "@/routes/health";
|
||||||
import { setupShutdown } from "@/shutdown";
|
import { setupShutdown } from "@/shutdown";
|
||||||
|
import { baseLogger } from "@/utils/logger";
|
||||||
|
|
||||||
setupShutdown();
|
setupShutdown();
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ if (env.IS_DEV) {
|
|||||||
version: "1.0.0",
|
version: "1.0.0",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { AuthenticationError } from "@/errors/AuthenticationError";
|
|
||||||
import type { Context } from "elysia";
|
import type { Context } from "elysia";
|
||||||
|
|
||||||
import { env } from "@/env";
|
import { env } from "@/env";
|
||||||
|
import { AuthenticationError } from "@/errors/AuthenticationError";
|
||||||
|
|
||||||
const API_KEY_HEADER = "x-api-key";
|
const API_KEY_HEADER = "x-api-key";
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import * as Sentry from "@sentry/bun";
|
import * as Sentry from "@sentry/bun";
|
||||||
|
|
||||||
import { Elysia, t } from "elysia";
|
import { Elysia, t } from "elysia";
|
||||||
import { redis } from "@/services/redis";
|
|
||||||
import { ModelValidationError } from "@/errors/ModelValidationError";
|
import { ModelValidationError } from "@/errors/ModelValidationError";
|
||||||
|
import { redis } from "@/services/redis";
|
||||||
import { loggerModule } from "@/utils/logger";
|
import { loggerModule } from "@/utils/logger";
|
||||||
import { truncate } from "@/utils/truncate";
|
|
||||||
import { timeout } from "@/utils/timeout";
|
import { timeout } from "@/utils/timeout";
|
||||||
|
import { truncate } from "@/utils/truncate";
|
||||||
|
|
||||||
const MIN_LENGTH = 1;
|
const MIN_LENGTH = 1;
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ export const cacheRoutes = new Elysia({ prefix: "/cache" })
|
|||||||
{
|
{
|
||||||
query: QUERY_TYPE,
|
query: QUERY_TYPE,
|
||||||
response: { 200: t.Object({ data: t.Any() }), 404: t.String() },
|
response: { 200: t.Object({ data: t.Any() }), 404: t.String() },
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
.put(
|
.put(
|
||||||
"/",
|
"/",
|
||||||
@@ -52,7 +52,7 @@ export const cacheRoutes = new Elysia({ prefix: "/cache" })
|
|||||||
|
|
||||||
if (!body.ttl || body.ttl < 0) {
|
if (!body.ttl || body.ttl < 0) {
|
||||||
cacheRouteLogger.warn(
|
cacheRouteLogger.warn(
|
||||||
`PUT /cache ${key} with ttl=${body.ttl}, will not cache the data`
|
`PUT /cache ${key} with ttl=${body.ttl}, will not cache the data`,
|
||||||
);
|
);
|
||||||
return status("Bad Request", "ttl is required");
|
return status("Bad Request", "ttl is required");
|
||||||
}
|
}
|
||||||
@@ -66,14 +66,14 @@ export const cacheRoutes = new Elysia({ prefix: "/cache" })
|
|||||||
body: t.Object({ data: t.Any(), ttl: t.Number() }),
|
body: t.Object({ data: t.Any(), ttl: t.Number() }),
|
||||||
query: QUERY_TYPE,
|
query: QUERY_TYPE,
|
||||||
response: { 204: t.Undefined(), 400: t.String() },
|
response: { 204: t.Undefined(), 400: t.String() },
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
.delete(
|
.delete(
|
||||||
"/",
|
"/",
|
||||||
async ({ query: { key, fuzzy } }) => {
|
async ({ query: { key, fuzzy } }) => {
|
||||||
key = validateKey(key);
|
key = validateKey(key);
|
||||||
cacheRouteLogger.debug(
|
cacheRouteLogger.debug(
|
||||||
`DELETE /cache ${key} ${fuzzy ? "fuzzy" : ""}`
|
`DELETE /cache ${key} ${fuzzy ? "fuzzy" : ""}`,
|
||||||
);
|
);
|
||||||
const deletedKeys: number = fuzzy
|
const deletedKeys: number = fuzzy
|
||||||
? await deleteWithPattern(`*${key}*`)
|
? await deleteWithPattern(`*${key}*`)
|
||||||
@@ -91,7 +91,7 @@ export const cacheRoutes = new Elysia({ prefix: "/cache" })
|
|||||||
200: t.Object({ deletedKeys: t.Number() }),
|
200: t.Object({ deletedKeys: t.Number() }),
|
||||||
400: t.String(),
|
400: t.String(),
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
function validateKey(key: string) {
|
function validateKey(key: string) {
|
||||||
@@ -99,7 +99,7 @@ function validateKey(key: string) {
|
|||||||
|
|
||||||
if (parsedKey.length < MIN_LENGTH) {
|
if (parsedKey.length < MIN_LENGTH) {
|
||||||
throw new ModelValidationError(
|
throw new ModelValidationError(
|
||||||
"Key has to be at least 1 character long"
|
"Key has to be at least 1 character long",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,7 +122,7 @@ async function deleteWithPattern(pattern: string) {
|
|||||||
"MATCH",
|
"MATCH",
|
||||||
pattern,
|
pattern,
|
||||||
"COUNT",
|
"COUNT",
|
||||||
SCAN_SIZE
|
SCAN_SIZE,
|
||||||
);
|
);
|
||||||
|
|
||||||
cursor = newCursor;
|
cursor = newCursor;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { Elysia } from "elysia";
|
import { Elysia } from "elysia";
|
||||||
import { cacheRoutes } from "./cache";
|
|
||||||
import { apiKeyMiddleware } from "@/middleware/apiKeyMiddleware";
|
import { apiKeyMiddleware } from "@/middleware/apiKeyMiddleware";
|
||||||
|
|
||||||
|
import { cacheRoutes } from "./cache";
|
||||||
|
|
||||||
export const apiRoutes = new Elysia({ prefix: "/api" })
|
export const apiRoutes = new Elysia({ prefix: "/api" })
|
||||||
.guard({ beforeHandle: apiKeyMiddleware })
|
.guard({ beforeHandle: apiKeyMiddleware })
|
||||||
.use(cacheRoutes);
|
.use(cacheRoutes);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import Elysia, { t } from "elysia";
|
import Elysia, { t } from "elysia";
|
||||||
|
|
||||||
import { redis } from "@/services/redis";
|
|
||||||
import { baseLogger, loggerModule } from "@/utils/logger";
|
|
||||||
import { env } from "@/env";
|
import { env } from "@/env";
|
||||||
|
import { redis } from "@/services/redis";
|
||||||
|
import { baseLogger } from "@/utils/logger";
|
||||||
|
|
||||||
const healthLogger = baseLogger.child({
|
const healthLogger = baseLogger.child({
|
||||||
module: "health",
|
module: "health",
|
||||||
@@ -52,5 +52,5 @@ export const healthRoutes = new Elysia().get(
|
|||||||
duration: t.String(),
|
duration: t.String(),
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import "@sentry/tracing";
|
import "@sentry/tracing";
|
||||||
import { env } from "@/env";
|
|
||||||
import * as Sentry from "@sentry/bun";
|
import * as Sentry from "@sentry/bun";
|
||||||
|
|
||||||
|
import { env } from "@/env";
|
||||||
|
|
||||||
Sentry.init({
|
Sentry.init({
|
||||||
dsn: env.SENTRY_DSN,
|
dsn: env.SENTRY_DSN,
|
||||||
enabled: env.SENTRY_ENABLED,
|
enabled: env.SENTRY_ENABLED,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { redisConfig, env } from "@/env";
|
|
||||||
import ioredis from "ioredis";
|
import ioredis from "ioredis";
|
||||||
|
|
||||||
|
import { env, redisConfig } from "@/env";
|
||||||
|
|
||||||
const redis = new ioredis({
|
const redis = new ioredis({
|
||||||
host: redisConfig.host,
|
host: redisConfig.host,
|
||||||
port: redisConfig.port,
|
port: redisConfig.port,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { loggerModule } from "@/utils/logger";
|
|
||||||
import { redis } from "@/services/redis";
|
import { redis } from "@/services/redis";
|
||||||
|
import { loggerModule } from "@/utils/logger";
|
||||||
|
|
||||||
const shutdownLogger = loggerModule("shutdown");
|
const shutdownLogger = loggerModule("shutdown");
|
||||||
|
|
||||||
|
|||||||
@@ -1,34 +1,36 @@
|
|||||||
import pino from "pino";
|
import pino from "pino";
|
||||||
import { mask } from "./mask";
|
|
||||||
import { env } from "@/env";
|
import { env } from "@/env";
|
||||||
|
|
||||||
const serializers: { [key: string]: pino.SerializerFn } = {
|
import { mask } from "./mask";
|
||||||
password: (payload) => {
|
|
||||||
if (payload) {
|
|
||||||
return env.IS_DEV
|
|
||||||
? mask(payload)
|
|
||||||
: mask(payload, {
|
|
||||||
visibleStart: 0,
|
|
||||||
visibleEnd: 0,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return payload;
|
const serializers: { [key: string]: pino.SerializerFn } = {
|
||||||
},
|
password: (payload) => {
|
||||||
email: (payload) => {
|
if (payload) {
|
||||||
if (payload) {
|
return env.IS_DEV
|
||||||
return env.IS_DEV ? payload : mask(payload);
|
? mask(payload)
|
||||||
}
|
: mask(payload, {
|
||||||
return payload;
|
visibleStart: 0,
|
||||||
},
|
visibleEnd: 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return payload;
|
||||||
|
},
|
||||||
|
email: (payload) => {
|
||||||
|
if (payload) {
|
||||||
|
return env.IS_DEV ? payload : mask(payload);
|
||||||
|
}
|
||||||
|
return payload;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const baseLogger = pino({
|
export const baseLogger = pino({
|
||||||
level: process.env.LOG_LEVEL || "info",
|
level: process.env.LOG_LEVEL || "info",
|
||||||
timestamp: pino.stdTimeFunctions.isoTime,
|
timestamp: pino.stdTimeFunctions.isoTime,
|
||||||
serializers,
|
serializers,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const loggerModule = (loggerName: string) => {
|
export const loggerModule = (loggerName: string) => {
|
||||||
return baseLogger.child({ module: loggerName });
|
return baseLogger.child({ module: loggerName });
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,42 +1,43 @@
|
|||||||
import { describe, it, expect } from "bun:test";
|
import { describe, expect, it } from "bun:test";
|
||||||
|
|
||||||
import { mask } from "./mask";
|
import { mask } from "./mask";
|
||||||
|
|
||||||
describe("mask", () => {
|
describe("mask", () => {
|
||||||
it("should return empty string for empty input", () => {
|
it("should return empty string for empty input", () => {
|
||||||
expect(mask("")).toBe("");
|
expect(mask("")).toBe("");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should mask string with default parameters", () => {
|
it("should mask string with default parameters", () => {
|
||||||
expect(mask("1234567890")).toBe("12******90");
|
expect(mask("1234567890")).toBe("12******90");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should show custom number of characters at start", () => {
|
it("should show custom number of characters at start", () => {
|
||||||
expect(mask("1234567890", { visibleStart: 3 })).toBe("123*****90");
|
expect(mask("1234567890", { visibleStart: 3 })).toBe("123*****90");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should show custom number of characters at end", () => {
|
it("should show custom number of characters at end", () => {
|
||||||
expect(mask("1234567890", { visibleStart: 2, visibleEnd: 3 })).toBe(
|
expect(mask("1234567890", { visibleStart: 2, visibleEnd: 3 })).toBe(
|
||||||
"12*****890",
|
"12*****890",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should mask entire string when visible parts exceed length", () => {
|
it("should mask entire string when visible parts exceed length", () => {
|
||||||
expect(mask("123", { visibleStart: 2, visibleEnd: 2 })).toBe("***");
|
expect(mask("123", { visibleStart: 2, visibleEnd: 2 })).toBe("***");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should handle undefined end part", () => {
|
it("should handle undefined end part", () => {
|
||||||
expect(mask("1234567890", { visibleStart: 2, visibleEnd: 0 })).toBe(
|
expect(mask("1234567890", { visibleStart: 2, visibleEnd: 0 })).toBe(
|
||||||
"12********",
|
"12********",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should handle long strings", () => {
|
it("should handle long strings", () => {
|
||||||
expect(mask("12345678901234567890")).toBe("12**********90");
|
expect(mask("12345678901234567890")).toBe("12**********90");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should handle emails", () => {
|
it("should handle emails", () => {
|
||||||
expect(mask("test.testsson@scandichotels.com")).toBe(
|
expect(mask("test.testsson@scandichotels.com")).toBe(
|
||||||
"te*********on@sc*********ls.com",
|
"te*********on@sc*********ls.com",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,89 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": ["next/core-web-vitals", "plugin:import/typescript"],
|
|
||||||
"plugins": ["simple-import-sort", "@typescript-eslint", "formatjs"],
|
|
||||||
"parser": "@typescript-eslint/parser",
|
|
||||||
"rules": {
|
|
||||||
"no-unused-vars": "off",
|
|
||||||
"react/function-component-definition": "error",
|
|
||||||
"simple-import-sort/imports": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"groups": [
|
|
||||||
// Side effect imports.
|
|
||||||
["^\\u0000"],
|
|
||||||
// Node.js builtins.
|
|
||||||
["^node:"],
|
|
||||||
// NPM packages.
|
|
||||||
["^@?\\w"],
|
|
||||||
// Internal packages.
|
|
||||||
["^@scandic-hotels/(?!.*\u0000$).*$"],
|
|
||||||
// Local imports (lib, constants, etc.), excl. types.
|
|
||||||
[
|
|
||||||
"^@/constants/?(?!.*\u0000$).*$",
|
|
||||||
"^@/env/?(?!.*\u0000$).*$",
|
|
||||||
"^@/lib/?(?!.*\u0000$).*$",
|
|
||||||
"^@/server/?(?!.*\u0000$).*$",
|
|
||||||
"^@/stores/?(?!.*\u0000$).*$"
|
|
||||||
],
|
|
||||||
// Local imports (the rest), excl. types.
|
|
||||||
["^@/(?!(types|.*\u0000$)).*$"],
|
|
||||||
// Parent imports. Put `..` last.
|
|
||||||
// Other relative imports. Put same-folder imports and `.` last.
|
|
||||||
[
|
|
||||||
"^\\.\\.(?!/?$)",
|
|
||||||
"^\\.\\./?$",
|
|
||||||
"^\\./(?=.*/)(?!/?$)",
|
|
||||||
"^\\.(?!/?$)",
|
|
||||||
"^\\./?$"
|
|
||||||
],
|
|
||||||
// Style imports.
|
|
||||||
["^(?!\\u0000).+\\.s?css$"],
|
|
||||||
// Node.js builtins and NPM packages type imports.
|
|
||||||
["^node:.*\\u0000$", "^@?\\w.*\\u0000$"],
|
|
||||||
// Local type imports.
|
|
||||||
[
|
|
||||||
"^@scandichotels/.*\\u0000$",
|
|
||||||
"^@/types/.*",
|
|
||||||
"^@/.*\\u0000$",
|
|
||||||
"^[^.].*\\u0000$",
|
|
||||||
"^\\..*\\u0000$"
|
|
||||||
]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"simple-import-sort/exports": "error",
|
|
||||||
"import/first": "error",
|
|
||||||
"import/newline-after-import": "error",
|
|
||||||
"import/no-duplicates": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"prefer-inline": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"@typescript-eslint/consistent-type-imports": "error",
|
|
||||||
"@typescript-eslint/no-unused-vars": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"args": "all",
|
|
||||||
"argsIgnorePattern": "^_",
|
|
||||||
"caughtErrors": "all",
|
|
||||||
"caughtErrorsIgnorePattern": "^_",
|
|
||||||
"destructuredArrayIgnorePattern": "^_",
|
|
||||||
"varsIgnorePattern": "^_",
|
|
||||||
"ignoreRestSiblings": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
// "formatjs/enforce-description": ["warn", "anything"],
|
|
||||||
"formatjs/enforce-default-message": ["error", "literal"],
|
|
||||||
"formatjs/enforce-placeholders": ["error"],
|
|
||||||
"formatjs/enforce-plural-rules": ["error"],
|
|
||||||
"formatjs/no-literal-string-in-jsx": ["error"],
|
|
||||||
"formatjs/no-multiple-whitespaces": ["error"],
|
|
||||||
"formatjs/no-multiple-plurals": ["error"],
|
|
||||||
"formatjs/no-invalid-icu": ["error"],
|
|
||||||
"formatjs/no-id": ["error"],
|
|
||||||
"formatjs/no-complex-selectors": ["error"],
|
|
||||||
"formatjs/no-useless-message": ["error"],
|
|
||||||
"formatjs/prefer-pound-in-plural": ["error"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -15,7 +15,11 @@ import { getIntl } from "@/i18n"
|
|||||||
import { getHotelSearchDetails } from "@/utils/hotelSearchDetails"
|
import { getHotelSearchDetails } from "@/utils/hotelSearchDetails"
|
||||||
import { parseSelectHotelSearchParams } from "@/utils/url"
|
import { parseSelectHotelSearchParams } from "@/utils/url"
|
||||||
|
|
||||||
import type { LangParams, NextSearchParams, PageArgs } from "@/types/params"
|
import {
|
||||||
|
type LangParams,
|
||||||
|
type NextSearchParams,
|
||||||
|
type PageArgs,
|
||||||
|
} from "@/types/params"
|
||||||
|
|
||||||
export default async function AlternativeHotelsPage(
|
export default async function AlternativeHotelsPage(
|
||||||
props: PageArgs<LangParams, NextSearchParams>
|
props: PageArgs<LangParams, NextSearchParams>
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ export default async function HotelReservationPage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
// eslint-disable-next-line formatjs/no-literal-string-in-jsx
|
|
||||||
<div className={styles.page}>
|
<div className={styles.page}>
|
||||||
<TrackingSDK pageData={pageTrackingData} />
|
<TrackingSDK pageData={pageTrackingData} />
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
/* eslint-disable @next/next/no-img-element */
|
|
||||||
|
|
||||||
import { env } from "@/env/server"
|
import { env } from "@/env/server"
|
||||||
|
|
||||||
import HotelMarkerByType from "@/components/Maps/Markers"
|
import HotelMarkerByType from "@/components/Maps/Markers"
|
||||||
|
|||||||
@@ -6,11 +6,10 @@ import type {
|
|||||||
NucleoIconProps,
|
NucleoIconProps,
|
||||||
} from "@scandic-hotels/design-system/Icons"
|
} from "@scandic-hotels/design-system/Icons"
|
||||||
import type { MaterialIconSetIconProps } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
import type { MaterialIconSetIconProps } from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||||
|
import type { JSX } from "react"
|
||||||
|
|
||||||
import { FacilityEnum } from "@/types/enums/facilities"
|
import { FacilityEnum } from "@/types/enums/facilities"
|
||||||
|
|
||||||
import type { JSX } from "react";
|
|
||||||
|
|
||||||
const facilityToIconMap: Record<FacilityEnum, IconName> = {
|
const facilityToIconMap: Record<FacilityEnum, IconName> = {
|
||||||
[FacilityEnum.AccessibleBathingControls]: IconName.StarFilled,
|
[FacilityEnum.AccessibleBathingControls]: IconName.StarFilled,
|
||||||
[FacilityEnum.AccessibleBathtubs]: IconName.StarFilled,
|
[FacilityEnum.AccessibleBathtubs]: IconName.StarFilled,
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import {
|
|||||||
|
|
||||||
import { ChildBedTypeEnum } from "@/constants/booking"
|
import { ChildBedTypeEnum } from "@/constants/booking"
|
||||||
|
|
||||||
|
import type { JSX } from "react"
|
||||||
|
|
||||||
import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
|
import { ChildBedMapEnum } from "@/types/components/bookingWidget/enums"
|
||||||
import {
|
import {
|
||||||
RoomPackageCodeEnum,
|
RoomPackageCodeEnum,
|
||||||
@@ -13,8 +15,6 @@ import {
|
|||||||
import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate"
|
import type { Child } from "@/types/components/hotelReservation/selectRate/selectRate"
|
||||||
import type { Packages } from "@/types/requests/packages"
|
import type { Packages } from "@/types/requests/packages"
|
||||||
|
|
||||||
import type { JSX } from "react";
|
|
||||||
|
|
||||||
interface IconForFeatureCodeProps {
|
interface IconForFeatureCodeProps {
|
||||||
featureCode: RoomPackageCodes
|
featureCode: RoomPackageCodes
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,8 +30,7 @@ import type {
|
|||||||
IconProps,
|
IconProps,
|
||||||
NucleoIconProps,
|
NucleoIconProps,
|
||||||
} from "@scandic-hotels/design-system/Icons"
|
} from "@scandic-hotels/design-system/Icons"
|
||||||
|
import type { JSX } from "react"
|
||||||
import type { JSX } from "react";
|
|
||||||
|
|
||||||
interface IconByIconNameProps {
|
interface IconByIconNameProps {
|
||||||
iconName: IconName | null
|
iconName: IconName | null
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { Dispatch, SetStateAction, JSX } from "react";
|
import type { Dispatch, JSX, SetStateAction } from "react"
|
||||||
|
|
||||||
export enum AnimationStateEnum {
|
export enum AnimationStateEnum {
|
||||||
unmounted = "unmounted",
|
unmounted = "unmounted",
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ import type {
|
|||||||
NucleoIconProps,
|
NucleoIconProps,
|
||||||
} from "@scandic-hotels/design-system/Icons"
|
} from "@scandic-hotels/design-system/Icons"
|
||||||
import type { MaterialSymbolProps } from "@scandic-hotels/design-system/Icons/MaterialIcon/MaterialSymbol"
|
import type { MaterialSymbolProps } from "@scandic-hotels/design-system/Icons/MaterialIcon/MaterialSymbol"
|
||||||
|
|
||||||
import type { JSX } from "react"
|
import type { JSX } from "react"
|
||||||
|
|
||||||
interface FacilityIconProps {
|
interface FacilityIconProps {
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ import {
|
|||||||
type MaterialIconSetIconProps,
|
type MaterialIconSetIconProps,
|
||||||
} from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
} from "@scandic-hotels/design-system/Icons/MaterialIcon"
|
||||||
|
|
||||||
|
import type { JSX } from "react"
|
||||||
|
|
||||||
import { AlertTypeEnum } from "@/types/enums/alert"
|
import { AlertTypeEnum } from "@/types/enums/alert"
|
||||||
import type { AlertProps } from "./alert"
|
import type { AlertProps } from "./alert"
|
||||||
|
|
||||||
import type { JSX } from "react";
|
|
||||||
|
|
||||||
interface IconByAlertProps {
|
interface IconByAlertProps {
|
||||||
alertType: AlertTypeEnum
|
alertType: AlertTypeEnum
|
||||||
variant?: AlertProps["variant"]
|
variant?: AlertProps["variant"]
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import type { IconProps } from "@scandic-hotels/design-system/Icons"
|
import type { IconProps } from "@scandic-hotels/design-system/Icons"
|
||||||
|
import type { JSX } from "react"
|
||||||
import type { JSX } from "react";
|
|
||||||
|
|
||||||
export interface RadioCardProps
|
export interface RadioCardProps
|
||||||
extends Omit<React.LabelHTMLAttributes<HTMLLabelElement>, "title"> {
|
extends Omit<React.LabelHTMLAttributes<HTMLLabelElement>, "title"> {
|
||||||
|
|||||||
106
apps/scandic-web/eslint.config.mjs
Normal file
106
apps/scandic-web/eslint.config.mjs
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
import { FlatCompat } from "@eslint/eslintrc"
|
||||||
|
import js from "@eslint/js"
|
||||||
|
import typescriptEslint from "@typescript-eslint/eslint-plugin"
|
||||||
|
import tsParser from "@typescript-eslint/parser"
|
||||||
|
import { defineConfig } from "eslint/config"
|
||||||
|
import formatjs from "eslint-plugin-formatjs"
|
||||||
|
import simpleImportSort from "eslint-plugin-simple-import-sort"
|
||||||
|
|
||||||
|
const compat = new FlatCompat({
|
||||||
|
recommendedConfig: js.configs.recommended,
|
||||||
|
allConfig: js.configs.all,
|
||||||
|
})
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
{
|
||||||
|
extends: compat.extends("next/core-web-vitals", "plugin:import/typescript"),
|
||||||
|
plugins: {
|
||||||
|
"simple-import-sort": simpleImportSort,
|
||||||
|
"@typescript-eslint": typescriptEslint,
|
||||||
|
formatjs,
|
||||||
|
},
|
||||||
|
|
||||||
|
languageOptions: {
|
||||||
|
parser: tsParser,
|
||||||
|
},
|
||||||
|
|
||||||
|
rules: {
|
||||||
|
"no-unused-vars": "off",
|
||||||
|
"react/function-component-definition": "error",
|
||||||
|
|
||||||
|
"simple-import-sort/imports": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
groups: [
|
||||||
|
["^\\u0000"],
|
||||||
|
["^node:"],
|
||||||
|
["^@?\\w"],
|
||||||
|
["^@scandic-hotels/(?!.*\u0000$).*$"],
|
||||||
|
[
|
||||||
|
"^@/constants/?(?!.*\u0000$).*$",
|
||||||
|
"^@/env/?(?!.*\u0000$).*$",
|
||||||
|
"^@/lib/?(?!.*\u0000$).*$",
|
||||||
|
"^@/server/?(?!.*\u0000$).*$",
|
||||||
|
"^@/stores/?(?!.*\u0000$).*$",
|
||||||
|
],
|
||||||
|
["^@/(?!(types|.*\u0000$)).*$"],
|
||||||
|
[
|
||||||
|
"^\\.\\.(?!/?$)",
|
||||||
|
"^\\.\\./?$",
|
||||||
|
"^\\./(?=.*/)(?!/?$)",
|
||||||
|
"^\\.(?!/?$)",
|
||||||
|
"^\\./?$",
|
||||||
|
],
|
||||||
|
["^(?!\\u0000).+\\.s?css$"],
|
||||||
|
["^node:.*\\u0000$", "^@?\\w.*\\u0000$"],
|
||||||
|
[
|
||||||
|
"^@scandichotels/.*\\u0000$",
|
||||||
|
"^@/types/.*",
|
||||||
|
"^@/.*\\u0000$",
|
||||||
|
"^[^.].*\\u0000$",
|
||||||
|
"^\\..*\\u0000$",
|
||||||
|
],
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
"simple-import-sort/exports": "error",
|
||||||
|
"import/first": "error",
|
||||||
|
"import/newline-after-import": "error",
|
||||||
|
|
||||||
|
"import/no-duplicates": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"prefer-inline": true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
"@typescript-eslint/consistent-type-imports": "error",
|
||||||
|
|
||||||
|
"@typescript-eslint/no-unused-vars": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
args: "all",
|
||||||
|
argsIgnorePattern: "^_",
|
||||||
|
caughtErrors: "all",
|
||||||
|
caughtErrorsIgnorePattern: "^_",
|
||||||
|
destructuredArrayIgnorePattern: "^_",
|
||||||
|
varsIgnorePattern: "^_",
|
||||||
|
ignoreRestSiblings: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
|
||||||
|
"formatjs/enforce-default-message": ["error", "literal"],
|
||||||
|
"formatjs/enforce-placeholders": ["error"],
|
||||||
|
"formatjs/enforce-plural-rules": ["error"],
|
||||||
|
"formatjs/no-literal-string-in-jsx": ["error"],
|
||||||
|
"formatjs/no-multiple-whitespaces": ["error"],
|
||||||
|
"formatjs/no-multiple-plurals": ["error"],
|
||||||
|
"formatjs/no-invalid-icu": ["error"],
|
||||||
|
"formatjs/no-id": ["error"],
|
||||||
|
"formatjs/no-complex-selectors": ["error"],
|
||||||
|
"formatjs/no-useless-message": ["error"],
|
||||||
|
"formatjs/prefer-pound-in-plural": ["error"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
])
|
||||||
@@ -114,6 +114,9 @@
|
|||||||
"zustand": "^4.5.2"
|
"zustand": "^4.5.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@eslint/compat": "^1.2.9",
|
||||||
|
"@eslint/eslintrc": "^3.3.1",
|
||||||
|
"@eslint/js": "^9.26.0",
|
||||||
"@formatjs/cli": "^6.7.1",
|
"@formatjs/cli": "^6.7.1",
|
||||||
"@lokalise/node-api": "^14.0.0",
|
"@lokalise/node-api": "^14.0.0",
|
||||||
"@scandic-hotels/typescript-config": "workspace:*",
|
"@scandic-hotels/typescript-config": "workspace:*",
|
||||||
@@ -134,7 +137,7 @@
|
|||||||
"adm-zip": "^0.5.16",
|
"adm-zip": "^0.5.16",
|
||||||
"cypress": "^14.3.3",
|
"cypress": "^14.3.3",
|
||||||
"dotenv": "^16.5.0",
|
"dotenv": "^16.5.0",
|
||||||
"eslint": "^8",
|
"eslint": "^9",
|
||||||
"eslint-config-next": "15.3.2",
|
"eslint-config-next": "15.3.2",
|
||||||
"eslint-plugin-formatjs": "^5.3.1",
|
"eslint-plugin-formatjs": "^5.3.1",
|
||||||
"eslint-plugin-import": "^2.31.0",
|
"eslint-plugin-import": "^2.31.0",
|
||||||
|
|||||||
@@ -9,6 +9,9 @@
|
|||||||
},
|
},
|
||||||
"test": {
|
"test": {
|
||||||
"dependsOn": ["@scandic-hotels/design-system#build"]
|
"dependsOn": ["@scandic-hotels/design-system#build"]
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"dependsOn": ["@scandic-hotels/design-system#build"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
|
import type { JSX } from "react"
|
||||||
|
|
||||||
import type { MembershipLevel } from "@/constants/membershipLevels"
|
import type { MembershipLevel } from "@/constants/membershipLevels"
|
||||||
import type { LoyaltyLevel } from "@/server/routers/contentstack/loyaltyLevel/output"
|
import type { LoyaltyLevel } from "@/server/routers/contentstack/loyaltyLevel/output"
|
||||||
import type { CMSReward } from "../trpc/routers/contentstack/reward"
|
import type { CMSReward } from "../trpc/routers/contentstack/reward"
|
||||||
|
|
||||||
import type { JSX } from "react";
|
|
||||||
|
|
||||||
export type OverviewTableClientProps = {
|
export type OverviewTableClientProps = {
|
||||||
activeMembership: MembershipLevel | null
|
activeMembership: MembershipLevel | null
|
||||||
levels: ComparisonLevel[]
|
levels: ComparisonLevel[]
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { RTETypeEnum } from "./enums"
|
import type { JSX } from "react"
|
||||||
|
|
||||||
import type { EmbedByUid } from "../components/deprecatedjsontohtml"
|
import type { EmbedByUid } from "../components/deprecatedjsontohtml"
|
||||||
import type {
|
import type {
|
||||||
@@ -8,10 +8,9 @@ import type {
|
|||||||
RTEImageVaultAttrs,
|
RTEImageVaultAttrs,
|
||||||
RTELinkAttrs,
|
RTELinkAttrs,
|
||||||
} from "./attrs"
|
} from "./attrs"
|
||||||
|
import type { RTETypeEnum } from "./enums"
|
||||||
import type { RenderOptions } from "./option"
|
import type { RenderOptions } from "./option"
|
||||||
|
|
||||||
import type { JSX } from "react";
|
|
||||||
|
|
||||||
export interface RTEDefaultNode {
|
export interface RTEDefaultNode {
|
||||||
attrs: Attributes
|
attrs: Attributes
|
||||||
children: RTENode[]
|
children: RTENode[]
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import type { JSX } from "react"
|
||||||
|
|
||||||
import type { EmbedByUid } from "../jsontohtml"
|
import type { EmbedByUid } from "../jsontohtml"
|
||||||
import type {
|
import type {
|
||||||
Attributes,
|
Attributes,
|
||||||
@@ -9,8 +11,6 @@ import type {
|
|||||||
import type { RTETypeEnum } from "./enums"
|
import type { RTETypeEnum } from "./enums"
|
||||||
import type { RenderOptions } from "./option"
|
import type { RenderOptions } from "./option"
|
||||||
|
|
||||||
import type { JSX } from "react";
|
|
||||||
|
|
||||||
export interface RTEDefaultNode {
|
export interface RTEDefaultNode {
|
||||||
attrs: Attributes
|
attrs: Attributes
|
||||||
children: RTENode[]
|
children: RTENode[]
|
||||||
|
|||||||
16
biome.jsonc
16
biome.jsonc
@@ -1,16 +0,0 @@
|
|||||||
{
|
|
||||||
"linter": {
|
|
||||||
"enabled": false,
|
|
||||||
"rules": {
|
|
||||||
"recommended": true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"overrides": [
|
|
||||||
{
|
|
||||||
"include": ["apps/redis-api/**"],
|
|
||||||
"linter": {
|
|
||||||
"enabled": true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}
|
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
"packages/*"
|
"packages/*"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@eslint/compat": "^1.2.9",
|
||||||
"@types/react": "19.1.0",
|
"@types/react": "19.1.0",
|
||||||
"@types/react-dom": "19.1.0",
|
"@types/react-dom": "19.1.0",
|
||||||
"husky": "^9.1.7",
|
"husky": "^9.1.7",
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
root: true,
|
|
||||||
env: { browser: true, es2020: true },
|
|
||||||
extends: [
|
|
||||||
'eslint:recommended',
|
|
||||||
'plugin:@typescript-eslint/recommended',
|
|
||||||
'plugin:react-hooks/recommended',
|
|
||||||
'plugin:storybook/recommended',
|
|
||||||
],
|
|
||||||
ignorePatterns: ['dist', '.eslintrc.cjs'],
|
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
plugins: ['react-refresh'],
|
|
||||||
rules: {
|
|
||||||
'react-refresh/only-export-components': [
|
|
||||||
'warn',
|
|
||||||
{ allowConstantExport: true },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
@@ -16,6 +16,6 @@ const config: StorybookConfig = {
|
|||||||
}
|
}
|
||||||
export default config
|
export default config
|
||||||
|
|
||||||
function getAbsolutePath(value: string): any {
|
function getAbsolutePath(value: string) {
|
||||||
return dirname(require.resolve(join(value, 'package.json')))
|
return dirname(require.resolve(join(value, 'package.json')))
|
||||||
}
|
}
|
||||||
|
|||||||
40
packages/design-system/eslint.config.mjs
Normal file
40
packages/design-system/eslint.config.mjs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { defineConfig, globalIgnores } from 'eslint/config'
|
||||||
|
import globals from 'globals'
|
||||||
|
import tsParser from '@typescript-eslint/parser'
|
||||||
|
import reactRefresh from 'eslint-plugin-react-refresh'
|
||||||
|
import { FlatCompat } from '@eslint/eslintrc'
|
||||||
|
import js from '@eslint/js'
|
||||||
|
|
||||||
|
const compat = new FlatCompat({
|
||||||
|
recommendedConfig: js.configs.recommended,
|
||||||
|
allConfig: js.configs.all,
|
||||||
|
})
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
{
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
...globals.browser,
|
||||||
|
},
|
||||||
|
parser: tsParser,
|
||||||
|
},
|
||||||
|
extends: compat.extends(
|
||||||
|
'eslint:recommended',
|
||||||
|
'plugin:@typescript-eslint/recommended',
|
||||||
|
'plugin:react-hooks/recommended',
|
||||||
|
'plugin:storybook/recommended'
|
||||||
|
),
|
||||||
|
plugins: {
|
||||||
|
'react-refresh': reactRefresh,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
'react-refresh/only-export-components': [
|
||||||
|
'warn',
|
||||||
|
{
|
||||||
|
allowConstantExport: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
globalIgnores(['**/dist', '**/.eslintrc.cjs']),
|
||||||
|
])
|
||||||
@@ -134,6 +134,8 @@
|
|||||||
"react-dom": "^19.1.0"
|
"react-dom": "^19.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@eslint/eslintrc": "^3.3.1",
|
||||||
|
"@eslint/js": "^9.26.0",
|
||||||
"@storybook/addon-essentials": "^8.6.12",
|
"@storybook/addon-essentials": "^8.6.12",
|
||||||
"@storybook/addon-interactions": "^8.6.12",
|
"@storybook/addon-interactions": "^8.6.12",
|
||||||
"@storybook/addon-links": "^8.6.12",
|
"@storybook/addon-links": "^8.6.12",
|
||||||
@@ -153,11 +155,12 @@
|
|||||||
"colord": "^2.9.3",
|
"colord": "^2.9.3",
|
||||||
"copy-to-clipboard": "^3.3.3",
|
"copy-to-clipboard": "^3.3.3",
|
||||||
"deepmerge-ts": "^7.1.5",
|
"deepmerge-ts": "^7.1.5",
|
||||||
"eslint": "^8",
|
"eslint": "^9",
|
||||||
"eslint-plugin-react-hooks": "^5.2.0",
|
"eslint-plugin-react-hooks": "^5.2.0",
|
||||||
"eslint-plugin-react-refresh": "^0.4.20",
|
"eslint-plugin-react-refresh": "^0.4.20",
|
||||||
"eslint-plugin-storybook": "^0.12.0",
|
"eslint-plugin-storybook": "^0.12.0",
|
||||||
"glob": "^11.0.2",
|
"glob": "^11.0.2",
|
||||||
|
"globals": "^16.1.0",
|
||||||
"husky": "^9.1.7",
|
"husky": "^9.1.7",
|
||||||
"jiti": "^1.21.0",
|
"jiti": "^1.21.0",
|
||||||
"lint-staged": "^15.5.2",
|
"lint-staged": "^15.5.2",
|
||||||
|
|||||||
Reference in New Issue
Block a user