mirror of
https://github.com/colanode/colanode.git
synced 2025-12-16 19:57:46 +01:00
Initiate monorepo
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -144,3 +144,5 @@ out/
|
|||||||
dist/
|
dist/
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
.turbo
|
||||||
|
.tsbuildinfo
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
dist
|
dist
|
||||||
out
|
out
|
||||||
/tsconfig.base.json
|
/tsconfig.base.json
|
||||||
|
pnpm-lock.yaml
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"semi": true,
|
"semi": true,
|
||||||
"trailingComma": "all",
|
"trailingComma": "es5",
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"printWidth": 80,
|
"printWidth": 80,
|
||||||
"tabWidth": 2
|
"tabWidth": 2
|
||||||
|
|||||||
@@ -1,34 +1,33 @@
|
|||||||
{
|
{
|
||||||
"name": "neuron-server",
|
"name": "@colanode/server",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"main": "src/index.ts",
|
"type": "module",
|
||||||
|
"main": "./dist/index.js",
|
||||||
|
"module": "./dist/index.js",
|
||||||
|
"files": [
|
||||||
|
"dist",
|
||||||
|
".env"
|
||||||
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc --project tsconfig.json && tsc-alias -p tsconfig.json",
|
"compile": "tsc --noEmit",
|
||||||
"start": "node dist/index.js",
|
"build": "tsup-node",
|
||||||
"dev": "node -r ts-node/register -r tsconfig-paths/register --env-file .env src/index.ts",
|
"clean": "del-cli dist isolate tsconfig.tsbuildinfo",
|
||||||
"format": "prettier --write \"{src,test}/**/*.{js,ts}\""
|
"lint": "eslint . --max-warnings 0",
|
||||||
|
"dev": "nodemon --env-file .env dist/index.js"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"author": "Hakan Shehu",
|
||||||
"author": "",
|
|
||||||
"license": "ISC",
|
|
||||||
"description": "",
|
"description": "",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bcrypt": "^5.0.2",
|
"@types/bcrypt": "^5.0.2",
|
||||||
"@types/cors": "^2.8.17",
|
"@types/cors": "^2.8.17",
|
||||||
"@types/express": "^4.17.21",
|
"@types/express": "^4.17.21",
|
||||||
"@types/jsonwebtoken": "^9.0.7",
|
|
||||||
"@types/lodash": "^4.17.12",
|
|
||||||
"@types/multer": "^1.4.12",
|
"@types/multer": "^1.4.12",
|
||||||
"@types/node": "^22.7.7",
|
"@types/node": "^22.7.7",
|
||||||
"@types/pg": "^8.11.10",
|
"@types/pg": "^8.11.10",
|
||||||
"@types/ws": "^8.5.12",
|
"@types/ws": "^8.5.12",
|
||||||
"concurrently": "^9.0.1",
|
|
||||||
"nodemon": "^3.1.7",
|
"nodemon": "^3.1.7",
|
||||||
"prettier": "^3.3.3",
|
|
||||||
"ts-node": "^10.9.2",
|
"ts-node": "^10.9.2",
|
||||||
"tsc-alias": "^1.8.10",
|
"tsup": "^8.3.0"
|
||||||
"tsconfig-paths": "^4.2.0",
|
|
||||||
"typescript": "^5.6.3"
|
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/client-s3": "^3.675.0",
|
"@aws-sdk/client-s3": "^3.675.0",
|
||||||
@@ -37,12 +36,12 @@
|
|||||||
"bcrypt": "^5.1.1",
|
"bcrypt": "^5.1.1",
|
||||||
"bullmq": "^5.21.1",
|
"bullmq": "^5.21.1",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
|
"dotenv": "^16.4.5",
|
||||||
"express": "^4.21.1",
|
"express": "^4.21.1",
|
||||||
"js-base64": "^3.7.7",
|
"js-base64": "^3.7.7",
|
||||||
"js-sha256": "^0.11.0",
|
"js-sha256": "^0.11.0",
|
||||||
"kafkajs": "^2.2.4",
|
"kafkajs": "^2.2.4",
|
||||||
"kysely": "^0.27.4",
|
"kysely": "^0.27.4",
|
||||||
"lodash": "^4.17.21",
|
|
||||||
"multer": "^1.4.5-lts.1",
|
"multer": "^1.4.5-lts.1",
|
||||||
"pg": "^8.13.0",
|
"pg": "^8.13.0",
|
||||||
"postgres": "^3.4.4",
|
"postgres": "^3.4.4",
|
||||||
@@ -7,12 +7,12 @@ import {
|
|||||||
PostgresDialect,
|
PostgresDialect,
|
||||||
UpdateResult,
|
UpdateResult,
|
||||||
} from 'kysely';
|
} from 'kysely';
|
||||||
import { Pool } from 'pg';
|
import pg from 'pg';
|
||||||
import { DatabaseSchema } from '@/data/schema';
|
import { DatabaseSchema } from '@/data/schema';
|
||||||
import { databaseMigrations } from '@/data/migrations';
|
import { databaseMigrations } from '@/data/migrations';
|
||||||
|
|
||||||
const dialect = new PostgresDialect({
|
const dialect = new PostgresDialect({
|
||||||
pool: new Pool({
|
pool: new pg.Pool({
|
||||||
connectionString: process.env.DATABASE_URL,
|
connectionString: process.env.DATABASE_URL,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
@@ -40,7 +40,7 @@ export const hasInsertChanges = (result: InsertResult[]): boolean => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return result.some(
|
return result.some(
|
||||||
(r) => r.numInsertedOrUpdatedRows && r.numInsertedOrUpdatedRows > 0n,
|
(r) => r.numInsertedOrUpdatedRows && r.numInsertedOrUpdatedRows > 0n
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -3,6 +3,9 @@ import { initRedis } from '@/data/redis';
|
|||||||
import { migrate } from '@/data/database';
|
import { migrate } from '@/data/database';
|
||||||
import { initEventWorker } from '@/queues/events';
|
import { initEventWorker } from '@/queues/events';
|
||||||
import { initTaskWorker } from '@/queues/tasks';
|
import { initTaskWorker } from '@/queues/tasks';
|
||||||
|
import dotenv from 'dotenv';
|
||||||
|
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
const init = async () => {
|
const init = async () => {
|
||||||
await migrate();
|
await migrate();
|
||||||
@@ -21,6 +21,9 @@ export const compareString = (a?: string | null, b?: string | null): number => {
|
|||||||
export const getNameFromEmail = (email: string): string => {
|
export const getNameFromEmail = (email: string): string => {
|
||||||
// Extract the part before the @ symbol
|
// Extract the part before the @ symbol
|
||||||
const namePart = email.split('@')[0];
|
const namePart = email.split('@')[0];
|
||||||
|
if (!namePart) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
// Split by dots, underscores, and dashes, then capitalize each part
|
// Split by dots, underscores, and dashes, then capitalize each part
|
||||||
const displayName = namePart
|
const displayName = namePart
|
||||||
@@ -16,7 +16,7 @@ import {
|
|||||||
import { ServerNodeAttributes } from '@/types/nodes';
|
import { ServerNodeAttributes } from '@/types/nodes';
|
||||||
import { DeleteObjectCommand } from '@aws-sdk/client-s3';
|
import { DeleteObjectCommand } from '@aws-sdk/client-s3';
|
||||||
import { Job, Queue, Worker } from 'bullmq';
|
import { Job, Queue, Worker } from 'bullmq';
|
||||||
import { difference } from 'lodash';
|
import { difference } from 'lodash-es';
|
||||||
|
|
||||||
const eventQueue = new Queue('events', {
|
const eventQueue = new Queue('events', {
|
||||||
connection: {
|
connection: {
|
||||||
@@ -59,7 +59,7 @@ const handleEventJob = async (job: Job) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleNodeCreatedEvent = async (
|
const handleNodeCreatedEvent = async (
|
||||||
event: NodeCreatedEvent,
|
event: NodeCreatedEvent
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
await createUserNodes(event);
|
await createUserNodes(event);
|
||||||
await synapse.sendSynapseMessage({
|
await synapse.sendSynapseMessage({
|
||||||
@@ -70,7 +70,7 @@ const handleNodeCreatedEvent = async (
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleNodeUpdatedEvent = async (
|
const handleNodeUpdatedEvent = async (
|
||||||
event: NodeUpdatedEvent,
|
event: NodeUpdatedEvent
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
await checkForCollaboratorsChange(event);
|
await checkForCollaboratorsChange(event);
|
||||||
await synapse.sendSynapseMessage({
|
await synapse.sendSynapseMessage({
|
||||||
@@ -81,7 +81,7 @@ const handleNodeUpdatedEvent = async (
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleNodeDeletedEvent = async (
|
const handleNodeDeletedEvent = async (
|
||||||
event: NodeDeletedEvent,
|
event: NodeDeletedEvent
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
if (event.attributes.type === NodeTypes.File) {
|
if (event.attributes.type === NodeTypes.File) {
|
||||||
const command = new DeleteObjectCommand({
|
const command = new DeleteObjectCommand({
|
||||||
@@ -167,19 +167,19 @@ const createUserNodes = async (event: NodeCreatedEvent): Promise<void> => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const checkForCollaboratorsChange = async (
|
const checkForCollaboratorsChange = async (
|
||||||
event: NodeUpdatedEvent,
|
event: NodeUpdatedEvent
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
const beforeCollaborators = extractCollaboratorIds(event.beforeAttributes);
|
const beforeCollaborators = extractCollaboratorIds(event.beforeAttributes);
|
||||||
const afterCollaborators = extractCollaboratorIds(event.afterAttributes);
|
const afterCollaborators = extractCollaboratorIds(event.afterAttributes);
|
||||||
|
|
||||||
const addedCollaborators = difference(
|
const addedCollaborators = difference(
|
||||||
afterCollaborators,
|
afterCollaborators,
|
||||||
beforeCollaborators,
|
beforeCollaborators
|
||||||
);
|
);
|
||||||
|
|
||||||
const removedCollaborators = difference(
|
const removedCollaborators = difference(
|
||||||
beforeCollaborators,
|
beforeCollaborators,
|
||||||
afterCollaborators,
|
afterCollaborators
|
||||||
);
|
);
|
||||||
|
|
||||||
if (addedCollaborators.length === 0 && removedCollaborators.length === 0) {
|
if (addedCollaborators.length === 0 && removedCollaborators.length === 0) {
|
||||||
@@ -198,7 +198,7 @@ const checkForCollaboratorsChange = async (
|
|||||||
|
|
||||||
const actualAddedCollaborators = difference(
|
const actualAddedCollaborators = difference(
|
||||||
addedCollaborators,
|
addedCollaborators,
|
||||||
existingCollaboratorIds,
|
existingCollaboratorIds
|
||||||
);
|
);
|
||||||
|
|
||||||
if (actualAddedCollaborators.length > 0) {
|
if (actualAddedCollaborators.length > 0) {
|
||||||
@@ -241,7 +241,7 @@ const checkForCollaboratorsChange = async (
|
|||||||
const nodeCollaboratorIds = nodeCollaborators.map((c) => c.collaboratorId);
|
const nodeCollaboratorIds = nodeCollaborators.map((c) => c.collaboratorId);
|
||||||
const actualRemovedCollaborators = difference(
|
const actualRemovedCollaborators = difference(
|
||||||
removedCollaborators,
|
removedCollaborators,
|
||||||
nodeCollaboratorIds,
|
nodeCollaboratorIds
|
||||||
);
|
);
|
||||||
|
|
||||||
if (actualRemovedCollaborators.length > 0) {
|
if (actualRemovedCollaborators.length > 0) {
|
||||||
@@ -170,7 +170,7 @@ workspacesRouter.post('/', async (req: NeuronRequest, res: NeuronResponse) => {
|
|||||||
workspacesRouter.put(
|
workspacesRouter.put(
|
||||||
'/:id',
|
'/:id',
|
||||||
async (req: NeuronRequest, res: NeuronResponse) => {
|
async (req: NeuronRequest, res: NeuronResponse) => {
|
||||||
const id = req.params.id;
|
const id = req.params.id as string;
|
||||||
const input: WorkspaceInput = req.body;
|
const input: WorkspaceInput = req.body;
|
||||||
|
|
||||||
if (!req.account) {
|
if (!req.account) {
|
||||||
@@ -276,13 +276,13 @@ workspacesRouter.put(
|
|||||||
};
|
};
|
||||||
|
|
||||||
return res.status(200).json(output);
|
return res.status(200).json(output);
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
workspacesRouter.delete(
|
workspacesRouter.delete(
|
||||||
'/:id',
|
'/:id',
|
||||||
async (req: NeuronRequest, res: NeuronResponse) => {
|
async (req: NeuronRequest, res: NeuronResponse) => {
|
||||||
const id = req.params.id;
|
const id = req.params.id as string;
|
||||||
|
|
||||||
if (!req.account) {
|
if (!req.account) {
|
||||||
return res.status(401).json({
|
return res.status(401).json({
|
||||||
@@ -330,13 +330,13 @@ workspacesRouter.delete(
|
|||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
id: workspace.id,
|
id: workspace.id,
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
workspacesRouter.get(
|
workspacesRouter.get(
|
||||||
'/:id',
|
'/:id',
|
||||||
async (req: NeuronRequest, res: NeuronResponse) => {
|
async (req: NeuronRequest, res: NeuronResponse) => {
|
||||||
const id = req.params.id;
|
const id = req.params.id as string;
|
||||||
|
|
||||||
if (!req.account) {
|
if (!req.account) {
|
||||||
return res.status(401).json({
|
return res.status(401).json({
|
||||||
@@ -400,7 +400,7 @@ workspacesRouter.get(
|
|||||||
};
|
};
|
||||||
|
|
||||||
return res.status(200).json(output);
|
return res.status(200).json(output);
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
workspacesRouter.get('/', async (req: NeuronRequest, res: NeuronResponse) => {
|
workspacesRouter.get('/', async (req: NeuronRequest, res: NeuronResponse) => {
|
||||||
@@ -430,7 +430,7 @@ workspacesRouter.get('/', async (req: NeuronRequest, res: NeuronResponse) => {
|
|||||||
.where(
|
.where(
|
||||||
'id',
|
'id',
|
||||||
'in',
|
'in',
|
||||||
workspaceUsers.map((wa) => wa.id),
|
workspaceUsers.map((wa) => wa.id)
|
||||||
)
|
)
|
||||||
.execute();
|
.execute();
|
||||||
|
|
||||||
@@ -438,7 +438,7 @@ workspacesRouter.get('/', async (req: NeuronRequest, res: NeuronResponse) => {
|
|||||||
|
|
||||||
for (const workspace of workspaces) {
|
for (const workspace of workspaces) {
|
||||||
const workspaceUser = workspaceUsers.find(
|
const workspaceUser = workspaceUsers.find(
|
||||||
(wa) => wa.workspace_id === workspace.id,
|
(wa) => wa.workspace_id === workspace.id
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!workspaceUser) {
|
if (!workspaceUser) {
|
||||||
@@ -474,7 +474,7 @@ workspacesRouter.get('/', async (req: NeuronRequest, res: NeuronResponse) => {
|
|||||||
workspacesRouter.post(
|
workspacesRouter.post(
|
||||||
'/:id/users',
|
'/:id/users',
|
||||||
async (req: NeuronRequest, res: NeuronResponse) => {
|
async (req: NeuronRequest, res: NeuronResponse) => {
|
||||||
const id = req.params.id;
|
const id = req.params.id as string;
|
||||||
const input: WorkspaceAccountsInviteInput = req.body;
|
const input: WorkspaceAccountsInviteInput = req.body;
|
||||||
|
|
||||||
if (!input.emails || input.emails.length === 0) {
|
if (!input.emails || input.emails.length === 0) {
|
||||||
@@ -545,14 +545,14 @@ workspacesRouter.post(
|
|||||||
eb.and([
|
eb.and([
|
||||||
eb('account_id', 'in', existingAccountIds),
|
eb('account_id', 'in', existingAccountIds),
|
||||||
eb('workspace_id', '=', workspace.id),
|
eb('workspace_id', '=', workspace.id),
|
||||||
]),
|
])
|
||||||
)
|
)
|
||||||
.execute();
|
.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (existingWorkspaceUsers.length > 0) {
|
if (existingWorkspaceUsers.length > 0) {
|
||||||
const existingUserIds = existingWorkspaceUsers.map(
|
const existingUserIds = existingWorkspaceUsers.map(
|
||||||
(workspaceAccount) => workspaceAccount.id,
|
(workspaceAccount) => workspaceAccount.id
|
||||||
);
|
);
|
||||||
existingUsers = await database
|
existingUsers = await database
|
||||||
.selectFrom('nodes')
|
.selectFrom('nodes')
|
||||||
@@ -592,12 +592,12 @@ workspacesRouter.post(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const existingWorkspaceUser = existingWorkspaceUsers.find(
|
const existingWorkspaceUser = existingWorkspaceUsers.find(
|
||||||
(workspaceUser) => workspaceUser.account_id === account!.id,
|
(workspaceUser) => workspaceUser.account_id === account!.id
|
||||||
);
|
);
|
||||||
|
|
||||||
if (existingWorkspaceUser) {
|
if (existingWorkspaceUser) {
|
||||||
const existingUser = existingUsers.find(
|
const existingUser = existingUsers.find(
|
||||||
(user) => user.id === existingWorkspaceUser.id,
|
(user) => user.id === existingWorkspaceUser.id
|
||||||
);
|
);
|
||||||
if (!existingUser) {
|
if (!existingUser) {
|
||||||
return res.status(500).json({
|
return res.status(500).json({
|
||||||
@@ -708,14 +708,14 @@ workspacesRouter.post(
|
|||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
users: users,
|
users: users,
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
workspacesRouter.put(
|
workspacesRouter.put(
|
||||||
'/:id/users/:userId',
|
'/:id/users/:userId',
|
||||||
async (req: NeuronRequest, res: NeuronResponse) => {
|
async (req: NeuronRequest, res: NeuronResponse) => {
|
||||||
const id = req.params.id;
|
const id = req.params.id as string;
|
||||||
const userId = req.params.userId;
|
const userId = req.params.userId as string;
|
||||||
const input: WorkspaceAccountRoleUpdateInput = req.body;
|
const input: WorkspaceAccountRoleUpdateInput = req.body;
|
||||||
|
|
||||||
if (!req.account) {
|
if (!req.account) {
|
||||||
@@ -852,5 +852,5 @@ workspacesRouter.put(
|
|||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
user: userNode,
|
user: userNode,
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
@@ -3,12 +3,12 @@ import { hasAdminAccess, hasEditorAccess } from '@/lib/constants';
|
|||||||
import { fetchNodeRole } from '@/lib/nodes';
|
import { fetchNodeRole } from '@/lib/nodes';
|
||||||
import { ServerNode, ServerNodeAttributes } from '@/types/nodes';
|
import { ServerNode, ServerNodeAttributes } from '@/types/nodes';
|
||||||
import { Validator } from '@/types/validators';
|
import { Validator } from '@/types/validators';
|
||||||
import { isEqual } from 'lodash';
|
import { isEqual } from 'lodash-es';
|
||||||
|
|
||||||
export class BoardViewValidator implements Validator {
|
export class BoardViewValidator implements Validator {
|
||||||
async canCreate(
|
async canCreate(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
attributes: ServerNodeAttributes,
|
attributes: ServerNodeAttributes
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
if (!attributes.parentId) {
|
if (!attributes.parentId) {
|
||||||
return false;
|
return false;
|
||||||
@@ -29,7 +29,7 @@ export class BoardViewValidator implements Validator {
|
|||||||
async canUpdate(
|
async canUpdate(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
node: ServerNode,
|
node: ServerNode,
|
||||||
attributes: ServerNodeAttributes,
|
attributes: ServerNodeAttributes
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
||||||
if (!role) {
|
if (!role) {
|
||||||
@@ -45,7 +45,7 @@ export class BoardViewValidator implements Validator {
|
|||||||
|
|
||||||
async canDelete(
|
async canDelete(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
node: ServerNode,
|
node: ServerNode
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
||||||
if (!role) {
|
if (!role) {
|
||||||
@@ -3,12 +3,12 @@ import { hasAdminAccess, hasEditorAccess } from '@/lib/constants';
|
|||||||
import { fetchNodeRole } from '@/lib/nodes';
|
import { fetchNodeRole } from '@/lib/nodes';
|
||||||
import { ServerNode, ServerNodeAttributes } from '@/types/nodes';
|
import { ServerNode, ServerNodeAttributes } from '@/types/nodes';
|
||||||
import { Validator } from '@/types/validators';
|
import { Validator } from '@/types/validators';
|
||||||
import { isEqual } from 'lodash';
|
import { isEqual } from 'lodash-es';
|
||||||
|
|
||||||
export class CalendarViewValidator implements Validator {
|
export class CalendarViewValidator implements Validator {
|
||||||
async canCreate(
|
async canCreate(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
attributes: ServerNodeAttributes,
|
attributes: ServerNodeAttributes
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
if (!attributes.parentId) {
|
if (!attributes.parentId) {
|
||||||
return false;
|
return false;
|
||||||
@@ -30,7 +30,7 @@ export class CalendarViewValidator implements Validator {
|
|||||||
async canUpdate(
|
async canUpdate(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
node: ServerNode,
|
node: ServerNode,
|
||||||
attributes: ServerNodeAttributes,
|
attributes: ServerNodeAttributes
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
||||||
if (!role) {
|
if (!role) {
|
||||||
@@ -46,7 +46,7 @@ export class CalendarViewValidator implements Validator {
|
|||||||
|
|
||||||
async canDelete(
|
async canDelete(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
node: ServerNode,
|
node: ServerNode
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
||||||
if (!role) {
|
if (!role) {
|
||||||
@@ -3,12 +3,12 @@ import { hasAdminAccess, hasEditorAccess } from '@/lib/constants';
|
|||||||
import { fetchNodeRole } from '@/lib/nodes';
|
import { fetchNodeRole } from '@/lib/nodes';
|
||||||
import { ServerNode, ServerNodeAttributes } from '@/types/nodes';
|
import { ServerNode, ServerNodeAttributes } from '@/types/nodes';
|
||||||
import { Validator } from '@/types/validators';
|
import { Validator } from '@/types/validators';
|
||||||
import { isEqual } from 'lodash';
|
import { isEqual } from 'lodash-es';
|
||||||
|
|
||||||
export class ChannelValidator implements Validator {
|
export class ChannelValidator implements Validator {
|
||||||
async canCreate(
|
async canCreate(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
attributes: ServerNodeAttributes,
|
attributes: ServerNodeAttributes
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
if (!attributes.parentId) {
|
if (!attributes.parentId) {
|
||||||
return false;
|
return false;
|
||||||
@@ -30,7 +30,7 @@ export class ChannelValidator implements Validator {
|
|||||||
async canUpdate(
|
async canUpdate(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
node: ServerNode,
|
node: ServerNode,
|
||||||
attributes: ServerNodeAttributes,
|
attributes: ServerNodeAttributes
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
||||||
if (!role) {
|
if (!role) {
|
||||||
@@ -46,7 +46,7 @@ export class ChannelValidator implements Validator {
|
|||||||
|
|
||||||
async canDelete(
|
async canDelete(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
node: ServerNode,
|
node: ServerNode
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
||||||
if (!role) {
|
if (!role) {
|
||||||
@@ -3,12 +3,12 @@ import { hasAdminAccess, hasEditorAccess } from '@/lib/constants';
|
|||||||
import { fetchNodeRole } from '@/lib/nodes';
|
import { fetchNodeRole } from '@/lib/nodes';
|
||||||
import { ServerNode, ServerNodeAttributes } from '@/types/nodes';
|
import { ServerNode, ServerNodeAttributes } from '@/types/nodes';
|
||||||
import { Validator } from '@/types/validators';
|
import { Validator } from '@/types/validators';
|
||||||
import { isEqual } from 'lodash';
|
import { isEqual } from 'lodash-es';
|
||||||
|
|
||||||
export class FolderValidator implements Validator {
|
export class FolderValidator implements Validator {
|
||||||
async canCreate(
|
async canCreate(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
attributes: ServerNodeAttributes,
|
attributes: ServerNodeAttributes
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
if (!attributes.parentId) {
|
if (!attributes.parentId) {
|
||||||
return false;
|
return false;
|
||||||
@@ -30,7 +30,7 @@ export class FolderValidator implements Validator {
|
|||||||
async canUpdate(
|
async canUpdate(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
node: ServerNode,
|
node: ServerNode,
|
||||||
attributes: ServerNodeAttributes,
|
attributes: ServerNodeAttributes
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
||||||
if (!role) {
|
if (!role) {
|
||||||
@@ -46,7 +46,7 @@ export class FolderValidator implements Validator {
|
|||||||
|
|
||||||
async canDelete(
|
async canDelete(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
node: ServerNode,
|
node: ServerNode
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
||||||
if (!role) {
|
if (!role) {
|
||||||
@@ -3,12 +3,12 @@ import { hasAdminAccess, hasCollaboratorAccess } from '@/lib/constants';
|
|||||||
import { fetchNodeRole } from '@/lib/nodes';
|
import { fetchNodeRole } from '@/lib/nodes';
|
||||||
import { ServerNode, ServerNodeAttributes } from '@/types/nodes';
|
import { ServerNode, ServerNodeAttributes } from '@/types/nodes';
|
||||||
import { Validator } from '@/types/validators';
|
import { Validator } from '@/types/validators';
|
||||||
import { isEqual } from 'lodash';
|
import { isEqual } from 'lodash-es';
|
||||||
|
|
||||||
export class MessageValidator implements Validator {
|
export class MessageValidator implements Validator {
|
||||||
async canCreate(
|
async canCreate(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
attributes: ServerNodeAttributes,
|
attributes: ServerNodeAttributes
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
if (!attributes.parentId) {
|
if (!attributes.parentId) {
|
||||||
return false;
|
return false;
|
||||||
@@ -26,7 +26,7 @@ export class MessageValidator implements Validator {
|
|||||||
async canUpdate(
|
async canUpdate(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
node: ServerNode,
|
node: ServerNode,
|
||||||
attributes: ServerNodeAttributes,
|
attributes: ServerNodeAttributes
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
if (
|
if (
|
||||||
!isEqual(attributes.content, node.attributes.content) &&
|
!isEqual(attributes.content, node.attributes.content) &&
|
||||||
@@ -45,7 +45,7 @@ export class MessageValidator implements Validator {
|
|||||||
|
|
||||||
async canDelete(
|
async canDelete(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
node: ServerNode,
|
node: ServerNode
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
if (node.createdBy === workspaceUser.id) {
|
if (node.createdBy === workspaceUser.id) {
|
||||||
return true;
|
return true;
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { SelectWorkspaceUser } from '@/data/schema';
|
import { SelectWorkspaceUser } from '@/data/schema';
|
||||||
import { hasAdminAccess, hasEditorAccess } from '@/lib/constants';
|
import { hasAdminAccess, hasEditorAccess } from '@/lib/constants';
|
||||||
import { isEqual } from 'lodash';
|
import { isEqual } from 'lodash-es';
|
||||||
import { fetchNodeRole } from '@/lib/nodes';
|
import { fetchNodeRole } from '@/lib/nodes';
|
||||||
import { ServerNode, ServerNodeAttributes } from '@/types/nodes';
|
import { ServerNode, ServerNodeAttributes } from '@/types/nodes';
|
||||||
import { Validator } from '@/types/validators';
|
import { Validator } from '@/types/validators';
|
||||||
@@ -8,7 +8,7 @@ import { Validator } from '@/types/validators';
|
|||||||
export class PageValidator implements Validator {
|
export class PageValidator implements Validator {
|
||||||
async canCreate(
|
async canCreate(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
attributes: ServerNodeAttributes,
|
attributes: ServerNodeAttributes
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
if (!attributes.parentId) {
|
if (!attributes.parentId) {
|
||||||
return false;
|
return false;
|
||||||
@@ -30,7 +30,7 @@ export class PageValidator implements Validator {
|
|||||||
async canUpdate(
|
async canUpdate(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
node: ServerNode,
|
node: ServerNode,
|
||||||
attributes: ServerNodeAttributes,
|
attributes: ServerNodeAttributes
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
||||||
if (!role) {
|
if (!role) {
|
||||||
@@ -46,7 +46,7 @@ export class PageValidator implements Validator {
|
|||||||
|
|
||||||
async canDelete(
|
async canDelete(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
node: ServerNode,
|
node: ServerNode
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
||||||
if (!role) {
|
if (!role) {
|
||||||
@@ -3,12 +3,12 @@ import { hasAdminAccess, hasEditorAccess } from '@/lib/constants';
|
|||||||
import { fetchNodeRole } from '@/lib/nodes';
|
import { fetchNodeRole } from '@/lib/nodes';
|
||||||
import { ServerNode, ServerNodeAttributes } from '@/types/nodes';
|
import { ServerNode, ServerNodeAttributes } from '@/types/nodes';
|
||||||
import { Validator } from '@/types/validators';
|
import { Validator } from '@/types/validators';
|
||||||
import { isEqual } from 'lodash';
|
import { isEqual } from 'lodash-es';
|
||||||
|
|
||||||
export class SelectOptionValidator implements Validator {
|
export class SelectOptionValidator implements Validator {
|
||||||
async canCreate(
|
async canCreate(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
attributes: ServerNodeAttributes,
|
attributes: ServerNodeAttributes
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
if (!attributes.parentId) {
|
if (!attributes.parentId) {
|
||||||
return false;
|
return false;
|
||||||
@@ -30,7 +30,7 @@ export class SelectOptionValidator implements Validator {
|
|||||||
async canUpdate(
|
async canUpdate(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
node: ServerNode,
|
node: ServerNode,
|
||||||
attributes: ServerNodeAttributes,
|
attributes: ServerNodeAttributes
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
||||||
if (!role) {
|
if (!role) {
|
||||||
@@ -46,7 +46,7 @@ export class SelectOptionValidator implements Validator {
|
|||||||
|
|
||||||
async canDelete(
|
async canDelete(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
node: ServerNode,
|
node: ServerNode
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
||||||
if (!role) {
|
if (!role) {
|
||||||
@@ -3,12 +3,12 @@ import { hasAdminAccess, hasEditorAccess } from '@/lib/constants';
|
|||||||
import { fetchNodeRole } from '@/lib/nodes';
|
import { fetchNodeRole } from '@/lib/nodes';
|
||||||
import { ServerNode, ServerNodeAttributes } from '@/types/nodes';
|
import { ServerNode, ServerNodeAttributes } from '@/types/nodes';
|
||||||
import { Validator } from '@/types/validators';
|
import { Validator } from '@/types/validators';
|
||||||
import { isEqual } from 'lodash';
|
import { isEqual } from 'lodash-es';
|
||||||
|
|
||||||
export class TableViewValidator implements Validator {
|
export class TableViewValidator implements Validator {
|
||||||
async canCreate(
|
async canCreate(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
attributes: ServerNodeAttributes,
|
attributes: ServerNodeAttributes
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
if (!attributes.parentId) {
|
if (!attributes.parentId) {
|
||||||
return false;
|
return false;
|
||||||
@@ -29,7 +29,7 @@ export class TableViewValidator implements Validator {
|
|||||||
async canUpdate(
|
async canUpdate(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
node: ServerNode,
|
node: ServerNode,
|
||||||
attributes: ServerNodeAttributes,
|
attributes: ServerNodeAttributes
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
||||||
if (!role) {
|
if (!role) {
|
||||||
@@ -45,7 +45,7 @@ export class TableViewValidator implements Validator {
|
|||||||
|
|
||||||
async canDelete(
|
async canDelete(
|
||||||
workspaceUser: SelectWorkspaceUser,
|
workspaceUser: SelectWorkspaceUser,
|
||||||
node: ServerNode,
|
node: ServerNode
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
const role = await fetchNodeRole(node.id, workspaceUser.id);
|
||||||
if (!role) {
|
if (!role) {
|
||||||
15
apps/server/tsconfig.json
Normal file
15
apps/server/tsconfig.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/tsconfig",
|
||||||
|
"display": "Server",
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"references": [
|
||||||
|
{
|
||||||
|
"path": "../../packages/core"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
18
apps/server/tsup.config.ts
Normal file
18
apps/server/tsup.config.ts
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import { defineConfig } from 'tsup';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
entry: ['src/index.ts'],
|
||||||
|
format: ['esm'],
|
||||||
|
target: 'es2022',
|
||||||
|
sourcemap: true,
|
||||||
|
/**
|
||||||
|
* The common package is using the internal packages approach, so it needs to
|
||||||
|
* be transpiled / bundled together with the deployed code.
|
||||||
|
*/
|
||||||
|
noExternal: ['@colanode/core'],
|
||||||
|
/**
|
||||||
|
* Do not use tsup for generating d.ts files because it can not generate type
|
||||||
|
* the definition maps required for go-to-definition to work in our IDE. We
|
||||||
|
* use tsc for that.
|
||||||
|
*/
|
||||||
|
});
|
||||||
19
apps/server/turbo.json
Normal file
19
apps/server/turbo.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"extends": ["//"],
|
||||||
|
"globalDependencies": [".env"],
|
||||||
|
"tasks": {
|
||||||
|
"build": {
|
||||||
|
"env": ["DEMO_ENV_VAR"],
|
||||||
|
"dependsOn": ["^build"],
|
||||||
|
"outputs": ["dist/**"]
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"dependsOn": ["^build"],
|
||||||
|
"outputs": ["coverage/**"],
|
||||||
|
"inputs": ["src/**/*.tsx", "src/**/*.ts"]
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"dependsOn": ["^lint"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
32
package.json
Normal file
32
package.json
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "@colanode",
|
||||||
|
"description": "Colanode monorepo",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"packageManager": "pnpm@9.0.4+sha256.caa915eaae9d9aefccf50ee8aeda25a2f8684d8f9d5c6e367eaf176d97c1f89e",
|
||||||
|
"author": "Hakan Shehu",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/colanode/colanode"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"compile": "turbo run compile",
|
||||||
|
"build": "turbo run build",
|
||||||
|
"clean": "turbo run clean",
|
||||||
|
"dev": "turbo run dev",
|
||||||
|
"watch": "turbo watch build --filter=@colanode/core --filter=@colanode/server",
|
||||||
|
"lint": "turbo run lint --parallel",
|
||||||
|
"test": "turbo run test -- --watch false",
|
||||||
|
"format": "prettier --write ."
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/lodash-es": "^4.17.12",
|
||||||
|
"prettier": "^3.3.3",
|
||||||
|
"turbo": "^2.1.3",
|
||||||
|
"typescript": "^5.6.3",
|
||||||
|
"vitest": "^1.6.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"lodash-es": "^4.17.21"
|
||||||
|
}
|
||||||
|
}
|
||||||
26
packages/core/package.json
Normal file
26
packages/core/package.json
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "@colanode/core",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"types": "./src/index.ts",
|
||||||
|
"exports": {
|
||||||
|
".": "./src/index.ts"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"compile": "tsc --noEmit",
|
||||||
|
"test": "vitest",
|
||||||
|
"lint": "eslint . --max-warnings 0",
|
||||||
|
"build?": "No build step required. This package links directly to its source files",
|
||||||
|
"coverage": "vitest run --coverage "
|
||||||
|
},
|
||||||
|
"author": "Hakan Shehu",
|
||||||
|
"devDependencies": {
|
||||||
|
"eslint": "^8.57.1",
|
||||||
|
"prettier": "^3.3.3",
|
||||||
|
"typescript": "^5.6.3",
|
||||||
|
"vitest": "^1.6.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
3
packages/core/src/index.ts
Normal file
3
packages/core/src/index.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
export const core = () => {
|
||||||
|
return 'core library';
|
||||||
|
};
|
||||||
10
packages/core/tsconfig.json
Normal file
10
packages/core/tsconfig.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/tsconfig",
|
||||||
|
"display": "Core Library",
|
||||||
|
"extends": "../../tsconfig.base.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"declaration": true,
|
||||||
|
"declarationMap": true,
|
||||||
|
"composite": true
|
||||||
|
}
|
||||||
|
}
|
||||||
13
packages/core/vitest.config.ts
Normal file
13
packages/core/vitest.config.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import path from 'node:path';
|
||||||
|
import { configDefaults, defineConfig } from 'vitest/config';
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
test: {
|
||||||
|
exclude: [...configDefaults.exclude],
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'~': path.resolve(__dirname, './src'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
6016
pnpm-lock.yaml
generated
Normal file
6016
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
3
pnpm-workspace.yaml
Normal file
3
pnpm-workspace.yaml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
packages:
|
||||||
|
- "apps/*"
|
||||||
|
- "packages/*"
|
||||||
5822
server/package-lock.json
generated
5822
server/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "ES2020",
|
|
||||||
"module": "commonjs",
|
|
||||||
"outDir": "./dist",
|
|
||||||
"rootDir": "./src",
|
|
||||||
"strict": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"noEmit": false,
|
|
||||||
"baseUrl": ".",
|
|
||||||
"paths": {
|
|
||||||
"@/*": ["./src/*"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
34
tsconfig.base.json
Normal file
34
tsconfig.base.json
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://json.schemastore.org/tsconfig",
|
||||||
|
"display": "Base Configuration",
|
||||||
|
"compilerOptions": {
|
||||||
|
/* Base Options: */
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"target": "esnext",
|
||||||
|
"lib": ["esnext"],
|
||||||
|
"allowJs": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"moduleDetection": "force",
|
||||||
|
"isolatedModules": true,
|
||||||
|
"verbatimModuleSyntax": false,
|
||||||
|
|
||||||
|
/* Strictness */
|
||||||
|
"strict": true,
|
||||||
|
"noUncheckedIndexedAccess": true,
|
||||||
|
"noImplicitOverride": true,
|
||||||
|
|
||||||
|
/* Opinion */
|
||||||
|
"incremental": true,
|
||||||
|
"tsBuildInfoFile": "${configDir}/tsconfig.tsbuildinfo",
|
||||||
|
"module": "preserve",
|
||||||
|
"outDir": "${configDir}/dist",
|
||||||
|
"baseUrl": "${configDir}",
|
||||||
|
"rootDir": "${configDir}/src",
|
||||||
|
"paths": {
|
||||||
|
"~/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["${configDir}/src", "${configDir}/src/**/*.json"],
|
||||||
|
"exclude": ["${configDir}/node_modules", "${configDir}/dist"]
|
||||||
|
}
|
||||||
24
turbo.json
Normal file
24
turbo.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"$schema": "https://turbo.build/schema.json",
|
||||||
|
"globalDependencies": [".env", "**/.env.*local"],
|
||||||
|
"tasks": {
|
||||||
|
"build": {
|
||||||
|
"dependsOn": ["^build"],
|
||||||
|
"outputs": ["dist/**"]
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
"dependsOn": ["^lint"]
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"dependsOn": ["^build"],
|
||||||
|
"outputs": ["coverage/**"],
|
||||||
|
"inputs": ["src/**/*.tsx", "src/**/*.ts", "test/**/*.ts", "test/**/*.tsx"]
|
||||||
|
},
|
||||||
|
"compile": {
|
||||||
|
"dependsOn": ["^compile"]
|
||||||
|
},
|
||||||
|
"clean": {
|
||||||
|
"dependsOn": ["^clean"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
vitest.workspace.ts
Normal file
3
vitest.workspace.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import { defineWorkspace } from "vitest/config";
|
||||||
|
|
||||||
|
export default defineWorkspace(["packages/*", "apps/*"]);
|
||||||
Reference in New Issue
Block a user