op-tasks-cli 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -0
- package/package.json +1 -1
- package/npm_recovery_codes.txt +0 -5
- package/src/commands/init.ts +0 -17
- package/src/commands/login.ts +0 -17
- package/src/commands/sync.ts +0 -109
- package/src/index.ts +0 -17
- package/src/services/openProject.ts +0 -68
- package/src/utils/config.ts +0 -26
- package/src/utils/fileSync.ts +0 -71
- package/tsconfig.json +0 -16
package/README.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Open Project Tasks CLI (op-tasks)
|
|
2
|
+
|
|
3
|
+
Uma interface de linha de comando (CLI) simples para baixar e sincronizar suas tarefas do [Open Project](https://www.openproject.org/) com arquivos Markdown (MD) locais.
|
|
4
|
+
|
|
5
|
+
## Instalação e Execução
|
|
6
|
+
|
|
7
|
+
Você não precisa instalar o pacote de forma permanente, basta usar o `npx` para baixar e executar a versão mais recente em qualquer diretório:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx op-tasks-cli [comando]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Como Usar
|
|
14
|
+
|
|
15
|
+
### 1. Login
|
|
16
|
+
O primeiro passo é fazer o login para salvar sua URL do servidor e seu Token de API localmente na sua máquina. O Token é salvo de forma segura no seu diretório `home`.
|
|
17
|
+
|
|
18
|
+
Para gerar um Token, vá no seu Open Project > "Minha Conta" (My Account) > "Tokens de Acesso" (Access tokens) > API.
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npx op-tasks-cli login <sua-url-do-open-project> <seu-token-api>
|
|
22
|
+
```
|
|
23
|
+
*Exemplo:* `npx op-tasks-cli login https://projetos.minhaempresa.com.br abc123def456`
|
|
24
|
+
|
|
25
|
+
### 2. Inicializar um Diretório
|
|
26
|
+
Vá até a pasta do seu computador onde você deseja salvar e gerenciar suas tarefas e inicialize a estrutura:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npx op-tasks-cli init
|
|
30
|
+
```
|
|
31
|
+
Isso criará uma pasta oculta chamada `.tasksOP` no diretório atual. É aqui que todos os seus arquivos Markdown serão armazenados.
|
|
32
|
+
|
|
33
|
+
### 3. Sincronizar (Download & Upload)
|
|
34
|
+
Para baixar novas tarefas ou enviar atualizações para o Open Project, use:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npx op-tasks-cli sync
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Como a sincronização funciona:**
|
|
41
|
+
- **Download:** Se houver novas tarefas atribuídas a você no Open Project, a CLI fará o download e criará os arquivos Markdown correspondentes na pasta `.tasksOP`.
|
|
42
|
+
- **Upload:** Se você alterar o status de uma tarefa no arquivo local para um status de conclusão (ex: `Closed`, `Concluída`, `Done`), a CLI avisará o Open Project e fechará a tarefa lá também!
|
|
43
|
+
|
|
44
|
+
## Formato dos Arquivos
|
|
45
|
+
|
|
46
|
+
Cada tarefa é salva como um arquivo Markdown com metadados (_Frontmatter_) no topo. Exemplo:
|
|
47
|
+
|
|
48
|
+
```yaml
|
|
49
|
+
---
|
|
50
|
+
id: 1234
|
|
51
|
+
subject: Corrigir bug no formulário de contato
|
|
52
|
+
status: In progress
|
|
53
|
+
lockVersion: 3
|
|
54
|
+
updatedAt: 2026-05-17T02:00:00Z
|
|
55
|
+
---
|
|
56
|
+
Descrição da tarefa que veio do Open Project.
|
|
57
|
+
Você pode fazer anotações aqui.
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Se quiser marcar a tarefa como concluída no sistema, basta alterar a linha `status:` para `Concluída` e rodar `npx op-tasks-cli sync`.
|
package/package.json
CHANGED
package/npm_recovery_codes.txt
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
18c3852e3b2bd514a6de09f91598374f4a0bc53fb7dbba87549a8101e568405e
|
|
2
|
-
23fc81570c930586fb139d4541548c5c843266429ab6ff1a72e891e50d9a8c1d
|
|
3
|
-
751f6fef546c9638e840f3d2cb59f7a25ebd597d06ee4d832cf4e90e76080dea
|
|
4
|
-
b2c4b475f52800defe158a21c20a40b28a733ef407229f556f1e76149b2c4715
|
|
5
|
-
fe8a4329e0cf7ca2531de556381a3f64b873fa7653853c832a1c9a7ac4b3cd18
|
package/src/commands/init.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import { initTasksDir } from '../utils/fileSync';
|
|
4
|
-
|
|
5
|
-
export function registerInitCommand(program: Command) {
|
|
6
|
-
program
|
|
7
|
-
.command('init')
|
|
8
|
-
.description('Inicializar o diretório de tarefas (.tasksOP) no diretório atual')
|
|
9
|
-
.action(() => {
|
|
10
|
-
const created = initTasksDir();
|
|
11
|
-
if (created) {
|
|
12
|
-
console.log(chalk.green('✔ Diretório .tasksOP criado com sucesso!'));
|
|
13
|
-
} else {
|
|
14
|
-
console.log(chalk.yellow('⚠ Diretório .tasksOP já existe neste local.'));
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
}
|
package/src/commands/login.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import { saveConfig } from '../utils/config';
|
|
4
|
-
|
|
5
|
-
export function registerLoginCommand(program: Command) {
|
|
6
|
-
program
|
|
7
|
-
.command('login')
|
|
8
|
-
.description('Configurar a URL e o Token do Open Project')
|
|
9
|
-
.argument('<url>', 'A URL base do seu servidor Open Project (ex: https://openproject.empresa.com)')
|
|
10
|
-
.argument('<token>', 'O token de API (apikey) gerado no Open Project')
|
|
11
|
-
.action((url: string, token: string) => {
|
|
12
|
-
saveConfig({ url, token });
|
|
13
|
-
console.log(chalk.green('✔ Configuração salva com sucesso!'));
|
|
14
|
-
console.log(chalk.gray(`URL: ${url}`));
|
|
15
|
-
console.log(chalk.gray('Token salvo de forma segura.'));
|
|
16
|
-
});
|
|
17
|
-
}
|
package/src/commands/sync.ts
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
import ora from 'ora';
|
|
4
|
-
import { getConfig } from '../utils/config';
|
|
5
|
-
import { checkTasksDir, getLocalTasks, saveTaskLocally } from '../utils/fileSync';
|
|
6
|
-
import { OpenProjectService, WorkPackage } from '../services/openProject';
|
|
7
|
-
|
|
8
|
-
export function registerSyncCommand(program: Command) {
|
|
9
|
-
program
|
|
10
|
-
.command('sync')
|
|
11
|
-
.description('Sincroniza tarefas do Open Project com a pasta local .tasksOP')
|
|
12
|
-
.action(async () => {
|
|
13
|
-
const config = getConfig();
|
|
14
|
-
if (!config) {
|
|
15
|
-
console.log(chalk.red('✖ Nenhuma configuração encontrada. Execute "op-tasks login <url> <token>" primeiro.'));
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
if (!checkTasksDir()) {
|
|
20
|
-
console.log(chalk.yellow('⚠ Diretório .tasksOP não encontrado. Execute "op-tasks init" primeiro.'));
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const spinner = ora('Iniciando sincronização...').start();
|
|
25
|
-
const opService = new OpenProjectService(config);
|
|
26
|
-
|
|
27
|
-
try {
|
|
28
|
-
// 1. Check local tasks for updates (e.g. status changes)
|
|
29
|
-
spinner.text = 'Verificando tarefas locais...';
|
|
30
|
-
const localTasks = getLocalTasks();
|
|
31
|
-
const localTasksMap = new Map(localTasks.map(t => [t.id, t]));
|
|
32
|
-
|
|
33
|
-
spinner.text = 'Buscando tarefas do Open Project...';
|
|
34
|
-
const userId = await opService.getCurrentUserId();
|
|
35
|
-
const remoteTasks = await opService.getMyWorkPackages(userId);
|
|
36
|
-
const remoteTasksMap = new Map(remoteTasks.map(t => [t.id, t]));
|
|
37
|
-
|
|
38
|
-
// Sync logic:
|
|
39
|
-
// Se uma tarefa local tem um status diferente da remota, a local vence se estivermos atualizando o OP.
|
|
40
|
-
// O caso de uso especifica: "marcar como concluida as que foram dadas como concluidas no open project"
|
|
41
|
-
// Wait, "as que foram dadas como concluidas no open project" - if the user meant:
|
|
42
|
-
// "marcar como concluidas (no OP) as que foram dadas como concluidas (localmente)" - that's upload.
|
|
43
|
-
// "ou marcar como concluidas (localmente) as que foram dadas como concluidas no open project" - that's download.
|
|
44
|
-
// We'll update the Open Project status if the local status changed and the local updatedAt is newer?
|
|
45
|
-
// Actually, markdown doesn't track local updatedAt automatically unless we use fs.stat.
|
|
46
|
-
// Let's do a simple approach: if local status != remote status, we update OP if we assume local changes have priority during sync, OR we just download remote changes.
|
|
47
|
-
// Let's update OP if local status is "Concluída", "Closed", "Fechada", "Done" and remote is not.
|
|
48
|
-
|
|
49
|
-
const completedStatuses = ['closed', 'concluída', 'concluida', 'fechada', 'done'];
|
|
50
|
-
|
|
51
|
-
let updatedRemoteCount = 0;
|
|
52
|
-
for (const localTask of localTasks) {
|
|
53
|
-
const remoteTask = remoteTasksMap.get(localTask.id);
|
|
54
|
-
if (remoteTask) {
|
|
55
|
-
const localIsCompleted = completedStatuses.includes(localTask.status.toLowerCase());
|
|
56
|
-
const remoteIsCompleted = completedStatuses.includes(remoteTask.status.toLowerCase());
|
|
57
|
-
|
|
58
|
-
if (localIsCompleted && !remoteIsCompleted) {
|
|
59
|
-
spinner.text = `Atualizando status da tarefa #${localTask.id} no Open Project...`;
|
|
60
|
-
await opService.updateWorkPackageStatus(localTask.id, remoteTask.lockVersion, localTask.status);
|
|
61
|
-
updatedRemoteCount++;
|
|
62
|
-
// After updating, update our local copy of remoteTask to have the new status so we don't overwrite it locally in the next step
|
|
63
|
-
remoteTask.status = localTask.status;
|
|
64
|
-
} else if (localTask.status !== remoteTask.status) {
|
|
65
|
-
// If there's another difference, we can choose to push local status or pull remote status.
|
|
66
|
-
// To be safe, we'll push local status to OP if they differ and we want local to be the source of truth for status.
|
|
67
|
-
spinner.text = `Atualizando status da tarefa #${localTask.id} no Open Project...`;
|
|
68
|
-
try {
|
|
69
|
-
await opService.updateWorkPackageStatus(localTask.id, remoteTask.lockVersion, localTask.status);
|
|
70
|
-
updatedRemoteCount++;
|
|
71
|
-
remoteTask.status = localTask.status;
|
|
72
|
-
} catch (e: any) {
|
|
73
|
-
// Ignore if status is not valid
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// 2. Download remote tasks to local (Creates new ones and updates existing ones)
|
|
80
|
-
spinner.text = 'Sincronizando tarefas para o diretório local...';
|
|
81
|
-
let updatedLocalCount = 0;
|
|
82
|
-
let createdLocalCount = 0;
|
|
83
|
-
|
|
84
|
-
for (const remoteTask of remoteTasks) {
|
|
85
|
-
const localTask = localTasksMap.get(remoteTask.id);
|
|
86
|
-
if (!localTask) {
|
|
87
|
-
saveTaskLocally(remoteTask);
|
|
88
|
-
createdLocalCount++;
|
|
89
|
-
} else {
|
|
90
|
-
// Se a tarefa remota for mais nova, ou se a gente acabou de atualizar o remoteTask, salvamos.
|
|
91
|
-
saveTaskLocally(remoteTask);
|
|
92
|
-
updatedLocalCount++;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
spinner.succeed(chalk.green('Sincronização concluída com sucesso!'));
|
|
97
|
-
console.log(chalk.gray(`Tarefas baixadas/atualizadas localmente: ${createdLocalCount + updatedLocalCount}`));
|
|
98
|
-
console.log(chalk.gray(`Tarefas atualizadas no Open Project: ${updatedRemoteCount}`));
|
|
99
|
-
|
|
100
|
-
} catch (error: any) {
|
|
101
|
-
spinner.fail(chalk.red('Erro durante a sincronização.'));
|
|
102
|
-
console.error(chalk.red(error.message || error));
|
|
103
|
-
if (error.response) {
|
|
104
|
-
console.error(chalk.gray(`Status: ${error.response.status}`));
|
|
105
|
-
console.error(chalk.gray(JSON.stringify(error.response.data)));
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
}
|
package/src/index.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import { registerLoginCommand } from './commands/login';
|
|
3
|
-
import { registerInitCommand } from './commands/init';
|
|
4
|
-
import { registerSyncCommand } from './commands/sync';
|
|
5
|
-
|
|
6
|
-
const program = new Command();
|
|
7
|
-
|
|
8
|
-
program
|
|
9
|
-
.name('op-tasks')
|
|
10
|
-
.description('CLI para sincronizar tarefas do Open Project localmente')
|
|
11
|
-
.version('1.0.0');
|
|
12
|
-
|
|
13
|
-
registerLoginCommand(program);
|
|
14
|
-
registerInitCommand(program);
|
|
15
|
-
registerSyncCommand(program);
|
|
16
|
-
|
|
17
|
-
program.parse();
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import axios, { AxiosInstance } from 'axios';
|
|
2
|
-
import { Config } from '../utils/config';
|
|
3
|
-
|
|
4
|
-
export interface WorkPackage {
|
|
5
|
-
id: number;
|
|
6
|
-
subject: string;
|
|
7
|
-
description: string;
|
|
8
|
-
status: string;
|
|
9
|
-
lockVersion: number;
|
|
10
|
-
updatedAt: string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export class OpenProjectService {
|
|
14
|
-
private client: AxiosInstance;
|
|
15
|
-
|
|
16
|
-
constructor(config: Config) {
|
|
17
|
-
this.client = axios.create({
|
|
18
|
-
baseURL: config.url.endsWith('/') ? config.url.slice(0, -1) : config.url,
|
|
19
|
-
headers: {
|
|
20
|
-
Authorization: `Basic ${Buffer.from(`apikey:${config.token}`).toString('base64')}`,
|
|
21
|
-
'Content-Type': 'application/json',
|
|
22
|
-
},
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async getCurrentUserId(): Promise<number> {
|
|
27
|
-
const response = await this.client.get('/api/v3/users/me');
|
|
28
|
-
return response.data.id;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async getMyWorkPackages(userId: number): Promise<WorkPackage[]> {
|
|
32
|
-
const filters = encodeURIComponent(
|
|
33
|
-
JSON.stringify([{ assignee: { operator: '=', values: [String(userId)] } }])
|
|
34
|
-
);
|
|
35
|
-
// Fetch more per page if needed, default is usually 20, let's set pageSize=100
|
|
36
|
-
const response = await this.client.get(`/api/v3/work_packages?pageSize=100&filters=${filters}`);
|
|
37
|
-
|
|
38
|
-
return response.data._embedded.elements.map((item: any) => ({
|
|
39
|
-
id: item.id,
|
|
40
|
-
subject: item.subject,
|
|
41
|
-
description: item.description?.raw || '',
|
|
42
|
-
status: item._links.status.title,
|
|
43
|
-
lockVersion: item.lockVersion,
|
|
44
|
-
updatedAt: item.updatedAt,
|
|
45
|
-
}));
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
async updateWorkPackageStatus(id: number, lockVersion: number, statusName: string): Promise<void> {
|
|
49
|
-
// First, we need to find the status ID for the given status name
|
|
50
|
-
// A more robust way is to fetch all statuses and find the id
|
|
51
|
-
const statusesResponse = await this.client.get('/api/v3/statuses');
|
|
52
|
-
const statuses = statusesResponse.data._embedded.elements;
|
|
53
|
-
const targetStatus = statuses.find((s: any) => s.name.toLowerCase() === statusName.toLowerCase());
|
|
54
|
-
|
|
55
|
-
if (!targetStatus) {
|
|
56
|
-
throw new Error(`Status "${statusName}" not found in OpenProject.`);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
await this.client.patch(`/api/v3/work_packages/${id}`, {
|
|
60
|
-
lockVersion,
|
|
61
|
-
_links: {
|
|
62
|
-
status: {
|
|
63
|
-
href: targetStatus._links.self.href,
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
}
|
package/src/utils/config.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import os from 'os';
|
|
4
|
-
|
|
5
|
-
const configFilePath = path.join(os.homedir(), '.op-tasks-config.json');
|
|
6
|
-
|
|
7
|
-
export interface Config {
|
|
8
|
-
url: string;
|
|
9
|
-
token: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function getConfig(): Config | null {
|
|
13
|
-
if (!fs.existsSync(configFilePath)) {
|
|
14
|
-
return null;
|
|
15
|
-
}
|
|
16
|
-
try {
|
|
17
|
-
const data = fs.readFileSync(configFilePath, 'utf8');
|
|
18
|
-
return JSON.parse(data) as Config;
|
|
19
|
-
} catch (error) {
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function saveConfig(config: Config): void {
|
|
25
|
-
fs.writeFileSync(configFilePath, JSON.stringify(config, null, 2), 'utf8');
|
|
26
|
-
}
|
package/src/utils/fileSync.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import matter from 'gray-matter';
|
|
4
|
-
import { WorkPackage } from '../services/openProject';
|
|
5
|
-
|
|
6
|
-
const TASKS_DIR = path.join(process.cwd(), '.tasksOP');
|
|
7
|
-
|
|
8
|
-
export interface LocalTask extends WorkPackage {
|
|
9
|
-
filePath: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export function initTasksDir(): boolean {
|
|
13
|
-
if (!fs.existsSync(TASKS_DIR)) {
|
|
14
|
-
fs.mkdirSync(TASKS_DIR, { recursive: true });
|
|
15
|
-
return true; // Created
|
|
16
|
-
}
|
|
17
|
-
return false; // Already exists
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function checkTasksDir(): boolean {
|
|
21
|
-
return fs.existsSync(TASKS_DIR);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function sanitizeFileName(name: string): string {
|
|
25
|
-
return name.replace(/[^a-z0-9]/gi, '_').toLowerCase();
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function saveTaskLocally(task: WorkPackage): void {
|
|
29
|
-
initTasksDir();
|
|
30
|
-
const fileName = `${task.id}-${sanitizeFileName(task.subject)}.md`;
|
|
31
|
-
const filePath = path.join(TASKS_DIR, fileName);
|
|
32
|
-
|
|
33
|
-
const content = matter.stringify(task.description || 'Nenhuma descrição fornecida.', {
|
|
34
|
-
id: task.id,
|
|
35
|
-
subject: task.subject,
|
|
36
|
-
status: task.status,
|
|
37
|
-
lockVersion: task.lockVersion,
|
|
38
|
-
updatedAt: task.updatedAt,
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
fs.writeFileSync(filePath, content, 'utf8');
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function getLocalTasks(): LocalTask[] {
|
|
45
|
-
if (!fs.existsSync(TASKS_DIR)) {
|
|
46
|
-
return [];
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const files = fs.readdirSync(TASKS_DIR).filter((file: string) => file.endsWith('.md'));
|
|
50
|
-
const tasks: LocalTask[] = [];
|
|
51
|
-
|
|
52
|
-
for (const file of files) {
|
|
53
|
-
const filePath = path.join(TASKS_DIR, file);
|
|
54
|
-
const content = fs.readFileSync(filePath, 'utf8');
|
|
55
|
-
const parsed = matter(content);
|
|
56
|
-
|
|
57
|
-
if (parsed.data.id) {
|
|
58
|
-
tasks.push({
|
|
59
|
-
id: parsed.data.id,
|
|
60
|
-
subject: parsed.data.subject,
|
|
61
|
-
status: parsed.data.status,
|
|
62
|
-
lockVersion: parsed.data.lockVersion,
|
|
63
|
-
updatedAt: parsed.data.updatedAt,
|
|
64
|
-
description: parsed.content.trim(),
|
|
65
|
-
filePath,
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return tasks;
|
|
71
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "es2018",
|
|
4
|
-
"module": "commonjs",
|
|
5
|
-
"moduleResolution": "node",
|
|
6
|
-
"rootDir": "./src",
|
|
7
|
-
"outDir": "./dist",
|
|
8
|
-
"esModuleInterop": true,
|
|
9
|
-
"forceConsistentCasingInFileNames": true,
|
|
10
|
-
"strict": true,
|
|
11
|
-
"skipLibCheck": true,
|
|
12
|
-
"types": ["node"],
|
|
13
|
-
"ignoreDeprecations": "6.0"
|
|
14
|
-
},
|
|
15
|
-
"include": ["src/**/*"]
|
|
16
|
-
}
|