langctl 0.1.2 โ†’ 0.3.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 (63) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/LICENSE +1 -1
  3. package/README.md +159 -1151
  4. package/dist/commands/auth.js +82 -24
  5. package/dist/commands/config.js +36 -25
  6. package/dist/commands/export.js +11 -112
  7. package/dist/commands/import.js +32 -164
  8. package/dist/commands/init.js +59 -80
  9. package/dist/commands/keys.js +145 -381
  10. package/dist/commands/org.js +45 -140
  11. package/dist/commands/projects.js +125 -390
  12. package/dist/commands/pull.js +78 -183
  13. package/dist/commands/push.js +125 -0
  14. package/dist/commands/team.js +68 -272
  15. package/dist/core/config.js +130 -0
  16. package/dist/core/errors.js +67 -0
  17. package/dist/core/files.js +38 -0
  18. package/dist/core/http.js +121 -0
  19. package/dist/core/output.js +96 -0
  20. package/dist/core/project.js +58 -0
  21. package/dist/core/prompts.js +56 -0
  22. package/dist/formats/index.js +285 -0
  23. package/dist/index.js +261 -508
  24. package/dist/version.js +4 -0
  25. package/package.json +22 -16
  26. package/.gitattributes +0 -2
  27. package/NEXT_PHASE.md +0 -618
  28. package/WORKING_INSTRUCTIONS.md +0 -1389
  29. package/dist/auth.d.ts +0 -37
  30. package/dist/auth.js +0 -112
  31. package/dist/commands/auth.d.ts +0 -3
  32. package/dist/commands/config.d.ts +0 -2
  33. package/dist/commands/debug.d.ts +0 -3
  34. package/dist/commands/debug.js +0 -57
  35. package/dist/commands/export.d.ts +0 -14
  36. package/dist/commands/import.d.ts +0 -11
  37. package/dist/commands/init.d.ts +0 -2
  38. package/dist/commands/keys.d.ts +0 -25
  39. package/dist/commands/org.d.ts +0 -13
  40. package/dist/commands/projects.d.ts +0 -30
  41. package/dist/commands/pull.d.ts +0 -9
  42. package/dist/commands/team.d.ts +0 -29
  43. package/dist/config.d.ts +0 -47
  44. package/dist/config.js +0 -69
  45. package/dist/exporters/index.d.ts +0 -36
  46. package/dist/exporters/index.js +0 -214
  47. package/dist/index.d.ts +0 -3
  48. package/dist/supabase.d.ts +0 -14
  49. package/dist/supabase.js +0 -30
  50. package/dist/utils/banner.d.ts +0 -9
  51. package/dist/utils/banner.js +0 -24
  52. package/translations/en.json +0 -5
  53. package/translations/en.xml +0 -9
  54. package/translations/fr.json +0 -4
  55. package/translations/fr.xml +0 -7
  56. package/translations/hi.json +0 -4
  57. package/translations/hi.xml +0 -7
  58. package/translations/ios/en.strings +0 -9
  59. package/translations/ios/fr.strings +0 -6
  60. package/translations/ios/hi.strings +0 -6
  61. package/translations/ios/ja.strings +0 -6
  62. package/translations/ja.json +0 -4
  63. package/translations/ja.xml +0 -7
@@ -1,147 +1,52 @@
1
1
  import chalk from 'chalk';
