feat(onboarding): add initial onboarding module with domain and persistence layers
- Created package.json for onboarding module with dependencies and scripts. - Implemented InitialOnboarding aggregate with validation and state management. - Added Sequelize model for initial onboarding with appropriate attributes and validations. - Developed mappers for converting between domain and persistence models. - Included tests for aggregate behavior and Sequelize model validation. - Configured TypeScript settings for the onboarding module.
This commit is contained in:
parent
1065311deb
commit
2f23d75b6f
61
modules/onboarding/package.json
Normal file
61
modules/onboarding/package.json
Normal file
@ -0,0 +1,61 @@
|
||||
{
|
||||
"name": "@erp/onboarding",
|
||||
"version": "0.10.8",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"typecheck": "tsc -p tsconfig.json --noEmit",
|
||||
"check": "biome check .",
|
||||
"lint": "biome lint .",
|
||||
"clean": "rimraf .turbo node_modules dist"
|
||||
},
|
||||
"exports": {
|
||||
".": "./src/common/index.ts",
|
||||
"./common": "./src/common/index.ts",
|
||||
"./api": "./src/api/index.ts",
|
||||
"./api/domain": "./src/api/domain/index.ts",
|
||||
"./client": "./src/web/manifest.ts",
|
||||
"./globals.css": "./src/web/globals.css",
|
||||
"./components": "./src/web/components/index.ts"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^19.2.5",
|
||||
"react-dom": "^19.2.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@erp/auth": "workspace:*",
|
||||
"@erp/core": "workspace:*",
|
||||
"@erp/identity": "workspace:*",
|
||||
"@hookform/resolvers": "^5.2.2",
|
||||
"@repo/i18next": "workspace:*",
|
||||
"@repo/rdx-audit": "workspace:*",
|
||||
"@repo/rdx-criteria": "workspace:*",
|
||||
"@repo/rdx-ddd": "workspace:*",
|
||||
"@repo/rdx-logger": "workspace:*",
|
||||
"@repo/rdx-ui": "workspace:*",
|
||||
"@repo/rdx-utils": "workspace:*",
|
||||
"@repo/shadcn-ui": "workspace:*",
|
||||
"@tanstack/react-query": "^5.98.0",
|
||||
"@tanstack/react-table": "^8.21.3",
|
||||
"express": "^4.22.1",
|
||||
"lucide-react": "^1.8.0",
|
||||
"react-hook-form": "^7.72.1",
|
||||
"react-i18next": "^17.0.2",
|
||||
"react-router-dom": "^7.14.0",
|
||||
"sequelize": "^6.37.8",
|
||||
"use-debounce": "^10.1.1",
|
||||
"zod": "^4.3.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/jest": "^30.0.0",
|
||||
"@types/node": "^25.9.1",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"react": "^19.2.5",
|
||||
"react-dom": "^19.2.5",
|
||||
"rimraf": "^6.1.3",
|
||||
"typescript": "^6.0.2"
|
||||
}
|
||||
}
|
||||
1
modules/onboarding/src/api/domain/index.ts
Normal file
1
modules/onboarding/src/api/domain/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from "./initial-onboarding";
|
||||
@ -0,0 +1 @@
|
||||
export * from "./initial-onboarding.aggregate";
|
||||
@ -0,0 +1,72 @@
|
||||
import { test } from "node:test";
|
||||
|
||||
import { UniqueID, UtcDateTime } from "@repo/rdx-ddd";
|
||||
import { Maybe } from "@repo/rdx-utils";
|
||||
|
||||
import { InitialOnboarding } from "./initial-onboarding.aggregate";
|
||||
|
||||
const check = (value: unknown) => {
|
||||
if (!value) throw new Error("Assertion failed");
|
||||
};
|
||||
|
||||
const date = () => UtcDateTime.now();
|
||||
const props = (
|
||||
status: "pending" | "completed",
|
||||
companyId = Maybe.none<UniqueID>(),
|
||||
completedAt = Maybe.none<UtcDateTime>()
|
||||
) => ({
|
||||
accountId: UniqueID.generateNewID(),
|
||||
status,
|
||||
companyId,
|
||||
createdAt: date(),
|
||||
updatedAt: date(),
|
||||
completedAt,
|
||||
});
|
||||
test("creates pending", () => {
|
||||
const accountId = UniqueID.generateNewID();
|
||||
const r = InitialOnboarding.createPending(accountId);
|
||||
check(r.isSuccess);
|
||||
check(r.data.status === "pending");
|
||||
check(r.data.companyId.isNone());
|
||||
check(r.data.completedAt.isNone());
|
||||
check(r.data.accountId.equals(accountId));
|
||||
});
|
||||
test("rehydrates valid states", () => {
|
||||
check(InitialOnboarding.rehydrate(props("pending"), UniqueID.generateNewID()).isSuccess);
|
||||
check(
|
||||
InitialOnboarding.rehydrate(
|
||||
props("completed", Maybe.some(UniqueID.generateNewID()), Maybe.some(date())),
|
||||
UniqueID.generateNewID()
|
||||
).isSuccess
|
||||
);
|
||||
});
|
||||
test("rejects invalid state combinations", () => {
|
||||
check(
|
||||
InitialOnboarding.rehydrate(
|
||||
props("pending", Maybe.some(UniqueID.generateNewID())),
|
||||
UniqueID.generateNewID()
|
||||
).isFailure
|
||||
);
|
||||
check(
|
||||
InitialOnboarding.rehydrate(
|
||||
props("pending", Maybe.none<UniqueID>(), Maybe.some(date())),
|
||||
UniqueID.generateNewID()
|
||||
).isFailure
|
||||
);
|
||||
check(InitialOnboarding.rehydrate(props("completed"), UniqueID.generateNewID()).isFailure);
|
||||
check(
|
||||
InitialOnboarding.rehydrate(
|
||||
props("completed", Maybe.some(UniqueID.generateNewID())),
|
||||
UniqueID.generateNewID()
|
||||
).isFailure
|
||||
);
|
||||
});
|
||||
test("completes once", () => {
|
||||
const o = InitialOnboarding.createPending(UniqueID.generateNewID()).data;
|
||||
const id = UniqueID.generateNewID();
|
||||
check(o.complete({ companyId: id, completedAt: date(), updatedAt: date() }).isSuccess);
|
||||
check(o.status === "completed");
|
||||
check(o.companyId.unwrap().equals(id));
|
||||
check(o.completedAt.isSome());
|
||||
check(o.complete({ companyId: id, completedAt: date(), updatedAt: date() }).isFailure);
|
||||
});
|
||||
@ -0,0 +1,79 @@
|
||||
import { AggregateRoot, UniqueID, type UtcDateTime } from "@repo/rdx-ddd";
|
||||
import { Maybe, Result } from "@repo/rdx-utils";
|
||||
|
||||
export type InitialOnboardingStatus = "pending" | "completed";
|
||||
export interface InitialOnboardingProps {
|
||||
accountId: UniqueID;
|
||||
status: InitialOnboardingStatus;
|
||||
companyId: Maybe<UniqueID>;
|
||||
completedAt: Maybe<UtcDateTime>;
|
||||
}
|
||||
export class InitialOnboarding extends AggregateRoot<InitialOnboardingProps> {
|
||||
private static validate(props: InitialOnboardingProps): Result<void, Error> {
|
||||
const valid =
|
||||
props.status === "pending"
|
||||
? props.companyId.isNone() && props.completedAt.isNone()
|
||||
: props.companyId.isSome() && props.completedAt.isSome();
|
||||
return valid
|
||||
? Result.ok(undefined)
|
||||
: Result.fail(new Error("Invalid initial onboarding state."));
|
||||
}
|
||||
|
||||
static createPending(accountId: UniqueID): Result<InitialOnboarding, Error> {
|
||||
return InitialOnboarding.rehydrate(
|
||||
{
|
||||
accountId,
|
||||
status: "pending",
|
||||
companyId: Maybe.none(),
|
||||
completedAt: Maybe.none(),
|
||||
},
|
||||
UniqueID.generateNewID()
|
||||
);
|
||||
}
|
||||
|
||||
static rehydrate(props: InitialOnboardingProps, id: UniqueID): Result<InitialOnboarding, Error> {
|
||||
const valid = InitialOnboarding.validate(props);
|
||||
return valid.isFailure ? Result.fail(valid.error) : Result.ok(new InitialOnboarding(props, id));
|
||||
}
|
||||
|
||||
complete(params: {
|
||||
companyId: UniqueID;
|
||||
completedAt: UtcDateTime;
|
||||
updatedAt: UtcDateTime;
|
||||
}): Result<void, Error> {
|
||||
if (this.props.status === "completed")
|
||||
return Result.fail(new Error("Initial onboarding already completed."));
|
||||
|
||||
const props = {
|
||||
...this.props,
|
||||
status: "completed" as const,
|
||||
companyId: Maybe.some(params.companyId),
|
||||
completedAt: Maybe.some(params.completedAt),
|
||||
updatedAt: params.updatedAt,
|
||||
};
|
||||
|
||||
const valid = InitialOnboarding.validate(props);
|
||||
|
||||
if (valid.isFailure) {
|
||||
return Result.fail(valid.error);
|
||||
}
|
||||
this.props = props;
|
||||
return Result.ok(undefined);
|
||||
}
|
||||
|
||||
get accountId() {
|
||||
return this.props.accountId;
|
||||
}
|
||||
|
||||
get status() {
|
||||
return this.props.status;
|
||||
}
|
||||
|
||||
get companyId() {
|
||||
return this.props.companyId;
|
||||
}
|
||||
|
||||
get completedAt() {
|
||||
return this.props.completedAt;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
import initialOnboardingModelInit from "./models/sequelize-initial-onboarding.model";
|
||||
|
||||
export * from "./mappers";
|
||||
export * from "./models";
|
||||
|
||||
export const models = [initialOnboardingModelInit];
|
||||
@ -0,0 +1 @@
|
||||
export * from "./sequelize-initial-onboarding-domain.mapper";
|
||||
@ -0,0 +1,142 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
|
||||
import { UniqueID, UtcDateTime } from "@repo/rdx-ddd";
|
||||
import { Maybe } from "@repo/rdx-utils";
|
||||
import type { InferAttributes } from "sequelize";
|
||||
import { Sequelize } from "sequelize";
|
||||
|
||||
import type { InitialOnboardingStatus } from "../../../../domain";
|
||||
import { InitialOnboarding } from "../../../../domain";
|
||||
import initialOnboardingModelInit, {
|
||||
InitialOnboardingModel,
|
||||
} from "../models/sequelize-initial-onboarding.model";
|
||||
|
||||
import { SequelizeInitialOnboardingDomainMapper } from "./sequelize-initial-onboarding-domain.mapper";
|
||||
|
||||
const database = new Sequelize("mysql://root:pass@localhost:3306/erp_test", { logging: false });
|
||||
initialOnboardingModelInit(database);
|
||||
const mapper = new SequelizeInitialOnboardingDomainMapper();
|
||||
const id = "11111111-1111-4111-8111-111111111111";
|
||||
const accountId = "22222222-2222-4222-8222-222222222222";
|
||||
const companyId = "33333333-3333-4333-8333-333333333333";
|
||||
const completedAt = "2026-01-02T10:30:00.789Z";
|
||||
|
||||
function aggregate(status: InitialOnboardingStatus) {
|
||||
const result = InitialOnboarding.rehydrate(
|
||||
{
|
||||
accountId: UniqueID.create(accountId).data,
|
||||
status,
|
||||
companyId:
|
||||
status === "completed" ? Maybe.some(UniqueID.create(companyId).data) : Maybe.none(),
|
||||
|
||||
completedAt:
|
||||
status === "completed"
|
||||
? Maybe.some(UtcDateTime.createFromISO(completedAt).data)
|
||||
: Maybe.none(),
|
||||
},
|
||||
UniqueID.create(id).data
|
||||
);
|
||||
assert.equal(result.isSuccess, true);
|
||||
return result.data;
|
||||
}
|
||||
|
||||
function row(patch: Partial<InferAttributes<InitialOnboardingModel>> = {}) {
|
||||
return InitialOnboardingModel.build(
|
||||
{
|
||||
id,
|
||||
account_id: accountId,
|
||||
status: "pending",
|
||||
company_id: null,
|
||||
completed_at: null,
|
||||
...patch,
|
||||
},
|
||||
{ raw: true }
|
||||
);
|
||||
}
|
||||
|
||||
for (const status of ["pending", "completed"] as const) {
|
||||
test(`toPersistence ${status}`, () => {
|
||||
const result = mapper.mapToPersistence(aggregate(status));
|
||||
assert.equal(result.isSuccess, true);
|
||||
assert.deepEqual(result.data, {
|
||||
id,
|
||||
account_id: accountId,
|
||||
status,
|
||||
company_id: status === "completed" ? companyId : null,
|
||||
completed_at: status === "completed" ? completedAt : null,
|
||||
});
|
||||
});
|
||||
|
||||
test(`toDomain ${status}`, () => {
|
||||
const result = mapper.mapToDomain(
|
||||
row({
|
||||
status,
|
||||
company_id: status === "completed" ? companyId : null,
|
||||
completed_at: status === "completed" ? completedAt : null,
|
||||
})
|
||||
);
|
||||
assert.equal(result.isSuccess, true);
|
||||
const value = result.data;
|
||||
assert.ok(value instanceof InitialOnboarding);
|
||||
assert.ok(value.id instanceof UniqueID);
|
||||
assert.equal(value.id.toPrimitive(), id);
|
||||
assert.equal(value.accountId.toPrimitive(), accountId);
|
||||
assert.equal(value.status, status);
|
||||
assert.equal(value.companyId.isSome(), status === "completed");
|
||||
assert.equal(value.completedAt.isSome(), status === "completed");
|
||||
if (status === "completed") {
|
||||
assert.ok(value.companyId.unwrap() instanceof UniqueID);
|
||||
assert.ok(value.completedAt.unwrap() instanceof UtcDateTime);
|
||||
assert.equal(value.companyId.unwrap().toPrimitive(), companyId);
|
||||
assert.equal(value.completedAt.unwrap().toISOString(), completedAt);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const invalidStates: [string, Partial<InferAttributes<InitialOnboardingModel>>][] = [
|
||||
["pending + companyId", { company_id: companyId }],
|
||||
["pending + completedAt", { completed_at: completedAt }],
|
||||
["completed sin companyId", { status: "completed", completed_at: completedAt }],
|
||||
["completed sin completedAt", { status: "completed", company_id: companyId }],
|
||||
];
|
||||
for (const [name, patch] of invalidStates) {
|
||||
test(name, () => {
|
||||
const result = mapper.mapToDomain(row(patch));
|
||||
assert.equal(result.isFailure, true);
|
||||
assert.equal(result.error.message, "Invalid initial onboarding persistence state.");
|
||||
});
|
||||
}
|
||||
|
||||
test("toDomain accepts Sequelize Date timestamps and preserves UTC milliseconds", () => {
|
||||
const result = mapper.mapToDomain(
|
||||
row({
|
||||
status: "completed",
|
||||
company_id: companyId,
|
||||
completed_at: new Date(completedAt),
|
||||
})
|
||||
);
|
||||
assert.equal(result.isSuccess, true);
|
||||
assert.equal(result.data.completedAt.unwrap().toISOString(), completedAt);
|
||||
});
|
||||
|
||||
test("toDomain rejects an unknown status explicitly", () => {
|
||||
const result = mapper.mapToDomain(
|
||||
row({ status: "unknown", company_id: companyId, completed_at: completedAt })
|
||||
);
|
||||
assert.equal(result.isFailure, true);
|
||||
assert.equal(result.error.message, "Invalid initial onboarding persistence status.");
|
||||
});
|
||||
|
||||
test("toDomain propagates invalid identifiers and timestamps as failures", () => {
|
||||
for (const patch of [
|
||||
{ id: "invalid" },
|
||||
{ account_id: "invalid" },
|
||||
{ status: "completed", company_id: "invalid", completed_at: completedAt },
|
||||
{ created_at: "invalid" },
|
||||
{ updated_at: "invalid" },
|
||||
{ status: "completed", company_id: companyId, completed_at: "invalid" },
|
||||
]) {
|
||||
assert.equal(mapper.mapToDomain(row(patch)).isFailure, true);
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,62 @@
|
||||
import { UniqueID, UtcDateTime, maybeFromNullableResult, maybeToNullable } from "@repo/rdx-ddd";
|
||||
import { Result } from "@repo/rdx-utils";
|
||||
|
||||
import { InitialOnboarding } from "../../../../domain";
|
||||
import type { InitialOnboardingCreationAttributes, InitialOnboardingModel } from "../models";
|
||||
|
||||
function toUtcDateTime(value: Date | string): Result<UtcDateTime, Error> {
|
||||
try {
|
||||
return UtcDateTime.createFromISO(value instanceof Date ? value.toISOString() : value);
|
||||
} catch (error: unknown) {
|
||||
return Result.fail(error instanceof Error ? error : new Error(String(error)));
|
||||
}
|
||||
}
|
||||
|
||||
export class SequelizeInitialOnboardingDomainMapper {
|
||||
public mapToDomain(source: InitialOnboardingModel): Result<InitialOnboarding, Error> {
|
||||
if (source.status !== "pending" && source.status !== "completed") {
|
||||
return Result.fail(new Error("Invalid initial onboarding persistence status."));
|
||||
}
|
||||
if (
|
||||
(source.status === "pending" &&
|
||||
(source.company_id !== null || source.completed_at !== null)) ||
|
||||
(source.status === "completed" &&
|
||||
(source.company_id === null || source.completed_at === null))
|
||||
) {
|
||||
return Result.fail(new Error("Invalid initial onboarding persistence state."));
|
||||
}
|
||||
|
||||
const id = UniqueID.create(source.id);
|
||||
if (id.isFailure) return Result.fail(id.error);
|
||||
const accountId = UniqueID.create(source.account_id);
|
||||
if (accountId.isFailure) return Result.fail(accountId.error);
|
||||
const companyId = maybeFromNullableResult(source.company_id, (value) => UniqueID.create(value));
|
||||
if (companyId.isFailure) return Result.fail(companyId.error);
|
||||
const completedAt = maybeFromNullableResult(source.completed_at, (value) =>
|
||||
toUtcDateTime(value)
|
||||
);
|
||||
if (completedAt.isFailure) return Result.fail(completedAt.error);
|
||||
|
||||
return InitialOnboarding.rehydrate(
|
||||
{
|
||||
accountId: accountId.data,
|
||||
status: source.status,
|
||||
companyId: companyId.data,
|
||||
completedAt: completedAt.data,
|
||||
},
|
||||
id.data
|
||||
);
|
||||
}
|
||||
|
||||
public mapToPersistence(
|
||||
source: InitialOnboarding
|
||||
): Result<InitialOnboardingCreationAttributes, Error> {
|
||||
return Result.ok({
|
||||
id: source.id.toPrimitive(),
|
||||
account_id: source.accountId.toPrimitive(),
|
||||
status: source.status,
|
||||
company_id: maybeToNullable(source.companyId, (value) => value.toPrimitive()),
|
||||
completed_at: maybeToNullable(source.completedAt, (value) => value.toISOString()),
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
export * from "./sequelize-initial-onboarding.model";
|
||||
@ -0,0 +1,64 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
|
||||
import { DataTypes, Sequelize } from "sequelize";
|
||||
|
||||
import initialOnboardingModelInit, {
|
||||
InitialOnboardingModel,
|
||||
} from "./sequelize-initial-onboarding.model";
|
||||
|
||||
const database = new Sequelize("mysql://root:pass@localhost:3306/erp_test", { logging: false });
|
||||
initialOnboardingModelInit(database);
|
||||
|
||||
test("model declares table, nullability, UUIDs, timestamps and unique account without cross-module FKs", () => {
|
||||
assert.equal(InitialOnboardingModel.getTableName(), "initial_onboardings");
|
||||
assert.equal(InitialOnboardingModel.options.timestamps, false);
|
||||
const attributes = InitialOnboardingModel.getAttributes();
|
||||
assert.deepEqual(Object.keys(attributes).sort(), [
|
||||
"account_id",
|
||||
"company_id",
|
||||
"completed_at",
|
||||
"created_at",
|
||||
"id",
|
||||
"status",
|
||||
"updated_at",
|
||||
]);
|
||||
for (const key of ["id", "account_id", "status", "created_at", "updated_at"] as const) {
|
||||
assert.equal(attributes[key].allowNull, false);
|
||||
}
|
||||
for (const key of ["company_id", "completed_at"] as const) {
|
||||
assert.equal(attributes[key].allowNull, true);
|
||||
}
|
||||
for (const key of ["id", "account_id", "company_id"] as const) {
|
||||
assert.ok(attributes[key].type instanceof DataTypes.UUID);
|
||||
assert.equal(attributes[key].references, undefined);
|
||||
}
|
||||
for (const key of ["created_at", "updated_at", "completed_at"] as const) {
|
||||
assert.ok(attributes[key].type instanceof DataTypes.DATE);
|
||||
}
|
||||
assert.ok(attributes.status.type instanceof DataTypes.STRING);
|
||||
assert.equal(attributes.id.primaryKey, true);
|
||||
const unique = InitialOnboardingModel.options.indexes?.find(
|
||||
(index) => index.name === "uq_initial_onboardings_account_id"
|
||||
);
|
||||
assert.equal(unique?.unique, true);
|
||||
assert.deepEqual(unique?.fields, ["account_id"]);
|
||||
});
|
||||
|
||||
test("model validation accepts only pending and completed", async () => {
|
||||
for (const status of ["pending", "completed", "processing", "failed", "cancelled", "draft"]) {
|
||||
const model = InitialOnboardingModel.build({
|
||||
id: "11111111-1111-4111-8111-111111111111",
|
||||
account_id: "22222222-2222-4222-8222-222222222222",
|
||||
status,
|
||||
});
|
||||
if (status === "pending" || status === "completed") {
|
||||
await model.validate({ fields: ["status"] });
|
||||
} else {
|
||||
await assert.rejects(
|
||||
model.validate({ fields: ["status"] }),
|
||||
/Validation isIn on status failed/
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,49 @@
|
||||
import type { InferAttributes, InferCreationAttributes, Sequelize } from "sequelize";
|
||||
import { DataTypes, Model } from "sequelize";
|
||||
|
||||
export type InitialOnboardingCreationAttributes = InferCreationAttributes<InitialOnboardingModel>;
|
||||
|
||||
export class InitialOnboardingModel extends Model<
|
||||
InferAttributes<InitialOnboardingModel>,
|
||||
InferCreationAttributes<InitialOnboardingModel>
|
||||
> {
|
||||
declare id: string;
|
||||
declare account_id: string;
|
||||
declare status: string;
|
||||
declare company_id: string | null;
|
||||
declare completed_at: Date | string | null;
|
||||
}
|
||||
|
||||
export default (database: Sequelize) => {
|
||||
InitialOnboardingModel.init(
|
||||
{
|
||||
id: { type: DataTypes.UUID, primaryKey: true, allowNull: false },
|
||||
// Referencias lógicas entre módulos, sin dependencias de sus modelos ORM.
|
||||
account_id: { type: DataTypes.UUID, allowNull: false },
|
||||
status: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
validate: { isIn: [["pending", "completed"]] },
|
||||
},
|
||||
company_id: { type: DataTypes.UUID, allowNull: true, defaultValue: null },
|
||||
completed_at: { type: DataTypes.DATE, allowNull: true, defaultValue: null },
|
||||
},
|
||||
{
|
||||
sequelize: database,
|
||||
modelName: "InitialOnboardingModel",
|
||||
tableName: "initial_onboardings",
|
||||
charset: "utf8mb4",
|
||||
collate: "utf8mb4_unicode_ci",
|
||||
underscored: true,
|
||||
timestamps: true,
|
||||
indexes: [
|
||||
{
|
||||
name: "uq_initial_onboardings_account_id",
|
||||
fields: ["account_id"],
|
||||
unique: true,
|
||||
},
|
||||
],
|
||||
}
|
||||
);
|
||||
return InitialOnboardingModel;
|
||||
};
|
||||
28
modules/onboarding/tsconfig.json
Normal file
28
modules/onboarding/tsconfig.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@erp/onboarding/*": ["./src/*"]
|
||||
},
|
||||
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
||||
"target": "ES2022",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["ES2022"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"isolatedModules": true,
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUncheckedSideEffectImports": true,
|
||||
"types": ["jest", "node"]
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
332
pnpm-lock.yaml
332
pnpm-lock.yaml
@ -1213,6 +1213,103 @@ importers:
|
||||
specifier: ^6.0.2
|
||||
version: 6.0.2
|
||||
|
||||
modules/onboarding:
|
||||
dependencies:
|
||||
'@erp/auth':
|
||||
specifier: workspace:*
|
||||
version: link:../auth
|
||||
'@erp/core':
|
||||
specifier: workspace:*
|
||||
version: link:../core
|
||||
'@erp/identity':
|
||||
specifier: workspace:*
|
||||
version: link:../identity
|
||||
'@hookform/resolvers':
|
||||
specifier: ^5.2.2
|
||||
version: 5.4.0(react-hook-form@7.76.1(react@19.2.6))
|
||||
'@repo/i18next':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/i18n
|
||||
'@repo/rdx-audit':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/rdx-audit
|
||||
'@repo/rdx-criteria':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/rdx-criteria
|
||||
'@repo/rdx-ddd':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/rdx-ddd
|
||||
'@repo/rdx-logger':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/rdx-logger
|
||||
'@repo/rdx-ui':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/rdx-ui
|
||||
'@repo/rdx-utils':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/rdx-utils
|
||||
'@repo/shadcn-ui':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/shadcn-ui
|
||||
'@tanstack/react-query':
|
||||
specifier: ^5.98.0
|
||||
version: 5.100.14(react@19.2.6)
|
||||
'@tanstack/react-table':
|
||||
specifier: ^8.21.3
|
||||
version: 8.21.3(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
express:
|
||||
specifier: ^4.22.1
|
||||
version: 4.22.2(supports-color@7.2.0)
|
||||
lucide-react:
|
||||
specifier: ^1.8.0
|
||||
version: 1.16.0(react@19.2.6)
|
||||
react-hook-form:
|
||||
specifier: ^7.72.1
|
||||
version: 7.76.1(react@19.2.6)
|
||||
react-i18next:
|
||||
specifier: ^17.0.2
|
||||
version: 17.0.8(i18next@26.4.0(typescript@6.0.2))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@6.0.2)
|
||||
react-router-dom:
|
||||
specifier: ^7.14.0
|
||||
version: 7.15.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
sequelize:
|
||||
specifier: ^6.37.8
|
||||
version: 6.37.8(mysql2@3.22.3(@types/node@25.9.1))(pg-hstore@2.3.4)(supports-color@7.2.0)
|
||||
use-debounce:
|
||||
specifier: ^10.1.1
|
||||
version: 10.1.1(react@19.2.6)
|
||||
zod:
|
||||
specifier: ^4.3.6
|
||||
version: 4.4.3
|
||||
devDependencies:
|
||||
'@types/express':
|
||||
specifier: ^4.17.21
|
||||
version: 4.17.25
|
||||
'@types/jest':
|
||||
specifier: ^30.0.0
|
||||
version: 30.0.0
|
||||
'@types/node':
|
||||
specifier: ^25.9.1
|
||||
version: 25.9.1
|
||||
'@types/react':
|
||||
specifier: ^19.2.14
|
||||
version: 19.2.15
|
||||
'@types/react-router-dom':
|
||||
specifier: ^5.3.3
|
||||
version: 5.3.3
|
||||
react:
|
||||
specifier: ^19.2.5
|
||||
version: 19.2.6
|
||||
react-dom:
|
||||
specifier: ^19.2.5
|
||||
version: 19.2.6(react@19.2.6)
|
||||
rimraf:
|
||||
specifier: ^6.1.3
|
||||
version: 6.1.3
|
||||
typescript:
|
||||
specifier: ^6.0.2
|
||||
version: 6.0.2
|
||||
|
||||
modules/supplier-invoices:
|
||||
dependencies:
|
||||
'@erp/auth':
|
||||
@ -2773,6 +2870,30 @@ packages:
|
||||
'@types/node':
|
||||
optional: true
|
||||
|
||||
'@jest/diff-sequences@30.5.0':
|
||||
resolution: {integrity: sha512-OsqBjHXCn8cadasoAZBP6nWYvMsRhpMzGXTpxJ5aO04NlbdhIz+FVe3q49l0AwVhsz/cEmIpBes6gAFl1/dWQg==}
|
||||
engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
|
||||
|
||||
'@jest/expect-utils@30.5.1':
|
||||
resolution: {integrity: sha512-WcRWhHQdTMRDpyWKZ/6MINBmovI7zeD+bL8wFjCncRV3NQOwKy1X45IfyblfHR4k/XciIlNEdFL9QjFO+HNKOg==}
|
||||
engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
|
||||
|
||||
'@jest/get-type@30.5.0':
|
||||
resolution: {integrity: sha512-9/2VUPitAjmBzbvDvqrxmvB7BzWsBW0WmkkojX1ODuxX1NLGxx9gfaZpHB0z8DtJ9uhGNmZG/VXBhf8uO0OV8Q==}
|
||||
engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
|
||||
|
||||
'@jest/pattern@30.5.0':
|
||||
resolution: {integrity: sha512-HdNQYSdRTEBNrginaqzQtTjG0HRMfrra/z6Ok7uL3S87vSlarIVohEsJsSj5edu3MiHoHjAkvPROz5ZjoKai+w==}
|
||||
engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
|
||||
|
||||
'@jest/schemas@30.5.0':
|
||||
resolution: {integrity: sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==}
|
||||
engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
|
||||
|
||||
'@jest/types@30.5.1':
|
||||
resolution: {integrity: sha512-LvVYn83nnXPl+Rg98nvcFgjx6nRMTArhSn6RAX/w3ELn54S8A42TYZvsCMdGUqTM8S0wyXbtlQdU6Hi6dykj9g==}
|
||||
engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
|
||||
|
||||
'@jridgewell/gen-mapping@0.3.13':
|
||||
resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
|
||||
|
||||
@ -4145,6 +4266,9 @@ packages:
|
||||
'@sec-ant/readable-stream@0.4.1':
|
||||
resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==}
|
||||
|
||||
'@sinclair/typebox@0.34.52':
|
||||
resolution: {integrity: sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==}
|
||||
|
||||
'@sindresorhus/merge-streams@4.0.0':
|
||||
resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==}
|
||||
engines: {node: '>=18'}
|
||||
@ -4419,6 +4543,18 @@ packages:
|
||||
'@types/inquirer@9.0.9':
|
||||
resolution: {integrity: sha512-/mWx5136gts2Z2e5izdoRCo46lPp5TMs9R15GTSsgg/XnZyxDWVqoVU3R9lWnccKpqwsJLvRoxbCjoJtZB7DSw==}
|
||||
|
||||
'@types/istanbul-lib-coverage@2.0.6':
|
||||
resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==}
|
||||
|
||||
'@types/istanbul-lib-report@3.0.3':
|
||||
resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==}
|
||||
|
||||
'@types/istanbul-reports@3.0.4':
|
||||
resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==}
|
||||
|
||||
'@types/jest@30.0.0':
|
||||
resolution: {integrity: sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==}
|
||||
|
||||
'@types/json-schema@7.0.15':
|
||||
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
|
||||
|
||||
@ -4505,6 +4641,9 @@ packages:
|
||||
'@types/set-cookie-parser@2.4.10':
|
||||
resolution: {integrity: sha512-GGmQVGpQWUe5qglJozEjZV/5dyxbOOZ0LHe/lqyWssB88Y4svNfst0uqBVscdDeIKl5Jy5+aPSvy7mI9tYRguw==}
|
||||
|
||||
'@types/stack-utils@2.0.3':
|
||||
resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==}
|
||||
|
||||
'@types/statuses@2.0.6':
|
||||
resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==}
|
||||
|
||||
@ -4523,6 +4662,12 @@ packages:
|
||||
'@types/validator@13.15.10':
|
||||
resolution: {integrity: sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==}
|
||||
|
||||
'@types/yargs-parser@21.0.3':
|
||||
resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==}
|
||||
|
||||
'@types/yargs@17.0.35':
|
||||
resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==}
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.60.0':
|
||||
resolution: {integrity: sha512-QYb/sa74/s7OKMbACMjrYnGspj9Hs5YI5aaffSL65UfeBUzVzBJfVo3oWSpbzPurvm7yaCCo2Lk7lVj610HqKw==}
|
||||
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
|
||||
@ -4662,6 +4807,10 @@ packages:
|
||||
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
ansi-styles@5.2.0:
|
||||
resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
any-promise@1.3.0:
|
||||
resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
|
||||
|
||||
@ -4833,6 +4982,10 @@ packages:
|
||||
resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==}
|
||||
engines: {node: '>= 20.19.0'}
|
||||
|
||||
ci-info@4.4.0:
|
||||
resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
class-variance-authority@0.7.1:
|
||||
resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==}
|
||||
|
||||
@ -5330,6 +5483,10 @@ packages:
|
||||
escape-html@1.0.3:
|
||||
resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==}
|
||||
|
||||
escape-string-regexp@2.0.0:
|
||||
resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
escape-string-regexp@4.0.0:
|
||||
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
|
||||
engines: {node: '>=10'}
|
||||
@ -5411,6 +5568,10 @@ packages:
|
||||
resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
expect@30.5.1:
|
||||
resolution: {integrity: sha512-m8YrYgvKe9+9gEnWEuKz+qCGfHqkrff7PPfyDnOFkjsfYRKqiYyOxDFMFieCGAuhtk/VNm63tvNgKZVzVy+Hvg==}
|
||||
engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
|
||||
|
||||
express-list-routes@1.3.2:
|
||||
resolution: {integrity: sha512-bwpS3aagDdzmtnIlYb9BDGoaIES3RQaOVNugfBUESM6kqkv+Y1bvztDju8wARzy8FDzuO6/HXT6OCGCiNd9f+g==}
|
||||
|
||||
@ -6026,6 +6187,30 @@ packages:
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
|
||||
jest-diff@30.5.1:
|
||||
resolution: {integrity: sha512-e3cNNMpv8Kh20MjjphTXs+3Vz7DQyLM1nft7KJhnh46atFhjVJRa+0Hq0beywuwsACtMQUBihQkFl8zxb7gt1Q==}
|
||||
engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
|
||||
|
||||
jest-matcher-utils@30.5.1:
|
||||
resolution: {integrity: sha512-aroZVqwOz/wC2y6pC+obgFWKV9viaQWQTTSB6W5H55+egtUczIfXR/rxExTv92xD/ADYwpqaYfVWx1aqwKg7FA==}
|
||||
engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
|
||||
|
||||
jest-message-util@30.5.1:
|
||||
resolution: {integrity: sha512-UdQlLdd9wL/Ys7xRErckqwD6wPlSZYueosSWuHc1r2ztGLwlgPvtSJq2+BPEgaEY13WLvfFbmhTj8pba0Sd1jg==}
|
||||
engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
|
||||
|
||||
jest-mock@30.5.1:
|
||||
resolution: {integrity: sha512-9fVjc3leUpGID2/by/LU4Dvdcp7PFh9LlxS3QRWK3ABm+KtvEVsG/AEGeLY3gKOZsjkBxyfwGltoAVlW7dygHg==}
|
||||
engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
|
||||
|
||||
jest-regex-util@30.5.0:
|
||||
resolution: {integrity: sha512-Mg0WK7A6xRHLSA1udJ8y9f3lM0uUhFTBnLKzwPmqB9AylvpleJ6BLemR8K9dK27DY+cesDryoA7yLZCAHsPG1A==}
|
||||
engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
|
||||
|
||||
jest-util@30.5.1:
|
||||
resolution: {integrity: sha512-yKuxmNy2rSbTXw+3SIPanJo+nV4/BS1p26v44IYBFMsswSQySfMMcPHErnOncda7i9HEz0q605rIhSTBVgrZTg==}
|
||||
engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
|
||||
|
||||
jiti@2.7.0:
|
||||
resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==}
|
||||
hasBin: true
|
||||
@ -6853,6 +7038,10 @@ packages:
|
||||
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
|
||||
pretty-format@30.5.1:
|
||||
resolution: {integrity: sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==}
|
||||
engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
|
||||
|
||||
pretty-ms@9.3.0:
|
||||
resolution: {integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ==}
|
||||
engines: {node: '>=18'}
|
||||
@ -6955,6 +7144,12 @@ packages:
|
||||
react-is@16.13.1:
|
||||
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
|
||||
|
||||
react-is@18.3.1:
|
||||
resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
|
||||
|
||||
react-is@19.2.8:
|
||||
resolution: {integrity: sha512-s5un28nYxKJw5gvUHyW5PCC28CvBqLu9r3cWgzHT4Vo/5fqqkFcdRYsGcKf50WMPpjjFZS5d76fn3YCo2njKwQ==}
|
||||
|
||||
react-qr-code@2.0.21:
|
||||
resolution: {integrity: sha512-xaywjo0eaF4S3LOz6ns5eoPbM2E+q9HYl4VATYpxK4bBniOhQ9noY2RJ9G4SnZFhUwzx63FUT6KdHzfKgUwyuQ==}
|
||||
peerDependencies:
|
||||
@ -7325,6 +7520,10 @@ packages:
|
||||
sisteransi@1.0.5:
|
||||
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
|
||||
|
||||
slash@3.0.0:
|
||||
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
sonner@2.0.7:
|
||||
resolution: {integrity: sha512-W6ZN4p58k8aDKA4XPcx2hpIQXBRAgyiWVkYhT7CvK6D3iAu7xjvVyhQHg2/iaKJZ1XVJ4r7XuwGL+WGEK37i9w==}
|
||||
peerDependencies:
|
||||
@ -7357,6 +7556,10 @@ packages:
|
||||
stack-trace@0.0.10:
|
||||
resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==}
|
||||
|
||||
stack-utils@2.0.6:
|
||||
resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
statuses@2.0.2:
|
||||
resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
|
||||
engines: {node: '>= 0.8'}
|
||||
@ -8838,6 +9041,33 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@types/node': 25.9.1
|
||||
|
||||
'@jest/diff-sequences@30.5.0': {}
|
||||
|
||||
'@jest/expect-utils@30.5.1':
|
||||
dependencies:
|
||||
'@jest/get-type': 30.5.0
|
||||
|
||||
'@jest/get-type@30.5.0': {}
|
||||
|
||||
'@jest/pattern@30.5.0':
|
||||
dependencies:
|
||||
'@types/node': 25.9.1
|
||||
jest-regex-util: 30.5.0
|
||||
|
||||
'@jest/schemas@30.5.0':
|
||||
dependencies:
|
||||
'@sinclair/typebox': 0.34.52
|
||||
|
||||
'@jest/types@30.5.1':
|
||||
dependencies:
|
||||
'@jest/pattern': 30.5.0
|
||||
'@jest/schemas': 30.5.0
|
||||
'@types/istanbul-lib-coverage': 2.0.6
|
||||
'@types/istanbul-reports': 3.0.4
|
||||
'@types/node': 25.9.1
|
||||
'@types/yargs': 17.0.35
|
||||
chalk: 4.1.2
|
||||
|
||||
'@jridgewell/gen-mapping@0.3.13':
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
@ -10114,6 +10344,8 @@ snapshots:
|
||||
|
||||
'@sec-ant/readable-stream@0.4.1': {}
|
||||
|
||||
'@sinclair/typebox@0.34.52': {}
|
||||
|
||||
'@sindresorhus/merge-streams@4.0.0': {}
|
||||
|
||||
'@so-ric/colorspace@1.1.6':
|
||||
@ -10362,6 +10594,21 @@ snapshots:
|
||||
'@types/through': 0.0.33
|
||||
rxjs: 7.8.2
|
||||
|
||||
'@types/istanbul-lib-coverage@2.0.6': {}
|
||||
|
||||
'@types/istanbul-lib-report@3.0.3':
|
||||
dependencies:
|
||||
'@types/istanbul-lib-coverage': 2.0.6
|
||||
|
||||
'@types/istanbul-reports@3.0.4':
|
||||
dependencies:
|
||||
'@types/istanbul-lib-report': 3.0.3
|
||||
|
||||
'@types/jest@30.0.0':
|
||||
dependencies:
|
||||
expect: 30.5.1
|
||||
pretty-format: 30.5.1
|
||||
|
||||
'@types/json-schema@7.0.15': {}
|
||||
|
||||
'@types/jsonwebtoken@9.0.10':
|
||||
@ -10467,6 +10714,8 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/node': 25.9.1
|
||||
|
||||
'@types/stack-utils@2.0.3': {}
|
||||
|
||||
'@types/statuses@2.0.6': {}
|
||||
|
||||
'@types/through@0.0.33':
|
||||
@ -10481,6 +10730,12 @@ snapshots:
|
||||
|
||||
'@types/validator@13.15.10': {}
|
||||
|
||||
'@types/yargs-parser@21.0.3': {}
|
||||
|
||||
'@types/yargs@17.0.35':
|
||||
dependencies:
|
||||
'@types/yargs-parser': 21.0.3
|
||||
|
||||
'@typescript-eslint/eslint-plugin@8.60.0(@typescript-eslint/parser@8.60.0(eslint@10.4.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.2))(eslint@10.4.0(jiti@2.7.0)(supports-color@7.2.0))(supports-color@7.2.0)(typescript@6.0.2)':
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.12.2
|
||||
@ -10639,6 +10894,8 @@ snapshots:
|
||||
dependencies:
|
||||
color-convert: 2.0.1
|
||||
|
||||
ansi-styles@5.2.0: {}
|
||||
|
||||
any-promise@1.3.0: {}
|
||||
|
||||
arg@4.1.3: {}
|
||||
@ -10828,6 +11085,8 @@ snapshots:
|
||||
dependencies:
|
||||
readdirp: 5.0.0
|
||||
|
||||
ci-info@4.4.0: {}
|
||||
|
||||
class-variance-authority@0.7.1:
|
||||
dependencies:
|
||||
clsx: 2.1.1
|
||||
@ -11294,6 +11553,8 @@ snapshots:
|
||||
|
||||
escape-html@1.0.3: {}
|
||||
|
||||
escape-string-regexp@2.0.0: {}
|
||||
|
||||
escape-string-regexp@4.0.0: {}
|
||||
|
||||
eslint-scope@9.1.2:
|
||||
@ -11407,6 +11668,15 @@ snapshots:
|
||||
dependencies:
|
||||
homedir-polyfill: 1.0.3
|
||||
|
||||
expect@30.5.1:
|
||||
dependencies:
|
||||
'@jest/expect-utils': 30.5.1
|
||||
'@jest/get-type': 30.5.0
|
||||
jest-matcher-utils: 30.5.1
|
||||
jest-message-util: 30.5.1
|
||||
jest-mock: 30.5.1
|
||||
jest-util: 30.5.1
|
||||
|
||||
express-list-routes@1.3.2: {}
|
||||
|
||||
express-rate-limit@8.5.2(express@5.2.1(supports-color@7.2.0)):
|
||||
@ -12047,6 +12317,51 @@ snapshots:
|
||||
filelist: 1.0.6
|
||||
picocolors: 1.1.1
|
||||
|
||||
jest-diff@30.5.1:
|
||||
dependencies:
|
||||
'@jest/diff-sequences': 30.5.0
|
||||
'@jest/get-type': 30.5.0
|
||||
chalk: 4.1.2
|
||||
pretty-format: 30.5.1
|
||||
|
||||
jest-matcher-utils@30.5.1:
|
||||
dependencies:
|
||||
'@jest/get-type': 30.5.0
|
||||
chalk: 4.1.2
|
||||
jest-diff: 30.5.1
|
||||
pretty-format: 30.5.1
|
||||
|
||||
jest-message-util@30.5.1:
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.29.7
|
||||
'@jest/types': 30.5.1
|
||||
'@types/stack-utils': 2.0.3
|
||||
chalk: 4.1.2
|
||||
graceful-fs: 4.2.11
|
||||
jest-util: 30.5.1
|
||||
picomatch: 4.0.4
|
||||
pretty-format: 30.5.1
|
||||
slash: 3.0.0
|
||||
stack-utils: 2.0.6
|
||||
|
||||
jest-mock@30.5.1:
|
||||
dependencies:
|
||||
'@jest/expect-utils': 30.5.1
|
||||
'@jest/types': 30.5.1
|
||||
'@types/node': 25.9.1
|
||||
jest-util: 30.5.1
|
||||
|
||||
jest-regex-util@30.5.0: {}
|
||||
|
||||
jest-util@30.5.1:
|
||||
dependencies:
|
||||
'@jest/types': 30.5.1
|
||||
'@types/node': 25.9.1
|
||||
chalk: 4.1.2
|
||||
ci-info: 4.4.0
|
||||
graceful-fs: 4.2.11
|
||||
picomatch: 4.0.4
|
||||
|
||||
jiti@2.7.0: {}
|
||||
|
||||
joi@18.2.1:
|
||||
@ -12828,6 +13143,13 @@ snapshots:
|
||||
|
||||
prelude-ls@1.2.1: {}
|
||||
|
||||
pretty-format@30.5.1:
|
||||
dependencies:
|
||||
'@jest/react-is-18': react-is@18.3.1
|
||||
'@jest/react-is-19': react-is@19.2.8
|
||||
'@jest/schemas': 30.5.0
|
||||
ansi-styles: 5.2.0
|
||||
|
||||
pretty-ms@9.3.0:
|
||||
dependencies:
|
||||
parse-ms: 4.0.0
|
||||
@ -12987,6 +13309,10 @@ snapshots:
|
||||
|
||||
react-is@16.13.1: {}
|
||||
|
||||
react-is@18.3.1: {}
|
||||
|
||||
react-is@19.2.8: {}
|
||||
|
||||
react-qr-code@2.0.21(react@19.2.6):
|
||||
dependencies:
|
||||
prop-types: 15.8.1
|
||||
@ -13459,6 +13785,8 @@ snapshots:
|
||||
|
||||
sisteransi@1.0.5: {}
|
||||
|
||||
slash@3.0.0: {}
|
||||
|
||||
sonner@2.0.7(react-dom@19.2.6(react@19.2.6))(react@19.2.6):
|
||||
dependencies:
|
||||
react: 19.2.6
|
||||
@ -13481,6 +13809,10 @@ snapshots:
|
||||
|
||||
stack-trace@0.0.10: {}
|
||||
|
||||
stack-utils@2.0.6:
|
||||
dependencies:
|
||||
escape-string-regexp: 2.0.0
|
||||
|
||||
statuses@2.0.2: {}
|
||||
|
||||
stdin-discarder@0.2.2: {}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user