langctl 0.1.2 → 0.2.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/.github/ISSUE_TEMPLATE/bug_report.md +26 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +19 -0
- package/CONTRIBUTING.md +33 -0
- package/LICENSE +1 -1
- package/README.md +52 -11
- package/dist/api.d.ts +20 -0
- package/dist/api.js +75 -0
- package/dist/auth.d.ts +3 -2
- package/dist/auth.js +21 -27
- package/dist/commands/auth.js +2 -10
- package/dist/commands/config.js +1 -0
- package/dist/commands/debug.js +45 -41
- package/dist/commands/export.d.ts +1 -2
- package/dist/commands/export.js +70 -60
- package/dist/commands/import.d.ts +1 -0
- package/dist/commands/import.js +51 -72
- package/dist/commands/init.js +0 -10
- package/dist/commands/keys.js +122 -224
- package/dist/commands/org.js +43 -72
- package/dist/commands/projects.d.ts +3 -0
- package/dist/commands/projects.js +146 -223
- package/dist/commands/pull.js +40 -95
- package/dist/commands/team.js +115 -130
- package/dist/config.d.ts +1 -0
- package/dist/index.js +3 -3
- package/package.json +2 -3
- package/NEXT_PHASE.md +0 -618
- package/WORKING_INSTRUCTIONS.md +0 -1389
- package/dist/supabase.d.ts +0 -14
- package/dist/supabase.js +0 -30
package/dist/commands/keys.js
CHANGED
|
@@ -1,30 +1,26 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import ora from 'ora';
|
|
3
|
-
import { isAuthenticated
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
import { isAuthenticated } from '../auth.js';
|
|
4
|
+
import { getApiClient } from '../api.js';
|
|
5
|
+
import { config } from '../config.js';
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Resolve a project slug to a full project object
|
|
8
8
|
*/
|
|
9
|
-
async function
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
catch (error) {
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
9
|
+
async function resolveProject(orgId, slug) {
|
|
10
|
+
const api = getApiClient();
|
|
11
|
+
return api.get(`/orgs/${orgId}/projects/by-slug/${slug}`);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Find a key by exact name within a project (search + exact match)
|
|
15
|
+
*/
|
|
16
|
+
async function findKeyByName(orgId, projectId, keyName) {
|
|
17
|
+
const api = getApiClient();
|
|
18
|
+
const result = await api.get(`/orgs/${orgId}/projects/${projectId}/keys`, {
|
|
19
|
+
search: keyName,
|
|
20
|
+
pageSize: '100'
|
|
21
|
+
});
|
|
22
|
+
const key = result.data?.find((k) => k.key === keyName);
|
|
23
|
+
return key || null;
|
|
28
24
|
}
|
|
29
25
|
/**
|
|
30
26
|
* List translation keys
|
|
@@ -32,43 +28,48 @@ async function getProjectBySlug(apiKey, slug) {
|
|
|
32
28
|
export async function listKeysCommand(projectSlug, options) {
|
|
33
29
|
if (!isAuthenticated()) {
|
|
34
30
|
console.log(chalk.red('✗ Not authenticated. Please run "langctl auth <api-key>" first.\n'));
|
|
31
|
+
process.exitCode = 1;
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const orgId = config.get('organizationId');
|
|
35
|
+
if (!orgId) {
|
|
36
|
+
console.log(chalk.red('✗ Organization ID not found. Please run "langctl auth <api-key>" again.\n'));
|
|
37
|
+
process.exitCode = 1;
|
|
35
38
|
return;
|
|
36
39
|
}
|
|
37
|
-
const apiKey = getApiKey();
|
|
38
40
|
const spinner = ora('Fetching keys...').start();
|
|
39
41
|
try {
|
|
40
|
-
const project = await
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
offset: options.offset || 0
|
|
59
|
-
})
|
|
60
|
-
});
|
|
61
|
-
const data = await response.json();
|
|
62
|
-
if (!data.success) {
|
|
63
|
-
throw new Error(data.error);
|
|
64
|
-
}
|
|
42
|
+
const project = await resolveProject(orgId, projectSlug);
|
|
43
|
+
const limit = Math.max(1, parseInt(options.limit || '100', 10) || 100);
|
|
44
|
+
const offset = Math.max(0, parseInt(options.offset || '0', 10) || 0);
|
|
45
|
+
const skipWithinPage = offset % limit;
|
|
46
|
+
const page = Math.floor(offset / limit) + 1;
|
|
47
|
+
const pageSize = Math.min(100, limit + skipWithinPage);
|
|
48
|
+
const api = getApiClient();
|
|
49
|
+
const params = {
|
|
50
|
+
page: String(page),
|
|
51
|
+
pageSize: String(pageSize)
|
|
52
|
+
};
|
|
53
|
+
if (options.module)
|
|
54
|
+
params.module = options.module;
|
|
55
|
+
if (options.search)
|
|
56
|
+
params.search = options.search;
|
|
57
|
+
if (options.published)
|
|
58
|
+
params.published = 'true';
|
|
59
|
+
const result = await api.get(`/orgs/${orgId}/projects/${project.id}/keys`, params);
|
|
65
60
|
spinner.stop();
|
|
66
|
-
|
|
61
|
+
let keys = result.data || [];
|
|
62
|
+
if (skipWithinPage > 0) {
|
|
63
|
+
keys = keys.slice(skipWithinPage);
|
|
64
|
+
}
|
|
65
|
+
keys = keys.slice(0, limit);
|
|
66
|
+
const total = result.pagination?.total;
|
|
67
|
+
if (!keys || keys.length === 0) {
|
|
67
68
|
console.log(chalk.yellow('\nNo keys found\n'));
|
|
68
69
|
return;
|
|
69
70
|
}
|
|
70
|
-
console.log(chalk.blue.bold(`\n🔑 Translation Keys (${
|
|
71
|
-
|
|
71
|
+
console.log(chalk.blue.bold(`\n🔑 Translation Keys (${keys.length}${total ? ` of ${total}` : ''})\n`));
|
|
72
|
+
keys.forEach((key) => {
|
|
72
73
|
console.log(chalk.white.bold(key.key));
|
|
73
74
|
if (key.description) {
|
|
74
75
|
console.log(chalk.gray(` Description: ${key.description}`));
|
|
@@ -77,7 +78,7 @@ export async function listKeysCommand(projectSlug, options) {
|
|
|
77
78
|
console.log(chalk.gray(` Module: ${key.module}`));
|
|
78
79
|
}
|
|
79
80
|
console.log(chalk.gray(` Published: ${key.published ? chalk.green('Yes') : chalk.yellow('No')}`));
|
|
80
|
-
const langs = Object.keys(key.translations);
|
|
81
|
+
const langs = Object.keys(key.translations || {});
|
|
81
82
|
if (langs.length > 0) {
|
|
82
83
|
console.log(chalk.gray(` Languages: ${langs.join(', ')}`));
|
|
83
84
|
}
|
|
@@ -87,6 +88,7 @@ export async function listKeysCommand(projectSlug, options) {
|
|
|
87
88
|
catch (error) {
|
|
88
89
|
spinner.fail(chalk.red('Failed to list keys'));
|
|
89
90
|
console.error(chalk.red(`Error: ${error.message}\n`));
|
|
91
|
+
process.exitCode = 1;
|
|
90
92
|
}
|
|
91
93
|
}
|
|
92
94
|
/**
|
|
@@ -95,36 +97,19 @@ export async function listKeysCommand(projectSlug, options) {
|
|
|
95
97
|
export async function getKeyCommand(projectSlug, keyName) {
|
|
96
98
|
if (!isAuthenticated()) {
|
|
97
99
|
console.log(chalk.red('✗ Not authenticated. Please run "langctl auth <api-key>" first.\n'));
|
|
100
|
+
process.exitCode = 1;
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const orgId = config.get('organizationId');
|
|
104
|
+
if (!orgId) {
|
|
105
|
+
console.log(chalk.red('✗ Organization ID not found. Please run "langctl auth <api-key>" again.\n'));
|
|
106
|
+
process.exitCode = 1;
|
|
98
107
|
return;
|
|
99
108
|
}
|
|
100
|
-
const apiKey = getApiKey();
|
|
101
109
|
const spinner = ora('Fetching key...').start();
|
|
102
110
|
try {
|
|
103
|
-
const project = await
|
|
104
|
-
|
|
105
|
-
spinner.fail(chalk.red(`Project "${projectSlug}" not found`));
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
// First list to find the key ID
|
|
109
|
-
const listResponse = await fetch(EDGE_FUNCTION_URL, {
|
|
110
|
-
method: 'POST',
|
|
111
|
-
headers: {
|
|
112
|
-
'Content-Type': 'application/json',
|
|
113
|
-
'X-API-Key': apiKey
|
|
114
|
-
},
|
|
115
|
-
body: JSON.stringify({
|
|
116
|
-
action: 'list',
|
|
117
|
-
projectId: project.id,
|
|
118
|
-
search: keyName,
|
|
119
|
-
limit: 1
|
|
120
|
-
})
|
|
121
|
-
});
|
|
122
|
-
const listData = await listResponse.json();
|
|
123
|
-
if (!listData.success || !listData.keys || listData.keys.length === 0) {
|
|
124
|
-
spinner.fail(chalk.red(`Key "${keyName}" not found`));
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
const key = listData.keys.find((k) => k.key === keyName);
|
|
111
|
+
const project = await resolveProject(orgId, projectSlug);
|
|
112
|
+
const key = await findKeyByName(orgId, project.id, keyName);
|
|
128
113
|
if (!key) {
|
|
129
114
|
spinner.fail(chalk.red(`Key "${keyName}" not found`));
|
|
130
115
|
return;
|
|
@@ -141,7 +126,7 @@ export async function getKeyCommand(projectSlug, keyName) {
|
|
|
141
126
|
}
|
|
142
127
|
console.log(chalk.gray(`Published: ${key.published ? chalk.green('Yes') : chalk.yellow('No')}`));
|
|
143
128
|
console.log(chalk.blue.bold('\nTranslations:'));
|
|
144
|
-
Object.entries(key.translations).forEach(([lang, value]) => {
|
|
129
|
+
Object.entries(key.translations || {}).forEach(([lang, value]) => {
|
|
145
130
|
console.log(chalk.white(` ${lang}: ${value}`));
|
|
146
131
|
});
|
|
147
132
|
console.log('');
|
|
@@ -149,6 +134,7 @@ export async function getKeyCommand(projectSlug, keyName) {
|
|
|
149
134
|
catch (error) {
|
|
150
135
|
spinner.fail(chalk.red('Failed to get key'));
|
|
151
136
|
console.error(chalk.red(`Error: ${error.message}\n`));
|
|
137
|
+
process.exitCode = 1;
|
|
152
138
|
}
|
|
153
139
|
}
|
|
154
140
|
/**
|
|
@@ -157,16 +143,18 @@ export async function getKeyCommand(projectSlug, keyName) {
|
|
|
157
143
|
export async function createKeyCommand(projectSlug, keyName, options) {
|
|
158
144
|
if (!isAuthenticated()) {
|
|
159
145
|
console.log(chalk.red('✗ Not authenticated. Please run "langctl auth <api-key>" first.\n'));
|
|
146
|
+
process.exitCode = 1;
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const orgId = config.get('organizationId');
|
|
150
|
+
if (!orgId) {
|
|
151
|
+
console.log(chalk.red('✗ Organization ID not found. Please run "langctl auth <api-key>" again.\n'));
|
|
152
|
+
process.exitCode = 1;
|
|
160
153
|
return;
|
|
161
154
|
}
|
|
162
|
-
const apiKey = getApiKey();
|
|
163
155
|
const spinner = ora('Creating key...').start();
|
|
164
156
|
try {
|
|
165
|
-
const project = await
|
|
166
|
-
if (!project) {
|
|
167
|
-
spinner.fail(chalk.red(`Project "${projectSlug}" not found`));
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
157
|
+
const project = await resolveProject(orgId, projectSlug);
|
|
170
158
|
// Build translations object from --value-* options
|
|
171
159
|
const translations = {};
|
|
172
160
|
Object.keys(options).forEach(opt => {
|
|
@@ -177,32 +165,21 @@ export async function createKeyCommand(projectSlug, keyName, options) {
|
|
|
177
165
|
}
|
|
178
166
|
}
|
|
179
167
|
});
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
action: 'create',
|
|
188
|
-
projectId: project.id,
|
|
189
|
-
key: keyName,
|
|
190
|
-
translations,
|
|
191
|
-
description: options.description,
|
|
192
|
-
module: options.module,
|
|
193
|
-
tags: options.tags ? options.tags.split(',') : []
|
|
194
|
-
})
|
|
168
|
+
const api = getApiClient();
|
|
169
|
+
await api.post(`/orgs/${orgId}/projects/${project.id}/keys`, {
|
|
170
|
+
key: keyName,
|
|
171
|
+
translations: Object.keys(translations).length > 0 ? translations : undefined,
|
|
172
|
+
description: options.description,
|
|
173
|
+
module: options.module,
|
|
174
|
+
tags: options.tags ? options.tags.split(',') : undefined
|
|
195
175
|
});
|
|
196
|
-
const data = await response.json();
|
|
197
|
-
if (!data.success) {
|
|
198
|
-
throw new Error(data.error);
|
|
199
|
-
}
|
|
200
176
|
spinner.succeed(chalk.green(`Created key: ${keyName}`));
|
|
201
177
|
console.log('');
|
|
202
178
|
}
|
|
203
179
|
catch (error) {
|
|
204
180
|
spinner.fail(chalk.red('Failed to create key'));
|
|
205
181
|
console.error(chalk.red(`Error: ${error.message}\n`));
|
|
182
|
+
process.exitCode = 1;
|
|
206
183
|
}
|
|
207
184
|
}
|
|
208
185
|
/**
|
|
@@ -211,59 +188,32 @@ export async function createKeyCommand(projectSlug, keyName, options) {
|
|
|
211
188
|
export async function deleteKeyCommand(projectSlug, keyName) {
|
|
212
189
|
if (!isAuthenticated()) {
|
|
213
190
|
console.log(chalk.red('✗ Not authenticated. Please run "langctl auth <api-key>" first.\n'));
|
|
191
|
+
process.exitCode = 1;
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const orgId = config.get('organizationId');
|
|
195
|
+
if (!orgId) {
|
|
196
|
+
console.log(chalk.red('✗ Organization ID not found. Please run "langctl auth <api-key>" again.\n'));
|
|
197
|
+
process.exitCode = 1;
|
|
214
198
|
return;
|
|
215
199
|
}
|
|
216
|
-
const apiKey = getApiKey();
|
|
217
200
|
const spinner = ora('Deleting key...').start();
|
|
218
201
|
try {
|
|
219
|
-
const project = await
|
|
220
|
-
|
|
221
|
-
spinner.fail(chalk.red(`Project "${projectSlug}" not found`));
|
|
222
|
-
return;
|
|
223
|
-
}
|
|
224
|
-
// Find key ID
|
|
225
|
-
const listResponse = await fetch(EDGE_FUNCTION_URL, {
|
|
226
|
-
method: 'POST',
|
|
227
|
-
headers: {
|
|
228
|
-
'Content-Type': 'application/json',
|
|
229
|
-
'X-API-Key': apiKey
|
|
230
|
-
},
|
|
231
|
-
body: JSON.stringify({
|
|
232
|
-
action: 'list',
|
|
233
|
-
projectId: project.id,
|
|
234
|
-
search: keyName,
|
|
235
|
-
limit: 1
|
|
236
|
-
})
|
|
237
|
-
});
|
|
238
|
-
const listData = await listResponse.json();
|
|
239
|
-
const key = listData.keys?.find((k) => k.key === keyName);
|
|
202
|
+
const project = await resolveProject(orgId, projectSlug);
|
|
203
|
+
const key = await findKeyByName(orgId, project.id, keyName);
|
|
240
204
|
if (!key) {
|
|
241
205
|
spinner.fail(chalk.red(`Key "${keyName}" not found`));
|
|
242
206
|
return;
|
|
243
207
|
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
method: 'POST',
|
|
247
|
-
headers: {
|
|
248
|
-
'Content-Type': 'application/json',
|
|
249
|
-
'X-API-Key': apiKey
|
|
250
|
-
},
|
|
251
|
-
body: JSON.stringify({
|
|
252
|
-
action: 'delete',
|
|
253
|
-
projectId: project.id,
|
|
254
|
-
keyId: key.id
|
|
255
|
-
})
|
|
256
|
-
});
|
|
257
|
-
const data = await response.json();
|
|
258
|
-
if (!data.success) {
|
|
259
|
-
throw new Error(data.error);
|
|
260
|
-
}
|
|
208
|
+
const api = getApiClient();
|
|
209
|
+
await api.delete(`/orgs/${orgId}/projects/${project.id}/keys/${key.id}`);
|
|
261
210
|
spinner.succeed(chalk.green(`Deleted key: ${keyName}`));
|
|
262
211
|
console.log('');
|
|
263
212
|
}
|
|
264
213
|
catch (error) {
|
|
265
214
|
spinner.fail(chalk.red('Failed to delete key'));
|
|
266
215
|
console.error(chalk.red(`Error: ${error.message}\n`));
|
|
216
|
+
process.exitCode = 1;
|
|
267
217
|
}
|
|
268
218
|
}
|
|
269
219
|
/**
|
|
@@ -272,61 +222,32 @@ export async function deleteKeyCommand(projectSlug, keyName) {
|
|
|
272
222
|
export async function translateKeyCommand(projectSlug, keyName, options) {
|
|
273
223
|
if (!isAuthenticated()) {
|
|
274
224
|
console.log(chalk.red('✗ Not authenticated. Please run "langctl auth <api-key>" first.\n'));
|
|
225
|
+
process.exitCode = 1;
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
const orgId = config.get('organizationId');
|
|
229
|
+
if (!orgId) {
|
|
230
|
+
console.log(chalk.red('✗ Organization ID not found. Please run "langctl auth <api-key>" again.\n'));
|
|
231
|
+
process.exitCode = 1;
|
|
275
232
|
return;
|
|
276
233
|
}
|
|
277
|
-
const apiKey = getApiKey();
|
|
278
234
|
const spinner = ora('Updating translation...').start();
|
|
279
235
|
try {
|
|
280
|
-
const project = await
|
|
281
|
-
|
|
282
|
-
spinner.fail(chalk.red(`Project "${projectSlug}" not found`));
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
// Find key ID
|
|
286
|
-
const listResponse = await fetch(EDGE_FUNCTION_URL, {
|
|
287
|
-
method: 'POST',
|
|
288
|
-
headers: {
|
|
289
|
-
'Content-Type': 'application/json',
|
|
290
|
-
'X-API-Key': apiKey
|
|
291
|
-
},
|
|
292
|
-
body: JSON.stringify({
|
|
293
|
-
action: 'list',
|
|
294
|
-
projectId: project.id,
|
|
295
|
-
search: keyName,
|
|
296
|
-
limit: 1
|
|
297
|
-
})
|
|
298
|
-
});
|
|
299
|
-
const listData = await listResponse.json();
|
|
300
|
-
const key = listData.keys?.find((k) => k.key === keyName);
|
|
236
|
+
const project = await resolveProject(orgId, projectSlug);
|
|
237
|
+
const key = await findKeyByName(orgId, project.id, keyName);
|
|
301
238
|
if (!key) {
|
|
302
239
|
spinner.fail(chalk.red(`Key "${keyName}" not found`));
|
|
303
240
|
return;
|
|
304
241
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
method: 'POST',
|
|
308
|
-
headers: {
|
|
309
|
-
'Content-Type': 'application/json',
|
|
310
|
-
'X-API-Key': apiKey
|
|
311
|
-
},
|
|
312
|
-
body: JSON.stringify({
|
|
313
|
-
action: 'translate',
|
|
314
|
-
projectId: project.id,
|
|
315
|
-
keyId: key.id,
|
|
316
|
-
language: options.language,
|
|
317
|
-
value: options.value
|
|
318
|
-
})
|
|
319
|
-
});
|
|
320
|
-
const data = await response.json();
|
|
321
|
-
if (!data.success) {
|
|
322
|
-
throw new Error(data.error);
|
|
323
|
-
}
|
|
242
|
+
const api = getApiClient();
|
|
243
|
+
await api.patch(`/orgs/${orgId}/projects/${project.id}/keys/${key.id}/translations/${options.language}`, { value: options.value });
|
|
324
244
|
spinner.succeed(chalk.green(`Updated ${options.language} translation for ${keyName}`));
|
|
325
245
|
console.log('');
|
|
326
246
|
}
|
|
327
247
|
catch (error) {
|
|
328
248
|
spinner.fail(chalk.red('Failed to update translation'));
|
|
329
249
|
console.error(chalk.red(`Error: ${error.message}\n`));
|
|
250
|
+
process.exitCode = 1;
|
|
330
251
|
}
|
|
331
252
|
}
|
|
332
253
|
/**
|
|
@@ -335,62 +256,39 @@ export async function translateKeyCommand(projectSlug, keyName, options) {
|
|
|
335
256
|
export async function publishKeysCommand(projectSlug, keys, options) {
|
|
336
257
|
if (!isAuthenticated()) {
|
|
337
258
|
console.log(chalk.red('✗ Not authenticated. Please run "langctl auth <api-key>" first.\n'));
|
|
259
|
+
process.exitCode = 1;
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
const orgId = config.get('organizationId');
|
|
263
|
+
if (!orgId) {
|
|
264
|
+
console.log(chalk.red('✗ Organization ID not found. Please run "langctl auth <api-key>" again.\n'));
|
|
265
|
+
process.exitCode = 1;
|
|
338
266
|
return;
|
|
339
267
|
}
|
|
340
|
-
const apiKey = getApiKey();
|
|
341
268
|
const action = options.unpublish ? 'unpublish' : 'publish';
|
|
342
269
|
const spinner = ora(`${action === 'publish' ? 'Publishing' : 'Unpublishing'} keys...`).start();
|
|
343
270
|
try {
|
|
344
|
-
const project = await
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
// Get key IDs
|
|
350
|
-
const listResponse = await fetch(EDGE_FUNCTION_URL, {
|
|
351
|
-
method: 'POST',
|
|
352
|
-
headers: {
|
|
353
|
-
'Content-Type': 'application/json',
|
|
354
|
-
'X-API-Key': apiKey
|
|
355
|
-
},
|
|
356
|
-
body: JSON.stringify({
|
|
357
|
-
action: 'list',
|
|
358
|
-
projectId: project.id,
|
|
359
|
-
limit: 1000
|
|
360
|
-
})
|
|
271
|
+
const project = await resolveProject(orgId, projectSlug);
|
|
272
|
+
// List all keys to match names to IDs
|
|
273
|
+
const api = getApiClient();
|
|
274
|
+
const result = await api.get(`/orgs/${orgId}/projects/${project.id}/keys`, {
|
|
275
|
+
pageSize: '1000'
|
|
361
276
|
});
|
|
362
|
-
const
|
|
363
|
-
const keyIds = listData.keys
|
|
277
|
+
const keyIds = result.data
|
|
364
278
|
?.filter((k) => keys.includes(k.key))
|
|
365
279
|
.map((k) => k.id) || [];
|
|
366
280
|
if (keyIds.length === 0) {
|
|
367
281
|
spinner.fail(chalk.red('No matching keys found'));
|
|
368
282
|
return;
|
|
369
283
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
method: 'POST',
|
|
373
|
-
headers: {
|
|
374
|
-
'Content-Type': 'application/json',
|
|
375
|
-
'X-API-Key': apiKey
|
|
376
|
-
},
|
|
377
|
-
body: JSON.stringify({
|
|
378
|
-
action: 'publish',
|
|
379
|
-
projectId: project.id,
|
|
380
|
-
keyIds,
|
|
381
|
-
published: !options.unpublish
|
|
382
|
-
})
|
|
383
|
-
});
|
|
384
|
-
const data = await response.json();
|
|
385
|
-
if (!data.success) {
|
|
386
|
-
throw new Error(data.error);
|
|
387
|
-
}
|
|
388
|
-
spinner.succeed(chalk.green(data.message));
|
|
284
|
+
const response = await api.post(`/orgs/${orgId}/projects/${project.id}/keys/bulk-publish`, { keyIds, published: !options.unpublish });
|
|
285
|
+
spinner.succeed(chalk.green(response.message || `${action === 'publish' ? 'Published' : 'Unpublished'} ${response.count} key(s)`));
|
|
389
286
|
console.log('');
|
|
390
287
|
}
|
|
391
288
|
catch (error) {
|
|
392
289
|
spinner.fail(chalk.red(`Failed to ${action} keys`));
|
|
393
290
|
console.error(chalk.red(`Error: ${error.message}\n`));
|
|
291
|
+
process.exitCode = 1;
|
|
394
292
|
}
|
|
395
293
|
}
|
|
396
294
|
//# sourceMappingURL=keys.js.map
|