schemory 0.1.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 +67 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.js +44 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/activate.d.ts +2 -0
- package/dist/commands/activate.js +15 -0
- package/dist/commands/activate.js.map +1 -0
- package/dist/commands/join.d.ts +2 -0
- package/dist/commands/join.js +74 -0
- package/dist/commands/join.js.map +1 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +61 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/pull.d.ts +2 -0
- package/dist/commands/pull.js +74 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/pullAll.d.ts +2 -0
- package/dist/commands/pullAll.js +74 -0
- package/dist/commands/pullAll.js.map +1 -0
- package/dist/commands/push.d.ts +2 -0
- package/dist/commands/push.js +114 -0
- package/dist/commands/push.js.map +1 -0
- package/dist/commands/signup.d.ts +2 -0
- package/dist/commands/signup.js +47 -0
- package/dist/commands/signup.js.map +1 -0
- package/dist/config.d.ts +67 -0
- package/dist/config.js +232 -0
- package/dist/config.js.map +1 -0
- package/dist/http.d.ts +51 -0
- package/dist/http.js +131 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Schemory CLI
|
|
2
|
+
|
|
3
|
+
Schemory CLI - Share TypeScript types and JSON schemas with your team.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx schemory --help
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or install globally:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install -g @schemory/cli
|
|
15
|
+
schemory --help
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
### One-time Setup
|
|
21
|
+
|
|
22
|
+
1. **Signup** - Register a new account
|
|
23
|
+
```bash
|
|
24
|
+
schemory signup your@email.com
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
2. **Activate** - Click the activation link sent to your email
|
|
28
|
+
|
|
29
|
+
3. **Login** - Authenticate with your access token
|
|
30
|
+
```bash
|
|
31
|
+
schemory login sk_your_access_token
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
4. **Join** - Join a team
|
|
35
|
+
```bash
|
|
36
|
+
schemory join your-team-name
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Sync Commands
|
|
40
|
+
|
|
41
|
+
5. **Push** - Push a schema or type to your team
|
|
42
|
+
```bash
|
|
43
|
+
schemory push UserSchema
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
6. **Pull** - Pull a schema or type from your team
|
|
47
|
+
```bash
|
|
48
|
+
schemory pull UserSchema
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
7. **Pull All** - Pull all schemas and types from your team
|
|
52
|
+
```bash
|
|
53
|
+
schemory pullAll
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Local File Format
|
|
57
|
+
|
|
58
|
+
- **Schemas**: Stored as `.schemory/items/schemas/{name}.json`
|
|
59
|
+
- **Types**: Stored as `.schemory/items/types/{name}.ts`
|
|
60
|
+
|
|
61
|
+
## Configuration
|
|
62
|
+
|
|
63
|
+
Configuration is stored in `~/.schemory/config.json` or `.schemory/config.json` in your project.
|
|
64
|
+
|
|
65
|
+
## Version
|
|
66
|
+
|
|
67
|
+
0.1.0
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Schemory CLI entry point
|
|
2
|
+
// Wires up commander.js with all seven commands
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { createSignupCommand } from './commands/signup.js';
|
|
5
|
+
import { createActivateCommand } from './commands/activate.js';
|
|
6
|
+
import { createLoginCommand } from './commands/login.js';
|
|
7
|
+
import { createJoinCommand } from './commands/join.js';
|
|
8
|
+
import { createPullCommand } from './commands/pull.js';
|
|
9
|
+
import { createPullAllCommand } from './commands/pullAll.js';
|
|
10
|
+
import { createPushCommand } from './commands/push.js';
|
|
11
|
+
/**
|
|
12
|
+
* Create the main CLI program
|
|
13
|
+
*/
|
|
14
|
+
function createCLI() {
|
|
15
|
+
const program = new Command();
|
|
16
|
+
// Configure program metadata
|
|
17
|
+
program
|
|
18
|
+
.name('schemory')
|
|
19
|
+
.description('Schemory CLI - Share TypeScript types and JSON schemas with your team')
|
|
20
|
+
.version('0.1.0');
|
|
21
|
+
// Add all seven commands
|
|
22
|
+
program
|
|
23
|
+
.addCommand(createSignupCommand())
|
|
24
|
+
.addCommand(createActivateCommand())
|
|
25
|
+
.addCommand(createLoginCommand())
|
|
26
|
+
.addCommand(createJoinCommand())
|
|
27
|
+
.addCommand(createPullCommand())
|
|
28
|
+
.addCommand(createPullAllCommand())
|
|
29
|
+
.addCommand(createPushCommand());
|
|
30
|
+
// Global error handling
|
|
31
|
+
program.configureOutput({
|
|
32
|
+
writeErr: (str) => {
|
|
33
|
+
console.error(str);
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
return program;
|
|
37
|
+
}
|
|
38
|
+
// Create the CLI program
|
|
39
|
+
const program = createCLI();
|
|
40
|
+
// Note: CLI execution is now handled explicitly by index.ts (the bin entry point)
|
|
41
|
+
// This file only exports the CLI factory and program instance for use by index.ts and tests
|
|
42
|
+
export { createCLI, program };
|
|
43
|
+
export default program;
|
|
44
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,gDAAgD;AAEhD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;GAEG;AACH,SAAS,SAAS;IAChB,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,6BAA6B;IAC7B,OAAO;SACJ,IAAI,CAAC,UAAU,CAAC;SAChB,WAAW,CAAC,uEAAuE,CAAC;SACpF,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpB,yBAAyB;IACzB,OAAO;SACJ,UAAU,CAAC,mBAAmB,EAAE,CAAC;SACjC,UAAU,CAAC,qBAAqB,EAAE,CAAC;SACnC,UAAU,CAAC,kBAAkB,EAAE,CAAC;SAChC,UAAU,CAAC,iBAAiB,EAAE,CAAC;SAC/B,UAAU,CAAC,iBAAiB,EAAE,CAAC;SAC/B,UAAU,CAAC,oBAAoB,EAAE,CAAC;SAClC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAEnC,wBAAwB;IACxB,OAAO,CAAC,eAAe,CAAC;QACtB,QAAQ,EAAE,CAAC,GAAG,EAAE,EAAE;YAChB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;KACF,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,yBAAyB;AACzB,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;AAE5B,kFAAkF;AAClF,4FAA4F;AAE5F,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AAC9B,eAAe,OAAO,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// activate command stub
|
|
2
|
+
// npx schemory activate <token>
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
export function createActivateCommand() {
|
|
5
|
+
return new Command('activate')
|
|
6
|
+
.description('Activate a Schemory account using the activation token')
|
|
7
|
+
.argument('<token>', 'Activation token from email')
|
|
8
|
+
.action(async (token) => {
|
|
9
|
+
// TODO: Implement
|
|
10
|
+
// POST /api/users/activate with { token }
|
|
11
|
+
// On success: print access token and save to config
|
|
12
|
+
console.log(`Activate stub: would activate with token ${token}`);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=activate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activate.js","sourceRoot":"","sources":["../../src/commands/activate.ts"],"names":[],"mappings":"AAAA,wBAAwB;AACxB,gCAAgC;AAEhC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,UAAU,qBAAqB;IACnC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;SAC3B,WAAW,CAAC,wDAAwD,CAAC;SACrE,QAAQ,CAAC,SAAS,EAAE,6BAA6B,CAAC;SAClD,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,EAAE;QAC9B,kBAAkB;QAClB,0CAA0C;QAC1C,oDAAoD;QACpD,OAAO,CAAC,GAAG,CAAC,4CAA4C,KAAK,EAAE,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// join command
|
|
2
|
+
// npx schemory join <team>
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { getHttpClient, setHttpClientConfig } from '../http.js';
|
|
5
|
+
import { readConfig, addTeam, setDefaultTeam } from '../config.js';
|
|
6
|
+
export function createJoinCommand() {
|
|
7
|
+
return new Command('join')
|
|
8
|
+
.description('Join a Schemory team')
|
|
9
|
+
.argument('<team>', 'Team name to join')
|
|
10
|
+
.action(async (team) => {
|
|
11
|
+
if (!team || team.trim().length === 0) {
|
|
12
|
+
console.error('Error: Team name is required');
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
// Get config to determine API URL and check for auth token
|
|
16
|
+
const config = readConfig();
|
|
17
|
+
const apiUrl = config.apiUrl;
|
|
18
|
+
const token = config.auth?.token;
|
|
19
|
+
if (!token) {
|
|
20
|
+
console.error('Error: You must be logged in to join a team. Please run `schemory login <token>` first.');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
// Configure HTTP client with API URL and token
|
|
24
|
+
setHttpClientConfig({ apiUrl, token });
|
|
25
|
+
const http = getHttpClient();
|
|
26
|
+
// POST /teams/:team/join
|
|
27
|
+
const response = await http.post(`/teams/${encodeURIComponent(team)}/join`);
|
|
28
|
+
if (response.error) {
|
|
29
|
+
// Handle specific error cases
|
|
30
|
+
if (response.error.code === 'UNAUTHORIZED') {
|
|
31
|
+
console.error('Error: Unauthorized - please check your authentication token');
|
|
32
|
+
}
|
|
33
|
+
else if (response.error.code === 'INVALID_TOKEN') {
|
|
34
|
+
console.error('Error: Invalid or expired access token');
|
|
35
|
+
}
|
|
36
|
+
else if (response.error.code === 'INVALID_TEAM_NAME') {
|
|
37
|
+
console.error('Error: Invalid team name');
|
|
38
|
+
}
|
|
39
|
+
else if (response.error.code === 'TEAM_NOT_FOUND') {
|
|
40
|
+
console.error(`Error: Team '${team}' not found`);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
console.error(`Error: ${response.error.message}`);
|
|
44
|
+
}
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
if (response.status === 200 && response.data) {
|
|
48
|
+
const data = response.data;
|
|
49
|
+
if (data.team) {
|
|
50
|
+
// Add team to config
|
|
51
|
+
addTeam({
|
|
52
|
+
id: data.team.id.toString(),
|
|
53
|
+
name: data.team.name,
|
|
54
|
+
createdAt: data.team.createdAt,
|
|
55
|
+
});
|
|
56
|
+
// Set as default team if it's the first team
|
|
57
|
+
const currentConfig = readConfig();
|
|
58
|
+
if (currentConfig.teams.length === 1) {
|
|
59
|
+
setDefaultTeam(data.team.name);
|
|
60
|
+
}
|
|
61
|
+
console.log(`Joined team ${data.team.name}`);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
console.error('Error: No team information returned from server');
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
console.error('Error: Unexpected response from server');
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=join.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"join.js","sourceRoot":"","sources":["../../src/commands/join.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// login command
|
|
2
|
+
// npx schemory login <token>
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { getHttpClient, setHttpClientConfig } from '../http.js';
|
|
5
|
+
import { readConfig, setAuthToken } from '../config.js';
|
|
6
|
+
export function createLoginCommand() {
|
|
7
|
+
return new Command('login')
|
|
8
|
+
.description('Authenticate the CLI with an access token')
|
|
9
|
+
.argument('<token>', 'Access token')
|
|
10
|
+
.action(async (token) => {
|
|
11
|
+
if (!token) {
|
|
12
|
+
console.error('Error: Access token is required');
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
// Get config to determine API URL
|
|
16
|
+
const config = readConfig();
|
|
17
|
+
const apiUrl = config.apiUrl;
|
|
18
|
+
// Configure HTTP client with API URL and token
|
|
19
|
+
setHttpClientConfig({ apiUrl, token });
|
|
20
|
+
const http = getHttpClient();
|
|
21
|
+
// POST /auth/login with token in body
|
|
22
|
+
const response = await http.post('/auth/login', { token });
|
|
23
|
+
if (response.error) {
|
|
24
|
+
// Handle specific error cases
|
|
25
|
+
if (response.error.code === 'MISSING_TOKEN') {
|
|
26
|
+
console.error('Error: Access token is required');
|
|
27
|
+
}
|
|
28
|
+
else if (response.error.code === 'INVALID_TOKEN') {
|
|
29
|
+
console.error('Error: Invalid or expired access token');
|
|
30
|
+
}
|
|
31
|
+
else if (response.error.code === 'UNAUTHORIZED') {
|
|
32
|
+
console.error('Error: Unauthorized - please check your token');
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
console.error(`Error: ${response.error.message}`);
|
|
36
|
+
}
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
if (response.status === 200 && response.data) {
|
|
40
|
+
const data = response.data;
|
|
41
|
+
// Extract user ID as string
|
|
42
|
+
const userId = data.user?.id?.toString() || '';
|
|
43
|
+
// For now, we don't have expiresAt from login, but we can use a default
|
|
44
|
+
// The activation endpoint returns expiresAt, but login doesn't
|
|
45
|
+
// We'll use a default of 1 year from now
|
|
46
|
+
const expiresAt = new Date(Date.now() + 24 * 365 * 60 * 60 * 1000).toISOString();
|
|
47
|
+
// Save token to config
|
|
48
|
+
setAuthToken(token, expiresAt, userId);
|
|
49
|
+
console.log('Logged in successfully');
|
|
50
|
+
// If teams are returned, we could add them to config too
|
|
51
|
+
if (data.teams && data.teams.length > 0) {
|
|
52
|
+
console.log(`You have access to ${data.teams.length} team(s)`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
console.error('Error: Unexpected response from server');
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// pull command
|
|
2
|
+
// npx schemory pull <schema|type>
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { getHttpClient, setHttpClientConfig } from '../http.js';
|
|
7
|
+
import { readConfig } from '../config.js';
|
|
8
|
+
export function createPullCommand() {
|
|
9
|
+
return new Command('pull')
|
|
10
|
+
.description('Pull a schema or type by name')
|
|
11
|
+
.argument('<name>', 'Name of the schema or type to pull')
|
|
12
|
+
.action(async (name) => {
|
|
13
|
+
if (!name || name.trim().length === 0) {
|
|
14
|
+
console.error('Error: Item name is required');
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
// Get config to determine API URL and check for auth token
|
|
18
|
+
const config = readConfig();
|
|
19
|
+
const apiUrl = config.apiUrl;
|
|
20
|
+
const token = config.auth?.token;
|
|
21
|
+
if (!token) {
|
|
22
|
+
console.error('Error: You must be logged in to pull items. Please run `schemory login <token>` first.');
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
// Configure HTTP client with API URL and token
|
|
26
|
+
setHttpClientConfig({ apiUrl, token });
|
|
27
|
+
const http = getHttpClient();
|
|
28
|
+
// GET /items/:name
|
|
29
|
+
const response = await http.get(`/items/${encodeURIComponent(name)}`);
|
|
30
|
+
if (response.error) {
|
|
31
|
+
// Handle specific error cases
|
|
32
|
+
if (response.error.code === 'UNAUTHORIZED') {
|
|
33
|
+
console.error('Error: Unauthorized - please check your authentication token');
|
|
34
|
+
}
|
|
35
|
+
else if (response.error.code === 'INVALID_TOKEN') {
|
|
36
|
+
console.error('Error: Invalid or expired access token');
|
|
37
|
+
}
|
|
38
|
+
else if (response.error.code === 'ITEM_NOT_FOUND') {
|
|
39
|
+
console.error(`Error: Item '${name}' not found or you lack access`);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
console.error(`Error: ${response.error.message}`);
|
|
43
|
+
}
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
if (response.status === 200 && response.data) {
|
|
47
|
+
const data = response.data;
|
|
48
|
+
if (!data.item) {
|
|
49
|
+
console.error(`Error: No item found with name '${name}'`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
const item = data.item;
|
|
53
|
+
// Determine file path based on item kind
|
|
54
|
+
// Schemas go to .schemory/items/schemas/{name}.json
|
|
55
|
+
// Types go to .schemory/items/types/{name}.ts
|
|
56
|
+
const itemsDir = path.join(process.cwd(), '.schemory', 'items');
|
|
57
|
+
const kindDir = path.join(itemsDir, item.kind === 'schema' ? 'schemas' : 'types');
|
|
58
|
+
const fileExt = item.kind === 'schema' ? 'json' : 'ts';
|
|
59
|
+
const filePath = path.join(kindDir, `${item.name}.${fileExt}`);
|
|
60
|
+
// Ensure directory exists
|
|
61
|
+
if (!fs.existsSync(kindDir)) {
|
|
62
|
+
fs.mkdirSync(kindDir, { recursive: true, mode: 0o755 });
|
|
63
|
+
}
|
|
64
|
+
// Write content to file
|
|
65
|
+
fs.writeFileSync(filePath, item.content, 'utf-8');
|
|
66
|
+
console.log(`Pulled ${item.kind} '${item.name}' to ${filePath}`);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
console.error('Error: Unexpected response from server');
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
//# 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,74 @@
|
|
|
1
|
+
// pullAll command
|
|
2
|
+
// npx schemory pullAll
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { getHttpClient, setHttpClientConfig } from '../http.js';
|
|
7
|
+
import { readConfig } from '../config.js';
|
|
8
|
+
export function createPullAllCommand() {
|
|
9
|
+
return new Command('pullAll')
|
|
10
|
+
.description('Pull all schemas and types')
|
|
11
|
+
.action(async () => {
|
|
12
|
+
// Get config to determine API URL and check for auth token
|
|
13
|
+
const config = readConfig();
|
|
14
|
+
const apiUrl = config.apiUrl;
|
|
15
|
+
const token = config.auth?.token;
|
|
16
|
+
if (!token) {
|
|
17
|
+
console.error('Error: You must be logged in to pull items. Please run `schemory login <token>` first.');
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
// Configure HTTP client with API URL and token
|
|
21
|
+
setHttpClientConfig({ apiUrl, token });
|
|
22
|
+
const http = getHttpClient();
|
|
23
|
+
// GET /items
|
|
24
|
+
const response = await http.get('/items');
|
|
25
|
+
if (response.error) {
|
|
26
|
+
// Handle specific error cases
|
|
27
|
+
if (response.error.code === 'UNAUTHORIZED') {
|
|
28
|
+
console.error('Error: Unauthorized - please check your authentication token');
|
|
29
|
+
}
|
|
30
|
+
else if (response.error.code === 'INVALID_TOKEN') {
|
|
31
|
+
console.error('Error: Invalid or expired access token');
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
console.error(`Error: ${response.error.message}`);
|
|
35
|
+
}
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
if (response.status === 200 && response.data) {
|
|
39
|
+
const data = response.data;
|
|
40
|
+
if (!data.items || data.items.length === 0) {
|
|
41
|
+
console.log('No items to pull');
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
// Ensure base directory exists
|
|
45
|
+
const itemsDir = path.join(process.cwd(), '.schemory', 'items');
|
|
46
|
+
const schemasDir = path.join(itemsDir, 'schemas');
|
|
47
|
+
const typesDir = path.join(itemsDir, 'types');
|
|
48
|
+
if (!fs.existsSync(schemasDir)) {
|
|
49
|
+
fs.mkdirSync(schemasDir, { recursive: true, mode: 0o755 });
|
|
50
|
+
}
|
|
51
|
+
if (!fs.existsSync(typesDir)) {
|
|
52
|
+
fs.mkdirSync(typesDir, { recursive: true, mode: 0o755 });
|
|
53
|
+
}
|
|
54
|
+
let pulledCount = 0;
|
|
55
|
+
// Process each item
|
|
56
|
+
for (const item of data.items) {
|
|
57
|
+
// Determine file path based on item kind
|
|
58
|
+
const kindDir = item.kind === 'schema' ? schemasDir : typesDir;
|
|
59
|
+
const fileExt = item.kind === 'schema' ? 'json' : 'ts';
|
|
60
|
+
const filePath = path.join(kindDir, `${item.name}.${fileExt}`);
|
|
61
|
+
// Write content to file
|
|
62
|
+
fs.writeFileSync(filePath, item.content, 'utf-8');
|
|
63
|
+
pulledCount++;
|
|
64
|
+
console.log(`Pulled ${item.kind} '${item.name}' to ${filePath}`);
|
|
65
|
+
}
|
|
66
|
+
console.log(`Pulled ${pulledCount} items total`);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
console.error('Error: Unexpected response from server');
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=pullAll.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pullAll.js","sourceRoot":"","sources":["../../src/commands/pullAll.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
// push command
|
|
2
|
+
// npx schemory push <schema|type>
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { getHttpClient, setHttpClientConfig } from '../http.js';
|
|
7
|
+
import { readConfig } from '../config.js';
|
|
8
|
+
export function createPushCommand() {
|
|
9
|
+
return new Command('push')
|
|
10
|
+
.description('Push a schema or type by name')
|
|
11
|
+
.argument('<name>', 'Name of the schema or type to push')
|
|
12
|
+
.action(async (name) => {
|
|
13
|
+
if (!name || name.trim().length === 0) {
|
|
14
|
+
console.error('Error: Item name is required');
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
// Get config to determine API URL and check for auth token
|
|
18
|
+
const config = readConfig();
|
|
19
|
+
const apiUrl = config.apiUrl;
|
|
20
|
+
const token = config.auth?.token;
|
|
21
|
+
if (!token) {
|
|
22
|
+
console.error('Error: You must be logged in to push items. Please run `schemory login <token>` first.');
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
// Look for the file in .schemory/items/schemas/{name}.json or .schemory/items/types/{name}.ts
|
|
26
|
+
const itemsDir = path.join(process.cwd(), '.schemory', 'items');
|
|
27
|
+
const jsonFilePath = path.join(itemsDir, 'schemas', `${name}.json`);
|
|
28
|
+
const tsFilePath = path.join(itemsDir, 'types', `${name}.ts`);
|
|
29
|
+
let filePath;
|
|
30
|
+
let kind;
|
|
31
|
+
let content;
|
|
32
|
+
// Check if JSON file exists (schema)
|
|
33
|
+
if (fs.existsSync(jsonFilePath)) {
|
|
34
|
+
filePath = jsonFilePath;
|
|
35
|
+
kind = 'schema';
|
|
36
|
+
content = fs.readFileSync(filePath, 'utf-8');
|
|
37
|
+
}
|
|
38
|
+
else if (fs.existsSync(tsFilePath)) {
|
|
39
|
+
// Check if TypeScript file exists (type)
|
|
40
|
+
filePath = tsFilePath;
|
|
41
|
+
kind = 'type';
|
|
42
|
+
content = fs.readFileSync(filePath, 'utf-8');
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
console.error(`Error: No file found for item '${name}'. Expected ${jsonFilePath} or ${tsFilePath}`);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
// Configure HTTP client with API URL and token
|
|
49
|
+
setHttpClientConfig({ apiUrl, token });
|
|
50
|
+
const http = getHttpClient();
|
|
51
|
+
// For push, we need to determine lastKnownVersion
|
|
52
|
+
// If the item already exists, we should get its current version first
|
|
53
|
+
// For new items, lastKnownVersion should be 0 or undefined
|
|
54
|
+
// Let's first try to get the existing item to get its version
|
|
55
|
+
let lastKnownVersion;
|
|
56
|
+
try {
|
|
57
|
+
const getResponse = await http.get(`/items/${encodeURIComponent(name)}`);
|
|
58
|
+
if (getResponse.status === 200 && getResponse.data) {
|
|
59
|
+
const existingData = getResponse.data;
|
|
60
|
+
if (existingData.item) {
|
|
61
|
+
lastKnownVersion = existingData.item.version;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// If not found (404), that's fine - it's a new item
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// If we can't get the item, assume it's new
|
|
68
|
+
lastKnownVersion = undefined;
|
|
69
|
+
}
|
|
70
|
+
// PUT /items/:name with { kind, content, lastKnownVersion }
|
|
71
|
+
const response = await http.put(`/items/${encodeURIComponent(name)}`, {
|
|
72
|
+
kind,
|
|
73
|
+
content,
|
|
74
|
+
lastKnownVersion,
|
|
75
|
+
});
|
|
76
|
+
if (response.error) {
|
|
77
|
+
// Handle specific error cases
|
|
78
|
+
if (response.error.code === 'UNAUTHORIZED') {
|
|
79
|
+
console.error('Error: Unauthorized - please check your authentication token');
|
|
80
|
+
}
|
|
81
|
+
else if (response.error.code === 'INVALID_TOKEN') {
|
|
82
|
+
console.error('Error: Invalid or expired access token');
|
|
83
|
+
}
|
|
84
|
+
else if (response.error.code === 'CONFLICT') {
|
|
85
|
+
console.error(`Error: Conflict - remote version is newer. Please pull and merge: ${response.error.message}`);
|
|
86
|
+
}
|
|
87
|
+
else if (response.error.code === 'INVALID_REQUEST') {
|
|
88
|
+
console.error('Error: Invalid request - kind and content are required');
|
|
89
|
+
}
|
|
90
|
+
else if (response.error.code === 'INVALID_KIND') {
|
|
91
|
+
console.error('Error: Invalid kind - must be "schema" or "type"');
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
console.error(`Error: ${response.error.message}`);
|
|
95
|
+
}
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
if (response.status === 200 && response.data) {
|
|
99
|
+
const data = response.data;
|
|
100
|
+
if (data.item) {
|
|
101
|
+
console.log(`Pushed ${kind} '${name}' version ${data.item.version}`);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
console.error('Error: No item returned from server');
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
console.error('Error: Unexpected response from server');
|
|
110
|
+
process.exit(1);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=push.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.js","sourceRoot":"","sources":["../../src/commands/push.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// signup command
|
|
2
|
+
// npx schemory signup <email>
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { getHttpClient, setHttpClientConfig } from '../http.js';
|
|
5
|
+
import { readConfig } from '../config.js';
|
|
6
|
+
export function createSignupCommand() {
|
|
7
|
+
return new Command('signup')
|
|
8
|
+
.description('Register a new Schemory account')
|
|
9
|
+
.argument('<email>', 'Email address for the new account')
|
|
10
|
+
.action(async (email) => {
|
|
11
|
+
// Validate email format
|
|
12
|
+
if (!email || !email.includes('@')) {
|
|
13
|
+
console.error('Error: Invalid email format');
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
// Get config to determine API URL
|
|
17
|
+
const config = readConfig();
|
|
18
|
+
const apiUrl = config.apiUrl;
|
|
19
|
+
// Configure HTTP client with API URL
|
|
20
|
+
setHttpClientConfig({ apiUrl });
|
|
21
|
+
const http = getHttpClient();
|
|
22
|
+
// POST /auth/signup with { email }
|
|
23
|
+
const response = await http.post('/auth/signup', { email });
|
|
24
|
+
if (response.error) {
|
|
25
|
+
// Handle specific error cases
|
|
26
|
+
if (response.error.code === 'INVALID_EMAIL') {
|
|
27
|
+
console.error('Error: Invalid email format');
|
|
28
|
+
}
|
|
29
|
+
else if (response.error.code === 'EMAIL_EXISTS') {
|
|
30
|
+
console.error('Error: Email already registered');
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
console.error(`Error: ${response.error.message}`);
|
|
34
|
+
}
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
if (response.status === 202 && response.data) {
|
|
38
|
+
const data = response.data;
|
|
39
|
+
console.log(data.message || 'Activation email sent. Please check your inbox.');
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
console.error('Error: Unexpected response from server');
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=signup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signup.js","sourceRoot":"","sources":["../../src/commands/signup.ts"],"names":[],"mappings":"AAAA,iBAAiB;AACjB,8BAA8B;AAE9B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,MAAM,UAAU,mBAAmB;IACjC,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC;SACzB,WAAW,CAAC,iCAAiC,CAAC;SAC9C,QAAQ,CAAC,SAAS,EAAE,mCAAmC,CAAC;SACxD,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,EAAE;QAC9B,wBAAwB;QACxB,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACnC,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,kCAAkC;QAClC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAE7B,qCAAqC;QACrC,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QAChC,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;QAE7B,mCAAmC;QACnC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAE5D,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnB,8BAA8B;YAC9B,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;gBAC5C,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAC/C,CAAC;iBAAM,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;gBAClD,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;YACnD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,UAAU,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACpD,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC7C,MAAM,IAAI,GAAG,QAAQ,CAAC,IAA6C,CAAC;YACpE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,iDAAiD,CAAC,CAAC;QACjF,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;YACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team type for the config
|
|
3
|
+
*/
|
|
4
|
+
export interface Team {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
createdAt: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Auth configuration
|
|
11
|
+
*/
|
|
12
|
+
export interface AuthConfig {
|
|
13
|
+
token: string;
|
|
14
|
+
expiresAt: string;
|
|
15
|
+
userId: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Main config schema from ARCHITECTURE.md
|
|
19
|
+
*/
|
|
20
|
+
export interface SchemoryConfig {
|
|
21
|
+
version: string;
|
|
22
|
+
auth?: AuthConfig;
|
|
23
|
+
teams: Team[];
|
|
24
|
+
defaultTeam?: string;
|
|
25
|
+
lastSyncAt?: string;
|
|
26
|
+
apiUrl?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Read the current config (merged from global, project, and env)
|
|
30
|
+
* Env vars: SCHEMORY_API_URL
|
|
31
|
+
*/
|
|
32
|
+
export declare function readConfig(): SchemoryConfig;
|
|
33
|
+
/**
|
|
34
|
+
* Write the config to the appropriate location
|
|
35
|
+
* Writes to project config if in a project with .schemory directory,
|
|
36
|
+
* otherwise writes to global config
|
|
37
|
+
*/
|
|
38
|
+
export declare function writeConfig(config: SchemoryConfig): void;
|
|
39
|
+
/**
|
|
40
|
+
* Write config to a specific location
|
|
41
|
+
*/
|
|
42
|
+
export declare function writeConfigTo(filePath: string, config: SchemoryConfig): void;
|
|
43
|
+
/**
|
|
44
|
+
* Get the config file path being used
|
|
45
|
+
*/
|
|
46
|
+
export declare function getConfigPath(): string;
|
|
47
|
+
/**
|
|
48
|
+
* Add a team to the config
|
|
49
|
+
*/
|
|
50
|
+
export declare function addTeam(team: Team): void;
|
|
51
|
+
/**
|
|
52
|
+
* Set the auth token
|
|
53
|
+
*/
|
|
54
|
+
export declare function setAuthToken(token: string, expiresAt: string, userId: string): void;
|
|
55
|
+
/**
|
|
56
|
+
* Clear the auth token
|
|
57
|
+
*/
|
|
58
|
+
export declare function clearAuthToken(): void;
|
|
59
|
+
/**
|
|
60
|
+
* Set the default team
|
|
61
|
+
*/
|
|
62
|
+
export declare function setDefaultTeam(teamName: string): void;
|
|
63
|
+
/**
|
|
64
|
+
* Set the API URL
|
|
65
|
+
*/
|
|
66
|
+
export declare function setApiUrl(apiUrl: string): void;
|
|
67
|
+
export type { AuthConfig as AuthConfigType, Team as TeamType };
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
// Config module for Schemory CLI
|
|
2
|
+
// Reads and writes the on-disk config file from ARCHITECTURE.md design
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import os from 'os';
|
|
6
|
+
// Current config version
|
|
7
|
+
const CONFIG_VERSION = '1';
|
|
8
|
+
// Default API URL from ARCHITECTURE.md
|
|
9
|
+
const DEFAULT_API_URL = 'https://api.schemory.org';
|
|
10
|
+
/**
|
|
11
|
+
* Get the global config file path (~/.schemory/config.json)
|
|
12
|
+
* Respects HOME environment variable for testing
|
|
13
|
+
*/
|
|
14
|
+
function getGlobalConfigPath() {
|
|
15
|
+
const homeDir = process.env.HOME || os.homedir();
|
|
16
|
+
return path.join(homeDir, '.schemory', 'config.json');
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Get the project config file path (.schemory/config.json)
|
|
20
|
+
*/
|
|
21
|
+
function getProjectConfigPath() {
|
|
22
|
+
return path.join(process.cwd(), '.schemory', 'config.json');
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Ensure the directory for a config file exists
|
|
26
|
+
*/
|
|
27
|
+
function ensureConfigDir(filePath) {
|
|
28
|
+
const dir = path.dirname(filePath);
|
|
29
|
+
if (!fs.existsSync(dir)) {
|
|
30
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Default config
|
|
35
|
+
*/
|
|
36
|
+
function getDefaultConfig() {
|
|
37
|
+
return {
|
|
38
|
+
version: CONFIG_VERSION,
|
|
39
|
+
teams: [],
|
|
40
|
+
apiUrl: DEFAULT_API_URL,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Read a config file
|
|
45
|
+
*/
|
|
46
|
+
function readConfigFile(filePath) {
|
|
47
|
+
if (!fs.existsSync(filePath)) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
52
|
+
const config = JSON.parse(content);
|
|
53
|
+
// Ensure version is set
|
|
54
|
+
if (!config.version) {
|
|
55
|
+
config.version = CONFIG_VERSION;
|
|
56
|
+
}
|
|
57
|
+
// Ensure teams is an array
|
|
58
|
+
if (!config.teams) {
|
|
59
|
+
config.teams = [];
|
|
60
|
+
}
|
|
61
|
+
// Set default API URL if not present
|
|
62
|
+
if (!config.apiUrl) {
|
|
63
|
+
config.apiUrl = DEFAULT_API_URL;
|
|
64
|
+
}
|
|
65
|
+
return config;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Write a config file
|
|
73
|
+
*/
|
|
74
|
+
function writeConfigFile(filePath, config) {
|
|
75
|
+
ensureConfigDir(filePath);
|
|
76
|
+
// Set permissions to 0600 (owner read/write only) for security
|
|
77
|
+
// Note: process.umask() is not supported in Vitest workers, so we skip it in test environment
|
|
78
|
+
let currentUmask;
|
|
79
|
+
let umaskSupported = true;
|
|
80
|
+
try {
|
|
81
|
+
currentUmask = process.umask(0o077);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
umaskSupported = false;
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
fs.writeFileSync(filePath, JSON.stringify(config, null, 2), 'utf-8');
|
|
88
|
+
// Only chmod if we successfully set umask (not in worker threads)
|
|
89
|
+
if (umaskSupported) {
|
|
90
|
+
fs.chmodSync(filePath, 0o600);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
finally {
|
|
94
|
+
if (umaskSupported && currentUmask !== undefined) {
|
|
95
|
+
process.umask(currentUmask);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Merge configs with precedence: passed config > project config > global config > defaults
|
|
101
|
+
*/
|
|
102
|
+
function mergeConfigs(...configs) {
|
|
103
|
+
const result = getDefaultConfig();
|
|
104
|
+
for (const config of configs) {
|
|
105
|
+
if (!config)
|
|
106
|
+
continue;
|
|
107
|
+
if (config.version !== undefined) {
|
|
108
|
+
result.version = config.version;
|
|
109
|
+
}
|
|
110
|
+
if (config.auth !== undefined) {
|
|
111
|
+
result.auth = config.auth;
|
|
112
|
+
}
|
|
113
|
+
if (config.teams !== undefined) {
|
|
114
|
+
result.teams = config.teams;
|
|
115
|
+
}
|
|
116
|
+
if (config.defaultTeam !== undefined) {
|
|
117
|
+
result.defaultTeam = config.defaultTeam;
|
|
118
|
+
}
|
|
119
|
+
if (config.lastSyncAt !== undefined) {
|
|
120
|
+
result.lastSyncAt = config.lastSyncAt;
|
|
121
|
+
}
|
|
122
|
+
if (config.apiUrl !== undefined) {
|
|
123
|
+
result.apiUrl = config.apiUrl;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Read the current config (merged from global, project, and env)
|
|
130
|
+
* Env vars: SCHEMORY_API_URL
|
|
131
|
+
*/
|
|
132
|
+
export function readConfig() {
|
|
133
|
+
// Read global config
|
|
134
|
+
const globalConfig = readConfigFile(getGlobalConfigPath());
|
|
135
|
+
// Read project config
|
|
136
|
+
const projectConfig = readConfigFile(getProjectConfigPath());
|
|
137
|
+
// Start with merged file configs
|
|
138
|
+
let config = mergeConfigs(globalConfig, projectConfig);
|
|
139
|
+
// Apply environment variables
|
|
140
|
+
if (process.env.SCHEMORY_API_URL) {
|
|
141
|
+
config.apiUrl = process.env.SCHEMORY_API_URL;
|
|
142
|
+
}
|
|
143
|
+
return config;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Write the config to the appropriate location
|
|
147
|
+
* Writes to project config if in a project with .schemory directory,
|
|
148
|
+
* otherwise writes to global config
|
|
149
|
+
*/
|
|
150
|
+
export function writeConfig(config) {
|
|
151
|
+
// Determine which config file to write to
|
|
152
|
+
const projectPath = getProjectConfigPath();
|
|
153
|
+
const projectDir = path.dirname(projectPath);
|
|
154
|
+
// Write to project config if the directory exists (or we're in a schemory project)
|
|
155
|
+
// Otherwise write to global config
|
|
156
|
+
if (fs.existsSync(projectDir) || fs.existsSync(path.join(process.cwd(), '.schemory'))) {
|
|
157
|
+
writeConfigFile(projectPath, config);
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
writeConfigFile(getGlobalConfigPath(), config);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Write config to a specific location
|
|
165
|
+
*/
|
|
166
|
+
export function writeConfigTo(filePath, config) {
|
|
167
|
+
writeConfigFile(filePath, config);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Get the config file path being used
|
|
171
|
+
*/
|
|
172
|
+
export function getConfigPath() {
|
|
173
|
+
const projectPath = getProjectConfigPath();
|
|
174
|
+
if (fs.existsSync(projectPath)) {
|
|
175
|
+
return projectPath;
|
|
176
|
+
}
|
|
177
|
+
return getGlobalConfigPath();
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Add a team to the config
|
|
181
|
+
*/
|
|
182
|
+
export function addTeam(team) {
|
|
183
|
+
const config = readConfig();
|
|
184
|
+
// Check if team already exists
|
|
185
|
+
const existingIndex = config.teams.findIndex(t => t.id === team.id || t.name === team.name);
|
|
186
|
+
if (existingIndex !== -1) {
|
|
187
|
+
// Update existing team
|
|
188
|
+
config.teams[existingIndex] = team;
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
// Add new team
|
|
192
|
+
config.teams.push(team);
|
|
193
|
+
}
|
|
194
|
+
writeConfig(config);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Set the auth token
|
|
198
|
+
*/
|
|
199
|
+
export function setAuthToken(token, expiresAt, userId) {
|
|
200
|
+
const config = readConfig();
|
|
201
|
+
config.auth = {
|
|
202
|
+
token,
|
|
203
|
+
expiresAt,
|
|
204
|
+
userId,
|
|
205
|
+
};
|
|
206
|
+
writeConfig(config);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Clear the auth token
|
|
210
|
+
*/
|
|
211
|
+
export function clearAuthToken() {
|
|
212
|
+
const config = readConfig();
|
|
213
|
+
delete config.auth;
|
|
214
|
+
writeConfig(config);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Set the default team
|
|
218
|
+
*/
|
|
219
|
+
export function setDefaultTeam(teamName) {
|
|
220
|
+
const config = readConfig();
|
|
221
|
+
config.defaultTeam = teamName;
|
|
222
|
+
writeConfig(config);
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Set the API URL
|
|
226
|
+
*/
|
|
227
|
+
export function setApiUrl(apiUrl) {
|
|
228
|
+
const config = readConfig();
|
|
229
|
+
config.apiUrl = apiUrl;
|
|
230
|
+
writeConfig(config);
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP response with parsed body
|
|
3
|
+
*/
|
|
4
|
+
export interface HttpResponse<T = unknown> {
|
|
5
|
+
status: number;
|
|
6
|
+
data?: T;
|
|
7
|
+
error?: {
|
|
8
|
+
code: string;
|
|
9
|
+
message: string;
|
|
10
|
+
details?: Record<string, unknown>;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Configuration for the HTTP client
|
|
15
|
+
*/
|
|
16
|
+
export interface HttpClientConfig {
|
|
17
|
+
apiUrl?: string;
|
|
18
|
+
token?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Create an HTTP client with configuration
|
|
22
|
+
*/
|
|
23
|
+
export declare function createHttpClient(config?: HttpClientConfig): {
|
|
24
|
+
request: <T = unknown>(method: string, path: string, body?: unknown, headers?: Record<string, string>) => Promise<HttpResponse<T>>;
|
|
25
|
+
get: <T = unknown>(path: string, headers?: Record<string, string>) => Promise<HttpResponse<T>>;
|
|
26
|
+
post: <T = unknown>(path: string, body?: unknown, headers?: Record<string, string>) => Promise<HttpResponse<T>>;
|
|
27
|
+
put: <T = unknown>(path: string, body?: unknown, headers?: Record<string, string>) => Promise<HttpResponse<T>>;
|
|
28
|
+
delete: <T = unknown>(path: string, headers?: Record<string, string>) => Promise<HttpResponse<T>>;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Reconfigure the default HTTP client
|
|
32
|
+
*/
|
|
33
|
+
export declare function setHttpClientConfig(config: HttpClientConfig): void;
|
|
34
|
+
/**
|
|
35
|
+
* Get the default HTTP client
|
|
36
|
+
*/
|
|
37
|
+
export declare function getHttpClient(): {
|
|
38
|
+
request: <T = unknown>(method: string, path: string, body?: unknown, headers?: Record<string, string>) => Promise<HttpResponse<T>>;
|
|
39
|
+
get: <T = unknown>(path: string, headers?: Record<string, string>) => Promise<HttpResponse<T>>;
|
|
40
|
+
post: <T = unknown>(path: string, body?: unknown, headers?: Record<string, string>) => Promise<HttpResponse<T>>;
|
|
41
|
+
put: <T = unknown>(path: string, body?: unknown, headers?: Record<string, string>) => Promise<HttpResponse<T>>;
|
|
42
|
+
delete: <T = unknown>(path: string, headers?: Record<string, string>) => Promise<HttpResponse<T>>;
|
|
43
|
+
};
|
|
44
|
+
export declare const http: {
|
|
45
|
+
request: <T = unknown>(method: string, path: string, body?: unknown, headers?: Record<string, string>) => Promise<HttpResponse<T>>;
|
|
46
|
+
get: <T = unknown>(path: string, headers?: Record<string, string>) => Promise<HttpResponse<T>>;
|
|
47
|
+
post: <T = unknown>(path: string, body?: unknown, headers?: Record<string, string>) => Promise<HttpResponse<T>>;
|
|
48
|
+
put: <T = unknown>(path: string, body?: unknown, headers?: Record<string, string>) => Promise<HttpResponse<T>>;
|
|
49
|
+
delete: <T = unknown>(path: string, headers?: Record<string, string>) => Promise<HttpResponse<T>>;
|
|
50
|
+
};
|
|
51
|
+
export default http;
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// HTTP client wrapper for Schemory CLI
|
|
2
|
+
// Base URL from environment or config, attaches session token if present
|
|
3
|
+
import fetch from 'node-fetch';
|
|
4
|
+
// Default API URL from ARCHITECTURE.md
|
|
5
|
+
const DEFAULT_API_URL = 'https://api.schemory.org';
|
|
6
|
+
/**
|
|
7
|
+
* Create an HTTP client with configuration
|
|
8
|
+
*/
|
|
9
|
+
export function createHttpClient(config = {}) {
|
|
10
|
+
const apiUrl = config.apiUrl || DEFAULT_API_URL;
|
|
11
|
+
const token = config.token;
|
|
12
|
+
/**
|
|
13
|
+
* Make an HTTP request to the Schemory API
|
|
14
|
+
*/
|
|
15
|
+
async function request(method, path, body, headers = {}) {
|
|
16
|
+
const url = `${apiUrl}${path}`;
|
|
17
|
+
// Build request options
|
|
18
|
+
const options = {
|
|
19
|
+
method,
|
|
20
|
+
headers: {
|
|
21
|
+
'Content-Type': 'application/json',
|
|
22
|
+
...headers,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
// Attach Authorization header only when a token is present
|
|
26
|
+
if (token) {
|
|
27
|
+
options.headers = {
|
|
28
|
+
...options.headers,
|
|
29
|
+
Authorization: `Bearer ${token}`,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
// Add body if provided
|
|
33
|
+
if (body !== undefined) {
|
|
34
|
+
options.body = JSON.stringify(body);
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const response = await fetch(url, options);
|
|
38
|
+
const responseData = await response.text();
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
// Try to parse error response
|
|
41
|
+
try {
|
|
42
|
+
const errorData = responseData ? JSON.parse(responseData) : null;
|
|
43
|
+
if (errorData && errorData.error) {
|
|
44
|
+
return {
|
|
45
|
+
status: response.status,
|
|
46
|
+
error: {
|
|
47
|
+
code: errorData.error.code || 'UNKNOWN_ERROR',
|
|
48
|
+
message: errorData.error.message || 'Unknown error',
|
|
49
|
+
details: errorData.error.details,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
status: response.status,
|
|
55
|
+
error: {
|
|
56
|
+
code: 'HTTP_ERROR',
|
|
57
|
+
message: responseData || `HTTP ${response.status}`,
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return {
|
|
63
|
+
status: response.status,
|
|
64
|
+
error: {
|
|
65
|
+
code: 'HTTP_ERROR',
|
|
66
|
+
message: responseData || `HTTP ${response.status}`,
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Parse successful response
|
|
72
|
+
if (responseData) {
|
|
73
|
+
try {
|
|
74
|
+
const data = JSON.parse(responseData);
|
|
75
|
+
return {
|
|
76
|
+
status: response.status,
|
|
77
|
+
data,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// If response is not JSON, return as-is
|
|
82
|
+
return {
|
|
83
|
+
status: response.status,
|
|
84
|
+
data: responseData,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
status: response.status,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
94
|
+
return {
|
|
95
|
+
status: 0,
|
|
96
|
+
error: {
|
|
97
|
+
code: 'NETWORK_ERROR',
|
|
98
|
+
message: errorMessage,
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
request,
|
|
105
|
+
get: (path, headers) => request('GET', path, undefined, headers),
|
|
106
|
+
post: (path, body, headers) => request('POST', path, body, headers),
|
|
107
|
+
put: (path, body, headers) => request('PUT', path, body, headers),
|
|
108
|
+
delete: (path, headers) => request('DELETE', path, undefined, headers),
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Default HTTP client instance (can be configured after import)
|
|
113
|
+
* This is a singleton that can be reconfigured with setHttpClientConfig
|
|
114
|
+
*/
|
|
115
|
+
let defaultClient = createHttpClient();
|
|
116
|
+
/**
|
|
117
|
+
* Reconfigure the default HTTP client
|
|
118
|
+
*/
|
|
119
|
+
export function setHttpClientConfig(config) {
|
|
120
|
+
defaultClient = createHttpClient(config);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Get the default HTTP client
|
|
124
|
+
*/
|
|
125
|
+
export function getHttpClient() {
|
|
126
|
+
return defaultClient;
|
|
127
|
+
}
|
|
128
|
+
// Export the default client methods directly for convenience
|
|
129
|
+
export const http = defaultClient;
|
|
130
|
+
export default http;
|
|
131
|
+
//# sourceMappingURL=http.js.map
|
package/dist/http.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Schemory CLI entry point
|
|
3
|
+
// This is the bin entry point that runs the CLI
|
|
4
|
+
import { createCLI } from './cli.js';
|
|
5
|
+
const program = createCLI();
|
|
6
|
+
(async () => {
|
|
7
|
+
try {
|
|
8
|
+
await program.parseAsync(process.argv);
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
const message = error instanceof Error ? error.message : 'Unknown error';
|
|
12
|
+
console.error(`Error: ${message}`);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
})();
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,2BAA2B;AAC3B,gDAAgD;AAEhD,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;AAE5B,CAAC,KAAK,IAAI,EAAE;IACV,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACzE,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,EAAE,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "schemory",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI tool for Schemory",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"schemory": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"test": "vitest run",
|
|
13
|
+
"test:watch": "vitest",
|
|
14
|
+
"lint": "echo \"cli: lint pass\"",
|
|
15
|
+
"dev": "echo \"cli: dev mode\""
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist/",
|
|
19
|
+
"package.json",
|
|
20
|
+
"README.md"
|
|
21
|
+
],
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"commander": "^12.0.0",
|
|
24
|
+
"node-fetch": "^3.3.2"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@types/node": "^20.19.43",
|
|
28
|
+
"typescript": "^5.4.5",
|
|
29
|
+
"vitest": "^1.6.1"
|
|
30
|
+
},
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=18.0.0"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"license": "MIT"
|
|
38
|
+
}
|