2
- import ora from 'ora';
3
- import { isAuthenticated, getApiKey } from '../auth.js';
4
- const ORG_INFO_URL = 'https://bcgnmvkgkbhbxzzflwdb.supabase.co/functions/v1/get-organization-info';
5
- /**
6
- * Get organization information
7
- */
2
+ import { getSession } from '../core/http.js';
3
+ import { log, printJson, runtime, table } from '../core/output.js';
4
+ const limit = (n) => (n === null || n === undefined ? 'unlimited' : String(n));
8
5
  export async function orgInfoCommand() {
9
- if (!isAuthenticated()) {
10
- console.log(chalk.red('โœ— Not authenticated. Please run "langctl auth <api-key>" first.\n'));
11
- return;
12
- }
13
- const apiKey = getApiKey();
14
- const spinner = ora('Fetching organization info...').start();
15
- try {
16
- const response = await fetch(ORG_INFO_URL, {
17
- method: 'POST',
18
- headers: {
19
- 'Content-Type': 'application/json',
20
- 'X-API-Key': apiKey
21
- },
22
- body: JSON.stringify({
23
- action: 'info'
24
- })
25
- });
26
- const data = await response.json();
27
- if (!data.success) {
28
- throw new Error(data.error);
29
- }
30
- spinner.stop();
31
- const org = data.organization;
32
- console.log(chalk.blue.bold('\n๐Ÿข Organization Information\n'));
33
- console.log(chalk.white.bold(org.name));
34
- console.log(chalk.gray(`ID: ${org.id}`));
35
- console.log(chalk.gray(`Slug: ${org.slug}`));
36
- if (org.description) {
37
- console.log(chalk.gray(`Description: ${org.description}`));
38
- }
39
- console.log(chalk.gray(`Plan: ${org.plan}`));
40
- console.log(chalk.gray(`Created: ${new Date(org.created_at).toLocaleDateString()}`));
41
- console.log('');
42
- }
43
- catch (error) {
44
- spinner.fail(chalk.red('Failed to fetch organization info'));
45
- console.error(chalk.red(`Error: ${error.message}\n`));
46
- }
6
+ const session = await getSession();
7
+ const org = await session.api.get(`/orgs/${session.orgId}`);
8
+ const { id, name, slug, plan, createdAt } = org;
9
+ if (runtime.json)
10
+ return printJson({ id, name, slug, plan, createdAt });
11
+ log.out(`${chalk.bold(name)} ${chalk.dim(`(${slug})`)} ${plan} plan`);
12
+ log.out(chalk.dim(`id ${id} ยท created ${createdAt.slice(0, 10)}`));
47
13
  }
48
- /**
49
- * Get organization statistics
50
- */
51
14
  export async function orgStatsCommand() {
52
- if (!isAuthenticated()) {
53
- console.log(chalk.red('โœ— Not authenticated. Please run "langctl auth <api-key>" first.\n'));
54
- return;
55
- }
56
- const apiKey = getApiKey();
57
- const spinner = ora('Fetching organization statistics...').start();
58
- try {
59
- const response = await fetch(ORG_INFO_URL, {
60
- method: 'POST',
61
- headers: {
62
- 'Content-Type': 'application/json',
63
- 'X-API-Key': apiKey
64
- },
65
- body: JSON.stringify({
66
- action: 'stats'
67
- })
68
- });
69
- const data = await response.json();
70
- if (!data.success) {
71
- throw new Error(data.error);
72
- }
73
- spinner.stop();
74
- const stats = data.stats;
75
- console.log(chalk.blue.bold('\n๐Ÿ“Š Organization Statistics\n'));
76
- console.log(chalk.white.bold('Team'));
77
- console.log(chalk.gray(` Members: ${stats.members}`));
78
- console.log('');
79
- console.log(chalk.white.bold('Projects'));
80
- console.log(chalk.gray(` Total Projects: ${stats.projects}`));
81
- console.log('');
82
- console.log(chalk.white.bold('Translation Keys'));
83
- console.log(chalk.gray(` Total Keys: ${stats.total_keys}`));
84
- console.log(chalk.green(` Published: ${stats.published_keys}`));
85
- console.log(chalk.yellow(` Unpublished: ${stats.unpublished_keys}`));
86
- console.log('');
87
- console.log(chalk.white.bold('Languages'));
88
- console.log(chalk.gray(` Total Languages: ${stats.languages}`));
89
- if (stats.language_codes && stats.language_codes.length > 0) {
90
- console.log(chalk.gray(` Codes: ${stats.language_codes.join(', ')}`));
91
- }
92
- console.log('');
93
- console.log(chalk.white.bold('Resources'));
94
- console.log(chalk.gray(` API Keys: ${stats.api_keys}`));
95
- console.log(chalk.gray(` Webhooks: ${stats.webhooks}`));
96
- console.log('');
97
- }
98
- catch (error) {
99
- spinner.fail(chalk.red('Failed to fetch statistics'));
100
- console.error(chalk.red(`Error: ${error.message}\n`));
101
- }
15
+ const session = await getSession();
16
+ const stats = await session.api.get(`/orgs/${session.orgId}/stats`);
17
+ if (runtime.json)
18
+ return printJson(stats);
19
+ table([
20
+ ['Members', String(stats.memberCount)],
21
+ ['Projects', String(stats.projectCount)],
22
+ ['Translation keys', String(stats.totalKeys)],
23
+ ['Active API keys', String(stats.apiKeyCount)],
24
+ ]);
102
25
  }
