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.
Files changed (71) hide show
  1. package/.env.test +4 -0
  2. package/.eslintrc.js +29 -0
  3. package/dist/__tests__/commands/init.test.js +76 -0
  4. package/dist/__tests__/commands/install.test.js +422 -0
  5. package/dist/__tests__/commands/list.test.js +173 -0
  6. package/dist/__tests__/commands/login.test.js +281 -0
  7. package/dist/__tests__/commands/rule-check.test.js +72 -0
  8. package/dist/__tests__/commands/search.test.js +175 -0
  9. package/dist/__tests__/commands/upload.test.js +367 -0
  10. package/dist/__tests__/config.test.js +179 -0
  11. package/dist/__tests__/setup.js +8 -0
  12. package/dist/api/client.js +18 -0
  13. package/dist/api/generated/api.js +912 -0
  14. package/dist/api/generated/base.js +48 -0
  15. package/dist/api/generated/common.js +108 -0
  16. package/dist/api/generated/configuration.js +48 -0
  17. package/dist/api/generated/index.js +31 -0
  18. package/dist/commands/init.js +79 -0
  19. package/dist/commands/install.js +150 -0
  20. package/dist/commands/list.js +70 -0
  21. package/dist/commands/login.js +64 -0
  22. package/dist/commands/rule-check.js +81 -0
  23. package/dist/commands/search.js +59 -0
  24. package/dist/commands/upload.js +138 -0
  25. package/dist/config.js +84 -0
  26. package/dist/index.js +71 -0
  27. package/e2e/install.e2e.test.ts +237 -0
  28. package/e2e/integration.e2e.test.ts +346 -0
  29. package/e2e/login.e2e.test.ts +188 -0
  30. package/jest.config.js +24 -0
  31. package/openapitools.json +7 -0
  32. package/package.json +41 -0
  33. package/src/__tests__/commands/init.test.ts +52 -0
  34. package/src/__tests__/commands/install.test.ts +449 -0
  35. package/src/__tests__/commands/list.test.ts +164 -0
  36. package/src/__tests__/commands/login.test.ts +293 -0
  37. package/src/__tests__/commands/rule-check.test.ts +52 -0
  38. package/src/__tests__/commands/search.test.ts +168 -0
  39. package/src/__tests__/commands/upload.test.ts +404 -0
  40. package/src/__tests__/config.test.ts +181 -0
  41. package/src/__tests__/setup.ts +11 -0
  42. package/src/api/client.ts +20 -0
  43. package/src/api/generated/.openapi-generator/FILES +17 -0
  44. package/src/api/generated/.openapi-generator/VERSION +1 -0
  45. package/src/api/generated/.openapi-generator-ignore +23 -0
  46. package/src/api/generated/api.ts +1171 -0
  47. package/src/api/generated/base.ts +62 -0
  48. package/src/api/generated/common.ts +113 -0
  49. package/src/api/generated/configuration.ts +121 -0
  50. package/src/api/generated/docs/AuthApi.md +158 -0
  51. package/src/api/generated/docs/AuthResponseDto.md +22 -0
  52. package/src/api/generated/docs/AuthUserDto.md +24 -0
  53. package/src/api/generated/docs/HealthApi.md +183 -0
  54. package/src/api/generated/docs/LoginDto.md +22 -0
  55. package/src/api/generated/docs/RegisterDto.md +24 -0
  56. package/src/api/generated/docs/RuleAuthorDto.md +22 -0
  57. package/src/api/generated/docs/RuleResponseDto.md +36 -0
  58. package/src/api/generated/docs/RulesApi.md +289 -0
  59. package/src/api/generated/git_push.sh +57 -0
  60. package/src/api/generated/index.ts +18 -0
  61. package/src/commands/init.ts +46 -0
  62. package/src/commands/install.ts +129 -0
  63. package/src/commands/list.ts +71 -0
  64. package/src/commands/login.ts +65 -0
  65. package/src/commands/rule-check.ts +49 -0
  66. package/src/commands/search.ts +66 -0
  67. package/src/commands/upload.ts +117 -0
  68. package/src/config.ts +66 -0
  69. package/src/index.ts +79 -0
  70. package/test-cli-config.js +118 -0
  71. 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,8 @@
1
+ "use strict";
2
+ // CLI Test Setup
3
+ // Load test environment variables
4
+ if (process.env.NODE_ENV === 'test') {
5
+ // Set test environment variables for CLI
6
+ process.env.API_BASE_URL = 'http://localhost:3001/api';
7
+ process.env.CLI_ENV = 'test';
8
+ }
@@ -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
+ }