Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module.exports = {
root: true,
plugins: ['import', 'unicorn', '@tanstack/query', 'sonarjs'],
extends: [
'@internxt/eslint-config-internxt',
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/check-pr-size.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ on:
jobs:
check_pr_size:
# Ignore PRs with name merge-X-X-X-release
if: |
!(startsWith(github.head_ref, 'merge-') && endsWith(github.head_ref, '-release') && github.base_ref == 'main')
if: false
# if: |
# !(startsWith(github.head_ref, 'merge-') && endsWith(github.head_ref, '-release') && github.base_ref == 'main')
runs-on: ubuntu-latest
timeout-minutes: 1

Expand Down
31 changes: 31 additions & 0 deletions .github/workflows/core-find-deadcode.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Core find deadcode

on:
pull_request:
paths: ['packages/core/**']
types: [opened, synchronize, reopened]

jobs:
find_deadcode:
runs-on: ubuntu-latest
timeout-minutes: 5
defaults:
run:
working-directory: packages/core

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20

- name: Install dependencies
run: npm ci

- name: Find deadcode
run: npm run find-deadcode
49 changes: 49 additions & 0 deletions .github/workflows/core-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Publish

on:
workflow_dispatch:

jobs:
publish:
runs-on: ubuntu-latest
timeout-minutes: 1
defaults:
run:
working-directory: packages/core

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20

- name: Install dependencies
run: npm ci

- name: Build
run: npm run build

- name: Create .npmrc file
shell: bash
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
echo "@internxt:registry=https://npm.pkg.github.com" > .npmrc
echo "//npm.pkg.github.com/:_authToken=$GITHUB_TOKEN" >> .npmrc

- name: Publish package to github
run: npm publish --scope=@internxt --access public

- name: Create .npmrc file
shell: bash
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
echo "registry=https://registry.npmjs.org/" > .npmrc
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> .npmrc

- name: Publish package to npm
run: npm publish --scope=@internxt --access public
37 changes: 37 additions & 0 deletions .github/workflows/core-pull-request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Core pull request

on:
pull_request:
paths: ['packages/core/**']
types: [opened, synchronize, reopened]

jobs:
pull_request:
runs-on: ubuntu-latest
timeout-minutes: 5
defaults:
run:
working-directory: packages/core

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20

- name: Install dependencies
run: npm ci

- name: Run TypeScript compiler
run: npm run type-check

- name: Run Prettier
run: npm run format

- name: Run Eslint
run: npm run lint
39 changes: 39 additions & 0 deletions .github/workflows/core-sonar-analysis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Core sonar analysis

on:
pull_request:
paths: ['packages/core/**']
types: [opened, synchronize, reopened]
push:
paths: ['packages/core/**']
branches: ['master']

jobs:
sonar_analysis:
runs-on: windows-latest
timeout-minutes: 10
defaults:
run:
working-directory: packages/core

steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20

- name: Install dependencies
run: npm ci

- name: Run tests
run: npm run test:cov

# - name: SonarQube Scan
# uses: SonarSource/sonarqube-scan-action@1a6d90ebcb0e6a6b1d87e37ba693fe453195ae25 # v5.3.1
# env:
# SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
182 changes: 182 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
# Contributing

## Table of Contents

- [Architecture](#architecture)
- [Code](#code)
- [File template](#file-template)
- [Testing](#testing)
- [Imports](#imports)
- [Use function instead of arrow functions by default](#use-function-instead-of-arrow-functions-by-default)
- [Use object props instead of multiple props](#use-object-props-instead-of-multiple-props)
- [Never use return types if the function infers the type correctly](#never-use-return-types-if-the-function-infers-the-type-correctly)
- [Logger](#logger)
- [Comments](#comments)
- [Frontend](#frontend)

## Architecture

```
📁 backend
📁 core
📁 logger
📁 utils
📁 infra
📁 drive-server-wip
📁 sqlite
📄 sqlite.module.ts
📁 services
📄 function1.ts
📄 function2.ts
📁 features
📁 backups
📁 sync
📄 sync.module.ts
📁 services
📄 function1.ts
📄 function2.ts
📁 frontend
📁 core
📁 api
```

## Code

### File template

```ts
type Props = { prop1: A; prop2: B };

export function fn({ prop1, prop2 }: Props) {}
```

### Testing

See [docs/TESTING.md](https://github.com/internxt/drive-desktop-core/blob/master/docs/TESTING.md).

### Imports

Always import the function used, not the module. This is to be consistent and import everything in the same way.

```ts
// bad
import fs from 'node:fs';
// good
import { stat } from 'node:fs';
```

### Use function instead of arrow functions by default

---

We recommend always creating functions using the `function` keyword because:

- We use the eslint `no-use-before-define` rule and we need to skip checking functions because they are hoisted (we cannot do this with arrow functions).

We only use arrow functions when we want to define a function using a type.

```ts
// bad
const connect = () => {}
// good
function connect() {}
// good
type func = () => void;
const connect: func = () => {}
```

### Use object props instead of multiple props

---

https://github.com/internxt/drive-desktop/issues/545

```ts
// bad
function connect(host: string, port: number) {}
// good
function connect({ host, port }: { host: string; port: number }) {}
// default parameters
function connect({ host, port = 5432 }: { host: string; port?: number }) {}
```

### Never use return types if the function infers the type correctly

---

We believe that using return types presents more problems than advantages:

- Naming return types.
- Maintaining return types.

However, using return types has one advantage: if a function is supposed to return a `boolean` value and we forget to add a return value, it will infer an `undefined` value and we might start checking that function's return value using the wrong `undefined`. To solve this, we use the TypeScript rule `noImplicitReturns` to ensure that we don't forget to return a value in all branches of a function and that the function doesn't return `undefined` without explicitly defining it.

```ts
// bad
function getNumber(): number {
return 8;
}
// good
function getNumber() {
return 8;
}
```

### Logger

---

Use logger.error for errors that should be logged in `drive-important.log` and logger.warn for all other errors. Almost all errors should be logged with logger.error. Do not concatenate strings in msg, otherwise it's more difficult to extend a log and also we won't have multiple colors for each prop.

```ts
logger.debug({
tag: 'TAG',
msg: 'Some message',
prop1,
prop2,
});
```

### Comments

---

```ts
/**
* vX.X.X Author
* Explain why it's done that way, not what it does.
* We should be able to understand what it does by reading the code, but not why we did it that way; that's the point of the comment.
* Also, don't delete these comments. The plan is for it to function as an Architecture Decision Record.
* Whenever we change something, we should retain the comments from the previous version to see the history of the decision.
*/
```

### Frontend

We'll follow a structure similar to Angular's with services and components. The service will be a hook that manages all the logic. Both the service and the component will be stored in the same file.

```ts
export function useComponent() {
const { t } = useI18n();
const { data, status } = useCustomHook();

const value = useMemo(() => {
switch (status) {
case 'loading':
return t('loading');
case 'error':
return '';
case 'success': {
return data;
}
}
}, [status]);

return { value };
}

export function Component() {
const { value } = useComponent();
return <p>{value}</p>;
}
```
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@

[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=internxt_node-win&metric=ncloc)](https://sonarcloud.io/summary/new_code?id=internxt_node-win) [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=internxt_node-win&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=internxt_node-win) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=internxt_node-win&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=internxt_node-win) [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=internxt_node-win&metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=internxt_node-win) [![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=internxt_node-win&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=internxt_node-win) [![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=internxt_node-win&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=internxt_node-win) [![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=internxt_node-win&metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=internxt_node-win) [![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=internxt_node-win&metric=sqale_index)](https://sonarcloud.io/summary/new_code?id=internxt_node-win) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=internxt_node-win&metric=coverage)](https://sonarcloud.io/summary/new_code?id=internxt_node-win) [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=internxt_node-win&metric=bugs)](https://sonarcloud.io/summary/new_code?id=internxt_node-win)

## Core

[![node](https://img.shields.io/badge/node-18-iron)](https://nodejs.org/download/release/latest-iron/) [![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=internxt_drive-desktop-core&metric=ncloc)](https://sonarcloud.io/summary/new_code?id=internxt_drive-desktop-core) [![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=internxt_drive-desktop-core&metric=sqale_rating)](https://sonarcloud.io/summary/new_code?id=internxt_drive-desktop-core) [![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=internxt_drive-desktop-core&metric=security_rating)](https://sonarcloud.io/summary/new_code?id=internxt_drive-desktop-core) [![Reliability Rating](https://sonarcloud.io/api/project_badges/measure?project=internxt_drive-desktop-core&metric=reliability_rating)](https://sonarcloud.io/summary/new_code?id=internxt_drive-desktop-core) [![Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=internxt_drive-desktop-core&metric=vulnerabilities)](https://sonarcloud.io/summary/new_code?id=internxt_drive-desktop-core) [![Code Smells](https://sonarcloud.io/api/project_badges/measure?project=internxt_drive-desktop-core&metric=code_smells)](https://sonarcloud.io/summary/new_code?id=internxt_drive-desktop-core) [![Duplicated Lines (%)](https://sonarcloud.io/api/project_badges/measure?project=internxt_drive-desktop-core&metric=duplicated_lines_density)](https://sonarcloud.io/summary/new_code?id=internxt_drive-desktop-core) [![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=internxt_drive-desktop-core&metric=sqale_index)](https://sonarcloud.io/summary/new_code?id=internxt_drive-desktop-core) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=internxt_drive-desktop-core&metric=coverage)](https://sonarcloud.io/summary/new_code?id=internxt_drive-desktop-core) [![Bugs](https://sonarcloud.io/api/project_badges/measure?project=internxt_drive-desktop-core&metric=bugs)](https://sonarcloud.io/summary/new_code?id=internxt_drive-desktop-core)

# Setup

## Windows
Expand Down
Loading
Loading