103
- /**
104
- * Get organization plan and limits
105
- */
106
26
  export async function orgPlanCommand() {
107
- if (!isAuthenticated()) {
108
- console.log(chalk.red('โœ— Not authenticated. Please run "langctl auth <api-key>" first.\n'));
109
- return;
110
- }
111
- const apiKey = getApiKey();
112
- const spinner = ora('Fetching plan information...').start();
113
- try {
114
- const response = await fetch(ORG_INFO_URL, {
115
- method: 'POST',
116
- headers: {
117
- 'Content-Type': 'application/json',
118
- 'X-API-Key': apiKey
119
- },
120
- body: JSON.stringify({
121
- action: 'plan'
122
- })
123
- });
124
- const data = await response.json();
125
- if (!data.success) {
126
- throw new Error(data.error);
127
- }
128
- spinner.stop();
129
- const limits = data.limits;
130
- console.log(chalk.blue.bold('\n๐Ÿ’Ž Subscription Plan\n'));
131
- console.log(chalk.white.bold(`Current Plan: ${data.plan.toUpperCase()}`));
132
- console.log('');
133
- console.log(chalk.white.bold('Plan Limits'));
134
- // Display limits with "Unlimited" for -1 or null values
135
- const formatLimit = (value) => (value === -1 || value === null) ? chalk.green('Unlimited') : chalk.gray(value.toString());
136
- console.log(chalk.gray(` Max Members: ${formatLimit(limits.max_members)}`));
137
- console.log(chalk.gray(` Max Projects: ${formatLimit(limits.max_projects)}`));
138
- console.log(chalk.gray(` Max Keys per Project: ${formatLimit(limits.max_keys_per_project)}`));
139
- console.log(chalk.gray(` Max API Keys: ${formatLimit(limits.max_api_keys)}`));
140
- console.log('');
141
- }
142
- catch (error) {
143
- spinner.fail(chalk.red('Failed to fetch plan information'));
144
- console.error(chalk.red(`Error: ${error.message}\n`));
145
- }
27
+ const session = await getSession();
28
+ const [org, stats] = await Promise.all([
29
+ session.api.get(`/orgs/${session.orgId}`),
30
+ session.api.get(`/orgs/${session.orgId}/stats`),
31
+ ]);
32
+ const rows = {
33
+ plan: org.plan,
34
+ members: { used: stats.memberCount, limit: org.maxMembers ?? null },
35
+ projects: { used: stats.projectCount, limit: org.maxProjects ?? null },
36
+ apiKeys: { used: stats.apiKeyCount, limit: org.maxApiKeys ?? null },
37
+ keysPerProject: { limit: org.maxKeysPerProject ?? null },
38
+ languagesPerProject: { limit: org.maxLanguagesPerProject ?? null },
39
+ aiTranslationsPerMonth: { used: org.aiTranslationsUsedThisMonth ?? 0, limit: org.aiTranslationsLimit ?? null },
40
+ };
41
+ if (runtime.json)
42
+ return printJson(rows);
43
+ log.out(`${chalk.bold(org.plan.toUpperCase())} plan`);
44
+ table([
45
+ ['Members', `${stats.memberCount} / ${limit(org.maxMembers)}`],
46
+ ['Projects', `${stats.projectCount} / ${limit(org.maxProjects)}`],
47
+ ['API keys', `${stats.apiKeyCount} / ${limit(org.maxApiKeys)}`],
48
+ ['Keys per project', limit(org.maxKeysPerProject)],
49
+ ['Languages per project', limit(org.maxLanguagesPerProject)],
50
+ ['AI translations / month', `${org.aiTranslationsUsedThisMonth ?? 0} / ${limit(org.aiTranslationsLimit)}`],
51
+ ]);
146
52
  }
147
- //# sourceMappingURL=org.js.map