kitstore-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/.env.test +4 -0
- package/.eslintrc.js +29 -0
- package/dist/__tests__/commands/init.test.js +76 -0
- package/dist/__tests__/commands/install.test.js +422 -0
- package/dist/__tests__/commands/list.test.js +173 -0
- package/dist/__tests__/commands/login.test.js +281 -0
- package/dist/__tests__/commands/rule-check.test.js +72 -0
- package/dist/__tests__/commands/search.test.js +175 -0
- package/dist/__tests__/commands/upload.test.js +367 -0
- package/dist/__tests__/config.test.js +179 -0
- package/dist/__tests__/setup.js +8 -0
- package/dist/api/client.js +18 -0
- package/dist/api/generated/api.js +912 -0
- package/dist/api/generated/base.js +48 -0
- package/dist/api/generated/common.js +108 -0
- package/dist/api/generated/configuration.js +48 -0
- package/dist/api/generated/index.js +31 -0
- package/dist/commands/init.js +79 -0
- package/dist/commands/install.js +150 -0
- package/dist/commands/list.js +70 -0
- package/dist/commands/login.js +64 -0
- package/dist/commands/rule-check.js +81 -0
- package/dist/commands/search.js +59 -0
- package/dist/commands/upload.js +138 -0
- package/dist/config.js +84 -0
- package/dist/index.js +71 -0
- package/e2e/install.e2e.test.ts +237 -0
- package/e2e/integration.e2e.test.ts +346 -0
- package/e2e/login.e2e.test.ts +188 -0
- package/jest.config.js +24 -0
- package/openapitools.json +7 -0
- package/package.json +41 -0
- package/src/__tests__/commands/init.test.ts +52 -0
- package/src/__tests__/commands/install.test.ts +449 -0
- package/src/__tests__/commands/list.test.ts +164 -0
- package/src/__tests__/commands/login.test.ts +293 -0
- package/src/__tests__/commands/rule-check.test.ts +52 -0
- package/src/__tests__/commands/search.test.ts +168 -0
- package/src/__tests__/commands/upload.test.ts +404 -0
- package/src/__tests__/config.test.ts +181 -0
- package/src/__tests__/setup.ts +11 -0
- package/src/api/client.ts +20 -0
- package/src/api/generated/.openapi-generator/FILES +17 -0
- package/src/api/generated/.openapi-generator/VERSION +1 -0
- package/src/api/generated/.openapi-generator-ignore +23 -0
- package/src/api/generated/api.ts +1171 -0
- package/src/api/generated/base.ts +62 -0
- package/src/api/generated/common.ts +113 -0
- package/src/api/generated/configuration.ts +121 -0
- package/src/api/generated/docs/AuthApi.md +158 -0
- package/src/api/generated/docs/AuthResponseDto.md +22 -0
- package/src/api/generated/docs/AuthUserDto.md +24 -0
- package/src/api/generated/docs/HealthApi.md +183 -0
- package/src/api/generated/docs/LoginDto.md +22 -0
- package/src/api/generated/docs/RegisterDto.md +24 -0
- package/src/api/generated/docs/RuleAuthorDto.md +22 -0
- package/src/api/generated/docs/RuleResponseDto.md +36 -0
- package/src/api/generated/docs/RulesApi.md +289 -0
- package/src/api/generated/git_push.sh +57 -0
- package/src/api/generated/index.ts +18 -0
- package/src/commands/init.ts +46 -0
- package/src/commands/install.ts +129 -0
- package/src/commands/list.ts +71 -0
- package/src/commands/login.ts +65 -0
- package/src/commands/rule-check.ts +49 -0
- package/src/commands/search.ts +66 -0
- package/src/commands/upload.ts +117 -0
- package/src/config.ts +66 -0
- package/src/index.ts +79 -0
- package/test-cli-config.js +118 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const globals_1 = require("@jest/globals");
|
|
37
|
+
const config_1 = require("../config");
|
|
38
|
+
// Mock dependencies
|
|
39
|
+
globals_1.jest.mock('fs-extra');
|
|
40
|
+
globals_1.jest.mock('os', () => ({
|
|
41
|
+
homedir: globals_1.jest.fn().mockReturnValue('C:\\Users\\trieu'),
|
|
42
|
+
}));
|
|
43
|
+
const fs = __importStar(require("fs-extra"));
|
|
44
|
+
const os = __importStar(require("os"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
describe('Config', () => {
|
|
47
|
+
const mockHomeDir = 'C:\\Users\\trieu';
|
|
48
|
+
const mockConfigDir = path.join(mockHomeDir, '.kitstore');
|
|
49
|
+
const mockConfigFile = path.join(mockConfigDir, 'config.json');
|
|
50
|
+
beforeEach(() => {
|
|
51
|
+
globals_1.jest.clearAllMocks();
|
|
52
|
+
// Setup default mocks
|
|
53
|
+
// @ts-ignore - Jest mock types are complex
|
|
54
|
+
os.homedir.mockReturnValue(mockHomeDir);
|
|
55
|
+
// @ts-ignore
|
|
56
|
+
fs.ensureDir.mockResolvedValue(undefined);
|
|
57
|
+
// @ts-ignore
|
|
58
|
+
fs.pathExists.mockResolvedValue(false);
|
|
59
|
+
// @ts-ignore
|
|
60
|
+
fs.writeJson.mockResolvedValue(undefined);
|
|
61
|
+
// @ts-ignore
|
|
62
|
+
fs.existsSync.mockReturnValue(false);
|
|
63
|
+
});
|
|
64
|
+
describe('getConfig', () => {
|
|
65
|
+
it('should return default config when config file does not exist', async () => {
|
|
66
|
+
// @ts-ignore
|
|
67
|
+
fs.pathExists.mockResolvedValue(false);
|
|
68
|
+
const result = await (0, config_1.getConfig)();
|
|
69
|
+
expect(result).toEqual({
|
|
70
|
+
server: 'http://localhost:3000'
|
|
71
|
+
});
|
|
72
|
+
expect(fs.ensureDir).toHaveBeenCalledWith(mockConfigDir);
|
|
73
|
+
expect(fs.pathExists).toHaveBeenCalledWith(mockConfigFile);
|
|
74
|
+
});
|
|
75
|
+
it('should load and merge config from file', async () => {
|
|
76
|
+
const fileConfig = {
|
|
77
|
+
token: 'test-token',
|
|
78
|
+
server: 'https://api.example.com',
|
|
79
|
+
user: { id: '123', username: 'testuser' }
|
|
80
|
+
};
|
|
81
|
+
// @ts-ignore
|
|
82
|
+
fs.pathExists.mockResolvedValue(true);
|
|
83
|
+
// @ts-ignore
|
|
84
|
+
fs.readJson.mockResolvedValue(fileConfig);
|
|
85
|
+
const result = await (0, config_1.getConfig)();
|
|
86
|
+
expect(result).toEqual({
|
|
87
|
+
server: 'https://api.example.com', // From file
|
|
88
|
+
token: 'test-token',
|
|
89
|
+
user: { id: '123', username: 'testuser' }
|
|
90
|
+
});
|
|
91
|
+
expect(fs.readJson).toHaveBeenCalledWith(mockConfigFile);
|
|
92
|
+
});
|
|
93
|
+
it('should handle file read errors gracefully', async () => {
|
|
94
|
+
// @ts-ignore
|
|
95
|
+
fs.pathExists.mockResolvedValue(true);
|
|
96
|
+
// @ts-ignore
|
|
97
|
+
fs.readJson.mockRejectedValue(new Error('Read failed'));
|
|
98
|
+
const result = await (0, config_1.getConfig)();
|
|
99
|
+
expect(result).toEqual({
|
|
100
|
+
server: 'http://localhost:3000'
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
it('should handle ensureDir errors gracefully', async () => {
|
|
104
|
+
// @ts-ignore
|
|
105
|
+
fs.ensureDir.mockRejectedValue(new Error('Permission denied'));
|
|
106
|
+
const result = await (0, config_1.getConfig)();
|
|
107
|
+
expect(result).toEqual({
|
|
108
|
+
server: 'http://localhost:3000'
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
describe('saveConfig', () => {
|
|
113
|
+
it('should save config to file', async () => {
|
|
114
|
+
const config = {
|
|
115
|
+
token: 'new-token',
|
|
116
|
+
server: 'https://new-server.com',
|
|
117
|
+
user: { id: '456', username: 'newuser' }
|
|
118
|
+
};
|
|
119
|
+
await (0, config_1.saveConfig)(config);
|
|
120
|
+
expect(fs.ensureDir).toHaveBeenCalledWith(mockConfigDir);
|
|
121
|
+
expect(fs.writeJson).toHaveBeenCalledWith(mockConfigFile, config, { spaces: 2 });
|
|
122
|
+
});
|
|
123
|
+
it('should handle write errors', async () => {
|
|
124
|
+
const config = { server: 'http://localhost:3000' };
|
|
125
|
+
// @ts-ignore
|
|
126
|
+
fs.writeJson.mockRejectedValue(new Error('Write failed'));
|
|
127
|
+
await expect((0, config_1.saveConfig)(config)).rejects.toThrow('Write failed');
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
describe('getInstallPaths', () => {
|
|
131
|
+
it('should return paths in current directory .cursor folder when it exists', () => {
|
|
132
|
+
// @ts-ignore
|
|
133
|
+
fs.existsSync.mockReturnValue(true);
|
|
134
|
+
const result = (0, config_1.getInstallPaths)();
|
|
135
|
+
const cwd = process.cwd();
|
|
136
|
+
expect(result).toEqual({
|
|
137
|
+
rules: path.join(cwd, '.cursor', 'rules'),
|
|
138
|
+
commands: path.join(cwd, '.cursor', 'commands')
|
|
139
|
+
});
|
|
140
|
+
expect(fs.existsSync).toHaveBeenCalledWith(path.join(cwd, '.cursor'));
|
|
141
|
+
});
|
|
142
|
+
it('should return home directory paths when .cursor does not exist in cwd', () => {
|
|
143
|
+
// @ts-ignore
|
|
144
|
+
fs.existsSync.mockReturnValue(false);
|
|
145
|
+
const result = (0, config_1.getInstallPaths)();
|
|
146
|
+
expect(result).toEqual({
|
|
147
|
+
rules: path.join(mockHomeDir, '.cursor', 'rules'),
|
|
148
|
+
commands: path.join(mockHomeDir, '.cursor', 'commands')
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
describe('Config interface', () => {
|
|
153
|
+
it('should support all config properties', () => {
|
|
154
|
+
const config = {
|
|
155
|
+
token: 'jwt-token',
|
|
156
|
+
server: 'https://api.test.com',
|
|
157
|
+
user: {
|
|
158
|
+
id: 'user-123',
|
|
159
|
+
username: 'testuser',
|
|
160
|
+
email: 'test@example.com'
|
|
161
|
+
},
|
|
162
|
+
lastLogin: '2024-01-01T00:00:00Z'
|
|
163
|
+
};
|
|
164
|
+
expect(config.token).toBe('jwt-token');
|
|
165
|
+
expect(config.server).toBe('https://api.test.com');
|
|
166
|
+
expect(config.user?.username).toBe('testuser');
|
|
167
|
+
expect(config.lastLogin).toBe('2024-01-01T00:00:00Z');
|
|
168
|
+
});
|
|
169
|
+
it('should allow optional properties', () => {
|
|
170
|
+
const minimalConfig = {
|
|
171
|
+
server: 'http://localhost:3000'
|
|
172
|
+
};
|
|
173
|
+
expect(minimalConfig.server).toBe('http://localhost:3000');
|
|
174
|
+
expect(minimalConfig.token).toBeUndefined();
|
|
175
|
+
expect(minimalConfig.user).toBeUndefined();
|
|
176
|
+
expect(minimalConfig.lastLogin).toBeUndefined();
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createApi = createApi;
|
|
4
|
+
const generated_1 = require("./generated");
|
|
5
|
+
const config_1 = require("../config");
|
|
6
|
+
async function createApi(options) {
|
|
7
|
+
const cfg = await (0, config_1.getConfig)();
|
|
8
|
+
const basePath = options?.server || cfg.server || 'http://localhost:3000';
|
|
9
|
+
const token = options?.token || cfg.token;
|
|
10
|
+
const configuration = new generated_1.Configuration({
|
|
11
|
+
basePath,
|
|
12
|
+
accessToken: token,
|
|
13
|
+
});
|
|
14
|
+
return {
|
|
15
|
+
authApi: new generated_1.AuthApi(configuration),
|
|
16
|
+
rulesApi: new generated_1.RulesApi(configuration),
|
|
17
|
+
};
|
|
18
|
+
}
|