@taggr/cli 1.0.0
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 +112 -0
- package/dist/commands/list.d.ts +2 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +41 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/login.d.ts +4 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +30 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +2 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +18 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/pull.d.ts +6 -0
- package/dist/commands/pull.d.ts.map +1 -0
- package/dist/commands/pull.js +87 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/whoami.d.ts +2 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +28 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +43 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/api.d.ts +18 -0
- package/dist/utils/api.d.ts.map +1 -0
- package/dist/utils/api.js +80 -0
- package/dist/utils/api.js.map +1 -0
- package/dist/utils/config.d.ts +22 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +66 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/generator.d.ts +18 -0
- package/dist/utils/generator.d.ts.map +1 -0
- package/dist/utils/generator.js +102 -0
- package/dist/utils/generator.js.map +1 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# @taggr/cli
|
|
2
|
+
|
|
3
|
+
CLI tool for Taggr - Pull and manage your labels locally.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @taggr/cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
1. **Get your token** from Taggr Tokens page
|
|
14
|
+
|
|
15
|
+
2. **Login** with your token:
|
|
16
|
+
```bash
|
|
17
|
+
taggr login <your-token>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
3. **Pull your labels**:
|
|
21
|
+
```bash
|
|
22
|
+
# Pull a specific label
|
|
23
|
+
taggr pull my-label
|
|
24
|
+
|
|
25
|
+
# Pull all labels
|
|
26
|
+
taggr pull --all
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
4. **Use in your code**:
|
|
30
|
+
```javascript
|
|
31
|
+
import labels from './taggr/labels.json';
|
|
32
|
+
|
|
33
|
+
console.log(labels.myLabel);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Commands
|
|
37
|
+
|
|
38
|
+
| Command | Description |
|
|
39
|
+
|---------|-------------|
|
|
40
|
+
| `taggr login <token>` | Authenticate with your token |
|
|
41
|
+
| `taggr logout` | Remove saved credentials |
|
|
42
|
+
| `taggr whoami` | Show current authenticated user |
|
|
43
|
+
| `taggr list` | List all your labels |
|
|
44
|
+
| `taggr pull <name>` | Pull a specific label |
|
|
45
|
+
| `taggr pull --all` | Pull all labels |
|
|
46
|
+
|
|
47
|
+
## Options
|
|
48
|
+
|
|
49
|
+
### Login
|
|
50
|
+
```bash
|
|
51
|
+
taggr login <token> [options]
|
|
52
|
+
|
|
53
|
+
Options:
|
|
54
|
+
-u, --url <url> API URL (default: http://localhost:5000/api)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Pull
|
|
58
|
+
```bash
|
|
59
|
+
taggr pull [name] [options]
|
|
60
|
+
|
|
61
|
+
Options:
|
|
62
|
+
-a, --all Pull all labels
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Generated Files
|
|
66
|
+
|
|
67
|
+
When you run `taggr pull`, files are created in a `./taggr` directory:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
./taggr/
|
|
71
|
+
├── labels.json # All your labels
|
|
72
|
+
└── labels.d.ts # TypeScript definitions for autocomplete
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### labels.json
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"myLabel": "your-label-value",
|
|
79
|
+
"anotherLabel": "another-value"
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### labels.d.ts
|
|
84
|
+
```typescript
|
|
85
|
+
declare const labels: {
|
|
86
|
+
myLabel: string;
|
|
87
|
+
anotherLabel: string;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export default labels;
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Usage Examples
|
|
94
|
+
|
|
95
|
+
### Import and use labels
|
|
96
|
+
```javascript
|
|
97
|
+
import labels from './taggr/labels.json';
|
|
98
|
+
|
|
99
|
+
console.log(labels.myLabel);
|
|
100
|
+
console.log(labels.anotherLabel);
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### TypeScript/JavaScript Support
|
|
104
|
+
The `labels.d.ts` file provides autocomplete in VS Code and other editors for both TypeScript and JavaScript projects.
|
|
105
|
+
|
|
106
|
+
## Configuration
|
|
107
|
+
|
|
108
|
+
The CLI stores your token in `~/.taggr/config.json`. This file is created when you run `taggr login`.
|
|
109
|
+
|
|
110
|
+
## License
|
|
111
|
+
|
|
112
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAKA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CA2CjD"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { requireAuth } from '../utils/config.js';
|
|
4
|
+
import { initApi, getLabels } from '../utils/api.js';
|
|
5
|
+
export async function listCommand() {
|
|
6
|
+
const spinner = ora('Fetching labels...').start();
|
|
7
|
+
try {
|
|
8
|
+
const config = await requireAuth();
|
|
9
|
+
initApi(config);
|
|
10
|
+
const { labels, count } = await getLabels();
|
|
11
|
+
spinner.stop();
|
|
12
|
+
if (count === 0) {
|
|
13
|
+
console.log(chalk.yellow('\nNo labels found.'));
|
|
14
|
+
console.log(chalk.dim('Create labels at https://taggr.dev'));
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
console.log();
|
|
18
|
+
console.log(chalk.bold(`Your Labels (${count}):`));
|
|
19
|
+
console.log();
|
|
20
|
+
for (const label of labels) {
|
|
21
|
+
const status = label.isPublished
|
|
22
|
+
? chalk.green('●')
|
|
23
|
+
: chalk.yellow('○');
|
|
24
|
+
console.log(` ${status} ${chalk.white(label.name)} ${chalk.dim(`v${label.version}`)}`);
|
|
25
|
+
if (label.description) {
|
|
26
|
+
console.log(chalk.dim(` ${label.description.substring(0, 60)}${label.description.length > 60 ? '...' : ''}`));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
console.log();
|
|
30
|
+
console.log(chalk.dim('● Published ○ Draft'));
|
|
31
|
+
console.log();
|
|
32
|
+
console.log(chalk.dim('Use "taggr pull <name>" to download a label.'));
|
|
33
|
+
console.log(chalk.dim('Use "taggr pull --all" to download all labels.'));
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
spinner.fail(chalk.red('Failed to fetch labels'));
|
|
37
|
+
console.error(chalk.red(`\nError: ${error.message}`));
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,OAAO,GAAG,GAAG,CAAC,oBAAoB,CAAC,CAAC,KAAK,EAAE,CAAC;IAElD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,WAAW,EAAE,CAAC;QACnC,OAAO,CAAC,MAAM,CAAC,CAAC;QAEhB,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,SAAS,EAAE,CAAC;QAE5C,OAAO,CAAC,IAAI,EAAE,CAAC;QAEf,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC,CAAC;YAC7D,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,KAAK,IAAI,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,EAAE,CAAC;QAEd,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW;gBAC9B,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;gBAClB,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAEtB,OAAO,CAAC,GAAG,CAAC,KAAK,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC;YAExF,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;gBACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YACnH,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC,CAAC;IAC3E,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC,CAAC;QAClD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAOA,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA2B3F"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { saveConfig } from '../utils/config.js';
|
|
4
|
+
import { initApi, whoami } from '../utils/api.js';
|
|
5
|
+
const DEFAULT_API_URL = 'http://localhost:5000/api';
|
|
6
|
+
export async function loginCommand(apiKey, options) {
|
|
7
|
+
const spinner = ora('Verifying API key...').start();
|
|
8
|
+
try {
|
|
9
|
+
const apiUrl = options.url || DEFAULT_API_URL;
|
|
10
|
+
// Initialize API with the provided key
|
|
11
|
+
initApi({ apiKey, apiUrl });
|
|
12
|
+
// Verify the API key by calling whoami
|
|
13
|
+
const { user } = await whoami();
|
|
14
|
+
// Save config
|
|
15
|
+
await saveConfig({ apiKey, apiUrl });
|
|
16
|
+
spinner.succeed(chalk.green('Successfully logged in!'));
|
|
17
|
+
console.log();
|
|
18
|
+
console.log(chalk.dim(' User: ') + chalk.white(user.displayName || user.email));
|
|
19
|
+
console.log(chalk.dim(' Email: ') + chalk.white(user.email));
|
|
20
|
+
console.log(chalk.dim(' Labels: ') + chalk.white(user.stats.totalLabels.toString()));
|
|
21
|
+
console.log();
|
|
22
|
+
console.log(chalk.dim('You can now use "taggr pull" to fetch your labels.'));
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
spinner.fail(chalk.red('Login failed'));
|
|
26
|
+
console.error(chalk.red(`\nError: ${error.message}`));
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,UAAU,EAAa,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,eAAe,GAAG,2BAA2B,CAAC;AAEpD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAc,EAAE,OAAyB;IAC1E,MAAM,OAAO,GAAG,GAAG,CAAC,sBAAsB,CAAC,CAAC,KAAK,EAAE,CAAC;IAEpD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,IAAI,eAAe,CAAC;QAE9C,uCAAuC;QACvC,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAE5B,uCAAuC;QACvC,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,EAAE,CAAC;QAEhC,cAAc;QACd,MAAM,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAErC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAClF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QACtF,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,oDAAoD,CAAC,CAAC,CAAC;IAC/E,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;QACxC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAGA,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAenD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { deleteConfig, isLoggedIn } from '../utils/config.js';
|
|
3
|
+
export async function logoutCommand() {
|
|
4
|
+
try {
|
|
5
|
+
const loggedIn = await isLoggedIn();
|
|
6
|
+
if (!loggedIn) {
|
|
7
|
+
console.log(chalk.yellow('You are not logged in.'));
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
await deleteConfig();
|
|
11
|
+
console.log(chalk.green('Successfully logged out.'));
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAE9D,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,UAAU,EAAE,CAAC;QAEpC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC,CAAC;YACpD,OAAO;QACT,CAAC;QAED,MAAM,YAAY,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull.d.ts","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"AAOA,UAAU,WAAW;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA4D/F"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { requireAuth } from '../utils/config.js';
|
|
4
|
+
import { initApi, getLabels, getLabelByName } from '../utils/api.js';
|
|
5
|
+
import { writeLabelFile, writeAllLabels, updateIndexFile } from '../utils/generator.js';
|
|
6
|
+
export async function pullCommand(name, options) {
|
|
7
|
+
const spinner = ora('Connecting to Taggr...').start();
|
|
8
|
+
try {
|
|
9
|
+
const config = await requireAuth();
|
|
10
|
+
initApi(config);
|
|
11
|
+
if (options.all) {
|
|
12
|
+
// Pull all labels
|
|
13
|
+
spinner.text = 'Fetching all labels...';
|
|
14
|
+
const { labels, count } = await getLabels();
|
|
15
|
+
if (count === 0) {
|
|
16
|
+
spinner.warn(chalk.yellow('No labels found.'));
|
|
17
|
+
console.log(chalk.dim('Create labels at https://taggr.dev'));
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
spinner.text = `Writing ${count} label(s)...`;
|
|
21
|
+
const files = await writeAllLabels(labels);
|
|
22
|
+
spinner.succeed(chalk.green(`Pulled ${count} label(s) successfully!`));
|
|
23
|
+
console.log();
|
|
24
|
+
console.log(chalk.dim('Files created:'));
|
|
25
|
+
for (const file of files) {
|
|
26
|
+
console.log(chalk.dim(` ${file}`));
|
|
27
|
+
}
|
|
28
|
+
console.log();
|
|
29
|
+
printUsageInstructions(labels);
|
|
30
|
+
}
|
|
31
|
+
else if (name) {
|
|
32
|
+
// Pull single label
|
|
33
|
+
spinner.text = `Fetching label "${name}"...`;
|
|
34
|
+
const { label } = await getLabelByName(name);
|
|
35
|
+
spinner.text = 'Writing file...';
|
|
36
|
+
const filePath = await writeLabelFile(label);
|
|
37
|
+
// Update files to include this label
|
|
38
|
+
const { labels: allLabels } = await getLabels();
|
|
39
|
+
await updateIndexFile(allLabels);
|
|
40
|
+
spinner.succeed(chalk.green(`Pulled "${label.name}" successfully!`));
|
|
41
|
+
console.log();
|
|
42
|
+
console.log(chalk.dim('File updated:'));
|
|
43
|
+
console.log(chalk.dim(` ${filePath}`));
|
|
44
|
+
console.log();
|
|
45
|
+
printUsageInstructions([label]);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
spinner.fail(chalk.red('Please specify a label name or use --all'));
|
|
49
|
+
console.log();
|
|
50
|
+
console.log(chalk.dim('Usage:'));
|
|
51
|
+
console.log(chalk.dim(' taggr pull <label-name> Pull a specific label'));
|
|
52
|
+
console.log(chalk.dim(' taggr pull --all Pull all labels'));
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
spinner.fail(chalk.red('Pull failed'));
|
|
58
|
+
console.error(chalk.red(`\nError: ${error.message}`));
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function printUsageInstructions(labels) {
|
|
63
|
+
console.log(chalk.bold('Usage:'));
|
|
64
|
+
console.log();
|
|
65
|
+
if (labels.length === 1) {
|
|
66
|
+
const label = labels[0];
|
|
67
|
+
const varName = toCamelCase(label.name);
|
|
68
|
+
console.log(chalk.dim(' // Import labels'));
|
|
69
|
+
console.log(chalk.white(` import labels from './taggr/labels.json';`));
|
|
70
|
+
console.log();
|
|
71
|
+
console.log(chalk.dim(' // Use the value'));
|
|
72
|
+
console.log(chalk.white(` console.log(labels.${varName});`));
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
console.log(chalk.dim(' // Import labels'));
|
|
76
|
+
console.log(chalk.white(` import labels from './taggr/labels.json';`));
|
|
77
|
+
console.log();
|
|
78
|
+
console.log(chalk.dim(' // Use the values'));
|
|
79
|
+
const firstLabel = labels[0];
|
|
80
|
+
console.log(chalk.white(` console.log(labels.${toCamelCase(firstLabel.name)});`));
|
|
81
|
+
}
|
|
82
|
+
console.log();
|
|
83
|
+
}
|
|
84
|
+
function toCamelCase(str) {
|
|
85
|
+
return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=pull.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pull.js","sourceRoot":"","sources":["../../src/commands/pull.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAKA,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAwBnD"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
import { requireAuth } from '../utils/config.js';
|
|
4
|
+
import { initApi, whoami } from '../utils/api.js';
|
|
5
|
+
export async function whoamiCommand() {
|
|
6
|
+
const spinner = ora('Fetching user info...').start();
|
|
7
|
+
try {
|
|
8
|
+
const config = await requireAuth();
|
|
9
|
+
initApi(config);
|
|
10
|
+
const { user } = await whoami();
|
|
11
|
+
spinner.stop();
|
|
12
|
+
console.log();
|
|
13
|
+
console.log(chalk.bold('Logged in as:'));
|
|
14
|
+
console.log();
|
|
15
|
+
console.log(chalk.dim(' Name: ') + chalk.white(user.displayName || 'Not set'));
|
|
16
|
+
console.log(chalk.dim(' Email: ') + chalk.white(user.email));
|
|
17
|
+
console.log(chalk.dim(' UID: ') + chalk.white(user.uid));
|
|
18
|
+
console.log(chalk.dim(' Labels: ') + chalk.white(user.stats.totalLabels.toString()));
|
|
19
|
+
console.log(chalk.dim(' Joined: ') + chalk.white(new Date(user.createdAt).toLocaleDateString()));
|
|
20
|
+
console.log();
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
spinner.fail(chalk.red('Failed to fetch user info'));
|
|
24
|
+
console.error(chalk.red(`\nError: ${error.message}`));
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=whoami.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAElD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,OAAO,GAAG,GAAG,CAAC,uBAAuB,CAAC,CAAC,KAAK,EAAE,CAAC;IAErD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,WAAW,EAAE,CAAC;QACnC,OAAO,CAAC,MAAM,CAAC,CAAC;QAEhB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,EAAE,CAAC;QAEhC,OAAO,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,IAAI,SAAS,CAAC,CAAC,CAAC;QAClF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QACtF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC;QAClG,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC,CAAC;QACrD,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { loginCommand } from './commands/login.js';
|
|
5
|
+
import { logoutCommand } from './commands/logout.js';
|
|
6
|
+
import { whoamiCommand } from './commands/whoami.js';
|
|
7
|
+
import { listCommand } from './commands/list.js';
|
|
8
|
+
import { pullCommand } from './commands/pull.js';
|
|
9
|
+
const program = new Command();
|
|
10
|
+
program
|
|
11
|
+
.name('taggr')
|
|
12
|
+
.description('CLI tool for Taggr - Pull and manage your labels locally')
|
|
13
|
+
.version('1.0.0');
|
|
14
|
+
// Login command
|
|
15
|
+
program
|
|
16
|
+
.command('login <api-key>')
|
|
17
|
+
.description('Authenticate with your Taggr API key')
|
|
18
|
+
.option('-u, --url <url>', 'API URL (default: http://localhost:5000/api)')
|
|
19
|
+
.action(loginCommand);
|
|
20
|
+
// Logout command
|
|
21
|
+
program
|
|
22
|
+
.command('logout')
|
|
23
|
+
.description('Remove saved API key')
|
|
24
|
+
.action(logoutCommand);
|
|
25
|
+
// Whoami command
|
|
26
|
+
program
|
|
27
|
+
.command('whoami')
|
|
28
|
+
.description('Show current authenticated user')
|
|
29
|
+
.action(whoamiCommand);
|
|
30
|
+
// List command
|
|
31
|
+
program
|
|
32
|
+
.command('list')
|
|
33
|
+
.alias('ls')
|
|
34
|
+
.description('List all your labels')
|
|
35
|
+
.action(listCommand);
|
|
36
|
+
// Pull command
|
|
37
|
+
program
|
|
38
|
+
.command('pull [name]')
|
|
39
|
+
.description('Pull label(s) and generate local files')
|
|
40
|
+
.option('-a, --all', 'Pull all labels')
|
|
41
|
+
.action(pullCommand);
|
|
42
|
+
// Help styling
|
|
43
|
+
program.addHelpText('after', `
|
|
44
|
+
${chalk.bold('Examples:')}
|
|
45
|
+
${chalk.dim('$')} taggr login YOUR_API_KEY ${chalk.dim('# Authenticate with API key')}
|
|
46
|
+
${chalk.dim('$')} taggr list ${chalk.dim('# List all your labels')}
|
|
47
|
+
${chalk.dim('$')} taggr pull my-label ${chalk.dim('# Pull a specific label')}
|
|
48
|
+
${chalk.dim('$')} taggr pull --all ${chalk.dim('# Pull all labels')}
|
|
49
|
+
${chalk.dim('$')} taggr whoami ${chalk.dim('# Show current user')}
|
|
50
|
+
${chalk.dim('$')} taggr logout ${chalk.dim('# Remove saved credentials')}
|
|
51
|
+
|
|
52
|
+
${chalk.bold('After pulling, import your labels:')}
|
|
53
|
+
${chalk.white("import myLabel from './taggr/my-label.js';")}
|
|
54
|
+
${chalk.white('console.log(myLabel.value);')}
|
|
55
|
+
`);
|
|
56
|
+
program.parse();
|
|
57
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,0DAA0D,CAAC;KACvE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,gBAAgB;AAChB,OAAO;KACJ,OAAO,CAAC,iBAAiB,CAAC;KAC1B,WAAW,CAAC,sCAAsC,CAAC;KACnD,MAAM,CAAC,iBAAiB,EAAE,8CAA8C,CAAC;KACzE,MAAM,CAAC,YAAY,CAAC,CAAC;AAExB,iBAAiB;AACjB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,sBAAsB,CAAC;KACnC,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,iBAAiB;AACjB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,iCAAiC,CAAC;KAC9C,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,eAAe;AACf,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,KAAK,CAAC,IAAI,CAAC;KACX,WAAW,CAAC,sBAAsB,CAAC;KACnC,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,eAAe;AACf,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,wCAAwC,CAAC;KACrD,MAAM,CAAC,WAAW,EAAE,iBAAiB,CAAC;KACtC,MAAM,CAAC,WAAW,CAAC,CAAC;AAEvB,eAAe;AACf,OAAO,CAAC,WAAW,CAAC,OAAO,EAAE;EAC3B,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC;IACrB,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,iCAAiC,KAAK,CAAC,GAAG,CAAC,6BAA6B,CAAC;IACvF,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,iCAAiC,KAAK,CAAC,GAAG,CAAC,wBAAwB,CAAC;IAClF,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,iCAAiC,KAAK,CAAC,GAAG,CAAC,yBAAyB,CAAC;IACnF,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,iCAAiC,KAAK,CAAC,GAAG,CAAC,mBAAmB,CAAC;IAC7E,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,iCAAiC,KAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC;IAC/E,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,iCAAiC,KAAK,CAAC,GAAG,CAAC,4BAA4B,CAAC;;EAExF,KAAK,CAAC,IAAI,CAAC,oCAAoC,CAAC;IAC9C,KAAK,CAAC,KAAK,CAAC,4CAA4C,CAAC;IACzD,KAAK,CAAC,KAAK,CAAC,6BAA6B,CAAC;CAC7C,CAAC,CAAC;AAEH,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export interface TaggrConfig {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
apiUrl: string;
|
|
4
|
+
}
|
|
5
|
+
export interface Label {
|
|
6
|
+
name: string;
|
|
7
|
+
displayName: string;
|
|
8
|
+
value: string;
|
|
9
|
+
description: string;
|
|
10
|
+
category: string;
|
|
11
|
+
tags: string[];
|
|
12
|
+
version: string;
|
|
13
|
+
isPublished: boolean;
|
|
14
|
+
packageName: string;
|
|
15
|
+
}
|
|
16
|
+
export interface UserInfo {
|
|
17
|
+
uid: string;
|
|
18
|
+
email: string;
|
|
19
|
+
displayName: string;
|
|
20
|
+
createdAt: string;
|
|
21
|
+
stats: {
|
|
22
|
+
totalLabels: number;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export interface ApiResponse<T> {
|
|
26
|
+
success: boolean;
|
|
27
|
+
data: T;
|
|
28
|
+
error?: {
|
|
29
|
+
code: string;
|
|
30
|
+
message: string;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
export interface LabelsResponse {
|
|
34
|
+
labels: Label[];
|
|
35
|
+
count: number;
|
|
36
|
+
}
|
|
37
|
+
export interface LabelResponse {
|
|
38
|
+
label: Label;
|
|
39
|
+
}
|
|
40
|
+
export interface WhoamiResponse {
|
|
41
|
+
user: UserInfo;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE;QACL,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,KAAK,EAAE,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,KAAK,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,CAAC;CAChB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { LabelsResponse, LabelResponse, WhoamiResponse, TaggrConfig } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Initialize the API client with config
|
|
4
|
+
*/
|
|
5
|
+
export declare function initApi(config: TaggrConfig): void;
|
|
6
|
+
/**
|
|
7
|
+
* Get current user info
|
|
8
|
+
*/
|
|
9
|
+
export declare function whoami(): Promise<WhoamiResponse>;
|
|
10
|
+
/**
|
|
11
|
+
* Get all labels for the user
|
|
12
|
+
*/
|
|
13
|
+
export declare function getLabels(): Promise<LabelsResponse>;
|
|
14
|
+
/**
|
|
15
|
+
* Get a single label by name
|
|
16
|
+
*/
|
|
17
|
+
export declare function getLabelByName(name: string): Promise<LabelResponse>;
|
|
18
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/utils/api.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,cAAc,EACd,aAAa,EACb,cAAc,EACd,WAAW,EACZ,MAAM,aAAa,CAAC;AAIrB;;GAEG;AACH,wBAAgB,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CASjD;AAgCD;;GAEG;AACH,wBAAsB,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC,CAOtD;AAED;;GAEG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,cAAc,CAAC,CAOzD;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAOzE"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import axios, { AxiosError } from 'axios';
|
|
2
|
+
let apiClient = null;
|
|
3
|
+
/**
|
|
4
|
+
* Initialize the API client with config
|
|
5
|
+
*/
|
|
6
|
+
export function initApi(config) {
|
|
7
|
+
apiClient = axios.create({
|
|
8
|
+
baseURL: config.apiUrl,
|
|
9
|
+
headers: {
|
|
10
|
+
'X-API-Key': config.apiKey,
|
|
11
|
+
'Content-Type': 'application/json',
|
|
12
|
+
},
|
|
13
|
+
timeout: 30000,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Get the API client (throws if not initialized)
|
|
18
|
+
*/
|
|
19
|
+
function getClient() {
|
|
20
|
+
if (!apiClient) {
|
|
21
|
+
throw new Error('API client not initialized. Call initApi first.');
|
|
22
|
+
}
|
|
23
|
+
return apiClient;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Handle API errors
|
|
27
|
+
*/
|
|
28
|
+
function handleError(error) {
|
|
29
|
+
if (error instanceof AxiosError) {
|
|
30
|
+
if (error.response) {
|
|
31
|
+
const data = error.response.data;
|
|
32
|
+
if (data.error) {
|
|
33
|
+
throw new Error(data.error.message);
|
|
34
|
+
}
|
|
35
|
+
throw new Error(`API error: ${error.response.status}`);
|
|
36
|
+
}
|
|
37
|
+
if (error.code === 'ECONNREFUSED') {
|
|
38
|
+
throw new Error('Cannot connect to Taggr API. Is the server running?');
|
|
39
|
+
}
|
|
40
|
+
throw new Error(`Network error: ${error.message}`);
|
|
41
|
+
}
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get current user info
|
|
46
|
+
*/
|
|
47
|
+
export async function whoami() {
|
|
48
|
+
try {
|
|
49
|
+
const response = await getClient().get('/cli/whoami');
|
|
50
|
+
return response.data.data;
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
handleError(error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get all labels for the user
|
|
58
|
+
*/
|
|
59
|
+
export async function getLabels() {
|
|
60
|
+
try {
|
|
61
|
+
const response = await getClient().get('/cli/labels');
|
|
62
|
+
return response.data.data;
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
handleError(error);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Get a single label by name
|
|
70
|
+
*/
|
|
71
|
+
export async function getLabelByName(name) {
|
|
72
|
+
try {
|
|
73
|
+
const response = await getClient().get(`/cli/labels/${name}`);
|
|
74
|
+
return response.data.data;
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
handleError(error);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/utils/api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAiB,UAAU,EAAE,MAAM,OAAO,CAAC;AASzD,IAAI,SAAS,GAAyB,IAAI,CAAC;AAE3C;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,MAAmB;IACzC,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC,MAAM;QACtB,OAAO,EAAE;YACP,WAAW,EAAE,MAAM,CAAC,MAAM;YAC1B,cAAc,EAAE,kBAAkB;SACnC;QACD,OAAO,EAAE,KAAK;KACf,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAS,SAAS;IAChB,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,KAAK,YAAY,UAAU,EAAE,CAAC;QAChC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACnB,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,IAA4B,CAAC;YACzD,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACtC,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QACzD,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;QACzE,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,MAAM,KAAK,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM;IAC1B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,SAAS,EAAE,CAAC,GAAG,CAA8B,aAAa,CAAC,CAAC;QACnF,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;IAC5B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,WAAW,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,SAAS,EAAE,CAAC,GAAG,CAA8B,aAAa,CAAC,CAAC;QACnF,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;IAC5B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,WAAW,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY;IAC/C,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,SAAS,EAAE,CAAC,GAAG,CAA6B,eAAe,IAAI,EAAE,CAAC,CAAC;QAC1F,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;IAC5B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,WAAW,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { TaggrConfig } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Get the current configuration
|
|
4
|
+
*/
|
|
5
|
+
export declare function getConfig(): Promise<TaggrConfig | null>;
|
|
6
|
+
/**
|
|
7
|
+
* Save configuration
|
|
8
|
+
*/
|
|
9
|
+
export declare function saveConfig(config: Partial<TaggrConfig>): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Delete configuration (logout)
|
|
12
|
+
*/
|
|
13
|
+
export declare function deleteConfig(): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Check if user is logged in
|
|
16
|
+
*/
|
|
17
|
+
export declare function isLoggedIn(): Promise<boolean>;
|
|
18
|
+
/**
|
|
19
|
+
* Get API key or throw if not logged in
|
|
20
|
+
*/
|
|
21
|
+
export declare function requireAuth(): Promise<TaggrConfig>;
|
|
22
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAc/C;;GAEG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAgB7D;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAO5E;AAED;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAIlD;AAED;;GAEG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAGnD;AAED;;GAEG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,CAQxD"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
const CONFIG_DIR = path.join(os.homedir(), '.taggr');
|
|
5
|
+
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
6
|
+
const DEFAULT_API_URL = 'http://localhost:5000/api';
|
|
7
|
+
/**
|
|
8
|
+
* Ensure config directory exists
|
|
9
|
+
*/
|
|
10
|
+
async function ensureConfigDir() {
|
|
11
|
+
await fs.ensureDir(CONFIG_DIR);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Get the current configuration
|
|
15
|
+
*/
|
|
16
|
+
export async function getConfig() {
|
|
17
|
+
try {
|
|
18
|
+
await ensureConfigDir();
|
|
19
|
+
if (await fs.pathExists(CONFIG_FILE)) {
|
|
20
|
+
const config = await fs.readJson(CONFIG_FILE);
|
|
21
|
+
return {
|
|
22
|
+
apiKey: config.apiKey || '',
|
|
23
|
+
apiUrl: config.apiUrl || DEFAULT_API_URL,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Save configuration
|
|
34
|
+
*/
|
|
35
|
+
export async function saveConfig(config) {
|
|
36
|
+
await ensureConfigDir();
|
|
37
|
+
const existingConfig = await getConfig() || { apiKey: '', apiUrl: DEFAULT_API_URL };
|
|
38
|
+
const newConfig = { ...existingConfig, ...config };
|
|
39
|
+
await fs.writeJson(CONFIG_FILE, newConfig, { spaces: 2 });
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Delete configuration (logout)
|
|
43
|
+
*/
|
|
44
|
+
export async function deleteConfig() {
|
|
45
|
+
if (await fs.pathExists(CONFIG_FILE)) {
|
|
46
|
+
await fs.remove(CONFIG_FILE);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Check if user is logged in
|
|
51
|
+
*/
|
|
52
|
+
export async function isLoggedIn() {
|
|
53
|
+
const config = await getConfig();
|
|
54
|
+
return config !== null && !!config.apiKey;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Get API key or throw if not logged in
|
|
58
|
+
*/
|
|
59
|
+
export async function requireAuth() {
|
|
60
|
+
const config = await getConfig();
|
|
61
|
+
if (!config || !config.apiKey) {
|
|
62
|
+
throw new Error('Not logged in. Run "taggr login <API_KEY>" first.');
|
|
63
|
+
}
|
|
64
|
+
return config;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAGpB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AACrD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEzD,MAAM,eAAe,GAAG,2BAA2B,CAAC;AAEpD;;GAEG;AACH,KAAK,UAAU,eAAe;IAC5B,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,IAAI,CAAC;QACH,MAAM,eAAe,EAAE,CAAC;QAExB,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YACrC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;YAC9C,OAAO;gBACL,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;gBAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,eAAe;aACzC,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAA4B;IAC3D,MAAM,eAAe,EAAE,CAAC;IAExB,MAAM,cAAc,GAAG,MAAM,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IACpF,MAAM,SAAS,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC;IAEnD,MAAM,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;AAC5D,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QACrC,MAAM,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IACjC,OAAO,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;IAEjC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Label } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Write a single label to labels.json (fetches all and rewrites)
|
|
4
|
+
*/
|
|
5
|
+
export declare function writeLabelFile(label: Label): Promise<string>;
|
|
6
|
+
/**
|
|
7
|
+
* Write all labels to labels.json and labels.d.ts
|
|
8
|
+
*/
|
|
9
|
+
export declare function writeAllLabels(labels: Label[]): Promise<string[]>;
|
|
10
|
+
/**
|
|
11
|
+
* Update labels files (alias for writeAllLabels)
|
|
12
|
+
*/
|
|
13
|
+
export declare function updateIndexFile(labels: Label[]): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* Get the output directory path
|
|
16
|
+
*/
|
|
17
|
+
export declare function getOutputDir(): string;
|
|
18
|
+
//# sourceMappingURL=generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/utils/generator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAiDzC;;GAEG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAiClE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAevE;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAEpE;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
const OUTPUT_DIR = './taggr';
|
|
4
|
+
/**
|
|
5
|
+
* Convert kebab-case to camelCase
|
|
6
|
+
*/
|
|
7
|
+
function toCamelCase(str) {
|
|
8
|
+
return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Generate labels.json content
|
|
12
|
+
*/
|
|
13
|
+
function generateLabelsJson(labels) {
|
|
14
|
+
const labelsObj = {};
|
|
15
|
+
for (const label of labels) {
|
|
16
|
+
const key = toCamelCase(label.name);
|
|
17
|
+
labelsObj[key] = label.value;
|
|
18
|
+
}
|
|
19
|
+
return JSON.stringify(labelsObj, null, 2);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Generate labels.d.ts for TypeScript/JS autocomplete
|
|
23
|
+
*/
|
|
24
|
+
function generateLabelsDts(labels) {
|
|
25
|
+
const properties = labels
|
|
26
|
+
.map(label => ` ${toCamelCase(label.name)}: string;`)
|
|
27
|
+
.join('\n');
|
|
28
|
+
return `// Generated by Taggr CLI - DO NOT EDIT
|
|
29
|
+
// Last updated: ${new Date().toISOString()}
|
|
30
|
+
|
|
31
|
+
declare const labels: {
|
|
32
|
+
${properties}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default labels;
|
|
36
|
+
`;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Ensure output directory exists
|
|
40
|
+
*/
|
|
41
|
+
async function ensureOutputDir() {
|
|
42
|
+
await fs.ensureDir(OUTPUT_DIR);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Write a single label to labels.json (fetches all and rewrites)
|
|
46
|
+
*/
|
|
47
|
+
export async function writeLabelFile(label) {
|
|
48
|
+
await ensureOutputDir();
|
|
49
|
+
const jsonPath = path.join(OUTPUT_DIR, 'labels.json');
|
|
50
|
+
const dtsPath = path.join(OUTPUT_DIR, 'labels.d.ts');
|
|
51
|
+
// Read existing labels if file exists
|
|
52
|
+
let existingLabels = {};
|
|
53
|
+
if (await fs.pathExists(jsonPath)) {
|
|
54
|
+
const content = await fs.readFile(jsonPath, 'utf-8');
|
|
55
|
+
existingLabels = JSON.parse(content);
|
|
56
|
+
}
|
|
57
|
+
// Add/update the label
|
|
58
|
+
const key = toCamelCase(label.name);
|
|
59
|
+
existingLabels[key] = label.value;
|
|
60
|
+
// Write JSON
|
|
61
|
+
await fs.writeFile(jsonPath, JSON.stringify(existingLabels, null, 2), 'utf-8');
|
|
62
|
+
// Generate d.ts from current keys
|
|
63
|
+
const dtsContent = `// Generated by Taggr CLI - DO NOT EDIT
|
|
64
|
+
// Last updated: ${new Date().toISOString()}
|
|
65
|
+
|
|
66
|
+
declare const labels: {
|
|
67
|
+
${Object.keys(existingLabels).map(k => ` ${k}: string;`).join('\n')}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export default labels;
|
|
71
|
+
`;
|
|
72
|
+
await fs.writeFile(dtsPath, dtsContent, 'utf-8');
|
|
73
|
+
return jsonPath;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Write all labels to labels.json and labels.d.ts
|
|
77
|
+
*/
|
|
78
|
+
export async function writeAllLabels(labels) {
|
|
79
|
+
await ensureOutputDir();
|
|
80
|
+
const jsonPath = path.join(OUTPUT_DIR, 'labels.json');
|
|
81
|
+
const dtsPath = path.join(OUTPUT_DIR, 'labels.d.ts');
|
|
82
|
+
// Write JSON
|
|
83
|
+
const jsonContent = generateLabelsJson(labels);
|
|
84
|
+
await fs.writeFile(jsonPath, jsonContent, 'utf-8');
|
|
85
|
+
// Write TypeScript declarations
|
|
86
|
+
const dtsContent = generateLabelsDts(labels);
|
|
87
|
+
await fs.writeFile(dtsPath, dtsContent, 'utf-8');
|
|
88
|
+
return [jsonPath, dtsPath];
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Update labels files (alias for writeAllLabels)
|
|
92
|
+
*/
|
|
93
|
+
export async function updateIndexFile(labels) {
|
|
94
|
+
await writeAllLabels(labels);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get the output directory path
|
|
98
|
+
*/
|
|
99
|
+
export function getOutputDir() {
|
|
100
|
+
return path.resolve(OUTPUT_DIR);
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/utils/generator.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@taggr/cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI tool for Taggr - Pull and manage your labels locally",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"taggr": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"dev": "tsc --watch",
|
|
13
|
+
"start": "node dist/index.js",
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"taggr",
|
|
18
|
+
"cli",
|
|
19
|
+
"labels",
|
|
20
|
+
"configuration"
|
|
21
|
+
],
|
|
22
|
+
"author": "Taggr",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"axios": "^1.6.0",
|
|
26
|
+
"chalk": "^5.3.0",
|
|
27
|
+
"commander": "^11.1.0",
|
|
28
|
+
"fs-extra": "^11.2.0",
|
|
29
|
+
"ora": "^8.0.1"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/fs-extra": "^11.0.4",
|
|
33
|
+
"@types/node": "^20.10.0",
|
|
34
|
+
"typescript": "^5.3.0"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=18.0.0"
|
|
38
|
+
},
|
|
39
|
+
"files": [
|
|
40
|
+
"dist"
|
|
41
|
+
],
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": "https://github.com/taggr/cli"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|